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