• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 		* Redistributions of source code must retain the above copyright
8 			notice, this list of conditions and the following disclaimer.
9 		* Redistributions in binary form must reproduce the above
10 			copyright notice, this list of conditions and the following
11 			disclaimer in the documentation and/or other materials provided
12 			with the distribution.
13 		* Neither the name of The Linux Foundation nor the names of its
14 			contributors may be used to endorse or promote products derived
15 			from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 /*!
30 	@file
31 	IPACM_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 						/* searh 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].iface_index = data->if_index;
247 									neighbor_client[i].ipa_if_num = ipa_interface_index;
248 									neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
249 									strlcpy(neighbor_client[i].iface_name, data->iface_name, sizeof(neighbor_client[i].iface_name));
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 							/*searh 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 						/* searh 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) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
380 								else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
381 								data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
382 								if (data_all == NULL)
383 								{
384 									IPACMERR("Unable to allocate memory\n");
385 									return;
386 								}
387 								memcpy(data_all, data, sizeof(ipacm_event_data_all));
388 								evt_data.evt_data = (void *)data_all;
389 								IPACM_EvtDispatcher::PostEvt(&evt_data);
390 								/* ask for replaced iface name*/
391 								ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
392 								/* check for failure return */
393 								if (IPACM_FAILURE == ipa_interface_index) {
394 									IPACMERR("not supported iface id: %d\n", data_all->if_index);
395 								} else {
396 									IPACMDBG_H("Posted event %d,\
397 										with %s for ipv6\n",
398 										evt_data.event,
399 										data->iface_name);
400 								}
401 								break;
402 							};
403 						}
404 					}
405 					else
406 					{
407 						/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
408 						if (event == IPA_NEW_NEIGH_EVENT)
409 							evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
410 						else
411 							evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
412 						data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
413 						if (data_all == NULL)
414 						{
415 							IPACMERR("Unable to allocate memory\n");
416 							return;
417 						}
418 						memcpy(data_all, data, sizeof(ipacm_event_data_all));
419 						evt_data.evt_data = (void *)data_all;
420 						IPACM_EvtDispatcher::PostEvt(&evt_data);
421 						IPACMDBG_H("Posted event %d with %s for ipv6\n",
422 							evt_data.event, data->iface_name);
423 					}
424 				}
425 				else
426 				{
427 					IPACMDBG(" Got Neighbor event with no ipv6/ipv4 address \n");
428 					/*no ipv6 in data searh if seen this client or not*/
429 					for (i = 0; i < num_neighbor_client_temp; i++)
430 					{
431 						/* find the client */
432 						if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
433 						{
434 							IPACMDBG_H(" find %d-st client, MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
435 												i,
436 												neighbor_client[i].mac_addr[0],
437 												neighbor_client[i].mac_addr[1],
438 												neighbor_client[i].mac_addr[2],
439 												neighbor_client[i].mac_addr[3],
440 												neighbor_client[i].mac_addr[4],
441 												neighbor_client[i].mac_addr[5],
442 												num_neighbor_client);
443 							/* check if iface is not bridge interface*/
444 							if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, data->iface_name) != 0)
445 							{
446 								/* use previous ipv4 first */
447 								if(data->if_index != neighbor_client[i].iface_index)
448 								{
449 									IPACMDBG_H("update new kernel iface index \n");
450 									neighbor_client[i].iface_index = data->if_index;
451 									strlcpy(neighbor_client[i].iface_name, data->iface_name, sizeof(neighbor_client[i].iface_name));
452 								}
453 
454 								/* check if client associated with previous network interface */
455 								if(ipa_interface_index != neighbor_client[i].ipa_if_num)
456 								{
457 									IPACMDBG_H("client associate to different AP \n");
458 								}
459 
460 								if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */
461 								{
462 									/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
463 									if (event == IPA_NEW_NEIGH_EVENT)
464 										evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
465 									else
466 										evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
467 									data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
468 									if (data_all == NULL)
469 									{
470 										IPACMERR("Unable to allocate memory\n");
471 										return;
472 									}
473 									data_all->iptype = IPA_IP_v4;
474 									data_all->if_index = neighbor_client[i].iface_index;
475 									data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address
476 									memcpy(data_all->mac_addr, neighbor_client[i].mac_addr,
477 										sizeof(data_all->mac_addr));
478 									strlcpy(data_all->iface_name, neighbor_client[i].iface_name, sizeof(data_all->iface_name));
479 									evt_data.evt_data = (void *)data_all;
480 									IPACM_EvtDispatcher::PostEvt(&evt_data);
481 									IPACMDBG_H("Posted event %d with %s for ipv4\n",
482 										evt_data.event, data_all->iface_name);
483 								}
484 							}
485 							/* delete cache neighbor entry */
486 							if (event == IPA_DEL_NEIGH_EVENT)
487 							{
488 								IPACMDBG_H("Clean %d-st Cached client-MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
489 										i,
490 										neighbor_client[i].mac_addr[0],
491 										neighbor_client[i].mac_addr[1],
492 										neighbor_client[i].mac_addr[2],
493 										neighbor_client[i].mac_addr[3],
494 										neighbor_client[i].mac_addr[4],
495 										neighbor_client[i].mac_addr[5],
496 										num_neighbor_client);
497 
498 								memset(neighbor_client[i].mac_addr, 0, sizeof(neighbor_client[i].mac_addr));
499 								neighbor_client[i].iface_index = 0;
500 								neighbor_client[i].v4_addr = 0;
501 								neighbor_client[i].ipa_if_num = 0;
502 								memset(neighbor_client[i].iface_name, 0, sizeof(neighbor_client[i].iface_name));
503 								for (; i < num_neighbor_client_temp - 1; i++)
504 								{
505 									memcpy(neighbor_client[i].mac_addr,
506 												neighbor_client[i+1].mac_addr,
507 												sizeof(neighbor_client[i].mac_addr));
508 									neighbor_client[i].iface_index = neighbor_client[i+1].iface_index;
509 									neighbor_client[i].v4_addr = neighbor_client[i+1].v4_addr;
510 									neighbor_client[i].ipa_if_num = neighbor_client[i+1].ipa_if_num;
511 									strlcpy(neighbor_client[i].iface_name, neighbor_client[i+1].iface_name,
512 										sizeof(neighbor_client[i].iface_name));
513 								}
514 								num_neighbor_client--;
515 								IPACMDBG_H(" total number of left cased clients: %d\n", num_neighbor_client);
516 							}
517 							break;
518 						}
519 					}
520 					/* not find client */
521 					if ((i == num_neighbor_client_temp) && (event == IPA_NEW_NEIGH_EVENT))
522 					{
523 						/* check if iface is not bridge interface*/
524 						if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, data->iface_name) != 0)
525 						{
526 							if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
527 							{
528 								memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
529 											data->mac_addr,
530 											sizeof(data->mac_addr));
531 								neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
532 								/* cache the network interface client associated */
533 								neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
534 								neighbor_client[num_neighbor_client_temp].v4_addr = 0;
535 								strlcpy(neighbor_client[num_neighbor_client_temp].iface_name, data->iface_name,
536 									sizeof(neighbor_client[num_neighbor_client_temp].iface_name));
537 								num_neighbor_client++;
538 								IPACMDBG_H("Copy client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
539 												neighbor_client[num_neighbor_client_temp].mac_addr[0],
540 												neighbor_client[num_neighbor_client_temp].mac_addr[1],
541 												neighbor_client[num_neighbor_client_temp].mac_addr[2],
542 												neighbor_client[num_neighbor_client_temp].mac_addr[3],
543 												neighbor_client[num_neighbor_client_temp].mac_addr[4],
544 												neighbor_client[num_neighbor_client_temp].mac_addr[5],
545 												num_neighbor_client);
546 								return;
547 							}
548 							else
549 							{
550 								IPACMERR("error:  neighbor client oversize! recycle %d-st entry ! \n", circular_index);
551 								memcpy(neighbor_client[circular_index].mac_addr,
552 											data->mac_addr,
553 											sizeof(data->mac_addr));
554 								neighbor_client[circular_index].iface_index = data->if_index;
555 								/* cache the network interface client associated */
556 								neighbor_client[circular_index].ipa_if_num = ipa_interface_index;
557 								neighbor_client[circular_index].v4_addr = 0;
558 								strlcpy(neighbor_client[circular_index].iface_name, data->iface_name,
559 									sizeof(neighbor_client[circular_index].iface_name));
560 								IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d, circular %d\n",
561 												neighbor_client[circular_index].mac_addr[0],
562 												neighbor_client[circular_index].mac_addr[1],
563 												neighbor_client[circular_index].mac_addr[2],
564 												neighbor_client[circular_index].mac_addr[3],
565 												neighbor_client[circular_index].mac_addr[4],
566 												neighbor_client[circular_index].mac_addr[5],
567 												num_neighbor_client,
568 												circular_index);
569 								circular_index = (circular_index + 1) % IPA_MAX_NUM_NEIGHBOR_CLIENTS;
570 								return;
571 							}
572 						}
573 					}
574 				}
575 			} //ipv6 ends
576 		}
577 		break;
578 	}
579 	return;
580 }
581