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