• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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