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