• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (c) 2013-2019, 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 #include "IPACM_Wan.h"
67 
68 #include "IPACM_ConntrackListener.h"
69 #include "IPACM_ConntrackClient.h"
70 #include "IPACM_Netlink.h"
71 
72 #ifdef FEATURE_IPACM_HAL
73 #include "IPACM_OffloadManager.h"
74 #include <HAL.h>
75 #endif
76 
77 #include "IPACM_LanToLan.h"
78 
79 #define IPA_DRIVER  "/dev/ipa"
80 
81 #define IPACM_FIREWALL_FILE_NAME    "mobileap_firewall.xml"
82 #define IPACM_CFG_FILE_NAME    "IPACM_cfg.xml"
83 #ifdef FEATURE_IPA_ANDROID
84 #define IPACM_PID_FILE "/data/vendor/ipa/ipacm.pid"
85 #define IPACM_DIR_NAME     "/data"
86 #else/* defined(FEATURE_IPA_ANDROID) */
87 #define IPACM_PID_FILE "/etc/ipacm.pid"
88 #define IPACM_DIR_NAME     "/etc"
89 #endif /* defined(NOT FEATURE_IPA_ANDROID)*/
90 #define IPACM_NAME "ipacm"
91 
92 #define INOTIFY_EVENT_SIZE  (sizeof(struct inotify_event))
93 #define INOTIFY_BUF_LEN     (INOTIFY_EVENT_SIZE + 2*sizeof(IPACM_FIREWALL_FILE_NAME))
94 
95 #define IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS  3
96 #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))
97 #define IPA_DRIVER_PIPE_STATS_EVENT_SIZE  (sizeof(struct ipa_get_data_stats_resp_msg_v01))
98 #define IPA_DRIVER_WLAN_META_MSG    (sizeof(struct ipa_msg_meta))
99 #define IPA_DRIVER_WLAN_BUF_LEN     (IPA_DRIVER_PIPE_STATS_EVENT_SIZE + IPA_DRIVER_WLAN_META_MSG)
100 
101 uint32_t ipacm_event_stats[IPACM_EVENT_MAX];
102 bool ipacm_logging = true;
103 
104 void ipa_is_ipacm_running(void);
105 int ipa_get_if_index(char *if_name, int *if_index);
106 
107 IPACM_Neighbor *neigh;
108 IPACM_IfaceManager *ifacemgr;
109 
110 #ifdef FEATURE_IPACM_RESTART
111 int ipa_reset();
112 /* support ipacm restart */
113 int ipa_query_wlan_client();
114 #endif
115 
116 
117 /* support ipa-hw-index-counters */
118 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
119 int ipa_reset_hw_index_counter();
120 #endif
121 
122 #ifdef FEATURE_IPACM_HAL
123 	IPACM_OffloadManager* OffloadMng;
124 	HAL *hal;
125 #endif
126 
127 /* start netlink socket monitor*/
netlink_start(void * param)128 void* netlink_start(void *param)
129 {
130 	param = NULL;
131 	ipa_nl_sk_fd_set_info_t sk_fdset;
132 	int ret_val = 0;
133 	memset(&sk_fdset, 0, sizeof(ipa_nl_sk_fd_set_info_t));
134 	IPACMDBG_H("netlink starter memset sk_fdset succeeds\n");
135 	ret_val = ipa_nl_listener_init(NETLINK_ROUTE, (RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_LINK |
136 																										RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NEIGH |
137 																										RTNLGRP_IPV6_PREFIX),
138 																 &sk_fdset, ipa_nl_recv_msg);
139 
140 	if (ret_val != IPACM_SUCCESS)
141 	{
142 		IPACMERR("Failed to initialize IPA netlink event listener\n");
143 		return NULL;
144 	}
145 
146 	return NULL;
147 }
148 
149 /* start firewall-rule monitor*/
firewall_monitor(void * param)150 void* firewall_monitor(void *param)
151 {
152 	int length;
153 	int wd;
154 	char buffer[INOTIFY_BUF_LEN];
155 	int inotify_fd;
156 	ipacm_cmd_q_data evt_data;
157 	uint32_t mask = IN_MODIFY | IN_MOVE;
158 
159 	param = NULL;
160 	inotify_fd = inotify_init();
161 	if (inotify_fd < 0)
162 	{
163 		PERROR("inotify_init");
164 	}
165 
166 	IPACMDBG_H("Waiting for nofications in dir %s with mask: 0x%x\n", IPACM_DIR_NAME, mask);
167 
168 	wd = inotify_add_watch(inotify_fd,
169 												 IPACM_DIR_NAME,
170 												 mask);
171 
172 	while (1)
173 	{
174 		length = read(inotify_fd, buffer, INOTIFY_BUF_LEN);
175 		if (length < 0)
176 		{
177 			IPACMERR("inotify read() error return length: %d and mask: 0x%x\n", length, mask);
178 			continue;
179 		}
180 
181 		struct inotify_event* event;
182 		event = (struct inotify_event*)malloc(length);
183 		if(event == NULL)
184 		{
185 			IPACMERR("Failed to allocate memory.\n");
186 			return NULL;
187 		}
188 		memset(event, 0, length);
189 		memcpy(event, buffer, length);
190 
191 		if (event->len > 0)
192 		{
193 			if ( (event->mask & IN_MODIFY) || (event->mask & IN_MOVE))
194 			{
195 				if (event->mask & IN_ISDIR)
196 				{
197 					IPACMDBG_H("The directory %s was 0x%x\n", event->name, event->mask);
198 				}
199 				else if (!strncmp(event->name, IPACM_FIREWALL_FILE_NAME, event->len)) // firewall_rule change
200 				{
201 					IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
202 					IPACMDBG_H("The interested file %s .\n", IPACM_FIREWALL_FILE_NAME);
203 
204 					evt_data.event = IPA_FIREWALL_CHANGE_EVENT;
205 					evt_data.evt_data = NULL;
206 
207 					/* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
208 					IPACM_EvtDispatcher::PostEvt(&evt_data);
209 				}
210 				else if (!strncmp(event->name, IPACM_CFG_FILE_NAME, event->len)) // IPACM_configuration change
211 				{
212 					IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
213 					IPACMDBG_H("The interested file %s .\n", IPACM_CFG_FILE_NAME);
214 
215 					evt_data.event = IPA_CFG_CHANGE_EVENT;
216 					evt_data.evt_data = NULL;
217 
218 					/* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
219 					IPACM_EvtDispatcher::PostEvt(&evt_data);
220 				}
221 			}
222 			IPACMDBG_H("Received monitoring event %s.\n", event->name);
223 		}
224 		free(event);
225 	}
226 
227 	(void)inotify_rm_watch(inotify_fd, wd);
228 	(void)close(inotify_fd);
229 	return NULL;
230 }
231 
232 
233 /* start IPACM wan-driver notifier */
ipa_driver_msg_notifier(void * param)234 void* ipa_driver_msg_notifier(void *param)
235 {
236 	int length, fd, cnt;
237 	char buffer[IPA_DRIVER_WLAN_BUF_LEN];
238 	struct ipa_msg_meta event_hdr;
239 	struct ipa_ecm_msg event_ecm;
240 	struct ipa_wan_msg event_wan;
241 	struct ipa_wlan_msg_ex event_ex_o;
242 	struct ipa_wlan_msg *event_wlan = NULL;
243 	struct ipa_wlan_msg_ex *event_ex = NULL;
244 #ifdef WIGIG_CLIENT_CONNECT
245 	struct ipa_wigig_msg *event_wigig = NULL;
246 #endif
247 	struct ipa_get_data_stats_resp_msg_v01 event_data_stats;
248 	struct ipa_get_apn_data_stats_resp_msg_v01 event_network_stats;
249 #ifdef IPA_RT_SUPPORT_COAL
250 	struct ipa_coalesce_info coalesce_info;
251 #endif
252 
253 #ifdef FEATURE_IPACM_HAL
254 	IPACM_OffloadManager* OffloadMng;
255 #endif
256 
257 	ipacm_cmd_q_data evt_data;
258 	ipacm_event_data_mac *data = NULL;
259 #ifdef WIGIG_CLIENT_CONNECT
260 	ipacm_event_data_mac_ep *data_wigig = NULL;
261 #endif
262 	ipacm_event_data_fid *data_fid = NULL;
263 	ipacm_event_data_iptype *data_iptype = NULL;
264 	ipacm_event_data_wlan_ex *data_ex;
265 	ipa_get_data_stats_resp_msg_v01 *data_tethering_stats = NULL;
266 	ipa_get_apn_data_stats_resp_msg_v01 *data_network_stats = NULL;
267 #ifdef FEATURE_L2TP
268 	ipa_ioc_vlan_iface_info *vlan_info = NULL;
269 	ipa_ioc_l2tp_vlan_mapping_info *mapping = NULL;
270 #endif
271 	ipacm_cmd_q_data new_neigh_evt;
272 	ipacm_event_data_all* new_neigh_data;
273 
274 	param = NULL;
275 	fd = open(IPA_DRIVER, O_RDWR);
276 	if (fd < 0)
277 	{
278 		IPACMERR("Failed opening %s.\n", IPA_DRIVER);
279 		return NULL;
280 	}
281 
282 	while (1)
283 	{
284 		IPACMDBG_H("Waiting for nofications from IPA driver \n");
285 		memset(buffer, 0, sizeof(buffer));
286 		memset(&evt_data, 0, sizeof(evt_data));
287 		memset(&new_neigh_evt, 0, sizeof(ipacm_cmd_q_data));
288 		new_neigh_data = NULL;
289 		data = NULL;
290 		data_fid = NULL;
291 		data_tethering_stats = NULL;
292 		data_network_stats = NULL;
293 
294 		length = read(fd, buffer, IPA_DRIVER_WLAN_BUF_LEN);
295 		if (length < 0)
296 		{
297 			PERROR("didn't read IPA_driver correctly");
298 			continue;
299 		}
300 
301 		memcpy(&event_hdr, buffer,sizeof(struct ipa_msg_meta));
302 		IPACMDBG_H("Message type: %d\n", event_hdr.msg_type);
303 		IPACMDBG_H("Event header length received: %d\n",event_hdr.msg_len);
304 
305 		/* Insert WLAN_DRIVER_EVENT to command queue */
306 		switch (event_hdr.msg_type)
307 		{
308 
309 		case SW_ROUTING_ENABLE:
310 			IPACMDBG_H("Received SW_ROUTING_ENABLE\n");
311 			evt_data.event = IPA_SW_ROUTING_ENABLE;
312 			IPACMDBG_H("Not supported anymore\n");
313 			continue;
314 
315 		case SW_ROUTING_DISABLE:
316 			IPACMDBG_H("Received SW_ROUTING_DISABLE\n");
317 			evt_data.event = IPA_SW_ROUTING_DISABLE;
318 			IPACMDBG_H("Not supported anymore\n");
319 			continue;
320 
321 		case WLAN_AP_CONNECT:
322 			event_wlan = (struct ipa_wlan_msg *) (buffer + sizeof(struct ipa_msg_meta));
323 			IPACMDBG_H("Received WLAN_AP_CONNECT name: %s\n",event_wlan->name);
324 			IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
325 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
326 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
327                         data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
328 			if(data_fid == NULL)
329 			{
330 				IPACMERR("unable to allocate memory for event_wlan data_fid\n");
331 				return NULL;
332 			}
333 			ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
334 			evt_data.event = IPA_WLAN_AP_LINK_UP_EVENT;
335 			evt_data.evt_data = data_fid;
336 			break;
337 
338 		case WLAN_AP_DISCONNECT:
339 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
340 			IPACMDBG_H("Received WLAN_AP_DISCONNECT name: %s\n",event_wlan->name);
341 			IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
342 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
343 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
344                         data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
345 			if(data_fid == NULL)
346 			{
347 				IPACMERR("unable to allocate memory for event_wlan data_fid\n");
348 				return NULL;
349 			}
350 			ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
351 			evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
352 			evt_data.evt_data = data_fid;
353 			break;
354 		case WLAN_STA_CONNECT:
355 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
356 			IPACMDBG_H("Received WLAN_STA_CONNECT name: %s\n",event_wlan->name);
357 			IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
358 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
359 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
360 			data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
361 			if(data == NULL)
362 			{
363 				IPACMERR("unable to allocate memory for event_wlan data_fid\n");
364 				return NULL;
365 			}
366 			memcpy(data->mac_addr,
367 				 event_wlan->mac_addr,
368 				 sizeof(event_wlan->mac_addr));
369 			ipa_get_if_index(event_wlan->name, &(data->if_index));
370 			evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT;
371 			evt_data.evt_data = data;
372 			break;
373 
374 		case WLAN_STA_DISCONNECT:
375 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
376 			IPACMDBG_H("Received WLAN_STA_DISCONNECT name: %s\n",event_wlan->name);
377 			IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
378 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
379 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
380                         data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
381 			if(data_fid == NULL)
382 			{
383 				IPACMERR("unable to allocate memory for event_wlan data_fid\n");
384 				return NULL;
385 			}
386 			ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
387 			evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
388 			evt_data.evt_data = data_fid;
389 			break;
390 
391 		case WLAN_CLIENT_CONNECT:
392 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
393 			IPACMDBG_H("Received WLAN_CLIENT_CONNECT\n");
394 			IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
395 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
396 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
397 		        data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
398 		        if (data == NULL)
399 		        {
400 		    	        IPACMERR("unable to allocate memory for event_wlan data\n");
401 		    	        return NULL;
402 		        }
403 			memcpy(data->mac_addr,
404 						 event_wlan->mac_addr,
405 						 sizeof(event_wlan->mac_addr));
406 			ipa_get_if_index(event_wlan->name, &(data->if_index));
407 		        evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT;
408 			evt_data.evt_data = data;
409 			break;
410 #ifdef WIGIG_CLIENT_CONNECT
411 		case WIGIG_CLIENT_CONNECT:
412 			event_wigig = (struct ipa_wigig_msg *)(buffer + sizeof(struct ipa_msg_meta));
413 			IPACMDBG_H("Received WIGIG_CLIENT_CONNECT\n");
414 			IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x, ep %d\n",
415 				event_wigig->client_mac_addr[0], event_wigig->client_mac_addr[1], event_wigig->client_mac_addr[2],
416 				event_wigig->client_mac_addr[3], event_wigig->client_mac_addr[4], event_wigig->client_mac_addr[5],
417 				event_wigig->u.ipa_client);
418 
419 			data_wigig = (ipacm_event_data_mac_ep *)malloc(sizeof(ipacm_event_data_mac_ep));
420 			if(data_wigig == NULL)
421 			{
422 				IPACMERR("unable to allocate memory for event_wigig data\n");
423 				return NULL;
424 			}
425 			memcpy(data_wigig->mac_addr,
426 				event_wigig->client_mac_addr,
427 				sizeof(data_wigig->mac_addr));
428 			ipa_get_if_index(event_wigig->name, &(data_wigig->if_index));
429 			data_wigig->client = event_wigig->u.ipa_client;
430 			evt_data.event = IPA_WIGIG_CLIENT_ADD_EVENT;
431 			evt_data.evt_data = data_wigig;
432 			break;
433 #endif
434 		case WLAN_CLIENT_CONNECT_EX:
435 			IPACMDBG_H("Received WLAN_CLIENT_CONNECT_EX\n");
436 
437 			memcpy(&event_ex_o, buffer + sizeof(struct ipa_msg_meta),sizeof(struct ipa_wlan_msg_ex));
438 			if(event_ex_o.num_of_attribs > IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS)
439 			{
440 				IPACMERR("buffer size overflow\n");
441 				return NULL;
442 			}
443 			length = sizeof(ipa_wlan_msg_ex)+ event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val);
444 			IPACMDBG_H("num_of_attribs %d, length %d\n", event_ex_o.num_of_attribs, length);
445 			event_ex = (ipa_wlan_msg_ex *)malloc(length);
446 			if(event_ex == NULL )
447 			{
448 				IPACMERR("Unable to allocate memory\n");
449 				return NULL;
450 			}
451 			memcpy(event_ex, buffer + sizeof(struct ipa_msg_meta), length);
452 			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));
453 		    if (data_ex == NULL)
454 		    {
455 				IPACMERR("unable to allocate memory for event data\n");
456 		    	return NULL;
457 		    }
458 			data_ex->num_of_attribs = event_ex->num_of_attribs;
459 
460 			memcpy(data_ex->attribs,
461 						event_ex->attribs,
462 						event_ex->num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
463 
464 			ipa_get_if_index(event_ex->name, &(data_ex->if_index));
465 			evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT_EX;
466 			evt_data.evt_data = data_ex;
467 
468 			/* Construct new_neighbor msg with netdev device internally */
469 			new_neigh_data = (ipacm_event_data_all*)malloc(sizeof(ipacm_event_data_all));
470 			if(new_neigh_data == NULL)
471 			{
472 				IPACMERR("Failed to allocate memory.\n");
473 				return NULL;
474 			}
475 			memset(new_neigh_data, 0, sizeof(ipacm_event_data_all));
476 			new_neigh_data->iptype = IPA_IP_v6;
477 			for(cnt = 0; cnt < event_ex->num_of_attribs; cnt++)
478 			{
479 				if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
480 				{
481 					memcpy(new_neigh_data->mac_addr, event_ex->attribs[cnt].u.mac_addr, sizeof(new_neigh_data->mac_addr));
482 					IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
483 								 event_ex->attribs[cnt].u.mac_addr[0], event_ex->attribs[cnt].u.mac_addr[1], event_ex->attribs[cnt].u.mac_addr[2],
484 								 event_ex->attribs[cnt].u.mac_addr[3], event_ex->attribs[cnt].u.mac_addr[4], event_ex->attribs[cnt].u.mac_addr[5]);
485 				}
486 				else if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
487 				{
488 					IPACMDBG_H("Wlan client id %d\n",event_ex->attribs[cnt].u.sta_id);
489 				}
490 				else
491 				{
492 					IPACMDBG_H("Wlan message has unexpected type!\n");
493 				}
494 			}
495 			new_neigh_data->if_index = data_ex->if_index;
496 			new_neigh_evt.evt_data = (void*)new_neigh_data;
497 			new_neigh_evt.event = IPA_NEW_NEIGH_EVENT;
498 			free(event_ex);
499 			break;
500 
501 		case WLAN_CLIENT_DISCONNECT:
502 			IPACMDBG_H("Received WLAN_CLIENT_DISCONNECT\n");
503 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
504 			IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
505 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
506 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
507 		        data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
508 		        if (data == NULL)
509 		        {
510 		    	        IPACMERR("unable to allocate memory for event_wlan data\n");
511 		    	        return NULL;
512 		        }
513 			memcpy(data->mac_addr,
514 						 event_wlan->mac_addr,
515 						 sizeof(event_wlan->mac_addr));
516 			ipa_get_if_index(event_wlan->name, &(data->if_index));
517 			evt_data.event = IPA_WLAN_CLIENT_DEL_EVENT;
518 			evt_data.evt_data = data;
519 			break;
520 
521 		case WLAN_CLIENT_POWER_SAVE_MODE:
522 			IPACMDBG_H("Received WLAN_CLIENT_POWER_SAVE_MODE\n");
523 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
524 			IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
525 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
526 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
527 		        data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
528 		        if (data == NULL)
529 		        {
530 		    	        IPACMERR("unable to allocate memory for event_wlan data\n");
531 		    	        return NULL;
532 		        }
533 			memcpy(data->mac_addr,
534 						 event_wlan->mac_addr,
535 						 sizeof(event_wlan->mac_addr));
536 			ipa_get_if_index(event_wlan->name, &(data->if_index));
537 			evt_data.event = IPA_WLAN_CLIENT_POWER_SAVE_EVENT;
538 			evt_data.evt_data = data;
539 			break;
540 
541 		case WLAN_CLIENT_NORMAL_MODE:
542 			IPACMDBG_H("Received WLAN_CLIENT_NORMAL_MODE\n");
543 			event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
544 			IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
545 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
546 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
547 		        data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
548 		        if (data == NULL)
549 		        {
550 		    	       IPACMERR("unable to allocate memory for event_wlan data\n");
551 		    	       return NULL;
552 		        }
553 			memcpy(data->mac_addr,
554 						 event_wlan->mac_addr,
555 						 sizeof(event_wlan->mac_addr));
556 			ipa_get_if_index(event_wlan->name, &(data->if_index));
557 			evt_data.evt_data = data;
558 			evt_data.event = IPA_WLAN_CLIENT_RECOVER_EVENT;
559 			break;
560 
561 		case ECM_CONNECT:
562 			memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
563 			IPACMDBG_H("Received ECM_CONNECT name: %s\n",event_ecm.name);
564 			data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
565 			if(data_fid == NULL)
566 			{
567 				IPACMERR("unable to allocate memory for event_ecm data_fid\n");
568 				return NULL;
569 			}
570 			data_fid->if_index = event_ecm.ifindex;
571 			evt_data.event = IPA_USB_LINK_UP_EVENT;
572 			evt_data.evt_data = data_fid;
573 			break;
574 
575 		case ECM_DISCONNECT:
576 			memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
577 			IPACMDBG_H("Received ECM_DISCONNECT name: %s\n",event_ecm.name);
578 			data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
579 			if(data_fid == NULL)
580 			{
581 				IPACMERR("unable to allocate memory for event_ecm data_fid\n");
582 				return NULL;
583 			}
584 			data_fid->if_index = event_ecm.ifindex;
585 			evt_data.event = IPA_LINK_DOWN_EVENT;
586 			evt_data.evt_data = data_fid;
587 			break;
588 		/* Add for 8994 Android case */
589 		case WAN_UPSTREAM_ROUTE_ADD:
590 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
591 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
592 			data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
593 			if(data_iptype == NULL)
594 			{
595 				IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
596 				return NULL;
597 			}
598 			ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
599 			ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
600 			data_iptype->iptype = event_wan.ip;
601 #ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
602 			data_iptype->ipv4_addr_gw = event_wan.ipv4_addr_gw;
603 			data_iptype->ipv6_addr_gw[0] = event_wan.ipv6_addr_gw[0];
604 			data_iptype->ipv6_addr_gw[1] = event_wan.ipv6_addr_gw[1];
605 			data_iptype->ipv6_addr_gw[2] = event_wan.ipv6_addr_gw[2];
606 			data_iptype->ipv6_addr_gw[3] = event_wan.ipv6_addr_gw[3];
607 			IPACMDBG_H("default gw ipv4 (%x)\n", data_iptype->ipv4_addr_gw);
608 			IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
609 							data_iptype->ipv6_addr_gw[0], data_iptype->ipv6_addr_gw[1], data_iptype->ipv6_addr_gw[2], data_iptype->ipv6_addr_gw[3]);
610 #endif
611 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index,
612 					data_iptype->if_index_tether, data_iptype->iptype);
613 			evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
614 			evt_data.evt_data = data_iptype;
615 			break;
616 		case WAN_UPSTREAM_ROUTE_DEL:
617 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
618 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
619 			data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
620 			if(data_iptype == NULL)
621 			{
622 				IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
623 				return NULL;
624 			}
625 			ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
626 			ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
627 			data_iptype->iptype = event_wan.ip;
628 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
629 			evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT;
630 			evt_data.evt_data = data_iptype;
631 			break;
632 		/* End of adding for 8994 Android case */
633 
634 		/* Add for embms case */
635 		case WAN_EMBMS_CONNECT:
636 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
637 			IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
638 			data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
639 			if(data_fid == NULL)
640 			{
641 				IPACMERR("unable to allocate memory for event data_fid\n");
642 				return NULL;
643 			}
644 			ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
645 			evt_data.event = IPA_WAN_EMBMS_LINK_UP_EVENT;
646 			evt_data.evt_data = data_fid;
647 			break;
648 
649 		case WLAN_SWITCH_TO_SCC:
650 			IPACMDBG_H("Received WLAN_SWITCH_TO_SCC\n");
651 			[[fallthrough]];
652 		case WLAN_WDI_ENABLE:
653 			IPACMDBG_H("Received WLAN_WDI_ENABLE\n");
654 			if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
655 			{
656 				IPACM_Iface::ipacmcfg->isMCC_Mode = false;
657 				evt_data.event = IPA_WLAN_SWITCH_TO_SCC;
658 				break;
659 			}
660 			continue;
661 		case WLAN_SWITCH_TO_MCC:
662 			IPACMDBG_H("Received WLAN_SWITCH_TO_MCC\n");
663 			[[fallthrough]];
664 		case WLAN_WDI_DISABLE:
665 			IPACMDBG_H("Received WLAN_WDI_DISABLE\n");
666 			if (IPACM_Iface::ipacmcfg->isMCC_Mode == false)
667 			{
668 				IPACM_Iface::ipacmcfg->isMCC_Mode = true;
669 				evt_data.event = IPA_WLAN_SWITCH_TO_MCC;
670 				break;
671 			}
672 			continue;
673 
674 		case WAN_XLAT_CONNECT:
675 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta),
676 				sizeof(struct ipa_wan_msg));
677 			IPACMDBG_H("Received WAN_XLAT_CONNECT name: %s\n",
678 					event_wan.upstream_ifname);
679 
680 			/* post IPA_LINK_UP_EVENT event
681 			 * may be WAN interface is not up
682 			*/
683 			data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
684 			if(data_fid == NULL)
685 			{
686 				IPACMERR("unable to allocate memory for xlat event\n");
687 				return NULL;
688 			}
689 			ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
690 			evt_data.event = IPA_LINK_UP_EVENT;
691 			evt_data.evt_data = data_fid;
692 			IPACMDBG_H("Posting IPA_LINK_UP_EVENT event:%d\n", evt_data.event);
693 			IPACM_EvtDispatcher::PostEvt(&evt_data);
694 
695 			/* post IPA_WAN_XLAT_CONNECT_EVENT event */
696 			memset(&evt_data, 0, sizeof(evt_data));
697 			data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
698 			if(data_fid == NULL)
699 			{
700 				IPACMERR("unable to allocate memory for xlat event\n");
701 				return NULL;
702 			}
703 			ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
704 			evt_data.event = IPA_WAN_XLAT_CONNECT_EVENT;
705 			evt_data.evt_data = data_fid;
706 			IPACMDBG_H("Posting IPA_WAN_XLAT_CONNECT_EVENT event:%d\n", evt_data.event);
707 			break;
708 
709 		case IPA_TETHERING_STATS_UPDATE_STATS:
710 			memcpy(&event_data_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_data_stats_resp_msg_v01));
711 			data_tethering_stats = (ipa_get_data_stats_resp_msg_v01 *)malloc(sizeof(struct ipa_get_data_stats_resp_msg_v01));
712 			if(data_tethering_stats == NULL)
713 			{
714 				IPACMERR("unable to allocate memory for event data_tethering_stats\n");
715 				return NULL;
716 			}
717 			memcpy(data_tethering_stats,
718 					 &event_data_stats,
719 						 sizeof(struct ipa_get_data_stats_resp_msg_v01));
720 			IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data_tethering_stats->ipa_stats_type);
721 			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);
722 			evt_data.event = IPA_TETHERING_STATS_UPDATE_EVENT;
723 			evt_data.evt_data = data_tethering_stats;
724 			break;
725 
726 		case IPA_TETHERING_STATS_UPDATE_NETWORK_STATS:
727 			memcpy(&event_network_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
728 			data_network_stats = (ipa_get_apn_data_stats_resp_msg_v01 *)malloc(sizeof(ipa_get_apn_data_stats_resp_msg_v01));
729 			if(data_network_stats == NULL)
730 			{
731 				IPACMERR("unable to allocate memory for event data_network_stats\n");
732 				return NULL;
733 			}
734 			memcpy(data_network_stats,
735 					 &event_network_stats,
736 						 sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
737 			IPACMDBG("Received %d apn network stats \n", data_network_stats->apn_data_stats_list_len);
738 			evt_data.event = IPA_NETWORK_STATS_UPDATE_EVENT;
739 			evt_data.evt_data = data_network_stats;
740 			break;
741 
742 #ifdef FEATURE_IPACM_HAL
743 		case IPA_QUOTA_REACH:
744 			IPACMDBG_H("Received IPA_QUOTA_REACH\n");
745 			OffloadMng = IPACM_OffloadManager::GetInstance();
746 			if (OffloadMng->elrInstance == NULL) {
747 				IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
748 			} else {
749 				IPACMERR("calling OffloadMng->elrInstance->onLimitReached \n");
750 				OffloadMng->elrInstance->onLimitReached();
751 			}
752 			continue;
753 		case IPA_SSR_BEFORE_SHUTDOWN:
754 			IPACMDBG_H("Received IPA_SSR_BEFORE_SHUTDOWN\n");
755 			IPACM_Wan::clearExtProp();
756 			OffloadMng = IPACM_OffloadManager::GetInstance();
757 			if (OffloadMng->elrInstance == NULL) {
758 				IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
759 			} else {
760 				IPACMERR("calling OffloadMng->elrInstance->onOffloadStopped \n");
761 				OffloadMng->elrInstance->onOffloadStopped(IpaEventRelay::ERROR);
762 			}
763 			/* WA to clean up wlan instances during SSR */
764 			evt_data.event = IPA_SSR_NOTICE;
765 			evt_data.evt_data = NULL;
766 			break;
767 		case IPA_SSR_AFTER_POWERUP:
768 			IPACMDBG_H("Received IPA_SSR_AFTER_POWERUP\n");
769 			OffloadMng = IPACM_OffloadManager::GetInstance();
770 			if (OffloadMng->elrInstance == NULL) {
771 				IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
772 			} else {
773 				IPACMERR("calling OffloadMng->elrInstance->onOffloadSupportAvailable \n");
774 				OffloadMng->elrInstance->onOffloadSupportAvailable();
775 			}
776 			continue;
777 #ifdef IPA_WLAN_FW_SSR_EVENT_MAX
778 		case WLAN_FWR_SSR_BEFORE_SHUTDOWN:
779                         IPACMDBG_H("Received WLAN_FWR_SSR_BEFORE_SHUTDOWN\n");
780                         evt_data.event = IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE;
781                         evt_data.evt_data = NULL;
782                         break;
783 #endif
784 #endif
785 #ifdef FEATURE_L2TP
786 		case ADD_VLAN_IFACE:
787 			vlan_info = (ipa_ioc_vlan_iface_info *)malloc(sizeof(*vlan_info));
788 			if(vlan_info == NULL)
789 			{
790 				IPACMERR("Failed to allocate memory.\n");
791 				return NULL;
792 			}
793 			memcpy(vlan_info, buffer + sizeof(struct ipa_msg_meta), sizeof(*vlan_info));
794 			evt_data.event = IPA_ADD_VLAN_IFACE;
795 			evt_data.evt_data = vlan_info;
796 			break;
797 
798 		case DEL_VLAN_IFACE:
799 			vlan_info = (ipa_ioc_vlan_iface_info *)malloc(sizeof(*vlan_info));
800 			if(vlan_info == NULL)
801 			{
802 				IPACMERR("Failed to allocate memory.\n");
803 				return NULL;
804 			}
805 			memcpy(vlan_info, buffer + sizeof(struct ipa_msg_meta), sizeof(*vlan_info));
806 			evt_data.event = IPA_DEL_VLAN_IFACE;
807 			evt_data.evt_data = vlan_info;
808 			break;
809 
810 		case ADD_L2TP_VLAN_MAPPING:
811 			mapping = (ipa_ioc_l2tp_vlan_mapping_info *)malloc(sizeof(*mapping));
812 			if(mapping == NULL)
813 			{
814 				IPACMERR("Failed to allocate memory.\n");
815 				return NULL;
816 			}
817 			memcpy(mapping, buffer + sizeof(struct ipa_msg_meta), sizeof(*mapping));
818 			evt_data.event = IPA_ADD_L2TP_VLAN_MAPPING;
819 			evt_data.evt_data = mapping;
820 			break;
821 
822 		case DEL_L2TP_VLAN_MAPPING:
823 			mapping = (ipa_ioc_l2tp_vlan_mapping_info *)malloc(sizeof(*mapping));
824 			if(mapping == NULL)
825 			{
826 				IPACMERR("Failed to allocate memory.\n");
827 				return NULL;
828 			}
829 			memcpy(mapping, buffer + sizeof(struct ipa_msg_meta), sizeof(*mapping));
830 			evt_data.event = IPA_DEL_L2TP_VLAN_MAPPING;
831 			evt_data.evt_data = mapping;
832 			break;
833 #endif
834 #ifdef IPA_RT_SUPPORT_COAL
835 		case IPA_COALESCE_ENABLE:
836 			memcpy(&coalesce_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_coalesce_info));
837 			IPACMDBG_H("Received IPA_COALESCE_ENABLE qmap-id:%d tcp:%d, udp%d\n",
838 				coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
839 			if (coalesce_info.qmap_id >=IPA_MAX_NUM_SW_PDNS)
840 			{
841 				IPACMERR("qmap_id (%d) beyond the Max range (%d), abort\n",
842 				coalesce_info.qmap_id, IPA_MAX_NUM_SW_PDNS);
843 				return NULL;
844 			}
845 			IPACM_Wan::coalesce_config(coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
846 			/* Notify all LTE instance to do RSC configuration */
847 			evt_data.event = IPA_COALESCE_NOTICE;
848 			evt_data.evt_data = NULL;
849 			break;
850 
851 		case IPA_COALESCE_DISABLE:
852 			memcpy(&coalesce_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_coalesce_info));
853 			IPACMDBG_H("Received IPA_COALESCE_DISABLE qmap-id:%d tcp:%d, udp%d\n",
854 				coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
855 			if (coalesce_info.qmap_id >=IPA_MAX_NUM_SW_PDNS)
856 			{
857 				IPACMERR("qmap_id (%d) beyond the Max range (%d), abort\n",
858 				coalesce_info.qmap_id, IPA_MAX_NUM_SW_PDNS);
859 				return NULL;
860 			}
861 			IPACM_Wan::coalesce_config(coalesce_info.qmap_id, false, false);
862 			/* Notify all LTE instance to do RSC configuration */
863 			evt_data.event = IPA_COALESCE_NOTICE;
864 			evt_data.evt_data = NULL;
865 			break;
866 #endif
867 
868 		default:
869 			IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
870 			continue;
871 
872 		}
873 		/* finish command queue */
874 		IPACMDBG_H("Posting event:%d\n", evt_data.event);
875 		IPACM_EvtDispatcher::PostEvt(&evt_data);
876 		/* push new_neighbor with netdev device internally */
877 		if(new_neigh_data != NULL)
878 		{
879 			IPACMDBG_H("Internally post event IPA_NEW_NEIGH_EVENT\n");
880 			IPACM_EvtDispatcher::PostEvt(&new_neigh_evt);
881 		}
882 	}
883 
884 	(void)close(fd);
885 	return NULL;
886 }
887 
IPACM_Sig_Handler(int sig)888 void IPACM_Sig_Handler(int sig)
889 {
890 	ipacm_cmd_q_data evt_data;
891 
892 	printf("Received Signal: %d\n", sig);
893 	memset(&evt_data, 0, sizeof(evt_data));
894 
895 	switch(sig)
896 	{
897 		case SIGUSR1:
898 			IPACMDBG_H("Received SW_ROUTING_ENABLE request \n");
899 			evt_data.event = IPA_SW_ROUTING_ENABLE;
900 			IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = true;
901 			break;
902 
903 		case SIGUSR2:
904 			IPACMDBG_H("Received SW_ROUTING_DISABLE request \n");
905 			evt_data.event = IPA_SW_ROUTING_DISABLE;
906 			IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = false;
907 			break;
908 	}
909 	/* finish command queue */
910 	IPACMDBG_H("Posting event:%d\n", evt_data.event);
911 	IPACM_EvtDispatcher::PostEvt(&evt_data);
912 	return;
913 }
914 
RegisterForSignals(void)915 void RegisterForSignals(void)
916 {
917 
918 	signal(SIGUSR1, IPACM_Sig_Handler);
919 	signal(SIGUSR2, IPACM_Sig_Handler);
920 }
921 
922 
main(int argc,char ** argv)923 int main(int argc, char **argv)
924 {
925 	int ret;
926 	pthread_t netlink_thread = 0, monitor_thread = 0, ipa_driver_thread = 0;
927 	pthread_t cmd_queue_thread = 0;
928 
929 	/* check if ipacm is already running or not */
930 	ipa_is_ipacm_running();
931 
932 	IPACMDBG_H("In main()\n");
933 	(void)argc;
934 	(void)argv;
935 
936 #ifdef FEATURE_IPACM_RESTART
937 	IPACMDBG_H("RESET IPA-HW rules\n");
938 	ipa_reset();
939 #endif
940 
941 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
942 	IPACMDBG_H("Configure IPA-HW index-counter\n");
943 	ipa_reset_hw_index_counter();
944 #endif
945 
946 	neigh = new IPACM_Neighbor();
947 	ifacemgr = new IPACM_IfaceManager();
948 #ifdef FEATURE_IPACM_HAL
949 	OffloadMng = IPACM_OffloadManager::GetInstance();
950 	hal = HAL::makeIPAHAL(1, OffloadMng);
951 	IPACMDBG_H(" START IPACM_OffloadManager and link to android framework\n");
952 #endif
953 
954 	if (IPACM_Iface::ipacmcfg->isEthBridgingSupported())
955 	{
956 		IPACM_LanToLan* lan2lan = IPACM_LanToLan::get_instance();
957 		IPACMDBG_H("Staring IPACM_LanToLan instance %p\n", lan2lan);
958 	}
959 	CtList = new IPACM_ConntrackListener();
960 
961 	IPACMDBG_H("Staring IPA main\n");
962 	IPACMDBG_H("ipa_cmdq_successful\n");
963 
964 	/* reset coalesce settings */
965 	IPACM_Wan::coalesce_config_reset();
966 
967 	RegisterForSignals();
968 
969 	if (IPACM_SUCCESS == cmd_queue_thread)
970 	{
971 		ret = pthread_create(&cmd_queue_thread, NULL, MessageQueue::Process, NULL);
972 		if (IPACM_SUCCESS != ret)
973 		{
974 			IPACMERR("unable to command queue thread\n");
975 			return ret;
976 		}
977 		IPACMDBG_H("created command queue thread\n");
978 		if(pthread_setname_np(cmd_queue_thread, "cmd queue process") != 0)
979 		{
980 			IPACMERR("unable to set thread name\n");
981 		}
982 	}
983 
984 	if (IPACM_SUCCESS == netlink_thread)
985 	{
986 		ret = pthread_create(&netlink_thread, NULL, netlink_start, NULL);
987 		if (IPACM_SUCCESS != ret)
988 		{
989 			IPACMERR("unable to create netlink thread\n");
990 			return ret;
991 		}
992 		IPACMDBG_H("created netlink thread\n");
993 		if(pthread_setname_np(netlink_thread, "netlink socket") != 0)
994 		{
995 			IPACMERR("unable to set thread name\n");
996 		}
997 	}
998 
999 	/* Enable Firewall support only on MDM targets */
1000 #ifndef FEATURE_IPA_ANDROID
1001 	if (IPACM_SUCCESS == monitor_thread)
1002 	{
1003 		ret = pthread_create(&monitor_thread, NULL, firewall_monitor, NULL);
1004 		if (IPACM_SUCCESS != ret)
1005 		{
1006 			IPACMERR("unable to create monitor thread\n");
1007 			return ret;
1008 		}
1009 		IPACMDBG_H("created firewall monitor thread\n");
1010 		if(pthread_setname_np(monitor_thread, "firewall cfg process") != 0)
1011 		{
1012 			IPACMERR("unable to set thread name\n");
1013 		}
1014 	}
1015 #endif
1016 
1017 	if (IPACM_SUCCESS == ipa_driver_thread)
1018 	{
1019 		ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_msg_notifier, NULL);
1020 		if (IPACM_SUCCESS != ret)
1021 		{
1022 			IPACMERR("unable to create ipa_driver_wlan thread\n");
1023 			return ret;
1024 		}
1025 		IPACMDBG_H("created ipa_driver_wlan thread\n");
1026 		if(pthread_setname_np(ipa_driver_thread, "ipa driver ntfy") != 0)
1027 		{
1028 			IPACMERR("unable to set thread name\n");
1029 		}
1030 	}
1031 
1032 	pthread_join(cmd_queue_thread, NULL);
1033 	pthread_join(netlink_thread, NULL);
1034 	pthread_join(monitor_thread, NULL);
1035 	pthread_join(ipa_driver_thread, NULL);
1036 	return IPACM_SUCCESS;
1037 }
1038 
1039 /*===========================================================================
1040 		FUNCTION  ipa_is_ipacm_running
1041 ===========================================================================*/
1042 /*!
1043 @brief
1044   Determine whether there's already an IPACM process running, if so, terminate
1045   the current one
1046 
1047 @return
1048 	None
1049 
1050 @note
1051 
1052 - Dependencies
1053 		- None
1054 
1055 - Side Effects
1056 		- None
1057 */
1058 /*=========================================================================*/
1059 
ipa_is_ipacm_running(void)1060 void ipa_is_ipacm_running(void) {
1061 
1062 	int fd;
1063 	struct flock lock;
1064 	int retval;
1065 
1066 	fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600);
1067 	if ( fd <= 0 )
1068 	{
1069 		IPACMERR("Failed to open %s, error is %d - %s\n",
1070 				 IPACM_PID_FILE, errno, strerror(errno));
1071 		exit(0);
1072 	}
1073 
1074 	/*
1075 	 * Getting an exclusive Write lock on the file, if it fails,
1076 	 * it means that another instance of IPACM is running and it
1077 	 * got the lock before us.
1078 	 */
1079 	memset(&lock, 0, sizeof(lock));
1080 	lock.l_type = F_WRLCK;
1081 	retval = fcntl(fd, F_SETLK, &lock);
1082 
1083 	if (retval != 0)
1084 	{
1085 		retval = fcntl(fd, F_GETLK, &lock);
1086 		if (retval == 0)
1087 		{
1088 			IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n",
1089 					 IPACM_PID_FILE, getpid(), lock.l_pid);
1090 			close(fd);
1091 			exit(0);
1092 		}
1093 	}
1094 	else
1095 	{
1096 		IPACMERR("PID %d is IPACM main process\n", getpid());
1097 	}
1098 
1099 	return;
1100 }
1101 
1102 /*===========================================================================
1103 		FUNCTION  ipa_get_if_index
1104 ===========================================================================*/
1105 /*!
1106 @brief
1107   get ipa interface index by given the interface name
1108 
1109 @return
1110 	IPACM_SUCCESS or IPA_FALUIRE
1111 
1112 @note
1113 
1114 - Dependencies
1115 		- None
1116 
1117 - Side Effects
1118 		- None
1119 */
1120 /*=========================================================================*/
ipa_get_if_index(char * if_name,int * if_index)1121 int ipa_get_if_index
1122 (
1123 	 char *if_name,
1124 	 int *if_index
1125 	 )
1126 {
1127 	int fd;
1128 	struct ifreq ifr;
1129 
1130 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1131 	{
1132 		PERROR("get interface index socket create failed");
1133 		return IPACM_FAILURE;
1134 	}
1135 
1136 	memset(&ifr, 0, sizeof(struct ifreq));
1137 
1138 	(void)strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
1139 
1140 	if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
1141 	{
1142 		IPACMERR("call_ioctl_on_dev: ioctl failed: can't find device %s",if_name);
1143 		*if_index = -1;
1144 		close(fd);
1145 		return IPACM_FAILURE;
1146 	}
1147 
1148 	*if_index = ifr.ifr_ifindex;
1149 	close(fd);
1150 	return IPACM_SUCCESS;
1151 }
1152 
1153 #ifdef FEATURE_IPACM_RESTART
ipa_reset()1154 int ipa_reset()
1155 {
1156 	int fd = -1;
1157 
1158 	if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
1159 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1160 		return IPACM_FAILURE;
1161 	}
1162 
1163 	if (ioctl(fd, IPA_IOC_CLEANUP) < 0) {
1164 		IPACMERR("IOCTL IPA_IOC_CLEANUP call failed: %s \n", strerror(errno));
1165 		close(fd);
1166 		return IPACM_FAILURE;
1167 	}
1168 
1169 	IPACMDBG_H("send IPA_IOC_CLEANUP \n");
1170 	close(fd);
1171 	return IPACM_SUCCESS;
1172 }
1173 #endif
1174 
1175 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
ipa_reset_hw_index_counter()1176 int ipa_reset_hw_index_counter()
1177 {
1178 	int fd = -1;
1179 	struct ipa_ioc_flt_rt_counter_alloc fnr_counters;
1180 	struct ipa_ioc_fnr_index_info fnr_info;
1181 
1182 	if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
1183 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1184 		return IPACM_FAILURE;
1185 	}
1186 
1187 	memset(&fnr_counters, 0, sizeof(fnr_counters));
1188 	fnr_counters.hw_counter.num_counters = 4;
1189 	fnr_counters.hw_counter.allow_less = false;
1190 	fnr_counters.sw_counter.num_counters = 4;
1191 	fnr_counters.sw_counter.allow_less = false;
1192 	IPACMDBG_H("Allocating %d hw counters and %d sw counters\n",
1193 		fnr_counters.hw_counter.num_counters, fnr_counters.sw_counter.num_counters);
1194 
1195 	if (ioctl(fd, IPA_IOC_FNR_COUNTER_ALLOC, &fnr_counters) < 0) {
1196 		IPACMERR("IPA_IOC_FNR_COUNTER_ALLOC call failed: %s \n", strerror(errno));
1197 		close(fd);
1198 		return IPACM_FAILURE;
1199 	}
1200 
1201 	IPACMDBG_H("hw-counter start offset %d, sw-counter start offset %d\n",
1202 		fnr_counters.hw_counter.start_id, fnr_counters.sw_counter.start_id);
1203 	IPACM_Iface::ipacmcfg->hw_fnr_stats_support = true;
1204 	IPACM_Iface::ipacmcfg->hw_counter_offset = fnr_counters.hw_counter.start_id;
1205 	IPACM_Iface::ipacmcfg->sw_counter_offset = fnr_counters.sw_counter.start_id;
1206 
1207 	/* set FNR counter info */
1208 	memset(&fnr_info, 0, sizeof(fnr_info));
1209 	fnr_info.hw_counter_offset = fnr_counters.hw_counter.start_id;
1210 	fnr_info.sw_counter_offset = fnr_counters.sw_counter.start_id;
1211 
1212 	if (ioctl(fd, IPA_IOC_SET_FNR_COUNTER_INFO, &fnr_info) < 0) {
1213 		IPACMERR("IPA_IOC_SET_FNR_COUNTER_INFO call failed: %s \n", strerror(errno));
1214 		close(fd);
1215 		return IPACM_FAILURE;
1216 	}
1217 
1218 	close(fd);
1219 	return IPACM_SUCCESS;
1220 }
1221 #endif
1222