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