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