1 /*
2 Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 /*!
30 @file
31 IPACM_Wlan.cpp
32
33 @brief
34 This file implements the WLAN iface functionality.
35
36 @Author
37 Skylar Chang
38
39 */
40
41 #include <string.h>
42 #include <unistd.h>
43 #include <sys/ioctl.h>
44 #include <IPACM_Wlan.h>
45 #include <IPACM_Netlink.h>
46 #include <fcntl.h>
47 #include <sys/inotify.h>
48 #include <IPACM_Wan.h>
49 #include <IPACM_Lan.h>
50 #include <IPACM_IfaceManager.h>
51 #include <IPACM_ConntrackListener.h>
52 #ifdef FEATURE_IPACM_HAL
53 #include "IPACM_OffloadManager.h"
54 #endif
55
56 /* static member to store the number of total wifi clients within all APs*/
57 int IPACM_Wlan::total_num_wifi_clients = 0;
58
59 int IPACM_Wlan::num_wlan_ap_iface = 0;
60
IPACM_Wlan(int iface_index)61 IPACM_Wlan::IPACM_Wlan(int iface_index) : IPACM_Lan(iface_index)
62 {
63 #define WLAN_AMPDU_DEFAULT_FILTER_RULES 3
64
65 wlan_ap_index = IPACM_Wlan::num_wlan_ap_iface;
66 if(wlan_ap_index < 0 || wlan_ap_index > 1)
67 {
68 IPACMERR("Wlan_ap_index is not correct: %d, not creating instance.\n", wlan_ap_index);
69 if (tx_prop != NULL)
70 {
71 free(tx_prop);
72 }
73 if (rx_prop != NULL)
74 {
75 free(rx_prop);
76 }
77 if (iface_query != NULL)
78 {
79 free(iface_query);
80 }
81 delete this;
82 return;
83 }
84
85 num_wifi_client = 0;
86 header_name_count = 0;
87 wlan_client = NULL;
88 wlan_client_len = 0;
89
90 if(iface_query != NULL)
91 {
92 wlan_client_len = (sizeof(ipa_wlan_client)) + (iface_query->num_tx_props * sizeof(wlan_client_rt_hdl));
93 wlan_client = (ipa_wlan_client *)calloc(IPA_MAX_NUM_WIFI_CLIENTS, wlan_client_len);
94 if (wlan_client == NULL)
95 {
96 IPACMERR("unable to allocate memory\n");
97 return;
98 }
99 IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props);
100 }
101 Nat_App = NatApp::GetInstance();
102 if (Nat_App == NULL)
103 {
104 IPACMERR("unable to get Nat App instance \n");
105 return;
106 }
107
108 IPACM_Wlan::num_wlan_ap_iface++;
109 IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface);
110
111 m_is_guest_ap = false;
112 if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET)
113 {
114 m_is_guest_ap = true;
115 }
116 IPACMDBG_H("%s: guest ap enable: %d \n",
117 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, m_is_guest_ap);
118
119 #ifdef FEATURE_IPA_ANDROID
120 /* set the IPA-client pipe enum */
121 if(ipa_if_cate == WLAN_IF)
122 {
123 #ifdef FEATURE_IPACM_HAL
124 handle_tethering_client(false, IPACM_CLIENT_MAX);
125 #else
126 handle_tethering_client(false, IPACM_CLIENT_WLAN);
127 #endif
128 }
129 #endif
130 return;
131 }
132
133
~IPACM_Wlan()134 IPACM_Wlan::~IPACM_Wlan()
135 {
136 IPACM_EvtDispatcher::deregistr(this);
137 IPACM_IfaceManager::deregistr(this);
138 IPACM_Wlan::num_wlan_ap_iface--;
139 return;
140 }
141
event_callback(ipa_cm_event_id event,void * param)142 void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
143 {
144 if(is_active == false && event != IPA_LAN_DELETE_SELF)
145 {
146 IPACMDBG_H("The interface is no longer active, return.\n");
147 return;
148 }
149
150 int ipa_interface_index;
151 int wlan_index;
152 ipacm_ext_prop* ext_prop;
153 ipacm_event_iface_up_tehter* data_wan_tether;
154 #ifdef FEATURE_IPACM_HAL
155 IPACM_OffloadManager* OffloadMng;
156 #endif
157
158 switch (event)
159 {
160
161 case IPA_WLAN_LINK_DOWN_EVENT:
162 {
163 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
164 ipa_interface_index = iface_ipa_index_query(data->if_index);
165 if (ipa_interface_index == ipa_if_num)
166 {
167 IPACMDBG_H("Received IPA_WLAN_LINK_DOWN_EVENT\n");
168 handle_down_evt();
169 /* reset the AP-iface category to unknown */
170 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat = UNKNOWN_IF;
171 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
172 IPACM_Wlan::total_num_wifi_clients = (IPACM_Wlan::total_num_wifi_clients) - \
173 (num_wifi_client);
174 return;
175 }
176 }
177 break;
178
179 case IPA_PRIVATE_SUBNET_CHANGE_EVENT:
180 {
181 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
182 /* internel event: data->if_index is ipa_if_index */
183 if (data->if_index == ipa_if_num)
184 {
185 IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n");
186 return;
187 }
188 else
189 {
190 IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n");
191 #ifdef FEATURE_IPA_ANDROID
192 handle_private_subnet_android(IPA_IP_v4);
193 #endif
194 IPACMDBG_H(" delete old private subnet rules, use new sets \n");
195 return;
196 }
197 }
198 break;
199
200 case IPA_LAN_DELETE_SELF:
201 {
202 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
203 if(data->if_index == ipa_if_num)
204 {
205 IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface);
206
207 IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n");
208 IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
209 if (IPACM_Iface::ipacmcfg->isEthBridgingSupported())
210 {
211 if(rx_prop != NULL)
212 {
213 free(rx_prop);
214 }
215 if(tx_prop != NULL)
216 {
217 free(tx_prop);
218 }
219 if(iface_query != NULL)
220 {
221 free(iface_query);
222 }
223 }
224 delete this;
225 }
226 break;
227 }
228
229 case IPA_ADDR_ADD_EVENT:
230 {
231 ipacm_event_data_addr *data = (ipacm_event_data_addr *)param;
232 ipa_interface_index = iface_ipa_index_query(data->if_index);
233
234 if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) ||
235 (data->iptype == IPA_IP_v6 &&
236 data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 &&
237 data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) )
238 {
239 IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n");
240 return;
241 }
242
243 if (ipa_interface_index == ipa_if_num)
244 {
245 /* check v4 not setup before, v6 can have 2 iface ip */
246 if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX))
247 || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
248 {
249 IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
250 /* Post event to NAT */
251 if (data->iptype == IPA_IP_v4)
252 {
253 ipacm_cmd_q_data evt_data;
254 ipacm_event_iface_up *info;
255
256 info = (ipacm_event_iface_up *)
257 malloc(sizeof(ipacm_event_iface_up));
258 if (info == NULL)
259 {
260 IPACMERR("Unable to allocate memory\n");
261 return;
262 }
263
264 memcpy(info->ifname, dev_name, IF_NAME_LEN);
265 info->ipv4_addr = data->ipv4_addr;
266 info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask;
267
268 evt_data.event = IPA_HANDLE_WLAN_UP;
269 evt_data.evt_data = (void *)info;
270
271 /* Insert IPA_HANDLE_WLAN_UP to command queue */
272 IPACMDBG_H("posting IPA_HANDLE_WLAN_UP for IPv4 with below information\n");
273 IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n",
274 info->ipv4_addr, info->addr_mask);
275 IPACM_EvtDispatcher::PostEvt(&evt_data);
276 #ifdef FEATURE_IPACM_RESTART
277 /* Query wlan-clients */
278 ipa_query_wlan_client();
279 #endif
280 }
281
282 if(handle_addr_evt(data) == IPACM_FAILURE)
283 {
284 return;
285 }
286
287 #ifdef FEATURE_IPA_ANDROID
288 add_dummy_private_subnet_flt_rule(data->iptype);
289 handle_private_subnet_android(data->iptype);
290 #else
291 handle_private_subnet(data->iptype);
292 #endif
293
294 #ifndef FEATURE_IPACM_HAL
295 if (IPACM_Wan::isWanUP(ipa_if_num))
296 {
297 if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
298 {
299 if(IPACM_Wan::backhaul_mode == Q6_WAN)
300 {
301 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
302 IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4,
303 IPACM_Wan::getXlat_Mux_Id());
304 }
305 else
306 {
307 IPACM_Lan::handle_wan_up(IPA_IP_v4);
308 }
309 }
310 IPACMDBG_H("Finished checking wan_up\n");
311 } else {
312 IPACMDBG_H("Wan_V4 haven't up yet \n");
313 }
314
315 if(IPACM_Wan::isWanUP_V6(ipa_if_num))
316 {
317 if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
318 {
319 memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix));
320 install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
321
322 if(IPACM_Wan::backhaul_mode == Q6_WAN)
323 {
324 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
325 IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
326 }
327 else
328 {
329 IPACM_Lan::handle_wan_up(IPA_IP_v6);
330 }
331 }
332 IPACMDBG_H("Finished checking wan_up_v6\n");
333 } else {
334 IPACMDBG_H("Wan_V6 haven't up yet \n");
335 }
336 #else
337 /* check if Upstream was set before */
338 if (IPACM_Wan::isWanUP(ipa_if_num))
339 {
340 IPACMDBG_H("Upstream was set previously for ipv4, change is_upstream_set flag\n");
341 is_upstream_set[IPA_IP_v4] = true;
342 }
343 if (IPACM_Wan::isWanUP_V6(ipa_if_num))
344 {
345 IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n");
346 is_upstream_set[IPA_IP_v6] = true;
347 }
348 #endif
349 /* checking if SW-RT_enable */
350 if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true)
351 {
352 /* handle software routing enable event*/
353 IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
354 handle_software_routing_enable(false);
355 }
356 }
357 }
358 }
359 break;
360 #ifdef FEATURE_IPA_ANDROID
361 case IPA_HANDLE_WAN_UP_TETHER:
362 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n");
363
364 data_wan_tether = (ipacm_event_iface_up_tehter*)param;
365 if(data_wan_tether == NULL)
366 {
367 IPACMERR("No event data is found.\n");
368 return;
369 }
370 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s xlat_mux_id: %d\n", data_wan_tether->backhaul_type,
371 data_wan_tether->if_index_tether,
372 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name,
373 data_wan_tether->xlat_mux_id);
374 #ifndef FEATURE_IPACM_HAL
375 if (data_wan_tether->if_index_tether != ipa_if_num)
376 {
377 IPACMERR("IPA_HANDLE_WAN_UP_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
378 return;
379 }
380 #endif
381 if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
382 {
383 #ifdef FEATURE_IPACM_HAL
384 if(is_upstream_set[IPA_IP_v4] == false)
385 {
386 IPACMDBG_H("Add upstream for IPv4.\n");
387 is_upstream_set[IPA_IP_v4] = true;
388 if(is_downstream_set[IPA_IP_v4] == true)
389 {
390 IPACMDBG_H("Downstream was set before, adding UL rules.\n");
391 if(data_wan_tether->backhaul_type == Q6_WAN)
392 {
393 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
394 handle_wan_up_ex(ext_prop, IPA_IP_v4,
395 data_wan_tether->xlat_mux_id);
396 } else {
397 handle_wan_up(IPA_IP_v4);
398 }
399 }
400 }
401 #else
402 if(data_wan_tether->backhaul_type == Q6_WAN)
403 {
404 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
405 handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
406 } else {
407 handle_wan_up(IPA_IP_v4);
408 }
409 #endif
410 }
411 break;
412
413 case IPA_HANDLE_WAN_UP_V6_TETHER:
414 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n");
415
416 data_wan_tether = (ipacm_event_iface_up_tehter*)param;
417 if(data_wan_tether == NULL)
418 {
419 IPACMERR("No event data is found.\n");
420 return;
421 }
422 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
423 data_wan_tether->if_index_tether,
424 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
425 #ifndef FEATURE_IPACM_HAL
426 if (data_wan_tether->if_index_tether != ipa_if_num)
427 {
428 IPACMERR("IPA_HANDLE_WAN_UP_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
429 return;
430 }
431 #endif
432 if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
433 {
434 #ifdef FEATURE_IPACM_HAL
435 if(is_upstream_set[IPA_IP_v6] == false)
436 {
437 IPACMDBG_H("Add upstream for IPv6.\n");
438 is_upstream_set[IPA_IP_v6] = true;
439
440 if(is_downstream_set[IPA_IP_v6] == true)
441 {
442 IPACMDBG_H("Downstream was set before, adding UL rules.\n");
443 memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix));
444 install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
445 if(data_wan_tether->backhaul_type == Q6_WAN)
446 {
447 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
448 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
449 }
450 else
451 {
452 handle_wan_up(IPA_IP_v6);
453 }
454 }
455 }
456 #else
457 if(data_wan_tether->backhaul_type == Q6_WAN)
458 {
459 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
460 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
461 }
462 else
463 {
464 handle_wan_up(IPA_IP_v6);
465 }
466 #endif
467 }
468 break;
469
470 case IPA_HANDLE_WAN_DOWN_TETHER:
471 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n");
472 data_wan_tether = (ipacm_event_iface_up_tehter*)param;
473 if(data_wan_tether == NULL)
474 {
475 IPACMERR("No event data is found.\n");
476 return;
477 }
478 if(rx_prop == NULL)
479 {
480 IPACMERR("No rx prop.\n");
481 return;
482 }
483 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
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_DOWN_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] == true)
497 {
498 IPACMDBG_H("Del upstream for IPv4.\n");
499 is_upstream_set[IPA_IP_v4] = false;
500 if(is_downstream_set[IPA_IP_v4] == true)
501 {
502 IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
503 handle_wan_down(data_wan_tether->backhaul_type);
504 }
505 }
506 #else
507 handle_wan_down(data_wan_tether->backhaul_type);
508 #endif
509 }
510 break;
511
512 case IPA_HANDLE_WAN_DOWN_V6_TETHER:
513 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n");
514 data_wan_tether = (ipacm_event_iface_up_tehter*)param;
515 if(data_wan_tether == NULL)
516 {
517 IPACMERR("No event data is found.\n");
518 return;
519 }
520 if(rx_prop == NULL)
521 {
522 IPACMERR("No rx prop.\n");
523 return;
524 }
525 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
526 data_wan_tether->if_index_tether,
527 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
528 #ifndef FEATURE_IPACM_HAL
529 if (data_wan_tether->if_index_tether != ipa_if_num)
530 {
531 IPACMERR("IPA_HANDLE_WAN_DOWN_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
532 return;
533 }
534 #endif
535 if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
536 {
537 #ifdef FEATURE_IPACM_HAL
538 if(is_upstream_set[IPA_IP_v6] == true)
539 {
540 IPACMDBG_H("Del upstream for IPv6.\n");
541 is_upstream_set[IPA_IP_v6] = false;
542 if(is_downstream_set[IPA_IP_v6] == true)
543 {
544 IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
545 /* reset usb-client ipv6 rt-rules */
546 handle_wlan_client_reset_rt(IPA_IP_v6);
547 handle_wan_down_v6(data_wan_tether->backhaul_type);
548 }
549 }
550 #else
551 /* reset usb-client ipv6 rt-rules */
552 handle_wlan_client_reset_rt(IPA_IP_v6);
553 handle_wan_down_v6(data_wan_tether->backhaul_type);
554 #endif
555 }
556 break;
557
558 case IPA_DOWNSTREAM_ADD:
559 {
560 ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
561 ipa_interface_index = iface_ipa_index_query(data->if_index);
562 if(ipa_interface_index == ipa_if_num)
563 {
564 IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
565 #ifdef FEATURE_IPA_ANDROID
566 if (IPACM_Wan::isXlat() && (data->prefix.iptype == IPA_IP_v4))
567 {
568 /* indicate v4-offload */
569 IPACM_OffloadManager::num_offload_v4_tethered_iface++;
570 IPACMDBG_H("in xlat: update num_offload_v4_tethered_iface %d\n", IPACM_OffloadManager::num_offload_v4_tethered_iface);
571
572 /* xlat not support for 2st tethered iface */
573 if (IPACM_OffloadManager::num_offload_v4_tethered_iface > 1)
574 {
575 IPACMDBG_H("Not support 2st downstream iface %s for xlat, cur: %d\n", dev_name,
576 IPACM_OffloadManager::num_offload_v4_tethered_iface);
577 return;
578 }
579 }
580
581 IPACMDBG_H(" support downstream iface %s, cur %d\n", dev_name,
582 IPACM_OffloadManager::num_offload_v4_tethered_iface);
583 #endif
584 if(data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false)
585 {
586 IPACMDBG_H("Add downstream for IP iptype %d.\n", data->prefix.iptype);
587 is_downstream_set[data->prefix.iptype] = true;
588 memcpy(&prefix[data->prefix.iptype], &data->prefix,
589 sizeof(prefix[data->prefix.iptype]));
590
591 if (is_upstream_set[data->prefix.iptype] == true)
592 {
593 IPACMDBG_H("Upstream was set before, adding modem UL rules.\n");
594 if(ip_type == IPA_IP_MAX || ip_type == data->prefix.iptype)
595 {
596 if (data->prefix.iptype == IPA_IP_v6) /* ipv6 only */
597 {
598 /* Only offload clients has same prefix as Android gave */
599 ipv6_prefix[0] = data->prefix.v6Addr[0];
600 ipv6_prefix[1] = data->prefix.v6Addr[1];
601 IPACMDBG_H("ipv6_prefix0x%x:%x\n", ipv6_prefix[0], ipv6_prefix[1]);
602 install_ipv6_prefix_flt_rule(ipv6_prefix);
603 }
604
605 if (IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
606 {
607 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
608 if (data->prefix.iptype == IPA_IP_v4)
609 {
610 IPACMDBG_H("check getXlat_Mux_Id:%d\n", IPACM_Wan::getXlat_Mux_Id());
611 handle_wan_up_ex(ext_prop, data->prefix.iptype,
612 IPACM_Wan::getXlat_Mux_Id());
613 }
614 else {
615 handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
616 }
617 } else {
618 handle_wan_up(data->prefix.iptype); /* STA */
619 }
620 }
621 }
622 }
623 }
624 break;
625 }
626
627 case IPA_DOWNSTREAM_DEL:
628 {
629 ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
630 ipa_interface_index = iface_ipa_index_query(data->if_index);
631 if(ipa_interface_index == ipa_if_num)
632 {
633 IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
634 if(is_downstream_set[data->prefix.iptype] == true)
635 {
636 IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
637 is_downstream_set[data->prefix.iptype] = false;
638
639 if(is_upstream_set[data->prefix.iptype] == true)
640 {
641 IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
642 if (data->prefix.iptype == IPA_IP_v4)
643 {
644 handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
645 } else {
646 handle_wlan_client_reset_rt(IPA_IP_v6);
647 handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
648 }
649 }
650 }
651 }
652 break;
653 }
654 #else
655 case IPA_HANDLE_WAN_UP:
656 IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
657
658 ipacm_event_iface_up* data_wan = (ipacm_event_iface_up*)param;
659 if(data_wan == NULL)
660 {
661 IPACMERR("No event data is found.\n");
662 return;
663 }
664 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
665 if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
666 {
667 if(data_wan->backhaul_type == Q6_WAN)
668 {
669 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
670 IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
671 }
672 else
673 {
674 IPACM_Lan::handle_wan_up(IPA_IP_v4);
675 }
676 }
677 break;
678
679 case IPA_HANDLE_WAN_UP_V6:
680 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6 event\n");
681
682 data_wan = (ipacm_event_iface_up*)param;
683 if(data_wan == NULL)
684 {
685 IPACMERR("No event data is found.\n");
686 return;
687 }
688 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
689 if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
690 {
691 memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix));
692 install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
693
694 if(data_wan->backhaul_type == Q6_WAN)
695 {
696 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
697 IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
698 }
699 else
700 {
701 IPACM_Lan::handle_wan_up(IPA_IP_v6);
702 }
703 }
704 break;
705
706 case IPA_HANDLE_WAN_DOWN:
707 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n");
708 data_wan = (ipacm_event_iface_up*)param;
709 if(data_wan == NULL)
710 {
711 IPACMERR("No event data is found.\n");
712 return;
713 }
714 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
715 if (rx_prop != NULL)
716 {
717 if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
718 {
719 handle_wan_down(data_wan->backhaul_type);
720 }
721 }
722 break;
723
724 case IPA_HANDLE_WAN_DOWN_V6:
725 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6 event\n");
726 data_wan = (ipacm_event_iface_up*)param;
727 if(data_wan == NULL)
728 {
729 IPACMERR("No event data is found.\n");
730 return;
731 }
732 /* clean up v6 RT rules*/
733 IPACMDBG_H("Received IPA_WAN_V6_DOWN in WLAN-instance and need clean up client IPv6 address \n");
734 /* reset wifi-client ipv6 rt-rules */
735 handle_wlan_client_reset_rt(IPA_IP_v6);
736 IPACMDBG_H("Backhaul is sta mode ? %d\n", data_wan->backhaul_type);
737 if (rx_prop != NULL)
738 {
739 if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
740 {
741 handle_wan_down_v6(data_wan->backhaul_type);
742 }
743 }
744 break;
745 #endif
746
747 case IPA_WLAN_CLIENT_ADD_EVENT_EX:
748 {
749 ipacm_event_data_wlan_ex *data = (ipacm_event_data_wlan_ex *)param;
750 ipa_interface_index = iface_ipa_index_query(data->if_index);
751 if (ipa_interface_index == ipa_if_num)
752 {
753 int i;
754 for(i=0; i<data->num_of_attribs; i++)
755 {
756 if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
757 {
758 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->attribs[i].u.mac_addr, NULL, NULL,
759 IPA_CLIENT_MAX);
760 break;
761 }
762 }
763 IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n");
764 handle_wlan_client_init_ex(data);
765 }
766 }
767 break;
768
769 case IPA_WIGIG_CLIENT_ADD_EVENT:
770 {
771 ipacm_event_data_mac_ep *data = (ipacm_event_data_mac_ep *)param;
772 ipa_interface_index = iface_ipa_index_query(data->if_index);
773 if(ipa_interface_index == ipa_if_num)
774 {
775 IPACMDBG_H("Received IPA_WIGIG_CLIENT_ADD_EVENT\n");
776 handle_wigig_client_add(data);
777 }
778 }
779 break;
780
781 case IPA_WLAN_CLIENT_DEL_EVENT:
782 {
783 ipacm_event_data_mac *data = (ipacm_event_data_mac *)param;
784 ipa_interface_index = iface_ipa_index_query(data->if_index);
785 if (ipa_interface_index == ipa_if_num)
786 {
787 IPACMDBG_H("Received IPA_WLAN_CLIENT_DEL_EVENT\n");
788 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_DEL, IPA_IP_MAX, data->mac_addr, NULL, NULL, IPA_CLIENT_MAX);
789 handle_wlan_client_down_evt(data->mac_addr);
790 }
791 }
792 break;
793
794 case IPA_WLAN_CLIENT_POWER_SAVE_EVENT:
795 {
796 ipacm_event_data_mac *data = (ipacm_event_data_mac *)param;
797 ipa_interface_index = iface_ipa_index_query(data->if_index);
798 if (ipa_interface_index == ipa_if_num)
799 {
800 IPACMDBG_H("Received IPA_WLAN_CLIENT_POWER_SAVE_EVENT\n");
801 handle_wlan_client_pwrsave(data->mac_addr);
802 }
803 }
804 break;
805
806 case IPA_WLAN_CLIENT_RECOVER_EVENT:
807 {
808 ipacm_event_data_mac *data = (ipacm_event_data_mac *)param;
809 ipa_interface_index = iface_ipa_index_query(data->if_index);
810 if (ipa_interface_index == ipa_if_num)
811 {
812 IPACMDBG_H("Received IPA_WLAN_CLIENT_RECOVER_EVENT\n");
813
814 wlan_index = get_wlan_client_index(data->mac_addr);
815 if ((wlan_index != IPACM_INVALID_INDEX) &&
816 (get_client_memptr(wlan_client, wlan_index)->power_save_set == true))
817 {
818
819 IPACMDBG_H("change wlan client out of power safe mode \n");
820 get_client_memptr(wlan_client, wlan_index)->power_save_set = false;
821
822 /* First add route rules and then nat rules */
823 if(get_client_memptr(wlan_client, wlan_index)->ipv4_set == true) /* for ipv4 */
824 {
825 IPACMDBG_H("recover client index(%d):ipv4 address: 0x%x\n",
826 wlan_index,
827 get_client_memptr(wlan_client, wlan_index)->v4_addr);
828
829 IPACMDBG_H("Adding Route Rules\n");
830 handle_wlan_client_route_rule(data->mac_addr, IPA_IP_v4);
831 IPACMDBG_H("Adding Nat Rules\n");
832 Nat_App->ResetPwrSaveIf(get_client_memptr(wlan_client, wlan_index)->v4_addr);
833 }
834
835 if(get_client_memptr(wlan_client, wlan_index)->ipv6_set != 0) /* for ipv6 */
836 {
837 handle_wlan_client_route_rule(data->mac_addr, IPA_IP_v6);
838 }
839 }
840 }
841 }
842 break;
843
844 case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
845 {
846 ipacm_event_data_all *data = (ipacm_event_data_all *)param;
847 ipa_interface_index = iface_ipa_index_query(data->if_index);
848 if (ipa_interface_index == ipa_if_num)
849 {
850 IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT\n");
851 if (handle_wlan_client_ipaddr(data) == IPACM_FAILURE)
852 {
853 return;
854 }
855
856 handle_wlan_client_route_rule(data->mac_addr, data->iptype);
857 if(data->iptype == IPA_IP_v4)
858 {
859 /* Add NAT rules after ipv4 RT rules are set */
860 CtList->HandleNeighIpAddrAddEvt(data);
861 //Nat_App->ResetPwrSaveIf(data->ipv4_addr);
862 }
863 }
864 }
865 break;
866 /* handle software routing enable event, iface will update softwarerouting_act to true*/
867 case IPA_SW_ROUTING_ENABLE:
868 IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n");
869 IPACM_Iface::handle_software_routing_enable(false);
870 break;
871
872 /* handle software routing disable event, iface will update softwarerouting_act to false*/
873 case IPA_SW_ROUTING_DISABLE:
874 IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n");
875 IPACM_Iface::handle_software_routing_disable(false);
876 break;
877
878 case IPA_WLAN_SWITCH_TO_SCC:
879 IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n");
880 if(ip_type == IPA_IP_MAX)
881 {
882 handle_SCC_MCC_switch(IPA_IP_v4);
883 handle_SCC_MCC_switch(IPA_IP_v6);
884 }
885 else
886 {
887 handle_SCC_MCC_switch(ip_type);
888 }
889 eth_bridge_post_event(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, IPA_IP_MAX, NULL, NULL, NULL, IPA_CLIENT_MAX);
890 break;
891
892 case IPA_WLAN_SWITCH_TO_MCC:
893 IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n");
894 if(ip_type == IPA_IP_MAX)
895 {
896 handle_SCC_MCC_switch(IPA_IP_v4);
897 handle_SCC_MCC_switch(IPA_IP_v6);
898 }
899 else
900 {
901 handle_SCC_MCC_switch(ip_type);
902 }
903 eth_bridge_post_event(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, IPA_IP_MAX, NULL, NULL, NULL, IPA_CLIENT_MAX);
904 break;
905
906 case IPA_CRADLE_WAN_MODE_SWITCH:
907 {
908 IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n");
909 ipacm_event_cradle_wan_mode* wan_mode = (ipacm_event_cradle_wan_mode*)param;
910 if(wan_mode == NULL)
911 {
912 IPACMERR("Event data is empty.\n");
913 return;
914 }
915
916 if(wan_mode->cradle_wan_mode == BRIDGE)
917 {
918 handle_cradle_wan_mode_switch(true);
919 }
920 else
921 {
922 handle_cradle_wan_mode_switch(false);
923 }
924 }
925 break;
926 case IPA_CFG_CHANGE_EVENT:
927 {
928 IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT event for %s with new wlan-mode: %s old wlan-mode: %s\n",
929 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name,
930 (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == 0) ? "full" : "internet",
931 (m_is_guest_ap == true) ? "internet" : "full");
932 /* Add Natting iface to IPACM_Config if there is Rx/Tx property */
933 if (rx_prop != NULL || tx_prop != NULL)
934 {
935 IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
936 IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_MAX);
937 }
938
939 if (m_is_guest_ap == true && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == FULL))
940 {
941 m_is_guest_ap = false;
942 IPACMDBG_H("wlan mode is switched to full access mode. \n");
943 eth_bridge_handle_wlan_mode_switch();
944 }
945 else if (m_is_guest_ap == false && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET))
946 {
947 m_is_guest_ap = true;
948 IPACMDBG_H("wlan mode is switched to internet only access mode. \n");
949 eth_bridge_handle_wlan_mode_switch();
950 }
951 else
952 {
953 IPACMDBG_H("No change in %s access mode. \n",
954 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
955 }
956 }
957 break;
958 case IPA_TETHERING_STATS_UPDATE_EVENT:
959 {
960 IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
961 if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
962 {
963 if(IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
964 {
965 ipa_get_data_stats_resp_msg_v01 *data = (ipa_get_data_stats_resp_msg_v01 *)param;
966 if (data->ipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01)
967 {
968 IPACMERR("not valid pipe stats\n");
969 return;
970 }
971 handle_tethering_stats_event(data);
972 };
973 }
974 }
975 break;
976 #ifdef FEATURE_IPACM_HAL
977 /* WA for WLAN to clean up NAT instance during SSR */
978 case IPA_SSR_NOTICE:
979 {
980 IPACMDBG_H("Received IPA_SSR_NOTICE event.\n");
981 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
982 }
983 break;
984 case IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE:
985 {
986 IPACMDBG_H("Received IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE.\n");
987
988 /* internal push add_downstream event in cache */
989 OffloadMng = IPACM_OffloadManager::GetInstance();
990 if (OffloadMng == NULL) {
991 IPACMERR("failed to get IPACM_OffloadManager instance !\n");
992 } else {
993 IPACMDBG_H("Update iface %s add_downstream cache events\n", dev_name);
994 if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
995 {
996 OffloadMng->push_framework_event(dev_name, prefix[IPA_IP_v4]);
997 }
998 else if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
999 {
1000 OffloadMng->push_framework_event(dev_name, prefix[IPA_IP_v6]);
1001 }
1002 }
1003 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
1004 }
1005 break;
1006 #endif
1007 default:
1008 break;
1009 }
1010 return;
1011 }
1012
1013
handle_wigig_client_add(ipacm_event_data_mac_ep * data)1014 int IPACM_Wlan::handle_wigig_client_add(ipacm_event_data_mac_ep *data)
1015 {
1016 ipacm_event_data_wlan_ex *wlan_data;
1017 int ret = IPACM_SUCCESS;
1018
1019 wlan_data = (ipacm_event_data_wlan_ex *)malloc(sizeof(ipa_wlan_msg_ex) + sizeof(ipa_wlan_hdr_attrib_val));
1020 if(wlan_data == NULL)
1021 {
1022 IPACMERR("Unable to allocate memory\n");
1023 return IPACM_FAILURE;
1024 }
1025
1026 wlan_data->num_of_attribs = 1;
1027 wlan_data->if_index = data->if_index;
1028 wlan_data->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
1029 wlan_data->attribs[0].offset = 0;
1030 memcpy(wlan_data->attribs[0].u.mac_addr, data->mac_addr, sizeof(wlan_data->attribs[0].u.mac_addr));
1031
1032 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr, NULL, NULL, data->client);
1033 handle_wlan_client_init_ex(wlan_data);
1034
1035 int idx = get_wlan_client_index(data->mac_addr);
1036
1037 if(idx == IPACM_INVALID_INDEX)
1038 {
1039 IPACMERR("wlan client not attached\n");
1040 ret = IPACM_FAILURE;
1041 goto fail;
1042 }
1043
1044 /* store client pipe hdl for the time we add the DL header */
1045 get_client_memptr(wlan_client, idx)->wigig_ipa_client = data->client;
1046 fail:
1047 free(wlan_data);
1048 return ret;
1049 }
1050
1051 /* handle wifi client initial,copy all partial headers (tx property) */
handle_wlan_client_init_ex(ipacm_event_data_wlan_ex * data)1052 int IPACM_Wlan::handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data)
1053 {
1054
1055 #define WLAN_IFACE_INDEX_LEN 2
1056
1057 int res = IPACM_SUCCESS, len = 0, i, evt_size;
1058 char index[WLAN_IFACE_INDEX_LEN];
1059 struct ipa_ioc_copy_hdr sCopyHeader;
1060 struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
1061 uint32_t cnt;
1062
1063 /* start of adding header */
1064 IPACMDBG_H("Wifi client number for this iface: %d & total number of wlan clients: %d\n",
1065 num_wifi_client,IPACM_Wlan::total_num_wifi_clients);
1066
1067 if ((num_wifi_client >= IPA_MAX_NUM_WIFI_CLIENTS) ||
1068 (IPACM_Wlan::total_num_wifi_clients >= IPA_MAX_NUM_WIFI_CLIENTS))
1069 {
1070 IPACMERR("Reached maximum number of wlan clients\n");
1071 return IPACM_FAILURE;
1072 }
1073
1074 IPACMDBG_H("Wifi client number: %d\n", num_wifi_client);
1075
1076 /* add header to IPA */
1077 if(tx_prop != NULL)
1078 {
1079 len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
1080 pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
1081 if (pHeaderDescriptor == NULL)
1082 {
1083 IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
1084 return IPACM_FAILURE;
1085 }
1086
1087 evt_size = sizeof(ipacm_event_data_wlan_ex) + data->num_of_attribs * sizeof(struct ipa_wlan_hdr_attrib_val);
1088 get_client_memptr(wlan_client, num_wifi_client)->p_hdr_info = (ipacm_event_data_wlan_ex*)malloc(evt_size);
1089 memcpy(get_client_memptr(wlan_client, num_wifi_client)->p_hdr_info, data, evt_size);
1090
1091 /* copy partial header for v4*/
1092 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
1093 {
1094 if(tx_prop->tx[cnt].ip==IPA_IP_v4)
1095 {
1096 IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt);
1097 memset(&sCopyHeader, 0, sizeof(sCopyHeader));
1098 memcpy(sCopyHeader.name,
1099 tx_prop->tx[cnt].hdr_name,
1100 sizeof(sCopyHeader.name));
1101
1102 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
1103 if (m_header.CopyHeader(&sCopyHeader) == false)
1104 {
1105 PERROR("ioctl copy header failed");
1106 res = IPACM_FAILURE;
1107 goto fail;
1108 }
1109
1110 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
1111 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
1112 {
1113 IPACMERR("header oversize\n");
1114 res = IPACM_FAILURE;
1115 goto fail;
1116 }
1117 else
1118 {
1119 memcpy(pHeaderDescriptor->hdr[0].hdr,
1120 sCopyHeader.hdr,
1121 sCopyHeader.hdr_len);
1122 }
1123
1124 for(i = 0; i < data->num_of_attribs; i++)
1125 {
1126 if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
1127 {
1128 memcpy(get_client_memptr(wlan_client, num_wifi_client)->mac,
1129 data->attribs[i].u.mac_addr,
1130 sizeof(get_client_memptr(wlan_client, num_wifi_client)->mac));
1131
1132 /* copy client mac_addr to partial header */
1133 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
1134 get_client_memptr(wlan_client, num_wifi_client)->mac,
1135 IPA_MAC_ADDR_SIZE);
1136 /* replace src mac to bridge mac_addr if any */
1137 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
1138 {
1139 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset+IPA_MAC_ADDR_SIZE],
1140 IPACM_Iface::ipacmcfg->bridge_mac,
1141 IPA_MAC_ADDR_SIZE);
1142 IPACMDBG_H("device is in bridge mode \n");
1143 }
1144
1145 }
1146 else if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
1147 {
1148 /* copy client id to header */
1149 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
1150 &data->attribs[i].u.sta_id, sizeof(data->attribs[i].u.sta_id));
1151 }
1152 else
1153 {
1154 IPACMDBG_H("The attribute type is not expected!\n");
1155 }
1156 }
1157
1158 pHeaderDescriptor->commit = true;
1159 pHeaderDescriptor->num_hdrs = 1;
1160
1161 memset(pHeaderDescriptor->hdr[0].name, 0,
1162 sizeof(pHeaderDescriptor->hdr[0].name));
1163
1164 snprintf(index,sizeof(index), "%d", ipa_if_num);
1165 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
1166 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1167
1168 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WLAN_PARTIAL_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1169 {
1170 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1171 res = IPACM_FAILURE;
1172 goto fail;
1173 }
1174 snprintf(index,sizeof(index), "%d", header_name_count);
1175 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1176 {
1177 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1178 res = IPACM_FAILURE;
1179 goto fail;
1180 }
1181
1182
1183 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
1184 pHeaderDescriptor->hdr[0].hdr_hdl = -1;
1185 pHeaderDescriptor->hdr[0].is_partial = 0;
1186 pHeaderDescriptor->hdr[0].status = -1;
1187
1188 if (m_header.AddHeader(pHeaderDescriptor) == false ||
1189 pHeaderDescriptor->hdr[0].status != 0)
1190 {
1191 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
1192 res = IPACM_FAILURE;
1193 goto fail;
1194 }
1195
1196 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
1197 IPACMDBG_H("client(%d) v4 full header name:%s header handle:(0x%x)\n",
1198 num_wifi_client,
1199 pHeaderDescriptor->hdr[0].name,
1200 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v4);
1201 get_client_memptr(wlan_client, num_wifi_client)->ipv4_header_set=true;
1202 break;
1203 }
1204 }
1205
1206 /* copy partial header for v6*/
1207 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
1208 {
1209 if(tx_prop->tx[cnt].ip==IPA_IP_v6)
1210 {
1211 IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt);
1212 memset(&sCopyHeader, 0, sizeof(sCopyHeader));
1213 memcpy(sCopyHeader.name,
1214 tx_prop->tx[cnt].hdr_name,
1215 sizeof(sCopyHeader.name));
1216
1217 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
1218 if (m_header.CopyHeader(&sCopyHeader) == false)
1219 {
1220 PERROR("ioctl copy header failed");
1221 res = IPACM_FAILURE;
1222 goto fail;
1223 }
1224
1225 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
1226 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
1227 {
1228 IPACMERR("header oversize\n");
1229 res = IPACM_FAILURE;
1230 goto fail;
1231 }
1232 else
1233 {
1234 memcpy(pHeaderDescriptor->hdr[0].hdr,
1235 sCopyHeader.hdr,
1236 sCopyHeader.hdr_len);
1237 }
1238
1239 for(i = 0; i < data->num_of_attribs; i++)
1240 {
1241 if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
1242 {
1243 memcpy(get_client_memptr(wlan_client, num_wifi_client)->mac,
1244 data->attribs[i].u.mac_addr,
1245 sizeof(get_client_memptr(wlan_client, num_wifi_client)->mac));
1246
1247 /* copy client mac_addr to partial header */
1248 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
1249 get_client_memptr(wlan_client, num_wifi_client)->mac,
1250 IPA_MAC_ADDR_SIZE);
1251
1252 /* replace src mac to bridge mac_addr if any */
1253 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
1254 {
1255 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset+IPA_MAC_ADDR_SIZE],
1256 IPACM_Iface::ipacmcfg->bridge_mac,
1257 IPA_MAC_ADDR_SIZE);
1258 IPACMDBG_H("device is in bridge mode \n");
1259 }
1260 }
1261 else if (data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
1262 {
1263 /* copy client id to header */
1264 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
1265 &data->attribs[i].u.sta_id, sizeof(data->attribs[i].u.sta_id));
1266 }
1267 else
1268 {
1269 IPACMDBG_H("The attribute type is not expected!\n");
1270 }
1271 }
1272
1273 pHeaderDescriptor->commit = true;
1274 pHeaderDescriptor->num_hdrs = 1;
1275
1276 memset(pHeaderDescriptor->hdr[0].name, 0,
1277 sizeof(pHeaderDescriptor->hdr[0].name));
1278
1279 snprintf(index,sizeof(index), "%d", ipa_if_num);
1280 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
1281 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1282 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WLAN_PARTIAL_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1283 {
1284 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1285 res = IPACM_FAILURE;
1286 goto fail;
1287 }
1288
1289 snprintf(index,sizeof(index), "%d", header_name_count);
1290 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1291 {
1292 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1293 res = IPACM_FAILURE;
1294 goto fail;
1295 }
1296
1297 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
1298 pHeaderDescriptor->hdr[0].hdr_hdl = -1;
1299 pHeaderDescriptor->hdr[0].is_partial = 0;
1300 pHeaderDescriptor->hdr[0].status = -1;
1301
1302 if (m_header.AddHeader(pHeaderDescriptor) == false ||
1303 pHeaderDescriptor->hdr[0].status != 0)
1304 {
1305 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
1306 res = IPACM_FAILURE;
1307 goto fail;
1308 }
1309
1310 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
1311 IPACMDBG_H("client(%d) v6 full header name:%s header handle:(0x%x)\n",
1312 num_wifi_client,
1313 pHeaderDescriptor->hdr[0].name,
1314 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v6);
1315
1316 get_client_memptr(wlan_client, num_wifi_client)->ipv6_header_set=true;
1317 break;
1318 }
1319 }
1320
1321 /* initialize wifi client*/
1322 get_client_memptr(wlan_client, num_wifi_client)->route_rule_set_v4 = false;
1323 get_client_memptr(wlan_client, num_wifi_client)->route_rule_set_v6 = 0;
1324 get_client_memptr(wlan_client, num_wifi_client)->ipv4_set = false;
1325 get_client_memptr(wlan_client, num_wifi_client)->ipv6_set = 0;
1326 get_client_memptr(wlan_client, num_wifi_client)->power_save_set=false;
1327 num_wifi_client++;
1328 header_name_count++; //keep increasing header_name_count
1329 IPACM_Wlan::total_num_wifi_clients++;
1330 res = IPACM_SUCCESS;
1331 IPACMDBG_H("Wifi client number: %d\n", num_wifi_client);
1332 }
1333 else
1334 {
1335 return res;
1336 }
1337
1338 fail:
1339 free(pHeaderDescriptor);
1340 return res;
1341 }
1342
1343 /*handle wifi client */
handle_wlan_client_ipaddr(ipacm_event_data_all * data)1344 int IPACM_Wlan::handle_wlan_client_ipaddr(ipacm_event_data_all *data)
1345 {
1346 int clnt_indx;
1347 int v6_num;
1348 uint32_t ipv6_link_local_prefix = 0xFE800000;
1349 uint32_t ipv6_link_local_prefix_mask = 0xFFC00000;
1350
1351 IPACMDBG_H("number of wifi clients: %d\n", num_wifi_client);
1352 IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1353 data->mac_addr[0],
1354 data->mac_addr[1],
1355 data->mac_addr[2],
1356 data->mac_addr[3],
1357 data->mac_addr[4],
1358 data->mac_addr[5]);
1359
1360 clnt_indx = get_wlan_client_index(data->mac_addr);
1361
1362 if (clnt_indx == IPACM_INVALID_INDEX)
1363 {
1364 IPACMERR("wlan client not found/attached \n");
1365 return IPACM_FAILURE;
1366 }
1367
1368 IPACMDBG_H("Ip-type received %d\n", data->iptype);
1369 if (data->iptype == IPA_IP_v4)
1370 {
1371 IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr);
1372 if (data->ipv4_addr != 0) /* not 0.0.0.0 */
1373 {
1374 if (get_client_memptr(wlan_client, clnt_indx)->ipv4_set == false)
1375 {
1376 get_client_memptr(wlan_client, clnt_indx)->v4_addr = data->ipv4_addr;
1377 get_client_memptr(wlan_client, clnt_indx)->ipv4_set = true;
1378 }
1379 else
1380 {
1381 /* check if client got new IPv4 address*/
1382 if(data->ipv4_addr == get_client_memptr(wlan_client, clnt_indx)->v4_addr)
1383 {
1384 IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx);
1385 return IPACM_FAILURE;
1386 }
1387 else
1388 {
1389 IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
1390 /* delete NAT rules first */
1391 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clnt_indx)->v4_addr);
1392 delete_default_qos_rtrules(clnt_indx, IPA_IP_v4);
1393 get_client_memptr(wlan_client, clnt_indx)->route_rule_set_v4 = false;
1394 get_client_memptr(wlan_client, clnt_indx)->v4_addr = data->ipv4_addr;
1395 }
1396 }
1397 }
1398 else
1399 {
1400 IPACMDBG_H("Invalid client IPv4 address \n");
1401 return IPACM_FAILURE;
1402 }
1403 }
1404 else
1405 {
1406 if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
1407 (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) /* check if all 0 not valid ipv6 address */
1408 {
1409 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]);
1410 if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) &&
1411 memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0)
1412 {
1413 IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n");
1414 IPACMDBG_H("ipv6 address: 0x%x:%x ipv6_prefix0x%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], ipv6_prefix[0], ipv6_prefix[1]);
1415 return IPACM_FAILURE;
1416 }
1417
1418 if(get_client_memptr(wlan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
1419 {
1420
1421 for(v6_num=0;v6_num < get_client_memptr(wlan_client, clnt_indx)->ipv6_set;v6_num++)
1422 {
1423 if( data->ipv6_addr[0] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][0] &&
1424 data->ipv6_addr[1] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][1] &&
1425 data->ipv6_addr[2]== get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][2] &&
1426 data->ipv6_addr[3] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][3])
1427 {
1428 IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx);
1429 return IPACM_FAILURE; /* not setup the RT rules*/
1430 break;
1431 }
1432 }
1433
1434 /* not see this ipv6 before for wifi client*/
1435 get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0];
1436 get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1];
1437 get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2];
1438 get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3];
1439 get_client_memptr(wlan_client, clnt_indx)->ipv6_set++;
1440 }
1441 else
1442 {
1443 IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx);
1444 return IPACM_FAILURE; /* not setup the RT rules*/
1445 }
1446 }
1447 else
1448 {
1449 IPACMDBG_H("IPV6 address is invalid\n");
1450 return IPACM_FAILURE;
1451 }
1452 }
1453
1454 return IPACM_SUCCESS;
1455 }
1456
1457 /*handle wifi client routing rule*/
handle_wlan_client_route_rule(uint8_t * mac_addr,ipa_ip_type iptype)1458 int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype)
1459 {
1460 struct ipa_ioc_add_rt_rule *rt_rule;
1461 struct ipa_rt_rule_add *rt_rule_entry;
1462 uint32_t tx_index;
1463 int wlan_index,v6_num;
1464 const int NUM = 1;
1465 bool result;
1466
1467 if(tx_prop == NULL)
1468 {
1469 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
1470 return IPACM_SUCCESS;
1471 }
1472
1473 IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1474 mac_addr[0], mac_addr[1], mac_addr[2],
1475 mac_addr[3], mac_addr[4], mac_addr[5]);
1476
1477 wlan_index = get_wlan_client_index(mac_addr);
1478 if (wlan_index == IPACM_INVALID_INDEX)
1479 {
1480 IPACMDBG_H("wlan client not found/attached \n");
1481 return IPACM_SUCCESS;
1482 }
1483
1484 /* during power_save mode, even receive IP_ADDR_ADD, not setting RT rules*/
1485 if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true)
1486 {
1487 IPACMDBG_H("wlan client is in power safe mode \n");
1488 return IPACM_SUCCESS;
1489 }
1490
1491 if (iptype==IPA_IP_v4)
1492 {
1493 IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", wlan_index, iptype,
1494 get_client_memptr(wlan_client, wlan_index)->ipv4_set,
1495 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4);
1496 }
1497 else
1498 {
1499 IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wlan_index, iptype,
1500 get_client_memptr(wlan_client, wlan_index)->ipv6_set,
1501 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6);
1502 }
1503
1504
1505 /* Add default Qos routing rules if not set yet */
1506 if ((iptype == IPA_IP_v4
1507 && get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 == false
1508 && get_client_memptr(wlan_client, wlan_index)->ipv4_set == true)
1509 || (iptype == IPA_IP_v6
1510 && get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 < get_client_memptr(wlan_client, wlan_index)->ipv6_set
1511 ))
1512 {
1513 rt_rule = (struct ipa_ioc_add_rt_rule *)
1514 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
1515 NUM * sizeof(struct ipa_rt_rule_add));
1516
1517 if (rt_rule == NULL)
1518 {
1519 PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n");
1520 return IPACM_FAILURE;
1521 }
1522
1523 rt_rule->commit = 1;
1524 rt_rule->num_rules = (uint8_t)NUM;
1525 rt_rule->ip = iptype;
1526
1527
1528 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
1529 {
1530
1531 if(iptype != tx_prop->tx[tx_index].ip)
1532 {
1533 IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n",
1534 tx_index, tx_prop->tx[tx_index].ip,iptype);
1535 continue;
1536 }
1537
1538 rt_rule_entry = &rt_rule->rules[0];
1539 rt_rule_entry->at_rear = 0;
1540
1541 if (iptype == IPA_IP_v4)
1542 {
1543 IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wlan_index,
1544 get_client_memptr(wlan_client, wlan_index)->v4_addr);
1545
1546 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
1547 wlan_index,
1548 get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4);
1549 strlcpy(rt_rule->rt_tbl_name,
1550 IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name,
1551 sizeof(rt_rule->rt_tbl_name));
1552 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1553
1554 if(!strcmp("wigig0", dev_name))
1555 {
1556 IPACMDBG_H("for WIGIG client use relevant pipe %d\n",
1557 get_client_memptr(wlan_client, wlan_index)->wigig_ipa_client);
1558 rt_rule_entry->rule.dst = get_client_memptr(wlan_client, wlan_index)->wigig_ipa_client;
1559 }
1560 else
1561 {
1562 if(IPACM_Iface::ipacmcfg->isMCC_Mode)
1563 {
1564 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
1565 tx_prop->tx[tx_index].alt_dst_pipe);
1566 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
1567 }
1568 else
1569 {
1570 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
1571 }
1572 }
1573
1574 memcpy(&rt_rule_entry->rule.attrib,
1575 &tx_prop->tx[tx_index].attrib,
1576 sizeof(rt_rule_entry->rule.attrib));
1577 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1578 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4;
1579 rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr;
1580 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
1581
1582 if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0)
1583 {
1584 rt_rule_entry->rule.hashable = true;
1585 }
1586 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
1587 /* use index hw-counter */
1588 if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
1589 {
1590 IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
1591 result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
1592 } else {
1593 result = m_routing.AddRoutingRule(rt_rule);
1594 }
1595 #else
1596 result = m_routing.AddRoutingRule(rt_rule);
1597 #endif
1598 if (result == false)
1599 {
1600 IPACMERR("Routing rule addition failed!\n");
1601 free(rt_rule);
1602 return IPACM_FAILURE;
1603 }
1604
1605 /* copy ipv4 RT hdl */
1606 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4 =
1607 rt_rule->rules[0].rt_rule_hdl;
1608 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
1609 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4, iptype);
1610 }
1611 else
1612 {
1613 for(v6_num = get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6;v6_num < get_client_memptr(wlan_client, wlan_index)->ipv6_set;v6_num++)
1614 {
1615 IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
1616 wlan_index,
1617 get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6);
1618
1619 /* v6 LAN_RT_TBL */
1620 strlcpy(rt_rule->rt_tbl_name,
1621 IPACM_Iface::ipacmcfg->rt_tbl_v6.name,
1622 sizeof(rt_rule->rt_tbl_name));
1623 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1624 /* Support QCMAP LAN traffic feature, send to A5 */
1625 rt_rule_entry->rule.dst = iface_query->excp_pipe;
1626 memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib));
1627 rt_rule_entry->rule.hdr_hdl = 0;
1628 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1629 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0];
1630 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1];
1631 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2];
1632 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3];
1633 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
1634 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
1635 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
1636 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
1637 if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
1638 rt_rule_entry->rule.hashable = true;
1639 if (false == m_routing.AddRoutingRule(rt_rule))
1640 {
1641 IPACMERR("Routing rule addition failed!\n");
1642 free(rt_rule);
1643 return IPACM_FAILURE;
1644 }
1645
1646 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[v6_num] = rt_rule->rules[0].rt_rule_hdl;
1647 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
1648 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[v6_num], iptype);
1649
1650 /*Copy same rule to v6 WAN RT TBL*/
1651 strlcpy(rt_rule->rt_tbl_name,
1652 IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name,
1653 sizeof(rt_rule->rt_tbl_name));
1654 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1655 /* Downlink traffic from Wan iface, directly through IPA */
1656 if(!strcmp("wigig0", dev_name))
1657 {
1658 IPACMDBG_H("for WIGIG client use relevant pipe %d\n",
1659 get_client_memptr(wlan_client, wlan_index)->wigig_ipa_client);
1660 rt_rule_entry->rule.dst = get_client_memptr(wlan_client, wlan_index)->wigig_ipa_client;
1661 }
1662 else
1663 {
1664 if(IPACM_Iface::ipacmcfg->isMCC_Mode)
1665 {
1666 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
1667 tx_prop->tx[tx_index].alt_dst_pipe);
1668 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
1669 }
1670 else
1671 {
1672 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
1673 }
1674 }
1675 memcpy(&rt_rule_entry->rule.attrib,
1676 &tx_prop->tx[tx_index].attrib,
1677 sizeof(rt_rule_entry->rule.attrib));
1678 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6;
1679 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1680 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0];
1681 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1];
1682 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2];
1683 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3];
1684 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
1685 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
1686 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
1687 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
1688 if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
1689 rt_rule_entry->rule.hashable = true;
1690 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
1691 /* use index hw-counter */
1692 if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
1693 {
1694 IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
1695 result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
1696 } else {
1697 result = m_routing.AddRoutingRule(rt_rule);
1698 }
1699 #else
1700 result = m_routing.AddRoutingRule(rt_rule);
1701 #endif
1702
1703 if (result == false)
1704 {
1705 IPACMERR("Routing rule addition failed!\n");
1706 free(rt_rule);
1707 return IPACM_FAILURE;
1708 }
1709
1710 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num] = rt_rule->rules[0].rt_rule_hdl;
1711
1712 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
1713 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num], iptype);
1714
1715 /* send client-v6 info to pcie modem only with global ipv6 with tx_index = 0 one time*/
1716 if(is_global_ipv6_addr(get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num]) && (IPACM_Wan::backhaul_mode == Q6_MHI_WAN))
1717 {
1718 if (add_connection(wlan_index, v6_num))
1719 {
1720 IPACMERR("PCIE filter rule addition failed! (%d-client) %d v6-entry\n",wlan_index, v6_num);
1721 }
1722 }
1723 }
1724 }
1725
1726 } /* end of for loop */
1727
1728 free(rt_rule);
1729
1730 if (iptype == IPA_IP_v4)
1731 {
1732 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 = true;
1733 }
1734 else
1735 {
1736 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 = get_client_memptr(wlan_client, wlan_index)->ipv6_set;
1737 }
1738 }
1739
1740 return IPACM_SUCCESS;
1741 }
1742
1743 /*handle wifi client power-save mode*/
handle_wlan_client_pwrsave(uint8_t * mac_addr)1744 int IPACM_Wlan::handle_wlan_client_pwrsave(uint8_t *mac_addr)
1745 {
1746 int clt_indx;
1747 IPACMDBG_H("wlan->handle_wlan_client_pwrsave();\n");
1748
1749 clt_indx = get_wlan_client_index(mac_addr);
1750 if (clt_indx == IPACM_INVALID_INDEX)
1751 {
1752 IPACMDBG_H("wlan client not attached\n");
1753 return IPACM_SUCCESS;
1754 }
1755
1756 if (get_client_memptr(wlan_client, clt_indx)->power_save_set == false)
1757 {
1758 /* First reset nat rules and then route rules */
1759 if(get_client_memptr(wlan_client, clt_indx)->ipv4_set == true)
1760 {
1761 IPACMDBG_H("Deleting Nat Rules\n");
1762 Nat_App->UpdatePwrSaveIf(get_client_memptr(wlan_client, clt_indx)->v4_addr);
1763 }
1764
1765 IPACMDBG_H("Deleting default qos Route Rules\n");
1766 delete_default_qos_rtrules(clt_indx, IPA_IP_v4);
1767 delete_default_qos_rtrules(clt_indx, IPA_IP_v6);
1768 get_client_memptr(wlan_client, clt_indx)->power_save_set = true;
1769 }
1770 else
1771 {
1772 IPACMDBG_H("wlan client already in power-save mode\n");
1773 }
1774 return IPACM_SUCCESS;
1775 }
1776
1777 /*handle wifi client del mode*/
handle_wlan_client_down_evt(uint8_t * mac_addr)1778 int IPACM_Wlan::handle_wlan_client_down_evt(uint8_t *mac_addr)
1779 {
1780 int clt_indx;
1781 uint32_t tx_index;
1782 int num_wifi_client_tmp = num_wifi_client;
1783 int num_v6;
1784
1785 IPACMDBG_H("total client: %d\n", num_wifi_client_tmp);
1786
1787 clt_indx = get_wlan_client_index(mac_addr);
1788 if (clt_indx == IPACM_INVALID_INDEX)
1789 {
1790 IPACMDBG_H("wlan client not attached\n");
1791 return IPACM_SUCCESS;
1792 }
1793
1794 /* First reset nat rules and then route rules */
1795 if(get_client_memptr(wlan_client, clt_indx)->ipv4_set == true)
1796 {
1797 IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, clt_indx)->v4_addr);
1798 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clt_indx)->v4_addr);
1799 }
1800
1801 if(delete_default_qos_rtrules(clt_indx, IPA_IP_v4))
1802 {
1803 IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", clt_indx);
1804 return IPACM_FAILURE;
1805 }
1806
1807 if(delete_default_qos_rtrules(clt_indx, IPA_IP_v6))
1808 {
1809 IPACMERR("unbale to delete v6 default qos route rules for indexn: %d\n", clt_indx);
1810 return IPACM_FAILURE;
1811 }
1812
1813 /* Delete wlan client header */
1814 if(get_client_memptr(wlan_client, clt_indx)->ipv4_header_set == true)
1815 {
1816 if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v4)
1817 == false)
1818 {
1819 return IPACM_FAILURE;
1820 }
1821 get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = false;
1822 }
1823
1824 if(get_client_memptr(wlan_client, clt_indx)->ipv6_header_set == true)
1825 {
1826 if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v6)
1827 == false)
1828 {
1829 return IPACM_FAILURE;
1830 }
1831 get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = false;
1832 }
1833
1834 /* Reset ip_set to 0*/
1835 get_client_memptr(wlan_client, clt_indx)->ipv4_set = false;
1836 get_client_memptr(wlan_client, clt_indx)->ipv6_set = 0;
1837 get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = false;
1838 get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = false;
1839 get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = false;
1840 get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = 0;
1841 free(get_client_memptr(wlan_client, clt_indx)->p_hdr_info);
1842
1843 for (; clt_indx < num_wifi_client_tmp - 1; clt_indx++)
1844 {
1845 get_client_memptr(wlan_client, clt_indx)->p_hdr_info = get_client_memptr(wlan_client, (clt_indx + 1))->p_hdr_info;
1846
1847 memcpy(get_client_memptr(wlan_client, clt_indx)->mac,
1848 get_client_memptr(wlan_client, (clt_indx + 1))->mac,
1849 sizeof(get_client_memptr(wlan_client, clt_indx)->mac));
1850
1851 get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v4 = get_client_memptr(wlan_client, (clt_indx + 1))->hdr_hdl_v4;
1852 get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v6 = get_client_memptr(wlan_client, (clt_indx + 1))->hdr_hdl_v6;
1853 get_client_memptr(wlan_client, clt_indx)->v4_addr = get_client_memptr(wlan_client, (clt_indx + 1))->v4_addr;
1854
1855 get_client_memptr(wlan_client, clt_indx)->ipv4_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv4_set;
1856 get_client_memptr(wlan_client, clt_indx)->ipv6_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv6_set;
1857 get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv4_header_set;
1858 get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv6_header_set;
1859
1860 get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = get_client_memptr(wlan_client, (clt_indx + 1))->route_rule_set_v4;
1861 get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = get_client_memptr(wlan_client, (clt_indx + 1))->route_rule_set_v6;
1862
1863 for(num_v6=0;num_v6< get_client_memptr(wlan_client, clt_indx)->ipv6_set;num_v6++)
1864 {
1865 get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][0] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][0];
1866 get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][1] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][1];
1867 get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][2] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][2];
1868 get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][3] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][3];
1869 }
1870
1871 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
1872 {
1873 get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4 =
1874 get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4;
1875
1876 for(num_v6=0;num_v6< get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6;num_v6++)
1877 {
1878 get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6] =
1879 get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6];
1880 get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6] =
1881 get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6];
1882 }
1883 }
1884 }
1885
1886 IPACMDBG_H(" %d wifi client deleted successfully \n", num_wifi_client);
1887 num_wifi_client = num_wifi_client - 1;
1888 IPACM_Wlan::total_num_wifi_clients = IPACM_Wlan::total_num_wifi_clients - 1;
1889 IPACMDBG_H(" Number of wifi client: %d\n", num_wifi_client);
1890
1891 return IPACM_SUCCESS;
1892 }
1893
1894 /*handle wlan iface down event*/
handle_down_evt()1895 int IPACM_Wlan::handle_down_evt()
1896 {
1897 int res = IPACM_SUCCESS, num_private_subnet_fl_rule;
1898 uint32_t i;
1899 num_private_subnet_fl_rule = 0;
1900
1901 IPACMDBG_H("WLAN ip-type: %d \n", ip_type);
1902 /* no iface address up, directly close iface*/
1903 if (ip_type == IPACM_IP_NULL)
1904 {
1905 IPACMERR("Invalid iptype: 0x%x\n", ip_type);
1906 goto fail;
1907 }
1908
1909 /* delete wan filter rule */
1910 if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
1911 {
1912 IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
1913 IPACM_Lan::handle_wan_down(IPACM_Wan::backhaul_mode);
1914 #ifdef FEATURE_IPA_ANDROID
1915 #ifndef FEATURE_IPACM_HAL
1916 /* Clean-up tethered-iface list */
1917 IPACM_Wan::delete_tether_iface(IPA_IP_v4, ipa_if_num);
1918 #endif
1919 #endif
1920 }
1921
1922 if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
1923 {
1924 IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
1925 handle_wan_down_v6(IPACM_Wan::backhaul_mode);
1926 #ifdef FEATURE_IPA_ANDROID
1927 /* Clean-up tethered-iface list */
1928 IPACM_Wan::delete_tether_iface(IPA_IP_v6, ipa_if_num);
1929 #endif
1930 }
1931 IPACMDBG_H("finished deleting wan filtering rules\n ");
1932
1933 /* Delete v4 filtering rules */
1934 if (ip_type != IPA_IP_v6 && rx_prop != NULL)
1935 {
1936 /* delete IPv4 icmp filter rules */
1937 if(m_filtering.DeleteFilteringHdls(ipv4_icmp_flt_rule_hdl, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE) == false)
1938 {
1939 IPACMERR("Error Deleting ICMPv4 Filtering Rule, aborting...\n");
1940 res = IPACM_FAILURE;
1941 goto fail;
1942 }
1943 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE);
1944 if (dft_v4fl_rule_hdl[0] != 0)
1945 {
1946 if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false)
1947 {
1948 IPACMERR("Error Deleting Filtering Rule, aborting...\n");
1949 res = IPACM_FAILURE;
1950 goto fail;
1951 }
1952 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
1953 IPACMDBG_H("Deleted default v4 filter rules successfully.\n");
1954 }
1955 /* delete private-ipv4 filter rules */
1956 #ifdef FEATURE_IPA_ANDROID
1957 if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) == false)
1958 {
1959 IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
1960 res = IPACM_FAILURE;
1961 goto fail;
1962 }
1963 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES);
1964 #else
1965 num_private_subnet_fl_rule = IPACM_Iface::ipacmcfg->ipa_num_private_subnet > (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES)?
1966 (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) : IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
1967 if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, num_private_subnet_fl_rule) == false)
1968 {
1969 IPACMERR("Error deleting private subnet flt rules, aborting...\n");
1970 res = IPACM_FAILURE;
1971 goto fail;
1972 }
1973 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_private_subnet_fl_rule);
1974 #endif
1975 IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n");
1976
1977 #ifdef FEATURE_L2TP
1978 if(m_filtering.DeleteFilteringHdls(&tcp_syn_flt_rule_hdl[IPA_IP_v4], IPA_IP_v4, 1) == false)
1979 {
1980 IPACMERR("Error deleting tcp syn flt rule, aborting...\n");
1981 res = IPACM_FAILURE;
1982 goto fail;
1983 }
1984 #endif
1985 }
1986
1987 /* Delete v6 filtering rules */
1988 if (ip_type != IPA_IP_v4 && rx_prop != NULL)
1989 {
1990 /* delete icmp filter rules */
1991 if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false)
1992 {
1993 IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n");
1994 res = IPACM_FAILURE;
1995 goto fail;
1996 }
1997 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE);
1998
1999 if (dft_v6fl_rule_hdl[0] != 0)
2000 {
2001 if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false)
2002 {
2003 IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
2004 res = IPACM_FAILURE;
2005 goto fail;
2006 }
2007 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
2008 IPACMDBG_H("Deleted default v6 filter rules successfully.\n");
2009 }
2010 #ifdef FEATURE_L2TP
2011 if(m_filtering.DeleteFilteringHdls(&tcp_syn_flt_rule_hdl[IPA_IP_v6], IPA_IP_v6, 1) == false)
2012 {
2013 IPACMERR("Error deleting tcp syn flt rule, aborting...\n");
2014 res = IPACM_FAILURE;
2015 goto fail;
2016 }
2017 #endif
2018 }
2019 IPACMDBG_H("finished delete filtering rules\n ");
2020
2021 /* Delete default v4 RT rule */
2022 if (ip_type != IPA_IP_v6)
2023 {
2024 IPACMDBG_H("Delete default v4 routing rules\n");
2025 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4)
2026 == false)
2027 {
2028 IPACMERR("Routing rule deletion failed!\n");
2029 res = IPACM_FAILURE;
2030 goto fail;
2031 }
2032 }
2033
2034 /* Delete default v6 RT rule */
2035 if (ip_type != IPA_IP_v4)
2036 {
2037 IPACMDBG_H("Delete default v6 routing rules\n");
2038 /* May have multiple ipv6 iface-RT rules */
2039 for (i = 0; i < 2*num_dft_rt_v6; i++)
2040 {
2041 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6)
2042 == false)
2043 {
2044 IPACMERR("Routing rule deletion failed!\n");
2045 res = IPACM_FAILURE;
2046 goto fail;
2047 }
2048 }
2049 }
2050 IPACMDBG_H("finished deleting default RT rules\n ");
2051
2052 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL, NULL, NULL, IPA_CLIENT_MAX);
2053
2054 /* free the wlan clients cache */
2055 IPACMDBG_H("Free wlan clients cache\n");
2056
2057 /* Delete private subnet*/
2058 #ifdef FEATURE_IPA_ANDROID
2059 if (ip_type != IPA_IP_v6)
2060 {
2061 IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
2062 IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
2063 if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
2064 {
2065 IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
2066 }
2067 }
2068 /* reset the IPA-client pipe enum */
2069 #ifdef FEATURE_IPACM_HAL
2070 handle_tethering_client(true, IPACM_CLIENT_MAX);
2071 #else
2072 handle_tethering_client(true, IPACM_CLIENT_WLAN);
2073 #endif
2074 #endif /* defined(FEATURE_IPA_ANDROID)*/
2075
2076 fail:
2077 /* clean wifi-client header, routing rules */
2078 /* clean wifi client rule*/
2079 IPACMDBG_H("left %d wifi clients need to be deleted \n ", num_wifi_client);
2080 for (i = 0; i < num_wifi_client; i++)
2081 {
2082 /* First reset nat rules and then route rules */
2083 if(get_client_memptr(wlan_client, i)->ipv4_set == true)
2084 {
2085 IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, i)->v4_addr);
2086 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, i)->v4_addr);
2087 }
2088
2089 if (delete_default_qos_rtrules(i, IPA_IP_v4))
2090 {
2091 IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", i);
2092 res = IPACM_FAILURE;
2093 }
2094
2095 if (delete_default_qos_rtrules(i, IPA_IP_v6))
2096 {
2097 IPACMERR("unbale to delete v6 default qos route rules for index: %d\n", i);
2098 res = IPACM_FAILURE;
2099 }
2100
2101 IPACMDBG_H("Delete %d client header\n", num_wifi_client);
2102
2103 if(get_client_memptr(wlan_client, i)->ipv4_header_set == true)
2104 {
2105 if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v4)
2106 == false)
2107 {
2108 res = IPACM_FAILURE;
2109 }
2110 }
2111
2112 if(get_client_memptr(wlan_client, i)->ipv6_header_set == true)
2113 {
2114 if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v6)
2115 == false)
2116 {
2117 res = IPACM_FAILURE;
2118 }
2119 }
2120 } /* end of for loop */
2121
2122 /* check software routing fl rule hdl */
2123 if (softwarerouting_act == true && rx_prop != NULL )
2124 {
2125 IPACMDBG_H("Delete sw routing filtering rules\n");
2126 IPACM_Iface::handle_software_routing_disable(false);
2127 }
2128 IPACMDBG_H("finished delete software-routing filtering rules\n ");
2129
2130 if (rx_prop != NULL)
2131 {
2132 if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
2133 {
2134 /* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
2135 IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2136 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]);
2137 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
2138 }
2139 if (!(IPACM_Iface::ipacmcfg->isEthBridgingSupported()))
2140 free(rx_prop);
2141 }
2142
2143 for (i = 0; i < num_wifi_client; i++)
2144 {
2145 if(get_client_memptr(wlan_client, i)->p_hdr_info != NULL)
2146 {
2147 free(get_client_memptr(wlan_client, i)->p_hdr_info);
2148 }
2149 }
2150 if(wlan_client != NULL)
2151 {
2152 free(wlan_client);
2153 }
2154 if (!(IPACM_Iface::ipacmcfg->isEthBridgingSupported()))
2155 {
2156 if (tx_prop != NULL)
2157 {
2158 free(tx_prop);
2159 }
2160
2161 if (iface_query != NULL)
2162 {
2163 free(iface_query);
2164 }
2165 }
2166
2167 is_active = false;
2168 post_del_self_evt();
2169
2170 return res;
2171 }
2172
2173 /*handle reset wifi-client rt-rules */
handle_wlan_client_reset_rt(ipa_ip_type iptype)2174 int IPACM_Wlan::handle_wlan_client_reset_rt(ipa_ip_type iptype)
2175 {
2176 uint32_t i;
2177 int res = IPACM_SUCCESS;
2178
2179 /* clean wifi-client routing rules */
2180 IPACMDBG_H("left %d wifi clients to reset ip-type(%d) rules \n ", num_wifi_client, iptype);
2181
2182 for (i = 0; i < num_wifi_client; i++)
2183 {
2184 /* Reset RT rules */
2185 res = delete_default_qos_rtrules(i, iptype);
2186 if (res != IPACM_SUCCESS)
2187 {
2188 IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype);
2189 return res;
2190 }
2191
2192 /* Reset ip-address */
2193 if(iptype == IPA_IP_v4)
2194 {
2195 get_client_memptr(wlan_client, i)->ipv4_set = false;
2196 }
2197 else
2198 {
2199 get_client_memptr(wlan_client, i)->ipv6_set = 0;
2200 }
2201 } /* end of for loop */
2202 return res;
2203 }
2204
handle_SCC_MCC_switch(ipa_ip_type iptype)2205 void IPACM_Wlan::handle_SCC_MCC_switch(ipa_ip_type iptype)
2206 {
2207 struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL;
2208 struct ipa_rt_rule_mdfy *rt_rule_entry;
2209 uint32_t tx_index;
2210 int wlan_index, v6_num;
2211 const int NUM = 1;
2212 int num_wifi_client_tmp = IPACM_Wlan::num_wifi_client;
2213 bool isAdded = false;
2214
2215 if (tx_prop == NULL)
2216 {
2217 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
2218 return;
2219 }
2220
2221 if (rt_rule == NULL)
2222 {
2223 rt_rule = (struct ipa_ioc_mdfy_rt_rule *)
2224 calloc(1, sizeof(struct ipa_ioc_mdfy_rt_rule) +
2225 NUM * sizeof(struct ipa_rt_rule_mdfy));
2226
2227 if (rt_rule == NULL)
2228 {
2229 PERROR("Error Locate ipa_ioc_mdfy_rt_rule memory...\n");
2230 return;
2231 }
2232
2233 rt_rule->commit = 0;
2234 rt_rule->num_rules = NUM;
2235 rt_rule->ip = iptype;
2236 }
2237 rt_rule_entry = &rt_rule->rules[0];
2238
2239 /* modify ipv4 routing rule */
2240 if (iptype == IPA_IP_v4)
2241 {
2242 for (wlan_index = 0; wlan_index < num_wifi_client_tmp; wlan_index++)
2243 {
2244 IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n",
2245 wlan_index, iptype,
2246 get_client_memptr(wlan_client, wlan_index)->ipv4_set,
2247 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4);
2248
2249 if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true ||
2250 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 == false)
2251 {
2252 IPACMDBG_H("client %d route rules not set\n", wlan_index);
2253 continue;
2254 }
2255
2256 IPACMDBG_H("Modify client %d route rule\n", wlan_index);
2257 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2258 {
2259 if (iptype != tx_prop->tx[tx_index].ip)
2260 {
2261 IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d ignore\n",
2262 tx_index, tx_prop->tx[tx_index].ip, iptype);
2263 continue;
2264 }
2265
2266 IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wlan_index,
2267 get_client_memptr(wlan_client, wlan_index)->v4_addr);
2268
2269 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
2270 wlan_index,
2271 get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4);
2272
2273 if (IPACM_Iface::ipacmcfg->isMCC_Mode)
2274 {
2275 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
2276 tx_prop->tx[tx_index].alt_dst_pipe);
2277 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
2278 }
2279 else
2280 {
2281 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2282 }
2283
2284 memcpy(&rt_rule_entry->rule.attrib,
2285 &tx_prop->tx[tx_index].attrib,
2286 sizeof(rt_rule_entry->rule.attrib));
2287
2288 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2289 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4;
2290
2291 rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr;
2292 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
2293
2294 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2295 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4, iptype);
2296
2297 rt_rule_entry->rt_rule_hdl =
2298 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4;
2299
2300 if (false == m_routing.ModifyRoutingRule(rt_rule))
2301 {
2302 IPACMERR("Routing rule modify failed!\n");
2303 free(rt_rule);
2304 return;
2305 }
2306 isAdded = true;
2307 }
2308
2309 }
2310 }
2311
2312 /* modify ipv6 routing rule */
2313 if (iptype == IPA_IP_v6)
2314 {
2315 for (wlan_index = 0; wlan_index < num_wifi_client_tmp; wlan_index++)
2316 {
2317
2318 IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wlan_index, iptype,
2319 get_client_memptr(wlan_client, wlan_index)->ipv6_set,
2320 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6);
2321
2322 if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true ||
2323 (get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 <
2324 get_client_memptr(wlan_client, wlan_index)->ipv6_set) )
2325 {
2326 IPACMDBG_H("client %d route rules not set\n", wlan_index);
2327 continue;
2328 }
2329
2330 IPACMDBG_H("Modify client %d route rule\n", wlan_index);
2331 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2332 {
2333 if (iptype != tx_prop->tx[tx_index].ip)
2334 {
2335 IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d Ignore\n",
2336 tx_index, tx_prop->tx[tx_index].ip, iptype);
2337 continue;
2338 }
2339
2340 for (v6_num = get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6;
2341 v6_num < get_client_memptr(wlan_client, wlan_index)->ipv6_set;
2342 v6_num++)
2343 {
2344
2345 IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
2346 wlan_index,
2347 get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6);
2348
2349 if (IPACM_Iface::ipacmcfg->isMCC_Mode)
2350 {
2351 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
2352 tx_prop->tx[tx_index].alt_dst_pipe);
2353 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
2354 }
2355 else
2356 {
2357 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2358 }
2359
2360 memcpy(&rt_rule_entry->rule.attrib,
2361 &tx_prop->tx[tx_index].attrib,
2362 sizeof(rt_rule_entry->rule.attrib));
2363
2364 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6;
2365 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2366
2367 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0];
2368 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1];
2369 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2];
2370 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3];
2371 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2372 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2373 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2374 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2375
2376 rt_rule_entry->rt_rule_hdl =
2377 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num];
2378
2379 if (false == m_routing.ModifyRoutingRule(rt_rule))
2380 {
2381 IPACMERR("Routing rule modify failed!\n");
2382 free(rt_rule);
2383 return;
2384 }
2385 isAdded = true;
2386 }
2387 }
2388
2389 }
2390 }
2391
2392
2393 if (isAdded)
2394 {
2395 if (false == m_routing.Commit(iptype))
2396 {
2397 IPACMERR("Routing rule modify commit failed!\n");
2398 free(rt_rule);
2399 return;
2400 }
2401
2402 IPACMDBG("Routing rule modified successfully \n");
2403 }
2404
2405 if(rt_rule)
2406 {
2407 free(rt_rule);
2408 }
2409 return;
2410 }
2411
2412 #ifdef FEATURE_IPACM_RESTART
ipa_query_wlan_client()2413 int IPACM_Wlan::ipa_query_wlan_client()
2414 {
2415 int fd = -1;
2416
2417 if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
2418 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
2419 return IPACM_FAILURE;
2420 }
2421
2422 if (ioctl(fd, IPA_IOC_QUERY_WLAN_CLIENT) < 0) {
2423 IPACMERR("IOCTL IPA_IOC_QUERY_WLAN_CLIENT call failed: %s \n", strerror(errno));
2424 close(fd);
2425 return IPACM_FAILURE;
2426 }
2427
2428 IPACMDBG_H("send IPA_IOC_QUERY_WLAN_CLIENT \n");
2429 close(fd);
2430 return IPACM_SUCCESS;
2431 }
2432 #endif
2433
eth_bridge_handle_wlan_mode_switch()2434 void IPACM_Wlan::eth_bridge_handle_wlan_mode_switch()
2435 {
2436 uint32_t i;
2437
2438 /* ====== post events to mimic WLAN interface goes down/up when AP mode is changing ====== */
2439
2440 /* first post IFACE_DOWN event */
2441 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL, NULL, NULL, IPA_CLIENT_MAX);
2442
2443 /* then post IFACE_UP event */
2444 if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
2445 {
2446 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL, NULL, NULL, IPA_CLIENT_MAX);
2447 }
2448 if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
2449 {
2450 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL, NULL, NULL, IPA_CLIENT_MAX);
2451 }
2452
2453 /* at last post CLIENT_ADD event */
2454 for(i = 0; i < num_wifi_client; i++)
2455 {
2456 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX,
2457 get_client_memptr(wlan_client, i)->mac, NULL, NULL, IPA_CLIENT_MAX);
2458 }
2459
2460 return;
2461 }
2462
is_guest_ap()2463 bool IPACM_Wlan::is_guest_ap()
2464 {
2465 return m_is_guest_ap;
2466 }
2467
add_connection(int client_index,int v6_num)2468 int IPACM_Wlan::add_connection(int client_index, int v6_num)
2469 {
2470 int len, res = IPACM_SUCCESS;
2471 uint8_t mux_id;
2472 ipa_ioc_add_flt_rule *pFilteringTable = NULL;
2473 int fd;
2474
2475 mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
2476 /* contruct filter rules to pcie modem */
2477 struct ipa_flt_rule_add flt_rule_entry;
2478 ipa_ioc_generate_flt_eq flt_eq;
2479
2480 IPACMDBG("\n");
2481 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
2482 pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
2483 if (pFilteringTable == NULL)
2484 {
2485 IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
2486 return IPACM_FAILURE;
2487 }
2488 memset(pFilteringTable, 0, len);
2489
2490
2491 pFilteringTable->commit = 1;
2492 pFilteringTable->global = false;
2493 pFilteringTable->ip = IPA_IP_v6;
2494 pFilteringTable->num_rules = (uint8_t)1;
2495
2496 /* Configuring Filtering Rule */
2497 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
2498 flt_rule_entry.at_rear = true;
2499 flt_rule_entry.flt_rule_hdl = -1;
2500 flt_rule_entry.status = -1;
2501
2502 flt_rule_entry.rule.retain_hdr = 1;
2503 flt_rule_entry.rule.to_uc = 0;
2504 flt_rule_entry.rule.eq_attrib_type = 1;
2505 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
2506 if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2507 flt_rule_entry.rule.hashable = true;
2508 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2509 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][0];
2510 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][1];
2511 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][2];
2512 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][3];
2513 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2514 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2515 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2516 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2517
2518 IPACMDBG_H("ipv6 address got: 0x%x:%x:%x:%x\n", get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][0],
2519 get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][1],
2520 get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][2],
2521 get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][3]);
2522
2523 /* change to network order for modem */
2524 change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
2525
2526 memset(&flt_eq, 0, sizeof(flt_eq));
2527 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
2528 flt_eq.ip = IPA_IP_v6;
2529
2530 fd = open(IPA_DEVICE_NAME, O_RDWR);
2531 if (fd < 0)
2532 {
2533 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
2534 free(pFilteringTable);
2535 return IPACM_FAILURE;
2536 }
2537
2538 if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
2539 {
2540 IPACMERR("Failed to get eq_attrib\n");
2541 res = IPACM_FAILURE;
2542 goto fail;
2543 }
2544 memcpy(&flt_rule_entry.rule.eq_attrib,
2545 &flt_eq.eq_attrib,
2546 sizeof(flt_rule_entry.rule.eq_attrib));
2547 memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
2548
2549 if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 0))
2550 {
2551 IPACMERR("Failed to install WAN DL filtering table.\n");
2552 res = IPACM_FAILURE;
2553 goto fail;
2554 }
2555
2556 get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num] = pFilteringTable->rules[0].flt_rule_hdl;
2557 IPACMDBG_H("%d-st client v6_num %d: id handle 0x%x\n", client_index, v6_num, get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num]);
2558
2559 fail:
2560 close(fd);
2561 if(pFilteringTable != NULL)
2562 {
2563 free(pFilteringTable);
2564 }
2565 return res;
2566 }
2567
del_connection(int client_index,int v6_num)2568 int IPACM_Wlan::del_connection(int client_index, int v6_num)
2569 {
2570 int len, res = IPACM_SUCCESS;
2571 ipa_ioc_del_flt_rule *pFilteringTable = NULL;
2572
2573 struct ipa_flt_rule_del flt_rule_entry;
2574
2575 IPACMDBG("\n");
2576 len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
2577 pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
2578 if (pFilteringTable == NULL)
2579 {
2580 IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
2581 return IPACM_FAILURE;
2582 }
2583 memset(pFilteringTable, 0, len);
2584
2585
2586 pFilteringTable->commit = 1;
2587 pFilteringTable->ip = IPA_IP_v6;
2588 pFilteringTable->num_hdls = (uint8_t)1;
2589
2590 /* Configuring Software-Routing Filtering Rule */
2591 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
2592 flt_rule_entry.hdl = get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num];
2593
2594 memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
2595
2596 if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
2597 {
2598 IPACMERR("Failed to install WAN DL filtering table.\n");
2599 res = IPACM_FAILURE;
2600 goto fail;
2601 }
2602 get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num] = 0;
2603
2604 fail:
2605 if(pFilteringTable != NULL)
2606 {
2607 free(pFilteringTable);
2608 }
2609 return res;
2610 }
2611