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 if(data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false)
566 {
567 IPACMDBG_H("Add downstream for IP iptype %d.\n", data->prefix.iptype);
568 is_downstream_set[data->prefix.iptype] = true;
569 memcpy(&prefix[data->prefix.iptype], &data->prefix,
570 sizeof(prefix[data->prefix.iptype]));
571
572 if (is_upstream_set[data->prefix.iptype] == true)
573 {
574 IPACMDBG_H("Upstream was set before, adding modem UL rules.\n");
575 if(ip_type == IPA_IP_MAX || ip_type == data->prefix.iptype)
576 {
577 if (data->prefix.iptype == IPA_IP_v6) /* ipv6 only */
578 {
579 /* Only offload clients has same prefix as Android gave */
580 ipv6_prefix[0] = data->prefix.v6Addr[0];
581 ipv6_prefix[1] = data->prefix.v6Addr[1];
582 IPACMDBG_H("ipv6_prefix0x%x:%x\n", ipv6_prefix[0], ipv6_prefix[1]);
583 install_ipv6_prefix_flt_rule(ipv6_prefix);
584 }
585
586 if (IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
587 {
588 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
589 if (data->prefix.iptype == IPA_IP_v4)
590 {
591 IPACMDBG_H("check getXlat_Mux_Id:%d\n", IPACM_Wan::getXlat_Mux_Id());
592 handle_wan_up_ex(ext_prop, data->prefix.iptype,
593 IPACM_Wan::getXlat_Mux_Id());
594 }
595 else {
596 handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
597 }
598 } else {
599 handle_wan_up(data->prefix.iptype); /* STA */
600 }
601 }
602 }
603 }
604 }
605 break;
606 }
607
608 case IPA_DOWNSTREAM_DEL:
609 {
610 ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param;
611 ipa_interface_index = iface_ipa_index_query(data->if_index);
612 if(ipa_interface_index == ipa_if_num)
613 {
614 IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
615 if(is_downstream_set[data->prefix.iptype] == true)
616 {
617 IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
618 is_downstream_set[data->prefix.iptype] = false;
619
620 if(is_upstream_set[data->prefix.iptype] == true)
621 {
622 IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
623 if (data->prefix.iptype == IPA_IP_v4)
624 {
625 handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
626 } else {
627 handle_wlan_client_reset_rt(IPA_IP_v6);
628 handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
629 }
630 }
631 }
632 }
633 break;
634 }
635 #ifdef IPA_MTU_EVENT_MAX
636 case IPA_MTU_UPDATE:
637 {
638 IPACMDBG_H("Received IPA_MTU_UPDATE");
639 ipacm_event_mtu_info *evt_data = (ipacm_event_mtu_info *)param;
640 ipa_mtu_info *data = &(evt_data->mtu_info);
641
642 /* IPA_IP_MAX means both ipv4 and ipv6 */
643 if ((data->ip_type == IPA_IP_v4 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP(ipa_if_num))
644 {
645 handle_private_subnet_android(IPA_IP_v4);
646 }
647
648 /* IPA_IP_MAX means both ipv4 and ipv6 */
649 if ((data->ip_type == IPA_IP_v6 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP_V6(ipa_if_num))
650 {
651 //check if the prefix + MTU rules are installed
652 if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1]) {
653 modify_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
654 }
655 else
656 {
657 IPACMERR("failed to update prefix MTU rules, no prefix rules set");
658 }
659 }
660 }
661 break;
662 #endif
663
664 #else
665 case IPA_HANDLE_WAN_UP:
666 IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
667
668 ipacm_event_iface_up* data_wan = (ipacm_event_iface_up*)param;
669 if(data_wan == NULL)
670 {
671 IPACMERR("No event data is found.\n");
672 return;
673 }
674 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
675 if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
676 {
677 if(data_wan->backhaul_type == Q6_WAN)
678 {
679 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
680 IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
681 }
682 else
683 {
684 IPACM_Lan::handle_wan_up(IPA_IP_v4);
685 }
686 }
687 break;
688
689 case IPA_HANDLE_WAN_UP_V6:
690 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6 event\n");
691
692 data_wan = (ipacm_event_iface_up*)param;
693 if(data_wan == NULL)
694 {
695 IPACMERR("No event data is found.\n");
696 return;
697 }
698 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
699 if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
700 {
701 memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix));
702 install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
703
704 if(data_wan->backhaul_type == Q6_WAN)
705 {
706 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
707 IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
708 }
709 else
710 {
711 IPACM_Lan::handle_wan_up(IPA_IP_v6);
712 }
713 }
714 break;
715
716 case IPA_HANDLE_WAN_DOWN:
717 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n");
718 data_wan = (ipacm_event_iface_up*)param;
719 if(data_wan == NULL)
720 {
721 IPACMERR("No event data is found.\n");
722 return;
723 }
724 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
725 if (rx_prop != NULL)
726 {
727 if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
728 {
729 handle_wan_down(data_wan->backhaul_type);
730 }
731 }
732 break;
733
734 case IPA_HANDLE_WAN_DOWN_V6:
735 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6 event\n");
736 data_wan = (ipacm_event_iface_up*)param;
737 if(data_wan == NULL)
738 {
739 IPACMERR("No event data is found.\n");
740 return;
741 }
742 /* clean up v6 RT rules*/
743 IPACMDBG_H("Received IPA_WAN_V6_DOWN in WLAN-instance and need clean up client IPv6 address \n");
744 /* reset wifi-client ipv6 rt-rules */
745 handle_wlan_client_reset_rt(IPA_IP_v6);
746 IPACMDBG_H("Backhaul is sta mode ? %d\n", data_wan->backhaul_type);
747 if (rx_prop != NULL)
748 {
749 if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
750 {
751 handle_wan_down_v6(data_wan->backhaul_type);
752 }
753 }
754 break;
755 #endif
756
757 case IPA_WLAN_CLIENT_ADD_EVENT_EX:
758 {
759 ipacm_event_data_wlan_ex *data = (ipacm_event_data_wlan_ex *)param;
760 ipa_interface_index = iface_ipa_index_query(data->if_index);
761 if (ipa_interface_index == ipa_if_num)
762 {
763 int i;
764 for(i=0; i<data->num_of_attribs; i++)
765 {
766 if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
767 {
768 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->attribs[i].u.mac_addr, NULL, NULL,
769 IPA_CLIENT_MAX);
770 break;
771 }
772 }
773 IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n");
774 handle_wlan_client_init_ex(data);
775 }
776 }
777 break;
778
779 case IPA_WIGIG_CLIENT_ADD_EVENT:
780 {
781 ipacm_event_data_mac_ep *data = (ipacm_event_data_mac_ep *)param;
782 ipa_interface_index = iface_ipa_index_query(data->if_index);
783 if(ipa_interface_index == ipa_if_num)
784 {
785 IPACMDBG_H("Received IPA_WIGIG_CLIENT_ADD_EVENT\n");
786 handle_wigig_client_add(data);
787 }
788 }
789 break;
790
791 case IPA_WLAN_CLIENT_DEL_EVENT:
792 {
793 ipacm_event_data_mac *data = (ipacm_event_data_mac *)param;
794 ipa_interface_index = iface_ipa_index_query(data->if_index);
795 if (ipa_interface_index == ipa_if_num)
796 {
797 IPACMDBG_H("Received IPA_WLAN_CLIENT_DEL_EVENT\n");
798 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_DEL, IPA_IP_MAX, data->mac_addr, NULL, NULL, IPA_CLIENT_MAX);
799 handle_wlan_client_down_evt(data->mac_addr);
800 }
801 }
802 break;
803
804 case IPA_WLAN_CLIENT_POWER_SAVE_EVENT:
805 {
806 ipacm_event_data_mac *data = (ipacm_event_data_mac *)param;
807 ipa_interface_index = iface_ipa_index_query(data->if_index);
808 if (ipa_interface_index == ipa_if_num)
809 {
810 IPACMDBG_H("Received IPA_WLAN_CLIENT_POWER_SAVE_EVENT\n");
811 handle_wlan_client_pwrsave(data->mac_addr);
812 }
813 }
814 break;
815
816 case IPA_WLAN_CLIENT_RECOVER_EVENT:
817 {
818 ipacm_event_data_mac *data = (ipacm_event_data_mac *)param;
819 ipa_interface_index = iface_ipa_index_query(data->if_index);
820 if (ipa_interface_index == ipa_if_num)
821 {
822 IPACMDBG_H("Received IPA_WLAN_CLIENT_RECOVER_EVENT\n");
823
824 wlan_index = get_wlan_client_index(data->mac_addr);
825 if ((wlan_index != IPACM_INVALID_INDEX) &&
826 (get_client_memptr(wlan_client, wlan_index)->power_save_set == true))
827 {
828
829 IPACMDBG_H("change wlan client out of power safe mode \n");
830 get_client_memptr(wlan_client, wlan_index)->power_save_set = false;
831
832 /* First add route rules and then nat rules */
833 if(get_client_memptr(wlan_client, wlan_index)->ipv4_set == true) /* for ipv4 */
834 {
835 IPACMDBG_H("recover client index(%d):ipv4 address: 0x%x\n",
836 wlan_index,
837 get_client_memptr(wlan_client, wlan_index)->v4_addr);
838
839 IPACMDBG_H("Adding Route Rules\n");
840 handle_wlan_client_route_rule(data->mac_addr, IPA_IP_v4);
841 IPACMDBG_H("Adding Nat Rules\n");
842 Nat_App->ResetPwrSaveIf(get_client_memptr(wlan_client, wlan_index)->v4_addr);
843 }
844
845 if(get_client_memptr(wlan_client, wlan_index)->ipv6_set != 0) /* for ipv6 */
846 {
847 handle_wlan_client_route_rule(data->mac_addr, IPA_IP_v6);
848 }
849 }
850 }
851 }
852 break;
853
854 case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
855 {
856 ipacm_event_data_all *data = (ipacm_event_data_all *)param;
857 ipa_interface_index = iface_ipa_index_query(data->if_index);
858 if (ipa_interface_index == ipa_if_num)
859 {
860 IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT\n");
861 if (handle_wlan_client_ipaddr(data) == IPACM_FAILURE)
862 {
863 return;
864 }
865
866 handle_wlan_client_route_rule(data->mac_addr, data->iptype);
867 if(data->iptype == IPA_IP_v4)
868 {
869 /* Add NAT rules after ipv4 RT rules are set */
870 CtList->HandleNeighIpAddrAddEvt(data);
871 //Nat_App->ResetPwrSaveIf(data->ipv4_addr);
872 }
873 }
874 }
875 break;
876 /* handle software routing enable event, iface will update softwarerouting_act to true*/
877 case IPA_SW_ROUTING_ENABLE:
878 IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n");
879 IPACM_Iface::handle_software_routing_enable(false);
880 break;
881
882 /* handle software routing disable event, iface will update softwarerouting_act to false*/
883 case IPA_SW_ROUTING_DISABLE:
884 IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n");
885 IPACM_Iface::handle_software_routing_disable(false);
886 break;
887
888 case IPA_WLAN_SWITCH_TO_SCC:
889 IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n");
890 if(ip_type == IPA_IP_MAX)
891 {
892 handle_SCC_MCC_switch(IPA_IP_v4);
893 handle_SCC_MCC_switch(IPA_IP_v6);
894 }
895 else
896 {
897 handle_SCC_MCC_switch(ip_type);
898 }
899 eth_bridge_post_event(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, IPA_IP_MAX, NULL, NULL, NULL, IPA_CLIENT_MAX);
900 break;
901
902 case IPA_WLAN_SWITCH_TO_MCC:
903 IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n");
904 if(ip_type == IPA_IP_MAX)
905 {
906 handle_SCC_MCC_switch(IPA_IP_v4);
907 handle_SCC_MCC_switch(IPA_IP_v6);
908 }
909 else
910 {
911 handle_SCC_MCC_switch(ip_type);
912 }
913 eth_bridge_post_event(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, IPA_IP_MAX, NULL, NULL, NULL, IPA_CLIENT_MAX);
914 break;
915
916 case IPA_CRADLE_WAN_MODE_SWITCH:
917 {
918 IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n");
919 ipacm_event_cradle_wan_mode* wan_mode = (ipacm_event_cradle_wan_mode*)param;
920 if(wan_mode == NULL)
921 {
922 IPACMERR("Event data is empty.\n");
923 return;
924 }
925
926 if(wan_mode->cradle_wan_mode == BRIDGE)
927 {
928 handle_cradle_wan_mode_switch(true);
929 }
930 else
931 {
932 handle_cradle_wan_mode_switch(false);
933 }
934 }
935 break;
936 case IPA_CFG_CHANGE_EVENT:
937 {
938 IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT event for %s with new wlan-mode: %s old wlan-mode: %s\n",
939 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name,
940 (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == 0) ? "full" : "internet",
941 (m_is_guest_ap == true) ? "internet" : "full");
942 /* Add Natting iface to IPACM_Config if there is Rx/Tx property */
943 if (rx_prop != NULL || tx_prop != NULL)
944 {
945 IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
946 IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_MAX);
947 }
948
949 if (m_is_guest_ap == true && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == FULL))
950 {
951 m_is_guest_ap = false;
952 IPACMDBG_H("wlan mode is switched to full access mode. \n");
953 eth_bridge_handle_wlan_mode_switch();
954 }
955 else if (m_is_guest_ap == false && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET))
956 {
957 m_is_guest_ap = true;
958 IPACMDBG_H("wlan mode is switched to internet only access mode. \n");
959 eth_bridge_handle_wlan_mode_switch();
960 }
961 else
962 {
963 IPACMDBG_H("No change in %s access mode. \n",
964 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
965 }
966 }
967 break;
968 case IPA_TETHERING_STATS_UPDATE_EVENT:
969 {
970 IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
971 if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
972 {
973 if(IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
974 {
975 ipa_get_data_stats_resp_msg_v01 *data = (ipa_get_data_stats_resp_msg_v01 *)param;
976 if (data->ipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01)
977 {
978 IPACMERR("not valid pipe stats\n");
979 return;
980 }
981 handle_tethering_stats_event(data);
982 };
983 }
984 }
985 break;
986 #ifdef FEATURE_IPACM_HAL
987 /* WA for WLAN to clean up NAT instance during SSR */
988 case IPA_SSR_NOTICE:
989 {
990 IPACMDBG_H("Received IPA_SSR_NOTICE event.\n");
991 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
992 }
993 break;
994 case IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE:
995 {
996 IPACMDBG_H("Received IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE.\n");
997
998 /* internal push add_downstream event in cache */
999 OffloadMng = IPACM_OffloadManager::GetInstance();
1000 if (OffloadMng == NULL) {
1001 IPACMERR("failed to get IPACM_OffloadManager instance !\n");
1002 } else {
1003 IPACMDBG_H("Update iface %s add_downstream cache events\n", dev_name);
1004 if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
1005 {
1006 OffloadMng->push_framework_event(dev_name, prefix[IPA_IP_v4]);
1007 }
1008 else if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
1009 {
1010 OffloadMng->push_framework_event(dev_name, prefix[IPA_IP_v6]);
1011 }
1012 }
1013 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
1014 }
1015 break;
1016 #endif
1017 default:
1018 break;
1019 }
1020 return;
1021 }
1022
1023
handle_wigig_client_add(ipacm_event_data_mac_ep * data)1024 int IPACM_Wlan::handle_wigig_client_add(ipacm_event_data_mac_ep *data)
1025 {
1026 ipacm_event_data_wlan_ex *wlan_data;
1027 int ret = IPACM_SUCCESS;
1028
1029 wlan_data = (ipacm_event_data_wlan_ex *)malloc(sizeof(ipa_wlan_msg_ex) + sizeof(ipa_wlan_hdr_attrib_val));
1030 if(wlan_data == NULL)
1031 {
1032 IPACMERR("Unable to allocate memory\n");
1033 return IPACM_FAILURE;
1034 }
1035
1036 wlan_data->num_of_attribs = 1;
1037 wlan_data->if_index = data->if_index;
1038 wlan_data->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
1039 wlan_data->attribs[0].offset = 0;
1040 memcpy(wlan_data->attribs[0].u.mac_addr, data->mac_addr, sizeof(wlan_data->attribs[0].u.mac_addr));
1041
1042 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr, NULL, NULL, data->client);
1043 handle_wlan_client_init_ex(wlan_data);
1044
1045 int idx = get_wlan_client_index(data->mac_addr);
1046
1047 if(idx == IPACM_INVALID_INDEX)
1048 {
1049 IPACMERR("wlan client not attached\n");
1050 ret = IPACM_FAILURE;
1051 goto fail;
1052 }
1053
1054 /* store client pipe hdl for the time we add the DL header */
1055 get_client_memptr(wlan_client, idx)->wigig_ipa_client = data->client;
1056 fail:
1057 free(wlan_data);
1058 return ret;
1059 }
1060
1061 /* handle wifi client initial,copy all partial headers (tx property) */
handle_wlan_client_init_ex(ipacm_event_data_wlan_ex * data)1062 int IPACM_Wlan::handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data)
1063 {
1064
1065 #define WLAN_IFACE_INDEX_LEN 2
1066
1067 int res = IPACM_SUCCESS, len = 0, i, evt_size;
1068 char index[WLAN_IFACE_INDEX_LEN];
1069 struct ipa_ioc_copy_hdr sCopyHeader;
1070 struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
1071 uint32_t cnt;
1072
1073 /* start of adding header */
1074 IPACMDBG_H("Wifi client number for this iface: %d & total number of wlan clients: %d\n",
1075 num_wifi_client,IPACM_Wlan::total_num_wifi_clients);
1076
1077 if ((num_wifi_client >= IPA_MAX_NUM_WIFI_CLIENTS) ||
1078 (IPACM_Wlan::total_num_wifi_clients >= IPA_MAX_NUM_WIFI_CLIENTS))
1079 {
1080 IPACMERR("Reached maximum number of wlan clients\n");
1081 return IPACM_FAILURE;
1082 }
1083
1084 IPACMDBG_H("Wifi client number: %d\n", num_wifi_client);
1085
1086 /* add header to IPA */
1087 if(tx_prop != NULL)
1088 {
1089 len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
1090 pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
1091 if (pHeaderDescriptor == NULL)
1092 {
1093 IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
1094 return IPACM_FAILURE;
1095 }
1096
1097 evt_size = sizeof(ipacm_event_data_wlan_ex) + data->num_of_attribs * sizeof(struct ipa_wlan_hdr_attrib_val);
1098 get_client_memptr(wlan_client, num_wifi_client)->p_hdr_info = (ipacm_event_data_wlan_ex*)malloc(evt_size);
1099 memcpy(get_client_memptr(wlan_client, num_wifi_client)->p_hdr_info, data, evt_size);
1100
1101 /* copy partial header for v4*/
1102 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
1103 {
1104 if(tx_prop->tx[cnt].ip==IPA_IP_v4)
1105 {
1106 IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt);
1107 memset(&sCopyHeader, 0, sizeof(sCopyHeader));
1108 memcpy(sCopyHeader.name,
1109 tx_prop->tx[cnt].hdr_name,
1110 sizeof(sCopyHeader.name));
1111
1112 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
1113 if (m_header.CopyHeader(&sCopyHeader) == false)
1114 {
1115 PERROR("ioctl copy header failed");
1116 res = IPACM_FAILURE;
1117 goto fail;
1118 }
1119
1120 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
1121 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
1122 {
1123 IPACMERR("header oversize\n");
1124 res = IPACM_FAILURE;
1125 goto fail;
1126 }
1127 else
1128 {
1129 memcpy(pHeaderDescriptor->hdr[0].hdr,
1130 sCopyHeader.hdr,
1131 sCopyHeader.hdr_len);
1132 }
1133
1134 for(i = 0; i < data->num_of_attribs; i++)
1135 {
1136 if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
1137 {
1138 memcpy(get_client_memptr(wlan_client, num_wifi_client)->mac,
1139 data->attribs[i].u.mac_addr,
1140 sizeof(get_client_memptr(wlan_client, num_wifi_client)->mac));
1141
1142 /* copy client mac_addr to partial header */
1143 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
1144 get_client_memptr(wlan_client, num_wifi_client)->mac,
1145 IPA_MAC_ADDR_SIZE);
1146 /* replace src mac to bridge mac_addr if any */
1147 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
1148 {
1149 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset+IPA_MAC_ADDR_SIZE],
1150 IPACM_Iface::ipacmcfg->bridge_mac,
1151 IPA_MAC_ADDR_SIZE);
1152 IPACMDBG_H("device is in bridge mode \n");
1153 }
1154
1155 }
1156 else if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
1157 {
1158 /* copy client id to header */
1159 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
1160 &data->attribs[i].u.sta_id, sizeof(data->attribs[i].u.sta_id));
1161 }
1162 else
1163 {
1164 IPACMDBG_H("The attribute type is not expected!\n");
1165 }
1166 }
1167
1168 pHeaderDescriptor->commit = true;
1169 pHeaderDescriptor->num_hdrs = 1;
1170
1171 memset(pHeaderDescriptor->hdr[0].name, 0,
1172 sizeof(pHeaderDescriptor->hdr[0].name));
1173
1174 snprintf(index,sizeof(index), "%d", ipa_if_num);
1175 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
1176 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1177
1178 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WLAN_PARTIAL_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1179 {
1180 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1181 res = IPACM_FAILURE;
1182 goto fail;
1183 }
1184 snprintf(index,sizeof(index), "%d", header_name_count);
1185 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1186 {
1187 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1188 res = IPACM_FAILURE;
1189 goto fail;
1190 }
1191
1192
1193 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
1194 pHeaderDescriptor->hdr[0].hdr_hdl = -1;
1195 pHeaderDescriptor->hdr[0].is_partial = 0;
1196 pHeaderDescriptor->hdr[0].status = -1;
1197
1198 if (m_header.AddHeader(pHeaderDescriptor) == false ||
1199 pHeaderDescriptor->hdr[0].status != 0)
1200 {
1201 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
1202 res = IPACM_FAILURE;
1203 goto fail;
1204 }
1205
1206 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
1207 IPACMDBG_H("client(%d) v4 full header name:%s header handle:(0x%x)\n",
1208 num_wifi_client,
1209 pHeaderDescriptor->hdr[0].name,
1210 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v4);
1211 get_client_memptr(wlan_client, num_wifi_client)->ipv4_header_set=true;
1212 break;
1213 }
1214 }
1215
1216 /* copy partial header for v6*/
1217 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
1218 {
1219 if(tx_prop->tx[cnt].ip==IPA_IP_v6)
1220 {
1221 IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt);
1222 memset(&sCopyHeader, 0, sizeof(sCopyHeader));
1223 memcpy(sCopyHeader.name,
1224 tx_prop->tx[cnt].hdr_name,
1225 sizeof(sCopyHeader.name));
1226
1227 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
1228 if (m_header.CopyHeader(&sCopyHeader) == false)
1229 {
1230 PERROR("ioctl copy header failed");
1231 res = IPACM_FAILURE;
1232 goto fail;
1233 }
1234
1235 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
1236 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
1237 {
1238 IPACMERR("header oversize\n");
1239 res = IPACM_FAILURE;
1240 goto fail;
1241 }
1242 else
1243 {
1244 memcpy(pHeaderDescriptor->hdr[0].hdr,
1245 sCopyHeader.hdr,
1246 sCopyHeader.hdr_len);
1247 }
1248
1249 for(i = 0; i < data->num_of_attribs; i++)
1250 {
1251 if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
1252 {
1253 memcpy(get_client_memptr(wlan_client, num_wifi_client)->mac,
1254 data->attribs[i].u.mac_addr,
1255 sizeof(get_client_memptr(wlan_client, num_wifi_client)->mac));
1256
1257 /* copy client mac_addr to partial header */
1258 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
1259 get_client_memptr(wlan_client, num_wifi_client)->mac,
1260 IPA_MAC_ADDR_SIZE);
1261
1262 /* replace src mac to bridge mac_addr if any */
1263 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
1264 {
1265 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset+IPA_MAC_ADDR_SIZE],
1266 IPACM_Iface::ipacmcfg->bridge_mac,
1267 IPA_MAC_ADDR_SIZE);
1268 IPACMDBG_H("device is in bridge mode \n");
1269 }
1270 }
1271 else if (data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
1272 {
1273 /* copy client id to header */
1274 memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
1275 &data->attribs[i].u.sta_id, sizeof(data->attribs[i].u.sta_id));
1276 }
1277 else
1278 {
1279 IPACMDBG_H("The attribute type is not expected!\n");
1280 }
1281 }
1282
1283 pHeaderDescriptor->commit = true;
1284 pHeaderDescriptor->num_hdrs = 1;
1285
1286 memset(pHeaderDescriptor->hdr[0].name, 0,
1287 sizeof(pHeaderDescriptor->hdr[0].name));
1288
1289 snprintf(index,sizeof(index), "%d", ipa_if_num);
1290 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
1291 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1292 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WLAN_PARTIAL_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1293 {
1294 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1295 res = IPACM_FAILURE;
1296 goto fail;
1297 }
1298
1299 snprintf(index,sizeof(index), "%d", header_name_count);
1300 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
1301 {
1302 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name));
1303 res = IPACM_FAILURE;
1304 goto fail;
1305 }
1306
1307 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
1308 pHeaderDescriptor->hdr[0].hdr_hdl = -1;
1309 pHeaderDescriptor->hdr[0].is_partial = 0;
1310 pHeaderDescriptor->hdr[0].status = -1;
1311
1312 if (m_header.AddHeader(pHeaderDescriptor) == false ||
1313 pHeaderDescriptor->hdr[0].status != 0)
1314 {
1315 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
1316 res = IPACM_FAILURE;
1317 goto fail;
1318 }
1319
1320 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
1321 IPACMDBG_H("client(%d) v6 full header name:%s header handle:(0x%x)\n",
1322 num_wifi_client,
1323 pHeaderDescriptor->hdr[0].name,
1324 get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v6);
1325
1326 get_client_memptr(wlan_client, num_wifi_client)->ipv6_header_set=true;
1327 break;
1328 }
1329 }
1330
1331 /* initialize wifi client*/
1332 get_client_memptr(wlan_client, num_wifi_client)->route_rule_set_v4 = false;
1333 get_client_memptr(wlan_client, num_wifi_client)->route_rule_set_v6 = 0;
1334 get_client_memptr(wlan_client, num_wifi_client)->ipv4_set = false;
1335 get_client_memptr(wlan_client, num_wifi_client)->ipv6_set = 0;
1336 get_client_memptr(wlan_client, num_wifi_client)->power_save_set=false;
1337 num_wifi_client++;
1338 header_name_count++; //keep increasing header_name_count
1339 IPACM_Wlan::total_num_wifi_clients++;
1340 res = IPACM_SUCCESS;
1341 IPACMDBG_H("Wifi client number: %d\n", num_wifi_client);
1342 }
1343 else
1344 {
1345 return res;
1346 }
1347
1348 fail:
1349 free(pHeaderDescriptor);
1350 return res;
1351 }
1352
1353 /*handle wifi client */
handle_wlan_client_ipaddr(ipacm_event_data_all * data)1354 int IPACM_Wlan::handle_wlan_client_ipaddr(ipacm_event_data_all *data)
1355 {
1356 int clnt_indx;
1357 int v6_num;
1358 uint32_t ipv6_link_local_prefix = 0xFE800000;
1359 uint32_t ipv6_link_local_prefix_mask = 0xFFC00000;
1360
1361 IPACMDBG_H("number of wifi clients: %d\n", num_wifi_client);
1362 IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1363 data->mac_addr[0],
1364 data->mac_addr[1],
1365 data->mac_addr[2],
1366 data->mac_addr[3],
1367 data->mac_addr[4],
1368 data->mac_addr[5]);
1369
1370 clnt_indx = get_wlan_client_index(data->mac_addr);
1371
1372 if (clnt_indx == IPACM_INVALID_INDEX)
1373 {
1374 IPACMERR("wlan client not found/attached \n");
1375 return IPACM_FAILURE;
1376 }
1377
1378 IPACMDBG_H("Ip-type received %d\n", data->iptype);
1379 if (data->iptype == IPA_IP_v4)
1380 {
1381 IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr);
1382 if (data->ipv4_addr != 0) /* not 0.0.0.0 */
1383 {
1384 if (get_client_memptr(wlan_client, clnt_indx)->ipv4_set == false)
1385 {
1386 get_client_memptr(wlan_client, clnt_indx)->v4_addr = data->ipv4_addr;
1387 get_client_memptr(wlan_client, clnt_indx)->ipv4_set = true;
1388 }
1389 else
1390 {
1391 /* check if client got new IPv4 address*/
1392 if(data->ipv4_addr == get_client_memptr(wlan_client, clnt_indx)->v4_addr)
1393 {
1394 IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx);
1395 return IPACM_FAILURE;
1396 }
1397 else
1398 {
1399 IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
1400 /* delete NAT rules first */
1401 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clnt_indx)->v4_addr);
1402 delete_default_qos_rtrules(clnt_indx, IPA_IP_v4);
1403 get_client_memptr(wlan_client, clnt_indx)->route_rule_set_v4 = false;
1404 get_client_memptr(wlan_client, clnt_indx)->v4_addr = data->ipv4_addr;
1405 }
1406 }
1407 }
1408 else
1409 {
1410 IPACMDBG_H("Invalid client IPv4 address \n");
1411 return IPACM_FAILURE;
1412 }
1413 }
1414 else
1415 {
1416 if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
1417 (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) /* check if all 0 not valid ipv6 address */
1418 {
1419 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]);
1420 if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) &&
1421 memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0)
1422 {
1423 IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n");
1424 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]);
1425 return IPACM_FAILURE;
1426 }
1427
1428 if(get_client_memptr(wlan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
1429 {
1430
1431 for(v6_num=0;v6_num < get_client_memptr(wlan_client, clnt_indx)->ipv6_set;v6_num++)
1432 {
1433 if( data->ipv6_addr[0] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][0] &&
1434 data->ipv6_addr[1] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][1] &&
1435 data->ipv6_addr[2]== get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][2] &&
1436 data->ipv6_addr[3] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][3])
1437 {
1438 IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx);
1439 return IPACM_FAILURE; /* not setup the RT rules*/
1440 break;
1441 }
1442 }
1443
1444 /* not see this ipv6 before for wifi client*/
1445 get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0];
1446 get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1];
1447 get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2];
1448 get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3];
1449 get_client_memptr(wlan_client, clnt_indx)->ipv6_set++;
1450 }
1451 else
1452 {
1453 IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx);
1454 return IPACM_FAILURE; /* not setup the RT rules*/
1455 }
1456 }
1457 else
1458 {
1459 IPACMDBG_H("IPV6 address is invalid\n");
1460 return IPACM_FAILURE;
1461 }
1462 }
1463
1464 return IPACM_SUCCESS;
1465 }
1466
1467 /*handle wifi client routing rule*/
handle_wlan_client_route_rule(uint8_t * mac_addr,ipa_ip_type iptype)1468 int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype)
1469 {
1470 struct ipa_ioc_add_rt_rule *rt_rule;
1471 struct ipa_rt_rule_add *rt_rule_entry;
1472 uint32_t tx_index;
1473 int wlan_index,v6_num;
1474 const int NUM = 1;
1475 bool result;
1476
1477 if(tx_prop == NULL)
1478 {
1479 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
1480 return IPACM_SUCCESS;
1481 }
1482
1483 IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1484 mac_addr[0], mac_addr[1], mac_addr[2],
1485 mac_addr[3], mac_addr[4], mac_addr[5]);
1486
1487 wlan_index = get_wlan_client_index(mac_addr);
1488 if (wlan_index == IPACM_INVALID_INDEX)
1489 {
1490 IPACMDBG_H("wlan client not found/attached \n");
1491 return IPACM_SUCCESS;
1492 }
1493
1494 /* during power_save mode, even receive IP_ADDR_ADD, not setting RT rules*/
1495 if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true)
1496 {
1497 IPACMDBG_H("wlan client is in power safe mode \n");
1498 return IPACM_SUCCESS;
1499 }
1500
1501 if (iptype==IPA_IP_v4)
1502 {
1503 IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", wlan_index, iptype,
1504 get_client_memptr(wlan_client, wlan_index)->ipv4_set,
1505 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4);
1506 }
1507 else
1508 {
1509 IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wlan_index, iptype,
1510 get_client_memptr(wlan_client, wlan_index)->ipv6_set,
1511 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6);
1512 }
1513
1514
1515 /* Add default Qos routing rules if not set yet */
1516 if ((iptype == IPA_IP_v4
1517 && get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 == false
1518 && get_client_memptr(wlan_client, wlan_index)->ipv4_set == true)
1519 || (iptype == IPA_IP_v6
1520 && get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 < get_client_memptr(wlan_client, wlan_index)->ipv6_set
1521 ))
1522 {
1523 rt_rule = (struct ipa_ioc_add_rt_rule *)
1524 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
1525 NUM * sizeof(struct ipa_rt_rule_add));
1526
1527 if (rt_rule == NULL)
1528 {
1529 PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n");
1530 return IPACM_FAILURE;
1531 }
1532
1533 rt_rule->commit = 1;
1534 rt_rule->num_rules = (uint8_t)NUM;
1535 rt_rule->ip = iptype;
1536
1537
1538 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
1539 {
1540
1541 if(iptype != tx_prop->tx[tx_index].ip)
1542 {
1543 IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n",
1544 tx_index, tx_prop->tx[tx_index].ip,iptype);
1545 continue;
1546 }
1547
1548 rt_rule_entry = &rt_rule->rules[0];
1549 rt_rule_entry->at_rear = 0;
1550
1551 if (iptype == IPA_IP_v4)
1552 {
1553 IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wlan_index,
1554 get_client_memptr(wlan_client, wlan_index)->v4_addr);
1555
1556 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
1557 wlan_index,
1558 get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4);
1559 strlcpy(rt_rule->rt_tbl_name,
1560 IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name,
1561 sizeof(rt_rule->rt_tbl_name));
1562 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1563
1564 if(!strcmp("wigig0", dev_name))
1565 {
1566 IPACMDBG_H("for WIGIG client use relevant pipe %d\n",
1567 get_client_memptr(wlan_client, wlan_index)->wigig_ipa_client);
1568 rt_rule_entry->rule.dst = get_client_memptr(wlan_client, wlan_index)->wigig_ipa_client;
1569 }
1570 else
1571 {
1572 if(IPACM_Iface::ipacmcfg->isMCC_Mode)
1573 {
1574 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
1575 tx_prop->tx[tx_index].alt_dst_pipe);
1576 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
1577 }
1578 else
1579 {
1580 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
1581 }
1582 }
1583
1584 memcpy(&rt_rule_entry->rule.attrib,
1585 &tx_prop->tx[tx_index].attrib,
1586 sizeof(rt_rule_entry->rule.attrib));
1587 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1588 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4;
1589 rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr;
1590 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
1591
1592 if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0)
1593 {
1594 rt_rule_entry->rule.hashable = true;
1595 }
1596 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
1597 /* use index hw-counter */
1598 if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
1599 {
1600 IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
1601 result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
1602 } else {
1603 result = m_routing.AddRoutingRule(rt_rule);
1604 }
1605 #else
1606 result = m_routing.AddRoutingRule(rt_rule);
1607 #endif
1608 if (result == false)
1609 {
1610 IPACMERR("Routing rule addition failed!\n");
1611 free(rt_rule);
1612 return IPACM_FAILURE;
1613 }
1614
1615 /* copy ipv4 RT hdl */
1616 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4 =
1617 rt_rule->rules[0].rt_rule_hdl;
1618 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
1619 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4, iptype);
1620 }
1621 else
1622 {
1623 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++)
1624 {
1625 IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
1626 wlan_index,
1627 get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6);
1628
1629 /* v6 LAN_RT_TBL */
1630 strlcpy(rt_rule->rt_tbl_name,
1631 IPACM_Iface::ipacmcfg->rt_tbl_v6.name,
1632 sizeof(rt_rule->rt_tbl_name));
1633 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1634 /* Support QCMAP LAN traffic feature, send to A5 */
1635 rt_rule_entry->rule.dst = iface_query->excp_pipe;
1636 memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib));
1637 rt_rule_entry->rule.hdr_hdl = 0;
1638 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1639 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0];
1640 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1];
1641 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2];
1642 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3];
1643 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
1644 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
1645 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
1646 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
1647 if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
1648 rt_rule_entry->rule.hashable = true;
1649 if (false == m_routing.AddRoutingRule(rt_rule))
1650 {
1651 IPACMERR("Routing rule addition failed!\n");
1652 free(rt_rule);
1653 return IPACM_FAILURE;
1654 }
1655
1656 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;
1657 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
1658 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[v6_num], iptype);
1659
1660 /*Copy same rule to v6 WAN RT TBL*/
1661 strlcpy(rt_rule->rt_tbl_name,
1662 IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name,
1663 sizeof(rt_rule->rt_tbl_name));
1664 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
1665 /* Downlink traffic from Wan iface, directly through IPA */
1666 if(!strcmp("wigig0", dev_name))
1667 {
1668 IPACMDBG_H("for WIGIG client use relevant pipe %d\n",
1669 get_client_memptr(wlan_client, wlan_index)->wigig_ipa_client);
1670 rt_rule_entry->rule.dst = get_client_memptr(wlan_client, wlan_index)->wigig_ipa_client;
1671 }
1672 else
1673 {
1674 if(IPACM_Iface::ipacmcfg->isMCC_Mode)
1675 {
1676 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
1677 tx_prop->tx[tx_index].alt_dst_pipe);
1678 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
1679 }
1680 else
1681 {
1682 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
1683 }
1684 }
1685 memcpy(&rt_rule_entry->rule.attrib,
1686 &tx_prop->tx[tx_index].attrib,
1687 sizeof(rt_rule_entry->rule.attrib));
1688 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6;
1689 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
1690 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0];
1691 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1];
1692 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2];
1693 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3];
1694 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
1695 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
1696 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
1697 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
1698 if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
1699 rt_rule_entry->rule.hashable = true;
1700 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
1701 /* use index hw-counter */
1702 if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
1703 {
1704 IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
1705 result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
1706 } else {
1707 result = m_routing.AddRoutingRule(rt_rule);
1708 }
1709 #else
1710 result = m_routing.AddRoutingRule(rt_rule);
1711 #endif
1712
1713 if (result == false)
1714 {
1715 IPACMERR("Routing rule addition failed!\n");
1716 free(rt_rule);
1717 return IPACM_FAILURE;
1718 }
1719
1720 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;
1721
1722 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
1723 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num], iptype);
1724
1725 /* send client-v6 info to pcie modem only with global ipv6 with tx_index = 0 one time*/
1726 if(is_global_ipv6_addr(get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num]) && (IPACM_Wan::backhaul_mode == Q6_MHI_WAN))
1727 {
1728 if (add_connection(wlan_index, v6_num))
1729 {
1730 IPACMERR("PCIE filter rule addition failed! (%d-client) %d v6-entry\n",wlan_index, v6_num);
1731 }
1732 }
1733 }
1734 }
1735
1736 } /* end of for loop */
1737
1738 free(rt_rule);
1739
1740 if (iptype == IPA_IP_v4)
1741 {
1742 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 = true;
1743 }
1744 else
1745 {
1746 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 = get_client_memptr(wlan_client, wlan_index)->ipv6_set;
1747 }
1748 }
1749
1750 return IPACM_SUCCESS;
1751 }
1752
1753 /*handle wifi client power-save mode*/
handle_wlan_client_pwrsave(uint8_t * mac_addr)1754 int IPACM_Wlan::handle_wlan_client_pwrsave(uint8_t *mac_addr)
1755 {
1756 int clt_indx;
1757 IPACMDBG_H("wlan->handle_wlan_client_pwrsave();\n");
1758
1759 clt_indx = get_wlan_client_index(mac_addr);
1760 if (clt_indx == IPACM_INVALID_INDEX)
1761 {
1762 IPACMDBG_H("wlan client not attached\n");
1763 return IPACM_SUCCESS;
1764 }
1765
1766 if (get_client_memptr(wlan_client, clt_indx)->power_save_set == false)
1767 {
1768 /* First reset nat rules and then route rules */
1769 if(get_client_memptr(wlan_client, clt_indx)->ipv4_set == true)
1770 {
1771 IPACMDBG_H("Deleting Nat Rules\n");
1772 Nat_App->UpdatePwrSaveIf(get_client_memptr(wlan_client, clt_indx)->v4_addr);
1773 }
1774
1775 IPACMDBG_H("Deleting default qos Route Rules\n");
1776 delete_default_qos_rtrules(clt_indx, IPA_IP_v4);
1777 delete_default_qos_rtrules(clt_indx, IPA_IP_v6);
1778 get_client_memptr(wlan_client, clt_indx)->power_save_set = true;
1779 }
1780 else
1781 {
1782 IPACMDBG_H("wlan client already in power-save mode\n");
1783 }
1784 return IPACM_SUCCESS;
1785 }
1786
1787 /*handle wifi client del mode*/
handle_wlan_client_down_evt(uint8_t * mac_addr)1788 int IPACM_Wlan::handle_wlan_client_down_evt(uint8_t *mac_addr)
1789 {
1790 int clt_indx;
1791 uint32_t tx_index;
1792 int num_wifi_client_tmp = num_wifi_client;
1793 int num_v6;
1794
1795 IPACMDBG_H("total client: %d\n", num_wifi_client_tmp);
1796
1797 clt_indx = get_wlan_client_index(mac_addr);
1798 if (clt_indx == IPACM_INVALID_INDEX)
1799 {
1800 IPACMDBG_H("wlan client not attached\n");
1801 return IPACM_SUCCESS;
1802 }
1803
1804 /* First reset nat rules and then route rules */
1805 if(get_client_memptr(wlan_client, clt_indx)->ipv4_set == true)
1806 {
1807 IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, clt_indx)->v4_addr);
1808 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clt_indx)->v4_addr);
1809 }
1810
1811 if(delete_default_qos_rtrules(clt_indx, IPA_IP_v4))
1812 {
1813 IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", clt_indx);
1814 return IPACM_FAILURE;
1815 }
1816
1817 if(delete_default_qos_rtrules(clt_indx, IPA_IP_v6))
1818 {
1819 IPACMERR("unbale to delete v6 default qos route rules for indexn: %d\n", clt_indx);
1820 return IPACM_FAILURE;
1821 }
1822
1823 /* Delete wlan client header */
1824 if(get_client_memptr(wlan_client, clt_indx)->ipv4_header_set == true)
1825 {
1826 if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v4)
1827 == false)
1828 {
1829 return IPACM_FAILURE;
1830 }
1831 get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = false;
1832 }
1833
1834 if(get_client_memptr(wlan_client, clt_indx)->ipv6_header_set == true)
1835 {
1836 if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v6)
1837 == false)
1838 {
1839 return IPACM_FAILURE;
1840 }
1841 get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = false;
1842 }
1843
1844 /* Reset ip_set to 0*/
1845 get_client_memptr(wlan_client, clt_indx)->ipv4_set = false;
1846 get_client_memptr(wlan_client, clt_indx)->ipv6_set = 0;
1847 get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = false;
1848 get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = false;
1849 get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = false;
1850 get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = 0;
1851 free(get_client_memptr(wlan_client, clt_indx)->p_hdr_info);
1852
1853 for (; clt_indx < num_wifi_client_tmp - 1; clt_indx++)
1854 {
1855 get_client_memptr(wlan_client, clt_indx)->p_hdr_info = get_client_memptr(wlan_client, (clt_indx + 1))->p_hdr_info;
1856
1857 memcpy(get_client_memptr(wlan_client, clt_indx)->mac,
1858 get_client_memptr(wlan_client, (clt_indx + 1))->mac,
1859 sizeof(get_client_memptr(wlan_client, clt_indx)->mac));
1860
1861 get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v4 = get_client_memptr(wlan_client, (clt_indx + 1))->hdr_hdl_v4;
1862 get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v6 = get_client_memptr(wlan_client, (clt_indx + 1))->hdr_hdl_v6;
1863 get_client_memptr(wlan_client, clt_indx)->v4_addr = get_client_memptr(wlan_client, (clt_indx + 1))->v4_addr;
1864
1865 get_client_memptr(wlan_client, clt_indx)->ipv4_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv4_set;
1866 get_client_memptr(wlan_client, clt_indx)->ipv6_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv6_set;
1867 get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv4_header_set;
1868 get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv6_header_set;
1869
1870 get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = get_client_memptr(wlan_client, (clt_indx + 1))->route_rule_set_v4;
1871 get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = get_client_memptr(wlan_client, (clt_indx + 1))->route_rule_set_v6;
1872
1873 for(num_v6=0;num_v6< get_client_memptr(wlan_client, clt_indx)->ipv6_set;num_v6++)
1874 {
1875 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];
1876 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];
1877 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];
1878 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];
1879 }
1880
1881 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
1882 {
1883 get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4 =
1884 get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4;
1885
1886 for(num_v6=0;num_v6< get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6;num_v6++)
1887 {
1888 get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6] =
1889 get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6];
1890 get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6] =
1891 get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6];
1892 }
1893 }
1894 }
1895
1896 IPACMDBG_H(" %d wifi client deleted successfully \n", num_wifi_client);
1897 num_wifi_client = num_wifi_client - 1;
1898 IPACM_Wlan::total_num_wifi_clients = IPACM_Wlan::total_num_wifi_clients - 1;
1899 IPACMDBG_H(" Number of wifi client: %d\n", num_wifi_client);
1900
1901 return IPACM_SUCCESS;
1902 }
1903
1904 /*handle wlan iface down event*/
handle_down_evt()1905 int IPACM_Wlan::handle_down_evt()
1906 {
1907 int res = IPACM_SUCCESS, num_private_subnet_fl_rule;
1908 uint32_t i;
1909 num_private_subnet_fl_rule = 0;
1910
1911 IPACMDBG_H("WLAN ip-type: %d \n", ip_type);
1912 /* no iface address up, directly close iface*/
1913 if (ip_type == IPACM_IP_NULL)
1914 {
1915 IPACMERR("Invalid iptype: 0x%x\n", ip_type);
1916 goto fail;
1917 }
1918
1919 /* delete wan filter rule */
1920 if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
1921 {
1922 IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
1923 IPACM_Lan::handle_wan_down(IPACM_Wan::backhaul_mode);
1924 #ifdef FEATURE_IPA_ANDROID
1925 #ifndef FEATURE_IPACM_HAL
1926 /* Clean-up tethered-iface list */
1927 IPACM_Wan::delete_tether_iface(IPA_IP_v4, ipa_if_num);
1928 #endif
1929 #endif
1930 }
1931
1932 if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
1933 {
1934 IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
1935 handle_wan_down_v6(IPACM_Wan::backhaul_mode);
1936 #ifdef FEATURE_IPA_ANDROID
1937 /* Clean-up tethered-iface list */
1938 IPACM_Wan::delete_tether_iface(IPA_IP_v6, ipa_if_num);
1939 #endif
1940 }
1941 IPACMDBG_H("finished deleting wan filtering rules\n ");
1942
1943 /* Delete v4 filtering rules */
1944 if (ip_type != IPA_IP_v6 && rx_prop != NULL)
1945 {
1946 /* delete IPv4 icmp filter rules */
1947 if(m_filtering.DeleteFilteringHdls(ipv4_icmp_flt_rule_hdl, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE) == false)
1948 {
1949 IPACMERR("Error Deleting ICMPv4 Filtering Rule, aborting...\n");
1950 res = IPACM_FAILURE;
1951 goto fail;
1952 }
1953 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE);
1954 if (dft_v4fl_rule_hdl[0] != 0)
1955 {
1956 if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false)
1957 {
1958 IPACMERR("Error Deleting Filtering Rule, aborting...\n");
1959 res = IPACM_FAILURE;
1960 goto fail;
1961 }
1962 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
1963 IPACMDBG_H("Deleted default v4 filter rules successfully.\n");
1964 }
1965 /* delete private-ipv4 filter rules */
1966 #ifdef FEATURE_IPA_ANDROID
1967 if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) == false)
1968 {
1969 IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
1970 res = IPACM_FAILURE;
1971 goto fail;
1972 }
1973 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES);
1974 #else
1975 num_private_subnet_fl_rule = IPACM_Iface::ipacmcfg->ipa_num_private_subnet > (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES)?
1976 (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) : IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
1977 if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, num_private_subnet_fl_rule) == false)
1978 {
1979 IPACMERR("Error deleting private subnet flt rules, aborting...\n");
1980 res = IPACM_FAILURE;
1981 goto fail;
1982 }
1983 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_private_subnet_fl_rule);
1984 #endif
1985 IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n");
1986
1987 #ifdef FEATURE_L2TP
1988 if(m_filtering.DeleteFilteringHdls(&tcp_syn_flt_rule_hdl[IPA_IP_v4], IPA_IP_v4, 1) == false)
1989 {
1990 IPACMERR("Error deleting tcp syn flt rule, aborting...\n");
1991 res = IPACM_FAILURE;
1992 goto fail;
1993 }
1994 #endif
1995 }
1996
1997 /* Delete v6 filtering rules */
1998 if (ip_type != IPA_IP_v4 && rx_prop != NULL)
1999 {
2000 /* delete icmp filter rules */
2001 if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false)
2002 {
2003 IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n");
2004 res = IPACM_FAILURE;
2005 goto fail;
2006 }
2007 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE);
2008
2009 if (dft_v6fl_rule_hdl[0] != 0)
2010 {
2011 if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false)
2012 {
2013 IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
2014 res = IPACM_FAILURE;
2015 goto fail;
2016 }
2017 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
2018 IPACMDBG_H("Deleted default v6 filter rules successfully.\n");
2019 }
2020 #ifdef FEATURE_L2TP
2021 if(m_filtering.DeleteFilteringHdls(&tcp_syn_flt_rule_hdl[IPA_IP_v6], IPA_IP_v6, 1) == false)
2022 {
2023 IPACMERR("Error deleting tcp syn flt rule, aborting...\n");
2024 res = IPACM_FAILURE;
2025 goto fail;
2026 }
2027 #endif
2028 }
2029 IPACMDBG_H("finished delete filtering rules\n ");
2030
2031 /* Delete default v4 RT rule */
2032 if (ip_type != IPA_IP_v6)
2033 {
2034 IPACMDBG_H("Delete default v4 routing rules\n");
2035 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4)
2036 == false)
2037 {
2038 IPACMERR("Routing rule deletion failed!\n");
2039 res = IPACM_FAILURE;
2040 goto fail;
2041 }
2042 }
2043
2044 /* Delete default v6 RT rule */
2045 if (ip_type != IPA_IP_v4)
2046 {
2047 IPACMDBG_H("Delete default v6 routing rules\n");
2048 /* May have multiple ipv6 iface-RT rules */
2049 for (i = 0; i < 2*num_dft_rt_v6; i++)
2050 {
2051 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6)
2052 == false)
2053 {
2054 IPACMERR("Routing rule deletion failed!\n");
2055 res = IPACM_FAILURE;
2056 goto fail;
2057 }
2058 }
2059 }
2060 IPACMDBG_H("finished deleting default RT rules\n ");
2061
2062 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL, NULL, NULL, IPA_CLIENT_MAX);
2063
2064 /* free the wlan clients cache */
2065 IPACMDBG_H("Free wlan clients cache\n");
2066
2067 /* Delete private subnet*/
2068 #ifdef FEATURE_IPA_ANDROID
2069 if (ip_type != IPA_IP_v6)
2070 {
2071 IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
2072 IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
2073 if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
2074 {
2075 IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
2076 }
2077 }
2078 /* reset the IPA-client pipe enum */
2079 #ifdef FEATURE_IPACM_HAL
2080 handle_tethering_client(true, IPACM_CLIENT_MAX);
2081 #else
2082 handle_tethering_client(true, IPACM_CLIENT_WLAN);
2083 #endif
2084 #endif /* defined(FEATURE_IPA_ANDROID)*/
2085
2086 fail:
2087 /* clean wifi-client header, routing rules */
2088 /* clean wifi client rule*/
2089 IPACMDBG_H("left %d wifi clients need to be deleted \n ", num_wifi_client);
2090 for (i = 0; i < num_wifi_client; i++)
2091 {
2092 /* First reset nat rules and then route rules */
2093 if(get_client_memptr(wlan_client, i)->ipv4_set == true)
2094 {
2095 IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, i)->v4_addr);
2096 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, i)->v4_addr);
2097 }
2098
2099 if (delete_default_qos_rtrules(i, IPA_IP_v4))
2100 {
2101 IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", i);
2102 res = IPACM_FAILURE;
2103 }
2104
2105 if (delete_default_qos_rtrules(i, IPA_IP_v6))
2106 {
2107 IPACMERR("unbale to delete v6 default qos route rules for index: %d\n", i);
2108 res = IPACM_FAILURE;
2109 }
2110
2111 IPACMDBG_H("Delete %d client header\n", num_wifi_client);
2112
2113 if(get_client_memptr(wlan_client, i)->ipv4_header_set == true)
2114 {
2115 if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v4)
2116 == false)
2117 {
2118 res = IPACM_FAILURE;
2119 }
2120 }
2121
2122 if(get_client_memptr(wlan_client, i)->ipv6_header_set == true)
2123 {
2124 if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v6)
2125 == false)
2126 {
2127 res = IPACM_FAILURE;
2128 }
2129 }
2130 } /* end of for loop */
2131
2132 /* check software routing fl rule hdl */
2133 if (softwarerouting_act == true && rx_prop != NULL )
2134 {
2135 IPACMDBG_H("Delete sw routing filtering rules\n");
2136 IPACM_Iface::handle_software_routing_disable(false);
2137 }
2138 IPACMDBG_H("finished delete software-routing filtering rules\n ");
2139
2140 if (rx_prop != NULL)
2141 {
2142 if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
2143 {
2144 /* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
2145 IPACMDBG_H("dev %s add producer dependency\n", dev_name);
2146 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]);
2147 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
2148 }
2149 if (!(IPACM_Iface::ipacmcfg->isEthBridgingSupported()))
2150 free(rx_prop);
2151 }
2152
2153 for (i = 0; i < num_wifi_client; i++)
2154 {
2155 if(get_client_memptr(wlan_client, i)->p_hdr_info != NULL)
2156 {
2157 free(get_client_memptr(wlan_client, i)->p_hdr_info);
2158 }
2159 }
2160 if(wlan_client != NULL)
2161 {
2162 free(wlan_client);
2163 }
2164 if (!(IPACM_Iface::ipacmcfg->isEthBridgingSupported()))
2165 {
2166 if (tx_prop != NULL)
2167 {
2168 free(tx_prop);
2169 }
2170
2171 if (iface_query != NULL)
2172 {
2173 free(iface_query);
2174 }
2175 }
2176
2177 is_active = false;
2178 post_del_self_evt();
2179
2180 return res;
2181 }
2182
2183 /*handle reset wifi-client rt-rules */
handle_wlan_client_reset_rt(ipa_ip_type iptype)2184 int IPACM_Wlan::handle_wlan_client_reset_rt(ipa_ip_type iptype)
2185 {
2186 uint32_t i;
2187 int res = IPACM_SUCCESS;
2188
2189 /* clean wifi-client routing rules */
2190 IPACMDBG_H("left %d wifi clients to reset ip-type(%d) rules \n ", num_wifi_client, iptype);
2191
2192 for (i = 0; i < num_wifi_client; i++)
2193 {
2194 /* Reset RT rules */
2195 res = delete_default_qos_rtrules(i, iptype);
2196 if (res != IPACM_SUCCESS)
2197 {
2198 IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype);
2199 return res;
2200 }
2201
2202 /* Reset ip-address */
2203 if(iptype == IPA_IP_v4)
2204 {
2205 get_client_memptr(wlan_client, i)->ipv4_set = false;
2206 }
2207 else
2208 {
2209 get_client_memptr(wlan_client, i)->ipv6_set = 0;
2210 }
2211 } /* end of for loop */
2212 return res;
2213 }
2214
handle_SCC_MCC_switch(ipa_ip_type iptype)2215 void IPACM_Wlan::handle_SCC_MCC_switch(ipa_ip_type iptype)
2216 {
2217 struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL;
2218 struct ipa_rt_rule_mdfy *rt_rule_entry;
2219 uint32_t tx_index;
2220 int wlan_index, v6_num;
2221 const int NUM = 1;
2222 int num_wifi_client_tmp = IPACM_Wlan::num_wifi_client;
2223 bool isAdded = false;
2224
2225 if (tx_prop == NULL)
2226 {
2227 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
2228 return;
2229 }
2230
2231 if (rt_rule == NULL)
2232 {
2233 rt_rule = (struct ipa_ioc_mdfy_rt_rule *)
2234 calloc(1, sizeof(struct ipa_ioc_mdfy_rt_rule) +
2235 NUM * sizeof(struct ipa_rt_rule_mdfy));
2236
2237 if (rt_rule == NULL)
2238 {
2239 PERROR("Error Locate ipa_ioc_mdfy_rt_rule memory...\n");
2240 return;
2241 }
2242
2243 rt_rule->commit = 0;
2244 rt_rule->num_rules = NUM;
2245 rt_rule->ip = iptype;
2246 }
2247 rt_rule_entry = &rt_rule->rules[0];
2248
2249 /* modify ipv4 routing rule */
2250 if (iptype == IPA_IP_v4)
2251 {
2252 for (wlan_index = 0; wlan_index < num_wifi_client_tmp; wlan_index++)
2253 {
2254 IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n",
2255 wlan_index, iptype,
2256 get_client_memptr(wlan_client, wlan_index)->ipv4_set,
2257 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4);
2258
2259 if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true ||
2260 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 == false)
2261 {
2262 IPACMDBG_H("client %d route rules not set\n", wlan_index);
2263 continue;
2264 }
2265
2266 IPACMDBG_H("Modify client %d route rule\n", wlan_index);
2267 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2268 {
2269 if (iptype != tx_prop->tx[tx_index].ip)
2270 {
2271 IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d ignore\n",
2272 tx_index, tx_prop->tx[tx_index].ip, iptype);
2273 continue;
2274 }
2275
2276 IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wlan_index,
2277 get_client_memptr(wlan_client, wlan_index)->v4_addr);
2278
2279 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
2280 wlan_index,
2281 get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4);
2282
2283 if (IPACM_Iface::ipacmcfg->isMCC_Mode)
2284 {
2285 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
2286 tx_prop->tx[tx_index].alt_dst_pipe);
2287 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
2288 }
2289 else
2290 {
2291 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2292 }
2293
2294 memcpy(&rt_rule_entry->rule.attrib,
2295 &tx_prop->tx[tx_index].attrib,
2296 sizeof(rt_rule_entry->rule.attrib));
2297
2298 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2299 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4;
2300
2301 rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr;
2302 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
2303
2304 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
2305 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4, iptype);
2306
2307 rt_rule_entry->rt_rule_hdl =
2308 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4;
2309
2310 if (false == m_routing.ModifyRoutingRule(rt_rule))
2311 {
2312 IPACMERR("Routing rule modify failed!\n");
2313 free(rt_rule);
2314 return;
2315 }
2316 isAdded = true;
2317 }
2318
2319 }
2320 }
2321
2322 /* modify ipv6 routing rule */
2323 if (iptype == IPA_IP_v6)
2324 {
2325 for (wlan_index = 0; wlan_index < num_wifi_client_tmp; wlan_index++)
2326 {
2327
2328 IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wlan_index, iptype,
2329 get_client_memptr(wlan_client, wlan_index)->ipv6_set,
2330 get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6);
2331
2332 if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true ||
2333 (get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 <
2334 get_client_memptr(wlan_client, wlan_index)->ipv6_set) )
2335 {
2336 IPACMDBG_H("client %d route rules not set\n", wlan_index);
2337 continue;
2338 }
2339
2340 IPACMDBG_H("Modify client %d route rule\n", wlan_index);
2341 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
2342 {
2343 if (iptype != tx_prop->tx[tx_index].ip)
2344 {
2345 IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d Ignore\n",
2346 tx_index, tx_prop->tx[tx_index].ip, iptype);
2347 continue;
2348 }
2349
2350 for (v6_num = get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6;
2351 v6_num < get_client_memptr(wlan_client, wlan_index)->ipv6_set;
2352 v6_num++)
2353 {
2354
2355 IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n",
2356 wlan_index,
2357 get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6);
2358
2359 if (IPACM_Iface::ipacmcfg->isMCC_Mode)
2360 {
2361 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
2362 tx_prop->tx[tx_index].alt_dst_pipe);
2363 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
2364 }
2365 else
2366 {
2367 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
2368 }
2369
2370 memcpy(&rt_rule_entry->rule.attrib,
2371 &tx_prop->tx[tx_index].attrib,
2372 sizeof(rt_rule_entry->rule.attrib));
2373
2374 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6;
2375 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2376
2377 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0];
2378 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1];
2379 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2];
2380 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3];
2381 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2382 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2383 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2384 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2385
2386 rt_rule_entry->rt_rule_hdl =
2387 get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num];
2388
2389 if (false == m_routing.ModifyRoutingRule(rt_rule))
2390 {
2391 IPACMERR("Routing rule modify failed!\n");
2392 free(rt_rule);
2393 return;
2394 }
2395 isAdded = true;
2396 }
2397 }
2398
2399 }
2400 }
2401
2402
2403 if (isAdded)
2404 {
2405 if (false == m_routing.Commit(iptype))
2406 {
2407 IPACMERR("Routing rule modify commit failed!\n");
2408 free(rt_rule);
2409 return;
2410 }
2411
2412 IPACMDBG("Routing rule modified successfully \n");
2413 }
2414
2415 if(rt_rule)
2416 {
2417 free(rt_rule);
2418 }
2419 return;
2420 }
2421
2422 #ifdef FEATURE_IPACM_RESTART
ipa_query_wlan_client()2423 int IPACM_Wlan::ipa_query_wlan_client()
2424 {
2425 int fd = -1;
2426
2427 if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
2428 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
2429 return IPACM_FAILURE;
2430 }
2431
2432 if (ioctl(fd, IPA_IOC_QUERY_WLAN_CLIENT) < 0) {
2433 IPACMERR("IOCTL IPA_IOC_QUERY_WLAN_CLIENT call failed: %s \n", strerror(errno));
2434 close(fd);
2435 return IPACM_FAILURE;
2436 }
2437
2438 IPACMDBG_H("send IPA_IOC_QUERY_WLAN_CLIENT \n");
2439 close(fd);
2440 return IPACM_SUCCESS;
2441 }
2442 #endif
2443
eth_bridge_handle_wlan_mode_switch()2444 void IPACM_Wlan::eth_bridge_handle_wlan_mode_switch()
2445 {
2446 uint32_t i;
2447
2448 /* ====== post events to mimic WLAN interface goes down/up when AP mode is changing ====== */
2449
2450 /* first post IFACE_DOWN event */
2451 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL, NULL, NULL, IPA_CLIENT_MAX);
2452
2453 /* then post IFACE_UP event */
2454 if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
2455 {
2456 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL, NULL, NULL, IPA_CLIENT_MAX);
2457 }
2458 if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
2459 {
2460 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL, NULL, NULL, IPA_CLIENT_MAX);
2461 }
2462
2463 /* at last post CLIENT_ADD event */
2464 for(i = 0; i < num_wifi_client; i++)
2465 {
2466 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX,
2467 get_client_memptr(wlan_client, i)->mac, NULL, NULL, IPA_CLIENT_MAX);
2468 }
2469
2470 return;
2471 }
2472
is_guest_ap()2473 bool IPACM_Wlan::is_guest_ap()
2474 {
2475 return m_is_guest_ap;
2476 }
2477
add_connection(int client_index,int v6_num)2478 int IPACM_Wlan::add_connection(int client_index, int v6_num)
2479 {
2480 int len, res = IPACM_SUCCESS;
2481 uint8_t mux_id;
2482 ipa_ioc_add_flt_rule *pFilteringTable = NULL;
2483 int fd;
2484
2485 mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
2486 /* contruct filter rules to pcie modem */
2487 struct ipa_flt_rule_add flt_rule_entry;
2488 ipa_ioc_generate_flt_eq flt_eq;
2489
2490 IPACMDBG("\n");
2491 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
2492 pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
2493 if (pFilteringTable == NULL)
2494 {
2495 IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
2496 return IPACM_FAILURE;
2497 }
2498 memset(pFilteringTable, 0, len);
2499
2500
2501 pFilteringTable->commit = 1;
2502 pFilteringTable->global = false;
2503 pFilteringTable->ip = IPA_IP_v6;
2504 pFilteringTable->num_rules = (uint8_t)1;
2505
2506 /* Configuring Filtering Rule */
2507 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
2508 flt_rule_entry.at_rear = true;
2509 flt_rule_entry.flt_rule_hdl = -1;
2510 flt_rule_entry.status = -1;
2511
2512 flt_rule_entry.rule.retain_hdr = 1;
2513 flt_rule_entry.rule.to_uc = 0;
2514 flt_rule_entry.rule.eq_attrib_type = 1;
2515 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
2516 if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
2517 flt_rule_entry.rule.hashable = true;
2518 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
2519 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][0];
2520 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][1];
2521 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][2];
2522 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][3];
2523 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
2524 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
2525 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
2526 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
2527
2528 IPACMDBG_H("ipv6 address got: 0x%x:%x:%x:%x\n", get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][0],
2529 get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][1],
2530 get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][2],
2531 get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][3]);
2532
2533 /* change to network order for modem */
2534 change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
2535
2536 memset(&flt_eq, 0, sizeof(flt_eq));
2537 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
2538 flt_eq.ip = IPA_IP_v6;
2539
2540 fd = open(IPA_DEVICE_NAME, O_RDWR);
2541 if (fd < 0)
2542 {
2543 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
2544 free(pFilteringTable);
2545 return IPACM_FAILURE;
2546 }
2547
2548 if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
2549 {
2550 IPACMERR("Failed to get eq_attrib\n");
2551 res = IPACM_FAILURE;
2552 goto fail;
2553 }
2554 memcpy(&flt_rule_entry.rule.eq_attrib,
2555 &flt_eq.eq_attrib,
2556 sizeof(flt_rule_entry.rule.eq_attrib));
2557 memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
2558
2559 if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 0))
2560 {
2561 IPACMERR("Failed to install WAN DL filtering table.\n");
2562 res = IPACM_FAILURE;
2563 goto fail;
2564 }
2565
2566 get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num] = pFilteringTable->rules[0].flt_rule_hdl;
2567 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]);
2568
2569 fail:
2570 close(fd);
2571 if(pFilteringTable != NULL)
2572 {
2573 free(pFilteringTable);
2574 }
2575 return res;
2576 }
2577
del_connection(int client_index,int v6_num)2578 int IPACM_Wlan::del_connection(int client_index, int v6_num)
2579 {
2580 int len, res = IPACM_SUCCESS;
2581 ipa_ioc_del_flt_rule *pFilteringTable = NULL;
2582
2583 struct ipa_flt_rule_del flt_rule_entry;
2584
2585 IPACMDBG("\n");
2586 len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
2587 pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
2588 if (pFilteringTable == NULL)
2589 {
2590 IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
2591 return IPACM_FAILURE;
2592 }
2593 memset(pFilteringTable, 0, len);
2594
2595
2596 pFilteringTable->commit = 1;
2597 pFilteringTable->ip = IPA_IP_v6;
2598 pFilteringTable->num_hdls = (uint8_t)1;
2599
2600 /* Configuring Software-Routing Filtering Rule */
2601 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
2602 flt_rule_entry.hdl = get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num];
2603
2604 memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
2605
2606 if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
2607 {
2608 IPACMERR("Failed to install WAN DL filtering table.\n");
2609 res = IPACM_FAILURE;
2610 goto fail;
2611 }
2612 get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num] = 0;
2613
2614 fail:
2615 if(pFilteringTable != NULL)
2616 {
2617 free(pFilteringTable);
2618 }
2619 return res;
2620 }
2621