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