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