1 /*
2 Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 		* Redistributions of source code must retain the above copyright
8 			notice, this list of conditions and the following disclaimer.
9 		* 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 #include <IPACM_Netlink.h>
56 #endif
57 
58 bool IPACM_Wan::wan_up = false;
59 bool IPACM_Wan::wan_up_v6 = false;
60 uint8_t IPACM_Wan::xlat_mux_id = 0;
61 
62 uint32_t IPACM_Wan::curr_wan_ip = 0;
63 int IPACM_Wan::num_v4_flt_rule = 0;
64 int IPACM_Wan::num_v6_flt_rule = 0;
65 
66 int IPACM_Wan::ipa_pm_q6_check = 0;
67 
68 struct ipa_flt_rule_add IPACM_Wan::flt_rule_v4[IPA_MAX_FLT_RULE];
69 struct ipa_flt_rule_add IPACM_Wan::flt_rule_v6[IPA_MAX_FLT_RULE];
70 
71 char IPACM_Wan::wan_up_dev_name[IF_NAME_LEN];
72 
73 ipacm_wan_iface_type IPACM_Wan::backhaul_mode = Q6_WAN;
74 bool IPACM_Wan::is_ext_prop_set = false;
75 
76 int IPACM_Wan::num_ipv4_modem_pdn = 0;
77 int IPACM_Wan::num_ipv6_modem_pdn = 0;
78 
79 bool IPACM_Wan::embms_is_on = false;
80 bool IPACM_Wan::backhaul_is_wan_bridge = false;
81 bool IPACM_Wan::is_xlat = false;
82 
83 ipacm_coalesce IPACM_Wan::coalesce_enable_info[IPA_MAX_NUM_SW_PDNS];
84 
85 uint32_t IPACM_Wan::backhaul_ipv6_prefix[2];
86 
87 #ifdef FEATURE_IPA_ANDROID
88 uint32_t	IPACM_Wan::ipa_if_num_tether_v4_total = 0;
89 uint32_t	IPACM_Wan::ipa_if_num_tether_v6_total = 0;
90 
91 int	IPACM_Wan::ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES];
92 int	IPACM_Wan::ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES];
93 #endif
94 
95 uint16_t IPACM_Wan::mtu_default_wan_v4 = DEFAULT_MTU_SIZE;
96 uint16_t IPACM_Wan::mtu_default_wan_v6 = DEFAULT_MTU_SIZE;
97 
IPACM_Wan(int iface_index,ipacm_wan_iface_type is_sta_mode,uint8_t * mac_addr)98 IPACM_Wan::IPACM_Wan(int iface_index,
99 	ipacm_wan_iface_type is_sta_mode,
100 	uint8_t *mac_addr) : IPACM_Iface(iface_index)
101 {
102 	num_firewall_v4 = 0;
103 	num_firewall_v6 = 0;
104 	wan_route_rule_v4_hdl = NULL;
105 	wan_route_rule_v6_hdl = NULL;
106 	wan_route_rule_v6_hdl_a5 = NULL;
107 	wan_client = NULL;
108 	mac_addr = NULL;
109 
110 	if(iface_query != NULL)
111 	{
112 		wan_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
113 		wan_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
114 		wan_route_rule_v6_hdl_a5 = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
115 		IPACMDBG_H("IPACM->IPACM_Wan(%d) constructor: Tx:%d\n", ipa_if_num, iface_query->num_tx_props);
116 	}
117 
118 	wan_v4_addr_set = false;
119 	wan_v4_addr_gw_set = false;
120 	wan_v6_addr_gw_set = false;
121 	active_v4 = false;
122 	active_v6 = false;
123 	header_set_v4 = false;
124 	header_set_v6 = false;
125 	header_partial_default_wan_v4 = false;
126 	header_partial_default_wan_v6 = false;
127 	hdr_hdl_sta_v4 = 0;
128 	hdr_hdl_sta_v6 = 0;
129 	num_ipv6_dest_flt_rule = 0;
130 	memset(ipv6_dest_flt_rule_hdl, 0, MAX_DEFAULT_v6_ROUTE_RULES*sizeof(uint32_t));
131 	memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
132 	memset(wan_v6_addr_gw, 0, sizeof(wan_v6_addr_gw));
133 	ext_prop = NULL;
134 	is_ipv6_frag_firewall_flt_rule_installed = false;
135 	ipv6_frag_firewall_flt_rule_hdl = 0;
136 
137 	icmpv6_exception_hdl = 0;
138 	tcp_fin_hdl = 0;
139 	tcp_rst_hdl = 0;
140 
141 	mtu_v4 = DEFAULT_MTU_SIZE;
142 	mtu_v4_set = false;
143 	mtu_v6 = DEFAULT_MTU_SIZE;
144 	mtu_v6_set = false;
145 
146 	num_wan_client = 0;
147 	header_name_count = 0;
148 	memset(invalid_mac, 0, sizeof(invalid_mac));
149 
150 	is_xlat_local = false;
151 	hdr_hdl_dummy_v6 = 0;
152 	hdr_proc_hdl_dummy_v6 = 0;
153 	is_default_gateway = false;
154 	m_fd_ipa = 0;
155 	wan_client_len = 0;
156 	m_is_sta_mode = is_sta_mode;
157 
158 #ifdef IPA_MTU_EVENT_MAX
159 	/* Query WAN MTU to handle IPACM restart scenarios. */
160 	if(is_sta_mode == Q6_WAN)
161 	{
162 		int fd_wwan_ioctl;
163 		ipa_mtu_info *mtu_info = (ipa_mtu_info *)malloc(sizeof(ipa_mtu_info));
164 		if (mtu_info)
165 		{
166 			memset(mtu_info, 0, sizeof(ipa_mtu_info));
167 			memcpy(mtu_info->if_name, dev_name, IPA_IFACE_NAME_LEN);
168 			fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
169 			if(fd_wwan_ioctl < 0)
170 			{
171 				IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
172 			}
173 			else
174 			{
175 				IPACMDBG_H("send WAN_IOC_GET_WAN_MTU for %s\n", mtu_info->if_name);
176 				if(ioctl(fd_wwan_ioctl, WAN_IOC_GET_WAN_MTU, mtu_info))
177 				{
178 					IPACMERR("Failed to send WAN_IOC_GET_WAN_MTU\n ");
179 				}
180 				else
181 				{
182 					/* Updated MTU values.*/
183 					if (mtu_info->mtu_v4)
184 					{
185 						mtu_v4 = mtu_info->mtu_v4;
186 						mtu_v4_set = true;
187 						IPACMDBG_H("Updated v4 mtu=[%d] for (%s)\n",
188 							mtu_v4, mtu_info->if_name);
189 					}
190 					if (mtu_info->mtu_v6)
191 					{
192 						mtu_v6 = mtu_info->mtu_v6;
193 						mtu_v6_set = true;
194 						IPACMDBG_H("Updated v6 mtu=[%d] for (%s)\n",
195 							mtu_v6, mtu_info->if_name);
196 					}
197 				}
198 				close(fd_wwan_ioctl);
199 			}
200 			free(mtu_info);
201 		}
202 	}
203 #endif
204 
205 	if(iface_query != NULL)
206 	{
207 		IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props);
208 
209 		if(is_sta_mode == Q6_WAN)
210 		{
211 			query_ext_prop();
212 
213 			if ((iface_query->num_ext_props == 1) && ((ext_prop != NULL) && ext_prop->ext[0].ip == IPA_IP_MAX))
214 			{
215 				/* only has one ext properties with IP_MAX type, will be the mhi-modem */
216 				IPACMDBG_H("One extended property for iface %s, replace %d to Q6_MHI_WAN\n", dev_name, is_sta_mode);
217 				m_is_sta_mode = Q6_MHI_WAN;
218 			}
219 			else
220 			{
221 				IPACMDBG_H("The new WAN interface is modem.\n");
222 				m_is_sta_mode = is_sta_mode;
223 				is_default_gateway = false;
224 			}
225 		}
226 		else
227 		{
228 			m_is_sta_mode = is_sta_mode;
229 			IPACMDBG_H("The new WAN interface is WLAN STA.\n");
230 		}
231 
232 		wan_client_len = (sizeof(ipa_wan_client)) + (iface_query->num_tx_props * sizeof(wan_client_rt_hdl));
233 		wan_client = (ipa_wan_client *)calloc(IPA_MAX_NUM_WAN_CLIENTS, wan_client_len);
234 		if (wan_client == NULL)
235 		{
236 			IPACMERR("unable to allocate memory\n");
237 			return;
238 		}
239 	}
240 	else
241 	{
242 		IPACMDBG_H("iface_query is empty.\n");
243 		return;
244 	}
245 
246 	m_fd_ipa = open(IPA_DEVICE_NAME, O_RDWR);
247 	if(0 == m_fd_ipa)
248 	{
249 		IPACMERR("Failed to open %s\n",IPA_DEVICE_NAME);
250 	}
251 
252 	if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == EMBMS_IF)
253 	{
254 		IPACMDBG(" IPACM->IPACM_Wan_eMBMS(%d)\n", ipa_if_num);
255 		embms_is_on = true;
256 		install_wan_filtering_rule(false);
257 		if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
258 		{
259 			/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
260 			if(tx_prop != NULL)
261 			{
262 				IPACMDBG_H("dev %s add producer dependency\n", dev_name);
263 				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]);
264 				IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
265 			}
266 		}
267 	}
268 	else
269 	{
270 		IPACMDBG(" IPACM->IPACM_Wan(%d)\n", ipa_if_num);
271 	}
272 	return;
273 }
274 
~IPACM_Wan()275 IPACM_Wan::~IPACM_Wan()
276 {
277 	IPACM_EvtDispatcher::deregistr(this);
278 	IPACM_IfaceManager::deregistr(this);
279 	return;
280 }
281 
282 /* handle new_address event */
handle_addr_evt(ipacm_event_data_addr * data)283 int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
284 {
285 	struct ipa_ioc_add_rt_rule *rt_rule = NULL;
286 	struct ipa_rt_rule_add *rt_rule_entry;
287 	struct ipa_ioc_add_flt_rule *flt_rule;
288 	struct ipa_flt_rule_add flt_rule_entry;
289 	struct ipa_ioc_get_hdr hdr;
290 	bool result;
291 
292 	const int NUM_RULES = 1;
293 	uint32_t num_ipv6_addr;
294 	int res = IPACM_SUCCESS,len;
295 #ifdef FEATURE_IPACM_HAL
296 	IPACM_OffloadManager* OffloadMng;
297 #endif
298 
299 	memset(&hdr, 0, sizeof(hdr));
300 	if(tx_prop == NULL || rx_prop == NULL)
301 	{
302 		IPACMDBG_H("Either tx or rx property is NULL, return.\n");
303 		return IPACM_SUCCESS;
304 	}
305 
306 	/* Update the IP Type. */
307 	config_ip_type(data->iptype);
308 
309 	if (data->iptype == IPA_IP_v6)
310 	{
311 		for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
312 		{
313 			if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
314 			   (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
315 			   (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
316 			   (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
317 			{
318 				IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
319 				return IPACM_SUCCESS;
320 				break;
321 			}
322 		}
323 		rt_rule = (struct ipa_ioc_add_rt_rule *)
324 			calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
325 				NUM_RULES * sizeof(struct ipa_rt_rule_add));
326 
327 		if (!rt_rule)
328 		{
329 			IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
330 			return IPACM_FAILURE;
331 		}
332 
333 		rt_rule->commit = 1;
334 		rt_rule->num_rules = NUM_RULES;
335 		rt_rule->ip = data->iptype;
336 		/* setup RT rule for v6_lan table*/
337 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
338 
339 		rt_rule_entry = &rt_rule->rules[0];
340 		rt_rule_entry->at_rear = false;
341 		rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
342 		rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0];
343 		rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1];
344 		rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2];
345 		rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3];
346 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
347 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
348 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
349 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
350 		ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
351 		ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
352 		ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
353 		ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
354 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
355 			rt_rule_entry->rule.hashable = false;
356 		if(m_is_sta_mode == Q6_WAN)
357 		{
358 			strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
359 			hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
360 			if(m_header.GetHeaderHandle(&hdr) == false)
361 			{
362 				IPACMERR("Failed to get QMAP header.\n");
363 				return IPACM_FAILURE;
364 			}
365 			rt_rule_entry->rule.hdr_hdl = hdr.hdl;
366 			rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
367 			/* legacy default v4 rt-rule */
368 #ifdef IPA_RT_SUPPORT_COAL
369 			rt_rule_entry->rule.coalesce = false;
370 #endif
371 			/* legacy default v6 rt-rule */
372 			if (false == m_routing.AddRoutingRule(rt_rule))
373 			{
374 				IPACMERR("Routing rule addition failed!\n");
375 				res = IPACM_FAILURE;
376 				goto fail;
377 			}
378 			else if (rt_rule_entry->status)
379 			{
380 				IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
381 				res = rt_rule_entry->status;
382 				goto fail;
383 			}
384 			dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
385 
386 			/* setup same rule for v6_wan table*/
387 			strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
388 			if (false == m_routing.AddRoutingRule(rt_rule))
389 			{
390 				IPACMERR("Routing rule addition failed!\n");
391 				res = IPACM_FAILURE;
392 				goto fail;
393 		}
394 			else if (rt_rule_entry->status)
395 		{
396 				IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
397 				res = rt_rule_entry->status;
398 				goto fail;
399 		}
400 			dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
401 
402 			IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, entry: %d %d\n",
403 					dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
404 					dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],
405 					MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6,
406 					MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1);
407 			/* RSC TCP rule*/
408 			rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
409 			rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
410 #ifdef IPA_RT_SUPPORT_COAL
411 			if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
412 				rt_rule_entry->rule.coalesce = true;
413 		else
414 				rt_rule_entry->rule.coalesce = false;
415 #endif
416 			if (false == m_routing.AddRoutingRule(rt_rule))
417 		{
418 				IPACMERR("Routing rule addition failed!\n");
419 				res = IPACM_FAILURE;
420 				goto fail;
421 			}
422 			else if (rt_rule_entry->status)
423 			{
424 				IPACMERR("rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
425 				res = rt_rule_entry->status;
426 				goto fail;
427 		}
428 			dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
429 			IPACMDBG_H("ipv6 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d), entry %d", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
430 				IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable,
431 				2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6);
432 			/* RSB UDP rule*/
433 			rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
434 #ifdef IPA_RT_SUPPORT_COAL
435 			if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable)
436 				rt_rule_entry->rule.coalesce = true;
437 			else
438 				rt_rule_entry->rule.coalesce = false;
439 #endif
440 		if (false == m_routing.AddRoutingRule(rt_rule))
441 		{
442 			IPACMERR("Routing rule addition failed!\n");
443 			res = IPACM_FAILURE;
444 			goto fail;
445 		}
446 		else if (rt_rule_entry->status)
447 		{
448 				IPACMERR("rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
449 				res = rt_rule_entry->status;
450 				goto fail;
451 			}
452 			dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
453 			IPACMDBG_H("ipv6 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d) entry %d", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],
454 				IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable,
455 				2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1);
456 		}
457 		else
458 		{
459 			rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
460 			/* legacy default v6 rt-rule */
461 			if (false == m_routing.AddRoutingRule(rt_rule))
462 			{
463 				IPACMERR("Routing rule addition failed!\n");
464 				res = IPACM_FAILURE;
465 				goto fail;
466 			}
467 			else if (rt_rule_entry->status)
468 			{
469 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
470 			res = rt_rule_entry->status;
471 			goto fail;
472 		}
473 		dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
474 
475 		/* setup same rule for v6_wan table*/
476 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
477 		if (false == m_routing.AddRoutingRule(rt_rule))
478 		{
479 			IPACMERR("Routing rule addition failed!\n");
480 			res = IPACM_FAILURE;
481 			goto fail;
482 		}
483 		else if (rt_rule_entry->status)
484 		{
485 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
486 			res = rt_rule_entry->status;
487 			goto fail;
488 		}
489 		dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
490 
491 			IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, entry: %d  %d\n",
492 				dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
493 					dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],
494 					MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6,
495 					MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1);
496 		}
497 
498 		/* add default filtering rules when wan-iface get global v6-prefix */
499 		if (num_dft_rt_v6 == 1)
500 		{
501 			if(m_is_sta_mode == Q6_WAN)
502 			{
503 				modem_ipv6_pdn_index = num_ipv6_modem_pdn;
504 				num_ipv6_modem_pdn++;
505 				IPACMDBG_H("Now the number of modem ipv6 pdn is %d.\n", num_ipv6_modem_pdn);
506 				init_fl_rule_ex(data->iptype);
507 			}
508 			else if(m_is_sta_mode == Q6_MHI_WAN)
509 			{
510 				IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, IPA_IP_v6);
511 				IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_v6);
512 			}
513 			else
514 			{
515 				init_fl_rule(data->iptype);
516 			}
517 		}
518 
519 		/* add WAN DL interface IP specific flt rule for IPv6 when backhaul is not Q6 */
520 		if(m_is_sta_mode != Q6_WAN)
521 		{
522 			if(rx_prop != NULL && is_global_ipv6_addr(data->ipv6_addr)
523 				&& num_ipv6_dest_flt_rule < MAX_DEFAULT_v6_ROUTE_RULES)
524 			{
525 				len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
526 
527 				flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
528 				if (!flt_rule)
529 				{
530 					IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
531 					return IPACM_FAILURE;
532 				}
533 
534 				flt_rule->commit = 1;
535 				flt_rule->ep = rx_prop->rx[0].src_pipe;
536 				flt_rule->global = false;
537 				flt_rule->ip = IPA_IP_v6;
538 				flt_rule->num_rules = 1;
539 
540 				memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
541 
542 				flt_rule_entry.rule.retain_hdr = 1;
543 				flt_rule_entry.rule.to_uc = 0;
544 				flt_rule_entry.rule.eq_attrib_type = 0;
545 				flt_rule_entry.at_rear = true;
546 				flt_rule_entry.flt_rule_hdl = -1;
547 				flt_rule_entry.status = -1;
548 				flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
549 				if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
550 					flt_rule_entry.rule.hashable = true;
551 				memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
552 
553 				flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
554 				memcpy(flt_rule_entry.rule.attrib.u.v6.dst_addr, data->ipv6_addr, sizeof(flt_rule_entry.rule.attrib.u.v6.dst_addr));
555 				flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
556 				flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
557 				flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
558 				flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
559 				memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
560 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
561 				/* use index hw-counter */
562 				if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
563 				{
564 					IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
565 					result = m_filtering.AddFilteringRule_hw_index(flt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
566 				} else {
567 					result = m_filtering.AddFilteringRule(flt_rule);
568 				}
569 #else
570 				result = m_filtering.AddFilteringRule(flt_rule);
571 #endif
572 
573 				if (result == false)
574 				{
575 					IPACMERR("Error Adding Filtering rule, aborting...\n");
576 					free(flt_rule);
577 					res = IPACM_FAILURE;
578 					goto fail;
579 				}
580 				else
581 				{
582 					IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
583 					ipv6_dest_flt_rule_hdl[num_ipv6_dest_flt_rule] = flt_rule->rules[0].flt_rule_hdl;
584 					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]);
585 					num_ipv6_dest_flt_rule++;
586 					free(flt_rule);
587 				}
588 			}
589 		}
590 		/* store ipv6 prefix if the ipv6 address is not link local */
591 		if(is_global_ipv6_addr(data->ipv6_addr))
592 		{
593 			memcpy(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix));
594 		}
595 	    num_dft_rt_v6++;
596     }
597 	else
598 	{
599 		if(wan_v4_addr_set)
600 		{
601 			/* check iface ipv4 same or not */
602 			if(data->ipv4_addr == wan_v4_addr)
603 			{
604 				IPACMDBG_H("Already setup device (%s) ipv4 and it didn't change(0x%x)\n", dev_name, data->ipv4_addr);
605 				return IPACM_SUCCESS;
606 			}
607 			else
608 			{
609 				IPACMDBG_H(" device (%s) ipv4 addr is changed\n", dev_name);
610 				/* Delete default Coalese v4 RT rule */
611 				if (m_is_sta_mode == Q6_WAN) {
612 					if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
613 					{
614 						IPACMERR("Routing old RSC TCP RT rule deletion failed!\n");
615 						res = IPACM_FAILURE;
616 						goto fail;
617 					}
618 					if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
619 					{
620 						IPACMERR("Routing old RSB UDP RT rule deletion failed!\n");
621 						res = IPACM_FAILURE;
622 						goto fail;
623 					}
624 				}
625 				/* Delete default v4 RT rule */
626 				IPACMDBG_H("Delete default v4 routing rules\n");
627 				if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
628 				{
629 					IPACMERR("Routing old RT rule deletion failed!\n");
630 					res = IPACM_FAILURE;
631 					goto fail;
632 				}
633 			}
634 		}
635 
636 		rt_rule = (struct ipa_ioc_add_rt_rule *)
637 			 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
638 							NUM_RULES * sizeof(struct ipa_rt_rule_add));
639 
640 		if (!rt_rule)
641 		{
642 			IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
643 			return IPACM_FAILURE;
644 		}
645 
646 		rt_rule->commit = 1;
647 		rt_rule->num_rules = NUM_RULES;
648 		rt_rule->ip = data->iptype;
649 		rt_rule_entry = &rt_rule->rules[0];
650 		rt_rule_entry->at_rear = false;
651 		rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
652 		/* still need setup v4 default routing rule to A5*/
653 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
654 		rt_rule_entry->rule.attrib.u.v4.dst_addr      = data->ipv4_addr;
655 		rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
656 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
657 			rt_rule_entry->rule.hashable = false;
658 		if(m_is_sta_mode == Q6_WAN)
659 		{
660 			/* query qmap header*/
661 			strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
662 			hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
663 			if(m_header.GetHeaderHandle(&hdr) == false)
664 			{
665 				IPACMERR("Failed to get QMAP header.\n");
666 				res = IPACM_FAILURE;
667 				goto fail;
668 			}
669 			rt_rule_entry->rule.hdr_hdl = hdr.hdl;
670 			rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
671 			/* legacy default v4 rt-rule */
672 #ifdef IPA_RT_SUPPORT_COAL
673 			rt_rule_entry->rule.coalesce = false;
674 #endif
675 			/* legacy default v4 rt-rule */
676 			if (false == m_routing.AddRoutingRule(rt_rule))
677 			{
678 				IPACMERR("Routing rule addition failed!\n");
679 				res = IPACM_FAILURE;
680 				goto fail;
681 			}
682 			else if (rt_rule_entry->status)
683 			{
684 				IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
685 				res = rt_rule_entry->status;
686 				goto fail;
687 		}
688 			dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
689 			IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
690 			/* RSC TCP rule*/
691 			rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
692 			rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
693 
694 #ifdef IPA_RT_SUPPORT_COAL
695 			if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
696 				rt_rule_entry->rule.coalesce = true;
697 		else
698 				rt_rule_entry->rule.coalesce = false;
699 #endif
700 			if (false == m_routing.AddRoutingRule(rt_rule))
701 		{
702 				IPACMERR("Routing rule addition failed!\n");
703 				res = IPACM_FAILURE;
704 				goto fail;
705 			}
706 			else if (rt_rule_entry->status)
707 			{
708 				IPACMERR("rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
709 				res = rt_rule_entry->status;
710 				goto fail;
711 		}
712 			dft_coalesce_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
713 			IPACMDBG_H("ipv4 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[0],
714 				IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
715 
716 			/* RSB UDP rule*/
717 			rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
718 #ifdef IPA_RT_SUPPORT_COAL
719 			if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable)
720 				rt_rule_entry->rule.coalesce = true;
721 			else
722 				rt_rule_entry->rule.coalesce = false;
723 #endif
724 		if (false == m_routing.AddRoutingRule(rt_rule))
725 		{
726 			IPACMERR("Routing rule addition failed!\n");
727 			res = IPACM_FAILURE;
728 			goto fail;
729 		}
730 		else if (rt_rule_entry->status)
731 		{
732 				IPACMERR("rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
733 				res = rt_rule_entry->status;
734 				goto fail;
735 			}
736 			dft_coalesce_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
737 			IPACMDBG_H("ipv4 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[1],
738 				IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
739 		}
740 		else
741 		{
742 			rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
743 			/* legacy default v4 rt-rule */
744 			if (false == m_routing.AddRoutingRule(rt_rule))
745 			{
746 				IPACMERR("Routing rule addition failed!\n");
747 				res = IPACM_FAILURE;
748 				goto fail;
749 			}
750 			else if (rt_rule_entry->status)
751 			{
752 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
753 			res = rt_rule_entry->status;
754 			goto fail;
755 		}
756 		dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
757 		IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
758 		}
759 
760 			/* initial multicast/broadcast/fragment filter rule */
761 		/* only do one time */
762 		if(!wan_v4_addr_set)
763 		{
764 			/* initial multicast/broadcast/fragment filter rule */
765 			if(m_is_sta_mode == Q6_WAN)
766 			{
767 				modem_ipv4_pdn_index = num_ipv4_modem_pdn;
768 				num_ipv4_modem_pdn++;
769 				IPACMDBG_H("Now the number of modem ipv4 pdn is %d.\n", num_ipv4_modem_pdn);
770 				init_fl_rule_ex(data->iptype);
771 			}
772 			else if(m_is_sta_mode == Q6_MHI_WAN)
773 			{
774 				IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, IPA_IP_v4);
775 				IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_v4);
776 			}
777 			else
778 			{
779 				init_fl_rule(data->iptype);
780 			}
781 		}
782 
783 		wan_v4_addr = data->ipv4_addr;
784 		wan_v4_addr_set = true;
785 
786 		if (m_is_sta_mode == Q6_WAN)
787 			curr_wan_ip = data->ipv4_addr;
788 
789 		IPACMDBG_H("Receved wan ipv4-addr:0x%x\n",wan_v4_addr);
790 	}
791 
792 #ifdef FEATURE_IPACM_HAL
793 	/* check if having pending set_upstream cache*/
794 	OffloadMng = IPACM_OffloadManager::GetInstance();
795 	if (OffloadMng == NULL) {
796 		IPACMERR("failed to get IPACM_OffloadManager instance !\n");
797 	} else {
798 		IPACMDBG_H(" check iface %s if having set_upstream cache events\n", dev_name);
799 		OffloadMng->search_framwork_cache(dev_name);
800 	}
801 #endif
802 	IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
803 
804 fail:
805 	if (rt_rule != NULL)
806 	{
807 		free(rt_rule);
808 	}
809 	return res;
810 }
811 
812 /* handle new_address event */
handle_addr_evt_mhi_q6(ipacm_event_data_addr * data)813 int IPACM_Wan::handle_addr_evt_mhi_q6(ipacm_event_data_addr *data)
814 {
815 	uint32_t num_ipv6_addr;
816 	int res = IPACM_SUCCESS;
817 	struct ipa_ioc_add_rt_rule *rt_rule = NULL;
818 	struct ipa_rt_rule_add *rt_rule_entry;
819 	struct ipa_ioc_get_hdr hdr;
820 	const int NUM_RULES = 1;
821 
822 #ifdef FEATURE_IPACM_HAL
823 	IPACM_OffloadManager* OffloadMng;
824 #endif
825 
826 	memset(&hdr, 0, sizeof(hdr));
827 	if(tx_prop == NULL || rx_prop == NULL)
828 	{
829 		IPACMDBG_H("Either tx or rx property is NULL, return.\n");
830 		return IPACM_SUCCESS;
831 	}
832 	/* Update the IP Type. */
833 	config_ip_type(data->iptype);
834 
835 	if (data->iptype == IPA_IP_v6)
836 	{
837 		for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
838 		{
839 			if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
840 			   (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
841 			   (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
842 			   (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
843 			{
844 				IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
845 				return IPACM_SUCCESS;
846 				break;
847 			}
848 		}
849 
850 		ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
851 		ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
852 		ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
853 		ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
854 
855 		/* store ipv6 prefix if the ipv6 address is not link local */
856 		if(is_global_ipv6_addr(data->ipv6_addr))
857 		{
858 			memcpy(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix));
859 		}
860 		num_dft_rt_v6++;
861 		if (num_dft_rt_v6 == 1)
862 		{
863 			/* Add Natting iface to IPACM_Config if there is  Rx/Tx property */
864 			if (rx_prop != NULL || tx_prop != NULL)
865 			{
866 				IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, IPA_IP_v6);
867 				IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_v6);
868 			}
869 			/* setup v6-wan-tbl */
870 			rt_rule = (struct ipa_ioc_add_rt_rule *)
871 				calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
872 				NUM_RULES * sizeof(struct ipa_rt_rule_add));
873 			if (!rt_rule)
874 			{
875 				IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
876 				return IPACM_FAILURE;
877 			}
878 
879 			rt_rule->commit = 1;
880 			rt_rule->num_rules = NUM_RULES;
881 			rt_rule->ip = data->iptype;
882 			strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
883 			rt_rule_entry = &rt_rule->rules[0];
884 			strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
885 			hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
886 			if(m_header.GetHeaderHandle(&hdr) == false)
887 			{
888 				IPACMERR("Failed to get QMAP header.\n");
889 				free(rt_rule);
890 				return IPACM_FAILURE;
891 			}
892 			rt_rule_entry->rule.hdr_hdl = hdr.hdl;
893 			rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
894 			rt_rule_entry->at_rear = false;
895 			rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
896 			/* still need setup v4 default routing rule to A5*/
897 			rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
898 			rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0];
899 			rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1];
900 			rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2];
901 			rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3];
902 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
903 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
904 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
905 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
906 			ipv6_addr[0][0] = data->ipv6_addr[0];
907 			ipv6_addr[0][1] = data->ipv6_addr[1];
908 			ipv6_addr[0][2] = data->ipv6_addr[2];
909 			ipv6_addr[0][3] = data->ipv6_addr[3];
910 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
911 				rt_rule_entry->rule.hashable = false;
912 			if (false == m_routing.AddRoutingRule(rt_rule))
913 			{
914 				IPACMERR("Routing rule addition failed!\n");
915 				free(rt_rule);
916 				return IPACM_FAILURE;
917 			}
918 			else if (rt_rule_entry->status)
919 			{
920 				IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
921 				free(rt_rule);
922 				return rt_rule_entry->status;
923 			}
924 			dft_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
925 			IPACMDBG_H("ipv6 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[1]);
926 		}
927 	}
928 	else
929 	{
930 		if(wan_v4_addr_set)
931 		{
932 			/* check iface ipv4 same or not */
933 			if(data->ipv4_addr == wan_v4_addr)
934 			{
935 				IPACMDBG_H("Already setup device (%s) ipv4 and it didn't change(0x%x)\n", dev_name, data->ipv4_addr);
936 				return IPACM_SUCCESS;
937 			}
938 			else
939 			{
940 				IPACMDBG_H(" device (%s) ipv4 addr is changed\n", dev_name);
941 				/* Delete default v4 RT rule */
942 				IPACMDBG_H("Delete default v4 routing rules\n");
943 				if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
944 				{
945 					IPACMERR("Routing old RT rule deletion failed!\n");
946 					return IPACM_FAILURE;
947 				}
948 			}
949 		}
950 		/* only do one time */
951 		if(!wan_v4_addr_set)
952 		{
953 			/* Add Natting iface to IPACM_Config if there is  Rx/Tx property */
954 			if (rx_prop != NULL || tx_prop != NULL)
955 			{
956 				IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, IPA_IP_v4);
957 				IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_v4);
958 			}
959 
960 			rt_rule = (struct ipa_ioc_add_rt_rule *)
961 				calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
962 					NUM_RULES * sizeof(struct ipa_rt_rule_add));
963 
964 			if (!rt_rule)
965 			{
966 				IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
967 				return IPACM_FAILURE;
968 			}
969 
970 			rt_rule->commit = 1;
971 			rt_rule->num_rules = NUM_RULES;
972 			rt_rule->ip = data->iptype;
973 			rt_rule_entry = &rt_rule->rules[0];
974 			strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
975 			hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
976 			if(m_header.GetHeaderHandle(&hdr) == false)
977 			{
978 				IPACMERR("Failed to get QMAP header.\n");
979 				free(rt_rule);
980 				return IPACM_FAILURE;
981 			}
982 			rt_rule_entry->rule.hdr_hdl = hdr.hdl;
983 			rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
984 			rt_rule_entry->at_rear = false;
985 			rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
986 			/* still need setup v4 default routing rule to A5*/
987 			strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
988 			rt_rule_entry->rule.attrib.u.v4.dst_addr      = data->ipv4_addr;
989 			rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
990 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
991 				rt_rule_entry->rule.hashable = false;
992 			if (false == m_routing.AddRoutingRule(rt_rule))
993 			{
994 				IPACMERR("Routing rule addition failed!\n");
995 				free(rt_rule);
996 				return IPACM_FAILURE;
997 			}
998 			else if (rt_rule_entry->status)
999 			{
1000 				IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1001 				free(rt_rule);
1002 				return rt_rule_entry->status;
1003 			}
1004 			dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
1005 			IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
1006 		}
1007 
1008 		wan_v4_addr = data->ipv4_addr;
1009 		wan_v4_addr_set = true;
1010 		IPACMDBG_H("Receved wan ipv4-addr:0x%x\n",wan_v4_addr);
1011 		free(rt_rule);
1012 	}
1013 
1014 #ifdef FEATURE_IPACM_HAL
1015 	/* check if having pending set_upstream cache*/
1016 	OffloadMng = IPACM_OffloadManager::GetInstance();
1017 	if (OffloadMng == NULL) {
1018 		IPACMERR("failed to get IPACM_OffloadManager instance !\n");
1019 	} else {
1020 		IPACMDBG_H(" check iface %s if having set_upstream cache events\n", dev_name);
1021 		OffloadMng->search_framwork_cache(dev_name);
1022 	}
1023 #endif
1024 	IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
1025 
1026 	return res;
1027 }
event_callback(ipa_cm_event_id event,void * param)1028 void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
1029 {
1030 	int ipa_interface_index;
1031 
1032 	switch (event)
1033 	{
1034 	case IPA_WLAN_LINK_DOWN_EVENT:
1035 		{
1036 			if(m_is_sta_mode == WLAN_WAN)
1037 			{
1038 				ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
1039 				ipa_interface_index = iface_ipa_index_query(data->if_index);
1040 				if (ipa_interface_index == ipa_if_num)
1041 				{
1042 					IPACMDBG_H("Received IPA_WLAN_LINK_DOWN_EVENT\n");
1043 					handle_down_evt();
1044 					/* reset the STA-iface category to unknown */
1045 					IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat = UNKNOWN_IF;
1046 					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);
1047 					IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
1048 					delete this;
1049 					return;
1050 				}
1051 			}
1052 		}
1053 		break;
1054 
1055 	case IPA_WAN_XLAT_CONNECT_EVENT:
1056 		{
1057 			IPACMDBG_H("Recieved IPA_WAN_XLAT_CONNECT_EVENT\n");
1058 			ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
1059 			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
1060 			if ((ipa_interface_index == ipa_if_num) && (m_is_sta_mode == Q6_WAN))
1061 			{
1062 				is_xlat_local = true;
1063 				IPACMDBG_H("WAN-LTE (%s) link up, iface: %d is_xlat_local: %d\n",
1064 						IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,data->if_index, is_xlat_local);
1065 			}
1066 			break;
1067 		}
1068 	case IPA_CFG_CHANGE_EVENT:
1069 		{
1070 			if ( (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ipa_if_cate) &&
1071 					(m_is_sta_mode ==ECM_WAN))
1072 			{
1073 				IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category did not change(wan_mode:%d)\n", m_is_sta_mode);
1074 				IPACMDBG_H("Now the cradle wan mode is %d.\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode);
1075 				if(is_default_gateway == true)
1076 				{
1077 					if(backhaul_is_wan_bridge == false && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE)
1078 					{
1079 						IPACMDBG_H("Cradle wan mode switch to bridge mode.\n");
1080 						backhaul_is_wan_bridge = true;
1081 					}
1082 					else if(backhaul_is_wan_bridge == true && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
1083 					{
1084 						IPACMDBG_H("Cradle wan mode switch to router mode.\n");
1085 						backhaul_is_wan_bridge = false;
1086 					}
1087 					else
1088 					{
1089 						IPACMDBG_H("No cradle mode switch, return.\n");
1090 						return;
1091 					}
1092 					/* post wan mode change event to LAN/WLAN */
1093 					if(IPACM_Wan::wan_up == true)
1094 					{
1095 						IPACMDBG_H("This interface is default GW.\n");
1096 						ipacm_cmd_q_data evt_data;
1097 						memset(&evt_data, 0, sizeof(evt_data));
1098 
1099 						ipacm_event_cradle_wan_mode *data_wan_mode = NULL;
1100 						data_wan_mode = (ipacm_event_cradle_wan_mode *)malloc(sizeof(ipacm_event_cradle_wan_mode));
1101 						if(data_wan_mode == NULL)
1102 						{
1103 							IPACMERR("unable to allocate memory.\n");
1104 							return;
1105 						}
1106 						data_wan_mode->cradle_wan_mode = IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode;
1107 						evt_data.event = IPA_CRADLE_WAN_MODE_SWITCH;
1108 						evt_data.evt_data = data_wan_mode;
1109 						IPACMDBG_H("Posting IPA_CRADLE_WAN_MODE_SWITCH event.\n");
1110 						IPACM_EvtDispatcher::PostEvt(&evt_data);
1111 					}
1112 					/* update the firewall flt rule actions */
1113 					if(active_v4)
1114 					{
1115 						del_dft_firewall_rules(IPA_IP_v4);
1116 						config_dft_firewall_rules(IPA_IP_v4);
1117 					}
1118 					if(active_v6)
1119 					{
1120 						del_dft_firewall_rules(IPA_IP_v6);
1121 						config_dft_firewall_rules(IPA_IP_v6);
1122 					}
1123 				}
1124 				else
1125 				{
1126 					IPACMDBG_H("This interface is not default GW, ignore.\n");
1127 				}
1128 			}
1129 			else if ( (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate) &&
1130 					(m_is_sta_mode ==ECM_WAN))
1131 			{
1132 				IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category changed(wan_mode:%d)\n", m_is_sta_mode);
1133 				/* posting link-up event for cradle use-case */
1134 				ipacm_cmd_q_data evt_data;
1135 				memset(&evt_data, 0, sizeof(evt_data));
1136 
1137 				ipacm_event_data_fid *data_fid = NULL;
1138 				data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
1139 				if(data_fid == NULL)
1140 				{
1141 					IPACMERR("unable to allocate memory for IPA_USB_LINK_UP_EVENT data_fid\n");
1142 					return;
1143 				}
1144 				if(IPACM_Iface::ipa_get_if_index(dev_name, &(data_fid->if_index)))
1145 				{
1146 					IPACMERR("Error while getting interface index for %s device", dev_name);
1147 				}
1148 				evt_data.event = IPA_USB_LINK_UP_EVENT;
1149 				evt_data.evt_data = data_fid;
1150 				IPACMDBG_H("Posting event:%d\n", evt_data.event);
1151 				IPACM_EvtDispatcher::PostEvt(&evt_data);
1152 
1153 				/* delete previous instance */
1154 				handle_down_evt();
1155 				IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
1156 				delete this;
1157 				return;
1158 			}
1159 		}
1160 		break;
1161 
1162 	case IPA_COALESCE_NOTICE:
1163 		{
1164 			if (m_is_sta_mode == Q6_WAN)
1165 			{
1166 				IPACMDBG_H("Received IPA_COALESCE_NOTICE (wan_mode:%d)\n", m_is_sta_mode);
1167 				handle_coalesce_evt();
1168 			}
1169 		}
1170 		break;
1171 
1172 	case IPA_LINK_DOWN_EVENT:
1173 		{
1174 			ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
1175 			ipa_interface_index = iface_ipa_index_query(data->if_index);
1176 			if (ipa_interface_index == ipa_if_num)
1177 			{
1178 				if(m_is_sta_mode == Q6_WAN)
1179 				{
1180 						IPACMDBG_H("Received IPA_LINK_DOWN_EVENT\n");
1181 						handle_down_evt_ex();
1182 						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);
1183 						IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
1184 						delete this;
1185 						return;
1186 				}
1187 				else if ((m_is_sta_mode == ECM_WAN) || (m_is_sta_mode == Q6_MHI_WAN))
1188 				{
1189 					IPACMDBG_H("Received IPA_LINK_DOWN_EVENT(wan_mode:%d)\n", m_is_sta_mode);
1190 					/* delete previous instance */
1191 					handle_down_evt();
1192 					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);
1193 					IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
1194 					delete this;
1195 					return;
1196 				}
1197 			}
1198 		}
1199 		break;
1200 
1201 	case IPA_ADDR_ADD_EVENT:
1202 		{
1203 			ipacm_event_data_addr *data = (ipacm_event_data_addr *)param;
1204 			ipa_interface_index = iface_ipa_index_query(data->if_index);
1205 
1206 			if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) ||
1207 					 (data->iptype == IPA_IP_v6 &&
1208 						data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 &&
1209 					  data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) )
1210 			{
1211 				IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n");
1212 				return;
1213 			}
1214 
1215 			if (ipa_interface_index == ipa_if_num)
1216 			{
1217 				IPACMDBG_H("Get IPA_ADDR_ADD_EVENT: IF ip type %d, incoming ip type %d\n", ip_type, data->iptype);
1218 				/* check v4 not setup before, v6 can have 2 iface ip */
1219 				if( (data->iptype == IPA_IP_v4)
1220 				    || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
1221 				{
1222 					if (m_is_sta_mode == Q6_MHI_WAN)
1223 					{
1224 						IPACMDBG_H("Got handle_addr_evt_mhi_q6 ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
1225 						handle_addr_evt_mhi_q6(data);
1226 					}
1227 					else
1228 					{
1229 						IPACMDBG_H("Got handle_addr_evt ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
1230 						handle_addr_evt(data);
1231 					}
1232 					/* checking if SW-RT_enable */
1233 					if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true &&
1234 							m_is_sta_mode != Q6_WAN)
1235 					{
1236 						/* handle software routing enable event*/
1237 						IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
1238 
1239 						if(m_is_sta_mode == Q6_MHI_WAN)
1240 						{
1241 							handle_software_routing_enable(true);
1242 						}
1243 						else
1244 						{
1245 							handle_software_routing_enable(false);
1246 						}
1247 					}
1248 
1249 				}
1250 			}
1251 		}
1252 		break;
1253 
1254 
1255 	case IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT:
1256 		{
1257 			ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param;
1258 			ipa_interface_index = iface_ipa_index_query(data->if_index);
1259 #ifndef FEATURE_IPACM_HAL
1260 			/* add the check see if tether_iface is valid or not */
1261 			if (iface_ipa_index_query(data->if_index_tether) == INVALID_IFACE)
1262 			{
1263 				IPACMERR("UPSTREAM_ROUTE_ADD tether_if(%d), not valid ignore\n", INVALID_IFACE);
1264 				return;
1265 			}
1266 #endif
1267 			if (ipa_interface_index == ipa_if_num)
1268 			{
1269 				IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT (Android) for ip-type (%d)\n", data->iptype);
1270 				/* The special below condition is to handle default gateway */
1271 				if ((data->iptype == IPA_IP_v4) && (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX))
1272 				{
1273 					if (active_v4 == false)
1274 					{
1275 #ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
1276 						IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d) default gw (%x)\n", dev_name,data->iptype, wan_v4_addr_gw);
1277 						wan_v4_addr_gw = data->ipv4_addr_gw;
1278 						wan_v4_addr_gw_set = true;
1279 						/* Check & construct STA header */
1280 						handle_sta_header_add_evt();
1281 #else
1282 						IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d)\n", dev_name,data->iptype);
1283 #endif
1284 						if (active_v4 == false)
1285 						{
1286 							handle_route_add_evt(data->iptype);
1287 						}
1288 					}
1289 #ifdef FEATURE_IPA_ANDROID
1290 #ifndef FEATURE_IPACM_HAL
1291 					/* Fixed CR 2438491 for HAL-android platform trgets.
1292 					   Need to revisit for non-hal-android-platform targets if issue could be reproduced there as well */
1293 					/* using ipa_if_index, not netdev_index */
1294 					post_wan_up_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether));
1295 #endif
1296 #endif
1297 				}
1298 				else if ((data->iptype == IPA_IP_v6) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
1299 				{
1300 					if(ipv6_prefix[0] == 0 && ipv6_prefix[1] == 0)
1301 					{
1302 						IPACMDBG_H("IPv6 default route comes earlier than global IP, ignore.\n");
1303 						return;
1304 					}
1305 
1306 					if (active_v6 == false)
1307 					{
1308 						IPACMDBG_H("\n get default v6 route (dst:00.00.00.00) upstream\n");
1309 #ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
1310 						IPACMDBG_H(" IPV6 gateway: %08x:%08x:%08x:%08x \n",
1311 								data->ipv6_addr_gw[0], data->ipv6_addr_gw[1], data->ipv6_addr_gw[2], data->ipv6_addr_gw[3]);
1312 						wan_v6_addr_gw[0] = data->ipv6_addr_gw[0];
1313 						wan_v6_addr_gw[1] = data->ipv6_addr_gw[1];
1314 						wan_v6_addr_gw[2] = data->ipv6_addr_gw[2];
1315 						wan_v6_addr_gw[3] = data->ipv6_addr_gw[3];
1316 						wan_v6_addr_gw_set = true;
1317 						/* Check & construct STA header */
1318 						handle_sta_header_add_evt();
1319 #endif
1320 						if (active_v6 == false)
1321 						{
1322 							handle_route_add_evt(data->iptype);
1323 						}
1324 					}
1325 				}
1326 #ifdef FEATURE_IPA_ANDROID
1327 #ifndef FEATURE_IPACM_HAL
1328 				/* using ipa_if_index, not netdev_index */
1329 				post_wan_up_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether));
1330 #endif
1331 #endif
1332 
1333 			}
1334 			else /* double check if current default iface is not itself */
1335 			{
1336 				if ((data->iptype == IPA_IP_v4) && (active_v4 == true))
1337 				{
1338 					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);
1339 					IPACMDBG_H("need clean default v4 route (dst:0.0.0.0) for old iface (%s)\n", dev_name);
1340 					wan_v4_addr_gw_set = false;
1341 					if(m_is_sta_mode == Q6_WAN)
1342 					{
1343 						del_wan_firewall_rule(IPA_IP_v4);
1344 						install_wan_filtering_rule(false);
1345 						handle_route_del_evt_ex(IPA_IP_v4);
1346 					}
1347 					else if(m_is_sta_mode == Q6_MHI_WAN)
1348 					{
1349 						/* only need cleanup rt-rule*/
1350 						handle_route_del_evt(IPA_IP_v4);
1351 					}
1352 					else
1353 					{
1354 						del_dft_firewall_rules(IPA_IP_v4);
1355 						handle_route_del_evt(IPA_IP_v4);
1356 					}
1357 				}
1358 				else if ((data->iptype == IPA_IP_v6) && (active_v6 == true))
1359 				{
1360 				    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);
1361 					IPACMDBG_H("need clean default v6 route for old iface (%s)\n", dev_name);
1362 					if(m_is_sta_mode == Q6_WAN)
1363 					{
1364 						del_wan_firewall_rule(IPA_IP_v6);
1365 						install_wan_filtering_rule(false);
1366 						handle_route_del_evt_ex(IPA_IP_v6);
1367 					}
1368 					else if(m_is_sta_mode == Q6_MHI_WAN)
1369 					{
1370 						/* only need cleanup rt-rule*/
1371 						handle_route_del_evt(IPA_IP_v6);
1372 					}
1373 					else
1374 					{
1375 						del_dft_firewall_rules(IPA_IP_v6);
1376 						handle_route_del_evt(IPA_IP_v6);
1377 					}
1378 				}
1379 			}
1380 		}
1381 		break;
1382 
1383 	case IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT:
1384 		{
1385 			ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param;
1386 			ipa_interface_index = iface_ipa_index_query(data->if_index);
1387 #ifndef FEATURE_IPACM_HAL
1388 			/* add the check see if tether_iface is valid or not */
1389 			if (iface_ipa_index_query(data->if_index_tether) == INVALID_IFACE)
1390 			{
1391 				IPACMERR("UPSTREAM_ROUTE_DEL tether_if(%d), not valid ignore\n", INVALID_IFACE);
1392 				return;
1393 			}
1394 #endif
1395 			if (ipa_interface_index == ipa_if_num)
1396 			{
1397 				IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT\n");
1398 				if ((data->iptype == IPA_IP_v4) && (active_v4 == true))
1399 				{
1400 					IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n");
1401 					wan_v4_addr_gw_set = false;
1402 #ifdef FEATURE_IPA_ANDROID
1403 #ifdef FEATURE_IPACM_HAL
1404 					post_wan_down_tether_evt(data->iptype, 0);
1405 #else
1406 					/* using ipa_if_index, not netdev_index */
1407 					post_wan_down_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether));
1408 					/* no any ipv4 tether iface support*/
1409 					if(IPACM_Wan::ipa_if_num_tether_v4_total != 0)
1410 					{
1411 						IPACMDBG_H("still have tether ipv4 client on upsteam iface\n");
1412 						return;
1413 					}
1414 #endif
1415 #endif
1416 					if(m_is_sta_mode == Q6_WAN)
1417 					{
1418 						del_wan_firewall_rule(IPA_IP_v4);
1419 						install_wan_filtering_rule(false);
1420 						handle_route_del_evt_ex(IPA_IP_v4);
1421 					}
1422 					else if(m_is_sta_mode == Q6_MHI_WAN)
1423 					{
1424 						/* only need cleanup rt-rule*/
1425 						del_dft_firewall_rules(IPA_IP_v4);
1426 						handle_route_del_evt(IPA_IP_v4);
1427 					}
1428 					else
1429 					{
1430 						del_dft_firewall_rules(IPA_IP_v4);
1431 						handle_route_del_evt(IPA_IP_v4);
1432 					}
1433 				}
1434 				else if ((data->iptype == IPA_IP_v6) && (active_v6 == true))
1435 				{
1436 #ifdef FEATURE_IPA_ANDROID
1437 #ifdef FEATURE_IPACM_HAL
1438 					post_wan_down_tether_evt(data->iptype, 0);
1439 #else
1440 
1441 					/* using ipa_if_index, not netdev_index */
1442 					post_wan_down_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether));
1443 					/* no any ipv6 tether iface support*/
1444 					if(IPACM_Wan::ipa_if_num_tether_v6_total != 0)
1445 					{
1446 						IPACMDBG_H("still have tether ipv6 client on upsteam iface\n");
1447 						return;
1448 					}
1449 #endif
1450 #endif
1451 					if(m_is_sta_mode == Q6_WAN)
1452 					{
1453 						del_wan_firewall_rule(IPA_IP_v6);
1454 						install_wan_filtering_rule(false);
1455 						handle_route_del_evt_ex(IPA_IP_v6);
1456 					}
1457 					else if(m_is_sta_mode == Q6_MHI_WAN)
1458 					{
1459 						/* only need cleanup rt-rule*/
1460 						del_dft_firewall_rules(IPA_IP_v6);
1461 						handle_route_del_evt(IPA_IP_v6);
1462 					}
1463 
1464 					else
1465 					{
1466 						del_dft_firewall_rules(IPA_IP_v6);
1467 						handle_route_del_evt(IPA_IP_v6);
1468 					}
1469 				}
1470 			}
1471 		}
1472 		break;
1473 	case IPA_NETWORK_STATS_UPDATE_EVENT:
1474 		{
1475 			ipa_get_apn_data_stats_resp_msg_v01 *data = (ipa_get_apn_data_stats_resp_msg_v01 *)param;
1476 			if (!data->apn_data_stats_list_valid)
1477 			{
1478 				IPACMERR("not valid APN\n");
1479 				return;
1480 			}
1481 			else
1482 			{
1483 				handle_network_stats_update(data);
1484 			}
1485 		}
1486 		break;
1487 	case IPA_ROUTE_ADD_EVENT:
1488 		{
1489 			ipacm_event_data_addr *data = (ipacm_event_data_addr *)param;
1490 			ipa_interface_index = iface_ipa_index_query(data->if_index);
1491 			if (ipa_interface_index == ipa_if_num)
1492 			{
1493 				IPACMDBG_H("Received IPA_ROUTE_ADD_EVENT\n");
1494 				IPACMDBG_H("ipv4 addr 0x%x\n", data->ipv4_addr);
1495 				IPACMDBG_H("ipv4 addr mask 0x%x\n", data->ipv4_addr_mask);
1496 
1497 				/* The special below condition is to handle default gateway */
1498 				if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == false)
1499 					&& (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX))
1500 				{
1501 					wan_v4_addr_gw = data->ipv4_addr_gw;
1502 					wan_v4_addr_gw_set = true;
1503 					IPACMDBG_H("adding routing table, dev (%s) ip-type(%d), default gw (%x)\n", dev_name,data->iptype, wan_v4_addr_gw);
1504 					/* Check & construct STA header */
1505 					handle_sta_header_add_evt();
1506 					handle_route_add_evt(data->iptype);
1507 					/* Add IPv6 routing table if XLAT is enabled */
1508 					if(is_xlat_local && (m_is_sta_mode == Q6_WAN) && (active_v6 == false))
1509 					{
1510 						IPACMDBG_H("XLAT enabled: adding IPv6 routing table dev (%s)\n", dev_name);
1511 						handle_route_add_evt(IPA_IP_v6);
1512 					}
1513 				}
1514 				else if ((data->iptype == IPA_IP_v6) &&
1515 						(!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) &&
1516 						(active_v6 == false) &&	(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
1517 				{
1518 					if(ipv6_prefix[0] == 0 && ipv6_prefix[1] == 0)
1519 					{
1520 						IPACMDBG_H("IPv6 default route comes earlier than global IP, ignore.\n");
1521 						return;
1522 					}
1523 
1524 					IPACMDBG_H("\n get default v6 route (dst:00.00.00.00)\n");
1525 					IPACMDBG_H(" IPV6 dst: %08x:%08x:%08x:%08x \n",
1526 							data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
1527 					IPACMDBG_H(" IPV6 gateway: %08x:%08x:%08x:%08x \n",
1528 							data->ipv6_addr_gw[0], data->ipv6_addr_gw[1], data->ipv6_addr_gw[2], data->ipv6_addr_gw[3]);
1529 					wan_v6_addr_gw[0] = data->ipv6_addr_gw[0];
1530 					wan_v6_addr_gw[1] = data->ipv6_addr_gw[1];
1531 					wan_v6_addr_gw[2] = data->ipv6_addr_gw[2];
1532 					wan_v6_addr_gw[3] = data->ipv6_addr_gw[3];
1533 					wan_v6_addr_gw_set = true;
1534 					/* Check & construct STA header */
1535 					handle_sta_header_add_evt();
1536 					handle_route_add_evt(data->iptype);
1537 				}
1538 			}
1539 			else /* double check if current default iface is not itself */
1540 			{
1541 				if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == true))
1542 				{
1543 					IPACMDBG_H("Received v4 IPA_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
1544 					IPACMDBG_H("ipv4 addr 0x%x\n", data->ipv4_addr);
1545 					IPACMDBG_H("ipv4 addr mask 0x%x\n", data->ipv4_addr_mask);
1546 					IPACMDBG_H("need clean default v4 route (dst:0.0.0.0) for old iface (%s)\n", dev_name);
1547 					wan_v4_addr_gw_set = false;
1548 					if(m_is_sta_mode == Q6_WAN)
1549 					{
1550 						del_wan_firewall_rule(IPA_IP_v4);
1551 						install_wan_filtering_rule(false);
1552 						handle_route_del_evt_ex(IPA_IP_v4);
1553 					}
1554 					else
1555 					{
1556 						del_dft_firewall_rules(IPA_IP_v4);
1557 						handle_route_del_evt(IPA_IP_v4);
1558 					}
1559 				}
1560 				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))
1561 				{
1562 				    IPACMDBG_H("Received v6 IPA_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
1563 					IPACMDBG_H("need clean default v6 route for old iface (%s)\n", dev_name);
1564 					if(m_is_sta_mode == Q6_WAN)
1565 					{
1566 						del_wan_firewall_rule(IPA_IP_v6);
1567 						install_wan_filtering_rule(false);
1568 						handle_route_del_evt_ex(IPA_IP_v6);
1569 					}
1570 					else
1571 					{
1572 						del_dft_firewall_rules(IPA_IP_v6);
1573 						handle_route_del_evt(IPA_IP_v6);
1574 					}
1575 				}
1576 			}
1577 		}
1578 		break;
1579 
1580 	case IPA_ROUTE_DEL_EVENT:
1581 		{
1582 			ipacm_event_data_addr *data = (ipacm_event_data_addr *)param;
1583 			ipa_interface_index = iface_ipa_index_query(data->if_index);
1584 			if (ipa_interface_index == ipa_if_num)
1585 			{
1586 				IPACMDBG_H("Received IPA_ROUTE_DEL_EVENT\n");
1587 				if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == true))
1588 				{
1589 					IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n");
1590 					wan_v4_addr_gw_set = false;
1591 					if(m_is_sta_mode == Q6_WAN)
1592 					{
1593 						del_wan_firewall_rule(IPA_IP_v4);
1594 						install_wan_filtering_rule(false);
1595 						handle_route_del_evt_ex(IPA_IP_v4);
1596 
1597 						if(is_xlat_local && active_v6 == true)
1598 						{
1599 							IPACMDBG_H("XLAT enabled: Delete IPv6 routing table dev (%s)\n", dev_name);
1600 							del_wan_firewall_rule(IPA_IP_v6);
1601 							install_wan_filtering_rule(false);
1602 							handle_route_del_evt_ex(IPA_IP_v6);
1603 						}
1604 					}
1605 					else
1606 					{
1607 						del_dft_firewall_rules(IPA_IP_v4);
1608 						handle_route_del_evt(IPA_IP_v4);
1609 					}
1610 				}
1611 				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))
1612 				{
1613 
1614 					IPACMDBG_H("get del default v6 route (dst:00.00.00.00)\n");
1615 					if(m_is_sta_mode == Q6_WAN)
1616 					{
1617 						del_wan_firewall_rule(IPA_IP_v6);
1618 						install_wan_filtering_rule(false);
1619 						handle_route_del_evt_ex(IPA_IP_v6);
1620 					}
1621 					else
1622 					{
1623 						del_dft_firewall_rules(IPA_IP_v6);
1624 						handle_route_del_evt(IPA_IP_v6);
1625 					}
1626 				}
1627 			}
1628 		}
1629 		break;
1630 
1631 	case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
1632 		{
1633 			ipacm_event_data_all *data = (ipacm_event_data_all *)param;
1634 			ipa_interface_index = iface_ipa_index_query(data->if_index);
1635 			int index = 0;
1636 			bool renew = false;
1637 
1638 			if (ipa_interface_index == ipa_if_num)
1639 			{
1640 				IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n");
1641 
1642 				if (m_is_sta_mode == WLAN_WAN)
1643 				{
1644 					if (data->iptype == IPA_IP_v4 && data->ipv4_addr == wan_v4_addr)
1645 					{
1646 						IPACMDBG_H("Ignore IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n");
1647 						IPACMDBG_H("for its own ipv4 address\n");
1648 						return;
1649 					}
1650 					else if (data->iptype == IPA_IP_v6)
1651 					{
1652 						for (uint32_t num_ipv6_addr = 0; num_ipv6_addr < num_dft_rt_v6; num_ipv6_addr++)
1653 						{
1654 							if ((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
1655 								(ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
1656 								(ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
1657 								(ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
1658 							{
1659 								IPACMDBG_H("Ignore IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n");
1660 								IPACMDBG_H("for its own ipv6 address\n");
1661 								return;
1662 							}
1663 						}
1664 					}
1665 				}
1666 
1667 				IPACMDBG_H("wan-iface got client \n");
1668 
1669 				/* first construc WAN-client full header */
1670 				if(memcmp(data->mac_addr,
1671 						invalid_mac,
1672 						sizeof(data->mac_addr)) == 0)
1673 				{
1674 					IPACMDBG_H("Received invalid Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1675 					 data->mac_addr[0], data->mac_addr[1], data->mac_addr[2],
1676 					 data->mac_addr[3], data->mac_addr[4], data->mac_addr[5]);
1677 					return;
1678 				}
1679 
1680 				/* check if same as GW_ip need replacing */
1681 				if( handle_gw_mac_renew(data, index) == IPACM_SUCCESS)
1682 				{
1683 					renew = true;
1684 					IPACMDBG_H("Renew is happening with client-index (%d)\n", index);
1685 					/* clinet renew procedure */
1686 					handle_wan_hdr_init(data->mac_addr, true, index);
1687 				}
1688 				else
1689 				{
1690 					IPACMDBG_H("Renew is no need!\n");
1691 					handle_wan_hdr_init(data->mac_addr);
1692 				}
1693 
1694 				IPACMDBG_H("construct wan-client header and route rules \n");
1695 				/* Associate with IP and construct RT-rule */
1696 				if (handle_wan_client_ipaddr(data) == IPACM_FAILURE)
1697 				{
1698 					return;
1699 				}
1700 				handle_wan_client_route_rule(data->mac_addr, data->iptype);
1701 				/* Check & construct STA header */
1702 				handle_sta_header_add_evt(renew);
1703 				return;
1704 			}
1705 		}
1706 		break;
1707 
1708 	case IPA_SW_ROUTING_ENABLE:
1709 		IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n");
1710 		/* handle software routing enable event */
1711 		if(m_is_sta_mode == Q6_WAN)
1712 		{
1713 			install_wan_filtering_rule(true);
1714 		}
1715 		else if(m_is_sta_mode == Q6_MHI_WAN)
1716 		{
1717 			handle_software_routing_enable(true);
1718 		}
1719 		else
1720 		{
1721 			handle_software_routing_enable(false);
1722 		}
1723 		break;
1724 
1725 	case IPA_SW_ROUTING_DISABLE:
1726 		IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n");
1727 		/* handle software routing disable event */
1728 		if(m_is_sta_mode == Q6_WAN)
1729 		{
1730 			/* send current DL rules to modem */
1731 			install_wan_filtering_rule(false);
1732 			softwarerouting_act = false;
1733 		}
1734 		else if(m_is_sta_mode == Q6_MHI_WAN)
1735 		{
1736 			handle_software_routing_disable(true);
1737 		}
1738 		else
1739 		{
1740 			handle_software_routing_disable(false);
1741 		}
1742 		break;
1743 
1744 	case IPA_FIREWALL_CHANGE_EVENT:
1745 		IPACMDBG_H("Received IPA_FIREWALL_CHANGE_EVENT\n");
1746 
1747 		if(m_is_sta_mode == Q6_WAN)
1748 		{
1749 			if(is_default_gateway == false)
1750 			{
1751 				IPACMDBG_H("Interface %s is not default gw, return.\n", dev_name);
1752 				return;
1753 			}
1754 
1755 			if(ip_type == IPA_IP_v4)
1756 			{
1757 				del_wan_firewall_rule(IPA_IP_v4);
1758 				config_wan_firewall_rule(IPA_IP_v4);
1759 				install_wan_filtering_rule(false);
1760 			}
1761 			else if(ip_type == IPA_IP_v6)
1762 			{
1763 				del_wan_firewall_rule(IPA_IP_v6);
1764 				config_wan_firewall_rule(IPA_IP_v6);
1765 				install_wan_filtering_rule(false);
1766 			}
1767 			else if(ip_type == IPA_IP_MAX)
1768 			{
1769 				del_wan_firewall_rule(IPA_IP_v4);
1770 				config_wan_firewall_rule(IPA_IP_v4);
1771 
1772 				del_wan_firewall_rule(IPA_IP_v6);
1773 				config_wan_firewall_rule(IPA_IP_v6);
1774 				install_wan_filtering_rule(false);
1775 			}
1776 			else
1777 			{
1778 				IPACMERR("IP type is not expected.\n");
1779 			}
1780 		}
1781 		else
1782 		{
1783 			if (active_v4)
1784 			{
1785 				del_dft_firewall_rules(IPA_IP_v4);
1786 				config_dft_firewall_rules(IPA_IP_v4);
1787 			}
1788 			if (active_v6)
1789 			{
1790 
1791 				del_dft_firewall_rules(IPA_IP_v6);
1792 				config_dft_firewall_rules(IPA_IP_v6);
1793 			}
1794 		}
1795 		break;
1796 
1797 	case IPA_WLAN_SWITCH_TO_SCC:
1798 		if(IPACM_Wan::backhaul_mode == WLAN_WAN)
1799 		{
1800 			IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n");
1801 			if(ip_type == IPA_IP_MAX)
1802 			{
1803 				handle_wlan_SCC_MCC_switch(true, IPA_IP_v4);
1804 				handle_wlan_SCC_MCC_switch(true, IPA_IP_v6);
1805 				handle_wan_client_SCC_MCC_switch(true, IPA_IP_v4);
1806 				handle_wan_client_SCC_MCC_switch(true, IPA_IP_v6);
1807 			}
1808 			else
1809 			{
1810 				handle_wlan_SCC_MCC_switch(true, ip_type);
1811 				handle_wan_client_SCC_MCC_switch(true, ip_type);
1812 			}
1813 		}
1814 		break;
1815 
1816 	case IPA_WLAN_SWITCH_TO_MCC:
1817 		if(IPACM_Wan::backhaul_mode == WLAN_WAN)
1818 		{
1819 			IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n");
1820 			if(ip_type == IPA_IP_MAX)
1821 			{
1822 				handle_wlan_SCC_MCC_switch(false, IPA_IP_v4);
1823 				handle_wlan_SCC_MCC_switch(false, IPA_IP_v6);
1824 				handle_wan_client_SCC_MCC_switch(false, IPA_IP_v4);
1825 				handle_wan_client_SCC_MCC_switch(false, IPA_IP_v6);
1826 			}
1827 			else
1828 			{
1829 				handle_wlan_SCC_MCC_switch(false, ip_type);
1830 				handle_wan_client_SCC_MCC_switch(false, ip_type);
1831 			}
1832 		}
1833 		break;
1834 #ifdef FEATURE_IPACM_HAL
1835 	/* WA for WLAN to clean up NAT instance during SSR */
1836 	case IPA_SSR_NOTICE:
1837 	case IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE:
1838 	{
1839 		IPACMDBG_H("Received IPA_SSR_NOTICE event.\n");
1840 		if(m_is_sta_mode == WLAN_WAN)
1841 		{
1842 			IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
1843 		}
1844 	}
1845 	break;
1846 #endif
1847 #ifdef IPA_MTU_EVENT_MAX
1848 	case IPA_MTU_SET:
1849 	{
1850 		ipacm_event_mtu_info *data = (ipacm_event_mtu_info *)param;
1851 		ipa_mtu_info *mtu_info = &(data->mtu_info);
1852 		ipa_interface_index = iface_ipa_index_query(data->if_index);
1853 
1854 		if (ipa_interface_index == ipa_if_num)
1855 		{
1856 			IPACMDBG_H("Received IPA_MTU_SET (Android) for interface (%d)\n",
1857 				ipa_interface_index);
1858 			if (mtu_info->ip_type == IPA_IP_v4 || mtu_info->ip_type == IPA_IP_MAX)
1859 			{
1860 				/* Update v4_mtu. */
1861 				mtu_v4 = mtu_info->mtu_v4;
1862 				mtu_v4_set = true;
1863 
1864 				if (active_v4)
1865 				{
1866 					/* upstream interface. update default MTU. */
1867 					mtu_default_wan_v4 = mtu_v4;
1868 				}
1869 				IPACMDBG_H("Updated v4 mtu=[%d] for (%s), upstream_mtu=[%d]\n",
1870 					mtu_v4, mtu_info->if_name, mtu_default_wan_v4);
1871 			}
1872 			if (mtu_info->ip_type == IPA_IP_v6 || mtu_info->ip_type == IPA_IP_MAX)
1873 			{
1874 				/* Update v4_mtu. */
1875 				mtu_v6 = mtu_info->mtu_v6;
1876 				mtu_v6_set = true;
1877 				if (active_v6)
1878 				{
1879 					/* upstream interface. update default MTU. */
1880 					mtu_default_wan_v6 = mtu_v6;
1881 				}
1882 				IPACMDBG_H("Updated v6 mtu=[%d] for (%s), upstream_mtu=[%d]\n",
1883 					mtu_v6, mtu_info->if_name, mtu_default_wan_v6);
1884 			}
1885 
1886 			if (active_v4 || active_v6)
1887 			{
1888 				ipacm_event_mtu_info *mtu_event;
1889 				ipacm_cmd_q_data evt_data;
1890 				mtu_event = (ipacm_event_mtu_info *)malloc(sizeof(*mtu_event));
1891 				if(mtu_event == NULL)
1892 				{
1893 					IPACMERR("Failed to allocate memory.\n");
1894 					return;
1895 				}
1896 				memcpy(&mtu_event->mtu_info, mtu_info, sizeof(ipa_mtu_info));
1897 				evt_data.event = IPA_MTU_UPDATE;
1898 				evt_data.evt_data = mtu_event;
1899 				/* finish command queue */
1900 				IPACMDBG_H("Posting IPA_MTU_UPDATE event\n");
1901 				IPACM_EvtDispatcher::PostEvt(&evt_data);
1902 			}
1903 		}
1904 	}
1905 	break;
1906 #endif
1907 
1908 	default:
1909 		break;
1910 	}
1911 
1912 	return;
1913 }
1914 
1915 /* wan default route/filter rule configuration */
handle_route_add_evt(ipa_ip_type iptype,bool add_only)1916 int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype, bool add_only)
1917 {
1918 	/* add default WAN route */
1919 	struct ipa_ioc_add_rt_rule *rt_rule = NULL;
1920 	struct ipa_rt_rule_add *rt_rule_entry;
1921 	uint32_t tx_index = 0;
1922 	const int NUM = 1;
1923 	ipacm_cmd_q_data evt_data;
1924 	struct ipa_ioc_get_hdr hdr;
1925 	bool result;
1926 #ifdef	WAN_IOC_NOTIFY_WAN_STATE //resolve compile issue on 4.9 kernel
1927 	struct wan_ioctl_notify_wan_state wan_state;
1928 	int fd_wwan_ioctl;
1929 	memset(&wan_state, 0, sizeof(wan_state));
1930 #endif
1931 	IPACMDBG_H("ip-type:%d\n", iptype);
1932 
1933 	/* copy header from tx-property, see if partial or not */
1934 	/* assume all tx-property uses the same header name for v4 or v6*/
1935 
1936 	if(tx_prop == NULL)
1937 	{
1938 		IPACMDBG_H("No tx properties, ignore default route setting\n");
1939 		return IPACM_SUCCESS;
1940 	}
1941 
1942 	is_default_gateway = true;
1943 	IPACMDBG_H("Default route is added to iface %s.\n", dev_name);
1944 
1945 	if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE)
1946 	{
1947 		IPACM_Wan::backhaul_is_wan_bridge = true;
1948 	}
1949 	else
1950 	{
1951 		IPACM_Wan::backhaul_is_wan_bridge = false;
1952 	}
1953 	IPACMDBG_H("backhaul_is_wan_bridge ?: %d \n", IPACM_Wan::backhaul_is_wan_bridge);
1954 
1955 	/* query MTU size of the interface if MTU is not set via ioctl. */
1956 	if (!mtu_v4_set && !mtu_v6_set)
1957 	{
1958 		if(query_mtu_size())
1959 		{
1960 			IPACMERR("Failed to query mtu");
1961 		}
1962 	}
1963 
1964 	if (m_is_sta_mode ==Q6_WAN)
1965 	{
1966 		IPACM_Wan::backhaul_mode = m_is_sta_mode;
1967 		IPACMDBG_H("reset backhaul to LTE \n");
1968 
1969 		if (iface_query != NULL && iface_query->num_ext_props > 0)
1970 		{
1971 			if(ext_prop == NULL)
1972 			{
1973 				IPACMERR("Extended property is empty.\n");
1974 				return IPACM_FAILURE;
1975 			}
1976 			else
1977 			{
1978 				IPACM_Iface::ipacmcfg->SetQmapId(ext_prop->ext[0].mux_id);
1979 				IPACMDBG_H("Setting up QMAP ID %d.\n", ext_prop->ext[0].mux_id);
1980 			}
1981 		}
1982 		else
1983 		{
1984 			IPACMERR("iface_query is empty.\n");
1985 			return IPACM_FAILURE;
1986 		}
1987 	}
1988 	else if (m_is_sta_mode == Q6_MHI_WAN)
1989 	{
1990 		if (iface_query != NULL && iface_query->num_ext_props > 0)
1991 		{
1992 			/* treat Q6_MHI_WAN as STA mode also */
1993 			IPACMDBG_H("Q6-MHI  ipv4/v6-header already constructed \n");
1994 			IPACM_Wan::backhaul_mode = m_is_sta_mode;
1995 			IPACMDBG_H("Setting up QMAP ID %d.\n", ext_prop->ext[0].mux_id);
1996 			IPACM_Iface::ipacmcfg->SetQmapId(ext_prop->ext[0].mux_id);
1997 			/* sending mux-id info to PCIE-modem for UL */
1998 			if(false == m_filtering.AddOffloadFilteringRule(NULL, ext_prop->ext[0].mux_id, 0))
1999 			{
2000 				IPACMERR("Failed to send mux id info to modem.\n");
2001 				return IPACM_FAILURE;
2002 			}
2003 			/* send UL UDP frag filtering rule */
2004 			if(iptype==IPA_IP_v4 && add_offload_frag_rule())
2005 			{
2006 				IPACMERR("Failed to send DL frag rule to modem.\n");
2007 				return IPACM_FAILURE;
2008 			}
2009 
2010 			/* send ipv6 ICMP filtering rule */
2011 			if(iptype==IPA_IP_v6 && add_icmpv6_exception_rule())
2012 			{
2013 				IPACMERR("Failed to send ICMPv6 ex rule to modem.\n");
2014 				return IPACM_FAILURE;
2015 			}
2016 
2017 			/* send ipv4 TCP FIN filtering rule */
2018 			if(iptype==IPA_IP_v4 && add_tcp_fin_rst_exception_rule())
2019 			{
2020 				IPACMERR("Failed to send TCP FIN RST rule to modem.\n");
2021 				return IPACM_FAILURE;
2022 			}
2023 		}
2024 		else
2025 		{
2026 			IPACMERR("iface_query is empty.\n");
2027 			return IPACM_FAILURE;
2028 		}
2029 	}
2030 	else
2031 	{
2032 		IPACM_Wan::backhaul_mode = m_is_sta_mode;
2033 		if((iptype==IPA_IP_v4) && (header_set_v4 != true))
2034 		{
2035 			header_partial_default_wan_v4 = true;
2036 			IPACMDBG_H("STA ipv4-header haven't constructed \n");
2037 			return IPACM_SUCCESS;
2038 		}
2039 		else if((iptype==IPA_IP_v6) && (header_set_v6 != true))
2040 		{
2041 			header_partial_default_wan_v6 = true;
2042 			IPACMDBG_H("STA ipv6-header haven't constructed \n");
2043 			return IPACM_SUCCESS;
2044 		}
2045 	}
2046 
2047 	rt_rule = (struct ipa_ioc_add_rt_rule *)
2048 		 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
2049 						NUM * sizeof(struct ipa_rt_rule_add));
2050 
2051 	if (!rt_rule)
2052 	{
2053 		IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
2054 		return IPACM_FAILURE;
2055 	}
2056 
2057 	rt_rule->commit = 1;
2058 	rt_rule->num_rules = (uint8_t)NUM;
2059 	rt_rule->ip = iptype;
2060 
2061 	rt_rule_entry = &rt_rule->rules[0];
2062 	rt_rule_entry->at_rear = true;
2063 
2064 	if(m_is_sta_mode != Q6_WAN)
2065 	{
2066 		IPACMDBG_H(" WAN instance is in STA mode \n");
2067 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2068 		{
2069 			if(iptype != tx_prop->tx[tx_index].ip)
2070 			{
2071 				IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n",
2072 									tx_index, tx_prop->tx[tx_index].ip,iptype);
2073 				continue;
2074 			}
2075 
2076 			/* use the STA-header handler */
2077 			if (iptype == IPA_IP_v4)
2078 			{
2079 				strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name, sizeof(rt_rule->rt_tbl_name));
2080 				rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v4;
2081 			}
2082 			else
2083 			{
2084 				strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
2085 				rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v6;
2086 			}
2087 
2088 			IPACMDBG_H(" WAN table created %s \n", rt_rule->rt_tbl_name);
2089 			/* replace the hdr handle for q6_PCIE*/
2090 			if(m_is_sta_mode == Q6_MHI_WAN)
2091 			{
2092 				memset(&hdr, 0, sizeof(hdr));
2093 				strlcpy(hdr.name, tx_prop->tx[tx_index].hdr_name, sizeof(hdr.name));
2094 				hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2095 				if(m_header.GetHeaderHandle(&hdr) == false)
2096 				{
2097 					IPACMERR("Failed to get QMAP header.\n");
2098 					free(rt_rule);
2099 					return IPACM_FAILURE;
2100 				}
2101 				rt_rule_entry->rule.hdr_hdl = hdr.hdl;
2102 				rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2103 			}
2104 			else
2105 			{
2106 				if(IPACM_Iface::ipacmcfg->isMCC_Mode == true)
2107 				{
2108 					IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
2109 							tx_prop->tx[tx_index].alt_dst_pipe);
2110 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
2111 				}
2112 				else
2113 				{
2114 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2115 				}
2116 			}
2117 			memcpy(&rt_rule_entry->rule.attrib,
2118 						 &tx_prop->tx[tx_index].attrib,
2119 						 sizeof(rt_rule_entry->rule.attrib));
2120 
2121 			rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2122 			if (iptype == IPA_IP_v4)
2123 			{
2124 				rt_rule_entry->rule.attrib.u.v4.dst_addr      = 0;
2125 				rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0;
2126 				if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2127 					rt_rule_entry->rule.hashable = true;
2128 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
2129 				/* use index hw-counter */
2130 				if((m_is_sta_mode == WLAN_WAN) && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
2131 				{
2132 					IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_HW);
2133 					result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_HW);
2134 				} else {
2135 					result = m_routing.AddRoutingRule(rt_rule);
2136 				}
2137 #else
2138 				result = m_routing.AddRoutingRule(rt_rule);
2139 #endif
2140 				if (result == false)
2141 				{
2142 		    		IPACMERR("Routing rule addition failed!\n");
2143 		    		free(rt_rule);
2144 		    		return IPACM_FAILURE;
2145 				}
2146 				wan_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
2147 				IPACMDBG_H("Got ipv4 wan-route rule hdl:0x%x,tx:%d,ip-type: %d \n",
2148 							 wan_route_rule_v4_hdl[tx_index],
2149 							 tx_index,
2150 							 iptype);
2151 			}
2152 			else
2153 			{
2154 				rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0;
2155 				rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0;
2156 				rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0;
2157 				rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0;
2158 				rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0;
2159 				rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0;
2160 				rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0;
2161 				rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0;
2162 				if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2163 					rt_rule_entry->rule.hashable = true;
2164 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
2165 				/* use index hw-counter */
2166 				if((m_is_sta_mode == WLAN_WAN) && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
2167 				{
2168 					IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_HW);
2169 					result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_HW);
2170 				} else {
2171 					result = m_routing.AddRoutingRule(rt_rule);
2172 				}
2173 #else
2174 				result = m_routing.AddRoutingRule(rt_rule);
2175 #endif
2176 				if (result == false)
2177 				{
2178 		    		IPACMERR("Routing rule addition failed!\n");
2179 		    		free(rt_rule);
2180 		    		return IPACM_FAILURE;
2181 				}
2182 				wan_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
2183 				IPACMDBG_H("Set ipv6 wan-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n",
2184 							 wan_route_rule_v6_hdl[tx_index],
2185 							 tx_index,
2186 							 iptype);
2187 			}
2188 		}
2189 	}
2190 
2191 	/* add a catch-all rule in wan dl routing table */
2192 
2193 	if (iptype == IPA_IP_v6 && m_is_sta_mode != Q6_MHI_WAN)
2194 	{
2195 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
2196 		IPACMDBG_H(" WAN table created %s \n", rt_rule->rt_tbl_name);
2197 		memset(rt_rule_entry, 0, sizeof(struct ipa_rt_rule_add));
2198 		rt_rule_entry->at_rear = true;
2199 		if(m_is_sta_mode == Q6_WAN)
2200 		{
2201 			memset(&hdr, 0, sizeof(hdr));
2202 			strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
2203 			hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2204 			if(m_header.GetHeaderHandle(&hdr) == false)
2205 			{
2206 				IPACMERR("Failed to get QMAP header.\n");
2207 				free(rt_rule);
2208 				return IPACM_FAILURE;
2209 			}
2210 			rt_rule_entry->rule.hdr_hdl = hdr.hdl;
2211 			rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
2212 		}
2213 		else
2214 		{
2215 			/* create dummy ethernet header for v6 RX path */
2216 			IPACMDBG_H("Construct dummy ethernet_header\n");
2217 			if (add_dummy_rx_hdr())
2218 			{
2219 				IPACMERR("Construct dummy ethernet_header failed!\n");
2220 				free(rt_rule);
2221 				return IPACM_FAILURE;
2222 			}
2223 			rt_rule_entry->rule.hdr_proc_ctx_hdl = hdr_proc_hdl_dummy_v6;
2224 			rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
2225 		}
2226 		rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
2227 		rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0;
2228 		rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0;
2229 		rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0;
2230 		rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0;
2231 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0;
2232 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0;
2233 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0;
2234 		rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0;
2235 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2236 			rt_rule_entry->rule.hashable = true;
2237 		if (false == m_routing.AddRoutingRule(rt_rule))
2238 		{
2239 			IPACMERR("Routing rule addition failed!\n");
2240 			free(rt_rule);
2241 			return IPACM_FAILURE;
2242 		}
2243 		wan_route_rule_v6_hdl_a5[0] = rt_rule_entry->rt_rule_hdl;
2244 		IPACMDBG_H("Set ipv6 wan-route rule hdl for v6_wan_table:0x%x,tx:%d,ip-type: %d \n",
2245 				wan_route_rule_v6_hdl_a5[0], 0, iptype);
2246 	}
2247 
2248 	/* support delete only, not post wan_down event */
2249 	if (add_only)
2250 	{
2251 		IPACMDBG_H(" Only add default WAN routing rules (%d)\n", add_only);
2252 		if(rt_rule != NULL)
2253 		{
2254 			free(rt_rule);
2255 		}
2256 		return IPACM_SUCCESS;
2257 	}
2258 
2259 	ipacm_event_iface_up *wanup_data;
2260 	wanup_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up));
2261 	if (wanup_data == NULL)
2262 	{
2263 		IPACMERR("Unable to allocate memory\n");
2264 		free(rt_rule);
2265 		return IPACM_FAILURE;
2266 	}
2267 	memset(wanup_data, 0, sizeof(ipacm_event_iface_up));
2268 
2269 	/* handling filter rule construction */
2270 	if (iptype == IPA_IP_v4)
2271 	{
2272 		/* set mtu_default_wan to current default wan instance */
2273 		mtu_default_wan_v4 = mtu_v4;
2274 		IPACMDBG_H("replace the mtu_wan to %d\n", mtu_default_wan_v4);
2275 
2276 		IPACM_Wan::wan_up = true;
2277 		active_v4 = true;
2278 		memcpy(IPACM_Wan::wan_up_dev_name,
2279 			dev_name,
2280 				sizeof(IPACM_Wan::wan_up_dev_name));
2281 
2282 		if(m_is_sta_mode == Q6_WAN)
2283 		{
2284 			config_wan_firewall_rule(IPA_IP_v4);
2285 			install_wan_filtering_rule(false);
2286 		}
2287 		else
2288 		{
2289 			config_dft_firewall_rules(IPA_IP_v4);
2290 		}
2291 
2292 		memcpy(wanup_data->ifname, dev_name, sizeof(wanup_data->ifname));
2293 		wanup_data->ipv4_addr = wan_v4_addr;
2294 		wanup_data->backhaul_type = m_is_sta_mode;
2295 		IPACMDBG_H("Posting IPA_HANDLE_WAN_UP with below information:\n");
2296 		IPACMDBG_H("if_name:%s, ipv4_address:0x%x, is sta mode:%d\n",
2297 				wanup_data->ifname, wanup_data->ipv4_addr, wanup_data->backhaul_type);
2298 		memset(&evt_data, 0, sizeof(evt_data));
2299 
2300 		/* set backhaul type as xlat */
2301 		IPACM_Wan::is_xlat = is_xlat_local;
2302 
2303 		/* send xlat configuration for installing uplink rules */
2304 		if(is_xlat_local && (m_is_sta_mode == Q6_WAN))
2305 		{
2306 			IPACM_Wan::xlat_mux_id = ext_prop->ext[0].mux_id;
2307 			wanup_data->xlat_mux_id = IPACM_Wan::xlat_mux_id;
2308 			IPACMDBG_H("Set xlat configuraiton with below information:\n");
2309 			IPACMDBG_H("xlat_enabled: %d set xlat_mux_id: %d \n",
2310 					is_xlat_local, IPACM_Wan::xlat_mux_id);
2311 		}
2312 		else /*temp put xlat = 0 for Q6_MHI_WAN*/
2313 		{
2314 			IPACM_Wan::xlat_mux_id = 0;
2315 			wanup_data->xlat_mux_id = 0;
2316 			if(m_is_sta_mode != WLAN_WAN) //both q6_wan/q6_mhi_wan
2317 			{
2318 				wanup_data->mux_id = ext_prop->ext[0].mux_id;
2319 				IPACMDBG_H("mux_id: %d\n", wanup_data->mux_id);
2320 			}
2321 			else
2322 				wanup_data->mux_id = 0;
2323 			IPACMDBG_H("No xlat configuration\n");
2324 		}
2325 		evt_data.event = IPA_HANDLE_WAN_UP;
2326 		evt_data.evt_data = (void *)wanup_data;
2327 		IPACM_EvtDispatcher::PostEvt(&evt_data);
2328 
2329 #ifdef FEATURE_IPACM_HAL
2330 		post_wan_up_tether_evt(IPA_IP_v4, 0);
2331 #endif
2332 	}
2333 	else
2334 	{
2335 		/* set mtu_default_wan to current default wan instance */
2336 		mtu_default_wan_v6 = mtu_v6;
2337 		IPACMDBG_H("replace the mtu_wan to %d\n", mtu_default_wan_v6);
2338 
2339 		memcpy(backhaul_ipv6_prefix, ipv6_prefix, sizeof(backhaul_ipv6_prefix));
2340 		IPACMDBG_H("Setup backhaul ipv6 prefix to be 0x%08x%08x.\n", backhaul_ipv6_prefix[0], backhaul_ipv6_prefix[1]);
2341 
2342 		IPACM_Wan::wan_up_v6 = true;
2343 		active_v6 = true;
2344 		memcpy(IPACM_Wan::wan_up_dev_name,
2345 			dev_name,
2346 				sizeof(IPACM_Wan::wan_up_dev_name));
2347 
2348 		if(m_is_sta_mode == Q6_WAN)
2349 		{
2350 			config_wan_firewall_rule(IPA_IP_v6);
2351 			install_wan_filtering_rule(false);
2352 		}
2353 		else
2354 		{
2355 			config_dft_firewall_rules(IPA_IP_v6);
2356 		}
2357 
2358 		memcpy(wanup_data->ifname, dev_name, sizeof(wanup_data->ifname));
2359 		wanup_data->backhaul_type = m_is_sta_mode;
2360 		memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix));
2361 		IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_V6 with below information:\n");
2362 		IPACMDBG_H("if_name:%s, is sta mode: %d\n", wanup_data->ifname, wanup_data->backhaul_type);
2363 		IPACMDBG_H("ipv6 prefix: 0x%08x%08x.\n", ipv6_prefix[0], ipv6_prefix[1]);
2364 		memset(&evt_data, 0, sizeof(evt_data));
2365 		evt_data.event = IPA_HANDLE_WAN_UP_V6;
2366 		evt_data.evt_data = (void *)wanup_data;
2367 		IPACM_EvtDispatcher::PostEvt(&evt_data);
2368 
2369 #ifdef FEATURE_IPACM_HAL
2370                 post_wan_up_tether_evt(IPA_IP_v6, 0);
2371 #endif
2372 	}
2373 
2374 	if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
2375 	{
2376 			/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
2377 			IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2378 			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]);
2379 			IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
2380 	}
2381 #ifdef WAN_IOC_NOTIFY_WAN_STATE
2382 	else {
2383 			if ((m_is_sta_mode == Q6_WAN && ipa_pm_q6_check == 0 ) || (m_is_sta_mode == Q6_MHI_WAN))
2384 			{
2385 				fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
2386 				if(fd_wwan_ioctl < 0)
2387 				{
2388 					IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
2389 					free(rt_rule);
2390 					return false;
2391 				}
2392 				IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE up to IPA_PM\n");
2393 				wan_state.up = true;
2394 #ifdef WAN_IOCTL_NOTIFY_WAN_INTF_NAME
2395 				strlcpy(wan_state.upstreamIface, dev_name, IFNAMSIZ);
2396 #endif
2397 				if(ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_WAN_STATE, &wan_state))
2398 				{
2399 					IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up);
2400 				}
2401 				close(fd_wwan_ioctl);
2402 
2403 				/* Store the Offload state. */
2404 				FILE *fp = NULL;
2405 				fp = fopen(IPA_OFFLOAD_TETHER_STATE_FILE_NAME, "w");
2406 				if (fp == NULL)
2407 				{
2408 					IPACMERR("Failed to write offload state to %s, error is %d - %s\n",
2409 						IPA_OFFLOAD_TETHER_STATE_FILE_NAME, errno, strerror(errno));
2410 				}
2411 				else
2412 				{
2413 					fprintf(fp, "UPSTREAM=%s,STATE=UP", dev_name);
2414 					fclose(fp);
2415 				}
2416 			}
2417 			ipa_pm_q6_check++;
2418 			IPACMDBG_H("update ipa_pm_q6_check to %d\n", ipa_pm_q6_check);
2419 	}
2420 #endif
2421 
2422 	if(rt_rule != NULL)
2423 	{
2424 		free(rt_rule);
2425 	}
2426 	return IPACM_SUCCESS;
2427 }
2428 
2429 #ifdef FEATURE_IPA_ANDROID
2430 /* wan default route/filter rule configuration */
post_wan_up_tether_evt(ipa_ip_type iptype,int ipa_if_num_tether)2431 int IPACM_Wan::post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
2432 {
2433 	ipacm_cmd_q_data evt_data;
2434 	ipacm_event_iface_up_tehter *wanup_data;
2435 
2436 	wanup_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter));
2437 	if (wanup_data == NULL)
2438 	{
2439 		IPACMERR("Unable to allocate memory\n");
2440 		return IPACM_FAILURE;
2441 	}
2442 	memset(wanup_data, 0, sizeof(ipacm_event_iface_up_tehter));
2443 
2444 	wanup_data->if_index_tether = ipa_if_num_tether;
2445 	wanup_data->backhaul_type = m_is_sta_mode;
2446 	/* xlat mux-id*/
2447 	if(is_xlat_local && (m_is_sta_mode == Q6_WAN))
2448 		wanup_data->xlat_mux_id = ext_prop->ext[0].mux_id;
2449 	else
2450 		wanup_data->xlat_mux_id = 0;
2451 	IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_TETHER with below information:\n");
2452 	IPACMDBG_H("tether_if_name:%s, is sta mode:%d xlat_mux_id: %d\n",
2453 			IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wanup_data->backhaul_type, wanup_data->xlat_mux_id);
2454 
2455 	memset(&evt_data, 0, sizeof(evt_data));
2456 
2457 	if (iptype == IPA_IP_v4)
2458 	{
2459 		evt_data.event = IPA_HANDLE_WAN_UP_TETHER;
2460 #ifndef FEATURE_IPACM_HAL
2461 		/* Add support tether ifaces to its array*/
2462 		IPACM_Wan::ipa_if_num_tether_v4[IPACM_Wan::ipa_if_num_tether_v4_total] = ipa_if_num_tether;
2463 		IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v4_total(%d) on wan_iface(%s)\n",
2464 			IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name,
2465 			IPACM_Wan::ipa_if_num_tether_v4_total,
2466 			IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
2467 		IPACM_Wan::ipa_if_num_tether_v4_total++;
2468 #endif
2469 	}
2470 	else
2471 	{
2472 		evt_data.event = IPA_HANDLE_WAN_UP_V6_TETHER;
2473 		memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix));
2474 #ifndef FEATURE_IPACM_HAL
2475 		/* Add support tether ifaces to its array*/
2476 		IPACM_Wan::ipa_if_num_tether_v6[IPACM_Wan::ipa_if_num_tether_v6_total] = ipa_if_num_tether;
2477 		IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v6_total(%d) on wan_iface(%s)\n",
2478 			IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name,
2479 			IPACM_Wan::ipa_if_num_tether_v6_total,
2480 			IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
2481 		IPACM_Wan::ipa_if_num_tether_v6_total++;
2482 #endif
2483 	}
2484 		evt_data.evt_data = (void *)wanup_data;
2485 		IPACM_EvtDispatcher::PostEvt(&evt_data);
2486 
2487 	return IPACM_SUCCESS;
2488 }
2489 
2490 
2491 /* wan default route/filter rule configuration */
post_wan_down_tether_evt(ipa_ip_type iptype,int ipa_if_num_tether)2492 int IPACM_Wan::post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
2493 {
2494 	ipacm_cmd_q_data evt_data;
2495 	ipacm_event_iface_up_tehter *wandown_data;
2496 
2497 	wandown_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter));
2498 	if (wandown_data == NULL)
2499 	{
2500 		IPACMERR("Unable to allocate memory\n");
2501 		return IPACM_FAILURE;
2502 	}
2503 	memset(wandown_data, 0, sizeof(ipacm_event_iface_up_tehter));
2504 
2505 	wandown_data->if_index_tether = ipa_if_num_tether;
2506 	wandown_data->backhaul_type = m_is_sta_mode;
2507 	IPACMDBG_H("Posting IPA_HANDLE_WAN_DOWN_TETHER with below information:\n");
2508 	IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n",
2509 			IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wandown_data->backhaul_type);
2510 	memset(&evt_data, 0, sizeof(evt_data));
2511 
2512 	if (iptype == IPA_IP_v4)
2513 	{
2514 #ifndef FEATURE_IPACM_HAL
2515 		if(delete_tether_iface(iptype, ipa_if_num_tether))
2516 		{
2517 			IPACMDBG_H("Not finding the tethered client on ipv4.\n");
2518 			free(wandown_data);
2519 			return IPACM_SUCCESS;
2520 		}
2521 #endif
2522 		evt_data.event = IPA_HANDLE_WAN_DOWN_TETHER;
2523 	}
2524 	else
2525 	{
2526 #ifndef FEATURE_IPACM_HAL
2527 		if(delete_tether_iface(iptype, ipa_if_num_tether))
2528 		{
2529 			IPACMDBG_H("Not finding the tethered client on ipv6.\n");
2530 			free(wandown_data);
2531 			return IPACM_SUCCESS;
2532 		}
2533 #endif
2534 		evt_data.event = IPA_HANDLE_WAN_DOWN_V6_TETHER;
2535 	}
2536 		evt_data.evt_data = (void *)wandown_data;
2537 		IPACM_EvtDispatcher::PostEvt(&evt_data);
2538 	return IPACM_SUCCESS;
2539 }
2540 #endif
2541 
2542 /* construct complete ethernet header */
handle_sta_header_add_evt(bool renew)2543 int IPACM_Wan::handle_sta_header_add_evt(bool renew)
2544 {
2545 	int res = IPACM_SUCCESS, index = IPACM_INVALID_INDEX;
2546 	if((header_set_v4 == true) || (header_set_v6 == true))
2547 	{
2548 		IPACMDBG_H("Already add STA full header\n");
2549 		return IPACM_SUCCESS;
2550 	}
2551 
2552 	/* checking if the ipv4 same as default route */
2553 	if(wan_v4_addr_gw_set)
2554 	{
2555 		index = get_wan_client_index_ipv4(wan_v4_addr_gw);
2556 		if (index != IPACM_INVALID_INDEX)
2557 		{
2558 			IPACMDBG_H("Matched client index: %d\n", index);
2559 			IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
2560 					 get_client_memptr(wan_client, index)->mac[0],
2561 					 get_client_memptr(wan_client, index)->mac[1],
2562 					 get_client_memptr(wan_client, index)->mac[2],
2563 					 get_client_memptr(wan_client, index)->mac[3],
2564 					 get_client_memptr(wan_client, index)->mac[4],
2565 					 get_client_memptr(wan_client, index)->mac[5]);
2566 
2567 			if(get_client_memptr(wan_client, index)->ipv4_header_set)
2568 			{
2569 				hdr_hdl_sta_v4 = get_client_memptr(wan_client, index)->hdr_hdl_v4;
2570 				header_set_v4 = true;
2571 				IPACMDBG_H("add full ipv4 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v4);
2572 				/* store external_ap's MAC */
2573 				memcpy(ext_router_mac_addr, get_client_memptr(wan_client, index)->mac, sizeof(ext_router_mac_addr));
2574 			}
2575 			else
2576 			{
2577 				IPACMERR(" wan-client got ipv4 however didn't construct complete ipv4 header \n");
2578 				return IPACM_FAILURE;
2579 			}
2580 
2581 			if(get_client_memptr(wan_client, index)->ipv6_header_set)
2582 			{
2583 				hdr_hdl_sta_v6 = get_client_memptr(wan_client, index)->hdr_hdl_v6;
2584 				header_set_v6 = true;
2585 				IPACMDBG_H("add full ipv6 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v6);
2586 			}
2587 			else
2588 			{
2589 				IPACMERR(" wan-client got ipv6 however didn't construct complete ipv6 header \n");
2590 				return IPACM_FAILURE;
2591 			}
2592 		}
2593 		else
2594 		{
2595 			IPACMDBG_H(" currently can't find matched wan-client's MAC-addr, waiting for header construction\n");
2596 			return IPACM_SUCCESS;
2597 		}
2598 	}
2599 
2600 	/* see if v4 default routes are setup before constructing full header */
2601 	if(header_partial_default_wan_v4 == true)
2602 	{
2603 	   handle_route_add_evt(IPA_IP_v4, renew);
2604 	}
2605 
2606 	/* checking if the ipv6 same as default route */
2607 	if(wan_v6_addr_gw_set)
2608 	{
2609 		index = get_wan_client_index_ipv6(wan_v6_addr_gw);
2610 		if (index != IPACM_INVALID_INDEX)
2611 		{
2612 			IPACMDBG_H("Matched client index: %d\n", index);
2613 			IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
2614 					 get_client_memptr(wan_client, index)->mac[0],
2615 					 get_client_memptr(wan_client, index)->mac[1],
2616 					 get_client_memptr(wan_client, index)->mac[2],
2617 					 get_client_memptr(wan_client, index)->mac[3],
2618 					 get_client_memptr(wan_client, index)->mac[4],
2619 					 get_client_memptr(wan_client, index)->mac[5]);
2620 
2621 			if(get_client_memptr(wan_client, index)->ipv6_header_set)
2622 			{
2623 				hdr_hdl_sta_v6 = get_client_memptr(wan_client, index)->hdr_hdl_v6;
2624 				header_set_v6 = true;
2625 				IPACMDBG_H("add full ipv6 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v6);
2626 				/* store external_ap's MAC */
2627 				memcpy(ext_router_mac_addr, get_client_memptr(wan_client, index)->mac, sizeof(ext_router_mac_addr));
2628 			}
2629 			else
2630 			{
2631 				IPACMERR(" wan-client got ipv6 however didn't construct complete ipv4 header \n");
2632 				return IPACM_FAILURE;
2633 			}
2634 
2635 			if(get_client_memptr(wan_client, index)->ipv4_header_set)
2636 			{
2637 				hdr_hdl_sta_v4 = get_client_memptr(wan_client, index)->hdr_hdl_v4;
2638 				header_set_v4 = true;
2639 				IPACMDBG_H("add full ipv4 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v4);
2640 			}
2641 			else
2642 			{
2643 				IPACMERR(" wan-client got ipv4 however didn't construct complete ipv4 header \n");
2644 				return IPACM_FAILURE;
2645 			}
2646 		}
2647 		else
2648 		{
2649 			IPACMDBG_H(" currently can't find matched wan-client's MAC-addr, waiting for header construction\n");
2650 			return IPACM_SUCCESS;
2651 		}
2652 	}
2653 
2654 	/* see if v6 default routes are setup before constructing full header */
2655 
2656 	if(header_partial_default_wan_v6 == true)
2657 	{
2658 	   handle_route_add_evt(IPA_IP_v6, renew);
2659 	}
2660 	return res;
2661 }
2662 
2663 /* For checking attribute mask field in firewall rules for IPv6 only */
check_dft_firewall_rules_attr_mask(IPACM_firewall_conf_t * firewall_config)2664 bool IPACM_Wan::check_dft_firewall_rules_attr_mask(IPACM_firewall_conf_t *firewall_config)
2665 {
2666 	uint32_t attrib_mask = 0ul;
2667 	attrib_mask =	IPA_FLT_SRC_PORT_RANGE |
2668 			IPA_FLT_DST_PORT_RANGE |
2669 			IPA_FLT_TYPE |
2670 			IPA_FLT_CODE |
2671 			IPA_FLT_SPI |
2672 			IPA_FLT_SRC_PORT |
2673 			IPA_FLT_DST_PORT;
2674 
2675 	for (int i = 0; i < firewall_config->num_extd_firewall_entries; i++)
2676 	{
2677 		if (firewall_config->extd_firewall_entries[i].ip_vsn == 6)
2678 		{
2679 			if (firewall_config->extd_firewall_entries[i].attrib.attrib_mask & attrib_mask)
2680 			{
2681 				IPACMDBG_H("IHL based attribute mask is found: install IPv6 frag firewall rule \n");
2682 				return true;
2683 			}
2684 		}
2685 	}
2686 	IPACMDBG_H("IHL based attribute mask is not found: no IPv6 frag firewall rule \n");
2687 	return false;
2688 }
2689 
2690 /* for STA mode: add firewall rules */
config_dft_firewall_rules(ipa_ip_type iptype)2691 int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
2692 {
2693 	struct ipa_flt_rule_add flt_rule_entry;
2694 	int i, rule_v4 = 0, rule_v6 = 0, len;
2695 	bool result;
2696 
2697 	IPACMDBG_H("ip-family: %d; \n", iptype);
2698 
2699 	if (rx_prop == NULL)
2700 	{
2701 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
2702 		return IPACM_SUCCESS;
2703 	}
2704 
2705 	/* default firewall is disable and the rule action is drop */
2706 	memset(&firewall_config, 0, sizeof(firewall_config));
2707 	strlcpy(firewall_config.firewall_config_file, "/etc/mobileap_firewall.xml", sizeof(firewall_config.firewall_config_file));
2708 
2709 	if(m_is_sta_mode != Q6_MHI_WAN)
2710 	{
2711 		IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file);
2712 		if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config))
2713 		{
2714 			IPACMDBG_H("QCMAP Firewall XML read OK \n");
2715 			/* find the number of v4/v6 firewall rules */
2716 			for (i = 0; i < firewall_config.num_extd_firewall_entries; i++)
2717 			{
2718 				if (firewall_config.extd_firewall_entries[i].ip_vsn == 4)
2719 				{
2720 					rule_v4++;
2721 				}
2722 				else
2723 				{
2724 					rule_v6++;
2725 				}
2726 			}
2727 			IPACMDBG_H("firewall rule v4:%d v6:%d total:%d\n", rule_v4, rule_v6, firewall_config.num_extd_firewall_entries);
2728 		}
2729 		else
2730 		{
2731 			IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n");
2732 		}
2733 	}
2734 	else
2735 	{
2736 		IPACMDBG_H("in Q6_MHI_WAN mode, skip firewall, use default configuration \n");
2737 	}
2738 	/* construct ipa_ioc_add_flt_rule with N firewall rules */
2739 	ipa_ioc_add_flt_rule *m_pFilteringTable = NULL;
2740 	len = sizeof(struct ipa_ioc_add_flt_rule) + 1 * sizeof(struct ipa_flt_rule_add);
2741 	m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
2742 	if (!m_pFilteringTable)
2743 	{
2744 		IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
2745 		return IPACM_FAILURE;
2746 	}
2747 
2748 	if(iptype == IPA_IP_v6 &&
2749 			firewall_config.firewall_enable == true &&
2750 			check_dft_firewall_rules_attr_mask(&firewall_config))
2751 	{
2752 		m_pFilteringTable->commit = 1;
2753 		m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
2754 		m_pFilteringTable->global = false;
2755 		m_pFilteringTable->ip = IPA_IP_v6;
2756 		m_pFilteringTable->num_rules = (uint8_t)1;
2757 
2758 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
2759 		flt_rule_entry.at_rear = true;
2760 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2761 		{
2762 			flt_rule_entry.at_rear = false;
2763 			flt_rule_entry.rule.hashable = false;
2764 		}
2765 		flt_rule_entry.flt_rule_hdl = -1;
2766 		flt_rule_entry.status = -1;
2767 		flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
2768 		memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib));
2769 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
2770 		memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
2771 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
2772 		/* use index hw-counter */
2773 		if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
2774 		{
2775 			IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
2776 			result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
2777 		} else {
2778 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
2779 		}
2780 #else
2781 		result = m_filtering.AddFilteringRule(m_pFilteringTable);
2782 #endif
2783 		if (false == result)
2784 		{
2785 			IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
2786 			free(m_pFilteringTable);
2787 			return IPACM_FAILURE;
2788 		}
2789 		else
2790 		{
2791 			IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
2792 			ipv6_frag_firewall_flt_rule_hdl = m_pFilteringTable->rules[0].flt_rule_hdl;
2793 			is_ipv6_frag_firewall_flt_rule_installed = true;
2794 			IPACMDBG_H("Installed IPv6 frag firewall rule, handle %d.\n", ipv6_frag_firewall_flt_rule_hdl);
2795 		}
2796 	}
2797 
2798 	if (iptype == IPA_IP_v4)
2799 	{
2800 		if (rule_v4 == 0)
2801 		{
2802 			memset(m_pFilteringTable, 0, len);
2803 
2804 			m_pFilteringTable->commit = 1;
2805 			m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
2806 			m_pFilteringTable->global = false;
2807 			m_pFilteringTable->ip = IPA_IP_v4;
2808 			m_pFilteringTable->num_rules = (uint8_t)1;
2809 
2810 			memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
2811 
2812 			if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4))
2813 			{
2814 				IPACMERR("m_routing.GetRoutingTable(rt_tbl_lan_v4) Failed.\n");
2815 				free(m_pFilteringTable);
2816 				return IPACM_FAILURE;
2817 			}
2818 
2819 			flt_rule_entry.flt_rule_hdl = -1;
2820 			flt_rule_entry.status = -1;
2821 
2822 			/* firewall disable, all traffic are allowed */
2823 			if(firewall_config.firewall_enable == true)
2824 			{
2825 				flt_rule_entry.at_rear = true;
2826 
2827 				/* default action for v4 is go DST_NAT unless user set to exception*/
2828 				if(firewall_config.rule_action_accept == true)
2829 				{
2830 					flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
2831 				}
2832 				else
2833 				{
2834 					if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
2835 					{
2836 						flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
2837 					}
2838 					else
2839 					{
2840 						flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
2841 					}
2842 				}
2843 			}
2844 			else
2845 			{
2846 				flt_rule_entry.at_rear = true;
2847 				if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
2848 				{
2849 					flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
2850 				}
2851 				else
2852 				{
2853 					flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
2854 				}
2855             }
2856 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2857 			{
2858 				flt_rule_entry.at_rear = true;
2859 				flt_rule_entry.rule.hashable = true;
2860 			}
2861 			flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl;
2862 			memcpy(&flt_rule_entry.rule.attrib,
2863 						 &rx_prop->rx[0].attrib,
2864 						 sizeof(struct ipa_rule_attrib));
2865 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2866 			flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000;
2867 			flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000;
2868 
2869 			/* disble meta-data filtering */
2870 			if(m_is_sta_mode == Q6_MHI_WAN)
2871 			{
2872 				flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
2873 				IPACMDBG_H("disable meta-data filtering 0x%x\n", flt_rule_entry.rule.attrib.attrib_mask);
2874 			}
2875 
2876 			memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
2877 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
2878 			/* use index hw-counter */
2879 			if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
2880 			{
2881 				IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
2882 				result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
2883 			} else {
2884 				result = m_filtering.AddFilteringRule(m_pFilteringTable);
2885 			}
2886 #else
2887 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
2888 #endif
2889 			if (false == result)
2890 			{
2891 				IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
2892 				free(m_pFilteringTable);
2893 				return IPACM_FAILURE;
2894 			}
2895 			else
2896 			{
2897 				IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
2898 				IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
2899 			}
2900 
2901 			/* copy filter hdls */
2902 			dft_wan_fl_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
2903 		}
2904 		else
2905 		{
2906 			memset(m_pFilteringTable, 0, len);
2907 
2908 			m_pFilteringTable->commit = 1;
2909 			m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
2910 			m_pFilteringTable->global = false;
2911 			m_pFilteringTable->ip = IPA_IP_v4;
2912 			m_pFilteringTable->num_rules = (uint8_t)1;
2913 
2914 			IPACMDBG_H("Retreiving Routing handle for routing table name:%s\n",
2915 							 IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name);
2916 			if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4))
2917 			{
2918 				IPACMERR("m_routing.GetRoutingTable(&rt_tbl_lan_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_lan_v4);
2919 				free(m_pFilteringTable);
2920 				return IPACM_FAILURE;
2921 			}
2922 			IPACMDBG_H("Routing handle for wan routing table:0x%x\n", IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl);
2923 
2924             if(firewall_config.firewall_enable == true)
2925             {
2926 			rule_v4 = 0;
2927 			for (i = 0; i < firewall_config.num_extd_firewall_entries; i++)
2928 			{
2929 				if (firewall_config.extd_firewall_entries[i].ip_vsn == 4)
2930 				{
2931 					memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
2932 
2933 		    			flt_rule_entry.at_rear = true;
2934 					flt_rule_entry.flt_rule_hdl = -1;
2935 					flt_rule_entry.status = -1;
2936 					flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl;
2937 
2938 					/* Accept v4 matched rules*/
2939                     if(firewall_config.rule_action_accept == true)
2940 			        {
2941 						if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
2942 						{
2943 							flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
2944 						}
2945 						else
2946 						{
2947 							flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
2948 						}
2949 			        }
2950 			        else
2951 			        {
2952 			            flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
2953                     }
2954 					if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2955 						flt_rule_entry.rule.hashable = true;
2956 					memcpy(&flt_rule_entry.rule.attrib,
2957 								 &firewall_config.extd_firewall_entries[i].attrib,
2958 								 sizeof(struct ipa_rule_attrib));
2959 
2960 					IPACMDBG_H("rx property attrib mask: 0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
2961 					flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask;
2962 					flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask;
2963 					flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data;
2964 
2965 					/* check if the rule is define as TCP_UDP, split into 2 rules, 1 for TCP and 1 UDP */
2966 					if (firewall_config.extd_firewall_entries[i].attrib.u.v4.protocol
2967 							== IPACM_FIREWALL_IPPROTO_TCP_UDP)
2968 					{
2969 						/* insert TCP rule*/
2970 						flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_TCP;
2971 						memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
2972 
2973 						IPACMDBG_H("Filter rule attrib mask: 0x%x\n",
2974 										 m_pFilteringTable->rules[0].rule.attrib.attrib_mask);
2975 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
2976 						/* use index hw-counter */
2977 						if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
2978 						{
2979 							IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
2980 							result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
2981 						} else {
2982 							result = m_filtering.AddFilteringRule(m_pFilteringTable);
2983 						}
2984 #else
2985 						result = m_filtering.AddFilteringRule(m_pFilteringTable);
2986 #endif
2987 
2988 						if (false == result)
2989 						{
2990 							IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
2991 							free(m_pFilteringTable);
2992 							return IPACM_FAILURE;
2993 						}
2994 						else
2995 						{
2996 							IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
2997 							/* save v4 firewall filter rule handler */
2998 							IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
2999 											 m_pFilteringTable->rules[rule_v4].flt_rule_hdl,
3000 											 m_pFilteringTable->rules[rule_v4].status);
3001 							firewall_hdl_v4[rule_v4] = m_pFilteringTable->rules[0].flt_rule_hdl;
3002 							num_firewall_v4++;
3003 							rule_v4++;
3004 						}
3005 
3006 						/* insert UDP rule*/
3007 						flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_UDP;
3008 						memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3009 
3010 						IPACMDBG_H("Filter rule attrib mask: 0x%x\n",
3011 										 m_pFilteringTable->rules[0].rule.attrib.attrib_mask);
3012 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3013 						/* use index hw-counter */
3014 						if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3015 						{
3016 							IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3017 							result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3018 						} else {
3019 							result = m_filtering.AddFilteringRule(m_pFilteringTable);
3020 						}
3021 #else
3022 						result = m_filtering.AddFilteringRule(m_pFilteringTable);
3023 #endif
3024 
3025 						if (false == result)
3026 						{
3027 							IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
3028 							free(m_pFilteringTable);
3029 							return IPACM_FAILURE;
3030 						}
3031 						else
3032 						{
3033 							IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
3034 							/* save v4 firewall filter rule handler */
3035 							IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
3036 											 m_pFilteringTable->rules[rule_v4].flt_rule_hdl,
3037 											 m_pFilteringTable->rules[rule_v4].status);
3038 							firewall_hdl_v4[rule_v4] = m_pFilteringTable->rules[0].flt_rule_hdl;
3039 							num_firewall_v4++;
3040 							rule_v4++;
3041 						}
3042 					}
3043 					else
3044 					{
3045 						memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3046 
3047 						IPACMDBG_H("Filter rule attrib mask: 0x%x\n",
3048 										 m_pFilteringTable->rules[0].rule.attrib.attrib_mask);
3049 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3050 						/* use index hw-counter */
3051 						if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3052 						{
3053 							IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3054 							result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3055 						} else {
3056 							result = m_filtering.AddFilteringRule(m_pFilteringTable);
3057 						}
3058 #else
3059 						result = m_filtering.AddFilteringRule(m_pFilteringTable);
3060 #endif
3061 
3062 						if (false == result)
3063 						{
3064 							IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
3065 							free(m_pFilteringTable);
3066 							return IPACM_FAILURE;
3067 						}
3068 						else
3069 						{
3070 							IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
3071 							/* save v4 firewall filter rule handler */
3072 							IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
3073 											 m_pFilteringTable->rules[rule_v4].flt_rule_hdl,
3074 											 m_pFilteringTable->rules[rule_v4].status);
3075 							firewall_hdl_v4[rule_v4] = m_pFilteringTable->rules[0].flt_rule_hdl;
3076 							num_firewall_v4++;
3077 							rule_v4++;
3078 						}
3079 					}
3080 				}
3081 			} /* end of firewall ipv4 filter rule add for loop*/
3082             }
3083 			/* configure default filter rule */
3084 			memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3085 
3086 			flt_rule_entry.flt_rule_hdl = -1;
3087 			flt_rule_entry.status = -1;
3088 
3089 			/* firewall disable, all traffic are allowed */
3090             if(firewall_config.firewall_enable == true)
3091 			{
3092 			     flt_rule_entry.at_rear = true;
3093 
3094 			     /* default action for v4 is go DST_NAT unless user set to exception*/
3095                              if(firewall_config.rule_action_accept == true)
3096 			     {
3097 			        flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3098 			     }
3099 			     else
3100 			     {
3101 					if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
3102 					{
3103 						flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
3104 					}
3105 					else
3106 					{
3107 						flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3108 					}
3109 				}
3110 		    }
3111 			else
3112 			{
3113 			    flt_rule_entry.at_rear = true;
3114 				if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
3115 				{
3116 					flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
3117 				}
3118 				else
3119 				{
3120 					flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3121 				}
3122             }
3123 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3124 				flt_rule_entry.rule.hashable = true;
3125 			flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl;
3126 			memcpy(&flt_rule_entry.rule.attrib,
3127 						 &rx_prop->rx[0].attrib,
3128 						 sizeof(struct ipa_rule_attrib));
3129 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3130 			flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000;
3131 			flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000;
3132 
3133 			memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3134 
3135 			IPACMDBG_H("Filter rule attrib mask: 0x%x\n",
3136 							 m_pFilteringTable->rules[0].rule.attrib.attrib_mask);
3137 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3138 			/* use index hw-counter */
3139 			if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3140 			{
3141 				IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3142 				result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3143 			} else {
3144 				result = m_filtering.AddFilteringRule(m_pFilteringTable);
3145 			}
3146 #else
3147 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
3148 #endif
3149 
3150 			if (false == result)
3151 			{
3152 				IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
3153 				free(m_pFilteringTable);
3154 				return IPACM_FAILURE;
3155 			}
3156 			else
3157 			{
3158 				IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
3159 				IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
3160 			}
3161 
3162 			/* copy filter hdls */
3163 			dft_wan_fl_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
3164 		}
3165 
3166 	}
3167 	else
3168 	{
3169 		if (rule_v6 == 0)
3170 		{
3171 			memset(m_pFilteringTable, 0, len);
3172 
3173 			m_pFilteringTable->commit = 1;
3174 			m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
3175 			m_pFilteringTable->global = false;
3176 			m_pFilteringTable->ip = IPA_IP_v6;
3177 			m_pFilteringTable->num_rules = (uint8_t)1;
3178 
3179 			if(m_is_sta_mode != Q6_MHI_WAN)
3180 			{
3181 				/* Construct ICMP rule */
3182 				memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3183 				flt_rule_entry.at_rear = true;
3184 				flt_rule_entry.flt_rule_hdl = -1;
3185 				flt_rule_entry.status = -1;
3186 				flt_rule_entry.rule.retain_hdr = 1;
3187 				flt_rule_entry.rule.eq_attrib_type = 0;
3188 				flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3189 				if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3190 					flt_rule_entry.rule.hashable = true;
3191 				memcpy(&flt_rule_entry.rule.attrib,
3192 						&rx_prop->rx[0].attrib,
3193 						sizeof(struct ipa_rule_attrib));
3194 				flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
3195 				flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
3196 				memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3197 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3198 			/* use index hw-counter */
3199 			if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3200 			{
3201 				IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3202 				result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3203 			} else {
3204 				result = m_filtering.AddFilteringRule(m_pFilteringTable);
3205 			}
3206 #else
3207 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
3208 #endif
3209 
3210 			if (false == result)
3211 				{
3212 					IPACMERR("Error Adding Filtering rules, aborting...\n");
3213 					free(m_pFilteringTable);
3214 					return IPACM_FAILURE;
3215 				}
3216 				else
3217 				{
3218 					IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3219 					IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
3220 				}
3221 				/* copy filter hdls */
3222 				dft_wan_fl_hdl[2] = m_pFilteringTable->rules[0].flt_rule_hdl;
3223 				/* End of construct ICMP rule */
3224 			}
3225 			else
3226 			{
3227 				IPACMDBG_H("in Q6_MHI_WAN mode, skip ICMPv6 flt rule \n");
3228 			}
3229 			/* v6 default route */
3230 			memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3231 			if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v6)) //rt_tbl_wan_v6 rt_tbl_v6
3232 			{
3233 				IPACMERR("m_routing.GetRoutingTable(rt_tbl_wan_v6) Failed.\n");
3234 				free(m_pFilteringTable);
3235 				return IPACM_FAILURE;
3236 			}
3237 
3238 			flt_rule_entry.flt_rule_hdl = -1;
3239 			flt_rule_entry.status = -1;
3240 			flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl;
3241 
3242 			/* firewall disable, all traffic are allowed */
3243 			if(firewall_config.firewall_enable == true)
3244 			{
3245 				flt_rule_entry.at_rear = true;
3246 				/* default action for v6 is PASS_TO_ROUTE unless user set to exception*/
3247 				if(firewall_config.rule_action_accept == true)
3248 				{
3249 					flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3250 				}
3251 				else
3252 				{
3253 			       flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3254 				}
3255 			}
3256 			else
3257 			{
3258 			  flt_rule_entry.at_rear = true;
3259 			  flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3260 			}
3261 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3262 				flt_rule_entry.rule.hashable = true;
3263 			memcpy(&flt_rule_entry.rule.attrib,
3264 						 &rx_prop->rx[0].attrib,
3265 						 sizeof(struct ipa_rule_attrib));
3266 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3267 			flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;
3268 			flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
3269 			flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
3270 			flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
3271 			flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000;
3272 			flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
3273 			flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
3274 			flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
3275 			/* disble meta-data filtering */
3276 			if(m_is_sta_mode == Q6_MHI_WAN)
3277 			{
3278 				flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
3279 				IPACMDBG_H("disable meta-data filtering 0x%x\n", flt_rule_entry.rule.attrib.attrib_mask);
3280 			}
3281 
3282 			memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3283 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3284 			/* use index hw-counter */
3285 			if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3286 			{
3287 				IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3288 				result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3289 			} else {
3290 				result = m_filtering.AddFilteringRule(m_pFilteringTable);
3291 			}
3292 #else
3293 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
3294 #endif
3295 
3296 			if (false == result)
3297 			{
3298 				IPACMERR("Error Adding Filtering rules, aborting...\n");
3299 				free(m_pFilteringTable);
3300 				return IPACM_FAILURE;
3301 			}
3302 			else
3303 			{
3304 				IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3305 				IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
3306 			}
3307 
3308 			/* copy filter hdls */
3309 			dft_wan_fl_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl;
3310 		}
3311 		else
3312 		{
3313 			memset(m_pFilteringTable, 0, len);
3314 
3315 			m_pFilteringTable->commit = 1;
3316 			m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
3317 			m_pFilteringTable->global = false;
3318 			m_pFilteringTable->ip = IPA_IP_v6;
3319 			m_pFilteringTable->num_rules = (uint8_t)1;
3320 
3321 			if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v6))
3322 			{
3323 				IPACMERR("m_routing.GetRoutingTable(rt_tbl_wan_v6) Failed.\n");
3324 				free(m_pFilteringTable);
3325 				return IPACM_FAILURE;
3326 			}
3327 
3328             if(firewall_config.firewall_enable == true)
3329             {
3330 			rule_v6 = 0;
3331 			for (i = 0; i < firewall_config.num_extd_firewall_entries; i++)
3332 			{
3333 				if (firewall_config.extd_firewall_entries[i].ip_vsn == 6)
3334 				{
3335 					memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3336 
3337 		    			flt_rule_entry.at_rear = true;
3338 					flt_rule_entry.flt_rule_hdl = -1;
3339 					flt_rule_entry.status = -1;
3340 
3341 				    /* matched rules for v6 go PASS_TO_ROUTE */
3342                                     if(firewall_config.rule_action_accept == true)
3343 			            {
3344 			                flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3345 			            }
3346 			            else
3347 			            {
3348 					flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3349                                     }
3350 					if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3351 						flt_rule_entry.rule.hashable = true;
3352 		    		flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl;
3353 					memcpy(&flt_rule_entry.rule.attrib,
3354 								 &firewall_config.extd_firewall_entries[i].attrib,
3355 								 sizeof(struct ipa_rule_attrib));
3356 					flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask;
3357 					flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask;
3358 					flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data;
3359 
3360 					/* check if the rule is define as TCP/UDP */
3361 					if (firewall_config.extd_firewall_entries[i].attrib.u.v6.next_hdr == IPACM_FIREWALL_IPPROTO_TCP_UDP)
3362 					{
3363 						/* insert TCP rule*/
3364 						flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP;
3365 						memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3366 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3367 						/* use index hw-counter */
3368 						if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3369 						{
3370 							IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3371 							result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3372 						} else {
3373 							result = m_filtering.AddFilteringRule(m_pFilteringTable);
3374 						}
3375 #else
3376 						result = m_filtering.AddFilteringRule(m_pFilteringTable);
3377 #endif
3378 
3379 						if (false == result)
3380 						{
3381 							IPACMERR("Error Adding Filtering rules, aborting...\n");
3382 							free(m_pFilteringTable);
3383 							return IPACM_FAILURE;
3384 						}
3385 						else
3386 						{
3387 							IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3388 							/* save v4 firewall filter rule handler */
3389 							IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
3390 							firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl;
3391 							num_firewall_v6++;
3392 							rule_v6++;
3393 						}
3394 
3395 						/* insert UDP rule*/
3396 						flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_UDP;
3397 						memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3398 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3399 						/* use index hw-counter */
3400 						if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3401 						{
3402 							IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3403 							result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3404 						} else {
3405 							result = m_filtering.AddFilteringRule(m_pFilteringTable);
3406 						}
3407 #else
3408 						result = m_filtering.AddFilteringRule(m_pFilteringTable);
3409 #endif
3410 						if (false == result)
3411 						{
3412 							IPACMERR("Error Adding Filtering rules, aborting...\n");
3413 							free(m_pFilteringTable);
3414 							return IPACM_FAILURE;
3415 						}
3416 						else
3417 						{
3418 							IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3419 							/* save v6 firewall filter rule handler */
3420 							IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
3421 							firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl;
3422 							num_firewall_v6++;
3423 							rule_v6++;
3424 						}
3425 					}
3426 					else
3427 					{
3428 						memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3429 
3430 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3431 						/* use index hw-counter */
3432 						if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3433 						{
3434 							IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3435 							result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3436 						} else {
3437 							result = m_filtering.AddFilteringRule(m_pFilteringTable);
3438 						}
3439 #else
3440 						result = m_filtering.AddFilteringRule(m_pFilteringTable);
3441 #endif
3442 						if (false == result)
3443 						{
3444 							IPACMERR("Error Adding Filtering rules, aborting...\n");
3445 							free(m_pFilteringTable);
3446 							return IPACM_FAILURE;
3447 						}
3448 						else
3449 						{
3450 							IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3451 							/* save v6 firewall filter rule handler */
3452 							IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
3453 							firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl;
3454 							num_firewall_v6++;
3455 							rule_v6++;
3456 						}
3457 					}
3458 				}
3459 			} /* end of firewall ipv6 filter rule add for loop*/
3460             }
3461 
3462 			/* Construct ICMP rule */
3463 			memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3464 			flt_rule_entry.at_rear = true;
3465 			flt_rule_entry.flt_rule_hdl = -1;
3466 			flt_rule_entry.status = -1;
3467 			flt_rule_entry.rule.retain_hdr = 1;
3468 			flt_rule_entry.rule.eq_attrib_type = 0;
3469 			flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3470 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3471 				flt_rule_entry.rule.hashable = true;
3472 			memcpy(&flt_rule_entry.rule.attrib,
3473 					 &rx_prop->rx[0].attrib,
3474 					 sizeof(struct ipa_rule_attrib));
3475 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
3476 			flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
3477 			memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3478 
3479 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3480 			/* use index hw-counter */
3481 			if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3482 			{
3483 				IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3484 				result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3485 			} else {
3486 				result = m_filtering.AddFilteringRule(m_pFilteringTable);
3487 			}
3488 #else
3489 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
3490 #endif
3491 			if (result == false)
3492 			{
3493 				IPACMERR("Error Adding Filtering rules, aborting...\n");
3494 				free(m_pFilteringTable);
3495 				return IPACM_FAILURE;
3496 			}
3497 			else
3498 			{
3499 				IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3500 				IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
3501 			}
3502 			/* copy filter hdls */
3503 			dft_wan_fl_hdl[2] = m_pFilteringTable->rules[0].flt_rule_hdl;
3504 			/* End of construct ICMP rule */
3505 
3506 			/* setup default wan filter rule */
3507 			memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3508 
3509 			flt_rule_entry.flt_rule_hdl = -1;
3510 			flt_rule_entry.status = -1;
3511 			flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl;
3512 
3513 			/* firewall disable, all traffic are allowed */
3514                         if(firewall_config.firewall_enable == true)
3515 			{
3516 			   flt_rule_entry.at_rear = true;
3517 
3518 			   /* default action for v6 is PASS_TO_ROUTE unless user set to exception*/
3519                if(firewall_config.rule_action_accept == true)
3520 			   {
3521 			        flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3522 			   }
3523 			   else
3524 			   {
3525 			flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3526                            }
3527 		        }
3528 			else
3529 			{
3530 			  flt_rule_entry.at_rear = true;
3531 			  flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3532                         }
3533 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3534 				flt_rule_entry.rule.hashable = true;
3535 			memcpy(&flt_rule_entry.rule.attrib,
3536 						 &rx_prop->rx[0].attrib,
3537 						 sizeof(struct ipa_rule_attrib));
3538 			flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3539 			flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;
3540 			flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
3541 			flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
3542 			flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
3543 			flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000;
3544 			flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
3545 			flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
3546 			flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
3547 
3548 			memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3549 
3550 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
3551 			/* use index hw-counter */
3552 			if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
3553 			{
3554 				IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
3555 				result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
3556 			} else {
3557 				result = m_filtering.AddFilteringRule(m_pFilteringTable);
3558 			}
3559 #else
3560 			result = m_filtering.AddFilteringRule(m_pFilteringTable);
3561 #endif
3562 
3563 			if (result == false)
3564 			{
3565 				IPACMERR("Error Adding Filtering rules, aborting...\n");
3566 				free(m_pFilteringTable);
3567 				return IPACM_FAILURE;
3568 			}
3569 			else
3570 			{
3571 				IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3572 				IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
3573 			}
3574 			/* copy filter hdls*/
3575 			dft_wan_fl_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl;
3576 		}
3577 	}
3578 
3579 	if(m_pFilteringTable != NULL)
3580 	{
3581 		free(m_pFilteringTable);
3582 	}
3583 	return IPACM_SUCCESS;
3584 }
3585 
3586 /* configure the initial firewall filter rules */
config_dft_firewall_rules_ex(struct ipa_flt_rule_add * rules,int rule_offset,ipa_ip_type iptype)3587 int IPACM_Wan::config_dft_firewall_rules_ex(struct ipa_flt_rule_add *rules, int rule_offset, ipa_ip_type iptype)
3588 {
3589 	struct ipa_flt_rule_add flt_rule_entry;
3590 	int i;
3591 	int num_rules = 0, original_num_rules = 0;
3592 	ipa_ioc_get_rt_tbl_indx rt_tbl_idx;
3593 	ipa_ioc_generate_flt_eq flt_eq;
3594 	int pos = rule_offset;
3595 
3596 	IPACMDBG_H("ip-family: %d; \n", iptype);
3597 
3598 	if (rx_prop == NULL)
3599 	{
3600 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
3601 		return IPACM_SUCCESS;
3602 	}
3603 
3604 	if(rules == NULL || rule_offset < 0)
3605 	{
3606 		IPACMERR("No filtering table is available.\n");
3607 		return IPACM_FAILURE;
3608 	}
3609 
3610 	/* default firewall is disable and the rule action is drop */
3611 	memset(&firewall_config, 0, sizeof(firewall_config));
3612 	strlcpy(firewall_config.firewall_config_file, "/etc/mobileap_firewall.xml", sizeof(firewall_config.firewall_config_file));
3613 
3614 	IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file);
3615 	if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config))
3616 	{
3617 		IPACMDBG_H("QCMAP Firewall XML read OK \n");
3618 	}
3619 	else
3620 	{
3621 		IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n");
3622 	}
3623 
3624 	/* add IPv6 frag rule when firewall is enabled*/
3625 	if(iptype == IPA_IP_v6 &&
3626 			firewall_config.firewall_enable == true &&
3627 			check_dft_firewall_rules_attr_mask(&firewall_config))
3628 	{
3629 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3630 		flt_rule_entry.at_rear = true;
3631 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3632 			flt_rule_entry.at_rear = false;
3633 		flt_rule_entry.flt_rule_hdl = -1;
3634 		flt_rule_entry.status = -1;
3635 
3636 		flt_rule_entry.rule.retain_hdr = 1;
3637 		flt_rule_entry.rule.to_uc = 0;
3638 		flt_rule_entry.rule.eq_attrib_type = 1;
3639 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3640 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3641 		{
3642 			flt_rule_entry.at_rear = false;
3643 			flt_rule_entry.rule.hashable = false;
3644 		}
3645 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
3646 		rt_tbl_idx.ip = IPA_IP_v6;
3647 		strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
3648 		rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
3649 		if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
3650 		{
3651 			IPACMERR("Failed to get routing table index from name\n");
3652 			return IPACM_FAILURE;
3653 		}
3654 		flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
3655 		IPACMDBG_H("IPv6 frag flt rule uses routing table index %d\n", rt_tbl_idx.idx);
3656 
3657 		flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask;
3658 		flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask;
3659 		flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data;
3660 
3661 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
3662 
3663 		change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
3664 
3665 		memset(&flt_eq, 0, sizeof(flt_eq));
3666 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
3667 		flt_eq.ip = IPA_IP_v6;
3668 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
3669 		{
3670 			IPACMERR("Failed to get eq_attrib\n");
3671 			return IPACM_FAILURE;
3672 		}
3673 		memcpy(&flt_rule_entry.rule.eq_attrib,
3674 			&flt_eq.eq_attrib,
3675 			sizeof(flt_rule_entry.rule.eq_attrib));
3676 
3677 		memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3678 		pos++;
3679 		IPACM_Wan::num_v6_flt_rule++;
3680 	}
3681 
3682 	if (iptype == IPA_IP_v4)
3683 	{
3684 		original_num_rules = IPACM_Wan::num_v4_flt_rule;
3685 		if(firewall_config.firewall_enable == true)
3686 		{
3687 			for (i = 0; i < firewall_config.num_extd_firewall_entries; i++)
3688 			{
3689 				if (firewall_config.extd_firewall_entries[i].ip_vsn == 4)
3690 				{
3691 					memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3692 
3693 					flt_rule_entry.at_rear = true;
3694 					flt_rule_entry.flt_rule_hdl = -1;
3695 					flt_rule_entry.status = -1;
3696 
3697 					flt_rule_entry.rule.retain_hdr = 1;
3698 					flt_rule_entry.rule.to_uc = 0;
3699 					flt_rule_entry.rule.eq_attrib_type = 1;
3700 
3701 					/* Accept v4 matched rules*/
3702 					if(firewall_config.rule_action_accept == true)
3703 					{
3704 						flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
3705 					}
3706 					else
3707 					{
3708 						flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3709 					}
3710 					if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3711 						flt_rule_entry.rule.hashable = true;
3712 					memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
3713 					rt_tbl_idx.ip = iptype;
3714 					if(flt_rule_entry.rule.action == IPA_PASS_TO_ROUTING)
3715 					{
3716 						strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
3717 					}
3718 					else /*pass to dst nat*/
3719 					{
3720 						strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, IPA_RESOURCE_NAME_MAX);
3721 					}
3722 					rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
3723 					if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
3724 					{
3725 						IPACMERR("Failed to get routing table index from name\n");
3726 						return IPACM_FAILURE;
3727 					}
3728 					flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
3729 
3730 					IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
3731 
3732 					memcpy(&flt_rule_entry.rule.attrib,
3733 						&firewall_config.extd_firewall_entries[i].attrib,
3734 						sizeof(struct ipa_rule_attrib));
3735 
3736 					flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask;
3737 					flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask;
3738 					flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data;
3739 
3740 					change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib);
3741 
3742 					/* check if the rule is define as TCP_UDP, split into 2 rules, 1 for TCP and 1 UDP */
3743 					if (firewall_config.extd_firewall_entries[i].attrib.u.v4.protocol == IPACM_FIREWALL_IPPROTO_TCP_UDP)
3744 					{
3745 						/* insert TCP rule*/
3746 						flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_TCP;
3747 
3748 						memset(&flt_eq, 0, sizeof(flt_eq));
3749 						memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
3750 						flt_eq.ip = iptype;
3751 						if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
3752 						{
3753 							IPACMERR("Failed to get eq_attrib\n");
3754 							return IPACM_FAILURE;
3755 						}
3756 						memcpy(&flt_rule_entry.rule.eq_attrib,
3757 							&flt_eq.eq_attrib,
3758 							sizeof(flt_rule_entry.rule.eq_attrib));
3759 
3760 						memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3761 						IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask);
3762 						pos++;
3763 						num_firewall_v4++;
3764 						IPACM_Wan::num_v4_flt_rule++;
3765 
3766 						/* insert UDP rule*/
3767 						flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_UDP;
3768 
3769 						memset(&flt_eq, 0, sizeof(flt_eq));
3770 						memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
3771 						flt_eq.ip = iptype;
3772 						if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
3773 						{
3774 							IPACMERR("Failed to get eq_attrib\n");
3775 							return IPACM_FAILURE;
3776 						}
3777 						memcpy(&flt_rule_entry.rule.eq_attrib,
3778 							&flt_eq.eq_attrib,
3779 							sizeof(flt_rule_entry.rule.eq_attrib));
3780 
3781 						memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3782 						IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask);
3783 						pos++;
3784 						num_firewall_v4++;
3785 						IPACM_Wan::num_v4_flt_rule++;
3786 					}
3787 					else
3788 					{
3789 						memset(&flt_eq, 0, sizeof(flt_eq));
3790 						memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
3791 						flt_eq.ip = iptype;
3792 						if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
3793 						{
3794 							IPACMERR("Failed to get eq_attrib\n");
3795 							return IPACM_FAILURE;
3796 						}
3797 						memcpy(&flt_rule_entry.rule.eq_attrib,
3798 							&flt_eq.eq_attrib,
3799 							sizeof(flt_rule_entry.rule.eq_attrib));
3800 
3801 						memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3802 						IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask);
3803 						pos++;
3804 						num_firewall_v4++;
3805 						IPACM_Wan::num_v4_flt_rule++;
3806 					}
3807 				}
3808 			} /* end of firewall ipv4 filter rule add for loop*/
3809 		}
3810 		/* configure default filter rule */
3811 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3812 
3813 		flt_rule_entry.at_rear = true;
3814 		flt_rule_entry.flt_rule_hdl = -1;
3815 		flt_rule_entry.status = -1;
3816 
3817 		flt_rule_entry.rule.retain_hdr = 1;
3818 		flt_rule_entry.rule.to_uc = 0;
3819 		flt_rule_entry.rule.eq_attrib_type = 1;
3820 
3821 		/* firewall disable, all traffic are allowed */
3822 		if(firewall_config.firewall_enable == true)
3823 		{
3824 			/* default action for v4 is go DST_NAT unless user set to exception*/
3825 			if(firewall_config.rule_action_accept == true)
3826 			{
3827 				flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3828 			}
3829 			else
3830 			{
3831 				flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
3832 			}
3833 		}
3834 		else
3835 		{
3836 			if(isWan_Bridge_Mode())
3837 			{
3838 				IPACMDBG_H("ODU is in bridge mode. \n");
3839 				flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3840 			}
3841 			else
3842 			{
3843 				flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
3844 			}
3845 		}
3846 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3847 			flt_rule_entry.rule.hashable = true;
3848 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
3849 		rt_tbl_idx.ip = iptype;
3850 
3851 		if(flt_rule_entry.rule.action == IPA_PASS_TO_ROUTING)
3852 		{
3853 			strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
3854 		}
3855 		else /*pass to dst nat*/
3856 		{
3857 			strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, IPA_RESOURCE_NAME_MAX);
3858 		}
3859 		rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
3860 
3861 		if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
3862 		{
3863 			IPACMERR("Failed to get routing table index from name\n");
3864 			return IPACM_FAILURE;
3865 		}
3866 		flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
3867 
3868 		IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
3869 
3870 		memcpy(&flt_rule_entry.rule.attrib,
3871 			&rx_prop->rx[0].attrib,
3872 			sizeof(struct ipa_rule_attrib));
3873 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3874 		flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000;
3875 		flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000;
3876 
3877 		change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib);
3878 
3879 		memset(&flt_eq, 0, sizeof(flt_eq));
3880 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
3881 		flt_eq.ip = iptype;
3882 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
3883 		{
3884 			IPACMERR("Failed to get eq_attrib\n");
3885 			return IPACM_FAILURE;
3886 		}
3887 
3888 		memcpy(&flt_rule_entry.rule.eq_attrib,
3889 			&flt_eq.eq_attrib,
3890 			sizeof(flt_rule_entry.rule.eq_attrib));
3891 
3892 		memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3893 		IPACMDBG_H("Filter rule attrib mask: 0x%x\n",	rules[pos].rule.attrib.attrib_mask);
3894 		pos++;
3895 		num_firewall_v4++;
3896 		IPACM_Wan::num_v4_flt_rule++;
3897 
3898 		num_rules = IPACM_Wan::num_v4_flt_rule - original_num_rules - 1;
3899 	}
3900 	else
3901 	{
3902 		original_num_rules = IPACM_Wan::num_v6_flt_rule;
3903 
3904 		if(firewall_config.firewall_enable == true)
3905 		{
3906 			for (i = 0; i < firewall_config.num_extd_firewall_entries; i++)
3907 			{
3908 				if (firewall_config.extd_firewall_entries[i].ip_vsn == 6)
3909 				{
3910 					memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3911 
3912 					flt_rule_entry.at_rear = true;
3913 					flt_rule_entry.flt_rule_hdl = -1;
3914 					flt_rule_entry.status = -1;
3915 
3916 					flt_rule_entry.rule.retain_hdr = 1;
3917 					flt_rule_entry.rule.to_uc = 0;
3918 					flt_rule_entry.rule.eq_attrib_type = 1;
3919 					flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3920 					if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
3921 						flt_rule_entry.rule.hashable = true;
3922 					memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
3923 					rt_tbl_idx.ip = iptype;
3924 
3925 					/* matched rules for v6 go PASS_TO_ROUTE */
3926 					if(firewall_config.rule_action_accept == true)
3927 					{
3928 						strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, IPA_RESOURCE_NAME_MAX);
3929 					}
3930 					else
3931 					{
3932 						strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
3933 					}
3934 					rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
3935 
3936 					if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
3937 					{
3938 						IPACMERR("Failed to get routing table index from name\n");
3939 						return IPACM_FAILURE;
3940 					}
3941 					flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
3942 
3943 					IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
3944 
3945 					memcpy(&flt_rule_entry.rule.attrib,
3946 						&firewall_config.extd_firewall_entries[i].attrib,
3947 						sizeof(struct ipa_rule_attrib));
3948 
3949 					flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask;
3950 					flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask;
3951 					flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data;
3952 
3953 					change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
3954 
3955 					/* check if the rule is define as TCP/UDP */
3956 					if (firewall_config.extd_firewall_entries[i].attrib.u.v6.next_hdr == IPACM_FIREWALL_IPPROTO_TCP_UDP)
3957 					{
3958 						/* insert TCP rule*/
3959 						flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP;
3960 
3961 						memset(&flt_eq, 0, sizeof(flt_eq));
3962 						memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
3963 						flt_eq.ip = iptype;
3964 						if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
3965 						{
3966 							IPACMERR("Failed to get eq_attrib\n");
3967 							return IPACM_FAILURE;
3968 						}
3969 
3970 						memcpy(&flt_rule_entry.rule.eq_attrib,
3971 							&flt_eq.eq_attrib,
3972 							sizeof(flt_rule_entry.rule.eq_attrib));
3973 						memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3974 						pos++;
3975 						num_firewall_v6++;
3976 						IPACM_Wan::num_v6_flt_rule++;
3977 
3978 						/* insert UDP rule*/
3979 						flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_UDP;
3980 
3981 						memset(&flt_eq, 0, sizeof(flt_eq));
3982 						memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
3983 						flt_eq.ip = iptype;
3984 						if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
3985 						{
3986 							IPACMERR("Failed to get eq_attrib\n");
3987 							return IPACM_FAILURE;
3988 						}
3989 
3990 						memcpy(&flt_rule_entry.rule.eq_attrib,
3991 							&flt_eq.eq_attrib,
3992 							sizeof(flt_rule_entry.rule.eq_attrib));
3993 						memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3994 						pos++;
3995 						num_firewall_v6++;
3996 						IPACM_Wan::num_v6_flt_rule++;
3997 					}
3998 					else
3999 					{
4000 						memset(&flt_eq, 0, sizeof(flt_eq));
4001 						memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4002 						flt_eq.ip = iptype;
4003 						if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4004 						{
4005 							IPACMERR("Failed to get eq_attrib\n");
4006 							return IPACM_FAILURE;
4007 						}
4008 
4009 						memcpy(&flt_rule_entry.rule.eq_attrib,
4010 							&flt_eq.eq_attrib,
4011 							sizeof(flt_rule_entry.rule.eq_attrib));
4012 						memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4013 						pos++;
4014 						num_firewall_v6++;
4015 						IPACM_Wan::num_v6_flt_rule++;
4016 					}
4017 				}
4018 			} /* end of firewall ipv6 filter rule add for loop*/
4019 		}
4020 
4021 		/* setup default wan filter rule */
4022 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
4023 
4024 		flt_rule_entry.at_rear = true;
4025 		flt_rule_entry.flt_rule_hdl = -1;
4026 		flt_rule_entry.status = -1;
4027 
4028 		flt_rule_entry.rule.retain_hdr = 1;
4029 		flt_rule_entry.rule.to_uc = 0;
4030 		flt_rule_entry.rule.eq_attrib_type = 1;
4031 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
4032 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
4033 			flt_rule_entry.rule.hashable = true;
4034 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
4035 		rt_tbl_idx.ip = iptype;
4036 		/* firewall disable, all traffic are allowed */
4037 		if(firewall_config.firewall_enable == true)
4038 		{
4039 			/* default action for v6 is PASS_TO_ROUTE unless user set to exception*/
4040 			if(firewall_config.rule_action_accept == true)
4041 			{
4042 				strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
4043 			}
4044 			else
4045 			{
4046 				strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, IPA_RESOURCE_NAME_MAX);
4047 			}
4048 		}
4049 		else
4050 		{
4051 			strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, IPA_RESOURCE_NAME_MAX);
4052 		}
4053 		rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
4054 		if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
4055 		{
4056 			IPACMERR("Failed to get routing table index from name\n");
4057 			return IPACM_FAILURE;
4058 		}
4059 		flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
4060 
4061 		IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
4062 
4063 		memcpy(&flt_rule_entry.rule.attrib,
4064 			&rx_prop->rx[1].attrib,
4065 			sizeof(struct ipa_rule_attrib));
4066 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
4067 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;
4068 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
4069 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
4070 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
4071 		flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000;
4072 		flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
4073 		flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
4074 		flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
4075 
4076 		change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
4077 
4078 		memset(&flt_eq, 0, sizeof(flt_eq));
4079 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4080 		flt_eq.ip = iptype;
4081 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4082 		{
4083 			IPACMERR("Failed to get eq_attrib\n");
4084 			return IPACM_FAILURE;
4085 		}
4086 		memcpy(&flt_rule_entry.rule.eq_attrib,
4087 			&flt_eq.eq_attrib,
4088 			sizeof(flt_rule_entry.rule.eq_attrib));
4089 		memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4090 		pos++;
4091 		num_firewall_v6++;
4092 		IPACM_Wan::num_v6_flt_rule++;
4093 
4094 		num_rules = IPACM_Wan::num_v6_flt_rule - original_num_rules - 1;
4095 	}
4096 	IPACMDBG_H("Constructed %d firewall rules for ip type %d\n", num_rules, iptype);
4097 	return IPACM_SUCCESS;
4098 }
4099 
init_fl_rule_ex(ipa_ip_type iptype)4100 int IPACM_Wan::init_fl_rule_ex(ipa_ip_type iptype)
4101 {
4102 	int res = IPACM_SUCCESS;
4103 
4104 	/* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */
4105 	IPACMDBG_H(" dun add producer dependency from %s with registered rx-prop\n", dev_name);
4106 
4107 	if(iptype == IPA_IP_v4)
4108 	{
4109 		if(modem_ipv4_pdn_index == 0)	/* install ipv4 default modem DL filtering rules only once */
4110 		{
4111 			/* reset the num_v4_flt_rule*/
4112 			IPACM_Wan::num_v4_flt_rule = 0;
4113 			add_dft_filtering_rule(flt_rule_v4, IPACM_Wan::num_v4_flt_rule, IPA_IP_v4);
4114 		}
4115 	}
4116 	else if(iptype == IPA_IP_v6)
4117 	{
4118 		if(modem_ipv6_pdn_index == 0)	/* install ipv6 default modem DL filtering rules only once */
4119 		{
4120 			/* reset the num_v6_flt_rule*/
4121 			IPACM_Wan::num_v6_flt_rule = 0;
4122 			add_dft_filtering_rule(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6);
4123 		}
4124 	}
4125 	else
4126 	{
4127 		IPACMERR("IP type is not expected.\n");
4128 		res = IPACM_FAILURE;
4129 		goto fail;
4130 	}
4131 	install_wan_filtering_rule(false);
4132 
4133 	/* Add Natting iface to IPACM_Config if there is  Rx/Tx property */
4134 	if (rx_prop != NULL || tx_prop != NULL)
4135 	{
4136 		IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
4137 		IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, iptype);
4138 	}
4139 
4140 fail:
4141 	return res;
4142 }
4143 
add_icmp_alg_rules(struct ipa_flt_rule_add * rules,int rule_offset,ipa_ip_type iptype)4144 int IPACM_Wan::add_icmp_alg_rules(struct ipa_flt_rule_add *rules, int rule_offset, ipa_ip_type iptype)
4145 {
4146 	int res = IPACM_SUCCESS, i, original_num_rules = 0, num_rules = 0;
4147 	struct ipa_flt_rule_add flt_rule_entry;
4148 	IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg;
4149 	ipa_ioc_generate_flt_eq flt_eq;
4150 	ipa_ioc_get_rt_tbl_indx rt_tbl_idx;
4151 
4152 	if(rules == NULL || rule_offset < 0)
4153 	{
4154 		IPACMERR("No filtering table is available.\n");
4155 		return IPACM_FAILURE;
4156 	}
4157 
4158 	if(iptype == IPA_IP_v4)
4159 	{
4160 		original_num_rules = IPACM_Wan::num_v4_flt_rule;
4161 
4162 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
4163 		strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
4164 		rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
4165 		rt_tbl_idx.ip = iptype;
4166 		if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
4167 		{
4168 			IPACMERR("Failed to get routing table index from name\n");
4169 			res = IPACM_FAILURE;
4170 			goto fail;
4171 		}
4172 
4173 		IPACMDBG_H("WAN DL routing table %s has index %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, rt_tbl_idx.idx);
4174 
4175 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
4176 
4177 		flt_rule_entry.at_rear = true;
4178 		flt_rule_entry.flt_rule_hdl = -1;
4179 		flt_rule_entry.status = -1;
4180 
4181 		flt_rule_entry.rule.retain_hdr = 1;
4182 		flt_rule_entry.rule.to_uc = 0;
4183 		flt_rule_entry.rule.eq_attrib_type = 1;
4184 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
4185 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
4186 			flt_rule_entry.rule.hashable = true;
4187 		flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
4188 
4189 		/* Configuring ICMP filtering rule */
4190 		memcpy(&flt_rule_entry.rule.attrib,
4191 					 &rx_prop->rx[0].attrib,
4192 					 sizeof(flt_rule_entry.rule.attrib));
4193 		/* Multiple PDNs may exist so keep meta-data */
4194 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
4195 		flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP;
4196 
4197 		memset(&flt_eq, 0, sizeof(flt_eq));
4198 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4199 		flt_eq.ip = iptype;
4200 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4201 		{
4202 			IPACMERR("Failed to get eq_attrib\n");
4203 			res = IPACM_FAILURE;
4204 			goto fail;
4205 		}
4206 
4207 		memcpy(&flt_rule_entry.rule.eq_attrib,
4208 					 &flt_eq.eq_attrib,
4209 					 sizeof(flt_rule_entry.rule.eq_attrib));
4210 
4211 		memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4212 
4213 		IPACM_Wan::num_v4_flt_rule++;
4214 
4215 		/* Configure ALG filtering rules */
4216 		/* maintain meta data mask */
4217 		memcpy(&flt_rule_entry.rule.attrib,
4218 					 &rx_prop->rx[0].attrib,
4219 					 sizeof(flt_rule_entry.rule.attrib));
4220 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_PORT;
4221 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
4222 		for(i = 0; i < ipacm_config->ipa_num_alg_ports; i++)
4223 		{
4224 			flt_rule_entry.rule.attrib.src_port = ipacm_config->alg_table[i].port;
4225 			flt_rule_entry.rule.attrib.u.v4.protocol = ipacm_config->alg_table[i].protocol;
4226 
4227 			memset(&flt_eq, 0, sizeof(flt_eq));
4228 			memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4229 			flt_eq.ip = iptype;
4230 			if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4231 			{
4232 				IPACMERR("Failed to get eq_attrib\n");
4233 				res = IPACM_FAILURE;
4234 				goto fail;
4235 			}
4236 			memcpy(&flt_rule_entry.rule.eq_attrib,
4237 						 &flt_eq.eq_attrib,
4238 						 sizeof(flt_rule_entry.rule.eq_attrib));
4239 			memcpy(&(rules[rule_offset + 1 + i]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4240 			IPACM_Wan::num_v4_flt_rule++;
4241 		}
4242 
4243 		/* maintain meta data mask */
4244 		memcpy(&flt_rule_entry.rule.attrib,
4245 					 &rx_prop->rx[0].attrib,
4246 					 sizeof(flt_rule_entry.rule.attrib));
4247 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_PORT;
4248 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
4249 		for(i = 0; i < ipacm_config->ipa_num_alg_ports; i++)
4250 		{
4251 			flt_rule_entry.rule.attrib.dst_port = ipacm_config->alg_table[i].port;
4252 			flt_rule_entry.rule.attrib.u.v4.protocol = ipacm_config->alg_table[i].protocol;
4253 
4254 			memset(&flt_eq, 0, sizeof(flt_eq));
4255 			memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4256 			flt_eq.ip = iptype;
4257 			if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4258 			{
4259 				IPACMERR("Failed to get eq_attrib\n");
4260 				res = IPACM_FAILURE;
4261 				goto fail;
4262 			}
4263 
4264 			memcpy(&flt_rule_entry.rule.eq_attrib,
4265 						 &flt_eq.eq_attrib,
4266 						 sizeof(flt_rule_entry.rule.eq_attrib));
4267 
4268 			memcpy(&(rules[rule_offset + ipacm_config->ipa_num_alg_ports + 1 + i]),
4269 				&flt_rule_entry,
4270 				sizeof(struct ipa_flt_rule_add));
4271 			IPACM_Wan::num_v4_flt_rule++;
4272 		}
4273 		num_rules = IPACM_Wan::num_v4_flt_rule - original_num_rules;
4274 	}
4275 	else /* IPv6 case */
4276 	{
4277 		original_num_rules = IPACM_Wan::num_v6_flt_rule;
4278 
4279 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
4280 		strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
4281 		rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
4282 		rt_tbl_idx.ip = iptype;
4283 		if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
4284 		{
4285 			IPACMERR("Failed to get routing table index from name\n");
4286 			res = IPACM_FAILURE;
4287 			goto fail;
4288 		}
4289 
4290 		IPACMDBG_H("WAN DL routing table %s has index %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, rt_tbl_idx.idx);
4291 
4292 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
4293 
4294 		flt_rule_entry.at_rear = true;
4295 		flt_rule_entry.flt_rule_hdl = -1;
4296 		flt_rule_entry.status = -1;
4297 
4298 		flt_rule_entry.rule.retain_hdr = 1;
4299 		flt_rule_entry.rule.to_uc = 0;
4300 		flt_rule_entry.rule.eq_attrib_type = 1;
4301 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
4302 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
4303 			flt_rule_entry.rule.hashable = true;
4304 		flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
4305 
4306 		/* Configuring ICMP filtering rule */
4307 		memcpy(&flt_rule_entry.rule.attrib,
4308 					 &rx_prop->rx[1].attrib,
4309 					 sizeof(flt_rule_entry.rule.attrib));
4310 		/* Multiple PDNs may exist so keep meta-data */
4311 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
4312 		flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
4313 
4314 		memset(&flt_eq, 0, sizeof(flt_eq));
4315 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4316 		flt_eq.ip = iptype;
4317 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4318 		{
4319 			IPACMERR("Failed to get eq_attrib\n");
4320 			res = IPACM_FAILURE;
4321 			goto fail;
4322 		}
4323 
4324 		memcpy(&flt_rule_entry.rule.eq_attrib,
4325 					 &flt_eq.eq_attrib,
4326 					 sizeof(flt_rule_entry.rule.eq_attrib));
4327 
4328 		memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4329 		IPACM_Wan::num_v6_flt_rule++;
4330 
4331 		num_rules = IPACM_Wan::num_v6_flt_rule - original_num_rules;
4332 	}
4333 
4334 fail:
4335 	IPACMDBG_H("Constructed %d ICMP/ALG rules for ip type %d\n", num_rules, iptype);
4336 		return res;
4337 }
4338 
query_ext_prop()4339 int IPACM_Wan::query_ext_prop()
4340 {
4341 	int fd, ret = IPACM_SUCCESS;
4342 	uint32_t cnt;
4343 
4344 	if (iface_query->num_ext_props > 0)
4345 	{
4346 		fd = open(IPA_DEVICE_NAME, O_RDWR);
4347 		IPACMDBG_H("iface query-property \n");
4348 		if (0 == fd)
4349 		{
4350 			IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
4351 			return IPACM_FAILURE;
4352 		}
4353 
4354 		ext_prop = (struct ipa_ioc_query_intf_ext_props *)
4355 			 calloc(1, sizeof(struct ipa_ioc_query_intf_ext_props) +
4356 							iface_query->num_ext_props * sizeof(struct ipa_ioc_ext_intf_prop));
4357 		if(ext_prop == NULL)
4358 		{
4359 			IPACMERR("Unable to allocate memory.\n");
4360 			return IPACM_FAILURE;
4361 		}
4362 		memcpy(ext_prop->name, dev_name,
4363 					 sizeof(dev_name));
4364 		ext_prop->num_ext_props = iface_query->num_ext_props;
4365 
4366 		IPACMDBG_H("Query extended property for iface %s\n", ext_prop->name);
4367 
4368 		ret = ioctl(fd, IPA_IOC_QUERY_INTF_EXT_PROPS, ext_prop);
4369 		if (ret < 0)
4370 		{
4371 			IPACMERR("ioctl IPA_IOC_QUERY_INTF_EXT_PROPS failed\n");
4372 			/* ext_prop memory will free when iface-down*/
4373 			free(ext_prop);
4374 			close(fd);
4375 			return ret;
4376 		}
4377 
4378 		IPACMDBG_H("Wan interface has %d tx props, %d rx props and %d ext props\n",
4379 				iface_query->num_tx_props, iface_query->num_rx_props, iface_query->num_ext_props);
4380 
4381 		for (cnt = 0; cnt < ext_prop->num_ext_props; cnt++)
4382 		{
4383 			if (!IPACM_Iface::ipacmcfg->isIPAv3Supported())
4384 			{
4385 				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",
4386 					cnt, ext_prop->ext[cnt].ip, ext_prop->ext[cnt].mux_id, ext_prop->ext[cnt].action,
4387 					ext_prop->ext[cnt].rt_tbl_idx, ext_prop->ext[cnt].is_xlat_rule, ext_prop->ext[cnt].filter_hdl);
4388 			}
4389 			else /* IPA_V3 */
4390 			{
4391 				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",
4392 					cnt, ext_prop->ext[cnt].ip, ext_prop->ext[cnt].mux_id, ext_prop->ext[cnt].action,
4393 					ext_prop->ext[cnt].rt_tbl_idx, ext_prop->ext[cnt].is_xlat_rule, ext_prop->ext[cnt].rule_id);
4394 			}
4395 		}
4396 
4397 		if(IPACM_Wan::is_ext_prop_set == false)
4398 		{
4399 			IPACM_Iface::ipacmcfg->SetExtProp(ext_prop);
4400 			IPACM_Wan::is_ext_prop_set = true;
4401 		}
4402 		close(fd);
4403 	}
4404 	return IPACM_SUCCESS;
4405 }
4406 
config_wan_firewall_rule(ipa_ip_type iptype)4407 int IPACM_Wan::config_wan_firewall_rule(ipa_ip_type iptype)
4408 {
4409 	int res = IPACM_SUCCESS;
4410 
4411 	IPACMDBG_H("Configure WAN DL firewall rules.\n");
4412 
4413 	if(iptype == IPA_IP_v4)
4414 	{
4415 		IPACM_Wan::num_v4_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4;
4416 		if(IPACM_FAILURE == add_icmp_alg_rules(flt_rule_v4, IPACM_Wan::num_v4_flt_rule, IPA_IP_v4))
4417 		{
4418 			IPACMERR("Failed to add ICMP and ALG port filtering rules.\n");
4419 			res = IPACM_FAILURE;
4420 			goto fail;
4421 		}
4422 		IPACMDBG_H("Succeded in constructing ICMP/ALG rules for ip type %d\n", iptype);
4423 
4424 		if(IPACM_FAILURE == config_dft_firewall_rules_ex(flt_rule_v4, IPACM_Wan::num_v4_flt_rule, IPA_IP_v4))
4425 		{
4426 			IPACMERR("Failed to add firewall filtering rules.\n");
4427 			res = IPACM_FAILURE;
4428 			goto fail;
4429 		}
4430 		IPACMDBG_H("Succeded in constructing firewall rules for ip type %d\n", iptype);
4431 	}
4432 	else if(iptype == IPA_IP_v6)
4433 	{
4434 		IPACM_Wan::num_v6_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6;
4435 		if(IPACM_FAILURE == add_icmp_alg_rules(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6))
4436 		{
4437 			IPACMERR("Failed to add ICMP and ALG port filtering rules.\n");
4438 			res = IPACM_FAILURE;
4439 			goto fail;
4440 		}
4441 		IPACMDBG_H("Succeded in constructing ICMP/ALG rules for ip type %d\n", iptype);
4442 
4443 		if(IPACM_FAILURE == config_dft_firewall_rules_ex(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6))
4444 		{
4445 			IPACMERR("Failed to add firewall filtering rules.\n");
4446 			res = IPACM_FAILURE;
4447 			goto fail;
4448 		}
4449 		IPACMDBG_H("Succeded in constructing firewall rules for ip type %d\n", iptype);
4450 	}
4451 	else
4452 	{
4453 		IPACMERR("IP type is not expected.\n");
4454 		return IPACM_FAILURE;
4455 	}
4456 
4457 fail:
4458 	return res;
4459 }
4460 
add_dft_filtering_rule(struct ipa_flt_rule_add * rules,int rule_offset,ipa_ip_type iptype)4461 int IPACM_Wan::add_dft_filtering_rule(struct ipa_flt_rule_add *rules, int rule_offset, ipa_ip_type iptype)
4462 {
4463 	struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx;
4464 	struct ipa_flt_rule_add flt_rule_entry;
4465 	struct ipa_ioc_generate_flt_eq flt_eq;
4466 	int res = IPACM_SUCCESS;
4467 
4468 	if(rules == NULL)
4469 	{
4470 		IPACMERR("No filtering table available.\n");
4471 		return IPACM_FAILURE;
4472 	}
4473 	if(rx_prop == NULL)
4474 	{
4475 		IPACMERR("No tx property.\n");
4476 		return IPACM_FAILURE;
4477 	}
4478 
4479 	if (iptype == IPA_IP_v4)
4480 	{
4481 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
4482 		strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
4483 		rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
4484 		rt_tbl_idx.ip = iptype;
4485 		if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
4486 		{
4487 			IPACMERR("Failed to get routing table index from name\n");
4488 			res = IPACM_FAILURE;
4489 			goto fail;
4490 		}
4491 
4492 		IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
4493 
4494 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
4495 
4496 		flt_rule_entry.at_rear = true;
4497 		flt_rule_entry.flt_rule_hdl = -1;
4498 		flt_rule_entry.status = -1;
4499 
4500 		flt_rule_entry.rule.retain_hdr = 1;
4501 		flt_rule_entry.rule.to_uc = 0;
4502 		flt_rule_entry.rule.eq_attrib_type = 1;
4503 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
4504 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
4505 			flt_rule_entry.rule.hashable = true;
4506 		flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
4507 
4508 		IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
4509 
4510 		/* Configuring Multicast Filtering Rule */
4511 		memcpy(&flt_rule_entry.rule.attrib,
4512 					 &rx_prop->rx[0].attrib,
4513 					 sizeof(flt_rule_entry.rule.attrib));
4514 		/* remove meta data mask since we only install default flt rules once for all modem PDN*/
4515 		flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
4516 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
4517 		flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xF0000000;
4518 		flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xE0000000;
4519 
4520 		change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib);
4521 
4522 		memset(&flt_eq, 0, sizeof(flt_eq));
4523 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4524 		flt_eq.ip = iptype;
4525 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4526 		{
4527 			IPACMERR("Failed to get eq_attrib\n");
4528 			res = IPACM_FAILURE;
4529 			goto fail;
4530 		}
4531 
4532 		memcpy(&flt_rule_entry.rule.eq_attrib,
4533 					 &flt_eq.eq_attrib,
4534 					 sizeof(flt_rule_entry.rule.eq_attrib));
4535 		memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4536 
4537 		/* Configuring Broadcast Filtering Rule */
4538 		flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
4539 		flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xFFFFFFFF;
4540 
4541 		change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib);
4542 
4543 		memset(&flt_eq, 0, sizeof(flt_eq));
4544 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4545 		flt_eq.ip = iptype;
4546 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4547 		{
4548 			IPACMERR("Failed to get eq_attrib\n");
4549 			res = IPACM_FAILURE;
4550 			goto fail;
4551 		}
4552 
4553 		memcpy(&flt_rule_entry.rule.eq_attrib,
4554 					 &flt_eq.eq_attrib,
4555 					 sizeof(flt_rule_entry.rule.eq_attrib));
4556 		memcpy(&(rules[rule_offset + 1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4557 
4558 		IPACM_Wan::num_v4_flt_rule += IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4;
4559 		IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n", IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4, iptype);
4560 	}
4561 	else	/*insert rules for ipv6*/
4562 	{
4563 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
4564 		strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
4565 		rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
4566 		rt_tbl_idx.ip = iptype;
4567 		if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
4568 		{
4569 			IPACMERR("Failed to get routing table index from name\n");
4570 			res = IPACM_FAILURE;
4571 			goto fail;
4572 		}
4573 
4574 		IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
4575 
4576 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
4577 
4578 		flt_rule_entry.at_rear = true;
4579 		flt_rule_entry.flt_rule_hdl = -1;
4580 		flt_rule_entry.status = -1;
4581 
4582 		flt_rule_entry.rule.retain_hdr = 1;
4583 		flt_rule_entry.rule.to_uc = 0;
4584 		flt_rule_entry.rule.eq_attrib_type = 1;
4585 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
4586 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
4587 			flt_rule_entry.rule.hashable = true;
4588 		flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
4589 
4590 		/* Configuring Multicast Filtering Rule */
4591 		memcpy(&flt_rule_entry.rule.attrib,
4592 					 &rx_prop->rx[0].attrib,
4593 					 sizeof(flt_rule_entry.rule.attrib));
4594 		/* remove meta data mask since we only install default flt rules once for all modem PDN*/
4595 		flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
4596 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
4597 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFF000000;
4598 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
4599 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
4600 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
4601 		flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFF000000;
4602 		flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
4603 		flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
4604 		flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x00000000;
4605 
4606 		change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
4607 
4608 		memset(&flt_eq, 0, sizeof(flt_eq));
4609 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4610 		flt_eq.ip = iptype;
4611 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4612 		{
4613 			IPACMERR("Failed to get eq_attrib\n");
4614 			res = IPACM_FAILURE;
4615 			goto fail;
4616 		}
4617 
4618 		memcpy(&flt_rule_entry.rule.eq_attrib,
4619 					 &flt_eq.eq_attrib,
4620 					 sizeof(flt_rule_entry.rule.eq_attrib));
4621 		memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4622 
4623 		/* Configuring fe80::/10 Link-Scoped Unicast Filtering Rule */
4624 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFC00000;
4625 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
4626 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
4627 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
4628 		flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFE800000;
4629 		flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
4630 		flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
4631 		flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x00000000;
4632 
4633 		change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
4634 
4635 		memset(&flt_eq, 0, sizeof(flt_eq));
4636 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4637 		flt_eq.ip = iptype;
4638 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4639 		{
4640 			IPACMERR("Failed to get eq_attrib\n");
4641 			res = IPACM_FAILURE;
4642 			goto fail;
4643 		}
4644 
4645 		memcpy(&flt_rule_entry.rule.eq_attrib,
4646 					 &flt_eq.eq_attrib,
4647 					 sizeof(flt_rule_entry.rule.eq_attrib));
4648 
4649 		memcpy(&(rules[rule_offset + 1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4650 
4651 		/* Configuring fec0::/10 Reserved by IETF Filtering Rule */
4652 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFC00000;
4653 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
4654 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
4655 		flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
4656 		flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFEC00000;
4657 		flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
4658 		flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
4659 		flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x00000000;
4660 
4661 		change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
4662 
4663 		memset(&flt_eq, 0, sizeof(flt_eq));
4664 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4665 		flt_eq.ip = iptype;
4666 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4667 		{
4668 			IPACMERR("Failed to get eq_attrib\n");
4669 			res = IPACM_FAILURE;
4670 			goto fail;
4671 		}
4672 
4673 		memcpy(&flt_rule_entry.rule.eq_attrib,
4674 					 &flt_eq.eq_attrib,
4675 					 sizeof(flt_rule_entry.rule.eq_attrib));
4676 
4677 		memcpy(&(rules[rule_offset + 2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4678 
4679 		/* Configuring fragment Filtering Rule */
4680 		flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_DST_ADDR);
4681 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
4682 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
4683 		flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP;
4684 
4685 		memset(&flt_eq, 0, sizeof(flt_eq));
4686 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
4687 		flt_eq.ip = iptype;
4688 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
4689 		{
4690 			IPACMERR("Failed to get eq_attrib\n");
4691 			res = IPACM_FAILURE;
4692 			goto fail;
4693 		}
4694 
4695 		memcpy(&flt_rule_entry.rule.eq_attrib,
4696 					 &flt_eq.eq_attrib,
4697 					 sizeof(flt_rule_entry.rule.eq_attrib));
4698 
4699 		memcpy(&(rules[rule_offset + 3]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
4700 
4701 #ifdef FEATURE_IPA_ANDROID
4702 		IPACM_Wan::num_v6_flt_rule += IPA_V2_NUM_MULTICAST_WAN_FILTER_RULE_IPV6;
4703 		IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n", IPA_V2_NUM_MULTICAST_WAN_FILTER_RULE_IPV6, iptype);
4704 #else
4705 		IPACM_Wan::num_v6_flt_rule += IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6;
4706 		IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n",
4707 				IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6, iptype);
4708 #endif
4709 		IPACM_Wan::num_v6_flt_rule += IPA_V2_NUM_FRAG_WAN_FILTER_RULE_IPV6;
4710 		IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n",
4711 				IPA_V2_NUM_FRAG_WAN_FILTER_RULE_IPV6, iptype);
4712 	}
4713 
4714 fail:
4715 	return res;
4716 }
4717 
del_wan_firewall_rule(ipa_ip_type iptype)4718 int IPACM_Wan::del_wan_firewall_rule(ipa_ip_type iptype)
4719 {
4720 	if(iptype == IPA_IP_v4)
4721 	{
4722 		IPACM_Wan::num_v4_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4;
4723 		memset(&IPACM_Wan::flt_rule_v4[IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4], 0,
4724 			(IPA_MAX_FLT_RULE - IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4) * sizeof(struct ipa_flt_rule_add));
4725 	}
4726 	else if(iptype == IPA_IP_v6)
4727 	{
4728 		IPACM_Wan::num_v6_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6;
4729 		memset(&IPACM_Wan::flt_rule_v6[IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6], 0,
4730 			(IPA_MAX_FLT_RULE - IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6) * sizeof(struct ipa_flt_rule_add));
4731 	}
4732 	else
4733 	{
4734 		IPACMERR("IP type is not expected.\n");
4735 		return IPACM_FAILURE;
4736 	}
4737 
4738 	return IPACM_SUCCESS;
4739 }
4740 
4741 /*for STA mode: clean firewall filter rules */
del_dft_firewall_rules(ipa_ip_type iptype)4742 int IPACM_Wan::del_dft_firewall_rules(ipa_ip_type iptype)
4743 {
4744 	/* free v4 firewall filter rule */
4745 	if (rx_prop == NULL)
4746 	{
4747 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
4748 		return IPACM_SUCCESS;
4749 	}
4750 
4751 	if ((iptype == IPA_IP_v4) && (active_v4 == true))
4752 	{
4753 		if (num_firewall_v4 > IPACM_MAX_FIREWALL_ENTRIES)
4754 		{
4755 			IPACMERR("the number of v4 firewall entries overflow, aborting...\n");
4756 			return IPACM_FAILURE;
4757 		}
4758 		if (num_firewall_v4 != 0)
4759 		{
4760 			if (m_filtering.DeleteFilteringHdls(firewall_hdl_v4,
4761 				IPA_IP_v4, num_firewall_v4) == false)
4762 			{
4763 				IPACMERR("Error Deleting Filtering rules, aborting...\n");
4764 				return IPACM_FAILURE;
4765 			}
4766 			IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_firewall_v4);
4767 		}
4768 		else
4769 		{
4770 			IPACMDBG_H("No ipv4 firewall rules, no need deleted\n");
4771 		}
4772 
4773 		if (m_filtering.DeleteFilteringHdls(dft_wan_fl_hdl,
4774 				IPA_IP_v4, 1) == false)
4775 		{
4776 			IPACMERR("Error Deleting Filtering rules, aborting...\n");
4777 			return IPACM_FAILURE;
4778 		}
4779 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
4780 
4781 		num_firewall_v4 = 0;
4782 	}
4783 
4784 	/* free v6 firewall filter rule */
4785 	if ((iptype == IPA_IP_v6) && (active_v6 == true))
4786 	{
4787 		if (num_firewall_v6 > IPACM_MAX_FIREWALL_ENTRIES)
4788 		{
4789 			IPACMERR("the number of v6 firewall entries overflow, aborting...\n");
4790 			return IPACM_FAILURE;
4791 		}
4792 		if (num_firewall_v6 != 0)
4793 		{
4794 			if (m_filtering.DeleteFilteringHdls(firewall_hdl_v6,
4795 				IPA_IP_v6, num_firewall_v6) == false)
4796 			{
4797 				IPACMERR("Error Deleting Filtering rules, aborting...\n");
4798 				return IPACM_FAILURE;
4799 			}
4800 			IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_firewall_v6);
4801 		}
4802 		else
4803 		{
4804 			IPACMDBG_H("No ipv6 firewall rules, no need deleted\n");
4805 		}
4806 
4807 		if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[1],
4808 			IPA_IP_v6, 1) == false)
4809 		{
4810 			IPACMERR("Error Deleting Filtering rules, aborting...\n");
4811 			return IPACM_FAILURE;
4812 		}
4813 
4814 		if(m_is_sta_mode != Q6_MHI_WAN)
4815 		{
4816 			IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
4817 			if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[2],
4818 				IPA_IP_v6, 1) == false)
4819 			{
4820 				IPACMERR("Error Deleting Filtering rules, aborting...\n");
4821 				return IPACM_FAILURE;
4822 			}
4823 			IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
4824 		}
4825 		else
4826 		{
4827 			IPACMDBG_H("in Q6_MHI_WAN mode, skip ICMPv6 flt rule deletion\n");
4828 		}
4829 		if (is_ipv6_frag_firewall_flt_rule_installed &&
4830 			check_dft_firewall_rules_attr_mask(&firewall_config))
4831 		{
4832 			if (m_filtering.DeleteFilteringHdls(&ipv6_frag_firewall_flt_rule_hdl, IPA_IP_v6, 1) == false)
4833 			{
4834 				IPACMERR("Error deleting IPv6 frag filtering rules.\n");
4835 				return IPACM_FAILURE;
4836 			}
4837 			is_ipv6_frag_firewall_flt_rule_installed = false;
4838 			IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
4839 		}
4840 		num_firewall_v6 = 0;
4841 	}
4842 	return IPACM_SUCCESS;
4843 }
4844 
4845 /* for STA mode: wan default route/filter rule delete */
handle_route_del_evt(ipa_ip_type iptype,bool delete_only)4846 int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype, bool delete_only)
4847 {
4848 	uint32_t tx_index;
4849 	ipacm_cmd_q_data evt_data;
4850 #ifdef WAN_IOC_NOTIFY_WAN_STATE
4851 	struct wan_ioctl_notify_wan_state wan_state;
4852 	int fd_wwan_ioctl;
4853 	memset(&wan_state, 0, sizeof(wan_state));
4854 #endif
4855 	int ret = IPACM_SUCCESS;
4856 
4857 	IPACMDBG_H("got handle_route_del_evt for STA-mode with ip-family:%d \n", iptype);
4858 
4859 	if(tx_prop == NULL)
4860 	{
4861 		IPACMDBG_H("No tx properties, ignore delete default route setting\n");
4862 		return IPACM_SUCCESS;
4863 	}
4864 
4865 	is_default_gateway = false;
4866 	IPACMDBG_H("Default route is deleted to iface %s.\n", dev_name);
4867 
4868 	if (((iptype == IPA_IP_v4) && (active_v4 == true)) ||
4869 			((iptype == IPA_IP_v6) && (active_v6 == true)))
4870 	{
4871 		if (!delete_only)
4872 		{
4873 			if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
4874 			{
4875 				/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
4876 				IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
4877 				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]);
4878 				IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
4879 			}
4880 			else
4881 			{
4882 				/* change wan_state for Q6_MHI */
4883 #ifdef WAN_IOC_NOTIFY_WAN_STATE
4884 				IPACMDBG_H("ipa_pm_q6_check to %d\n", ipa_pm_q6_check);
4885 				if(ipa_pm_q6_check == 1 && m_is_sta_mode == Q6_MHI_WAN)
4886 				{
4887 					fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
4888 					if(fd_wwan_ioctl < 0)
4889 					{
4890 						IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
4891 						return false;
4892 					}
4893 					IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE down to IPA_PM\n");
4894 					if(ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_WAN_STATE, &wan_state))
4895 					{
4896 						IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up);
4897 					}
4898 					close(fd_wwan_ioctl);
4899 				}
4900 				if (ipa_pm_q6_check > 0)
4901 					ipa_pm_q6_check--;
4902 				else
4903 					IPACMERR(" ipa_pm_q6_check becomes negative !!!\n");
4904 #endif
4905 			}
4906 		} // end of delete_only
4907 
4908 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
4909 		{
4910 		    if(iptype != tx_prop->tx[tx_index].ip)
4911 		    {
4912 		    	IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d, no RT-rule deleted\n",
4913 		    					    tx_index, tx_prop->tx[tx_index].ip,iptype);
4914 		    	continue;
4915 		    }
4916 
4917 			if (iptype == IPA_IP_v4)
4918 			{
4919 		    	IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", tx_index, tx_prop->tx[tx_index].ip,iptype);
4920 
4921 				if (m_routing.DeleteRoutingHdl(wan_route_rule_v4_hdl[tx_index], IPA_IP_v4) == false)
4922 				{
4923 					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);
4924 					return IPACM_FAILURE;
4925 				}
4926 			}
4927 			else
4928 			{
4929 		    	IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", tx_index, tx_prop->tx[tx_index].ip,iptype);
4930 
4931 				if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl[tx_index], IPA_IP_v6) == false)
4932 				{
4933 					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);
4934 					return IPACM_FAILURE;
4935 				}
4936 			}
4937 		}
4938 
4939 		/* Delete the default wan route*/
4940 		if (iptype == IPA_IP_v6 && m_is_sta_mode != Q6_MHI_WAN)
4941 		{
4942 		   	IPACMDBG_H("ip-type %d: default v6 wan RT-rule deleted\n",iptype);
4943 			if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl_a5[0], IPA_IP_v6) == false)
4944 			{
4945 			IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed!\n",IPA_IP_v6,wan_route_rule_v6_hdl_a5[0]);
4946 				return IPACM_FAILURE;
4947 			}
4948 		}
4949 
4950 		/* support delete only, not post wan_down event */
4951 		if(delete_only)
4952 		{
4953 			IPACMDBG_H(" Only delete default WAN routing rules (%d)\n", delete_only);
4954 			return IPACM_SUCCESS;
4955 		}
4956 
4957 		ipacm_event_iface_up *wandown_data;
4958 		wandown_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up));
4959 		if (wandown_data == NULL)
4960 		{
4961 			IPACMERR("Unable to allocate memory\n");
4962 			return IPACM_FAILURE;
4963 		}
4964 		memset(wandown_data, 0, sizeof(ipacm_event_iface_up));
4965 
4966 		if (iptype == IPA_IP_v4)
4967 		{
4968 			wandown_data->ipv4_addr = wan_v4_addr;
4969 			wandown_data->backhaul_type = m_is_sta_mode;
4970 			evt_data.event = IPA_HANDLE_WAN_DOWN;
4971 			evt_data.evt_data = (void *)wandown_data;
4972 			/* Insert IPA_HANDLE_WAN_DOWN to command queue */
4973 			IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN for IPv4 (%d.%d.%d.%d) \n",
4974 					(unsigned char)(wandown_data->ipv4_addr),
4975 					(unsigned char)(wandown_data->ipv4_addr >> 8),
4976 					(unsigned char)(wandown_data->ipv4_addr >> 16),
4977 					(unsigned char)(wandown_data->ipv4_addr >> 24));
4978 
4979 			IPACM_EvtDispatcher::PostEvt(&evt_data);
4980 			IPACMDBG_H("setup wan_up/active_v4= false \n");
4981 			IPACM_Wan::wan_up = false;
4982 			active_v4 = false;
4983 			if(IPACM_Wan::wan_up_v6)
4984 			{
4985 				IPACMDBG_H("modem v6-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name);
4986 			}
4987 			else
4988 			{
4989 				memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
4990 			}
4991 
4992 			/* Delete MHI frag rule */
4993 			if(delete_offload_frag_rule())
4994 			{
4995 				IPACMERR("Failed to delete DL frag rule \n");
4996 				ret = IPACM_FAILURE;
4997 			}
4998 
4999 			/* Delete tcp_fin_rst rule */
5000 			if(delete_tcp_fin_rst_exception_rule())
5001 			{
5002 				IPACMERR("Failed to delete tcp_fin_rst rule \n");
5003 				ret = IPACM_FAILURE;
5004 			}
5005 			return ret;
5006 		}
5007 		else
5008 		{
5009 			wandown_data->backhaul_type = m_is_sta_mode;
5010 			memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix));
5011 			evt_data.event = IPA_HANDLE_WAN_DOWN_V6;
5012 			evt_data.evt_data = (void *)wandown_data;
5013 			/* Insert IPA_HANDLE_WAN_DOWN to command queue */
5014 			IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN for IPv6 with prefix 0x%08x%08x\n", ipv6_prefix[0], ipv6_prefix[1]);
5015 			IPACM_EvtDispatcher::PostEvt(&evt_data);
5016 			IPACMDBG_H("setup wan_up_v6/active_v6= false \n");
5017 			IPACM_Wan::wan_up_v6 = false;
5018 			active_v6 = false;
5019 			if(IPACM_Wan::wan_up)
5020 			{
5021 				IPACMDBG_H("modem v4-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name);
5022 			}
5023 			else
5024 			{
5025 				memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
5026 			}
5027 			/* Delete MHI icmpv6 exception rule */
5028 			if(delete_icmpv6_exception_rule())
5029 			{
5030 				IPACMERR("Failed to delete icmpv6 rule \n");
5031 				return IPACM_FAILURE;
5032 			}
5033 
5034 		}
5035 	}
5036 	else
5037 	{
5038 		IPACMDBG_H(" The default WAN routing rules are deleted already \n");
5039 	}
5040 
5041 	return IPACM_SUCCESS;
5042 }
5043 
handle_route_del_evt_ex(ipa_ip_type iptype)5044 int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype)
5045 {
5046 	ipacm_cmd_q_data evt_data;
5047 #ifdef WAN_IOC_NOTIFY_WAN_STATE
5048 	struct wan_ioctl_notify_wan_state wan_state;
5049 	int fd_wwan_ioctl;
5050 	memset(&wan_state, 0, sizeof(wan_state));
5051 #endif
5052 
5053 	IPACMDBG_H("got handle_route_del_evt_ex with ip-family:%d \n", iptype);
5054 
5055 	if(tx_prop == NULL)
5056 	{
5057 		IPACMDBG_H("No tx properties, ignore delete default route setting\n");
5058 		return IPACM_SUCCESS;
5059 	}
5060 
5061 	is_default_gateway = false;
5062 	IPACMDBG_H("Default route is deleted to iface %s.\n", dev_name);
5063 
5064 	if (((iptype == IPA_IP_v4) && (active_v4 == true)) ||
5065 		((iptype == IPA_IP_v6) && (active_v6 == true)))
5066 	{
5067 		if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
5068 		{
5069 			/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
5070 			IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
5071 			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]);
5072 			IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
5073 		}
5074 #ifdef WAN_IOC_NOTIFY_WAN_STATE
5075 		else {
5076 			IPACMDBG_H("ipa_pm_q6_check to %d\n", ipa_pm_q6_check);
5077 			if(ipa_pm_q6_check == 1)
5078 			{
5079 				fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
5080 				if(fd_wwan_ioctl < 0)
5081 				{
5082 					IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
5083 					return false;
5084 				}
5085 				IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE down to IPA_PM\n");
5086 #ifdef WAN_IOCTL_NOTIFY_WAN_INTF_NAME
5087                                 strlcpy(wan_state.upstreamIface, dev_name, IFNAMSIZ);
5088 #endif
5089 				if(ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_WAN_STATE, &wan_state))
5090 				{
5091 					IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up);
5092 				}
5093 				close(fd_wwan_ioctl);
5094 
5095 				/* Store the Offload state. */
5096 				FILE *fp = NULL;
5097 				fp = fopen(IPA_OFFLOAD_TETHER_STATE_FILE_NAME, "w");
5098 				if (fp == NULL)
5099 				{
5100 					IPACMERR("Failed to write offload state to %s, error is %d - %s\n",
5101 						IPA_OFFLOAD_TETHER_STATE_FILE_NAME, errno, strerror(errno));
5102 				}
5103 				else
5104 				{
5105 					fprintf(fp, "UPSTREAM=%s,STATE=DOWN", dev_name);
5106 					fclose(fp);
5107 				}
5108 			}
5109 			if (ipa_pm_q6_check > 0)
5110 				ipa_pm_q6_check--;
5111 			else
5112 				IPACMERR(" ipa_pm_q6_check becomes negative !!!\n");
5113 		}
5114 #endif
5115 		/* Delete the default route*/
5116 		if (iptype == IPA_IP_v6)
5117 		{
5118 			IPACMDBG_H("ip-type %d: default v6 wan RT-rule deleted\n",iptype);
5119 			if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl_a5[0], IPA_IP_v6) == false)
5120 			{
5121 				IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed!\n",IPA_IP_v6,wan_route_rule_v6_hdl_a5[0]);
5122 				return IPACM_FAILURE;
5123 			}
5124 		}
5125 
5126 		ipacm_event_iface_up *wandown_data;
5127 		wandown_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up));
5128 		if (wandown_data == NULL)
5129 		{
5130 			IPACMERR("Unable to allocate memory\n");
5131 			return IPACM_FAILURE;
5132 		}
5133 		memset(wandown_data, 0, sizeof(ipacm_event_iface_up));
5134 
5135 		if (iptype == IPA_IP_v4)
5136 		{
5137 			wandown_data->ipv4_addr = wan_v4_addr;
5138 			wandown_data->backhaul_type = m_is_sta_mode;
5139 			evt_data.event = IPA_HANDLE_WAN_DOWN;
5140 			evt_data.evt_data = (void *)wandown_data;
5141 			/* Insert IPA_HANDLE_WAN_DOWN to command queue */
5142 			IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN for IPv4 with address: 0x%x\n", wan_v4_addr);
5143 			IPACM_EvtDispatcher::PostEvt(&evt_data);
5144 
5145 			IPACMDBG_H("setup wan_up/active_v4= false \n");
5146 			IPACM_Wan::wan_up = false;
5147 			active_v4 = false;
5148 			if(IPACM_Wan::wan_up_v6)
5149 			{
5150 				IPACMDBG_H("modem v6-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name);
5151 			}
5152 			else
5153 			{
5154 				memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
5155 			}
5156 		}
5157 		else
5158 		{
5159 
5160 			wandown_data->backhaul_type = m_is_sta_mode;
5161 			memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix));
5162 			evt_data.event = IPA_HANDLE_WAN_DOWN_V6;
5163 			evt_data.evt_data = (void *)wandown_data;
5164 			IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN_V6 for IPv6 with prefix 0x%08x%08x\n", ipv6_prefix[0], ipv6_prefix[1]);
5165 			IPACM_EvtDispatcher::PostEvt(&evt_data);
5166 
5167 			IPACMDBG_H("setup wan_up_v6/active_v6= false \n");
5168 			IPACM_Wan::wan_up_v6 = false;
5169 			active_v6 = false;
5170 			if(IPACM_Wan::wan_up)
5171 			{
5172 				IPACMDBG_H("modem v4-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name);
5173 			}
5174 			else
5175 			{
5176 				memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
5177 			}
5178 		}
5179 	}
5180 	else
5181 	{
5182 		IPACMDBG_H(" The default WAN routing rules are deleted already \n");
5183 	}
5184 
5185 	return IPACM_SUCCESS;
5186 }
5187 
5188 /* configure the initial embms filter rules */
config_dft_embms_rules(ipa_ioc_add_flt_rule * pFilteringTable_v4,ipa_ioc_add_flt_rule * pFilteringTable_v6)5189 int IPACM_Wan::config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, ipa_ioc_add_flt_rule *pFilteringTable_v6)
5190 {
5191 	struct ipa_flt_rule_add flt_rule_entry;
5192 	struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx;
5193 	struct ipa_ioc_generate_flt_eq flt_eq;
5194 
5195 	if (rx_prop == NULL)
5196 	{
5197 		IPACMDBG("No rx properties registered for iface %s\n", dev_name);
5198 		return IPACM_SUCCESS;
5199 	}
5200 
5201 	if(pFilteringTable_v4 == NULL || pFilteringTable_v6 == NULL)
5202 	{
5203 		IPACMERR("Either v4 or v6 filtering table is empty.\n");
5204 		return IPACM_FAILURE;
5205 	}
5206 
5207 	/* set up ipv4 odu rule*/
5208 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
5209 
5210 	/* get eMBMS ODU tbl index*/
5211 	memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
5212 	strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, IPA_RESOURCE_NAME_MAX);
5213 	rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
5214 	rt_tbl_idx.ip = IPA_IP_v4;
5215 	if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
5216 	{
5217 		IPACMERR("Failed to get routing table index from name\n");
5218 		return IPACM_FAILURE;
5219 	}
5220 	IPACMDBG_H("Odu routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
5221 
5222 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
5223 	flt_rule_entry.flt_rule_hdl = -1;
5224 	flt_rule_entry.status = -1;
5225 	flt_rule_entry.at_rear = false;
5226 
5227 	flt_rule_entry.rule.retain_hdr = 0;
5228 	flt_rule_entry.rule.to_uc = 0;
5229 	flt_rule_entry.rule.eq_attrib_type = 1;
5230 	flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
5231 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
5232 		flt_rule_entry.rule.hashable = true;
5233 	flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
5234 
5235 	memcpy(&flt_rule_entry.rule.attrib,
5236 				 &rx_prop->rx[0].attrib,
5237 				 sizeof(struct ipa_rule_attrib));
5238 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
5239 	flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000;
5240 	flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000;
5241 
5242 	memset(&flt_eq, 0, sizeof(flt_eq));
5243 	memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
5244 	flt_eq.ip = IPA_IP_v4;
5245 	if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
5246 	{
5247 		IPACMERR("Failed to get eq_attrib\n");
5248 		return IPACM_FAILURE;
5249 	}
5250 	memcpy(&flt_rule_entry.rule.eq_attrib,
5251 				 &flt_eq.eq_attrib,
5252 				 sizeof(flt_rule_entry.rule.eq_attrib));
5253 
5254 	memcpy(&(pFilteringTable_v4->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
5255 
5256 	/* construc v6 rule */
5257 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
5258 	/* get eMBMS ODU tbl*/
5259 	memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
5260 	strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, IPA_RESOURCE_NAME_MAX);
5261 	rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
5262 	rt_tbl_idx.ip = IPA_IP_v6;
5263 	if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
5264 	{
5265 		IPACMERR("Failed to get routing table index from name\n");
5266 		return IPACM_FAILURE;
5267 	}
5268 	IPACMDBG_H("Odu routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
5269 
5270 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
5271 	flt_rule_entry.flt_rule_hdl = -1;
5272 	flt_rule_entry.status = -1;
5273 	flt_rule_entry.at_rear = false;
5274 
5275 	flt_rule_entry.rule.retain_hdr = 0;
5276 	flt_rule_entry.rule.to_uc = 0;
5277 	flt_rule_entry.rule.eq_attrib_type = 1;
5278 	flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
5279 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
5280 		flt_rule_entry.rule.hashable = true;
5281 	flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
5282 
5283 	memcpy(&flt_rule_entry.rule.attrib,
5284 				 &rx_prop->rx[0].attrib,
5285 				 sizeof(struct ipa_rule_attrib));
5286 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
5287 	flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;
5288 	flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
5289 	flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
5290 	flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
5291 	flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000;
5292 	flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
5293 	flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
5294 	flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
5295 
5296 	memset(&flt_eq, 0, sizeof(flt_eq));
5297 	memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
5298 	flt_eq.ip = IPA_IP_v6;
5299 	if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
5300 	{
5301 		IPACMERR("Failed to get eq_attrib\n");
5302 		return IPACM_FAILURE;
5303 	}
5304 	memcpy(&flt_rule_entry.rule.eq_attrib,
5305 				 &flt_eq.eq_attrib,
5306 				 sizeof(flt_rule_entry.rule.eq_attrib));
5307 
5308 	memcpy(&(pFilteringTable_v6->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
5309 
5310 	return IPACM_SUCCESS;
5311 }
5312 
5313 
5314 /*for STA mode: handle wan-iface down event */
handle_down_evt()5315 int IPACM_Wan::handle_down_evt()
5316 {
5317 	int res = IPACM_SUCCESS;
5318 	uint32_t i, tether_total;
5319 	int ipa_if_num_tether_tmp[IPA_MAX_IFACE_ENTRIES];
5320 
5321 	tether_total = 0;
5322 	memset(ipa_if_num_tether_tmp, 0, IPA_MAX_IFACE_ENTRIES);
5323 
5324 	IPACMDBG_H(" wan handle_down_evt \n");
5325 	if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
5326 	{
5327 		/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
5328 		IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
5329 		if (tx_prop != NULL)
5330 		{
5331 			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]);
5332 			IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
5333 		}
5334 	}
5335 	/* no iface address up, directly close iface*/
5336 	if (ip_type == IPACM_IP_NULL)
5337 	{
5338 		goto fail;
5339 	}
5340 
5341 	/* make sure default routing rules and firewall rules are deleted*/
5342 	if (active_v4)
5343 	{
5344 		if (rx_prop != NULL)
5345 		{
5346 			del_dft_firewall_rules(IPA_IP_v4);
5347 		}
5348 		handle_route_del_evt(IPA_IP_v4);
5349 		IPACMDBG_H("Delete default v4 routing rules\n");
5350 
5351 
5352 #ifdef FEATURE_IPA_ANDROID
5353 		/* posting wan_down_tether for lan clients */
5354 #ifdef FEATURE_IPACM_HAL
5355 		IPACMDBG_H("Posting IPA_WAN_DOWN_TETHER_EVENT for IPV4\n");
5356 		post_wan_down_tether_evt(IPA_IP_v4, 0);
5357 #else
5358 		for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++)
5359 		{
5360 			ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i];
5361 		}
5362 		tether_total = IPACM_Wan::ipa_if_num_tether_v4_total;
5363 		for (i=0; i < tether_total; i++)
5364 		{
5365 			post_wan_down_tether_evt(IPA_IP_v4, ipa_if_num_tether_tmp[i]);
5366 			IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n",
5367 				i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
5368 		}
5369 #endif
5370 #endif
5371 	}
5372 
5373 	if (active_v6)
5374 	{
5375 		if (rx_prop != NULL)
5376 		{
5377 			del_dft_firewall_rules(IPA_IP_v6);
5378 		}
5379 		handle_route_del_evt(IPA_IP_v6);
5380 		IPACMDBG_H("Delete default v6 routing rules\n");
5381 
5382 #ifdef FEATURE_IPA_ANDROID
5383 		/* posting wan_down_tether for lan clients */
5384 #ifdef FEATURE_IPACM_HAL
5385 		IPACMDBG_H("Posting IPA_WAN_DOWN_TETHER_EVENT for IPV6\n");
5386 		post_wan_down_tether_evt(IPA_IP_v6, 0);
5387 #else
5388 		for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++)
5389 		{
5390 			ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i];
5391 		}
5392 		tether_total = IPACM_Wan::ipa_if_num_tether_v6_total;
5393 		for (i=0; i < tether_total; i++)
5394 		{
5395 			post_wan_down_tether_evt(IPA_IP_v6, ipa_if_num_tether_tmp[i]);
5396 			IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n",
5397 				i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
5398 		}
5399 #endif
5400 #endif
5401 	}
5402 
5403 	/* Delete default v4 RT rule */
5404 	if (ip_type != IPA_IP_v6 && wan_v4_addr_set)
5405 	{
5406 		/* no need delete v4 RSC routing rules */
5407 		IPACMDBG_H("Delete default v4 routing rules\n");
5408 		if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
5409 		{
5410 			IPACMERR("Routing rule deletion failed!\n");
5411 			res = IPACM_FAILURE;
5412 			goto fail;
5413 		}
5414 	}
5415 
5416 	/* delete default v6 RT rule */
5417 	if (ip_type != IPA_IP_v4)
5418 	{
5419 		IPACMDBG_H("Delete default v6 routing rules\n");
5420 		/* May have multiple ipv6 iface-routing rules*/
5421 		for (i = 0; i < 2*num_dft_rt_v6; i++)
5422 		{
5423 			if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
5424 			{
5425 				IPACMERR("Routing rule deletion failed!\n");
5426 				res = IPACM_FAILURE;
5427 				goto fail;
5428 			}
5429 		}
5430 		IPACMDBG_H("finished delete default v6 RT rules\n ");
5431 	}
5432 
5433 	/* check software routing fl rule hdl */
5434 	if (softwarerouting_act == true)
5435 	{
5436 		if(m_is_sta_mode == Q6_MHI_WAN)
5437 		{
5438 			handle_software_routing_disable(true);
5439 		}
5440 		else
5441 		{
5442 			handle_software_routing_disable(false);
5443 		}
5444 	}
5445 
5446 	if(m_is_sta_mode != Q6_MHI_WAN)
5447 	{
5448 		/* clean wan-client header, routing rules */
5449 		IPACMDBG_H("left %d wan clients need to be deleted \n ", num_wan_client);
5450 		for (i = 0; i < num_wan_client; i++)
5451 		{
5452 				/* Del NAT rules before ipv4 RT rules are delete */
5453 				if(get_client_memptr(wan_client, i)->ipv4_set == true)
5454 				{
5455 					IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wan_client, i)->v4_addr);
5456 					CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, i)->v4_addr);
5457 				}
5458 
5459 				if (delete_wan_rtrules(i, IPA_IP_v4))
5460 				{
5461 					IPACMERR("unbale to delete wan-client v4 route rules for index %d\n", i);
5462 					res = IPACM_FAILURE;
5463 					goto fail;
5464 				}
5465 
5466 				if (delete_wan_rtrules(i, IPA_IP_v6))
5467 				{
5468 					IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
5469 					res = IPACM_FAILURE;
5470 					goto fail;
5471 				}
5472 
5473 				IPACMDBG_H("Delete %d client header\n", num_wan_client);
5474 				if(get_client_memptr(wan_client, i)->ipv4_header_set == true)
5475 				{
5476 					if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v4)
5477 						== false)
5478 					{
5479 						res = IPACM_FAILURE;
5480 						goto fail;
5481 					}
5482 				}
5483 				if(get_client_memptr(wan_client, i)->ipv6_header_set == true)
5484 				{
5485 					if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v6)
5486 						== false)
5487 					{
5488 						res = IPACM_FAILURE;
5489 						goto fail;
5490 					}
5491 				}
5492 		} /* end of for loop */
5493 		/* free the edm clients cache */
5494 		IPACMDBG_H("Free wan clients cache\n");
5495 
5496 		/* free dft ipv4 filter rule handlers if any */
5497 		if (ip_type != IPA_IP_v6 && rx_prop != NULL)
5498 		{
5499 			if (dft_v4fl_rule_hdl[0] != 0)
5500 			{
5501 				if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl,
5502 					IPA_IP_v4,
5503 					IPV4_DEFAULT_FILTERTING_RULES) == false)
5504 				{
5505 					IPACMERR("Error Delete Filtering rules, aborting...\n");
5506 					res = IPACM_FAILURE;
5507 					goto fail;
5508 				}
5509 				IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
5510 				IPACMDBG_H("finished delete default v4 filtering rules\n ");
5511 			}
5512 		}
5513 		/* free dft ipv6 filter rule handlers if any */
5514 		if (ip_type != IPA_IP_v4 && rx_prop != NULL)
5515 		{
5516 			if (dft_v6fl_rule_hdl[0] != 0)
5517 			{
5518 				if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl,
5519 					IPA_IP_v6,
5520 					IPV6_DEFAULT_FILTERTING_RULES) == false)
5521 				{
5522 					IPACMERR("ErrorDeleting Filtering rule, aborting...\n");
5523 					res = IPACM_FAILURE;
5524 					goto fail;
5525 				}
5526 				IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
5527 			}
5528 			if(num_ipv6_dest_flt_rule > 0 && num_ipv6_dest_flt_rule <= MAX_DEFAULT_v6_ROUTE_RULES)
5529 			{
5530 				if(m_filtering.DeleteFilteringHdls(ipv6_dest_flt_rule_hdl,  IPA_IP_v6, num_ipv6_dest_flt_rule) == false)
5531 				{
5532 					IPACMERR("Failed to delete ipv6 dest flt rules.\n");
5533 					res = IPACM_FAILURE;
5534 					goto fail;
5535 				}
5536 				IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_ipv6_dest_flt_rule);
5537 			}
5538 			IPACMDBG_H("finished delete default v6 filtering rules\n ");
5539 		}
5540 		if(hdr_proc_hdl_dummy_v6)
5541 		{
5542 			if(m_header.DeleteHeaderProcCtx(hdr_proc_hdl_dummy_v6) == false)
5543 			{
5544 				IPACMERR("Failed to delete hdr_proc_hdl_dummy_v6\n");
5545 				res = IPACM_FAILURE;
5546 				goto fail;
5547 			}
5548 		}
5549 		if(hdr_hdl_dummy_v6)
5550 		{
5551 			if (m_header.DeleteHeaderHdl(hdr_hdl_dummy_v6) == false)
5552 			{
5553 				IPACMERR("Failed to delete hdr_hdl_dummy_v6\n");
5554 				res = IPACM_FAILURE;
5555 				goto fail;
5556 			}
5557 		}
5558 	}
5559 fail:
5560 	if (tx_prop != NULL)
5561 	{
5562 		free(tx_prop);
5563 	}
5564 	if (rx_prop != NULL)
5565 	{
5566 		free(rx_prop);
5567 	}
5568 	if (iface_query != NULL)
5569 	{
5570 		free(iface_query);
5571 	}
5572 	if (wan_route_rule_v4_hdl != NULL)
5573 	{
5574 		free(wan_route_rule_v4_hdl);
5575 	}
5576 	if (wan_route_rule_v6_hdl != NULL)
5577 	{
5578 		free(wan_route_rule_v6_hdl);
5579 	}
5580 	if (wan_route_rule_v6_hdl_a5 != NULL)
5581 	{
5582 		free(wan_route_rule_v6_hdl_a5);
5583 	}
5584 	if (wan_client != NULL)
5585 	{
5586 		free(wan_client);
5587 	}
5588 	close(m_fd_ipa);
5589 	return res;
5590 }
5591 
handle_down_evt_ex()5592 int IPACM_Wan::handle_down_evt_ex()
5593 {
5594 	int res = IPACM_SUCCESS;
5595 	uint32_t i;
5596 #ifndef FEATURE_IPACM_HAL
5597 	uint32_t tether_total;
5598 	int ipa_if_num_tether_tmp[IPA_MAX_IFACE_ENTRIES];
5599 #endif
5600 
5601 	IPACMDBG_H(" wan handle_down_evt \n");
5602 
5603 	/* free ODU filter rule handlers */
5604 	if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == EMBMS_IF)
5605 	{
5606 		embms_is_on = false;
5607 		if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
5608 		{
5609 			/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
5610 			IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
5611 			if (tx_prop != NULL)
5612 			{
5613 				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]);
5614 				IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
5615 			}
5616 		}
5617 		if (rx_prop != NULL)
5618 		{
5619 			install_wan_filtering_rule(false);
5620 			IPACMDBG("finished delete embms filtering rule\n ");
5621 		}
5622 		goto fail;
5623 	}
5624 
5625 	/* no iface address up, directly close iface*/
5626 	if (ip_type == IPACM_IP_NULL)
5627 	{
5628 		goto fail;
5629 	}
5630 
5631 #ifndef IPA_MTU_EVENT_MAX
5632 	/* reset the mtu size */
5633 	mtu_v4 = DEFAULT_MTU_SIZE;
5634 	mtu_v4_set = false;
5635 	mtu_v6 = DEFAULT_MTU_SIZE;
5636 	mtu_v6_set = false;
5637 #endif
5638 
5639 	if(ip_type == IPA_IP_v4)
5640 	{
5641 		num_ipv4_modem_pdn--;
5642 		IPACMDBG_H("Now the number of ipv4 modem pdn is %d.\n", num_ipv4_modem_pdn);
5643 		/* only when default gw goes down we post WAN_DOWN event*/
5644 		if(is_default_gateway == true)
5645 		{
5646 			IPACM_Wan::wan_up = false;
5647 			del_wan_firewall_rule(IPA_IP_v4);
5648 			install_wan_filtering_rule(false);
5649 			handle_route_del_evt_ex(IPA_IP_v4);
5650 #ifdef FEATURE_IPA_ANDROID
5651 			/* posting wan_down_tether for all lan clients */
5652 #ifdef FEATURE_IPACM_HAL
5653 			post_wan_down_tether_evt(IPA_IP_v4, 0);
5654 #else
5655 			for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++)
5656 			{
5657 				ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i];
5658 			}
5659 			tether_total = IPACM_Wan::ipa_if_num_tether_v4_total;
5660 			for (i=0; i < tether_total; i++)
5661 			{
5662 				post_wan_down_tether_evt(IPA_IP_v4, ipa_if_num_tether_tmp[i]);
5663 				IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n",
5664 					i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
5665 			}
5666 #endif
5667 #endif
5668 			if(IPACM_Wan::wan_up_v6)
5669 			{
5670 				IPACMDBG_H("modem v6-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name);
5671 			}
5672 			else
5673 			{
5674 				memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
5675 			}
5676 		}
5677 
5678 		/* only when the last ipv4 modem interface goes down, delete ipv4 default flt rules*/
5679 		if(num_ipv4_modem_pdn == 0)
5680 		{
5681 			IPACMDBG_H("Now the number of modem ipv4 interface is 0, delete default flt rules.\n");
5682 		IPACM_Wan::num_v4_flt_rule = 0;
5683 		memset(IPACM_Wan::flt_rule_v4, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add));
5684 		install_wan_filtering_rule(false);
5685 		}
5686 
5687 		IPACMDBG_H("Delete default v4 coalesce routing rules\n");
5688 		if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
5689 		{
5690 			IPACMERR("Routing rule RSC TCP deletion failed!\n");
5691 			res = IPACM_FAILURE;
5692 			goto fail;
5693 		}
5694 
5695 		if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
5696 		{
5697 			IPACMERR("Routing rule RSB UDP deletion failed!\n");
5698 			res = IPACM_FAILURE;
5699 			goto fail;
5700 		}
5701 
5702 		if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
5703 		{
5704 			IPACMERR("Routing rule deletion failed!\n");
5705 			res = IPACM_FAILURE;
5706 			goto fail;
5707 		}
5708 	}
5709 	else if(ip_type == IPA_IP_v6)
5710 	{
5711 	    if (num_dft_rt_v6 > 1)
5712 			num_ipv6_modem_pdn--;
5713 		IPACMDBG_H("Now the number of ipv6 modem pdn is %d.\n", num_ipv6_modem_pdn);
5714 		/* only when default gw goes down we post WAN_DOWN event*/
5715 		if(is_default_gateway == true)
5716 		{
5717 			IPACM_Wan::wan_up_v6 = false;
5718 			del_wan_firewall_rule(IPA_IP_v6);
5719 			install_wan_filtering_rule(false);
5720 			handle_route_del_evt_ex(IPA_IP_v6);
5721 #ifdef FEATURE_IPA_ANDROID
5722 			/* posting wan_down_tether for all lan clients */
5723 #ifdef FEATURE_IPACM_HAL
5724 			post_wan_down_tether_evt(IPA_IP_v6, 0);
5725 #else
5726 			for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++)
5727 			{
5728 				ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i];
5729 			}
5730 			tether_total = IPACM_Wan::ipa_if_num_tether_v6_total;
5731 			for (i=0; i < tether_total; i++)
5732 			{
5733 				post_wan_down_tether_evt(IPA_IP_v6, ipa_if_num_tether_tmp[i]);
5734 				IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n",
5735 					i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
5736 			}
5737 #endif
5738 #endif
5739 			if(IPACM_Wan::wan_up)
5740 			{
5741 				IPACMDBG_H("modem v4-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name);
5742 			}
5743 			else
5744 			{
5745 				memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
5746 			}
5747 		}
5748 
5749 		/* only when the last ipv6 modem interface goes down, delete ipv6 default flt rules*/
5750 		if(num_ipv6_modem_pdn == 0)
5751 		{
5752 			IPACMDBG_H("Now the number of modem ipv6 interface is 0, delete default flt rules.\n");
5753 		IPACM_Wan::num_v6_flt_rule = 0;
5754 		memset(IPACM_Wan::flt_rule_v6, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add));
5755 		install_wan_filtering_rule(false);
5756 		}
5757 
5758 		for (i = 0; i < 2*num_dft_rt_v6; i++)
5759 		{
5760 			/* delete v6 colasce rules */
5761 			if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
5762 			{
5763 				IPACMERR("Colasce Routing rule deletion failed!\n");
5764 				res = IPACM_FAILURE;
5765 				goto fail;
5766 			}
5767 			if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
5768 			{
5769 				IPACMERR("Routing rule deletion failed!\n");
5770 				res = IPACM_FAILURE;
5771 				goto fail;
5772 			}
5773 		}
5774 	}
5775 	else
5776 	{
5777 		num_ipv4_modem_pdn--;
5778 		IPACMDBG_H("Now the number of ipv4 modem pdn is %d.\n", num_ipv4_modem_pdn);
5779 	    if (num_dft_rt_v6 > 1)
5780 			num_ipv6_modem_pdn--;
5781 		IPACMDBG_H("Now the number of ipv6 modem pdn is %d.\n", num_ipv6_modem_pdn);
5782 		/* only when default gw goes down we post WAN_DOWN event*/
5783 		if(is_default_gateway == true)
5784 		{
5785 			IPACM_Wan::wan_up = false;
5786 			del_wan_firewall_rule(IPA_IP_v4);
5787 			handle_route_del_evt_ex(IPA_IP_v4);
5788 #ifdef FEATURE_IPA_ANDROID
5789 			/* posting wan_down_tether for all lan clients */
5790 #ifdef FEATURE_IPACM_HAL
5791 			IPACMDBG_H("Posting IPA_WAN_DOWN_TETHER_EVENT for IPV4\n");
5792 			post_wan_down_tether_evt(IPA_IP_v4, 0);
5793 #else
5794 			for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++)
5795 			{
5796 				ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i];
5797 			}
5798 			tether_total = IPACM_Wan::ipa_if_num_tether_v4_total;
5799 			for (i=0; i < tether_total; i++)
5800 			{
5801 				post_wan_down_tether_evt(IPA_IP_v4, ipa_if_num_tether_tmp[i]);
5802 				IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n",
5803 					i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
5804 			}
5805 #endif
5806 #endif
5807 			IPACM_Wan::wan_up_v6 = false;
5808 			del_wan_firewall_rule(IPA_IP_v6);
5809 			handle_route_del_evt_ex(IPA_IP_v6);
5810 #ifdef FEATURE_IPA_ANDROID
5811 			/* posting wan_down_tether for all lan clients */
5812 #ifdef FEATURE_IPACM_HAL
5813                         IPACMDBG_H("Posting IPA_WAN_DOWN_TETHER_EVENT for IPV6\n");
5814                         post_wan_down_tether_evt(IPA_IP_v6, 0);
5815 #else
5816 			for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++)
5817 			{
5818 				ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i];
5819 			}
5820 			tether_total = IPACM_Wan::ipa_if_num_tether_v6_total;
5821 			for (i=0; i < tether_total; i++)
5822 			{
5823 				post_wan_down_tether_evt(IPA_IP_v6, ipa_if_num_tether_tmp[i]);
5824 				IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n",
5825 					i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
5826 			}
5827 #endif
5828 #endif
5829 			memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
5830 
5831 			install_wan_filtering_rule(false);
5832 		}
5833 
5834 		/* only when the last ipv4 modem interface goes down, delete ipv4 default flt rules*/
5835 		if(num_ipv4_modem_pdn == 0)
5836 		{
5837 			IPACMDBG_H("Now the number of modem ipv4 interface is 0, delete default flt rules.\n");
5838 			IPACM_Wan::num_v4_flt_rule = 0;
5839 			memset(IPACM_Wan::flt_rule_v4, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add));
5840 			install_wan_filtering_rule(false);
5841 		}
5842 		/* only when the last ipv6 modem interface goes down, delete ipv6 default flt rules*/
5843 		if(num_ipv6_modem_pdn == 0)
5844 		{
5845 			IPACMDBG_H("Now the number of modem ipv6 interface is 0, delete default flt rules.\n");
5846 			IPACM_Wan::num_v6_flt_rule = 0;
5847 			memset(IPACM_Wan::flt_rule_v6, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add));
5848 			install_wan_filtering_rule(false);
5849 		}
5850 
5851 		IPACMDBG_H("Delete default v4 coalesce routing rules\n");
5852 		if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
5853 		{
5854 			IPACMERR("Routing rule RSC TCP deletion failed!\n");
5855 			res = IPACM_FAILURE;
5856 			goto fail;
5857 		}
5858 
5859 		if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
5860 		{
5861 			IPACMERR("Routing rule RSB UDP deletion failed!\n");
5862 			res = IPACM_FAILURE;
5863 			goto fail;
5864 		}
5865 
5866 		if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
5867 		{
5868 			IPACMERR("Routing rule deletion failed!\n");
5869 			res = IPACM_FAILURE;
5870 			goto fail;
5871 		}
5872 
5873 		for (i = 0; i < 2*num_dft_rt_v6; i++)
5874 		{
5875 			/* delete v6 colasce rules */
5876 			if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
5877 			{
5878 				IPACMERR("Colasce Routing rule deletion failed!\n");
5879 				res = IPACM_FAILURE;
5880 				goto fail;
5881 			}
5882 			if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
5883 			{
5884 				IPACMERR("Routing rule deletion failed!\n");
5885 				res = IPACM_FAILURE;
5886 				goto fail;
5887 			}
5888 		}
5889 	}
5890 
5891 //	/* check software routing fl rule hdl */
5892 //	if (softwarerouting_act == true)
5893 //	{
5894 //		handle_software_routing_disable();
5895 //	}
5896 
5897 fail:
5898 	if (tx_prop != NULL)
5899 	{
5900 		free(tx_prop);
5901 	}
5902 	if (rx_prop != NULL)
5903 	{
5904 		free(rx_prop);
5905 	}
5906 	if (ext_prop != NULL)
5907 	{
5908 		free(ext_prop);
5909 	}
5910 	if (iface_query != NULL)
5911 	{
5912 		free(iface_query);
5913 	}
5914 	if (wan_route_rule_v4_hdl != NULL)
5915 	{
5916 		free(wan_route_rule_v4_hdl);
5917 	}
5918 	if (wan_route_rule_v6_hdl != NULL)
5919 	{
5920 		free(wan_route_rule_v6_hdl);
5921 	}
5922 	if (wan_route_rule_v6_hdl_a5 != NULL)
5923 	{
5924 		free(wan_route_rule_v6_hdl_a5);
5925 	}
5926 	if (wan_client != NULL)
5927 	{
5928 		free(wan_client);
5929 	}
5930 	close(m_fd_ipa);
5931 	return res;
5932 }
5933 
install_wan_filtering_rule(bool is_sw_routing)5934 int IPACM_Wan::install_wan_filtering_rule(bool is_sw_routing)
5935 {
5936 	int len, res = IPACM_SUCCESS;
5937 	uint8_t mux_id;
5938 	ipa_ioc_add_flt_rule *pFilteringTable_v4 = NULL;
5939 	ipa_ioc_add_flt_rule *pFilteringTable_v6 = NULL;
5940 
5941 	mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
5942 	if(rx_prop == NULL)
5943 	{
5944 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
5945 		return IPACM_SUCCESS;
5946 	}
5947 	if (is_sw_routing == true ||
5948 			IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true)
5949 	{
5950 		/* contruct SW-RT rules to Q6*/
5951 		struct ipa_flt_rule_add flt_rule_entry;
5952 		struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx;
5953 		ipa_ioc_generate_flt_eq flt_eq;
5954 
5955 		IPACMDBG("\n");
5956 		if (softwarerouting_act == true)
5957 		{
5958 			IPACMDBG("already setup software_routing rule for (%s)iface ip-family %d\n",
5959 								IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ip_type);
5960 			return IPACM_SUCCESS;
5961 		}
5962 
5963 		len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
5964 		pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len);
5965 		if (pFilteringTable_v4 == NULL)
5966 		{
5967 			IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
5968 			return IPACM_FAILURE;
5969 		}
5970 		memset(pFilteringTable_v4, 0, len);
5971 		IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is 1\n");
5972 
5973 		pFilteringTable_v4->commit = 1;
5974 		pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe;
5975 		pFilteringTable_v4->global = false;
5976 		pFilteringTable_v4->ip = IPA_IP_v4;
5977 		pFilteringTable_v4->num_rules = (uint8_t)1;
5978 
5979 		/* Configuring Software-Routing Filtering Rule */
5980 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
5981 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
5982 		strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
5983 		rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
5984 		rt_tbl_idx.ip = IPA_IP_v4;
5985 		if(ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx) < 0)
5986 		{
5987 			IPACMERR("Failed to get routing table index from name\n");
5988 			res = IPACM_FAILURE;
5989 			goto fail;
5990 		}
5991 		IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
5992 
5993 		flt_rule_entry.at_rear = false;
5994 		flt_rule_entry.flt_rule_hdl = -1;
5995 		flt_rule_entry.status = -1;
5996 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
5997 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
5998 			flt_rule_entry.rule.hashable = true;
5999 
6000 		flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
6001 
6002 		memcpy(&flt_rule_entry.rule.attrib,
6003 					&rx_prop->rx[0].attrib,
6004 					sizeof(flt_rule_entry.rule.attrib));
6005 		flt_rule_entry.rule.retain_hdr = 0;
6006 		flt_rule_entry.rule.to_uc = 0;
6007 		flt_rule_entry.rule.eq_attrib_type = 1;
6008 
6009 		memset(&flt_eq, 0, sizeof(flt_eq));
6010 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
6011 		flt_eq.ip = IPA_IP_v4;
6012 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
6013 		{
6014 			IPACMERR("Failed to get eq_attrib\n");
6015 			res = IPACM_FAILURE;
6016 			goto fail;
6017 		}
6018 		memcpy(&flt_rule_entry.rule.eq_attrib,
6019 			&flt_eq.eq_attrib,
6020 			sizeof(flt_rule_entry.rule.eq_attrib));
6021 		memcpy(&(pFilteringTable_v4->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
6022 
6023 		len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
6024 		pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len);
6025 		if (pFilteringTable_v6 == NULL)
6026 		{
6027 			IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
6028 			free(pFilteringTable_v4);
6029 			return IPACM_FAILURE;
6030 		}
6031 		memset(pFilteringTable_v6, 0, len);
6032 		IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is 1\n");
6033 
6034 		pFilteringTable_v6->commit = 1;
6035 		pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe;
6036 		pFilteringTable_v6->global = false;
6037 		pFilteringTable_v6->ip = IPA_IP_v6;
6038 		pFilteringTable_v6->num_rules = (uint8_t)1;
6039 
6040 		/* Configuring Software-Routing Filtering Rule */
6041 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
6042 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
6043 		strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
6044 		rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
6045 		rt_tbl_idx.ip = IPA_IP_v6;
6046 		if(ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx) < 0)
6047 		{
6048 			IPACMERR("Failed to get routing table index from name\n");
6049 			res = IPACM_FAILURE;
6050 			goto fail;
6051 		}
6052 		IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
6053 
6054 		flt_rule_entry.at_rear = false;
6055 		flt_rule_entry.flt_rule_hdl = -1;
6056 		flt_rule_entry.status = -1;
6057 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
6058 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
6059 			flt_rule_entry.rule.hashable = true;
6060 		flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
6061 		memcpy(&flt_rule_entry.rule.attrib,
6062 					&rx_prop->rx[0].attrib,
6063 					sizeof(flt_rule_entry.rule.attrib));
6064 		flt_rule_entry.rule.retain_hdr = 0;
6065 		flt_rule_entry.rule.to_uc = 0;
6066 		flt_rule_entry.rule.eq_attrib_type = 1;
6067 
6068 		memset(&flt_eq, 0, sizeof(flt_eq));
6069 		memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
6070 		flt_eq.ip = IPA_IP_v6;
6071 		if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
6072 		{
6073 			IPACMERR("Failed to get eq_attrib\n");
6074 			res = IPACM_FAILURE;
6075 			goto fail;
6076 		}
6077 		memcpy(&flt_rule_entry.rule.eq_attrib,
6078 			&flt_eq.eq_attrib,
6079 			sizeof(flt_rule_entry.rule.eq_attrib));
6080 		memcpy(&(pFilteringTable_v6->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
6081 		softwarerouting_act = true;
6082 		/* end of contruct SW-RT rules to Q6*/
6083 	}
6084 	else
6085 	{
6086 		if(embms_is_on == false)
6087 		{
6088 			if(IPACM_Wan::num_v4_flt_rule > 0)
6089 			{
6090 				len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v4_flt_rule * sizeof(struct ipa_flt_rule_add);
6091 				pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len);
6092 
6093 				IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is %d\n", IPACM_Wan::num_v4_flt_rule);
6094 
6095 				if (pFilteringTable_v4 == NULL)
6096 				{
6097 					IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
6098 					return IPACM_FAILURE;
6099 				}
6100 				memset(pFilteringTable_v4, 0, len);
6101 				pFilteringTable_v4->commit = 1;
6102 				pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe;
6103 				pFilteringTable_v4->global = false;
6104 				pFilteringTable_v4->ip = IPA_IP_v4;
6105 				pFilteringTable_v4->num_rules = (uint8_t)IPACM_Wan::num_v4_flt_rule;
6106 
6107 				memcpy(pFilteringTable_v4->rules, IPACM_Wan::flt_rule_v4, IPACM_Wan::num_v4_flt_rule * sizeof(ipa_flt_rule_add));
6108 			}
6109 
6110 			if(IPACM_Wan::num_v6_flt_rule > 0)
6111 			{
6112 				len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v6_flt_rule * sizeof(struct ipa_flt_rule_add);
6113 				pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len);
6114 
6115 				IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is %d\n", IPACM_Wan::num_v6_flt_rule);
6116 
6117 				if (pFilteringTable_v6 == NULL)
6118 				{
6119 					IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
6120 					free(pFilteringTable_v4);
6121 					return IPACM_FAILURE;
6122 				}
6123 				memset(pFilteringTable_v6, 0, len);
6124 				pFilteringTable_v6->commit = 1;
6125 				pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe;
6126 				pFilteringTable_v6->global = false;
6127 				pFilteringTable_v6->ip = IPA_IP_v6;
6128 				pFilteringTable_v6->num_rules = (uint8_t)IPACM_Wan::num_v6_flt_rule;
6129 
6130 				memcpy(pFilteringTable_v6->rules, IPACM_Wan::flt_rule_v6, IPACM_Wan::num_v6_flt_rule * sizeof(ipa_flt_rule_add));
6131 			}
6132 		}
6133 		else	//embms is on, always add 1 embms rule on top of WAN DL flt table
6134 		{
6135 			/* allocate ipv4 filtering table */
6136 			len = sizeof(struct ipa_ioc_add_flt_rule) + (1 + IPACM_Wan::num_v4_flt_rule) * sizeof(struct ipa_flt_rule_add);
6137 			pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len);
6138 			IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is %d\n", IPACM_Wan::num_v4_flt_rule + 1);
6139 			if (pFilteringTable_v4 == NULL)
6140 			{
6141 				IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
6142 				return IPACM_FAILURE;
6143 			}
6144 			memset(pFilteringTable_v4, 0, len);
6145 			pFilteringTable_v4->commit = 1;
6146 			pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe;
6147 			pFilteringTable_v4->global = false;
6148 			pFilteringTable_v4->ip = IPA_IP_v4;
6149 			pFilteringTable_v4->num_rules = (uint8_t)IPACM_Wan::num_v4_flt_rule + 1;
6150 
6151 			/* allocate ipv6 filtering table */
6152 			len = sizeof(struct ipa_ioc_add_flt_rule) + (1 + IPACM_Wan::num_v6_flt_rule) * sizeof(struct ipa_flt_rule_add);
6153 			pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len);
6154 			IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is %d\n", IPACM_Wan::num_v6_flt_rule + 1);
6155 			if (pFilteringTable_v6 == NULL)
6156 			{
6157 				IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
6158 				free(pFilteringTable_v4);
6159 				return IPACM_FAILURE;
6160 			}
6161 			memset(pFilteringTable_v6, 0, len);
6162 			pFilteringTable_v6->commit = 1;
6163 			pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe;
6164 			pFilteringTable_v6->global = false;
6165 			pFilteringTable_v6->ip = IPA_IP_v6;
6166 			pFilteringTable_v6->num_rules = (uint8_t)IPACM_Wan::num_v6_flt_rule + 1;
6167 
6168 			config_dft_embms_rules(pFilteringTable_v4, pFilteringTable_v6);
6169 			if(IPACM_Wan::num_v4_flt_rule > 0)
6170 			{
6171 				memcpy(&(pFilteringTable_v4->rules[1]), IPACM_Wan::flt_rule_v4, IPACM_Wan::num_v4_flt_rule * sizeof(ipa_flt_rule_add));
6172 			}
6173 
6174 			if(IPACM_Wan::num_v6_flt_rule > 0)
6175 			{
6176 				memcpy(&(pFilteringTable_v6->rules[1]), IPACM_Wan::flt_rule_v6, IPACM_Wan::num_v6_flt_rule * sizeof(ipa_flt_rule_add));
6177 			}
6178 		}
6179 	}
6180 
6181 	if(false == m_filtering.AddWanDLFilteringRule(pFilteringTable_v4, pFilteringTable_v6, mux_id))
6182 	{
6183 		IPACMERR("Failed to install WAN DL filtering table.\n");
6184 		res = IPACM_FAILURE;
6185 		goto fail;
6186 	}
6187 
6188 fail:
6189 	if(pFilteringTable_v4 != NULL)
6190 	{
6191 		free(pFilteringTable_v4);
6192 	}
6193 	if(pFilteringTable_v6 != NULL)
6194 	{
6195 		free(pFilteringTable_v6);
6196 	}
6197 	return res;
6198 }
6199 
6200 /* handle STA WAN-client */
6201 /* handle WAN client initial, construct full headers (tx property) */
handle_wan_hdr_init(uint8_t * mac_addr,bool replaced,int entry)6202 int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr, bool replaced, int entry)
6203 {
6204 
6205 #define WAN_IFACE_INDEX_LEN 2
6206 
6207 	int res = IPACM_SUCCESS, len = 0;
6208 	char index[WAN_IFACE_INDEX_LEN];
6209 	struct ipa_ioc_copy_hdr sCopyHeader;
6210 	struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
6211 	uint32_t cnt;
6212 	int clnt_indx;
6213 
6214 	IPACMDBG_H("WAN client number: %d\n", num_wan_client);
6215 
6216 	if(!replaced)
6217 	{
6218 		clnt_indx = get_wan_client_index(mac_addr);
6219 
6220 		if (clnt_indx != IPACM_INVALID_INDEX)
6221 		{
6222 			IPACMERR("eth client is found/attached already with index %d \n", clnt_indx);
6223 			return IPACM_FAILURE;
6224 		}
6225 
6226 		/* add header to IPA */
6227 		if (num_wan_client >= IPA_MAX_NUM_WAN_CLIENTS)
6228 		{
6229 			IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_WAN_CLIENTS);
6230 			return IPACM_FAILURE;
6231 		}
6232 
6233 		memcpy(get_client_memptr(wan_client, num_wan_client)->mac,
6234 				 mac_addr,
6235 				 sizeof(get_client_memptr(wan_client, num_wan_client)->mac));
6236 
6237 		IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
6238 					 mac_addr[0], mac_addr[1], mac_addr[2],
6239 					 mac_addr[3], mac_addr[4], mac_addr[5]);
6240 
6241 		IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
6242 					 get_client_memptr(wan_client, num_wan_client)->mac[0],
6243 					 get_client_memptr(wan_client, num_wan_client)->mac[1],
6244 					 get_client_memptr(wan_client, num_wan_client)->mac[2],
6245 					 get_client_memptr(wan_client, num_wan_client)->mac[3],
6246 					 get_client_memptr(wan_client, num_wan_client)->mac[4],
6247 					 get_client_memptr(wan_client, num_wan_client)->mac[5]);
6248 	}
6249 
6250 	/* add header to IPA */
6251 	if(tx_prop != NULL)
6252 	{
6253 		len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
6254 		pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
6255 		if (pHeaderDescriptor == NULL)
6256 		{
6257 			IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
6258 			return IPACM_FAILURE;
6259 		}
6260 
6261 		/* copy partial header for v4*/
6262 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
6263 		{
6264 				 if(tx_prop->tx[cnt].ip==IPA_IP_v4)
6265 				 {
6266 								IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt);
6267 								memset(&sCopyHeader, 0, sizeof(sCopyHeader));
6268 								memcpy(sCopyHeader.name,
6269 											 tx_prop->tx[cnt].hdr_name,
6270 											 sizeof(sCopyHeader.name));
6271 
6272 								IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
6273 								if (m_header.CopyHeader(&sCopyHeader) == false)
6274 								{
6275 									PERROR("ioctl copy header failed");
6276 									res = IPACM_FAILURE;
6277 									goto fail;
6278 								}
6279 
6280 								IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
6281 								IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
6282 								if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
6283 								{
6284 									IPACMERR("header oversize\n");
6285 									res = IPACM_FAILURE;
6286 									goto fail;
6287 								}
6288 								else
6289 								{
6290 									memcpy(pHeaderDescriptor->hdr[0].hdr,
6291 												 sCopyHeader.hdr,
6292 												 sCopyHeader.hdr_len);
6293 								}
6294 
6295 								/* copy client mac_addr to partial header */
6296 								IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n",
6297 										sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
6298 
6299 								/* only copy 6 bytes mac-address */
6300 								if(sCopyHeader.is_eth2_ofst_valid == false)
6301 								{
6302 									memcpy(&pHeaderDescriptor->hdr[0].hdr[0],
6303 											mac_addr, IPA_MAC_ADDR_SIZE);
6304 								}
6305 								else
6306 								{
6307 									memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
6308 											mac_addr, IPA_MAC_ADDR_SIZE);
6309 								}
6310 
6311 
6312 								pHeaderDescriptor->commit = true;
6313 								pHeaderDescriptor->num_hdrs = 1;
6314 
6315 								memset(pHeaderDescriptor->hdr[0].name, 0,
6316 											 sizeof(pHeaderDescriptor->hdr[0].name));
6317 
6318 								snprintf(index,sizeof(index), "%d", ipa_if_num);
6319 								strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
6320 								pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
6321 								if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
6322 								{
6323 									IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
6324 									res = IPACM_FAILURE;
6325 									goto fail;
6326 								}
6327 
6328 								snprintf(index,sizeof(index), "%d", header_name_count);
6329 								if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
6330 								{
6331 									IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
6332 									res = IPACM_FAILURE;
6333 									goto fail;
6334 								}
6335 
6336 								pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
6337 								pHeaderDescriptor->hdr[0].hdr_hdl = -1;
6338 								pHeaderDescriptor->hdr[0].is_partial = 0;
6339 								pHeaderDescriptor->hdr[0].status = -1;
6340 
6341 					 if (m_header.AddHeader(pHeaderDescriptor) == false ||
6342 							pHeaderDescriptor->hdr[0].status != 0)
6343 					 {
6344 						IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
6345 						res = IPACM_FAILURE;
6346 						goto fail;
6347 					 }
6348 
6349 					if (!replaced)
6350 					{
6351 						get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
6352 						IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n",
6353 												 num_wan_client,
6354 												 pHeaderDescriptor->hdr[0].name,
6355 												 get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v4);
6356 									get_client_memptr(wan_client, num_wan_client)->ipv4_header_set=true;
6357 					} else
6358 					{
6359 						get_client_memptr(wan_client, entry)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
6360 						IPACMDBG_H("replaced eth-client(%d) v4 full header name:%s header handle:(0x%x)\n",
6361 												 entry,
6362 												 pHeaderDescriptor->hdr[0].name,
6363 												 get_client_memptr(wan_client, entry)->hdr_hdl_v4);
6364 									get_client_memptr(wan_client, entry)->ipv4_header_set=true;
6365 					}
6366 					break;
6367 				 }
6368 		}
6369 
6370 
6371 		/* copy partial header for v6*/
6372 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
6373 		{
6374 			if(tx_prop->tx[cnt].ip==IPA_IP_v6)
6375 			{
6376 
6377 				IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt);
6378 				memset(&sCopyHeader, 0, sizeof(sCopyHeader));
6379 				memcpy(sCopyHeader.name,
6380 						tx_prop->tx[cnt].hdr_name,
6381 							sizeof(sCopyHeader.name));
6382 
6383 				IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
6384 				if (m_header.CopyHeader(&sCopyHeader) == false)
6385 				{
6386 					PERROR("ioctl copy header failed");
6387 					res = IPACM_FAILURE;
6388 					goto fail;
6389 				}
6390 
6391 				IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
6392 				IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
6393 				if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
6394 				{
6395 					IPACMERR("header oversize\n");
6396 					res = IPACM_FAILURE;
6397 					goto fail;
6398 				}
6399 				else
6400 				{
6401 					memcpy(pHeaderDescriptor->hdr[0].hdr,
6402 							sCopyHeader.hdr,
6403 							sCopyHeader.hdr_len);
6404 				}
6405 
6406 				/* copy client mac_addr to partial header */
6407 				if(sCopyHeader.is_eth2_ofst_valid == false)
6408 				{
6409 					memcpy(&pHeaderDescriptor->hdr[0].hdr[0],
6410 								 mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
6411 				}
6412 				else
6413 				{
6414 					memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
6415 								 mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
6416 				}
6417 
6418 
6419 				pHeaderDescriptor->commit = true;
6420 				pHeaderDescriptor->num_hdrs = 1;
6421 
6422 				memset(pHeaderDescriptor->hdr[0].name, 0,
6423 					 sizeof(pHeaderDescriptor->hdr[0].name));
6424 
6425 				snprintf(index,sizeof(index), "%d", ipa_if_num);
6426 				strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
6427 				pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
6428 				if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
6429 				{
6430 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
6431 					res = IPACM_FAILURE;
6432 					goto fail;
6433 				}
6434 				snprintf(index,sizeof(index), "%d", header_name_count);
6435 				if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
6436 				{
6437 					IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
6438 					res = IPACM_FAILURE;
6439 					goto fail;
6440 				}
6441 
6442 				pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
6443 				pHeaderDescriptor->hdr[0].hdr_hdl = -1;
6444 				pHeaderDescriptor->hdr[0].is_partial = 0;
6445 				pHeaderDescriptor->hdr[0].status = -1;
6446 
6447 				if (m_header.AddHeader(pHeaderDescriptor) == false ||
6448 						pHeaderDescriptor->hdr[0].status != 0)
6449 				{
6450 					IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
6451 					res = IPACM_FAILURE;
6452 					goto fail;
6453 				}
6454 
6455 				if (!replaced)
6456 				{
6457 					get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
6458 					IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n",
6459 						 num_wan_client,
6460 						 pHeaderDescriptor->hdr[0].name,
6461 									 get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v6);
6462 									get_client_memptr(wan_client, num_wan_client)->ipv6_header_set=true;
6463 				}
6464 				else
6465 				{
6466 					get_client_memptr(wan_client, entry)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
6467 					IPACMDBG_H("replaced eth-client(%d) v6 full header name:%s header handle:(0x%x)\n",
6468 							entry,
6469 							pHeaderDescriptor->hdr[0].name,
6470 							get_client_memptr(wan_client, entry)->hdr_hdl_v6);
6471 							get_client_memptr(wan_client, entry)->ipv6_header_set=true;
6472 				}
6473 
6474 				break;
6475 
6476 			}
6477 		}
6478 		/* initialize wifi client*/
6479 		if (!replaced)
6480 		{
6481 			get_client_memptr(wan_client, num_wan_client)->route_rule_set_v4 = false;
6482 			get_client_memptr(wan_client, num_wan_client)->route_rule_set_v6 = 0;
6483 			get_client_memptr(wan_client, num_wan_client)->ipv4_set = false;
6484 			get_client_memptr(wan_client, num_wan_client)->ipv6_set = 0;
6485 			num_wan_client++;
6486 		}
6487 		else
6488 		{
6489 			get_client_memptr(wan_client, entry)->route_rule_set_v4 = false;
6490 			get_client_memptr(wan_client, entry)->route_rule_set_v6 = 0;
6491 			get_client_memptr(wan_client, entry)->ipv4_set = false;
6492 			get_client_memptr(wan_client, entry)->ipv6_set = 0;
6493 		}
6494 		header_name_count++; //keep increasing header_name_count
6495 		res = IPACM_SUCCESS;
6496 		IPACMDBG_H("eth client number: %d\n", num_wan_client);
6497 	}
6498 	else
6499 	{
6500 		return res;
6501 	}
6502 fail:
6503 	free(pHeaderDescriptor);
6504 
6505 	return res;
6506 }
6507 
6508 /*handle eth client */
handle_wan_client_ipaddr(ipacm_event_data_all * data)6509 int IPACM_Wan::handle_wan_client_ipaddr(ipacm_event_data_all *data)
6510 {
6511 	int clnt_indx;
6512 	int v6_num;
6513 
6514 	IPACMDBG_H("number of wan clients: %d\n", num_wan_client);
6515 	IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
6516 					 data->mac_addr[0],
6517 					 data->mac_addr[1],
6518 					 data->mac_addr[2],
6519 					 data->mac_addr[3],
6520 					 data->mac_addr[4],
6521 					 data->mac_addr[5]);
6522 
6523 	clnt_indx = get_wan_client_index(data->mac_addr);
6524 
6525 		if (clnt_indx == IPACM_INVALID_INDEX)
6526 		{
6527 			IPACMERR("wan client not found/attached \n");
6528 			return IPACM_FAILURE;
6529 		}
6530 
6531 	IPACMDBG_H("Ip-type received %d\n", data->iptype);
6532 	if (data->iptype == IPA_IP_v4)
6533 	{
6534 		IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr);
6535 		if (data->ipv4_addr != 0) /* not 0.0.0.0 */
6536 		{
6537 			if (get_client_memptr(wan_client, clnt_indx)->ipv4_set == false)
6538 			{
6539 				get_client_memptr(wan_client, clnt_indx)->v4_addr = data->ipv4_addr;
6540 				get_client_memptr(wan_client, clnt_indx)->ipv4_set = true;
6541 				/* Add NAT rules after ipv4 RT rules are set */
6542 				CtList->HandleSTAClientAddEvt(data->ipv4_addr);
6543 			}
6544 			else
6545 			{
6546 			   /* check if client got new IPv4 address*/
6547 			   if(data->ipv4_addr == get_client_memptr(wan_client, clnt_indx)->v4_addr)
6548 			   {
6549 			     IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx);
6550 				 return IPACM_FAILURE;
6551 			   }
6552 			   else
6553 			   {
6554 					IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
6555 					/* Del NAT rules before ipv4 RT rules are delete */
6556 					CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, clnt_indx)->v4_addr);
6557 					delete_wan_rtrules(clnt_indx,IPA_IP_v4);
6558 					get_client_memptr(wan_client, clnt_indx)->route_rule_set_v4 = false;
6559 					get_client_memptr(wan_client, clnt_indx)->v4_addr = data->ipv4_addr;
6560 					/* Add NAT rules after ipv4 RT rules are set */
6561 					CtList->HandleSTAClientAddEvt(data->ipv4_addr);
6562 				}
6563 			}
6564 		}
6565 		else
6566 		{
6567 				IPACMDBG_H("Invalid client IPv4 address \n");
6568 				return IPACM_FAILURE;
6569 		}
6570 	}
6571 	else
6572 	{
6573 		if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
6574 				(data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) /* check if all 0 not valid ipv6 address */
6575 		{
6576 		   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]);
6577                    if(get_client_memptr(wan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
6578 		   {
6579 
6580 		       for(v6_num=0;v6_num < get_client_memptr(wan_client, clnt_indx)->ipv6_set;v6_num++)
6581 	               {
6582 			      if( data->ipv6_addr[0] == get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][0] &&
6583 			           data->ipv6_addr[1] == get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][1] &&
6584 			  	        data->ipv6_addr[2]== get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][2] &&
6585 			  	         data->ipv6_addr[3] == get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][3])
6586 			      {
6587 			  	    IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx);
6588 			  	    return IPACM_FAILURE; /* not setup the RT rules*/
6589 			      }
6590 		       }
6591 
6592 		       /* not see this ipv6 before for wifi client*/
6593 			   get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0];
6594 			   get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1];
6595 			   get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2];
6596 			   get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3];
6597 			   get_client_memptr(wan_client, clnt_indx)->ipv6_set++;
6598 		    }
6599 		    else
6600 		    {
6601 		         IPACMDBG_H("Already got 3 ipv6 addr for client:%d\n", clnt_indx);
6602 			 return IPACM_FAILURE; /* not setup the RT rules*/
6603 		    }
6604 		}
6605 		else
6606 		{
6607 			IPACMDBG_H("Invalid IPV6 address\n");
6608 			return IPACM_FAILURE;
6609 		}
6610 	}
6611 
6612 	return IPACM_SUCCESS;
6613 }
6614 
6615 /*handle wan client routing rule*/
handle_wan_client_route_rule(uint8_t * mac_addr,ipa_ip_type iptype)6616 int IPACM_Wan::handle_wan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype)
6617 {
6618 	struct ipa_ioc_add_rt_rule *rt_rule;
6619 	struct ipa_rt_rule_add *rt_rule_entry;
6620 	uint32_t tx_index;
6621 	int wan_index,v6_num;
6622 	const int NUM = 1;
6623 
6624 	if(tx_prop == NULL)
6625 	{
6626 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
6627 		return IPACM_SUCCESS;
6628 	}
6629 
6630 	IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
6631 			mac_addr[0], mac_addr[1], mac_addr[2],
6632 			mac_addr[3], mac_addr[4], mac_addr[5]);
6633 
6634 	wan_index = get_wan_client_index(mac_addr);
6635 	if (wan_index == IPACM_INVALID_INDEX)
6636 	{
6637 		IPACMDBG_H("wan client not found/attached \n");
6638 		return IPACM_SUCCESS;
6639 	}
6640 
6641 	if (iptype==IPA_IP_v4) {
6642 		IPACMDBG_H("wan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", wan_index, iptype,
6643 				get_client_memptr(wan_client, wan_index)->ipv4_set,
6644 				get_client_memptr(wan_client, wan_index)->route_rule_set_v4);
6645 	} else {
6646 		IPACMDBG_H("wan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wan_index, iptype,
6647 				get_client_memptr(wan_client, wan_index)->ipv6_set,
6648 				get_client_memptr(wan_client, wan_index)->route_rule_set_v6);
6649 	}
6650 
6651 	/* Add default routing rules if not set yet */
6652 	if ((iptype == IPA_IP_v4
6653 				&& get_client_memptr(wan_client, wan_index)->route_rule_set_v4 == false
6654 				&& get_client_memptr(wan_client, wan_index)->ipv4_set == true)
6655 			|| (iptype == IPA_IP_v6
6656 				&& get_client_memptr(wan_client, wan_index)->route_rule_set_v6 < get_client_memptr(wan_client, wan_index)->ipv6_set
6657 			   ))
6658 	{
6659 		if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
6660 		{
6661 			/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
6662 			IPACMDBG_H("dev %s add producer dependency\n", dev_name);
6663 			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]);
6664 			IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
6665 		}
6666 		rt_rule = (struct ipa_ioc_add_rt_rule *)
6667 			calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
6668 					NUM * sizeof(struct ipa_rt_rule_add));
6669 
6670 		if (rt_rule == NULL)
6671 		{
6672 			PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n");
6673 			return IPACM_FAILURE;
6674 		}
6675 
6676 		rt_rule->commit = 1;
6677 		rt_rule->num_rules = (uint8_t)NUM;
6678 		rt_rule->ip = iptype;
6679 
6680 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
6681 		{
6682 			if(iptype != tx_prop->tx[tx_index].ip)
6683 			{
6684 				IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n",
6685 						tx_index, tx_prop->tx[tx_index].ip,iptype);
6686 				continue;
6687 			}
6688 
6689 			rt_rule_entry = &rt_rule->rules[0];
6690 			rt_rule_entry->at_rear = 0;
6691 
6692 			if (iptype == IPA_IP_v4)
6693 			{
6694 				IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wan_index,
6695 						get_client_memptr(wan_client, wan_index)->v4_addr);
6696 
6697 				IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
6698 						wan_index,
6699 						get_client_memptr(wan_client, wan_index)->hdr_hdl_v4);
6700 				strlcpy(rt_rule->rt_tbl_name,
6701 						IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name,
6702 						sizeof(rt_rule->rt_tbl_name));
6703 				rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
6704 				if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
6705 				{
6706 					IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
6707 							tx_prop->tx[tx_index].alt_dst_pipe);
6708 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
6709 				}
6710 				else
6711 				{
6712 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
6713 				}
6714 				memcpy(&rt_rule_entry->rule.attrib,
6715 						&tx_prop->tx[tx_index].attrib,
6716 						sizeof(rt_rule_entry->rule.attrib));
6717 				rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
6718 				rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, wan_index)->hdr_hdl_v4;
6719 				rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wan_client, wan_index)->v4_addr;
6720 				rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
6721 				if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
6722 					rt_rule_entry->rule.hashable = true;
6723 				if (false == m_routing.AddRoutingRule(rt_rule))
6724 				{
6725 					IPACMERR("Routing rule addition failed!\n");
6726 					free(rt_rule);
6727 					return IPACM_FAILURE;
6728 				}
6729 
6730 				/* copy ipv4 RT hdl */
6731 				get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4 =
6732 					rt_rule->rules[0].rt_rule_hdl;
6733 				IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
6734 						get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4, iptype);
6735 			} else {
6736 
6737 				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++)
6738 				{
6739 					IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
6740 							wan_index,
6741 							get_client_memptr(wan_client, wan_index)->hdr_hdl_v6);
6742 
6743 					/* v6 LAN_RT_TBL */
6744 					strlcpy(rt_rule->rt_tbl_name,
6745 							IPACM_Iface::ipacmcfg->rt_tbl_v6.name,
6746 							sizeof(rt_rule->rt_tbl_name));
6747 					rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
6748 					/* Uplink going to wan clients should go to IPA */
6749 					if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
6750 					{
6751 						IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
6752 								tx_prop->tx[tx_index].alt_dst_pipe);
6753 						rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
6754 					}
6755 					else
6756 					{
6757 						rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
6758 					}
6759 					memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib));
6760 					rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, wan_index)->hdr_hdl_v6;;
6761 					rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
6762 					rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][0];
6763 					rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][1];
6764 					rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][2];
6765 					rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][3];
6766 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
6767 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
6768 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
6769 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
6770 					if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
6771 						rt_rule_entry->rule.hashable = true;
6772 					if (false == m_routing.AddRoutingRule(rt_rule))
6773 					{
6774 						IPACMERR("Routing rule addition failed!\n");
6775 						free(rt_rule);
6776 						return IPACM_FAILURE;
6777 					}
6778 
6779 					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;
6780 					IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
6781 							get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6[v6_num], iptype);
6782 
6783 					/*Copy same rule to v6 WAN RT TBL*/
6784 					strlcpy(rt_rule->rt_tbl_name,
6785 							IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name,
6786 							sizeof(rt_rule->rt_tbl_name));
6787 					rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
6788 					/* Downlink traffic from Wan clients, should go exception */
6789 					rt_rule_entry->rule.dst = iface_query->excp_pipe;
6790 					memcpy(&rt_rule_entry->rule.attrib,
6791 							&tx_prop->tx[tx_index].attrib,
6792 							sizeof(rt_rule_entry->rule.attrib));
6793 					rt_rule_entry->rule.hdr_hdl = 0;
6794 					rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
6795 					rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][0];
6796 					rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][1];
6797 					rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][2];
6798 					rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][3];
6799 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
6800 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
6801 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
6802 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
6803 					if (false == m_routing.AddRoutingRule(rt_rule))
6804 					{
6805 						IPACMERR("Routing rule addition failed!\n");
6806 						free(rt_rule);
6807 						return IPACM_FAILURE;
6808 					}
6809 
6810 					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;
6811 					IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
6812 							get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[v6_num], iptype);
6813 				}
6814 			}
6815 
6816 		} /* end of for loop */
6817 
6818 		free(rt_rule);
6819 
6820 		if (iptype == IPA_IP_v4)
6821 		{
6822 			get_client_memptr(wan_client, wan_index)->route_rule_set_v4 = true;
6823 		}
6824 		else
6825 		{
6826 			get_client_memptr(wan_client, wan_index)->route_rule_set_v6 = get_client_memptr(wan_client, wan_index)->ipv6_set;
6827 		}
6828 	}
6829 
6830 	return IPACM_SUCCESS;
6831 }
6832 
6833 /* TODO Handle wan client routing rules also */
handle_wlan_SCC_MCC_switch(bool isSCCMode,ipa_ip_type iptype)6834 void IPACM_Wan::handle_wlan_SCC_MCC_switch(bool isSCCMode, ipa_ip_type iptype)
6835 {
6836 	struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL;
6837 	struct ipa_rt_rule_mdfy *rt_rule_entry;
6838 	uint32_t tx_index = 0;
6839 
6840 	IPACMDBG("\n");
6841 	if (tx_prop == NULL || is_default_gateway == false)
6842 	{
6843 		IPACMDBG_H("No tx properties or no default route set yet\n");
6844 		return;
6845 	}
6846 
6847 	const int NUM = tx_prop->num_tx_props;
6848 
6849 	for (tx_index = 0; tx_index < tx_prop->num_tx_props; tx_index++)
6850 	{
6851 		if (tx_prop->tx[tx_index].ip != iptype)
6852 		{
6853 			IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d Ignore\n",
6854 					tx_index, tx_prop->tx[tx_index].ip, iptype);
6855 			continue;
6856 		}
6857 
6858 		if (rt_rule == NULL)
6859 		{
6860 			rt_rule = (struct ipa_ioc_mdfy_rt_rule *)
6861 				calloc(1, sizeof(struct ipa_ioc_mdfy_rt_rule) +
6862 						NUM * sizeof(struct ipa_rt_rule_mdfy));
6863 
6864 			if (rt_rule == NULL)
6865 			{
6866 				IPACMERR("Unable to allocate memory for modify rt rule\n");
6867 				return;
6868 			}
6869 			IPACMDBG("Allocated memory for %d rules successfully\n", NUM);
6870 
6871 			rt_rule->commit = 1;
6872 			rt_rule->num_rules = 0;
6873 			rt_rule->ip = iptype;
6874 		}
6875 
6876 		rt_rule_entry = &rt_rule->rules[rt_rule->num_rules];
6877 
6878 		memcpy(&rt_rule_entry->rule.attrib,
6879 				&tx_prop->tx[tx_index].attrib,
6880 				sizeof(rt_rule_entry->rule.attrib));
6881 		rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
6882 
6883 		if (iptype == IPA_IP_v4)
6884 		{
6885 			rt_rule_entry->rule.attrib.u.v4.dst_addr      = 0;
6886 			rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0;
6887 			rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v4;
6888 			rt_rule_entry->rt_rule_hdl = wan_route_rule_v4_hdl[tx_index];
6889 		}
6890 		else
6891 		{
6892 			rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0;
6893 			rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0;
6894 			rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0;
6895 			rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0;
6896 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0;
6897 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0;
6898 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0;
6899 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0;
6900 
6901 			rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v6;
6902 			rt_rule_entry->rt_rule_hdl = wan_route_rule_v6_hdl[tx_index];
6903 		}
6904 		IPACMDBG_H("Header handle: 0x%x\n", rt_rule_entry->rule.hdr_hdl);
6905 
6906 		if (isSCCMode)
6907 		{
6908 			rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
6909 		}
6910 		else
6911 		{
6912 			IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
6913 					tx_prop->tx[tx_index].alt_dst_pipe);
6914 			rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
6915 		}
6916 
6917 		rt_rule->num_rules++;
6918 	}
6919 
6920 	if (rt_rule != NULL)
6921 	{
6922 
6923 		if (rt_rule->num_rules > 0)
6924 		{
6925 			if (false == m_routing.ModifyRoutingRule(rt_rule))
6926 			{
6927 				IPACMERR("Routing rule modify failed!\n");
6928 				free(rt_rule);
6929 				return;
6930 			}
6931 
6932 			IPACMDBG("Routing rule modified successfully \n");
6933 		}
6934 
6935 		free(rt_rule);
6936 	}
6937 
6938 	return;
6939 }
6940 
handle_wan_client_SCC_MCC_switch(bool isSCCMode,ipa_ip_type iptype)6941 void IPACM_Wan::handle_wan_client_SCC_MCC_switch(bool isSCCMode, ipa_ip_type iptype)
6942 {
6943 	struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL;
6944 	struct ipa_rt_rule_mdfy *rt_rule_entry;
6945 
6946 	uint32_t tx_index = 0, clnt_index =0;
6947 	int v6_num = 0;
6948 	const int NUM_RULES = 1;
6949 
6950 	int size = sizeof(struct ipa_ioc_mdfy_rt_rule) +
6951 		NUM_RULES * sizeof(struct ipa_rt_rule_mdfy);
6952 
6953 	IPACMDBG("isSCCMode: %d\n",isSCCMode);
6954 
6955 	if (tx_prop == NULL || is_default_gateway == false)
6956 	{
6957 		IPACMDBG_H("No tx properties or no default route set yet\n");
6958 		return;
6959 	}
6960 
6961 	rt_rule = (struct ipa_ioc_mdfy_rt_rule *)calloc(1, size);
6962 	if (rt_rule == NULL)
6963 	{
6964 		IPACMERR("Unable to allocate memory for modify rt rule\n");
6965 		return;
6966 	}
6967 
6968 
6969 	for (clnt_index = 0; clnt_index < num_wan_client; clnt_index++)
6970 	{
6971 		if (iptype == IPA_IP_v4)
6972 		{
6973 			IPACMDBG_H("wan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n",
6974 					clnt_index, iptype,
6975 					get_client_memptr(wan_client, clnt_index)->ipv4_set,
6976 					get_client_memptr(wan_client, clnt_index)->route_rule_set_v4);
6977 
6978 			if( get_client_memptr(wan_client, clnt_index)->route_rule_set_v4 == false ||
6979 					get_client_memptr(wan_client, clnt_index)->ipv4_set == false)
6980 			{
6981 				continue;
6982 			}
6983 
6984 			for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
6985 			{
6986 				if (iptype != tx_prop->tx[tx_index].ip)
6987 				{
6988 					IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d skip\n",
6989 							tx_index, tx_prop->tx[tx_index].ip, iptype);
6990 					continue;
6991 				}
6992 
6993 				memset(rt_rule, 0, size);
6994 				rt_rule->commit = 1;
6995 				rt_rule->num_rules = NUM_RULES;
6996 				rt_rule->ip = iptype;
6997 				rt_rule_entry = &rt_rule->rules[0];
6998 
6999 				IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", clnt_index,
7000 						get_client_memptr(wan_client, clnt_index)->v4_addr);
7001 
7002 				IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
7003 						clnt_index,
7004 						get_client_memptr(wan_client, clnt_index)->hdr_hdl_v4);
7005 
7006 				if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
7007 				{
7008 					IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
7009 							tx_prop->tx[tx_index].alt_dst_pipe);
7010 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
7011 				}
7012 				else
7013 				{
7014 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
7015 				}
7016 
7017 				memcpy(&rt_rule_entry->rule.attrib,
7018 						&tx_prop->tx[tx_index].attrib,
7019 						sizeof(rt_rule_entry->rule.attrib));
7020 				rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
7021 
7022 				rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, clnt_index)->hdr_hdl_v4;
7023 				rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wan_client, clnt_index)->v4_addr;
7024 				rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
7025 
7026 				/* copy ipv4 RT rule hdl */
7027 				IPACMDBG_H("rt rule hdl=%x\n",
7028 						get_client_memptr(wan_client, clnt_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4);
7029 
7030 				rt_rule_entry->rt_rule_hdl =
7031 					get_client_memptr(wan_client, clnt_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4;
7032 
7033 				if (false == m_routing.ModifyRoutingRule(rt_rule))
7034 				{
7035 					IPACMERR("Routing rule modify failed!\n");
7036 					free(rt_rule);
7037 					return;
7038 				}
7039 			}
7040 		}
7041 		else
7042 		{
7043 			IPACMDBG_H("wan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", clnt_index, iptype,
7044 					get_client_memptr(wan_client, clnt_index)->ipv6_set,
7045 					get_client_memptr(wan_client, clnt_index)->route_rule_set_v6);
7046 
7047 			if( get_client_memptr(wan_client, clnt_index)->route_rule_set_v6 == 0)
7048 			{
7049 				continue;
7050 			}
7051 
7052 			for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
7053 			{
7054 				if (iptype != tx_prop->tx[tx_index].ip)
7055 				{
7056 					IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d skip\n",
7057 							tx_index, tx_prop->tx[tx_index].ip, iptype);
7058 					continue;
7059 				}
7060 
7061 				memset(rt_rule, 0, size);
7062 				rt_rule->commit = 1;
7063 				rt_rule->num_rules = NUM_RULES;
7064 				rt_rule->ip = iptype;
7065 				rt_rule_entry = &rt_rule->rules[0];
7066 
7067 				/* Modify only rules in v6 WAN RT TBL*/
7068 				for (v6_num = 0;
7069 						v6_num < get_client_memptr(wan_client, clnt_index)->route_rule_set_v6;
7070 						v6_num++)
7071 				{
7072 					IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
7073 							clnt_index,
7074 							get_client_memptr(wan_client, clnt_index)->hdr_hdl_v6);
7075 
7076 					/* Downlink traffic from Wan iface, directly through IPA */
7077 					if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
7078 					{
7079 						IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
7080 								tx_prop->tx[tx_index].alt_dst_pipe);
7081 						rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
7082 					}
7083 					else
7084 					{
7085 						rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
7086 					}
7087 
7088 					memcpy(&rt_rule_entry->rule.attrib,
7089 							&tx_prop->tx[tx_index].attrib,
7090 							sizeof(rt_rule_entry->rule.attrib));
7091 
7092 					rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, clnt_index)->hdr_hdl_v6;
7093 					rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
7094 					rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wan_client, clnt_index)->v6_addr[v6_num][0];
7095 					rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wan_client, clnt_index)->v6_addr[v6_num][1];
7096 					rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wan_client, clnt_index)->v6_addr[v6_num][2];
7097 					rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wan_client, clnt_index)->v6_addr[v6_num][3];
7098 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
7099 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
7100 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
7101 					rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
7102 
7103 					IPACMDBG_H("rt rule hdl=%x\n",
7104 							get_client_memptr(wan_client, clnt_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[v6_num]);
7105 
7106 					rt_rule_entry->rt_rule_hdl =
7107 						get_client_memptr(wan_client, clnt_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[v6_num];
7108 
7109 					if (false == m_routing.ModifyRoutingRule(rt_rule))
7110 					{
7111 						IPACMERR("Routing rule Modify failed!\n");
7112 						free(rt_rule);
7113 						return;
7114 					}
7115 				}
7116 			} /* end of for loop */
7117 		}
7118 
7119 	}
7120 
7121 	free(rt_rule);
7122 	return;
7123 }
7124 
7125 /*handle eth client */
handle_network_stats_update(ipa_get_apn_data_stats_resp_msg_v01 * data)7126 int IPACM_Wan::handle_network_stats_update(ipa_get_apn_data_stats_resp_msg_v01 *data)
7127 {
7128 	FILE *fp = NULL;
7129 
7130 	for (uint32_t apn_index =0; apn_index < data->apn_data_stats_list_len; apn_index++)
7131 	{
7132 		if(data->apn_data_stats_list[apn_index].mux_id == ext_prop->ext[0].mux_id)
7133 		{
7134 			IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_NETWORK_STATS, MUX ID %d TX (P%llu/B%llu) RX (P%llu/B%llu)\n",
7135 				data->apn_data_stats_list[apn_index].mux_id,
7136 					(long long)data->apn_data_stats_list[apn_index].num_ul_packets,
7137 						(long long)data->apn_data_stats_list[apn_index].num_ul_bytes,
7138 							(long long)data->apn_data_stats_list[apn_index].num_dl_packets,
7139 								(long long)data->apn_data_stats_list[apn_index].num_dl_bytes);
7140 			fp = fopen(IPA_NETWORK_STATS_FILE_NAME, "w");
7141 			if ( fp == NULL )
7142 			{
7143 				IPACMERR("Failed to write pipe stats to %s, error is %d - %s\n",
7144 						IPA_NETWORK_STATS_FILE_NAME, errno, strerror(errno));
7145 				return IPACM_FAILURE;
7146 			}
7147 
7148 			fprintf(fp, NETWORK_STATS,
7149 				dev_name,
7150 					(long long)data->apn_data_stats_list[apn_index].num_ul_packets,
7151 						(long long)data->apn_data_stats_list[apn_index].num_ul_bytes,
7152 							(long long)data->apn_data_stats_list[apn_index].num_dl_packets,
7153 								(long long)data->apn_data_stats_list[apn_index].num_dl_bytes);
7154 			fclose(fp);
7155 			break;
7156 		};
7157 	}
7158 	return IPACM_SUCCESS;
7159 }
7160 
add_dummy_rx_hdr()7161 int IPACM_Wan::add_dummy_rx_hdr()
7162 {
7163 
7164 #define IFACE_INDEX_LEN 2
7165 	char index[IFACE_INDEX_LEN];
7166 	struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
7167 	int len = 0;
7168 	struct ipa_ioc_copy_hdr sCopyHeader;
7169 	struct ipa_hdr_add *ipv6_hdr;
7170 	struct ethhdr *eth_ipv6;
7171 	struct ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL;
7172 	uint32_t cnt;
7173 
7174 	/* get netdev-mac */
7175 	if(tx_prop != NULL)
7176 	{
7177 		/* copy partial header for v6 */
7178 		for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
7179 		{
7180 				 if(tx_prop->tx[cnt].ip==IPA_IP_v6)
7181 				 {
7182 								IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt);
7183 								memset(&sCopyHeader, 0, sizeof(sCopyHeader));
7184 								memcpy(sCopyHeader.name,
7185 											 tx_prop->tx[cnt].hdr_name,
7186 											 sizeof(sCopyHeader.name));
7187 
7188 								IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
7189 								if (m_header.CopyHeader(&sCopyHeader) == false)
7190 								{
7191 									PERROR("ioctl copy header failed");
7192 									return IPACM_FAILURE;
7193 								}
7194 
7195 								IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
7196 								IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
7197 								if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
7198 								{
7199 									IPACMERR("header oversize\n");
7200 									return IPACM_FAILURE;
7201 								}
7202 								else
7203 								{
7204 									/* copy client mac_addr to partial header */
7205 									IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n",
7206 											sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
7207 									/* only copy 6 bytes mac-address */
7208 									if(sCopyHeader.is_eth2_ofst_valid == false)
7209 									{
7210 										memcpy(netdev_mac, &sCopyHeader.hdr[0+IPA_MAC_ADDR_SIZE],
7211 												sizeof(netdev_mac));
7212 									}
7213 									else
7214 									{
7215 										memcpy(netdev_mac, &sCopyHeader.hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
7216 												sizeof(netdev_mac));
7217 									}
7218 								}
7219 					break;
7220 				}
7221 		}
7222 	}
7223 
7224 	len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
7225 	pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
7226 	if (pHeaderDescriptor == NULL)
7227 	{
7228 		IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
7229 		return IPACM_FAILURE;
7230 	}
7231 	ipv6_hdr = &pHeaderDescriptor->hdr[0];
7232 	/* copy ethernet type to header */
7233 	eth_ipv6 = (struct ethhdr *) (ipv6_hdr->hdr +2);
7234 	memcpy(eth_ipv6->h_dest, netdev_mac, ETH_ALEN);
7235 	memcpy(eth_ipv6->h_source, ext_router_mac_addr, ETH_ALEN);
7236 	eth_ipv6->h_proto = htons(ETH_P_IPV6);
7237 	pHeaderDescriptor->commit = true;
7238 	pHeaderDescriptor->num_hdrs = 1;
7239 
7240 	memset(ipv6_hdr->name, 0,
7241 			 sizeof(pHeaderDescriptor->hdr[0].name));
7242 
7243 	snprintf(index,sizeof(index), "%d", ipa_if_num);
7244 	strlcpy(ipv6_hdr->name, index, sizeof(ipv6_hdr->name));
7245 	ipv6_hdr->name[IPA_RESOURCE_NAME_MAX-1] = '\0';
7246 
7247 	if (strlcat(ipv6_hdr->name, IPA_DUMMY_ETH_HDR_NAME_v6, sizeof(ipv6_hdr->name)) > IPA_RESOURCE_NAME_MAX)
7248 	{
7249 		IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(ipv6_hdr->name));
7250 		return IPACM_FAILURE;
7251 	}
7252 
7253 	ipv6_hdr->hdr_len = ETH_HLEN + 2;
7254 	ipv6_hdr->hdr_hdl = -1;
7255 	ipv6_hdr->is_partial = 0;
7256 	ipv6_hdr->status = -1;
7257 	ipv6_hdr->type = IPA_HDR_L2_ETHERNET_II;
7258 
7259 	if (m_header.AddHeader(pHeaderDescriptor) == false ||
7260 			ipv6_hdr->status != 0)
7261 	{
7262 		IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", ipv6_hdr->status);
7263 		return IPACM_FAILURE;
7264 	}
7265 
7266 	hdr_hdl_dummy_v6 = ipv6_hdr->hdr_hdl;
7267 	IPACMDBG_H("dummy v6 full header name:%s header handle:(0x%x)\n",
7268 								 ipv6_hdr->name,
7269 								 hdr_hdl_dummy_v6);
7270 	/* add dummy hdr_proc_hdl */
7271 	len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add);
7272 	pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len);
7273 	if(pHeaderProcTable == NULL)
7274 	{
7275 		IPACMERR("Cannot allocate header processing table.\n");
7276 		return IPACM_FAILURE;
7277 	}
7278 
7279 	memset(pHeaderProcTable, 0, len);
7280 	pHeaderProcTable->commit = 1;
7281 	pHeaderProcTable->num_proc_ctxs = 1;
7282 	pHeaderProcTable->proc_ctx[0].hdr_hdl = hdr_hdl_dummy_v6;
7283 	if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false)
7284 	{
7285 		IPACMERR("Adding dummy hhdr_proc_hdl failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status);
7286 		return IPACM_FAILURE;
7287 	}
7288 	else
7289 	{
7290 		hdr_proc_hdl_dummy_v6 = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl;
7291 		IPACMDBG_H("dummy hhdr_proc_hdl is added successfully. (0x%x)\n", hdr_proc_hdl_dummy_v6);
7292 	}
7293 	return IPACM_SUCCESS;
7294 }
7295 
handle_coalesce_evt()7296 int IPACM_Wan::handle_coalesce_evt()
7297 {
7298 	struct ipa_ioc_add_rt_rule *rt_rule = NULL;
7299 	struct ipa_rt_rule_add *rt_rule_entry;
7300 	const int NUM_RULES = 1;
7301 	int res = IPACM_SUCCESS;
7302 	struct ipa_ioc_get_hdr hdr;
7303 	uint32_t i;
7304 
7305 	if(wan_v4_addr_set)
7306 	{
7307 		/* Delete default RSC v4 RT rule */
7308 		if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
7309 		{
7310 			IPACMERR("Routing old RSC TCP RT rule deletion failed!\n");
7311 			return  IPACM_FAILURE;
7312 		}
7313 		if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
7314 		{
7315 			IPACMERR("Routing old RSB UDP RT rule deletion failed!\n");
7316 			return  IPACM_FAILURE;
7317 		}
7318 		/* Delete default v4 RT rule */
7319 		IPACMDBG_H("Delete default v4 routing rules\n");
7320 		if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
7321 		{
7322 			IPACMERR("Routing old RT rule deletion failed!\n");
7323 			return  IPACM_FAILURE;
7324 		}
7325 
7326 		/* apply the new coalesce configuration */
7327 		rt_rule = (struct ipa_ioc_add_rt_rule *)
7328 			 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
7329 							NUM_RULES * sizeof(struct ipa_rt_rule_add));
7330 		if (!rt_rule)
7331 		{
7332 			IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
7333 			return IPACM_FAILURE;
7334 		}
7335 		rt_rule->commit = 1;
7336 		rt_rule->num_rules = NUM_RULES;
7337 		rt_rule->ip = IPA_IP_v4;
7338 		rt_rule_entry = &rt_rule->rules[0];
7339 		rt_rule_entry->at_rear = false;
7340 		rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
7341 		/* still need setup v4 default routing rule to APPs*/
7342 		strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
7343 		rt_rule_entry->rule.attrib.u.v4.dst_addr = wan_v4_addr;
7344 		rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
7345 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
7346 			rt_rule_entry->rule.hashable = false;
7347 		/* query qmap header*/
7348 		memset(&hdr, 0, sizeof(hdr));
7349 		strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
7350 		hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
7351 		if(m_header.GetHeaderHandle(&hdr) == false)
7352 		{
7353 			IPACMERR("Failed to get QMAP header.\n");
7354 			res = IPACM_FAILURE;
7355 			goto fail;
7356 		}
7357 		rt_rule_entry->rule.hdr_hdl = hdr.hdl;
7358 		rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
7359 		/*  default v4 rt-rule */
7360 #ifdef IPA_RT_SUPPORT_COAL
7361 			rt_rule_entry->rule.coalesce = false;
7362 #endif
7363 		/* default v4 rt-rule */
7364 		if (false == m_routing.AddRoutingRule(rt_rule))
7365 		{
7366 			IPACMERR("Routing rule addition failed!\n");
7367 			res = IPACM_FAILURE;
7368 			goto fail;
7369 		}
7370 		else if (rt_rule_entry->status)
7371 		{
7372 			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
7373 			res = rt_rule_entry->status;
7374 			goto fail;
7375 		}
7376 		dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
7377 		IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
7378 
7379 		/* RSC TCP rule*/
7380 		rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
7381 		rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
7382 #ifdef IPA_RT_SUPPORT_COAL
7383 		if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
7384 			rt_rule_entry->rule.coalesce = true;
7385 		else
7386 			rt_rule_entry->rule.coalesce = false;
7387 #endif
7388 		if (false == m_routing.AddRoutingRule(rt_rule))
7389 		{
7390 			IPACMERR("Routing rule addition failed!\n");
7391 			res = IPACM_FAILURE;
7392 			goto fail;
7393 		}
7394 		else if (rt_rule_entry->status)
7395 		{
7396 			IPACMERR("rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
7397 			res = rt_rule_entry->status;
7398 			goto fail;
7399 		}
7400 		dft_coalesce_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
7401 		IPACMDBG_H("ipv4 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[0],
7402 			IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
7403 
7404 		/* RSB UDP rule*/
7405 		rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
7406 #ifdef IPA_RT_SUPPORT_COAL
7407 		if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
7408 			rt_rule_entry->rule.coalesce = true;
7409 		else
7410 			rt_rule_entry->rule.coalesce = false;
7411 #endif
7412 		if (false == m_routing.AddRoutingRule(rt_rule))
7413 		{
7414 			IPACMERR("Routing rule addition failed!\n");
7415 			res = IPACM_FAILURE;
7416 			goto fail;
7417 		}
7418 		else if (rt_rule_entry->status)
7419 		{
7420 			IPACMERR("rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
7421 			res = rt_rule_entry->status;
7422 			goto fail;
7423 		}
7424 		dft_coalesce_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
7425 		IPACMDBG_H("ipv4 wan iface rsb udp rt-rule hdll=0x%x enable(%d)\n", dft_coalesce_rt_rule_hdl[1],
7426 			IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
7427 fail:
7428 	free(rt_rule);
7429 	}
7430 	/* v6 */
7431 	if (num_dft_rt_v6 !=0)
7432 	{
7433 		for (i = 0; i < 2*num_dft_rt_v6; i++)
7434 		{
7435 			/* delete v6 colasce rules */
7436 			if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
7437 			{
7438 				IPACMERR("Colasce Routing rule deletion failed!\n");
7439 				return  IPACM_FAILURE;
7440 			}
7441 			/* delete v6 default rules */
7442 			if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
7443 			{
7444 				IPACMERR("Routing rule deletion failed!\n");
7445 				return  IPACM_FAILURE;
7446 			}
7447 		}
7448 
7449 		rt_rule = (struct ipa_ioc_add_rt_rule *)
7450 			calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
7451 				NUM_RULES * sizeof(struct ipa_rt_rule_add));
7452 		if (!rt_rule)
7453 		{
7454 			IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
7455 			return IPACM_FAILURE;
7456 		}
7457 		rt_rule->commit = 1;
7458 		rt_rule->num_rules = NUM_RULES;
7459 		rt_rule->ip = IPA_IP_v6;
7460 
7461 		for (i = 0; i < num_dft_rt_v6; i++)
7462 		{
7463 			/* setup same rule for v6_wan table */
7464 			strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
7465 			rt_rule_entry = &rt_rule->rules[0];
7466 			rt_rule_entry->at_rear = false;
7467 			rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
7468 			rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = ipv6_addr[i][0];
7469 			rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = ipv6_addr[i][1];
7470 			rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = ipv6_addr[i][2];
7471 			rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = ipv6_addr[i][3];
7472 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
7473 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
7474 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
7475 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
7476 			if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
7477 				rt_rule_entry->rule.hashable = false;
7478 			strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
7479 			hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
7480 			if(m_header.GetHeaderHandle(&hdr) == false)
7481 			{
7482 				IPACMERR("Failed to get QMAP header.\n");
7483 				return IPACM_FAILURE;
7484 			}
7485 			rt_rule_entry->rule.hdr_hdl = hdr.hdl;
7486 			rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
7487 			/* legacy default v4 rt-rule */
7488 #ifdef IPA_RT_SUPPORT_COAL
7489 			rt_rule_entry->rule.coalesce = false;
7490 #endif
7491 			/* legacy default v6 rt-rule */
7492 			if (false == m_routing.AddRoutingRule(rt_rule))
7493 			{
7494 				IPACMERR("Routing rule addition failed!\n");
7495 				res = IPACM_FAILURE;
7496 				goto fail2;
7497 			}
7498 			else if (rt_rule_entry->status)
7499 			{
7500 				IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
7501 				res = rt_rule_entry->status;
7502 				goto fail2;
7503 			}
7504 			dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i] = rt_rule_entry->rt_rule_hdl;
7505 
7506 			/* setup same rule for v6_lan table*/
7507 			strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
7508 			if (false == m_routing.AddRoutingRule(rt_rule))
7509 			{
7510 				IPACMERR("Routing rule addition failed!\n");
7511 				res = IPACM_FAILURE;
7512 				goto fail2;
7513 			}
7514 			else if (rt_rule_entry->status)
7515 			{
7516 				IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
7517 				res = rt_rule_entry->status;
7518 				goto fail2;
7519 			}
7520 			dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1] = rt_rule_entry->rt_rule_hdl;
7521 			IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, entry: %d %d\n",
7522 				dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i],
7523 				dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1],
7524 				MAX_DEFAULT_v4_ROUTE_RULES + 2*i,
7525 				MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1);
7526 			/* RSC TCP rule*/
7527 			rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
7528 			rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
7529 #ifdef IPA_RT_SUPPORT_COAL
7530 			if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
7531 				rt_rule_entry->rule.coalesce = true;
7532 			else
7533 				rt_rule_entry->rule.coalesce = false;
7534 #endif
7535 			if (false == m_routing.AddRoutingRule(rt_rule))
7536 			{
7537 				IPACMERR("Routing rule addition failed!\n");
7538 				res = IPACM_FAILURE;
7539 				goto fail2;
7540 			}
7541 			else if (rt_rule_entry->status)
7542 			{
7543 				IPACMERR("rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
7544 				res = rt_rule_entry->status;
7545 				goto fail2;
7546 			}
7547 			dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i] = rt_rule_entry->rt_rule_hdl;
7548 			IPACMDBG_H("ipv6 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i],
7549 				IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
7550 			/* RSB UDP rule*/
7551 			rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
7552 #ifdef IPA_RT_SUPPORT_COAL
7553 			if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable)
7554 				rt_rule_entry->rule.coalesce = true;
7555 			else
7556 				rt_rule_entry->rule.coalesce = false;
7557 #endif
7558 			if (false == m_routing.AddRoutingRule(rt_rule))
7559 			{
7560 				IPACMERR("Routing rule addition failed!\n");
7561 				res = IPACM_FAILURE;
7562 				goto fail2;
7563 			}
7564 			else if (rt_rule_entry->status)
7565 			{
7566 				IPACMERR("rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
7567 				res = rt_rule_entry->status;
7568 				goto fail2;
7569 			}
7570 			dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1] = rt_rule_entry->rt_rule_hdl;
7571 			IPACMDBG_H("ipv6 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1],
7572 				IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
7573 		}
7574 fail2:
7575 	free(rt_rule);
7576 	}
7577 	return res;
7578 }
7579 
add_offload_frag_rule()7580 int IPACM_Wan::add_offload_frag_rule()
7581 {
7582 	int fd;
7583 	int len, res = IPACM_SUCCESS;
7584 	uint8_t mux_id;
7585 	ipa_ioc_add_flt_rule *pFilteringTable = NULL;
7586 
7587 	/* Return if rules are there */
7588 	if (mhi_dl_v4_frag_hdl)
7589 	{
7590 		IPACMERR("frag rule have not been deleted. Don't install again\n");
7591 		return IPACM_FAILURE;
7592 	}
7593 
7594 	mux_id = ext_prop->ext[0].mux_id;
7595 	/* contruct filter rules to pcie modem */
7596 	struct ipa_flt_rule_add flt_rule_entry;
7597 	ipa_ioc_generate_flt_eq flt_eq;
7598 
7599 	/* construct rule */
7600 	IPACMDBG_H("adding MHi frag rule\n");
7601 	len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
7602 	pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
7603 	if (pFilteringTable == NULL)
7604 	{
7605 		IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
7606 		return IPACM_FAILURE;
7607 	}
7608 	memset(pFilteringTable, 0, len);
7609 
7610 	pFilteringTable->commit = 1;
7611 	pFilteringTable->global = false;
7612 	pFilteringTable->ip = IPA_IP_v4;
7613 	pFilteringTable->num_rules = (uint8_t)1;
7614 
7615 	/* Configuring Fragment Filtering Rule */
7616 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
7617 	flt_rule_entry.at_rear = false;
7618 	flt_rule_entry.flt_rule_hdl = -1;
7619 	flt_rule_entry.status = -1;
7620 
7621 	flt_rule_entry.rule.retain_hdr = 1;
7622 	flt_rule_entry.rule.to_uc = 0;
7623 	flt_rule_entry.rule.eq_attrib_type = 1;
7624 	flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
7625 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
7626 		flt_rule_entry.rule.hashable = true;
7627 	IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
7628 	memcpy(&flt_rule_entry.rule.attrib,
7629 				&rx_prop->rx[0].attrib,
7630 				sizeof(flt_rule_entry.rule.attrib));
7631 
7632 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
7633 
7634 	/* generate eq */
7635 	memset(&flt_eq, 0, sizeof(flt_eq));
7636 	memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
7637 	flt_eq.ip = IPA_IP_v4;
7638 
7639 	fd = open(IPA_DEVICE_NAME, O_RDWR);
7640 	if (fd < 0)
7641 	{
7642 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
7643 		free(pFilteringTable);
7644 		return IPACM_FAILURE;
7645 	}
7646 
7647 	if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) //define and cpy attribute to this struct
7648 	{
7649 		IPACMERR("Failed to get eq_attrib\n");
7650 		goto fail;
7651 	}
7652 	memcpy(&flt_rule_entry.rule.eq_attrib,
7653 		&flt_eq.eq_attrib,
7654 		sizeof(flt_rule_entry.rule.eq_attrib));
7655 	memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
7656 
7657 	/* add rule */
7658 	if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 1))
7659 	{
7660 		IPACMERR("Failed to install WAN DL filtering table.\n");
7661 		res = IPACM_FAILURE;
7662 		goto fail;
7663 	}
7664 
7665 	/* save handle */
7666 	mhi_dl_v4_frag_hdl = pFilteringTable->rules[0].flt_rule_hdl;
7667 
7668 fail:
7669 	close(fd);
7670 	if(pFilteringTable != NULL)
7671 	{
7672 		free(pFilteringTable);
7673 	}
7674 	return res;
7675 }
7676 
delete_offload_frag_rule()7677 int IPACM_Wan::delete_offload_frag_rule()
7678 {
7679 	int res = IPACM_SUCCESS;
7680 	int len;
7681 	ipa_ioc_del_flt_rule *pFilteringTable = NULL;
7682 
7683 	struct ipa_flt_rule_del flt_rule_entry;
7684 
7685 	IPACMDBG_H("deleting MHI frag rule \n");
7686 	len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
7687 	pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
7688 	if (pFilteringTable == NULL)
7689 	{
7690 		IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
7691 		return false;
7692 	}
7693 	memset(pFilteringTable, 0, len);
7694 
7695 	pFilteringTable->commit = 1;
7696 	pFilteringTable->ip = IPA_IP_v4;
7697 	pFilteringTable->num_hdls = (uint8_t)1;
7698 
7699 	if (mhi_dl_v4_frag_hdl == 0)
7700 	{
7701 		IPACMERR("invalid dl_v4_frag_hdl.\n");
7702 		res = false;
7703 		goto fail;
7704 	}
7705 
7706 	/* Configuring Software-Routing Filtering Rule */
7707 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
7708 	flt_rule_entry.hdl = mhi_dl_v4_frag_hdl;
7709 
7710 	memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
7711 
7712 	if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
7713 	{
7714 		IPACMERR("Failed to delete DL offload frag rule.\n");
7715 		res = false;
7716 		goto fail;
7717 	}
7718 	mhi_dl_v4_frag_hdl = 0;
7719 
7720 fail:
7721 	if(pFilteringTable != NULL)
7722 	{
7723 		free(pFilteringTable);
7724 	}
7725 	return res;
7726 }
7727 
add_icmpv6_exception_rule()7728 int IPACM_Wan::add_icmpv6_exception_rule()
7729 {
7730 	int fd;
7731 	int len, res = IPACM_SUCCESS;
7732 	uint8_t mux_id;
7733 	ipa_ioc_add_flt_rule *pFilteringTable = NULL;
7734 
7735 	/* Return if rules are there */
7736 	if (icmpv6_exception_hdl)
7737 	{
7738 		IPACMERR("icmpv6 rule have not been deleted. Don't install again\n");
7739 		return IPACM_FAILURE;
7740 	}
7741 
7742 	mux_id = ext_prop->ext[0].mux_id;
7743 	/* contruct filter rules to pcie modem */
7744 	struct ipa_flt_rule_add flt_rule_entry;
7745 	ipa_ioc_generate_flt_eq flt_eq;
7746 
7747 	/* construct rule */
7748 	IPACMDBG_H("adding MHI icmpv6 rule\n");
7749 	len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
7750 	pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
7751 	if (pFilteringTable == NULL)
7752 	{
7753 		IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
7754 		return IPACM_FAILURE;
7755 	}
7756 	memset(pFilteringTable, 0, len);
7757 
7758 	pFilteringTable->commit = 1;
7759 	pFilteringTable->global = false;
7760 	pFilteringTable->ip = IPA_IP_v6;
7761 	pFilteringTable->num_rules = (uint8_t)1;
7762 
7763 	/* Configuring ICMPv6 Filtering Rule */
7764 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
7765 	flt_rule_entry.rule.retain_hdr = 1;
7766 	flt_rule_entry.rule.to_uc = 0;
7767 	flt_rule_entry.rule.eq_attrib_type = 0;
7768 	flt_rule_entry.at_rear = false;
7769 	flt_rule_entry.flt_rule_hdl = -1;
7770 	flt_rule_entry.status = -1;
7771 	flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
7772 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
7773 		flt_rule_entry.rule.hashable = true;
7774 	IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
7775 	memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
7776 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
7777 	flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
7778 
7779 	/* generate eq */
7780 	memset(&flt_eq, 0, sizeof(flt_eq));
7781 	memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
7782 	flt_eq.ip = IPA_IP_v6;
7783 
7784 	fd = open(IPA_DEVICE_NAME, O_RDWR);
7785 	if (fd < 0)
7786 	{
7787 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
7788 		free(pFilteringTable);
7789 		return IPACM_FAILURE;
7790 	}
7791 
7792 	if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) //define and cpy attribute to this struct
7793 	{
7794 		IPACMERR("Failed to get eq_attrib\n");
7795 		res = IPACM_FAILURE;
7796 		goto fail;
7797 	}
7798 	memcpy(&flt_rule_entry.rule.eq_attrib,
7799 		&flt_eq.eq_attrib,
7800 		sizeof(flt_rule_entry.rule.eq_attrib));
7801 	memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
7802 
7803 	/* add rule */
7804 	if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 1))
7805 	{
7806 		IPACMERR("Failed to install WAN DL filtering table.\n");
7807 		res = IPACM_FAILURE;
7808 		goto fail;
7809 	}
7810 
7811 	/* save handle */
7812 	icmpv6_exception_hdl = pFilteringTable->rules[0].flt_rule_hdl;
7813 
7814 fail:
7815 	close(fd);
7816 	if(pFilteringTable != NULL)
7817 	{
7818 		free(pFilteringTable);
7819 	}
7820 	return res;
7821 }
7822 
delete_icmpv6_exception_rule()7823 int IPACM_Wan::delete_icmpv6_exception_rule()
7824 {
7825 	int len, res = IPACM_SUCCESS;
7826 	ipa_ioc_del_flt_rule *pFilteringTable = NULL;
7827 
7828 	struct ipa_flt_rule_del flt_rule_entry;
7829 
7830 	IPACMDBG_H("deleting MHI icmpv6 rule \n");
7831 	len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
7832 	pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
7833 	if (pFilteringTable == NULL)
7834 	{
7835 		IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
7836 		return IPACM_FAILURE;
7837 	}
7838 	memset(pFilteringTable, 0, len);
7839 
7840 	pFilteringTable->commit = 1;
7841 	pFilteringTable->ip = IPA_IP_v6;
7842 	pFilteringTable->num_hdls = (uint8_t)1;
7843 
7844 	if (icmpv6_exception_hdl == 0)
7845 	{
7846 		IPACMERR("invalid icmpv6_exception_hdl.\n");
7847 		res = IPACM_FAILURE;
7848 		goto fail;
7849 	}
7850 
7851 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
7852 	flt_rule_entry.hdl = icmpv6_exception_hdl;
7853 
7854 	memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
7855 
7856 	if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
7857 	{
7858 		IPACMERR("Failed to delete MHI icmpv6 rule.\n");
7859 		res = IPACM_FAILURE;
7860 		goto fail;
7861 	}
7862 	icmpv6_exception_hdl = 0;
7863 
7864 fail:
7865 	if(pFilteringTable != NULL)
7866 	{
7867 		free(pFilteringTable);
7868 	}
7869 	return res;
7870 }
7871 
add_tcp_fin_rst_exception_rule()7872 int IPACM_Wan::add_tcp_fin_rst_exception_rule()
7873 {
7874 	int fd;
7875 	int len, res = IPACM_SUCCESS;
7876 	uint8_t mux_id;
7877 	ipa_ioc_add_flt_rule *pFilteringTable = NULL;
7878 
7879 	/* Return if rules are there */
7880 	if (tcp_fin_hdl || tcp_rst_hdl)
7881 	{
7882 		IPACMERR("tcp RST/FIN rules have not been deleted. Don't install again\n");
7883 		return IPACM_FAILURE;
7884 	}
7885 
7886 	mux_id = ext_prop->ext[0].mux_id;
7887 	/* contruct filter rules to pcie modem */
7888 	struct ipa_flt_rule_add flt_rule_entry;
7889 	ipa_ioc_generate_flt_eq flt_eq;
7890 
7891 	/* construct rule */
7892 	IPACMDBG_H("adding MHI TCP FIN RST rule\n");
7893 	len = sizeof(struct ipa_ioc_add_flt_rule) + (2 * sizeof(struct ipa_flt_rule_add));
7894 	pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
7895 	if (pFilteringTable == NULL)
7896 	{
7897 		IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
7898 		return IPACM_FAILURE;
7899 	}
7900 	memset(pFilteringTable, 0, len);
7901 
7902 	pFilteringTable->commit = 1;
7903 	pFilteringTable->global = false;
7904 	pFilteringTable->ip = IPA_IP_v4;
7905 	pFilteringTable->num_rules = (uint8_t)2;
7906 
7907 	/* Configuring TCP FIN RST Filtering Rule */
7908 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
7909 	flt_rule_entry.rule.retain_hdr = 1;
7910 	flt_rule_entry.rule.to_uc = 0;
7911 	flt_rule_entry.rule.eq_attrib_type = 0;
7912 	flt_rule_entry.at_rear = false;
7913 	flt_rule_entry.flt_rule_hdl = -1;
7914 	flt_rule_entry.status = -1;
7915 	flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
7916 	/*
7917 	 * need this since fin is last packet in an ongoing TCP connection
7918 	 * so it will always match the previous hash and take MHIP path
7919 	 */
7920 	flt_rule_entry.rule.hashable = false;
7921 
7922 	IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
7923 	memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
7924 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
7925 	flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
7926 
7927 	/* generate eq */
7928 	memset(&flt_eq, 0, sizeof(flt_eq));
7929 	memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
7930 	flt_eq.ip = IPA_IP_v4;
7931 
7932 	fd = open(IPA_DEVICE_NAME, O_RDWR);
7933 	if (fd < 0)
7934 	{
7935 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
7936 		free(pFilteringTable);
7937 		return IPACM_FAILURE;
7938 	}
7939 
7940 	if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) //define and cpy attribute to this struct
7941 	{
7942 		IPACMERR("Failed to get eq_attrib\n");
7943 		res = IPACM_FAILURE;
7944 		goto fail;
7945 	}
7946 	memcpy(&flt_rule_entry.rule.eq_attrib,
7947 		&flt_eq.eq_attrib,
7948 		sizeof(flt_rule_entry.rule.eq_attrib));
7949 
7950 	/* set the bit mask to use MEQ32_IHL offset */
7951 		if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
7952 			flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<7);
7953 		else
7954 			flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<8);
7955 
7956 	/* add offset to compare TCP flags */
7957 	flt_rule_entry.rule.eq_attrib.num_ihl_offset_meq_32 = 1;
7958 	flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12;
7959 
7960 	/* add TCP FIN RULE */
7961 	flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT);
7962 	flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT);
7963 	memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
7964 
7965 	/* add TCP RST rule*/
7966 	flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_RST_SHIFT);
7967 	flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT);
7968 	memcpy(&(pFilteringTable->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
7969 
7970 	/* add rules */
7971 	if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 1))
7972 	{
7973 		IPACMERR("Failed to install WAN DL filtering table.\n");
7974 		res = IPACM_FAILURE;
7975 		goto fail;
7976 	}
7977 
7978 	/* save handle */
7979 	tcp_fin_hdl = pFilteringTable->rules[0].flt_rule_hdl;
7980 	tcp_rst_hdl = pFilteringTable->rules[1].flt_rule_hdl;
7981 
7982 fail:
7983 	close(fd);
7984 	if(pFilteringTable != NULL)
7985 	{
7986 		free(pFilteringTable);
7987 	}
7988 	return res;
7989 }
7990 
delete_tcp_fin_rst_exception_rule()7991 int IPACM_Wan::delete_tcp_fin_rst_exception_rule()
7992 {
7993 	int len, res = IPACM_SUCCESS;
7994 	ipa_ioc_del_flt_rule *pFilteringTable = NULL;
7995 
7996 	struct ipa_flt_rule_del flt_rule_entry;
7997 
7998 	IPACMDBG_H("deleting MHI TCP FIN RST rule \n");
7999 	len = sizeof(struct ipa_ioc_del_flt_rule) + (2 * sizeof(struct ipa_flt_rule_del));
8000 	pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
8001 	if (pFilteringTable == NULL)
8002 	{
8003 		IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
8004 		return IPACM_FAILURE;
8005 	}
8006 	memset(pFilteringTable, 0, len);
8007 
8008 	pFilteringTable->commit = 1;
8009 	pFilteringTable->ip = IPA_IP_v4;
8010 	pFilteringTable->num_hdls = (uint8_t)2;
8011 
8012 	if (tcp_fin_hdl == 0 || tcp_rst_hdl == 0)
8013 	{
8014 		IPACMERR("invalid tcp_fin_rst_hdl.\n");
8015 		res = IPACM_FAILURE;
8016 		goto fail;
8017 	}
8018 
8019 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
8020 	flt_rule_entry.hdl = tcp_fin_hdl;
8021 
8022 	memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
8023 
8024 	flt_rule_entry.hdl = tcp_rst_hdl;
8025 
8026 	memcpy(&(pFilteringTable->hdl[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
8027 
8028 	if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
8029 	{
8030 		IPACMERR("Failed to delete MHI TCP FIN RST rule.\n");
8031 		res = IPACM_FAILURE;
8032 		goto fail;
8033 	}
8034 	tcp_fin_hdl = 0;
8035 	tcp_rst_hdl = 0;
8036 
8037 fail:
8038 	if(pFilteringTable != NULL)
8039 	{
8040 		free(pFilteringTable);
8041 	}
8042 	return res;
8043 }
8044 
query_mtu_size()8045 int IPACM_Wan::query_mtu_size()
8046 {
8047 	int fd;
8048 	struct ifreq if_mtu;
8049 
8050 	fd = socket(AF_INET, SOCK_DGRAM, 0);
8051 	if ( fd < 0 ) {
8052 		IPACMERR("ipacm: socket open failed [%d]\n", fd);
8053 		return IPACM_FAILURE;
8054 	}
8055 
8056 	strlcpy(if_mtu.ifr_name, dev_name, IFNAMSIZ);
8057 	IPACMDBG_H("device name: %s\n", dev_name);
8058 	if_mtu.ifr_name[IFNAMSIZ - 1] = '\0';
8059 
8060 	if ( ioctl(fd, SIOCGIFMTU, &if_mtu) < 0 ) {
8061 		IPACMERR("ioctl failed to get mtu\n");
8062 		close(fd);
8063 		return IPACM_FAILURE;
8064 	}
8065 	IPACMDBG_H("mtu=[%d]\n", if_mtu.ifr_mtu);
8066 	if (if_mtu.ifr_mtu <= DEFAULT_MTU_SIZE) {
8067 		mtu_v4 = mtu_v6 = if_mtu.ifr_mtu;
8068 	}else {
8069 		mtu_v4 = mtu_v6 = DEFAULT_MTU_SIZE;
8070 	}
8071 	IPACMDBG_H("Updated mtu=[%d] for (%s)\n", mtu_v4, dev_name);
8072 
8073 	close(fd);
8074 	return IPACM_SUCCESS;
8075 }
8076 
8077 /* construct complete ethernet header */
handle_gw_mac_renew(ipacm_event_data_all * data,int index_client)8078 int IPACM_Wan::handle_gw_mac_renew(ipacm_event_data_all *data, int index_client)
8079 {
8080 	int index = IPACM_INVALID_INDEX;
8081 
8082 	/* checking if client has same ipv4, v6 will put future work */
8083 	if (data->iptype == IPA_IP_v4)
8084 	{
8085 		index = get_wan_client_index_ipv4(data->ipv4_addr);
8086 		if (index != IPACM_INVALID_INDEX)
8087 		{
8088 			IPACMDBG_H("Matched client index: %d\n", index);
8089 			IPACMDBG_H("Client MAC in cache %02x:%02x:%02x:%02x:%02x:%02x\n",
8090 				get_client_memptr(wan_client, index)->mac[0],
8091 				get_client_memptr(wan_client, index)->mac[1],
8092 				get_client_memptr(wan_client, index)->mac[2],
8093 				get_client_memptr(wan_client, index)->mac[3],
8094 					get_client_memptr(wan_client, index)->mac[4],
8095 					get_client_memptr(wan_client, index)->mac[5]);
8096 
8097 			/* check mac same or not */
8098 			if ((data->mac_addr[0] == get_client_memptr(wan_client, index)->mac[0]) &&
8099 				(data->mac_addr[1] == get_client_memptr(wan_client, index)->mac[1]) &&
8100 				(data->mac_addr[2] == get_client_memptr(wan_client, index)->mac[2]) &&
8101 				(data->mac_addr[3] == get_client_memptr(wan_client, index)->mac[3]) &&
8102 				(data->mac_addr[4] == get_client_memptr(wan_client, index)->mac[4]) &&
8103 				(data->mac_addr[5] == get_client_memptr(wan_client, index)->mac[5]))
8104 			{
8105 				IPACMDBG_H(" No need client (%d) mac renew with IPv4 (0x%x)\n", index, data->ipv4_addr);
8106 				return IPACM_FAILURE;
8107 			}
8108 			else
8109 			{
8110 				IPACMDBG_H(" client %d need mac renew with IPv4 (0x%x)\n", index, data->ipv4_addr);
8111 
8112 				/* Del NAT rules before ipv4 RT rules are delete */
8113 				if(get_client_memptr(wan_client, index)->ipv4_set == true)
8114 				{
8115 					IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wan_client, index)->v4_addr);
8116 					CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, index)->v4_addr);
8117 				}
8118 
8119 				/* clean up STA header / routing rule */
8120 				if (data->ipv4_addr == wan_v4_addr_gw && active_v4)
8121 				{
8122 					handle_route_del_evt(IPA_IP_v4, true);
8123 					IPACMDBG_H("Delete default v4 routing rules\n");
8124 					hdr_hdl_sta_v4 = 0;
8125 					header_set_v4 = false;
8126 					header_partial_default_wan_v4 = true;
8127 
8128 					if (active_v6)
8129 					{
8130 						handle_route_del_evt(IPA_IP_v6, true);
8131 						IPACMDBG_H("Delete default v6 routing rules\n");
8132 						header_partial_default_wan_v6 = true;
8133 					}
8134 					hdr_hdl_sta_v6 = 0;
8135 					header_set_v6 = false;
8136 				}
8137 
8138 				/* clean up client header routing rule entry */
8139 				if(delete_wan_rtrules(index, IPA_IP_v4))
8140 				{
8141 						IPACMERR("unbale to delete wan-client v4 route rules for index %d\n", index);
8142 						return IPACM_FAILURE;
8143 				}
8144 
8145 				get_client_memptr(wan_client, index)->route_rule_set_v4 = false;
8146 				get_client_memptr(wan_client, index)->ipv4_set = false;
8147 
8148 				IPACMDBG_H("Delete client %d header\n", index);
8149 				if(get_client_memptr(wan_client, index)->ipv4_header_set == true)
8150 				{
8151 					if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, index)->hdr_hdl_v4) == false)
8152 					{
8153 						IPACMERR("unable to delete client v4 header for index %d\n", index);
8154 						return IPACM_FAILURE;
8155 					}
8156 					get_client_memptr(wan_client, index)->ipv4_header_set = false;
8157 				}
8158 
8159 				if(delete_wan_rtrules(index, IPA_IP_v6))
8160 				{
8161 					IPACMERR("unbale to delete wan-client v6 route rules for index %d\n", index);
8162 					return IPACM_FAILURE;
8163 				}
8164 				get_client_memptr(wan_client, index)->route_rule_set_v6 = 0;
8165 				get_client_memptr(wan_client, index)->ipv6_set = 0;
8166 				if(get_client_memptr(wan_client, index)->ipv6_header_set == true)
8167 				{
8168 					if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, index)->hdr_hdl_v6) == false)
8169 					{
8170 						IPACMERR("unable to delete client v6 header for index %d\n", index);
8171 						return IPACM_FAILURE;
8172 					}
8173 					get_client_memptr(wan_client, index)->ipv6_header_set = false;
8174 				}
8175 				/* replacing the old mac to new_mac on same entry */
8176 				get_client_memptr(wan_client, index)->mac[0] = data->mac_addr[0];
8177 				get_client_memptr(wan_client, index)->mac[1] = data->mac_addr[1];
8178 				get_client_memptr(wan_client, index)->mac[2] = data->mac_addr[2];
8179 				get_client_memptr(wan_client, index)->mac[3] = data->mac_addr[3];
8180 				get_client_memptr(wan_client, index)->mac[4] = data->mac_addr[4];
8181 				get_client_memptr(wan_client, index)->mac[5] = data->mac_addr[5];
8182 				index_client = index;
8183 				return IPACM_SUCCESS;
8184 			}
8185 		}
8186 	}
8187 	return IPACM_FAILURE;
8188 }
8189