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