1 /*
2 Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 		* Redistributions of source code must retain the above copyright
8 			notice, this list of conditions and the following disclaimer.
9 		* Redistributions in binary form must reproduce the above
10 			copyright notice, this list of conditions and the following
11 			disclaimer in the documentation and/or other materials provided
12 			with the distribution.
13 		* Neither the name of The Linux Foundation nor the names of its
14 			contributors may be used to endorse or promote products derived
15 			from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 /*!
30 	@file
31 	IPACM_Main.cpp
32 
33 	@brief
34 	This file implements the IPAM functionality.
35 
36 	@Author
37 	Skylar Chang
38 
39 */
40 /******************************************************************************
41 
42                       IPCM_MAIN.C
43 
44 ******************************************************************************/
45 
46 #include <sys/socket.h>
47 #include <signal.h>
48 #include <fcntl.h>
49 #include <pthread.h>
50 #include <sys/ioctl.h>
51 #include <linux/if.h>
52 #include <linux/netlink.h>
53 #include <linux/rtnetlink.h>
54 #include <fcntl.h>
55 #include <sys/inotify.h>
56 #include <stdlib.h>
57 #include <signal.h>
58 #include "linux/ipa_qmi_service_v01.h"
59 
60 #include "IPACM_CmdQueue.h"
61 #include "IPACM_EvtDispatcher.h"
62 #include "IPACM_Defs.h"
63 #include "IPACM_Neighbor.h"
64 #include "IPACM_IfaceManager.h"
65 #include "IPACM_Log.h"
66 
67 #include "IPACM_ConntrackListener.h"
68 #include "IPACM_ConntrackClient.h"
69 #include "IPACM_Netlink.h"
70 
71 #ifdef FEATURE_IPACM_HAL
72 #include "IPACM_OffloadManager.h"
73 #include <HAL.h>
74 #endif
75 
76 /* not defined(FEATURE_IPA_ANDROID)*/
77 #ifndef FEATURE_IPA_ANDROID
78 #include "IPACM_LanToLan.h"
79 #endif
80 
81 #define IPA_DRIVER  "/dev/ipa"
82 
83 #define IPACM_FIREWALL_FILE_NAME    "mobileap_firewall.xml"
84 #define IPACM_CFG_FILE_NAME    "IPACM_cfg.xml"
85 #ifdef FEATURE_IPA_ANDROID
86 #define IPACM_PID_FILE "/data/vendor/ipa/ipacm.pid"
87 #define IPACM_DIR_NAME     "/data"
88 #else/* defined(FEATURE_IPA_ANDROID) */
89 #define IPACM_PID_FILE "/etc/ipacm.pid"
90 #define IPACM_DIR_NAME     "/etc"
91 #endif /* defined(NOT FEATURE_IPA_ANDROID)*/
92 #define IPACM_NAME "ipacm"
93 
94 #define INOTIFY_EVENT_SIZE  (sizeof(struct inotify_event))
95 #define INOTIFY_BUF_LEN     (INOTIFY_EVENT_SIZE + 2*sizeof(IPACM_FIREWALL_FILE_NAME))
96 
97 #define IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS  3
98 #define IPA_DRIVER_WLAN_EVENT_SIZE  (sizeof(struct ipa_wlan_msg_ex)+ IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS*sizeof(ipa_wlan_hdr_attrib_val))
99 #define IPA_DRIVER_PIPE_STATS_EVENT_SIZE  (sizeof(struct ipa_get_data_stats_resp_msg_v01))
100 #define IPA_DRIVER_WLAN_META_MSG    (sizeof(struct ipa_msg_meta))
101 #define IPA_DRIVER_WLAN_BUF_LEN     (IPA_DRIVER_PIPE_STATS_EVENT_SIZE + IPA_DRIVER_WLAN_META_MSG)
102 
103 uint32_t ipacm_event_stats[IPACM_EVENT_MAX];
104 bool ipacm_logging = true;
105 
106 void ipa_is_ipacm_running(void);
107 int ipa_get_if_index(char *if_name, int *if_index);
108 
109 IPACM_Neighbor *neigh;
110 IPACM_IfaceManager *ifacemgr;
111 #ifdef FEATURE_IPACM_HAL
112 	IPACM_OffloadManager* OffloadMng;
113 	HAL *hal;
114 int ipa_reset();
115 /* support ipacm restart */
116 int ipa_query_wlan_client();
117 #endif
118 
119 /* start netlink socket monitor*/
netlink_start(void * param)120 void* netlink_start(void *param)
121 {
122 	param = NULL;
123 	ipa_nl_sk_fd_set_info_t sk_fdset;
124 	int ret_val = 0;
125 	memset(&sk_fdset, 0, sizeof(ipa_nl_sk_fd_set_info_t));
126 	IPACMDBG_H("netlink starter memset sk_fdset succeeds\n");
127 	ret_val = ipa_nl_listener_init(NETLINK_ROUTE, (RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_LINK |
128 																										RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NEIGH |
129 																										RTNLGRP_IPV6_PREFIX),
130 																 &sk_fdset, ipa_nl_recv_msg);
131 
132 	if (ret_val != IPACM_SUCCESS)
133 	{
134 		IPACMERR("Failed to initialize IPA netlink event listener\n");
135 		return NULL;
136 	}
137 
138 	return NULL;
139 }
140 
141 /* start firewall-rule monitor*/
firewall_monitor(void * param)142 void* firewall_monitor(void *param)
143 {
144 	int length;
145 	int wd;
146 	char buffer[INOTIFY_BUF_LEN];
147 	int inotify_fd;
148 	ipacm_cmd_q_data evt_data;
149 	uint32_t mask = IN_MODIFY | IN_MOVE;
150 
151 	param = NULL;
152 	inotify_fd = inotify_init();
153 	if (inotify_fd < 0)
154 	{
155 		PERROR("inotify_init");
156 	}
157 
158 	IPACMDBG_H("Waiting for nofications in dir %s with mask: 0x%x\n", IPACM_DIR_NAME, mask);
159 
160 	wd = inotify_add_watch(inotify_fd,
161 												 IPACM_DIR_NAME,
162 												 mask);
163 
164 	while (1)
165 	{
166 		length = read(inotify_fd, buffer, INOTIFY_BUF_LEN);
167 		if (length < 0)
168 		{
169 			IPACMERR("inotify read() error return length: %d and mask: 0x%x\n", length, mask);
170 			continue;
171 		}
172 
173 		struct inotify_event* event;
174 		event = (struct inotify_event*)malloc(length);
175 		if(event == NULL)
176 		{
177 			IPACMERR("Failed to allocate memory.\n");
178 			return NULL;
179 		}
180 		memset(event, 0, length);
181 		memcpy(event, buffer, length);
182 
183 		if (event->len > 0)
184 		{
185 			if ( (event->mask & IN_MODIFY) || (event->mask & IN_MOVE))
186 			{
187 				if (event->mask & IN_ISDIR)
188 				{
189 					IPACMDBG_H("The directory %s was 0x%x\n", event->name, event->mask);
190 				}
191 				else if (!strncmp(event->name, IPACM_FIREWALL_FILE_NAME, event->len)) // firewall_rule change
192 				{
193 					IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
194 					IPACMDBG_H("The interested file %s .\n", IPACM_FIREWALL_FILE_NAME);
195 
196 					evt_data.event = IPA_FIREWALL_CHANGE_EVENT;
197 					evt_data.evt_data = NULL;
198 
199 					/* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
200 					IPACM_EvtDispatcher::PostEvt(&evt_data);
201 				}
202 				else if (!strncmp(event->name, IPACM_CFG_FILE_NAME, event->len)) // IPACM_configuration change
203 				{
204 					IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
205 					IPACMDBG_H("The interested file %s .\n", IPACM_CFG_FILE_NAME);
206 
207 					evt_data.event = IPA_CFG_CHANGE_EVENT;
208 					evt_data.evt_data = NULL;
209 
210 					/* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
211 					IPACM_EvtDispatcher::PostEvt(&evt_data);
212 				}
213 			}
214 			IPACMDBG_H("Received monitoring event %s.\n", event->name);
215 		}
216 		free(event);
217 	}
218 
219 	(void)inotify_rm_watch(inotify_fd, wd);
220 	(void)close(inotify_fd);
221 	return NULL;
222 }
223 
224 
225 /* start IPACM wan-driver notifier */
ipa_driver_msg_notifier(void * param)226 void* ipa_driver_msg_notifier(void *param)
227 {
228 	int length, fd, cnt;
229 	char buffer[IPA_DRIVER_WLAN_BUF_LEN];
230 	struct ipa_msg_meta event_hdr;
231 	struct ipa_ecm_msg event_ecm;
232 	struct ipa_wan_msg event_wan;
233 	struct ipa_wlan_msg_ex event_ex_o;
234 	struct ipa_wlan_msg *event_wlan=NULL;
235 	struct ipa_wlan_msg_ex *event_ex= NULL;
236 	struct ipa_get_data_stats_resp_msg_v01 event_data_stats;
237 	struct ipa_get_apn_data_stats_resp_msg_v01 event_network_stats;
238 #ifdef FEATURE_IPACM_HAL
239 	IPACM_OffloadManager* OffloadMng;
240 #endif
241 
242 	ipacm_cmd_q_data evt_data;
243 	ipacm_event_data_mac *data = NULL;
244 	ipacm_event_data_fid *data_fid = NULL;
245 	ipacm_event_data_iptype *data_iptype = NULL;
246 	ipacm_event_data_wlan_ex *data_ex;
247 	ipa_get_data_stats_resp_msg_v01 *data_tethering_stats = NULL;
248 	ipa_get_apn_data_stats_resp_msg_v01 *data_network_stats = NULL;
249 #ifdef FEATURE_L2TP
250 	ipa_ioc_vlan_iface_info *vlan_info = NULL;
251 	ipa_ioc_l2tp_vlan_mapping_info *mapping = NULL;
252 #endif
253 	ipacm_cmd_q_data new_neigh_evt;
254 	ipacm_event_data_all* new_neigh_data;
255 
256 	param = NULL;
257 	fd = open(IPA_DRIVER, O_RDWR);
258 	if (fd < 0)
259 	{
260 		IPACMERR("Failed opening %s.\n", IPA_DRIVER);
261 		return NULL;
262 	}
263 
264 	while (1)
265 	{
266 		IPACMDBG_H("Waiting for nofications from IPA driver \n");
267 		memset(buffer, 0, sizeof(buffer));
268 		memset(&evt_data, 0, sizeof(evt_data));
269 		memset(&new_neigh_evt, 0, sizeof(ipacm_cmd_q_data));
270 		new_neigh_data = NULL;
271 		data = NULL;
272 		data_fid = NULL;
273 		data_tethering_stats = NULL;
274 		data_network_stats = NULL;
275 
276 		length = read(fd, buffer, IPA_DRIVER_WLAN_BUF_LEN);
277 		if (length < 0)
278 		{
279 			PERROR("didn't read IPA_driver correctly");
280 			continue;
281 		}
282 
283 		memcpy(&event_hdr, buffer,sizeof(struct ipa_msg_meta));
284 		IPACMDBG_H("Message type: %d\n", event_hdr.msg_type);
285 		IPACMDBG_H("Event header length received: %d\n",event_hdr.msg_len);
286 
287 		/* Insert WLAN_DRIVER_EVENT to command queue */
288 		switch (event_hdr.msg_type)
289 		{
290 
291 		case SW_ROUTING_ENABLE:
292 			IPACMDBG_H("Received SW_ROUTING_ENABLE\n");
293 			evt_data.event = IPA_SW_ROUTING_ENABLE;
294 			IPACMDBG_H("Not supported anymore\n");
295 			continue;
296 
297 		case SW_ROUTING_DISABLE:
298 			IPACMDBG_H("Received SW_ROUTING_DISABLE\n");
299 			evt_data.event = IPA_SW_ROUTING_DISABLE;
300 			IPACMDBG_H("Not supported anymore\n");
301 			continue;
302 
303 		case WLAN_AP_CONNECT:
304 			event_wlan = (struct ipa_wlan_msg *) (buffer + sizeof(struct ipa_msg_meta));
305 			IPACMDBG_H("Received WLAN_AP_CONNECT name: %s\n",event_wlan->name);
306 			IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
307 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
308 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
309                         data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
310 			if(data_fid == NULL)
311 			{
312 				IPACMERR("unable to allocate memory for event_wlan data_fid\n");
313 				return NULL;
314 			}
315 			ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
316 			evt_data.event = IPA_WLAN_AP_LINK_UP_EVENT;
317 			evt_data.evt_data = data_fid;
318 			break;
319 
320 		case WLAN_AP_DISCONNECT:
321 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
322 			IPACMDBG_H("Received WLAN_AP_DISCONNECT name: %s\n",event_wlan->name);
323 			IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
324 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
325 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
326                         data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
327 			if(data_fid == NULL)
328 			{
329 				IPACMERR("unable to allocate memory for event_wlan data_fid\n");
330 				return NULL;
331 			}
332 			ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
333 			evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
334 			evt_data.evt_data = data_fid;
335 			break;
336 		case WLAN_STA_CONNECT:
337 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
338 			IPACMDBG_H("Received WLAN_STA_CONNECT name: %s\n",event_wlan->name);
339 			IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
340 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
341 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
342 			data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
343 			if(data == NULL)
344 			{
345 				IPACMERR("unable to allocate memory for event_wlan data_fid\n");
346 				return NULL;
347 			}
348 			memcpy(data->mac_addr,
349 				 event_wlan->mac_addr,
350 				 sizeof(event_wlan->mac_addr));
351 			ipa_get_if_index(event_wlan->name, &(data->if_index));
352 			evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT;
353 			evt_data.evt_data = data;
354 			break;
355 
356 		case WLAN_STA_DISCONNECT:
357 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
358 			IPACMDBG_H("Received WLAN_STA_DISCONNECT name: %s\n",event_wlan->name);
359 			IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
360 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
361 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
362                         data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
363 			if(data_fid == NULL)
364 			{
365 				IPACMERR("unable to allocate memory for event_wlan data_fid\n");
366 				return NULL;
367 			}
368 			ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
369 			evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
370 			evt_data.evt_data = data_fid;
371 			break;
372 
373 		case WLAN_CLIENT_CONNECT:
374 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
375 			IPACMDBG_H("Received WLAN_CLIENT_CONNECT\n");
376 			IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
377 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
378 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
379 		        data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
380 		        if (data == NULL)
381 		        {
382 		    	        IPACMERR("unable to allocate memory for event_wlan data\n");
383 		    	        return NULL;
384 		        }
385 			memcpy(data->mac_addr,
386 						 event_wlan->mac_addr,
387 						 sizeof(event_wlan->mac_addr));
388 			ipa_get_if_index(event_wlan->name, &(data->if_index));
389 		        evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT;
390 			evt_data.evt_data = data;
391 			break;
392 
393 		case WLAN_CLIENT_CONNECT_EX:
394 			IPACMDBG_H("Received WLAN_CLIENT_CONNECT_EX\n");
395 
396 			memcpy(&event_ex_o, buffer + sizeof(struct ipa_msg_meta),sizeof(struct ipa_wlan_msg_ex));
397 			if(event_ex_o.num_of_attribs > IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS)
398 			{
399 				IPACMERR("buffer size overflow\n");
400 				return NULL;
401 			}
402 			length = sizeof(ipa_wlan_msg_ex)+ event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val);
403 			IPACMDBG_H("num_of_attribs %d, length %d\n", event_ex_o.num_of_attribs, length);
404 			event_ex = (ipa_wlan_msg_ex *)malloc(length);
405 			if(event_ex == NULL )
406 			{
407 				IPACMERR("Unable to allocate memory\n");
408 				return NULL;
409 			}
410 			memcpy(event_ex, buffer + sizeof(struct ipa_msg_meta), length);
411 			data_ex = (ipacm_event_data_wlan_ex *)malloc(sizeof(ipacm_event_data_wlan_ex) + event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
412 		    if (data_ex == NULL)
413 		    {
414 				IPACMERR("unable to allocate memory for event data\n");
415 		    	return NULL;
416 		    }
417 			data_ex->num_of_attribs = event_ex->num_of_attribs;
418 
419 			memcpy(data_ex->attribs,
420 						event_ex->attribs,
421 						event_ex->num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
422 
423 			ipa_get_if_index(event_ex->name, &(data_ex->if_index));
424 			evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT_EX;
425 			evt_data.evt_data = data_ex;
426 
427 			/* Construct new_neighbor msg with netdev device internally */
428 			new_neigh_data = (ipacm_event_data_all*)malloc(sizeof(ipacm_event_data_all));
429 			if(new_neigh_data == NULL)
430 			{
431 				IPACMERR("Failed to allocate memory.\n");
432 				return NULL;
433 			}
434 			memset(new_neigh_data, 0, sizeof(ipacm_event_data_all));
435 			new_neigh_data->iptype = IPA_IP_v6;
436 			for(cnt = 0; cnt < event_ex->num_of_attribs; cnt++)
437 			{
438 				if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
439 				{
440 					memcpy(new_neigh_data->mac_addr, event_ex->attribs[cnt].u.mac_addr, sizeof(new_neigh_data->mac_addr));
441 					IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
442 								 event_ex->attribs[cnt].u.mac_addr[0], event_ex->attribs[cnt].u.mac_addr[1], event_ex->attribs[cnt].u.mac_addr[2],
443 								 event_ex->attribs[cnt].u.mac_addr[3], event_ex->attribs[cnt].u.mac_addr[4], event_ex->attribs[cnt].u.mac_addr[5]);
444 				}
445 				else if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
446 				{
447 					IPACMDBG_H("Wlan client id %d\n",event_ex->attribs[cnt].u.sta_id);
448 				}
449 				else
450 				{
451 					IPACMDBG_H("Wlan message has unexpected type!\n");
452 				}
453 			}
454 			new_neigh_data->if_index = data_ex->if_index;
455 			new_neigh_evt.evt_data = (void*)new_neigh_data;
456 			new_neigh_evt.event = IPA_NEW_NEIGH_EVENT;
457 			free(event_ex);
458 			break;
459 
460 		case WLAN_CLIENT_DISCONNECT:
461 			IPACMDBG_H("Received WLAN_CLIENT_DISCONNECT\n");
462 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
463 			IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
464 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
465 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
466 		        data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
467 		        if (data == NULL)
468 		        {
469 		    	        IPACMERR("unable to allocate memory for event_wlan data\n");
470 		    	        return NULL;
471 		        }
472 			memcpy(data->mac_addr,
473 						 event_wlan->mac_addr,
474 						 sizeof(event_wlan->mac_addr));
475 			ipa_get_if_index(event_wlan->name, &(data->if_index));
476 			evt_data.event = IPA_WLAN_CLIENT_DEL_EVENT;
477 			evt_data.evt_data = data;
478 			break;
479 
480 		case WLAN_CLIENT_POWER_SAVE_MODE:
481 			IPACMDBG_H("Received WLAN_CLIENT_POWER_SAVE_MODE\n");
482 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
483 			IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
484 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
485 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
486 		        data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
487 		        if (data == NULL)
488 		        {
489 		    	        IPACMERR("unable to allocate memory for event_wlan data\n");
490 		    	        return NULL;
491 		        }
492 			memcpy(data->mac_addr,
493 						 event_wlan->mac_addr,
494 						 sizeof(event_wlan->mac_addr));
495 			ipa_get_if_index(event_wlan->name, &(data->if_index));
496 			evt_data.event = IPA_WLAN_CLIENT_POWER_SAVE_EVENT;
497 			evt_data.evt_data = data;
498 			break;
499 
500 		case WLAN_CLIENT_NORMAL_MODE:
501 			IPACMDBG_H("Received WLAN_CLIENT_NORMAL_MODE\n");
502 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
503 			IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
504 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
505 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
506 		        data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
507 		        if (data == NULL)
508 		        {
509 		    	       IPACMERR("unable to allocate memory for event_wlan data\n");
510 		    	       return NULL;
511 		        }
512 			memcpy(data->mac_addr,
513 						 event_wlan->mac_addr,
514 						 sizeof(event_wlan->mac_addr));
515 			ipa_get_if_index(event_wlan->name, &(data->if_index));
516 			evt_data.evt_data = data;
517 			evt_data.event = IPA_WLAN_CLIENT_RECOVER_EVENT;
518 			break;
519 
520 		case ECM_CONNECT:
521 			memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
522 			IPACMDBG_H("Received ECM_CONNECT name: %s\n",event_ecm.name);
523 			data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
524 			if(data_fid == NULL)
525 			{
526 				IPACMERR("unable to allocate memory for event_ecm data_fid\n");
527 				return NULL;
528 			}
529 			data_fid->if_index = event_ecm.ifindex;
530 			evt_data.event = IPA_USB_LINK_UP_EVENT;
531 			evt_data.evt_data = data_fid;
532 			break;
533 
534 		case ECM_DISCONNECT:
535 			memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
536 			IPACMDBG_H("Received ECM_DISCONNECT name: %s\n",event_ecm.name);
537 			data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
538 			if(data_fid == NULL)
539 			{
540 				IPACMERR("unable to allocate memory for event_ecm data_fid\n");
541 				return NULL;
542 			}
543 			data_fid->if_index = event_ecm.ifindex;
544 			evt_data.event = IPA_LINK_DOWN_EVENT;
545 			evt_data.evt_data = data_fid;
546 			break;
547 		/* Add for 8994 Android case */
548 		case WAN_UPSTREAM_ROUTE_ADD:
549 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
550 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
551 			data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
552 			if(data_iptype == NULL)
553 			{
554 				IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
555 				return NULL;
556 			}
557 			ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
558 			ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
559 			data_iptype->iptype = event_wan.ip;
560 #ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
561 			data_iptype->ipv4_addr_gw = event_wan.ipv4_addr_gw;
562 			data_iptype->ipv6_addr_gw[0] = event_wan.ipv6_addr_gw[0];
563 			data_iptype->ipv6_addr_gw[1] = event_wan.ipv6_addr_gw[1];
564 			data_iptype->ipv6_addr_gw[2] = event_wan.ipv6_addr_gw[2];
565 			data_iptype->ipv6_addr_gw[3] = event_wan.ipv6_addr_gw[3];
566 			IPACMDBG_H("default gw ipv4 (%x)\n", data_iptype->ipv4_addr_gw);
567 			IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
568 							data_iptype->ipv6_addr_gw[0], data_iptype->ipv6_addr_gw[1], data_iptype->ipv6_addr_gw[2], data_iptype->ipv6_addr_gw[3]);
569 #endif
570 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index,
571 					data_iptype->if_index_tether, data_iptype->iptype);
572 			evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
573 			evt_data.evt_data = data_iptype;
574 			break;
575 		case WAN_UPSTREAM_ROUTE_DEL:
576 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
577 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
578 			data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
579 			if(data_iptype == NULL)
580 			{
581 				IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
582 				return NULL;
583 			}
584 			ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
585 			ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
586 			data_iptype->iptype = event_wan.ip;
587 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
588 			evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT;
589 			evt_data.evt_data = data_iptype;
590 			break;
591 		/* End of adding for 8994 Android case */
592 
593 		/* Add for embms case */
594 		case WAN_EMBMS_CONNECT:
595 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
596 			IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
597 			data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
598 			if(data_fid == NULL)
599 			{
600 				IPACMERR("unable to allocate memory for event data_fid\n");
601 				return NULL;
602 			}
603 			ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
604 			evt_data.event = IPA_WAN_EMBMS_LINK_UP_EVENT;
605 			evt_data.evt_data = data_fid;
606 			break;
607 
608 		case WLAN_SWITCH_TO_SCC:
609 			IPACMDBG_H("Received WLAN_SWITCH_TO_SCC\n");
610 			[[fallthrough]];
611 		case WLAN_WDI_ENABLE:
612 			IPACMDBG_H("Received WLAN_WDI_ENABLE\n");
613 			if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
614 			{
615 				IPACM_Iface::ipacmcfg->isMCC_Mode = false;
616 				evt_data.event = IPA_WLAN_SWITCH_TO_SCC;
617 				break;
618 			}
619 			continue;
620 		case WLAN_SWITCH_TO_MCC:
621 			IPACMDBG_H("Received WLAN_SWITCH_TO_MCC\n");
622 			[[fallthrough]];
623 		case WLAN_WDI_DISABLE:
624 			IPACMDBG_H("Received WLAN_WDI_DISABLE\n");
625 			if (IPACM_Iface::ipacmcfg->isMCC_Mode == false)
626 			{
627 				IPACM_Iface::ipacmcfg->isMCC_Mode = true;
628 				evt_data.event = IPA_WLAN_SWITCH_TO_MCC;
629 				break;
630 			}
631 			continue;
632 
633 		case WAN_XLAT_CONNECT:
634 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta),
635 				sizeof(struct ipa_wan_msg));
636 			IPACMDBG_H("Received WAN_XLAT_CONNECT name: %s\n",
637 					event_wan.upstream_ifname);
638 
639 			/* post IPA_LINK_UP_EVENT event
640 			 * may be WAN interface is not up
641 			*/
642 			data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
643 			if(data_fid == NULL)
644 			{
645 				IPACMERR("unable to allocate memory for xlat event\n");
646 				return NULL;
647 			}
648 			ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
649 			evt_data.event = IPA_LINK_UP_EVENT;
650 			evt_data.evt_data = data_fid;
651 			IPACMDBG_H("Posting IPA_LINK_UP_EVENT event:%d\n", evt_data.event);
652 			IPACM_EvtDispatcher::PostEvt(&evt_data);
653 
654 			/* post IPA_WAN_XLAT_CONNECT_EVENT event */
655 			memset(&evt_data, 0, sizeof(evt_data));
656 			data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
657 			if(data_fid == NULL)
658 			{
659 				IPACMERR("unable to allocate memory for xlat event\n");
660 				return NULL;
661 			}
662 			ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
663 			evt_data.event = IPA_WAN_XLAT_CONNECT_EVENT;
664 			evt_data.evt_data = data_fid;
665 			IPACMDBG_H("Posting IPA_WAN_XLAT_CONNECT_EVENT event:%d\n", evt_data.event);
666 			break;
667 
668 		case IPA_TETHERING_STATS_UPDATE_STATS:
669 			memcpy(&event_data_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_data_stats_resp_msg_v01));
670 			data_tethering_stats = (ipa_get_data_stats_resp_msg_v01 *)malloc(sizeof(struct ipa_get_data_stats_resp_msg_v01));
671 			if(data_tethering_stats == NULL)
672 			{
673 				IPACMERR("unable to allocate memory for event data_tethering_stats\n");
674 				return NULL;
675 			}
676 			memcpy(data_tethering_stats,
677 					 &event_data_stats,
678 						 sizeof(struct ipa_get_data_stats_resp_msg_v01));
679 			IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data_tethering_stats->ipa_stats_type);
680 			IPACMDBG("Received %d UL, %d DL pipe stats\n",data_tethering_stats->ul_src_pipe_stats_list_len, data_tethering_stats->dl_dst_pipe_stats_list_len);
681 			evt_data.event = IPA_TETHERING_STATS_UPDATE_EVENT;
682 			evt_data.evt_data = data_tethering_stats;
683 			break;
684 
685 		case IPA_TETHERING_STATS_UPDATE_NETWORK_STATS:
686 			memcpy(&event_network_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
687 			data_network_stats = (ipa_get_apn_data_stats_resp_msg_v01 *)malloc(sizeof(ipa_get_apn_data_stats_resp_msg_v01));
688 			if(data_network_stats == NULL)
689 			{
690 				IPACMERR("unable to allocate memory for event data_network_stats\n");
691 				return NULL;
692 			}
693 			memcpy(data_network_stats,
694 					 &event_network_stats,
695 						 sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
696 			IPACMDBG("Received %d apn network stats \n", data_network_stats->apn_data_stats_list_len);
697 			evt_data.event = IPA_NETWORK_STATS_UPDATE_EVENT;
698 			evt_data.evt_data = data_network_stats;
699 			break;
700 
701 #ifdef FEATURE_IPACM_HAL
702 		case IPA_QUOTA_REACH:
703 			IPACMDBG_H("Received IPA_QUOTA_REACH\n");
704 			OffloadMng = IPACM_OffloadManager::GetInstance();
705 			if (OffloadMng->elrInstance == NULL) {
706 				IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
707 			} else {
708 				IPACMERR("calling OffloadMng->elrInstance->onLimitReached \n");
709 				OffloadMng->elrInstance->onLimitReached();
710 			}
711 			continue;
712 		case IPA_SSR_BEFORE_SHUTDOWN:
713 			IPACMDBG_H("Received IPA_SSR_BEFORE_SHUTDOWN\n");
714 			OffloadMng = IPACM_OffloadManager::GetInstance();
715 			if (OffloadMng->elrInstance == NULL) {
716 				IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
717 			} else {
718 				IPACMERR("calling OffloadMng->elrInstance->onOffloadStopped \n");
719 				OffloadMng->elrInstance->onOffloadStopped(IpaEventRelay::ERROR);
720 			}
721 			/* WA to clean up wlan instances during SSR */
722 			evt_data.event = IPA_SSR_NOTICE;
723 			evt_data.evt_data = NULL;
724 			break;
725 		case IPA_SSR_AFTER_POWERUP:
726 			IPACMDBG_H("Received IPA_SSR_AFTER_POWERUP\n");
727 			OffloadMng = IPACM_OffloadManager::GetInstance();
728 			if (OffloadMng->elrInstance == NULL) {
729 				IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
730 			} else {
731 				IPACMERR("calling OffloadMng->elrInstance->onOffloadSupportAvailable \n");
732 				OffloadMng->elrInstance->onOffloadSupportAvailable();
733 			}
734 			continue;
735 #ifdef IPA_WLAN_FW_SSR_EVENT_MAX
736 		case WLAN_FWR_SSR_BEFORE_SHUTDOWN:
737                         IPACMDBG_H("Received WLAN_FWR_SSR_BEFORE_SHUTDOWN\n");
738                         evt_data.event = IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE;
739                         evt_data.evt_data = NULL;
740                         break;
741 #endif
742 #endif
743 #ifdef FEATURE_L2TP
744 		case ADD_VLAN_IFACE:
745 			vlan_info = (ipa_ioc_vlan_iface_info *)malloc(sizeof(*vlan_info));
746 			if(vlan_info == NULL)
747 			{
748 				IPACMERR("Failed to allocate memory.\n");
749 				return NULL;
750 			}
751 			memcpy(vlan_info, buffer + sizeof(struct ipa_msg_meta), sizeof(*vlan_info));
752 			evt_data.event = IPA_ADD_VLAN_IFACE;
753 			evt_data.evt_data = vlan_info;
754 			break;
755 
756 		case DEL_VLAN_IFACE:
757 			vlan_info = (ipa_ioc_vlan_iface_info *)malloc(sizeof(*vlan_info));
758 			if(vlan_info == NULL)
759 			{
760 				IPACMERR("Failed to allocate memory.\n");
761 				return NULL;
762 			}
763 			memcpy(vlan_info, buffer + sizeof(struct ipa_msg_meta), sizeof(*vlan_info));
764 			evt_data.event = IPA_DEL_VLAN_IFACE;
765 			evt_data.evt_data = vlan_info;
766 			break;
767 
768 		case ADD_L2TP_VLAN_MAPPING:
769 			mapping = (ipa_ioc_l2tp_vlan_mapping_info *)malloc(sizeof(*mapping));
770 			if(mapping == NULL)
771 			{
772 				IPACMERR("Failed to allocate memory.\n");
773 				return NULL;
774 			}
775 			memcpy(mapping, buffer + sizeof(struct ipa_msg_meta), sizeof(*mapping));
776 			evt_data.event = IPA_ADD_L2TP_VLAN_MAPPING;
777 			evt_data.evt_data = mapping;
778 			break;
779 
780 		case DEL_L2TP_VLAN_MAPPING:
781 			mapping = (ipa_ioc_l2tp_vlan_mapping_info *)malloc(sizeof(*mapping));
782 			if(mapping == NULL)
783 			{
784 				IPACMERR("Failed to allocate memory.\n");
785 				return NULL;
786 			}
787 			memcpy(mapping, buffer + sizeof(struct ipa_msg_meta), sizeof(*mapping));
788 			evt_data.event = IPA_DEL_L2TP_VLAN_MAPPING;
789 			evt_data.evt_data = mapping;
790 			break;
791 #endif
792 		default:
793 			IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
794 			continue;
795 
796 		}
797 		/* finish command queue */
798 		IPACMDBG_H("Posting event:%d\n", evt_data.event);
799 		IPACM_EvtDispatcher::PostEvt(&evt_data);
800 		/* push new_neighbor with netdev device internally */
801 		if(new_neigh_data != NULL)
802 		{
803 			IPACMDBG_H("Internally post event IPA_NEW_NEIGH_EVENT\n");
804 			IPACM_EvtDispatcher::PostEvt(&new_neigh_evt);
805 		}
806 	}
807 
808 	(void)close(fd);
809 	return NULL;
810 }
811 
IPACM_Sig_Handler(int sig)812 void IPACM_Sig_Handler(int sig)
813 {
814 	ipacm_cmd_q_data evt_data;
815 
816 	printf("Received Signal: %d\n", sig);
817 	memset(&evt_data, 0, sizeof(evt_data));
818 
819 	switch(sig)
820 	{
821 		case SIGUSR1:
822 			IPACMDBG_H("Received SW_ROUTING_ENABLE request \n");
823 			evt_data.event = IPA_SW_ROUTING_ENABLE;
824 			IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = true;
825 			break;
826 
827 		case SIGUSR2:
828 			IPACMDBG_H("Received SW_ROUTING_DISABLE request \n");
829 			evt_data.event = IPA_SW_ROUTING_DISABLE;
830 			IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = false;
831 			break;
832 	}
833 	/* finish command queue */
834 	IPACMDBG_H("Posting event:%d\n", evt_data.event);
835 	IPACM_EvtDispatcher::PostEvt(&evt_data);
836 	return;
837 }
838 
RegisterForSignals(void)839 void RegisterForSignals(void)
840 {
841 
842 	signal(SIGUSR1, IPACM_Sig_Handler);
843 	signal(SIGUSR2, IPACM_Sig_Handler);
844 }
845 
846 
main(int argc,char ** argv)847 int main(int argc, char **argv)
848 {
849 	int ret;
850 	pthread_t netlink_thread = 0, monitor_thread = 0, ipa_driver_thread = 0;
851 	pthread_t cmd_queue_thread = 0;
852 
853 	/* check if ipacm is already running or not */
854 	ipa_is_ipacm_running();
855 
856 	IPACMDBG_H("In main()\n");
857 	(void)argc;
858 	(void)argv;
859 
860 	IPACMDBG_H("RESET IPA-HW rules\n");
861 	ipa_reset();
862 
863 	neigh = new IPACM_Neighbor();
864 	ifacemgr = new IPACM_IfaceManager();
865 #ifdef FEATURE_IPACM_HAL
866 	OffloadMng = IPACM_OffloadManager::GetInstance();
867 	hal = HAL::makeIPAHAL(1, OffloadMng);
868 	IPACMDBG_H(" START IPACM_OffloadManager and link to android framework\n");
869 #endif
870 
871 #ifdef FEATURE_ETH_BRIDGE_LE
872 	IPACM_LanToLan* lan2lan = IPACM_LanToLan::get_instance();
873 #endif
874 
875 	CtList = new IPACM_ConntrackListener();
876 
877 	IPACMDBG_H("Staring IPA main\n");
878 	IPACMDBG_H("ipa_cmdq_successful\n");
879 
880 
881 	RegisterForSignals();
882 
883 	if (IPACM_SUCCESS == cmd_queue_thread)
884 	{
885 		ret = pthread_create(&cmd_queue_thread, NULL, MessageQueue::Process, NULL);
886 		if (IPACM_SUCCESS != ret)
887 		{
888 			IPACMERR("unable to command queue thread\n");
889 			return ret;
890 		}
891 		IPACMDBG_H("created command queue thread\n");
892 		if(pthread_setname_np(cmd_queue_thread, "cmd queue process") != 0)
893 		{
894 			IPACMERR("unable to set thread name\n");
895 		}
896 	}
897 
898 	if (IPACM_SUCCESS == netlink_thread)
899 	{
900 		ret = pthread_create(&netlink_thread, NULL, netlink_start, NULL);
901 		if (IPACM_SUCCESS != ret)
902 		{
903 			IPACMERR("unable to create netlink thread\n");
904 			return ret;
905 		}
906 		IPACMDBG_H("created netlink thread\n");
907 		if(pthread_setname_np(netlink_thread, "netlink socket") != 0)
908 		{
909 			IPACMERR("unable to set thread name\n");
910 		}
911 	}
912 
913 	/* Enable Firewall support only on MDM targets */
914 #ifndef FEATURE_IPA_ANDROID
915 	if (IPACM_SUCCESS == monitor_thread)
916 	{
917 		ret = pthread_create(&monitor_thread, NULL, firewall_monitor, NULL);
918 		if (IPACM_SUCCESS != ret)
919 		{
920 			IPACMERR("unable to create monitor thread\n");
921 			return ret;
922 		}
923 		IPACMDBG_H("created firewall monitor thread\n");
924 		if(pthread_setname_np(monitor_thread, "firewall cfg process") != 0)
925 		{
926 			IPACMERR("unable to set thread name\n");
927 		}
928 	}
929 #endif
930 
931 	if (IPACM_SUCCESS == ipa_driver_thread)
932 	{
933 		ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_msg_notifier, NULL);
934 		if (IPACM_SUCCESS != ret)
935 		{
936 			IPACMERR("unable to create ipa_driver_wlan thread\n");
937 			return ret;
938 		}
939 		IPACMDBG_H("created ipa_driver_wlan thread\n");
940 		if(pthread_setname_np(ipa_driver_thread, "ipa driver ntfy") != 0)
941 		{
942 			IPACMERR("unable to set thread name\n");
943 		}
944 	}
945 
946 	pthread_join(cmd_queue_thread, NULL);
947 	pthread_join(netlink_thread, NULL);
948 	pthread_join(monitor_thread, NULL);
949 	pthread_join(ipa_driver_thread, NULL);
950 	return IPACM_SUCCESS;
951 }
952 
953 /*===========================================================================
954 		FUNCTION  ipa_is_ipacm_running
955 ===========================================================================*/
956 /*!
957 @brief
958   Determine whether there's already an IPACM process running, if so, terminate
959   the current one
960 
961 @return
962 	None
963 
964 @note
965 
966 - Dependencies
967 		- None
968 
969 - Side Effects
970 		- None
971 */
972 /*=========================================================================*/
973 
ipa_is_ipacm_running(void)974 void ipa_is_ipacm_running(void) {
975 
976 	int fd;
977 	struct flock lock;
978 	int retval;
979 
980 	fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600);
981 	if ( fd <= 0 )
982 	{
983 		IPACMERR("Failed to open %s, error is %d - %s\n",
984 				 IPACM_PID_FILE, errno, strerror(errno));
985 		exit(0);
986 	}
987 
988 	/*
989 	 * Getting an exclusive Write lock on the file, if it fails,
990 	 * it means that another instance of IPACM is running and it
991 	 * got the lock before us.
992 	 */
993 	memset(&lock, 0, sizeof(lock));
994 	lock.l_type = F_WRLCK;
995 	retval = fcntl(fd, F_SETLK, &lock);
996 
997 	if (retval != 0)
998 	{
999 		retval = fcntl(fd, F_GETLK, &lock);
1000 		if (retval == 0)
1001 		{
1002 			IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n",
1003 					 IPACM_PID_FILE, getpid(), lock.l_pid);
1004 			close(fd);
1005 			exit(0);
1006 		}
1007 	}
1008 	else
1009 	{
1010 		IPACMERR("PID %d is IPACM main process\n", getpid());
1011 	}
1012 
1013 	return;
1014 }
1015 
1016 /*===========================================================================
1017 		FUNCTION  ipa_get_if_index
1018 ===========================================================================*/
1019 /*!
1020 @brief
1021   get ipa interface index by given the interface name
1022 
1023 @return
1024 	IPACM_SUCCESS or IPA_FALUIRE
1025 
1026 @note
1027 
1028 - Dependencies
1029 		- None
1030 
1031 - Side Effects
1032 		- None
1033 */
1034 /*=========================================================================*/
ipa_get_if_index(char * if_name,int * if_index)1035 int ipa_get_if_index
1036 (
1037 	 char *if_name,
1038 	 int *if_index
1039 	 )
1040 {
1041 	int fd;
1042 	struct ifreq ifr;
1043 
1044 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1045 	{
1046 		PERROR("get interface index socket create failed");
1047 		return IPACM_FAILURE;
1048 	}
1049 
1050 	memset(&ifr, 0, sizeof(struct ifreq));
1051 
1052 	(void)strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
1053 
1054 	if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
1055 	{
1056 		IPACMERR("call_ioctl_on_dev: ioctl failed: can't find device %s",if_name);
1057 		*if_index = -1;
1058 		close(fd);
1059 		return IPACM_FAILURE;
1060 	}
1061 
1062 	*if_index = ifr.ifr_ifindex;
1063 	close(fd);
1064 	return IPACM_SUCCESS;
1065 }
1066 
ipa_reset()1067 int ipa_reset()
1068 {
1069 	int fd = -1;
1070 
1071 	if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
1072 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1073 		return IPACM_FAILURE;
1074 	}
1075 
1076 	if (ioctl(fd, IPA_IOC_CLEANUP) < 0) {
1077 		IPACMERR("IOCTL IPA_IOC_CLEANUP call failed: %s \n", strerror(errno));
1078 		close(fd);
1079 		return IPACM_FAILURE;
1080 	}
1081 
1082 	IPACMDBG_H("send IPA_IOC_CLEANUP \n");
1083 	close(fd);
1084 	return IPACM_SUCCESS;
1085 }
1086