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