1 /*
2 Copyright (c) 2014-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_LanToLan.cpp
32
33 @brief
34 This file implements the functionality of offloading LAN to LAN traffic.
35
36 @Author
37 Shihuan Liu
38
39 */
40
41 #include <stdlib.h>
42 #include "IPACM_LanToLan.h"
43 #include "IPACM_Wlan.h"
44
45 #define __stringify(x...) #x
46
47 const char *ipa_l2_hdr_type[] = {
48 __stringify(NONE),
49 __stringify(ETH_II),
50 __stringify(802_3),
51 __stringify(L2_MAX)
52 };
53
54 IPACM_LanToLan* IPACM_LanToLan::p_instance;
55
IPACM_LanToLan_Iface(IPACM_Lan * p_iface)56 IPACM_LanToLan_Iface::IPACM_LanToLan_Iface(IPACM_Lan *p_iface)
57 {
58 int i;
59
60 m_p_iface = p_iface;
61 memset(m_is_ip_addr_assigned, 0, sizeof(m_is_ip_addr_assigned));
62 m_support_inter_iface_offload = true;
63 m_support_intra_iface_offload = false;
64 m_is_l2tp_iface = false;
65 for(i = 0; i < IPA_HDR_L2_MAX; i++)
66 {
67 ref_cnt_peer_l2_hdr_type[i] = 0;
68 hdr_proc_ctx_for_inter_interface[i] = 0;
69 }
70 hdr_proc_ctx_for_intra_interface = 0;
71 hdr_proc_ctx_for_l2tp = 0;
72
73 if(p_iface->ipa_if_cate == WLAN_IF)
74 {
75 IPACMDBG_H("Interface %s is WLAN interface.\n", p_iface->dev_name);
76 m_support_intra_iface_offload = true;
77 if( ((IPACM_Wlan*)p_iface)->is_guest_ap() )
78 {
79 IPACMDBG_H("Interface %s is guest AP.\n", p_iface->dev_name);
80 m_support_inter_iface_offload = false;
81 }
82 }
83 return;
84 }
85
~IPACM_LanToLan_Iface()86 IPACM_LanToLan_Iface::~IPACM_LanToLan_Iface()
87 {
88 }
89
IPACM_LanToLan()90 IPACM_LanToLan::IPACM_LanToLan()
91 {
92 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_IFACE_UP, this);
93 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_IFACE_DOWN, this);
94 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_CLIENT_ADD, this);
95 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_CLIENT_DEL, this);
96 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, this);
97 #ifdef FEATURE_L2TP
98 IPACM_EvtDispatcher::registr(IPA_ADD_VLAN_IFACE, this);
99 IPACM_EvtDispatcher::registr(IPA_DEL_VLAN_IFACE, this);
100 IPACM_EvtDispatcher::registr(IPA_ADD_L2TP_VLAN_MAPPING, this);
101 IPACM_EvtDispatcher::registr(IPA_DEL_L2TP_VLAN_MAPPING, this);
102 IPACM_EvtDispatcher::registr(IPA_HANDLE_VLAN_CLIENT_INFO, this);
103 IPACM_EvtDispatcher::registr(IPA_HANDLE_VLAN_IFACE_INFO, this);
104 #endif
105 m_has_l2tp_iface = false;
106 return;
107 }
108
~IPACM_LanToLan()109 IPACM_LanToLan::~IPACM_LanToLan()
110 {
111 IPACMDBG_DMESG("WARNING: UNEXPECTEDLY KILL LAN2LAN CONTROLLER!\n");
112 return;
113 }
114
get_instance()115 IPACM_LanToLan* IPACM_LanToLan::get_instance()
116 {
117 if(p_instance == NULL)
118 {
119 p_instance = new IPACM_LanToLan();
120 IPACMDBG_H("Created LanToLan instance.\n");
121 }
122 return p_instance;
123 }
124
125 #ifdef FEATURE_L2TP
has_l2tp_iface()126 bool IPACM_LanToLan::has_l2tp_iface()
127 {
128 list<IPACM_LanToLan_Iface>::iterator it;
129 bool has_l2tp_iface = false;
130
131 for(it = m_iface.begin(); it != m_iface.end(); it++)
132 {
133 if(it->is_l2tp_iface() == true)
134 {
135 has_l2tp_iface = true;
136 break;
137 }
138 }
139 return has_l2tp_iface;
140 }
141 #endif
142
event_callback(ipa_cm_event_id event,void * param)143 void IPACM_LanToLan::event_callback(ipa_cm_event_id event, void* param)
144 {
145 ipacm_event_eth_bridge *eth_bridge_data;
146 const char *eventName = IPACM_Iface::ipacmcfg->getEventName(event);
147 #ifdef FEATURE_L2TP
148 ipa_ioc_vlan_iface_info *vlan_iface_data;
149 ipa_ioc_l2tp_vlan_mapping_info *l2tp_vlan_mapping_data;
150 ipacm_event_data_all *vlan_data;
151 #endif
152
153 if (eventName != NULL)
154 IPACMDBG_H("Get %s event.\n", eventName);
155
156 switch(event)
157 {
158 case IPA_ETH_BRIDGE_IFACE_UP:
159 {
160 eth_bridge_data = (ipacm_event_eth_bridge*)param;
161 handle_iface_up(eth_bridge_data);
162 break;
163 }
164
165 case IPA_ETH_BRIDGE_IFACE_DOWN:
166 {
167 eth_bridge_data = (ipacm_event_eth_bridge*)param;
168 handle_iface_down(eth_bridge_data);
169 break;
170 }
171
172 case IPA_ETH_BRIDGE_CLIENT_ADD:
173 {
174 eth_bridge_data = (ipacm_event_eth_bridge*)param;
175 handle_client_add(eth_bridge_data);
176 break;
177 }
178
179 case IPA_ETH_BRIDGE_CLIENT_DEL:
180 {
181 eth_bridge_data = (ipacm_event_eth_bridge*)param;
182 handle_client_del(eth_bridge_data);
183 break;
184 }
185
186 case IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH:
187 {
188 eth_bridge_data = (ipacm_event_eth_bridge*)param;
189 handle_wlan_scc_mcc_switch(eth_bridge_data);
190 break;
191 }
192
193 #ifdef FEATURE_L2TP
194 case IPA_ADD_VLAN_IFACE:
195 {
196 vlan_iface_data = (ipa_ioc_vlan_iface_info*)param;
197 handle_add_vlan_iface(vlan_iface_data);
198 break;
199 }
200
201 case IPA_DEL_VLAN_IFACE:
202 {
203 vlan_iface_data = (ipa_ioc_vlan_iface_info*)param;
204 handle_del_vlan_iface(vlan_iface_data);
205 break;
206 }
207 case IPA_ADD_L2TP_VLAN_MAPPING:
208 {
209 l2tp_vlan_mapping_data = (ipa_ioc_l2tp_vlan_mapping_info*)param;
210 handle_add_l2tp_vlan_mapping(l2tp_vlan_mapping_data);
211 break;
212 }
213 case IPA_DEL_L2TP_VLAN_MAPPING:
214 {
215 l2tp_vlan_mapping_data = (ipa_ioc_l2tp_vlan_mapping_info*)param;
216 handle_del_l2tp_vlan_mapping(l2tp_vlan_mapping_data);
217 break;
218 }
219 case IPA_HANDLE_VLAN_CLIENT_INFO:
220 {
221 vlan_data = (ipacm_event_data_all*)param;
222 handle_vlan_client_info(vlan_data);
223 break;
224 }
225 case IPA_HANDLE_VLAN_IFACE_INFO:
226 {
227 vlan_data = (ipacm_event_data_all*)param;
228 handle_vlan_iface_info(vlan_data);
229 break;
230 }
231 #endif
232 default:
233 break;
234 }
235
236 print_data_structure_info();
237 return;
238 }
239
handle_iface_up(ipacm_event_eth_bridge * data)240 void IPACM_LanToLan::handle_iface_up(ipacm_event_eth_bridge *data)
241 {
242 list<IPACM_LanToLan_Iface>::iterator it;
243 list<l2tp_vlan_mapping_info>::iterator it_mapping;
244 #ifdef FEATURE_L2TP
245 bool has_l2tp_iface = false;
246 #endif
247
248 IPACMDBG_H("Interface name: %s IP type: %d\n", data->p_iface->dev_name, data->iptype);
249 for(it = m_iface.begin(); it != m_iface.end(); it++)
250 {
251 if(it->get_iface_pointer() == data->p_iface)
252 {
253 IPACMDBG_H("Found the interface.\n");
254 if(it->get_m_is_ip_addr_assigned(data->iptype) == false)
255 {
256 IPACMDBG_H("IP type %d was not active before, activating it now.\n", data->iptype);
257 it->set_m_is_ip_addr_assigned(data->iptype, true);
258
259 /* install inter-interface rules */
260 if(it->get_m_support_inter_iface_offload())
261 it->add_all_inter_interface_client_flt_rule(data->iptype);
262
263 /* install intra-BSS rules */
264 if(it->get_m_support_intra_iface_offload())
265 it->add_all_intra_interface_client_flt_rule(data->iptype);
266 }
267 break;
268 }
269 }
270
271 if(it == m_iface.end()) //If the interface has not been created before
272 {
273 if(m_iface.size() == MAX_NUM_IFACE)
274 {
275 IPACMERR("The number of interfaces has reached maximum %d.\n", MAX_NUM_IFACE);
276 return;
277 }
278
279 if(!data->p_iface->tx_prop || !data->p_iface->rx_prop)
280 {
281 IPACMERR("The interface %s does not have tx_prop or rx_prop.\n", data->p_iface->dev_name);
282 return;
283 }
284
285 if(data->p_iface->tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_NONE || data->p_iface->tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_MAX)
286 {
287 IPACMERR("Invalid l2 header type %s!\n", ipa_l2_hdr_type[data->p_iface->tx_prop->tx[0].hdr_l2_type]);
288 return;
289 }
290
291 IPACMDBG_H("Does not find the interface, insert a new one.\n");
292 IPACM_LanToLan_Iface new_iface(data->p_iface);
293 new_iface.set_m_is_ip_addr_assigned(data->iptype, true);
294
295 m_iface.push_front(new_iface);
296 IPACMDBG_H("Now the total number of interfaces is %zu.\n", m_iface.size());
297
298 IPACM_LanToLan_Iface &front_iface = m_iface.front();
299 #ifdef FEATURE_L2TP
300 for(it_mapping = m_l2tp_vlan_mapping.begin(); it_mapping != m_l2tp_vlan_mapping.end(); it_mapping++)
301 {
302 if(front_iface.set_l2tp_iface(it_mapping->vlan_iface_name) == true)
303 {
304 has_l2tp_iface = true;
305 }
306 }
307
308 if(m_has_l2tp_iface == false && has_l2tp_iface == true)
309 {
310 IPACMDBG_H("There is l2tp iface, add rt rules for l2tp iface.\n");
311 m_has_l2tp_iface = true;
312 for(it = ++m_iface.begin(); it != m_iface.end(); it++)
313 {
314 if(it->is_l2tp_iface() == false)
315 {
316 it->handle_l2tp_enable();
317 }
318 }
319 }
320 #endif
321 /* install inter-interface rules */
322 if(front_iface.get_m_support_inter_iface_offload())
323 {
324 for(it = ++m_iface.begin(); it != m_iface.end(); it++)
325 {
326 /* add peer info only when both interfaces support inter-interface communication */
327 if(it->get_m_support_inter_iface_offload())
328 {
329 /* populate hdr_proc_ctx and routing table handle */
330 handle_new_iface_up(&front_iface, &(*it));
331
332 /* add client specific routing rule on existing interface */
333 it->add_client_rt_rule_for_new_iface();
334 }
335 }
336
337 /* add client specific filtering rule on new interface */
338 front_iface.add_all_inter_interface_client_flt_rule(data->iptype);
339 }
340
341 /* populate the intra-interface information */
342 if(front_iface.get_m_support_intra_iface_offload())
343 {
344 front_iface.handle_intra_interface_info();
345 }
346
347 /* handle cached client add event */
348 handle_cached_client_add_event(front_iface.get_iface_pointer());
349 }
350 return;
351 }
352
handle_iface_down(ipacm_event_eth_bridge * data)353 void IPACM_LanToLan::handle_iface_down(ipacm_event_eth_bridge *data)
354 {
355 list<IPACM_LanToLan_Iface>::iterator it_target_iface;
356 #ifdef FEATURE_L2TP
357 bool has_l2tp_iface = false;
358 #endif
359
360 IPACMDBG_H("Interface name: %s\n", data->p_iface->dev_name);
361
362 for(it_target_iface = m_iface.begin(); it_target_iface != m_iface.end(); it_target_iface++)
363 {
364 if(it_target_iface->get_iface_pointer() == data->p_iface)
365 {
366 IPACMDBG_H("Found the interface.\n");
367 break;
368 }
369 }
370
371 if(it_target_iface == m_iface.end())
372 {
373 IPACMDBG_H("The interface has not been found.\n");
374 /* clear cached client add event for the unfound interface*/
375 clear_cached_client_add_event(data->p_iface);
376 return;
377 }
378
379 it_target_iface->handle_down_event();
380 m_iface.erase(it_target_iface);
381 #ifdef FEATURE_L2TP
382 for(it_target_iface = m_iface.begin(); it_target_iface != m_iface.end(); it_target_iface++)
383 {
384 if(it_target_iface->is_l2tp_iface() == true)
385 {
386 has_l2tp_iface = true;
387 break;
388 }
389 }
390 if(m_has_l2tp_iface == true && has_l2tp_iface == false)
391 {
392 IPACMDBG_H("There is no l2tp iface now, delete rt rules for l2tp iface.\n");
393 m_has_l2tp_iface = false;
394 for(it_target_iface = m_iface.begin(); it_target_iface != m_iface.end(); it_target_iface++)
395 {
396 if(it_target_iface->is_l2tp_iface() == false)
397 {
398 it_target_iface->handle_l2tp_disable();
399 }
400 }
401 }
402 #endif
403 return;
404 }
405
handle_new_iface_up(IPACM_LanToLan_Iface * new_iface,IPACM_LanToLan_Iface * exist_iface)406 void IPACM_LanToLan::handle_new_iface_up(IPACM_LanToLan_Iface *new_iface, IPACM_LanToLan_Iface *exist_iface)
407 {
408 char rt_tbl_name_for_flt[IPA_IP_MAX][IPA_RESOURCE_NAME_MAX];
409 char rt_tbl_name_for_rt[IPA_IP_MAX][IPA_RESOURCE_NAME_MAX];
410
411 IPACMDBG_H("Populate peer info between: new_iface %s, existing iface %s\n", new_iface->get_iface_pointer()->dev_name,
412 exist_iface->get_iface_pointer()->dev_name);
413
414 /* populate the routing table information */
415 snprintf(rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX, "eth_v4_%s_to_%s",
416 ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type],
417 ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]);
418 IPACMDBG_H("IPv4 routing table for flt name: %s\n", rt_tbl_name_for_flt[IPA_IP_v4]);
419
420 snprintf(rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX, "eth_v6_%s_to_%s",
421 ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type],
422 ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]);
423 IPACMDBG_H("IPv6 routing table for flt name: %s\n", rt_tbl_name_for_flt[IPA_IP_v6]);
424
425 snprintf(rt_tbl_name_for_rt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX, "eth_v4_%s_to_%s",
426 ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type],
427 ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]);
428 IPACMDBG_H("IPv4 routing table for rt name: %s\n", rt_tbl_name_for_rt[IPA_IP_v4]);
429
430 snprintf(rt_tbl_name_for_rt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX, "eth_v6_%s_to_%s",
431 ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type],
432 ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]);
433 IPACMDBG_H("IPv6 routing table for rt name: %s\n", rt_tbl_name_for_rt[IPA_IP_v6]);
434
435 /* add new peer info in both new iface and existing iface */
436 exist_iface->handle_new_iface_up(rt_tbl_name_for_flt, rt_tbl_name_for_rt, new_iface);
437
438 new_iface->handle_new_iface_up(rt_tbl_name_for_rt, rt_tbl_name_for_flt, exist_iface);
439
440 return;
441 }
442
handle_client_add(ipacm_event_eth_bridge * data)443 void IPACM_LanToLan::handle_client_add(ipacm_event_eth_bridge *data)
444 {
445 list<IPACM_LanToLan_Iface>::iterator it_iface;
446 list<l2tp_vlan_mapping_info>::iterator it_mapping;
447 l2tp_vlan_mapping_info *mapping_info = NULL;
448 bool is_l2tp_client = false;
449
450 IPACMDBG_H("Incoming client MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", data->mac_addr[0], data->mac_addr[1],
451 data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->p_iface->dev_name);
452 #ifdef FEATURE_L2TP
453 for(it_mapping = m_l2tp_vlan_mapping.begin(); it_mapping != m_l2tp_vlan_mapping.end(); it_mapping++)
454 {
455 if(strncmp(it_mapping->l2tp_iface_name, data->iface_name,
456 sizeof(it_mapping->l2tp_iface_name)) == 0)
457 {
458 IPACMDBG_H("Found l2tp iface %s with l2tp client MAC 0x%02x%02x%02x%02x%02x%02x\n",
459 it_mapping->l2tp_iface_name, it_mapping->l2tp_client_mac[0], it_mapping->l2tp_client_mac[1],
460 it_mapping->l2tp_client_mac[2], it_mapping->l2tp_client_mac[3], it_mapping->l2tp_client_mac[4],
461 it_mapping->l2tp_client_mac[5]);
462 memcpy(it_mapping->l2tp_client_mac, data->mac_addr, sizeof(it_mapping->l2tp_client_mac));
463 mapping_info = &(*it_mapping);
464 is_l2tp_client = true;
465 break;
466 }
467 }
468 #endif
469 for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++)
470 {
471 if(it_iface->get_iface_pointer() == data->p_iface) //find the interface
472 {
473 IPACMDBG_H("Found the interface.\n");
474 it_iface->handle_client_add(data->mac_addr, is_l2tp_client, mapping_info, data->ep);
475 break;
476 }
477 }
478
479 /* if the iface was not found, cache the client add event */
480 if(it_iface == m_iface.end())
481 {
482 IPACMDBG_H("The interface is not found.\n");
483 if(m_cached_client_add_event.size() < MAX_NUM_CACHED_CLIENT_ADD_EVENT)
484 {
485 IPACMDBG_H("Cached the client information.\n");
486 m_cached_client_add_event.push_front(*data);
487 }
488 else
489 {
490 IPACMDBG_H("Cached client add event has reached maximum number.\n");
491 }
492 }
493 return;
494 }
495
handle_client_del(ipacm_event_eth_bridge * data)496 void IPACM_LanToLan::handle_client_del(ipacm_event_eth_bridge *data)
497 {
498 list<IPACM_LanToLan_Iface>::iterator it_iface;
499
500 IPACMDBG_H("Incoming client MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", data->mac_addr[0], data->mac_addr[1],
501 data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->p_iface->dev_name);
502
503 for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++)
504 {
505 if(it_iface->get_iface_pointer() == data->p_iface) //found the interface
506 {
507 IPACMDBG_H("Found the interface.\n");
508 it_iface->handle_client_del(data->mac_addr);
509 break;
510 }
511 }
512
513 if(it_iface == m_iface.end())
514 {
515 IPACMDBG_H("The interface is not found.\n");
516 }
517
518 return;
519 }
520
handle_wlan_scc_mcc_switch(ipacm_event_eth_bridge * data)521 void IPACM_LanToLan::handle_wlan_scc_mcc_switch(ipacm_event_eth_bridge *data)
522 {
523 list<IPACM_LanToLan_Iface>::iterator it_iface;
524
525 IPACMDBG_H("Incoming interface: %s\n", data->p_iface->dev_name);
526 for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++)
527 {
528 if(it_iface->get_iface_pointer() == data->p_iface)
529 {
530 it_iface->handle_wlan_scc_mcc_switch();
531 break;
532 }
533 }
534 return;
535 }
536
537 #ifdef FEATURE_L2TP
handle_add_vlan_iface(ipa_ioc_vlan_iface_info * data)538 void IPACM_LanToLan::handle_add_vlan_iface(ipa_ioc_vlan_iface_info *data)
539 {
540 list<vlan_iface_info>::iterator it_vlan;
541 list<l2tp_vlan_mapping_info>::iterator it_mapping;
542 vlan_iface_info new_vlan_info;
543
544 IPACMDBG_H("Vlan iface: %s vlan id: %d\n", data->name, data->vlan_id);
545 for(it_vlan = m_vlan_iface.begin(); it_vlan != m_vlan_iface.end(); it_vlan++)
546 {
547 if(strncmp(it_vlan->vlan_iface_name, data->name, sizeof(it_vlan->vlan_iface_name)) == 0)
548 {
549 IPACMERR("The vlan iface was added before with id %d\n", it_vlan->vlan_id);
550 return;
551 }
552 }
553
554 for(it_mapping = m_l2tp_vlan_mapping.begin(); it_mapping != m_l2tp_vlan_mapping.end(); it_mapping++)
555 {
556 if(strncmp(data->name, it_mapping->vlan_iface_name, sizeof(data->name)) == 0)
557 {
558 IPACMDBG_H("Found a mapping: l2tp iface %s.\n", it_mapping->l2tp_iface_name);
559 it_mapping->vlan_id = data->vlan_id;
560 }
561 }
562
563 memset(&new_vlan_info, 0 , sizeof(new_vlan_info));
564 strlcpy(new_vlan_info.vlan_iface_name, data->name, sizeof(new_vlan_info.vlan_iface_name));
565 new_vlan_info.vlan_id = data->vlan_id;
566 m_vlan_iface.push_front(new_vlan_info);
567 return;
568 }
569
handle_del_vlan_iface(ipa_ioc_vlan_iface_info * data)570 void IPACM_LanToLan::handle_del_vlan_iface(ipa_ioc_vlan_iface_info *data)
571 {
572 list<vlan_iface_info>::iterator it_vlan;
573 list<l2tp_vlan_mapping_info>::iterator it_mapping;
574
575 IPACMDBG_H("Vlan iface: %s vlan id: %d\n", data->name, data->vlan_id);
576 for(it_vlan = m_vlan_iface.begin(); it_vlan != m_vlan_iface.end(); it_vlan++)
577 {
578 if(strncmp(it_vlan->vlan_iface_name, data->name, sizeof(it_vlan->vlan_iface_name)) == 0)
579 {
580 IPACMDBG_H("Found the vlan interface\n");
581 m_vlan_iface.erase(it_vlan);
582 break;
583 }
584 }
585
586 it_mapping = m_l2tp_vlan_mapping.begin();
587 while(it_mapping != m_l2tp_vlan_mapping.end())
588 {
589 if(strncmp(data->name, it_mapping->vlan_iface_name, sizeof(data->name)) == 0)
590 {
591 IPACMDBG_H("Delete mapping with l2tp iface %s\n", it_mapping->l2tp_iface_name);
592 it_mapping = m_l2tp_vlan_mapping.erase(it_mapping);
593 }
594 else
595 {
596 it_mapping++;
597 }
598 }
599 return;
600 }
handle_add_l2tp_vlan_mapping(ipa_ioc_l2tp_vlan_mapping_info * data)601 void IPACM_LanToLan::handle_add_l2tp_vlan_mapping(ipa_ioc_l2tp_vlan_mapping_info *data)
602 {
603 list<l2tp_vlan_mapping_info>::iterator it_mapping;
604 list<vlan_iface_info>::iterator it_vlan;
605 list<IPACM_LanToLan_Iface>::iterator it_iface;
606 IPACM_LanToLan_Iface *l2tp_iface;
607 l2tp_vlan_mapping_info new_mapping;
608 bool has_l2tp_iface = false;
609
610 IPACMDBG_H("L2tp iface: %s session id: %d vlan iface: %s \n",
611 data->l2tp_iface_name, data->l2tp_session_id, data->vlan_iface_name);
612 for(it_mapping = m_l2tp_vlan_mapping.begin(); it_mapping != m_l2tp_vlan_mapping.end(); it_mapping++)
613 {
614 if(strncmp(data->l2tp_iface_name, it_mapping->l2tp_iface_name,
615 sizeof(data->l2tp_iface_name)) == 0)
616 {
617 IPACMERR("L2tp mapping was added before mapped to vlan %s.\n", it_mapping->vlan_iface_name);
618 return;
619 }
620 }
621 memset(&new_mapping, 0, sizeof(new_mapping));
622 strlcpy(new_mapping.l2tp_iface_name, data->l2tp_iface_name,
623 sizeof(new_mapping.l2tp_iface_name));
624 strlcpy(new_mapping.vlan_iface_name, data->vlan_iface_name,
625 sizeof(new_mapping.vlan_iface_name));
626 new_mapping.l2tp_session_id = data->l2tp_session_id;
627
628 for(it_vlan = m_vlan_iface.begin(); it_vlan != m_vlan_iface.end(); it_vlan++)
629 {
630 if(strncmp(it_vlan->vlan_iface_name, data->vlan_iface_name, sizeof(it_vlan->vlan_iface_name)) == 0)
631 {
632 IPACMDBG_H("Found vlan iface with id %d\n", it_vlan->vlan_id);
633 new_mapping.vlan_id = it_vlan->vlan_id;
634 memcpy(new_mapping.vlan_iface_ipv6_addr, it_vlan->vlan_iface_ipv6_addr,
635 sizeof(new_mapping.vlan_iface_ipv6_addr));
636 memcpy(new_mapping.vlan_client_mac, it_vlan->vlan_client_mac,
637 sizeof(new_mapping.vlan_client_mac));
638 memcpy(new_mapping.vlan_client_ipv6_addr, it_vlan->vlan_client_ipv6_addr,
639 sizeof(new_mapping.vlan_client_ipv6_addr));
640 break;
641 }
642 }
643 m_l2tp_vlan_mapping.push_front(new_mapping);
644
645 for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++)
646 {
647 if(it_iface->set_l2tp_iface(data->vlan_iface_name) == true)
648 {
649 has_l2tp_iface = true;
650 l2tp_iface = &(*it_iface);
651 break;
652 }
653 }
654
655 if(m_has_l2tp_iface == false && has_l2tp_iface == true)
656 {
657 IPACMDBG_H("There is l2tp iface, add rt rules for l2tp iface.\n");
658 m_has_l2tp_iface = true;
659 for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++)
660 {
661 if(it_iface->is_l2tp_iface() == false)
662 {
663 it_iface->handle_l2tp_enable();
664 }
665 }
666 l2tp_iface->switch_to_l2tp_iface();
667 }
668 return;
669 }
670
handle_del_l2tp_vlan_mapping(ipa_ioc_l2tp_vlan_mapping_info * data)671 void IPACM_LanToLan::handle_del_l2tp_vlan_mapping(ipa_ioc_l2tp_vlan_mapping_info *data)
672 {
673 list<l2tp_vlan_mapping_info>::iterator it;
674 list<IPACM_LanToLan_Iface>::iterator it_iface;
675
676 IPACMDBG_H("L2tp iface: %s session id: %d vlan iface: %s \n",
677 data->l2tp_iface_name, data->l2tp_session_id, data->vlan_iface_name);
678 for(it = m_l2tp_vlan_mapping.begin(); it != m_l2tp_vlan_mapping.end(); it++)
679 {
680 if(strncmp(data->l2tp_iface_name, it->l2tp_iface_name,
681 sizeof(data->l2tp_iface_name)) == 0)
682 {
683 IPACMDBG_H("Found l2tp iface mapped to vlan %s.\n", it->vlan_iface_name);
684 if(strncmp(data->vlan_iface_name, it->vlan_iface_name,
685 sizeof(data->vlan_iface_name)) == 0)
686 {
687 m_l2tp_vlan_mapping.erase(it);
688 }
689 else
690 {
691 IPACMERR("Incoming mapping is incorrect.\n");
692 }
693 break;
694 }
695 }
696 return;
697 }
handle_vlan_client_info(ipacm_event_data_all * data)698 void IPACM_LanToLan::handle_vlan_client_info(ipacm_event_data_all *data)
699 {
700 list<l2tp_vlan_mapping_info>::iterator it_mapping;
701 list<vlan_iface_info>::iterator it_vlan;
702
703 IPACMDBG_H("Incoming vlan client iface: %s IPv6 address: 0x%08x%08x%08x%08x\n", data->iface_name,
704 data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
705 IPACMDBG_H("MAC address: 0x%02x%02x%02x%02x%02x%02x\n", data->mac_addr[0], data->mac_addr[1],
706 data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5]);
707
708 for(it_vlan = m_vlan_iface.begin(); it_vlan != m_vlan_iface.end(); it_vlan++)
709 {
710 if(strncmp(it_vlan->vlan_iface_name, data->iface_name, sizeof(it_vlan->vlan_iface_name)) == 0)
711 {
712 IPACMDBG_H("Found vlan iface in vlan list: %s\n", it_vlan->vlan_iface_name);
713 if(it_vlan->vlan_client_ipv6_addr[0] > 0 || it_vlan->vlan_client_ipv6_addr[1] > 0 ||
714 it_vlan->vlan_client_ipv6_addr[2] > 0 || it_vlan->vlan_client_ipv6_addr[3] > 0)
715 {
716 IPACMDBG_H("Vlan client info has been populated before, return.\n");
717 return;
718 }
719 memcpy(it_vlan->vlan_client_mac, data->mac_addr, sizeof(it_vlan->vlan_client_mac));
720 memcpy(it_vlan->vlan_client_ipv6_addr, data->ipv6_addr, sizeof(it_vlan->vlan_client_ipv6_addr));
721 }
722 }
723
724 for(it_mapping = m_l2tp_vlan_mapping.begin(); it_mapping != m_l2tp_vlan_mapping.end(); it_mapping++)
725 {
726 if(strncmp(it_mapping->vlan_iface_name, data->iface_name, sizeof(it_mapping->vlan_iface_name)) == 0)
727 {
728 IPACMDBG_H("Found vlan iface in l2tp mapping list: %s, l2tp iface: %s\n", it_mapping->vlan_iface_name,
729 it_mapping->l2tp_iface_name);
730 memcpy(it_mapping->vlan_client_mac, data->mac_addr, sizeof(it_mapping->vlan_client_mac));
731 memcpy(it_mapping->vlan_client_ipv6_addr, data->ipv6_addr, sizeof(it_mapping->vlan_client_ipv6_addr));
732 }
733 }
734 return;
735 }
736
handle_vlan_iface_info(ipacm_event_data_all * data)737 void IPACM_LanToLan::handle_vlan_iface_info(ipacm_event_data_all *data)
738 {
739 list<vlan_iface_info>::iterator it_vlan;
740 list<l2tp_vlan_mapping_info>::iterator it_mapping;
741
742 IPACMDBG_H("Incoming vlan iface: %s IPv6 address: 0x%08x%08x%08x%08x\n", data->iface_name,
743 data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
744
745 for(it_vlan = m_vlan_iface.begin(); it_vlan != m_vlan_iface.end(); it_vlan++)
746 {
747 if(strncmp(it_vlan->vlan_iface_name, data->iface_name,
748 sizeof(it_vlan->vlan_iface_name)) == 0)
749 {
750 IPACMDBG_H("Found vlan iface: %s\n", it_vlan->vlan_iface_name);
751 memcpy(it_vlan->vlan_iface_ipv6_addr, data->ipv6_addr,
752 sizeof(it_vlan->vlan_iface_ipv6_addr));
753
754 for(it_mapping = m_l2tp_vlan_mapping.begin(); it_mapping != m_l2tp_vlan_mapping.end(); it_mapping++)
755 {
756 if(strncmp(it_mapping->vlan_iface_name, it_vlan->vlan_iface_name,
757 sizeof(it_mapping->vlan_iface_name)) == 0)
758 {
759 IPACMDBG_H("Found the l2tp-vlan mapping: l2tp %s\n", it_mapping->l2tp_iface_name);
760 memcpy(it_mapping->vlan_iface_ipv6_addr, data->ipv6_addr,
761 sizeof(it_mapping->vlan_iface_ipv6_addr));
762 }
763 }
764 break;
765 }
766 }
767
768 if(it_vlan == m_vlan_iface.end())
769 {
770 IPACMDBG_H("Failed to find the vlan iface: %s\n", data->iface_name);
771 }
772 return;
773 }
774 #endif
775
handle_cached_client_add_event(IPACM_Lan * p_iface)776 void IPACM_LanToLan::handle_cached_client_add_event(IPACM_Lan *p_iface)
777 {
778 list<ipacm_event_eth_bridge>::iterator it;
779
780 it = m_cached_client_add_event.begin();
781 while(it != m_cached_client_add_event.end())
782 {
783 if(it->p_iface == p_iface)
784 {
785 IPACMDBG_H("Found client with MAC: 0x%02x%02x%02x%02x%02x%02x\n", it->mac_addr[0], it->mac_addr[1],
786 it->mac_addr[2], it->mac_addr[3], it->mac_addr[4], it->mac_addr[5]);
787 handle_client_add(&(*it));
788 it = m_cached_client_add_event.erase(it);
789 }
790 else
791 {
792 it++;
793 }
794 }
795 return;
796 }
797
clear_cached_client_add_event(IPACM_Lan * p_iface)798 void IPACM_LanToLan::clear_cached_client_add_event(IPACM_Lan *p_iface)
799 {
800 list<ipacm_event_eth_bridge>::iterator it;
801
802 it = m_cached_client_add_event.begin();
803 while(it != m_cached_client_add_event.end())
804 {
805 if(it->p_iface == p_iface)
806 {
807 IPACMDBG_H("Found client with MAC: 0x%02x%02x%02x%02x%02x%02x\n", it->mac_addr[0], it->mac_addr[1],
808 it->mac_addr[2], it->mac_addr[3], it->mac_addr[4], it->mac_addr[5]);
809 it = m_cached_client_add_event.erase(it);
810 }
811 else
812 {
813 it++;
814 }
815 }
816 return;
817 }
818
print_data_structure_info()819 void IPACM_LanToLan::print_data_structure_info()
820 {
821 list<IPACM_LanToLan_Iface>::iterator it;
822 list<ipacm_event_eth_bridge>::iterator it_event;
823 list<vlan_iface_info>::iterator it_vlan;
824 list<l2tp_vlan_mapping_info>::iterator it_mapping;
825 int i;
826
827 IPACMDBG_H("Is there l2tp interface? %d\n", m_has_l2tp_iface);
828
829 #ifdef FEATURE_L2TP
830 IPACMDBG_H("There are %zu vlan interfaces.\n", m_vlan_iface.size());
831 for(it_vlan = m_vlan_iface.begin(); it_vlan != m_vlan_iface.end(); it_vlan++)
832 {
833 IPACMDBG_H("Vlan iface: %s, id: %d, ipv6 addr: 0x%08x%08x%08x%08x\n", it_vlan->vlan_iface_name,
834 it_vlan->vlan_id, it_vlan->vlan_iface_ipv6_addr[0], it_vlan->vlan_iface_ipv6_addr[1],
835 it_vlan->vlan_iface_ipv6_addr[2], it_vlan->vlan_iface_ipv6_addr[3]);
836 IPACMDBG_H("Vlan client mac: 0x%02x%02x%02x%02x%02x%02x, ipv6 addr: 0x%08x%08x%08x%08x\n",
837 it_vlan->vlan_client_mac[0], it_vlan->vlan_client_mac[1], it_vlan->vlan_client_mac[2],
838 it_vlan->vlan_client_mac[3], it_vlan->vlan_client_mac[4], it_vlan->vlan_client_mac[5],
839 it_vlan->vlan_client_ipv6_addr[0], it_vlan->vlan_client_ipv6_addr[1], it_vlan->vlan_client_ipv6_addr[2],
840 it_vlan->vlan_client_ipv6_addr[3]);
841 }
842
843 IPACMDBG_H("There are %zu vlan-l2tp mapping.\n", m_l2tp_vlan_mapping.size());
844 for(it_mapping = m_l2tp_vlan_mapping.begin(); it_mapping != m_l2tp_vlan_mapping.end(); it_mapping++)
845 {
846 IPACMDBG_H("L2tp iface: %s, session id: %d\n", it_mapping->l2tp_iface_name, it_mapping->l2tp_session_id);
847 IPACMDBG_H("Vlan iface: %s, id: %d, ipv6 addr: 0x%08x%08x%08x%08x\n", it_mapping->vlan_iface_name,
848 it_mapping->vlan_id, it_mapping->vlan_iface_ipv6_addr[0], it_mapping->vlan_iface_ipv6_addr[1],
849 it_mapping->vlan_iface_ipv6_addr[2], it_mapping->vlan_iface_ipv6_addr[3]);
850 IPACMDBG_H("Vlan client mac: 0x%02x%02x%02x%02x%02x%02x, ipv6 addr: 0x%08x%08x%08x%08x\n",
851 it_mapping->vlan_client_mac[0], it_mapping->vlan_client_mac[1], it_mapping->vlan_client_mac[2],
852 it_mapping->vlan_client_mac[3], it_mapping->vlan_client_mac[4], it_mapping->vlan_client_mac[5],
853 it_mapping->vlan_client_ipv6_addr[0], it_mapping->vlan_client_ipv6_addr[1], it_mapping->vlan_client_ipv6_addr[2],
854 it_mapping->vlan_client_ipv6_addr[3]);
855 IPACMDBG_H("L2tp client mac: 0x%02x%02x%02x%02x%02x%02x\n", it_mapping->l2tp_client_mac[0], it_mapping->l2tp_client_mac[1],
856 it_mapping->l2tp_client_mac[2], it_mapping->l2tp_client_mac[3], it_mapping->l2tp_client_mac[4], it_mapping->l2tp_client_mac[5]);
857 }
858 #endif
859 IPACMDBG_H("There are %zu interfaces in total.\n", m_iface.size());
860 for(it = m_iface.begin(); it != m_iface.end(); it++)
861 {
862 it->print_data_structure_info();
863 }
864
865 IPACMDBG_H("There are %zu cached client add events in total.\n", m_cached_client_add_event.size());
866
867 i = 1;
868 for(it_event = m_cached_client_add_event.begin(); it_event != m_cached_client_add_event.end(); it_event++)
869 {
870 IPACMDBG_H("Client %d MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", i, it_event->mac_addr[0], it_event->mac_addr[1], it_event->mac_addr[2],
871 it_event->mac_addr[3], it_event->mac_addr[4], it_event->mac_addr[5], it_event->p_iface->dev_name);
872 i++;
873 }
874
875 return;
876 }
877
add_client_rt_rule_for_new_iface()878 void IPACM_LanToLan_Iface::add_client_rt_rule_for_new_iface()
879 {
880 list<client_info>::iterator it;
881 ipa_hdr_l2_type peer_l2_type;
882 peer_iface_info &peer = m_peer_iface_info.front();
883
884 peer_l2_type = peer.peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type;
885 if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 1)
886 {
887 for(it = m_client_info.begin(); it != m_client_info.end(); it++)
888 {
889 #ifdef FEATURE_L2TP
890 if(it->is_l2tp_client == false)
891 {
892 add_client_rt_rule(&peer, &(*it));
893 }
894 /* add l2tp rt rules */
895 add_l2tp_client_rt_rule(&peer, &(*it));
896 #else
897 add_client_rt_rule(&peer, &(*it));
898 #endif
899 }
900 }
901
902 return;
903 }
904
add_client_rt_rule(peer_iface_info * peer_info,client_info * client)905 void IPACM_LanToLan_Iface::add_client_rt_rule(peer_iface_info *peer_info, client_info *client)
906 {
907 int i, num_rt_rule;
908 uint32_t rt_rule_hdl[MAX_NUM_PROP];
909 ipa_hdr_l2_type peer_l2_hdr_type;
910
911 peer_l2_hdr_type = peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type;
912
913 /* if the peer info is not for intra interface communication */
914 if(peer_info->peer != this)
915 {
916 IPACMDBG_H("This is for inter interface communication.\n");
917
918 m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v4], hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type],
919 peer_l2_hdr_type, IPA_IP_v4, rt_rule_hdl, &num_rt_rule, client->ep);
920
921 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4] = num_rt_rule;
922 IPACMDBG_H("Number of IPv4 routing rule is %d.\n", num_rt_rule);
923 for(i=0; i<num_rt_rule; i++)
924 {
925 IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]);
926 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i] = rt_rule_hdl[i];
927 }
928
929 m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v6], hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type],
930 peer_l2_hdr_type, IPA_IP_v6, rt_rule_hdl, &num_rt_rule, client->ep);
931
932 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6] = num_rt_rule;
933 IPACMDBG_H("Number of IPv6 routing rule is %d.\n", num_rt_rule);
934 for(i=0; i<num_rt_rule; i++)
935 {
936 IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]);
937 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i] = rt_rule_hdl[i];
938 }
939 }
940 else
941 {
942 IPACMDBG_H("This is for intra interface communication.\n");
943 m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v4], hdr_proc_ctx_for_intra_interface,
944 peer_l2_hdr_type, IPA_IP_v4, rt_rule_hdl, &num_rt_rule, client->ep);
945
946 client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4] = num_rt_rule;
947 IPACMDBG_H("Number of IPv4 routing rule is %d.\n", num_rt_rule);
948 for(i=0; i<num_rt_rule; i++)
949 {
950 IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]);
951 client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i] = rt_rule_hdl[i];
952 }
953
954 m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v6], hdr_proc_ctx_for_intra_interface,
955 peer_l2_hdr_type, IPA_IP_v6, rt_rule_hdl, &num_rt_rule, client->ep);
956
957 client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6] = num_rt_rule;
958 IPACMDBG_H("Number of IPv6 routing rule is %d.\n", num_rt_rule);
959 for(i=0; i<num_rt_rule; i++)
960 {
961 IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]);
962 client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i] = rt_rule_hdl[i];
963 }
964 }
965
966 return;
967 }
968
969 #ifdef FEATURE_L2TP
add_l2tp_client_rt_rule(peer_iface_info * peer,client_info * client)970 void IPACM_LanToLan_Iface::add_l2tp_client_rt_rule(peer_iface_info *peer, client_info *client)
971 {
972 ipa_hdr_l2_type peer_l2_hdr_type;
973 l2tp_vlan_mapping_info *mapping_info;
974
975 peer_l2_hdr_type = peer->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type;
976 mapping_info = client->mapping_info;
977 if(client->is_l2tp_client)
978 {
979 m_p_iface->add_l2tp_rt_rule(IPA_IP_v4, client->mac_addr, peer_l2_hdr_type, mapping_info->l2tp_session_id,
980 mapping_info->vlan_id, mapping_info->vlan_client_mac, mapping_info->vlan_iface_ipv6_addr,
981 mapping_info->vlan_client_ipv6_addr, &client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_hdr_hdl,
982 &client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_hdr_proc_ctx_hdl[IPA_IP_v4], &client->l2tp_rt_rule_hdl[peer_l2_hdr_type].second_pass_hdr_hdl,
983 &client->l2tp_rt_rule_hdl[peer_l2_hdr_type].num_rt_hdl[IPA_IP_v4], client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_rt_rule_hdl[IPA_IP_v4],
984 client->l2tp_rt_rule_hdl[peer_l2_hdr_type].second_pass_rt_rule_hdl);
985
986 m_p_iface->add_l2tp_rt_rule(IPA_IP_v6, client->mac_addr, peer_l2_hdr_type, mapping_info->l2tp_session_id,
987 mapping_info->vlan_id, mapping_info->vlan_client_mac, mapping_info->vlan_iface_ipv6_addr,
988 mapping_info->vlan_client_ipv6_addr, &client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_hdr_hdl,
989 &client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_hdr_proc_ctx_hdl[IPA_IP_v6], &client->l2tp_rt_rule_hdl[peer_l2_hdr_type].second_pass_hdr_hdl,
990 &client->l2tp_rt_rule_hdl[peer_l2_hdr_type].num_rt_hdl[IPA_IP_v6], client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_rt_rule_hdl[IPA_IP_v6],
991 client->l2tp_rt_rule_hdl[peer_l2_hdr_type].second_pass_rt_rule_hdl);
992 }
993 else
994 {
995 if(IPACM_LanToLan::get_instance()->has_l2tp_iface() == true)
996 {
997 m_p_iface->add_l2tp_rt_rule(IPA_IP_v6, client->mac_addr, &hdr_proc_ctx_for_l2tp, &client->l2tp_rt_rule_hdl[peer_l2_hdr_type].num_rt_hdl[IPA_IP_v6],
998 client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_rt_rule_hdl[IPA_IP_v6]);
999 }
1000 }
1001 return;
1002 }
1003 #endif
1004
add_all_inter_interface_client_flt_rule(ipa_ip_type iptype)1005 void IPACM_LanToLan_Iface::add_all_inter_interface_client_flt_rule(ipa_ip_type iptype)
1006 {
1007 list<peer_iface_info>::iterator it_iface;
1008 list<client_info>::iterator it_client;
1009
1010 for(it_iface = m_peer_iface_info.begin(); it_iface != m_peer_iface_info.end(); it_iface++)
1011 {
1012 IPACMDBG_H("Add flt rules for clients of interface %s.\n", it_iface->peer->get_iface_pointer()->dev_name);
1013 for(it_client = it_iface->peer->m_client_info.begin(); it_client != it_iface->peer->m_client_info.end(); it_client++)
1014 {
1015 add_client_flt_rule(&(*it_iface), &(*it_client), iptype);
1016 }
1017 }
1018 return;
1019 }
1020
add_all_intra_interface_client_flt_rule(ipa_ip_type iptype)1021 void IPACM_LanToLan_Iface::add_all_intra_interface_client_flt_rule(ipa_ip_type iptype)
1022 {
1023 list<client_info>::iterator it_client;
1024
1025 IPACMDBG_H("Add flt rules for own clients.\n");
1026 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++)
1027 {
1028 add_client_flt_rule(&m_intra_interface_info, &(*it_client), iptype);
1029 }
1030
1031 return;
1032 }
1033
add_one_client_flt_rule(IPACM_LanToLan_Iface * peer_iface,client_info * client)1034 void IPACM_LanToLan_Iface::add_one_client_flt_rule(IPACM_LanToLan_Iface *peer_iface, client_info *client)
1035 {
1036 list<peer_iface_info>::iterator it;
1037
1038 for(it = m_peer_iface_info.begin(); it != m_peer_iface_info.end(); it++)
1039 {
1040 if(it->peer == peer_iface)
1041 {
1042 IPACMDBG_H("Found the peer iface info.\n");
1043 if(m_is_ip_addr_assigned[IPA_IP_v4])
1044 {
1045 add_client_flt_rule(&(*it), client, IPA_IP_v4);
1046 }
1047 if(m_is_ip_addr_assigned[IPA_IP_v6])
1048 {
1049 add_client_flt_rule(&(*it), client, IPA_IP_v6);
1050 }
1051
1052 break;
1053 }
1054 }
1055 return;
1056 }
1057
add_client_flt_rule(peer_iface_info * peer,client_info * client,ipa_ip_type iptype)1058 void IPACM_LanToLan_Iface::add_client_flt_rule(peer_iface_info *peer, client_info *client, ipa_ip_type iptype)
1059 {
1060 list<flt_rule_info>::iterator it_flt;
1061 uint32_t flt_rule_hdl;
1062 uint32_t l2tp_first_pass_flt_rule_hdl = 0, l2tp_second_pass_flt_rule_hdl = 0;
1063 flt_rule_info new_flt_info;
1064 ipa_ioc_get_rt_tbl rt_tbl;
1065
1066 if(m_is_l2tp_iface && iptype == IPA_IP_v4)
1067 {
1068 IPACMDBG_H("No need to install IPv4 flt rule on l2tp interface.\n");
1069 return;
1070 }
1071
1072 for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++)
1073 {
1074 if(it_flt->p_client == client) //the client is already in the flt info list
1075 {
1076 IPACMDBG_H("The client is found in flt info list.\n");
1077 break;
1078 }
1079 }
1080
1081 if(it_flt != peer->flt_rule.end())
1082 {
1083 l2tp_first_pass_flt_rule_hdl = it_flt->l2tp_first_pass_flt_rule_hdl[iptype];
1084 l2tp_second_pass_flt_rule_hdl = it_flt->l2tp_second_pass_flt_rule_hdl;
1085 }
1086
1087 #ifdef FEATURE_L2TP
1088 if(m_is_l2tp_iface)
1089 {
1090 m_p_iface->add_l2tp_flt_rule(client->mac_addr, &l2tp_first_pass_flt_rule_hdl);
1091 }
1092 else
1093 #endif
1094 {
1095 #ifdef FEATURE_L2TP
1096 if(client->is_l2tp_client)
1097 {
1098 m_p_iface->add_l2tp_flt_rule(iptype, client->mac_addr, client->mapping_info->vlan_client_ipv6_addr,
1099 &l2tp_first_pass_flt_rule_hdl, &l2tp_second_pass_flt_rule_hdl);
1100 }
1101 else
1102 #endif
1103 {
1104 rt_tbl.ip = iptype;
1105 memcpy(rt_tbl.name, peer->rt_tbl_name_for_flt[iptype], sizeof(rt_tbl.name));
1106 IPACMDBG_H("This flt rule points to rt tbl %s.\n", rt_tbl.name);
1107
1108 if(IPACM_Iface::m_routing.GetRoutingTable(&rt_tbl) == false)
1109 {
1110 IPACMERR("Failed to get routing table.\n");
1111 return;
1112 }
1113
1114 m_p_iface->eth_bridge_add_flt_rule(client->mac_addr, rt_tbl.hdl,
1115 iptype, &flt_rule_hdl);
1116 IPACMDBG_H("Installed flt rule for IP type %d: handle %d\n", iptype, flt_rule_hdl);
1117 }
1118 }
1119
1120 if(it_flt != peer->flt_rule.end())
1121 {
1122 it_flt->flt_rule_hdl[iptype] = flt_rule_hdl;
1123 it_flt->l2tp_first_pass_flt_rule_hdl[iptype] = l2tp_first_pass_flt_rule_hdl;
1124 it_flt->l2tp_second_pass_flt_rule_hdl = l2tp_second_pass_flt_rule_hdl;
1125 }
1126 else
1127 {
1128 IPACMDBG_H("The client is not found in flt info list, insert a new one.\n");
1129 memset(&new_flt_info, 0, sizeof(new_flt_info));
1130 new_flt_info.p_client = client;
1131 new_flt_info.flt_rule_hdl[iptype] = flt_rule_hdl;
1132 new_flt_info.l2tp_first_pass_flt_rule_hdl[iptype] = l2tp_first_pass_flt_rule_hdl;
1133 new_flt_info.l2tp_second_pass_flt_rule_hdl = l2tp_second_pass_flt_rule_hdl;
1134
1135 peer->flt_rule.push_front(new_flt_info);
1136 }
1137
1138 return;
1139 }
1140
del_one_client_flt_rule(IPACM_LanToLan_Iface * peer_iface,client_info * client)1141 void IPACM_LanToLan_Iface::del_one_client_flt_rule(IPACM_LanToLan_Iface *peer_iface, client_info *client)
1142 {
1143 list<peer_iface_info>::iterator it;
1144
1145 for(it = m_peer_iface_info.begin(); it != m_peer_iface_info.end(); it++)
1146 {
1147 if(it->peer == peer_iface)
1148 {
1149 IPACMDBG_H("Found the peer iface info.\n");
1150 del_client_flt_rule(&(*it), client);
1151 break;
1152 }
1153 }
1154 return;
1155 }
1156
del_client_flt_rule(peer_iface_info * peer,client_info * client)1157 void IPACM_LanToLan_Iface::del_client_flt_rule(peer_iface_info *peer, client_info *client)
1158 {
1159 list<flt_rule_info>::iterator it_flt;
1160
1161 for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++)
1162 {
1163 if(it_flt->p_client == client) //found the client in flt info list
1164 {
1165 IPACMDBG_H("Found the client in flt info list.\n");
1166 if(m_is_ip_addr_assigned[IPA_IP_v4])
1167 {
1168 if(m_is_l2tp_iface)
1169 {
1170 IPACMDBG_H("No IPv4 client flt rule on l2tp iface.\n");
1171 }
1172 else
1173 {
1174 #ifdef FEATURE_L2TP
1175 if(client->is_l2tp_client)
1176 {
1177 m_p_iface->del_l2tp_flt_rule(IPA_IP_v4, it_flt->l2tp_first_pass_flt_rule_hdl[IPA_IP_v4],
1178 it_flt->l2tp_second_pass_flt_rule_hdl);
1179 it_flt->l2tp_second_pass_flt_rule_hdl = 0;
1180 IPACMDBG_H("Deleted IPv4 first pass flt rule %d and second pass flt rule %d.\n",
1181 it_flt->l2tp_first_pass_flt_rule_hdl[IPA_IP_v4], it_flt->l2tp_second_pass_flt_rule_hdl);
1182 }
1183 else
1184 #endif
1185 {
1186 m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v4], IPA_IP_v4);
1187 IPACMDBG_H("Deleted IPv4 flt rule %d.\n", it_flt->flt_rule_hdl[IPA_IP_v4]);
1188 }
1189 }
1190 }
1191 if(m_is_ip_addr_assigned[IPA_IP_v6])
1192 {
1193 #ifdef FEATURE_L2TP
1194 if(m_is_l2tp_iface)
1195 {
1196 m_p_iface->del_l2tp_flt_rule(it_flt->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6]);
1197 IPACMDBG_H("Deleted IPv6 flt rule %d.\n", it_flt->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6]);
1198 }
1199 else
1200 #endif
1201 {
1202 #ifdef FEATURE_L2TP
1203 if(client->is_l2tp_client)
1204 {
1205 m_p_iface->del_l2tp_flt_rule(IPA_IP_v6, it_flt->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6],
1206 it_flt->l2tp_second_pass_flt_rule_hdl);
1207 IPACMDBG_H("Deleted IPv6 first pass flt rule %d and second pass flt rule %d.\n",
1208 it_flt->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6], it_flt->l2tp_second_pass_flt_rule_hdl);
1209 }
1210 else
1211 #endif
1212 {
1213 m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v6], IPA_IP_v6);
1214 IPACMDBG_H("Deleted IPv6 flt rule %d.\n", it_flt->flt_rule_hdl[IPA_IP_v6]);
1215 }
1216 }
1217 }
1218 peer->flt_rule.erase(it_flt);
1219 break;
1220 }
1221 }
1222 return;
1223 }
1224
del_client_rt_rule(peer_iface_info * peer,client_info * client)1225 void IPACM_LanToLan_Iface::del_client_rt_rule(peer_iface_info *peer, client_info *client)
1226 {
1227 ipa_hdr_l2_type peer_l2_hdr_type;
1228 int i, num_rules;
1229
1230 peer_l2_hdr_type = peer->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type;
1231 /* if the peer info is not for intra interface communication */
1232 if(peer->peer != this)
1233 {
1234 IPACMDBG_H("Delete routing rules for inter interface communication.\n");
1235
1236 if(client->is_l2tp_client == false)
1237 {
1238 num_rules = client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4];
1239 for(i = 0; i < num_rules; i++)
1240 {
1241 m_p_iface->eth_bridge_del_rt_rule(client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i], IPA_IP_v4);
1242 IPACMDBG_H("IPv4 rt rule %d is deleted.\n", client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i]);
1243 }
1244 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4] = 0;
1245
1246 num_rules = client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6];
1247 for(i = 0; i < num_rules; i++)
1248 {
1249 m_p_iface->eth_bridge_del_rt_rule(client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i], IPA_IP_v6);
1250 IPACMDBG_H("IPv6 rt rule %d is deleted.\n", client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i]);
1251 }
1252 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6] = 0;
1253 #ifdef FEATURE_L2TP
1254 if(IPACM_LanToLan::get_instance()->has_l2tp_iface() == true)
1255 {
1256 m_p_iface->del_l2tp_rt_rule(IPA_IP_v6, client->l2tp_rt_rule_hdl[peer_l2_hdr_type].num_rt_hdl[IPA_IP_v6],
1257 client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_rt_rule_hdl[IPA_IP_v6]);
1258 }
1259 #endif
1260 }
1261 else
1262 {
1263 #ifdef FEATURE_L2TP
1264 m_p_iface->del_l2tp_rt_rule(IPA_IP_v4, client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_hdr_hdl,
1265 client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_hdr_proc_ctx_hdl[IPA_IP_v4], client->l2tp_rt_rule_hdl[peer_l2_hdr_type].second_pass_hdr_hdl,
1266 client->l2tp_rt_rule_hdl[peer_l2_hdr_type].num_rt_hdl[IPA_IP_v4], client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_rt_rule_hdl[IPA_IP_v4],
1267 client->l2tp_rt_rule_hdl[peer_l2_hdr_type].second_pass_rt_rule_hdl);
1268
1269 m_p_iface->del_l2tp_rt_rule(IPA_IP_v6, 0, client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_hdr_proc_ctx_hdl[IPA_IP_v6],
1270 0, client->l2tp_rt_rule_hdl[peer_l2_hdr_type].num_rt_hdl[IPA_IP_v6], client->l2tp_rt_rule_hdl[peer_l2_hdr_type].first_pass_rt_rule_hdl[IPA_IP_v6],
1271 NULL);
1272 #endif
1273 }
1274 }
1275 else
1276 {
1277 IPACMDBG_H("Delete routing rules for intra interface communication.\n");
1278 num_rules = client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4];
1279 for(i = 0; i < num_rules; i++)
1280 {
1281 m_p_iface->eth_bridge_del_rt_rule(client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i], IPA_IP_v4);
1282 IPACMDBG_H("IPv4 rt rule %d is deleted.\n", client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i]);
1283 }
1284 client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4] = 0;
1285
1286 num_rules = client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6];
1287 for(i = 0; i < num_rules; i++)
1288 {
1289 m_p_iface->eth_bridge_del_rt_rule(client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i], IPA_IP_v6);
1290 IPACMDBG_H("IPv6 rt rule %d is deleted.\n", client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i]);
1291 }
1292 client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6] = 0;
1293 }
1294
1295 return;
1296 }
1297
handle_down_event()1298 void IPACM_LanToLan_Iface::handle_down_event()
1299 {
1300 list<IPACM_LanToLan_Iface>::iterator it_other_iface;
1301 list<peer_iface_info>::iterator it_own_peer_info, it_other_iface_peer_info;
1302 IPACM_LanToLan_Iface *other_iface;
1303
1304 /* clear inter-interface rules */
1305 if(m_support_inter_iface_offload)
1306 {
1307 for(it_own_peer_info = m_peer_iface_info.begin(); it_own_peer_info != m_peer_iface_info.end();
1308 it_own_peer_info++)
1309 {
1310 /* decrement reference count of peer l2 header type on both interfaces*/
1311 if (it_own_peer_info->peer &&
1312 it_own_peer_info->peer->get_iface_pointer() &&
1313 it_own_peer_info->peer->get_iface_pointer()->tx_prop)
1314 decrement_ref_cnt_peer_l2_hdr_type(it_own_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type);
1315 if (it_own_peer_info->peer && m_p_iface && m_p_iface->tx_prop)
1316 it_own_peer_info->peer->decrement_ref_cnt_peer_l2_hdr_type(m_p_iface->tx_prop->tx[0].hdr_l2_type);
1317
1318 /* first clear all flt rule on target interface */
1319 IPACMDBG_H("Clear all flt rule on target interface.\n");
1320 clear_all_flt_rule_for_one_peer_iface(&(*it_own_peer_info));
1321
1322 other_iface = it_own_peer_info->peer;
1323 /* then clear all flt/rt rule and hdr proc ctx for target interface on peer interfaces */
1324 IPACMDBG_H("Clear all flt/rt rules and hdr proc ctx for target interface on peer interfaces %s.\n",
1325 it_own_peer_info->peer->get_iface_pointer()->dev_name);
1326 for(it_other_iface_peer_info = other_iface->m_peer_iface_info.begin();
1327 it_other_iface_peer_info != other_iface->m_peer_iface_info.end();
1328 it_other_iface_peer_info++)
1329 {
1330 if(it_other_iface_peer_info->peer == this) //found myself in other iface's peer info list
1331 {
1332 IPACMDBG_H("Found the right peer info on other iface.\n");
1333 other_iface->clear_all_flt_rule_for_one_peer_iface(&(*it_other_iface_peer_info));
1334 other_iface->clear_all_rt_rule_for_one_peer_iface(&(*it_other_iface_peer_info));
1335 /* remove the peer info from the list */
1336 other_iface->m_peer_iface_info.erase(it_other_iface_peer_info);
1337 if (m_p_iface && m_p_iface->tx_prop)
1338 other_iface->del_hdr_proc_ctx(m_p_iface->tx_prop->tx[0].hdr_l2_type);
1339 break;
1340 }
1341 }
1342
1343 /* then clear rt rule and hdr proc ctx and release rt table on target interface */
1344 IPACMDBG_H("Clear rt rules and hdr proc ctx and release rt table on target interface.\n");
1345 clear_all_rt_rule_for_one_peer_iface(&(*it_own_peer_info));
1346 if (it_own_peer_info->peer &&
1347 it_own_peer_info->peer->get_iface_pointer() &&
1348 it_own_peer_info->peer->get_iface_pointer()->tx_prop)
1349 del_hdr_proc_ctx(it_own_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type);
1350 }
1351 m_peer_iface_info.clear();
1352 }
1353
1354 /* clear intra interface rules */
1355 if(m_support_intra_iface_offload)
1356 {
1357 IPACMDBG_H("Clear intra interface flt/rt rules and hdr proc ctx, release rt tables.\n");
1358 clear_all_flt_rule_for_one_peer_iface(&m_intra_interface_info);
1359 clear_all_rt_rule_for_one_peer_iface(&m_intra_interface_info);
1360 m_p_iface->eth_bridge_del_hdr_proc_ctx(hdr_proc_ctx_for_intra_interface);
1361 IPACMDBG_H("Hdr proc ctx with hdl %d is deleted.\n", hdr_proc_ctx_for_intra_interface);
1362 }
1363
1364 /* then clear the client info list */
1365 m_client_info.clear();
1366
1367 return;
1368 }
1369
clear_all_flt_rule_for_one_peer_iface(peer_iface_info * peer)1370 void IPACM_LanToLan_Iface::clear_all_flt_rule_for_one_peer_iface(peer_iface_info *peer)
1371 {
1372 list<flt_rule_info>::iterator it;
1373
1374 for(it = peer->flt_rule.begin(); it != peer->flt_rule.end(); it++)
1375 {
1376 if(m_is_ip_addr_assigned[IPA_IP_v4])
1377 {
1378 if(m_is_l2tp_iface)
1379 {
1380 IPACMDBG_H("No IPv4 client flt rule on l2tp iface.\n");
1381 }
1382 else
1383 {
1384 #ifdef FEATURE_L2TP
1385 if(it->p_client->is_l2tp_client)
1386 {
1387 m_p_iface->del_l2tp_flt_rule(IPA_IP_v4, it->l2tp_first_pass_flt_rule_hdl[IPA_IP_v4],
1388 it->l2tp_second_pass_flt_rule_hdl);
1389 it->l2tp_second_pass_flt_rule_hdl = 0;
1390 IPACMDBG_H("Deleted IPv4 first pass flt rule %d and second pass flt rule %d.\n",
1391 it->l2tp_first_pass_flt_rule_hdl[IPA_IP_v4], it->l2tp_second_pass_flt_rule_hdl);
1392 }
1393 else
1394 #endif
1395 {
1396 m_p_iface->eth_bridge_del_flt_rule(it->flt_rule_hdl[IPA_IP_v4], IPA_IP_v4);
1397 IPACMDBG_H("Deleted IPv4 flt rule %d.\n", it->flt_rule_hdl[IPA_IP_v4]);
1398 }
1399 }
1400 }
1401 if(m_is_ip_addr_assigned[IPA_IP_v6])
1402 {
1403 #ifdef FEATURE_L2TP
1404 if(m_is_l2tp_iface)
1405 {
1406 m_p_iface->del_l2tp_flt_rule(it->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6]);
1407 IPACMDBG_H("Deleted IPv6 flt rule %d.\n", it->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6]);
1408 }
1409 else
1410 #endif
1411 {
1412 #ifdef FEATURE_L2TP
1413 if(it->p_client->is_l2tp_client)
1414 {
1415 m_p_iface->del_l2tp_flt_rule(IPA_IP_v6, it->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6],
1416 it->l2tp_second_pass_flt_rule_hdl);
1417 IPACMDBG_H("Deleted IPv6 first pass flt rule %d and second pass flt rule %d.\n",
1418 it->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6], it->l2tp_second_pass_flt_rule_hdl);
1419 }
1420 else
1421 #endif
1422 {
1423 m_p_iface->eth_bridge_del_flt_rule(it->flt_rule_hdl[IPA_IP_v6], IPA_IP_v6);
1424 IPACMDBG_H("Deleted IPv6 flt rule %d.\n", it->flt_rule_hdl[IPA_IP_v6]);
1425 }
1426 }
1427 }
1428 }
1429 peer->flt_rule.clear();
1430 return;
1431 }
1432
clear_all_rt_rule_for_one_peer_iface(peer_iface_info * peer)1433 void IPACM_LanToLan_Iface::clear_all_rt_rule_for_one_peer_iface(peer_iface_info *peer)
1434 {
1435 list<client_info>::iterator it;
1436 ipa_hdr_l2_type peer_l2_type;
1437
1438 peer_l2_type = peer->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type;
1439 if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 0)
1440 {
1441 for(it = m_client_info.begin(); it != m_client_info.end(); it++)
1442 {
1443 del_client_rt_rule(peer, &(*it));
1444 }
1445 #ifdef FEATURE_L2TP
1446 if(IPACM_LanToLan::get_instance()->has_l2tp_iface() == true)
1447 {
1448 m_p_iface->eth_bridge_del_hdr_proc_ctx(hdr_proc_ctx_for_l2tp);
1449 hdr_proc_ctx_for_l2tp = 0;
1450 }
1451 #endif
1452 }
1453
1454 return;
1455 }
1456
handle_wlan_scc_mcc_switch()1457 void IPACM_LanToLan_Iface::handle_wlan_scc_mcc_switch()
1458 {
1459 list<peer_iface_info>::iterator it_peer_info;
1460 list<client_info>::iterator it_client;
1461 ipa_hdr_l2_type peer_l2_hdr_type;
1462 bool flag[IPA_HDR_L2_MAX];
1463 int i;
1464
1465 /* modify inter-interface routing rules */
1466 if(m_support_inter_iface_offload)
1467 {
1468 IPACMDBG_H("Modify rt rules for peer interfaces.\n");
1469 memset(flag, 0, sizeof(flag));
1470 for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); it_peer_info++)
1471 {
1472 peer_l2_hdr_type = it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type;
1473 if(flag[peer_l2_hdr_type] == false)
1474 {
1475 flag[peer_l2_hdr_type] = true;
1476 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++)
1477 {
1478 m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type],
1479 peer_l2_hdr_type, IPA_IP_v4, it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4],
1480 it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4]);
1481 IPACMDBG_H("The following IPv4 routing rules are modified:\n");
1482 for(i = 0; i < it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4]; i++)
1483 {
1484 IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i]);
1485 }
1486
1487 m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type],
1488 peer_l2_hdr_type, IPA_IP_v6, it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6],
1489 it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6]);
1490 IPACMDBG_H("The following IPv6 routing rules are modified:\n");
1491 for(i = 0; i < it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6]; i++)
1492 {
1493 IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i]);
1494 }
1495 }
1496 }
1497 }
1498 }
1499
1500 /* modify routing rules for intra-interface communication */
1501 IPACMDBG_H("Modify rt rules for intra-interface communication.\n");
1502 if(m_support_intra_iface_offload)
1503 {
1504 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++)
1505 {
1506 m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_intra_interface,
1507 m_p_iface->tx_prop->tx[0].hdr_l2_type, IPA_IP_v4, it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4],
1508 it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]);
1509 IPACMDBG_H("The following IPv4 routing rules are modified:\n");
1510 for(i = 0; i < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]; i++)
1511 {
1512 IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i]);
1513 }
1514
1515 m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_intra_interface,
1516 m_p_iface->tx_prop->tx[0].hdr_l2_type, IPA_IP_v6, it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6],
1517 it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]);
1518 IPACMDBG_H("The following IPv6 routing rules are modified:\n");
1519 for(i = 0; i < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]; i++)
1520 {
1521 IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i]);
1522 }
1523 }
1524 }
1525
1526 return;
1527 }
1528
handle_intra_interface_info()1529 void IPACM_LanToLan_Iface::handle_intra_interface_info()
1530 {
1531 uint32_t hdr_proc_ctx_hdl;
1532
1533 if(m_p_iface->tx_prop == NULL)
1534 {
1535 IPACMERR("No tx prop.\n");
1536 return;
1537 }
1538
1539 m_intra_interface_info.peer = this;
1540
1541 snprintf(m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX,
1542 "eth_v4_intra_interface");
1543 IPACMDBG_H("IPv4 routing table for flt name: %s\n", m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4]);
1544 snprintf(m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX,
1545 "eth_v6_intra_interface");
1546 IPACMDBG_H("IPv6 routing table for flt name: %s\n", m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6]);
1547
1548 memcpy(m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v4], m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4],
1549 IPA_RESOURCE_NAME_MAX);
1550 IPACMDBG_H("IPv4 routing table for rt name: %s\n", m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v4]);
1551 memcpy(m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v6], m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6],
1552 IPA_RESOURCE_NAME_MAX);
1553 IPACMDBG_H("IPv6 routing table for rt name: %s\n", m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v6]);
1554
1555 m_p_iface->eth_bridge_add_hdr_proc_ctx(m_p_iface->tx_prop->tx[0].hdr_l2_type,
1556 &hdr_proc_ctx_hdl);
1557 hdr_proc_ctx_for_intra_interface = hdr_proc_ctx_hdl;
1558 IPACMDBG_H("Hdr proc ctx for intra-interface communication: hdl %d\n", hdr_proc_ctx_hdl);
1559
1560 return;
1561 }
1562
handle_new_iface_up(char rt_tbl_name_for_flt[][IPA_RESOURCE_NAME_MAX],char rt_tbl_name_for_rt[][IPA_RESOURCE_NAME_MAX],IPACM_LanToLan_Iface * peer_iface)1563 void IPACM_LanToLan_Iface::handle_new_iface_up(char rt_tbl_name_for_flt[][IPA_RESOURCE_NAME_MAX], char rt_tbl_name_for_rt[][IPA_RESOURCE_NAME_MAX],
1564 IPACM_LanToLan_Iface *peer_iface)
1565 {
1566 peer_iface_info new_peer;
1567 ipa_hdr_l2_type peer_l2_hdr_type;
1568
1569 new_peer.peer = peer_iface;
1570 memcpy(new_peer.rt_tbl_name_for_rt[IPA_IP_v4], rt_tbl_name_for_rt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX);
1571 memcpy(new_peer.rt_tbl_name_for_rt[IPA_IP_v6], rt_tbl_name_for_rt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX);
1572 memcpy(new_peer.rt_tbl_name_for_flt[IPA_IP_v4], rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX);
1573 memcpy(new_peer.rt_tbl_name_for_flt[IPA_IP_v6], rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX);
1574
1575 peer_l2_hdr_type = peer_iface->m_p_iface->tx_prop->tx[0].hdr_l2_type;
1576 increment_ref_cnt_peer_l2_hdr_type(peer_l2_hdr_type);
1577 add_hdr_proc_ctx(peer_l2_hdr_type);
1578
1579 /* push the new peer_iface_info into the list */
1580 m_peer_iface_info.push_front(new_peer);
1581
1582 return;
1583 }
1584
handle_client_add(uint8_t * mac,bool is_l2tp_client,l2tp_vlan_mapping_info * mapping_info,int ep)1585 void IPACM_LanToLan_Iface::handle_client_add(uint8_t *mac,
1586 bool is_l2tp_client,
1587 l2tp_vlan_mapping_info *mapping_info,
1588 int ep)
1589 {
1590 list<client_info>::iterator it_client;
1591 list<peer_iface_info>::iterator it_peer_info;
1592 client_info new_client;
1593 bool flag[IPA_HDR_L2_MAX];
1594
1595 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++)
1596 {
1597 if((memcmp(it_client->mac_addr, mac, sizeof(it_client->mac_addr)) == 0))
1598 {
1599 IPACMDBG_H("This client has been added before.\n");
1600 return;
1601 }
1602 }
1603
1604 if(m_client_info.size() == MAX_NUM_CLIENT)
1605 {
1606 IPACMDBG_H("The number of clients has reached maximum %d.\n", MAX_NUM_CLIENT);
1607 return;
1608 }
1609
1610 IPACMDBG_H("is_l2tp_client: %d, mapping_info: %p\n", is_l2tp_client, mapping_info);
1611 memset(&new_client, 0, sizeof(new_client));
1612 memcpy(new_client.mac_addr, mac, sizeof(new_client.mac_addr));
1613 new_client.is_l2tp_client = is_l2tp_client;
1614 new_client.mapping_info = mapping_info;
1615 new_client.ep = ep;
1616 m_client_info.push_front(new_client);
1617
1618 client_info &front_client = m_client_info.front();
1619
1620 /* install inter-interface rules */
1621 if(m_support_inter_iface_offload)
1622 {
1623 memset(flag, 0, sizeof(flag));
1624 for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); it_peer_info++)
1625 {
1626 /* make sure add routing rule only once for each peer l2 header type */
1627 if(flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] == false)
1628 {
1629 /* add client routing rule for each peer interface */
1630 if(front_client.is_l2tp_client == false)
1631 {
1632 add_client_rt_rule(&(*it_peer_info), &front_client);
1633 }
1634 #ifdef FEATURE_L2TP
1635 /* add l2tp rt rules */
1636 add_l2tp_client_rt_rule(&(*it_peer_info), &front_client);
1637 #endif
1638 flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] = true;
1639 }
1640
1641 /* add client filtering rule on peer interfaces */
1642 it_peer_info->peer->add_one_client_flt_rule(this, &front_client);
1643 }
1644 }
1645
1646 /* install intra-interface rules */
1647 if(m_support_intra_iface_offload)
1648 {
1649 /* add routing rule first */
1650 add_client_rt_rule(&m_intra_interface_info, &front_client);
1651
1652 /* add filtering rule */
1653 if(m_is_ip_addr_assigned[IPA_IP_v4])
1654 {
1655 add_client_flt_rule(&m_intra_interface_info, &front_client, IPA_IP_v4);
1656 }
1657 if(m_is_ip_addr_assigned[IPA_IP_v6])
1658 {
1659 add_client_flt_rule(&m_intra_interface_info, &front_client, IPA_IP_v6);
1660 }
1661 }
1662
1663 return;
1664 }
1665
handle_client_del(uint8_t * mac)1666 void IPACM_LanToLan_Iface::handle_client_del(uint8_t *mac)
1667 {
1668 list<client_info>::iterator it_client;
1669 list<peer_iface_info>::iterator it_peer_info;
1670 bool flag[IPA_HDR_L2_MAX];
1671
1672 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++)
1673 {
1674 if(memcmp(it_client->mac_addr, mac, sizeof(it_client->mac_addr)) == 0) //found the client
1675 {
1676 IPACMDBG_H("Found the client.\n");
1677 break;
1678 }
1679 }
1680
1681 if(it_client != m_client_info.end()) //if we found the client
1682 {
1683 /* uninstall inter-interface rules */
1684 if(m_support_inter_iface_offload)
1685 {
1686 memset(flag, 0, sizeof(flag));
1687 for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end();
1688 it_peer_info++)
1689 {
1690 IPACMDBG_H("Delete client filtering rule on peer interface.\n");
1691 it_peer_info->peer->del_one_client_flt_rule(this, &(*it_client));
1692
1693 /* make sure to delete routing rule only once for each peer l2 header type */
1694 if(flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] == false)
1695 {
1696 IPACMDBG_H("Delete client routing rule for peer interface.\n");
1697 del_client_rt_rule(&(*it_peer_info), &(*it_client));
1698 #ifdef FEATURE_L2TP
1699 if(it_client->is_l2tp_client == false && IPACM_LanToLan::get_instance()->has_l2tp_iface() == true
1700 && m_client_info.size() == 1)
1701 {
1702 m_p_iface->eth_bridge_del_hdr_proc_ctx(hdr_proc_ctx_for_l2tp);
1703 hdr_proc_ctx_for_l2tp = 0;
1704 }
1705 #endif
1706 flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] = true;
1707 }
1708 }
1709 }
1710
1711 /* uninstall intra-interface rules */
1712 if(m_support_intra_iface_offload)
1713 {
1714 /* delete filtering rule first */
1715 IPACMDBG_H("Delete client filtering rule for intra-interface communication.\n");
1716 del_client_flt_rule(&m_intra_interface_info, &(*it_client));
1717
1718 /* delete routing rule */
1719 IPACMDBG_H("Delete client routing rule for intra-interface communication.\n");
1720 del_client_rt_rule(&m_intra_interface_info, &(*it_client));
1721 }
1722
1723 /* erase the client from client info list */
1724 m_client_info.erase(it_client);
1725 }
1726 else
1727 {
1728 IPACMDBG_H("The client is not found.\n");
1729 }
1730
1731 return;
1732 }
1733
add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type)1734 void IPACM_LanToLan_Iface::add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type)
1735 {
1736 uint32_t hdr_proc_ctx_hdl;
1737
1738 if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 1)
1739 {
1740 m_p_iface->eth_bridge_add_hdr_proc_ctx(peer_l2_type, &hdr_proc_ctx_hdl);
1741 hdr_proc_ctx_for_inter_interface[peer_l2_type] = hdr_proc_ctx_hdl;
1742 IPACMDBG_H("Installed inter-interface hdr proc ctx on iface %s: handle %d\n", m_p_iface->dev_name, hdr_proc_ctx_hdl);
1743 }
1744 return;
1745 }
1746
del_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type)1747 void IPACM_LanToLan_Iface::del_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type)
1748 {
1749 if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 0)
1750 {
1751 m_p_iface->eth_bridge_del_hdr_proc_ctx(hdr_proc_ctx_for_inter_interface[peer_l2_type]);
1752 IPACMDBG_H("Hdr proc ctx with hdl %d is deleted.\n", hdr_proc_ctx_for_inter_interface[peer_l2_type]);
1753 }
1754 return;
1755 }
1756
print_data_structure_info()1757 void IPACM_LanToLan_Iface::print_data_structure_info()
1758 {
1759 list<peer_iface_info>::iterator it_peer;
1760 list<client_info>::iterator it_client;
1761 int i, j, k;
1762
1763 IPACMDBG_H("\n");
1764 IPACMDBG_H("Interface %s:\n", m_p_iface->dev_name);
1765 IPACMDBG_H("Is IPv4 addr assigned? %d\n", m_is_ip_addr_assigned[IPA_IP_v4]);
1766 IPACMDBG_H("Is IPv6 addr assigned? %d\n", m_is_ip_addr_assigned[IPA_IP_v6]);
1767 IPACMDBG_H("Support inter interface offload? %d\n", m_support_inter_iface_offload);
1768 IPACMDBG_H("Support intra interface offload? %d\n", m_support_intra_iface_offload);
1769 IPACMDBG_H("Is l2tp interface? %d\n", m_is_l2tp_iface);
1770
1771 if(m_support_inter_iface_offload)
1772 {
1773 for(i = 0; i < IPA_HDR_L2_MAX; i++)
1774 {
1775 IPACMDBG_H("Ref_cnt of peer l2 type %s is %d.\n", ipa_l2_hdr_type[i], ref_cnt_peer_l2_hdr_type[i]);
1776 if(ref_cnt_peer_l2_hdr_type[i] > 0)
1777 {
1778 IPACMDBG_H("Hdr proc ctx for peer l2 type %s: %d\n", ipa_l2_hdr_type[i], hdr_proc_ctx_for_inter_interface[i]);
1779 }
1780 }
1781 }
1782
1783 if(m_support_intra_iface_offload)
1784 {
1785 IPACMDBG_H("Hdr proc ctx for intra-interface: %d\n", hdr_proc_ctx_for_intra_interface);
1786 }
1787
1788 IPACMDBG_H("Hdr proc ctx for l2tp: %d\n", hdr_proc_ctx_for_l2tp);
1789
1790 i = 1;
1791 IPACMDBG_H("There are %zu clients in total.\n", m_client_info.size());
1792 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++)
1793 {
1794 IPACMDBG_H("Client %d MAC: 0x%02x%02x%02x%02x%02x%02x Pointer: 0x%p\n", i, it_client->mac_addr[0], it_client->mac_addr[1],
1795 it_client->mac_addr[2], it_client->mac_addr[3], it_client->mac_addr[4], it_client->mac_addr[5], &(*it_client));
1796 IPACMDBG_H("Is l2tp client? %d\n", it_client->is_l2tp_client);
1797 if(it_client->is_l2tp_client && it_client->mapping_info)
1798 {
1799 IPACMDBG_H("Vlan iface associated with this client: %s\n", it_client->mapping_info->vlan_iface_name);
1800 }
1801
1802 if(m_support_inter_iface_offload)
1803 {
1804 for(j = 0; j < IPA_HDR_L2_MAX; j++)
1805 {
1806 if(ref_cnt_peer_l2_hdr_type[j] > 0)
1807 {
1808 IPACMDBG_H("Printing routing rule info for inter-interface communication for peer l2 type %s.\n",
1809 ipa_l2_hdr_type[j]);
1810 IPACMDBG_H("Number of IPv4 routing rules is %d, handles:\n", it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v4]);
1811 for(k = 0; k < it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v4]; k++)
1812 {
1813 IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[j].rule_hdl[IPA_IP_v4][k]);
1814 }
1815
1816 IPACMDBG_H("Number of IPv6 routing rules is %d, handles:\n", it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v6]);
1817 for(k = 0; k < it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v6]; k++)
1818 {
1819 IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[j].rule_hdl[IPA_IP_v6][k]);
1820 }
1821
1822 #ifdef FEATURE_L2TP
1823 if(it_client->is_l2tp_client)
1824 {
1825 IPACMDBG_H("Printing l2tp hdr info for l2tp client.\n");
1826 IPACMDBG_H("First pass hdr hdl: %d, IPv4 hdr proc ctx hdl: IPv6 hdr proc ctx hdl: %d\n",
1827 it_client->l2tp_rt_rule_hdl[j].first_pass_hdr_hdl, it_client->l2tp_rt_rule_hdl[j].first_pass_hdr_proc_ctx_hdl[IPA_IP_v4],
1828 it_client->l2tp_rt_rule_hdl[j].first_pass_hdr_proc_ctx_hdl[IPA_IP_v6]);
1829 IPACMDBG_H("Second pass hdr hdl: %d\n", it_client->l2tp_rt_rule_hdl[j].second_pass_hdr_hdl);
1830
1831 IPACMDBG_H("Printing l2tp routing rule info for l2tp client.\n");
1832 IPACMDBG_H("Number of IPv4 routing rules is %d, first pass handles:\n", it_client->l2tp_rt_rule_hdl[j].num_rt_hdl[IPA_IP_v4]);
1833 for(k = 0; k < it_client->l2tp_rt_rule_hdl[j].num_rt_hdl[IPA_IP_v4]; k++)
1834 {
1835 IPACMDBG_H("%d\n", it_client->l2tp_rt_rule_hdl[j].first_pass_rt_rule_hdl[IPA_IP_v4][k]);
1836 }
1837 IPACMDBG_H("Number of IPv6 routing rules is %d, first pass handles:\n", it_client->l2tp_rt_rule_hdl[j].num_rt_hdl[IPA_IP_v6]);
1838 for(k = 0; k < it_client->l2tp_rt_rule_hdl[j].num_rt_hdl[IPA_IP_v6]; k++)
1839 {
1840 IPACMDBG_H("%d\n", it_client->l2tp_rt_rule_hdl[j].first_pass_rt_rule_hdl[IPA_IP_v6][k]);
1841 }
1842 IPACMDBG_H("Second pass handles:\n");
1843 for(k = 0; k < it_client->l2tp_rt_rule_hdl[j].num_rt_hdl[IPA_IP_v6]; k++)
1844 {
1845 IPACMDBG_H("%d\n", it_client->l2tp_rt_rule_hdl[j].second_pass_rt_rule_hdl[k]);
1846 }
1847 }
1848 else
1849 {
1850 if(IPACM_LanToLan::get_instance()->has_l2tp_iface())
1851 {
1852 IPACMDBG_H("Printing l2tp hdr info for non l2tp client.\n");
1853 IPACMDBG_H("Hdr hdl: %d, IPv4 hdr proc ctx hdl: IPv6 hdr proc ctx hdl: %d\n",
1854 it_client->l2tp_rt_rule_hdl[j].first_pass_hdr_hdl, it_client->l2tp_rt_rule_hdl[j].first_pass_hdr_proc_ctx_hdl[IPA_IP_v4],
1855 it_client->l2tp_rt_rule_hdl[j].first_pass_hdr_proc_ctx_hdl[IPA_IP_v6]);
1856
1857 IPACMDBG_H("Printing l2tp routing rule info for non l2tp client.\n");
1858 IPACMDBG_H("Number of IPv4 routing rules is %d, handles:\n", it_client->l2tp_rt_rule_hdl[j].num_rt_hdl[IPA_IP_v4]);
1859 for(k = 0; k < it_client->l2tp_rt_rule_hdl[j].num_rt_hdl[IPA_IP_v4]; k++)
1860 {
1861 IPACMDBG_H("%d\n", it_client->l2tp_rt_rule_hdl[j].first_pass_rt_rule_hdl[IPA_IP_v4][k]);
1862 }
1863 IPACMDBG_H("Number of IPv6 routing rules is %d, handles:\n", it_client->l2tp_rt_rule_hdl[j].num_rt_hdl[IPA_IP_v6]);
1864 for(k = 0; k < it_client->l2tp_rt_rule_hdl[j].num_rt_hdl[IPA_IP_v6]; k++)
1865 {
1866 IPACMDBG_H("%d\n", it_client->l2tp_rt_rule_hdl[j].first_pass_rt_rule_hdl[IPA_IP_v6][k]);
1867 }
1868 }
1869 }
1870 #endif
1871 }
1872 }
1873 }
1874
1875 if(m_support_intra_iface_offload)
1876 {
1877 IPACMDBG_H("Printing routing rule info for intra-interface communication.\n");
1878 IPACMDBG_H("Number of IPv4 routing rules is %d, handles:\n", it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]);
1879 for(j = 0; j < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]; j++)
1880 {
1881 IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][j]);
1882 }
1883
1884 IPACMDBG_H("Number of IPv6 routing rules is %d, handles:\n", it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]);
1885 for(j = 0; j < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]; j++)
1886 {
1887 IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][j]);
1888 }
1889 }
1890 i++;
1891 }
1892
1893 IPACMDBG_H("There are %zu peer interfaces in total.\n", m_peer_iface_info.size());
1894 for(it_peer = m_peer_iface_info.begin(); it_peer != m_peer_iface_info.end(); it_peer++)
1895 {
1896 print_peer_info(&(*it_peer));
1897 }
1898
1899 if(m_support_intra_iface_offload)
1900 {
1901 IPACMDBG_H("This interface supports intra-interface communication, printing info:\n");
1902 print_peer_info(&m_intra_interface_info);
1903 }
1904
1905 return;
1906 }
1907
print_peer_info(peer_iface_info * peer_info)1908 void IPACM_LanToLan_Iface::print_peer_info(peer_iface_info *peer_info)
1909 {
1910 list<flt_rule_info>::iterator it_flt;
1911 list<rt_rule_info>::iterator it_rt;
1912
1913 IPACMDBG_H("Printing peer info for iface %s:\n", peer_info->peer->m_p_iface->dev_name);
1914
1915 IPACMDBG_H("There are %zu flt info in total.\n", peer_info->flt_rule.size());
1916 for(it_flt = peer_info->flt_rule.begin(); it_flt != peer_info->flt_rule.end(); it_flt++)
1917 {
1918 IPACMDBG_H("Flt rule handle for client 0x%p:\n", it_flt->p_client);
1919 if(m_is_ip_addr_assigned[IPA_IP_v4])
1920 {
1921 IPACMDBG_H("IPv4 %d\n", it_flt->flt_rule_hdl[IPA_IP_v4]);
1922 IPACMDBG_H("IPv4 l2tp first pass flt rule: %d\n", it_flt->l2tp_first_pass_flt_rule_hdl[IPA_IP_v4]);
1923 }
1924 if(m_is_ip_addr_assigned[IPA_IP_v6])
1925 {
1926 IPACMDBG_H("IPv6 %d\n", it_flt->flt_rule_hdl[IPA_IP_v6]);
1927 IPACMDBG_H("IPv6 l2tp first pass flt rule: %d\n", it_flt->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6]);
1928 }
1929 IPACMDBG_H("L2tp second pass flt rule: %d\n", it_flt->l2tp_second_pass_flt_rule_hdl);
1930 }
1931
1932 return;
1933 }
1934
get_iface_pointer()1935 IPACM_Lan* IPACM_LanToLan_Iface::get_iface_pointer()
1936 {
1937 return m_p_iface;
1938 }
1939
get_m_is_ip_addr_assigned(ipa_ip_type iptype)1940 bool IPACM_LanToLan_Iface::get_m_is_ip_addr_assigned(ipa_ip_type iptype)
1941 {
1942 IPACMDBG_H("Has IP address been assigned to interface %s for IP type %d? %d\n",
1943 m_p_iface->dev_name, iptype, m_is_ip_addr_assigned[iptype]);
1944 return m_is_ip_addr_assigned[iptype];
1945 }
1946
set_m_is_ip_addr_assigned(ipa_ip_type iptype,bool value)1947 void IPACM_LanToLan_Iface::set_m_is_ip_addr_assigned(ipa_ip_type iptype, bool value)
1948 {
1949 IPACMDBG_H("Is IP address of IP type %d assigned to interface %s? %d\n", iptype,
1950 m_p_iface->dev_name, value);
1951 m_is_ip_addr_assigned[iptype] = value;
1952 }
1953
get_m_support_inter_iface_offload()1954 bool IPACM_LanToLan_Iface::get_m_support_inter_iface_offload()
1955 {
1956 IPACMDBG_H("Support inter interface offload on %s? %d\n", m_p_iface->dev_name,
1957 m_support_inter_iface_offload);
1958 return m_support_inter_iface_offload;
1959 }
1960
get_m_support_intra_iface_offload()1961 bool IPACM_LanToLan_Iface::get_m_support_intra_iface_offload()
1962 {
1963 IPACMDBG_H("Support intra interface offload on %s? %d\n", m_p_iface->dev_name,
1964 m_support_intra_iface_offload);
1965 return m_support_intra_iface_offload;
1966 }
1967
increment_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type)1968 void IPACM_LanToLan_Iface::increment_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type)
1969 {
1970 ref_cnt_peer_l2_hdr_type[peer_l2_type]++;
1971 IPACMDBG_H("Now the ref_cnt of peer l2 hdr type %s is %d.\n", ipa_l2_hdr_type[peer_l2_type],
1972 ref_cnt_peer_l2_hdr_type[peer_l2_type]);
1973
1974 return;
1975 }
1976
decrement_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type)1977 void IPACM_LanToLan_Iface::decrement_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type)
1978 {
1979 ref_cnt_peer_l2_hdr_type[peer_l2_type]--;
1980 IPACMDBG_H("Now the ref_cnt of peer l2 hdr type %s is %d.\n", ipa_l2_hdr_type[peer_l2_type],
1981 ref_cnt_peer_l2_hdr_type[peer_l2_type]);
1982
1983 return;
1984 }
1985
1986 #ifdef FEATURE_L2TP
set_l2tp_iface(char * vlan_iface_name)1987 bool IPACM_LanToLan_Iface::set_l2tp_iface(char *vlan_iface_name)
1988 {
1989 IPACMDBG_H("Self iface %s, vlan iface %s\n", m_p_iface->dev_name,
1990 vlan_iface_name);
1991
1992 if(m_is_l2tp_iface == false)
1993 {
1994 if(strncmp(m_p_iface->dev_name, vlan_iface_name, strlen(m_p_iface->dev_name)) == 0)
1995 {
1996 IPACMDBG_H("This interface is l2tp interface.\n");
1997 m_is_l2tp_iface = true;
1998 }
1999 }
2000 return m_is_l2tp_iface;
2001 }
2002
is_l2tp_iface()2003 bool IPACM_LanToLan_Iface::is_l2tp_iface()
2004 {
2005 return m_is_l2tp_iface;
2006 }
2007
switch_to_l2tp_iface()2008 void IPACM_LanToLan_Iface::switch_to_l2tp_iface()
2009 {
2010 list<peer_iface_info>::iterator it_peer;
2011 list<flt_rule_info>::iterator it_flt;
2012
2013 for(it_peer = m_peer_iface_info.begin(); it_peer != m_peer_iface_info.end(); it_peer++)
2014 {
2015 for(it_flt = it_peer->flt_rule.begin(); it_flt != it_peer->flt_rule.end(); it_flt++)
2016 {
2017 if(m_is_ip_addr_assigned[IPA_IP_v4])
2018 {
2019 m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v4], IPA_IP_v4);
2020 IPACMDBG_H("Deleted IPv4 flt rule %d.\n", it_flt->flt_rule_hdl[IPA_IP_v4]);
2021 }
2022 if(m_is_ip_addr_assigned[IPA_IP_v6])
2023 {
2024 m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v6], IPA_IP_v6);
2025 m_p_iface->add_l2tp_flt_rule(it_flt->p_client->mac_addr, &it_flt->l2tp_first_pass_flt_rule_hdl[IPA_IP_v6]);
2026 IPACMDBG_H("Deleted IPv6 flt rule %d.\n", it_flt->flt_rule_hdl[IPA_IP_v6]);
2027 }
2028 }
2029 }
2030 return;
2031 }
handle_l2tp_enable()2032 void IPACM_LanToLan_Iface::handle_l2tp_enable()
2033 {
2034 int i;
2035 ipa_hdr_l2_type peer_l2_hdr_type;
2036 list<peer_iface_info>::iterator it_peer_info;
2037 list<client_info>::iterator it_client;
2038 bool flag[IPA_HDR_L2_MAX];
2039
2040 if(m_support_inter_iface_offload)
2041 {
2042 memset(flag, 0, sizeof(flag));
2043 for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); it_peer_info++)
2044 {
2045 if(it_peer_info->peer->is_l2tp_iface())
2046 {
2047 peer_l2_hdr_type = it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type;
2048 flag[peer_l2_hdr_type] = true;
2049 }
2050 }
2051
2052 for(i = 0; i < IPA_HDR_L2_MAX; i++)
2053 {
2054 if(flag[i] == true)
2055 {
2056 IPACMDBG_H("Add rt rule for peer l2 type %s\n", ipa_l2_hdr_type[i]);
2057 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++)
2058 {
2059 m_p_iface->add_l2tp_rt_rule(IPA_IP_v6, it_client->mac_addr, &hdr_proc_ctx_for_l2tp,
2060 &it_client->l2tp_rt_rule_hdl[i].num_rt_hdl[IPA_IP_v6],
2061 it_client->l2tp_rt_rule_hdl[i].first_pass_rt_rule_hdl[IPA_IP_v6]);
2062 }
2063 }
2064 }
2065 }
2066 return;
2067 }
2068
handle_l2tp_disable()2069 void IPACM_LanToLan_Iface::handle_l2tp_disable()
2070 {
2071 int i;
2072 ipa_hdr_l2_type peer_l2_hdr_type;
2073 list<peer_iface_info>::iterator it_peer_info;
2074 list<client_info>::iterator it_client;
2075 bool flag[IPA_HDR_L2_MAX];
2076
2077 if(m_support_inter_iface_offload)
2078 {
2079 memset(flag, 0, sizeof(flag));
2080 for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); it_peer_info++)
2081 {
2082 peer_l2_hdr_type = it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type;
2083 flag[peer_l2_hdr_type] = true;
2084 }
2085
2086 for(i = 0; i < IPA_HDR_L2_MAX; i++)
2087 {
2088 if(flag[i] == true)
2089 {
2090 IPACMDBG_H("Delete rt rule for peer l2 type %s\n", ipa_l2_hdr_type[i]);
2091 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++)
2092 {
2093 m_p_iface->del_l2tp_rt_rule(IPA_IP_v6, it_client->l2tp_rt_rule_hdl[i].num_rt_hdl[IPA_IP_v6],
2094 it_client->l2tp_rt_rule_hdl[i].first_pass_rt_rule_hdl[IPA_IP_v6]);
2095 }
2096 }
2097 }
2098 }
2099 return;
2100 }
2101 #endif
2102