Home | History | Annotate | Download | only in src
      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*/
    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*/
    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 */
    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 				IPACMERR("calling OffloadMng->elrInstance->onLimitReached \n");
    698 				OffloadMng->elrInstance->onLimitReached();
    699 			}
    700 			continue;
    701 		case IPA_SSR_BEFORE_SHUTDOWN:
    702 			IPACMDBG_H("Received IPA_SSR_BEFORE_SHUTDOWN\n");
    703 			OffloadMng = IPACM_OffloadManager::GetInstance();
    704 			if (OffloadMng->elrInstance == NULL) {
    705 				IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
    706 			} else {
    707 				IPACMERR("calling OffloadMng->elrInstance->onOffloadStopped \n");
    708 				OffloadMng->elrInstance->onOffloadStopped(IpaEventRelay::ERROR);
    709 			}
    710 			continue;
    711 		case IPA_SSR_AFTER_POWERUP:
    712 			IPACMDBG_H("Received IPA_SSR_AFTER_POWERUP\n");
    713 			OffloadMng = IPACM_OffloadManager::GetInstance();
    714 			if (OffloadMng->elrInstance == NULL) {
    715 				IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
    716 			} else {
    717 				IPACMERR("calling OffloadMng->elrInstance->onOffloadSupportAvailable \n");
    718 				OffloadMng->elrInstance->onOffloadSupportAvailable();
    719 			}
    720 			continue;
    721 #endif
    722 		default:
    723 			IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
    724 			continue;
    725 
    726 		}
    727 		/* finish command queue */
    728 		IPACMDBG_H("Posting event:%d\n", evt_data.event);
    729 		IPACM_EvtDispatcher::PostEvt(&evt_data);
    730 		/* push new_neighbor with netdev device internally */
    731 		if(new_neigh_data != NULL)
    732 		{
    733 			IPACMDBG_H("Internally post event IPA_NEW_NEIGH_EVENT\n");
    734 			IPACM_EvtDispatcher::PostEvt(&new_neigh_evt);
    735 		}
    736 	}
    737 
    738 	(void)close(fd);
    739 	return NULL;
    740 }
    741 
    742 void IPACM_Sig_Handler(int sig)
    743 {
    744 	ipacm_cmd_q_data evt_data;
    745 
    746 	printf("Received Signal: %d\n", sig);
    747 	memset(&evt_data, 0, sizeof(evt_data));
    748 
    749 	switch(sig)
    750 	{
    751 		case SIGUSR1:
    752 			IPACMDBG_H("Received SW_ROUTING_ENABLE request \n");
    753 			evt_data.event = IPA_SW_ROUTING_ENABLE;
    754 			IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = true;
    755 			break;
    756 
    757 		case SIGUSR2:
    758 			IPACMDBG_H("Received SW_ROUTING_DISABLE request \n");
    759 			evt_data.event = IPA_SW_ROUTING_DISABLE;
    760 			IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = false;
    761 			break;
    762 	}
    763 	/* finish command queue */
    764 	IPACMDBG_H("Posting event:%d\n", evt_data.event);
    765 	IPACM_EvtDispatcher::PostEvt(&evt_data);
    766 	return;
    767 }
    768 
    769 void RegisterForSignals(void)
    770 {
    771 
    772 	signal(SIGUSR1, IPACM_Sig_Handler);
    773 	signal(SIGUSR2, IPACM_Sig_Handler);
    774 }
    775 
    776 
    777 int main(int argc, char **argv)
    778 {
    779 	int ret;
    780 	pthread_t netlink_thread = 0, monitor_thread = 0, ipa_driver_thread = 0;
    781 	pthread_t cmd_queue_thread = 0;
    782 
    783 	/* check if ipacm is already running or not */
    784 	ipa_is_ipacm_running();
    785 
    786 	IPACMDBG_H("In main()\n");
    787 	(void)argc;
    788 	(void)argv;
    789 
    790 	neigh = new IPACM_Neighbor();
    791 	ifacemgr = new IPACM_IfaceManager();
    792 #ifdef FEATURE_IPACM_HAL
    793 	OffloadMng = IPACM_OffloadManager::GetInstance();
    794 	hal = HAL::makeIPAHAL(1, OffloadMng);
    795 	IPACMDBG_H(" START IPACM_OffloadManager and link to android framework\n");
    796 #endif
    797 
    798 #ifdef FEATURE_ETH_BRIDGE_LE
    799 	IPACM_LanToLan* lan2lan = new IPACM_LanToLan();
    800 #endif
    801 
    802 	CtList = new IPACM_ConntrackListener();
    803 
    804 	IPACMDBG_H("Staring IPA main\n");
    805 	IPACMDBG_H("ipa_cmdq_successful\n");
    806 
    807 
    808 	RegisterForSignals();
    809 
    810 	if (IPACM_SUCCESS == cmd_queue_thread)
    811 	{
    812 		ret = pthread_create(&cmd_queue_thread, NULL, MessageQueue::Process, NULL);
    813 		if (IPACM_SUCCESS != ret)
    814 		{
    815 			IPACMERR("unable to command queue thread\n");
    816 			return ret;
    817 		}
    818 		IPACMDBG_H("created command queue thread\n");
    819 		if(pthread_setname_np(cmd_queue_thread, "cmd queue process") != 0)
    820 		{
    821 			IPACMERR("unable to set thread name\n");
    822 		}
    823 	}
    824 
    825 	if (IPACM_SUCCESS == netlink_thread)
    826 	{
    827 		ret = pthread_create(&netlink_thread, NULL, netlink_start, NULL);
    828 		if (IPACM_SUCCESS != ret)
    829 		{
    830 			IPACMERR("unable to create netlink thread\n");
    831 			return ret;
    832 		}
    833 		IPACMDBG_H("created netlink thread\n");
    834 		if(pthread_setname_np(netlink_thread, "netlink socket") != 0)
    835 		{
    836 			IPACMERR("unable to set thread name\n");
    837 		}
    838 	}
    839 
    840 	/* Enable Firewall support only on MDM targets */
    841 #ifndef FEATURE_IPA_ANDROID
    842 	if (IPACM_SUCCESS == monitor_thread)
    843 	{
    844 		ret = pthread_create(&monitor_thread, NULL, firewall_monitor, NULL);
    845 		if (IPACM_SUCCESS != ret)
    846 		{
    847 			IPACMERR("unable to create monitor thread\n");
    848 			return ret;
    849 		}
    850 		IPACMDBG_H("created firewall monitor thread\n");
    851 		if(pthread_setname_np(monitor_thread, "firewall cfg process") != 0)
    852 		{
    853 			IPACMERR("unable to set thread name\n");
    854 		}
    855 	}
    856 #endif
    857 
    858 	if (IPACM_SUCCESS == ipa_driver_thread)
    859 	{
    860 		ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_msg_notifier, NULL);
    861 		if (IPACM_SUCCESS != ret)
    862 		{
    863 			IPACMERR("unable to create ipa_driver_wlan thread\n");
    864 			return ret;
    865 		}
    866 		IPACMDBG_H("created ipa_driver_wlan thread\n");
    867 		if(pthread_setname_np(ipa_driver_thread, "ipa driver ntfy") != 0)
    868 		{
    869 			IPACMERR("unable to set thread name\n");
    870 		}
    871 	}
    872 
    873 	pthread_join(cmd_queue_thread, NULL);
    874 	pthread_join(netlink_thread, NULL);
    875 	pthread_join(monitor_thread, NULL);
    876 	pthread_join(ipa_driver_thread, NULL);
    877 	return IPACM_SUCCESS;
    878 }
    879 
    880 /*===========================================================================
    881 		FUNCTION  ipa_is_ipacm_running
    882 ===========================================================================*/
    883 /*!
    884 @brief
    885   Determine whether there's already an IPACM process running, if so, terminate
    886   the current one
    887 
    888 @return
    889 	None
    890 
    891 @note
    892 
    893 - Dependencies
    894 		- None
    895 
    896 - Side Effects
    897 		- None
    898 */
    899 /*=========================================================================*/
    900 
    901 void ipa_is_ipacm_running(void) {
    902 
    903 	int fd;
    904 	struct flock lock;
    905 	int retval;
    906 
    907 	fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600);
    908 	if ( fd <= 0 )
    909 	{
    910 		IPACMERR("Failed to open %s, error is %d - %s\n",
    911 				 IPACM_PID_FILE, errno, strerror(errno));
    912 		exit(0);
    913 	}
    914 
    915 	/*
    916 	 * Getting an exclusive Write lock on the file, if it fails,
    917 	 * it means that another instance of IPACM is running and it
    918 	 * got the lock before us.
    919 	 */
    920 	memset(&lock, 0, sizeof(lock));
    921 	lock.l_type = F_WRLCK;
    922 	retval = fcntl(fd, F_SETLK, &lock);
    923 
    924 	if (retval != 0)
    925 	{
    926 		retval = fcntl(fd, F_GETLK, &lock);
    927 		if (retval == 0)
    928 		{
    929 			IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n",
    930 					 IPACM_PID_FILE, getpid(), lock.l_pid);
    931 			close(fd);
    932 			exit(0);
    933 		}
    934 	}
    935 	else
    936 	{
    937 		IPACMERR("PID %d is IPACM main process\n", getpid());
    938 	}
    939 
    940 	return;
    941 }
    942 
    943 /*===========================================================================
    944 		FUNCTION  ipa_get_if_index
    945 ===========================================================================*/
    946 /*!
    947 @brief
    948   get ipa interface index by given the interface name
    949 
    950 @return
    951 	IPACM_SUCCESS or IPA_FALUIRE
    952 
    953 @note
    954 
    955 - Dependencies
    956 		- None
    957 
    958 - Side Effects
    959 		- None
    960 */
    961 /*=========================================================================*/
    962 int ipa_get_if_index
    963 (
    964 	 char *if_name,
    965 	 int *if_index
    966 	 )
    967 {
    968 	int fd;
    969 	struct ifreq ifr;
    970 
    971 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    972 	{
    973 		PERROR("get interface index socket create failed");
    974 		return IPACM_FAILURE;
    975 	}
    976 
    977 	memset(&ifr, 0, sizeof(struct ifreq));
    978 
    979 	(void)strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
    980 
    981 	if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
    982 	{
    983 		IPACMERR("call_ioctl_on_dev: ioctl failed: can't find device %s",if_name);
    984 		*if_index = -1;
    985 		close(fd);
    986 		return IPACM_FAILURE;
    987 	}
    988 
    989 	*if_index = ifr.ifr_ifindex;
    990 	close(fd);
    991 	return IPACM_SUCCESS;
    992 }
    993