1 /*
2 Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9
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 modem_ul_v6_set = false;
85 is_mode_switch = false;
86 if_ipv4_subnet =0;
87 each_client_rt_rule_count[IPA_IP_v4] = 0;
88 each_client_rt_rule_count[IPA_IP_v6] = 0;
89 eth_client_len = 0;
90
91 /* support eth multiple clients */
92 if(iface_query != NULL)
93 {
94 if(ipa_if_cate != WLAN_IF)
95 {
96 eth_client_len = (sizeof(ipa_eth_client)) + (iface_query->num_tx_props * sizeof(eth_client_rt_hdl));
97 eth_client = (ipa_eth_client *)calloc(IPA_MAX_NUM_ETH_CLIENTS, eth_client_len);
98 if (eth_client == NULL)
99 {
100 IPACMERR("unable to allocate memory\n");
101 return;
102 }
103 }
104
105 IPACMDBG_H(" IPACM->IPACM_Lan(%d) constructor: Tx:%d Rx:%d \n", ipa_if_num,
106 iface_query->num_tx_props, iface_query->num_rx_props);
107
108 /* ODU routing table initilization */
109 if(ipa_if_cate == ODU_IF)
110 {
111 odu_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
112 odu_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
113 if ((odu_route_rule_v4_hdl == NULL) || (odu_route_rule_v6_hdl == NULL))
114 {
115 IPACMERR("unable to allocate memory\n");
116 return;
117 }
118 }
119 }
120
121 memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
122 memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
123
124 memset(ipv4_icmp_flt_rule_hdl, 0, NUM_IPV4_ICMP_FLT_RULE * sizeof(uint32_t));
125
126 memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t));
127 memset(ipv6_prefix_flt_rule_hdl, 0, NUM_IPV6_PREFIX_FLT_RULE * sizeof(uint32_t));
128 memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t));
129 memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
130
131 /* ODU routing table initilization */
132 if(ipa_if_cate == ODU_IF)
133 {
134 /* only do one time ioctl to odu-driver to infrom in router or bridge mode*/
135 if (IPACM_Lan::odu_up != true)
136 {
137 m_fd_odu = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR);
138 if (0 == m_fd_odu)
139 {
140 IPACMERR("Failed opening %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU);
141 return ;
142 }
143
144 if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)
145 {
146 ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_ROUTER);
147 IPACM_Iface::ipacmcfg->ipacm_odu_enable = true;
148 }
149 else
150 {
151 ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_BRIDGE);
152 IPACM_Iface::ipacmcfg->ipacm_odu_enable = true;
153 }
154
155 if (ret)
156 {
157 IPACMERR("Failed tell odu-driver the mode\n");
158 }
159 IPACMDBG("Tell odu-driver in router-mode(%d)\n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode);
160 IPACMDBG_H("odu is up: odu-driver in router-mode(%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode);
161 close(m_fd_odu);
162 IPACM_Lan::odu_up = true;
163 }
164 }
165
166 if(iface_query != NULL && tx_prop != NULL)
167 {
168 for(i=0; i<iface_query->num_tx_props; i++)
169 each_client_rt_rule_count[tx_prop->tx[i].ip]++;
170 }
171 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]);
172
173 #ifdef FEATURE_IPA_ANDROID
174 /* set the IPA-client pipe enum */
175 if(ipa_if_cate == LAN_IF)
176 {
177 #ifdef FEATURE_IPACM_HAL
178 handle_tethering_client(false, IPACM_CLIENT_MAX);
179 #else
180 handle_tethering_client(false, IPACM_CLIENT_USB);
181 #endif
182 }
183 #endif
184
185 memset(is_downstream_set, 0, sizeof(is_downstream_set));
186 memset(is_upstream_set, 0, sizeof(is_upstream_set));
187 memset(&prefix, 0, sizeof(prefix));
188
189 #ifdef FEATURE_IPACM_HAL
190 /* check if Upstream was set before */
191 if (IPACM_Wan::isWanUP(ipa_if_num))
192 {
193 IPACMDBG_H("Upstream was set previously for ipv4, change is_upstream_set flag\n");
194 is_upstream_set[IPA_IP_v4] = true;
195 }
196
197 if (IPACM_Wan::isWanUP_V6(ipa_if_num))
198 {
199 IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n");
200 is_upstream_set[IPA_IP_v6] = true;
201 }
202 #endif
203 return;
204 }
205
~IPACM_Lan()206 IPACM_Lan::~IPACM_Lan()
207 {
208 IPACM_EvtDispatcher::deregistr(this);
209 IPACM_IfaceManager::deregistr(this);
210 return;
211 }
212
213
214 /* LAN-iface's callback function */
event_callback(ipa_cm_event_id event,void * param)215 void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
216 {
217 if(is_active == false && event != IPA_LAN_DELETE_SELF)
218 {
219 IPACMDBG_H("The interface is no longer active, return.\n");
220 return;
221 }
222
223 int ipa_interface_index;
224 ipacm_ext_prop* ext_prop;
225 ipacm_event_iface_up_tehter* data_wan_tether;
226
227 switch (event)
228 {
229 case IPA_LINK_DOWN_EVENT:
230 {
231 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
232 ipa_interface_index = iface_ipa_index_query(data->if_index);
233 if (ipa_interface_index == ipa_if_num)
234 {
235 IPACMDBG_H("Received IPA_LINK_DOWN_EVENT\n");
236 handle_down_evt();
237 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
238 return;
239 }
240 }
241 break;
242
243 case IPA_CFG_CHANGE_EVENT:
244 {
245 if ( IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate)
246 {
247 IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category changed\n");
248 /* delete previous instance */
249 handle_down_evt();
250 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
251 is_mode_switch = true; // need post internal usb-link up event
252 return;
253 }
254 /* Add Natting iface to IPACM_Config if there is Rx/Tx property */
255 if (rx_prop != NULL || tx_prop != NULL)
256 {
257 IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
258 IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name);
259 }
260 }
261 break;
262
263 case IPA_PRIVATE_SUBNET_CHANGE_EVENT:
264 {
265 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
266 /* internel event: data->if_index is ipa_if_index */
267 if (data->if_index == ipa_if_num)
268 {
269 IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n");
270 return;
271 }
272 else
273 {
274 IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n");
275 #ifdef FEATURE_IPA_ANDROID
276 handle_private_subnet_android(IPA_IP_v4);
277 #endif
278 IPACMDBG_H(" delete old private subnet rules, use new sets \n");
279 return;
280 }
281 }
282 break;
283
284 case IPA_LAN_DELETE_SELF:
285 {
286 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
287 if(data->if_index == ipa_if_num)
288 {
289 IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n");
290 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
291 /* posting link-up event for cradle use-case */
292 if(is_mode_switch)
293 {
294 IPACMDBG_H("Posting IPA_USB_LINK_UP_EVENT event for (%s)\n", dev_name);
295 ipacm_cmd_q_data evt_data;
296 memset(&evt_data, 0, sizeof(evt_data));
297
298 ipacm_event_data_fid *data_fid = NULL;
299 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
300 if(data_fid == NULL)
301 {
302 IPACMERR("unable to allocate memory for IPA_USB_LINK_UP_EVENT data_fid\n");
303 return;
304 }
305 if(IPACM_Iface::ipa_get_if_index(dev_name, &(data_fid->if_index)))
306 {
307 IPACMERR("Error while getting interface index for %s device", dev_name);
308 }
309 evt_data.event = IPA_USB_LINK_UP_EVENT;
310 evt_data.evt_data = data_fid;
311 //IPACMDBG_H("Posting event:%d\n", evt_data.event);
312 IPACM_EvtDispatcher::PostEvt(&evt_data);
313 }
314 #ifndef FEATURE_IPA_ANDROID
315 if(rx_prop != NULL)
316 {
317 if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4) != 0)
318 {
319 IPACMDBG_DMESG("### WARNING ### num ipv4 flt rules on client %d is not expected: %d expected value: 0",
320 rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4));
321 }
322 if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6) != 0)
323 {
324 IPACMDBG_DMESG("### WARNING ### num ipv6 flt rules on client %d is not expected: %d expected value: 0",
325 rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6));
326 }
327 }
328 #endif
329 delete this;
330 }
331 break;
332 }
333
334 case IPA_ADDR_ADD_EVENT:
335 {
336 ipacm_event_data_addr *data = (ipacm_event_data_addr *)param;
337 ipa_interface_index = iface_ipa_index_query(data->if_index);
338
339 if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) ||
340 (data->iptype == IPA_IP_v6 &&
341 data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 &&
342 data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) )
343 {
344 IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n");
345 return;
346 }
347
348
349 if (ipa_interface_index == ipa_if_num)
350 {
351 IPACMDBG_H("Received IPA_ADDR_ADD_EVENT\n");
352
353 /* only call ioctl for ODU iface with bridge mode */
354 if(IPACM_Iface::ipacmcfg->ipacm_odu_enable == true && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false
355 && ipa_if_cate == ODU_IF)
356 {
357 if((data->iptype == IPA_IP_v6) && (num_dft_rt_v6 == 0))
358 {
359 handle_addr_evt_odu_bridge(data);
360 }
361 #ifdef FEATURE_IPA_ANDROID
362 add_dummy_private_subnet_flt_rule(data->iptype);
363 handle_private_subnet_android(data->iptype);
364 #else
365 handle_private_subnet(data->iptype);
366 #endif
367 }
368 else
369 {
370
371 /* check v4 not setup before, v6 can have 2 iface ip */
372 if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX))
373 || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
374 {
375 IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
376 if(handle_addr_evt(data) == IPACM_FAILURE)
377 {
378 return;
379 }
380
381 #ifdef FEATURE_IPA_ANDROID
382 add_dummy_private_subnet_flt_rule(data->iptype);
383 handle_private_subnet_android(data->iptype);
384 #else
385 handle_private_subnet(data->iptype);
386 #endif
387
388 #ifndef FEATURE_IPACM_HAL
389 if (IPACM_Wan::isWanUP(ipa_if_num))
390 {
391 if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
392 {
393 if(IPACM_Wan::backhaul_is_sta_mode == false)
394 {
395 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
396 handle_wan_up_ex(ext_prop, IPA_IP_v4,
397 IPACM_Wan::getXlat_Mux_Id());
398 }
399 else
400 {
401 handle_wan_up(IPA_IP_v4);
402 }
403 }
404 IPACMDBG_H("Finished checking wan_up\n");
405 } else {
406 IPACMDBG_H("Wan_V4 haven't up yet\n");
407 }
408
409 if(IPACM_Wan::isWanUP_V6(ipa_if_num))
410 {
411 if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
412 {
413 memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix));
414 install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
415 if(IPACM_Wan::backhaul_is_sta_mode == false)
416 {
417 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
418 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
419 }
420 else
421 {
422 handle_wan_up(IPA_IP_v6);
423 }
424 }
425 IPACMDBG_H("Finished checking wan_up_v6\n");
426 } else {
427 IPACMDBG_H("Wan_V6 haven't up yet\n");
428 }
429 #endif
430 /* Post event to NAT */
431 if (data->iptype == IPA_IP_v4)
432 {
433 ipacm_cmd_q_data evt_data;
434 ipacm_event_iface_up *info;
435
436 info = (ipacm_event_iface_up *)
437 malloc(sizeof(ipacm_event_iface_up));
438 if (info == NULL)
439 {
440 IPACMERR("Unable to allocate memory\n");
441 return;
442 }
443
444 memcpy(info->ifname, dev_name, IF_NAME_LEN);
445 info->ipv4_addr = data->ipv4_addr;
446 info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask;
447
448 evt_data.event = IPA_HANDLE_LAN_UP;
449 evt_data.evt_data = (void *)info;
450
451 /* Insert IPA_HANDLE_LAN_UP to command queue */
452 IPACMDBG_H("posting IPA_HANDLE_LAN_UP for IPv4 with below information\n");
453 IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n",
454 info->ipv4_addr, info->addr_mask);
455 IPACM_EvtDispatcher::PostEvt(&evt_data);
456 }
457 IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype);
458 }
459
460 IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype);
461 /* checking if SW-RT_enable */
462 if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true)
463 {
464 /* handle software routing enable event*/
465 IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
466 handle_software_routing_enable();
467 }
468
469 }
470 }
471 }
472 break;
473 #ifdef FEATURE_IPA_ANDROID
474 case IPA_HANDLE_WAN_UP_TETHER:
475 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n");
476
477 data_wan_tether = (ipacm_event_iface_up_tehter*)param;
478 if(data_wan_tether == NULL)
479 {
480 IPACMERR("No event data is found.\n");
481 return;
482 }
483 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
484 data_wan_tether->if_index_tether,
485 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
486 #ifndef FEATURE_IPACM_HAL
487 if (data_wan_tether->if_index_tether != ipa_if_num)
488 {
489 IPACMERR("IPA_HANDLE_WAN_UP_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
490 return;
491 }
492 #endif
493 if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
494 {
495 #ifdef FEATURE_IPACM_HAL
496 if (is_upstream_set[IPA_IP_v4] == false)
497 {
498 IPACMDBG_H("Add upstream for IPv4.\n");
499 is_upstream_set[IPA_IP_v4] = true;
500 if (is_downstream_set[IPA_IP_v4] == true)
501 {
502 IPACMDBG_H("Downstream was set before, adding UL rules.\n");
503 if (data_wan_tether->is_sta == false)
504 {
505 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
506 handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
507 } else {
508 handle_wan_up(IPA_IP_v4);
509 }
510 }
511 }
512 #else
513 if (data_wan_tether->is_sta == false)
514 {
515 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
516 handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
517 } else {
518 handle_wan_up(IPA_IP_v4);
519 }
520 #endif
521 }
522 break;
523
524 case IPA_HANDLE_WAN_UP_V6_TETHER:
525 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n");
526
527 data_wan_tether = (ipacm_event_iface_up_tehter*)param;
528 if (data_wan_tether == NULL)
529 {
530 IPACMERR("No event data is found.\n");
531 return;
532 }
533 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
534 data_wan_tether->if_index_tether,
535 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
536 #ifndef FEATURE_IPACM_HAL
537 if (data_wan_tether->if_index_tether != ipa_if_num)
538 {
539 IPACMERR("IPA_HANDLE_WAN_UP_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
540 return;
541 }
542 #endif
543 if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
544 {
545 #ifdef FEATURE_IPACM_HAL
546 if (is_upstream_set[IPA_IP_v6] == false)
547 {
548 IPACMDBG_H("Add upstream for IPv6.\n");
549 is_upstream_set[IPA_IP_v6] = true;
550
551 if (is_downstream_set[IPA_IP_v6] == true)
552 {
553 IPACMDBG_H("Downstream was set before, adding UL rules.\n");
554 memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix));
555 install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
556 if (data_wan_tether->is_sta == false)
557 {
558 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
559 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
560 }
561 else
562 {
563 handle_wan_up(IPA_IP_v6);
564 }
565 }
566 }
567 #else
568 if (data_wan_tether->is_sta == false)
569 {
570 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
571 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
572 } else {
573 handle_wan_up(IPA_IP_v6);
574 }
575 #endif
576 }
577 break;
578
579 case IPA_HANDLE_WAN_DOWN_TETHER:
580 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n");
581 data_wan_tether = (ipacm_event_iface_up_tehter*)param;
582 if (data_wan_tether == NULL)
583 {
584 IPACMERR("No event data is found.\n");
585 return;
586 }
587 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
588 data_wan_tether->if_index_tether,
589 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
590 #ifndef FEATURE_IPACM_HAL
591 if (data_wan_tether->if_index_tether != ipa_if_num)
592 {
593 IPACMERR("IPA_HANDLE_WAN_DOWN_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
594 return;
595 }
596 #endif
597 if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
598 {
599 #ifdef FEATURE_IPACM_HAL
600 if(is_upstream_set[IPA_IP_v4] == true)
601 {
602 IPACMDBG_H("Del upstream for IPv4.\n");
603 is_upstream_set[IPA_IP_v4] = false;
604 if(is_downstream_set[IPA_IP_v4] == true)
605 {
606 IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
607 handle_wan_down(data_wan_tether->is_sta);
608 }
609 }
610 #else
611 handle_wan_down(data_wan_tether->is_sta);
612 #endif
613 }
614 break;
615
616 case IPA_HANDLE_WAN_DOWN_V6_TETHER:
617 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n");
618 data_wan_tether = (ipacm_event_iface_up_tehter*)param;
619 if(data_wan_tether == NULL)
620 {
621 IPACMERR("No event data is found.\n");
622 return;
623 }
624 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
625 data_wan_tether->if_index_tether,
626 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
627 #ifndef FEATURE_IPACM_HAL
628 if (data_wan_tether->if_index_tether != ipa_if_num)
629 {
630 IPACMERR("IPA_HANDLE_WAN_DOWN_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
631 return;
632 }
633 #endif
634 if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
635 {
636 #ifdef FEATURE_IPACM_HAL
637 if (is_upstream_set[IPA_IP_v6] == true)
638 {
639 IPACMDBG_H("Del upstream for IPv6.\n");
640 is_upstream_set[IPA_IP_v6] = false;
641 if(is_downstream_set[IPA_IP_v6] == true)
642 {
643 IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
644 /* reset usb-client ipv6 rt-rules */
645 handle_lan_client_reset_rt(IPA_IP_v6);
646 handle_wan_down_v6(data_wan_tether->is_sta);
647 }
648 }
649 #else
650 /* reset usb-client ipv6 rt-rules */
651 handle_lan_client_reset_rt(IPA_IP_v6);
652 handle_wan_down_v6(data_wan_tether->is_sta);
653 #endif
654 }
655 break;
656
657 case IPA_DOWNSTREAM_ADD:
658 {
659 ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
660 ipa_interface_index = iface_ipa_index_query(data->if_index);
661 if (ipa_interface_index == ipa_if_num)
662 {
663 IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
664 if (is_downstream_set[data->prefix.iptype] == false)
665 {
666 IPACMDBG_H("Add downstream for IP iptype %d\n", data->prefix.iptype);
667 is_downstream_set[data->prefix.iptype] = true;
668 memcpy(&prefix[data->prefix.iptype], &data->prefix,
669 sizeof(prefix[data->prefix.iptype]));
670
671 if (is_upstream_set[data->prefix.iptype] == true)
672 {
673 IPACMDBG_H("Upstream was set before, adding UL rules.\n");
674 if (ip_type == IPA_IP_MAX || ip_type == data->prefix.iptype)
675 {
676 if (data->prefix.iptype == IPA_IP_v6) /* ipv6 only */
677 {
678 /* Only offload clients has same prefix as Android gave */
679 ipv6_prefix[0] = data->prefix.v6Addr[0];
680 ipv6_prefix[1] = data->prefix.v6Addr[1];
681 IPACMDBG_H("ipv6_prefix0x%x:%x\n", ipv6_prefix[0], ipv6_prefix[1]);
682 install_ipv6_prefix_flt_rule(ipv6_prefix);
683 }
684
685 if (IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
686 {
687 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
688 handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
689 } else {
690 handle_wan_up(data->prefix.iptype); /* STA */
691 }
692 }
693 }
694 } else {
695 IPACMDBG_H("downstream for IP iptype %d already set \n", data->prefix.iptype);
696 }
697 }
698 break;
699 }
700
701 case IPA_DOWNSTREAM_DEL:
702 {
703 ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
704 ipa_interface_index = iface_ipa_index_query(data->if_index);
705 if (ipa_interface_index == ipa_if_num)
706 {
707 IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
708 if (is_downstream_set[data->prefix.iptype] == true)
709 {
710 IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
711 is_downstream_set[data->prefix.iptype] = false;
712
713 if (is_upstream_set[data->prefix.iptype] == true)
714 {
715 IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
716 if (data->prefix.iptype == IPA_IP_v4)
717 {
718 handle_wan_down(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
719 } else {
720 handle_lan_client_reset_rt(IPA_IP_v6);
721 handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
722 }
723 }
724 }
725 }
726 break;
727 }
728
729 #else
730 case IPA_HANDLE_WAN_UP:
731 IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
732
733 ipacm_event_iface_up* data_wan = (ipacm_event_iface_up*)param;
734 if (data_wan == NULL)
735 {
736 IPACMERR("No event data is found.\n");
737 return;
738 }
739 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
740 if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
741 {
742 if (data_wan->is_sta == false)
743 {
744 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
745 handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
746 }
747 else
748 {
749 handle_wan_up(IPA_IP_v4);
750 }
751 }
752 break;
753
754 case IPA_HANDLE_WAN_UP_V6:
755 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6 event\n");
756
757 data_wan = (ipacm_event_iface_up*)param;
758 if (data_wan == NULL)
759 {
760 IPACMERR("No event data is found.\n");
761 return;
762 }
763 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
764 if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
765 {
766 memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix));
767 install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
768 if (data_wan->is_sta == false)
769 {
770 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
771 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
772 }
773 else
774 {
775 handle_wan_up(IPA_IP_v6);
776 }
777 }
778 break;
779
780 case IPA_HANDLE_WAN_DOWN:
781 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n");
782 data_wan = (ipacm_event_iface_up*)param;
783 if (data_wan == NULL)
784 {
785 IPACMERR("No event data is found.\n");
786 return;
787 }
788 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
789 if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
790 {
791 handle_wan_down(data_wan->is_sta);
792 }
793 break;
794
795 case IPA_HANDLE_WAN_DOWN_V6:
796 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6 event\n");
797 data_wan = (ipacm_event_iface_up*)param;
798 if (data_wan == NULL)
799 {
800 IPACMERR("No event data is found.\n");
801 return;
802 }
803 /* clean up v6 RT rules*/
804 IPACMDBG_H("Received IPA_WAN_V6_DOWN in LAN-instance and need clean up client IPv6 address \n");
805 /* reset usb-client ipv6 rt-rules */
806 handle_lan_client_reset_rt(IPA_IP_v6);
807
808 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
809 if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
810 {
811 handle_wan_down_v6(data_wan->is_sta);
812 }
813 break;
814 #endif
815
816 case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
817 {
818 ipacm_event_data_all *data = (ipacm_event_data_all *)param;
819 ipa_interface_index = iface_ipa_index_query(data->if_index);
820 IPACMDBG_H("Recieved IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event \n");
821 IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate);
822
823 if (ipa_interface_index == ipa_if_num && ipa_if_cate == ODU_IF)
824 {
825 IPACMDBG_H("ODU iface got v4-ip \n");
826 /* first construc ODU full header */
827 if ((ipv4_header_set == false) && (ipv6_header_set == false))
828 {
829 /* construct ODU RT tbl */
830 handle_odu_hdr_init(data->mac_addr);
831 if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true)
832 {
833 handle_odu_route_add();
834 IPACMDBG_H("construct ODU header and route rules, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
835 }
836 else
837 {
838 IPACMDBG_H("construct ODU header only, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
839 }
840 }
841 /* if ODU in bridge mode, directly return */
842 if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
843 {
844 IPACMDBG_H("ODU is in bridge mode, no action \n");
845 return;
846 }
847 }
848
849 if (ipa_interface_index == ipa_if_num)
850 {
851 IPACMDBG_H("ETH iface got client \n");
852 /* first construc ETH full header */
853 handle_eth_hdr_init(data->mac_addr);
854 IPACMDBG_H("construct ETH header and route rules \n");
855 /* Associate with IP and construct RT-rule */
856 if (handle_eth_client_ipaddr(data) == IPACM_FAILURE)
857 {
858 return;
859 }
860 handle_eth_client_route_rule(data->mac_addr, data->iptype);
861 if (data->iptype == IPA_IP_v4)
862 {
863 /* Add NAT rules after ipv4 RT rules are set */
864 CtList->HandleNeighIpAddrAddEvt(data);
865 }
866 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr);
867 return;
868 }
869 }
870 break;
871
872 case IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT:
873 {
874 ipacm_event_data_all *data = (ipacm_event_data_all *)param;
875 ipa_interface_index = iface_ipa_index_query(data->if_index);
876
877 IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event. \n");
878 IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate);
879 /* if ODU in bridge mode, directly return */
880 if (ipa_if_cate == ODU_IF && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
881 {
882 IPACMDBG_H("ODU is in bridge mode, no action \n");
883 return;
884 }
885
886 if (ipa_interface_index == ipa_if_num)
887 {
888 if (data->iptype == IPA_IP_v6)
889 {
890 handle_del_ipv6_addr(data);
891 return;
892 }
893
894 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_DEL, IPA_IP_MAX, data->mac_addr);
895
896 IPACMDBG_H("LAN iface delete client \n");
897 handle_eth_client_down_evt(data->mac_addr);
898 return;
899 }
900 }
901 break;
902
903 case IPA_SW_ROUTING_ENABLE:
904 IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n");
905 /* handle software routing enable event*/
906 handle_software_routing_enable();
907 break;
908
909 case IPA_SW_ROUTING_DISABLE:
910 IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n");
911 /* handle software routing disable event*/
912 handle_software_routing_disable();
913 break;
914
915 case IPA_CRADLE_WAN_MODE_SWITCH:
916 {
917 IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n");
918 ipacm_event_cradle_wan_mode* wan_mode = (ipacm_event_cradle_wan_mode*)param;
919 if(wan_mode == NULL)
920 {
921 IPACMERR("Event data is empty.\n");
922 return;
923 }
924
925 if(wan_mode->cradle_wan_mode == BRIDGE)
926 {
927 handle_cradle_wan_mode_switch(true);
928 }
929 else
930 {
931 handle_cradle_wan_mode_switch(false);
932 }
933 }
934 break;
935
936 case IPA_TETHERING_STATS_UPDATE_EVENT:
937 {
938 IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
939 if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
940 {
941 if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
942 {
943 ipa_get_data_stats_resp_msg_v01 *data = (ipa_get_data_stats_resp_msg_v01 *)param;
944 IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data->ipa_stats_type);
945 IPACMDBG("Received %d UL, %d DL pipe stats\n",data->ul_src_pipe_stats_list_len,
946 data->dl_dst_pipe_stats_list_len);
947 if (data->ipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01)
948 {
949 IPACMERR("not valid pipe stats enum(%d)\n", data->ipa_stats_type);
950 return;
951 }
952 handle_tethering_stats_event(data);
953 }
954 }
955 }
956 break;
957
958 default:
959 break;
960 }
961
962 return;
963 }
964
965
handle_del_ipv6_addr(ipacm_event_data_all * data)966 int IPACM_Lan::handle_del_ipv6_addr(ipacm_event_data_all *data)
967 {
968 uint32_t tx_index;
969 uint32_t rt_hdl;
970 int num_v6 =0, clnt_indx;
971
972 clnt_indx = get_eth_client_index(data->mac_addr);
973 if (clnt_indx == IPACM_INVALID_INDEX)
974 {
975 IPACMERR("eth client not found/attached \n");
976 return IPACM_FAILURE;
977 }
978
979 if(data->iptype == IPA_IP_v6)
980 {
981 if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
982 (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0))
983 {
984 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]);
985 for(num_v6=0;num_v6 < get_client_memptr(eth_client, clnt_indx)->ipv6_set;num_v6++)
986 {
987 if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][0] &&
988 data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][1] &&
989 data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][2] &&
990 data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][3])
991 {
992 IPACMDBG_H("ipv6 addr is found at position:%d for client:%d\n", num_v6, clnt_indx);
993 break;
994 }
995 }
996 }
997 else
998 {
999 IPACMDBG_H("Invalid ipv6 address\n");
1000 return IPACM_FAILURE;
1001 }
1002 if (num_v6 == IPV6_NUM_ADDR)
1003 {
1004 IPACMDBG_H("ipv6 addr is not found. \n");
1005 return IPACM_FAILURE;
1006 }
1007
1008 for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
1009 {
1010 if((tx_prop->tx[tx_index].ip == IPA_IP_v6) && (get_client_memptr(eth_client, clnt_indx)->route_rule_set_v6 != 0))
1011 {
1012 IPACMDBG_H("Delete client index %d ipv6 RT-rules for %d-st ipv6 for tx:%d\n", clnt_indx, num_v6, tx_index);
1013 rt_hdl = get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6];
1014 if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
1015 {
1016 return IPACM_FAILURE;
1017 }
1018 rt_hdl = get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6];
1019 if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
1020 {
1021 return IPACM_FAILURE;
1022 }
1023 get_client_memptr(eth_client, clnt_indx)->ipv6_set--;
1024 get_client_memptr(eth_client, clnt_indx)->route_rule_set_v6--;
1025
1026 for(;num_v6< get_client_memptr(eth_client, clnt_indx)->ipv6_set;num_v6++)
1027 {
1028 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][0] =
1029 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][0];
1030 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][1] =
1031 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][1];
1032 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][2] =
1033 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][2];
1034 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][3] =
1035 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][3];
1036 get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6] =
1037 get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6+1];
1038 get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6] =
1039 get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6+1];
1040 }
1041 }
1042 }
1043 }
1044 return IPACM_SUCCESS;
1045 }
1046
1047 /* delete filter rule for wan_down event for IPv4*/
handle_wan_down(bool is_sta_mode)1048 int IPACM_Lan::handle_wan_down(bool is_sta_mode)
1049 {
1050 ipa_fltr_installed_notif_req_msg_v01 flt_index;
1051 int fd;
1052
1053 fd = open(IPA_DEVICE_NAME, O_RDWR);
1054 if (0 == fd)
1055 {
1056 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1057 return IPACM_FAILURE;
1058 }
1059
1060 if(is_sta_mode == false && modem_ul_v4_set == true)
1061 {
1062 if (num_wan_ul_fl_rule_v4 > MAX_WAN_UL_FILTER_RULES)
1063 {
1064 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);
1065 close(fd);
1066 return IPACM_FAILURE;
1067 }
1068 if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v4,
1069 IPA_IP_v4, num_wan_ul_fl_rule_v4) == false)
1070 {
1071 IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n");
1072 close(fd);
1073 return IPACM_FAILURE;
1074 }
1075 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_wan_ul_fl_rule_v4);
1076
1077 memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
1078 num_wan_ul_fl_rule_v4 = 0;
1079 modem_ul_v4_set = false;
1080
1081 memset(&flt_index, 0, sizeof(flt_index));
1082 flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe);
1083 flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01;
1084 #ifndef FEATURE_IPA_V3
1085 flt_index.filter_index_list_len = 0;
1086 #else /* defined (FEATURE_IPA_V3) */
1087 flt_index.rule_id_valid = 1;
1088 flt_index.rule_id_len = 0;
1089 #endif
1090 flt_index.embedded_pipe_index_valid = 1;
1091 flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD);
1092 flt_index.retain_header_valid = 1;
1093 flt_index.retain_header = 0;
1094 flt_index.embedded_call_mux_id_valid = 1;
1095 flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
1096
1097 if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
1098 {
1099 IPACMERR("Error sending filtering rule index, aborting...\n");
1100 close(fd);
1101 return IPACM_FAILURE;
1102 }
1103 }
1104 else
1105 {
1106 if (m_filtering.DeleteFilteringHdls(&lan_wan_fl_rule_hdl[0], IPA_IP_v4, 1) == false)
1107 {
1108 IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
1109 close(fd);
1110 return IPACM_FAILURE;
1111 }
1112 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
1113 }
1114
1115 close(fd);
1116 return IPACM_SUCCESS;
1117 }
1118
1119 /* handle new_address event*/
handle_addr_evt(ipacm_event_data_addr * data)1120 int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data)
1121 {
1122 struct ipa_ioc_add_rt_rule *rt_rule;
1123 struct ipa_rt_rule_add *rt_rule_entry;
1124 const int NUM_RULES = 1;
1125 uint32_t num_ipv6_addr;
1126 int res = IPACM_SUCCESS;
1127 #ifdef FEATURE_IPACM_HAL
1128 IPACM_OffloadManager* OffloadMng;
1129 #endif
1130
1131 IPACMDBG_H("set route/filter rule ip-type: %d \n", data->iptype);
1132
1133 /* Add private subnet*/
1134 #ifdef FEATURE_IPA_ANDROID
1135 if (data->iptype == IPA_IP_v4)
1136 {
1137 IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
1138 if_ipv4_subnet = (data->ipv4_addr >> 8) << 8;
1139 IPACMDBG_H(" Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
1140 if(IPACM_Iface::ipacmcfg->AddPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
1141 {
1142 IPACMERR(" can't Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
1143 }
1144 }
1145 #endif /* defined(FEATURE_IPA_ANDROID)*/
1146
1147 /* Update the IP Type. */
1148 config_ip_type(data->iptype);
1149
1150 if (data->iptype == IPA_IP_v4)
1151 {
1152 rt_rule = (struct ipa_ioc_add_rt_rule *)
1153 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
1154 NUM_RULES * sizeof(struct ipa_rt_rule_add));
1155
1156 if (!rt_rule)
1157 {
1158 IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
1159 return IPACM_FAILURE;
1160 }
1161
1162 rt_rule->commit = 1;
1163 rt_rule->num_rules = NUM_RULES;
1164 rt_rule->ip = data->iptype;
1165 rt_rule_entry = &rt_rule->rules[0];
1166 rt_rule_entry->at_rear = false;
1167 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; //go to A5
1168 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
1169 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
1170 rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr;
1171 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
1172 #ifdef FEATURE_IPA_V3
1173 rt_rule_entry->rule.hashable = true;
1174 #endif
1175 if (false == m_routing.AddRoutingRule(rt_rule))
1176 {
1177 IPACMERR("Routing rule addition failed!\n");
1178 res = IPACM_FAILURE;
1179 goto fail;
1180 }
1181 else if (rt_rule_entry->status)
1182 {
1183 IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1184 res = rt_rule_entry->status;
1185 goto fail;
1186 }
1187 dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
1188 IPACMDBG_H("ipv4 iface rt-rule hdl1=0x%x\n", dft_rt_rule_hdl[0]);
1189 /* initial multicast/broadcast/fragment filter rule */
1190
1191 init_fl_rule(data->iptype);
1192 install_ipv4_icmp_flt_rule();
1193
1194 /* populate the flt rule offset for eth bridge */
1195 eth_bridge_flt_rule_offset[data->iptype] = ipv4_icmp_flt_rule_hdl[0];
1196 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL);
1197 }
1198 else
1199 {
1200 /* check if see that v6-addr already or not*/
1201 for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
1202 {
1203 if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
1204 (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
1205 (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
1206 (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
1207 {
1208 return IPACM_FAILURE;
1209 break;
1210 }
1211 }
1212
1213 rt_rule = (struct ipa_ioc_add_rt_rule *)
1214 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
1215 NUM_RULES * sizeof(struct ipa_rt_rule_add));
1216
1217 if (!rt_rule)
1218 {
1219 IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
1220 return IPACM_FAILURE;
1221 }
1222
1223 rt_rule->commit = 1;
1224 rt_rule->num_rules = NUM_RULES;
1225 rt_rule->ip = data->iptype;
1226 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
1227
1228 rt_rule_entry = &rt_rule->rules[0];
1229 rt_rule_entry->at_rear = false;
1230 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; //go to A5
1231 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
1232 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0];
1233 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1];
1234 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2];
1235 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3];
1236 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
1237 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
1238 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
1239 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
1240 ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
1241 ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
1242 ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
1243 ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
1244 #ifdef FEATURE_IPA_V3
1245 rt_rule_entry->rule.hashable = true;
1246 #endif
1247 if (false == m_routing.AddRoutingRule(rt_rule))
1248 {
1249 IPACMERR("Routing rule addition failed!\n");
1250 res = IPACM_FAILURE;
1251 goto fail;
1252 }
1253 else if (rt_rule_entry->status)
1254 {
1255 IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1256 res = rt_rule_entry->status;
1257 goto fail;
1258 }
1259 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
1260
1261 /* setup same rule for v6_wan table*/
1262 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
1263 if (false == m_routing.AddRoutingRule(rt_rule))
1264 {
1265 IPACMERR("Routing rule addition failed!\n");
1266 res = IPACM_FAILURE;
1267 goto fail;
1268 }
1269 else if (rt_rule_entry->status)
1270 {
1271 IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
1272 res = rt_rule_entry->status;
1273 goto fail;
1274 }
1275 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
1276
1277 IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n",
1278 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
1279 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6);
1280
1281 if (num_dft_rt_v6 == 0)
1282 {
1283 install_ipv6_icmp_flt_rule();
1284
1285 /* populate the flt rule offset for eth bridge */
1286 eth_bridge_flt_rule_offset[data->iptype] = ipv6_icmp_flt_rule_hdl[0];
1287 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL);
1288
1289 init_fl_rule(data->iptype);
1290 }
1291 num_dft_rt_v6++;
1292 IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
1293 }
1294
1295 #ifdef FEATURE_IPACM_HAL
1296 /* check if having pending add_downstream cache*/
1297 OffloadMng = IPACM_OffloadManager::GetInstance();
1298 if (OffloadMng == NULL) {
1299 IPACMERR("failed to get IPACM_OffloadManager instance !\n");
1300 } else {
1301 IPACMDBG_H(" check iface %s if having add_downstream cache events\n", dev_name);
1302 OffloadMng->search_framwork_cache(dev_name);
1303 }
1304 #endif
1305
1306 IPACMDBG_H("finish route/filter rule ip-type: %d, res(%d)\n", data->iptype, res);
1307
1308 fail:
1309 free(rt_rule);
1310 return res;
1311 }
1312
1313 /* configure private subnet filter rules*/
handle_private_subnet(ipa_ip_type iptype)1314 int IPACM_Lan::handle_private_subnet(ipa_ip_type iptype)
1315 {
1316 struct ipa_flt_rule_add flt_rule_entry;
1317 int i;
1318
1319 ipa_ioc_add_flt_rule *m_pFilteringTable;
1320
1321 IPACMDBG_H("lan->handle_private_subnet(); set route/filter rule \n");
1322
1323 if (rx_prop == NULL)
1324 {
1325 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
1326 return IPACM_SUCCESS;
1327 }
1328
1329 if (iptype == IPA_IP_v4)
1330 {
1331
1332 m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
1333 calloc(1,
1334 sizeof(struct ipa_ioc_add_flt_rule) +
1335 (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_add)
1336 );
1337 if (!m_pFilteringTable)
1338 {
1339 PERROR("Error Locate ipa_flt_rule_add memory...\n");
1340 return IPACM_FAILURE;
1341 }
1342 m_pFilteringTable->commit = 1;
1343 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
1344 m_pFilteringTable->global = false;
1345 m_pFilteringTable->ip = IPA_IP_v4;
1346 m_pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
1347
1348 /* Make LAN-traffic always go A5, use default IPA-RT table */
1349 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4))
1350 {
1351 IPACMERR("LAN m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_default_v4);
1352 free(m_pFilteringTable);
1353 return IPACM_FAILURE;
1354 }
1355
1356 for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
1357 {
1358 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
1359 flt_rule_entry.at_rear = true;
1360 flt_rule_entry.rule.retain_hdr = 1;
1361 flt_rule_entry.flt_rule_hdl = -1;
1362 flt_rule_entry.status = -1;
1363 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
1364 #ifdef FEATURE_IPA_V3
1365 flt_rule_entry.rule.hashable = true;
1366 #endif
1367 /* Support private subnet feature including guest-AP can't talk to primary AP etc */
1368 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl;
1369 IPACMDBG_H(" private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name);
1370
1371 memcpy(&flt_rule_entry.rule.attrib,
1372 &rx_prop->rx[0].attrib,
1373 sizeof(flt_rule_entry.rule.attrib));
1374 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1375 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
1376 flt_rule_entry.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
1377 memcpy(&(m_pFilteringTable->rules[i]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
1378 IPACMDBG_H("Loop %d 5\n", i);
1379 }
1380
1381 if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
1382 {
1383 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
1384 free(m_pFilteringTable);
1385 return IPACM_FAILURE;
1386 }
1387 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
1388
1389 /* copy filter rule hdls */
1390 for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
1391 {
1392 private_fl_rule_hdl[i] = m_pFilteringTable->rules[i].flt_rule_hdl;
1393 }
1394 free(m_pFilteringTable);
1395 }
1396 else
1397 {
1398 IPACMDBG_H("No private subnet rules for ipv6 iface %s\n", dev_name);
1399 }
1400 return IPACM_SUCCESS;
1401 }
1402
1403
1404 /* for STA mode wan up: configure filter rule for wan_up event*/
handle_wan_up(ipa_ip_type ip_type)1405 int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type)
1406 {
1407 struct ipa_flt_rule_add flt_rule_entry;
1408 int len = 0;
1409 ipa_ioc_add_flt_rule *m_pFilteringTable;
1410
1411 IPACMDBG_H("set WAN interface as default filter rule\n");
1412
1413 if (rx_prop == NULL)
1414 {
1415 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
1416 return IPACM_SUCCESS;
1417 }
1418
1419 if(ip_type == IPA_IP_v4)
1420 {
1421 len = sizeof(struct ipa_ioc_add_flt_rule) + (1 * sizeof(struct ipa_flt_rule_add));
1422 m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
1423 if (m_pFilteringTable == NULL)
1424 {
1425 PERROR("Error Locate ipa_flt_rule_add memory...\n");
1426 return IPACM_FAILURE;
1427 }
1428
1429 m_pFilteringTable->commit = 1;
1430 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
1431 m_pFilteringTable->global = false;
1432 m_pFilteringTable->ip = IPA_IP_v4;
1433 m_pFilteringTable->num_rules = (uint8_t)1;
1434
1435 IPACMDBG_H("Retrieving routing hanle for table: %s\n",
1436 IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name);
1437 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4))
1438 {
1439 IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n",
1440 &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4);
1441 free(m_pFilteringTable);
1442 return IPACM_FAILURE;
1443 }
1444 IPACMDBG_H("Routing hanle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl);
1445
1446
1447 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields
1448 flt_rule_entry.at_rear = true;
1449 flt_rule_entry.flt_rule_hdl = -1;
1450 flt_rule_entry.status = -1;
1451 if(IPACM_Wan::isWan_Bridge_Mode())
1452 {
1453 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
1454 }
1455 else
1456 {
1457 flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; //IPA_PASS_TO_ROUTING
1458 }
1459 #ifdef FEATURE_IPA_V3
1460 flt_rule_entry.rule.hashable = true;
1461 #endif
1462 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl;
1463
1464 memcpy(&flt_rule_entry.rule.attrib,
1465 &rx_prop->rx[0].attrib,
1466 sizeof(flt_rule_entry.rule.attrib));
1467
1468 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1469 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0;
1470 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0;
1471
1472 /* only offload UL traffic of certain clients */
1473 #ifdef FEATURE_IPACM_HAL
1474 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
1475 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = prefix[IPA_IP_v4].v4Mask;
1476 flt_rule_entry.rule.attrib.u.v4.dst_addr = prefix[IPA_IP_v4].v4Addr;
1477 #endif
1478 memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry));
1479 if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
1480 {
1481 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
1482 free(m_pFilteringTable);
1483 return IPACM_FAILURE;
1484 }
1485 else
1486 {
1487 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
1488 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
1489 m_pFilteringTable->rules[0].flt_rule_hdl,
1490 m_pFilteringTable->rules[0].status);
1491 }
1492
1493
1494 /* copy filter hdls */
1495 lan_wan_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
1496 free(m_pFilteringTable);
1497 }
1498 else if(ip_type == IPA_IP_v6)
1499 {
1500 /* add default v6 filter rule */
1501 m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
1502 calloc(1, sizeof(struct ipa_ioc_add_flt_rule) +
1503 1 * sizeof(struct ipa_flt_rule_add));
1504
1505 if (!m_pFilteringTable)
1506 {
1507 PERROR("Error Locate ipa_flt_rule_add memory...\n");
1508 return IPACM_FAILURE;
1509 }
1510
1511 m_pFilteringTable->commit = 1;
1512 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
1513 m_pFilteringTable->global = false;
1514 m_pFilteringTable->ip = IPA_IP_v6;
1515 m_pFilteringTable->num_rules = (uint8_t)1;
1516
1517 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6))
1518 {
1519 IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_v6);
1520 free(m_pFilteringTable);
1521 return IPACM_FAILURE;
1522 }
1523
1524 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
1525
1526 flt_rule_entry.at_rear = true;
1527 flt_rule_entry.flt_rule_hdl = -1;
1528 flt_rule_entry.status = -1;
1529 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
1530 #ifdef FEATURE_IPA_V3
1531 flt_rule_entry.rule.hashable = true;
1532 #endif
1533 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_v6.hdl;
1534
1535 memcpy(&flt_rule_entry.rule.attrib,
1536 &rx_prop->rx[0].attrib,
1537 sizeof(flt_rule_entry.rule.attrib));
1538
1539 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1540 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;
1541 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
1542 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
1543 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
1544 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000;
1545 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
1546 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
1547 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
1548
1549 /* only offload UL traffic of certain clients */
1550 #ifdef FEATURE_IPACM_HAL
1551 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
1552 flt_rule_entry.rule.attrib.u.v6.src_addr_mask[0] = ntohl(prefix[IPA_IP_v6].v6Mask[0]);
1553 flt_rule_entry.rule.attrib.u.v6.src_addr_mask[1] = ntohl(prefix[IPA_IP_v6].v6Mask[1]);
1554 flt_rule_entry.rule.attrib.u.v6.src_addr_mask[2] = ntohl(prefix[IPA_IP_v6].v6Mask[2]);
1555 flt_rule_entry.rule.attrib.u.v6.src_addr_mask[3] = ntohl(prefix[IPA_IP_v6].v6Mask[3]);
1556 flt_rule_entry.rule.attrib.u.v6.src_addr[0] = ntohl(prefix[IPA_IP_v6].v6Addr[0]);
1557 flt_rule_entry.rule.attrib.u.v6.src_addr[1] = ntohl(prefix[IPA_IP_v6].v6Addr[1]);
1558 flt_rule_entry.rule.attrib.u.v6.src_addr[2] = ntohl(prefix[IPA_IP_v6].v6Addr[2]);
1559 flt_rule_entry.rule.attrib.u.v6.src_addr[3] = ntohl(prefix[IPA_IP_v6].v6Addr[3]);
1560
1561 #endif
1562 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
1563 if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
1564 {
1565 IPACMERR("Error Adding Filtering rule, aborting...\n");
1566 free(m_pFilteringTable);
1567 return IPACM_FAILURE;
1568 }
1569 else
1570 {
1571 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
1572 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
1573 }
1574
1575 /* copy filter hdls */
1576 dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES] = m_pFilteringTable->rules[0].flt_rule_hdl;
1577 free(m_pFilteringTable);
1578 }
1579
1580 return IPACM_SUCCESS;
1581 }
1582
handle_wan_up_ex(ipacm_ext_prop * ext_prop,ipa_ip_type iptype,uint8_t xlat_mux_id)1583 int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, uint8_t xlat_mux_id)
1584 {
1585 int fd, ret = IPACM_SUCCESS;
1586 uint32_t cnt;
1587 IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg;
1588 struct ipa_ioc_write_qmapid mux;
1589
1590 if(rx_prop != NULL)
1591 {
1592 /* give mud ID to IPA-driver for WLAN/LAN pkts */
1593 fd = open(IPA_DEVICE_NAME, O_RDWR);
1594 if (0 == fd)
1595 {
1596 IPACMDBG_H("Failed opening %s.\n", IPA_DEVICE_NAME);
1597 return IPACM_FAILURE;
1598 }
1599
1600 mux.qmap_id = ipacm_config->GetQmapId();
1601 for(cnt=0; cnt<rx_prop->num_rx_props; cnt++)
1602 {
1603 mux.client = rx_prop->rx[cnt].src_pipe;
1604 ret = ioctl(fd, IPA_IOC_WRITE_QMAPID, &mux);
1605 if (ret)
1606 {
1607 IPACMERR("Failed to write mux id %d\n", mux.qmap_id);
1608 close(fd);
1609 return IPACM_FAILURE;
1610 }
1611 }
1612 close(fd);
1613 }
1614
1615 /* check only add static UL filter rule once */
1616 if (iptype ==IPA_IP_v6 && modem_ul_v6_set == false)
1617 {
1618 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);
1619 ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
1620 modem_ul_v6_set = true;
1621 } else if (iptype ==IPA_IP_v4 && modem_ul_v4_set == false) {
1622 IPACMDBG_H("IPA_IP_v4 xlat_mux_id: %d, modem_ul_v4_set %d\n", xlat_mux_id, modem_ul_v4_set);
1623 ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
1624 modem_ul_v4_set = true;
1625 } else {
1626 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);
1627 }
1628 return ret;
1629 }
1630
1631 /* handle ETH client initial, construct full headers (tx property) */
handle_eth_hdr_init(uint8_t * mac_addr)1632 int IPACM_Lan::handle_eth_hdr_init(uint8_t *mac_addr)
1633 {
1634
1635 #define ETH_IFACE_INDEX_LEN 2
1636
1637 int res = IPACM_SUCCESS, len = 0;
1638 char index[ETH_IFACE_INDEX_LEN];
1639 struct ipa_ioc_copy_hdr sCopyHeader;
1640 struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
1641 uint32_t cnt;
1642 int clnt_indx;
1643
1644 clnt_indx = get_eth_client_index(mac_addr);
1645
1646 if (clnt_indx != IPACM_INVALID_INDEX)
1647 {
1648 IPACMERR("eth client is found/attached already with index %d \n", clnt_indx);
1649 return IPACM_FAILURE;
1650 }
1651
1652 /* add header to IPA */
1653 if (num_eth_client >= IPA_MAX_NUM_ETH_CLIENTS)
1654 {
1655 IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_ETH_CLIENTS);
1656 return IPACM_FAILURE;
1657 }
1658
1659 IPACMDBG_H("ETH client number: %d\n", num_eth_client);
1660
1661 memcpy(get_client_memptr(eth_client, num_eth_client)->mac,
1662 mac_addr,
1663 sizeof(get_client_memptr(eth_client, num_eth_client)->mac));
1664
1665
1666 IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1667 mac_addr[0], mac_addr[1], mac_addr[2],
1668 mac_addr[3], mac_addr[4], mac_addr[5]);
1669
1670 IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1671 get_client_memptr(eth_client, num_eth_client)->mac[0],
1672 get_client_memptr(eth_client, num_eth_client)->mac[1],
1673 get_client_memptr(eth_client, num_eth_client)->mac[2],
1674 get_client_memptr(eth_client, num_eth_client)->mac[3],
1675 get_client_memptr(eth_client, num_eth_client)->mac[4],
1676 get_client_memptr(eth_client, num_eth_client)->mac[5]);
1677
1678 /* add header to IPA */
1679 if(tx_prop != NULL)
1680 {
1681 len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
1682 pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
1683 if (pHeaderDescriptor == NULL)
1684 {
1685 IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
1686 return IPACM_FAILURE;
1687 }
1688
1689 /* copy partial header for v4*/
1690 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
1691 {
1692 if(tx_prop->tx[cnt].ip==IPA_IP_v4)
1693 {
1694 IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt);
1695 memset(&sCopyHeader, 0, sizeof(sCopyHeader));
1696 memcpy(sCopyHeader.name,
1697 tx_prop->tx[cnt].hdr_name,
1698 sizeof(sCopyHeader.name));
1699
1700 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
1701 if (m_header.CopyHeader(&sCopyHeader) == false)
1702 {
1703 PERROR("ioctl copy header failed");
1704 res = IPACM_FAILURE;
1705 goto fail;
1706 }
1707
1708 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
1709 IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
1710 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
1711 {
1712 IPACMERR("header oversize\n");
1713 res = IPACM_FAILURE;
1714 goto fail;
1715 }
1716 else
1717 {
1718 memcpy(pHeaderDescriptor->hdr[0].hdr,
1719 sCopyHeader.hdr,
1720 sCopyHeader.hdr_len);
1721 }
1722
1723 /* copy client mac_addr to partial header */
1724 if (sCopyHeader.is_eth2_ofst_valid)
1725 {
1726 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
1727 mac_addr,
1728 IPA_MAC_ADDR_SIZE);
1729 }
1730 /* replace src mac to bridge mac_addr if any */
1731 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
1732 {
1733 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
1734 IPACM_Iface::ipacmcfg->bridge_mac,
1735 IPA_MAC_ADDR_SIZE);
1736 IPACMDBG_H("device is in bridge mode \n");
1737 }
1738
1739 pHeaderDescriptor->commit = true;
1740 pHeaderDescriptor->num_hdrs = 1;
1741
1742 memset(pHeaderDescriptor->hdr[0].name, 0,
1743 sizeof(pHeaderDescriptor->hdr[0].name));
1744
1745 snprintf(index,sizeof(index), "%d", ipa_if_num);
1746 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
1747 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1748 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1749 {
1750 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1751 res = IPACM_FAILURE;
1752 goto fail;
1753 }
1754
1755 snprintf(index,sizeof(index), "%d", header_name_count);
1756 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1757 {
1758 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1759 res = IPACM_FAILURE;
1760 goto fail;
1761 }
1762
1763 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
1764 pHeaderDescriptor->hdr[0].hdr_hdl = -1;
1765 pHeaderDescriptor->hdr[0].is_partial = 0;
1766 pHeaderDescriptor->hdr[0].status = -1;
1767
1768 if (m_header.AddHeader(pHeaderDescriptor) == false ||
1769 pHeaderDescriptor->hdr[0].status != 0)
1770 {
1771 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
1772 res = IPACM_FAILURE;
1773 goto fail;
1774 }
1775
1776 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
1777 IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n",
1778 num_eth_client,
1779 pHeaderDescriptor->hdr[0].name,
1780 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4);
1781 get_client_memptr(eth_client, num_eth_client)->ipv4_header_set=true;
1782
1783 break;
1784 }
1785 }
1786
1787
1788 /* copy partial header for v6*/
1789 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
1790 {
1791 if(tx_prop->tx[cnt].ip==IPA_IP_v6)
1792 {
1793
1794 IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt);
1795 memset(&sCopyHeader, 0, sizeof(sCopyHeader));
1796 memcpy(sCopyHeader.name,
1797 tx_prop->tx[cnt].hdr_name,
1798 sizeof(sCopyHeader.name));
1799
1800 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
1801 if (m_header.CopyHeader(&sCopyHeader) == false)
1802 {
1803 PERROR("ioctl copy header failed");
1804 res = IPACM_FAILURE;
1805 goto fail;
1806 }
1807
1808 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
1809 IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
1810 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
1811 {
1812 IPACMERR("header oversize\n");
1813 res = IPACM_FAILURE;
1814 goto fail;
1815 }
1816 else
1817 {
1818 memcpy(pHeaderDescriptor->hdr[0].hdr,
1819 sCopyHeader.hdr,
1820 sCopyHeader.hdr_len);
1821 }
1822
1823 /* copy client mac_addr to partial header */
1824 if (sCopyHeader.is_eth2_ofst_valid)
1825 {
1826 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
1827 mac_addr,
1828 IPA_MAC_ADDR_SIZE);
1829 }
1830 /* replace src mac to bridge mac_addr if any */
1831 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
1832 {
1833 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
1834 IPACM_Iface::ipacmcfg->bridge_mac,
1835 IPA_MAC_ADDR_SIZE);
1836 IPACMDBG_H("device is in bridge mode \n");
1837 }
1838
1839 pHeaderDescriptor->commit = true;
1840 pHeaderDescriptor->num_hdrs = 1;
1841
1842 memset(pHeaderDescriptor->hdr[0].name, 0,
1843 sizeof(pHeaderDescriptor->hdr[0].name));
1844
1845 snprintf(index,sizeof(index), "%d", ipa_if_num);
1846 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
1847 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1848 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1849 {
1850 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1851 res = IPACM_FAILURE;
1852 goto fail;
1853 }
1854 snprintf(index,sizeof(index), "%d", header_name_count);
1855 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1856 {
1857 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1858 res = IPACM_FAILURE;
1859 goto fail;
1860 }
1861
1862 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
1863 pHeaderDescriptor->hdr[0].hdr_hdl = -1;
1864 pHeaderDescriptor->hdr[0].is_partial = 0;
1865 pHeaderDescriptor->hdr[0].status = -1;
1866
1867 if (m_header.AddHeader(pHeaderDescriptor) == false ||
1868 pHeaderDescriptor->hdr[0].status != 0)
1869 {
1870 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
1871 res = IPACM_FAILURE;
1872 goto fail;
1873 }
1874
1875 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
1876 IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n",
1877 num_eth_client,
1878 pHeaderDescriptor->hdr[0].name,
1879 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6);
1880
1881 get_client_memptr(eth_client, num_eth_client)->ipv6_header_set=true;
1882
1883 break;
1884
1885 }
1886 }
1887 /* initialize wifi client*/
1888 get_client_memptr(eth_client, num_eth_client)->route_rule_set_v4 = false;
1889 get_client_memptr(eth_client, num_eth_client)->route_rule_set_v6 = 0;
1890 get_client_memptr(eth_client, num_eth_client)->ipv4_set = false;
1891 get_client_memptr(eth_client, num_eth_client)->ipv6_set = 0;
1892 num_eth_client++;
1893 header_name_count++; //keep increasing header_name_count
1894 res = IPACM_SUCCESS;
1895 IPACMDBG_H("eth client number: %d\n", num_eth_client);
1896 }
1897 else
1898 {
1899 return res;
1900 }
1901 fail:
1902 free(pHeaderDescriptor);
1903 return res;
1904 }
1905
1906 /*handle eth client */
handle_eth_client_ipaddr(ipacm_event_data_all * data)1907 int IPACM_Lan::handle_eth_client_ipaddr(ipacm_event_data_all *data)
1908 {
1909 int clnt_indx;
1910 int v6_num;
1911 uint32_t ipv6_link_local_prefix = 0xFE800000;
1912 uint32_t ipv6_link_local_prefix_mask = 0xFFC00000;
1913
1914 IPACMDBG_H("number of eth clients: %d\n", num_eth_client);
1915 IPACMDBG_H("event MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1916 data->mac_addr[0],
1917 data->mac_addr[1],
1918 data->mac_addr[2],
1919 data->mac_addr[3],
1920 data->mac_addr[4],
1921 data->mac_addr[5]);
1922
1923 clnt_indx = get_eth_client_index(data->mac_addr);
1924
1925 if (clnt_indx == IPACM_INVALID_INDEX)
1926 {
1927 IPACMERR("eth client not found/attached \n");
1928 return IPACM_FAILURE;
1929 }
1930
1931 IPACMDBG_H("Ip-type received %d\n", data->iptype);
1932 if (data->iptype == IPA_IP_v4)
1933 {
1934 IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr);
1935 if (data->ipv4_addr != 0) /* not 0.0.0.0 */
1936 {
1937 if (get_client_memptr(eth_client, clnt_indx)->ipv4_set == false)
1938 {
1939 get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr;
1940 get_client_memptr(eth_client, clnt_indx)->ipv4_set = true;
1941 }
1942 else
1943 {
1944 /* check if client got new IPv4 address*/
1945 if(data->ipv4_addr == get_client_memptr(eth_client, clnt_indx)->v4_addr)
1946 {
1947 IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx);
1948 return IPACM_FAILURE;
1949 }
1950 else
1951 {
1952 IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
1953 /* delete NAT rules first */
1954 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clnt_indx)->v4_addr);
1955 delete_eth_rtrules(clnt_indx,IPA_IP_v4);
1956 get_client_memptr(eth_client, clnt_indx)->route_rule_set_v4 = false;
1957 get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr;
1958 }
1959 }
1960 }
1961 else
1962 {
1963 IPACMDBG_H("Invalid client IPv4 address \n");
1964 return IPACM_FAILURE;
1965 }
1966 }
1967 else
1968 {
1969 if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
1970 (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) /* check if all 0 not valid ipv6 address */
1971 {
1972 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]);
1973 if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) &&
1974 memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0)
1975 {
1976 IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n");
1977 return IPACM_FAILURE;
1978 }
1979
1980 if(get_client_memptr(eth_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
1981 {
1982
1983 for(v6_num=0;v6_num < get_client_memptr(eth_client, clnt_indx)->ipv6_set;v6_num++)
1984 {
1985 if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][0] &&
1986 data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][1] &&
1987 data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][2] &&
1988 data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][3])
1989 {
1990 IPACMDBG_H("Already see this ipv6 addr at position: %d for client:%d\n", v6_num, clnt_indx);
1991 return IPACM_FAILURE; /* not setup the RT rules*/
1992 }
1993 }
1994
1995 /* not see this ipv6 before for wifi client*/
1996 get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0];
1997 get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1];
1998 get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2];
1999 get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3];
2000 get_client_memptr(eth_client, clnt_indx)->ipv6_set++;
2001 }
2002 else
2003 {
2004 IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx);
2005 return IPACM_FAILURE; /* not setup the RT rules*/
2006 }
2007 }
2008 else
2009 {
2010 IPACMDBG_H("Invalid IPV6 address\n");
2011 return IPACM_FAILURE;
2012 }
2013 }
2014
2015 return IPACM_SUCCESS;
2016 }
2017
2018 /*handle eth client routing rule*/
handle_eth_client_route_rule(uint8_t * mac_addr,ipa_ip_type iptype)2019 int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype)
2020 {
2021 struct ipa_ioc_add_rt_rule *rt_rule;
2022 struct ipa_rt_rule_add *rt_rule_entry;
2023 uint32_t tx_index;
2024 int eth_index,v6_num;
2025 const int NUM = 1;
2026
2027 if(tx_prop == NULL)
2028 {
2029 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
2030 return IPACM_SUCCESS;
2031 }
2032
2033 IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
2034 mac_addr[0], mac_addr[1], mac_addr[2],
2035 mac_addr[3], mac_addr[4], mac_addr[5]);
2036
2037 eth_index = get_eth_client_index(mac_addr);
2038 if (eth_index == IPACM_INVALID_INDEX)
2039 {
2040 IPACMDBG_H("eth client not found/attached \n");
2041 return IPACM_SUCCESS;
2042 }
2043
2044 if (iptype==IPA_IP_v4) {
2045 IPACMDBG_H("eth client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", eth_index, iptype,
2046 get_client_memptr(eth_client, eth_index)->ipv4_set,
2047 get_client_memptr(eth_client, eth_index)->route_rule_set_v4);
2048 } else {
2049 IPACMDBG_H("eth client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", eth_index, iptype,
2050 get_client_memptr(eth_client, eth_index)->ipv6_set,
2051 get_client_memptr(eth_client, eth_index)->route_rule_set_v6);
2052 }
2053 /* Add default routing rules if not set yet */
2054 if ((iptype == IPA_IP_v4
2055 && get_client_memptr(eth_client, eth_index)->route_rule_set_v4 == false
2056 && get_client_memptr(eth_client, eth_index)->ipv4_set == true)
2057 || (iptype == IPA_IP_v6
2058 && get_client_memptr(eth_client, eth_index)->route_rule_set_v6 < get_client_memptr(eth_client, eth_index)->ipv6_set
2059 ))
2060 {
2061
2062 /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
2063 IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2064 if (tx_prop != NULL)
2065 {
2066 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]);
2067 IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
2068 }
2069 rt_rule = (struct ipa_ioc_add_rt_rule *)
2070 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
2071 NUM * sizeof(struct ipa_rt_rule_add));
2072
2073 if (rt_rule == NULL)
2074 {
2075 PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n");
2076 return IPACM_FAILURE;
2077 }
2078
2079 rt_rule->commit = 1;
2080 rt_rule->num_rules = (uint8_t)NUM;
2081 rt_rule->ip = iptype;
2082
2083 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2084 {
2085 if(iptype != tx_prop->tx[tx_index].ip)
2086 {
2087 IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n",
2088 tx_index, tx_prop->tx[tx_index].ip,iptype);
2089 continue;
2090 }
2091
2092 rt_rule_entry = &rt_rule->rules[0];
2093 rt_rule_entry->at_rear = 0;
2094
2095 if (iptype == IPA_IP_v4)
2096 {
2097 IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", eth_index,
2098 get_client_memptr(eth_client, eth_index)->v4_addr);
2099
2100 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
2101 eth_index,
2102 get_client_memptr(eth_client, eth_index)->hdr_hdl_v4);
2103 strlcpy(rt_rule->rt_tbl_name,
2104 IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name,
2105 sizeof(rt_rule->rt_tbl_name));
2106 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2107 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2108 memcpy(&rt_rule_entry->rule.attrib,
2109 &tx_prop->tx[tx_index].attrib,
2110 sizeof(rt_rule_entry->rule.attrib));
2111 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2112 rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v4;
2113 rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr;
2114 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
2115 #ifdef FEATURE_IPA_V3
2116 rt_rule_entry->rule.hashable = false;
2117 #endif
2118 if (false == m_routing.AddRoutingRule(rt_rule))
2119 {
2120 IPACMERR("Routing rule addition failed!\n");
2121 free(rt_rule);
2122 return IPACM_FAILURE;
2123 }
2124
2125 /* copy ipv4 RT hdl */
2126 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 =
2127 rt_rule->rules[0].rt_rule_hdl;
2128 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2129 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4, iptype);
2130
2131 } else {
2132
2133 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++)
2134 {
2135 IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
2136 eth_index,
2137 get_client_memptr(eth_client, eth_index)->hdr_hdl_v6);
2138
2139 /* v6 LAN_RT_TBL */
2140 strlcpy(rt_rule->rt_tbl_name,
2141 IPACM_Iface::ipacmcfg->rt_tbl_v6.name,
2142 sizeof(rt_rule->rt_tbl_name));
2143 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2144 /* Support QCMAP LAN traffic feature, send to A5 */
2145 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
2146 memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib));
2147 rt_rule_entry->rule.hdr_hdl = 0;
2148 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2149 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0];
2150 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1];
2151 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2];
2152 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3];
2153 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2154 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2155 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2156 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2157 #ifdef FEATURE_IPA_V3
2158 rt_rule_entry->rule.hashable = true;
2159 #endif
2160 if (false == m_routing.AddRoutingRule(rt_rule))
2161 {
2162 IPACMERR("Routing rule addition failed!\n");
2163 free(rt_rule);
2164 return IPACM_FAILURE;
2165 }
2166
2167 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;
2168 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2169 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[v6_num], iptype);
2170
2171 /*Copy same rule to v6 WAN RT TBL*/
2172 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
2173 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
2174 /* Downlink traffic from Wan iface, directly through IPA */
2175 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2176 memcpy(&rt_rule_entry->rule.attrib,
2177 &tx_prop->tx[tx_index].attrib,
2178 sizeof(rt_rule_entry->rule.attrib));
2179 rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v6;
2180 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2181 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0];
2182 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1];
2183 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2];
2184 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3];
2185 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2186 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2187 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2188 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2189 #ifdef FEATURE_IPA_V3
2190 rt_rule_entry->rule.hashable = true;
2191 #endif
2192 if (false == m_routing.AddRoutingRule(rt_rule))
2193 {
2194 IPACMERR("Routing rule addition failed!\n");
2195 free(rt_rule);
2196 return IPACM_FAILURE;
2197 }
2198
2199 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;
2200 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2201 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num], iptype);
2202 }
2203 }
2204
2205 } /* end of for loop */
2206
2207 free(rt_rule);
2208
2209 if (iptype == IPA_IP_v4)
2210 {
2211 get_client_memptr(eth_client, eth_index)->route_rule_set_v4 = true;
2212 }
2213 else
2214 {
2215 get_client_memptr(eth_client, eth_index)->route_rule_set_v6 = get_client_memptr(eth_client, eth_index)->ipv6_set;
2216 }
2217 }
2218 return IPACM_SUCCESS;
2219 }
2220
2221 /* handle odu client initial, construct full headers (tx property) */
handle_odu_hdr_init(uint8_t * mac_addr)2222 int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr)
2223 {
2224 int res = IPACM_SUCCESS, len = 0;
2225 struct ipa_ioc_copy_hdr sCopyHeader;
2226 struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
2227 uint32_t cnt;
2228
2229 IPACMDBG("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
2230 mac_addr[0], mac_addr[1], mac_addr[2],
2231 mac_addr[3], mac_addr[4], mac_addr[5]);
2232
2233 /* add header to IPA */
2234 if(tx_prop != NULL)
2235 {
2236 len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
2237 pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
2238 if (pHeaderDescriptor == NULL)
2239 {
2240 IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
2241 return IPACM_FAILURE;
2242 }
2243
2244 /* copy partial header for v4*/
2245 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
2246 {
2247 if(tx_prop->tx[cnt].ip==IPA_IP_v4)
2248 {
2249 IPACMDBG("Got partial v4-header name from %d tx props\n", cnt);
2250 memset(&sCopyHeader, 0, sizeof(sCopyHeader));
2251 memcpy(sCopyHeader.name,
2252 tx_prop->tx[cnt].hdr_name,
2253 sizeof(sCopyHeader.name));
2254 IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
2255 if (m_header.CopyHeader(&sCopyHeader) == false)
2256 {
2257 PERROR("ioctl copy header failed");
2258 res = IPACM_FAILURE;
2259 goto fail;
2260 }
2261 IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
2262 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
2263 {
2264 IPACMERR("header oversize\n");
2265 res = IPACM_FAILURE;
2266 goto fail;
2267 }
2268 else
2269 {
2270 memcpy(pHeaderDescriptor->hdr[0].hdr,
2271 sCopyHeader.hdr,
2272 sCopyHeader.hdr_len);
2273 }
2274 /* copy client mac_addr to partial header */
2275 if (sCopyHeader.is_eth2_ofst_valid)
2276 {
2277 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
2278 mac_addr,
2279 IPA_MAC_ADDR_SIZE);
2280 }
2281 /* replace src mac to bridge mac_addr if any */
2282 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
2283 {
2284 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
2285 IPACM_Iface::ipacmcfg->bridge_mac,
2286 IPA_MAC_ADDR_SIZE);
2287 IPACMDBG_H("device is in bridge mode \n");
2288 }
2289
2290 pHeaderDescriptor->commit = true;
2291 pHeaderDescriptor->num_hdrs = 1;
2292
2293 memset(pHeaderDescriptor->hdr[0].name, 0,
2294 sizeof(pHeaderDescriptor->hdr[0].name));
2295 strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name));
2296 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
2297 pHeaderDescriptor->hdr[0].hdr_hdl = -1;
2298 pHeaderDescriptor->hdr[0].is_partial = 0;
2299 pHeaderDescriptor->hdr[0].status = -1;
2300
2301 if (m_header.AddHeader(pHeaderDescriptor) == false ||
2302 pHeaderDescriptor->hdr[0].status != 0)
2303 {
2304 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
2305 res = IPACM_FAILURE;
2306 goto fail;
2307 }
2308
2309 ODU_hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
2310 ipv4_header_set = true ;
2311 IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n",
2312 pHeaderDescriptor->hdr[0].name,
2313 ODU_hdr_hdl_v4);
2314 break;
2315 }
2316 }
2317
2318
2319 /* copy partial header for v6*/
2320 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
2321 {
2322 if(tx_prop->tx[cnt].ip==IPA_IP_v6)
2323 {
2324
2325 IPACMDBG("Got partial v6-header name from %d tx props\n", cnt);
2326 memset(&sCopyHeader, 0, sizeof(sCopyHeader));
2327 memcpy(sCopyHeader.name,
2328 tx_prop->tx[cnt].hdr_name,
2329 sizeof(sCopyHeader.name));
2330
2331 IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
2332 if (m_header.CopyHeader(&sCopyHeader) == false)
2333 {
2334 PERROR("ioctl copy header failed");
2335 res = IPACM_FAILURE;
2336 goto fail;
2337 }
2338
2339 IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
2340 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
2341 {
2342 IPACMERR("header oversize\n");
2343 res = IPACM_FAILURE;
2344 goto fail;
2345 }
2346 else
2347 {
2348 memcpy(pHeaderDescriptor->hdr[0].hdr,
2349 sCopyHeader.hdr,
2350 sCopyHeader.hdr_len);
2351 }
2352
2353 /* copy client mac_addr to partial header */
2354 if (sCopyHeader.is_eth2_ofst_valid)
2355 {
2356 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
2357 mac_addr,
2358 IPA_MAC_ADDR_SIZE);
2359 }
2360 /* replace src mac to bridge mac_addr if any */
2361 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
2362 {
2363 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
2364 IPACM_Iface::ipacmcfg->bridge_mac,
2365 IPA_MAC_ADDR_SIZE);
2366 IPACMDBG_H("device is in bridge mode \n");
2367 }
2368
2369 pHeaderDescriptor->commit = true;
2370 pHeaderDescriptor->num_hdrs = 1;
2371
2372 memset(pHeaderDescriptor->hdr[0].name, 0,
2373 sizeof(pHeaderDescriptor->hdr[0].name));
2374
2375 strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name));
2376 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
2377 pHeaderDescriptor->hdr[0].hdr_hdl = -1;
2378 pHeaderDescriptor->hdr[0].is_partial = 0;
2379 pHeaderDescriptor->hdr[0].status = -1;
2380
2381 if (m_header.AddHeader(pHeaderDescriptor) == false ||
2382 pHeaderDescriptor->hdr[0].status != 0)
2383 {
2384 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
2385 res = IPACM_FAILURE;
2386 goto fail;
2387 }
2388
2389 ODU_hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
2390 ipv6_header_set = true ;
2391 IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n",
2392 pHeaderDescriptor->hdr[0].name,
2393 ODU_hdr_hdl_v6);
2394 break;
2395 }
2396 }
2397 }
2398 fail:
2399 free(pHeaderDescriptor);
2400 return res;
2401 }
2402
2403
2404 /* handle odu default route rule configuration */
handle_odu_route_add()2405 int IPACM_Lan::handle_odu_route_add()
2406 {
2407 /* add default WAN route */
2408 struct ipa_ioc_add_rt_rule *rt_rule;
2409 struct ipa_rt_rule_add *rt_rule_entry;
2410 uint32_t tx_index;
2411 const int NUM = 1;
2412
2413 if(tx_prop == NULL)
2414 {
2415 IPACMDBG_H("No tx properties, ignore default route setting\n");
2416 return IPACM_SUCCESS;
2417 }
2418
2419 rt_rule = (struct ipa_ioc_add_rt_rule *)
2420 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
2421 NUM * sizeof(struct ipa_rt_rule_add));
2422
2423 if (!rt_rule)
2424 {
2425 IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
2426 return IPACM_FAILURE;
2427 }
2428
2429 rt_rule->commit = 1;
2430 rt_rule->num_rules = (uint8_t)NUM;
2431
2432
2433 IPACMDBG_H("WAN table created %s \n", rt_rule->rt_tbl_name);
2434 rt_rule_entry = &rt_rule->rules[0];
2435 rt_rule_entry->at_rear = true;
2436
2437 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2438 {
2439
2440 if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
2441 {
2442 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, sizeof(rt_rule->rt_tbl_name));
2443 rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4;
2444 rt_rule->ip = IPA_IP_v4;
2445 }
2446 else
2447 {
2448 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, sizeof(rt_rule->rt_tbl_name));
2449 rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6;
2450 rt_rule->ip = IPA_IP_v6;
2451 }
2452
2453 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2454 memcpy(&rt_rule_entry->rule.attrib,
2455 &tx_prop->tx[tx_index].attrib,
2456 sizeof(rt_rule_entry->rule.attrib));
2457
2458 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2459 if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
2460 {
2461 rt_rule_entry->rule.attrib.u.v4.dst_addr = 0;
2462 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0;
2463 #ifdef FEATURE_IPA_V3
2464 rt_rule_entry->rule.hashable = true;
2465 #endif
2466 if (false == m_routing.AddRoutingRule(rt_rule))
2467 {
2468 IPACMERR("Routing rule addition failed!\n");
2469 free(rt_rule);
2470 return IPACM_FAILURE;
2471 }
2472 odu_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
2473 IPACMDBG_H("Got ipv4 ODU-route rule hdl:0x%x,tx:%d,ip-type: %d \n",
2474 odu_route_rule_v4_hdl[tx_index],
2475 tx_index,
2476 IPA_IP_v4);
2477 }
2478 else
2479 {
2480 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0;
2481 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0;
2482 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0;
2483 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0;
2484 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0;
2485 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0;
2486 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0;
2487 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0;
2488 #ifdef FEATURE_IPA_V3
2489 rt_rule_entry->rule.hashable = true;
2490 #endif
2491 if (false == m_routing.AddRoutingRule(rt_rule))
2492 {
2493 IPACMERR("Routing rule addition failed!\n");
2494 free(rt_rule);
2495 return IPACM_FAILURE;
2496 }
2497 odu_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
2498 IPACMDBG_H("Set ipv6 ODU-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n",
2499 odu_route_rule_v6_hdl[tx_index],
2500 tx_index,
2501 IPA_IP_v6);
2502 }
2503 }
2504 free(rt_rule);
2505 return IPACM_SUCCESS;
2506 }
2507
2508 /* handle odu default route rule deletion */
handle_odu_route_del()2509 int IPACM_Lan::handle_odu_route_del()
2510 {
2511 uint32_t tx_index;
2512
2513 if(tx_prop == NULL)
2514 {
2515 IPACMDBG_H("No tx properties, ignore delete default route setting\n");
2516 return IPACM_SUCCESS;
2517 }
2518
2519 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2520 {
2521 if (tx_prop->tx[tx_index].ip == IPA_IP_v4)
2522 {
2523 IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
2524 tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v4);
2525
2526 if (m_routing.DeleteRoutingHdl(odu_route_rule_v4_hdl[tx_index], IPA_IP_v4)
2527 == false)
2528 {
2529 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);
2530 return IPACM_FAILURE;
2531 }
2532 }
2533 else
2534 {
2535 IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
2536 tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v6);
2537
2538 if (m_routing.DeleteRoutingHdl(odu_route_rule_v6_hdl[tx_index], IPA_IP_v6)
2539 == false)
2540 {
2541 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);
2542 return IPACM_FAILURE;
2543 }
2544 }
2545 }
2546
2547 return IPACM_SUCCESS;
2548 }
2549
2550 /*handle eth client del mode*/
handle_eth_client_down_evt(uint8_t * mac_addr)2551 int IPACM_Lan::handle_eth_client_down_evt(uint8_t *mac_addr)
2552 {
2553 int clt_indx;
2554 uint32_t tx_index;
2555 int num_eth_client_tmp = num_eth_client;
2556 int num_v6;
2557
2558 IPACMDBG_H("total client: %d\n", num_eth_client_tmp);
2559
2560 clt_indx = get_eth_client_index(mac_addr);
2561 if (clt_indx == IPACM_INVALID_INDEX)
2562 {
2563 IPACMDBG_H("eth client not attached\n");
2564 return IPACM_SUCCESS;
2565 }
2566
2567 /* First reset nat rules and then route rules */
2568 if(get_client_memptr(eth_client, clt_indx)->ipv4_set == true)
2569 {
2570 IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, clt_indx)->v4_addr);
2571 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clt_indx)->v4_addr);
2572 }
2573
2574 if (delete_eth_rtrules(clt_indx, IPA_IP_v4))
2575 {
2576 IPACMERR("unbale to delete ecm-client v4 route rules for index: %d\n", clt_indx);
2577 return IPACM_FAILURE;
2578 }
2579
2580 if (delete_eth_rtrules(clt_indx, IPA_IP_v6))
2581 {
2582 IPACMERR("unbale to delete ecm-client v6 route rules for index: %d\n", clt_indx);
2583 return IPACM_FAILURE;
2584 }
2585
2586 /* Delete eth client header */
2587 if(get_client_memptr(eth_client, clt_indx)->ipv4_header_set == true)
2588 {
2589 if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4)
2590 == false)
2591 {
2592 return IPACM_FAILURE;
2593 }
2594 get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false;
2595 }
2596
2597 if(get_client_memptr(eth_client, clt_indx)->ipv6_header_set == true)
2598 {
2599 if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6)
2600 == false)
2601 {
2602 return IPACM_FAILURE;
2603 }
2604 get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false;
2605 }
2606
2607 /* Reset ip_set to 0*/
2608 get_client_memptr(eth_client, clt_indx)->ipv4_set = false;
2609 get_client_memptr(eth_client, clt_indx)->ipv6_set = 0;
2610 get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false;
2611 get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false;
2612 get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = false;
2613 get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = 0;
2614
2615 for (; clt_indx < num_eth_client_tmp - 1; clt_indx++)
2616 {
2617 memcpy(get_client_memptr(eth_client, clt_indx)->mac,
2618 get_client_memptr(eth_client, (clt_indx + 1))->mac,
2619 sizeof(get_client_memptr(eth_client, clt_indx)->mac));
2620
2621 get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v4;
2622 get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v6;
2623 get_client_memptr(eth_client, clt_indx)->v4_addr = get_client_memptr(eth_client, (clt_indx + 1))->v4_addr;
2624
2625 get_client_memptr(eth_client, clt_indx)->ipv4_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_set;
2626 get_client_memptr(eth_client, clt_indx)->ipv6_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_set;
2627 get_client_memptr(eth_client, clt_indx)->ipv4_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_header_set;
2628 get_client_memptr(eth_client, clt_indx)->ipv6_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_header_set;
2629
2630 get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v4;
2631 get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v6;
2632
2633 for (num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->ipv6_set;num_v6++)
2634 {
2635 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];
2636 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];
2637 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];
2638 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];
2639 }
2640
2641 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2642 {
2643 get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 =
2644 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4;
2645
2646 for(num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->route_rule_set_v6;num_v6++)
2647 {
2648 get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6] =
2649 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6];
2650 get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6] =
2651 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6];
2652 }
2653 }
2654 }
2655
2656 IPACMDBG_H(" %d eth client deleted successfully \n", num_eth_client);
2657 num_eth_client = num_eth_client - 1;
2658 IPACMDBG_H(" Number of eth client: %d\n", num_eth_client);
2659
2660 /* Del RM dependency */
2661 if(num_eth_client == 0)
2662 {
2663 /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule*/
2664 IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2665 if (tx_prop != NULL)
2666 {
2667 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]);
2668 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
2669 }
2670 }
2671
2672 return IPACM_SUCCESS;
2673 }
2674
2675 /*handle LAN iface down event*/
handle_down_evt()2676 int IPACM_Lan::handle_down_evt()
2677 {
2678 uint32_t i;
2679 int res = IPACM_SUCCESS;
2680
2681 IPACMDBG_H("lan handle_down_evt\n ");
2682 if (ipa_if_cate == ODU_IF)
2683 {
2684 /* delete ODU default RT rules */
2685 if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true)
2686 {
2687 IPACMDBG_H("eMBMS enable, delete eMBMS DL RT rule\n");
2688 handle_odu_route_del();
2689 }
2690
2691 /* delete full header */
2692 if (ipv4_header_set)
2693 {
2694 if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v4)
2695 == false)
2696 {
2697 IPACMERR("ODU ipv4 header delete fail\n");
2698 res = IPACM_FAILURE;
2699 goto fail;
2700 }
2701 IPACMDBG_H("ODU ipv4 header delete success\n");
2702 }
2703
2704 if (ipv6_header_set)
2705 {
2706 if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v6)
2707 == false)
2708 {
2709 IPACMERR("ODU ipv6 header delete fail\n");
2710 res = IPACM_FAILURE;
2711 goto fail;
2712 }
2713 IPACMERR("ODU ipv6 header delete success\n");
2714 }
2715 }
2716
2717 /* no iface address up, directly close iface*/
2718 if (ip_type == IPACM_IP_NULL)
2719 {
2720 goto fail;
2721 }
2722
2723 /* delete wan filter rule */
2724 if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
2725 {
2726 IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
2727 handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
2728 }
2729
2730 if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
2731 {
2732 IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
2733 handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode);
2734 }
2735
2736 /* delete default filter rules */
2737 if (ip_type != IPA_IP_v6 && rx_prop != NULL)
2738 {
2739 if(m_filtering.DeleteFilteringHdls(ipv4_icmp_flt_rule_hdl, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE) == false)
2740 {
2741 IPACMERR("Error Deleting ICMPv4 Filtering Rule, aborting...\n");
2742 res = IPACM_FAILURE;
2743 goto fail;
2744 }
2745 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE);
2746
2747 if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false)
2748 {
2749 IPACMERR("Error Deleting Filtering Rule, aborting...\n");
2750 res = IPACM_FAILURE;
2751 goto fail;
2752 }
2753 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
2754
2755 /* free private-subnet ipv4 filter rules */
2756 if (IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_PRIV_SUBNET_FILTER_RULE_HANDLES)
2757 {
2758 IPACMERR(" the number of rules are bigger than array, aborting...\n");
2759 res = IPACM_FAILURE;
2760 goto fail;
2761 }
2762
2763 #ifdef FEATURE_IPA_ANDROID
2764 if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES) == false)
2765 {
2766 IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
2767 res = IPACM_FAILURE;
2768 goto fail;
2769 }
2770 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES);
2771 #else
2772 if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false)
2773 {
2774 IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
2775 res = IPACM_FAILURE;
2776 goto fail;
2777 }
2778 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
2779 #endif
2780 IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n");
2781 }
2782 IPACMDBG_H("Finished delete default iface ipv4 filtering rules \n ");
2783
2784 if (ip_type != IPA_IP_v4 && rx_prop != NULL)
2785 {
2786 if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false)
2787 {
2788 IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n");
2789 res = IPACM_FAILURE;
2790 goto fail;
2791 }
2792 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE);
2793
2794 if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false)
2795 {
2796 IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
2797 res = IPACM_FAILURE;
2798 goto fail;
2799 }
2800 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
2801 }
2802 IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n ");
2803
2804 if (ip_type != IPA_IP_v6)
2805 {
2806 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4)
2807 == false)
2808 {
2809 IPACMERR("Routing rule deletion failed!\n");
2810 res = IPACM_FAILURE;
2811 goto fail;
2812 }
2813 }
2814 IPACMDBG_H("Finished delete default iface ipv4 rules \n ");
2815
2816 /* delete default v6 routing rule */
2817 if (ip_type != IPA_IP_v4)
2818 {
2819 /* may have multiple ipv6 iface-RT rules*/
2820 for (i = 0; i < 2*num_dft_rt_v6; i++)
2821 {
2822 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + i], IPA_IP_v6)
2823 == false)
2824 {
2825 IPACMERR("Routing rule deletion failed!\n");
2826 res = IPACM_FAILURE;
2827 goto fail;
2828 }
2829 }
2830 }
2831
2832 IPACMDBG_H("Finished delete default iface ipv6 rules \n ");
2833
2834 /* free the edm clients cache */
2835 IPACMDBG_H("Free ecm clients cache\n");
2836
2837 /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule */
2838 IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
2839 if (tx_prop != NULL)
2840 {
2841 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]);
2842 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
2843 }
2844
2845 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL);
2846
2847 /* Delete private subnet*/
2848 #ifdef FEATURE_IPA_ANDROID
2849 if (ip_type != IPA_IP_v6)
2850 {
2851 IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
2852 IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
2853 if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
2854 {
2855 IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
2856 }
2857 }
2858
2859 /* reset the IPA-client pipe enum */
2860 if(ipa_if_cate != WAN_IF)
2861 {
2862 #ifdef FEATURE_IPACM_HAL
2863 handle_tethering_client(true, IPACM_CLIENT_MAX);
2864 #else
2865 handle_tethering_client(true, IPACM_CLIENT_USB);
2866 #endif
2867 }
2868 #endif /* defined(FEATURE_IPA_ANDROID)*/
2869 fail:
2870 /* clean eth-client header, routing rules */
2871 IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
2872 for (i = 0; i < num_eth_client; i++)
2873 {
2874 /* First reset nat rules and then route rules */
2875 if(get_client_memptr(eth_client, i)->ipv4_set == true)
2876 {
2877 IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr);
2878 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr);
2879 }
2880
2881 if (delete_eth_rtrules(i, IPA_IP_v4))
2882 {
2883 IPACMERR("unbale to delete ecm-client v4 route rules for index %d\n", i);
2884 res = IPACM_FAILURE;
2885 }
2886
2887 if (delete_eth_rtrules(i, IPA_IP_v6))
2888 {
2889 IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
2890 res = IPACM_FAILURE;
2891 }
2892
2893 IPACMDBG_H("Delete %d client header\n", num_eth_client);
2894
2895 if(get_client_memptr(eth_client, i)->ipv4_header_set == true)
2896 {
2897 if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v4)
2898 == false)
2899 {
2900 res = IPACM_FAILURE;
2901 }
2902 }
2903
2904 if(get_client_memptr(eth_client, i)->ipv6_header_set == true)
2905 {
2906 if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v6)
2907 == false)
2908 {
2909 res = IPACM_FAILURE;
2910 }
2911 }
2912 } /* end of for loop */
2913
2914 /* check software routing fl rule hdl */
2915 if (softwarerouting_act == true && rx_prop != NULL)
2916 {
2917 handle_software_routing_disable();
2918 }
2919
2920 if (odu_route_rule_v4_hdl != NULL)
2921 {
2922 free(odu_route_rule_v4_hdl);
2923 }
2924 if (odu_route_rule_v6_hdl != NULL)
2925 {
2926 free(odu_route_rule_v6_hdl);
2927 }
2928 /* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
2929 if (rx_prop != NULL)
2930 {
2931 IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2932 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]);
2933 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
2934 IPACMDBG_H("Finished delete dependency \n ");
2935 free(rx_prop);
2936 }
2937
2938 if (eth_client != NULL)
2939 {
2940 free(eth_client);
2941 }
2942
2943 if (tx_prop != NULL)
2944 {
2945 free(tx_prop);
2946 }
2947 if (iface_query != NULL)
2948 {
2949 free(iface_query);
2950 }
2951
2952 is_active = false;
2953 post_del_self_evt();
2954
2955 return res;
2956 }
2957
2958 /* install UL filter rule from Q6 */
handle_uplink_filter_rule(ipacm_ext_prop * prop,ipa_ip_type iptype,uint8_t xlat_mux_id)2959 int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptype, uint8_t xlat_mux_id)
2960 {
2961 ipa_flt_rule_add flt_rule_entry;
2962 int len = 0, cnt, ret = IPACM_SUCCESS;
2963 ipa_ioc_add_flt_rule *pFilteringTable;
2964 ipa_fltr_installed_notif_req_msg_v01 flt_index;
2965 int fd;
2966 int i, index, eq_index;
2967 uint32_t value = 0;
2968
2969 IPACMDBG_H("Set modem UL flt rules\n");
2970
2971 if (rx_prop == NULL)
2972 {
2973 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
2974 return IPACM_SUCCESS;
2975 }
2976
2977 if(prop == NULL || prop->num_ext_props <= 0)
2978 {
2979 IPACMDBG_H("No extended property.\n");
2980 return IPACM_SUCCESS;
2981 }
2982
2983 fd = open(IPA_DEVICE_NAME, O_RDWR);
2984 if (0 == fd)
2985 {
2986 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
2987 return IPACM_FAILURE;
2988 }
2989 if (prop->num_ext_props > MAX_WAN_UL_FILTER_RULES)
2990 {
2991 IPACMERR("number of modem UL rules > MAX_WAN_UL_FILTER_RULES, aborting...\n");
2992 close(fd);
2993 return IPACM_FAILURE;
2994 }
2995
2996 memset(&flt_index, 0, sizeof(flt_index));
2997 flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe);
2998 flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01;
2999 #ifndef FEATURE_IPA_V3
3000 flt_index.filter_index_list_len = prop->num_ext_props;
3001 #else /* defined (FEATURE_IPA_V3) */
3002 flt_index.rule_id_valid = 1;
3003 flt_index.rule_id_len = prop->num_ext_props;
3004 #endif
3005 flt_index.embedded_pipe_index_valid = 1;
3006 flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD);
3007 flt_index.retain_header_valid = 1;
3008 flt_index.retain_header = 0;
3009 flt_index.embedded_call_mux_id_valid = 1;
3010 flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
3011 #ifndef FEATURE_IPA_V3
3012 IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n",
3013 flt_index.source_pipe_index, flt_index.filter_index_list_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id);
3014 #else /* defined (FEATURE_IPA_V3) */
3015 IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n",
3016 flt_index.source_pipe_index, flt_index.rule_id_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id);
3017 #endif
3018 len = sizeof(struct ipa_ioc_add_flt_rule) + prop->num_ext_props * sizeof(struct ipa_flt_rule_add);
3019 pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
3020 if (pFilteringTable == NULL)
3021 {
3022 IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3023 close(fd);
3024 return IPACM_FAILURE;
3025 }
3026 memset(pFilteringTable, 0, len);
3027
3028 pFilteringTable->commit = 1;
3029 pFilteringTable->ep = rx_prop->rx[0].src_pipe;
3030 pFilteringTable->global = false;
3031 pFilteringTable->ip = iptype;
3032 pFilteringTable->num_rules = prop->num_ext_props;
3033
3034 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields
3035 flt_rule_entry.at_rear = 1;
3036 #ifdef FEATURE_IPA_V3
3037 if (flt_rule_entry.rule.eq_attrib.ipv4_frag_eq_present)
3038 flt_rule_entry.at_rear = 0;
3039 #endif
3040 flt_rule_entry.flt_rule_hdl = -1;
3041 flt_rule_entry.status = -1;
3042
3043 flt_rule_entry.rule.retain_hdr = 0;
3044 flt_rule_entry.rule.to_uc = 0;
3045 flt_rule_entry.rule.eq_attrib_type = 1;
3046 if(iptype == IPA_IP_v4)
3047 {
3048 if (ipa_if_cate == ODU_IF && IPACM_Wan::isWan_Bridge_Mode())
3049 {
3050 IPACMDBG_H("WAN, ODU are in bridge mode \n");
3051 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3052 }
3053 else
3054 {
3055 flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
3056 }
3057 }
3058 else if(iptype == IPA_IP_v6)
3059 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3060 else
3061 {
3062 IPACMERR("IP type is not expected.\n");
3063 ret = IPACM_FAILURE;
3064 goto fail;
3065 }
3066
3067 index = IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, iptype);
3068
3069 for(cnt=0; cnt<prop->num_ext_props; cnt++)
3070 {
3071 memcpy(&flt_rule_entry.rule.eq_attrib,
3072 &prop->prop[cnt].eq_attrib,
3073 sizeof(prop->prop[cnt].eq_attrib));
3074 flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx;
3075
3076 /* Handle XLAT configuration */
3077 if ((iptype == IPA_IP_v4) && prop->prop[cnt].is_xlat_rule && (xlat_mux_id != 0))
3078 {
3079 /* fill the value of meta-data */
3080 value = xlat_mux_id;
3081 flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
3082 flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
3083 flt_rule_entry.rule.eq_attrib.metadata_meq32.value = (value & 0xFF) << 16;
3084 flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = 0x00FF0000;
3085 IPACMDBG_H("xlat meta-data is modified for rule: %d has index %d with xlat_mux_id: %d\n",
3086 cnt, index, xlat_mux_id);
3087 }
3088
3089 #ifdef FEATURE_IPACM_HAL
3090 /* add prefix equation in modem UL rules */
3091 if(iptype == IPA_IP_v4)
3092 {
3093 flt_rule_entry.rule.eq_attrib.num_offset_meq_32++;
3094 if(flt_rule_entry.rule.eq_attrib.num_offset_meq_32 <= IPA_IPFLTR_NUM_MEQ_32_EQNS)
3095 {
3096 eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_32 - 1;
3097 #ifdef FEATURE_IPA_V3
3098 if(eq_index == 0)
3099 {
3100 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<5);
3101 }
3102 else
3103 {
3104 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<6);
3105 }
3106 #else
3107 if(eq_index == 0)
3108 {
3109 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<2);
3110 }
3111 else
3112 {
3113 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3);
3114 }
3115 #endif
3116 flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].offset = 12;
3117 flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].mask = prefix[IPA_IP_v4].v4Mask;
3118 flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].value = prefix[IPA_IP_v4].v4Addr;
3119 }
3120 else
3121 {
3122 IPACMERR("Run out of MEQ32 equation.\n");
3123 flt_rule_entry.rule.eq_attrib.num_offset_meq_32--;
3124 }
3125 }
3126 else
3127 {
3128 flt_rule_entry.rule.eq_attrib.num_offset_meq_128++;
3129 if(flt_rule_entry.rule.eq_attrib.num_offset_meq_128 <= IPA_IPFLTR_NUM_MEQ_128_EQNS)
3130 {
3131 eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_128 - 1;
3132 #ifdef FEATURE_IPA_V3
3133 if(eq_index == 0)
3134 {
3135 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3);
3136 }
3137 else
3138 {
3139 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<4);
3140 }
3141 #else
3142 if(eq_index == 0)
3143 {
3144 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9);
3145 }
3146 else
3147 {
3148 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<10);
3149 }
3150 #endif
3151 flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].offset = 8;
3152 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 0)
3153 = prefix[IPA_IP_v6].v6Mask[3];
3154 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 4)
3155 = prefix[IPA_IP_v6].v6Mask[2];
3156 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 8)
3157 = prefix[IPA_IP_v6].v6Mask[1];
3158 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 12)
3159 = prefix[IPA_IP_v6].v6Mask[0];
3160 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 0)
3161 = prefix[IPA_IP_v6].v6Addr[3];
3162 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 4)
3163 = prefix[IPA_IP_v6].v6Addr[2];
3164 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 8)
3165 = prefix[IPA_IP_v6].v6Addr[1];
3166 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 12)
3167 = prefix[IPA_IP_v6].v6Addr[0];
3168 }
3169 else
3170 {
3171 IPACMERR("Run out of MEQ128 equation.\n");
3172 flt_rule_entry.rule.eq_attrib.num_offset_meq_128--;
3173 }
3174 }
3175 #endif
3176
3177 #ifdef FEATURE_IPA_V3
3178 flt_rule_entry.rule.hashable = prop->prop[cnt].is_rule_hashable;
3179 flt_rule_entry.rule.rule_id = prop->prop[cnt].rule_id;
3180 if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA) //turn on meta-data equation
3181 {
3182 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9);
3183 flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
3184 flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
3185 flt_rule_entry.rule.eq_attrib.metadata_meq32.value |= rx_prop->rx[0].attrib.meta_data;
3186 flt_rule_entry.rule.eq_attrib.metadata_meq32.mask |= rx_prop->rx[0].attrib.meta_data_mask;
3187 }
3188 #endif
3189 memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry));
3190
3191 IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, index);
3192 #ifndef FEATURE_IPA_V3
3193 flt_index.filter_index_list[cnt].filter_index = index;
3194 flt_index.filter_index_list[cnt].filter_handle = prop->prop[cnt].filter_hdl;
3195 #else /* defined (FEATURE_IPA_V3) */
3196 flt_index.rule_id[cnt] = prop->prop[cnt].rule_id;
3197 #endif
3198 index++;
3199 }
3200
3201 if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
3202 {
3203 IPACMERR("Error sending filtering rule index, aborting...\n");
3204 ret = IPACM_FAILURE;
3205 goto fail;
3206 }
3207
3208 if(false == m_filtering.AddFilteringRule(pFilteringTable))
3209 {
3210 IPACMERR("Error Adding RuleTable to Filtering, aborting...\n");
3211 ret = IPACM_FAILURE;
3212 goto fail;
3213 }
3214 else
3215 {
3216 if(iptype == IPA_IP_v4)
3217 {
3218 for(i=0; i<pFilteringTable->num_rules; i++)
3219 {
3220 wan_ul_fl_rule_hdl_v4[num_wan_ul_fl_rule_v4] = pFilteringTable->rules[i].flt_rule_hdl;
3221 num_wan_ul_fl_rule_v4++;
3222 }
3223 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
3224 }
3225 else if(iptype == IPA_IP_v6)
3226 {
3227 for(i=0; i<pFilteringTable->num_rules; i++)
3228 {
3229 wan_ul_fl_rule_hdl_v6[num_wan_ul_fl_rule_v6] = pFilteringTable->rules[i].flt_rule_hdl;
3230 num_wan_ul_fl_rule_v6++;
3231 }
3232 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
3233 }
3234 else
3235 {
3236 IPACMERR("IP type is not expected.\n");
3237 goto fail;
3238 }
3239 }
3240
3241 fail:
3242 free(pFilteringTable);
3243 close(fd);
3244 return ret;
3245 }
3246
handle_wan_down_v6(bool is_sta_mode)3247 int IPACM_Lan::handle_wan_down_v6(bool is_sta_mode)
3248 {
3249 ipa_fltr_installed_notif_req_msg_v01 flt_index;
3250 int fd;
3251
3252 fd = open(IPA_DEVICE_NAME, O_RDWR);
3253 if (0 == fd)
3254 {
3255 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
3256 return IPACM_FAILURE;
3257 }
3258
3259 delete_ipv6_prefix_flt_rule();
3260
3261 memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
3262
3263 if(is_sta_mode == false && modem_ul_v6_set == true)
3264 {
3265 if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES)
3266 {
3267 IPACMERR(" the number of rules (%d) are bigger than array (%d), aborting...\n", num_wan_ul_fl_rule_v6, MAX_WAN_UL_FILTER_RULES);
3268 close(fd);
3269 return IPACM_FAILURE;
3270 }
3271 if (num_wan_ul_fl_rule_v6 == 0)
3272 {
3273 IPACMERR("No modem UL rules were installed, return...\n");
3274 close(fd);
3275 return IPACM_FAILURE;
3276 }
3277
3278 if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v6,
3279 IPA_IP_v6, num_wan_ul_fl_rule_v6) == false)
3280 {
3281 IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n");
3282 close(fd);
3283 return IPACM_FAILURE;
3284 }
3285 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_wan_ul_fl_rule_v6);
3286 memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
3287 num_wan_ul_fl_rule_v6 = 0;
3288 modem_ul_v6_set = false;
3289
3290 memset(&flt_index, 0, sizeof(flt_index));
3291 flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe);
3292 flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01;
3293 #ifndef FEATURE_IPA_V3
3294 flt_index.filter_index_list_len = 0;
3295 #else /* defined (FEATURE_IPA_V3) */
3296 flt_index.rule_id_valid = 1;
3297 flt_index.rule_id_len = 0;
3298 #endif
3299 flt_index.embedded_pipe_index_valid = 1;
3300 flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD);
3301 flt_index.retain_header_valid = 1;
3302 flt_index.retain_header = 0;
3303 flt_index.embedded_call_mux_id_valid = 1;
3304 flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
3305 if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
3306 {
3307 IPACMERR("Error sending filtering rule index, aborting...\n");
3308 close(fd);
3309 return IPACM_FAILURE;
3310 }
3311 }
3312 else
3313 {
3314 if (m_filtering.DeleteFilteringHdls(&dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES],
3315 IPA_IP_v6, 1) == false)
3316 {
3317 IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
3318 close(fd);
3319 return IPACM_FAILURE;
3320 }
3321 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3322 }
3323 close(fd);
3324 return IPACM_SUCCESS;
3325 }
3326
reset_to_dummy_flt_rule(ipa_ip_type iptype,uint32_t rule_hdl)3327 int IPACM_Lan::reset_to_dummy_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl)
3328 {
3329 int len, res = IPACM_SUCCESS;
3330 struct ipa_flt_rule_mdfy flt_rule;
3331 struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
3332
3333 IPACMDBG_H("Reset flt rule to dummy, IP type: %d, hdl: %d\n", iptype, rule_hdl);
3334 len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy);
3335 pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
3336
3337 if (pFilteringTable == NULL)
3338 {
3339 IPACMERR("Error allocate flt rule memory...\n");
3340 return IPACM_FAILURE;
3341 }
3342 memset(pFilteringTable, 0, len);
3343
3344 pFilteringTable->commit = 1;
3345 pFilteringTable->ip = iptype;
3346 pFilteringTable->num_rules = 1;
3347
3348 memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
3349 flt_rule.status = -1;
3350 flt_rule.rule_hdl = rule_hdl;
3351
3352 flt_rule.rule.retain_hdr = 0;
3353 flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
3354
3355 if(iptype == IPA_IP_v4)
3356 {
3357 IPACMDBG_H("Reset IPv4 flt rule to dummy\n");
3358
3359 flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
3360 flt_rule.rule.attrib.u.v4.dst_addr = ~0;
3361 flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0;
3362 flt_rule.rule.attrib.u.v4.src_addr = ~0;
3363 flt_rule.rule.attrib.u.v4.src_addr_mask = ~0;
3364
3365 memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
3366 if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
3367 {
3368 IPACMERR("Error modifying filtering rule.\n");
3369 res = IPACM_FAILURE;
3370 goto fail;
3371 }
3372 else
3373 {
3374 IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl,
3375 pFilteringTable->rules[0].status);
3376 }
3377 }
3378 else if(iptype == IPA_IP_v6)
3379 {
3380 IPACMDBG_H("Reset IPv6 flt rule to dummy\n");
3381
3382 flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
3383 flt_rule.rule.attrib.u.v6.src_addr[0] = ~0;
3384 flt_rule.rule.attrib.u.v6.src_addr[1] = ~0;
3385 flt_rule.rule.attrib.u.v6.src_addr[2] = ~0;
3386 flt_rule.rule.attrib.u.v6.src_addr[3] = ~0;
3387 flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0;
3388 flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0;
3389 flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0;
3390 flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0;
3391 flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0;
3392 flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0;
3393 flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0;
3394 flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0;
3395 flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0;
3396 flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0;
3397 flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0;
3398 flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0;
3399
3400
3401 memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
3402 if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
3403 {
3404 IPACMERR("Error modifying filtering rule.\n");
3405 res = IPACM_FAILURE;
3406 goto fail;
3407 }
3408 else
3409 {
3410 IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl,
3411 pFilteringTable->rules[0].status);
3412 }
3413 }
3414 else
3415 {
3416 IPACMERR("IP type is not expected.\n");
3417 res = IPACM_FAILURE;
3418 goto fail;
3419 }
3420
3421 fail:
3422 free(pFilteringTable);
3423 return res;
3424 }
3425
post_del_self_evt()3426 void IPACM_Lan::post_del_self_evt()
3427 {
3428 ipacm_cmd_q_data evt;
3429 ipacm_event_data_fid* fid;
3430 fid = (ipacm_event_data_fid*)malloc(sizeof(ipacm_event_data_fid));
3431 if(fid == NULL)
3432 {
3433 IPACMERR("Failed to allocate fid memory.\n");
3434 return;
3435 }
3436 memset(fid, 0, sizeof(ipacm_event_data_fid));
3437 memset(&evt, 0, sizeof(ipacm_cmd_q_data));
3438
3439 fid->if_index = ipa_if_num;
3440
3441 evt.evt_data = (void*)fid;
3442 evt.event = IPA_LAN_DELETE_SELF;
3443
3444 IPACMDBG_H("Posting event IPA_LAN_DELETE_SELF\n");
3445 IPACM_EvtDispatcher::PostEvt(&evt);
3446 }
3447
3448 /*handle reset usb-client rt-rules */
handle_lan_client_reset_rt(ipa_ip_type iptype)3449 int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype)
3450 {
3451 uint32_t i;
3452 int res = IPACM_SUCCESS;
3453
3454 /* clean eth-client routing rules */
3455 IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
3456 for (i = 0; i < num_eth_client; i++)
3457 {
3458 res = delete_eth_rtrules(i, iptype);
3459 if (res != IPACM_SUCCESS)
3460 {
3461 IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype);
3462 return res;
3463 }
3464 } /* end of for loop */
3465
3466 /* Reset ip-address */
3467 for (i = 0; i < num_eth_client; i++)
3468 {
3469 if(iptype == IPA_IP_v4)
3470 {
3471 get_client_memptr(eth_client, i)->ipv4_set = false;
3472 }
3473 else
3474 {
3475 get_client_memptr(eth_client, i)->ipv6_set = 0;
3476 }
3477 } /* end of for loop */
3478 return res;
3479 }
3480
install_ipv4_icmp_flt_rule()3481 int IPACM_Lan::install_ipv4_icmp_flt_rule()
3482 {
3483 int len;
3484 struct ipa_ioc_add_flt_rule* flt_rule;
3485 struct ipa_flt_rule_add flt_rule_entry;
3486
3487 if(rx_prop != NULL)
3488 {
3489 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
3490
3491 flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
3492 if (!flt_rule)
3493 {
3494 IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3495 return IPACM_FAILURE;
3496 }
3497
3498 flt_rule->commit = 1;
3499 flt_rule->ep = rx_prop->rx[0].src_pipe;
3500 flt_rule->global = false;
3501 flt_rule->ip = IPA_IP_v4;
3502 flt_rule->num_rules = 1;
3503
3504 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3505
3506 flt_rule_entry.rule.retain_hdr = 1;
3507 flt_rule_entry.rule.to_uc = 0;
3508 flt_rule_entry.rule.eq_attrib_type = 0;
3509 flt_rule_entry.at_rear = true;
3510 flt_rule_entry.flt_rule_hdl = -1;
3511 flt_rule_entry.status = -1;
3512 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3513 #ifdef FEATURE_IPA_V3
3514 flt_rule_entry.rule.hashable = true;
3515 #endif
3516 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
3517
3518 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
3519 flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP;
3520 memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3521
3522 if (m_filtering.AddFilteringRule(flt_rule) == false)
3523 {
3524 IPACMERR("Error Adding Filtering rule, aborting...\n");
3525 free(flt_rule);
3526 return IPACM_FAILURE;
3527 }
3528 else
3529 {
3530 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
3531 ipv4_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
3532 IPACMDBG_H("IPv4 icmp filter rule HDL:0x%x\n", ipv4_icmp_flt_rule_hdl[0]);
3533 free(flt_rule);
3534 }
3535 }
3536 return IPACM_SUCCESS;
3537 }
3538
install_ipv6_icmp_flt_rule()3539 int IPACM_Lan::install_ipv6_icmp_flt_rule()
3540 {
3541
3542 int len;
3543 struct ipa_ioc_add_flt_rule* flt_rule;
3544 struct ipa_flt_rule_add flt_rule_entry;
3545
3546 if(rx_prop != NULL)
3547 {
3548 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
3549
3550 flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
3551 if (!flt_rule)
3552 {
3553 IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3554 return IPACM_FAILURE;
3555 }
3556
3557 flt_rule->commit = 1;
3558 flt_rule->ep = rx_prop->rx[0].src_pipe;
3559 flt_rule->global = false;
3560 flt_rule->ip = IPA_IP_v6;
3561 flt_rule->num_rules = 1;
3562
3563 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3564
3565 flt_rule_entry.rule.retain_hdr = 1;
3566 flt_rule_entry.rule.to_uc = 0;
3567 flt_rule_entry.rule.eq_attrib_type = 0;
3568 flt_rule_entry.at_rear = true;
3569 flt_rule_entry.flt_rule_hdl = -1;
3570 flt_rule_entry.status = -1;
3571 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3572 #ifdef FEATURE_IPA_V3
3573 flt_rule_entry.rule.hashable = false;
3574 #endif
3575 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
3576 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
3577 flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
3578 memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3579
3580 if (m_filtering.AddFilteringRule(flt_rule) == false)
3581 {
3582 IPACMERR("Error Adding Filtering rule, aborting...\n");
3583 free(flt_rule);
3584 return IPACM_FAILURE;
3585 }
3586 else
3587 {
3588 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3589 ipv6_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
3590 IPACMDBG_H("IPv6 icmp filter rule HDL:0x%x\n", ipv6_icmp_flt_rule_hdl[0]);
3591 free(flt_rule);
3592 }
3593 }
3594 return IPACM_SUCCESS;
3595 }
3596
add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)3597 int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
3598 {
3599 if(rx_prop == NULL)
3600 {
3601 IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy private subnet filtering rule.\n", dev_name);
3602 return 0;
3603 }
3604
3605 if(iptype == IPA_IP_v6)
3606 {
3607 IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name);
3608 return 0;
3609 }
3610 int i, len, res = IPACM_SUCCESS;
3611 struct ipa_flt_rule_add flt_rule;
3612 ipa_ioc_add_flt_rule* pFilteringTable;
3613
3614 len = sizeof(struct ipa_ioc_add_flt_rule) + IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(struct ipa_flt_rule_add);
3615
3616 pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
3617 if (pFilteringTable == NULL)
3618 {
3619 IPACMERR("Error allocate flt table memory...\n");
3620 return IPACM_FAILURE;
3621 }
3622 memset(pFilteringTable, 0, len);
3623
3624 pFilteringTable->commit = 1;
3625 pFilteringTable->ep = rx_prop->rx[0].src_pipe;
3626 pFilteringTable->global = false;
3627 pFilteringTable->ip = iptype;
3628 pFilteringTable->num_rules = IPA_MAX_PRIVATE_SUBNET_ENTRIES;
3629
3630 memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add));
3631
3632 flt_rule.rule.retain_hdr = 0;
3633 flt_rule.at_rear = true;
3634 flt_rule.flt_rule_hdl = -1;
3635 flt_rule.status = -1;
3636 flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
3637 #ifdef FEATURE_IPA_V3
3638 flt_rule.rule.hashable = true;
3639 #endif
3640 memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib,
3641 sizeof(flt_rule.rule.attrib));
3642
3643 if(iptype == IPA_IP_v4)
3644 {
3645 flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
3646 flt_rule.rule.attrib.u.v4.src_addr_mask = ~0;
3647 flt_rule.rule.attrib.u.v4.src_addr = ~0;
3648 flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0;
3649 flt_rule.rule.attrib.u.v4.dst_addr = ~0;
3650
3651 for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
3652 {
3653 memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add));
3654 }
3655
3656 if (false == m_filtering.AddFilteringRule(pFilteringTable))
3657 {
3658 IPACMERR("Error adding dummy private subnet v4 flt rule\n");
3659 res = IPACM_FAILURE;
3660 goto fail;
3661 }
3662 else
3663 {
3664 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES);
3665 /* copy filter rule hdls */
3666 for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
3667 {
3668 if (pFilteringTable->rules[i].status == 0)
3669 {
3670 private_fl_rule_hdl[i] = pFilteringTable->rules[i].flt_rule_hdl;
3671 IPACMDBG_H("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]);
3672 }
3673 else
3674 {
3675 IPACMERR("Failed adding lan2lan v4 flt rule %d\n", i);
3676 res = IPACM_FAILURE;
3677 goto fail;
3678 }
3679 }
3680 }
3681 }
3682 fail:
3683 free(pFilteringTable);
3684 return res;
3685 }
3686
handle_private_subnet_android(ipa_ip_type iptype)3687 int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype)
3688 {
3689 int i, len, res = IPACM_SUCCESS;
3690 struct ipa_flt_rule_mdfy flt_rule;
3691 struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
3692
3693 if (rx_prop == NULL)
3694 {
3695 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
3696 return IPACM_SUCCESS;
3697 }
3698
3699 if(iptype == IPA_IP_v6)
3700 {
3701 IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name);
3702 return 0;
3703 }
3704 else
3705 {
3706 for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
3707 {
3708 reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]);
3709 }
3710
3711 len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy);
3712 pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
3713 if (!pFilteringTable)
3714 {
3715 IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n");
3716 return IPACM_FAILURE;
3717 }
3718 memset(pFilteringTable, 0, len);
3719
3720 pFilteringTable->commit = 1;
3721 pFilteringTable->ip = iptype;
3722 pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
3723
3724 /* Make LAN-traffic always go A5, use default IPA-RT table */
3725 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4))
3726 {
3727 IPACMERR("Failed to get routing table handle.\n");
3728 res = IPACM_FAILURE;
3729 goto fail;
3730 }
3731
3732 memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
3733 flt_rule.status = -1;
3734
3735 flt_rule.rule.retain_hdr = 1;
3736 flt_rule.rule.to_uc = 0;
3737 flt_rule.rule.action = IPA_PASS_TO_ROUTING;
3738 flt_rule.rule.eq_attrib_type = 0;
3739 flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl;
3740 IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name);
3741
3742 memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
3743 flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3744
3745 for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
3746 {
3747 flt_rule.rule_hdl = private_fl_rule_hdl[i];
3748 flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
3749 flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
3750 memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
3751 IPACMDBG_H(" IPACM private subnet_addr as: 0x%x entry(%d)\n", flt_rule.rule.attrib.u.v4.dst_addr, i);
3752 }
3753
3754 if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
3755 {
3756 IPACMERR("Failed to modify private subnet filtering rules.\n");
3757 res = IPACM_FAILURE;
3758 goto fail;
3759 }
3760 }
3761 fail:
3762 if(pFilteringTable != NULL)
3763 {
3764 free(pFilteringTable);
3765 }
3766 return res;
3767 }
3768
install_ipv6_prefix_flt_rule(uint32_t * prefix)3769 int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
3770 {
3771 if(prefix == NULL)
3772 {
3773 IPACMERR("IPv6 prefix is empty.\n");
3774 return IPACM_FAILURE;
3775 }
3776 IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]);
3777
3778 int len;
3779 struct ipa_ioc_add_flt_rule* flt_rule;
3780 struct ipa_flt_rule_add flt_rule_entry;
3781
3782 if(rx_prop != NULL)
3783 {
3784 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
3785
3786 flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
3787 if (!flt_rule)
3788 {
3789 IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
3790 return IPACM_FAILURE;
3791 }
3792
3793 flt_rule->commit = 1;
3794 flt_rule->ep = rx_prop->rx[0].src_pipe;
3795 flt_rule->global = false;
3796 flt_rule->ip = IPA_IP_v6;
3797 flt_rule->num_rules = 1;
3798
3799 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
3800
3801 flt_rule_entry.rule.retain_hdr = 1;
3802 flt_rule_entry.rule.to_uc = 0;
3803 flt_rule_entry.rule.eq_attrib_type = 0;
3804 flt_rule_entry.at_rear = true;
3805 flt_rule_entry.flt_rule_hdl = -1;
3806 flt_rule_entry.status = -1;
3807 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
3808 #ifdef FEATURE_IPA_V3
3809 flt_rule_entry.rule.hashable = true;
3810 #endif
3811 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
3812 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3813 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0];
3814 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1];
3815 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x0;
3816 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x0;
3817 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
3818 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
3819 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x0;
3820 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0;
3821 memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
3822
3823 if (m_filtering.AddFilteringRule(flt_rule) == false)
3824 {
3825 IPACMERR("Error Adding Filtering rule, aborting...\n");
3826 free(flt_rule);
3827 return IPACM_FAILURE;
3828 }
3829 else
3830 {
3831 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
3832 ipv6_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
3833 IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]);
3834 free(flt_rule);
3835 }
3836 }
3837 return IPACM_SUCCESS;
3838 }
3839
delete_ipv6_prefix_flt_rule()3840 void IPACM_Lan::delete_ipv6_prefix_flt_rule()
3841 {
3842 if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE) == false)
3843 {
3844 IPACMERR("Failed to delete ipv6 prefix flt rule.\n");
3845 return;
3846 }
3847 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE);
3848 return;
3849 }
3850
handle_addr_evt_odu_bridge(ipacm_event_data_addr * data)3851 int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data)
3852 {
3853 int fd, res = IPACM_SUCCESS;
3854 struct in6_addr ipv6_addr;
3855 if(data == NULL)
3856 {
3857 IPACMERR("Failed to get interface IP address.\n");
3858 return IPACM_FAILURE;
3859 }
3860
3861 if(data->iptype == IPA_IP_v6)
3862 {
3863 fd = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR);
3864 if(fd == 0)
3865 {
3866 IPACMERR("Failed to open %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU);
3867 return IPACM_FAILURE;
3868 }
3869
3870 memcpy(&ipv6_addr, data->ipv6_addr, sizeof(struct in6_addr));
3871
3872 if( ioctl(fd, ODU_BRIDGE_IOC_SET_LLV6_ADDR, &ipv6_addr) )
3873 {
3874 IPACMERR("Failed to write IPv6 address to odu driver.\n");
3875 res = IPACM_FAILURE;
3876 }
3877 num_dft_rt_v6++;
3878 close(fd);
3879 }
3880
3881 return res;
3882 }
3883
eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1,ipa_hdr_l2_type t2)3884 ipa_hdr_proc_type IPACM_Lan::eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2)
3885 {
3886 if(t1 == IPA_HDR_L2_ETHERNET_II)
3887 {
3888 if(t2 == IPA_HDR_L2_ETHERNET_II)
3889 {
3890 return IPA_HDR_PROC_ETHII_TO_ETHII;
3891 }
3892 if(t2 == IPA_HDR_L2_802_3)
3893 {
3894 return IPA_HDR_PROC_ETHII_TO_802_3;
3895 }
3896 }
3897
3898 if(t1 == IPA_HDR_L2_802_3)
3899 {
3900 if(t2 == IPA_HDR_L2_ETHERNET_II)
3901 {
3902 return IPA_HDR_PROC_802_3_TO_ETHII;
3903 }
3904 if(t2 == IPA_HDR_L2_802_3)
3905 {
3906 return IPA_HDR_PROC_802_3_TO_802_3;
3907 }
3908 }
3909
3910 return IPA_HDR_PROC_NONE;
3911 }
3912
eth_bridge_get_hdr_template_hdl(uint32_t * hdr_hdl)3913 int IPACM_Lan::eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl)
3914 {
3915 if(hdr_hdl == NULL)
3916 {
3917 IPACMDBG_H("Hdr handle pointer is empty.\n");
3918 return IPACM_FAILURE;
3919 }
3920
3921 struct ipa_ioc_get_hdr hdr;
3922 memset(&hdr, 0, sizeof(hdr));
3923
3924 memcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
3925 if(m_header.GetHeaderHandle(&hdr) == false)
3926 {
3927 IPACMERR("Failed to get template hdr hdl.\n");
3928 return IPACM_FAILURE;
3929 }
3930
3931 *hdr_hdl = hdr.hdl;
3932 return IPACM_SUCCESS;
3933 }
3934
handle_cradle_wan_mode_switch(bool is_wan_bridge_mode)3935 int IPACM_Lan::handle_cradle_wan_mode_switch(bool is_wan_bridge_mode)
3936 {
3937 struct ipa_flt_rule_mdfy flt_rule_entry;
3938 int len = 0;
3939 ipa_ioc_mdfy_flt_rule *m_pFilteringTable;
3940
3941 IPACMDBG_H("Handle wan mode swtich: is wan bridge mode?%d\n", is_wan_bridge_mode);
3942
3943 if (rx_prop == NULL)
3944 {
3945 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
3946 return IPACM_SUCCESS;
3947 }
3948
3949 len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (1 * sizeof(struct ipa_flt_rule_mdfy));
3950 m_pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len);
3951 if (m_pFilteringTable == NULL)
3952 {
3953 PERROR("Error Locate ipa_ioc_mdfy_flt_rule memory...\n");
3954 return IPACM_FAILURE;
3955 }
3956
3957 m_pFilteringTable->commit = 1;
3958 m_pFilteringTable->ip = IPA_IP_v4;
3959 m_pFilteringTable->num_rules = (uint8_t)1;
3960
3961 IPACMDBG_H("Retrieving routing hanle for table: %s\n",
3962 IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name);
3963 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4))
3964 {
3965 IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n",
3966 &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4);
3967 free(m_pFilteringTable);
3968 return IPACM_FAILURE;
3969 }
3970 IPACMDBG_H("Routing handle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl);
3971
3972
3973 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_mdfy)); // Zero All Fields
3974 flt_rule_entry.status = -1;
3975 flt_rule_entry.rule_hdl = lan_wan_fl_rule_hdl[0];
3976
3977 flt_rule_entry.rule.retain_hdr = 0;
3978 flt_rule_entry.rule.to_uc = 0;
3979 flt_rule_entry.rule.eq_attrib_type = 0;
3980 if(is_wan_bridge_mode)
3981 {
3982 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
3983 }
3984 else
3985 {
3986 flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
3987 }
3988 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl;
3989
3990 memcpy(&flt_rule_entry.rule.attrib,
3991 &rx_prop->rx[0].attrib,
3992 sizeof(flt_rule_entry.rule.attrib));
3993
3994 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
3995 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0;
3996 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0;
3997
3998 memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry));
3999 if (false == m_filtering.ModifyFilteringRule(m_pFilteringTable))
4000 {
4001 IPACMERR("Error Modifying RuleTable(0) to Filtering, aborting...\n");
4002 free(m_pFilteringTable);
4003 return IPACM_FAILURE;
4004 }
4005 else
4006 {
4007 IPACMDBG_H("flt rule hdl = %d, status = %d\n",
4008 m_pFilteringTable->rules[0].rule_hdl,
4009 m_pFilteringTable->rules[0].status);
4010 }
4011 free(m_pFilteringTable);
4012 return IPACM_SUCCESS;
4013 }
4014
4015 /*handle reset usb-client rt-rules */
handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 * data)4016 int IPACM_Lan::handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 *data)
4017 {
4018 int fd;
4019 uint32_t pipe_len, cnt;
4020 uint64_t num_ul_packets, num_ul_bytes;
4021 uint64_t num_dl_packets, num_dl_bytes;
4022 bool ul_pipe_found, dl_pipe_found;
4023 FILE *fp = NULL;
4024
4025 fd = open(IPA_DEVICE_NAME, O_RDWR);
4026 if (fd < 0)
4027 {
4028 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
4029 return IPACM_FAILURE;
4030 }
4031
4032
4033 ul_pipe_found = false;
4034 dl_pipe_found = false;
4035 num_ul_packets = 0;
4036 num_dl_packets = 0;
4037 num_ul_bytes = 0;
4038 num_dl_bytes = 0;
4039
4040 if (data->dl_dst_pipe_stats_list_valid)
4041 {
4042 if(tx_prop != NULL)
4043 {
4044 for (pipe_len = 0; pipe_len < data->dl_dst_pipe_stats_list_len; pipe_len++)
4045 {
4046 IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->dl_dst_pipe_stats_list[pipe_len].pipe_index);
4047 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
4048 {
4049 IPACMDBG_H("Check Tx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe));
4050 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)
4051 {
4052 /* update the DL stats */
4053 dl_pipe_found = true;
4054 num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_packets;
4055 num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_packets;
4056 num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_bytes;
4057 num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_bytes;
4058 IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->dl_dst_pipe_stats_list[pipe_len].pipe_index, cnt);
4059 IPACMDBG_H("DL_packets:(%lu) DL_bytes:(%lu) \n", num_dl_packets, num_dl_bytes);
4060 break;
4061 }
4062 }
4063 }
4064 }
4065 }
4066
4067 if (data->ul_src_pipe_stats_list_valid)
4068 {
4069 if(rx_prop != NULL)
4070 {
4071 for (pipe_len = 0; pipe_len < data->ul_src_pipe_stats_list_len; pipe_len++)
4072 {
4073 IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->ul_src_pipe_stats_list[pipe_len].pipe_index);
4074 for (cnt=0; cnt < rx_prop->num_rx_props; cnt++)
4075 {
4076 IPACMDBG_H("Check Rx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe));
4077 //Typecasting to avoid -Wall -Werror errors
4078 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)
4079 {
4080 /* update the UL stats */
4081 ul_pipe_found = true;
4082 num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_packets;
4083 num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_packets;
4084 num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_bytes;
4085 num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_bytes;
4086 IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->ul_src_pipe_stats_list[pipe_len].pipe_index, cnt);
4087 IPACMDBG_H("UL_packets:(%lu) UL_bytes:(%lu) \n", num_ul_packets, num_ul_bytes);
4088 break;
4089 }
4090 }
4091 }
4092 }
4093 }
4094 close(fd);
4095
4096 if (ul_pipe_found || dl_pipe_found)
4097 {
4098 IPACMDBG_H("Update IPA_TETHERING_STATS_UPDATE_EVENT, TX(P%lu/B%lu) RX(P%lu/B%lu) DEV(%s) to LTE(%s) \n",
4099 num_ul_packets,
4100 num_ul_bytes,
4101 num_dl_packets,
4102 num_dl_bytes,
4103 dev_name,
4104 IPACM_Wan::wan_up_dev_name);
4105 fp = fopen(IPA_PIPE_STATS_FILE_NAME, "w");
4106 if ( fp == NULL )
4107 {
4108 IPACMERR("Failed to write pipe stats to %s, error is %d - %s\n",
4109 IPA_PIPE_STATS_FILE_NAME, errno, strerror(errno));
4110 return IPACM_FAILURE;
4111 }
4112
4113 fprintf(fp, PIPE_STATS,
4114 dev_name,
4115 IPACM_Wan::wan_up_dev_name,
4116 num_ul_bytes,
4117 num_ul_packets,
4118 num_dl_bytes,
4119 num_dl_packets);
4120 fclose(fp);
4121 }
4122 return IPACM_SUCCESS;
4123 }
4124
4125 /*handle tether client */
handle_tethering_client(bool reset,ipacm_client_enum ipa_client)4126 int IPACM_Lan::handle_tethering_client(bool reset, ipacm_client_enum ipa_client)
4127 {
4128 int fd, ret = IPACM_SUCCESS;
4129 uint32_t cnt;
4130 int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
4131 wan_ioctl_set_tether_client_pipe tether_client;
4132
4133 if(fd_wwan_ioctl < 0)
4134 {
4135 IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
4136 return IPACM_FAILURE;
4137 }
4138
4139 fd = open(IPA_DEVICE_NAME, O_RDWR);
4140 if (fd < 0)
4141 {
4142 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
4143 close(fd_wwan_ioctl);
4144 return IPACM_FAILURE;
4145 }
4146
4147 memset(&tether_client, 0, sizeof(tether_client));
4148 tether_client.reset_client = reset;
4149 tether_client.ipa_client = ipa_client;
4150
4151 if(tx_prop != NULL)
4152 {
4153 tether_client.dl_dst_pipe_len = tx_prop->num_tx_props;
4154 for (cnt = 0; cnt < tx_prop->num_tx_props; cnt++)
4155 {
4156 IPACMDBG_H("Tx(%d), dst_pipe: %d, ipa_pipe: %d\n",
4157 cnt, tx_prop->tx[cnt].dst_pipe,
4158 ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe));
4159 tether_client.dl_dst_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe);
4160 }
4161 }
4162
4163 if(rx_prop != NULL)
4164 {
4165 tether_client.ul_src_pipe_len = rx_prop->num_rx_props;
4166 for (cnt = 0; cnt < rx_prop->num_rx_props; cnt++)
4167 {
4168 IPACMDBG_H("Rx(%d), src_pipe: %d, ipa_pipe: %d\n",
4169 cnt, rx_prop->rx[cnt].src_pipe,
4170 ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe));
4171 tether_client.ul_src_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe);
4172 }
4173 }
4174
4175 ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, &tether_client);
4176 if (ret != 0)
4177 {
4178 IPACMERR("Failed set tether-client-pipe %p with ret %d\n ", &tether_client, ret);
4179 }
4180 IPACMDBG("Set tether-client-pipe %p\n", &tether_client);
4181 close(fd);
4182 close(fd_wwan_ioctl);
4183 return ret;
4184 }
4185
4186 /* 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)4187 void IPACM_Lan::eth_bridge_post_event(ipa_cm_event_id evt, ipa_ip_type iptype, uint8_t *mac)
4188 {
4189 ipacm_cmd_q_data eth_bridge_evt;
4190 ipacm_event_eth_bridge *evt_data;
4191
4192 evt_data = (ipacm_event_eth_bridge*)malloc(sizeof(ipacm_event_eth_bridge));
4193 if(evt_data == NULL)
4194 {
4195 IPACMERR("Failed to allocate memory.\n");
4196 return;
4197 }
4198 memset(evt_data, 0, sizeof(ipacm_event_eth_bridge));
4199
4200 evt_data->p_iface = this;
4201 evt_data->iptype = iptype;
4202 if(mac)
4203 {
4204 IPACMDBG_H("Client mac: 0x%02x%02x%02x%02x%02x%02x \n",
4205 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4206 memcpy(evt_data->mac_addr, mac, sizeof(evt_data->mac_addr));
4207 }
4208
4209 memset(ð_bridge_evt, 0, sizeof(ipacm_cmd_q_data));
4210 eth_bridge_evt.evt_data = (void*)evt_data;
4211 eth_bridge_evt.event = evt;
4212
4213 IPACMDBG_H("Posting event %s\n",
4214 IPACM_Iface::ipacmcfg->getEventName(evt));
4215 IPACM_EvtDispatcher::PostEvt(ð_bridge_evt);
4216 }
4217
4218 /* 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)4219 int IPACM_Lan::eth_bridge_add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_hdr_type, uint32_t *hdl)
4220 {
4221 int len, res = IPACM_SUCCESS;
4222 uint32_t hdr_template;
4223 ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL;
4224
4225 if(tx_prop == NULL)
4226 {
4227 IPACMERR("No tx prop.\n");
4228 return IPACM_FAILURE;
4229 }
4230
4231 len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add);
4232 pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len);
4233 if(pHeaderProcTable == NULL)
4234 {
4235 IPACMERR("Cannot allocate header processing context table.\n");
4236 return IPACM_FAILURE;
4237 }
4238
4239 memset(pHeaderProcTable, 0, len);
4240 pHeaderProcTable->commit = 1;
4241 pHeaderProcTable->num_proc_ctxs = 1;
4242 pHeaderProcTable->proc_ctx[0].type = eth_bridge_get_hdr_proc_type(peer_l2_hdr_type, tx_prop->tx[0].hdr_l2_type);
4243 eth_bridge_get_hdr_template_hdl(&hdr_template);
4244 pHeaderProcTable->proc_ctx[0].hdr_hdl = hdr_template;
4245 if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false)
4246 {
4247 IPACMERR("Adding hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status);
4248 res = IPACM_FAILURE;
4249 goto end;
4250 }
4251
4252 *hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl;
4253
4254 end:
4255 free(pHeaderProcTable);
4256 return res;
4257 }
4258
4259 /* 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)4260 int IPACM_Lan::eth_bridge_add_rt_rule(uint8_t *mac, char *rt_tbl_name, uint32_t hdr_proc_ctx_hdl,
4261 ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int *rt_rule_count)
4262 {
4263 int len, res = IPACM_SUCCESS;
4264 uint32_t i, position, num_rt_rule;
4265 struct ipa_ioc_add_rt_rule* rt_rule_table = NULL;
4266 struct ipa_rt_rule_add rt_rule;
4267
4268 IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n",
4269 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4270
4271 num_rt_rule = each_client_rt_rule_count[iptype];
4272
4273 len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add);
4274 rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len);
4275 if (rt_rule_table == NULL)
4276 {
4277 IPACMERR("Failed to allocate memory.\n");
4278 return IPACM_FAILURE;
4279 }
4280 memset(rt_rule_table, 0, len);
4281
4282 rt_rule_table->commit = 1;
4283 rt_rule_table->ip = iptype;
4284 rt_rule_table->num_rules = num_rt_rule;
4285 strlcpy(rt_rule_table->rt_tbl_name, rt_tbl_name, sizeof(rt_rule_table->rt_tbl_name));
4286 rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = 0;
4287
4288 memset(&rt_rule, 0, sizeof(ipa_rt_rule_add));
4289 rt_rule.at_rear = false;
4290 rt_rule.status = -1;
4291 rt_rule.rt_rule_hdl = -1;
4292 #ifdef FEATURE_IPA_V3
4293 rt_rule.rule.hashable = true;
4294 #endif
4295 rt_rule.rule.hdr_hdl = 0;
4296 rt_rule.rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl;
4297
4298 position = 0;
4299 for(i=0; i<iface_query->num_tx_props; i++)
4300 {
4301 if(tx_prop->tx[i].ip == iptype)
4302 {
4303 if(position >= num_rt_rule || position >= MAX_NUM_PROP)
4304 {
4305 IPACMERR("Number of routing rules already exceeds limit.\n");
4306 res = IPACM_FAILURE;
4307 goto end;
4308 }
4309
4310 if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->isMCC_Mode)
4311 {
4312 IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n",
4313 tx_prop->tx[i].alt_dst_pipe);
4314 rt_rule.rule.dst = tx_prop->tx[i].alt_dst_pipe;
4315 }
4316 else
4317 {
4318 IPACMDBG_H("It is not WLAN MCC mode, use dst pipe: %d\n",
4319 tx_prop->tx[i].dst_pipe);
4320 rt_rule.rule.dst = tx_prop->tx[i].dst_pipe;
4321 }
4322
4323 memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib));
4324 if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II)
4325 rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
4326 else
4327 rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
4328 memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr));
4329 memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask));
4330
4331 memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position]));
4332 position++;
4333 }
4334 }
4335 if(false == m_routing.AddRoutingRule(rt_rule_table))
4336 {
4337 IPACMERR("Routing rule addition failed!\n");
4338 res = IPACM_FAILURE;
4339 goto end;
4340 }
4341 else
4342 {
4343 *rt_rule_count = position;
4344 for(i=0; i<position; i++)
4345 rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
4346 }
4347
4348 end:
4349 free(rt_rule_table);
4350 return res;
4351 }
4352
4353 /* 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)4354 int IPACM_Lan::eth_bridge_modify_rt_rule(uint8_t *mac, uint32_t hdr_proc_ctx_hdl,
4355 ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int rt_rule_count)
4356 {
4357 struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL;
4358 struct ipa_rt_rule_mdfy *rt_rule_entry;
4359 int len, res = IPACM_SUCCESS;
4360 uint32_t index;
4361
4362 if(tx_prop == NULL)
4363 {
4364 IPACMDBG_H("No tx properties \n");
4365 return IPACM_FAILURE;
4366 }
4367
4368 if(ipa_if_cate != WLAN_IF)
4369 {
4370 IPACMDBG_H("This is not WLAN IF, no need to modify rt rule.\n");
4371 return IPACM_SUCCESS;
4372 }
4373
4374 IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n",
4375 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4376
4377 len = sizeof(struct ipa_ioc_mdfy_rt_rule) + rt_rule_count * sizeof(struct ipa_rt_rule_mdfy);
4378 rt_rule = (struct ipa_ioc_mdfy_rt_rule *)malloc(len);
4379 if(rt_rule == NULL)
4380 {
4381 IPACMERR("Unable to allocate memory for modify rt rule\n");
4382 return IPACM_FAILURE;
4383 }
4384 memset(rt_rule, 0, len);
4385
4386 rt_rule->commit = 1;
4387 rt_rule->num_rules = 0;
4388 rt_rule->ip = iptype;
4389
4390 for (index = 0; index < tx_prop->num_tx_props; index++)
4391 {
4392 if (tx_prop->tx[index].ip == iptype)
4393 {
4394 if (rt_rule->num_rules >= rt_rule_count ||
4395 rt_rule->num_rules >= MAX_NUM_PROP)
4396 {
4397 IPACMERR("Number of routing rules exceeds limit.\n");
4398 res = IPACM_FAILURE;
4399 goto end;
4400 }
4401
4402 rt_rule_entry = &rt_rule->rules[rt_rule->num_rules];
4403
4404 if (IPACM_Iface::ipacmcfg->isMCC_Mode)
4405 {
4406 IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n",
4407 tx_prop->tx[index].alt_dst_pipe);
4408 rt_rule_entry->rule.dst = tx_prop->tx[index].alt_dst_pipe;
4409 }
4410 else
4411 {
4412 IPACMDBG_H("In WLAN SCC mode, use dst pipe: %d\n",
4413 tx_prop->tx[index].dst_pipe);
4414 rt_rule_entry->rule.dst = tx_prop->tx[index].dst_pipe;
4415 }
4416
4417 rt_rule_entry->rule.hdr_hdl = 0;
4418 rt_rule_entry->rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl;
4419 #ifdef FEATURE_IPA_V3
4420 rt_rule_entry->rule.hashable = true;
4421 #endif
4422 memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[index].attrib,
4423 sizeof(rt_rule_entry->rule.attrib));
4424 if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II)
4425 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
4426 else
4427 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
4428 memcpy(rt_rule_entry->rule.attrib.dst_mac_addr, mac,
4429 sizeof(rt_rule_entry->rule.attrib.dst_mac_addr));
4430 memset(rt_rule_entry->rule.attrib.dst_mac_addr_mask, 0xFF,
4431 sizeof(rt_rule_entry->rule.attrib.dst_mac_addr_mask));
4432
4433 rt_rule_entry->rt_rule_hdl = rt_rule_hdl[rt_rule->num_rules];
4434 rt_rule->num_rules++;
4435 }
4436 }
4437
4438 if(m_routing.ModifyRoutingRule(rt_rule) == false)
4439 {
4440 IPACMERR("Failed to modify routing rules.\n");
4441 res = IPACM_FAILURE;
4442 goto end;
4443 }
4444 if(m_routing.Commit(iptype) == false)
4445 {
4446 IPACMERR("Failed to commit routing rules.\n");
4447 res = IPACM_FAILURE;
4448 goto end;
4449 }
4450 IPACMDBG("Modified routing rules successfully.\n");
4451
4452 end:
4453 free(rt_rule);
4454 return res;
4455 }
4456
eth_bridge_add_flt_rule(uint8_t * mac,uint32_t rt_tbl_hdl,ipa_ip_type iptype,uint32_t * flt_rule_hdl)4457 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)
4458 {
4459 int len, res = IPACM_SUCCESS;
4460 struct ipa_flt_rule_add flt_rule_entry;
4461 struct ipa_ioc_add_flt_rule_after *pFilteringTable = NULL;
4462
4463 #ifdef FEATURE_IPA_V3
4464 if (rx_prop == NULL || tx_prop == NULL)
4465 {
4466 IPACMDBG_H("No rx or tx properties registered for iface %s\n", dev_name);
4467 return IPACM_FAILURE;
4468 }
4469
4470 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]);
4471
4472 len = sizeof(struct ipa_ioc_add_flt_rule_after) + sizeof(struct ipa_flt_rule_add);
4473 pFilteringTable = (struct ipa_ioc_add_flt_rule_after*)malloc(len);
4474 if (!pFilteringTable)
4475 {
4476 IPACMERR("Failed to allocate ipa_ioc_add_flt_rule_after memory...\n");
4477 return IPACM_FAILURE;
4478 }
4479 memset(pFilteringTable, 0, len);
4480
4481 /* add mac based rule*/
4482 pFilteringTable->commit = 1;
4483 pFilteringTable->ep = rx_prop->rx[0].src_pipe;
4484 pFilteringTable->ip = iptype;
4485 pFilteringTable->num_rules = 1;
4486 pFilteringTable->add_after_hdl = eth_bridge_flt_rule_offset[iptype];
4487
4488 memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
4489 flt_rule_entry.at_rear = 1;
4490
4491 flt_rule_entry.rule.retain_hdr = 0;
4492 flt_rule_entry.rule.to_uc = 0;
4493 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
4494 flt_rule_entry.rule.eq_attrib_type = 0;
4495 flt_rule_entry.rule.rt_tbl_hdl = rt_tbl_hdl;
4496 flt_rule_entry.rule.hashable = true;
4497
4498 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
4499 if(tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_ETHERNET_II)
4500 {
4501 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
4502 }
4503 else
4504 {
4505 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
4506 }
4507
4508 memcpy(flt_rule_entry.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr));
4509 memset(flt_rule_entry.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr_mask));
4510
4511 memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
4512 if (false == m_filtering.AddFilteringRuleAfter(pFilteringTable))
4513 {
4514 IPACMERR("Failed to add client filtering rules.\n");
4515 res = IPACM_FAILURE;
4516 goto end;
4517 }
4518 *flt_rule_hdl = pFilteringTable->rules[0].flt_rule_hdl;
4519
4520 end:
4521 free(pFilteringTable);
4522 #endif
4523 return res;
4524 }
4525
eth_bridge_del_flt_rule(uint32_t flt_rule_hdl,ipa_ip_type iptype)4526 int IPACM_Lan::eth_bridge_del_flt_rule(uint32_t flt_rule_hdl, ipa_ip_type iptype)
4527 {
4528 if(m_filtering.DeleteFilteringHdls(&flt_rule_hdl, iptype, 1) == false)
4529 {
4530 IPACMERR("Failed to delete the client specific flt rule.\n");
4531 return IPACM_FAILURE;
4532 }
4533 return IPACM_SUCCESS;
4534 }
4535
eth_bridge_del_rt_rule(uint32_t rt_rule_hdl,ipa_ip_type iptype)4536 int IPACM_Lan::eth_bridge_del_rt_rule(uint32_t rt_rule_hdl, ipa_ip_type iptype)
4537 {
4538 if(m_routing.DeleteRoutingHdl(rt_rule_hdl, iptype) == false)
4539 {
4540 IPACMERR("Failed to delete routing rule.\n");
4541 return IPACM_FAILURE;
4542 }
4543 return IPACM_SUCCESS;
4544 }
4545
4546 /* delete header processing context */
eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl)4547 int IPACM_Lan::eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl)
4548 {
4549 if(m_header.DeleteHeaderProcCtx(hdr_proc_ctx_hdl) == false)
4550 {
4551 IPACMERR("Failed to delete hdr proc ctx.\n");
4552 return IPACM_FAILURE;
4553 }
4554 return IPACM_SUCCESS;
4555 }
4556