1 /*
2 Copyright (c) 2013-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_Neighbor.cpp
32 
33 	@brief
34 	This file implements the functionality of handling IPACM Neighbor events.
35 
36 	@Author
37 	Skylar Chang
38 
39 */
40 
41 #include <sys/ioctl.h>
42 #include <IPACM_Neighbor.h>
43 #include <IPACM_EvtDispatcher.h>
44 #include "IPACM_Defs.h"
45 #include "IPACM_Log.h"
46 
47 
IPACM_Neighbor()48 IPACM_Neighbor::IPACM_Neighbor()
49 {
50 	num_neighbor_client = 0;
51 	circular_index = 0;
52 	memset(neighbor_client, 0, IPA_MAX_NUM_NEIGHBOR_CLIENTS * sizeof(ipa_neighbor_client));
53 	IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT_EX, this);
54 	IPACM_EvtDispatcher::registr(IPA_NEW_NEIGH_EVENT, this);
55 	IPACM_EvtDispatcher::registr(IPA_DEL_NEIGH_EVENT, this);
56 	return;
57 }
58 
event_callback(ipa_cm_event_id event,void * param)59 void IPACM_Neighbor::event_callback(ipa_cm_event_id event, void *param)
60 {
61 	ipacm_event_data_all *data_all = NULL;
62 	int i, ipa_interface_index;
63 	ipacm_cmd_q_data evt_data;
64 	int num_neighbor_client_temp = num_neighbor_client;
65 
66 	IPACMDBG("Recieved event %d\n", event);
67 
68 	switch (event)
69 	{
70 		case IPA_WLAN_CLIENT_ADD_EVENT_EX:
71 		{
72 			ipacm_event_data_wlan_ex *data = (ipacm_event_data_wlan_ex *)param;
73 			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
74 			/* check for failure return */
75 			if (IPACM_FAILURE == ipa_interface_index) {
76 				IPACMERR("IPA_WLAN_CLIENT_ADD_EVENT_EX: not supported iface id: %d\n", data->if_index);
77 				break;
78 			}
79 			uint8_t client_mac_addr[6] = {0};
80 
81 			IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n");
82 			for(i = 0; i < data->num_of_attribs; i++)
83 			{
84 				if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
85 				{
86 					memcpy(client_mac_addr,
87 							data->attribs[i].u.mac_addr,
88 							sizeof(client_mac_addr));
89 					IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
90 							 client_mac_addr[0], client_mac_addr[1], client_mac_addr[2],
91 							 client_mac_addr[3], client_mac_addr[4], client_mac_addr[5]);
92 				}
93 				else
94 				{
95 					IPACMDBG_H("The attribute type is not expected!\n");
96 				}
97 			}
98 
99 			for (i = 0; i < num_neighbor_client_temp; i++)
100 			{
101 				/* find the client */
102 				if (memcmp(neighbor_client[i].mac_addr, client_mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
103 				{
104 					/* check if iface is not bridge interface*/
105 					if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
106 					{
107 						/* use previous ipv4 first */
108 						if(data->if_index != neighbor_client[i].iface_index)
109 						{
110 							IPACMERR("update new kernel iface index \n");
111 							neighbor_client[i].iface_index = data->if_index;
112 						}
113 
114 						/* check if client associated with previous network interface */
115 						if(ipa_interface_index != neighbor_client[i].ipa_if_num)
116 						{
117 							IPACMERR("client associate to different AP \n");
118 							return;
119 						}
120 
121 						if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */
122 						{
123 							evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
124 							data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
125 							if (data_all == NULL)
126 							{
127 								IPACMERR("Unable to allocate memory\n");
128 								return;
129 							}
130 							memset(data_all,0,sizeof(ipacm_event_data_all));
131 							data_all->iptype = IPA_IP_v4;
132 							data_all->if_index = neighbor_client[i].iface_index;
133 							data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address
134 							memcpy(data_all->mac_addr,
135 									neighbor_client[i].mac_addr,
136 												sizeof(data_all->mac_addr));
137 							memcpy(data_all->iface_name, neighbor_client[i].iface_name,
138 								sizeof(data_all->iface_name));
139 							evt_data.evt_data = (void *)data_all;
140 							IPACM_EvtDispatcher::PostEvt(&evt_data);
141 							/* ask for replaced iface name*/
142 							ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
143 							/* check for failure return */
144 							if (IPACM_FAILURE == ipa_interface_index) {
145 								IPACMERR("not supported iface id: %d\n", data_all->if_index);
146 							} else {
147 								IPACMDBG_H("Posted event %d, with %s for ipv4 client re-connect\n",
148 									evt_data.event,
149 									data_all->iface_name);
150 							}
151 						}
152 					}
153 					break;
154 				}
155 			}
156 		}
157 		break;
158 
159 		default:
160 		{
161 			if (event == IPA_NEW_NEIGH_EVENT)
162 			{
163 				IPACMDBG_H("Received IPA_NEW_NEIGH_EVENT\n");
164 			}
165 			else
166 			{
167 				IPACMDBG_H("Received IPA_DEL_NEIGH_EVENT\n");
168 			}
169 
170 			ipacm_event_data_all *data = (ipacm_event_data_all *)param;
171 			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
172 #ifndef FEATURE_L2TP
173 			/* check for failure return */
174 			if (IPACM_FAILURE == ipa_interface_index) {
175 				IPACMERR("not supported iface id: %d\n", data->if_index);
176 				break;
177 			}
178 #endif
179 			if (data->iptype == IPA_IP_v4)
180 			{
181 				if (data->ipv4_addr != 0) /* not 0.0.0.0 */
182 				{
183 					IPACMDBG("Got Neighbor event with ipv4 address: 0x%x \n", data->ipv4_addr);
184 					/* check if ipv4 address is link local(169.254.xxx.xxx) */
185 					if ((data->ipv4_addr & IPV4_ADDR_LINKLOCAL_MASK) == IPV4_ADDR_LINKLOCAL)
186 					{
187 						IPACMDBG_H("This is link local ipv4 address: 0x%x : ignore this NEIGH_EVENT\n", data->ipv4_addr);
188 						return;
189 					}
190 					/* check if iface is bridge interface */
191 					if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, data->iface_name) == 0)
192 					{
193 						/* search if seen this client or not */
194 						for (i = 0; i < num_neighbor_client_temp; i++)
195 						{
196 							if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
197 							{
198 								data->if_index = neighbor_client[i].iface_index;
199 								strlcpy(data->iface_name, neighbor_client[i].iface_name, sizeof(data->iface_name));
200 								neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
201 								/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
202 								if (event == IPA_NEW_NEIGH_EVENT)
203 									evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
204 								else
205 									/* not to clean-up the client mac cache on bridge0 delneigh */
206 									evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
207 								data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
208 								if (data_all == NULL)
209 								{
210 									IPACMERR("Unable to allocate memory\n");
211 									return;
212 								}
213 								memcpy(data_all, data, sizeof(ipacm_event_data_all));
214 								evt_data.evt_data = (void *)data_all;
215 								IPACM_EvtDispatcher::PostEvt(&evt_data);
216 
217 								/* ask for replaced iface name*/
218 								ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
219 								/* check for failure return */
220 								if (IPACM_FAILURE == ipa_interface_index) {
221 									IPACMERR("not supported iface id: %d\n", data_all->if_index);
222 								} else {
223 									IPACMDBG_H("Posted event %d,\
224 										with %s for ipv4\n",
225 										evt_data.event,
226 										data->iface_name);
227 								}
228 								break;
229 							}
230 						}
231 					}
232 					else
233 					{
234 						/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
235 						if (event == IPA_NEW_NEIGH_EVENT)
236 						{
237 							evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
238 							/* Also save to cache for ipv4 */
239 							/*searh if seen this client or not*/
240 							for (i = 0; i < num_neighbor_client_temp; i++)
241 							{
242 								/* find the client */
243 								if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
244 								{
245 									/* update the network interface client associated */
246 									neighbor_client[i].ipa_if_num = ipa_interface_index;
247 									neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
248 									strlcpy(neighbor_client[i].iface_name, data->iface_name, sizeof(neighbor_client[i].iface_name));
249 									neighbor_client[i].iface_index = data->if_index;
250 									IPACMDBG_H("update cache %d-entry, with %s iface, ipv4 address: 0x%x\n",
251 										i, data->iface_name, data->ipv4_addr);
252 									break;
253 								}
254 							}
255 							/* not find client */
256 							if (i == num_neighbor_client_temp)
257 							{
258 								if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
259 								{
260 									memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
261 												data->mac_addr,
262 												sizeof(data->mac_addr));
263 									neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
264 									/* cache the network interface client associated */
265 									neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
266 									neighbor_client[num_neighbor_client_temp].v4_addr = data->ipv4_addr;
267 									strlcpy(neighbor_client[num_neighbor_client_temp].iface_name,
268 										data->iface_name, sizeof(neighbor_client[num_neighbor_client_temp].iface_name));
269 									num_neighbor_client++;
270 									IPACMDBG_H("Cache client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
271 												neighbor_client[num_neighbor_client_temp].mac_addr[0],
272 												neighbor_client[num_neighbor_client_temp].mac_addr[1],
273 												neighbor_client[num_neighbor_client_temp].mac_addr[2],
274 												neighbor_client[num_neighbor_client_temp].mac_addr[3],
275 												neighbor_client[num_neighbor_client_temp].mac_addr[4],
276 												neighbor_client[num_neighbor_client_temp].mac_addr[5],
277 												num_neighbor_client);
278 								}
279 								else
280 								{
281 
282 									IPACMERR("error:  neighbor client oversize! recycle %d-st entry ! \n", circular_index);
283 									memcpy(neighbor_client[circular_index].mac_addr,
284 												data->mac_addr,
285 												sizeof(data->mac_addr));
286 									neighbor_client[circular_index].iface_index = data->if_index;
287 									/* cache the network interface client associated */
288 									neighbor_client[circular_index].ipa_if_num = ipa_interface_index;
289 									neighbor_client[circular_index].v4_addr = 0;
290 									strlcpy(neighbor_client[circular_index].iface_name,
291 										data->iface_name, sizeof(neighbor_client[circular_index].iface_name));
292 									IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d, circular %d\n",
293 													neighbor_client[circular_index].mac_addr[0],
294 													neighbor_client[circular_index].mac_addr[1],
295 													neighbor_client[circular_index].mac_addr[2],
296 													neighbor_client[circular_index].mac_addr[3],
297 													neighbor_client[circular_index].mac_addr[4],
298 													neighbor_client[circular_index].mac_addr[5],
299 													num_neighbor_client,
300 													circular_index);
301 									circular_index = (circular_index + 1) % IPA_MAX_NUM_NEIGHBOR_CLIENTS;
302 								}
303 							}
304 						}
305 						else
306 						{
307 							evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
308 							/*search if seen this client or not*/
309 							for (i = 0; i < num_neighbor_client_temp; i++)
310 							{
311 								/* find the client */
312 								if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
313 								{
314 									IPACMDBG_H("Clean %d-st Cached client-MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
315 												i,
316 												neighbor_client[i].mac_addr[0],
317 												neighbor_client[i].mac_addr[1],
318 												neighbor_client[i].mac_addr[2],
319 												neighbor_client[i].mac_addr[3],
320 												neighbor_client[i].mac_addr[4],
321 												neighbor_client[i].mac_addr[5],
322 												num_neighbor_client);
323 
324 									memset(neighbor_client[i].mac_addr, 0, sizeof(neighbor_client[i].mac_addr));
325 									neighbor_client[i].iface_index = 0;
326 									neighbor_client[i].v4_addr = 0;
327 									neighbor_client[i].ipa_if_num = 0;
328 									memset(neighbor_client[i].iface_name, 0, sizeof(neighbor_client[i].iface_name));
329 									for (; i < num_neighbor_client_temp - 1; i++)
330 									{
331 										memcpy(neighbor_client[i].mac_addr,
332 													neighbor_client[i + 1].mac_addr,
333 													sizeof(neighbor_client[i].mac_addr));
334 										neighbor_client[i].iface_index = neighbor_client[i + 1].iface_index;
335 										neighbor_client[i].v4_addr = neighbor_client[i + 1].v4_addr;
336 										neighbor_client[i].ipa_if_num = neighbor_client[i + 1].ipa_if_num;
337 										strlcpy(neighbor_client[i].iface_name, neighbor_client[i + 1].iface_name,
338 											sizeof(neighbor_client[i].iface_name));
339 									}
340 									num_neighbor_client--;
341 									IPACMDBG_H(" total number of left cased clients: %d\n", num_neighbor_client);
342 									break;
343 								}
344 							}
345 							/* not find client, no need clean-up */
346 						}
347 
348 						data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
349 						if (data_all == NULL)
350 						{
351 							IPACMERR("Unable to allocate memory\n");
352 							return;
353 						}
354 						memcpy(data_all, data, sizeof(ipacm_event_data_all));
355 						evt_data.evt_data = (void *)data_all;
356 						IPACM_EvtDispatcher::PostEvt(&evt_data);
357 						IPACMDBG_H("Posted event %d with %s for ipv4\n",
358 							evt_data.event, data->iface_name);
359 					}
360 				}
361 			}
362 			else
363 			{   //ipv6 starts
364 
365 				if ((data->ipv6_addr[0]) || (data->ipv6_addr[1]) || (data->ipv6_addr[2]) || (data->ipv6_addr[3]))
366 				{
367 					IPACMDBG("Got New_Neighbor event with ipv6 address \n");
368 					/* check if iface is bridge  interface */
369 					if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, data->iface_name) == 0)
370 					{
371 						/* search if seen this client or not*/
372 						for (i = 0; i < num_neighbor_client_temp; i++)
373 						{
374 							if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
375 							{
376 								data->if_index = neighbor_client[i].iface_index;
377 								strlcpy(data->iface_name, neighbor_client[i].iface_name, sizeof(data->iface_name));
378 								/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
379 								if (event == IPA_NEW_NEIGH_EVENT)
380 									evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
381 								else
382 									evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
383 								data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
384 								if (data_all == NULL)
385 								{
386 									IPACMERR("Unable to allocate memory\n");
387 									return;
388 								}
389 								memcpy(data_all, data, sizeof(ipacm_event_data_all));
390 								evt_data.evt_data = (void *)data_all;
391 								IPACM_EvtDispatcher::PostEvt(&evt_data);
392 								/* ask for replaced iface name*/
393 								ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
394 								/* check for failure return */
395 								if (IPACM_FAILURE == ipa_interface_index) {
396 									IPACMERR("not supported iface id: %d\n", data_all->if_index);
397 								} else {
398 									IPACMDBG_H("Posted event %d,\
399 										with %s for ipv6\n",
400 										evt_data.event,
401 										data->iface_name);
402 								}
403 								break;
404 							};
405 						}
406 					}
407 					else
408 					{
409 						/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
410 						if (event == IPA_NEW_NEIGH_EVENT)
411 							evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
412 						else
413 							evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
414 						data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
415 						if (data_all == NULL)
416 						{
417 							IPACMERR("Unable to allocate memory\n");
418 							return;
419 						}
420 						memcpy(data_all, data, sizeof(ipacm_event_data_all));
421 						evt_data.evt_data = (void *)data_all;
422 						IPACM_EvtDispatcher::PostEvt(&evt_data);
423 						IPACMDBG_H("Posted event %d with %s for ipv6\n",
424 							evt_data.event, data->iface_name);
425 					}
426 				}
427 				else
428 				{
429 					IPACMDBG(" Got Neighbor event with no ipv6/ipv4 address \n");
430 					/*no ipv6 in data searh if seen this client or not*/
431 					for (i = 0; i < num_neighbor_client_temp; i++)
432 					{
433 						/* find the client */
434 						if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
435 						{
436 							IPACMDBG_H(" find %d-st client, MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
437 												i,
438 												neighbor_client[i].mac_addr[0],
439 												neighbor_client[i].mac_addr[1],
440 												neighbor_client[i].mac_addr[2],
441 												neighbor_client[i].mac_addr[3],
442 												neighbor_client[i].mac_addr[4],
443 												neighbor_client[i].mac_addr[5],
444 												num_neighbor_client);
445 							/* check if iface is not bridge interface*/
446 							if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, data->iface_name) != 0)
447 							{
448 								/* use previous ipv4 first */
449 								if(data->if_index != neighbor_client[i].iface_index)
450 								{
451 									IPACMDBG_H("update new kernel iface index \n");
452 									neighbor_client[i].iface_index = data->if_index;
453 									strlcpy(neighbor_client[i].iface_name, data->iface_name, sizeof(neighbor_client[i].iface_name));
454 								}
455 
456 								/* check if client associated with previous network interface */
457 								if(ipa_interface_index != neighbor_client[i].ipa_if_num)
458 								{
459 									IPACMDBG_H("client associate to different AP \n");
460 								}
461 
462 								if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */
463 								{
464 									/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
465 									if (event == IPA_NEW_NEIGH_EVENT)
466 										evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
467 									else
468 										evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
469 									data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
470 									if (data_all == NULL)
471 									{
472 										IPACMERR("Unable to allocate memory\n");
473 										return;
474 									}
475 									data_all->iptype = IPA_IP_v4;
476 									data_all->if_index = neighbor_client[i].iface_index;
477 									data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address
478 									memcpy(data_all->mac_addr, neighbor_client[i].mac_addr,
479 										sizeof(data_all->mac_addr));
480 									strlcpy(data_all->iface_name, neighbor_client[i].iface_name, sizeof(data_all->iface_name));
481 									evt_data.evt_data = (void *)data_all;
482 									IPACM_EvtDispatcher::PostEvt(&evt_data);
483 									IPACMDBG_H("Posted event %d with %s for ipv4\n",
484 										evt_data.event, data_all->iface_name);
485 								}
486 							}
487 							/* delete cache neighbor entry */
488 							if (event == IPA_DEL_NEIGH_EVENT)
489 							{
490 								IPACMDBG_H("Clean %d-st Cached client-MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
491 									i,
492 									neighbor_client[i].mac_addr[0],
493 									neighbor_client[i].mac_addr[1],
494 									neighbor_client[i].mac_addr[2],
495 									neighbor_client[i].mac_addr[3],
496 									neighbor_client[i].mac_addr[4],
497 									neighbor_client[i].mac_addr[5],
498 									num_neighbor_client);
499 
500 								memset(neighbor_client[i].mac_addr, 0, sizeof(neighbor_client[i].mac_addr));
501 								neighbor_client[i].iface_index = 0;
502 								neighbor_client[i].v4_addr = 0;
503 								neighbor_client[i].ipa_if_num = 0;
504 								memset(neighbor_client[i].iface_name, 0, sizeof(neighbor_client[i].iface_name));
505 								for(; i < num_neighbor_client_temp - 1; i++)
506 								{
507 									memcpy(neighbor_client[i].mac_addr,
508 										neighbor_client[i + 1].mac_addr,
509 										sizeof(neighbor_client[i].mac_addr));
510 									neighbor_client[i].iface_index = neighbor_client[i + 1].iface_index;
511 									neighbor_client[i].v4_addr = neighbor_client[i + 1].v4_addr;
512 									neighbor_client[i].ipa_if_num = neighbor_client[i + 1].ipa_if_num;
513 									strlcpy(neighbor_client[i].iface_name, neighbor_client[i + 1].iface_name,
514 										sizeof(neighbor_client[i].iface_name));
515 								}
516 								num_neighbor_client--;
517 								IPACMDBG_H(" total number of left cased clients: %d\n", num_neighbor_client);
518 							}
519 							break;
520 						}
521 					}
522 					/* not find client */
523 					if ((i == num_neighbor_client_temp) && (event == IPA_NEW_NEIGH_EVENT))
524 					{
525 						/* check if iface is not bridge interface*/
526 						if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, data->iface_name) != 0)
527 						{
528 							if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
529 							{
530 								memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
531 											data->mac_addr,
532 											sizeof(data->mac_addr));
533 								neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
534 								/* cache the network interface client associated */
535 								neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
536 								neighbor_client[num_neighbor_client_temp].v4_addr = 0;
537 								strlcpy(neighbor_client[num_neighbor_client_temp].iface_name, data->iface_name,
538 									sizeof(neighbor_client[num_neighbor_client_temp].iface_name));
539 								num_neighbor_client++;
540 								IPACMDBG_H("Copy client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
541 												neighbor_client[num_neighbor_client_temp].mac_addr[0],
542 												neighbor_client[num_neighbor_client_temp].mac_addr[1],
543 												neighbor_client[num_neighbor_client_temp].mac_addr[2],
544 												neighbor_client[num_neighbor_client_temp].mac_addr[3],
545 												neighbor_client[num_neighbor_client_temp].mac_addr[4],
546 												neighbor_client[num_neighbor_client_temp].mac_addr[5],
547 												num_neighbor_client);
548 								return;
549 							}
550 							else
551 							{
552 								IPACMERR("error:  neighbor client oversize! recycle %d-st entry ! \n", circular_index);
553 								memcpy(neighbor_client[circular_index].mac_addr,
554 											data->mac_addr,
555 											sizeof(data->mac_addr));
556 								neighbor_client[circular_index].iface_index = data->if_index;
557 								/* cache the network interface client associated */
558 								neighbor_client[circular_index].ipa_if_num = ipa_interface_index;
559 								neighbor_client[circular_index].v4_addr = 0;
560 								strlcpy(neighbor_client[circular_index].iface_name, data->iface_name,
561 									sizeof(neighbor_client[circular_index].iface_name));
562 								IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d, circular %d\n",
563 												neighbor_client[circular_index].mac_addr[0],
564 												neighbor_client[circular_index].mac_addr[1],
565 												neighbor_client[circular_index].mac_addr[2],
566 												neighbor_client[circular_index].mac_addr[3],
567 												neighbor_client[circular_index].mac_addr[4],
568 												neighbor_client[circular_index].mac_addr[5],
569 												num_neighbor_client,
570 												circular_index);
571 								circular_index = (circular_index + 1) % IPA_MAX_NUM_NEIGHBOR_CLIENTS;
572 								return;
573 							}
574 						}
575 					}
576 				}
577 			} //ipv6 ends
578 		}
579 		break;
580 	}
581 	return;
582 }
583