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