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