• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (c) 2013-2020, 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 
10 * Redistributions in binary form must reproduce the above
11 copyright notice, this list of conditions and the following
12 disclaimer in the documentation and/or other materials provided
13 with the distribution.
14 
15 * Neither the name of The Linux Foundation nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
18 
19 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
20 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
22 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
23 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 /*!
32 	@file
33 	IPACM_Lan.cpp
34 
35 	@brief
36 	This file implements the LAN iface functionality.
37 
38 	@Author
39 	Skylar Chang
40 
41 */
42 #include <string.h>
43 #include <fcntl.h>
44 #include <sys/ioctl.h>
45 #include "IPACM_Netlink.h"
46 #include "IPACM_Lan.h"
47 #include "IPACM_Wan.h"
48 #include "IPACM_IfaceManager.h"
49 #include "linux/rmnet_ipa_fd_ioctl.h"
50 #include "linux/ipa_qmi_service_v01.h"
51 #include "linux/msm_ipa.h"
52 #include "IPACM_ConntrackListener.h"
53 #include <sys/ioctl.h>
54 #include <fcntl.h>
55 #ifdef FEATURE_IPACM_HAL
56 #include "IPACM_OffloadManager.h"
57 #endif
58 bool IPACM_Lan::odu_up = false;
59 
IPACM_Lan(int iface_index)60 IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
61 {
62 	num_eth_client = 0;
63 	header_name_count = 0;
64 	ipv6_set = 0;
65 	ipv4_header_set = false;
66 	ipv6_header_set = false;
67 	odu_route_rule_v4_hdl = NULL;
68 	odu_route_rule_v6_hdl = NULL;
69 	eth_client = NULL;
70 	int m_fd_odu, ret = IPACM_SUCCESS;
71 	uint32_t i;
72 
73 	Nat_App = NatApp::GetInstance();
74 	if (Nat_App == NULL)
75 	{
76 		IPACMERR("unable to get Nat App instance \n");
77 		return;
78 	}
79 
80 	num_wan_ul_fl_rule_v4 = 0;
81 	num_wan_ul_fl_rule_v6 = 0;
82 	is_active = true;
83 	modem_ul_v4_set = false;
84 	v4_mux_id = 0;
85 	modem_ul_v6_set = false;
86 	v6_mux_id = 0;
87 
88 	sta_ul_v4_set = false;
89 	sta_ul_v6_set = false;
90 
91 	is_mode_switch = false;
92 	if_ipv4_subnet =0;
93 	each_client_rt_rule_count[IPA_IP_v4] = 0;
94 	each_client_rt_rule_count[IPA_IP_v6] = 0;
95 	eth_client_len = 0;
96 
97 	/* support eth multiple clients */
98 	if(iface_query != NULL)
99 	{
100 		if(ipa_if_cate != WLAN_IF)
101 		{
102 			eth_client_len = (sizeof(ipa_eth_client)) + (iface_query->num_tx_props * sizeof(eth_client_rt_hdl));
103 			eth_client = (ipa_eth_client *)calloc(IPA_MAX_NUM_ETH_CLIENTS, eth_client_len);
104 			if (eth_client == NULL)
105 			{
106 				IPACMERR("unable to allocate memory\n");
107 				return;
108 			}
109 		}
110 
111 		IPACMDBG_H(" IPACM->IPACM_Lan(%d) constructor: Tx:%d Rx:%d \n", ipa_if_num,
112 					 iface_query->num_tx_props, iface_query->num_rx_props);
113 
114 		/* ODU routing table initilization */
115 		if(ipa_if_cate == ODU_IF)
116 		{
117 			odu_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
118 			odu_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
119 			if ((odu_route_rule_v4_hdl == NULL) || (odu_route_rule_v6_hdl == NULL))
120 			{
121 				IPACMERR("unable to allocate memory\n");
122 				return;
123 			}
124 		}
125 	}
126 
127 	memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
128 	memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
129 
130 	memset(ipv4_icmp_flt_rule_hdl, 0, NUM_IPV4_ICMP_FLT_RULE * sizeof(uint32_t));
131 
132 	memset(private_fl_rule_hdl, 0, (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) * sizeof(uint32_t));
133 	memset(ipv6_prefix_flt_rule_hdl, 0, (NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_PREFIX_MTU_RULE) * sizeof(uint32_t));
134 	memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t));
135 	memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
136 
137 	/* ODU routing table initilization */
138 	if(ipa_if_cate == ODU_IF)
139 	{
140 		/* only do one time ioctl to odu-driver to infrom in router or bridge mode*/
141 		if (IPACM_Lan::odu_up != true)
142 		{
143 				m_fd_odu = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR);
144 				if (0 == m_fd_odu)
145 				{
146 					IPACMERR("Failed opening %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU);
147 					return ;
148 				}
149 
150 				if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)
151 				{
152 					ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_ROUTER);
153 					IPACM_Iface::ipacmcfg->ipacm_odu_enable = true;
154 				}
155 				else
156 				{
157 					ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_BRIDGE);
158 					IPACM_Iface::ipacmcfg->ipacm_odu_enable = true;
159 				}
160 
161 				if (ret)
162 				{
163 					IPACMERR("Failed tell odu-driver the mode\n");
164 				}
165 				IPACMDBG("Tell odu-driver in router-mode(%d)\n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode);
166 				IPACMDBG_H("odu is up: odu-driver in router-mode(%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode);
167 				close(m_fd_odu);
168 				IPACM_Lan::odu_up = true;
169 		}
170 	}
171 
172 	if(iface_query != NULL && tx_prop != NULL)
173 	{
174 		for(i=0; i<iface_query->num_tx_props; i++)
175 			each_client_rt_rule_count[tx_prop->tx[i].ip]++;
176 	}
177 	IPACMDBG_H("Need to add %d IPv4 and %d IPv6 routing rules for eth bridge for each client.\n", each_client_rt_rule_count[IPA_IP_v4], each_client_rt_rule_count[IPA_IP_v6]);
178 
179 #ifdef FEATURE_IPA_ANDROID
180 	/* set the IPA-client pipe enum */
181 	if(ipa_if_cate == LAN_IF)
182 	{
183 #ifdef FEATURE_IPACM_HAL
184 		handle_tethering_client(false, IPACM_CLIENT_MAX);
185 #else
186 		handle_tethering_client(false, IPACM_CLIENT_USB);
187 #endif // FEATURE_IPACM_HAL end
188 	}
189 #endif // FEATURE_IPA_ANDROID end
190 
191 	memset(is_downstream_set, 0, sizeof(is_downstream_set));
192 	memset(is_upstream_set, 0, sizeof(is_upstream_set));
193 	memset(&prefix, 0, sizeof(prefix));
194 
195 #ifdef FEATURE_IPACM_HAL
196 
197 		/* check if Upstream was set before as WIFI with RNDIS case */
198 		if(ipa_if_cate == LAN_IF && IPACM_Wan::backhaul_mode == WLAN_WAN)  /* LTE */
199 		{
200 			IPACMDBG_H(" Skip the Upstream flag set on LAN instance (%d) with WIFI backhaul (%d)\n", ipa_if_cate, IPACM_Wan::backhaul_mode ); /* RNDIS+WIFI not support on msm*/
201 			return;
202 		}
203 
204 		/* check if Upstream was set before */
205 		if (IPACM_Wan::isWanUP(ipa_if_num))
206 		{
207 				IPACMDBG_H("Upstream was set previously for ipv4, change is_upstream_set flag\n");
208 				is_upstream_set[IPA_IP_v4] = true;
209 		}
210 
211 		if (IPACM_Wan::isWanUP_V6(ipa_if_num))
212 		{
213 				IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n");
214 				is_upstream_set[IPA_IP_v6] = true;
215 		}
216 #endif // FEATURE_IPACM_HAL end
217 	return;
218 }
219 
~IPACM_Lan()220 IPACM_Lan::~IPACM_Lan()
221 {
222 	IPACM_EvtDispatcher::deregistr(this);
223 	IPACM_IfaceManager::deregistr(this);
224 	return;
225 }
226 
227 
228 /* LAN-iface's callback function */
event_callback(ipa_cm_event_id event,void * param)229 void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
230 {
231 	if(is_active == false && event != IPA_LAN_DELETE_SELF)
232 	{
233 		IPACMDBG_H("The interface is no longer active, return.\n");
234 		return;
235 	}
236 
237 	int ipa_interface_index;
238 	uint32_t i;
239 	ipacm_ext_prop* ext_prop;
240 	ipacm_event_iface_up_tehter* data_wan_tether;
241 
242 	switch (event)
243 	{
244 	case IPA_LINK_DOWN_EVENT:
245 		{
246 			ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
247 			ipa_interface_index = iface_ipa_index_query(data->if_index);
248 			if (ipa_interface_index == ipa_if_num)
249 			{
250 				IPACMDBG_H("Received IPA_LINK_DOWN_EVENT\n");
251 				handle_down_evt();
252 				IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
253 				return;
254 			}
255 		}
256 		break;
257 
258 	case IPA_CFG_CHANGE_EVENT:
259 		{
260 			if ( IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate)
261 			{
262 				IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category changed\n");
263 				/* delete previous instance */
264 				handle_down_evt();
265 				IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
266 				is_mode_switch = true; // need post internal usb-link up event
267 				return;
268 			}
269 			/* Add Natting iface to IPACM_Config if there is  Rx/Tx property */
270 			if (rx_prop != NULL || tx_prop != NULL)
271 			{
272 				IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
273 				IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_MAX);
274 			}
275 		}
276 		break;
277 
278 	case IPA_PRIVATE_SUBNET_CHANGE_EVENT:
279 		{
280 			ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
281 			/* internel event: data->if_index is ipa_if_index */
282 			if (data->if_index == ipa_if_num)
283 			{
284 				IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n");
285 				return;
286 			}
287 			else
288 			{
289 				IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n");
290 #ifdef FEATURE_IPA_ANDROID
291 				handle_private_subnet_android(IPA_IP_v4);
292 #endif
293 				IPACMDBG_H(" delete old private subnet rules, use new sets \n");
294 				return;
295 			}
296 		}
297 		break;
298 
299 	case IPA_LAN_DELETE_SELF:
300 	{
301 		ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
302 		if(data->if_index == ipa_if_num)
303 		{
304 			IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n");
305 			IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
306 			/* posting link-up event for cradle use-case */
307 			if(is_mode_switch)
308 			{
309 				IPACMDBG_H("Posting IPA_USB_LINK_UP_EVENT event for (%s)\n", dev_name);
310 				ipacm_cmd_q_data evt_data;
311 				memset(&evt_data, 0, sizeof(evt_data));
312 
313 				ipacm_event_data_fid *data_fid = NULL;
314 				data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
315 				if(data_fid == NULL)
316 				{
317 					IPACMERR("unable to allocate memory for IPA_USB_LINK_UP_EVENT data_fid\n");
318 					return;
319 				}
320 				if(IPACM_Iface::ipa_get_if_index(dev_name, &(data_fid->if_index)))
321 				{
322 					IPACMERR("Error while getting interface index for %s device", dev_name);
323 				}
324 				evt_data.event = IPA_USB_LINK_UP_EVENT;
325 				evt_data.evt_data = data_fid;
326 				//IPACMDBG_H("Posting event:%d\n", evt_data.event);
327 				IPACM_EvtDispatcher::PostEvt(&evt_data);
328 			}
329 #ifndef FEATURE_IPA_ANDROID
330 			if(rx_prop != NULL)
331 			{
332 				if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4) != 0)
333 				{
334 					IPACMDBG_DMESG("### WARNING ### num ipv4 flt rules on client %d is not expected: %d expected value: 0",
335 						rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4));
336 				}
337 				if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6) != 0)
338 				{
339 					IPACMDBG_DMESG("### WARNING ### num ipv6 flt rules on client %d is not expected: %d expected value: 0",
340 						rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6));
341 				}
342 			}
343 #endif
344 
345 			if (IPACM_Iface::ipacmcfg->isEthBridgingSupported())
346 			{
347 				if(rx_prop != NULL)
348 				{
349 					free(rx_prop);
350 				}
351 				if(tx_prop != NULL)
352 				{
353 					free(tx_prop);
354 				}
355 				if(iface_query != NULL)
356 				{
357 					free(iface_query);
358 				}
359 			}
360 			delete this;
361 		}
362 		break;
363 	}
364 
365 	case IPA_ADDR_ADD_EVENT:
366 		{
367 			ipacm_event_data_addr *data = (ipacm_event_data_addr *)param;
368 			ipa_interface_index = iface_ipa_index_query(data->if_index);
369 
370 			if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) ||
371 					 (data->iptype == IPA_IP_v6 &&
372 						data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 &&
373 					  data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) )
374 			{
375 				IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n");
376 				return;
377 			}
378 #ifdef FEATURE_L2TP
379 			if(data->iptype == IPA_IP_v6 && is_vlan_event(data->iface_name) && is_unique_local_ipv6_addr(data->ipv6_addr))
380 			{
381 				IPACMDBG_H("Got IPv6 new addr event for a vlan iface %s.\n", data->iface_name);
382 				eth_bridge_post_event(IPA_HANDLE_VLAN_IFACE_INFO, data->iptype, NULL,
383 					data->ipv6_addr, data->iface_name, IPA_CLIENT_MAX);
384 			}
385 #endif
386 			if (ipa_interface_index == ipa_if_num)
387 			{
388 				IPACMDBG_H("Received IPA_ADDR_ADD_EVENT\n");
389 
390 				/* only call ioctl for ODU iface with bridge mode */
391 				if(IPACM_Iface::ipacmcfg->ipacm_odu_enable == true && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false
392 						&& ipa_if_cate == ODU_IF)
393 				{
394 					if((data->iptype == IPA_IP_v6) && (num_dft_rt_v6 == 0))
395 					{
396 						handle_addr_evt_odu_bridge(data);
397 					}
398 #ifdef FEATURE_IPA_ANDROID
399 					add_dummy_private_subnet_flt_rule(data->iptype);
400 					handle_private_subnet_android(data->iptype);
401 #else
402 					handle_private_subnet(data->iptype);
403 #endif // FEATURE_IPA_ANDROID end
404 				}
405 				else
406 				{
407 
408 					/* check v4 not setup before, v6 can have 2 iface ip */
409 					if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX))
410 						|| ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
411 					{
412 						IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
413 						if(handle_addr_evt(data) == IPACM_FAILURE)
414 						{
415 							return;
416 						}
417 
418 #ifdef FEATURE_IPA_ANDROID
419 						add_dummy_private_subnet_flt_rule(data->iptype);
420 						handle_private_subnet_android(data->iptype);
421 #else
422 						handle_private_subnet(data->iptype);
423 #endif // FEATURE_IPA_ANDROID end
424 
425 #ifndef FEATURE_IPACM_HAL
426 						if (IPACM_Wan::isWanUP(ipa_if_num))
427 						{
428 							if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
429 							{
430 								if(IPACM_Wan::backhaul_mode == Q6_WAN)
431 								{
432 									ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
433 									handle_wan_up_ex(ext_prop, IPA_IP_v4,
434 												IPACM_Wan::getXlat_Mux_Id());
435 								}
436 								else
437 								{
438 									handle_wan_up(IPA_IP_v4);
439 								}
440 							}
441 							IPACMDBG_H("Finished checking wan_up\n");
442 						} else {
443 							IPACMDBG_H("Wan_V4 haven't up yet\n");
444 						}
445 
446 						if(IPACM_Wan::isWanUP_V6(ipa_if_num))
447 						{
448 							if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
449 							{
450 								memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix));
451 								install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
452 								if(IPACM_Wan::backhaul_mode == Q6_WAN)
453 								{
454 									ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
455 									handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
456 								}
457 								else
458 								{
459 									handle_wan_up(IPA_IP_v6);
460 								}
461 							}
462 							IPACMDBG_H("Finished checking wan_up_v6\n");
463 						} else {
464 							IPACMDBG_H("Wan_V6 haven't up yet\n");
465 						}
466 #else
467 						/* check if Upstream was set before */
468 						if (IPACM_Wan::isWanUP(ipa_if_num))
469 						{
470 							IPACMDBG_H("Upstream was set previously for ipv4, change is_upstream_set flag\n");
471 							is_upstream_set[IPA_IP_v4] = true;
472 						}
473 						if (IPACM_Wan::isWanUP_V6(ipa_if_num))
474 						{
475 							IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n");
476 							is_upstream_set[IPA_IP_v6] = true;
477 						}
478 #endif //FEATURE_IPACM_HAL end
479 						/* Post event to NAT */
480 						if (data->iptype == IPA_IP_v4)
481 						{
482 							ipacm_cmd_q_data evt_data;
483 							ipacm_event_iface_up *info;
484 
485 							info = (ipacm_event_iface_up *)
486 								malloc(sizeof(ipacm_event_iface_up));
487 							if (info == NULL)
488 							{
489 								IPACMERR("Unable to allocate memory\n");
490 								return;
491 							}
492 
493 							memcpy(info->ifname, dev_name, IF_NAME_LEN);
494 							info->ipv4_addr = data->ipv4_addr;
495 							info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask;
496 
497 							evt_data.event = IPA_HANDLE_LAN_UP;
498 							evt_data.evt_data = (void *)info;
499 
500 							/* Insert IPA_HANDLE_LAN_UP to command queue */
501 							IPACMDBG_H("posting IPA_HANDLE_LAN_UP for IPv4 with below information\n");
502 							IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n",
503 											info->ipv4_addr, info->addr_mask);
504 							IPACM_EvtDispatcher::PostEvt(&evt_data);
505 						}
506 						IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype);
507 					}
508 
509 					IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype);
510 					/* checking if SW-RT_enable */
511 					if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true)
512 					{
513 						/* handle software routing enable event*/
514 						IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
515 						handle_software_routing_enable(false);
516 					}
517 
518 				}
519 			}
520 		}
521 		break;
522 #ifdef FEATURE_IPA_ANDROID
523 	case IPA_HANDLE_WAN_UP_TETHER:
524 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n");
525 
526 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
527 		if(data_wan_tether == NULL)
528 		{
529 			IPACMERR("No event data is found.\n");
530 			return;
531 		}
532 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s, xlat %d\n", data_wan_tether->backhaul_type,
533 					data_wan_tether->if_index_tether,
534 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name,
535 					data_wan_tether->xlat_mux_id);
536 #ifndef FEATURE_IPACM_HAL
537 		if (data_wan_tether->if_index_tether != ipa_if_num)
538 		{
539 			IPACMERR("IPA_HANDLE_WAN_UP_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
540 			return;
541 		}
542 #else /* not offload rndis on WIFI mode on MSM targets */
543 		if (data_wan_tether->backhaul_type == WLAN_WAN)
544 		{
545 			IPACMERR("Not support RNDIS offload on WIFI mode, dun install UL filter rules for WIFI mode\n");
546 
547 			/* clean rndis  header, routing rules */
548 			IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
549 			for (i = 0; i < num_eth_client; i++)
550 			{
551 				/* First reset nat rules and then route rules */
552 				if(get_client_memptr(eth_client, i)->ipv4_set == true)
553 				{
554 					IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr);
555 					CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr);
556 				}
557 				if (delete_eth_rtrules(i, IPA_IP_v4))
558 					IPACMERR("unbale to delete usb-client v4 route rules for index %d\n", i);
559 
560 				if (delete_eth_rtrules(i, IPA_IP_v6))
561 					IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
562 
563 				IPACMDBG_H("Delete %d client header\n", num_eth_client);
564 
565 				if(get_client_memptr(eth_client, i)->ipv4_header_set == true)
566 				{
567 					if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v4)
568 						== false)
569 						IPACMERR("unbale to delete usb-client v4 header for index %d\n", i);
570 				}
571 
572 				if(get_client_memptr(eth_client, i)->ipv6_header_set == true)
573 				{
574 					if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v6)
575 							== false)
576 						IPACMERR("unbale to delete usb-client v6 header for index %d\n", i);
577 				}
578 			} /* end of for loop */
579 			return;
580 		}
581 #endif // FEATURE_IPACM_HAL end
582 		if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
583 		{
584 #ifdef FEATURE_IPACM_HAL
585 			if (is_upstream_set[IPA_IP_v4] == false)
586 			{
587 				IPACMDBG_H("Add upstream for IPv4.\n");
588 				is_upstream_set[IPA_IP_v4] = true;
589 				if (is_downstream_set[IPA_IP_v4] == true)
590 				{
591 					IPACMDBG_H("Downstream was set before, adding UL rules.\n");
592 					if (data_wan_tether->backhaul_type == Q6_WAN)
593 					{
594 							ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
595 							handle_wan_up_ex(ext_prop, IPA_IP_v4,
596 								data_wan_tether->xlat_mux_id);
597 					} else {
598 							handle_wan_up(IPA_IP_v4);
599 					}
600 				}
601 			}
602 #else
603 			if (data_wan_tether->backhaul_type == Q6_WAN)
604 			{
605 					ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
606 					handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan_tether->xlat_mux_id);
607 			} else {
608 					handle_wan_up(IPA_IP_v4);
609 			}
610 #endif // FEATURE_IPACM_HAL end
611 		}
612 		break;
613 
614 	case IPA_HANDLE_WAN_UP_V6_TETHER:
615 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n");
616 
617 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
618 		if (data_wan_tether == NULL)
619 		{
620 			IPACMERR("No event data is found.\n");
621 			return;
622 		}
623 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
624 					data_wan_tether->if_index_tether,
625 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
626 #ifndef FEATURE_IPACM_HAL
627 		if (data_wan_tether->if_index_tether != ipa_if_num)
628 		{
629 			IPACMERR("IPA_HANDLE_WAN_UP_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
630 			return;
631 		}
632 #endif // FEATURE_IPACM_HAL end
633 		if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
634 		{
635 #ifdef FEATURE_IPACM_HAL
636 			if (is_upstream_set[IPA_IP_v6] == false)
637 			{
638 				IPACMDBG_H("Add upstream for IPv6.\n");
639 				is_upstream_set[IPA_IP_v6] = true;
640 
641 				if (is_downstream_set[IPA_IP_v6] == true)
642 				{
643 					IPACMDBG_H("Downstream was set before, adding UL rules.\n");
644 					memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix));
645 					install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
646 					if (data_wan_tether->backhaul_type == Q6_WAN)
647 					{
648 						ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
649 						handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
650 					}
651 					else
652 					{
653 						handle_wan_up(IPA_IP_v6);
654 					}
655 				}
656 			}
657 #else
658 			if (data_wan_tether->backhaul_type == Q6_WAN)
659 			{
660 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
661 				handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
662 			} else {
663 				handle_wan_up(IPA_IP_v6);
664 			}
665 #endif // FEATURE_IPACM_HAL end
666 		}
667 		break;
668 
669 	case IPA_HANDLE_WAN_DOWN_TETHER:
670 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n");
671 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
672 		if (data_wan_tether == NULL)
673 		{
674 			IPACMERR("No event data is found.\n");
675 			return;
676 		}
677 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
678 					data_wan_tether->if_index_tether,
679 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
680 #ifndef FEATURE_IPACM_HAL
681 		if (data_wan_tether->if_index_tether != ipa_if_num)
682 		{
683 			IPACMERR("IPA_HANDLE_WAN_DOWN_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
684 			return;
685 		}
686 #endif // FEATURE_IPACM_HAL end
687 		if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
688 		{
689 #ifdef FEATURE_IPACM_HAL
690 			if(is_upstream_set[IPA_IP_v4] == true)
691 			{
692 				IPACMDBG_H("Del upstream for IPv4.\n");
693 				is_upstream_set[IPA_IP_v4] = false;
694 				if(is_downstream_set[IPA_IP_v4] == true)
695 				{
696 					IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
697 					handle_wan_down(data_wan_tether->backhaul_type);
698 				}
699 			}
700 #else
701 			handle_wan_down(data_wan_tether->backhaul_type);
702 #endif // FEATURE_IPACM_HAL end
703 		}
704 		break;
705 
706 	case IPA_HANDLE_WAN_DOWN_V6_TETHER:
707 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n");
708 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
709 		if(data_wan_tether == NULL)
710 		{
711 			IPACMERR("No event data is found.\n");
712 			return;
713 		}
714 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
715 					data_wan_tether->if_index_tether,
716 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
717 #ifndef FEATURE_IPACM_HAL
718 		if (data_wan_tether->if_index_tether != ipa_if_num)
719 		{
720 			IPACMERR("IPA_HANDLE_WAN_DOWN_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
721 			return;
722 		}
723 #endif // FEATURE_IPACM_HAL end
724 		if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
725 		{
726 #ifdef FEATURE_IPACM_HAL
727 			if (is_upstream_set[IPA_IP_v6] == true)
728 			{
729 				IPACMDBG_H("Del upstream for IPv6.\n");
730 				is_upstream_set[IPA_IP_v6] = false;
731 				if(is_downstream_set[IPA_IP_v6] == true)
732 				{
733 					IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
734 					/* reset usb-client ipv6 rt-rules */
735 					handle_lan_client_reset_rt(IPA_IP_v6);
736 					handle_wan_down_v6(data_wan_tether->backhaul_type);
737 				}
738 			}
739 #else
740 			/* reset usb-client ipv6 rt-rules */
741 			handle_lan_client_reset_rt(IPA_IP_v6);
742 			handle_wan_down_v6(data_wan_tether->backhaul_type);
743 #endif // FEATURE_IPACM_HAL end
744 		}
745 		break;
746 
747 	case IPA_DOWNSTREAM_ADD:
748 	{
749 		ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
750 		ipa_interface_index = iface_ipa_index_query(data->if_index);
751 		if (ipa_interface_index == ipa_if_num)
752 		{
753 			IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
754 #ifdef FEATURE_IPA_ANDROID
755 			if (IPACM_Wan::isXlat() && (data->prefix.iptype == IPA_IP_v4))
756 			{
757 				/* indicate v4-offload */
758 				IPACM_OffloadManager::num_offload_v4_tethered_iface++;
759 				IPACMDBG_H("in xlat: update num_offload_v4_tethered_iface %d\n", IPACM_OffloadManager::num_offload_v4_tethered_iface);
760 
761 				/* xlat not support for 2st tethered iface */
762 				if (IPACM_OffloadManager::num_offload_v4_tethered_iface > 1)
763 				{
764 					IPACMDBG_H("Not support 2st downstream iface %s for xlat, cur: %d\n", dev_name,
765 						IPACM_OffloadManager::num_offload_v4_tethered_iface);
766 					return;
767 				}
768 			}
769 
770 			IPACMDBG_H(" support downstream iface %s, cur %d\n", dev_name,
771 				IPACM_OffloadManager::num_offload_v4_tethered_iface);
772 #endif
773 			if (data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false)
774 			{
775 				IPACMDBG_H("Add downstream for IP iptype %d\n", data->prefix.iptype);
776 				is_downstream_set[data->prefix.iptype] = true;
777 				memcpy(&prefix[data->prefix.iptype], &data->prefix,
778 					sizeof(prefix[data->prefix.iptype]));
779 
780 				if (is_upstream_set[data->prefix.iptype] == true)
781 				{
782 					IPACMDBG_H("Upstream was set before, adding UL rules.\n");
783 					if (ip_type == IPA_IP_MAX || ip_type == data->prefix.iptype)
784 					{
785 						if (data->prefix.iptype == IPA_IP_v6) /* ipv6 only */
786 						{
787 							/* Only offload clients has same prefix as Andorid gave */
788 							ipv6_prefix[0] = data->prefix.v6Addr[0];
789 							ipv6_prefix[1] = data->prefix.v6Addr[1];
790 							IPACMDBG_H("ipv6_prefix0x%x:%x\n", ipv6_prefix[0], ipv6_prefix[1]);
791 							install_ipv6_prefix_flt_rule(ipv6_prefix);
792 						}
793 
794 						if (IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
795 						{
796 							ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
797 							if (data->prefix.iptype == IPA_IP_v4)
798 							{
799 								IPACMDBG_H("check getXlat_Mux_Id:%d\n", IPACM_Wan::getXlat_Mux_Id());
800 								handle_wan_up_ex(ext_prop, data->prefix.iptype,
801 									IPACM_Wan::getXlat_Mux_Id());
802 							}
803 							else {
804 								handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
805 							}
806 						} else {
807 							handle_wan_up(data->prefix.iptype); /* STA */
808 						}
809 					}
810 				}
811 			} else {
812 				IPACMDBG_H("downstream for IP iptype %d already set \n", data->prefix.iptype);
813 			}
814 		}
815 		break;
816 	}
817 
818 	case IPA_DOWNSTREAM_DEL:
819 	{
820 		ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
821 		ipa_interface_index = iface_ipa_index_query(data->if_index);
822 		if (ipa_interface_index == ipa_if_num)
823 		{
824 			IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
825 			if (is_downstream_set[data->prefix.iptype] == true)
826 			{
827 				IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
828 				is_downstream_set[data->prefix.iptype] = false;
829 
830 				if (is_upstream_set[data->prefix.iptype] == true)
831 				{
832 					IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
833 					if (data->prefix.iptype == IPA_IP_v4)
834 					{
835 						handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
836 					} else {
837 						handle_lan_client_reset_rt(IPA_IP_v6);
838 						handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
839 					}
840 				}
841 			}
842 		}
843 		break;
844 	}
845 
846 #else // above Andorid
847 	case IPA_HANDLE_WAN_UP:
848 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
849 
850 		ipacm_event_iface_up* data_wan = (ipacm_event_iface_up*)param;
851 		if (data_wan == NULL)
852 		{
853 			IPACMERR("No event data is found.\n");
854 			return;
855 		}
856 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
857 		if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
858 		{
859 		if (data_wan->backhaul_type == Q6_WAN)
860 		{
861 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
862 				handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
863 		}
864 		else
865 		{
866 			handle_wan_up(IPA_IP_v4);
867 		}
868 		}
869 		break;
870 
871 	case IPA_HANDLE_WAN_UP_V6:
872 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6 event\n");
873 
874 		data_wan = (ipacm_event_iface_up*)param;
875 		if (data_wan == NULL)
876 		{
877 			IPACMERR("No event data is found.\n");
878 			return;
879 		}
880 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
881 		if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
882 		{
883 			memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix));
884 			install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
885 
886 			/* MTU might have changed. Need to update ipv4 MTU rule if up */
887 			if (IPACM_Wan::isWanUP(ipa_if_num))
888 				handle_private_subnet_android(IPA_IP_v4);
889 
890 			if (data_wan->backhaul_type == Q6_WAN)
891 			{
892 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
893 				handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
894 			}
895 			else
896 			{
897 				handle_wan_up(IPA_IP_v6);
898 			}
899 		}
900 		break;
901 
902 	case IPA_HANDLE_WAN_DOWN:
903 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n");
904 		data_wan = (ipacm_event_iface_up*)param;
905 		if (data_wan == NULL)
906 		{
907 			IPACMERR("No event data is found.\n");
908 			return;
909 		}
910 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
911 		if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
912 		{
913 			handle_wan_down(data_wan->backhaul_type);
914 		}
915 		break;
916 
917 	case IPA_HANDLE_WAN_DOWN_V6:
918 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6 event\n");
919 		data_wan = (ipacm_event_iface_up*)param;
920 		if (data_wan == NULL)
921 		{
922 			IPACMERR("No event data is found.\n");
923 			return;
924 		}
925 		/* clean up v6 RT rules*/
926 		IPACMDBG_H("Received IPA_WAN_V6_DOWN in LAN-instance and need clean up client IPv6 address \n");
927 		/* reset usb-client ipv6 rt-rules */
928 		handle_lan_client_reset_rt(IPA_IP_v6);
929 
930 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
931 		if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
932 		{
933 			handle_wan_down_v6(data_wan->backhaul_type);
934 		}
935 		break;
936 #endif // FEATURE_IPA_ANDROID end
937 
938 	case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
939 		{
940 			ipacm_event_data_all *data = (ipacm_event_data_all *)param;
941 			ipa_interface_index = iface_ipa_index_query(data->if_index);
942 			IPACMDBG_H("Recieved IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event \n");
943 			IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate);
944 
945 			/* if RNDIS under WIFI mode in MSM, dun add RT rule*/
946 #ifdef FEATURE_IPACM_HAL
947 			if(IPACM_Wan::backhaul_mode == WLAN_WAN) /* WIFI */
948 			{
949 				IPACMDBG_H(" dun construct header and RT-rules for RNDIS-PC in WIFI mode on MSM targets (STA %d) \n", IPACM_Wan::backhaul_mode);
950 				return;
951 			}
952 #endif
953 			if (ipa_interface_index == ipa_if_num && ipa_if_cate == ODU_IF)
954 			{
955 				IPACMDBG_H("ODU iface got v4-ip \n");
956 				/* first construc ODU full header */
957 				if ((ipv4_header_set == false) && (ipv6_header_set == false))
958 				{
959 					/* construct ODU RT tbl */
960 					handle_odu_hdr_init(data->mac_addr);
961 					if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true)
962 					{
963 						handle_odu_route_add();
964 						IPACMDBG_H("construct ODU header and route rules, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
965 					}
966 					else
967 					{
968 						IPACMDBG_H("construct ODU header only, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
969 					}
970 				}
971 				/* if ODU in bridge mode, directly return */
972 				if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
973 				{
974 					IPACMDBG_H("ODU is in bridge mode, no action \n");
975 					return;
976 				}
977 			}
978 
979 			if (ipa_interface_index == ipa_if_num
980 #ifdef FEATURE_L2TP
981 				|| is_vlan_event(data->iface_name)
982 				|| (is_l2tp_event(data->iface_name) && ipa_if_cate == ODU_IF)
983 #endif
984 				)
985 			{
986 				IPACMDBG_H("ETH iface got client \n");
987 				if(ipa_interface_index == ipa_if_num)
988 				{
989 					/* first construc ETH full header */
990 					handle_eth_hdr_init(data->mac_addr);
991 					IPACMDBG_H("construct ETH header and route rules \n");
992 					/* Associate with IP and construct RT-rule */
993 					if (handle_eth_client_ipaddr(data) == IPACM_FAILURE)
994 					{
995 						return;
996 					}
997 					handle_eth_client_route_rule(data->mac_addr, data->iptype);
998 					if (data->iptype == IPA_IP_v4)
999 					{
1000 						/* Add NAT rules after ipv4 RT rules are set */
1001 						CtList->HandleNeighIpAddrAddEvt(data);
1002 					}
1003 					eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr, NULL, data->iface_name,
1004 						IPA_CLIENT_MAX);
1005 				}
1006 #ifdef FEATURE_L2TP
1007 				else if(is_l2tp_event(data->iface_name) && ipa_if_cate == ODU_IF)
1008 				{
1009 
1010 					if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
1011 					{
1012 						/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
1013 						IPACMDBG_H("dev %s add producer dependency\n", dev_name);
1014 						if (tx_prop != NULL)
1015 						{
1016 							IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
1017 							IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
1018 						}
1019 					}
1020 					eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr, NULL, data->iface_name,
1021 						IPA_CLIENT_MAX);
1022 				}
1023 				else
1024 				{
1025 					if(data->iptype == IPA_IP_v6 && is_unique_local_ipv6_addr(data->ipv6_addr))
1026 					{
1027 						eth_bridge_post_event(IPA_HANDLE_VLAN_CLIENT_INFO, IPA_IP_MAX, data->mac_addr, data->ipv6_addr, data->iface_name, IPA_CLIENT_MAX);
1028 					}
1029 				}
1030 #endif
1031 				return;
1032 			}
1033 		}
1034 		break;
1035 
1036 	case IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT:
1037 		{
1038 			ipacm_event_data_all *data = (ipacm_event_data_all *)param;
1039 			ipa_interface_index = iface_ipa_index_query(data->if_index);
1040 
1041 			IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event. \n");
1042 			IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate);
1043 			/* if ODU in bridge mode, directly return */
1044 			if (ipa_if_cate == ODU_IF && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
1045 			{
1046 				IPACMDBG_H("ODU is in bridge mode, no action \n");
1047 				return;
1048 			}
1049 
1050 			if (ipa_interface_index == ipa_if_num
1051 #ifdef FEATURE_L2TP
1052 				|| (is_l2tp_event(data->iface_name) && ipa_if_cate == ODU_IF)
1053 #endif
1054 				)
1055 			{
1056 				if(ipa_interface_index == ipa_if_num)
1057 				{
1058 					if (data->iptype == IPA_IP_v6)
1059 					{
1060 						handle_del_ipv6_addr(data);
1061 						return;
1062 					}
1063 					IPACMDBG_H("LAN iface delete client \n");
1064 					handle_eth_client_down_evt(data->mac_addr);
1065 				}
1066 				else
1067 				{
1068 					eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_DEL, IPA_IP_MAX, data->mac_addr, NULL, data->iface_name,
1069 						IPA_CLIENT_MAX);
1070 				}
1071 				return;
1072 			}
1073 		}
1074 		break;
1075 
1076 	case IPA_SW_ROUTING_ENABLE:
1077 		IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n");
1078 		/* handle software routing enable event*/
1079 		handle_software_routing_enable(false);
1080 		break;
1081 
1082 	case IPA_SW_ROUTING_DISABLE:
1083 		IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n");
1084 		/* handle software routing disable event*/
1085 		handle_software_routing_disable(false);
1086 		break;
1087 
1088 	case IPA_CRADLE_WAN_MODE_SWITCH:
1089 	{
1090 		IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n");
1091 		ipacm_event_cradle_wan_mode* wan_mode = (ipacm_event_cradle_wan_mode*)param;
1092 		if(wan_mode == NULL)
1093 		{
1094 			IPACMERR("Event data is empty.\n");
1095 			return;
1096 		}
1097 
1098 		if(wan_mode->cradle_wan_mode == BRIDGE)
1099 		{
1100 			handle_cradle_wan_mode_switch(true);
1101 		}
1102 		else
1103 		{
1104 			handle_cradle_wan_mode_switch(false);
1105 		}
1106 	}
1107 	break;
1108 
1109 	case IPA_TETHERING_STATS_UPDATE_EVENT:
1110 	{
1111 		IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
1112 		if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
1113 		{
1114 			if(IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
1115 			{
1116 				ipa_get_data_stats_resp_msg_v01 *data = (ipa_get_data_stats_resp_msg_v01 *)param;
1117 				IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data->ipa_stats_type);
1118 				IPACMDBG("Received %d UL, %d DL pipe stats\n",data->ul_src_pipe_stats_list_len,
1119 					data->dl_dst_pipe_stats_list_len);
1120 				if (data->ipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01)
1121 				{
1122 					IPACMERR("not valid pipe stats enum(%d)\n", data->ipa_stats_type);
1123 					return;
1124 				}
1125 				handle_tethering_stats_event(data);
1126 			}
1127 		}
1128 	}
1129 	break;
1130 
1131 	default:
1132 		break;
1133 	}
1134 
1135 	return;
1136 }
1137 
1138 
handle_del_ipv6_addr(ipacm_event_data_all * data)1139 int IPACM_Lan::handle_del_ipv6_addr(ipacm_event_data_all *data)
1140 {
1141 	uint32_t tx_index;
1142 	uint32_t rt_hdl;
1143 	int num_v6 =0, clnt_indx;
1144 
1145 	clnt_indx = get_eth_client_index(data->mac_addr);
1146 	if (clnt_indx == IPACM_INVALID_INDEX)
1147 	{
1148 		IPACMERR("eth client not found/attached \n");
1149 		return IPACM_FAILURE;
1150 	}
1151 
1152 	if(data->iptype == IPA_IP_v6)
1153 	{
1154 		if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
1155 				(data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0))
1156 		{
1157 			IPACMDBG_H("ipv6 address got: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
1158 			for(num_v6=0;num_v6 < get_client_memptr(eth_client, clnt_indx)->ipv6_set;num_v6++)
1159 			{
1160 				if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][0] &&
1161 					data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][1] &&
1162 					data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][2] &&
1163 					data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][3])
1164 				{
1165 					IPACMDBG_H("ipv6 addr is found at position:%d for client:%d\n", num_v6, clnt_indx);
1166 					break;
1167 				}
1168 			}
1169 		}
1170 		else
1171 		{
1172 			IPACMDBG_H("Invalid ipv6 address\n");
1173 			return IPACM_FAILURE;
1174 		}
1175 		if (num_v6 == IPV6_NUM_ADDR)
1176 		{
1177 			IPACMDBG_H("ipv6 addr is not found. \n");
1178 			return IPACM_FAILURE;
1179 		}
1180 
1181 		for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
1182 		{
1183 			if((tx_prop->tx[tx_index].ip == IPA_IP_v6) && (get_client_memptr(eth_client, clnt_indx)->route_rule_set_v6 != 0))
1184 			{
1185 				IPACMDBG_H("Delete client index %d ipv6 RT-rules for %d-st ipv6 for tx:%d\n", clnt_indx, num_v6, tx_index);
1186 				rt_hdl = get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6];
1187 				if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
1188 				{
1189 					return IPACM_FAILURE;
1190 				}
1191 				rt_hdl = get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6];
1192 				if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
1193 				{
1194 					return IPACM_FAILURE;
1195 				}
1196 				get_client_memptr(eth_client, clnt_indx)->ipv6_set--;
1197 				get_client_memptr(eth_client, clnt_indx)->route_rule_set_v6--;
1198 
1199 				for(;num_v6< get_client_memptr(eth_client, clnt_indx)->ipv6_set;num_v6++)
1200 				{
1201 					get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][0] =
1202 						get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][0];
1203 					get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][1] =
1204 						get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][1];
1205 					get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][2] =
1206 						get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][2];
1207 					get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][3] =
1208 						get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][3];
1209 					get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6] =
1210 						get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6+1];
1211 					get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6] =
1212 						get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6+1];
1213 				}
1214 			}
1215 		}
1216 	}
1217 	return IPACM_SUCCESS;
1218 }
1219 
1220 /* delete filter rule for wan_down event for IPv4*/
handle_wan_down(ipacm_wan_iface_type backhaul_mode)1221 int IPACM_Lan::handle_wan_down(ipacm_wan_iface_type backhaul_mode)
1222 {
1223 	ipa_fltr_installed_notif_req_msg_v01 flt_index;
1224 	int fd;
1225 
1226 	fd = open(IPA_DEVICE_NAME, O_RDWR);
1227 	if (0 == fd)
1228 	{
1229 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1230 		return IPACM_FAILURE;
1231 	}
1232 
1233 #ifdef FEATURE_IPA_ANDROID
1234 		/* indicate v4-offload remove */
1235 		if (IPACM_Wan::isXlat() && (IPACM_OffloadManager::num_offload_v4_tethered_iface > 0)) {
1236 			IPACM_OffloadManager::num_offload_v4_tethered_iface--;
1237 			IPACMDBG_H("num_offload_v4_tethered_iface %d\n", IPACM_OffloadManager::num_offload_v4_tethered_iface);
1238 		}
1239 #endif
1240 
1241 	if(backhaul_mode == Q6_WAN && modem_ul_v4_set == true)
1242 	{
1243 		if (num_wan_ul_fl_rule_v4 > MAX_WAN_UL_FILTER_RULES)
1244 		{
1245 			IPACMERR("number of wan_ul_fl_rule_v4 (%d) > MAX_WAN_UL_FILTER_RULES (%d), aborting...\n", num_wan_ul_fl_rule_v4, MAX_WAN_UL_FILTER_RULES);
1246 			close(fd);
1247 			return IPACM_FAILURE;
1248 		}
1249 		if (num_wan_ul_fl_rule_v4 == 0)
1250 		{
1251 			IPACMERR("No modem UL rules were installed, return...\n");
1252 			close(fd);
1253 			return IPACM_FAILURE;
1254 		}
1255 		if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v4,
1256 			IPA_IP_v4, num_wan_ul_fl_rule_v4) == false)
1257 		{
1258 			IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n");
1259 			close(fd);
1260 			return IPACM_FAILURE;
1261 		}
1262 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_wan_ul_fl_rule_v4);
1263 
1264 		memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
1265 		num_wan_ul_fl_rule_v4 = 0;
1266 		modem_ul_v4_set = false;
1267 
1268 		memset(&flt_index, 0, sizeof(flt_index));
1269 		flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe);
1270 		if ((int)flt_index.source_pipe_index == -1)
1271 		{
1272 			IPACMERR("Error Query src pipe idx, aborting...\n");
1273 			close(fd);
1274 			return IPACM_FAILURE;
1275 		}
1276 		flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01;
1277 		if (!IPACM_Iface::ipacmcfg->isIPAv3Supported())
1278 		{
1279 			flt_index.filter_index_list_len = 0;
1280 		}
1281 		else /* IPAv3 */
1282 		{
1283 			flt_index.rule_id_valid = 1;
1284 			flt_index.rule_id_len = 0;
1285 		}
1286 		flt_index.embedded_pipe_index_valid = 1;
1287 		flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD);
1288 		if ((int)flt_index.embedded_pipe_index == -1)
1289 		{
1290 			IPACMERR("Error Query emb pipe idx, aborting...\n");
1291 			close(fd);
1292 			return IPACM_FAILURE;
1293 		}
1294 		flt_index.retain_header_valid = 1;
1295 		flt_index.retain_header = 0;
1296 		flt_index.embedded_call_mux_id_valid = 1;
1297 		flt_index.embedded_call_mux_id = v4_mux_id;
1298 		v4_mux_id = 0;
1299 		if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
1300 		{
1301 			IPACMERR("Error sending filtering rule index, aborting...\n");
1302 			close(fd);
1303 			return IPACM_FAILURE;
1304 		}
1305 	}
1306 	else
1307 	{
1308 		if (m_filtering.DeleteFilteringHdls(&lan_wan_fl_rule_hdl[0], IPA_IP_v4, 1) == false)
1309 		{
1310 			IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
1311 			close(fd);
1312 			return IPACM_FAILURE;
1313 		}
1314 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
1315 		sta_ul_v4_set = false;
1316 	}
1317 
1318 	/* clean MTU rules if needed */
1319 	handle_private_subnet_android(IPA_IP_v4);
1320 
1321 	close(fd);
1322 	return IPACM_SUCCESS;
1323 }
1324 
1325 /* handle new_address event*/
handle_addr_evt(ipacm_event_data_addr * data)1326 int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data)
1327 {
1328 	struct ipa_ioc_add_rt_rule *rt_rule;
1329 	struct ipa_rt_rule_add *rt_rule_entry;
1330 	const int NUM_RULES = 1;
1331 	uint32_t num_ipv6_addr;
1332 	int res = IPACM_SUCCESS;
1333 #ifdef FEATURE_IPACM_HAL
1334 	IPACM_OffloadManager* OffloadMng;
1335 #endif
1336 
1337 	IPACMDBG_H("set route/filter rule ip-type: %d \n", data->iptype);
1338 
1339 /* Add private subnet*/
1340 #ifdef FEATURE_IPA_ANDROID
1341 	if (data->iptype == IPA_IP_v4)
1342 	{
1343 		IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
1344 		if_ipv4_subnet = (data->ipv4_addr >> 8) << 8;
1345 		IPACMDBG_H(" Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
1346 		if(IPACM_Iface::ipacmcfg->AddPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
1347 		{
1348 			IPACMERR(" can't Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
1349 		}
1350 	}
1351 #endif /* defined(FEATURE_IPA_ANDROID)*/
1352 
1353 	/* Update the IP Type. */
1354 	config_ip_type(data->iptype);
1355 
1356 	if (data->iptype == IPA_IP_v4)
1357 	{
1358 		rt_rule = (struct ipa_ioc_add_rt_rule *)
1359 			 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
1360 							NUM_RULES * sizeof(struct ipa_rt_rule_add));
1361 
1362 		if (!rt_rule)
1363 		{
1364 			IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
1365 			return IPACM_FAILURE;
1366 		}
1367 
1368 		rt_rule->commit = 1;
1369 		rt_rule->num_rules = NUM_RULES;
1370 		rt_rule->ip = data->iptype;
1371 		rt_rule_entry = &rt_rule->rules[0];
1372 		rt_rule_entry->at_rear = false;
1373 		rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;  //go to A5
1374 		rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
1375 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
1376 		rt_rule_entry->rule.attrib.u.v4.dst_addr      = data->ipv4_addr;
1377 		rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
1378 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
1379 			rt_rule_entry->rule.hashable = true;
1380 		if (false == m_routing.AddRoutingRule(rt_rule))
1381 		{
1382 			IPACMERR("Routing rule addition failed!\n");
1383 			res = IPACM_FAILURE;
1384 			goto fail;
1385 		}
1386 		else if (rt_rule_entry->status)
1387 		{
1388 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1389 			res = rt_rule_entry->status;
1390 			goto fail;
1391 		}
1392 		dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
1393 		IPACMDBG_H("ipv4 iface rt-rule hdl1=0x%x\n", dft_rt_rule_hdl[0]);
1394 		/* initial multicast/broadcast/fragment filter rule */
1395 
1396 		init_fl_rule(data->iptype);
1397 #ifdef FEATURE_L2TP
1398 		if(ipa_if_cate == WLAN_IF)
1399 		{
1400 			add_tcp_syn_flt_rule(data->iptype);
1401 		}
1402 #endif
1403 		install_ipv4_icmp_flt_rule();
1404 
1405 		/* populate the flt rule offset for eth bridge */
1406 		eth_bridge_flt_rule_offset[data->iptype] = ipv4_icmp_flt_rule_hdl[0];
1407 		eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL, NULL, NULL, IPA_CLIENT_MAX);
1408 	}
1409 	else
1410 	{
1411 	    /* check if see that v6-addr already or not*/
1412 	    for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
1413 	    {
1414             if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
1415 	           (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
1416 	           (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
1417 	           (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
1418             {
1419 				return IPACM_FAILURE;
1420 				break;
1421 	        }
1422 	    }
1423 
1424 		rt_rule = (struct ipa_ioc_add_rt_rule *)
1425 			 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
1426 							NUM_RULES * sizeof(struct ipa_rt_rule_add));
1427 
1428 		if (!rt_rule)
1429 		{
1430 			IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
1431 			return IPACM_FAILURE;
1432 		}
1433 
1434 		rt_rule->commit = 1;
1435 		rt_rule->num_rules = NUM_RULES;
1436 		rt_rule->ip = data->iptype;
1437 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
1438 
1439 		rt_rule_entry = &rt_rule->rules[0];
1440 		rt_rule_entry->at_rear = false;
1441 		rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;  //go to A5
1442 		rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
1443 		rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0];
1444 		rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1];
1445 		rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2];
1446 		rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3];
1447 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
1448 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
1449 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
1450 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
1451 		ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
1452 		ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
1453 		ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
1454 		ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
1455 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
1456 			rt_rule_entry->rule.hashable = true;
1457 		if (false == m_routing.AddRoutingRule(rt_rule))
1458 		{
1459 			IPACMERR("Routing rule addition failed!\n");
1460 			res = IPACM_FAILURE;
1461 			goto fail;
1462 		}
1463 		else if (rt_rule_entry->status)
1464 		{
1465 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1466 			res = rt_rule_entry->status;
1467 			goto fail;
1468 		}
1469 		dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
1470 
1471 		/* setup same rule for v6_wan table*/
1472 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
1473 		if (false == m_routing.AddRoutingRule(rt_rule))
1474 		{
1475 			IPACMERR("Routing rule addition failed!\n");
1476 			res = IPACM_FAILURE;
1477 			goto fail;
1478 		}
1479 		else if (rt_rule_entry->status)
1480 		{
1481 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1482 			res = rt_rule_entry->status;
1483 			goto fail;
1484 		}
1485 		dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
1486 
1487 		IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n",
1488 		          dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
1489 		          dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6);
1490 
1491 		if (num_dft_rt_v6 == 0)
1492 		{
1493 #ifdef FEATURE_L2TP
1494 			if(ipa_if_cate == WLAN_IF)
1495 			{
1496 				add_tcp_syn_flt_rule(data->iptype);
1497 			}
1498 			else if(ipa_if_cate == ODU_IF)
1499 			{
1500 				add_tcp_syn_flt_rule_l2tp(IPA_IP_v4);
1501 				add_tcp_syn_flt_rule_l2tp(IPA_IP_v6);
1502 			}
1503 #endif
1504 			install_ipv6_icmp_flt_rule();
1505 
1506 			/* populate the flt rule offset for eth bridge */
1507 			eth_bridge_flt_rule_offset[data->iptype] = ipv6_icmp_flt_rule_hdl[0];
1508 			eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL, NULL, NULL, IPA_CLIENT_MAX);
1509 
1510 			init_fl_rule(data->iptype);
1511 		}
1512 		num_dft_rt_v6++;
1513 		IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
1514 	}
1515 
1516 #ifdef FEATURE_IPACM_HAL
1517 	/* check if having pending add_downstream cache*/
1518 	OffloadMng = IPACM_OffloadManager::GetInstance();
1519 	if (OffloadMng == NULL) {
1520 		IPACMERR("failed to get IPACM_OffloadManager instance !\n");
1521 	} else {
1522 		IPACMDBG_H(" check iface %s if having add_downstream cache events\n", dev_name);
1523 		OffloadMng->search_framwork_cache(dev_name);
1524 	}
1525 #endif
1526 
1527 	IPACMDBG_H("finish route/filter rule ip-type: %d, res(%d)\n", data->iptype, res);
1528 
1529 fail:
1530 	free(rt_rule);
1531 	return res;
1532 }
1533 
1534 /* configure private subnet filter rules*/
handle_private_subnet(ipa_ip_type iptype)1535 int IPACM_Lan::handle_private_subnet(ipa_ip_type iptype)
1536 {
1537 	struct ipa_flt_rule_add flt_rule_entry;
1538 	int i;
1539 	bool result;
1540 
1541 	ipa_ioc_add_flt_rule *m_pFilteringTable;
1542 
1543 	IPACMDBG_H("lan->handle_private_subnet(); set route/filter rule \n");
1544 
1545 	if (rx_prop == NULL)
1546 	{
1547 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
1548 		return IPACM_SUCCESS;
1549 	}
1550 
1551 	if (iptype == IPA_IP_v4)
1552 	{
1553 
1554 		m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
1555 			 calloc(1,
1556 							sizeof(struct ipa_ioc_add_flt_rule) +
1557 							(IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_add)
1558 							);
1559 		if (!m_pFilteringTable)
1560 		{
1561 			PERROR("Error Locate ipa_flt_rule_add memory...\n");
1562 			return IPACM_FAILURE;
1563 		}
1564 		m_pFilteringTable->commit = 1;
1565 		m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
1566 		m_pFilteringTable->global = false;
1567 		m_pFilteringTable->ip = IPA_IP_v4;
1568 		m_pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
1569 
1570 		/* Make LAN-traffic always go A5, use default IPA-RT table */
1571 		if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4))
1572 		{
1573 			IPACMERR("LAN m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_default_v4);
1574 			free(m_pFilteringTable);
1575 			return IPACM_FAILURE;
1576 		}
1577 
1578 		for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
1579 		{
1580 			memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
1581 			flt_rule_entry.at_rear = true;
1582 			flt_rule_entry.rule.retain_hdr = 1;
1583 			flt_rule_entry.flt_rule_hdl = -1;
1584 			flt_rule_entry.status = -1;
1585 			flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
1586 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
1587 				flt_rule_entry.rule.hashable = true;
1588                         /* Support private subnet feature including guest-AP can't talk to primary AP etc */
1589 			flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl;
1590 			IPACMDBG_H(" private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name);
1591 
1592 			memcpy(&flt_rule_entry.rule.attrib,
1593 						 &rx_prop->rx[0].attrib,
1594 						 sizeof(flt_rule_entry.rule.attrib));
1595 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1596 			flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
1597 			flt_rule_entry.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
1598 			memcpy(&(m_pFilteringTable->rules[i]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
1599 			IPACMDBG_H("Loop %d  5\n", i);
1600 		}
1601 
1602 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
1603 		/* use index hw-counter */
1604 		if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
1605 		{
1606 			IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
1607 			result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
1608 		} else {
1609 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
1610 		}
1611 #else
1612 		result = m_filtering.AddFilteringRule(m_pFilteringTable);
1613 #endif
1614 
1615 		if (result == false)
1616 		{
1617 			IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
1618 			free(m_pFilteringTable);
1619 			return IPACM_FAILURE;
1620 		}
1621 		IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
1622 
1623 		/* copy filter rule hdls */
1624 		for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
1625 		{
1626 			private_fl_rule_hdl[i] = m_pFilteringTable->rules[i].flt_rule_hdl;
1627 		}
1628 		free(m_pFilteringTable);
1629 	}
1630 	else
1631 	{
1632 		IPACMDBG_H("No private subnet rules for ipv6 iface %s\n", dev_name);
1633 	}
1634 	return IPACM_SUCCESS;
1635 }
1636 
1637 
1638 /* for STA mode wan up:  configure filter rule for wan_up event*/
handle_wan_up(ipa_ip_type ip_type)1639 int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type)
1640 {
1641 	struct ipa_flt_rule_add flt_rule_entry;
1642 	int len = 0;
1643 	ipa_ioc_add_flt_rule *m_pFilteringTable;
1644 	bool result;
1645 
1646 	IPACMDBG_H("set WAN interface as default filter rule\n");
1647 
1648 	if (rx_prop == NULL)
1649 	{
1650 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
1651 		return IPACM_SUCCESS;
1652 	}
1653 
1654 	if(ip_type == IPA_IP_v4)
1655 	{
1656 		/* add MTU rules for ipv4 */
1657 		handle_private_subnet_android(IPA_IP_v4);
1658 
1659 		/* Update ipv6 MTU here if WAN_v6 is up and filter rules were installed */
1660 		if (IPACM_Wan::isWanUP_V6(ipa_if_num))
1661 		{
1662 			if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1] ) {
1663 				delete_ipv6_prefix_flt_rule();
1664 				install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
1665 			}
1666 		}
1667 
1668 		if(sta_ul_v4_set == true)
1669 		{
1670 			IPACMDBG_H("Filetring rule for IPV4 of STA mode is already configured, sta_ul_v4_set: %d\n",sta_ul_v4_set);
1671 			return IPACM_FAILURE;
1672 		}
1673 		len = sizeof(struct ipa_ioc_add_flt_rule) + (1 * sizeof(struct ipa_flt_rule_add));
1674 		m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
1675 		if (m_pFilteringTable == NULL)
1676 		{
1677 			PERROR("Error Locate ipa_flt_rule_add memory...\n");
1678 			return IPACM_FAILURE;
1679 		}
1680 
1681 		m_pFilteringTable->commit = 1;
1682 		m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
1683 		m_pFilteringTable->global = false;
1684 		m_pFilteringTable->ip = IPA_IP_v4;
1685 		m_pFilteringTable->num_rules = (uint8_t)1;
1686 
1687 		IPACMDBG_H("Retrieving routing hanle for table: %s\n",
1688 						 IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name);
1689 		if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4))
1690 		{
1691 			IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n",
1692 							 &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4);
1693 			free(m_pFilteringTable);
1694 			return IPACM_FAILURE;
1695 		}
1696 		IPACMDBG_H("Routing hanle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl);
1697 
1698 
1699 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields
1700 		flt_rule_entry.at_rear = true;
1701 		flt_rule_entry.flt_rule_hdl = -1;
1702 		flt_rule_entry.status = -1;
1703 		if(IPACM_Wan::isWan_Bridge_Mode())
1704 		{
1705 			flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
1706 		}
1707 		else
1708 		{
1709 			flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; //IPA_PASS_TO_ROUTING
1710 		}
1711 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
1712 			flt_rule_entry.rule.hashable = true;
1713 		flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl;
1714 
1715 		memcpy(&flt_rule_entry.rule.attrib,
1716 					 &rx_prop->rx[0].attrib,
1717 					 sizeof(flt_rule_entry.rule.attrib));
1718 
1719 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1720 		flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0;
1721 		flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0;
1722 
1723 /* only offload UL traffic of certain clients */
1724 #ifdef FEATURE_IPACM_HAL
1725 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
1726 		flt_rule_entry.rule.attrib.u.v4.src_addr_mask = prefix[IPA_IP_v4].v4Mask;
1727 		flt_rule_entry.rule.attrib.u.v4.src_addr = prefix[IPA_IP_v4].v4Addr;
1728 #endif
1729 		memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry));
1730 
1731 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
1732 		/* use index hw-counter */
1733 		if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
1734 		{
1735 			IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
1736 			result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
1737 		} else {
1738 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
1739 		}
1740 #else
1741 		result = m_filtering.AddFilteringRule(m_pFilteringTable);
1742 #endif
1743 		if (result == false)
1744 		{
1745 			IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
1746 			free(m_pFilteringTable);
1747 			return IPACM_FAILURE;
1748 		}
1749 		else
1750 		{
1751 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
1752 			IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
1753 							 m_pFilteringTable->rules[0].flt_rule_hdl,
1754 							 m_pFilteringTable->rules[0].status);
1755 		}
1756 
1757 		sta_ul_v4_set = true;
1758 		/* copy filter hdls  */
1759 		lan_wan_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
1760 		free(m_pFilteringTable);
1761 	}
1762 	else if(ip_type == IPA_IP_v6)
1763 	{
1764 		if(sta_ul_v6_set == true)
1765 		{
1766 			IPACMDBG_H("Filetring rule for IPV6 of STA mode is already configured, sta_ul_v6_set: %d\n",sta_ul_v6_set);
1767 			return IPACM_FAILURE;
1768 		}
1769 		/* add default v6 filter rule */
1770 		m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
1771 			 calloc(1, sizeof(struct ipa_ioc_add_flt_rule) +
1772 					1 * sizeof(struct ipa_flt_rule_add));
1773 
1774 		if (!m_pFilteringTable)
1775 		{
1776 			PERROR("Error Locate ipa_flt_rule_add memory...\n");
1777 			return IPACM_FAILURE;
1778 		}
1779 
1780 		m_pFilteringTable->commit = 1;
1781 		m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
1782 		m_pFilteringTable->global = false;
1783 		m_pFilteringTable->ip = IPA_IP_v6;
1784 		m_pFilteringTable->num_rules = (uint8_t)1;
1785 
1786 		if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6))
1787 		{
1788 			IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_v6);
1789 			free(m_pFilteringTable);
1790 			return IPACM_FAILURE;
1791 		}
1792 
1793 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
1794 
1795 		flt_rule_entry.at_rear = true;
1796 		flt_rule_entry.flt_rule_hdl = -1;
1797 		flt_rule_entry.status = -1;
1798 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
1799 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
1800 			flt_rule_entry.rule.hashable = true;
1801 		flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_v6.hdl;
1802 
1803 		memcpy(&flt_rule_entry.rule.attrib,
1804 					 &rx_prop->rx[0].attrib,
1805 					 sizeof(flt_rule_entry.rule.attrib));
1806 
1807 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1808 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;
1809 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
1810 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
1811 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
1812 		flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000;
1813 		flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
1814 		flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
1815 		flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
1816 
1817 /* only offload UL traffic of certain clients */
1818 #ifdef FEATURE_IPACM_HAL
1819 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
1820 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[0] = prefix[IPA_IP_v6].v6Mask[0];
1821 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[1] = prefix[IPA_IP_v6].v6Mask[1];
1822 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[2] = prefix[IPA_IP_v6].v6Mask[2];
1823 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[3] = prefix[IPA_IP_v6].v6Mask[3];
1824 		flt_rule_entry.rule.attrib.u.v6.src_addr[0] = prefix[IPA_IP_v6].v6Addr[0];
1825 		flt_rule_entry.rule.attrib.u.v6.src_addr[1] = prefix[IPA_IP_v6].v6Addr[1];
1826 		flt_rule_entry.rule.attrib.u.v6.src_addr[2] = prefix[IPA_IP_v6].v6Addr[2];
1827 		flt_rule_entry.rule.attrib.u.v6.src_addr[3] = prefix[IPA_IP_v6].v6Addr[3];
1828 
1829 #endif
1830 		memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
1831 
1832 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
1833 		/* use index hw-counter */
1834 		if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
1835 		{
1836 			IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
1837 			result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
1838 		} else {
1839 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
1840 		}
1841 #else
1842 		result = m_filtering.AddFilteringRule(m_pFilteringTable);
1843 #endif
1844 
1845 		if (result == false)
1846 		{
1847 			IPACMERR("Error Adding Filtering rule, aborting...\n");
1848 			free(m_pFilteringTable);
1849 			return IPACM_FAILURE;
1850 		}
1851 		else
1852 		{
1853 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
1854 			IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
1855 		}
1856 
1857 		sta_ul_v6_set = true;
1858 		/* copy filter hdls */
1859 		dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES] = m_pFilteringTable->rules[0].flt_rule_hdl;
1860 		free(m_pFilteringTable);
1861 	}
1862 
1863 	return IPACM_SUCCESS;
1864 }
1865 
handle_wan_up_ex(ipacm_ext_prop * ext_prop,ipa_ip_type iptype,uint8_t xlat_mux_id)1866 int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, uint8_t xlat_mux_id)
1867 {
1868 	int fd, ret = IPACM_SUCCESS;
1869 	uint32_t cnt;
1870 	IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg;
1871 	struct ipa_ioc_write_qmapid mux;
1872 
1873 	/* for newer versions metadata is overridden by NAT metadata replacement for IPAv4 and up */
1874 	/* this is still needed for IPv6 traffic in case qmapid need to be used */
1875 	if(rx_prop != NULL)
1876 	{
1877 		/* give mux ID of the default PDN to IPA-driver for WLAN/LAN pkts */
1878 		fd = open(IPA_DEVICE_NAME, O_RDWR);
1879 		if (0 == fd)
1880 		{
1881 			IPACMDBG_H("Failed opening %s.\n", IPA_DEVICE_NAME);
1882 			return IPACM_FAILURE;
1883 		}
1884 
1885 		mux.qmap_id = ipacm_config->GetQmapId();
1886 		IPACMDBG("get mux id %d for rx-endpoint\n", mux.qmap_id);
1887 		for(cnt=0; cnt<rx_prop->num_rx_props; cnt++)
1888 		{
1889 			mux.client = rx_prop->rx[cnt].src_pipe;
1890 			ret = ioctl(fd, IPA_IOC_WRITE_QMAPID, &mux);
1891 			if (ret)
1892 			{
1893 				IPACMERR("Failed to write mux id %d\n", mux.qmap_id);
1894 				close(fd);
1895 				return IPACM_FAILURE;
1896 			}
1897 		}
1898 		close(fd);
1899 	}
1900 
1901 	/* check only add static UL filter rule once */
1902 	if (iptype ==IPA_IP_v6 && modem_ul_v6_set == false)
1903 	{
1904 		IPACMDBG_H("IPA_IP_v6 num_dft_rt_v6 %d xlat_mux_id: %d modem_ul_v6_set: %d\n", num_dft_rt_v6, xlat_mux_id, modem_ul_v6_set);
1905 		ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
1906 		modem_ul_v6_set = true;
1907 	} else if (iptype ==IPA_IP_v4 && modem_ul_v4_set == false) {
1908 		/* add MTU rules for ipv4 */
1909 		handle_private_subnet_android(IPA_IP_v4);
1910 
1911 		/* Update ipv6 MTU here if WAN_v6 is up and filter rules were installed */
1912 		if (IPACM_Wan::isWanUP_V6(ipa_if_num))
1913 		{
1914 			if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1] ) {
1915 				delete_ipv6_prefix_flt_rule();
1916 				install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
1917 			}
1918 		}
1919 
1920 		IPACMDBG_H("check getXlat_Mux_Id:%d\n", IPACM_Wan::getXlat_Mux_Id());
1921 		IPACMDBG_H("IPA_IP_v4 xlat_mux_id: %d, modem_ul_v4_set %d\n", xlat_mux_id, modem_ul_v4_set);
1922 		ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
1923 		modem_ul_v4_set = true;
1924 	} else {
1925 		IPACMDBG_H("ip-type: %d modem_ul_v4_set: %d, modem_ul_v6_set %d\n", iptype, modem_ul_v4_set, modem_ul_v6_set);
1926 	}
1927 	return ret;
1928 }
1929 
1930 /* handle ETH client initial, construct full headers (tx property) */
handle_eth_hdr_init(uint8_t * mac_addr)1931 int IPACM_Lan::handle_eth_hdr_init(uint8_t *mac_addr)
1932 {
1933 
1934 #define ETH_IFACE_INDEX_LEN 2
1935 
1936 	int res = IPACM_SUCCESS, len = 0;
1937 	char index[ETH_IFACE_INDEX_LEN];
1938 	struct ipa_ioc_copy_hdr sCopyHeader;
1939 	struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
1940 	uint32_t cnt;
1941 	int clnt_indx;
1942 
1943 	clnt_indx = get_eth_client_index(mac_addr);
1944 
1945 	if (clnt_indx != IPACM_INVALID_INDEX)
1946 	{
1947 		IPACMERR("eth client is found/attached already with index %d \n", clnt_indx);
1948 		return IPACM_FAILURE;
1949 	}
1950 
1951 	/* add header to IPA */
1952 	if (num_eth_client >= IPA_MAX_NUM_ETH_CLIENTS)
1953 	{
1954 		IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_ETH_CLIENTS);
1955 		return IPACM_FAILURE;
1956 	}
1957 
1958 	IPACMDBG_H("ETH client number: %d\n", num_eth_client);
1959 
1960 	memcpy(get_client_memptr(eth_client, num_eth_client)->mac,
1961 				 mac_addr,
1962 				 sizeof(get_client_memptr(eth_client, num_eth_client)->mac));
1963 
1964 
1965 	IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1966 					 mac_addr[0], mac_addr[1], mac_addr[2],
1967 					 mac_addr[3], mac_addr[4], mac_addr[5]);
1968 
1969 	IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1970 					 get_client_memptr(eth_client, num_eth_client)->mac[0],
1971 					 get_client_memptr(eth_client, num_eth_client)->mac[1],
1972 					 get_client_memptr(eth_client, num_eth_client)->mac[2],
1973 					 get_client_memptr(eth_client, num_eth_client)->mac[3],
1974 					 get_client_memptr(eth_client, num_eth_client)->mac[4],
1975 					 get_client_memptr(eth_client, num_eth_client)->mac[5]);
1976 
1977 	/* add header to IPA */
1978 	if(tx_prop != NULL)
1979 	{
1980 		len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
1981 		pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
1982 		if (pHeaderDescriptor == NULL)
1983 		{
1984 			IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
1985 			return IPACM_FAILURE;
1986 		}
1987 
1988 		/* copy partial header for v4*/
1989 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
1990 		{
1991 				 if(tx_prop->tx[cnt].ip==IPA_IP_v4)
1992 				 {
1993 								IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt);
1994 								memset(&sCopyHeader, 0, sizeof(sCopyHeader));
1995 								memcpy(sCopyHeader.name,
1996 											 tx_prop->tx[cnt].hdr_name,
1997 											 sizeof(sCopyHeader.name));
1998 
1999 								IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
2000 								if (m_header.CopyHeader(&sCopyHeader) == false)
2001 								{
2002 									PERROR("ioctl copy header failed");
2003 									res = IPACM_FAILURE;
2004 									goto fail;
2005 								}
2006 
2007 								IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
2008 								IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
2009 								if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
2010 								{
2011 									IPACMERR("header oversize\n");
2012 									res = IPACM_FAILURE;
2013 									goto fail;
2014 								}
2015 								else
2016 								{
2017 									memcpy(pHeaderDescriptor->hdr[0].hdr,
2018 												 sCopyHeader.hdr,
2019 												 sCopyHeader.hdr_len);
2020 								}
2021 
2022 								/* copy client mac_addr to partial header */
2023 								if (sCopyHeader.is_eth2_ofst_valid)
2024 								{
2025 									memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
2026 											 mac_addr,
2027 											 IPA_MAC_ADDR_SIZE);
2028 								}
2029 								/* replace src mac to bridge mac_addr if any  */
2030 								if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
2031 								{
2032 									memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
2033 											IPACM_Iface::ipacmcfg->bridge_mac,
2034 											IPA_MAC_ADDR_SIZE);
2035 									IPACMDBG_H("device is in bridge mode \n");
2036 								}
2037 
2038 								pHeaderDescriptor->commit = true;
2039 								pHeaderDescriptor->num_hdrs = 1;
2040 
2041 								memset(pHeaderDescriptor->hdr[0].name, 0,
2042 											 sizeof(pHeaderDescriptor->hdr[0].name));
2043 
2044 								snprintf(index,sizeof(index), "%d", ipa_if_num);
2045 								strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
2046 								pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2047 								if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
2048 								{
2049 									IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
2050 									res = IPACM_FAILURE;
2051 									goto fail;
2052 								}
2053 
2054 								snprintf(index,sizeof(index), "%d", header_name_count);
2055 								if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
2056 								{
2057 									IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
2058 									res = IPACM_FAILURE;
2059 									goto fail;
2060 								}
2061 
2062 								pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
2063 								pHeaderDescriptor->hdr[0].hdr_hdl = -1;
2064 								pHeaderDescriptor->hdr[0].is_partial = 0;
2065 								pHeaderDescriptor->hdr[0].status = -1;
2066 
2067 					 if (m_header.AddHeader(pHeaderDescriptor) == false ||
2068 							pHeaderDescriptor->hdr[0].status != 0)
2069 					 {
2070 						IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
2071 						res = IPACM_FAILURE;
2072 						goto fail;
2073 					 }
2074 
2075 					get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
2076 					IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n",
2077 												 num_eth_client,
2078 												 pHeaderDescriptor->hdr[0].name,
2079 												 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4);
2080 									get_client_memptr(eth_client, num_eth_client)->ipv4_header_set=true;
2081 
2082 					break;
2083 				 }
2084 		}
2085 
2086 
2087 		/* copy partial header for v6*/
2088 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
2089 		{
2090 			if(tx_prop->tx[cnt].ip==IPA_IP_v6)
2091 			{
2092 
2093 				IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt);
2094 				memset(&sCopyHeader, 0, sizeof(sCopyHeader));
2095 				memcpy(sCopyHeader.name,
2096 						tx_prop->tx[cnt].hdr_name,
2097 							sizeof(sCopyHeader.name));
2098 
2099 				IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
2100 				if (m_header.CopyHeader(&sCopyHeader) == false)
2101 				{
2102 					PERROR("ioctl copy header failed");
2103 					res = IPACM_FAILURE;
2104 					goto fail;
2105 				}
2106 
2107 				IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
2108 				IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
2109 				if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
2110 				{
2111 					IPACMERR("header oversize\n");
2112 					res = IPACM_FAILURE;
2113 					goto fail;
2114 				}
2115 				else
2116 				{
2117 					memcpy(pHeaderDescriptor->hdr[0].hdr,
2118 							sCopyHeader.hdr,
2119 								sCopyHeader.hdr_len);
2120 				}
2121 
2122 				/* copy client mac_addr to partial header */
2123 				if (sCopyHeader.is_eth2_ofst_valid)
2124 				{
2125 					memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
2126 						mac_addr,
2127 						IPA_MAC_ADDR_SIZE);
2128 				}
2129 				/* replace src mac to bridge mac_addr if any  */
2130 				if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
2131 				{
2132 					memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
2133 							IPACM_Iface::ipacmcfg->bridge_mac,
2134 							IPA_MAC_ADDR_SIZE);
2135 					IPACMDBG_H("device is in bridge mode \n");
2136 				}
2137 
2138 				pHeaderDescriptor->commit = true;
2139 				pHeaderDescriptor->num_hdrs = 1;
2140 
2141 				memset(pHeaderDescriptor->hdr[0].name, 0,
2142 					 sizeof(pHeaderDescriptor->hdr[0].name));
2143 
2144 				snprintf(index,sizeof(index), "%d", ipa_if_num);
2145 				strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
2146 				pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2147 				if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
2148 				{
2149 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
2150 					res = IPACM_FAILURE;
2151 					goto fail;
2152 				}
2153 				snprintf(index,sizeof(index), "%d", header_name_count);
2154 				if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
2155 				{
2156 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
2157 					res = IPACM_FAILURE;
2158 					goto fail;
2159 				}
2160 
2161 				pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
2162 				pHeaderDescriptor->hdr[0].hdr_hdl = -1;
2163 				pHeaderDescriptor->hdr[0].is_partial = 0;
2164 				pHeaderDescriptor->hdr[0].status = -1;
2165 
2166 				if (m_header.AddHeader(pHeaderDescriptor) == false ||
2167 						pHeaderDescriptor->hdr[0].status != 0)
2168 				{
2169 					IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
2170 					res = IPACM_FAILURE;
2171 					goto fail;
2172 				}
2173 
2174 				get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
2175 				IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n",
2176 						 num_eth_client,
2177 						 pHeaderDescriptor->hdr[0].name,
2178 									 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6);
2179 
2180 									get_client_memptr(eth_client, num_eth_client)->ipv6_header_set=true;
2181 
2182 				break;
2183 
2184 			}
2185 		}
2186 		/* initialize wifi client*/
2187 		get_client_memptr(eth_client, num_eth_client)->route_rule_set_v4 = false;
2188 		get_client_memptr(eth_client, num_eth_client)->route_rule_set_v6 = 0;
2189 		get_client_memptr(eth_client, num_eth_client)->ipv4_set = false;
2190 		get_client_memptr(eth_client, num_eth_client)->ipv6_set = 0;
2191 		num_eth_client++;
2192 		header_name_count++; //keep increasing header_name_count
2193 		res = IPACM_SUCCESS;
2194 		IPACMDBG_H("eth client number: %d\n", num_eth_client);
2195 	}
2196 	else
2197 	{
2198 		return res;
2199 	}
2200 fail:
2201 	free(pHeaderDescriptor);
2202 	return res;
2203 }
2204 
2205 /*handle eth client */
handle_eth_client_ipaddr(ipacm_event_data_all * data)2206 int IPACM_Lan::handle_eth_client_ipaddr(ipacm_event_data_all *data)
2207 {
2208 	int clnt_indx;
2209 	int v6_num;
2210 	uint32_t ipv6_link_local_prefix = 0xFE800000;
2211 	uint32_t ipv6_link_local_prefix_mask = 0xFFC00000;
2212 
2213 	IPACMDBG_H("number of eth clients: %d\n", num_eth_client);
2214 	IPACMDBG_H("event MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
2215 					 data->mac_addr[0],
2216 					 data->mac_addr[1],
2217 					 data->mac_addr[2],
2218 					 data->mac_addr[3],
2219 					 data->mac_addr[4],
2220 					 data->mac_addr[5]);
2221 
2222 	clnt_indx = get_eth_client_index(data->mac_addr);
2223 
2224 		if (clnt_indx == IPACM_INVALID_INDEX)
2225 		{
2226 			IPACMERR("eth client not found/attached \n");
2227 			return IPACM_FAILURE;
2228 		}
2229 
2230 	IPACMDBG_H("Ip-type received %d\n", data->iptype);
2231 	if (data->iptype == IPA_IP_v4)
2232 	{
2233 		IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr);
2234 		if (data->ipv4_addr != 0) /* not 0.0.0.0 */
2235 		{
2236 			if (get_client_memptr(eth_client, clnt_indx)->ipv4_set == false)
2237 			{
2238 				get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr;
2239 				get_client_memptr(eth_client, clnt_indx)->ipv4_set = true;
2240 			}
2241 			else
2242 			{
2243 			   /* check if client got new IPv4 address*/
2244 			   if(data->ipv4_addr == get_client_memptr(eth_client, clnt_indx)->v4_addr)
2245 			   {
2246 				IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx);
2247 				 return IPACM_FAILURE;
2248 			   }
2249 			   else
2250 			   {
2251 					IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
2252 					/* delete NAT rules first */
2253 					CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clnt_indx)->v4_addr);
2254 					delete_eth_rtrules(clnt_indx,IPA_IP_v4);
2255 					get_client_memptr(eth_client, clnt_indx)->route_rule_set_v4 = false;
2256 					get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr;
2257 				}
2258 			}
2259 		}
2260 		else
2261 		{
2262 		    IPACMDBG_H("Invalid client IPv4 address \n");
2263 		    return IPACM_FAILURE;
2264 		}
2265 	}
2266 	else
2267 	{
2268 		if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
2269 				(data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) /* check if all 0 not valid ipv6 address */
2270 		{
2271 			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]);
2272 			if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) &&
2273 				memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0)
2274 			{
2275 				IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n");
2276 				return IPACM_FAILURE;
2277 			}
2278 
2279             if(get_client_memptr(eth_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
2280 			{
2281 
2282 		       for(v6_num=0;v6_num < get_client_memptr(eth_client, clnt_indx)->ipv6_set;v6_num++)
2283 				{
2284 					if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][0] &&
2285 			           data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][1] &&
2286 			  	        data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][2] &&
2287 			  	         data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][3])
2288 					{
2289 						IPACMDBG_H("Already see this ipv6 addr at position: %d for client:%d\n", v6_num, clnt_indx);
2290 						return IPACM_FAILURE; /* not setup the RT rules*/
2291 					}
2292 				}
2293 
2294 		       /* not see this ipv6 before for wifi client*/
2295 			   get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0];
2296 			   get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1];
2297 			   get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2];
2298 			   get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3];
2299 			   get_client_memptr(eth_client, clnt_indx)->ipv6_set++;
2300 		    }
2301 		    else
2302 		    {
2303 		        IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx);
2304 				return IPACM_FAILURE; /* not setup the RT rules*/
2305 		    }
2306 		}
2307 		else
2308 		{
2309 			IPACMDBG_H("Invalid IPV6 address\n");
2310 			return IPACM_FAILURE;
2311 		}
2312 	}
2313 
2314 	return IPACM_SUCCESS;
2315 }
2316 
2317 /*handle eth client routing rule*/
handle_eth_client_route_rule(uint8_t * mac_addr,ipa_ip_type iptype)2318 int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype)
2319 {
2320 	struct ipa_ioc_add_rt_rule *rt_rule;
2321 	struct ipa_rt_rule_add *rt_rule_entry;
2322 	uint32_t tx_index;
2323 	int eth_index,v6_num;
2324 	const int NUM = 1;
2325 
2326 	if(tx_prop == NULL)
2327 	{
2328 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
2329 		return IPACM_SUCCESS;
2330 	}
2331 
2332 	IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
2333 					 mac_addr[0], mac_addr[1], mac_addr[2],
2334 					 mac_addr[3], mac_addr[4], mac_addr[5]);
2335 
2336 	eth_index = get_eth_client_index(mac_addr);
2337 	if (eth_index == IPACM_INVALID_INDEX)
2338 	{
2339 		IPACMDBG_H("eth client not found/attached \n");
2340 		return IPACM_SUCCESS;
2341 	}
2342 
2343 	if (iptype==IPA_IP_v4) {
2344 		IPACMDBG_H("eth client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", eth_index, iptype,
2345 					 get_client_memptr(eth_client, eth_index)->ipv4_set,
2346 					 get_client_memptr(eth_client, eth_index)->route_rule_set_v4);
2347 	} else {
2348 		IPACMDBG_H("eth client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", eth_index, iptype,
2349 					 get_client_memptr(eth_client, eth_index)->ipv6_set,
2350 					 get_client_memptr(eth_client, eth_index)->route_rule_set_v6);
2351 	}
2352 	/* Add default routing rules if not set yet */
2353 	if ((iptype == IPA_IP_v4
2354 			 && get_client_memptr(eth_client, eth_index)->route_rule_set_v4 == false
2355 			 && get_client_memptr(eth_client, eth_index)->ipv4_set == true)
2356 			|| (iptype == IPA_IP_v6
2357 		            && get_client_memptr(eth_client, eth_index)->route_rule_set_v6 < get_client_memptr(eth_client, eth_index)->ipv6_set
2358 					))
2359 	{
2360 		if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
2361 		{
2362 			/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
2363 			IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2364 			if (tx_prop != NULL)
2365 			{
2366 				IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
2367 				IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
2368 			}
2369 		}
2370 		rt_rule = (struct ipa_ioc_add_rt_rule *)
2371 			 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
2372 						NUM * sizeof(struct ipa_rt_rule_add));
2373 
2374 		if (rt_rule == NULL)
2375 		{
2376 			PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n");
2377 			return IPACM_FAILURE;
2378 		}
2379 
2380 		rt_rule->commit = 1;
2381 		rt_rule->num_rules = (uint8_t)NUM;
2382 		rt_rule->ip = iptype;
2383 
2384 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2385 		{
2386 			if(iptype != tx_prop->tx[tx_index].ip)
2387 		    {
2388 				IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n",
2389 						tx_index, tx_prop->tx[tx_index].ip,iptype);
2390 		   	        continue;
2391 		    }
2392 
2393 			rt_rule_entry = &rt_rule->rules[0];
2394 			rt_rule_entry->at_rear = 0;
2395 
2396 			if (iptype == IPA_IP_v4)
2397 			{
2398 		        IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", eth_index,
2399 		  		        get_client_memptr(eth_client, eth_index)->v4_addr);
2400 
2401                 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
2402 		  				 eth_index,
2403 		  				 get_client_memptr(eth_client, eth_index)->hdr_hdl_v4);
2404 				strlcpy(rt_rule->rt_tbl_name,
2405 								IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name,
2406 								sizeof(rt_rule->rt_tbl_name));
2407 				rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2408 			    rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2409 			    memcpy(&rt_rule_entry->rule.attrib,
2410 						 &tx_prop->tx[tx_index].attrib,
2411 						 sizeof(rt_rule_entry->rule.attrib));
2412 			    rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2413 		   	    rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v4;
2414 				rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr;
2415 				rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
2416 
2417 				if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0)
2418 				{
2419 					rt_rule_entry->rule.hashable = true;
2420 				}
2421 
2422 				if (false == m_routing.AddRoutingRule(rt_rule))
2423 				{
2424 					IPACMERR("Routing rule addition failed!\n");
2425 					free(rt_rule);
2426 					return IPACM_FAILURE;
2427 				}
2428 
2429 			    /* copy ipv4 RT hdl */
2430 		        get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 =
2431   	   	        rt_rule->rules[0].rt_rule_hdl;
2432 		        IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2433 		      	get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4, iptype);
2434 			} else {
2435 
2436 		        for(v6_num = get_client_memptr(eth_client, eth_index)->route_rule_set_v6;v6_num < get_client_memptr(eth_client, eth_index)->ipv6_set;v6_num++)
2437 			    {
2438                     IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
2439 		  	    			 eth_index,
2440 		  	    			 get_client_memptr(eth_client, eth_index)->hdr_hdl_v6);
2441 
2442 		            /* v6 LAN_RT_TBL */
2443 				strlcpy(rt_rule->rt_tbl_name,
2444 			    					IPACM_Iface::ipacmcfg->rt_tbl_v6.name,
2445 			    					sizeof(rt_rule->rt_tbl_name));
2446 				rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2447 		            /* Support QCMAP LAN traffic feature, send to A5 */
2448 					rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
2449 			        memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib));
2450 		   	        rt_rule_entry->rule.hdr_hdl = 0;
2451 			        rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2452 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0];
2453 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1];
2454 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2];
2455 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3];
2456 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2457 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2458 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2459 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2460 					if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2461 						rt_rule_entry->rule.hashable = true;
2462 			if (false == m_routing.AddRoutingRule(rt_rule))
2463 			{
2464 				IPACMERR("Routing rule addition failed!\n");
2465 				free(rt_rule);
2466 				return IPACM_FAILURE;
2467 			}
2468 
2469 		            get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[v6_num] = rt_rule->rules[0].rt_rule_hdl;
2470 		            IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2471 		            				 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[v6_num], iptype);
2472 
2473 			        /*Copy same rule to v6 WAN RT TBL*/
2474 				strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
2475 				rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2476 				/* Downlink traffic from Wan iface, directly through IPA */
2477 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2478 			        memcpy(&rt_rule_entry->rule.attrib,
2479 						 &tx_prop->tx[tx_index].attrib,
2480 						 sizeof(rt_rule_entry->rule.attrib));
2481 		   	        rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v6;
2482 			        rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2483 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0];
2484 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1];
2485 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2];
2486 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3];
2487 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2488 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2489 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2490 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2491 					if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2492 						rt_rule_entry->rule.hashable = true;
2493 		            if (false == m_routing.AddRoutingRule(rt_rule))
2494 		            {
2495 							IPACMERR("Routing rule addition failed!\n");
2496 							free(rt_rule);
2497 							return IPACM_FAILURE;
2498 		            }
2499 
2500 		            get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num] = rt_rule->rules[0].rt_rule_hdl;
2501 					IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2502 		            				 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num], iptype);
2503 
2504 					/* send client-v6 info to pcie modem only with global ipv6 with tx_index = 1 one time*/
2505 					if(is_global_ipv6_addr(get_client_memptr(eth_client, eth_index)->v6_addr[v6_num]) && (IPACM_Wan::backhaul_mode == Q6_MHI_WAN))
2506 					{
2507 						if (add_connection(eth_index, v6_num))
2508 						{
2509 							IPACMERR("PCIE filter rule addition failed! (%d-client) %d v6-entry\n",eth_index, v6_num);
2510 						}
2511 					}
2512 			    }
2513 			}
2514 
2515 		} /* end of for loop */
2516 
2517 		free(rt_rule);
2518 
2519 		if (iptype == IPA_IP_v4)
2520 		{
2521 			get_client_memptr(eth_client, eth_index)->route_rule_set_v4 = true;
2522 		}
2523 		else
2524 		{
2525 			get_client_memptr(eth_client, eth_index)->route_rule_set_v6 = get_client_memptr(eth_client, eth_index)->ipv6_set;
2526 		}
2527 	}
2528 	return IPACM_SUCCESS;
2529 }
2530 
2531 /* handle odu client initial, construct full headers (tx property) */
handle_odu_hdr_init(uint8_t * mac_addr)2532 int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr)
2533 {
2534 	int res = IPACM_SUCCESS, len = 0;
2535 	struct ipa_ioc_copy_hdr sCopyHeader;
2536 	struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
2537 	uint32_t cnt;
2538 
2539 	IPACMDBG("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
2540 					 mac_addr[0], mac_addr[1], mac_addr[2],
2541 					 mac_addr[3], mac_addr[4], mac_addr[5]);
2542 
2543 	/* add header to IPA */
2544 	if(tx_prop != NULL)
2545 	{
2546 		len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
2547 		pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
2548 		if (pHeaderDescriptor == NULL)
2549 		{
2550 			IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
2551 			return IPACM_FAILURE;
2552 		}
2553 
2554 		/* copy partial header for v4*/
2555 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
2556 		{
2557 				 if(tx_prop->tx[cnt].ip==IPA_IP_v4)
2558 				 {
2559 								IPACMDBG("Got partial v4-header name from %d tx props\n", cnt);
2560 								memset(&sCopyHeader, 0, sizeof(sCopyHeader));
2561 								memcpy(sCopyHeader.name,
2562 											tx_prop->tx[cnt].hdr_name,
2563 											 sizeof(sCopyHeader.name));
2564 								IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
2565 								if (m_header.CopyHeader(&sCopyHeader) == false)
2566 								{
2567 									PERROR("ioctl copy header failed");
2568 									res = IPACM_FAILURE;
2569 									goto fail;
2570 								}
2571 								IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
2572 								if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
2573 								{
2574 									IPACMERR("header oversize\n");
2575 									res = IPACM_FAILURE;
2576 									goto fail;
2577 								}
2578 								else
2579 								{
2580 									memcpy(pHeaderDescriptor->hdr[0].hdr,
2581 												 sCopyHeader.hdr,
2582 												 sCopyHeader.hdr_len);
2583 								}
2584 								/* copy client mac_addr to partial header */
2585 								if (sCopyHeader.is_eth2_ofst_valid)
2586 								{
2587 									memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
2588 											 mac_addr,
2589 											 IPA_MAC_ADDR_SIZE);
2590 								}
2591 								/* replace src mac to bridge mac_addr if any  */
2592 								if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
2593 								{
2594 									memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
2595 											IPACM_Iface::ipacmcfg->bridge_mac,
2596 											IPA_MAC_ADDR_SIZE);
2597 									IPACMDBG_H("device is in bridge mode \n");
2598 								}
2599 
2600 								pHeaderDescriptor->commit = true;
2601 								pHeaderDescriptor->num_hdrs = 1;
2602 
2603 								memset(pHeaderDescriptor->hdr[0].name, 0,
2604 											 sizeof(pHeaderDescriptor->hdr[0].name));
2605 								strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name));
2606 								pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
2607 								pHeaderDescriptor->hdr[0].hdr_hdl = -1;
2608 								pHeaderDescriptor->hdr[0].is_partial = 0;
2609 								pHeaderDescriptor->hdr[0].status = -1;
2610 
2611 					 if (m_header.AddHeader(pHeaderDescriptor) == false ||
2612 							pHeaderDescriptor->hdr[0].status != 0)
2613 					 {
2614 						IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
2615 						res = IPACM_FAILURE;
2616 						goto fail;
2617 					 }
2618 
2619 					ODU_hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
2620 					ipv4_header_set = true ;
2621 					IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n",
2622 										 pHeaderDescriptor->hdr[0].name,
2623 												 ODU_hdr_hdl_v4);
2624 					break;
2625 				 }
2626 		}
2627 
2628 
2629 		/* copy partial header for v6*/
2630 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
2631 		{
2632 			if(tx_prop->tx[cnt].ip==IPA_IP_v6)
2633 			{
2634 
2635 				IPACMDBG("Got partial v6-header name from %d tx props\n", cnt);
2636 				memset(&sCopyHeader, 0, sizeof(sCopyHeader));
2637 				memcpy(sCopyHeader.name,
2638 						tx_prop->tx[cnt].hdr_name,
2639 							sizeof(sCopyHeader.name));
2640 
2641 				IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
2642 				if (m_header.CopyHeader(&sCopyHeader) == false)
2643 				{
2644 					PERROR("ioctl copy header failed");
2645 					res = IPACM_FAILURE;
2646 					goto fail;
2647 				}
2648 
2649 				IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
2650 				if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
2651 				{
2652 					IPACMERR("header oversize\n");
2653 					res = IPACM_FAILURE;
2654 					goto fail;
2655 				}
2656 				else
2657 				{
2658 					memcpy(pHeaderDescriptor->hdr[0].hdr,
2659 							sCopyHeader.hdr,
2660 								sCopyHeader.hdr_len);
2661 				}
2662 
2663 				/* copy client mac_addr to partial header */
2664 				if (sCopyHeader.is_eth2_ofst_valid)
2665 				{
2666 					memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
2667 					 mac_addr,
2668 					 IPA_MAC_ADDR_SIZE);
2669 				}
2670 				/* replace src mac to bridge mac_addr if any  */
2671 				if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
2672 				{
2673 					memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
2674 							IPACM_Iface::ipacmcfg->bridge_mac,
2675 							IPA_MAC_ADDR_SIZE);
2676 					IPACMDBG_H("device is in bridge mode \n");
2677 				}
2678 
2679 				pHeaderDescriptor->commit = true;
2680 				pHeaderDescriptor->num_hdrs = 1;
2681 
2682 				memset(pHeaderDescriptor->hdr[0].name, 0,
2683 					 sizeof(pHeaderDescriptor->hdr[0].name));
2684 
2685 				strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name));
2686 				pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
2687 				pHeaderDescriptor->hdr[0].hdr_hdl = -1;
2688 				pHeaderDescriptor->hdr[0].is_partial = 0;
2689 				pHeaderDescriptor->hdr[0].status = -1;
2690 
2691 				if (m_header.AddHeader(pHeaderDescriptor) == false ||
2692 						pHeaderDescriptor->hdr[0].status != 0)
2693 				{
2694 					IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
2695 					res = IPACM_FAILURE;
2696 					goto fail;
2697 				}
2698 
2699 				ODU_hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
2700 				ipv6_header_set = true ;
2701 				IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n",
2702 									 pHeaderDescriptor->hdr[0].name,
2703 											 ODU_hdr_hdl_v6);
2704 				break;
2705 			}
2706 		}
2707 	}
2708 fail:
2709 	free(pHeaderDescriptor);
2710 	return res;
2711 }
2712 
2713 
2714 /* handle odu default route rule configuration */
handle_odu_route_add()2715 int IPACM_Lan::handle_odu_route_add()
2716 {
2717 	/* add default WAN route */
2718 	struct ipa_ioc_add_rt_rule *rt_rule;
2719 	struct ipa_rt_rule_add *rt_rule_entry;
2720 	uint32_t tx_index;
2721 	const int NUM = 1;
2722 
2723 	if(tx_prop == NULL)
2724 	{
2725 	  IPACMDBG_H("No tx properties, ignore default route setting\n");
2726 	  return IPACM_SUCCESS;
2727 	}
2728 
2729 	rt_rule = (struct ipa_ioc_add_rt_rule *)
2730 		 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
2731 						NUM * sizeof(struct ipa_rt_rule_add));
2732 
2733 	if (!rt_rule)
2734 	{
2735 		IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
2736 		return IPACM_FAILURE;
2737 	}
2738 
2739 	rt_rule->commit = 1;
2740 	rt_rule->num_rules = (uint8_t)NUM;
2741 
2742 
2743 	IPACMDBG_H("WAN table created %s \n", rt_rule->rt_tbl_name);
2744 	rt_rule_entry = &rt_rule->rules[0];
2745 	rt_rule_entry->at_rear = true;
2746 
2747 	for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2748 	{
2749 
2750 		if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
2751 		{
2752 			strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, sizeof(rt_rule->rt_tbl_name));
2753 			rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4;
2754 			rt_rule->ip = IPA_IP_v4;
2755 		}
2756 		else
2757 		{
2758 			strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, sizeof(rt_rule->rt_tbl_name));
2759 			rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6;
2760 			rt_rule->ip = IPA_IP_v6;
2761 		}
2762 
2763 		rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2764 		memcpy(&rt_rule_entry->rule.attrib,
2765 					 &tx_prop->tx[tx_index].attrib,
2766 					 sizeof(rt_rule_entry->rule.attrib));
2767 
2768 		rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2769 		if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
2770 		{
2771 			rt_rule_entry->rule.attrib.u.v4.dst_addr      = 0;
2772 			rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0;
2773 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2774 				rt_rule_entry->rule.hashable = true;
2775 			if (false == m_routing.AddRoutingRule(rt_rule))
2776 			{
2777 				IPACMERR("Routing rule addition failed!\n");
2778 				free(rt_rule);
2779 				return IPACM_FAILURE;
2780 			}
2781 			odu_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
2782 			IPACMDBG_H("Got ipv4 ODU-route rule hdl:0x%x,tx:%d,ip-type: %d \n",
2783 						 odu_route_rule_v4_hdl[tx_index],
2784 						 tx_index,
2785 						 IPA_IP_v4);
2786 		}
2787 		else
2788 		{
2789 			rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0;
2790 			rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0;
2791 			rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0;
2792 			rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0;
2793 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0;
2794 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0;
2795 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0;
2796 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0;
2797 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2798 				rt_rule_entry->rule.hashable = true;
2799 			if (false == m_routing.AddRoutingRule(rt_rule))
2800 			{
2801 				IPACMERR("Routing rule addition failed!\n");
2802 				free(rt_rule);
2803 				return IPACM_FAILURE;
2804 			}
2805 			odu_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
2806 			IPACMDBG_H("Set ipv6 ODU-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n",
2807 					odu_route_rule_v6_hdl[tx_index],
2808 					tx_index,
2809 					IPA_IP_v6);
2810 		}
2811 	}
2812 	free(rt_rule);
2813 	return IPACM_SUCCESS;
2814 }
2815 
2816 /* handle odu default route rule deletion */
handle_odu_route_del()2817 int IPACM_Lan::handle_odu_route_del()
2818 {
2819 	uint32_t tx_index;
2820 
2821 	if(tx_prop == NULL)
2822 	{
2823 		IPACMDBG_H("No tx properties, ignore delete default route setting\n");
2824 		return IPACM_SUCCESS;
2825 	}
2826 
2827 	for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2828 	{
2829 		if (tx_prop->tx[tx_index].ip == IPA_IP_v4)
2830 		{
2831 			IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
2832 					tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v4);
2833 
2834 			if (m_routing.DeleteRoutingHdl(odu_route_rule_v4_hdl[tx_index], IPA_IP_v4)
2835 					== false)
2836 			{
2837 				IPACMERR("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v4, odu_route_rule_v4_hdl[tx_index], tx_index);
2838 				return IPACM_FAILURE;
2839 			}
2840 		}
2841 		else
2842 		{
2843 			IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
2844 					tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v6);
2845 
2846 			if (m_routing.DeleteRoutingHdl(odu_route_rule_v6_hdl[tx_index], IPA_IP_v6)
2847 					== false)
2848 			{
2849 				IPACMERR("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v6, odu_route_rule_v6_hdl[tx_index], tx_index);
2850 				return IPACM_FAILURE;
2851 			}
2852 		}
2853 	}
2854 
2855 	return IPACM_SUCCESS;
2856 }
2857 
2858 /*handle eth client del mode*/
handle_eth_client_down_evt(uint8_t * mac_addr)2859 int IPACM_Lan::handle_eth_client_down_evt(uint8_t *mac_addr)
2860 {
2861 	int clt_indx;
2862 	uint32_t tx_index;
2863 	int num_eth_client_tmp = num_eth_client;
2864 	int num_v6;
2865 
2866 	IPACMDBG_H("total client: %d\n", num_eth_client_tmp);
2867 
2868 	clt_indx = get_eth_client_index(mac_addr);
2869 	if (clt_indx == IPACM_INVALID_INDEX)
2870 	{
2871 		IPACMDBG_H("eth client not attached\n");
2872 		return IPACM_SUCCESS;
2873 	}
2874 
2875 	/* First reset nat rules and then route rules */
2876 	if(get_client_memptr(eth_client, clt_indx)->ipv4_set == true)
2877 	{
2878 			IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, clt_indx)->v4_addr);
2879 			CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clt_indx)->v4_addr);
2880 	}
2881 
2882 	if (delete_eth_rtrules(clt_indx, IPA_IP_v4))
2883 	{
2884 		IPACMERR("unbale to delete ecm-client v4 route rules for index: %d\n", clt_indx);
2885 		return IPACM_FAILURE;
2886 	}
2887 
2888 	if (delete_eth_rtrules(clt_indx, IPA_IP_v6))
2889 	{
2890 		IPACMERR("unbale to delete ecm-client v6 route rules for index: %d\n", clt_indx);
2891 		return IPACM_FAILURE;
2892 	}
2893 
2894 	/* Delete eth client header */
2895 	if(get_client_memptr(eth_client, clt_indx)->ipv4_header_set == true)
2896 	{
2897 		if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4)
2898 				== false)
2899 		{
2900 			return IPACM_FAILURE;
2901 		}
2902 		get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false;
2903 	}
2904 
2905 	if(get_client_memptr(eth_client, clt_indx)->ipv6_header_set == true)
2906 	{
2907 		if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6)
2908 				== false)
2909 		{
2910 			return IPACM_FAILURE;
2911 		}
2912 		get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false;
2913 	}
2914 
2915 	/* Reset ip_set to 0*/
2916 	get_client_memptr(eth_client, clt_indx)->ipv4_set = false;
2917 	get_client_memptr(eth_client, clt_indx)->ipv6_set = 0;
2918 	get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false;
2919 	get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false;
2920 	get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = false;
2921 	get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = 0;
2922 
2923 	for (; clt_indx < num_eth_client_tmp - 1; clt_indx++)
2924 	{
2925 		memcpy(get_client_memptr(eth_client, clt_indx)->mac,
2926 					 get_client_memptr(eth_client, (clt_indx + 1))->mac,
2927 					 sizeof(get_client_memptr(eth_client, clt_indx)->mac));
2928 
2929 		get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v4;
2930 		get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v6;
2931 		get_client_memptr(eth_client, clt_indx)->v4_addr = get_client_memptr(eth_client, (clt_indx + 1))->v4_addr;
2932 
2933 		get_client_memptr(eth_client, clt_indx)->ipv4_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_set;
2934 		get_client_memptr(eth_client, clt_indx)->ipv6_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_set;
2935 		get_client_memptr(eth_client, clt_indx)->ipv4_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_header_set;
2936 		get_client_memptr(eth_client, clt_indx)->ipv6_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_header_set;
2937 
2938 		get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v4;
2939 		get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v6;
2940 
2941         for (num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->ipv6_set;num_v6++)
2942 	    {
2943 		    get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][0] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][0];
2944 		    get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][1] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][1];
2945 		    get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][2] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][2];
2946 		    get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][3] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][3];
2947         }
2948 
2949 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2950 		{
2951 			get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 =
2952 				 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4;
2953 
2954 			for(num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->route_rule_set_v6;num_v6++)
2955 			{
2956 			  get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6] =
2957 			   	 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6];
2958 			  get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6] =
2959 			   	 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6];
2960 		    }
2961 		}
2962 	}
2963 
2964 	IPACMDBG_H(" %d eth client deleted successfully \n", num_eth_client);
2965 	num_eth_client = num_eth_client - 1;
2966 	IPACMDBG_H(" Number of eth client: %d\n", num_eth_client);
2967 
2968 	/* Del RM dependency */
2969 	if(num_eth_client == 0)
2970 	{
2971 		if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
2972 		{
2973 			/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule*/
2974 			IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
2975 			if (tx_prop != NULL)
2976 			{
2977 				IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
2978 				IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
2979 			}
2980 		}
2981 	}
2982 
2983 	return IPACM_SUCCESS;
2984 }
2985 
2986 /*handle LAN iface down event*/
handle_down_evt()2987 int IPACM_Lan::handle_down_evt()
2988 {
2989 	uint32_t i;
2990 	int res = IPACM_SUCCESS;
2991 
2992 	IPACMDBG_H("lan handle_down_evt\n ");
2993 	if (ipa_if_cate == ODU_IF)
2994 	{
2995 		/* delete ODU default RT rules */
2996 		if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true)
2997 		{
2998 			IPACMDBG_H("eMBMS enable, delete eMBMS DL RT rule\n");
2999 			handle_odu_route_del();
3000 		}
3001 
3002 		/* delete full header */
3003 		if (ipv4_header_set)
3004 		{
3005 			if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v4)
3006 					== false)
3007 			{
3008 					IPACMERR("ODU ipv4 header delete fail\n");
3009 					res = IPACM_FAILURE;
3010 					goto fail;
3011 			}
3012 			IPACMDBG_H("ODU ipv4 header delete success\n");
3013 		}
3014 
3015 		if (ipv6_header_set)
3016 		{
3017 			if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v6)
3018 					== false)
3019 			{
3020 				IPACMERR("ODU ipv6 header delete fail\n");
3021 				res = IPACM_FAILURE;
3022 				goto fail;
3023 			}
3024 			IPACMERR("ODU ipv6 header delete success\n");
3025 		}
3026 	}
3027 
3028 	/* no iface address up, directly close iface*/
3029 	if (ip_type == IPACM_IP_NULL)
3030 	{
3031 		goto fail;
3032 	}
3033 
3034 	/* delete wan filter rule */
3035 	if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
3036 	{
3037 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
3038 		handle_wan_down(IPACM_Wan::backhaul_mode);
3039 #ifdef FEATURE_IPA_ANDROID
3040 #ifndef FEATURE_IPACM_HAL
3041 		/* Clean-up tethered-iface list */
3042 		IPACM_Wan::delete_tether_iface(IPA_IP_v4, ipa_if_num);
3043 #endif
3044 #endif
3045 	}
3046 
3047 	if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
3048 	{
3049 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
3050 		handle_wan_down_v6(IPACM_Wan::backhaul_mode);
3051 #ifdef FEATURE_IPA_ANDROID
3052 		/* Clean-up tethered-iface list */
3053 		IPACM_Wan::delete_tether_iface(IPA_IP_v6, ipa_if_num);
3054 #endif
3055 	}
3056 
3057 	/* delete default filter rules */
3058 	if (ip_type != IPA_IP_v6 && rx_prop != NULL)
3059 	{
3060 		if(m_filtering.DeleteFilteringHdls(ipv4_icmp_flt_rule_hdl, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE) == false)
3061 		{
3062 			IPACMERR("Error Deleting ICMPv4 Filtering Rule, aborting...\n");
3063 			res = IPACM_FAILURE;
3064 			goto fail;
3065 		}
3066 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE);
3067 
3068 		if(dft_v4fl_rule_hdl[0] != 0)
3069 		{
3070 				if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4,
3071 						IPV4_DEFAULT_FILTERTING_RULES) == false)
3072 				{
3073 					IPACMERR("Error Deleting Filtering Rule, aborting...\n");
3074 					res = IPACM_FAILURE;
3075 					goto fail;
3076 				}
3077 				IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
3078 		}
3079 
3080 		/* free private-subnet ipv4 filter rules */
3081 		if (IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_PRIV_SUBNET_FILTER_RULE_HANDLES)
3082 		{
3083 			IPACMERR(" the number of rules are bigger than array, aborting...\n");
3084 			res = IPACM_FAILURE;
3085 			goto fail;
3086 		}
3087 
3088 #ifdef FEATURE_IPA_ANDROID
3089 		if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) == false)
3090 		{
3091 			IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
3092 			res = IPACM_FAILURE;
3093 			goto fail;
3094 		}
3095 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES);
3096 #else
3097 		if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false)
3098 		{
3099 			IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
3100 			res = IPACM_FAILURE;
3101 			goto fail;
3102 		}
3103 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
3104 #endif
3105 		IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n");
3106 	}
3107 	IPACMDBG_H("Finished delete default iface ipv4 filtering rules \n ");
3108 
3109 	if (ip_type != IPA_IP_v4 && rx_prop != NULL)
3110 	{
3111 		if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false)
3112 		{
3113 			IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n");
3114 			res = IPACM_FAILURE;
3115 			goto fail;
3116 		}
3117 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE);
3118 
3119 		if (dft_v6fl_rule_hdl[0] != 0)
3120 		{
3121 			if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false)
3122 			{
3123 				IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
3124 				res = IPACM_FAILURE;
3125 				goto fail;
3126 			}
3127 				IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
3128 		}
3129 #ifdef FEATURE_L2TP
3130 		if(ipa_if_cate == ODU_IF)
3131 		{
3132 			if(m_filtering.DeleteFilteringHdls(tcp_syn_flt_rule_hdl, IPA_IP_v6, IPA_IP_MAX) == false)
3133 			{
3134 				IPACMERR("Error Deleting TCP SYN L2TP Filtering Rule, aborting...\n");
3135 				res = IPACM_FAILURE;
3136 				goto fail;
3137 			}
3138 		}
3139 #endif
3140 	}
3141 	IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n ");
3142 
3143 	if (ip_type != IPA_IP_v6)
3144 	{
3145 		if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4)
3146 				== false)
3147 		{
3148 			IPACMERR("Routing rule deletion failed!\n");
3149 			res = IPACM_FAILURE;
3150 			goto fail;
3151 		}
3152 	}
3153 	IPACMDBG_H("Finished delete default iface ipv4 rules \n ");
3154 
3155 	/* delete default v6 routing rule */
3156 	if (ip_type != IPA_IP_v4)
3157 	{
3158 		/* may have multiple ipv6 iface-RT rules*/
3159 		for (i = 0; i < 2*num_dft_rt_v6; i++)
3160 		{
3161 			if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + i], IPA_IP_v6)
3162 					== false)
3163 			{
3164 				IPACMERR("Routing rule deletion failed!\n");
3165 				res = IPACM_FAILURE;
3166 				goto fail;
3167 			}
3168 		}
3169 	}
3170 
3171 	IPACMDBG_H("Finished delete default iface ipv6 rules \n ");
3172 
3173 	/* free the edm clients cache */
3174 	IPACMDBG_H("Free ecm clients cache\n");
3175 
3176 	if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
3177 	{
3178 		/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule */
3179 		IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
3180 		if (tx_prop != NULL)
3181 		{
3182 			IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
3183 			IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
3184 		}
3185 	}
3186 	eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL, NULL, NULL, IPA_CLIENT_MAX);
3187 
3188 /* Delete private subnet*/
3189 #ifdef FEATURE_IPA_ANDROID
3190 	if (ip_type != IPA_IP_v6)
3191 	{
3192 		IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
3193 		IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
3194 		if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
3195 		{
3196 			IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
3197 		}
3198 	}
3199 
3200 	/* reset the IPA-client pipe enum */
3201 	if(ipa_if_cate != WAN_IF)
3202 	{
3203 #ifdef FEATURE_IPACM_HAL
3204 		handle_tethering_client(true, IPACM_CLIENT_MAX);
3205 #else
3206 		handle_tethering_client(true, IPACM_CLIENT_USB);
3207 #endif
3208 	}
3209 #endif /* defined(FEATURE_IPA_ANDROID)*/
3210 fail:
3211 	/* clean eth-client header, routing rules */
3212 	IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
3213 	for (i = 0; i < num_eth_client; i++)
3214 	{
3215 		/* First reset nat rules and then route rules */
3216 		if(get_client_memptr(eth_client, i)->ipv4_set == true)
3217 		{
3218 			IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr);
3219 			CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr);
3220 		}
3221 
3222 		if (delete_eth_rtrules(i, IPA_IP_v4))
3223 		{
3224 			IPACMERR("unbale to delete ecm-client v4 route rules for index %d\n", i);
3225 			res = IPACM_FAILURE;
3226 		}
3227 
3228 		if (delete_eth_rtrules(i, IPA_IP_v6))
3229 		{
3230 			IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
3231 			res = IPACM_FAILURE;
3232 		}
3233 
3234 		IPACMDBG_H("Delete %d client header\n", num_eth_client);
3235 
3236 		if(get_client_memptr(eth_client, i)->ipv4_header_set == true)
3237 		{
3238 			if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v4)
3239 				== false)
3240 			{
3241 				res = IPACM_FAILURE;
3242 			}
3243 		}
3244 
3245 		if(get_client_memptr(eth_client, i)->ipv6_header_set == true)
3246 		{
3247 			if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v6)
3248 					== false)
3249 			{
3250 				res = IPACM_FAILURE;
3251 			}
3252 		}
3253 	} /* end of for loop */
3254 
3255 	/* check software routing fl rule hdl */
3256 	if (softwarerouting_act == true && rx_prop != NULL)
3257 	{
3258 		handle_software_routing_disable(false);
3259 	}
3260 
3261 	if (odu_route_rule_v4_hdl != NULL)
3262 	{
3263 		free(odu_route_rule_v4_hdl);
3264 	}
3265 	if (odu_route_rule_v6_hdl != NULL)
3266 	{
3267 		free(odu_route_rule_v6_hdl);
3268 	}
3269 	if (rx_prop != NULL)
3270 	{
3271 		if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
3272 		{
3273 			/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
3274 			IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
3275 			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]);
3276 			IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
3277 			IPACMDBG_H("Finished delete dependency \n ");
3278 		}
3279 		if (!(IPACM_Iface::ipacmcfg->isEthBridgingSupported()))
3280 				free(rx_prop);
3281 	}
3282 
3283 	if (eth_client != NULL)
3284 	{
3285 		free(eth_client);
3286 	}
3287 	if (!(IPACM_Iface::ipacmcfg->isEthBridgingSupported()))
3288 	{
3289 		if (tx_prop != NULL)
3290 		{
3291 			free(tx_prop);
3292 		}
3293 		if (iface_query != NULL)
3294 		{
3295 			free(iface_query);
3296 		}
3297 	}
3298 	is_active = false;
3299 	post_del_self_evt();
3300 
3301 	return res;
3302 }
3303 
3304 /* install UL filter rule from Q6 */
handle_uplink_filter_rule(ipacm_ext_prop * prop,ipa_ip_type iptype,uint8_t xlat_mux_id)3305 int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptype, uint8_t xlat_mux_id)
3306 {
3307 	ipa_flt_rule_add flt_rule_entry;
3308 	int len = 0, cnt, ret = IPACM_SUCCESS;
3309 	ipa_ioc_add_flt_rule *pFilteringTable;
3310 	ipa_fltr_installed_notif_req_msg_v01 flt_index;
3311 	int fd;
3312 	int i, index, eq_index;
3313 	uint32_t value = 0;
3314 	uint8_t qmap_id, xlat_debug;
3315 	bool result;
3316 
3317 	IPACMDBG_H("Set modem UL flt rules\n");
3318 
3319 	if (rx_prop == NULL)
3320 	{
3321 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
3322 		return IPACM_SUCCESS;
3323 	}
3324 
3325 	if(prop == NULL || prop->num_ext_props <= 0)
3326 	{
3327 		IPACMDBG_H("No extended property.\n");
3328 		return IPACM_SUCCESS;
3329 	}
3330 
3331 	fd = open(IPA_DEVICE_NAME, O_RDWR);
3332 	if (0 == fd)
3333 	{
3334 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
3335 		return IPACM_FAILURE;
3336 	}
3337 	if (prop->num_ext_props > MAX_WAN_UL_FILTER_RULES)
3338 	{
3339 		IPACMERR("number of modem UL rules > MAX_WAN_UL_FILTER_RULES, aborting...\n");
3340 		close(fd);
3341 		return IPACM_FAILURE;
3342 	}
3343 
3344 	memset(&flt_index, 0, sizeof(flt_index));
3345 	flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe);
3346 	if ((int)flt_index.source_pipe_index == -1)
3347 	{
3348 		IPACMERR("Error Query src pipe idx, aborting...\n");
3349 		close(fd);
3350 		return IPACM_FAILURE;
3351 	}
3352 
3353 	flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01;
3354 	if (!IPACM_Iface::ipacmcfg->isIPAv3Supported())
3355 	{
3356 		flt_index.filter_index_list_len = prop->num_ext_props;
3357 	}
3358 	else /* IPAv3 */
3359 	{
3360 		flt_index.rule_id_valid = 1;
3361 		flt_index.rule_id_len = prop->num_ext_props;
3362 	}
3363 	flt_index.embedded_pipe_index_valid = 1;
3364 	flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD);
3365 	if ((int)flt_index.embedded_pipe_index == -1)
3366 	{
3367 		IPACMERR("Error Query emb pipe idx, aborting...\n");
3368 		close(fd);
3369 		return IPACM_FAILURE;
3370 	}
3371 
3372 	flt_index.retain_header_valid = 1;
3373 	flt_index.retain_header = 0;
3374 	flt_index.embedded_call_mux_id_valid = 1;
3375 	qmap_id = IPACM_Iface::ipacmcfg->GetQmapId();
3376 	xlat_debug = IPACM_Wan::getXlat_Mux_Id();
3377 	flt_index.embedded_call_mux_id = qmap_id;
3378 	if (!IPACM_Iface::ipacmcfg->isIPAv3Supported())
3379 	{
3380 		IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d, xlat_mux id: %d, wan-debug %d\n",
3381 			flt_index.source_pipe_index, flt_index.filter_index_list_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id, xlat_mux_id, xlat_debug);
3382 	}
3383 	else /* IPAv3 */
3384 	{
3385 		IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d, xlat_mux id: %d, wan-debug %d\n",
3386 			flt_index.source_pipe_index, flt_index.rule_id_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id, xlat_mux_id, xlat_debug);
3387 	}
3388 	len = sizeof(struct ipa_ioc_add_flt_rule) + prop->num_ext_props * sizeof(struct ipa_flt_rule_add);
3389 	pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
3390 	if (pFilteringTable == NULL)
3391 	{
3392 		IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3393 		close(fd);
3394 		return IPACM_FAILURE;
3395 	}
3396 	memset(pFilteringTable, 0, len);
3397 
3398 	pFilteringTable->commit = 1;
3399 	pFilteringTable->ep = rx_prop->rx[0].src_pipe;
3400 	pFilteringTable->global = false;
3401 	pFilteringTable->ip = iptype;
3402 	pFilteringTable->num_rules = prop->num_ext_props;
3403 
3404 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields
3405 	flt_rule_entry.at_rear = 1;
3406 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3407 		if (flt_rule_entry.rule.eq_attrib.ipv4_frag_eq_present)
3408 			flt_rule_entry.at_rear = 0;
3409 	flt_rule_entry.flt_rule_hdl = -1;
3410 	flt_rule_entry.status = -1;
3411 
3412 	flt_rule_entry.rule.retain_hdr = 0;
3413 	flt_rule_entry.rule.to_uc = 0;
3414 	flt_rule_entry.rule.eq_attrib_type = 1;
3415 	if(iptype == IPA_IP_v4)
3416 	{
3417 		if (ipa_if_cate == ODU_IF && IPACM_Wan::isWan_Bridge_Mode())
3418 		{
3419 			IPACMDBG_H("WAN, ODU are in bridge mode \n");
3420 			flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3421 		}
3422 		else
3423 		{
3424 			flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
3425 		}
3426 	}
3427 	else if(iptype == IPA_IP_v6)
3428 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3429 	else
3430 	{
3431 		IPACMERR("IP type is not expected.\n");
3432 		ret = IPACM_FAILURE;
3433 		goto fail;
3434 	}
3435 
3436 	index = IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, iptype);
3437 
3438 	for(cnt=0; cnt<prop->num_ext_props; cnt++)
3439 	{
3440 		memcpy(&flt_rule_entry.rule.eq_attrib,
3441 					 &prop->prop[cnt].eq_attrib,
3442 					 sizeof(prop->prop[cnt].eq_attrib));
3443 		flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx;
3444 
3445 		if (iptype == IPA_IP_v4)
3446 		{
3447 			if ((ipa_if_cate != ODU_IF) || (IPACM_Wan::isWan_Bridge_Mode() == false))
3448 			{
3449 				/* NAT block will set the proper MUX ID in the metadata according to the relevant PDN */
3450 				if (IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0)
3451 					flt_rule_entry.rule.set_metadata = true;
3452 			}
3453 		}
3454 
3455 		/* Handle XLAT configuration */
3456 		/* temp wa to reset xlat_mux_id to qmap_id if it's xlat call */
3457 		if (IPACM_Wan::isXlat() && (iptype == IPA_IP_v4))
3458 		{
3459 			IPACMDBG_H("WA to replace xlat_mux_id %d with qmap_id: %d\n", xlat_mux_id, qmap_id);
3460 			xlat_mux_id = qmap_id;
3461 		}
3462 
3463 		if ((iptype == IPA_IP_v4) && prop->prop[cnt].is_xlat_rule && (xlat_mux_id != 0))
3464 		{
3465 			/* fill the value of meta-data */
3466 			value = xlat_mux_id;
3467 			flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
3468 			flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
3469 			flt_rule_entry.rule.eq_attrib.metadata_meq32.value = (value & 0xFF) << 16;
3470 			flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = 0x00FF0000;
3471 			IPACMDBG_H("xlat meta-data is modified for rule: %d has index %d with xlat_mux_id: %d\n",
3472 					cnt, index, xlat_mux_id);
3473 			/* disable metadata replacement for xlat rules */
3474 			if (IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0)
3475 				flt_rule_entry.rule.set_metadata = false;
3476 		}
3477 
3478 #ifdef FEATURE_IPACM_HAL
3479 		/* add prefix equation in modem UL rules */
3480 		if(iptype == IPA_IP_v4 && (flt_rule_entry.rule.eq_attrib.num_offset_meq_32 >= 0)
3481 			&& (flt_rule_entry.rule.eq_attrib.num_offset_meq_32 < IPA_IPFLTR_NUM_MEQ_32_EQNS))
3482 		{
3483 			flt_rule_entry.rule.eq_attrib.num_offset_meq_32++;
3484 			eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_32 - 1;
3485 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3486 			{
3487 				if(eq_index == 0)
3488 				{
3489 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<5);
3490 				}
3491 				else
3492 				{
3493 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<6);
3494 				}
3495 			}
3496 			else
3497 			{
3498 				if(eq_index == 0)
3499 				{
3500 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<2);
3501 				}
3502 				else
3503 				{
3504 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3);
3505 				}
3506 			}
3507 			flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].offset = 12;
3508 			flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].mask = prefix[IPA_IP_v4].v4Mask;
3509 			flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].value = prefix[IPA_IP_v4].v4Addr;
3510 		}
3511 		else if (flt_rule_entry.rule.eq_attrib.num_offset_meq_32 > IPA_IPFLTR_NUM_MEQ_32_EQNS)
3512 		{
3513 			IPACMERR("Run out of MEQ32 equation.\n");
3514 			flt_rule_entry.rule.eq_attrib.num_offset_meq_32--;
3515 		}
3516 		else
3517 		{
3518 			if ((flt_rule_entry.rule.eq_attrib.num_offset_meq_128 >= 0) &&
3519 				(flt_rule_entry.rule.eq_attrib.num_offset_meq_128
3520 					< IPA_IPFLTR_NUM_MEQ_128_EQNS))
3521 			{
3522 				flt_rule_entry.rule.eq_attrib.num_offset_meq_128++;
3523 				eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_128 - 1;
3524 				if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3525 				{
3526 					if(eq_index == 0)
3527 					{
3528 						flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3);
3529 					}
3530 					else
3531 					{
3532 						flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<4);
3533 					}
3534 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 0)
3535 							= prefix[IPA_IP_v6].v6Mask[3];
3536 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 4)
3537 							= prefix[IPA_IP_v6].v6Mask[2];
3538 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 8)
3539 							= prefix[IPA_IP_v6].v6Mask[1];
3540 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 12)
3541 							= prefix[IPA_IP_v6].v6Mask[0];
3542 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 0)
3543 							= prefix[IPA_IP_v6].v6Addr[3];
3544 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 4)
3545 							= prefix[IPA_IP_v6].v6Addr[2];
3546 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 8)
3547 							= prefix[IPA_IP_v6].v6Addr[1];
3548 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 12)
3549 							= prefix[IPA_IP_v6].v6Addr[0];
3550 				}
3551 				else
3552 				{
3553 					if(eq_index == 0)
3554 					{
3555 						flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9);
3556 					}
3557 					else
3558 					{
3559 						flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<10);
3560 					}
3561 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 0)
3562 							= prefix[IPA_IP_v6].v6Mask[0];
3563 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 4)
3564 							= prefix[IPA_IP_v6].v6Mask[1];
3565 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 8)
3566 							= prefix[IPA_IP_v6].v6Mask[2];
3567 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 12)
3568 							= prefix[IPA_IP_v6].v6Mask[3];
3569 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 0)
3570 							= prefix[IPA_IP_v6].v6Addr[0];
3571 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 4)
3572 							= prefix[IPA_IP_v6].v6Addr[1];
3573 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 8)
3574 							= prefix[IPA_IP_v6].v6Addr[2];
3575 					*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 12)
3576 							= prefix[IPA_IP_v6].v6Addr[3];
3577 				}
3578 				flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].offset = 8;
3579 			}
3580 			else
3581 			{
3582 				IPACMERR("Run out of MEQ128 equation.\n");
3583 					flt_rule_entry.rule.eq_attrib.num_offset_meq_128--;
3584 			}
3585 		}
3586 
3587 #endif
3588 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3589 		{
3590 			flt_rule_entry.rule.hashable = prop->prop[cnt].is_rule_hashable;
3591 			flt_rule_entry.rule.rule_id = prop->prop[cnt].rule_id;
3592 			if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA)	//turn on meta-data equation
3593 			{
3594 				flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9);
3595 				flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
3596 				flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
3597 				flt_rule_entry.rule.eq_attrib.metadata_meq32.value |= rx_prop->rx[0].attrib.meta_data;
3598 				flt_rule_entry.rule.eq_attrib.metadata_meq32.mask |= rx_prop->rx[0].attrib.meta_data_mask;
3599 			}
3600 		}
3601 		memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry));
3602 
3603 		IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, index);
3604 		if (!IPACM_Iface::ipacmcfg->isIPAv3Supported())
3605 		{
3606 			flt_index.filter_index_list[cnt].filter_index = index;
3607 			flt_index.filter_index_list[cnt].filter_handle = prop->prop[cnt].filter_hdl;
3608 		}
3609 		else /* IPAv3 */
3610 		{
3611 			flt_index.rule_id[cnt] = prop->prop[cnt].rule_id;
3612 		}
3613 		index++;
3614 	}
3615 
3616 	if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
3617 	{
3618 		IPACMERR("Error sending filtering rule index, aborting...\n");
3619 		ret = IPACM_FAILURE;
3620 		goto fail;
3621 	}
3622 
3623 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3624 	/* use index hw-counter */
3625 	if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3626 	{
3627 		IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
3628 		result = m_filtering.AddFilteringRule_hw_index(pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
3629 	} else {
3630 		result = m_filtering.AddFilteringRule(pFilteringTable);
3631 	}
3632 #else
3633 	result = m_filtering.AddFilteringRule(pFilteringTable);
3634 #endif
3635 
3636 	if(result == false)
3637 	{
3638 		IPACMERR("Error Adding RuleTable to Filtering, aborting...\n");
3639 		ret = IPACM_FAILURE;
3640 		goto fail;
3641 	}
3642 	else
3643 	{
3644 		if(iptype == IPA_IP_v4)
3645 		{
3646 			for(i=0; i<pFilteringTable->num_rules; i++)
3647 			{
3648 				wan_ul_fl_rule_hdl_v4[num_wan_ul_fl_rule_v4] = pFilteringTable->rules[i].flt_rule_hdl;
3649 				num_wan_ul_fl_rule_v4++;
3650 			}
3651 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
3652 			v4_mux_id = qmap_id;
3653 		}
3654 		else if(iptype == IPA_IP_v6)
3655 		{
3656 			for(i=0; i<pFilteringTable->num_rules; i++)
3657 			{
3658 				wan_ul_fl_rule_hdl_v6[num_wan_ul_fl_rule_v6] = pFilteringTable->rules[i].flt_rule_hdl;
3659 				num_wan_ul_fl_rule_v6++;
3660 			}
3661 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
3662 			v6_mux_id = qmap_id;
3663 		}
3664 
3665 		else
3666 		{
3667 			IPACMERR("IP type is not expected.\n");
3668 			goto fail;
3669 		}
3670 	}
3671 
3672 fail:
3673 	free(pFilteringTable);
3674 	close(fd);
3675 	return ret;
3676 }
3677 
handle_wan_down_v6(ipacm_wan_iface_type backhaul_mode)3678 int IPACM_Lan::handle_wan_down_v6(ipacm_wan_iface_type backhaul_mode)
3679 {
3680 	ipa_fltr_installed_notif_req_msg_v01 flt_index;
3681 	int fd;
3682 
3683 	fd = open(IPA_DEVICE_NAME, O_RDWR);
3684 	if (0 == fd)
3685 	{
3686 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
3687 		return IPACM_FAILURE;
3688 	}
3689 
3690 	delete_ipv6_prefix_flt_rule();
3691 
3692 	memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
3693 
3694 	if(backhaul_mode == Q6_WAN && modem_ul_v6_set == true)
3695 	{
3696 		if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES)
3697 		{
3698 			IPACMERR(" the number of rules (%d) are bigger than array (%d), aborting...\n", num_wan_ul_fl_rule_v6, MAX_WAN_UL_FILTER_RULES);
3699 			close(fd);
3700 			return IPACM_FAILURE;
3701 		}
3702 		if (num_wan_ul_fl_rule_v6 == 0)
3703 		{
3704 			IPACMERR("No modem UL rules were installed, return...\n");
3705 			close(fd);
3706 			return IPACM_FAILURE;
3707 		}
3708 
3709 		if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v6,
3710 			IPA_IP_v6, num_wan_ul_fl_rule_v6) == false)
3711 		{
3712 			IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n");
3713 			close(fd);
3714 			return IPACM_FAILURE;
3715 		}
3716 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_wan_ul_fl_rule_v6);
3717 		memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
3718 		num_wan_ul_fl_rule_v6 = 0;
3719 		modem_ul_v6_set = false;
3720 
3721 		memset(&flt_index, 0, sizeof(flt_index));
3722 		flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe);
3723 		if ((int)flt_index.source_pipe_index == -1)
3724 		{
3725 			IPACMERR("Error Query src pipe idx, aborting...\n");
3726 			close(fd);
3727 			return IPACM_FAILURE;
3728 		}
3729 		flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01;
3730 		if (!IPACM_Iface::ipacmcfg->isIPAv3Supported())
3731 		{
3732 			flt_index.filter_index_list_len = 0;
3733 		}
3734 		else /* IPAv3 */
3735 		{
3736 			flt_index.rule_id_valid = 1;
3737 			flt_index.rule_id_len = 0;
3738 		}
3739 		flt_index.embedded_pipe_index_valid = 1;
3740 		flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD);
3741 		if ((int)flt_index.embedded_pipe_index == -1)
3742 		{
3743 			IPACMERR("Error Query emb pipe idx, aborting...\n");
3744 			close(fd);
3745 			return IPACM_FAILURE;
3746 		}
3747 
3748 		flt_index.retain_header_valid = 1;
3749 		flt_index.retain_header = 0;
3750 		flt_index.embedded_call_mux_id_valid = 1;
3751 		flt_index.embedded_call_mux_id = v6_mux_id;
3752 		v6_mux_id = 0;
3753 		if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
3754 		{
3755 			IPACMERR("Error sending filtering rule index, aborting...\n");
3756 			close(fd);
3757 			return IPACM_FAILURE;
3758 		}
3759 	}
3760 	else
3761 	{
3762 		if (m_filtering.DeleteFilteringHdls(&dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES],
3763 																				IPA_IP_v6, 1) == false)
3764 		{
3765 			IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
3766 			close(fd);
3767 			return IPACM_FAILURE;
3768 		}
3769 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3770 		sta_ul_v6_set = false;
3771 	}
3772 	close(fd);
3773 	return IPACM_SUCCESS;
3774 }
3775 
reset_to_dummy_flt_rule(ipa_ip_type iptype,uint32_t rule_hdl)3776 int IPACM_Lan::reset_to_dummy_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl)
3777 {
3778 	int len, res = IPACM_SUCCESS;
3779 	struct ipa_flt_rule_mdfy flt_rule;
3780 	struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
3781 
3782 	IPACMDBG_H("Reset flt rule to dummy, IP type: %d, hdl: %d\n", iptype, rule_hdl);
3783 	len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy);
3784 	pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
3785 
3786 	if (pFilteringTable == NULL)
3787 	{
3788 		IPACMERR("Error allocate flt rule memory...\n");
3789 		return IPACM_FAILURE;
3790 	}
3791 	memset(pFilteringTable, 0, len);
3792 
3793 	pFilteringTable->commit = 1;
3794 	pFilteringTable->ip = iptype;
3795 	pFilteringTable->num_rules = 1;
3796 
3797 	memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
3798 	flt_rule.status = -1;
3799 	flt_rule.rule_hdl = rule_hdl;
3800 
3801 	flt_rule.rule.retain_hdr = 0;
3802 	flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
3803 
3804 	if(iptype == IPA_IP_v4)
3805 	{
3806 		IPACMDBG_H("Reset IPv4 flt rule to dummy\n");
3807 
3808 		flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
3809 		flt_rule.rule.attrib.u.v4.dst_addr = ~0;
3810 		flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0;
3811 		flt_rule.rule.attrib.u.v4.src_addr = ~0;
3812 		flt_rule.rule.attrib.u.v4.src_addr_mask = ~0;
3813 
3814 		memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
3815 		if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
3816 		{
3817 			IPACMERR("Error modifying filtering rule.\n");
3818 			res = IPACM_FAILURE;
3819 			goto fail;
3820 		}
3821 		else
3822 		{
3823 			IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl,
3824 						pFilteringTable->rules[0].status);
3825 		}
3826 	}
3827 	else if(iptype == IPA_IP_v6)
3828 	{
3829 		IPACMDBG_H("Reset IPv6 flt rule to dummy\n");
3830 
3831 		flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
3832 		flt_rule.rule.attrib.u.v6.src_addr[0] = ~0;
3833 		flt_rule.rule.attrib.u.v6.src_addr[1] = ~0;
3834 		flt_rule.rule.attrib.u.v6.src_addr[2] = ~0;
3835 		flt_rule.rule.attrib.u.v6.src_addr[3] = ~0;
3836 		flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0;
3837 		flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0;
3838 		flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0;
3839 		flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0;
3840 		flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0;
3841 		flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0;
3842 		flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0;
3843 		flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0;
3844 		flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0;
3845 		flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0;
3846 		flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0;
3847 		flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0;
3848 
3849 
3850 		memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
3851 		if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
3852 		{
3853 			IPACMERR("Error modifying filtering rule.\n");
3854 			res = IPACM_FAILURE;
3855 			goto fail;
3856 		}
3857 		else
3858 		{
3859 			IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl,
3860 						pFilteringTable->rules[0].status);
3861 		}
3862 	}
3863 	else
3864 	{
3865 		IPACMERR("IP type is not expected.\n");
3866 		res = IPACM_FAILURE;
3867 		goto fail;
3868 	}
3869 
3870 fail:
3871 	free(pFilteringTable);
3872 	return res;
3873 }
3874 
post_del_self_evt()3875 void IPACM_Lan::post_del_self_evt()
3876 {
3877 	ipacm_cmd_q_data evt;
3878 	ipacm_event_data_fid* fid;
3879 	fid = (ipacm_event_data_fid*)malloc(sizeof(ipacm_event_data_fid));
3880 	if(fid == NULL)
3881 	{
3882 		IPACMERR("Failed to allocate fid memory.\n");
3883 		return;
3884 	}
3885 	memset(fid, 0, sizeof(ipacm_event_data_fid));
3886 	memset(&evt, 0, sizeof(ipacm_cmd_q_data));
3887 
3888 	fid->if_index = ipa_if_num;
3889 
3890 	evt.evt_data = (void*)fid;
3891 	evt.event = IPA_LAN_DELETE_SELF;
3892 
3893 	IPACMDBG_H("Posting event IPA_LAN_DELETE_SELF\n");
3894 	IPACM_EvtDispatcher::PostEvt(&evt);
3895 }
3896 
3897 /*handle reset usb-client rt-rules */
handle_lan_client_reset_rt(ipa_ip_type iptype)3898 int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype)
3899 {
3900 	uint32_t i;
3901 	int res = IPACM_SUCCESS;
3902 
3903 	/* clean eth-client routing rules */
3904 	IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
3905 	for (i = 0; i < num_eth_client; i++)
3906 	{
3907 		res = delete_eth_rtrules(i, iptype);
3908 		if (res != IPACM_SUCCESS)
3909 		{
3910 			IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype);
3911 			return res;
3912 		}
3913 	} /* end of for loop */
3914 
3915 	/* Reset ip-address */
3916 	for (i = 0; i < num_eth_client; i++)
3917 	{
3918 		if(iptype == IPA_IP_v4)
3919 		{
3920 			get_client_memptr(eth_client, i)->ipv4_set = false;
3921 		}
3922 		else
3923 		{
3924 			get_client_memptr(eth_client, i)->ipv6_set = 0;
3925 		}
3926 	} /* end of for loop */
3927 	return res;
3928 }
3929 
install_ipv4_icmp_flt_rule()3930 int IPACM_Lan::install_ipv4_icmp_flt_rule()
3931 {
3932 	int len;
3933 	struct ipa_ioc_add_flt_rule* flt_rule;
3934 	struct ipa_flt_rule_add flt_rule_entry;
3935 	bool result;
3936 
3937 	if(rx_prop != NULL)
3938 	{
3939 		len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
3940 
3941 		flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
3942 		if (!flt_rule)
3943 		{
3944 			IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3945 			return IPACM_FAILURE;
3946 		}
3947 
3948 		flt_rule->commit = 1;
3949 		flt_rule->ep = rx_prop->rx[0].src_pipe;
3950 		flt_rule->global = false;
3951 		flt_rule->ip = IPA_IP_v4;
3952 		flt_rule->num_rules = 1;
3953 
3954 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3955 
3956 		flt_rule_entry.rule.retain_hdr = 1;
3957 		flt_rule_entry.rule.to_uc = 0;
3958 		flt_rule_entry.rule.eq_attrib_type = 0;
3959 		flt_rule_entry.at_rear = true;
3960 		flt_rule_entry.flt_rule_hdl = -1;
3961 		flt_rule_entry.status = -1;
3962 		flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3963 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3964 			flt_rule_entry.rule.hashable = true;
3965 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
3966 
3967 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
3968 		flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP;
3969 		memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3970 
3971 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3972 		/* use index hw-counter */
3973 		if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3974 		{
3975 			IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
3976 			result = m_filtering.AddFilteringRule_hw_index(flt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
3977 		} else {
3978 			result = m_filtering.AddFilteringRule(flt_rule);
3979 		}
3980 #else
3981 		result = m_filtering.AddFilteringRule(flt_rule);
3982 #endif
3983 
3984 		if (result == false)
3985 		{
3986 			IPACMERR("Error Adding Filtering rule, aborting...\n");
3987 			free(flt_rule);
3988 			return IPACM_FAILURE;
3989 		}
3990 		else
3991 		{
3992 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
3993 			ipv4_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
3994 			IPACMDBG_H("IPv4 icmp filter rule HDL:0x%x\n", ipv4_icmp_flt_rule_hdl[0]);
3995                         free(flt_rule);
3996 		}
3997 	}
3998 	return IPACM_SUCCESS;
3999 }
4000 
install_ipv6_icmp_flt_rule()4001 int IPACM_Lan::install_ipv6_icmp_flt_rule()
4002 {
4003 
4004 	int len;
4005 	struct ipa_ioc_add_flt_rule* flt_rule;
4006 	struct ipa_flt_rule_add flt_rule_entry;
4007 	bool result;
4008 
4009 	if(rx_prop != NULL)
4010 	{
4011 		len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
4012 
4013 		flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
4014 		if (!flt_rule)
4015 		{
4016 			IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
4017 			return IPACM_FAILURE;
4018 		}
4019 
4020 		flt_rule->commit = 1;
4021 		flt_rule->ep = rx_prop->rx[0].src_pipe;
4022 		flt_rule->global = false;
4023 		flt_rule->ip = IPA_IP_v6;
4024 		flt_rule->num_rules = 1;
4025 
4026 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
4027 
4028 		flt_rule_entry.rule.retain_hdr = 1;
4029 		flt_rule_entry.rule.to_uc = 0;
4030 		flt_rule_entry.rule.eq_attrib_type = 0;
4031 		flt_rule_entry.at_rear = true;
4032 		flt_rule_entry.flt_rule_hdl = -1;
4033 		flt_rule_entry.status = -1;
4034 		flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
4035 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
4036 			flt_rule_entry.rule.hashable = false;
4037 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
4038 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
4039 		flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
4040 		memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4041 
4042 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
4043 		/* use index hw-counter */
4044 		if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
4045 		{
4046 			IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
4047 			result = m_filtering.AddFilteringRule_hw_index(flt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
4048 		} else {
4049 			result = m_filtering.AddFilteringRule(flt_rule);
4050 		}
4051 #else
4052 		result = m_filtering.AddFilteringRule(flt_rule);
4053 #endif
4054 
4055 		if (result == false)
4056 		{
4057 			IPACMERR("Error Adding Filtering rule, aborting...\n");
4058 			free(flt_rule);
4059 			return IPACM_FAILURE;
4060 		}
4061 		else
4062 		{
4063 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
4064 			ipv6_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
4065 			IPACMDBG_H("IPv6 icmp filter rule HDL:0x%x\n", ipv6_icmp_flt_rule_hdl[0]);
4066 			free(flt_rule);
4067 		}
4068 	}
4069 	return IPACM_SUCCESS;
4070 }
4071 
add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)4072 int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
4073 {
4074 	if(rx_prop == NULL)
4075 	{
4076 		IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy private subnet filtering rule.\n", dev_name);
4077 		return 0;
4078 	}
4079 
4080 	if(iptype == IPA_IP_v6)
4081 	{
4082 		IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name);
4083 		return 0;
4084 	}
4085 	int i, len, res = IPACM_SUCCESS;
4086 	struct ipa_flt_rule_add flt_rule;
4087 	ipa_ioc_add_flt_rule* pFilteringTable;
4088 	bool result;
4089 
4090 	len = sizeof(struct ipa_ioc_add_flt_rule) + (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) * sizeof(struct ipa_flt_rule_add);
4091 
4092 	pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
4093 	if (pFilteringTable == NULL)
4094 	{
4095 		IPACMERR("Error allocate flt table memory...\n");
4096 		return IPACM_FAILURE;
4097 	}
4098 	memset(pFilteringTable, 0, len);
4099 
4100 	pFilteringTable->commit = 1;
4101 	pFilteringTable->ep = rx_prop->rx[0].src_pipe;
4102 	pFilteringTable->global = false;
4103 	pFilteringTable->ip = iptype;
4104 	pFilteringTable->num_rules = IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES;
4105 
4106 	memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add));
4107 
4108 	flt_rule.rule.retain_hdr = 0;
4109 	flt_rule.at_rear = true;
4110 	flt_rule.flt_rule_hdl = -1;
4111 	flt_rule.status = -1;
4112 	flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
4113 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
4114 		flt_rule.rule.hashable = true;
4115 	memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib,
4116 			sizeof(flt_rule.rule.attrib));
4117 
4118 	if(iptype == IPA_IP_v4)
4119 	{
4120 		flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
4121 		flt_rule.rule.attrib.u.v4.src_addr_mask = ~0;
4122 		flt_rule.rule.attrib.u.v4.src_addr = ~0;
4123 		flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0;
4124 		flt_rule.rule.attrib.u.v4.dst_addr = ~0;
4125 
4126 		for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES; i++)
4127 		{
4128 			memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add));
4129 		}
4130 
4131 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
4132 		/* use index hw-counter */
4133 		if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
4134 		{
4135 			IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
4136 			result = m_filtering.AddFilteringRule_hw_index(pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
4137 		} else {
4138 			result = m_filtering.AddFilteringRule(pFilteringTable);
4139 		}
4140 #else
4141 		result = m_filtering.AddFilteringRule(pFilteringTable);
4142 #endif
4143 
4144 		if (result == false)
4145 		{
4146 			IPACMERR("Error adding dummy private subnet v4 flt rule\n");
4147 			res = IPACM_FAILURE;
4148 			goto fail;
4149 		}
4150 		else
4151 		{
4152 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES);
4153 			/* copy filter rule hdls */
4154 			for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES; i++)
4155 			{
4156 				if (pFilteringTable->rules[i].status == 0)
4157 				{
4158 					private_fl_rule_hdl[i] = pFilteringTable->rules[i].flt_rule_hdl;
4159 					IPACMDBG_H("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]);
4160 				}
4161 				else
4162 				{
4163 					IPACMERR("Failed adding lan2lan v4 flt rule %d\n", i);
4164 					res = IPACM_FAILURE;
4165 					goto fail;
4166 				}
4167 			}
4168 		}
4169 	}
4170 fail:
4171 	free(pFilteringTable);
4172 	return res;
4173 }
4174 
handle_private_subnet_android(ipa_ip_type iptype)4175 int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype)
4176 {
4177 	int i, len, res = IPACM_SUCCESS;
4178 	struct ipa_flt_rule_mdfy flt_rule;
4179 	struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
4180 	int mtu_rule_cnt = 0;
4181 	uint16_t mtu[IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES] = { };
4182 	int mtu_rule_idx = IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
4183 
4184 	if (rx_prop == NULL)
4185 	{
4186 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
4187 		return IPACM_SUCCESS;
4188 	}
4189 
4190 	if(iptype == IPA_IP_v6)
4191 	{
4192 		IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name);
4193 		return 0;
4194 	}
4195 	else
4196 	{
4197 		for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES; i++)
4198 		{
4199 			reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]);
4200 		}
4201 
4202 		/* check how many MTU rules we need to add */
4203 		for(i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
4204 		{
4205 			mtu[i] = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v4);
4206 
4207 			if (mtu[i] > 0)
4208 				mtu_rule_cnt++;
4209 			else
4210 				IPACMERR("MTU is zero\n");
4211 		}
4212 		IPACMDBG_H("total %d MTU rules are needed\n", mtu_rule_cnt);
4213 
4214 		len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet + mtu_rule_cnt) * sizeof(struct ipa_flt_rule_mdfy);
4215 		pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
4216 		if (!pFilteringTable)
4217 		{
4218 			IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n");
4219 			return IPACM_FAILURE;
4220 		}
4221 		memset(pFilteringTable, 0, len);
4222 
4223 		pFilteringTable->commit = 1;
4224 		pFilteringTable->ip = iptype;
4225 		pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet + mtu_rule_cnt;
4226 
4227 		/* Make LAN-traffic always go A5, use default IPA-RT table */
4228 		if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4))
4229 		{
4230 			IPACMERR("Failed to get routing table handle.\n");
4231 			res = IPACM_FAILURE;
4232 			goto fail;
4233 		}
4234 
4235 		memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
4236 		flt_rule.status = -1;
4237 
4238 		flt_rule.rule.retain_hdr = 1;
4239 		flt_rule.rule.to_uc = 0;
4240 		flt_rule.rule.action = IPA_PASS_TO_ROUTING;
4241 		flt_rule.rule.eq_attrib_type = 0;
4242 		flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl;
4243 		IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name);
4244 
4245 		for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
4246 		{
4247 			/* add private subnet rule for ipv4 */
4248 			flt_rule.rule.action = IPA_PASS_TO_ROUTING;
4249 			flt_rule.rule.eq_attrib_type = 0;
4250 			flt_rule.rule_hdl = private_fl_rule_hdl[i];
4251 			memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
4252 			flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
4253 			flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
4254 			flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
4255 			memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
4256 			IPACMDBG_H(" IPACM private subnet_addr as: 0x%x entry(%d)\n", flt_rule.rule.attrib.u.v4.dst_addr, i);
4257 
4258 			/* add corresponding MTU rule for ipv4 */
4259 			if (mtu[i] > 0)
4260 			{
4261 				flt_rule.rule_hdl = private_fl_rule_hdl[mtu_rule_idx + i];
4262 				memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
4263 				flt_rule.rule.attrib.u.v4.src_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
4264 				flt_rule.rule.attrib.u.v4.src_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
4265 				flt_rule.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
4266 				if (construct_mtu_rule(&flt_rule.rule, IPA_IP_v4, mtu[i]))
4267 					IPACMERR("Failed to modify MTU filtering rule.\n");
4268 				memcpy(&(pFilteringTable->rules[mtu_rule_idx + i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
4269 				IPACMDBG_H("Adding MTU rule for private subnet 0x%x.\n", flt_rule.rule.attrib.u.v4.src_addr);
4270 			}
4271 		}
4272 
4273 		if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
4274 		{
4275 			IPACMERR("Failed to modify private subnet filtering rules.\n");
4276 			res = IPACM_FAILURE;
4277 			goto fail;
4278 		}
4279 	}
4280 fail:
4281 	if(pFilteringTable != NULL)
4282 	{
4283 		free(pFilteringTable);
4284 	}
4285 	return res;
4286 }
4287 
install_ipv6_prefix_flt_rule(uint32_t * prefix)4288 int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
4289 {
4290 	if(prefix == NULL)
4291 	{
4292 		IPACMERR("IPv6 prefix is empty.\n");
4293 		return IPACM_FAILURE;
4294 	}
4295 	IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]);
4296 
4297 	int len;
4298 	struct ipa_ioc_add_flt_rule* flt_rule;
4299 	struct ipa_flt_rule_add flt_rule_entry;
4300 	bool result;
4301 	int rule_cnt = 1;
4302 
4303 	uint16_t mtu = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v6);
4304 	if (mtu > 0)
4305 		rule_cnt ++;
4306 
4307 	if(rx_prop != NULL)
4308 	{
4309 		len = sizeof(struct ipa_ioc_add_flt_rule) + rule_cnt * sizeof(struct ipa_flt_rule_add);
4310 
4311 		flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(rule_cnt, len);
4312 		if (!flt_rule)
4313 		{
4314 			IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
4315 			return IPACM_FAILURE;
4316 		}
4317 
4318 		flt_rule->commit = 1;
4319 		flt_rule->ep = rx_prop->rx[0].src_pipe;
4320 		flt_rule->global = false;
4321 		flt_rule->ip = IPA_IP_v6;
4322 		flt_rule->num_rules = rule_cnt;
4323 
4324 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
4325 
4326 		flt_rule_entry.rule.retain_hdr = 1;
4327 		flt_rule_entry.rule.to_uc = 0;
4328 		flt_rule_entry.rule.eq_attrib_type = 0;
4329 		flt_rule_entry.at_rear = true;
4330 		flt_rule_entry.flt_rule_hdl = -1;
4331 		flt_rule_entry.status = -1;
4332 		flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
4333 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
4334 			flt_rule_entry.rule.hashable = true;
4335 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
4336 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
4337 		flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0];
4338 		flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1];
4339 		flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x0;
4340 		flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x0;
4341 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
4342 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
4343 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x0;
4344 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0;
4345 		memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4346 
4347 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); // this will remove the IPA_FLT_DST_ADDR
4348 		flt_rule_entry.rule.attrib.u.v6.src_addr[3] = prefix[0];
4349 		flt_rule_entry.rule.attrib.u.v6.src_addr[2] = prefix[1];
4350 		flt_rule_entry.rule.attrib.u.v6.src_addr[1] = 0x0;
4351 		flt_rule_entry.rule.attrib.u.v6.src_addr[0] = 0x0;
4352 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[3] = 0xFFFFFFFF;
4353 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[2] = 0xFFFFFFFF;
4354 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[1] = 0x0;
4355 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[0] = 0x0;
4356 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
4357 
4358 		/* Add an MTU rule with every new private prefix */
4359 		if (mtu > 0)
4360 		{
4361 			if (construct_mtu_rule(&flt_rule_entry.rule, IPA_IP_v6, mtu))
4362 			{
4363 				IPACMERR("Failed to add MTU filtering rule.\n")
4364 			}
4365 			else
4366 			{
4367 				memcpy(&(flt_rule->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4368 			}
4369 		}
4370 
4371 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
4372 		/* use index hw-counter */
4373 		if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
4374 		{
4375 			IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
4376 			result = m_filtering.AddFilteringRule_hw_index(flt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
4377 		} else {
4378 			result = m_filtering.AddFilteringRule(flt_rule);
4379 		}
4380 #else
4381 		result = m_filtering.AddFilteringRule(flt_rule);
4382 #endif
4383 
4384 		if (result == false)
4385 		{
4386 			IPACMERR("Error Adding Filtering rule, aborting...\n");
4387 			free(flt_rule);
4388 			return IPACM_FAILURE;
4389 		}
4390 		else
4391 		{
4392 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 2);
4393 			ipv6_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
4394 			IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]);
4395 			if (rule_cnt > 1)
4396 			{
4397 				ipv6_prefix_flt_rule_hdl[1] = flt_rule->rules[1].flt_rule_hdl;
4398 				IPACMDBG_H("IPv6 prefix MTU filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[1]);
4399 			}
4400 			free(flt_rule);
4401 		}
4402 	}
4403 	return IPACM_SUCCESS;
4404 }
4405 
delete_ipv6_prefix_flt_rule()4406 void IPACM_Lan::delete_ipv6_prefix_flt_rule()
4407 {
4408 	if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_PREFIX_MTU_RULE) == false)
4409 	{
4410 		IPACMERR("Failed to delete ipv6 prefix flt rules.\n");
4411 		return;
4412 	}
4413 	IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_PREFIX_MTU_RULE);
4414 	return;
4415 }
4416 
handle_addr_evt_odu_bridge(ipacm_event_data_addr * data)4417 int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data)
4418 {
4419 	int fd, res = IPACM_SUCCESS;
4420 	struct in6_addr ipv6_addr;
4421 	if(data == NULL)
4422 	{
4423 		IPACMERR("Failed to get interface IP address.\n");
4424 		return IPACM_FAILURE;
4425 	}
4426 
4427 	if(data->iptype == IPA_IP_v6)
4428 	{
4429 		fd = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR);
4430 		if(fd == 0)
4431 		{
4432 			IPACMERR("Failed to open %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU);
4433 			return IPACM_FAILURE;
4434 		}
4435 
4436 		memcpy(&ipv6_addr, data->ipv6_addr, sizeof(struct in6_addr));
4437 
4438 		if( ioctl(fd, ODU_BRIDGE_IOC_SET_LLV6_ADDR, &ipv6_addr) )
4439 		{
4440 			IPACMERR("Failed to write IPv6 address to odu driver.\n");
4441 			res = IPACM_FAILURE;
4442 		}
4443 		num_dft_rt_v6++;
4444 		close(fd);
4445 	}
4446 
4447 	return res;
4448 }
4449 
eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1,ipa_hdr_l2_type t2)4450 ipa_hdr_proc_type IPACM_Lan::eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2)
4451 {
4452 	if(t1 == IPA_HDR_L2_ETHERNET_II)
4453 	{
4454 		if(t2 == IPA_HDR_L2_ETHERNET_II)
4455 		{
4456 			return IPA_HDR_PROC_ETHII_TO_ETHII;
4457 		}
4458 		if(t2 == IPA_HDR_L2_802_3)
4459 		{
4460 			return IPA_HDR_PROC_ETHII_TO_802_3;
4461 		}
4462 	}
4463 
4464 	if(t1 == IPA_HDR_L2_802_3)
4465 	{
4466 		if(t2 == IPA_HDR_L2_ETHERNET_II)
4467 		{
4468 			return IPA_HDR_PROC_802_3_TO_ETHII;
4469 		}
4470 		if(t2 == IPA_HDR_L2_802_3)
4471 		{
4472 			return IPA_HDR_PROC_802_3_TO_802_3;
4473 		}
4474 	}
4475 
4476 	return IPA_HDR_PROC_NONE;
4477 }
4478 
eth_bridge_get_hdr_template_hdl(uint32_t * hdr_hdl)4479 int IPACM_Lan::eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl)
4480 {
4481 	if(hdr_hdl == NULL)
4482 	{
4483 		IPACMDBG_H("Hdr handle pointer is empty.\n");
4484 		return IPACM_FAILURE;
4485 	}
4486 
4487 	struct ipa_ioc_get_hdr hdr;
4488 	memset(&hdr, 0, sizeof(hdr));
4489 
4490 	memcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
4491 	if(m_header.GetHeaderHandle(&hdr) == false)
4492 	{
4493 		IPACMERR("Failed to get template hdr hdl.\n");
4494 		return IPACM_FAILURE;
4495 	}
4496 
4497 	*hdr_hdl = hdr.hdl;
4498 	return IPACM_SUCCESS;
4499 }
4500 
handle_cradle_wan_mode_switch(bool is_wan_bridge_mode)4501 int IPACM_Lan::handle_cradle_wan_mode_switch(bool is_wan_bridge_mode)
4502 {
4503 	struct ipa_flt_rule_mdfy flt_rule_entry;
4504 	int len = 0;
4505 	ipa_ioc_mdfy_flt_rule *m_pFilteringTable;
4506 
4507 	IPACMDBG_H("Handle wan mode swtich: is wan bridge mode?%d\n", is_wan_bridge_mode);
4508 
4509 	if (rx_prop == NULL)
4510 	{
4511 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
4512 		return IPACM_SUCCESS;
4513 	}
4514 
4515 	len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (1 * sizeof(struct ipa_flt_rule_mdfy));
4516 	m_pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len);
4517 	if (m_pFilteringTable == NULL)
4518 	{
4519 		PERROR("Error Locate ipa_ioc_mdfy_flt_rule memory...\n");
4520 		return IPACM_FAILURE;
4521 	}
4522 
4523 	m_pFilteringTable->commit = 1;
4524 	m_pFilteringTable->ip = IPA_IP_v4;
4525 	m_pFilteringTable->num_rules = (uint8_t)1;
4526 
4527 	IPACMDBG_H("Retrieving routing hanle for table: %s\n",
4528 					 IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name);
4529 	if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4))
4530 	{
4531 		IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n",
4532 						 &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4);
4533 		free(m_pFilteringTable);
4534 		return IPACM_FAILURE;
4535 	}
4536 	IPACMDBG_H("Routing handle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl);
4537 
4538 
4539 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_mdfy)); // Zero All Fields
4540 	flt_rule_entry.status = -1;
4541 	flt_rule_entry.rule_hdl = lan_wan_fl_rule_hdl[0];
4542 
4543 	flt_rule_entry.rule.retain_hdr = 0;
4544 	flt_rule_entry.rule.to_uc = 0;
4545 	flt_rule_entry.rule.eq_attrib_type = 0;
4546 	if(is_wan_bridge_mode)
4547 	{
4548 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
4549 	}
4550 	else
4551 	{
4552 		flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
4553 	}
4554 	flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl;
4555 
4556 	memcpy(&flt_rule_entry.rule.attrib,
4557 				 &rx_prop->rx[0].attrib,
4558 				 sizeof(flt_rule_entry.rule.attrib));
4559 
4560 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
4561 	flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0;
4562 	flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0;
4563 
4564 	memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry));
4565 	if (false == m_filtering.ModifyFilteringRule(m_pFilteringTable))
4566 	{
4567 		IPACMERR("Error Modifying RuleTable(0) to Filtering, aborting...\n");
4568 		free(m_pFilteringTable);
4569 		return IPACM_FAILURE;
4570 	}
4571 	else
4572 	{
4573 		IPACMDBG_H("flt rule hdl = %d, status = %d\n",
4574 						 m_pFilteringTable->rules[0].rule_hdl,
4575 						 m_pFilteringTable->rules[0].status);
4576 	}
4577 	free(m_pFilteringTable);
4578 	return IPACM_SUCCESS;
4579 }
4580 
4581 /*handle reset usb-client rt-rules */
handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 * data)4582 int IPACM_Lan::handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 *data)
4583 {
4584 	int fd;
4585 	uint32_t pipe_len, cnt;
4586 	uint64_t num_ul_packets, num_ul_bytes;
4587 	uint64_t num_dl_packets, num_dl_bytes;
4588 	bool ul_pipe_found, dl_pipe_found;
4589 	FILE *fp = NULL;
4590 
4591 	fd = open(IPA_DEVICE_NAME, O_RDWR);
4592 	if (fd < 0)
4593 	{
4594 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
4595 		return IPACM_FAILURE;
4596 	}
4597 
4598 
4599 	ul_pipe_found = false;
4600 	dl_pipe_found = false;
4601 	num_ul_packets = 0;
4602 	num_dl_packets = 0;
4603 	num_ul_bytes = 0;
4604 	num_dl_bytes = 0;
4605 
4606 	if (data->dl_dst_pipe_stats_list_valid)
4607 	{
4608 		if(tx_prop != NULL)
4609 		{
4610 			for (pipe_len = 0; pipe_len < data->dl_dst_pipe_stats_list_len; pipe_len++)
4611 			{
4612 				IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->dl_dst_pipe_stats_list[pipe_len].pipe_index);
4613 				for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
4614 				{
4615 					IPACMDBG_H("Check Tx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe));
4616 					if(ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe) == (int)data->dl_dst_pipe_stats_list[pipe_len].pipe_index)
4617 					{
4618 						/* update the DL stats */
4619 						dl_pipe_found = true;
4620 						num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_packets;
4621 						num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_packets;
4622 						num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_bytes;
4623 						num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_bytes;
4624 						IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->dl_dst_pipe_stats_list[pipe_len].pipe_index, cnt);
4625 						IPACMDBG_H("DL_packets:(%llu) DL_bytes:(%llu) \n", (long long)num_dl_packets, (long long)num_dl_bytes);
4626 						break;
4627 					}
4628 				}
4629 			}
4630 		}
4631 	}
4632 
4633 	if (data->ul_src_pipe_stats_list_valid)
4634 	{
4635 		if(rx_prop != NULL)
4636 		{
4637 			for (pipe_len = 0; pipe_len < data->ul_src_pipe_stats_list_len; pipe_len++)
4638 			{
4639 				IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->ul_src_pipe_stats_list[pipe_len].pipe_index);
4640 				for (cnt=0; cnt < rx_prop->num_rx_props; cnt++)
4641 				{
4642 					IPACMDBG_H("Check Rx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe));
4643 					//Typecasting to avoid -Wall -Werror errors
4644 					if(ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe) == (int)data->ul_src_pipe_stats_list[pipe_len].pipe_index)
4645 					{
4646 						/* update the UL stats */
4647 						ul_pipe_found = true;
4648 						num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_packets;
4649 						num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_packets;
4650 						num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_bytes;
4651 						num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_bytes;
4652 						IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->ul_src_pipe_stats_list[pipe_len].pipe_index, cnt);
4653 						IPACMDBG_H("UL_packets:(%llu) UL_bytes:(%llu) \n", (long long)num_ul_packets, (long long)num_ul_bytes);
4654 						break;
4655 					}
4656 				}
4657 			}
4658 		}
4659 	}
4660 	close(fd);
4661 
4662 	if (ul_pipe_found || dl_pipe_found)
4663 	{
4664 		IPACMDBG_H("Update IPA_TETHERING_STATS_UPDATE_EVENT, TX(P%llu/B%llu) RX(P%llu/B%llu) DEV(%s) to LTE(%s) \n",
4665 					(long long)num_ul_packets,
4666 						(long long)num_ul_bytes,
4667 							(long long)num_dl_packets,
4668 								(long long)num_dl_bytes,
4669 									dev_name,
4670 										IPACM_Wan::wan_up_dev_name);
4671 		fp = fopen(IPA_PIPE_STATS_FILE_NAME, "w");
4672 		if ( fp == NULL )
4673 		{
4674 			IPACMERR("Failed to write pipe stats to %s, error is %d - %s\n",
4675 					IPA_PIPE_STATS_FILE_NAME, errno, strerror(errno));
4676 			return IPACM_FAILURE;
4677 		}
4678 
4679 		fprintf(fp, PIPE_STATS,
4680 				dev_name,
4681 					IPACM_Wan::wan_up_dev_name,
4682 						(long long)num_ul_bytes,
4683 						(long long)num_ul_packets,
4684 							    (long long)num_dl_bytes,
4685 							(long long)num_dl_packets);
4686 		fclose(fp);
4687 	}
4688 	return IPACM_SUCCESS;
4689 }
4690 
set_client_pipe(enum ipa_client_type client,uint32_t * pipe)4691 int IPACM_Lan::set_client_pipe(enum ipa_client_type client, uint32_t *pipe)
4692 {
4693 	int fd;
4694 
4695 	fd = open(IPA_DEVICE_NAME, O_RDWR);
4696 	if(fd < 0)
4697 	{
4698 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
4699 		return IPACM_FAILURE;
4700 	}
4701 
4702 	*pipe = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, client);
4703 
4704 	close(fd);
4705 	return IPACM_SUCCESS;
4706 }
4707 
set_tether_client_wigig(wan_ioctl_set_tether_client_pipe * tether_client)4708 int IPACM_Lan::set_tether_client_wigig(wan_ioctl_set_tether_client_pipe *tether_client)
4709 {
4710 #define NUM_WIGIG_TX_PIPES 4
4711 
4712 	uint32_t cnt;
4713 	int ret;
4714 	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
4715 
4716 	if(fd_wwan_ioctl < 0)
4717 	{
4718 		IPACMERR("Failed to open %s.\n", WWAN_QMI_IOCTL_DEVICE_NAME);
4719 		return IPACM_FAILURE;
4720 	}
4721 
4722 	if(!tx_prop || !rx_prop)
4723 	{
4724 		IPACMERR("no props, can't set client %p, %p\n", rx_prop, tx_prop);
4725 		close(fd_wwan_ioctl);
4726 		return IPACM_FAILURE;
4727 	}
4728 
4729 	/* only one rx pipe for wigig */
4730 	tether_client->ul_src_pipe_len = rx_prop->num_rx_props;
4731 	for(cnt = 0; cnt < rx_prop->num_rx_props; cnt++)
4732 	{
4733 		ret = set_client_pipe(rx_prop->rx[cnt].src_pipe, &tether_client->ul_src_pipe_list[cnt]);
4734 		if(ret)
4735 		{
4736 			close(fd_wwan_ioctl);
4737 			return ret;
4738 		}
4739 		IPACMDBG_H("Rx(%d), src_pipe: %d, ipa_pipe: %d\n",
4740 			cnt, rx_prop->rx[cnt].src_pipe,
4741 			tether_client->ul_src_pipe_list[cnt]);
4742 	}
4743 
4744 	for(int i = 0; i < NUM_WIGIG_TX_PIPES; i++)
4745 	{
4746 		/* 4 tx pipes for wigig */
4747 		tether_client->dl_dst_pipe_len = tx_prop->num_tx_props;
4748 
4749 #ifdef IPA_CLIENT_WIGIG4_CONS
4750 		for(cnt = 0; cnt < tx_prop->num_tx_props; cnt++)
4751 		{
4752 			enum ipa_client_type client;
4753 
4754 			switch(i) {
4755 				case 0:
4756 					client = IPA_CLIENT_WIGIG1_CONS;
4757 					break;
4758 				case 1:
4759 					client = IPA_CLIENT_WIGIG2_CONS;
4760 					break;
4761 				case 2:
4762 					client = IPA_CLIENT_WIGIG3_CONS;
4763 					break;
4764 				case 3:
4765 					client = IPA_CLIENT_WIGIG4_CONS;
4766 					break;
4767 				default:
4768 					IPACMERR("shouldn't get here\n");
4769 					close(fd_wwan_ioctl);
4770 					return IPACM_FAILURE;
4771 			}
4772 			ret = set_client_pipe(client, &tether_client->dl_dst_pipe_list[cnt]);
4773 			if(ret)
4774 			{
4775 				close(fd_wwan_ioctl);
4776 				return ret;
4777 			}
4778 			IPACMDBG_H("Tx(%d), IPA_CLIENT_WIGIG%d_CONS, ipa_pipe: %d\n",
4779 				cnt, i + 1,
4780 				tether_client->dl_dst_pipe_list[cnt]);
4781 		}
4782 #endif
4783 		ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, tether_client);
4784 		if(ret != 0)
4785 		{
4786 			IPACMERR("Failed set tether-client-pipe %p with ret %d\n ", tether_client, ret);
4787 		}
4788 		IPACMDBG("Set wigig tether-client-pipe (%d) %p\n", i, tether_client);
4789 	}
4790 
4791 	close(fd_wwan_ioctl);
4792 	return ret;
4793 }
4794 
set_tether_client(wan_ioctl_set_tether_client_pipe * tether_client)4795 int IPACM_Lan::set_tether_client(wan_ioctl_set_tether_client_pipe *tether_client)
4796 {
4797 	uint32_t cnt;
4798 	int ret;
4799 	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
4800 
4801 	if(fd_wwan_ioctl < 0)
4802 	{
4803 		IPACMERR("Failed to open %s.\n", WWAN_QMI_IOCTL_DEVICE_NAME);
4804 		return IPACM_FAILURE;
4805 	}
4806 
4807 	if(tx_prop != NULL)
4808 	{
4809 		tether_client->dl_dst_pipe_len = tx_prop->num_tx_props;
4810 		for(cnt = 0; cnt < tx_prop->num_tx_props; cnt++)
4811 		{
4812 			ret = set_client_pipe(tx_prop->tx[cnt].dst_pipe, &tether_client->dl_dst_pipe_list[cnt]);
4813 			if(ret)
4814 			{
4815 				close(fd_wwan_ioctl);
4816 				return ret;
4817 			}
4818 			IPACMDBG_H("Tx(%d), dst_pipe: %d, ipa_pipe: %d\n",
4819 				cnt, tx_prop->tx[cnt].dst_pipe,
4820 				tether_client->dl_dst_pipe_list[cnt]);
4821 		}
4822 	}
4823 
4824 	if(rx_prop != NULL)
4825 	{
4826 		tether_client->ul_src_pipe_len = rx_prop->num_rx_props;
4827 		for(cnt = 0; cnt < rx_prop->num_rx_props; cnt++)
4828 		{
4829 			ret = set_client_pipe(rx_prop->rx[cnt].src_pipe, &tether_client->ul_src_pipe_list[cnt]);
4830 			if(ret)
4831 			{
4832 				close(fd_wwan_ioctl);
4833 				return ret;
4834 			}
4835 			IPACMDBG_H("Rx(%d), src_pipe: %d, ipa_pipe: %d\n",
4836 				cnt, rx_prop->rx[cnt].src_pipe,
4837 				tether_client->ul_src_pipe_list[cnt]);
4838 		}
4839 	}
4840 
4841 	ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, tether_client);
4842 	if(ret != 0)
4843 	{
4844 		IPACMERR("Failed set tether-client-pipe %p with ret %d\n ", &tether_client, ret);
4845 	}
4846 	IPACMDBG("Set tether-client-pipe %p\n", &tether_client);
4847 
4848 	close(fd_wwan_ioctl);
4849 	return ret;
4850 }
4851 
4852 /*handle tether client */
handle_tethering_client(bool reset,ipacm_client_enum ipa_client)4853 int IPACM_Lan::handle_tethering_client(bool reset, ipacm_client_enum ipa_client)
4854 {
4855 	int ret = IPACM_SUCCESS;
4856 	wan_ioctl_set_tether_client_pipe tether_client;
4857 
4858 	memset(&tether_client, 0, sizeof(tether_client));
4859 	tether_client.reset_client = reset;
4860 	tether_client.ipa_client = ipa_client;
4861 
4862 	/* special case for wigig (11ad) who has 4 Tx and 1 RX pipe */
4863 	if(!strcmp(dev_name, "wigig0"))
4864 	{
4865 		set_tether_client_wigig(&tether_client);
4866 	}
4867 	else
4868 	{
4869 		set_tether_client(&tether_client);
4870 	}
4871 
4872 	return ret;
4873 }
4874 
4875 /* mac address has to be provided for client related events */
eth_bridge_post_event(ipa_cm_event_id evt,ipa_ip_type iptype,uint8_t * mac,uint32_t * ipv6_addr,char * iface_name,int ep)4876 void IPACM_Lan::eth_bridge_post_event(ipa_cm_event_id evt, ipa_ip_type iptype, uint8_t *mac, uint32_t *ipv6_addr, char *iface_name,
4877 	int ep)
4878 {
4879 	ipacm_cmd_q_data eth_bridge_evt;
4880 	ipacm_event_eth_bridge *evt_data_eth_bridge;
4881 	const char *eventName = IPACM_Iface::ipacmcfg->getEventName(evt);
4882 #ifdef FEATURE_L2TP
4883 	ipacm_event_data_all *evt_data_all;
4884 #endif
4885 
4886 
4887 /* not enable rndis for lan2lan HW-offload due to android limitation */
4888 #ifdef FEATURE_IPA_ANDROID
4889 	if(ipa_if_cate == LAN_IF)
4890 	{
4891 		IPACMDBG_H("This is LAN IF (%s):ipa_index (%d) skip lan2lan events for Android \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
4892 		return;
4893 	}
4894 #endif
4895 
4896 	if(ipv6_addr)
4897 	{
4898 		IPACMDBG_H("IPv6 addr: %08x:%08x:%08x:%08x \n", ipv6_addr[0],
4899 			ipv6_addr[1], ipv6_addr[2], ipv6_addr[3]);
4900 	}
4901 	memset(&eth_bridge_evt, 0, sizeof(ipacm_cmd_q_data));
4902 	eth_bridge_evt.event = evt;
4903 
4904 #ifdef FEATURE_L2TP
4905 	if(evt == IPA_HANDLE_VLAN_CLIENT_INFO || evt == IPA_HANDLE_VLAN_IFACE_INFO)
4906 	{
4907 		evt_data_all = (ipacm_event_data_all*)malloc(sizeof(*evt_data_all));
4908 		if(evt_data_all == NULL)
4909 		{
4910 			IPACMERR("Failed to allocate memory.\n");
4911 			return;
4912 		}
4913 		memset(evt_data_all, 0, sizeof(*evt_data_all));
4914 
4915 		if(ipv6_addr)
4916 		{
4917 			IPACMDBG_H("IPv6 addr: %08x:%08x:%08x:%08x \n", ipv6_addr[0],
4918 				ipv6_addr[1], ipv6_addr[2], ipv6_addr[3]);
4919 			memcpy(evt_data_all->ipv6_addr, ipv6_addr, sizeof(evt_data_all->ipv6_addr));
4920 		}
4921 		if(mac)
4922 		{
4923 			IPACMDBG_H("Mac: 0x%02x%02x%02x%02x%02x%02x \n",
4924 				mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4925 			memcpy(evt_data_all->mac_addr, mac, sizeof(evt_data_all->mac_addr));
4926 		}
4927 		if(iface_name)
4928 		{
4929 			IPACMDBG_H("Iface: %s\n", iface_name);
4930 			memcpy(evt_data_all->iface_name, iface_name, sizeof(evt_data_all->iface_name));
4931 		}
4932 		eth_bridge_evt.evt_data = (void*)evt_data_all;
4933 	}
4934 	else
4935 #endif
4936 	{
4937 		evt_data_eth_bridge = (ipacm_event_eth_bridge*)malloc(sizeof(*evt_data_eth_bridge));
4938 		if(evt_data_eth_bridge == NULL)
4939 		{
4940 			IPACMERR("Failed to allocate memory.\n");
4941 			return;
4942 		}
4943 		memset(evt_data_eth_bridge, 0, sizeof(*evt_data_eth_bridge));
4944 
4945 		evt_data_eth_bridge->p_iface = this;
4946 		evt_data_eth_bridge->iptype = iptype;
4947 		evt_data_eth_bridge->ep = ep;
4948 		if(mac)
4949 		{
4950 			IPACMDBG_H("Mac: 0x%02x%02x%02x%02x%02x%02x \n",
4951 				mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4952 			memcpy(evt_data_eth_bridge->mac_addr, mac, sizeof(evt_data_eth_bridge->mac_addr));
4953 		}
4954 		if(iface_name)
4955 		{
4956 			IPACMDBG_H("Iface: %s\n", iface_name);
4957 			memcpy(evt_data_eth_bridge->iface_name, iface_name,
4958 				sizeof(evt_data_eth_bridge->iface_name));
4959 		}
4960 		eth_bridge_evt.evt_data = (void*)evt_data_eth_bridge;
4961 	}
4962 	if (eventName != NULL)
4963 	{
4964 		IPACMDBG_H("Posting event %s\n",
4965 				eventName);
4966 	}
4967 	IPACM_EvtDispatcher::PostEvt(&eth_bridge_evt);
4968 }
4969 
4970 /* add header processing context and return handle to lan2lan controller */
eth_bridge_add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_hdr_type,uint32_t * hdl)4971 int IPACM_Lan::eth_bridge_add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_hdr_type, uint32_t *hdl)
4972 {
4973 	int len, res = IPACM_SUCCESS;
4974 	uint32_t hdr_template;
4975 	ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL;
4976 
4977 	if(tx_prop == NULL)
4978 	{
4979 		IPACMERR("No tx prop.\n");
4980 		return IPACM_FAILURE;
4981 	}
4982 
4983 	len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add);
4984 	pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len);
4985 	if(pHeaderProcTable == NULL)
4986 	{
4987 		IPACMERR("Cannot allocate header processing context table.\n");
4988 		return IPACM_FAILURE;
4989 	}
4990 
4991 	memset(pHeaderProcTable, 0, len);
4992 	pHeaderProcTable->commit = 1;
4993 	pHeaderProcTable->num_proc_ctxs = 1;
4994 	pHeaderProcTable->proc_ctx[0].type = eth_bridge_get_hdr_proc_type(peer_l2_hdr_type, tx_prop->tx[0].hdr_l2_type);
4995 	eth_bridge_get_hdr_template_hdl(&hdr_template);
4996 	pHeaderProcTable->proc_ctx[0].hdr_hdl = hdr_template;
4997 	if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false)
4998 	{
4999 		IPACMERR("Adding hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status);
5000 		res = IPACM_FAILURE;
5001 		goto end;
5002 	}
5003 
5004 	*hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl;
5005 
5006 end:
5007 	free(pHeaderProcTable);
5008 	return res;
5009 }
5010 
5011 /* add routing rule and return handle to lan2lan controller */
eth_bridge_add_rt_rule(uint8_t * mac,char * rt_tbl_name,uint32_t hdr_proc_ctx_hdl,ipa_hdr_l2_type peer_l2_hdr_type,ipa_ip_type iptype,uint32_t * rt_rule_hdl,int * rt_rule_count,int ep)5012 int IPACM_Lan::eth_bridge_add_rt_rule(uint8_t *mac, char *rt_tbl_name, uint32_t hdr_proc_ctx_hdl,
5013 		ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int *rt_rule_count,
5014 		int ep)
5015 {
5016 	int len, res = IPACM_SUCCESS;
5017 	uint32_t i, position, num_rt_rule;
5018 	struct ipa_ioc_add_rt_rule* rt_rule_table = NULL;
5019 	struct ipa_rt_rule_add rt_rule;
5020 
5021 	IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n",
5022 			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
5023 
5024 	/*fix -Wall -Werror if wigig feature is not enabled */
5025 	IPACMDBG_H("ep: %d\n", ep);
5026 
5027 	num_rt_rule = each_client_rt_rule_count[iptype];
5028 
5029 	len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add);
5030 	rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len);
5031 	if (rt_rule_table == NULL)
5032 	{
5033 		IPACMERR("Failed to allocate memory.\n");
5034 		return IPACM_FAILURE;
5035 	}
5036 	memset(rt_rule_table, 0, len);
5037 
5038 	rt_rule_table->commit = 1;
5039 	rt_rule_table->ip = iptype;
5040 	rt_rule_table->num_rules = num_rt_rule;
5041 	strlcpy(rt_rule_table->rt_tbl_name, rt_tbl_name, sizeof(rt_rule_table->rt_tbl_name));
5042 	rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = 0;
5043 
5044 	memset(&rt_rule, 0, sizeof(ipa_rt_rule_add));
5045 	rt_rule.at_rear = false;
5046 	rt_rule.status = -1;
5047 	rt_rule.rt_rule_hdl = -1;
5048 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
5049 		rt_rule.rule.hashable = true;
5050 	rt_rule.rule.hdr_hdl = 0;
5051 	rt_rule.rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl;
5052 
5053 	position = 0;
5054 	for(i=0; i<iface_query->num_tx_props; i++)
5055 	{
5056 		if(tx_prop->tx[i].ip == iptype)
5057 		{
5058 			if(position >= num_rt_rule || position >= MAX_NUM_PROP)
5059 			{
5060 				IPACMERR("Number of routing rules already exceeds limit.\n");
5061 				res = IPACM_FAILURE;
5062 				goto end;
5063 			}
5064 #ifdef IPA_CLIENT_WIGIG4_CONS
5065 			if ((ep >= IPA_CLIENT_WIGIG1_CONS) && (ep <= IPA_CLIENT_WIGIG4_CONS))
5066 			{
5067 				IPACMDBG_H("wigig DL pipe %d\n", ep);
5068 				rt_rule.rule.dst = (enum ipa_client_type)ep;
5069 			}
5070 			else
5071 #endif
5072 			if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->isMCC_Mode)
5073 			{
5074 				IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n",
5075 						tx_prop->tx[i].alt_dst_pipe);
5076 				rt_rule.rule.dst = tx_prop->tx[i].alt_dst_pipe;
5077 			}
5078 			else
5079 			{
5080 				IPACMDBG_H("It is not WLAN MCC mode, use dst pipe: %d\n",
5081 						tx_prop->tx[i].dst_pipe);
5082 				rt_rule.rule.dst = tx_prop->tx[i].dst_pipe;
5083 			}
5084 
5085 			memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib));
5086 			if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II)
5087 				rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
5088 			else
5089 				rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
5090 			memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr));
5091 			memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask));
5092 
5093 			memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position]));
5094 			position++;
5095 		}
5096 	}
5097 	if(false == m_routing.AddRoutingRule(rt_rule_table))
5098 	{
5099 		IPACMERR("Routing rule addition failed!\n");
5100 		res = IPACM_FAILURE;
5101 		goto end;
5102 	}
5103 	else
5104 	{
5105 		*rt_rule_count = position;
5106 		for(i=0; i<position; i++)
5107 			rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
5108 	}
5109 
5110 end:
5111 	free(rt_rule_table);
5112 	return res;
5113 }
5114 
5115 /* modify routing rule*/
eth_bridge_modify_rt_rule(uint8_t * mac,uint32_t hdr_proc_ctx_hdl,ipa_hdr_l2_type peer_l2_hdr_type,ipa_ip_type iptype,uint32_t * rt_rule_hdl,int rt_rule_count)5116 int IPACM_Lan::eth_bridge_modify_rt_rule(uint8_t *mac, uint32_t hdr_proc_ctx_hdl,
5117 		ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int rt_rule_count)
5118 {
5119 	struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL;
5120 	struct ipa_rt_rule_mdfy *rt_rule_entry;
5121 	int len, res = IPACM_SUCCESS;
5122 	uint32_t index;
5123 
5124 	if(tx_prop == NULL)
5125 	{
5126 		IPACMDBG_H("No tx properties \n");
5127 		return IPACM_FAILURE;
5128 	}
5129 
5130 	if(ipa_if_cate != WLAN_IF)
5131 	{
5132 		IPACMDBG_H("This is not WLAN IF, no need to modify rt rule.\n");
5133 		return IPACM_SUCCESS;
5134 	}
5135 
5136 	IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n",
5137 			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
5138 
5139 	len = sizeof(struct ipa_ioc_mdfy_rt_rule) + rt_rule_count * sizeof(struct ipa_rt_rule_mdfy);
5140 	rt_rule = (struct ipa_ioc_mdfy_rt_rule *)malloc(len);
5141 	if(rt_rule == NULL)
5142 	{
5143 		IPACMERR("Unable to allocate memory for modify rt rule\n");
5144 		return IPACM_FAILURE;
5145 	}
5146 	memset(rt_rule, 0, len);
5147 
5148 	rt_rule->commit = 1;
5149 	rt_rule->num_rules = 0;
5150 	rt_rule->ip = iptype;
5151 
5152 	for (index = 0; index < tx_prop->num_tx_props; index++)
5153 	{
5154 		if (tx_prop->tx[index].ip == iptype)
5155 		{
5156 			if (rt_rule->num_rules >= rt_rule_count ||
5157 				rt_rule->num_rules >= MAX_NUM_PROP)
5158 			{
5159 				IPACMERR("Number of routing rules exceeds limit.\n");
5160 				res = IPACM_FAILURE;
5161 				goto end;
5162 			}
5163 
5164 			rt_rule_entry = &rt_rule->rules[rt_rule->num_rules];
5165 
5166 			if (IPACM_Iface::ipacmcfg->isMCC_Mode)
5167 			{
5168 				IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n",
5169 						tx_prop->tx[index].alt_dst_pipe);
5170 				rt_rule_entry->rule.dst = tx_prop->tx[index].alt_dst_pipe;
5171 			}
5172 			else
5173 			{
5174 				IPACMDBG_H("In WLAN SCC mode, use dst pipe: %d\n",
5175 						tx_prop->tx[index].dst_pipe);
5176 				rt_rule_entry->rule.dst = tx_prop->tx[index].dst_pipe;
5177 			}
5178 
5179 			rt_rule_entry->rule.hdr_hdl = 0;
5180 			rt_rule_entry->rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl;
5181 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
5182 				rt_rule_entry->rule.hashable = true;
5183 			memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[index].attrib,
5184 					sizeof(rt_rule_entry->rule.attrib));
5185 			if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II)
5186 				rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
5187 			else
5188 				rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
5189 			memcpy(rt_rule_entry->rule.attrib.dst_mac_addr, mac,
5190 					sizeof(rt_rule_entry->rule.attrib.dst_mac_addr));
5191 			memset(rt_rule_entry->rule.attrib.dst_mac_addr_mask, 0xFF,
5192 					sizeof(rt_rule_entry->rule.attrib.dst_mac_addr_mask));
5193 
5194 			rt_rule_entry->rt_rule_hdl = rt_rule_hdl[rt_rule->num_rules];
5195 			rt_rule->num_rules++;
5196 		}
5197 	}
5198 
5199 	if(m_routing.ModifyRoutingRule(rt_rule) == false)
5200 	{
5201 		IPACMERR("Failed to modify routing rules.\n");
5202 		res = IPACM_FAILURE;
5203 		goto end;
5204 	}
5205 	if(m_routing.Commit(iptype) == false)
5206 	{
5207 		IPACMERR("Failed to commit routing rules.\n");
5208 		res = IPACM_FAILURE;
5209 		goto end;
5210 	}
5211 	IPACMDBG("Modified routing rules successfully.\n");
5212 
5213 end:
5214 	free(rt_rule);
5215 	return res;
5216 }
5217 
eth_bridge_add_flt_rule(uint8_t * mac,uint32_t rt_tbl_hdl,ipa_ip_type iptype,uint32_t * flt_rule_hdl)5218 int IPACM_Lan::eth_bridge_add_flt_rule(uint8_t *mac, uint32_t rt_tbl_hdl, ipa_ip_type iptype, uint32_t *flt_rule_hdl)
5219 {
5220 	int res = IPACM_SUCCESS;
5221 	int len;
5222 	struct ipa_flt_rule_add flt_rule_entry;
5223 	struct ipa_ioc_add_flt_rule_after *pFilteringTable = NULL;
5224 	bool result;
5225 
5226 	IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
5227 	IPACMDBG_H("Received rt_tbl_hdl :%d iptype %d\n", rt_tbl_hdl,iptype);
5228 	*flt_rule_hdl = 0;
5229 
5230 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
5231 	{
5232 		if (rx_prop == NULL || tx_prop == NULL)
5233 		{
5234 			IPACMDBG_H("No rx or tx properties registered for iface %s\n", dev_name);
5235 			return IPACM_FAILURE;
5236 		}
5237 
5238 
5239 		len = sizeof(struct ipa_ioc_add_flt_rule_after) + sizeof(struct ipa_flt_rule_add);
5240 		pFilteringTable = (struct ipa_ioc_add_flt_rule_after*)malloc(len);
5241 		if (!pFilteringTable)
5242 		{
5243 			IPACMERR("Failed to allocate ipa_ioc_add_flt_rule_after memory...\n");
5244 			return IPACM_FAILURE;
5245 		}
5246 		memset(pFilteringTable, 0, len);
5247 
5248 		/* add mac based rule*/
5249 		pFilteringTable->commit = 1;
5250 		pFilteringTable->ep = rx_prop->rx[0].src_pipe;
5251 		pFilteringTable->ip = iptype;
5252 		pFilteringTable->num_rules = 1;
5253 		pFilteringTable->add_after_hdl = eth_bridge_flt_rule_offset[iptype];
5254 
5255 		memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
5256 		flt_rule_entry.at_rear = 1;
5257 
5258 		flt_rule_entry.rule.retain_hdr = 0;
5259 		flt_rule_entry.rule.to_uc = 0;
5260 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
5261 		flt_rule_entry.rule.eq_attrib_type = 0;
5262 		flt_rule_entry.rule.rt_tbl_hdl = rt_tbl_hdl;
5263 		flt_rule_entry.rule.hashable = true;
5264 
5265 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
5266 		if(tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_ETHERNET_II)
5267 		{
5268 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
5269 		}
5270 		else
5271 		{
5272 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
5273 		}
5274 
5275 		memcpy(flt_rule_entry.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr));
5276 		memset(flt_rule_entry.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr_mask));
5277 
5278 		memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
5279 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
5280 		/* use index hw-counter */
5281 		if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
5282 		{
5283 			IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
5284 			result = m_filtering.AddFilteringRuleAfter_hw_index(pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
5285 		} else {
5286 			result = m_filtering.AddFilteringRuleAfter(pFilteringTable);
5287 		}
5288 #else
5289 		result = m_filtering.AddFilteringRuleAfter(pFilteringTable);
5290 #endif
5291 		if (result == false)
5292 		{
5293 			IPACMERR("Failed to add client filtering rules.\n");
5294 			res = IPACM_FAILURE;
5295 			goto end;
5296 		}
5297 		*flt_rule_hdl = pFilteringTable->rules[0].flt_rule_hdl;
5298 
5299 end:
5300 		free(pFilteringTable);
5301 	}
5302 	else
5303 	{
5304 		IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
5305 		IPACMDBG_H("Not support rt_tbl_hdl %d flt_rule_hdl %p ip-type %d\n", rt_tbl_hdl, flt_rule_hdl, iptype);
5306 	}
5307 	return res;
5308 }
5309 
eth_bridge_del_flt_rule(uint32_t flt_rule_hdl,ipa_ip_type iptype)5310 int IPACM_Lan::eth_bridge_del_flt_rule(uint32_t flt_rule_hdl, ipa_ip_type iptype)
5311 {
5312 	if(m_filtering.DeleteFilteringHdls(&flt_rule_hdl, iptype, 1) == false)
5313 	{
5314 		IPACMERR("Failed to delete the client specific flt rule.\n");
5315 		return IPACM_FAILURE;
5316 	}
5317 	return IPACM_SUCCESS;
5318 }
5319 
eth_bridge_del_rt_rule(uint32_t rt_rule_hdl,ipa_ip_type iptype)5320 int IPACM_Lan::eth_bridge_del_rt_rule(uint32_t rt_rule_hdl, ipa_ip_type iptype)
5321 {
5322 	if(m_routing.DeleteRoutingHdl(rt_rule_hdl, iptype) == false)
5323 	{
5324 		IPACMERR("Failed to delete routing rule.\n");
5325 		return IPACM_FAILURE;
5326 	}
5327 	return IPACM_SUCCESS;
5328 }
5329 
5330 /* delete header processing context */
eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl)5331 int IPACM_Lan::eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl)
5332 {
5333 	if(m_header.DeleteHeaderProcCtx(hdr_proc_ctx_hdl) == false)
5334 	{
5335 		IPACMERR("Failed to delete hdr proc ctx.\n");
5336 		return IPACM_FAILURE;
5337 	}
5338 	return IPACM_SUCCESS;
5339 }
5340 
5341 #ifdef FEATURE_L2TP
5342 /* check if the event is associated with vlan interface */
is_vlan_event(char * event_iface_name)5343 bool IPACM_Lan::is_vlan_event(char *event_iface_name)
5344 {
5345 	int self_name_len, event_iface_name_len;
5346 	if(event_iface_name == NULL)
5347 	{
5348 		IPACMERR("Invalid input\n");
5349 		return false;
5350 	}
5351 
5352 	IPACMDBG_H("Self iface %s, event iface %s\n", dev_name, event_iface_name);
5353 	self_name_len = strlen(dev_name);
5354 	event_iface_name_len = strlen(event_iface_name);
5355 
5356 	if(event_iface_name_len > self_name_len && strncmp(dev_name, event_iface_name, self_name_len) == 0)
5357 	{
5358 		IPACMDBG_H("This is vlan event.\n");
5359 		return true;
5360 	}
5361 	return false;
5362 }
5363 
5364 /* check if the event is associated with l2tp interface */
is_l2tp_event(char * event_iface_name)5365 bool IPACM_Lan::is_l2tp_event(char *event_iface_name)
5366 {
5367 	if(event_iface_name == NULL)
5368 	{
5369 		IPACMERR("Invalid input\n");
5370 		return false;
5371 	}
5372 
5373 	IPACMDBG_H("Self iface %s, event iface %s\n", dev_name, event_iface_name);
5374 	if(strncmp(event_iface_name, "l2tp", 4) == 0)
5375 	{
5376 		IPACMDBG_H("This is l2tp event.\n");
5377 		return true;
5378 	}
5379 	return false;
5380 }
5381 
5382 /* add l2tp rt rule for l2tp client */
add_l2tp_rt_rule(ipa_ip_type iptype,uint8_t * dst_mac,ipa_hdr_l2_type peer_l2_hdr_type,uint32_t l2tp_session_id,uint32_t vlan_id,uint8_t * vlan_client_mac,uint32_t * vlan_iface_ipv6_addr,uint32_t * vlan_client_ipv6_addr,uint32_t * first_pass_hdr_hdl,uint32_t * first_pass_hdr_proc_ctx_hdl,uint32_t * second_pass_hdr_hdl,int * num_rt_hdl,uint32_t * first_pass_rt_rule_hdl,uint32_t * second_pass_rt_rule_hdl)5383 int IPACM_Lan::add_l2tp_rt_rule(ipa_ip_type iptype, uint8_t *dst_mac, ipa_hdr_l2_type peer_l2_hdr_type,
5384 	uint32_t l2tp_session_id, uint32_t vlan_id, uint8_t *vlan_client_mac, uint32_t *vlan_iface_ipv6_addr,
5385 	uint32_t *vlan_client_ipv6_addr, uint32_t *first_pass_hdr_hdl, uint32_t *first_pass_hdr_proc_ctx_hdl,
5386 	uint32_t *second_pass_hdr_hdl, int *num_rt_hdl, uint32_t *first_pass_rt_rule_hdl, uint32_t *second_pass_rt_rule_hdl)
5387 {
5388 	int i, size, position;
5389 	uint32_t tx_index;
5390 	uint32_t vlan_iface_ipv6_addr_network[4], vlan_client_ipv6_addr_network[4];
5391 	ipa_ioc_add_hdr *hdr_table;
5392 	ipa_hdr_add *hdr;
5393 	ipa_ioc_add_hdr_proc_ctx *hdr_proc_ctx_table;
5394 	ipa_hdr_proc_ctx_add *hdr_proc_ctx;
5395 	ipa_ioc_add_rt_rule* rt_rule_table;
5396 	ipa_rt_rule_add *rt_rule;
5397 	ipa_ioc_copy_hdr copy_hdr;
5398 
5399 	if(tx_prop == NULL)
5400 	{
5401 		IPACMERR("No tx prop.\n");
5402 		return IPACM_FAILURE;
5403 	}
5404 
5405 	/* =========== install first pass hdr template (IPv6 + L2TP + inner ETH header = 62 bytes) ============= */
5406 	if(*first_pass_hdr_hdl != 0)
5407 	{
5408 		IPACMDBG_H("First pass hdr template was added before.\n");
5409 	}
5410 	else
5411 	{
5412 		size = sizeof(ipa_ioc_add_hdr) + sizeof(ipa_hdr_add);
5413 		hdr_table = (ipa_ioc_add_hdr*)malloc(size);
5414 		if(hdr_table == NULL)
5415 		{
5416 			IPACMERR("Failed to allocate memory.\n");
5417 			return IPACM_FAILURE;
5418 		}
5419 		memset(hdr_table, 0, size);
5420 
5421 		hdr_table->commit = 1;
5422 		hdr_table->num_hdrs = 1;
5423 		hdr = &hdr_table->hdr[0];
5424 
5425 		if(iptype == IPA_IP_v4)
5426 		{
5427 			snprintf(hdr->name, sizeof(hdr->name), "vlan_%d_l2tp_%d_v4", vlan_id, l2tp_session_id);
5428 		}
5429 		else
5430 		{
5431 			snprintf(hdr->name, sizeof(hdr->name), "vlan_%d_l2tp_%d_v6", vlan_id, l2tp_session_id);
5432 		}
5433 		hdr->hdr_len = 62;
5434 		hdr->type = IPA_HDR_L2_ETHERNET_II;
5435 		hdr->is_partial = 0;
5436 
5437 		hdr->hdr[0] = 0x60;	/* version */
5438 		hdr->hdr[6] = 0x73; /* next header = L2TP */
5439 		hdr->hdr[7] = 0x40; /* hop limit = 64 */
5440 		for(i = 0; i < 4; i++)
5441 		{
5442 			vlan_iface_ipv6_addr_network[i] = htonl(vlan_iface_ipv6_addr[i]);
5443 			vlan_client_ipv6_addr_network[i] = htonl(vlan_client_ipv6_addr[i]);
5444 		}
5445 		memcpy(hdr->hdr + 8, vlan_iface_ipv6_addr_network, 16); /* source IPv6 addr */
5446 		memcpy(hdr->hdr + 24, vlan_client_ipv6_addr_network, 16); /* dest IPv6 addr */
5447 		hdr->hdr[43] = (uint8_t)(l2tp_session_id & 0xFF); /* l2tp header */
5448 		hdr->hdr[42] = (uint8_t)(l2tp_session_id >> 8 & 0xFF);
5449 		hdr->hdr[41] = (uint8_t)(l2tp_session_id >> 16 & 0xFF);
5450 		hdr->hdr[40] = (uint8_t)(l2tp_session_id >> 24 & 0xFF);
5451 
5452 		if(m_header.AddHeader(hdr_table) == false)
5453 		{
5454 			IPACMERR("Failed to add hdr with status: %d\n", hdr_table->hdr[0].status);
5455 			free(hdr_table);
5456 			return IPACM_FAILURE;
5457 		}
5458 		*first_pass_hdr_hdl = hdr_table->hdr[0].hdr_hdl;
5459 		IPACMDBG_H("Installed first pass hdr: hdl %d\n", *first_pass_hdr_hdl);
5460 		free(hdr_table);
5461 	}
5462 
5463 	/* =========== install first pass hdr proc ctx (populate src/dst MAC and Ether type) ============= */
5464 	size = sizeof(ipa_ioc_add_hdr_proc_ctx) + sizeof(ipa_hdr_proc_ctx_add);
5465 	hdr_proc_ctx_table = (ipa_ioc_add_hdr_proc_ctx*)malloc(size);
5466 	if(hdr_proc_ctx_table == NULL)
5467 	{
5468 		IPACMERR("Failed to allocate memory.\n");
5469 		return IPACM_FAILURE;
5470 	}
5471 	memset(hdr_proc_ctx_table, 0, size);
5472 
5473 	hdr_proc_ctx_table->commit = 1;
5474 	hdr_proc_ctx_table->num_proc_ctxs = 1;
5475 	hdr_proc_ctx = &hdr_proc_ctx_table->proc_ctx[0];
5476 
5477 	hdr_proc_ctx->type = IPA_HDR_PROC_L2TP_HEADER_ADD;
5478 	hdr_proc_ctx->hdr_hdl = *first_pass_hdr_hdl;
5479 	hdr_proc_ctx->l2tp_params.hdr_add_param.eth_hdr_retained = 1;
5480 	hdr_proc_ctx->l2tp_params.hdr_add_param.input_ip_version = iptype;
5481 	hdr_proc_ctx->l2tp_params.hdr_add_param.output_ip_version = IPA_IP_v6;
5482 	if(m_header.AddHeaderProcCtx(hdr_proc_ctx_table) == false)
5483 	{
5484 		IPACMERR("Failed to add hdr proc ctx with status: %d\n", hdr_proc_ctx_table->proc_ctx[0].status);
5485 		free(hdr_proc_ctx_table);
5486 		return IPACM_FAILURE;
5487 	}
5488 	*first_pass_hdr_proc_ctx_hdl = hdr_proc_ctx_table->proc_ctx[0].proc_ctx_hdl;
5489 	IPACMDBG_H("Installed first pass hdr proc ctx: hdl %d\n", *first_pass_hdr_proc_ctx_hdl);
5490 	free(hdr_proc_ctx_table);
5491 
5492 	/* =========== install first pass rt rules (match dst MAC then doing UCP) ============= */
5493 	*num_rt_hdl = each_client_rt_rule_count[iptype];
5494 	size = sizeof(ipa_ioc_add_rt_rule) + (*num_rt_hdl) * sizeof(ipa_rt_rule_add);
5495 	rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(size);
5496 	if (rt_rule_table == NULL)
5497 	{
5498 		IPACMERR("Failed to allocate memory.\n");
5499 		return IPACM_FAILURE;
5500 	}
5501 	memset(rt_rule_table, 0, size);
5502 
5503 	rt_rule_table->commit = 1;
5504 	rt_rule_table->ip = iptype;
5505 	rt_rule_table->num_rules = *num_rt_hdl;
5506 	snprintf(rt_rule_table->rt_tbl_name, sizeof(rt_rule_table->rt_tbl_name), "l2tp");
5507 	rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = 0;
5508 
5509 	position = 0;
5510 	for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
5511 	{
5512 		if(tx_prop->tx[tx_index].ip == iptype)
5513 		{
5514 			if(position >= *num_rt_hdl || position >= MAX_NUM_PROP)
5515 			{
5516 				IPACMERR("Number of routing rules already exceeds limit.\n");
5517 				free(rt_rule_table);
5518 				return IPACM_FAILURE;
5519 			}
5520 
5521 			rt_rule = &rt_rule_table->rules[position];
5522 			rt_rule->at_rear = false;
5523 			rt_rule->status = -1;
5524 			rt_rule->rt_rule_hdl = -1;
5525 			rt_rule->rule.hashable = false;	//WLAN->ETH direction rules are set to non-hashable to keep consistent with the other direction
5526 			rt_rule->rule.hdr_hdl = 0;
5527 			rt_rule->rule.hdr_proc_ctx_hdl = *first_pass_hdr_proc_ctx_hdl;
5528 			rt_rule->rule.dst = IPA_CLIENT_DUMMY_CONS;
5529 
5530 			memcpy(&rt_rule->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule->rule.attrib));
5531 			if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II)
5532 				rt_rule->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
5533 			else
5534 				rt_rule->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
5535 			memcpy(rt_rule->rule.attrib.dst_mac_addr, dst_mac, sizeof(rt_rule->rule.attrib.dst_mac_addr));
5536 			memset(rt_rule->rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule->rule.attrib.dst_mac_addr_mask));
5537 			position++;
5538 		}
5539 	}
5540 	if(m_routing.AddRoutingRule(rt_rule_table) == false)
5541 	{
5542 		IPACMERR("Failed to add first pass rt rules.\n");
5543 		free(rt_rule_table);
5544 		return IPACM_FAILURE;
5545 	}
5546 	for(i = 0; i < position; i++)
5547 	{
5548 		first_pass_rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
5549 	}
5550 	free(rt_rule_table);
5551 
5552 	/* =========== install second pass hdr (Ethernet header with L2TP tag = 18 bytes) ============= */
5553 	if(*second_pass_hdr_hdl != 0)
5554 	{
5555 		IPACMDBG_H("Second pass hdr was added before.\n");
5556 	}
5557 	else
5558 	{
5559 		size = sizeof(ipa_ioc_add_hdr) + sizeof(ipa_hdr_add);
5560 		hdr_table = (ipa_ioc_add_hdr*)malloc(size);
5561 		if(hdr_table == NULL)
5562 		{
5563 			IPACMERR("Failed to allocate memory.\n");
5564 			return IPACM_FAILURE;
5565 		}
5566 		memset(hdr_table, 0, size);
5567 
5568 		hdr_table->commit = 1;
5569 		hdr_table->num_hdrs = 1;
5570 		hdr = &hdr_table->hdr[0];
5571 
5572 		if(iptype == IPA_IP_v4)
5573 		{
5574 			snprintf(hdr->name, sizeof(hdr->name), "vlan_%d_v4", vlan_id);
5575 		}
5576 		else
5577 		{
5578 			snprintf(hdr->name, sizeof(hdr->name), "vlan_%d_v6", vlan_id);
5579 		}
5580 		hdr->type = IPA_HDR_L2_ETHERNET_II;
5581 		hdr->is_partial = 0;
5582 		for(tx_index = 0; tx_index < tx_prop->num_tx_props; tx_index++)
5583 		{
5584 			if(tx_prop->tx[tx_index].ip == IPA_IP_v6)
5585 			{
5586 				memset(&copy_hdr, 0, sizeof(copy_hdr));
5587 				strlcpy(copy_hdr.name, tx_prop->tx[tx_index].hdr_name,
5588 					sizeof(copy_hdr.name));
5589 				IPACMDBG_H("Header name: %s in tx:%d\n", copy_hdr.name, tx_index);
5590 				if(m_header.CopyHeader(&copy_hdr) == false)
5591 				{
5592 					IPACMERR("Failed to get partial header.\n");
5593 					free(hdr_table);
5594 					return IPACM_FAILURE;
5595 				}
5596 				IPACMDBG_H("Header length: %d\n", copy_hdr.hdr_len);
5597 				hdr->hdr_len = copy_hdr.hdr_len;
5598 				memcpy(hdr->hdr, copy_hdr.hdr, hdr->hdr_len);
5599 				break;
5600 			}
5601 		}
5602 		/* copy vlan client mac */
5603 		memcpy(hdr->hdr + hdr->hdr_len - 18, vlan_client_mac, 6);
5604 		hdr->hdr[hdr->hdr_len - 3] = (uint8_t)vlan_id & 0xFF;
5605 		hdr->hdr[hdr->hdr_len - 4] = (uint8_t)(vlan_id >> 8) & 0xFF;
5606 
5607 		if(m_header.AddHeader(hdr_table) == false)
5608 		{
5609 			IPACMERR("Failed to add hdr with status: %d\n", hdr->status);
5610 			free(hdr_table);
5611 			return IPACM_FAILURE;
5612 		}
5613 		*second_pass_hdr_hdl = hdr->hdr_hdl;
5614 		IPACMDBG_H("Installed second pass hdr: hdl %d\n", *second_pass_hdr_hdl);
5615 		free(hdr_table);
5616 	}
5617 
5618 	/* =========== install second pass rt rules (match VLAN interface IPv6 address at dst client side) ============= */
5619 	if(second_pass_rt_rule_hdl[0] != 0)
5620 	{
5621 		IPACMDBG_H("Second pass rt rule was added before, return.\n");
5622 		return IPACM_SUCCESS;
5623 	}
5624 
5625 	*num_rt_hdl = each_client_rt_rule_count[IPA_IP_v6];
5626 	size = sizeof(ipa_ioc_add_rt_rule) + (*num_rt_hdl) * sizeof(ipa_rt_rule_add);
5627 	rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(size);
5628 	if (rt_rule_table == NULL)
5629 	{
5630 		IPACMERR("Failed to allocate memory.\n");
5631 		return IPACM_FAILURE;
5632 	}
5633 	memset(rt_rule_table, 0, size);
5634 
5635 	rt_rule_table->commit = 1;
5636 	rt_rule_table->ip = IPA_IP_v6;
5637 	rt_rule_table->num_rules = *num_rt_hdl;
5638 	snprintf(rt_rule_table->rt_tbl_name, sizeof(rt_rule_table->rt_tbl_name), "l2tp");
5639 	rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = 0;
5640 
5641 	position = 0;
5642 	for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
5643 	{
5644 		if(tx_prop->tx[tx_index].ip == IPA_IP_v6)
5645 		{
5646 			if(position >= *num_rt_hdl || position >= MAX_NUM_PROP)
5647 			{
5648 				IPACMERR("Number of routing rules already exceeds limit.\n");
5649 				free(rt_rule_table);
5650 				return IPACM_FAILURE;
5651 			}
5652 
5653 			rt_rule = &rt_rule_table->rules[position];
5654 			rt_rule->at_rear = false;
5655 			rt_rule->status = -1;
5656 			rt_rule->rt_rule_hdl = -1;
5657 			rt_rule->rule.hashable = false;	//WLAN->ETH direction rules are set to non-hashable to keep consistent with the other direction
5658 			rt_rule->rule.hdr_hdl = *second_pass_hdr_hdl;
5659 			rt_rule->rule.hdr_proc_ctx_hdl = 0;
5660 			rt_rule->rule.dst = tx_prop->tx[tx_index].dst_pipe;
5661 
5662 			memcpy(&rt_rule->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule->rule.attrib));
5663 			rt_rule->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
5664 			memcpy(rt_rule->rule.attrib.u.v6.dst_addr, vlan_client_ipv6_addr,
5665 				sizeof(rt_rule->rule.attrib.u.v6.dst_addr));
5666 			memset(rt_rule->rule.attrib.u.v6.dst_addr_mask, 0xFF, sizeof(rt_rule->rule.attrib.u.v6.dst_addr_mask));
5667 			position++;
5668 		}
5669 	}
5670 	if(m_routing.AddRoutingRule(rt_rule_table) == false)
5671 	{
5672 		IPACMERR("Failed to add second pass rt rules.\n");
5673 		free(rt_rule_table);
5674 		return IPACM_FAILURE;
5675 	}
5676 	for(i = 0; i < position; i++)
5677 	{
5678 		second_pass_rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
5679 	}
5680 	free(rt_rule_table);
5681 
5682 	return IPACM_SUCCESS;
5683 }
5684 
5685 /* delete l2tp rt rule for l2tp client */
del_l2tp_rt_rule(ipa_ip_type iptype,uint32_t first_pass_hdr_hdl,uint32_t first_pass_hdr_proc_ctx_hdl,uint32_t second_pass_hdr_hdl,int num_rt_hdl,uint32_t * first_pass_rt_rule_hdl,uint32_t * second_pass_rt_rule_hdl)5686 int IPACM_Lan::del_l2tp_rt_rule(ipa_ip_type iptype, uint32_t first_pass_hdr_hdl, uint32_t first_pass_hdr_proc_ctx_hdl,
5687 	uint32_t second_pass_hdr_hdl, int num_rt_hdl, uint32_t *first_pass_rt_rule_hdl, uint32_t *second_pass_rt_rule_hdl)
5688 {
5689 	int i;
5690 
5691 	if(num_rt_hdl < 0)
5692 	{
5693 		IPACMERR("Invalid num rt rule: %d\n", num_rt_hdl);
5694 		return IPACM_FAILURE;
5695 	}
5696 
5697 	for(i = 0; i < num_rt_hdl; i++)
5698 	{
5699 		if(first_pass_rt_rule_hdl != NULL)
5700 		{
5701 			if(m_routing.DeleteRoutingHdl(first_pass_rt_rule_hdl[i], iptype) == false)
5702 			{
5703 				return IPACM_FAILURE;
5704 			}
5705 		}
5706 		if(second_pass_rt_rule_hdl != NULL)
5707 		{
5708 			if(m_routing.DeleteRoutingHdl(second_pass_rt_rule_hdl[i], IPA_IP_v6) == false)
5709 			{
5710 				return IPACM_FAILURE;
5711 			}
5712 		}
5713 	}
5714 
5715 	if(first_pass_hdr_proc_ctx_hdl != 0)
5716 	{
5717 		if(m_header.DeleteHeaderProcCtx(first_pass_hdr_proc_ctx_hdl) == false)
5718 		{
5719 			return IPACM_FAILURE;
5720 		}
5721 	}
5722 
5723 	if(first_pass_hdr_hdl != 0)
5724 	{
5725 		if(m_header.DeleteHeaderHdl(first_pass_hdr_hdl) == false)
5726 		{
5727 			return IPACM_FAILURE;
5728 		}
5729 	}
5730 	if(second_pass_hdr_hdl != 0)
5731 	{
5732 		if(m_header.DeleteHeaderHdl(second_pass_hdr_hdl) == false)
5733 		{
5734 			return IPACM_FAILURE;
5735 		}
5736 	}
5737 
5738 	return IPACM_SUCCESS;
5739 }
5740 
5741 /* add l2tp rt rule for non l2tp client */
add_l2tp_rt_rule(ipa_ip_type iptype,uint8_t * dst_mac,uint32_t * hdr_proc_ctx_hdl,int * num_rt_hdl,uint32_t * rt_rule_hdl)5742 int IPACM_Lan::add_l2tp_rt_rule(ipa_ip_type iptype, uint8_t *dst_mac, uint32_t *hdr_proc_ctx_hdl,
5743 	int *num_rt_hdl, uint32_t *rt_rule_hdl)
5744 {
5745 	int i, size, position;
5746 	uint32_t tx_index;
5747 	ipa_ioc_add_hdr_proc_ctx *hdr_proc_ctx_table;
5748 	ipa_hdr_proc_ctx_add *hdr_proc_ctx;
5749 	ipa_ioc_add_rt_rule* rt_rule_table;
5750 	ipa_rt_rule_add *rt_rule;
5751 	ipa_ioc_get_hdr hdr;
5752 
5753 	if(tx_prop == NULL)
5754 	{
5755 		IPACMERR("No tx prop.\n");
5756 		return IPACM_FAILURE;
5757 	}
5758 
5759 	memset(&hdr, 0, sizeof(hdr));
5760 	for(tx_index = 0; tx_index < tx_prop->num_tx_props; tx_index++)
5761 	{
5762 		if(tx_prop->tx[tx_index].ip == iptype)
5763 		{
5764 			strlcpy(hdr.name, tx_prop->tx[tx_index].hdr_name,
5765 				sizeof(hdr.name));
5766 			break;
5767 		}
5768 	}
5769 	if(m_header.GetHeaderHandle(&hdr) == false)
5770 	{
5771 		IPACMERR("Failed to get template hdr hdl.\n");
5772 		return IPACM_FAILURE;
5773 	}
5774 
5775 	/* =========== install hdr proc ctx (uc needs to remove IPv6 + L2TP + inner ETH header = 62 bytes) ============= */
5776 	if(*hdr_proc_ctx_hdl != 0)
5777 	{
5778 		IPACMDBG_H("Hdr proc ctx was added before.\n");
5779 	}
5780 	else
5781 	{
5782 		size = sizeof(ipa_ioc_add_hdr_proc_ctx) + sizeof(ipa_hdr_proc_ctx_add);
5783 		hdr_proc_ctx_table = (ipa_ioc_add_hdr_proc_ctx*)malloc(size);
5784 		if(hdr_proc_ctx_table == NULL)
5785 		{
5786 			IPACMERR("Failed to allocate memory.\n");
5787 			return IPACM_FAILURE;
5788 		}
5789 		memset(hdr_proc_ctx_table, 0, size);
5790 
5791 		hdr_proc_ctx_table->commit = 1;
5792 		hdr_proc_ctx_table->num_proc_ctxs = 1;
5793 		hdr_proc_ctx = &hdr_proc_ctx_table->proc_ctx[0];
5794 
5795 		hdr_proc_ctx->type = IPA_HDR_PROC_L2TP_HEADER_REMOVE;
5796 		hdr_proc_ctx->hdr_hdl = hdr.hdl;
5797 		hdr_proc_ctx->l2tp_params.hdr_remove_param.hdr_len_remove = 62;
5798 		hdr_proc_ctx->l2tp_params.hdr_remove_param.eth_hdr_retained = 1;
5799 		hdr_proc_ctx->l2tp_params.is_dst_pipe_valid = 1;
5800 		hdr_proc_ctx->l2tp_params.dst_pipe = tx_prop->tx[0].dst_pipe;
5801 		IPACMDBG_H("Header_remove: hdr len %d, hdr retained %d, dst client: %d\n",
5802 			hdr_proc_ctx->l2tp_params.hdr_remove_param.hdr_len_remove,
5803 			hdr_proc_ctx->l2tp_params.hdr_remove_param.eth_hdr_retained,
5804 			hdr_proc_ctx->l2tp_params.dst_pipe);
5805 		if(m_header.AddHeaderProcCtx(hdr_proc_ctx_table) == false)
5806 		{
5807 			IPACMERR("Failed to add hdr proc ctx with status: %d\n", hdr_proc_ctx_table->proc_ctx[0].status);
5808 			free(hdr_proc_ctx_table);
5809 			return IPACM_FAILURE;
5810 		}
5811 		*hdr_proc_ctx_hdl = hdr_proc_ctx_table->proc_ctx[0].proc_ctx_hdl;
5812 		IPACMDBG_H("Installed hdr proc ctx: hdl %d\n", *hdr_proc_ctx_hdl);
5813 		free(hdr_proc_ctx_table);
5814 	}
5815 
5816 	/* =========== install rt rules (match dst MAC within 62 bytes header) ============= */
5817 	*num_rt_hdl = each_client_rt_rule_count[iptype];
5818 	size = sizeof(ipa_ioc_add_rt_rule) + (*num_rt_hdl) * sizeof(ipa_rt_rule_add);
5819 	rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(size);
5820 	if (rt_rule_table == NULL)
5821 	{
5822 		IPACMERR("Failed to allocate memory.\n");
5823 		return IPACM_FAILURE;
5824 	}
5825 	memset(rt_rule_table, 0, size);
5826 
5827 	rt_rule_table->commit = 1;
5828 	rt_rule_table->ip = iptype;
5829 	rt_rule_table->num_rules = *num_rt_hdl;
5830 	snprintf(rt_rule_table->rt_tbl_name, sizeof(rt_rule_table->rt_tbl_name), "l2tp");
5831 	rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = 0;
5832 
5833 	position = 0;
5834 	for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
5835 	{
5836 		if(tx_prop->tx[tx_index].ip == iptype)
5837 		{
5838 			if(position >= *num_rt_hdl || position >= MAX_NUM_PROP)
5839 			{
5840 				IPACMERR("Number of routing rules already exceeds limit.\n");
5841 				free(rt_rule_table);
5842 				return IPACM_FAILURE;
5843 			}
5844 
5845 			rt_rule = &rt_rule_table->rules[position];
5846 			rt_rule->at_rear = false;
5847 			rt_rule->status = -1;
5848 			rt_rule->rt_rule_hdl = -1;
5849 			rt_rule->rule.hashable = false;	//ETH->WLAN direction rules need to be non-hashable due to encapsulation
5850 
5851 			rt_rule->rule.hdr_hdl = 0;
5852 			rt_rule->rule.hdr_proc_ctx_hdl = *hdr_proc_ctx_hdl;
5853 			rt_rule->rule.dst = tx_prop->tx[tx_index].dst_pipe;
5854 
5855 			memcpy(&rt_rule->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule->rule.attrib));
5856 
5857 			rt_rule->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_L2TP;
5858 			memset(rt_rule->rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule->rule.attrib.dst_mac_addr_mask));
5859 			memcpy(rt_rule->rule.attrib.dst_mac_addr, dst_mac, sizeof(rt_rule->rule.attrib.dst_mac_addr));
5860 
5861 			position++;
5862 		}
5863 	}
5864 	if(m_routing.AddRoutingRule(rt_rule_table) == false)
5865 	{
5866 		IPACMERR("Failed to add first pass rt rules.\n");
5867 		free(rt_rule_table);
5868 		return IPACM_FAILURE;
5869 	}
5870 	for(i = 0; i < position; i++)
5871 		rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
5872 
5873 	free(rt_rule_table);
5874 	return IPACM_SUCCESS;
5875 }
5876 
del_l2tp_rt_rule(ipa_ip_type iptype,int num_rt_hdl,uint32_t * rt_rule_hdl)5877 int IPACM_Lan::del_l2tp_rt_rule(ipa_ip_type iptype, int num_rt_hdl, uint32_t *rt_rule_hdl)
5878 {
5879 	int i;
5880 
5881 	if(num_rt_hdl < 0)
5882 	{
5883 		IPACMERR("Invalid num rt rule: %d\n", num_rt_hdl);
5884 		return IPACM_FAILURE;
5885 	}
5886 
5887 	for(i = 0; i < num_rt_hdl; i++)
5888 	{
5889 		if(m_routing.DeleteRoutingHdl(rt_rule_hdl[i], iptype) == false)
5890 		{
5891 			return IPACM_FAILURE;
5892 		}
5893 	}
5894 
5895 	return IPACM_SUCCESS;
5896 }
5897 
5898 /* add l2tp flt rule on l2tp interface */
add_l2tp_flt_rule(uint8_t * dst_mac,uint32_t * flt_rule_hdl)5899 int IPACM_Lan::add_l2tp_flt_rule(uint8_t *dst_mac, uint32_t *flt_rule_hdl)
5900 {
5901 	int len;
5902 	int fd_ipa;
5903 	struct ipa_flt_rule_add flt_rule_entry;
5904 	struct ipa_ioc_add_flt_rule_after *pFilteringTable = NULL;
5905 	ipa_ioc_get_rt_tbl rt_tbl;
5906 
5907 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
5908 	{
5909 		if (rx_prop == NULL || tx_prop == NULL)
5910 		{
5911 			IPACMDBG_H("No rx or tx properties registered for iface %s\n", dev_name);
5912 			return IPACM_FAILURE;
5913 		}
5914 
5915 		len = sizeof(struct ipa_ioc_add_flt_rule_after) + sizeof(struct ipa_flt_rule_add);
5916 		pFilteringTable = (struct ipa_ioc_add_flt_rule_after*)malloc(len);
5917 		if (!pFilteringTable)
5918 		{
5919 			IPACMERR("Failed to allocate ipa_ioc_add_flt_rule_after memory...\n");
5920 			return IPACM_FAILURE;
5921 		}
5922 		memset(pFilteringTable, 0, len);
5923 
5924 		pFilteringTable->commit = 1;
5925 		pFilteringTable->ep = rx_prop->rx[0].src_pipe;
5926 		pFilteringTable->ip = IPA_IP_v6;
5927 		pFilteringTable->num_rules = 1;
5928 		pFilteringTable->add_after_hdl = eth_bridge_flt_rule_offset[IPA_IP_v6];
5929 
5930 		fd_ipa = open(IPA_DEVICE_NAME, O_RDWR);
5931 		if(fd_ipa == 0)
5932 		{
5933 			IPACMERR("Failed to open %s\n",IPA_DEVICE_NAME);
5934 			free(pFilteringTable);
5935 			return IPACM_FAILURE;
5936 		}
5937 
5938 		rt_tbl.ip = IPA_IP_v6;
5939 		snprintf(rt_tbl.name, sizeof(rt_tbl.name), "l2tp");
5940 		rt_tbl.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
5941 		IPACMDBG_H("This flt rule points to rt tbl %s.\n", rt_tbl.name);
5942 		if(m_routing.GetRoutingTable(&rt_tbl) == false)
5943 		{
5944 			IPACMERR("Failed to get routing table from name\n");
5945 			free(pFilteringTable);
5946 			close(fd_ipa);
5947 			return IPACM_FAILURE;
5948 		}
5949 
5950 		memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
5951 		flt_rule_entry.at_rear = 1;
5952 
5953 		flt_rule_entry.rule.retain_hdr = 0;
5954 		flt_rule_entry.rule.to_uc = 0;
5955 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
5956 		flt_rule_entry.rule.eq_attrib_type = 0;
5957 		flt_rule_entry.rule.rt_tbl_hdl = rt_tbl.hdl;
5958 		flt_rule_entry.rule.hashable = false;	//ETH->WLAN direction rules need to be non-hashable due to encapsulation
5959 
5960 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
5961 
5962 		/* flt rule is matching dst MAC within 62 bytes header */
5963 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_L2TP;
5964 		memset(flt_rule_entry.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr_mask));
5965 		memcpy(flt_rule_entry.rule.attrib.dst_mac_addr, dst_mac, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr));
5966 
5967 		memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
5968 		if(m_filtering.AddFilteringRuleAfter(pFilteringTable) == false)
5969 		{
5970 			IPACMERR("Failed to add client filtering rules.\n");
5971 			free(pFilteringTable);
5972 			close(fd_ipa);
5973 			return IPACM_FAILURE;
5974 		}
5975 		*flt_rule_hdl = pFilteringTable->rules[0].flt_rule_hdl;
5976 
5977 		free(pFilteringTable);
5978 		close(fd_ipa);
5979 	}
5980 	return IPACM_SUCCESS;
5981 }
5982 
5983 /* delete l2tp flt rule on l2tp interface */
del_l2tp_flt_rule(uint32_t flt_rule_hdl)5984 int IPACM_Lan::del_l2tp_flt_rule(uint32_t flt_rule_hdl)
5985 {
5986 	if(m_filtering.DeleteFilteringHdls(&flt_rule_hdl, IPA_IP_v6, 1) == false)
5987 	{
5988 		return IPACM_FAILURE;
5989 	}
5990 
5991 	return IPACM_SUCCESS;
5992 }
5993 
5994 /* add l2tp flt rule on non l2tp interface */
add_l2tp_flt_rule(ipa_ip_type iptype,uint8_t * dst_mac,uint32_t * vlan_client_ipv6_addr,uint32_t * first_pass_flt_rule_hdl,uint32_t * second_pass_flt_rule_hdl)5995 int IPACM_Lan::add_l2tp_flt_rule(ipa_ip_type iptype, uint8_t *dst_mac, uint32_t *vlan_client_ipv6_addr,
5996 	uint32_t *first_pass_flt_rule_hdl, uint32_t *second_pass_flt_rule_hdl)
5997 {
5998 	int len;
5999 	struct ipa_flt_rule_add flt_rule_entry;
6000 	struct ipa_ioc_add_flt_rule_after *pFilteringTable = NULL;
6001 	ipa_ioc_get_rt_tbl rt_tbl;
6002 
6003 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
6004 	{
6005 		if (rx_prop == NULL || tx_prop == NULL)
6006 		{
6007 			IPACMDBG_H("No rx or tx properties registered for iface %s\n", dev_name);
6008 			return IPACM_FAILURE;
6009 		}
6010 
6011 		IPACMDBG_H("Dst client MAC 0x%02x%02x%02x%02x%02x%02x.\n", dst_mac[0], dst_mac[1],
6012 			dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]);
6013 
6014 		len = sizeof(struct ipa_ioc_add_flt_rule_after) + sizeof(struct ipa_flt_rule_add);
6015 		pFilteringTable = (struct ipa_ioc_add_flt_rule_after*)malloc(len);
6016 		if (!pFilteringTable)
6017 		{
6018 			IPACMERR("Failed to allocate ipa_ioc_add_flt_rule_after memory...\n");
6019 			return IPACM_FAILURE;
6020 		}
6021 		memset(pFilteringTable, 0, len);
6022 
6023 		pFilteringTable->commit = 1;
6024 		pFilteringTable->ep = rx_prop->rx[0].src_pipe;
6025 		pFilteringTable->ip = iptype;
6026 		pFilteringTable->num_rules = 1;
6027 		pFilteringTable->add_after_hdl = eth_bridge_flt_rule_offset[iptype];
6028 
6029 		/* =========== add first pass flt rule (match dst MAC) ============= */
6030 		rt_tbl.ip = iptype;
6031 		snprintf(rt_tbl.name, sizeof(rt_tbl.name), "l2tp");
6032 		IPACMDBG_H("This flt rule points to rt tbl %s.\n", rt_tbl.name);
6033 
6034 		if(m_routing.GetRoutingTable(&rt_tbl) == false)
6035 		{
6036 			IPACMERR("Failed to get routing table.\n");
6037 			return IPACM_FAILURE;
6038 		}
6039 
6040 		memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
6041 		flt_rule_entry.at_rear = 1;
6042 
6043 		flt_rule_entry.rule.retain_hdr = 0;
6044 		flt_rule_entry.rule.to_uc = 0;
6045 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
6046 		flt_rule_entry.rule.eq_attrib_type = 0;
6047 		flt_rule_entry.rule.rt_tbl_hdl = rt_tbl.hdl;
6048 		flt_rule_entry.rule.hashable = false;	//WLAN->ETH direction rules are set to non-hashable to keep consistent with the other direction
6049 
6050 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
6051 		if(tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_ETHERNET_II)
6052 		{
6053 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
6054 		}
6055 		else
6056 		{
6057 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
6058 		}
6059 
6060 		memcpy(flt_rule_entry.rule.attrib.dst_mac_addr, dst_mac, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr));
6061 		memset(flt_rule_entry.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr_mask));
6062 
6063 		memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
6064 		if (false == m_filtering.AddFilteringRuleAfter(pFilteringTable))
6065 		{
6066 			IPACMERR("Failed to add first pass filtering rules.\n");
6067 			free(pFilteringTable);
6068 			return IPACM_FAILURE;
6069 		}
6070 		*first_pass_flt_rule_hdl = pFilteringTable->rules[0].flt_rule_hdl;
6071 
6072 		/* =========== add second pass flt rule (match VLAN interface IPv6 address at client side) ============= */
6073 		if(*second_pass_flt_rule_hdl != 0)
6074 		{
6075 			IPACMDBG_H("Second pass flt rule was added before, return.\n");
6076 			free(pFilteringTable);
6077 			return IPACM_SUCCESS;
6078 		}
6079 
6080 		rt_tbl.ip = IPA_IP_v6;
6081 		snprintf(rt_tbl.name, sizeof(rt_tbl.name), "l2tp");
6082 		IPACMDBG_H("This flt rule points to rt tbl %s.\n", rt_tbl.name);
6083 
6084 		if(m_routing.GetRoutingTable(&rt_tbl) == false)
6085 		{
6086 			IPACMERR("Failed to get routing table.\n");
6087 			return IPACM_FAILURE;
6088 		}
6089 
6090 		pFilteringTable->ip = IPA_IP_v6;
6091 		pFilteringTable->add_after_hdl = eth_bridge_flt_rule_offset[IPA_IP_v6];
6092 
6093 		memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
6094 		flt_rule_entry.at_rear = 1;
6095 
6096 		flt_rule_entry.rule.retain_hdr = 0;
6097 		flt_rule_entry.rule.to_uc = 0;
6098 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
6099 		flt_rule_entry.rule.eq_attrib_type = 0;
6100 		flt_rule_entry.rule.rt_tbl_hdl = rt_tbl.hdl;
6101 		flt_rule_entry.rule.hashable = false;	//WLAN->ETH direction rules are set to non-hashable to keep consistent with the other direction
6102 
6103 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
6104 		flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
6105 
6106 		memcpy(flt_rule_entry.rule.attrib.u.v6.dst_addr, vlan_client_ipv6_addr, sizeof(flt_rule_entry.rule.attrib.u.v6.dst_addr));
6107 		memset(flt_rule_entry.rule.attrib.u.v6.dst_addr_mask, 0xFF, sizeof(flt_rule_entry.rule.attrib.u.v6.dst_addr_mask));
6108 
6109 		memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
6110 		if (false == m_filtering.AddFilteringRuleAfter(pFilteringTable))
6111 		{
6112 			IPACMERR("Failed to add client filtering rules.\n");
6113 			free(pFilteringTable);
6114 			return IPACM_FAILURE;
6115 		}
6116 		*second_pass_flt_rule_hdl = pFilteringTable->rules[0].flt_rule_hdl;
6117 
6118 		free(pFilteringTable);
6119 	}
6120 	return IPACM_SUCCESS;
6121 }
6122 
6123 /* delete l2tp flt rule on non l2tp interface */
del_l2tp_flt_rule(ipa_ip_type iptype,uint32_t first_pass_flt_rule_hdl,uint32_t second_pass_flt_rule_hdl)6124 int IPACM_Lan::del_l2tp_flt_rule(ipa_ip_type iptype, uint32_t first_pass_flt_rule_hdl, uint32_t second_pass_flt_rule_hdl)
6125 {
6126 	if(first_pass_flt_rule_hdl != 0)
6127 	{
6128 		if(m_filtering.DeleteFilteringHdls(&first_pass_flt_rule_hdl, iptype, 1) == false)
6129 		{
6130 			return IPACM_FAILURE;
6131 		}
6132 	}
6133 
6134 	if(second_pass_flt_rule_hdl != 0)
6135 	{
6136 		if(m_filtering.DeleteFilteringHdls(&second_pass_flt_rule_hdl, iptype, 1) == false)
6137 		{
6138 			return IPACM_FAILURE;
6139 		}
6140 	}
6141 
6142 	return IPACM_SUCCESS;
6143 }
6144 
is_unique_local_ipv6_addr(uint32_t * ipv6_addr)6145 bool IPACM_Lan::is_unique_local_ipv6_addr(uint32_t* ipv6_addr)
6146 {
6147 	uint32_t ipv6_unique_local_prefix, ipv6_unique_local_prefix_mask;
6148 
6149 	if(ipv6_addr == NULL)
6150 	{
6151 		IPACMERR("IPv6 address is empty.\n");
6152 		return false;
6153 	}
6154 	IPACMDBG_H("Get ipv6 address with first word 0x%08x.\n", ipv6_addr[0]);
6155 
6156 	ipv6_unique_local_prefix = 0xFD000000;
6157 	ipv6_unique_local_prefix_mask = 0xFF000000;
6158 	if((ipv6_addr[0] & ipv6_unique_local_prefix_mask) == (ipv6_unique_local_prefix & ipv6_unique_local_prefix_mask))
6159 	{
6160 		IPACMDBG_H("This IPv6 address is unique local IPv6 address.\n");
6161 		return true;
6162 	}
6163 	return false;
6164 }
6165 #endif
6166 
6167 /* add tcp syn flt rule */
add_tcp_syn_flt_rule(ipa_ip_type iptype)6168 int IPACM_Lan::add_tcp_syn_flt_rule(ipa_ip_type iptype)
6169 {
6170 	int len;
6171 	struct ipa_flt_rule_add flt_rule_entry;
6172 	ipa_ioc_add_flt_rule *m_pFilteringTable;
6173 	bool result;
6174 
6175 	if(rx_prop == NULL)
6176 	{
6177 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
6178 		return IPACM_SUCCESS;
6179 	}
6180 
6181 	len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
6182 	m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
6183 	if(!m_pFilteringTable)
6184 	{
6185 		PERROR("Not enough memory.\n");
6186 		return IPACM_FAILURE;
6187 	}
6188 	memset(m_pFilteringTable, 0, len);
6189 
6190 	m_pFilteringTable->commit = 1;
6191 	m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
6192 	m_pFilteringTable->global = false;
6193 	m_pFilteringTable->ip = iptype;
6194 	m_pFilteringTable->num_rules = 1;
6195 
6196 	memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
6197 	flt_rule_entry.at_rear = true;
6198 	flt_rule_entry.rule.retain_hdr = 1;
6199 	flt_rule_entry.flt_rule_hdl = -1;
6200 	flt_rule_entry.status = -1;
6201 	flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
6202 
6203 	memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib,
6204 		sizeof(flt_rule_entry.rule.attrib));
6205 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_TCP_SYN;
6206 	if(iptype == IPA_IP_v4)
6207 	{
6208 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
6209 		flt_rule_entry.rule.attrib.u.v4.protocol = 6;
6210 	}
6211 	else
6212 	{
6213 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
6214 		flt_rule_entry.rule.attrib.u.v6.next_hdr = 6;
6215 	}
6216 
6217 	memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
6218 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
6219 	/* use index hw-counter */
6220 	if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
6221 	{
6222 		IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
6223 		result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
6224 	} else {
6225 		result = m_filtering.AddFilteringRule(m_pFilteringTable);
6226 	}
6227 #else
6228 	result = m_filtering.AddFilteringRule(m_pFilteringTable);
6229 #endif
6230 
6231 	if(result == false)
6232 	{
6233 		IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
6234 		free(m_pFilteringTable);
6235 		return IPACM_FAILURE;
6236 	}
6237 
6238 	tcp_syn_flt_rule_hdl[iptype] = m_pFilteringTable->rules[0].flt_rule_hdl;
6239 	free(m_pFilteringTable);
6240 	return IPACM_SUCCESS;
6241 }
6242 
6243 /* add tcp syn flt rule for l2tp interface*/
add_tcp_syn_flt_rule_l2tp(ipa_ip_type inner_ip_type)6244 int IPACM_Lan::add_tcp_syn_flt_rule_l2tp(ipa_ip_type inner_ip_type)
6245 {
6246 	int len;
6247 	struct ipa_flt_rule_add flt_rule_entry;
6248 	ipa_ioc_add_flt_rule *m_pFilteringTable;
6249 
6250 	if(rx_prop == NULL)
6251 	{
6252 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
6253 		return IPACM_SUCCESS;
6254 	}
6255 
6256 	len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
6257 	m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
6258 	if(!m_pFilteringTable)
6259 	{
6260 		PERROR("Not enough memory.\n");
6261 		return IPACM_FAILURE;
6262 	}
6263 	memset(m_pFilteringTable, 0, len);
6264 
6265 	m_pFilteringTable->commit = 1;
6266 	m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
6267 	m_pFilteringTable->global = false;
6268 	m_pFilteringTable->ip = IPA_IP_v6;
6269 	m_pFilteringTable->num_rules = 1;
6270 
6271 	memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
6272 	flt_rule_entry.at_rear = true;
6273 	flt_rule_entry.rule.retain_hdr = 1;
6274 	flt_rule_entry.flt_rule_hdl = -1;
6275 	flt_rule_entry.status = -1;
6276 	flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
6277 
6278 	memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib,
6279 		sizeof(flt_rule_entry.rule.attrib));
6280 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_TCP_SYN_L2TP;
6281 	if(inner_ip_type == IPA_IP_v4)
6282 	{
6283 		flt_rule_entry.rule.attrib.ether_type = 0x0800;
6284 	}
6285 	else
6286 	{
6287 		flt_rule_entry.rule.attrib.ether_type = 0x86dd;
6288 	}
6289 
6290 	memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
6291 	/* no need for hw counters */
6292 	if(false == m_filtering.AddFilteringRule(m_pFilteringTable))
6293 	{
6294 		IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
6295 		free(m_pFilteringTable);
6296 		return IPACM_FAILURE;
6297 	}
6298 
6299 	tcp_syn_flt_rule_hdl[inner_ip_type] = m_pFilteringTable->rules[0].flt_rule_hdl;
6300 	free(m_pFilteringTable);
6301 	return IPACM_SUCCESS;
6302 }
6303 
add_connection(int client_index,int v6_num)6304 int IPACM_Lan::add_connection(int client_index, int v6_num)
6305 {
6306 	int len, res = IPACM_SUCCESS;
6307 	uint8_t mux_id;
6308 	ipa_ioc_add_flt_rule *pFilteringTable = NULL;
6309 	int fd;
6310 
6311 	mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
6312 	/* contruct filter rules to pcie modem */
6313 	struct ipa_flt_rule_add flt_rule_entry;
6314 	ipa_ioc_generate_flt_eq flt_eq;
6315 
6316 	IPACMDBG("\n");
6317 	len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
6318 	pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
6319 	if (pFilteringTable == NULL)
6320 	{
6321 		IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
6322 		return IPACM_FAILURE;
6323 	}
6324 	memset(pFilteringTable, 0, len);
6325 
6326 
6327 	pFilteringTable->commit = 1;
6328 	pFilteringTable->global = false;
6329 	pFilteringTable->ip = IPA_IP_v6;
6330 	pFilteringTable->num_rules = (uint8_t)1;
6331 
6332 	/* Configuring Filtering Rule */
6333 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
6334 	flt_rule_entry.at_rear = true;
6335 	flt_rule_entry.flt_rule_hdl = -1;
6336 	flt_rule_entry.status = -1;
6337 
6338 	flt_rule_entry.rule.retain_hdr = 1;
6339 	flt_rule_entry.rule.to_uc = 0;
6340 	flt_rule_entry.rule.eq_attrib_type = 1;
6341 	flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
6342 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
6343 		flt_rule_entry.rule.hashable = true;
6344 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
6345 	flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, client_index)->v6_addr[v6_num][0];
6346 	flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, client_index)->v6_addr[v6_num][1];
6347 	flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, client_index)->v6_addr[v6_num][2];
6348 	flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, client_index)->v6_addr[v6_num][3];
6349 	flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
6350 	flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
6351 	flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
6352 	flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
6353 
6354 	IPACMDBG_H("ipv6 address got: 0x%x:%x:%x:%x\n", get_client_memptr(eth_client, client_index)->v6_addr[v6_num][0],
6355 		get_client_memptr(eth_client, client_index)->v6_addr[v6_num][1],
6356 		get_client_memptr(eth_client, client_index)->v6_addr[v6_num][2],
6357 		get_client_memptr(eth_client, client_index)->v6_addr[v6_num][3]);
6358 
6359 	/* change to network order for modem */
6360 	change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
6361 
6362 	memset(&flt_eq, 0, sizeof(flt_eq));
6363 	memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
6364 	flt_eq.ip = IPA_IP_v6;
6365 
6366 	fd = open(IPA_DEVICE_NAME, O_RDWR);
6367 	if (fd < 0)
6368 	{
6369 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
6370 		free(pFilteringTable);
6371 		return IPACM_FAILURE;
6372 	}
6373 
6374 	if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
6375 	{
6376 		IPACMERR("Failed to get eq_attrib\n");
6377 		res = IPACM_FAILURE;
6378 		goto fail;
6379 	}
6380 	memcpy(&flt_rule_entry.rule.eq_attrib,
6381 		&flt_eq.eq_attrib,
6382 		sizeof(flt_rule_entry.rule.eq_attrib));
6383 	memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
6384 
6385 	if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 0))
6386 	{
6387 		IPACMERR("Failed to install WAN DL filtering table.\n");
6388 		res = IPACM_FAILURE;
6389 		goto fail;
6390 	}
6391 
6392 	get_client_memptr(eth_client, client_index)->v6_rt_rule_id[v6_num] = pFilteringTable->rules[0].flt_rule_hdl;
6393 	IPACMDBG_H("%d-st client v6_num %d: id handle 0x%x\n", client_index, v6_num, get_client_memptr(eth_client, client_index)->v6_rt_rule_id[v6_num]);
6394 fail:
6395 	close(fd);
6396 	if(pFilteringTable != NULL)
6397 	{
6398 		free(pFilteringTable);
6399 	}
6400 	return res;
6401 }
6402 
del_connection(int client_index,int v6_num)6403 int IPACM_Lan::del_connection(int client_index, int v6_num)
6404 {
6405 	int len, res = IPACM_SUCCESS;
6406 	ipa_ioc_del_flt_rule *pFilteringTable = NULL;
6407 
6408 	struct ipa_flt_rule_del flt_rule_entry;
6409 
6410 	IPACMDBG("\n");
6411 	len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
6412 	pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
6413 	if (pFilteringTable == NULL)
6414 	{
6415 		IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
6416 		return IPACM_FAILURE;
6417 	}
6418 	memset(pFilteringTable, 0, len);
6419 
6420 
6421 	pFilteringTable->commit = 1;
6422 	pFilteringTable->ip = IPA_IP_v6;
6423 	pFilteringTable->num_hdls = (uint8_t)1;
6424 
6425 	/* Configuring Software-Routing Filtering Rule */
6426 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
6427 	flt_rule_entry.hdl = get_client_memptr(eth_client, client_index)->v6_rt_rule_id[v6_num];
6428 
6429 	memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
6430 
6431 	if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
6432 	{
6433 		IPACMERR("Failed to install WAN DL filtering table.\n");
6434 		res = IPACM_FAILURE;
6435 		goto fail;
6436 	}
6437 	get_client_memptr(eth_client, client_index)->v6_rt_rule_id[v6_num] = 0;
6438 
6439 fail:
6440 	if(pFilteringTable != NULL)
6441 	{
6442 		free(pFilteringTable);
6443 	}
6444 	return res;
6445 }
6446 
construct_mtu_rule(struct ipa_flt_rule * rule,ipa_ip_type iptype,uint16_t mtu)6447 int IPACM_Lan::construct_mtu_rule(struct ipa_flt_rule *rule, ipa_ip_type iptype, uint16_t mtu)
6448 {
6449 	int res = IPACM_SUCCESS;
6450 	int fd;
6451 	ipa_ioc_generate_flt_eq flt_eq;
6452 
6453 	if (rule == NULL)
6454 	{
6455 		IPACMERR("rule is empty");
6456 		return IPACM_FAILURE;
6457 	}
6458 
6459 	if (mtu == 0)
6460 	{
6461 		IPACMERR("mtu is uninitialized");
6462 		return IPACM_FAILURE;
6463 	}
6464 
6465 	IPACMDBG_H("Adding MTU rule for iptype = %d\n", iptype);
6466 
6467 	rule->eq_attrib_type = 1;
6468 	rule->eq_attrib.rule_eq_bitmap = 0;
6469 	rule->action = IPA_PASS_TO_EXCEPTION;
6470 
6471 	/* generate eq */
6472 	memset(&flt_eq, 0, sizeof(flt_eq));
6473 	memcpy(&flt_eq.attrib, &rule->attrib, sizeof(flt_eq.attrib));
6474 	flt_eq.ip = iptype;
6475 
6476 	fd = open(IPA_DEVICE_NAME, O_RDWR);
6477 	if (fd < 0)
6478 	{
6479 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
6480 		return IPACM_FAILURE;
6481 	}
6482 
6483 	if (0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) //define and cpy attribute to this struct
6484 	{
6485 		IPACMERR("Failed to get eq_attrib\n");
6486 		res = IPACM_FAILURE;
6487 		goto fail;
6488 	}
6489 	memcpy(&rule->eq_attrib,
6490 		&flt_eq.eq_attrib, sizeof(rule->eq_attrib));
6491 
6492 	//add IHL offsets
6493 	rule->eq_attrib.rule_eq_bitmap |= (1<<10);
6494 	rule->eq_attrib.num_ihl_offset_range_16 = 1;
6495 	if (iptype == IPA_IP_v4)
6496 		rule->eq_attrib.ihl_offset_range_16[0].offset = 0x82;
6497 	else
6498 		rule->eq_attrib.ihl_offset_range_16[0].offset = 0x84;
6499 	rule->eq_attrib.ihl_offset_range_16[0].range_low = mtu + 1;
6500 	rule->eq_attrib.ihl_offset_range_16[0].range_high = UINT16_MAX; //0xFFFF
6501 
6502 fail:
6503 	close(fd);
6504 	return res;
6505 }
6506