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