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_Wlan.cpp
     32 
     33 @brief
     34 This file implements the WLAN iface functionality.
     35 
     36 @Author
     37 Skylar Chang
     38 
     39 */
     40 
     41 #include <string.h>
     42 #include <unistd.h>
     43 #include <sys/ioctl.h>
     44 #include <IPACM_Wlan.h>
     45 #include <IPACM_Netlink.h>
     46 #include <fcntl.h>
     47 #include <sys/inotify.h>
     48 #include <IPACM_Wan.h>
     49 #include <IPACM_Lan.h>
     50 #include <IPACM_IfaceManager.h>
     51 #include <IPACM_ConntrackListener.h>
     52 
     53 
     54 /* static member to store the number of total wifi clients within all APs*/
     55 int IPACM_Wlan::total_num_wifi_clients = 0;
     56 
     57 int IPACM_Wlan::num_wlan_ap_iface = 0;
     58 
     59 IPACM_Wlan::IPACM_Wlan(int iface_index) : IPACM_Lan(iface_index)
     60 {
     61 #define WLAN_AMPDU_DEFAULT_FILTER_RULES 3
     62 
     63 	wlan_ap_index = IPACM_Wlan::num_wlan_ap_iface;
     64 	if(wlan_ap_index < 0 || wlan_ap_index > 1)
     65 	{
     66 		IPACMERR("Wlan_ap_index is not correct: %d, not creating instance.\n", wlan_ap_index);
     67 		if (tx_prop != NULL)
     68 		{
     69 			free(tx_prop);
     70 		}
     71 		if (rx_prop != NULL)
     72 		{
     73 			free(rx_prop);
     74 		}
     75 		if (iface_query != NULL)
     76 		{
     77 			free(iface_query);
     78 		}
     79 		delete this;
     80 		return;
     81 	}
     82 
     83 	num_wifi_client = 0;
     84 	header_name_count = 0;
     85 	wlan_client = NULL;
     86 	wlan_client_len = 0;
     87 
     88 	if(iface_query != NULL)
     89 	{
     90 		wlan_client_len = (sizeof(ipa_wlan_client)) + (iface_query->num_tx_props * sizeof(wlan_client_rt_hdl));
     91 		wlan_client = (ipa_wlan_client *)calloc(IPA_MAX_NUM_WIFI_CLIENTS, wlan_client_len);
     92 		if (wlan_client == NULL)
     93 		{
     94 			IPACMERR("unable to allocate memory\n");
     95 			return;
     96 		}
     97 		IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props);
     98 	}
     99 	Nat_App = NatApp::GetInstance();
    100 	if (Nat_App == NULL)
    101 	{
    102 		IPACMERR("unable to get Nat App instance \n");
    103 		return;
    104 	}
    105 
    106 	IPACM_Wlan::num_wlan_ap_iface++;
    107 	IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface);
    108 
    109 	m_is_guest_ap = false;
    110 	if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET)
    111 	{
    112 		m_is_guest_ap = true;
    113 	}
    114 	IPACMDBG_H("%s: guest ap enable: %d \n",
    115 		IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, m_is_guest_ap);
    116 
    117 #ifdef FEATURE_IPA_ANDROID
    118 	/* set the IPA-client pipe enum */
    119 	if(ipa_if_cate == WLAN_IF)
    120 	{
    121 #ifdef FEATURE_IPACM_HAL
    122 		handle_tethering_client(false, IPACM_CLIENT_MAX);
    123 #else
    124 		handle_tethering_client(false, IPACM_CLIENT_WLAN);
    125 #endif
    126 	}
    127 #endif
    128 	return;
    129 }
    130 
    131 
    132 IPACM_Wlan::~IPACM_Wlan()
    133 {
    134 	IPACM_EvtDispatcher::deregistr(this);
    135 	IPACM_IfaceManager::deregistr(this);
    136 	return;
    137 }
    138 
    139 void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
    140 {
    141 	if(is_active == false && event != IPA_LAN_DELETE_SELF)
    142 	{
    143 		IPACMDBG_H("The interface is no longer active, return.\n");
    144 		return;
    145 	}
    146 
    147 	int ipa_interface_index;
    148 	int wlan_index;
    149 	ipacm_ext_prop* ext_prop;
    150 	ipacm_event_iface_up_tehter* data_wan_tether;
    151 
    152 	switch (event)
    153 	{
    154 
    155 	case IPA_WLAN_LINK_DOWN_EVENT:
    156 		{
    157 			ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
    158 			ipa_interface_index = iface_ipa_index_query(data->if_index);
    159 			if (ipa_interface_index == ipa_if_num)
    160 			{
    161 				IPACMDBG_H("Received IPA_WLAN_LINK_DOWN_EVENT\n");
    162 				handle_down_evt();
    163 				/* reset the AP-iface category to unknown */
    164 				IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat = UNKNOWN_IF;
    165 				IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
    166 				IPACM_Wlan::total_num_wifi_clients = (IPACM_Wlan::total_num_wifi_clients) - \
    167                                                                      (num_wifi_client);
    168 				return;
    169 			}
    170 		}
    171 		break;
    172 
    173 	case IPA_PRIVATE_SUBNET_CHANGE_EVENT:
    174 		{
    175 			ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
    176 			/* internel event: data->if_index is ipa_if_index */
    177 			if (data->if_index == ipa_if_num)
    178 			{
    179 				IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n");
    180 				return;
    181 			}
    182 			else
    183 			{
    184 				IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n");
    185 #ifdef FEATURE_IPA_ANDROID
    186 				handle_private_subnet_android(IPA_IP_v4);
    187 #endif
    188 				IPACMDBG_H(" delete old private subnet rules, use new sets \n");
    189 				return;
    190 			}
    191 		}
    192 		break;
    193 
    194 	case IPA_LAN_DELETE_SELF:
    195 	{
    196 		ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
    197 		if(data->if_index == ipa_if_num)
    198 		{
    199 			IPACM_Wlan::num_wlan_ap_iface--;
    200 			IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface);
    201 
    202 			IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n");
    203 			IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
    204 			delete this;
    205 		}
    206 		break;
    207 	}
    208 
    209 	case IPA_ADDR_ADD_EVENT:
    210 		{
    211 			ipacm_event_data_addr *data = (ipacm_event_data_addr *)param;
    212 			ipa_interface_index = iface_ipa_index_query(data->if_index);
    213 
    214 			if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) ||
    215 					 (data->iptype == IPA_IP_v6 &&
    216 						data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 &&
    217 					  data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) )
    218 			{
    219 				IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n");
    220 				return;
    221 			}
    222 
    223 			if (ipa_interface_index == ipa_if_num)
    224 			{
    225 				/* check v4 not setup before, v6 can have 2 iface ip */
    226 				if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX))
    227 				    || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
    228 				{
    229 					IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
    230 					/* Post event to NAT */
    231 					if (data->iptype == IPA_IP_v4)
    232 					{
    233 						ipacm_cmd_q_data evt_data;
    234 						ipacm_event_iface_up *info;
    235 
    236 						info = (ipacm_event_iface_up *)
    237 							 malloc(sizeof(ipacm_event_iface_up));
    238 						if (info == NULL)
    239 						{
    240 							IPACMERR("Unable to allocate memory\n");
    241 							return;
    242 						}
    243 
    244 						memcpy(info->ifname, dev_name, IF_NAME_LEN);
    245 						info->ipv4_addr = data->ipv4_addr;
    246 						info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask;
    247 
    248 						evt_data.event = IPA_HANDLE_WLAN_UP;
    249 						evt_data.evt_data = (void *)info;
    250 
    251 						/* Insert IPA_HANDLE_WLAN_UP to command queue */
    252 						IPACMDBG_H("posting IPA_HANDLE_WLAN_UP for IPv4 with below information\n");
    253 						IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n",
    254 										 info->ipv4_addr, info->addr_mask);
    255 						IPACM_EvtDispatcher::PostEvt(&evt_data);
    256 					}
    257 
    258 					if(handle_addr_evt(data) == IPACM_FAILURE)
    259 					{
    260 						return;
    261 					}
    262 
    263 #ifdef FEATURE_IPA_ANDROID
    264 					add_dummy_private_subnet_flt_rule(data->iptype);
    265 					handle_private_subnet_android(data->iptype);
    266 #else
    267 					handle_private_subnet(data->iptype);
    268 #endif
    269 
    270 #ifndef FEATURE_IPACM_HAL
    271 					if (IPACM_Wan::isWanUP(ipa_if_num))
    272 					{
    273 						if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
    274 						{
    275 							if(IPACM_Wan::backhaul_is_sta_mode == false)
    276 							{
    277 								ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
    278 								IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4,
    279 												IPACM_Wan::getXlat_Mux_Id());
    280 							}
    281 							else
    282 							{
    283 								IPACM_Lan::handle_wan_up(IPA_IP_v4);
    284 							}
    285 						}
    286 						IPACMDBG_H("Finished checking wan_up\n");
    287 					} else {
    288 						IPACMDBG_H("Wan_V4 haven't up yet \n");
    289 					}
    290 
    291 					if(IPACM_Wan::isWanUP_V6(ipa_if_num))
    292 					{
    293 						if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
    294 						{
    295 							memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix));
    296 							install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
    297 
    298 							if(IPACM_Wan::backhaul_is_sta_mode == false)
    299 							{
    300 								ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
    301 								IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
    302 							}
    303 							else
    304 							{
    305 								IPACM_Lan::handle_wan_up(IPA_IP_v6);
    306 							}
    307 						}
    308 						IPACMDBG_H("Finished checking wan_up_v6\n");
    309 					} else {
    310 						IPACMDBG_H("Wan_V6 haven't up yet \n");
    311 					}
    312 #endif
    313 					/* checking if SW-RT_enable */
    314 					if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true)
    315 					{
    316 						/* handle software routing enable event*/
    317 						IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
    318 						handle_software_routing_enable();
    319 					}
    320 				}
    321 			}
    322 		}
    323 		break;
    324 #ifdef FEATURE_IPA_ANDROID
    325 	case IPA_HANDLE_WAN_UP_TETHER:
    326 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n");
    327 
    328 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
    329 		if(data_wan_tether == NULL)
    330 		{
    331 			IPACMERR("No event data is found.\n");
    332 			return;
    333 		}
    334 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
    335 					data_wan_tether->if_index_tether,
    336 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
    337 #ifndef FEATURE_IPACM_HAL
    338 		if (data_wan_tether->if_index_tether != ipa_if_num)
    339 		{
    340 			IPACMERR("IPA_HANDLE_WAN_UP_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
    341 			return;
    342 		}
    343 #endif
    344 		if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
    345 		{
    346 #ifdef FEATURE_IPACM_HAL
    347 			if(is_upstream_set[IPA_IP_v4] == false)
    348 			{
    349 				IPACMDBG_H("Add upstream for IPv4.\n");
    350 				is_upstream_set[IPA_IP_v4] = true;
    351 				if(is_downstream_set[IPA_IP_v4] == true)
    352 				{
    353 					IPACMDBG_H("Downstream was set before, adding UL rules.\n");
    354 					if(data_wan_tether->is_sta == false)
    355 					{
    356 						ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
    357 						handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
    358 					} else {
    359 						handle_wan_up(IPA_IP_v4);
    360 					}
    361 				}
    362 			}
    363 #else
    364 			if(data_wan_tether->is_sta == false)
    365 			{
    366 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
    367 				handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
    368 			} else {
    369 				handle_wan_up(IPA_IP_v4);
    370 			}
    371 #endif
    372 		}
    373 		break;
    374 
    375 	case IPA_HANDLE_WAN_UP_V6_TETHER:
    376 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n");
    377 
    378 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
    379 		if(data_wan_tether == NULL)
    380 		{
    381 			IPACMERR("No event data is found.\n");
    382 			return;
    383 		}
    384 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
    385 					data_wan_tether->if_index_tether,
    386 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
    387 #ifndef FEATURE_IPACM_HAL
    388 		if (data_wan_tether->if_index_tether != ipa_if_num)
    389 		{
    390 			IPACMERR("IPA_HANDLE_WAN_UP_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
    391 			return;
    392 		}
    393 #endif
    394 		if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
    395 		{
    396 #ifdef FEATURE_IPACM_HAL
    397 			if(is_upstream_set[IPA_IP_v6] == false)
    398 			{
    399 				IPACMDBG_H("Add upstream for IPv6.\n");
    400 				is_upstream_set[IPA_IP_v6] = true;
    401 
    402 				if(is_downstream_set[IPA_IP_v6] == true)
    403 				{
    404 					IPACMDBG_H("Downstream was set before, adding UL rules.\n");
    405 					memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix));
    406 					install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
    407 					if(data_wan_tether->is_sta == false)
    408 					{
    409 						ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
    410 						handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
    411 					}
    412 					else
    413 					{
    414 						handle_wan_up(IPA_IP_v6);
    415 					}
    416 				}
    417 			}
    418 #else
    419 			if(data_wan_tether->is_sta == false)
    420 			{
    421 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
    422 				handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
    423 			}
    424 			else
    425 			{
    426 				handle_wan_up(IPA_IP_v6);
    427 			}
    428 #endif
    429 		}
    430 		break;
    431 
    432 	case IPA_HANDLE_WAN_DOWN_TETHER:
    433 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n");
    434 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
    435 		if(data_wan_tether == NULL)
    436 		{
    437 			IPACMERR("No event data is found.\n");
    438 			return;
    439 		}
    440 		if(rx_prop == NULL)
    441 		{
    442 			IPACMERR("No rx prop.\n");
    443 			return;
    444 		}
    445 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
    446 					data_wan_tether->if_index_tether,
    447 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
    448 #ifndef FEATURE_IPACM_HAL
    449 		if (data_wan_tether->if_index_tether != ipa_if_num)
    450 		{
    451 			IPACMERR("IPA_HANDLE_WAN_DOWN_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
    452 			return;
    453 		}
    454 #endif
    455 		if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
    456 		{
    457 #ifdef FEATURE_IPACM_HAL
    458 			if(is_upstream_set[IPA_IP_v4] == true)
    459 			{
    460 				IPACMDBG_H("Del upstream for IPv4.\n");
    461 				is_upstream_set[IPA_IP_v4] = false;
    462 				if(is_downstream_set[IPA_IP_v4] == true)
    463 				{
    464 					IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
    465 					handle_wan_down(data_wan_tether->is_sta);
    466 				}
    467 			}
    468 #else
    469 			handle_wan_down(data_wan_tether->is_sta);
    470 #endif
    471 		}
    472 		break;
    473 
    474 	case IPA_HANDLE_WAN_DOWN_V6_TETHER:
    475 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n");
    476 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
    477 		if(data_wan_tether == NULL)
    478 		{
    479 			IPACMERR("No event data is found.\n");
    480 			return;
    481 		}
    482 		if(rx_prop == NULL)
    483 		{
    484 			IPACMERR("No rx prop.\n");
    485 			return;
    486 		}
    487 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
    488 					data_wan_tether->if_index_tether,
    489 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
    490 #ifndef FEATURE_IPACM_HAL
    491 		if (data_wan_tether->if_index_tether != ipa_if_num)
    492 		{
    493 			IPACMERR("IPA_HANDLE_WAN_DOWN_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
    494 			return;
    495 		}
    496 #endif
    497 		if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
    498 		{
    499 #ifdef FEATURE_IPACM_HAL
    500 			if(is_upstream_set[IPA_IP_v6] == true)
    501 			{
    502 				IPACMDBG_H("Del upstream for IPv6.\n");
    503 				is_upstream_set[IPA_IP_v6] = false;
    504 				if(is_downstream_set[IPA_IP_v6] == true)
    505 				{
    506 					IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
    507 					/* reset usb-client ipv6 rt-rules */
    508 					handle_wlan_client_reset_rt(IPA_IP_v6);
    509 					handle_wan_down_v6(data_wan_tether->is_sta);
    510 				}
    511 			}
    512 #else
    513 			/* reset usb-client ipv6 rt-rules */
    514 			handle_wlan_client_reset_rt(IPA_IP_v6);
    515 			handle_wan_down_v6(data_wan_tether->is_sta);
    516 #endif
    517 		}
    518 		break;
    519 
    520 	case IPA_DOWNSTREAM_ADD:
    521 	{
    522 		ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
    523 		ipa_interface_index = iface_ipa_index_query(data->if_index);
    524 		if(ipa_interface_index == ipa_if_num)
    525 		{
    526 			IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
    527 			if(is_downstream_set[data->prefix.iptype] == false)
    528 			{
    529 				IPACMDBG_H("Add downstream for IP iptype %d.\n", data->prefix.iptype);
    530 				is_downstream_set[data->prefix.iptype] = true;
    531 				memcpy(&prefix[data->prefix.iptype], &data->prefix,
    532 					sizeof(prefix[data->prefix.iptype]));
    533 
    534 				if(is_upstream_set[data->prefix.iptype] == true)
    535 				{
    536 					IPACMDBG_H("Upstream was set before, adding modem UL rules.\n");
    537 					if(ip_type == IPA_IP_MAX || ip_type == data->prefix.iptype)
    538 					{
    539 						if (data->prefix.iptype == IPA_IP_v6) /* ipv6 only */
    540 						{
    541 							/* Only offload clients has same prefix as Andorid gave */
    542 							ipv6_prefix[0] = data->prefix.v6Addr[0];
    543 							ipv6_prefix[1] = data->prefix.v6Addr[1];
    544 							IPACMDBG_H("ipv6_prefix0x%x:%x\n", ipv6_prefix[0], ipv6_prefix[1]);
    545 							install_ipv6_prefix_flt_rule(ipv6_prefix);
    546 						}
    547 
    548 						if (IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
    549 						{
    550 							ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
    551 							handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
    552 						} else {
    553 							handle_wan_up(data->prefix.iptype); /* STA */
    554 						}
    555 					}
    556 				}
    557 			}
    558 		}
    559 		break;
    560 	}
    561 
    562 	case IPA_DOWNSTREAM_DEL:
    563 	{
    564 		ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
    565 		ipa_interface_index = iface_ipa_index_query(data->if_index);
    566 		if(ipa_interface_index == ipa_if_num)
    567 		{
    568 			IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
    569 			if(is_downstream_set[data->prefix.iptype] == true)
    570 			{
    571 				IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
    572 				is_downstream_set[data->prefix.iptype] = false;
    573 
    574 				if(is_upstream_set[data->prefix.iptype] == true)
    575 				{
    576 					IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
    577 					if (data->prefix.iptype == IPA_IP_v4)
    578 					{
    579 						handle_wan_down(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
    580 					} else {
    581 						handle_wlan_client_reset_rt(IPA_IP_v6);
    582 						handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
    583 					}
    584 				}
    585 			}
    586 		}
    587 		break;
    588 	}
    589 #else
    590 	case IPA_HANDLE_WAN_UP:
    591 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
    592 
    593 		ipacm_event_iface_up* data_wan = (ipacm_event_iface_up*)param;
    594 		if(data_wan == NULL)
    595 		{
    596 			IPACMERR("No event data is found.\n");
    597 			return;
    598 		}
    599 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
    600 		if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
    601 		{
    602 			if(data_wan->is_sta == false)
    603 			{
    604 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
    605 				IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
    606 			}
    607 			else
    608 			{
    609 				IPACM_Lan::handle_wan_up(IPA_IP_v4);
    610 			}
    611 		}
    612 		break;
    613 
    614 	case IPA_HANDLE_WAN_UP_V6:
    615 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6 event\n");
    616 
    617 		data_wan = (ipacm_event_iface_up*)param;
    618 		if(data_wan == NULL)
    619 		{
    620 			IPACMERR("No event data is found.\n");
    621 			return;
    622 		}
    623 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
    624 		if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
    625 		{
    626 			memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix));
    627 			install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
    628 
    629 			if(data_wan->is_sta == false)
    630 			{
    631 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
    632 				IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
    633 			}
    634 			else
    635 			{
    636 				IPACM_Lan::handle_wan_up(IPA_IP_v6);
    637 			}
    638 		}
    639 		break;
    640 
    641 	case IPA_HANDLE_WAN_DOWN:
    642 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n");
    643 		data_wan = (ipacm_event_iface_up*)param;
    644 		if(data_wan == NULL)
    645 		{
    646 			IPACMERR("No event data is found.\n");
    647 			return;
    648 		}
    649 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
    650 		if (rx_prop != NULL)
    651 		{
    652 			if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
    653 			{
    654 				handle_wan_down(data_wan->is_sta);
    655 			}
    656 		}
    657 		break;
    658 
    659 	case IPA_HANDLE_WAN_DOWN_V6:
    660 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6 event\n");
    661 		data_wan = (ipacm_event_iface_up*)param;
    662 		if(data_wan == NULL)
    663 		{
    664 			IPACMERR("No event data is found.\n");
    665 			return;
    666 		}
    667 		/* clean up v6 RT rules*/
    668 		IPACMDBG_H("Received IPA_WAN_V6_DOWN in WLAN-instance and need clean up client IPv6 address \n");
    669 		/* reset wifi-client ipv6 rt-rules */
    670 		handle_wlan_client_reset_rt(IPA_IP_v6);
    671 		IPACMDBG_H("Backhaul is sta mode ? %d\n", data_wan->is_sta);
    672 		if (rx_prop != NULL)
    673 		{
    674 			if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
    675 			{
    676 				handle_wan_down_v6(data_wan->is_sta);
    677 			}
    678 		}
    679 		break;
    680 #endif
    681 
    682 	case IPA_WLAN_CLIENT_ADD_EVENT_EX:
    683 		{
    684 			ipacm_event_data_wlan_ex *data = (ipacm_event_data_wlan_ex *)param;
    685 			ipa_interface_index = iface_ipa_index_query(data->if_index);
    686 			if (ipa_interface_index == ipa_if_num)
    687 			{
    688 				int i;
    689 				for(i=0; i<data->num_of_attribs; i++)
    690 				{
    691 					if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
    692 					{
    693 						eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->attribs[i].u.mac_addr);
    694 						break;
    695 					}
    696 				}
    697 				IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n");
    698 				handle_wlan_client_init_ex(data);
    699 			}
    700 		}
    701 		break;
    702 
    703 	case IPA_WLAN_CLIENT_DEL_EVENT:
    704 		{
    705 			ipacm_event_data_mac *data = (ipacm_event_data_mac *)param;
    706 			ipa_interface_index = iface_ipa_index_query(data->if_index);
    707 			if (ipa_interface_index == ipa_if_num)
    708 			{
    709 				IPACMDBG_H("Received IPA_WLAN_CLIENT_DEL_EVENT\n");
    710 				eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_DEL, IPA_IP_MAX, data->mac_addr);
    711 				handle_wlan_client_down_evt(data->mac_addr);
    712 			}
    713 		}
    714 		break;
    715 
    716 	case IPA_WLAN_CLIENT_POWER_SAVE_EVENT:
    717 		{
    718 			ipacm_event_data_mac *data = (ipacm_event_data_mac *)param;
    719 			ipa_interface_index = iface_ipa_index_query(data->if_index);
    720 			if (ipa_interface_index == ipa_if_num)
    721 			{
    722 				IPACMDBG_H("Received IPA_WLAN_CLIENT_POWER_SAVE_EVENT\n");
    723 				handle_wlan_client_pwrsave(data->mac_addr);
    724 			}
    725 		}
    726 		break;
    727 
    728 	case IPA_WLAN_CLIENT_RECOVER_EVENT:
    729 		{
    730 			ipacm_event_data_mac *data = (ipacm_event_data_mac *)param;
    731 			ipa_interface_index = iface_ipa_index_query(data->if_index);
    732 			if (ipa_interface_index == ipa_if_num)
    733 			{
    734 				IPACMDBG_H("Received IPA_WLAN_CLIENT_RECOVER_EVENT\n");
    735 
    736 				wlan_index = get_wlan_client_index(data->mac_addr);
    737 				if ((wlan_index != IPACM_INVALID_INDEX) &&
    738 						(get_client_memptr(wlan_client, wlan_index)->power_save_set == true))
    739 				{
    740 
    741 					IPACMDBG_H("change wlan client out of  power safe mode \n");
    742 					get_client_memptr(wlan_client, wlan_index)->power_save_set = false;
    743 
    744 					/* First add route rules and then nat rules */
    745 					if(get_client_memptr(wlan_client, wlan_index)->ipv4_set == true) /* for ipv4 */
    746 					{
    747 						     IPACMDBG_H("recover client index(%d):ipv4 address: 0x%x\n",
    748 										 wlan_index,
    749 										 get_client_memptr(wlan_client, wlan_index)->v4_addr);
    750 
    751 						IPACMDBG_H("Adding Route Rules\n");
    752 						handle_wlan_client_route_rule(data->mac_addr, IPA_IP_v4);
    753 						IPACMDBG_H("Adding Nat Rules\n");
    754 						Nat_App->ResetPwrSaveIf(get_client_memptr(wlan_client, wlan_index)->v4_addr);
    755 					}
    756 
    757 					if(get_client_memptr(wlan_client, wlan_index)->ipv6_set != 0) /* for ipv6 */
    758 					{
    759 						handle_wlan_client_route_rule(data->mac_addr, IPA_IP_v6);
    760 					}
    761 				}
    762 			}
    763 		}
    764 		break;
    765 
    766 	case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
    767 		{
    768 			ipacm_event_data_all *data = (ipacm_event_data_all *)param;
    769 			ipa_interface_index = iface_ipa_index_query(data->if_index);
    770 			if (ipa_interface_index == ipa_if_num)
    771 			{
    772 				IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT\n");
    773 				if (handle_wlan_client_ipaddr(data) == IPACM_FAILURE)
    774 				{
    775 					return;
    776 				}
    777 
    778 				handle_wlan_client_route_rule(data->mac_addr, data->iptype);
    779 				if (data->iptype == IPA_IP_v4)
    780 				{
    781 					/* Add NAT rules after ipv4 RT rules are set */
    782 					CtList->HandleNeighIpAddrAddEvt(data);
    783 					//Nat_App->ResetPwrSaveIf(data->ipv4_addr);
    784 				}
    785 			}
    786 		}
    787 		break;
    788 
    789 		/* handle software routing enable event, iface will update softwarerouting_act to true*/
    790 	case IPA_SW_ROUTING_ENABLE:
    791 		IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n");
    792 		IPACM_Iface::handle_software_routing_enable();
    793 		break;
    794 
    795 		/* handle software routing disable event, iface will update softwarerouting_act to false*/
    796 	case IPA_SW_ROUTING_DISABLE:
    797 		IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n");
    798 		IPACM_Iface::handle_software_routing_disable();
    799 		break;
    800 
    801 	case IPA_WLAN_SWITCH_TO_SCC:
    802 		IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n");
    803 		if(ip_type == IPA_IP_MAX)
    804 		{
    805 			handle_SCC_MCC_switch(IPA_IP_v4);
    806 			handle_SCC_MCC_switch(IPA_IP_v6);
    807 		}
    808 		else
    809 		{
    810 			handle_SCC_MCC_switch(ip_type);
    811 		}
    812 		eth_bridge_post_event(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, IPA_IP_MAX, NULL);
    813 		break;
    814 
    815 	case IPA_WLAN_SWITCH_TO_MCC:
    816 		IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n");
    817 		if(ip_type == IPA_IP_MAX)
    818 		{
    819 			handle_SCC_MCC_switch(IPA_IP_v4);
    820 			handle_SCC_MCC_switch(IPA_IP_v6);
    821 		}
    822 		else
    823 		{
    824 			handle_SCC_MCC_switch(ip_type);
    825 		}
    826 		eth_bridge_post_event(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, IPA_IP_MAX, NULL);
    827 		break;
    828 
    829 	case IPA_CRADLE_WAN_MODE_SWITCH:
    830 	{
    831 		IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n");
    832 		ipacm_event_cradle_wan_mode* wan_mode = (ipacm_event_cradle_wan_mode*)param;
    833 		if(wan_mode == NULL)
    834 		{
    835 			IPACMERR("Event data is empty.\n");
    836 			return;
    837 		}
    838 
    839 		if(wan_mode->cradle_wan_mode == BRIDGE)
    840 		{
    841 			handle_cradle_wan_mode_switch(true);
    842 		}
    843 		else
    844 		{
    845 			handle_cradle_wan_mode_switch(false);
    846 		}
    847 	}
    848 	break;
    849 	case IPA_CFG_CHANGE_EVENT:
    850 	{
    851 		IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT event for %s with new wlan-mode: %s old wlan-mode: %s\n",
    852 				IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name,
    853 				(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == 0) ? "full" : "internet",
    854 				(m_is_guest_ap == true) ? "internet" : "full");
    855 		/* Add Natting iface to IPACM_Config if there is  Rx/Tx property */
    856 		if (rx_prop != NULL || tx_prop != NULL)
    857 		{
    858 			IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
    859 			IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name);
    860 		}
    861 
    862 		if (m_is_guest_ap == true && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == FULL))
    863 		{
    864 			m_is_guest_ap = false;
    865 			IPACMDBG_H("wlan mode is switched to full access mode. \n");
    866 			eth_bridge_handle_wlan_mode_switch();
    867 		}
    868 		else if (m_is_guest_ap == false && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET))
    869 		{
    870 			m_is_guest_ap = true;
    871 			IPACMDBG_H("wlan mode is switched to internet only access mode. \n");
    872 			eth_bridge_handle_wlan_mode_switch();
    873 		}
    874 		else
    875 		{
    876 			IPACMDBG_H("No change in %s access mode. \n",
    877 					IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
    878 		}
    879 	}
    880 	break;
    881 	case IPA_TETHERING_STATS_UPDATE_EVENT:
    882 	{
    883 		IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
    884 		if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
    885 		{
    886 			if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
    887 			{
    888 				ipa_get_data_stats_resp_msg_v01 *data = (ipa_get_data_stats_resp_msg_v01 *)param;
    889 				if (data->ipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01)
    890 				{
    891 					IPACMERR("not valid pipe stats\n");
    892 					return;
    893 				}
    894 				handle_tethering_stats_event(data);
    895 			};
    896 		}
    897 	}
    898 	break;
    899 	default:
    900 		break;
    901 	}
    902 	return;
    903 }
    904 
    905 /* handle wifi client initial,copy all partial headers (tx property) */
    906 int IPACM_Wlan::handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data)
    907 {
    908 
    909 #define WLAN_IFACE_INDEX_LEN 2
    910 
    911 	int res = IPACM_SUCCESS, len = 0, i, evt_size;
    912 	char index[WLAN_IFACE_INDEX_LEN];
    913 	struct ipa_ioc_copy_hdr sCopyHeader;
    914 	struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
    915         uint32_t cnt;
    916 
    917 	/* start of adding header */
    918 	IPACMDBG_H("Wifi client number for this iface: %d & total number of wlan clients: %d\n",
    919                  num_wifi_client,IPACM_Wlan::total_num_wifi_clients);
    920 
    921 	if ((num_wifi_client >= IPA_MAX_NUM_WIFI_CLIENTS) ||
    922 			(IPACM_Wlan::total_num_wifi_clients >= IPA_MAX_NUM_WIFI_CLIENTS))
    923 	{
    924 		IPACMERR("Reached maximum number of wlan clients\n");
    925 		return IPACM_FAILURE;
    926 	}
    927 
    928 	IPACMDBG_H("Wifi client number: %d\n", num_wifi_client);
    929 
    930 	/* add header to IPA */
    931 	if(tx_prop != NULL)
    932 	{
    933 		len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
    934 		pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
    935 		if (pHeaderDescriptor == NULL)
    936 		{
    937 			IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
    938 			return IPACM_FAILURE;
    939 		}
    940 
    941 		evt_size = sizeof(ipacm_event_data_wlan_ex) + data->num_of_attribs * sizeof(struct ipa_wlan_hdr_attrib_val);
    942 		get_client_memptr(wlan_client, num_wifi_client)->p_hdr_info = (ipacm_event_data_wlan_ex*)malloc(evt_size);
    943 		memcpy(get_client_memptr(wlan_client, num_wifi_client)->p_hdr_info, data, evt_size);
    944 
    945 		/* copy partial header for v4*/
    946 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
    947 		{
    948 			if(tx_prop->tx[cnt].ip==IPA_IP_v4)
    949 			{
    950 				IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt);
    951 				memset(&sCopyHeader, 0, sizeof(sCopyHeader));
    952 				memcpy(sCopyHeader.name,
    953 							 tx_prop->tx[cnt].hdr_name,
    954 							 sizeof(sCopyHeader.name));
    955 
    956 				IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
    957 				if (m_header.CopyHeader(&sCopyHeader) == false)
    958 				{
    959 					PERROR("ioctl copy header failed");
    960 					res = IPACM_FAILURE;
    961 					goto fail;
    962 				}
    963 
    964 				IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
    965 				if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
    966 				{
    967 					IPACMERR("header oversize\n");
    968 					res = IPACM_FAILURE;
    969 					goto fail;
    970 				}
    971 				else
    972 				{
    973 					memcpy(pHeaderDescriptor->hdr[0].hdr,
    974 								 sCopyHeader.hdr,
    975 								 sCopyHeader.hdr_len);
    976 				}
    977 
    978 				for(i = 0; i < data->num_of_attribs; i++)
    979 				{
    980 					if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
    981 					{
    982 						memcpy(get_client_memptr(wlan_client, num_wifi_client)->mac,
    983 								data->attribs[i].u.mac_addr,
    984 								sizeof(get_client_memptr(wlan_client, num_wifi_client)->mac));
    985 
    986 						/* copy client mac_addr to partial header */
    987 						memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
    988 									 get_client_memptr(wlan_client, num_wifi_client)->mac,
    989 									 IPA_MAC_ADDR_SIZE);
    990 						/* replace src mac to bridge mac_addr if any  */
    991 						if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
    992 						{
    993 							memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset+IPA_MAC_ADDR_SIZE],
    994 									 IPACM_Iface::ipacmcfg->bridge_mac,
    995 									 IPA_MAC_ADDR_SIZE);
    996 							IPACMDBG_H("device is in bridge mode \n");
    997 						}
    998 
    999 					}
   1000 					else if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
   1001 					{
   1002 						/* copy client id to header */
   1003 						memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
   1004 									&data->attribs[i].u.sta_id, sizeof(data->attribs[i].u.sta_id));
   1005 					}
   1006 					else
   1007 					{
   1008 						IPACMDBG_H("The attribute type is not expected!\n");
   1009 					}
   1010 				}
   1011 
   1012 				pHeaderDescriptor->commit = true;
   1013 				pHeaderDescriptor->num_hdrs = 1;
   1014 
   1015 				memset(pHeaderDescriptor->hdr[0].name, 0,
   1016 							 sizeof(pHeaderDescriptor->hdr[0].name));
   1017 
   1018 				snprintf(index,sizeof(index), "%d", ipa_if_num);
   1019 				strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
   1020 				pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
   1021 
   1022 				if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WLAN_PARTIAL_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
   1023 				{
   1024 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
   1025 					res = IPACM_FAILURE;
   1026 					goto fail;
   1027 				}
   1028 				snprintf(index,sizeof(index), "%d", header_name_count);
   1029 				if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
   1030 				{
   1031 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
   1032 					res = IPACM_FAILURE;
   1033 					goto fail;
   1034 				}
   1035 
   1036 
   1037 				pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
   1038 				pHeaderDescriptor->hdr[0].hdr_hdl = -1;
   1039 				pHeaderDescriptor->hdr[0].is_partial = 0;
   1040 				pHeaderDescriptor->hdr[0].status = -1;
   1041 
   1042 				if (m_header.AddHeader(pHeaderDescriptor) == false ||
   1043 						pHeaderDescriptor->hdr[0].status != 0)
   1044 				{
   1045 					IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
   1046 					res = IPACM_FAILURE;
   1047 					goto fail;
   1048 				}
   1049 
   1050 				get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
   1051 				IPACMDBG_H("client(%d) v4 full header name:%s header handle:(0x%x)\n",
   1052 								 num_wifi_client,
   1053 								 pHeaderDescriptor->hdr[0].name,
   1054 								 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v4);
   1055 				get_client_memptr(wlan_client, num_wifi_client)->ipv4_header_set=true;
   1056 				break;
   1057 			}
   1058 		}
   1059 
   1060 		/* copy partial header for v6*/
   1061 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
   1062 		{
   1063 			if(tx_prop->tx[cnt].ip==IPA_IP_v6)
   1064 			{
   1065 				IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt);
   1066 				memset(&sCopyHeader, 0, sizeof(sCopyHeader));
   1067 				memcpy(sCopyHeader.name,
   1068 							 tx_prop->tx[cnt].hdr_name,
   1069 							 sizeof(sCopyHeader.name));
   1070 
   1071 				IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
   1072 				if (m_header.CopyHeader(&sCopyHeader) == false)
   1073 				{
   1074 					PERROR("ioctl copy header failed");
   1075 					res = IPACM_FAILURE;
   1076 					goto fail;
   1077 				}
   1078 
   1079 				IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
   1080 				if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
   1081 				{
   1082 					IPACMERR("header oversize\n");
   1083 					res = IPACM_FAILURE;
   1084 					goto fail;
   1085 				}
   1086 				else
   1087 				{
   1088 					memcpy(pHeaderDescriptor->hdr[0].hdr,
   1089 								 sCopyHeader.hdr,
   1090 								 sCopyHeader.hdr_len);
   1091 				}
   1092 
   1093 				for(i = 0; i < data->num_of_attribs; i++)
   1094 				{
   1095 					if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
   1096 					{
   1097 						memcpy(get_client_memptr(wlan_client, num_wifi_client)->mac,
   1098 								data->attribs[i].u.mac_addr,
   1099 								sizeof(get_client_memptr(wlan_client, num_wifi_client)->mac));
   1100 
   1101 						/* copy client mac_addr to partial header */
   1102 						memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
   1103 								get_client_memptr(wlan_client, num_wifi_client)->mac,
   1104 								IPA_MAC_ADDR_SIZE);
   1105 
   1106 						/* replace src mac to bridge mac_addr if any  */
   1107 						if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
   1108 						{
   1109 							memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset+IPA_MAC_ADDR_SIZE],
   1110 									 IPACM_Iface::ipacmcfg->bridge_mac,
   1111 									 IPA_MAC_ADDR_SIZE);
   1112 							IPACMDBG_H("device is in bridge mode \n");
   1113 						}
   1114 					}
   1115 					else if (data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
   1116 					{
   1117 						/* copy client id to header */
   1118 						memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
   1119 								&data->attribs[i].u.sta_id, sizeof(data->attribs[i].u.sta_id));
   1120 					}
   1121 					else
   1122 					{
   1123 						IPACMDBG_H("The attribute type is not expected!\n");
   1124 					}
   1125 				}
   1126 
   1127 				pHeaderDescriptor->commit = true;
   1128 				pHeaderDescriptor->num_hdrs = 1;
   1129 
   1130 				memset(pHeaderDescriptor->hdr[0].name, 0,
   1131 							 sizeof(pHeaderDescriptor->hdr[0].name));
   1132 
   1133 				snprintf(index,sizeof(index), "%d", ipa_if_num);
   1134 				strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
   1135 				pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
   1136 				if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WLAN_PARTIAL_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
   1137 				{
   1138 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
   1139 					res = IPACM_FAILURE;
   1140 					goto fail;
   1141 				}
   1142 
   1143 				snprintf(index,sizeof(index), "%d", header_name_count);
   1144 				if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
   1145 				{
   1146 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
   1147 					res = IPACM_FAILURE;
   1148 					goto fail;
   1149 				}
   1150 
   1151 				pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
   1152 				pHeaderDescriptor->hdr[0].hdr_hdl = -1;
   1153 				pHeaderDescriptor->hdr[0].is_partial = 0;
   1154 				pHeaderDescriptor->hdr[0].status = -1;
   1155 
   1156 				if (m_header.AddHeader(pHeaderDescriptor) == false ||
   1157 						pHeaderDescriptor->hdr[0].status != 0)
   1158 				{
   1159 					IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
   1160 					res = IPACM_FAILURE;
   1161 					goto fail;
   1162 				}
   1163 
   1164 				get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
   1165 				IPACMDBG_H("client(%d) v6 full header name:%s header handle:(0x%x)\n",
   1166 								 num_wifi_client,
   1167 								 pHeaderDescriptor->hdr[0].name,
   1168 											 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v6);
   1169 
   1170 				get_client_memptr(wlan_client, num_wifi_client)->ipv6_header_set=true;
   1171 				break;
   1172 			}
   1173 		}
   1174 
   1175 		/* initialize wifi client*/
   1176 		get_client_memptr(wlan_client, num_wifi_client)->route_rule_set_v4 = false;
   1177 		get_client_memptr(wlan_client, num_wifi_client)->route_rule_set_v6 = 0;
   1178 		get_client_memptr(wlan_client, num_wifi_client)->ipv4_set = false;
   1179 		get_client_memptr(wlan_client, num_wifi_client)->ipv6_set = 0;
   1180 		get_client_memptr(wlan_client, num_wifi_client)->power_save_set=false;
   1181 		num_wifi_client++;
   1182 		header_name_count++; //keep increasing header_name_count
   1183 		IPACM_Wlan::total_num_wifi_clients++;
   1184 		res = IPACM_SUCCESS;
   1185 		IPACMDBG_H("Wifi client number: %d\n", num_wifi_client);
   1186 	}
   1187 	else
   1188 	{
   1189 		return res;
   1190 	}
   1191 
   1192 fail:
   1193 	free(pHeaderDescriptor);
   1194 	return res;
   1195 }
   1196 
   1197 /*handle wifi client */
   1198 int IPACM_Wlan::handle_wlan_client_ipaddr(ipacm_event_data_all *data)
   1199 {
   1200 	int clnt_indx;
   1201 	int v6_num;
   1202 	uint32_t ipv6_link_local_prefix = 0xFE800000;
   1203 	uint32_t ipv6_link_local_prefix_mask = 0xFFC00000;
   1204 
   1205 	IPACMDBG_H("number of wifi clients: %d\n", num_wifi_client);
   1206 	IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
   1207 					 data->mac_addr[0],
   1208 					 data->mac_addr[1],
   1209 					 data->mac_addr[2],
   1210 					 data->mac_addr[3],
   1211 					 data->mac_addr[4],
   1212 					 data->mac_addr[5]);
   1213 
   1214 	clnt_indx = get_wlan_client_index(data->mac_addr);
   1215 
   1216 		if (clnt_indx == IPACM_INVALID_INDEX)
   1217 		{
   1218 			IPACMERR("wlan client not found/attached \n");
   1219 			return IPACM_FAILURE;
   1220 		}
   1221 
   1222 	IPACMDBG_H("Ip-type received %d\n", data->iptype);
   1223 	if (data->iptype == IPA_IP_v4)
   1224 	{
   1225 		IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr);
   1226 		if (data->ipv4_addr != 0) /* not 0.0.0.0 */
   1227 		{
   1228 			if (get_client_memptr(wlan_client, clnt_indx)->ipv4_set == false)
   1229 			{
   1230 				get_client_memptr(wlan_client, clnt_indx)->v4_addr = data->ipv4_addr;
   1231 				get_client_memptr(wlan_client, clnt_indx)->ipv4_set = true;
   1232 			}
   1233 			else
   1234 			{
   1235 			   /* check if client got new IPv4 address*/
   1236 			   if(data->ipv4_addr == get_client_memptr(wlan_client, clnt_indx)->v4_addr)
   1237 			   {
   1238 			     IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx);
   1239 				 return IPACM_FAILURE;
   1240 			   }
   1241 			   else
   1242 			   {
   1243 			     IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
   1244 				 /* delete NAT rules first */
   1245 				 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clnt_indx)->v4_addr);
   1246 			     delete_default_qos_rtrules(clnt_indx,IPA_IP_v4);
   1247 		         get_client_memptr(wlan_client, clnt_indx)->route_rule_set_v4 = false;
   1248 			     get_client_memptr(wlan_client, clnt_indx)->v4_addr = data->ipv4_addr;
   1249 			}
   1250 		}
   1251 	}
   1252 	else
   1253 	{
   1254 		    IPACMDBG_H("Invalid client IPv4 address \n");
   1255 		    return IPACM_FAILURE;
   1256 		}
   1257 	}
   1258 	else
   1259 	{
   1260 		if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
   1261 				(data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) /* check if all 0 not valid ipv6 address */
   1262 		{
   1263 			IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
   1264 			if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) &&
   1265 				memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0)
   1266 			{
   1267 				IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n");
   1268 				IPACMDBG_H("ipv6 address: 0x%x:%x ipv6_prefix0x%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], ipv6_prefix[0], ipv6_prefix[1]);
   1269 				return IPACM_FAILURE;
   1270 			}
   1271 
   1272 			if(get_client_memptr(wlan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
   1273 			{
   1274 
   1275 		       for(v6_num=0;v6_num < get_client_memptr(wlan_client, clnt_indx)->ipv6_set;v6_num++)
   1276 				{
   1277 					if( data->ipv6_addr[0] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][0] &&
   1278 			           data->ipv6_addr[1] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][1] &&
   1279 			  	        data->ipv6_addr[2]== get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][2] &&
   1280 			  	         data->ipv6_addr[3] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][3])
   1281 					{
   1282 			  	    IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx);
   1283 			  	    return IPACM_FAILURE; /* not setup the RT rules*/
   1284 			  		break;
   1285 					}
   1286 				}
   1287 
   1288 		       /* not see this ipv6 before for wifi client*/
   1289 			   get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0];
   1290 			   get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1];
   1291 			   get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2];
   1292 			   get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3];
   1293 			   get_client_memptr(wlan_client, clnt_indx)->ipv6_set++;
   1294 		    }
   1295 		    else
   1296 		    {
   1297 				IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx);
   1298 				return IPACM_FAILURE; /* not setup the RT rules*/
   1299 		    }
   1300 		}
   1301 		else
   1302 		{
   1303 			IPACMDBG_H("IPV6 address is invalid\n");
   1304 			return IPACM_FAILURE;
   1305 		}
   1306 	}
   1307 
   1308 	return IPACM_SUCCESS;
   1309 }
   1310 
   1311 /*handle wifi client routing rule*/
   1312 int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype)
   1313 {
   1314 	struct ipa_ioc_add_rt_rule *rt_rule;
   1315 	struct ipa_rt_rule_add *rt_rule_entry;
   1316 	uint32_t tx_index;
   1317 	int wlan_index,v6_num;
   1318 	const int NUM = 1;
   1319 
   1320 	if(tx_prop == NULL)
   1321 	{
   1322 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
   1323 		return IPACM_SUCCESS;
   1324 	}
   1325 
   1326 	IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
   1327 			mac_addr[0], mac_addr[1], mac_addr[2],
   1328 			mac_addr[3], mac_addr[4], mac_addr[5]);
   1329 
   1330 	wlan_index = get_wlan_client_index(mac_addr);
   1331 	if (wlan_index == IPACM_INVALID_INDEX)
   1332 	{
   1333 		IPACMDBG_H("wlan client not found/attached \n");
   1334 		return IPACM_SUCCESS;
   1335 	}
   1336 
   1337 	/* during power_save mode, even receive IP_ADDR_ADD, not setting RT rules*/
   1338 	if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true)
   1339 	{
   1340 		IPACMDBG_H("wlan client is in power safe mode \n");
   1341 		return IPACM_SUCCESS;
   1342 	}
   1343 
   1344 	if (iptype==IPA_IP_v4)
   1345 	{
   1346 		IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", wlan_index, iptype,
   1347 				get_client_memptr(wlan_client, wlan_index)->ipv4_set,
   1348 				get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4);
   1349 	}
   1350 	else
   1351 	{
   1352 		IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wlan_index, iptype,
   1353 				get_client_memptr(wlan_client, wlan_index)->ipv6_set,
   1354 				get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6);
   1355 	}
   1356 
   1357 
   1358 	/* Add default  Qos routing rules if not set yet */
   1359 	if ((iptype == IPA_IP_v4
   1360 				&& get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 == false
   1361 				&& get_client_memptr(wlan_client, wlan_index)->ipv4_set == true)
   1362 			|| (iptype == IPA_IP_v6
   1363 				&& get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 < get_client_memptr(wlan_client, wlan_index)->ipv6_set
   1364 			   ))
   1365 	{
   1366 		rt_rule = (struct ipa_ioc_add_rt_rule *)
   1367 			calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
   1368 					NUM * sizeof(struct ipa_rt_rule_add));
   1369 
   1370 		if (rt_rule == NULL)
   1371 		{
   1372 			PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n");
   1373 			return IPACM_FAILURE;
   1374 		}
   1375 
   1376 		rt_rule->commit = 1;
   1377 		rt_rule->num_rules = (uint8_t)NUM;
   1378 		rt_rule->ip = iptype;
   1379 
   1380 
   1381 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
   1382 		{
   1383 
   1384 			if(iptype != tx_prop->tx[tx_index].ip)
   1385 			{
   1386 				IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n",
   1387 						tx_index, tx_prop->tx[tx_index].ip,iptype);
   1388 				continue;
   1389 			}
   1390 
   1391 			rt_rule_entry = &rt_rule->rules[0];
   1392 			rt_rule_entry->at_rear = 0;
   1393 
   1394 			if (iptype == IPA_IP_v4)
   1395 			{
   1396 				IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wlan_index,
   1397 						get_client_memptr(wlan_client, wlan_index)->v4_addr);
   1398 
   1399 				IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
   1400 						wlan_index,
   1401 						get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4);
   1402 				strlcpy(rt_rule->rt_tbl_name,
   1403 						IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name,
   1404 						sizeof(rt_rule->rt_tbl_name));
   1405 				rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
   1406 
   1407 				if(IPACM_Iface::ipacmcfg->isMCC_Mode)
   1408 				{
   1409 					IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
   1410 							tx_prop->tx[tx_index].alt_dst_pipe);
   1411 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
   1412 				}
   1413 				else
   1414 				{
   1415 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
   1416 				}
   1417 
   1418 				memcpy(&rt_rule_entry->rule.attrib,
   1419 						&tx_prop->tx[tx_index].attrib,
   1420 						sizeof(rt_rule_entry->rule.attrib));
   1421 				rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
   1422 				rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4;
   1423 				rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr;
   1424 				rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
   1425 #ifdef FEATURE_IPA_V3
   1426 				rt_rule_entry->rule.hashable = false;
   1427 #endif
   1428 				if (false == m_routing.AddRoutingRule(rt_rule))
   1429 				{
   1430 					IPACMERR("Routing rule addition failed!\n");
   1431 					free(rt_rule);
   1432 					return IPACM_FAILURE;
   1433 				}
   1434 
   1435 				/* copy ipv4 RT hdl */
   1436 				get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4 =
   1437 					rt_rule->rules[0].rt_rule_hdl;
   1438 				IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
   1439 						get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4, iptype);
   1440 			}
   1441 			else
   1442 			{
   1443 				for(v6_num = get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6;v6_num < get_client_memptr(wlan_client, wlan_index)->ipv6_set;v6_num++)
   1444 				{
   1445 					IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
   1446 							wlan_index,
   1447 							get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6);
   1448 
   1449 					/* v6 LAN_RT_TBL */
   1450 					strlcpy(rt_rule->rt_tbl_name,
   1451 							IPACM_Iface::ipacmcfg->rt_tbl_v6.name,
   1452 							sizeof(rt_rule->rt_tbl_name));
   1453 					rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
   1454 					/* Support QCMAP LAN traffic feature, send to A5 */
   1455 					rt_rule_entry->rule.dst = iface_query->excp_pipe;
   1456 					memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib));
   1457 					rt_rule_entry->rule.hdr_hdl = 0;
   1458 					rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
   1459 					rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0];
   1460 					rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1];
   1461 					rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2];
   1462 					rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3];
   1463 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
   1464 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
   1465 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
   1466 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
   1467 #ifdef FEATURE_IPA_V3
   1468 					rt_rule_entry->rule.hashable = true;
   1469 #endif
   1470 					if (false == m_routing.AddRoutingRule(rt_rule))
   1471 					{
   1472 						IPACMERR("Routing rule addition failed!\n");
   1473 						free(rt_rule);
   1474 						return IPACM_FAILURE;
   1475 					}
   1476 
   1477 					get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[v6_num] = rt_rule->rules[0].rt_rule_hdl;
   1478 					IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
   1479 							get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[v6_num], iptype);
   1480 
   1481 					/*Copy same rule to v6 WAN RT TBL*/
   1482 					strlcpy(rt_rule->rt_tbl_name,
   1483 							IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name,
   1484 							sizeof(rt_rule->rt_tbl_name));
   1485 					rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
   1486 					/* Downlink traffic from Wan iface, directly through IPA */
   1487 					if(IPACM_Iface::ipacmcfg->isMCC_Mode)
   1488 					{
   1489 						IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
   1490 								tx_prop->tx[tx_index].alt_dst_pipe);
   1491 						rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
   1492 					}
   1493 					else
   1494 					{
   1495 						rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
   1496 					}
   1497 					memcpy(&rt_rule_entry->rule.attrib,
   1498 							&tx_prop->tx[tx_index].attrib,
   1499 							sizeof(rt_rule_entry->rule.attrib));
   1500 					rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6;
   1501 					rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
   1502 					rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0];
   1503 					rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1];
   1504 					rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2];
   1505 					rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3];
   1506 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
   1507 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
   1508 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
   1509 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
   1510 #ifdef FEATURE_IPA_V3
   1511 					rt_rule_entry->rule.hashable = true;
   1512 #endif
   1513 					if (false == m_routing.AddRoutingRule(rt_rule))
   1514 					{
   1515 						IPACMERR("Routing rule addition failed!\n");
   1516 						free(rt_rule);
   1517 						return IPACM_FAILURE;
   1518 					}
   1519 
   1520 					get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num] = rt_rule->rules[0].rt_rule_hdl;
   1521 
   1522 					IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
   1523 							get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num], iptype);
   1524 				}
   1525 			}
   1526 
   1527 		} /* end of for loop */
   1528 
   1529 		free(rt_rule);
   1530 
   1531 		if (iptype == IPA_IP_v4)
   1532 		{
   1533 			get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 = true;
   1534 		}
   1535 		else
   1536 		{
   1537 			get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 = get_client_memptr(wlan_client, wlan_index)->ipv6_set;
   1538 		}
   1539 	}
   1540 
   1541 	return IPACM_SUCCESS;
   1542 }
   1543 
   1544 /*handle wifi client power-save mode*/
   1545 int IPACM_Wlan::handle_wlan_client_pwrsave(uint8_t *mac_addr)
   1546 {
   1547 	int clt_indx;
   1548 	IPACMDBG_H("wlan->handle_wlan_client_pwrsave();\n");
   1549 
   1550 	clt_indx = get_wlan_client_index(mac_addr);
   1551 	if (clt_indx == IPACM_INVALID_INDEX)
   1552 	{
   1553 		IPACMDBG_H("wlan client not attached\n");
   1554 		return IPACM_SUCCESS;
   1555 	}
   1556 
   1557         if (get_client_memptr(wlan_client, clt_indx)->power_save_set == false)
   1558 	{
   1559 		/* First reset nat rules and then route rules */
   1560 	    if(get_client_memptr(wlan_client, clt_indx)->ipv4_set == true)
   1561 	    {
   1562 			IPACMDBG_H("Deleting Nat Rules\n");
   1563 			Nat_App->UpdatePwrSaveIf(get_client_memptr(wlan_client, clt_indx)->v4_addr);
   1564  	     }
   1565 
   1566 		IPACMDBG_H("Deleting default qos Route Rules\n");
   1567 		delete_default_qos_rtrules(clt_indx, IPA_IP_v4);
   1568 		delete_default_qos_rtrules(clt_indx, IPA_IP_v6);
   1569                 get_client_memptr(wlan_client, clt_indx)->power_save_set = true;
   1570 	}
   1571 	else
   1572 	{
   1573 		IPACMDBG_H("wlan client already in power-save mode\n");
   1574 	}
   1575     return IPACM_SUCCESS;
   1576 }
   1577 
   1578 /*handle wifi client del mode*/
   1579 int IPACM_Wlan::handle_wlan_client_down_evt(uint8_t *mac_addr)
   1580 {
   1581 	int clt_indx;
   1582 	uint32_t tx_index;
   1583 	int num_wifi_client_tmp = num_wifi_client;
   1584 	int num_v6;
   1585 
   1586 	IPACMDBG_H("total client: %d\n", num_wifi_client_tmp);
   1587 
   1588 	clt_indx = get_wlan_client_index(mac_addr);
   1589 	if (clt_indx == IPACM_INVALID_INDEX)
   1590 	{
   1591 		IPACMDBG_H("wlan client not attached\n");
   1592 		return IPACM_SUCCESS;
   1593 	}
   1594 
   1595 	/* First reset nat rules and then route rules */
   1596 	if(get_client_memptr(wlan_client, clt_indx)->ipv4_set == true)
   1597 	{
   1598 	        IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, clt_indx)->v4_addr);
   1599 			CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clt_indx)->v4_addr);
   1600  	}
   1601 
   1602 	if (delete_default_qos_rtrules(clt_indx, IPA_IP_v4))
   1603 	{
   1604 		IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", clt_indx);
   1605 		return IPACM_FAILURE;
   1606 	}
   1607 
   1608 	if (delete_default_qos_rtrules(clt_indx, IPA_IP_v6))
   1609 	{
   1610 		IPACMERR("unbale to delete v6 default qos route rules for indexn: %d\n", clt_indx);
   1611 		return IPACM_FAILURE;
   1612 	}
   1613 
   1614 	/* Delete wlan client header */
   1615 	if(get_client_memptr(wlan_client, clt_indx)->ipv4_header_set == true)
   1616 	{
   1617 	if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v4)
   1618 			== false)
   1619 	{
   1620 		return IPACM_FAILURE;
   1621 	}
   1622 		get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = false;
   1623 	}
   1624 
   1625 	if(get_client_memptr(wlan_client, clt_indx)->ipv6_header_set == true)
   1626 	{
   1627 	if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v6)
   1628 			== false)
   1629 	{
   1630 		return IPACM_FAILURE;
   1631 	}
   1632 		get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = false;
   1633 	}
   1634 
   1635 	/* Reset ip_set to 0*/
   1636 	get_client_memptr(wlan_client, clt_indx)->ipv4_set = false;
   1637 	get_client_memptr(wlan_client, clt_indx)->ipv6_set = 0;
   1638 	get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = false;
   1639 	get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = false;
   1640 	get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = false;
   1641 	get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = 0;
   1642 	free(get_client_memptr(wlan_client, clt_indx)->p_hdr_info);
   1643 
   1644 	for (; clt_indx < num_wifi_client_tmp - 1; clt_indx++)
   1645 	{
   1646 		get_client_memptr(wlan_client, clt_indx)->p_hdr_info = get_client_memptr(wlan_client, (clt_indx + 1))->p_hdr_info;
   1647 
   1648 		memcpy(get_client_memptr(wlan_client, clt_indx)->mac,
   1649 					 get_client_memptr(wlan_client, (clt_indx + 1))->mac,
   1650 					 sizeof(get_client_memptr(wlan_client, clt_indx)->mac));
   1651 
   1652 		get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v4 = get_client_memptr(wlan_client, (clt_indx + 1))->hdr_hdl_v4;
   1653 		get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v6 = get_client_memptr(wlan_client, (clt_indx + 1))->hdr_hdl_v6;
   1654 		get_client_memptr(wlan_client, clt_indx)->v4_addr = get_client_memptr(wlan_client, (clt_indx + 1))->v4_addr;
   1655 
   1656 		get_client_memptr(wlan_client, clt_indx)->ipv4_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv4_set;
   1657 		get_client_memptr(wlan_client, clt_indx)->ipv6_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv6_set;
   1658 		get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv4_header_set;
   1659 		get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv6_header_set;
   1660 
   1661 		get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = get_client_memptr(wlan_client, (clt_indx + 1))->route_rule_set_v4;
   1662 		get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = get_client_memptr(wlan_client, (clt_indx + 1))->route_rule_set_v6;
   1663 
   1664                 for(num_v6=0;num_v6< get_client_memptr(wlan_client, clt_indx)->ipv6_set;num_v6++)
   1665 	        {
   1666 		    get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][0] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][0];
   1667 		    get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][1] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][1];
   1668 		    get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][2] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][2];
   1669 		    get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][3] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][3];
   1670                 }
   1671 
   1672 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
   1673 		{
   1674 			get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4 =
   1675 				 get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4;
   1676 
   1677 			for(num_v6=0;num_v6< get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6;num_v6++)
   1678 			{
   1679 			  get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6] =
   1680 			   	 get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6];
   1681 			  get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6] =
   1682 			   	 get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6];
   1683 		    }
   1684 		}
   1685 	}
   1686 
   1687 	IPACMDBG_H(" %d wifi client deleted successfully \n", num_wifi_client);
   1688 	num_wifi_client = num_wifi_client - 1;
   1689 	IPACM_Wlan::total_num_wifi_clients = IPACM_Wlan::total_num_wifi_clients - 1;
   1690 	IPACMDBG_H(" Number of wifi client: %d\n", num_wifi_client);
   1691 
   1692 	return IPACM_SUCCESS;
   1693 }
   1694 
   1695 /*handle wlan iface down event*/
   1696 int IPACM_Wlan::handle_down_evt()
   1697 {
   1698 	int res = IPACM_SUCCESS, num_private_subnet_fl_rule;
   1699 	uint32_t i;
   1700 	num_private_subnet_fl_rule = 0;
   1701 
   1702 	IPACMDBG_H("WLAN ip-type: %d \n", ip_type);
   1703 	/* no iface address up, directly close iface*/
   1704 	if (ip_type == IPACM_IP_NULL)
   1705 	{
   1706 		IPACMERR("Invalid iptype: 0x%x\n", ip_type);
   1707 		goto fail;
   1708 	}
   1709 
   1710 	/* delete wan filter rule */
   1711 	if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
   1712 	{
   1713 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
   1714 		IPACM_Lan::handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
   1715 	}
   1716 
   1717 	if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
   1718 	{
   1719 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
   1720 		handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode);
   1721 	}
   1722 	IPACMDBG_H("finished deleting wan filtering rules\n ");
   1723 
   1724 	/* Delete v4 filtering rules */
   1725 	if (ip_type != IPA_IP_v6 && rx_prop != NULL)
   1726 	{
   1727 		/* delete IPv4 icmp filter rules */
   1728 		if(m_filtering.DeleteFilteringHdls(ipv4_icmp_flt_rule_hdl, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE) == false)
   1729 		{
   1730 			IPACMERR("Error Deleting ICMPv4 Filtering Rule, aborting...\n");
   1731 			res = IPACM_FAILURE;
   1732 			goto fail;
   1733 		}
   1734 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE);
   1735 
   1736 		if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false)
   1737 		{
   1738 			IPACMERR("Error Deleting Filtering Rule, aborting...\n");
   1739 			res = IPACM_FAILURE;
   1740 			goto fail;
   1741 		}
   1742 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
   1743 		IPACMDBG_H("Deleted default v4 filter rules successfully.\n");
   1744 
   1745 		/* delete private-ipv4 filter rules */
   1746 #ifdef FEATURE_IPA_ANDROID
   1747 		if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES) == false)
   1748 		{
   1749 			IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
   1750 			res = IPACM_FAILURE;
   1751 			goto fail;
   1752 		}
   1753 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES);
   1754 #else
   1755 		num_private_subnet_fl_rule = IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_MAX_PRIVATE_SUBNET_ENTRIES?
   1756 			IPA_MAX_PRIVATE_SUBNET_ENTRIES : IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
   1757 		if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, num_private_subnet_fl_rule) == false)
   1758 		{
   1759 			IPACMERR("Error deleting private subnet flt rules, aborting...\n");
   1760 			res = IPACM_FAILURE;
   1761 			goto fail;
   1762 		}
   1763 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_private_subnet_fl_rule);
   1764 #endif
   1765 		IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n");
   1766 	}
   1767 
   1768 	/* Delete v6 filtering rules */
   1769 	if (ip_type != IPA_IP_v4 && rx_prop != NULL)
   1770 	{
   1771 		/* delete icmp filter rules */
   1772 		if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false)
   1773 		{
   1774 			IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n");
   1775 			res = IPACM_FAILURE;
   1776 			goto fail;
   1777 		}
   1778 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE);
   1779 
   1780 		if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false)
   1781 		{
   1782 			IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
   1783 			res = IPACM_FAILURE;
   1784 			goto fail;
   1785 		}
   1786 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
   1787 		IPACMDBG_H("Deleted default v6 filter rules successfully.\n");
   1788 	}
   1789 	IPACMDBG_H("finished delete filtering rules\n ");
   1790 
   1791 	/* Delete default v4 RT rule */
   1792 	if (ip_type != IPA_IP_v6)
   1793 	{
   1794 		IPACMDBG_H("Delete default v4 routing rules\n");
   1795 		if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4)
   1796 				== false)
   1797 		{
   1798 			IPACMERR("Routing rule deletion failed!\n");
   1799 			res = IPACM_FAILURE;
   1800 			goto fail;
   1801 		}
   1802 	}
   1803 
   1804 	/* Delete default v6 RT rule */
   1805 	if (ip_type != IPA_IP_v4)
   1806 	{
   1807 		IPACMDBG_H("Delete default v6 routing rules\n");
   1808 		/* May have multiple ipv6 iface-RT rules */
   1809 		for (i = 0; i < 2*num_dft_rt_v6; i++)
   1810 		{
   1811 			if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6)
   1812 					== false)
   1813 			{
   1814 				IPACMERR("Routing rule deletion failed!\n");
   1815 				res = IPACM_FAILURE;
   1816 				goto fail;
   1817 			}
   1818 		}
   1819 	}
   1820 	IPACMDBG_H("finished deleting default RT rules\n ");
   1821 
   1822 	eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL);
   1823 
   1824 	/* free the wlan clients cache */
   1825 	IPACMDBG_H("Free wlan clients cache\n");
   1826 
   1827 	/* Delete private subnet*/
   1828 #ifdef FEATURE_IPA_ANDROID
   1829 	if (ip_type != IPA_IP_v6)
   1830 	{
   1831 		IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
   1832 		IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
   1833 		if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
   1834 		{
   1835 			IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
   1836 		}
   1837 	}
   1838 	/* reset the IPA-client pipe enum */
   1839 #ifdef FEATURE_IPACM_HAL
   1840 	handle_tethering_client(true, IPACM_CLIENT_MAX);
   1841 #else
   1842 	handle_tethering_client(true, IPACM_CLIENT_WLAN);
   1843 #endif
   1844 #endif /* defined(FEATURE_IPA_ANDROID)*/
   1845 
   1846 fail:
   1847 	/* clean wifi-client header, routing rules */
   1848 	/* clean wifi client rule*/
   1849 	IPACMDBG_H("left %d wifi clients need to be deleted \n ", num_wifi_client);
   1850 	for (i = 0; i < num_wifi_client; i++)
   1851 	{
   1852 		/* First reset nat rules and then route rules */
   1853 		if(get_client_memptr(wlan_client, i)->ipv4_set == true)
   1854 		{
   1855 	        IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, i)->v4_addr);
   1856 			CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, i)->v4_addr);
   1857 		}
   1858 
   1859 		if (delete_default_qos_rtrules(i, IPA_IP_v4))
   1860 		{
   1861 			IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", i);
   1862 			res = IPACM_FAILURE;
   1863 		}
   1864 
   1865 		if (delete_default_qos_rtrules(i, IPA_IP_v6))
   1866 		{
   1867 			IPACMERR("unbale to delete v6 default qos route rules for index: %d\n", i);
   1868 			res = IPACM_FAILURE;
   1869 		}
   1870 
   1871 		IPACMDBG_H("Delete %d client header\n", num_wifi_client);
   1872 
   1873 		if(get_client_memptr(wlan_client, i)->ipv4_header_set == true)
   1874 		{
   1875 			if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v4)
   1876 				== false)
   1877 			{
   1878 				res = IPACM_FAILURE;
   1879 			}
   1880 		}
   1881 
   1882 		if(get_client_memptr(wlan_client, i)->ipv6_header_set == true)
   1883 		{
   1884 			if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v6)
   1885 					== false)
   1886 			{
   1887 				res = IPACM_FAILURE;
   1888 			}
   1889 		}
   1890 	} /* end of for loop */
   1891 
   1892 	/* check software routing fl rule hdl */
   1893 	if (softwarerouting_act == true && rx_prop != NULL )
   1894 	{
   1895 		IPACMDBG_H("Delete sw routing filtering rules\n");
   1896 		IPACM_Iface::handle_software_routing_disable();
   1897 	}
   1898 	IPACMDBG_H("finished delete software-routing filtering rules\n ");
   1899 
   1900 	/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
   1901 	if (rx_prop != NULL)
   1902 	{
   1903 		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
   1904 		IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
   1905 		IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
   1906 		free(rx_prop);
   1907 	}
   1908 
   1909 	for (i = 0; i < num_wifi_client; i++)
   1910 	{
   1911 		if(get_client_memptr(wlan_client, i)->p_hdr_info != NULL)
   1912 		{
   1913 			free(get_client_memptr(wlan_client, i)->p_hdr_info);
   1914 		}
   1915 	}
   1916 	if(wlan_client != NULL)
   1917 	{
   1918 		free(wlan_client);
   1919 	}
   1920 	if (tx_prop != NULL)
   1921 	{
   1922 		free(tx_prop);
   1923 	}
   1924 
   1925 	if (iface_query != NULL)
   1926 	{
   1927 		free(iface_query);
   1928 	}
   1929 
   1930 	is_active = false;
   1931 	post_del_self_evt();
   1932 
   1933 	return res;
   1934 }
   1935 
   1936 /*handle reset wifi-client rt-rules */
   1937 int IPACM_Wlan::handle_wlan_client_reset_rt(ipa_ip_type iptype)
   1938 {
   1939 	uint32_t i;
   1940 	int res = IPACM_SUCCESS;
   1941 
   1942 	/* clean wifi-client routing rules */
   1943 	IPACMDBG_H("left %d wifi clients to reset ip-type(%d) rules \n ", num_wifi_client, iptype);
   1944 
   1945 	for (i = 0; i < num_wifi_client; i++)
   1946 	{
   1947 		/* Reset RT rules */
   1948 		res = delete_default_qos_rtrules(i, iptype);
   1949 		if (res != IPACM_SUCCESS)
   1950 		{
   1951 			IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype);
   1952 			return res;
   1953 		}
   1954 
   1955 		/* Reset ip-address */
   1956 		if(iptype == IPA_IP_v4)
   1957 		{
   1958 			get_client_memptr(wlan_client, i)->ipv4_set = false;
   1959 		}
   1960 		else
   1961 		{
   1962 			get_client_memptr(wlan_client, i)->ipv6_set = 0;
   1963 		}
   1964 	} /* end of for loop */
   1965 	return res;
   1966 }
   1967 
   1968 void IPACM_Wlan::handle_SCC_MCC_switch(ipa_ip_type iptype)
   1969 {
   1970 	struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL;
   1971 	struct ipa_rt_rule_mdfy *rt_rule_entry;
   1972 	uint32_t tx_index;
   1973 	int wlan_index, v6_num;
   1974 	const int NUM = 1;
   1975 	int num_wifi_client_tmp = IPACM_Wlan::num_wifi_client;
   1976 	bool isAdded = false;
   1977 
   1978 	if (tx_prop == NULL)
   1979 	{
   1980 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
   1981 		return;
   1982 	}
   1983 
   1984 	if (rt_rule == NULL)
   1985 	{
   1986 		rt_rule = (struct ipa_ioc_mdfy_rt_rule *)
   1987 			calloc(1, sizeof(struct ipa_ioc_mdfy_rt_rule) +
   1988 					NUM * sizeof(struct ipa_rt_rule_mdfy));
   1989 
   1990 		if (rt_rule == NULL)
   1991 		{
   1992 			PERROR("Error Locate ipa_ioc_mdfy_rt_rule memory...\n");
   1993 			return;
   1994 		}
   1995 
   1996 		rt_rule->commit = 0;
   1997 		rt_rule->num_rules = NUM;
   1998 		rt_rule->ip = iptype;
   1999 	}
   2000 	rt_rule_entry = &rt_rule->rules[0];
   2001 
   2002 	/* modify ipv4 routing rule */
   2003 	if (iptype == IPA_IP_v4)
   2004 	{
   2005 		for (wlan_index = 0; wlan_index < num_wifi_client_tmp; wlan_index++)
   2006 		{
   2007 			IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n",
   2008 					wlan_index, iptype,
   2009 					get_client_memptr(wlan_client, wlan_index)->ipv4_set,
   2010 					get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4);
   2011 
   2012 			if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true ||
   2013 					get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 == false)
   2014 			{
   2015 				IPACMDBG_H("client %d route rules not set\n", wlan_index);
   2016 				continue;
   2017 			}
   2018 
   2019 			IPACMDBG_H("Modify client %d route rule\n", wlan_index);
   2020 			for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
   2021 			{
   2022 				if (iptype != tx_prop->tx[tx_index].ip)
   2023 				{
   2024 					IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d ignore\n",
   2025 							tx_index, tx_prop->tx[tx_index].ip, iptype);
   2026 					continue;
   2027 				}
   2028 
   2029 				IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wlan_index,
   2030 						get_client_memptr(wlan_client, wlan_index)->v4_addr);
   2031 
   2032 				IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
   2033 						wlan_index,
   2034 						get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4);
   2035 
   2036 				if (IPACM_Iface::ipacmcfg->isMCC_Mode)
   2037 				{
   2038 					IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
   2039 							tx_prop->tx[tx_index].alt_dst_pipe);
   2040 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
   2041 				}
   2042 				else
   2043 				{
   2044 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
   2045 				}
   2046 
   2047 				memcpy(&rt_rule_entry->rule.attrib,
   2048 						&tx_prop->tx[tx_index].attrib,
   2049 						sizeof(rt_rule_entry->rule.attrib));
   2050 
   2051 				rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
   2052 				rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4;
   2053 
   2054 				rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr;
   2055 				rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
   2056 
   2057 				IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
   2058 						get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4, iptype);
   2059 
   2060 				rt_rule_entry->rt_rule_hdl =
   2061 					get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4;
   2062 
   2063 				if (false == m_routing.ModifyRoutingRule(rt_rule))
   2064 				{
   2065 					IPACMERR("Routing rule modify failed!\n");
   2066 					free(rt_rule);
   2067 					return;
   2068 				}
   2069 				isAdded = true;
   2070 			}
   2071 
   2072 		}
   2073 	}
   2074 
   2075 	/* modify ipv6 routing rule */
   2076 	if (iptype == IPA_IP_v6)
   2077 	{
   2078 		for (wlan_index = 0; wlan_index < num_wifi_client_tmp; wlan_index++)
   2079 		{
   2080 
   2081 			IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wlan_index, iptype,
   2082 					get_client_memptr(wlan_client, wlan_index)->ipv6_set,
   2083 					get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6);
   2084 
   2085 			if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true ||
   2086 					(get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 <
   2087 					 get_client_memptr(wlan_client, wlan_index)->ipv6_set) )
   2088 			{
   2089 				IPACMDBG_H("client %d route rules not set\n", wlan_index);
   2090 				continue;
   2091 			}
   2092 
   2093 			IPACMDBG_H("Modify client %d route rule\n", wlan_index);
   2094 			for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
   2095 			{
   2096 				if (iptype != tx_prop->tx[tx_index].ip)
   2097 				{
   2098 					IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d Ignore\n",
   2099 							tx_index, tx_prop->tx[tx_index].ip, iptype);
   2100 					continue;
   2101 				}
   2102 
   2103 				for (v6_num = get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6;
   2104 						v6_num < get_client_memptr(wlan_client, wlan_index)->ipv6_set;
   2105 						v6_num++)
   2106 				{
   2107 
   2108 					IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
   2109 							wlan_index,
   2110 							get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6);
   2111 
   2112 					if (IPACM_Iface::ipacmcfg->isMCC_Mode)
   2113 					{
   2114 						IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
   2115 								tx_prop->tx[tx_index].alt_dst_pipe);
   2116 						rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
   2117 					}
   2118 					else
   2119 					{
   2120 						rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
   2121 					}
   2122 
   2123 					memcpy(&rt_rule_entry->rule.attrib,
   2124 							&tx_prop->tx[tx_index].attrib,
   2125 							sizeof(rt_rule_entry->rule.attrib));
   2126 
   2127 					rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6;
   2128 					rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
   2129 
   2130 					rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0];
   2131 					rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1];
   2132 					rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2];
   2133 					rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3];
   2134 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
   2135 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
   2136 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
   2137 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
   2138 
   2139 					rt_rule_entry->rt_rule_hdl =
   2140 						get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num];
   2141 
   2142 					if (false == m_routing.ModifyRoutingRule(rt_rule))
   2143 					{
   2144 						IPACMERR("Routing rule modify failed!\n");
   2145 						free(rt_rule);
   2146 						return;
   2147 					}
   2148 					isAdded = true;
   2149 				}
   2150 			}
   2151 
   2152 		}
   2153 	}
   2154 
   2155 
   2156 	if (isAdded)
   2157 	{
   2158 		if (false == m_routing.Commit(iptype))
   2159 		{
   2160 			IPACMERR("Routing rule modify commit failed!\n");
   2161 			free(rt_rule);
   2162 			return;
   2163 		}
   2164 
   2165 		IPACMDBG("Routing rule modified successfully \n");
   2166 	}
   2167 
   2168 	if(rt_rule)
   2169 	{
   2170 		free(rt_rule);
   2171 	}
   2172 	return;
   2173 }
   2174 
   2175 void IPACM_Wlan::eth_bridge_handle_wlan_mode_switch()
   2176 {
   2177 	uint32_t i;
   2178 
   2179 	/* ====== post events to mimic WLAN interface goes down/up when AP mode is changing ====== */
   2180 
   2181 	/* first post IFACE_DOWN event */
   2182 	eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL);
   2183 
   2184 	/* then post IFACE_UP event */
   2185 	if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
   2186 	{
   2187 		eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL);
   2188 	}
   2189 	if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
   2190 	{
   2191 		eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL);
   2192 	}
   2193 
   2194 	/* at last post CLIENT_ADD event */
   2195 	for(i = 0; i < num_wifi_client; i++)
   2196 	{
   2197 		eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX,
   2198 			get_client_memptr(wlan_client, i)->mac);
   2199 	}
   2200 
   2201 	return;
   2202 }
   2203 
   2204 bool IPACM_Wlan::is_guest_ap()
   2205 {
   2206 	return m_is_guest_ap;
   2207 }
   2208