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