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