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