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