1 /*
2 Copyright (c) 2013-2017, 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 	modem_ul_v6_set = false;
85 	is_mode_switch = false;
86 	if_ipv4_subnet =0;
87 	each_client_rt_rule_count[IPA_IP_v4] = 0;
88 	each_client_rt_rule_count[IPA_IP_v6] = 0;
89 	eth_client_len = 0;
90 
91 	/* support eth multiple clients */
92 	if(iface_query != NULL)
93 	{
94 		if(ipa_if_cate != WLAN_IF)
95 		{
96 			eth_client_len = (sizeof(ipa_eth_client)) + (iface_query->num_tx_props * sizeof(eth_client_rt_hdl));
97 			eth_client = (ipa_eth_client *)calloc(IPA_MAX_NUM_ETH_CLIENTS, eth_client_len);
98 			if (eth_client == NULL)
99 			{
100 				IPACMERR("unable to allocate memory\n");
101 				return;
102 			}
103 		}
104 
105 		IPACMDBG_H(" IPACM->IPACM_Lan(%d) constructor: Tx:%d Rx:%d \n", ipa_if_num,
106 					 iface_query->num_tx_props, iface_query->num_rx_props);
107 
108 		/* ODU routing table initilization */
109 		if(ipa_if_cate == ODU_IF)
110 		{
111 			odu_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
112 			odu_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
113 			if ((odu_route_rule_v4_hdl == NULL) || (odu_route_rule_v6_hdl == NULL))
114 			{
115 				IPACMERR("unable to allocate memory\n");
116 				return;
117 			}
118 		}
119 	}
120 
121 	memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
122 	memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
123 
124 	memset(ipv4_icmp_flt_rule_hdl, 0, NUM_IPV4_ICMP_FLT_RULE * sizeof(uint32_t));
125 
126 	memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t));
127 	memset(ipv6_prefix_flt_rule_hdl, 0, NUM_IPV6_PREFIX_FLT_RULE * sizeof(uint32_t));
128 	memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t));
129 	memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
130 
131 	/* ODU routing table initilization */
132 	if(ipa_if_cate == ODU_IF)
133 	{
134 		/* only do one time ioctl to odu-driver to infrom in router or bridge mode*/
135 		if (IPACM_Lan::odu_up != true)
136 		{
137 				m_fd_odu = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR);
138 				if (0 == m_fd_odu)
139 				{
140 					IPACMERR("Failed opening %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU);
141 					return ;
142 				}
143 
144 				if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)
145 				{
146 					ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_ROUTER);
147 					IPACM_Iface::ipacmcfg->ipacm_odu_enable = true;
148 				}
149 				else
150 				{
151 					ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_BRIDGE);
152 					IPACM_Iface::ipacmcfg->ipacm_odu_enable = true;
153 				}
154 
155 				if (ret)
156 				{
157 					IPACMERR("Failed tell odu-driver the mode\n");
158 				}
159 				IPACMDBG("Tell odu-driver in router-mode(%d)\n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode);
160 				IPACMDBG_H("odu is up: odu-driver in router-mode(%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode);
161 				close(m_fd_odu);
162 				IPACM_Lan::odu_up = true;
163 		}
164 	}
165 
166 	if(iface_query != NULL && tx_prop != NULL)
167 	{
168 		for(i=0; i<iface_query->num_tx_props; i++)
169 			each_client_rt_rule_count[tx_prop->tx[i].ip]++;
170 	}
171 	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]);
172 
173 #ifdef FEATURE_IPA_ANDROID
174 	/* set the IPA-client pipe enum */
175 	if(ipa_if_cate == LAN_IF)
176 	{
177 #ifdef FEATURE_IPACM_HAL
178 		handle_tethering_client(false, IPACM_CLIENT_MAX);
179 #else
180 		handle_tethering_client(false, IPACM_CLIENT_USB);
181 #endif
182 	}
183 #endif
184 
185 	memset(is_downstream_set, 0, sizeof(is_downstream_set));
186 	memset(is_upstream_set, 0, sizeof(is_upstream_set));
187 	memset(&prefix, 0, sizeof(prefix));
188 
189 #ifdef FEATURE_IPACM_HAL
190 		/* check if Upstream was set before */
191 		if (IPACM_Wan::isWanUP(ipa_if_num))
192 		{
193 				IPACMDBG_H("Upstream was set previously for ipv4, change is_upstream_set flag\n");
194 				is_upstream_set[IPA_IP_v4] = true;
195 		}
196 
197 		if (IPACM_Wan::isWanUP_V6(ipa_if_num))
198 		{
199 				IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n");
200 				is_upstream_set[IPA_IP_v6] = true;
201 		}
202 #endif
203 	return;
204 }
205 
~IPACM_Lan()206 IPACM_Lan::~IPACM_Lan()
207 {
208 	IPACM_EvtDispatcher::deregistr(this);
209 	IPACM_IfaceManager::deregistr(this);
210 	return;
211 }
212 
213 
214 /* LAN-iface's callback function */
event_callback(ipa_cm_event_id event,void * param)215 void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
216 {
217 	if(is_active == false && event != IPA_LAN_DELETE_SELF)
218 	{
219 		IPACMDBG_H("The interface is no longer active, return.\n");
220 		return;
221 	}
222 
223 	int ipa_interface_index;
224 	ipacm_ext_prop* ext_prop;
225 	ipacm_event_iface_up_tehter* data_wan_tether;
226 
227 	switch (event)
228 	{
229 	case IPA_LINK_DOWN_EVENT:
230 		{
231 			ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
232 			ipa_interface_index = iface_ipa_index_query(data->if_index);
233 			if (ipa_interface_index == ipa_if_num)
234 			{
235 				IPACMDBG_H("Received IPA_LINK_DOWN_EVENT\n");
236 				handle_down_evt();
237 				IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
238 				return;
239 			}
240 		}
241 		break;
242 
243 	case IPA_CFG_CHANGE_EVENT:
244 		{
245 			if ( IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate)
246 			{
247 				IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category changed\n");
248 				/* delete previous instance */
249 				handle_down_evt();
250 				IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
251 				is_mode_switch = true; // need post internal usb-link up event
252 				return;
253 			}
254 			/* Add Natting iface to IPACM_Config if there is  Rx/Tx property */
255 			if (rx_prop != NULL || tx_prop != NULL)
256 			{
257 				IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
258 				IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name);
259 			}
260 		}
261 		break;
262 
263 	case IPA_PRIVATE_SUBNET_CHANGE_EVENT:
264 		{
265 			ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
266 			/* internel event: data->if_index is ipa_if_index */
267 			if (data->if_index == ipa_if_num)
268 			{
269 				IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n");
270 				return;
271 			}
272 			else
273 			{
274 				IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n");
275 #ifdef FEATURE_IPA_ANDROID
276 				handle_private_subnet_android(IPA_IP_v4);
277 #endif
278 				IPACMDBG_H(" delete old private subnet rules, use new sets \n");
279 				return;
280 			}
281 		}
282 		break;
283 
284 	case IPA_LAN_DELETE_SELF:
285 	{
286 		ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
287 		if(data->if_index == ipa_if_num)
288 		{
289 			IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n");
290 			IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
291 			/* posting link-up event for cradle use-case */
292 			if(is_mode_switch)
293 			{
294 				IPACMDBG_H("Posting IPA_USB_LINK_UP_EVENT event for (%s)\n", dev_name);
295 				ipacm_cmd_q_data evt_data;
296 				memset(&evt_data, 0, sizeof(evt_data));
297 
298 				ipacm_event_data_fid *data_fid = NULL;
299 				data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
300 				if(data_fid == NULL)
301 				{
302 					IPACMERR("unable to allocate memory for IPA_USB_LINK_UP_EVENT data_fid\n");
303 					return;
304 				}
305 				if(IPACM_Iface::ipa_get_if_index(dev_name, &(data_fid->if_index)))
306 				{
307 					IPACMERR("Error while getting interface index for %s device", dev_name);
308 				}
309 				evt_data.event = IPA_USB_LINK_UP_EVENT;
310 				evt_data.evt_data = data_fid;
311 				//IPACMDBG_H("Posting event:%d\n", evt_data.event);
312 				IPACM_EvtDispatcher::PostEvt(&evt_data);
313 			}
314 #ifndef FEATURE_IPA_ANDROID
315 			if(rx_prop != NULL)
316 			{
317 				if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4) != 0)
318 				{
319 					IPACMDBG_DMESG("### WARNING ### num ipv4 flt rules on client %d is not expected: %d expected value: 0",
320 						rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4));
321 				}
322 				if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6) != 0)
323 				{
324 					IPACMDBG_DMESG("### WARNING ### num ipv6 flt rules on client %d is not expected: %d expected value: 0",
325 						rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6));
326 				}
327 			}
328 #endif
329 			delete this;
330 		}
331 		break;
332 	}
333 
334 	case IPA_ADDR_ADD_EVENT:
335 		{
336 			ipacm_event_data_addr *data = (ipacm_event_data_addr *)param;
337 			ipa_interface_index = iface_ipa_index_query(data->if_index);
338 
339 			if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) ||
340 					 (data->iptype == IPA_IP_v6 &&
341 						data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 &&
342 					  data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) )
343 			{
344 				IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n");
345 				return;
346 			}
347 
348 
349 			if (ipa_interface_index == ipa_if_num)
350 			{
351 				IPACMDBG_H("Received IPA_ADDR_ADD_EVENT\n");
352 
353 				/* only call ioctl for ODU iface with bridge mode */
354 				if(IPACM_Iface::ipacmcfg->ipacm_odu_enable == true && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false
355 						&& ipa_if_cate == ODU_IF)
356 				{
357 					if((data->iptype == IPA_IP_v6) && (num_dft_rt_v6 == 0))
358 					{
359 						handle_addr_evt_odu_bridge(data);
360 					}
361 #ifdef FEATURE_IPA_ANDROID
362 					add_dummy_private_subnet_flt_rule(data->iptype);
363 					handle_private_subnet_android(data->iptype);
364 #else
365 					handle_private_subnet(data->iptype);
366 #endif
367 				}
368 				else
369 				{
370 
371 					/* check v4 not setup before, v6 can have 2 iface ip */
372 					if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX))
373 						|| ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
374 					{
375 						IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
376 						if(handle_addr_evt(data) == IPACM_FAILURE)
377 						{
378 							return;
379 						}
380 
381 #ifdef FEATURE_IPA_ANDROID
382 						add_dummy_private_subnet_flt_rule(data->iptype);
383 						handle_private_subnet_android(data->iptype);
384 #else
385 						handle_private_subnet(data->iptype);
386 #endif
387 
388 #ifndef FEATURE_IPACM_HAL
389 						if (IPACM_Wan::isWanUP(ipa_if_num))
390 						{
391 							if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
392 							{
393 								if(IPACM_Wan::backhaul_is_sta_mode == false)
394 								{
395 									ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
396 									handle_wan_up_ex(ext_prop, IPA_IP_v4,
397 												IPACM_Wan::getXlat_Mux_Id());
398 								}
399 								else
400 								{
401 									handle_wan_up(IPA_IP_v4);
402 								}
403 							}
404 							IPACMDBG_H("Finished checking wan_up\n");
405 						} else {
406 							IPACMDBG_H("Wan_V4 haven't up yet\n");
407 						}
408 
409 						if(IPACM_Wan::isWanUP_V6(ipa_if_num))
410 						{
411 							if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
412 							{
413 								memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix));
414 								install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
415 								if(IPACM_Wan::backhaul_is_sta_mode == false)
416 								{
417 									ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
418 									handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
419 								}
420 								else
421 								{
422 									handle_wan_up(IPA_IP_v6);
423 								}
424 							}
425 							IPACMDBG_H("Finished checking wan_up_v6\n");
426 						} else {
427 							IPACMDBG_H("Wan_V6 haven't up yet\n");
428 						}
429 #endif
430 						/* Post event to NAT */
431 						if (data->iptype == IPA_IP_v4)
432 						{
433 							ipacm_cmd_q_data evt_data;
434 							ipacm_event_iface_up *info;
435 
436 							info = (ipacm_event_iface_up *)
437 								malloc(sizeof(ipacm_event_iface_up));
438 							if (info == NULL)
439 							{
440 								IPACMERR("Unable to allocate memory\n");
441 								return;
442 							}
443 
444 							memcpy(info->ifname, dev_name, IF_NAME_LEN);
445 							info->ipv4_addr = data->ipv4_addr;
446 							info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask;
447 
448 							evt_data.event = IPA_HANDLE_LAN_UP;
449 							evt_data.evt_data = (void *)info;
450 
451 							/* Insert IPA_HANDLE_LAN_UP to command queue */
452 							IPACMDBG_H("posting IPA_HANDLE_LAN_UP for IPv4 with below information\n");
453 							IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n",
454 											info->ipv4_addr, info->addr_mask);
455 							IPACM_EvtDispatcher::PostEvt(&evt_data);
456 						}
457 						IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype);
458 					}
459 
460 					IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype);
461 					/* checking if SW-RT_enable */
462 					if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true)
463 					{
464 						/* handle software routing enable event*/
465 						IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
466 						handle_software_routing_enable();
467 					}
468 
469 				}
470 			}
471 		}
472 		break;
473 #ifdef FEATURE_IPA_ANDROID
474 	case IPA_HANDLE_WAN_UP_TETHER:
475 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n");
476 
477 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
478 		if(data_wan_tether == NULL)
479 		{
480 			IPACMERR("No event data is found.\n");
481 			return;
482 		}
483 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
484 					data_wan_tether->if_index_tether,
485 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
486 #ifndef FEATURE_IPACM_HAL
487 		if (data_wan_tether->if_index_tether != ipa_if_num)
488 		{
489 			IPACMERR("IPA_HANDLE_WAN_UP_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
490 			return;
491 		}
492 #endif
493 		if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
494 		{
495 #ifdef FEATURE_IPACM_HAL
496 			if (is_upstream_set[IPA_IP_v4] == false)
497 			{
498 				IPACMDBG_H("Add upstream for IPv4.\n");
499 				is_upstream_set[IPA_IP_v4] = true;
500 				if (is_downstream_set[IPA_IP_v4] == true)
501 				{
502 					IPACMDBG_H("Downstream was set before, adding UL rules.\n");
503 					if (data_wan_tether->is_sta == false)
504 					{
505 							ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
506 							handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
507 					} else {
508 							handle_wan_up(IPA_IP_v4);
509 					}
510 				}
511 			}
512 #else
513 			if (data_wan_tether->is_sta == false)
514 			{
515 					ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
516 					handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
517 			} else {
518 					handle_wan_up(IPA_IP_v4);
519 			}
520 #endif
521 		}
522 		break;
523 
524 	case IPA_HANDLE_WAN_UP_V6_TETHER:
525 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n");
526 
527 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
528 		if (data_wan_tether == NULL)
529 		{
530 			IPACMERR("No event data is found.\n");
531 			return;
532 		}
533 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
534 					data_wan_tether->if_index_tether,
535 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
536 #ifndef FEATURE_IPACM_HAL
537 		if (data_wan_tether->if_index_tether != ipa_if_num)
538 		{
539 			IPACMERR("IPA_HANDLE_WAN_UP_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
540 			return;
541 		}
542 #endif
543 		if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
544 		{
545 #ifdef FEATURE_IPACM_HAL
546 			if (is_upstream_set[IPA_IP_v6] == false)
547 			{
548 				IPACMDBG_H("Add upstream for IPv6.\n");
549 				is_upstream_set[IPA_IP_v6] = true;
550 
551 				if (is_downstream_set[IPA_IP_v6] == true)
552 				{
553 					IPACMDBG_H("Downstream was set before, adding UL rules.\n");
554 					memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix));
555 					install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
556 					if (data_wan_tether->is_sta == false)
557 					{
558 						ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
559 						handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
560 					}
561 					else
562 					{
563 						handle_wan_up(IPA_IP_v6);
564 					}
565 				}
566 			}
567 #else
568 			if (data_wan_tether->is_sta == false)
569 			{
570 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
571 				handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
572 			} else {
573 				handle_wan_up(IPA_IP_v6);
574 			}
575 #endif
576 		}
577 		break;
578 
579 	case IPA_HANDLE_WAN_DOWN_TETHER:
580 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n");
581 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
582 		if (data_wan_tether == NULL)
583 		{
584 			IPACMERR("No event data is found.\n");
585 			return;
586 		}
587 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
588 					data_wan_tether->if_index_tether,
589 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
590 #ifndef FEATURE_IPACM_HAL
591 		if (data_wan_tether->if_index_tether != ipa_if_num)
592 		{
593 			IPACMERR("IPA_HANDLE_WAN_DOWN_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
594 			return;
595 		}
596 #endif
597 		if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
598 		{
599 #ifdef FEATURE_IPACM_HAL
600 			if(is_upstream_set[IPA_IP_v4] == true)
601 			{
602 				IPACMDBG_H("Del upstream for IPv4.\n");
603 				is_upstream_set[IPA_IP_v4] = false;
604 				if(is_downstream_set[IPA_IP_v4] == true)
605 				{
606 					IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
607 					handle_wan_down(data_wan_tether->is_sta);
608 				}
609 			}
610 #else
611 			handle_wan_down(data_wan_tether->is_sta);
612 #endif
613 		}
614 		break;
615 
616 	case IPA_HANDLE_WAN_DOWN_V6_TETHER:
617 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n");
618 		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
619 		if(data_wan_tether == NULL)
620 		{
621 			IPACMERR("No event data is found.\n");
622 			return;
623 		}
624 		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
625 					data_wan_tether->if_index_tether,
626 					IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
627 #ifndef FEATURE_IPACM_HAL
628 		if (data_wan_tether->if_index_tether != ipa_if_num)
629 		{
630 			IPACMERR("IPA_HANDLE_WAN_DOWN_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
631 			return;
632 		}
633 #endif
634 		if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
635 		{
636 #ifdef FEATURE_IPACM_HAL
637 			if (is_upstream_set[IPA_IP_v6] == true)
638 			{
639 				IPACMDBG_H("Del upstream for IPv6.\n");
640 				is_upstream_set[IPA_IP_v6] = false;
641 				if(is_downstream_set[IPA_IP_v6] == true)
642 				{
643 					IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
644 					/* reset usb-client ipv6 rt-rules */
645 					handle_lan_client_reset_rt(IPA_IP_v6);
646 					handle_wan_down_v6(data_wan_tether->is_sta);
647 				}
648 			}
649 #else
650 			/* reset usb-client ipv6 rt-rules */
651 			handle_lan_client_reset_rt(IPA_IP_v6);
652 			handle_wan_down_v6(data_wan_tether->is_sta);
653 #endif
654 		}
655 		break;
656 
657 	case IPA_DOWNSTREAM_ADD:
658 	{
659 		ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
660 		ipa_interface_index = iface_ipa_index_query(data->if_index);
661 		if (ipa_interface_index == ipa_if_num)
662 		{
663 			IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
664 			if (is_downstream_set[data->prefix.iptype] == false)
665 			{
666 				IPACMDBG_H("Add downstream for IP iptype %d\n", data->prefix.iptype);
667 				is_downstream_set[data->prefix.iptype] = true;
668 				memcpy(&prefix[data->prefix.iptype], &data->prefix,
669 					sizeof(prefix[data->prefix.iptype]));
670 
671 				if (is_upstream_set[data->prefix.iptype] == true)
672 				{
673 					IPACMDBG_H("Upstream was set before, adding UL rules.\n");
674 					if (ip_type == IPA_IP_MAX || ip_type == data->prefix.iptype)
675 					{
676 						if (data->prefix.iptype == IPA_IP_v6) /* ipv6 only */
677 						{
678 							/* Only offload clients has same prefix as Android gave */
679 							ipv6_prefix[0] = data->prefix.v6Addr[0];
680 							ipv6_prefix[1] = data->prefix.v6Addr[1];
681 							IPACMDBG_H("ipv6_prefix0x%x:%x\n", ipv6_prefix[0], ipv6_prefix[1]);
682 							install_ipv6_prefix_flt_rule(ipv6_prefix);
683 						}
684 
685 						if (IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
686 						{
687 							ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
688 							handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
689 						} else {
690 							handle_wan_up(data->prefix.iptype); /* STA */
691 						}
692 					}
693 				}
694 			} else {
695 				IPACMDBG_H("downstream for IP iptype %d already set \n", data->prefix.iptype);
696 			}
697 		}
698 		break;
699 	}
700 
701 	case IPA_DOWNSTREAM_DEL:
702 	{
703 		ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
704 		ipa_interface_index = iface_ipa_index_query(data->if_index);
705 		if (ipa_interface_index == ipa_if_num)
706 		{
707 			IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
708 			if (is_downstream_set[data->prefix.iptype] == true)
709 			{
710 				IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
711 				is_downstream_set[data->prefix.iptype] = false;
712 
713 				if (is_upstream_set[data->prefix.iptype] == true)
714 				{
715 					IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
716 					if (data->prefix.iptype == IPA_IP_v4)
717 					{
718 						handle_wan_down(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
719 					} else {
720 						handle_lan_client_reset_rt(IPA_IP_v6);
721 						handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
722 					}
723 				}
724 			}
725 		}
726 		break;
727 	}
728 
729 #else
730 	case IPA_HANDLE_WAN_UP:
731 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
732 
733 		ipacm_event_iface_up* data_wan = (ipacm_event_iface_up*)param;
734 		if (data_wan == NULL)
735 		{
736 			IPACMERR("No event data is found.\n");
737 			return;
738 		}
739 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
740 		if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
741 		{
742 		if (data_wan->is_sta == false)
743 		{
744 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
745 				handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
746 		}
747 		else
748 		{
749 			handle_wan_up(IPA_IP_v4);
750 		}
751 		}
752 		break;
753 
754 	case IPA_HANDLE_WAN_UP_V6:
755 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6 event\n");
756 
757 		data_wan = (ipacm_event_iface_up*)param;
758 		if (data_wan == NULL)
759 		{
760 			IPACMERR("No event data is found.\n");
761 			return;
762 		}
763 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
764 		if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
765 		{
766 			memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix));
767 			install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
768 			if (data_wan->is_sta == false)
769 			{
770 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
771 				handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
772 			}
773 			else
774 			{
775 				handle_wan_up(IPA_IP_v6);
776 			}
777 		}
778 		break;
779 
780 	case IPA_HANDLE_WAN_DOWN:
781 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n");
782 		data_wan = (ipacm_event_iface_up*)param;
783 		if (data_wan == NULL)
784 		{
785 			IPACMERR("No event data is found.\n");
786 			return;
787 		}
788 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
789 		if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
790 		{
791 			handle_wan_down(data_wan->is_sta);
792 		}
793 		break;
794 
795 	case IPA_HANDLE_WAN_DOWN_V6:
796 		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6 event\n");
797 		data_wan = (ipacm_event_iface_up*)param;
798 		if (data_wan == NULL)
799 		{
800 			IPACMERR("No event data is found.\n");
801 			return;
802 		}
803 		/* clean up v6 RT rules*/
804 		IPACMDBG_H("Received IPA_WAN_V6_DOWN in LAN-instance and need clean up client IPv6 address \n");
805 		/* reset usb-client ipv6 rt-rules */
806 		handle_lan_client_reset_rt(IPA_IP_v6);
807 
808 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
809 		if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
810 		{
811 			handle_wan_down_v6(data_wan->is_sta);
812 		}
813 		break;
814 #endif
815 
816 	case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
817 		{
818 			ipacm_event_data_all *data = (ipacm_event_data_all *)param;
819 			ipa_interface_index = iface_ipa_index_query(data->if_index);
820 			IPACMDBG_H("Recieved IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event \n");
821 			IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate);
822 
823 			if (ipa_interface_index == ipa_if_num && ipa_if_cate == ODU_IF)
824 			{
825 				IPACMDBG_H("ODU iface got v4-ip \n");
826 				/* first construc ODU full header */
827 				if ((ipv4_header_set == false) && (ipv6_header_set == false))
828 				{
829 					/* construct ODU RT tbl */
830 					handle_odu_hdr_init(data->mac_addr);
831 					if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true)
832 					{
833 						handle_odu_route_add();
834 						IPACMDBG_H("construct ODU header and route rules, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
835 					}
836 					else
837 					{
838 						IPACMDBG_H("construct ODU header only, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
839 					}
840 				}
841 				/* if ODU in bridge mode, directly return */
842 				if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
843 				{
844 					IPACMDBG_H("ODU is in bridge mode, no action \n");
845 					return;
846 				}
847 			}
848 
849 			if (ipa_interface_index == ipa_if_num)
850 			{
851 				IPACMDBG_H("ETH iface got client \n");
852 				/* first construc ETH full header */
853 				handle_eth_hdr_init(data->mac_addr);
854 				IPACMDBG_H("construct ETH header and route rules \n");
855 				/* Associate with IP and construct RT-rule */
856 				if (handle_eth_client_ipaddr(data) == IPACM_FAILURE)
857 				{
858 					return;
859 				}
860 				handle_eth_client_route_rule(data->mac_addr, data->iptype);
861 				if (data->iptype == IPA_IP_v4)
862 				{
863 					/* Add NAT rules after ipv4 RT rules are set */
864 					CtList->HandleNeighIpAddrAddEvt(data);
865 				}
866 				eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr);
867 				return;
868 			}
869 		}
870 		break;
871 
872 	case IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT:
873 		{
874 			ipacm_event_data_all *data = (ipacm_event_data_all *)param;
875 			ipa_interface_index = iface_ipa_index_query(data->if_index);
876 
877 			IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event. \n");
878 			IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate);
879 			/* if ODU in bridge mode, directly return */
880 			if (ipa_if_cate == ODU_IF && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
881 			{
882 				IPACMDBG_H("ODU is in bridge mode, no action \n");
883 				return;
884 			}
885 
886 			if (ipa_interface_index == ipa_if_num)
887 			{
888 				if (data->iptype == IPA_IP_v6)
889 				{
890 					handle_del_ipv6_addr(data);
891 					return;
892 				}
893 
894 				eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_DEL, IPA_IP_MAX, data->mac_addr);
895 
896 				IPACMDBG_H("LAN iface delete client \n");
897 				handle_eth_client_down_evt(data->mac_addr);
898 				return;
899 			}
900 		}
901 		break;
902 
903 	case IPA_SW_ROUTING_ENABLE:
904 		IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n");
905 		/* handle software routing enable event*/
906 		handle_software_routing_enable();
907 		break;
908 
909 	case IPA_SW_ROUTING_DISABLE:
910 		IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n");
911 		/* handle software routing disable event*/
912 		handle_software_routing_disable();
913 		break;
914 
915 	case IPA_CRADLE_WAN_MODE_SWITCH:
916 	{
917 		IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n");
918 		ipacm_event_cradle_wan_mode* wan_mode = (ipacm_event_cradle_wan_mode*)param;
919 		if(wan_mode == NULL)
920 		{
921 			IPACMERR("Event data is empty.\n");
922 			return;
923 		}
924 
925 		if(wan_mode->cradle_wan_mode == BRIDGE)
926 		{
927 			handle_cradle_wan_mode_switch(true);
928 		}
929 		else
930 		{
931 			handle_cradle_wan_mode_switch(false);
932 		}
933 	}
934 	break;
935 
936 	case IPA_TETHERING_STATS_UPDATE_EVENT:
937 	{
938 		IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
939 		if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
940 		{
941 			if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
942 			{
943 				ipa_get_data_stats_resp_msg_v01 *data = (ipa_get_data_stats_resp_msg_v01 *)param;
944 				IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data->ipa_stats_type);
945 				IPACMDBG("Received %d UL, %d DL pipe stats\n",data->ul_src_pipe_stats_list_len,
946 					data->dl_dst_pipe_stats_list_len);
947 				if (data->ipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01)
948 				{
949 					IPACMERR("not valid pipe stats enum(%d)\n", data->ipa_stats_type);
950 					return;
951 				}
952 				handle_tethering_stats_event(data);
953 			}
954 		}
955 	}
956 	break;
957 
958 	default:
959 		break;
960 	}
961 
962 	return;
963 }
964 
965 
handle_del_ipv6_addr(ipacm_event_data_all * data)966 int IPACM_Lan::handle_del_ipv6_addr(ipacm_event_data_all *data)
967 {
968 	uint32_t tx_index;
969 	uint32_t rt_hdl;
970 	int num_v6 =0, clnt_indx;
971 
972 	clnt_indx = get_eth_client_index(data->mac_addr);
973 	if (clnt_indx == IPACM_INVALID_INDEX)
974 	{
975 		IPACMERR("eth client not found/attached \n");
976 		return IPACM_FAILURE;
977 	}
978 
979 	if(data->iptype == IPA_IP_v6)
980 	{
981 		if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
982 				(data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0))
983 		{
984 			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]);
985 			for(num_v6=0;num_v6 < get_client_memptr(eth_client, clnt_indx)->ipv6_set;num_v6++)
986 			{
987 				if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][0] &&
988 					data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][1] &&
989 					data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][2] &&
990 					data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][3])
991 				{
992 					IPACMDBG_H("ipv6 addr is found at position:%d for client:%d\n", num_v6, clnt_indx);
993 					break;
994 				}
995 			}
996 		}
997 		else
998 		{
999 			IPACMDBG_H("Invalid ipv6 address\n");
1000 			return IPACM_FAILURE;
1001 		}
1002 		if (num_v6 == IPV6_NUM_ADDR)
1003 		{
1004 			IPACMDBG_H("ipv6 addr is not found. \n");
1005 			return IPACM_FAILURE;
1006 		}
1007 
1008 		for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
1009 		{
1010 			if((tx_prop->tx[tx_index].ip == IPA_IP_v6) && (get_client_memptr(eth_client, clnt_indx)->route_rule_set_v6 != 0))
1011 			{
1012 				IPACMDBG_H("Delete client index %d ipv6 RT-rules for %d-st ipv6 for tx:%d\n", clnt_indx, num_v6, tx_index);
1013 				rt_hdl = get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6];
1014 				if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
1015 				{
1016 					return IPACM_FAILURE;
1017 				}
1018 				rt_hdl = get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6];
1019 				if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
1020 				{
1021 					return IPACM_FAILURE;
1022 				}
1023 				get_client_memptr(eth_client, clnt_indx)->ipv6_set--;
1024 				get_client_memptr(eth_client, clnt_indx)->route_rule_set_v6--;
1025 
1026 				for(;num_v6< get_client_memptr(eth_client, clnt_indx)->ipv6_set;num_v6++)
1027 				{
1028 					get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][0] =
1029 						get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][0];
1030 					get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][1] =
1031 						get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][1];
1032 					get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][2] =
1033 						get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][2];
1034 					get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][3] =
1035 						get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][3];
1036 					get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6] =
1037 						get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6+1];
1038 					get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6] =
1039 						get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6+1];
1040 				}
1041 			}
1042 		}
1043 	}
1044 	return IPACM_SUCCESS;
1045 }
1046 
1047 /* delete filter rule for wan_down event for IPv4*/
handle_wan_down(bool is_sta_mode)1048 int IPACM_Lan::handle_wan_down(bool is_sta_mode)
1049 {
1050 	ipa_fltr_installed_notif_req_msg_v01 flt_index;
1051 	int fd;
1052 
1053 	fd = open(IPA_DEVICE_NAME, O_RDWR);
1054 	if (0 == fd)
1055 	{
1056 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1057 		return IPACM_FAILURE;
1058 	}
1059 
1060 	if(is_sta_mode == false && modem_ul_v4_set == true)
1061 	{
1062 		if (num_wan_ul_fl_rule_v4 > MAX_WAN_UL_FILTER_RULES)
1063 		{
1064 			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);
1065 			close(fd);
1066 			return IPACM_FAILURE;
1067 		}
1068 		if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v4,
1069 			IPA_IP_v4, num_wan_ul_fl_rule_v4) == false)
1070 		{
1071 			IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n");
1072 			close(fd);
1073 			return IPACM_FAILURE;
1074 		}
1075 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_wan_ul_fl_rule_v4);
1076 
1077 		memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
1078 		num_wan_ul_fl_rule_v4 = 0;
1079 		modem_ul_v4_set = false;
1080 
1081 		memset(&flt_index, 0, sizeof(flt_index));
1082 		flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe);
1083 		flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01;
1084 #ifndef FEATURE_IPA_V3
1085 		flt_index.filter_index_list_len = 0;
1086 #else /* defined (FEATURE_IPA_V3) */
1087 		flt_index.rule_id_valid = 1;
1088 		flt_index.rule_id_len = 0;
1089 #endif
1090 		flt_index.embedded_pipe_index_valid = 1;
1091 		flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD);
1092 		flt_index.retain_header_valid = 1;
1093 		flt_index.retain_header = 0;
1094 		flt_index.embedded_call_mux_id_valid = 1;
1095 		flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
1096 
1097 		if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
1098 		{
1099 			IPACMERR("Error sending filtering rule index, aborting...\n");
1100 			close(fd);
1101 			return IPACM_FAILURE;
1102 		}
1103 	}
1104 	else
1105 	{
1106 		if (m_filtering.DeleteFilteringHdls(&lan_wan_fl_rule_hdl[0], IPA_IP_v4, 1) == false)
1107 		{
1108 			IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
1109 			close(fd);
1110 			return IPACM_FAILURE;
1111 		}
1112 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
1113 	}
1114 
1115 	close(fd);
1116 	return IPACM_SUCCESS;
1117 }
1118 
1119 /* handle new_address event*/
handle_addr_evt(ipacm_event_data_addr * data)1120 int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data)
1121 {
1122 	struct ipa_ioc_add_rt_rule *rt_rule;
1123 	struct ipa_rt_rule_add *rt_rule_entry;
1124 	const int NUM_RULES = 1;
1125 	uint32_t num_ipv6_addr;
1126 	int res = IPACM_SUCCESS;
1127 #ifdef FEATURE_IPACM_HAL
1128 	IPACM_OffloadManager* OffloadMng;
1129 #endif
1130 
1131 	IPACMDBG_H("set route/filter rule ip-type: %d \n", data->iptype);
1132 
1133 /* Add private subnet*/
1134 #ifdef FEATURE_IPA_ANDROID
1135 	if (data->iptype == IPA_IP_v4)
1136 	{
1137 		IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
1138 		if_ipv4_subnet = (data->ipv4_addr >> 8) << 8;
1139 		IPACMDBG_H(" Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
1140 		if(IPACM_Iface::ipacmcfg->AddPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
1141 		{
1142 			IPACMERR(" can't Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
1143 		}
1144 	}
1145 #endif /* defined(FEATURE_IPA_ANDROID)*/
1146 
1147 	/* Update the IP Type. */
1148 	config_ip_type(data->iptype);
1149 
1150 	if (data->iptype == IPA_IP_v4)
1151 	{
1152 		rt_rule = (struct ipa_ioc_add_rt_rule *)
1153 			 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
1154 							NUM_RULES * sizeof(struct ipa_rt_rule_add));
1155 
1156 		if (!rt_rule)
1157 		{
1158 			IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
1159 			return IPACM_FAILURE;
1160 		}
1161 
1162 		rt_rule->commit = 1;
1163 		rt_rule->num_rules = NUM_RULES;
1164 		rt_rule->ip = data->iptype;
1165 		rt_rule_entry = &rt_rule->rules[0];
1166 		rt_rule_entry->at_rear = false;
1167 		rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;  //go to A5
1168 		rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
1169 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
1170 		rt_rule_entry->rule.attrib.u.v4.dst_addr      = data->ipv4_addr;
1171 		rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
1172 #ifdef FEATURE_IPA_V3
1173 		rt_rule_entry->rule.hashable = true;
1174 #endif
1175 		if (false == m_routing.AddRoutingRule(rt_rule))
1176 		{
1177 			IPACMERR("Routing rule addition failed!\n");
1178 			res = IPACM_FAILURE;
1179 			goto fail;
1180 		}
1181 		else if (rt_rule_entry->status)
1182 		{
1183 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1184 			res = rt_rule_entry->status;
1185 			goto fail;
1186 		}
1187 		dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
1188 		IPACMDBG_H("ipv4 iface rt-rule hdl1=0x%x\n", dft_rt_rule_hdl[0]);
1189 		/* initial multicast/broadcast/fragment filter rule */
1190 
1191 		init_fl_rule(data->iptype);
1192 		install_ipv4_icmp_flt_rule();
1193 
1194 		/* populate the flt rule offset for eth bridge */
1195 		eth_bridge_flt_rule_offset[data->iptype] = ipv4_icmp_flt_rule_hdl[0];
1196 		eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL);
1197 	}
1198 	else
1199 	{
1200 	    /* check if see that v6-addr already or not*/
1201 	    for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
1202 	    {
1203             if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
1204 	           (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
1205 	           (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
1206 	           (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
1207             {
1208 				return IPACM_FAILURE;
1209 				break;
1210 	        }
1211 	    }
1212 
1213 		rt_rule = (struct ipa_ioc_add_rt_rule *)
1214 			 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
1215 							NUM_RULES * sizeof(struct ipa_rt_rule_add));
1216 
1217 		if (!rt_rule)
1218 		{
1219 			IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
1220 			return IPACM_FAILURE;
1221 		}
1222 
1223 		rt_rule->commit = 1;
1224 		rt_rule->num_rules = NUM_RULES;
1225 		rt_rule->ip = data->iptype;
1226 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
1227 
1228 		rt_rule_entry = &rt_rule->rules[0];
1229 		rt_rule_entry->at_rear = false;
1230 		rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;  //go to A5
1231 		rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
1232 		rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0];
1233 		rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1];
1234 		rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2];
1235 		rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3];
1236 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
1237 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
1238 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
1239 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
1240 		ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
1241 		ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
1242 		ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
1243 		ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
1244 #ifdef FEATURE_IPA_V3
1245 		rt_rule_entry->rule.hashable = true;
1246 #endif
1247 		if (false == m_routing.AddRoutingRule(rt_rule))
1248 		{
1249 			IPACMERR("Routing rule addition failed!\n");
1250 			res = IPACM_FAILURE;
1251 			goto fail;
1252 		}
1253 		else if (rt_rule_entry->status)
1254 		{
1255 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1256 			res = rt_rule_entry->status;
1257 			goto fail;
1258 		}
1259 		dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
1260 
1261 		/* setup same rule for v6_wan table*/
1262 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
1263 		if (false == m_routing.AddRoutingRule(rt_rule))
1264 		{
1265 			IPACMERR("Routing rule addition failed!\n");
1266 			res = IPACM_FAILURE;
1267 			goto fail;
1268 		}
1269 		else if (rt_rule_entry->status)
1270 		{
1271 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1272 			res = rt_rule_entry->status;
1273 			goto fail;
1274 		}
1275 		dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
1276 
1277 		IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n",
1278 		          dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
1279 		          dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6);
1280 
1281 		if (num_dft_rt_v6 == 0)
1282 		{
1283 			install_ipv6_icmp_flt_rule();
1284 
1285 			/* populate the flt rule offset for eth bridge */
1286 			eth_bridge_flt_rule_offset[data->iptype] = ipv6_icmp_flt_rule_hdl[0];
1287 			eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL);
1288 
1289 			init_fl_rule(data->iptype);
1290 		}
1291 		num_dft_rt_v6++;
1292 		IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
1293 	}
1294 
1295 #ifdef FEATURE_IPACM_HAL
1296 	/* check if having pending add_downstream cache*/
1297 	OffloadMng = IPACM_OffloadManager::GetInstance();
1298 	if (OffloadMng == NULL) {
1299 		IPACMERR("failed to get IPACM_OffloadManager instance !\n");
1300 	} else {
1301 		IPACMDBG_H(" check iface %s if having add_downstream cache events\n", dev_name);
1302 		OffloadMng->search_framwork_cache(dev_name);
1303 	}
1304 #endif
1305 
1306 	IPACMDBG_H("finish route/filter rule ip-type: %d, res(%d)\n", data->iptype, res);
1307 
1308 fail:
1309 	free(rt_rule);
1310 	return res;
1311 }
1312 
1313 /* configure private subnet filter rules*/
handle_private_subnet(ipa_ip_type iptype)1314 int IPACM_Lan::handle_private_subnet(ipa_ip_type iptype)
1315 {
1316 	struct ipa_flt_rule_add flt_rule_entry;
1317 	int i;
1318 
1319 	ipa_ioc_add_flt_rule *m_pFilteringTable;
1320 
1321 	IPACMDBG_H("lan->handle_private_subnet(); set route/filter rule \n");
1322 
1323 	if (rx_prop == NULL)
1324 	{
1325 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
1326 		return IPACM_SUCCESS;
1327 	}
1328 
1329 	if (iptype == IPA_IP_v4)
1330 	{
1331 
1332 		m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
1333 			 calloc(1,
1334 							sizeof(struct ipa_ioc_add_flt_rule) +
1335 							(IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_add)
1336 							);
1337 		if (!m_pFilteringTable)
1338 		{
1339 			PERROR("Error Locate ipa_flt_rule_add memory...\n");
1340 			return IPACM_FAILURE;
1341 		}
1342 		m_pFilteringTable->commit = 1;
1343 		m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
1344 		m_pFilteringTable->global = false;
1345 		m_pFilteringTable->ip = IPA_IP_v4;
1346 		m_pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
1347 
1348 		/* Make LAN-traffic always go A5, use default IPA-RT table */
1349 		if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4))
1350 		{
1351 			IPACMERR("LAN m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_default_v4);
1352 			free(m_pFilteringTable);
1353 			return IPACM_FAILURE;
1354 		}
1355 
1356 		for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
1357 		{
1358 			memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
1359 			flt_rule_entry.at_rear = true;
1360 			flt_rule_entry.rule.retain_hdr = 1;
1361 			flt_rule_entry.flt_rule_hdl = -1;
1362 			flt_rule_entry.status = -1;
1363 			flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
1364 #ifdef FEATURE_IPA_V3
1365 			flt_rule_entry.rule.hashable = true;
1366 #endif
1367                         /* Support private subnet feature including guest-AP can't talk to primary AP etc */
1368 			flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl;
1369 			IPACMDBG_H(" private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name);
1370 
1371 			memcpy(&flt_rule_entry.rule.attrib,
1372 						 &rx_prop->rx[0].attrib,
1373 						 sizeof(flt_rule_entry.rule.attrib));
1374 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1375 			flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
1376 			flt_rule_entry.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
1377 			memcpy(&(m_pFilteringTable->rules[i]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
1378 			IPACMDBG_H("Loop %d  5\n", i);
1379 		}
1380 
1381 		if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
1382 		{
1383 			IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
1384 			free(m_pFilteringTable);
1385 			return IPACM_FAILURE;
1386 		}
1387 		IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
1388 
1389 		/* copy filter rule hdls */
1390 		for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
1391 		{
1392 			private_fl_rule_hdl[i] = m_pFilteringTable->rules[i].flt_rule_hdl;
1393 		}
1394 		free(m_pFilteringTable);
1395 	}
1396 	else
1397 	{
1398 		IPACMDBG_H("No private subnet rules for ipv6 iface %s\n", dev_name);
1399 	}
1400 	return IPACM_SUCCESS;
1401 }
1402 
1403 
1404 /* for STA mode wan up:  configure filter rule for wan_up event*/
handle_wan_up(ipa_ip_type ip_type)1405 int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type)
1406 {
1407 	struct ipa_flt_rule_add flt_rule_entry;
1408 	int len = 0;
1409 	ipa_ioc_add_flt_rule *m_pFilteringTable;
1410 
1411 	IPACMDBG_H("set WAN interface as default filter rule\n");
1412 
1413 	if (rx_prop == NULL)
1414 	{
1415 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
1416 		return IPACM_SUCCESS;
1417 	}
1418 
1419 	if(ip_type == IPA_IP_v4)
1420 	{
1421 		len = sizeof(struct ipa_ioc_add_flt_rule) + (1 * sizeof(struct ipa_flt_rule_add));
1422 		m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
1423 		if (m_pFilteringTable == NULL)
1424 		{
1425 			PERROR("Error Locate ipa_flt_rule_add memory...\n");
1426 			return IPACM_FAILURE;
1427 		}
1428 
1429 		m_pFilteringTable->commit = 1;
1430 		m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
1431 		m_pFilteringTable->global = false;
1432 		m_pFilteringTable->ip = IPA_IP_v4;
1433 		m_pFilteringTable->num_rules = (uint8_t)1;
1434 
1435 		IPACMDBG_H("Retrieving routing hanle for table: %s\n",
1436 						 IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name);
1437 		if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4))
1438 		{
1439 			IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n",
1440 							 &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4);
1441 			free(m_pFilteringTable);
1442 			return IPACM_FAILURE;
1443 		}
1444 		IPACMDBG_H("Routing hanle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl);
1445 
1446 
1447 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields
1448 		flt_rule_entry.at_rear = true;
1449 		flt_rule_entry.flt_rule_hdl = -1;
1450 		flt_rule_entry.status = -1;
1451 		if(IPACM_Wan::isWan_Bridge_Mode())
1452 		{
1453 			flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
1454 		}
1455 		else
1456 		{
1457 			flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; //IPA_PASS_TO_ROUTING
1458 		}
1459 #ifdef FEATURE_IPA_V3
1460 		flt_rule_entry.rule.hashable = true;
1461 #endif
1462 		flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl;
1463 
1464 		memcpy(&flt_rule_entry.rule.attrib,
1465 					 &rx_prop->rx[0].attrib,
1466 					 sizeof(flt_rule_entry.rule.attrib));
1467 
1468 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1469 		flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0;
1470 		flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0;
1471 
1472 /* only offload UL traffic of certain clients */
1473 #ifdef FEATURE_IPACM_HAL
1474 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
1475 		flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = prefix[IPA_IP_v4].v4Mask;
1476 		flt_rule_entry.rule.attrib.u.v4.dst_addr = prefix[IPA_IP_v4].v4Addr;
1477 #endif
1478 		memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry));
1479 		if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
1480 		{
1481 			IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
1482 			free(m_pFilteringTable);
1483 			return IPACM_FAILURE;
1484 		}
1485 		else
1486 		{
1487 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
1488 			IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
1489 							 m_pFilteringTable->rules[0].flt_rule_hdl,
1490 							 m_pFilteringTable->rules[0].status);
1491 		}
1492 
1493 
1494 		/* copy filter hdls  */
1495 		lan_wan_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
1496 		free(m_pFilteringTable);
1497 	}
1498 	else if(ip_type == IPA_IP_v6)
1499 	{
1500 		/* add default v6 filter rule */
1501 		m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
1502 			 calloc(1, sizeof(struct ipa_ioc_add_flt_rule) +
1503 					1 * sizeof(struct ipa_flt_rule_add));
1504 
1505 		if (!m_pFilteringTable)
1506 		{
1507 			PERROR("Error Locate ipa_flt_rule_add memory...\n");
1508 			return IPACM_FAILURE;
1509 		}
1510 
1511 		m_pFilteringTable->commit = 1;
1512 		m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
1513 		m_pFilteringTable->global = false;
1514 		m_pFilteringTable->ip = IPA_IP_v6;
1515 		m_pFilteringTable->num_rules = (uint8_t)1;
1516 
1517 		if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6))
1518 		{
1519 			IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_v6);
1520 			free(m_pFilteringTable);
1521 			return IPACM_FAILURE;
1522 		}
1523 
1524 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
1525 
1526 		flt_rule_entry.at_rear = true;
1527 		flt_rule_entry.flt_rule_hdl = -1;
1528 		flt_rule_entry.status = -1;
1529 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
1530 #ifdef FEATURE_IPA_V3
1531 		flt_rule_entry.rule.hashable = true;
1532 #endif
1533 		flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_v6.hdl;
1534 
1535 		memcpy(&flt_rule_entry.rule.attrib,
1536 					 &rx_prop->rx[0].attrib,
1537 					 sizeof(flt_rule_entry.rule.attrib));
1538 
1539 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1540 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;
1541 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
1542 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
1543 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
1544 		flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000;
1545 		flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
1546 		flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
1547 		flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
1548 
1549 /* only offload UL traffic of certain clients */
1550 #ifdef FEATURE_IPACM_HAL
1551 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
1552 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[0] = ntohl(prefix[IPA_IP_v6].v6Mask[0]);
1553 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[1] = ntohl(prefix[IPA_IP_v6].v6Mask[1]);
1554 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[2] = ntohl(prefix[IPA_IP_v6].v6Mask[2]);
1555 		flt_rule_entry.rule.attrib.u.v6.src_addr_mask[3] = ntohl(prefix[IPA_IP_v6].v6Mask[3]);
1556 		flt_rule_entry.rule.attrib.u.v6.src_addr[0] = ntohl(prefix[IPA_IP_v6].v6Addr[0]);
1557 		flt_rule_entry.rule.attrib.u.v6.src_addr[1] = ntohl(prefix[IPA_IP_v6].v6Addr[1]);
1558 		flt_rule_entry.rule.attrib.u.v6.src_addr[2] = ntohl(prefix[IPA_IP_v6].v6Addr[2]);
1559 		flt_rule_entry.rule.attrib.u.v6.src_addr[3] = ntohl(prefix[IPA_IP_v6].v6Addr[3]);
1560 
1561 #endif
1562 		memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
1563 		if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
1564 		{
1565 			IPACMERR("Error Adding Filtering rule, aborting...\n");
1566 			free(m_pFilteringTable);
1567 			return IPACM_FAILURE;
1568 		}
1569 		else
1570 		{
1571 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
1572 			IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
1573 		}
1574 
1575 		/* copy filter hdls */
1576 		dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES] = m_pFilteringTable->rules[0].flt_rule_hdl;
1577 		free(m_pFilteringTable);
1578 	}
1579 
1580 	return IPACM_SUCCESS;
1581 }
1582 
handle_wan_up_ex(ipacm_ext_prop * ext_prop,ipa_ip_type iptype,uint8_t xlat_mux_id)1583 int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, uint8_t xlat_mux_id)
1584 {
1585 	int fd, ret = IPACM_SUCCESS;
1586 	uint32_t cnt;
1587 	IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg;
1588 	struct ipa_ioc_write_qmapid mux;
1589 
1590 	if(rx_prop != NULL)
1591 	{
1592 		/* give mud ID to IPA-driver for WLAN/LAN pkts */
1593 		fd = open(IPA_DEVICE_NAME, O_RDWR);
1594 		if (0 == fd)
1595 		{
1596 			IPACMDBG_H("Failed opening %s.\n", IPA_DEVICE_NAME);
1597 			return IPACM_FAILURE;
1598 		}
1599 
1600 		mux.qmap_id = ipacm_config->GetQmapId();
1601 		for(cnt=0; cnt<rx_prop->num_rx_props; cnt++)
1602 		{
1603 			mux.client = rx_prop->rx[cnt].src_pipe;
1604 			ret = ioctl(fd, IPA_IOC_WRITE_QMAPID, &mux);
1605 			if (ret)
1606 			{
1607 				IPACMERR("Failed to write mux id %d\n", mux.qmap_id);
1608 				close(fd);
1609 				return IPACM_FAILURE;
1610 			}
1611 		}
1612 		close(fd);
1613 	}
1614 
1615 	/* check only add static UL filter rule once */
1616 	if (iptype ==IPA_IP_v6 && modem_ul_v6_set == false)
1617 	{
1618 		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);
1619 		ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
1620 		modem_ul_v6_set = true;
1621 	} else if (iptype ==IPA_IP_v4 && modem_ul_v4_set == false) {
1622 		IPACMDBG_H("IPA_IP_v4 xlat_mux_id: %d, modem_ul_v4_set %d\n", xlat_mux_id, modem_ul_v4_set);
1623 		ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
1624 		modem_ul_v4_set = true;
1625 	} else {
1626 		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);
1627 	}
1628 	return ret;
1629 }
1630 
1631 /* handle ETH client initial, construct full headers (tx property) */
handle_eth_hdr_init(uint8_t * mac_addr)1632 int IPACM_Lan::handle_eth_hdr_init(uint8_t *mac_addr)
1633 {
1634 
1635 #define ETH_IFACE_INDEX_LEN 2
1636 
1637 	int res = IPACM_SUCCESS, len = 0;
1638 	char index[ETH_IFACE_INDEX_LEN];
1639 	struct ipa_ioc_copy_hdr sCopyHeader;
1640 	struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
1641 	uint32_t cnt;
1642 	int clnt_indx;
1643 
1644 	clnt_indx = get_eth_client_index(mac_addr);
1645 
1646 	if (clnt_indx != IPACM_INVALID_INDEX)
1647 	{
1648 		IPACMERR("eth client is found/attached already with index %d \n", clnt_indx);
1649 		return IPACM_FAILURE;
1650 	}
1651 
1652 	/* add header to IPA */
1653 	if (num_eth_client >= IPA_MAX_NUM_ETH_CLIENTS)
1654 	{
1655 		IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_ETH_CLIENTS);
1656 		return IPACM_FAILURE;
1657 	}
1658 
1659 	IPACMDBG_H("ETH client number: %d\n", num_eth_client);
1660 
1661 	memcpy(get_client_memptr(eth_client, num_eth_client)->mac,
1662 				 mac_addr,
1663 				 sizeof(get_client_memptr(eth_client, num_eth_client)->mac));
1664 
1665 
1666 	IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1667 					 mac_addr[0], mac_addr[1], mac_addr[2],
1668 					 mac_addr[3], mac_addr[4], mac_addr[5]);
1669 
1670 	IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1671 					 get_client_memptr(eth_client, num_eth_client)->mac[0],
1672 					 get_client_memptr(eth_client, num_eth_client)->mac[1],
1673 					 get_client_memptr(eth_client, num_eth_client)->mac[2],
1674 					 get_client_memptr(eth_client, num_eth_client)->mac[3],
1675 					 get_client_memptr(eth_client, num_eth_client)->mac[4],
1676 					 get_client_memptr(eth_client, num_eth_client)->mac[5]);
1677 
1678 	/* add header to IPA */
1679 	if(tx_prop != NULL)
1680 	{
1681 		len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
1682 		pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
1683 		if (pHeaderDescriptor == NULL)
1684 		{
1685 			IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
1686 			return IPACM_FAILURE;
1687 		}
1688 
1689 		/* copy partial header for v4*/
1690 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
1691 		{
1692 				 if(tx_prop->tx[cnt].ip==IPA_IP_v4)
1693 				 {
1694 								IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt);
1695 								memset(&sCopyHeader, 0, sizeof(sCopyHeader));
1696 								memcpy(sCopyHeader.name,
1697 											 tx_prop->tx[cnt].hdr_name,
1698 											 sizeof(sCopyHeader.name));
1699 
1700 								IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
1701 								if (m_header.CopyHeader(&sCopyHeader) == false)
1702 								{
1703 									PERROR("ioctl copy header failed");
1704 									res = IPACM_FAILURE;
1705 									goto fail;
1706 								}
1707 
1708 								IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
1709 								IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
1710 								if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
1711 								{
1712 									IPACMERR("header oversize\n");
1713 									res = IPACM_FAILURE;
1714 									goto fail;
1715 								}
1716 								else
1717 								{
1718 									memcpy(pHeaderDescriptor->hdr[0].hdr,
1719 												 sCopyHeader.hdr,
1720 												 sCopyHeader.hdr_len);
1721 								}
1722 
1723 								/* copy client mac_addr to partial header */
1724 								if (sCopyHeader.is_eth2_ofst_valid)
1725 								{
1726 									memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
1727 											 mac_addr,
1728 											 IPA_MAC_ADDR_SIZE);
1729 								}
1730 								/* replace src mac to bridge mac_addr if any  */
1731 								if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
1732 								{
1733 									memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
1734 											IPACM_Iface::ipacmcfg->bridge_mac,
1735 											IPA_MAC_ADDR_SIZE);
1736 									IPACMDBG_H("device is in bridge mode \n");
1737 								}
1738 
1739 								pHeaderDescriptor->commit = true;
1740 								pHeaderDescriptor->num_hdrs = 1;
1741 
1742 								memset(pHeaderDescriptor->hdr[0].name, 0,
1743 											 sizeof(pHeaderDescriptor->hdr[0].name));
1744 
1745 								snprintf(index,sizeof(index), "%d", ipa_if_num);
1746 								strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
1747 								pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1748 								if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1749 								{
1750 									IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1751 									res = IPACM_FAILURE;
1752 									goto fail;
1753 								}
1754 
1755 								snprintf(index,sizeof(index), "%d", header_name_count);
1756 								if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1757 								{
1758 									IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1759 									res = IPACM_FAILURE;
1760 									goto fail;
1761 								}
1762 
1763 								pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
1764 								pHeaderDescriptor->hdr[0].hdr_hdl = -1;
1765 								pHeaderDescriptor->hdr[0].is_partial = 0;
1766 								pHeaderDescriptor->hdr[0].status = -1;
1767 
1768 					 if (m_header.AddHeader(pHeaderDescriptor) == false ||
1769 							pHeaderDescriptor->hdr[0].status != 0)
1770 					 {
1771 						IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
1772 						res = IPACM_FAILURE;
1773 						goto fail;
1774 					 }
1775 
1776 					get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
1777 					IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n",
1778 												 num_eth_client,
1779 												 pHeaderDescriptor->hdr[0].name,
1780 												 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4);
1781 									get_client_memptr(eth_client, num_eth_client)->ipv4_header_set=true;
1782 
1783 					break;
1784 				 }
1785 		}
1786 
1787 
1788 		/* copy partial header for v6*/
1789 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
1790 		{
1791 			if(tx_prop->tx[cnt].ip==IPA_IP_v6)
1792 			{
1793 
1794 				IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt);
1795 				memset(&sCopyHeader, 0, sizeof(sCopyHeader));
1796 				memcpy(sCopyHeader.name,
1797 						tx_prop->tx[cnt].hdr_name,
1798 							sizeof(sCopyHeader.name));
1799 
1800 				IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
1801 				if (m_header.CopyHeader(&sCopyHeader) == false)
1802 				{
1803 					PERROR("ioctl copy header failed");
1804 					res = IPACM_FAILURE;
1805 					goto fail;
1806 				}
1807 
1808 				IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
1809 				IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
1810 				if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
1811 				{
1812 					IPACMERR("header oversize\n");
1813 					res = IPACM_FAILURE;
1814 					goto fail;
1815 				}
1816 				else
1817 				{
1818 					memcpy(pHeaderDescriptor->hdr[0].hdr,
1819 							sCopyHeader.hdr,
1820 								sCopyHeader.hdr_len);
1821 				}
1822 
1823 				/* copy client mac_addr to partial header */
1824 				if (sCopyHeader.is_eth2_ofst_valid)
1825 				{
1826 					memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
1827 						mac_addr,
1828 						IPA_MAC_ADDR_SIZE);
1829 				}
1830 				/* replace src mac to bridge mac_addr if any  */
1831 				if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
1832 				{
1833 					memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
1834 							IPACM_Iface::ipacmcfg->bridge_mac,
1835 							IPA_MAC_ADDR_SIZE);
1836 					IPACMDBG_H("device is in bridge mode \n");
1837 				}
1838 
1839 				pHeaderDescriptor->commit = true;
1840 				pHeaderDescriptor->num_hdrs = 1;
1841 
1842 				memset(pHeaderDescriptor->hdr[0].name, 0,
1843 					 sizeof(pHeaderDescriptor->hdr[0].name));
1844 
1845 				snprintf(index,sizeof(index), "%d", ipa_if_num);
1846 				strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
1847 				pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1848 				if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1849 				{
1850 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1851 					res = IPACM_FAILURE;
1852 					goto fail;
1853 				}
1854 				snprintf(index,sizeof(index), "%d", header_name_count);
1855 				if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1856 				{
1857 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1858 					res = IPACM_FAILURE;
1859 					goto fail;
1860 				}
1861 
1862 				pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
1863 				pHeaderDescriptor->hdr[0].hdr_hdl = -1;
1864 				pHeaderDescriptor->hdr[0].is_partial = 0;
1865 				pHeaderDescriptor->hdr[0].status = -1;
1866 
1867 				if (m_header.AddHeader(pHeaderDescriptor) == false ||
1868 						pHeaderDescriptor->hdr[0].status != 0)
1869 				{
1870 					IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
1871 					res = IPACM_FAILURE;
1872 					goto fail;
1873 				}
1874 
1875 				get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
1876 				IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n",
1877 						 num_eth_client,
1878 						 pHeaderDescriptor->hdr[0].name,
1879 									 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6);
1880 
1881 									get_client_memptr(eth_client, num_eth_client)->ipv6_header_set=true;
1882 
1883 				break;
1884 
1885 			}
1886 		}
1887 		/* initialize wifi client*/
1888 		get_client_memptr(eth_client, num_eth_client)->route_rule_set_v4 = false;
1889 		get_client_memptr(eth_client, num_eth_client)->route_rule_set_v6 = 0;
1890 		get_client_memptr(eth_client, num_eth_client)->ipv4_set = false;
1891 		get_client_memptr(eth_client, num_eth_client)->ipv6_set = 0;
1892 		num_eth_client++;
1893 		header_name_count++; //keep increasing header_name_count
1894 		res = IPACM_SUCCESS;
1895 		IPACMDBG_H("eth client number: %d\n", num_eth_client);
1896 	}
1897 	else
1898 	{
1899 		return res;
1900 	}
1901 fail:
1902 	free(pHeaderDescriptor);
1903 	return res;
1904 }
1905 
1906 /*handle eth client */
handle_eth_client_ipaddr(ipacm_event_data_all * data)1907 int IPACM_Lan::handle_eth_client_ipaddr(ipacm_event_data_all *data)
1908 {
1909 	int clnt_indx;
1910 	int v6_num;
1911 	uint32_t ipv6_link_local_prefix = 0xFE800000;
1912 	uint32_t ipv6_link_local_prefix_mask = 0xFFC00000;
1913 
1914 	IPACMDBG_H("number of eth clients: %d\n", num_eth_client);
1915 	IPACMDBG_H("event MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1916 					 data->mac_addr[0],
1917 					 data->mac_addr[1],
1918 					 data->mac_addr[2],
1919 					 data->mac_addr[3],
1920 					 data->mac_addr[4],
1921 					 data->mac_addr[5]);
1922 
1923 	clnt_indx = get_eth_client_index(data->mac_addr);
1924 
1925 		if (clnt_indx == IPACM_INVALID_INDEX)
1926 		{
1927 			IPACMERR("eth client not found/attached \n");
1928 			return IPACM_FAILURE;
1929 		}
1930 
1931 	IPACMDBG_H("Ip-type received %d\n", data->iptype);
1932 	if (data->iptype == IPA_IP_v4)
1933 	{
1934 		IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr);
1935 		if (data->ipv4_addr != 0) /* not 0.0.0.0 */
1936 		{
1937 			if (get_client_memptr(eth_client, clnt_indx)->ipv4_set == false)
1938 			{
1939 				get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr;
1940 				get_client_memptr(eth_client, clnt_indx)->ipv4_set = true;
1941 			}
1942 			else
1943 			{
1944 			   /* check if client got new IPv4 address*/
1945 			   if(data->ipv4_addr == get_client_memptr(eth_client, clnt_indx)->v4_addr)
1946 			   {
1947 				IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx);
1948 				 return IPACM_FAILURE;
1949 			   }
1950 			   else
1951 			   {
1952 					IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
1953 					/* delete NAT rules first */
1954 					CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clnt_indx)->v4_addr);
1955 					delete_eth_rtrules(clnt_indx,IPA_IP_v4);
1956 					get_client_memptr(eth_client, clnt_indx)->route_rule_set_v4 = false;
1957 					get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr;
1958 				}
1959 			}
1960 		}
1961 		else
1962 		{
1963 		    IPACMDBG_H("Invalid client IPv4 address \n");
1964 		    return IPACM_FAILURE;
1965 		}
1966 	}
1967 	else
1968 	{
1969 		if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
1970 				(data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) /* check if all 0 not valid ipv6 address */
1971 		{
1972 			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]);
1973 			if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) &&
1974 				memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0)
1975 			{
1976 				IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n");
1977 				return IPACM_FAILURE;
1978 			}
1979 
1980             if(get_client_memptr(eth_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
1981 			{
1982 
1983 		       for(v6_num=0;v6_num < get_client_memptr(eth_client, clnt_indx)->ipv6_set;v6_num++)
1984 				{
1985 					if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][0] &&
1986 			           data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][1] &&
1987 			  	        data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][2] &&
1988 			  	         data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][3])
1989 					{
1990 						IPACMDBG_H("Already see this ipv6 addr at position: %d for client:%d\n", v6_num, clnt_indx);
1991 						return IPACM_FAILURE; /* not setup the RT rules*/
1992 					}
1993 				}
1994 
1995 		       /* not see this ipv6 before for wifi client*/
1996 			   get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0];
1997 			   get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1];
1998 			   get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2];
1999 			   get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3];
2000 			   get_client_memptr(eth_client, clnt_indx)->ipv6_set++;
2001 		    }
2002 		    else
2003 		    {
2004 		        IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx);
2005 				return IPACM_FAILURE; /* not setup the RT rules*/
2006 		    }
2007 		}
2008 		else
2009 		{
2010 			IPACMDBG_H("Invalid IPV6 address\n");
2011 			return IPACM_FAILURE;
2012 		}
2013 	}
2014 
2015 	return IPACM_SUCCESS;
2016 }
2017 
2018 /*handle eth client routing rule*/
handle_eth_client_route_rule(uint8_t * mac_addr,ipa_ip_type iptype)2019 int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype)
2020 {
2021 	struct ipa_ioc_add_rt_rule *rt_rule;
2022 	struct ipa_rt_rule_add *rt_rule_entry;
2023 	uint32_t tx_index;
2024 	int eth_index,v6_num;
2025 	const int NUM = 1;
2026 
2027 	if(tx_prop == NULL)
2028 	{
2029 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
2030 		return IPACM_SUCCESS;
2031 	}
2032 
2033 	IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
2034 					 mac_addr[0], mac_addr[1], mac_addr[2],
2035 					 mac_addr[3], mac_addr[4], mac_addr[5]);
2036 
2037 	eth_index = get_eth_client_index(mac_addr);
2038 	if (eth_index == IPACM_INVALID_INDEX)
2039 	{
2040 		IPACMDBG_H("eth client not found/attached \n");
2041 		return IPACM_SUCCESS;
2042 	}
2043 
2044 	if (iptype==IPA_IP_v4) {
2045 		IPACMDBG_H("eth client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", eth_index, iptype,
2046 					 get_client_memptr(eth_client, eth_index)->ipv4_set,
2047 					 get_client_memptr(eth_client, eth_index)->route_rule_set_v4);
2048 	} else {
2049 		IPACMDBG_H("eth client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", eth_index, iptype,
2050 					 get_client_memptr(eth_client, eth_index)->ipv6_set,
2051 					 get_client_memptr(eth_client, eth_index)->route_rule_set_v6);
2052 	}
2053 	/* Add default routing rules if not set yet */
2054 	if ((iptype == IPA_IP_v4
2055 			 && get_client_memptr(eth_client, eth_index)->route_rule_set_v4 == false
2056 			 && get_client_memptr(eth_client, eth_index)->ipv4_set == true)
2057 			|| (iptype == IPA_IP_v6
2058 		            && get_client_memptr(eth_client, eth_index)->route_rule_set_v6 < get_client_memptr(eth_client, eth_index)->ipv6_set
2059 					))
2060 	{
2061 
2062         /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
2063 		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2064 		if (tx_prop != NULL)
2065 		{
2066 			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]);
2067 			IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
2068 		}
2069 		rt_rule = (struct ipa_ioc_add_rt_rule *)
2070 			 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
2071 						NUM * sizeof(struct ipa_rt_rule_add));
2072 
2073 		if (rt_rule == NULL)
2074 		{
2075 			PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n");
2076 			return IPACM_FAILURE;
2077 		}
2078 
2079 		rt_rule->commit = 1;
2080 		rt_rule->num_rules = (uint8_t)NUM;
2081 		rt_rule->ip = iptype;
2082 
2083 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2084 		{
2085 			if(iptype != tx_prop->tx[tx_index].ip)
2086 		    {
2087 				IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n",
2088 						tx_index, tx_prop->tx[tx_index].ip,iptype);
2089 		   	        continue;
2090 		    }
2091 
2092   	   	    rt_rule_entry = &rt_rule->rules[0];
2093 			rt_rule_entry->at_rear = 0;
2094 
2095 			if (iptype == IPA_IP_v4)
2096 			{
2097 		        IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", eth_index,
2098 		  		        get_client_memptr(eth_client, eth_index)->v4_addr);
2099 
2100                 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
2101 		  				 eth_index,
2102 		  				 get_client_memptr(eth_client, eth_index)->hdr_hdl_v4);
2103 				strlcpy(rt_rule->rt_tbl_name,
2104 								IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name,
2105 								sizeof(rt_rule->rt_tbl_name));
2106 				rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2107 			    rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2108 			    memcpy(&rt_rule_entry->rule.attrib,
2109 						 &tx_prop->tx[tx_index].attrib,
2110 						 sizeof(rt_rule_entry->rule.attrib));
2111 			    rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2112 		   	    rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v4;
2113 				rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr;
2114 				rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
2115 #ifdef FEATURE_IPA_V3
2116 				rt_rule_entry->rule.hashable = false;
2117 #endif
2118 			    if (false == m_routing.AddRoutingRule(rt_rule))
2119   	            {
2120   	          	            IPACMERR("Routing rule addition failed!\n");
2121   	          	            free(rt_rule);
2122   	          	            return IPACM_FAILURE;
2123 			    }
2124 
2125 			    /* copy ipv4 RT hdl */
2126 		        get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 =
2127   	   	        rt_rule->rules[0].rt_rule_hdl;
2128 		        IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2129 		      	get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4, iptype);
2130 
2131   	   	    } else {
2132 
2133 		        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++)
2134 			    {
2135                     IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
2136 		  	    			 eth_index,
2137 		  	    			 get_client_memptr(eth_client, eth_index)->hdr_hdl_v6);
2138 
2139 		            /* v6 LAN_RT_TBL */
2140 				strlcpy(rt_rule->rt_tbl_name,
2141 			    					IPACM_Iface::ipacmcfg->rt_tbl_v6.name,
2142 			    					sizeof(rt_rule->rt_tbl_name));
2143 				rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2144 		            /* Support QCMAP LAN traffic feature, send to A5 */
2145 					rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
2146 			        memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib));
2147 		   	        rt_rule_entry->rule.hdr_hdl = 0;
2148 			        rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2149 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0];
2150 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1];
2151 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2];
2152 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3];
2153 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2154 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2155 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2156 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2157 #ifdef FEATURE_IPA_V3
2158 					rt_rule_entry->rule.hashable = true;
2159 #endif
2160    	                if (false == m_routing.AddRoutingRule(rt_rule))
2161   	                {
2162   	                	    IPACMERR("Routing rule addition failed!\n");
2163   	                	    free(rt_rule);
2164   	                	    return IPACM_FAILURE;
2165 			        }
2166 
2167 		            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;
2168 		            IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2169 		            				 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[v6_num], iptype);
2170 
2171 			        /*Copy same rule to v6 WAN RT TBL*/
2172 				strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
2173 				rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2174 				/* Downlink traffic from Wan iface, directly through IPA */
2175 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2176 			        memcpy(&rt_rule_entry->rule.attrib,
2177 						 &tx_prop->tx[tx_index].attrib,
2178 						 sizeof(rt_rule_entry->rule.attrib));
2179 		   	        rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v6;
2180 			        rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2181 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0];
2182 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1];
2183 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2];
2184 		   	        rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3];
2185 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2186 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2187 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2188 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2189 #ifdef FEATURE_IPA_V3
2190 					rt_rule_entry->rule.hashable = true;
2191 #endif
2192 		            if (false == m_routing.AddRoutingRule(rt_rule))
2193 		            {
2194 							IPACMERR("Routing rule addition failed!\n");
2195 							free(rt_rule);
2196 							return IPACM_FAILURE;
2197 		            }
2198 
2199 		            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;
2200 					IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2201 		            				 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num], iptype);
2202 			    }
2203 			}
2204 
2205   	    } /* end of for loop */
2206 
2207 		free(rt_rule);
2208 
2209 		if (iptype == IPA_IP_v4)
2210 		{
2211 			get_client_memptr(eth_client, eth_index)->route_rule_set_v4 = true;
2212 		}
2213 		else
2214 		{
2215 			get_client_memptr(eth_client, eth_index)->route_rule_set_v6 = get_client_memptr(eth_client, eth_index)->ipv6_set;
2216 		}
2217 	}
2218 	return IPACM_SUCCESS;
2219 }
2220 
2221 /* handle odu client initial, construct full headers (tx property) */
handle_odu_hdr_init(uint8_t * mac_addr)2222 int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr)
2223 {
2224 	int res = IPACM_SUCCESS, len = 0;
2225 	struct ipa_ioc_copy_hdr sCopyHeader;
2226 	struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
2227 	uint32_t cnt;
2228 
2229 	IPACMDBG("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
2230 					 mac_addr[0], mac_addr[1], mac_addr[2],
2231 					 mac_addr[3], mac_addr[4], mac_addr[5]);
2232 
2233 	/* add header to IPA */
2234 	if(tx_prop != NULL)
2235 	{
2236 		len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
2237 		pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
2238 		if (pHeaderDescriptor == NULL)
2239 		{
2240 			IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
2241 			return IPACM_FAILURE;
2242 		}
2243 
2244 		/* copy partial header for v4*/
2245 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
2246 		{
2247 				 if(tx_prop->tx[cnt].ip==IPA_IP_v4)
2248 				 {
2249 								IPACMDBG("Got partial v4-header name from %d tx props\n", cnt);
2250 								memset(&sCopyHeader, 0, sizeof(sCopyHeader));
2251 								memcpy(sCopyHeader.name,
2252 											tx_prop->tx[cnt].hdr_name,
2253 											 sizeof(sCopyHeader.name));
2254 								IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
2255 								if (m_header.CopyHeader(&sCopyHeader) == false)
2256 								{
2257 									PERROR("ioctl copy header failed");
2258 									res = IPACM_FAILURE;
2259 									goto fail;
2260 								}
2261 								IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
2262 								if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
2263 								{
2264 									IPACMERR("header oversize\n");
2265 									res = IPACM_FAILURE;
2266 									goto fail;
2267 								}
2268 								else
2269 								{
2270 									memcpy(pHeaderDescriptor->hdr[0].hdr,
2271 												 sCopyHeader.hdr,
2272 												 sCopyHeader.hdr_len);
2273 								}
2274 								/* copy client mac_addr to partial header */
2275 								if (sCopyHeader.is_eth2_ofst_valid)
2276 								{
2277 									memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
2278 											 mac_addr,
2279 											 IPA_MAC_ADDR_SIZE);
2280 								}
2281 								/* replace src mac to bridge mac_addr if any  */
2282 								if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
2283 								{
2284 									memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
2285 											IPACM_Iface::ipacmcfg->bridge_mac,
2286 											IPA_MAC_ADDR_SIZE);
2287 									IPACMDBG_H("device is in bridge mode \n");
2288 								}
2289 
2290 								pHeaderDescriptor->commit = true;
2291 								pHeaderDescriptor->num_hdrs = 1;
2292 
2293 								memset(pHeaderDescriptor->hdr[0].name, 0,
2294 											 sizeof(pHeaderDescriptor->hdr[0].name));
2295 								strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name));
2296 								pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
2297 								pHeaderDescriptor->hdr[0].hdr_hdl = -1;
2298 								pHeaderDescriptor->hdr[0].is_partial = 0;
2299 								pHeaderDescriptor->hdr[0].status = -1;
2300 
2301 					 if (m_header.AddHeader(pHeaderDescriptor) == false ||
2302 							pHeaderDescriptor->hdr[0].status != 0)
2303 					 {
2304 						IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
2305 						res = IPACM_FAILURE;
2306 						goto fail;
2307 					 }
2308 
2309 					ODU_hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
2310 					ipv4_header_set = true ;
2311 					IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n",
2312 										 pHeaderDescriptor->hdr[0].name,
2313 												 ODU_hdr_hdl_v4);
2314 					break;
2315 				 }
2316 		}
2317 
2318 
2319 		/* copy partial header for v6*/
2320 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
2321 		{
2322 			if(tx_prop->tx[cnt].ip==IPA_IP_v6)
2323 			{
2324 
2325 				IPACMDBG("Got partial v6-header name from %d tx props\n", cnt);
2326 				memset(&sCopyHeader, 0, sizeof(sCopyHeader));
2327 				memcpy(sCopyHeader.name,
2328 						tx_prop->tx[cnt].hdr_name,
2329 							sizeof(sCopyHeader.name));
2330 
2331 				IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
2332 				if (m_header.CopyHeader(&sCopyHeader) == false)
2333 				{
2334 					PERROR("ioctl copy header failed");
2335 					res = IPACM_FAILURE;
2336 					goto fail;
2337 				}
2338 
2339 				IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
2340 				if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
2341 				{
2342 					IPACMERR("header oversize\n");
2343 					res = IPACM_FAILURE;
2344 					goto fail;
2345 				}
2346 				else
2347 				{
2348 					memcpy(pHeaderDescriptor->hdr[0].hdr,
2349 							sCopyHeader.hdr,
2350 								sCopyHeader.hdr_len);
2351 				}
2352 
2353 				/* copy client mac_addr to partial header */
2354 				if (sCopyHeader.is_eth2_ofst_valid)
2355 				{
2356 					memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
2357 					 mac_addr,
2358 					 IPA_MAC_ADDR_SIZE);
2359 				}
2360 				/* replace src mac to bridge mac_addr if any  */
2361 				if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
2362 				{
2363 					memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
2364 							IPACM_Iface::ipacmcfg->bridge_mac,
2365 							IPA_MAC_ADDR_SIZE);
2366 					IPACMDBG_H("device is in bridge mode \n");
2367 				}
2368 
2369 				pHeaderDescriptor->commit = true;
2370 				pHeaderDescriptor->num_hdrs = 1;
2371 
2372 				memset(pHeaderDescriptor->hdr[0].name, 0,
2373 					 sizeof(pHeaderDescriptor->hdr[0].name));
2374 
2375 				strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name));
2376 				pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
2377 				pHeaderDescriptor->hdr[0].hdr_hdl = -1;
2378 				pHeaderDescriptor->hdr[0].is_partial = 0;
2379 				pHeaderDescriptor->hdr[0].status = -1;
2380 
2381 				if (m_header.AddHeader(pHeaderDescriptor) == false ||
2382 						pHeaderDescriptor->hdr[0].status != 0)
2383 				{
2384 					IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
2385 					res = IPACM_FAILURE;
2386 					goto fail;
2387 				}
2388 
2389 				ODU_hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
2390 				ipv6_header_set = true ;
2391 				IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n",
2392 									 pHeaderDescriptor->hdr[0].name,
2393 											 ODU_hdr_hdl_v6);
2394 				break;
2395 			}
2396 		}
2397 	}
2398 fail:
2399 	free(pHeaderDescriptor);
2400 	return res;
2401 }
2402 
2403 
2404 /* handle odu default route rule configuration */
handle_odu_route_add()2405 int IPACM_Lan::handle_odu_route_add()
2406 {
2407 	/* add default WAN route */
2408 	struct ipa_ioc_add_rt_rule *rt_rule;
2409 	struct ipa_rt_rule_add *rt_rule_entry;
2410 	uint32_t tx_index;
2411 	const int NUM = 1;
2412 
2413 	if(tx_prop == NULL)
2414 	{
2415 	  IPACMDBG_H("No tx properties, ignore default route setting\n");
2416 	  return IPACM_SUCCESS;
2417 	}
2418 
2419 	rt_rule = (struct ipa_ioc_add_rt_rule *)
2420 		 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
2421 						NUM * sizeof(struct ipa_rt_rule_add));
2422 
2423 	if (!rt_rule)
2424 	{
2425 		IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
2426 		return IPACM_FAILURE;
2427 	}
2428 
2429 	rt_rule->commit = 1;
2430 	rt_rule->num_rules = (uint8_t)NUM;
2431 
2432 
2433 	IPACMDBG_H("WAN table created %s \n", rt_rule->rt_tbl_name);
2434 	rt_rule_entry = &rt_rule->rules[0];
2435 	rt_rule_entry->at_rear = true;
2436 
2437 	for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2438 	{
2439 
2440 		if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
2441 		{
2442 			strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, sizeof(rt_rule->rt_tbl_name));
2443 			rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4;
2444 			rt_rule->ip = IPA_IP_v4;
2445 		}
2446 		else
2447 		{
2448 			strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, sizeof(rt_rule->rt_tbl_name));
2449 			rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6;
2450 			rt_rule->ip = IPA_IP_v6;
2451 		}
2452 
2453 		rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2454 		memcpy(&rt_rule_entry->rule.attrib,
2455 					 &tx_prop->tx[tx_index].attrib,
2456 					 sizeof(rt_rule_entry->rule.attrib));
2457 
2458 		rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2459 		if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
2460 		{
2461 			rt_rule_entry->rule.attrib.u.v4.dst_addr      = 0;
2462 			rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0;
2463 #ifdef FEATURE_IPA_V3
2464 			rt_rule_entry->rule.hashable = true;
2465 #endif
2466 			if (false == m_routing.AddRoutingRule(rt_rule))
2467 			{
2468 				IPACMERR("Routing rule addition failed!\n");
2469 				free(rt_rule);
2470 				return IPACM_FAILURE;
2471 			}
2472 			odu_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
2473 			IPACMDBG_H("Got ipv4 ODU-route rule hdl:0x%x,tx:%d,ip-type: %d \n",
2474 						 odu_route_rule_v4_hdl[tx_index],
2475 						 tx_index,
2476 						 IPA_IP_v4);
2477 		}
2478 		else
2479 		{
2480 			rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0;
2481 			rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0;
2482 			rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0;
2483 			rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0;
2484 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0;
2485 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0;
2486 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0;
2487 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0;
2488 #ifdef FEATURE_IPA_V3
2489 			rt_rule_entry->rule.hashable = true;
2490 #endif
2491 			if (false == m_routing.AddRoutingRule(rt_rule))
2492 			{
2493 				IPACMERR("Routing rule addition failed!\n");
2494 				free(rt_rule);
2495 				return IPACM_FAILURE;
2496 			}
2497 			odu_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
2498 			IPACMDBG_H("Set ipv6 ODU-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n",
2499 					odu_route_rule_v6_hdl[tx_index],
2500 					tx_index,
2501 					IPA_IP_v6);
2502 		}
2503 	}
2504 	free(rt_rule);
2505 	return IPACM_SUCCESS;
2506 }
2507 
2508 /* handle odu default route rule deletion */
handle_odu_route_del()2509 int IPACM_Lan::handle_odu_route_del()
2510 {
2511 	uint32_t tx_index;
2512 
2513 	if(tx_prop == NULL)
2514 	{
2515 		IPACMDBG_H("No tx properties, ignore delete default route setting\n");
2516 		return IPACM_SUCCESS;
2517 	}
2518 
2519 	for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2520 	{
2521 		if (tx_prop->tx[tx_index].ip == IPA_IP_v4)
2522 		{
2523 			IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
2524 					tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v4);
2525 
2526 			if (m_routing.DeleteRoutingHdl(odu_route_rule_v4_hdl[tx_index], IPA_IP_v4)
2527 					== false)
2528 			{
2529 				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);
2530 				return IPACM_FAILURE;
2531 			}
2532 		}
2533 		else
2534 		{
2535 			IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
2536 					tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v6);
2537 
2538 			if (m_routing.DeleteRoutingHdl(odu_route_rule_v6_hdl[tx_index], IPA_IP_v6)
2539 					== false)
2540 			{
2541 				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);
2542 				return IPACM_FAILURE;
2543 			}
2544 		}
2545 	}
2546 
2547 	return IPACM_SUCCESS;
2548 }
2549 
2550 /*handle eth client del mode*/
handle_eth_client_down_evt(uint8_t * mac_addr)2551 int IPACM_Lan::handle_eth_client_down_evt(uint8_t *mac_addr)
2552 {
2553 	int clt_indx;
2554 	uint32_t tx_index;
2555 	int num_eth_client_tmp = num_eth_client;
2556 	int num_v6;
2557 
2558 	IPACMDBG_H("total client: %d\n", num_eth_client_tmp);
2559 
2560 	clt_indx = get_eth_client_index(mac_addr);
2561 	if (clt_indx == IPACM_INVALID_INDEX)
2562 	{
2563 		IPACMDBG_H("eth client not attached\n");
2564 		return IPACM_SUCCESS;
2565 	}
2566 
2567 	/* First reset nat rules and then route rules */
2568 	if(get_client_memptr(eth_client, clt_indx)->ipv4_set == true)
2569 	{
2570 			IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, clt_indx)->v4_addr);
2571 			CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clt_indx)->v4_addr);
2572  	}
2573 
2574 	if (delete_eth_rtrules(clt_indx, IPA_IP_v4))
2575 	{
2576 		IPACMERR("unbale to delete ecm-client v4 route rules for index: %d\n", clt_indx);
2577 		return IPACM_FAILURE;
2578 	}
2579 
2580 	if (delete_eth_rtrules(clt_indx, IPA_IP_v6))
2581 	{
2582 		IPACMERR("unbale to delete ecm-client v6 route rules for index: %d\n", clt_indx);
2583 		return IPACM_FAILURE;
2584 	}
2585 
2586 	/* Delete eth client header */
2587 	if(get_client_memptr(eth_client, clt_indx)->ipv4_header_set == true)
2588 	{
2589 		if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4)
2590 				== false)
2591 		{
2592 			return IPACM_FAILURE;
2593 		}
2594 		get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false;
2595 	}
2596 
2597 	if(get_client_memptr(eth_client, clt_indx)->ipv6_header_set == true)
2598 	{
2599 		if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6)
2600 				== false)
2601 		{
2602 			return IPACM_FAILURE;
2603 		}
2604 		get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false;
2605 	}
2606 
2607 	/* Reset ip_set to 0*/
2608 	get_client_memptr(eth_client, clt_indx)->ipv4_set = false;
2609 	get_client_memptr(eth_client, clt_indx)->ipv6_set = 0;
2610 	get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false;
2611 	get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false;
2612 	get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = false;
2613 	get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = 0;
2614 
2615 	for (; clt_indx < num_eth_client_tmp - 1; clt_indx++)
2616 	{
2617 		memcpy(get_client_memptr(eth_client, clt_indx)->mac,
2618 					 get_client_memptr(eth_client, (clt_indx + 1))->mac,
2619 					 sizeof(get_client_memptr(eth_client, clt_indx)->mac));
2620 
2621 		get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v4;
2622 		get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v6;
2623 		get_client_memptr(eth_client, clt_indx)->v4_addr = get_client_memptr(eth_client, (clt_indx + 1))->v4_addr;
2624 
2625 		get_client_memptr(eth_client, clt_indx)->ipv4_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_set;
2626 		get_client_memptr(eth_client, clt_indx)->ipv6_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_set;
2627 		get_client_memptr(eth_client, clt_indx)->ipv4_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_header_set;
2628 		get_client_memptr(eth_client, clt_indx)->ipv6_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_header_set;
2629 
2630 		get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v4;
2631 		get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v6;
2632 
2633         for (num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->ipv6_set;num_v6++)
2634 	    {
2635 		    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];
2636 		    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];
2637 		    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];
2638 		    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];
2639         }
2640 
2641 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2642 		{
2643 			get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 =
2644 				 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4;
2645 
2646 			for(num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->route_rule_set_v6;num_v6++)
2647 			{
2648 			  get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6] =
2649 			   	 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6];
2650 			  get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6] =
2651 			   	 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6];
2652 		    }
2653 		}
2654 	}
2655 
2656 	IPACMDBG_H(" %d eth client deleted successfully \n", num_eth_client);
2657 	num_eth_client = num_eth_client - 1;
2658 	IPACMDBG_H(" Number of eth client: %d\n", num_eth_client);
2659 
2660 	/* Del RM dependency */
2661 	if(num_eth_client == 0)
2662 	{
2663 		/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule*/
2664 		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2665 		if (tx_prop != NULL)
2666 		{
2667 			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]);
2668 			IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
2669 		}
2670 	}
2671 
2672 	return IPACM_SUCCESS;
2673 }
2674 
2675 /*handle LAN iface down event*/
handle_down_evt()2676 int IPACM_Lan::handle_down_evt()
2677 {
2678 	uint32_t i;
2679 	int res = IPACM_SUCCESS;
2680 
2681 	IPACMDBG_H("lan handle_down_evt\n ");
2682 	if (ipa_if_cate == ODU_IF)
2683 	{
2684 		/* delete ODU default RT rules */
2685 		if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true)
2686 		{
2687 			IPACMDBG_H("eMBMS enable, delete eMBMS DL RT rule\n");
2688 			handle_odu_route_del();
2689 		}
2690 
2691 		/* delete full header */
2692 		if (ipv4_header_set)
2693 		{
2694 			if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v4)
2695 					== false)
2696 			{
2697 					IPACMERR("ODU ipv4 header delete fail\n");
2698 					res = IPACM_FAILURE;
2699 					goto fail;
2700 			}
2701 			IPACMDBG_H("ODU ipv4 header delete success\n");
2702 		}
2703 
2704 		if (ipv6_header_set)
2705 		{
2706 			if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v6)
2707 					== false)
2708 			{
2709 				IPACMERR("ODU ipv6 header delete fail\n");
2710 				res = IPACM_FAILURE;
2711 				goto fail;
2712 			}
2713 			IPACMERR("ODU ipv6 header delete success\n");
2714 		}
2715 	}
2716 
2717 	/* no iface address up, directly close iface*/
2718 	if (ip_type == IPACM_IP_NULL)
2719 	{
2720 		goto fail;
2721 	}
2722 
2723 	/* delete wan filter rule */
2724 	if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
2725 	{
2726 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
2727 		handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
2728 	}
2729 
2730 	if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
2731 	{
2732 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
2733 		handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode);
2734 	}
2735 
2736 	/* delete default filter rules */
2737 	if (ip_type != IPA_IP_v6 && rx_prop != NULL)
2738 	{
2739 		if(m_filtering.DeleteFilteringHdls(ipv4_icmp_flt_rule_hdl, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE) == false)
2740 		{
2741 			IPACMERR("Error Deleting ICMPv4 Filtering Rule, aborting...\n");
2742 			res = IPACM_FAILURE;
2743 			goto fail;
2744 		}
2745 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE);
2746 
2747 		if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false)
2748 		{
2749 			IPACMERR("Error Deleting Filtering Rule, aborting...\n");
2750 			res = IPACM_FAILURE;
2751 			goto fail;
2752 		}
2753 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
2754 
2755 		/* free private-subnet ipv4 filter rules */
2756 		if (IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_PRIV_SUBNET_FILTER_RULE_HANDLES)
2757 		{
2758 			IPACMERR(" the number of rules are bigger than array, aborting...\n");
2759 			res = IPACM_FAILURE;
2760 			goto fail;
2761 		}
2762 
2763 #ifdef FEATURE_IPA_ANDROID
2764 		if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES) == false)
2765 		{
2766 			IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
2767 			res = IPACM_FAILURE;
2768 			goto fail;
2769 		}
2770 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES);
2771 #else
2772 		if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false)
2773 		{
2774 			IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
2775 			res = IPACM_FAILURE;
2776 			goto fail;
2777 		}
2778 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
2779 #endif
2780 		IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n");
2781 	}
2782 	IPACMDBG_H("Finished delete default iface ipv4 filtering rules \n ");
2783 
2784 	if (ip_type != IPA_IP_v4 && rx_prop != NULL)
2785 	{
2786 		if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false)
2787 		{
2788 			IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n");
2789 			res = IPACM_FAILURE;
2790 			goto fail;
2791 		}
2792 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE);
2793 
2794 		if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false)
2795 		{
2796 			IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
2797 			res = IPACM_FAILURE;
2798 			goto fail;
2799 		}
2800 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
2801 	}
2802 	IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n ");
2803 
2804 	if (ip_type != IPA_IP_v6)
2805 	{
2806 		if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4)
2807 				== false)
2808 		{
2809 			IPACMERR("Routing rule deletion failed!\n");
2810 			res = IPACM_FAILURE;
2811 			goto fail;
2812 		}
2813 	}
2814 	IPACMDBG_H("Finished delete default iface ipv4 rules \n ");
2815 
2816 	/* delete default v6 routing rule */
2817 	if (ip_type != IPA_IP_v4)
2818 	{
2819 		/* may have multiple ipv6 iface-RT rules*/
2820 		for (i = 0; i < 2*num_dft_rt_v6; i++)
2821 		{
2822 			if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + i], IPA_IP_v6)
2823 					== false)
2824 			{
2825 				IPACMERR("Routing rule deletion failed!\n");
2826 				res = IPACM_FAILURE;
2827 				goto fail;
2828 			}
2829 		}
2830 	}
2831 
2832 	IPACMDBG_H("Finished delete default iface ipv6 rules \n ");
2833 
2834 	/* free the edm clients cache */
2835 	IPACMDBG_H("Free ecm clients cache\n");
2836 
2837 	/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule */
2838 	IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
2839 	if (tx_prop != NULL)
2840 	{
2841 		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]);
2842 		IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
2843 	}
2844 
2845 	eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL);
2846 
2847 /* Delete private subnet*/
2848 #ifdef FEATURE_IPA_ANDROID
2849 	if (ip_type != IPA_IP_v6)
2850 	{
2851 		IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
2852 		IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
2853 		if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
2854 		{
2855 			IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
2856 		}
2857 	}
2858 
2859 	/* reset the IPA-client pipe enum */
2860 	if(ipa_if_cate != WAN_IF)
2861 	{
2862 #ifdef FEATURE_IPACM_HAL
2863 		handle_tethering_client(true, IPACM_CLIENT_MAX);
2864 #else
2865 		handle_tethering_client(true, IPACM_CLIENT_USB);
2866 #endif
2867 	}
2868 #endif /* defined(FEATURE_IPA_ANDROID)*/
2869 fail:
2870 	/* clean eth-client header, routing rules */
2871 	IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
2872 	for (i = 0; i < num_eth_client; i++)
2873 	{
2874 		/* First reset nat rules and then route rules */
2875 		if(get_client_memptr(eth_client, i)->ipv4_set == true)
2876 		{
2877 			IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr);
2878 			CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr);
2879 		}
2880 
2881 		if (delete_eth_rtrules(i, IPA_IP_v4))
2882 		{
2883 			IPACMERR("unbale to delete ecm-client v4 route rules for index %d\n", i);
2884 			res = IPACM_FAILURE;
2885 		}
2886 
2887 		if (delete_eth_rtrules(i, IPA_IP_v6))
2888 		{
2889 			IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
2890 			res = IPACM_FAILURE;
2891 		}
2892 
2893 		IPACMDBG_H("Delete %d client header\n", num_eth_client);
2894 
2895 		if(get_client_memptr(eth_client, i)->ipv4_header_set == true)
2896 		{
2897 			if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v4)
2898 				== false)
2899 			{
2900 				res = IPACM_FAILURE;
2901 			}
2902 		}
2903 
2904 		if(get_client_memptr(eth_client, i)->ipv6_header_set == true)
2905 		{
2906 			if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v6)
2907 					== false)
2908 			{
2909 				res = IPACM_FAILURE;
2910 			}
2911 		}
2912 	} /* end of for loop */
2913 
2914 	/* check software routing fl rule hdl */
2915 	if (softwarerouting_act == true && rx_prop != NULL)
2916 	{
2917 		handle_software_routing_disable();
2918 	}
2919 
2920 	if (odu_route_rule_v4_hdl != NULL)
2921 	{
2922 		free(odu_route_rule_v4_hdl);
2923 	}
2924 	if (odu_route_rule_v6_hdl != NULL)
2925 	{
2926 		free(odu_route_rule_v6_hdl);
2927 	}
2928 	/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
2929 	if (rx_prop != NULL)
2930 	{
2931 		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2932 		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]);
2933 		IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
2934 		IPACMDBG_H("Finished delete dependency \n ");
2935 		free(rx_prop);
2936 	}
2937 
2938 	if (eth_client != NULL)
2939 	{
2940 		free(eth_client);
2941 	}
2942 
2943 	if (tx_prop != NULL)
2944 	{
2945 		free(tx_prop);
2946 	}
2947 	if (iface_query != NULL)
2948 	{
2949 		free(iface_query);
2950 	}
2951 
2952 	is_active = false;
2953 	post_del_self_evt();
2954 
2955 	return res;
2956 }
2957 
2958 /* install UL filter rule from Q6 */
handle_uplink_filter_rule(ipacm_ext_prop * prop,ipa_ip_type iptype,uint8_t xlat_mux_id)2959 int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptype, uint8_t xlat_mux_id)
2960 {
2961 	ipa_flt_rule_add flt_rule_entry;
2962 	int len = 0, cnt, ret = IPACM_SUCCESS;
2963 	ipa_ioc_add_flt_rule *pFilteringTable;
2964 	ipa_fltr_installed_notif_req_msg_v01 flt_index;
2965 	int fd;
2966 	int i, index, eq_index;
2967 	uint32_t value = 0;
2968 
2969 	IPACMDBG_H("Set modem UL flt rules\n");
2970 
2971 	if (rx_prop == NULL)
2972 	{
2973 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
2974 		return IPACM_SUCCESS;
2975 	}
2976 
2977 	if(prop == NULL || prop->num_ext_props <= 0)
2978 	{
2979 		IPACMDBG_H("No extended property.\n");
2980 		return IPACM_SUCCESS;
2981 	}
2982 
2983 	fd = open(IPA_DEVICE_NAME, O_RDWR);
2984 	if (0 == fd)
2985 	{
2986 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
2987 		return IPACM_FAILURE;
2988 	}
2989 	if (prop->num_ext_props > MAX_WAN_UL_FILTER_RULES)
2990 	{
2991 		IPACMERR("number of modem UL rules > MAX_WAN_UL_FILTER_RULES, aborting...\n");
2992 		close(fd);
2993 		return IPACM_FAILURE;
2994 	}
2995 
2996 	memset(&flt_index, 0, sizeof(flt_index));
2997 	flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe);
2998 	flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01;
2999 #ifndef FEATURE_IPA_V3
3000 	flt_index.filter_index_list_len = prop->num_ext_props;
3001 #else /* defined (FEATURE_IPA_V3) */
3002 	flt_index.rule_id_valid = 1;
3003 	flt_index.rule_id_len = prop->num_ext_props;
3004 #endif
3005 	flt_index.embedded_pipe_index_valid = 1;
3006 	flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD);
3007 	flt_index.retain_header_valid = 1;
3008 	flt_index.retain_header = 0;
3009 	flt_index.embedded_call_mux_id_valid = 1;
3010 	flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
3011 #ifndef FEATURE_IPA_V3
3012 	IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n",
3013 		flt_index.source_pipe_index, flt_index.filter_index_list_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id);
3014 #else /* defined (FEATURE_IPA_V3) */
3015 	IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n",
3016 		flt_index.source_pipe_index, flt_index.rule_id_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id);
3017 #endif
3018 	len = sizeof(struct ipa_ioc_add_flt_rule) + prop->num_ext_props * sizeof(struct ipa_flt_rule_add);
3019 	pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
3020 	if (pFilteringTable == NULL)
3021 	{
3022 		IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3023 		close(fd);
3024 		return IPACM_FAILURE;
3025 	}
3026 	memset(pFilteringTable, 0, len);
3027 
3028 	pFilteringTable->commit = 1;
3029 	pFilteringTable->ep = rx_prop->rx[0].src_pipe;
3030 	pFilteringTable->global = false;
3031 	pFilteringTable->ip = iptype;
3032 	pFilteringTable->num_rules = prop->num_ext_props;
3033 
3034 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields
3035 	flt_rule_entry.at_rear = 1;
3036 #ifdef FEATURE_IPA_V3
3037 	if (flt_rule_entry.rule.eq_attrib.ipv4_frag_eq_present)
3038 		flt_rule_entry.at_rear = 0;
3039 #endif
3040 	flt_rule_entry.flt_rule_hdl = -1;
3041 	flt_rule_entry.status = -1;
3042 
3043 	flt_rule_entry.rule.retain_hdr = 0;
3044 	flt_rule_entry.rule.to_uc = 0;
3045 	flt_rule_entry.rule.eq_attrib_type = 1;
3046 	if(iptype == IPA_IP_v4)
3047 	{
3048 		if (ipa_if_cate == ODU_IF && IPACM_Wan::isWan_Bridge_Mode())
3049 		{
3050 			IPACMDBG_H("WAN, ODU are in bridge mode \n");
3051 			flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3052 		}
3053 		else
3054 		{
3055 			flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
3056 		}
3057 	}
3058 	else if(iptype == IPA_IP_v6)
3059 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3060 	else
3061 	{
3062 		IPACMERR("IP type is not expected.\n");
3063 		ret = IPACM_FAILURE;
3064 		goto fail;
3065 	}
3066 
3067 	index = IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, iptype);
3068 
3069 	for(cnt=0; cnt<prop->num_ext_props; cnt++)
3070 	{
3071 		memcpy(&flt_rule_entry.rule.eq_attrib,
3072 					 &prop->prop[cnt].eq_attrib,
3073 					 sizeof(prop->prop[cnt].eq_attrib));
3074 		flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx;
3075 
3076 		/* Handle XLAT configuration */
3077 		if ((iptype == IPA_IP_v4) && prop->prop[cnt].is_xlat_rule && (xlat_mux_id != 0))
3078 		{
3079 			/* fill the value of meta-data */
3080 			value = xlat_mux_id;
3081 			flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
3082 			flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
3083 			flt_rule_entry.rule.eq_attrib.metadata_meq32.value = (value & 0xFF) << 16;
3084 			flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = 0x00FF0000;
3085 			IPACMDBG_H("xlat meta-data is modified for rule: %d has index %d with xlat_mux_id: %d\n",
3086 					cnt, index, xlat_mux_id);
3087 		}
3088 
3089 #ifdef FEATURE_IPACM_HAL
3090 		/* add prefix equation in modem UL rules */
3091 		if(iptype == IPA_IP_v4)
3092 		{
3093 			flt_rule_entry.rule.eq_attrib.num_offset_meq_32++;
3094 			if(flt_rule_entry.rule.eq_attrib.num_offset_meq_32 <= IPA_IPFLTR_NUM_MEQ_32_EQNS)
3095 			{
3096 				eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_32 - 1;
3097 #ifdef FEATURE_IPA_V3
3098 				if(eq_index == 0)
3099 				{
3100 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<5);
3101 				}
3102 				else
3103 				{
3104 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<6);
3105 				}
3106 #else
3107 				if(eq_index == 0)
3108 				{
3109 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<2);
3110 				}
3111 				else
3112 				{
3113 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3);
3114 				}
3115 #endif
3116 				flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].offset = 12;
3117 				flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].mask = prefix[IPA_IP_v4].v4Mask;
3118 				flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].value = prefix[IPA_IP_v4].v4Addr;
3119 			}
3120 			else
3121 			{
3122 				IPACMERR("Run out of MEQ32 equation.\n");
3123 				flt_rule_entry.rule.eq_attrib.num_offset_meq_32--;
3124 			}
3125 		}
3126 		else
3127 		{
3128 			flt_rule_entry.rule.eq_attrib.num_offset_meq_128++;
3129 			if(flt_rule_entry.rule.eq_attrib.num_offset_meq_128 <= IPA_IPFLTR_NUM_MEQ_128_EQNS)
3130 			{
3131 				eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_128 - 1;
3132 #ifdef FEATURE_IPA_V3
3133 				if(eq_index == 0)
3134 				{
3135 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3);
3136 				}
3137 				else
3138 				{
3139 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<4);
3140 				}
3141 #else
3142 				if(eq_index == 0)
3143 				{
3144 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9);
3145 				}
3146 				else
3147 				{
3148 					flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<10);
3149 				}
3150 #endif
3151 				flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].offset = 8;
3152 				*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 0)
3153 					= prefix[IPA_IP_v6].v6Mask[3];
3154 				*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 4)
3155 					= prefix[IPA_IP_v6].v6Mask[2];
3156 				*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 8)
3157 					= prefix[IPA_IP_v6].v6Mask[1];
3158 				*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 12)
3159 					= prefix[IPA_IP_v6].v6Mask[0];
3160 				*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 0)
3161 					= prefix[IPA_IP_v6].v6Addr[3];
3162 				*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 4)
3163 					= prefix[IPA_IP_v6].v6Addr[2];
3164 				*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 8)
3165 					= prefix[IPA_IP_v6].v6Addr[1];
3166 				*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 12)
3167 					= prefix[IPA_IP_v6].v6Addr[0];
3168 			}
3169 			else
3170 			{
3171 				IPACMERR("Run out of MEQ128 equation.\n");
3172 				flt_rule_entry.rule.eq_attrib.num_offset_meq_128--;
3173 			}
3174 		}
3175 #endif
3176 
3177 #ifdef FEATURE_IPA_V3
3178 		flt_rule_entry.rule.hashable = prop->prop[cnt].is_rule_hashable;
3179 		flt_rule_entry.rule.rule_id = prop->prop[cnt].rule_id;
3180 		if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA)	//turn on meta-data equation
3181 		{
3182 			flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9);
3183 			flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
3184 			flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
3185 			flt_rule_entry.rule.eq_attrib.metadata_meq32.value |= rx_prop->rx[0].attrib.meta_data;
3186 			flt_rule_entry.rule.eq_attrib.metadata_meq32.mask |= rx_prop->rx[0].attrib.meta_data_mask;
3187 		}
3188 #endif
3189 		memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry));
3190 
3191 		IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, index);
3192 #ifndef FEATURE_IPA_V3
3193 		flt_index.filter_index_list[cnt].filter_index = index;
3194 		flt_index.filter_index_list[cnt].filter_handle = prop->prop[cnt].filter_hdl;
3195 #else /* defined (FEATURE_IPA_V3) */
3196 		flt_index.rule_id[cnt] = prop->prop[cnt].rule_id;
3197 #endif
3198 		index++;
3199 	}
3200 
3201 	if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
3202 	{
3203 		IPACMERR("Error sending filtering rule index, aborting...\n");
3204 		ret = IPACM_FAILURE;
3205 		goto fail;
3206 	}
3207 
3208 	if(false == m_filtering.AddFilteringRule(pFilteringTable))
3209 	{
3210 		IPACMERR("Error Adding RuleTable to Filtering, aborting...\n");
3211 		ret = IPACM_FAILURE;
3212 		goto fail;
3213 	}
3214 	else
3215 	{
3216 		if(iptype == IPA_IP_v4)
3217 		{
3218 			for(i=0; i<pFilteringTable->num_rules; i++)
3219 			{
3220 				wan_ul_fl_rule_hdl_v4[num_wan_ul_fl_rule_v4] = pFilteringTable->rules[i].flt_rule_hdl;
3221 				num_wan_ul_fl_rule_v4++;
3222 			}
3223 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
3224 		}
3225 		else if(iptype == IPA_IP_v6)
3226 		{
3227 			for(i=0; i<pFilteringTable->num_rules; i++)
3228 			{
3229 				wan_ul_fl_rule_hdl_v6[num_wan_ul_fl_rule_v6] = pFilteringTable->rules[i].flt_rule_hdl;
3230 				num_wan_ul_fl_rule_v6++;
3231 			}
3232 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
3233 		}
3234 		else
3235 		{
3236 			IPACMERR("IP type is not expected.\n");
3237 			goto fail;
3238 		}
3239 	}
3240 
3241 fail:
3242 	free(pFilteringTable);
3243 	close(fd);
3244 	return ret;
3245 }
3246 
handle_wan_down_v6(bool is_sta_mode)3247 int IPACM_Lan::handle_wan_down_v6(bool is_sta_mode)
3248 {
3249 	ipa_fltr_installed_notif_req_msg_v01 flt_index;
3250 	int fd;
3251 
3252 	fd = open(IPA_DEVICE_NAME, O_RDWR);
3253 	if (0 == fd)
3254 	{
3255 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
3256 		return IPACM_FAILURE;
3257 	}
3258 
3259 	delete_ipv6_prefix_flt_rule();
3260 
3261 	memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
3262 
3263 	if(is_sta_mode == false && modem_ul_v6_set == true)
3264 	{
3265 		if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES)
3266 		{
3267 			IPACMERR(" the number of rules (%d) are bigger than array (%d), aborting...\n", num_wan_ul_fl_rule_v6, MAX_WAN_UL_FILTER_RULES);
3268 			close(fd);
3269 			return IPACM_FAILURE;
3270 		}
3271 		if (num_wan_ul_fl_rule_v6 == 0)
3272 		{
3273 			IPACMERR("No modem UL rules were installed, return...\n");
3274 			close(fd);
3275 			return IPACM_FAILURE;
3276 		}
3277 
3278 		if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v6,
3279 			IPA_IP_v6, num_wan_ul_fl_rule_v6) == false)
3280 		{
3281 			IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n");
3282 			close(fd);
3283 			return IPACM_FAILURE;
3284 		}
3285 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_wan_ul_fl_rule_v6);
3286 		memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
3287 		num_wan_ul_fl_rule_v6 = 0;
3288 		modem_ul_v6_set = false;
3289 
3290 		memset(&flt_index, 0, sizeof(flt_index));
3291 		flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe);
3292 		flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01;
3293 #ifndef FEATURE_IPA_V3
3294 		flt_index.filter_index_list_len = 0;
3295 #else /* defined (FEATURE_IPA_V3) */
3296 		flt_index.rule_id_valid = 1;
3297 		flt_index.rule_id_len = 0;
3298 #endif
3299 		flt_index.embedded_pipe_index_valid = 1;
3300 		flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD);
3301 		flt_index.retain_header_valid = 1;
3302 		flt_index.retain_header = 0;
3303 		flt_index.embedded_call_mux_id_valid = 1;
3304 		flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
3305 		if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
3306 		{
3307 			IPACMERR("Error sending filtering rule index, aborting...\n");
3308 			close(fd);
3309 			return IPACM_FAILURE;
3310 		}
3311 	}
3312 	else
3313 	{
3314 		if (m_filtering.DeleteFilteringHdls(&dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES],
3315 																				IPA_IP_v6, 1) == false)
3316 		{
3317 			IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
3318 			close(fd);
3319 			return IPACM_FAILURE;
3320 		}
3321 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3322 	}
3323 	close(fd);
3324 	return IPACM_SUCCESS;
3325 }
3326 
reset_to_dummy_flt_rule(ipa_ip_type iptype,uint32_t rule_hdl)3327 int IPACM_Lan::reset_to_dummy_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl)
3328 {
3329 	int len, res = IPACM_SUCCESS;
3330 	struct ipa_flt_rule_mdfy flt_rule;
3331 	struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
3332 
3333 	IPACMDBG_H("Reset flt rule to dummy, IP type: %d, hdl: %d\n", iptype, rule_hdl);
3334 	len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy);
3335 	pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
3336 
3337 	if (pFilteringTable == NULL)
3338 	{
3339 		IPACMERR("Error allocate flt rule memory...\n");
3340 		return IPACM_FAILURE;
3341 	}
3342 	memset(pFilteringTable, 0, len);
3343 
3344 	pFilteringTable->commit = 1;
3345 	pFilteringTable->ip = iptype;
3346 	pFilteringTable->num_rules = 1;
3347 
3348 	memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
3349 	flt_rule.status = -1;
3350 	flt_rule.rule_hdl = rule_hdl;
3351 
3352 	flt_rule.rule.retain_hdr = 0;
3353 	flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
3354 
3355 	if(iptype == IPA_IP_v4)
3356 	{
3357 		IPACMDBG_H("Reset IPv4 flt rule to dummy\n");
3358 
3359 		flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
3360 		flt_rule.rule.attrib.u.v4.dst_addr = ~0;
3361 		flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0;
3362 		flt_rule.rule.attrib.u.v4.src_addr = ~0;
3363 		flt_rule.rule.attrib.u.v4.src_addr_mask = ~0;
3364 
3365 		memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
3366 		if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
3367 		{
3368 			IPACMERR("Error modifying filtering rule.\n");
3369 			res = IPACM_FAILURE;
3370 			goto fail;
3371 		}
3372 		else
3373 		{
3374 			IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl,
3375 						pFilteringTable->rules[0].status);
3376 		}
3377 	}
3378 	else if(iptype == IPA_IP_v6)
3379 	{
3380 		IPACMDBG_H("Reset IPv6 flt rule to dummy\n");
3381 
3382 		flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
3383 		flt_rule.rule.attrib.u.v6.src_addr[0] = ~0;
3384 		flt_rule.rule.attrib.u.v6.src_addr[1] = ~0;
3385 		flt_rule.rule.attrib.u.v6.src_addr[2] = ~0;
3386 		flt_rule.rule.attrib.u.v6.src_addr[3] = ~0;
3387 		flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0;
3388 		flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0;
3389 		flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0;
3390 		flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0;
3391 		flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0;
3392 		flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0;
3393 		flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0;
3394 		flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0;
3395 		flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0;
3396 		flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0;
3397 		flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0;
3398 		flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0;
3399 
3400 
3401 		memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
3402 		if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
3403 		{
3404 			IPACMERR("Error modifying filtering rule.\n");
3405 			res = IPACM_FAILURE;
3406 			goto fail;
3407 		}
3408 		else
3409 		{
3410 			IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl,
3411 						pFilteringTable->rules[0].status);
3412 		}
3413 	}
3414 	else
3415 	{
3416 		IPACMERR("IP type is not expected.\n");
3417 		res = IPACM_FAILURE;
3418 		goto fail;
3419 	}
3420 
3421 fail:
3422 	free(pFilteringTable);
3423 	return res;
3424 }
3425 
post_del_self_evt()3426 void IPACM_Lan::post_del_self_evt()
3427 {
3428 	ipacm_cmd_q_data evt;
3429 	ipacm_event_data_fid* fid;
3430 	fid = (ipacm_event_data_fid*)malloc(sizeof(ipacm_event_data_fid));
3431 	if(fid == NULL)
3432 	{
3433 		IPACMERR("Failed to allocate fid memory.\n");
3434 		return;
3435 	}
3436 	memset(fid, 0, sizeof(ipacm_event_data_fid));
3437 	memset(&evt, 0, sizeof(ipacm_cmd_q_data));
3438 
3439 	fid->if_index = ipa_if_num;
3440 
3441 	evt.evt_data = (void*)fid;
3442 	evt.event = IPA_LAN_DELETE_SELF;
3443 
3444 	IPACMDBG_H("Posting event IPA_LAN_DELETE_SELF\n");
3445 	IPACM_EvtDispatcher::PostEvt(&evt);
3446 }
3447 
3448 /*handle reset usb-client rt-rules */
handle_lan_client_reset_rt(ipa_ip_type iptype)3449 int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype)
3450 {
3451 	uint32_t i;
3452 	int res = IPACM_SUCCESS;
3453 
3454 	/* clean eth-client routing rules */
3455 	IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
3456 	for (i = 0; i < num_eth_client; i++)
3457 	{
3458 		res = delete_eth_rtrules(i, iptype);
3459 		if (res != IPACM_SUCCESS)
3460 		{
3461 			IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype);
3462 			return res;
3463 		}
3464 	} /* end of for loop */
3465 
3466 	/* Reset ip-address */
3467 	for (i = 0; i < num_eth_client; i++)
3468 	{
3469 		if(iptype == IPA_IP_v4)
3470 		{
3471 			get_client_memptr(eth_client, i)->ipv4_set = false;
3472 		}
3473 		else
3474 		{
3475 			get_client_memptr(eth_client, i)->ipv6_set = 0;
3476 		}
3477 	} /* end of for loop */
3478 	return res;
3479 }
3480 
install_ipv4_icmp_flt_rule()3481 int IPACM_Lan::install_ipv4_icmp_flt_rule()
3482 {
3483 	int len;
3484 	struct ipa_ioc_add_flt_rule* flt_rule;
3485 	struct ipa_flt_rule_add flt_rule_entry;
3486 
3487 	if(rx_prop != NULL)
3488 	{
3489 		len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
3490 
3491 		flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
3492 		if (!flt_rule)
3493 		{
3494 			IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3495 			return IPACM_FAILURE;
3496 		}
3497 
3498 		flt_rule->commit = 1;
3499 		flt_rule->ep = rx_prop->rx[0].src_pipe;
3500 		flt_rule->global = false;
3501 		flt_rule->ip = IPA_IP_v4;
3502 		flt_rule->num_rules = 1;
3503 
3504 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3505 
3506 		flt_rule_entry.rule.retain_hdr = 1;
3507 		flt_rule_entry.rule.to_uc = 0;
3508 		flt_rule_entry.rule.eq_attrib_type = 0;
3509 		flt_rule_entry.at_rear = true;
3510 		flt_rule_entry.flt_rule_hdl = -1;
3511 		flt_rule_entry.status = -1;
3512 		flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3513 #ifdef FEATURE_IPA_V3
3514 		flt_rule_entry.rule.hashable = true;
3515 #endif
3516 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
3517 
3518 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
3519 		flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP;
3520 		memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3521 
3522 		if (m_filtering.AddFilteringRule(flt_rule) == false)
3523 		{
3524 			IPACMERR("Error Adding Filtering rule, aborting...\n");
3525 			free(flt_rule);
3526 			return IPACM_FAILURE;
3527 		}
3528 		else
3529 		{
3530 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
3531 			ipv4_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
3532 			IPACMDBG_H("IPv4 icmp filter rule HDL:0x%x\n", ipv4_icmp_flt_rule_hdl[0]);
3533                         free(flt_rule);
3534 		}
3535 	}
3536 	return IPACM_SUCCESS;
3537 }
3538 
install_ipv6_icmp_flt_rule()3539 int IPACM_Lan::install_ipv6_icmp_flt_rule()
3540 {
3541 
3542 	int len;
3543 	struct ipa_ioc_add_flt_rule* flt_rule;
3544 	struct ipa_flt_rule_add flt_rule_entry;
3545 
3546 	if(rx_prop != NULL)
3547 	{
3548 		len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
3549 
3550 		flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
3551 		if (!flt_rule)
3552 		{
3553 			IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3554 			return IPACM_FAILURE;
3555 		}
3556 
3557 		flt_rule->commit = 1;
3558 		flt_rule->ep = rx_prop->rx[0].src_pipe;
3559 		flt_rule->global = false;
3560 		flt_rule->ip = IPA_IP_v6;
3561 		flt_rule->num_rules = 1;
3562 
3563 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3564 
3565 		flt_rule_entry.rule.retain_hdr = 1;
3566 		flt_rule_entry.rule.to_uc = 0;
3567 		flt_rule_entry.rule.eq_attrib_type = 0;
3568 		flt_rule_entry.at_rear = true;
3569 		flt_rule_entry.flt_rule_hdl = -1;
3570 		flt_rule_entry.status = -1;
3571 		flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3572 #ifdef FEATURE_IPA_V3
3573 		flt_rule_entry.rule.hashable = false;
3574 #endif
3575 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
3576 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
3577 		flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
3578 		memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3579 
3580 		if (m_filtering.AddFilteringRule(flt_rule) == false)
3581 		{
3582 			IPACMERR("Error Adding Filtering rule, aborting...\n");
3583 			free(flt_rule);
3584 			return IPACM_FAILURE;
3585 		}
3586 		else
3587 		{
3588 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3589 			ipv6_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
3590 			IPACMDBG_H("IPv6 icmp filter rule HDL:0x%x\n", ipv6_icmp_flt_rule_hdl[0]);
3591 			free(flt_rule);
3592 		}
3593 	}
3594 	return IPACM_SUCCESS;
3595 }
3596 
add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)3597 int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
3598 {
3599 	if(rx_prop == NULL)
3600 	{
3601 		IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy private subnet filtering rule.\n", dev_name);
3602 		return 0;
3603 	}
3604 
3605 	if(iptype == IPA_IP_v6)
3606 	{
3607 		IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name);
3608 		return 0;
3609 	}
3610 	int i, len, res = IPACM_SUCCESS;
3611 	struct ipa_flt_rule_add flt_rule;
3612 	ipa_ioc_add_flt_rule* pFilteringTable;
3613 
3614 	len = sizeof(struct ipa_ioc_add_flt_rule) +	IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(struct ipa_flt_rule_add);
3615 
3616 	pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
3617 	if (pFilteringTable == NULL)
3618 	{
3619 		IPACMERR("Error allocate flt table memory...\n");
3620 		return IPACM_FAILURE;
3621 	}
3622 	memset(pFilteringTable, 0, len);
3623 
3624 	pFilteringTable->commit = 1;
3625 	pFilteringTable->ep = rx_prop->rx[0].src_pipe;
3626 	pFilteringTable->global = false;
3627 	pFilteringTable->ip = iptype;
3628 	pFilteringTable->num_rules = IPA_MAX_PRIVATE_SUBNET_ENTRIES;
3629 
3630 	memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add));
3631 
3632 	flt_rule.rule.retain_hdr = 0;
3633 	flt_rule.at_rear = true;
3634 	flt_rule.flt_rule_hdl = -1;
3635 	flt_rule.status = -1;
3636 	flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
3637 #ifdef FEATURE_IPA_V3
3638 	flt_rule.rule.hashable = true;
3639 #endif
3640 	memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib,
3641 			sizeof(flt_rule.rule.attrib));
3642 
3643 	if(iptype == IPA_IP_v4)
3644 	{
3645 		flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
3646 		flt_rule.rule.attrib.u.v4.src_addr_mask = ~0;
3647 		flt_rule.rule.attrib.u.v4.src_addr = ~0;
3648 		flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0;
3649 		flt_rule.rule.attrib.u.v4.dst_addr = ~0;
3650 
3651 		for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
3652 		{
3653 			memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add));
3654 		}
3655 
3656 		if (false == m_filtering.AddFilteringRule(pFilteringTable))
3657 		{
3658 			IPACMERR("Error adding dummy private subnet v4 flt rule\n");
3659 			res = IPACM_FAILURE;
3660 			goto fail;
3661 		}
3662 		else
3663 		{
3664 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES);
3665 			/* copy filter rule hdls */
3666 			for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
3667 			{
3668 				if (pFilteringTable->rules[i].status == 0)
3669 				{
3670 					private_fl_rule_hdl[i] = pFilteringTable->rules[i].flt_rule_hdl;
3671 					IPACMDBG_H("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]);
3672 				}
3673 				else
3674 				{
3675 					IPACMERR("Failed adding lan2lan v4 flt rule %d\n", i);
3676 					res = IPACM_FAILURE;
3677 					goto fail;
3678 				}
3679 			}
3680 		}
3681 	}
3682 fail:
3683 	free(pFilteringTable);
3684 	return res;
3685 }
3686 
handle_private_subnet_android(ipa_ip_type iptype)3687 int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype)
3688 {
3689 	int i, len, res = IPACM_SUCCESS;
3690 	struct ipa_flt_rule_mdfy flt_rule;
3691 	struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
3692 
3693 	if (rx_prop == NULL)
3694 	{
3695 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
3696 		return IPACM_SUCCESS;
3697 	}
3698 
3699 	if(iptype == IPA_IP_v6)
3700 	{
3701 		IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name);
3702 		return 0;
3703 	}
3704 	else
3705 	{
3706 		for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
3707 		{
3708 			reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]);
3709 		}
3710 
3711 		len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy);
3712 		pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
3713 		if (!pFilteringTable)
3714 		{
3715 			IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n");
3716 			return IPACM_FAILURE;
3717 		}
3718 		memset(pFilteringTable, 0, len);
3719 
3720 		pFilteringTable->commit = 1;
3721 		pFilteringTable->ip = iptype;
3722 		pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
3723 
3724 		/* Make LAN-traffic always go A5, use default IPA-RT table */
3725 		if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4))
3726 		{
3727 			IPACMERR("Failed to get routing table handle.\n");
3728 			res = IPACM_FAILURE;
3729 			goto fail;
3730 		}
3731 
3732 		memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
3733 		flt_rule.status = -1;
3734 
3735 		flt_rule.rule.retain_hdr = 1;
3736 		flt_rule.rule.to_uc = 0;
3737 		flt_rule.rule.action = IPA_PASS_TO_ROUTING;
3738 		flt_rule.rule.eq_attrib_type = 0;
3739 		flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl;
3740 		IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name);
3741 
3742 		memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
3743 		flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3744 
3745 		for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
3746 		{
3747 			flt_rule.rule_hdl = private_fl_rule_hdl[i];
3748 			flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
3749 			flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
3750 			memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
3751 			IPACMDBG_H(" IPACM private subnet_addr as: 0x%x entry(%d)\n", flt_rule.rule.attrib.u.v4.dst_addr, i);
3752 		}
3753 
3754 		if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
3755 		{
3756 			IPACMERR("Failed to modify private subnet filtering rules.\n");
3757 			res = IPACM_FAILURE;
3758 			goto fail;
3759 		}
3760 	}
3761 fail:
3762 	if(pFilteringTable != NULL)
3763 	{
3764 		free(pFilteringTable);
3765 	}
3766 	return res;
3767 }
3768 
install_ipv6_prefix_flt_rule(uint32_t * prefix)3769 int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
3770 {
3771 	if(prefix == NULL)
3772 	{
3773 		IPACMERR("IPv6 prefix is empty.\n");
3774 		return IPACM_FAILURE;
3775 	}
3776 	IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]);
3777 
3778 	int len;
3779 	struct ipa_ioc_add_flt_rule* flt_rule;
3780 	struct ipa_flt_rule_add flt_rule_entry;
3781 
3782 	if(rx_prop != NULL)
3783 	{
3784 		len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
3785 
3786 		flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
3787 		if (!flt_rule)
3788 		{
3789 			IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3790 			return IPACM_FAILURE;
3791 		}
3792 
3793 		flt_rule->commit = 1;
3794 		flt_rule->ep = rx_prop->rx[0].src_pipe;
3795 		flt_rule->global = false;
3796 		flt_rule->ip = IPA_IP_v6;
3797 		flt_rule->num_rules = 1;
3798 
3799 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3800 
3801 		flt_rule_entry.rule.retain_hdr = 1;
3802 		flt_rule_entry.rule.to_uc = 0;
3803 		flt_rule_entry.rule.eq_attrib_type = 0;
3804 		flt_rule_entry.at_rear = true;
3805 		flt_rule_entry.flt_rule_hdl = -1;
3806 		flt_rule_entry.status = -1;
3807 		flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3808 #ifdef FEATURE_IPA_V3
3809 		flt_rule_entry.rule.hashable = true;
3810 #endif
3811 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
3812 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3813 		flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0];
3814 		flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1];
3815 		flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x0;
3816 		flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x0;
3817 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
3818 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
3819 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x0;
3820 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0;
3821 		memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3822 
3823 		if (m_filtering.AddFilteringRule(flt_rule) == false)
3824 		{
3825 			IPACMERR("Error Adding Filtering rule, aborting...\n");
3826 			free(flt_rule);
3827 			return IPACM_FAILURE;
3828 		}
3829 		else
3830 		{
3831 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3832 			ipv6_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
3833 			IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]);
3834 			free(flt_rule);
3835 		}
3836 	}
3837 	return IPACM_SUCCESS;
3838 }
3839 
delete_ipv6_prefix_flt_rule()3840 void IPACM_Lan::delete_ipv6_prefix_flt_rule()
3841 {
3842 	if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE) == false)
3843 	{
3844 		IPACMERR("Failed to delete ipv6 prefix flt rule.\n");
3845 		return;
3846 	}
3847 	IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE);
3848 	return;
3849 }
3850 
handle_addr_evt_odu_bridge(ipacm_event_data_addr * data)3851 int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data)
3852 {
3853 	int fd, res = IPACM_SUCCESS;
3854 	struct in6_addr ipv6_addr;
3855 	if(data == NULL)
3856 	{
3857 		IPACMERR("Failed to get interface IP address.\n");
3858 		return IPACM_FAILURE;
3859 	}
3860 
3861 	if(data->iptype == IPA_IP_v6)
3862 	{
3863 		fd = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR);
3864 		if(fd == 0)
3865 		{
3866 			IPACMERR("Failed to open %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU);
3867 			return IPACM_FAILURE;
3868 		}
3869 
3870 		memcpy(&ipv6_addr, data->ipv6_addr, sizeof(struct in6_addr));
3871 
3872 		if( ioctl(fd, ODU_BRIDGE_IOC_SET_LLV6_ADDR, &ipv6_addr) )
3873 		{
3874 			IPACMERR("Failed to write IPv6 address to odu driver.\n");
3875 			res = IPACM_FAILURE;
3876 		}
3877 		num_dft_rt_v6++;
3878 		close(fd);
3879 	}
3880 
3881 	return res;
3882 }
3883 
eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1,ipa_hdr_l2_type t2)3884 ipa_hdr_proc_type IPACM_Lan::eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2)
3885 {
3886 	if(t1 == IPA_HDR_L2_ETHERNET_II)
3887 	{
3888 		if(t2 == IPA_HDR_L2_ETHERNET_II)
3889 		{
3890 			return IPA_HDR_PROC_ETHII_TO_ETHII;
3891 		}
3892 		if(t2 == IPA_HDR_L2_802_3)
3893 		{
3894 			return IPA_HDR_PROC_ETHII_TO_802_3;
3895 		}
3896 	}
3897 
3898 	if(t1 == IPA_HDR_L2_802_3)
3899 	{
3900 		if(t2 == IPA_HDR_L2_ETHERNET_II)
3901 		{
3902 			return IPA_HDR_PROC_802_3_TO_ETHII;
3903 		}
3904 		if(t2 == IPA_HDR_L2_802_3)
3905 		{
3906 			return IPA_HDR_PROC_802_3_TO_802_3;
3907 		}
3908 	}
3909 
3910 	return IPA_HDR_PROC_NONE;
3911 }
3912 
eth_bridge_get_hdr_template_hdl(uint32_t * hdr_hdl)3913 int IPACM_Lan::eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl)
3914 {
3915 	if(hdr_hdl == NULL)
3916 	{
3917 		IPACMDBG_H("Hdr handle pointer is empty.\n");
3918 		return IPACM_FAILURE;
3919 	}
3920 
3921 	struct ipa_ioc_get_hdr hdr;
3922 	memset(&hdr, 0, sizeof(hdr));
3923 
3924 	memcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
3925 	if(m_header.GetHeaderHandle(&hdr) == false)
3926 	{
3927 		IPACMERR("Failed to get template hdr hdl.\n");
3928 		return IPACM_FAILURE;
3929 	}
3930 
3931 	*hdr_hdl = hdr.hdl;
3932 	return IPACM_SUCCESS;
3933 }
3934 
handle_cradle_wan_mode_switch(bool is_wan_bridge_mode)3935 int IPACM_Lan::handle_cradle_wan_mode_switch(bool is_wan_bridge_mode)
3936 {
3937 	struct ipa_flt_rule_mdfy flt_rule_entry;
3938 	int len = 0;
3939 	ipa_ioc_mdfy_flt_rule *m_pFilteringTable;
3940 
3941 	IPACMDBG_H("Handle wan mode swtich: is wan bridge mode?%d\n", is_wan_bridge_mode);
3942 
3943 	if (rx_prop == NULL)
3944 	{
3945 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
3946 		return IPACM_SUCCESS;
3947 	}
3948 
3949 	len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (1 * sizeof(struct ipa_flt_rule_mdfy));
3950 	m_pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len);
3951 	if (m_pFilteringTable == NULL)
3952 	{
3953 		PERROR("Error Locate ipa_ioc_mdfy_flt_rule memory...\n");
3954 		return IPACM_FAILURE;
3955 	}
3956 
3957 	m_pFilteringTable->commit = 1;
3958 	m_pFilteringTable->ip = IPA_IP_v4;
3959 	m_pFilteringTable->num_rules = (uint8_t)1;
3960 
3961 	IPACMDBG_H("Retrieving routing hanle for table: %s\n",
3962 					 IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name);
3963 	if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4))
3964 	{
3965 		IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n",
3966 						 &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4);
3967 		free(m_pFilteringTable);
3968 		return IPACM_FAILURE;
3969 	}
3970 	IPACMDBG_H("Routing handle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl);
3971 
3972 
3973 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_mdfy)); // Zero All Fields
3974 	flt_rule_entry.status = -1;
3975 	flt_rule_entry.rule_hdl = lan_wan_fl_rule_hdl[0];
3976 
3977 	flt_rule_entry.rule.retain_hdr = 0;
3978 	flt_rule_entry.rule.to_uc = 0;
3979 	flt_rule_entry.rule.eq_attrib_type = 0;
3980 	if(is_wan_bridge_mode)
3981 	{
3982 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3983 	}
3984 	else
3985 	{
3986 		flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
3987 	}
3988 	flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl;
3989 
3990 	memcpy(&flt_rule_entry.rule.attrib,
3991 				 &rx_prop->rx[0].attrib,
3992 				 sizeof(flt_rule_entry.rule.attrib));
3993 
3994 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3995 	flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0;
3996 	flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0;
3997 
3998 	memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry));
3999 	if (false == m_filtering.ModifyFilteringRule(m_pFilteringTable))
4000 	{
4001 		IPACMERR("Error Modifying RuleTable(0) to Filtering, aborting...\n");
4002 		free(m_pFilteringTable);
4003 		return IPACM_FAILURE;
4004 	}
4005 	else
4006 	{
4007 		IPACMDBG_H("flt rule hdl = %d, status = %d\n",
4008 						 m_pFilteringTable->rules[0].rule_hdl,
4009 						 m_pFilteringTable->rules[0].status);
4010 	}
4011 	free(m_pFilteringTable);
4012 	return IPACM_SUCCESS;
4013 }
4014 
4015 /*handle reset usb-client rt-rules */
handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 * data)4016 int IPACM_Lan::handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 *data)
4017 {
4018 	int fd;
4019 	uint32_t pipe_len, cnt;
4020 	uint64_t num_ul_packets, num_ul_bytes;
4021 	uint64_t num_dl_packets, num_dl_bytes;
4022 	bool ul_pipe_found, dl_pipe_found;
4023 	FILE *fp = NULL;
4024 
4025 	fd = open(IPA_DEVICE_NAME, O_RDWR);
4026 	if (fd < 0)
4027 	{
4028 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
4029 		return IPACM_FAILURE;
4030 	}
4031 
4032 
4033 	ul_pipe_found = false;
4034 	dl_pipe_found = false;
4035 	num_ul_packets = 0;
4036 	num_dl_packets = 0;
4037 	num_ul_bytes = 0;
4038 	num_dl_bytes = 0;
4039 
4040 	if (data->dl_dst_pipe_stats_list_valid)
4041 	{
4042 		if(tx_prop != NULL)
4043 		{
4044 			for (pipe_len = 0; pipe_len < data->dl_dst_pipe_stats_list_len; pipe_len++)
4045 			{
4046 				IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->dl_dst_pipe_stats_list[pipe_len].pipe_index);
4047 				for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
4048 				{
4049 					IPACMDBG_H("Check Tx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe));
4050 					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)
4051 					{
4052 						/* update the DL stats */
4053 						dl_pipe_found = true;
4054 						num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_packets;
4055 						num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_packets;
4056 						num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_bytes;
4057 						num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_bytes;
4058 						IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->dl_dst_pipe_stats_list[pipe_len].pipe_index, cnt);
4059 						IPACMDBG_H("DL_packets:(%lu) DL_bytes:(%lu) \n", num_dl_packets, num_dl_bytes);
4060 						break;
4061 					}
4062 				}
4063 			}
4064 		}
4065 	}
4066 
4067 	if (data->ul_src_pipe_stats_list_valid)
4068 	{
4069 		if(rx_prop != NULL)
4070 		{
4071 			for (pipe_len = 0; pipe_len < data->ul_src_pipe_stats_list_len; pipe_len++)
4072 			{
4073 				IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->ul_src_pipe_stats_list[pipe_len].pipe_index);
4074 				for (cnt=0; cnt < rx_prop->num_rx_props; cnt++)
4075 				{
4076 					IPACMDBG_H("Check Rx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe));
4077 					//Typecasting to avoid -Wall -Werror errors
4078 					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)
4079 					{
4080 						/* update the UL stats */
4081 						ul_pipe_found = true;
4082 						num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_packets;
4083 						num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_packets;
4084 						num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_bytes;
4085 						num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_bytes;
4086 						IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->ul_src_pipe_stats_list[pipe_len].pipe_index, cnt);
4087 						IPACMDBG_H("UL_packets:(%lu) UL_bytes:(%lu) \n", num_ul_packets, num_ul_bytes);
4088 						break;
4089 					}
4090 				}
4091 			}
4092 		}
4093 	}
4094 	close(fd);
4095 
4096 	if (ul_pipe_found || dl_pipe_found)
4097 	{
4098 		IPACMDBG_H("Update IPA_TETHERING_STATS_UPDATE_EVENT, TX(P%lu/B%lu) RX(P%lu/B%lu) DEV(%s) to LTE(%s) \n",
4099 					num_ul_packets,
4100 						num_ul_bytes,
4101 							num_dl_packets,
4102 								num_dl_bytes,
4103 									dev_name,
4104 										IPACM_Wan::wan_up_dev_name);
4105 		fp = fopen(IPA_PIPE_STATS_FILE_NAME, "w");
4106 		if ( fp == NULL )
4107 		{
4108 			IPACMERR("Failed to write pipe stats to %s, error is %d - %s\n",
4109 					IPA_PIPE_STATS_FILE_NAME, errno, strerror(errno));
4110 			return IPACM_FAILURE;
4111 		}
4112 
4113 		fprintf(fp, PIPE_STATS,
4114 				dev_name,
4115 					IPACM_Wan::wan_up_dev_name,
4116 						num_ul_bytes,
4117 						num_ul_packets,
4118 							    num_dl_bytes,
4119 							num_dl_packets);
4120 		fclose(fp);
4121 	}
4122 	return IPACM_SUCCESS;
4123 }
4124 
4125 /*handle tether client */
handle_tethering_client(bool reset,ipacm_client_enum ipa_client)4126 int IPACM_Lan::handle_tethering_client(bool reset, ipacm_client_enum ipa_client)
4127 {
4128 	int fd, ret = IPACM_SUCCESS;
4129 	uint32_t cnt;
4130 	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
4131 	wan_ioctl_set_tether_client_pipe tether_client;
4132 
4133 	if(fd_wwan_ioctl < 0)
4134 	{
4135 		IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
4136 		return IPACM_FAILURE;
4137 	}
4138 
4139 	fd = open(IPA_DEVICE_NAME, O_RDWR);
4140 	if (fd < 0)
4141 	{
4142 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
4143 		close(fd_wwan_ioctl);
4144 		return IPACM_FAILURE;
4145 	}
4146 
4147 	memset(&tether_client, 0, sizeof(tether_client));
4148 	tether_client.reset_client = reset;
4149 	tether_client.ipa_client = ipa_client;
4150 
4151 	if(tx_prop != NULL)
4152 	{
4153 		tether_client.dl_dst_pipe_len = tx_prop->num_tx_props;
4154 		for (cnt = 0; cnt < tx_prop->num_tx_props; cnt++)
4155 		{
4156 			IPACMDBG_H("Tx(%d), dst_pipe: %d, ipa_pipe: %d\n",
4157 					cnt, tx_prop->tx[cnt].dst_pipe,
4158 						ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe));
4159 			tether_client.dl_dst_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe);
4160 		}
4161 	}
4162 
4163 	if(rx_prop != NULL)
4164 	{
4165 		tether_client.ul_src_pipe_len = rx_prop->num_rx_props;
4166 		for (cnt = 0; cnt < rx_prop->num_rx_props; cnt++)
4167 		{
4168 			IPACMDBG_H("Rx(%d), src_pipe: %d, ipa_pipe: %d\n",
4169 					cnt, rx_prop->rx[cnt].src_pipe,
4170 						ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe));
4171 			tether_client.ul_src_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe);
4172 		}
4173 	}
4174 
4175 	ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, &tether_client);
4176 	if (ret != 0)
4177 	{
4178 		IPACMERR("Failed set tether-client-pipe %p with ret %d\n ", &tether_client, ret);
4179 	}
4180 	IPACMDBG("Set tether-client-pipe %p\n", &tether_client);
4181 	close(fd);
4182 	close(fd_wwan_ioctl);
4183 	return ret;
4184 }
4185 
4186 /* 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)4187 void IPACM_Lan::eth_bridge_post_event(ipa_cm_event_id evt, ipa_ip_type iptype, uint8_t *mac)
4188 {
4189 	ipacm_cmd_q_data eth_bridge_evt;
4190 	ipacm_event_eth_bridge *evt_data;
4191 
4192 	evt_data = (ipacm_event_eth_bridge*)malloc(sizeof(ipacm_event_eth_bridge));
4193 	if(evt_data == NULL)
4194 	{
4195 		IPACMERR("Failed to allocate memory.\n");
4196 		return;
4197 	}
4198 	memset(evt_data, 0, sizeof(ipacm_event_eth_bridge));
4199 
4200 	evt_data->p_iface = this;
4201 	evt_data->iptype = iptype;
4202 	if(mac)
4203 	{
4204 		IPACMDBG_H("Client mac: 0x%02x%02x%02x%02x%02x%02x \n",
4205 			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4206 		memcpy(evt_data->mac_addr, mac, sizeof(evt_data->mac_addr));
4207 	}
4208 
4209 	memset(&eth_bridge_evt, 0, sizeof(ipacm_cmd_q_data));
4210 	eth_bridge_evt.evt_data = (void*)evt_data;
4211 	eth_bridge_evt.event = evt;
4212 
4213 	IPACMDBG_H("Posting event %s\n",
4214 		IPACM_Iface::ipacmcfg->getEventName(evt));
4215 	IPACM_EvtDispatcher::PostEvt(&eth_bridge_evt);
4216 }
4217 
4218 /* 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)4219 int IPACM_Lan::eth_bridge_add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_hdr_type, uint32_t *hdl)
4220 {
4221 	int len, res = IPACM_SUCCESS;
4222 	uint32_t hdr_template;
4223 	ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL;
4224 
4225 	if(tx_prop == NULL)
4226 	{
4227 		IPACMERR("No tx prop.\n");
4228 		return IPACM_FAILURE;
4229 	}
4230 
4231 	len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add);
4232 	pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len);
4233 	if(pHeaderProcTable == NULL)
4234 	{
4235 		IPACMERR("Cannot allocate header processing context table.\n");
4236 		return IPACM_FAILURE;
4237 	}
4238 
4239 	memset(pHeaderProcTable, 0, len);
4240 	pHeaderProcTable->commit = 1;
4241 	pHeaderProcTable->num_proc_ctxs = 1;
4242 	pHeaderProcTable->proc_ctx[0].type = eth_bridge_get_hdr_proc_type(peer_l2_hdr_type, tx_prop->tx[0].hdr_l2_type);
4243 	eth_bridge_get_hdr_template_hdl(&hdr_template);
4244 	pHeaderProcTable->proc_ctx[0].hdr_hdl = hdr_template;
4245 	if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false)
4246 	{
4247 		IPACMERR("Adding hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status);
4248 		res = IPACM_FAILURE;
4249 		goto end;
4250 	}
4251 
4252 	*hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl;
4253 
4254 end:
4255 	free(pHeaderProcTable);
4256 	return res;
4257 }
4258 
4259 /* 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)4260 int IPACM_Lan::eth_bridge_add_rt_rule(uint8_t *mac, char *rt_tbl_name, uint32_t hdr_proc_ctx_hdl,
4261 		ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int *rt_rule_count)
4262 {
4263 	int len, res = IPACM_SUCCESS;
4264 	uint32_t i, position, num_rt_rule;
4265 	struct ipa_ioc_add_rt_rule* rt_rule_table = NULL;
4266 	struct ipa_rt_rule_add rt_rule;
4267 
4268 	IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n",
4269 			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4270 
4271 	num_rt_rule = each_client_rt_rule_count[iptype];
4272 
4273 	len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add);
4274 	rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len);
4275 	if (rt_rule_table == NULL)
4276 	{
4277 		IPACMERR("Failed to allocate memory.\n");
4278 		return IPACM_FAILURE;
4279 	}
4280 	memset(rt_rule_table, 0, len);
4281 
4282 	rt_rule_table->commit = 1;
4283 	rt_rule_table->ip = iptype;
4284 	rt_rule_table->num_rules = num_rt_rule;
4285 	strlcpy(rt_rule_table->rt_tbl_name, rt_tbl_name, sizeof(rt_rule_table->rt_tbl_name));
4286 	rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = 0;
4287 
4288 	memset(&rt_rule, 0, sizeof(ipa_rt_rule_add));
4289 	rt_rule.at_rear = false;
4290 	rt_rule.status = -1;
4291 	rt_rule.rt_rule_hdl = -1;
4292 #ifdef FEATURE_IPA_V3
4293 	rt_rule.rule.hashable = true;
4294 #endif
4295 	rt_rule.rule.hdr_hdl = 0;
4296 	rt_rule.rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl;
4297 
4298 	position = 0;
4299 	for(i=0; i<iface_query->num_tx_props; i++)
4300 	{
4301 		if(tx_prop->tx[i].ip == iptype)
4302 		{
4303 			if(position >= num_rt_rule || position >= MAX_NUM_PROP)
4304 			{
4305 				IPACMERR("Number of routing rules already exceeds limit.\n");
4306 				res = IPACM_FAILURE;
4307 				goto end;
4308 			}
4309 
4310 			if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->isMCC_Mode)
4311 			{
4312 				IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n",
4313 						tx_prop->tx[i].alt_dst_pipe);
4314 				rt_rule.rule.dst = tx_prop->tx[i].alt_dst_pipe;
4315 			}
4316 			else
4317 			{
4318 				IPACMDBG_H("It is not WLAN MCC mode, use dst pipe: %d\n",
4319 						tx_prop->tx[i].dst_pipe);
4320 				rt_rule.rule.dst = tx_prop->tx[i].dst_pipe;
4321 			}
4322 
4323 			memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib));
4324 			if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II)
4325 				rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
4326 			else
4327 				rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
4328 			memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr));
4329 			memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask));
4330 
4331 			memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position]));
4332 			position++;
4333 		}
4334 	}
4335 	if(false == m_routing.AddRoutingRule(rt_rule_table))
4336 	{
4337 		IPACMERR("Routing rule addition failed!\n");
4338 		res = IPACM_FAILURE;
4339 		goto end;
4340 	}
4341 	else
4342 	{
4343 		*rt_rule_count = position;
4344 		for(i=0; i<position; i++)
4345 			rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
4346 	}
4347 
4348 end:
4349 	free(rt_rule_table);
4350 	return res;
4351 }
4352 
4353 /* 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)4354 int IPACM_Lan::eth_bridge_modify_rt_rule(uint8_t *mac, uint32_t hdr_proc_ctx_hdl,
4355 		ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int rt_rule_count)
4356 {
4357 	struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL;
4358 	struct ipa_rt_rule_mdfy *rt_rule_entry;
4359 	int len, res = IPACM_SUCCESS;
4360 	uint32_t index;
4361 
4362 	if(tx_prop == NULL)
4363 	{
4364 		IPACMDBG_H("No tx properties \n");
4365 		return IPACM_FAILURE;
4366 	}
4367 
4368 	if(ipa_if_cate != WLAN_IF)
4369 	{
4370 		IPACMDBG_H("This is not WLAN IF, no need to modify rt rule.\n");
4371 		return IPACM_SUCCESS;
4372 	}
4373 
4374 	IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n",
4375 			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4376 
4377 	len = sizeof(struct ipa_ioc_mdfy_rt_rule) + rt_rule_count * sizeof(struct ipa_rt_rule_mdfy);
4378 	rt_rule = (struct ipa_ioc_mdfy_rt_rule *)malloc(len);
4379 	if(rt_rule == NULL)
4380 	{
4381 		IPACMERR("Unable to allocate memory for modify rt rule\n");
4382 		return IPACM_FAILURE;
4383 	}
4384 	memset(rt_rule, 0, len);
4385 
4386 	rt_rule->commit = 1;
4387 	rt_rule->num_rules = 0;
4388 	rt_rule->ip = iptype;
4389 
4390 	for (index = 0; index < tx_prop->num_tx_props; index++)
4391 	{
4392 		if (tx_prop->tx[index].ip == iptype)
4393 		{
4394 			if (rt_rule->num_rules >= rt_rule_count ||
4395 				rt_rule->num_rules >= MAX_NUM_PROP)
4396 			{
4397 				IPACMERR("Number of routing rules exceeds limit.\n");
4398 				res = IPACM_FAILURE;
4399 				goto end;
4400 			}
4401 
4402 			rt_rule_entry = &rt_rule->rules[rt_rule->num_rules];
4403 
4404 			if (IPACM_Iface::ipacmcfg->isMCC_Mode)
4405 			{
4406 				IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n",
4407 						tx_prop->tx[index].alt_dst_pipe);
4408 				rt_rule_entry->rule.dst = tx_prop->tx[index].alt_dst_pipe;
4409 			}
4410 			else
4411 			{
4412 				IPACMDBG_H("In WLAN SCC mode, use dst pipe: %d\n",
4413 						tx_prop->tx[index].dst_pipe);
4414 				rt_rule_entry->rule.dst = tx_prop->tx[index].dst_pipe;
4415 			}
4416 
4417 			rt_rule_entry->rule.hdr_hdl = 0;
4418 			rt_rule_entry->rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl;
4419 #ifdef FEATURE_IPA_V3
4420 			rt_rule_entry->rule.hashable = true;
4421 #endif
4422 			memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[index].attrib,
4423 					sizeof(rt_rule_entry->rule.attrib));
4424 			if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II)
4425 				rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
4426 			else
4427 				rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
4428 			memcpy(rt_rule_entry->rule.attrib.dst_mac_addr, mac,
4429 					sizeof(rt_rule_entry->rule.attrib.dst_mac_addr));
4430 			memset(rt_rule_entry->rule.attrib.dst_mac_addr_mask, 0xFF,
4431 					sizeof(rt_rule_entry->rule.attrib.dst_mac_addr_mask));
4432 
4433 			rt_rule_entry->rt_rule_hdl = rt_rule_hdl[rt_rule->num_rules];
4434 			rt_rule->num_rules++;
4435 		}
4436 	}
4437 
4438 	if(m_routing.ModifyRoutingRule(rt_rule) == false)
4439 	{
4440 		IPACMERR("Failed to modify routing rules.\n");
4441 		res = IPACM_FAILURE;
4442 		goto end;
4443 	}
4444 	if(m_routing.Commit(iptype) == false)
4445 	{
4446 		IPACMERR("Failed to commit routing rules.\n");
4447 		res = IPACM_FAILURE;
4448 		goto end;
4449 	}
4450 	IPACMDBG("Modified routing rules successfully.\n");
4451 
4452 end:
4453 	free(rt_rule);
4454 	return res;
4455 }
4456 
eth_bridge_add_flt_rule(uint8_t * mac,uint32_t rt_tbl_hdl,ipa_ip_type iptype,uint32_t * flt_rule_hdl)4457 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)
4458 {
4459 	int len, res = IPACM_SUCCESS;
4460 	struct ipa_flt_rule_add flt_rule_entry;
4461 	struct ipa_ioc_add_flt_rule_after *pFilteringTable = NULL;
4462 
4463 #ifdef FEATURE_IPA_V3
4464 	if (rx_prop == NULL || tx_prop == NULL)
4465 	{
4466 		IPACMDBG_H("No rx or tx properties registered for iface %s\n", dev_name);
4467 		return IPACM_FAILURE;
4468 	}
4469 
4470 	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]);
4471 
4472 	len = sizeof(struct ipa_ioc_add_flt_rule_after) + sizeof(struct ipa_flt_rule_add);
4473 	pFilteringTable = (struct ipa_ioc_add_flt_rule_after*)malloc(len);
4474 	if (!pFilteringTable)
4475 	{
4476 		IPACMERR("Failed to allocate ipa_ioc_add_flt_rule_after memory...\n");
4477 		return IPACM_FAILURE;
4478 	}
4479 	memset(pFilteringTable, 0, len);
4480 
4481 	/* add mac based rule*/
4482 	pFilteringTable->commit = 1;
4483 	pFilteringTable->ep = rx_prop->rx[0].src_pipe;
4484 	pFilteringTable->ip = iptype;
4485 	pFilteringTable->num_rules = 1;
4486 	pFilteringTable->add_after_hdl = eth_bridge_flt_rule_offset[iptype];
4487 
4488 	memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
4489 	flt_rule_entry.at_rear = 1;
4490 
4491 	flt_rule_entry.rule.retain_hdr = 0;
4492 	flt_rule_entry.rule.to_uc = 0;
4493 	flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
4494 	flt_rule_entry.rule.eq_attrib_type = 0;
4495 	flt_rule_entry.rule.rt_tbl_hdl = rt_tbl_hdl;
4496 	flt_rule_entry.rule.hashable = true;
4497 
4498 	memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
4499 	if(tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_ETHERNET_II)
4500 	{
4501 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
4502 	}
4503 	else
4504 	{
4505 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
4506 	}
4507 
4508 	memcpy(flt_rule_entry.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr));
4509 	memset(flt_rule_entry.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr_mask));
4510 
4511 	memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
4512 	if (false == m_filtering.AddFilteringRuleAfter(pFilteringTable))
4513 	{
4514 		IPACMERR("Failed to add client filtering rules.\n");
4515 		res = IPACM_FAILURE;
4516 		goto end;
4517 	}
4518 	*flt_rule_hdl = pFilteringTable->rules[0].flt_rule_hdl;
4519 
4520 end:
4521 	free(pFilteringTable);
4522 #endif
4523 	return res;
4524 }
4525 
eth_bridge_del_flt_rule(uint32_t flt_rule_hdl,ipa_ip_type iptype)4526 int IPACM_Lan::eth_bridge_del_flt_rule(uint32_t flt_rule_hdl, ipa_ip_type iptype)
4527 {
4528 	if(m_filtering.DeleteFilteringHdls(&flt_rule_hdl, iptype, 1) == false)
4529 	{
4530 		IPACMERR("Failed to delete the client specific flt rule.\n");
4531 		return IPACM_FAILURE;
4532 	}
4533 	return IPACM_SUCCESS;
4534 }
4535 
eth_bridge_del_rt_rule(uint32_t rt_rule_hdl,ipa_ip_type iptype)4536 int IPACM_Lan::eth_bridge_del_rt_rule(uint32_t rt_rule_hdl, ipa_ip_type iptype)
4537 {
4538 	if(m_routing.DeleteRoutingHdl(rt_rule_hdl, iptype) == false)
4539 	{
4540 		IPACMERR("Failed to delete routing rule.\n");
4541 		return IPACM_FAILURE;
4542 	}
4543 	return IPACM_SUCCESS;
4544 }
4545 
4546 /* delete header processing context */
eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl)4547 int IPACM_Lan::eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl)
4548 {
4549 	if(m_header.DeleteHeaderProcCtx(hdr_proc_ctx_hdl) == false)
4550 	{
4551 		IPACMERR("Failed to delete hdr proc ctx.\n");
4552 		return IPACM_FAILURE;
4553 	}
4554 	return IPACM_SUCCESS;
4555 }
4556