1 /*
2 Copyright (c) 2013, 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 data_all->iptype = IPA_IP_v4;
131 data_all->if_index = neighbor_client[i].iface_index;
132 data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address
133 memcpy(data_all->mac_addr,
134 neighbor_client[i].mac_addr,
135 sizeof(data_all->mac_addr));
136 evt_data.evt_data = (void *)data_all;
137 IPACM_EvtDispatcher::PostEvt(&evt_data);
138 /* ask for replaced iface name*/
139 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
140 /* check for failure return */
141 if (IPACM_FAILURE == ipa_interface_index) {
142 IPACMERR("not supported iface id: %d\n", data_all->if_index);
143 } else {
144 IPACMDBG_H("Posted event %d, with %s for ipv4 client re-connect\n",
145 evt_data.event,
146 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
147 }
148 }
149 }
150 break;
151 }
152 }
153 }
154 break;
155
156 default:
157 {
158 if (event == IPA_NEW_NEIGH_EVENT)
159 {
160 IPACMDBG_H("Received IPA_NEW_NEIGH_EVENT\n");
161 }
162 else
163 {
164 IPACMDBG_H("Received IPA_DEL_NEIGH_EVENT\n");
165 }
166
167 ipacm_event_data_all *data = (ipacm_event_data_all *)param;
168 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
169 /* check for failure return */
170 if (IPACM_FAILURE == ipa_interface_index) {
171 IPACMERR("not supported iface id: %d\n", data->if_index);
172 break;
173 }
174 if (data->iptype == IPA_IP_v4)
175 {
176 if (data->ipv4_addr != 0) /* not 0.0.0.0 */
177 {
178 IPACMDBG("Got Neighbor event with ipv4 address: 0x%x \n", data->ipv4_addr);
179 /* check if ipv4 address is link local(169.254.xxx.xxx) */
180 if ((data->ipv4_addr & IPV4_ADDR_LINKLOCAL_MASK) == IPV4_ADDR_LINKLOCAL)
181 {
182 IPACMDBG_H("This is link local ipv4 address: 0x%x : ignore this NEIGH_EVENT\n", data->ipv4_addr);
183 return;
184 }
185 /* check if iface is bridge interface*/
186 if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
187 {
188 /* searh if seen this client or not*/
189 for (i = 0; i < num_neighbor_client_temp; i++)
190 {
191 if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
192 {
193 data->if_index = neighbor_client[i].iface_index;
194 neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
195 /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
196 if (event == IPA_NEW_NEIGH_EVENT)
197 evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
198 else
199 /* not to clean-up the client mac cache on bridge0 delneigh */
200 evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
201 data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
202 if (data_all == NULL)
203 {
204 IPACMERR("Unable to allocate memory\n");
205 return;
206 }
207 memcpy(data_all, data, sizeof(ipacm_event_data_all));
208 evt_data.evt_data = (void *)data_all;
209 IPACM_EvtDispatcher::PostEvt(&evt_data);
210
211 /* ask for replaced iface name*/
212 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
213 /* check for failure return */
214 if (IPACM_FAILURE == ipa_interface_index) {
215 IPACMERR("not supported iface id: %d\n", data_all->if_index);
216 } else {
217 IPACMDBG_H("Posted event %d,\
218 with %s for ipv4\n",
219 evt_data.event,
220 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
221 }
222 break;
223 }
224 }
225 }
226 else
227 {
228 /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
229 if (event == IPA_NEW_NEIGH_EVENT)
230 {
231 evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
232 /* Also save to cache for ipv4 */
233 /*searh if seen this client or not*/
234 for (i = 0; i < num_neighbor_client_temp; i++)
235 {
236 /* find the client */
237 if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
238 {
239 /* update the network interface client associated */
240 neighbor_client[i].iface_index = data->if_index;
241 neighbor_client[i].ipa_if_num = ipa_interface_index;
242 neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
243 IPACMDBG_H("update cache %d-entry, with %s iface, ipv4 address: 0x%x\n",
244 i,
245 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
246 data->ipv4_addr);
247 break;
248 }
249 }
250 /* not find client */
251 if (i == num_neighbor_client_temp)
252 {
253 if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
254 {
255 memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
256 data->mac_addr,
257 sizeof(data->mac_addr));
258 neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
259 /* cache the network interface client associated */
260 neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
261 neighbor_client[num_neighbor_client_temp].v4_addr = data->ipv4_addr;
262 num_neighbor_client++;
263 IPACMDBG_H("Cache client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
264 neighbor_client[num_neighbor_client_temp].mac_addr[0],
265 neighbor_client[num_neighbor_client_temp].mac_addr[1],
266 neighbor_client[num_neighbor_client_temp].mac_addr[2],
267 neighbor_client[num_neighbor_client_temp].mac_addr[3],
268 neighbor_client[num_neighbor_client_temp].mac_addr[4],
269 neighbor_client[num_neighbor_client_temp].mac_addr[5],
270 num_neighbor_client);
271 }
272 else
273 {
274
275 IPACMERR("error: neighbor client oversize! recycle %d-st entry ! \n", circular_index);
276 memcpy(neighbor_client[circular_index].mac_addr,
277 data->mac_addr,
278 sizeof(data->mac_addr));
279 neighbor_client[circular_index].iface_index = data->if_index;
280 /* cache the network interface client associated */
281 neighbor_client[circular_index].ipa_if_num = ipa_interface_index;
282 neighbor_client[circular_index].v4_addr = 0;
283 IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d, circular %d\n",
284 neighbor_client[circular_index].mac_addr[0],
285 neighbor_client[circular_index].mac_addr[1],
286 neighbor_client[circular_index].mac_addr[2],
287 neighbor_client[circular_index].mac_addr[3],
288 neighbor_client[circular_index].mac_addr[4],
289 neighbor_client[circular_index].mac_addr[5],
290 num_neighbor_client,
291 circular_index);
292 circular_index++;
293 }
294 }
295 }
296 else
297 {
298 evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
299 /*searh if seen this client or not*/
300 for (i = 0; i < num_neighbor_client_temp; i++)
301 {
302 /* find the client */
303 if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
304 {
305 IPACMDBG_H("Clean %d-st Cached client-MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
306 i,
307 neighbor_client[i].mac_addr[0],
308 neighbor_client[i].mac_addr[1],
309 neighbor_client[i].mac_addr[2],
310 neighbor_client[i].mac_addr[3],
311 neighbor_client[i].mac_addr[4],
312 neighbor_client[i].mac_addr[5],
313 num_neighbor_client);
314
315 memset(neighbor_client[i].mac_addr, 0, sizeof(neighbor_client[i].mac_addr));
316 neighbor_client[i].iface_index = 0;
317 neighbor_client[i].v4_addr = 0;
318 neighbor_client[i].ipa_if_num = 0;
319 for (; i < num_neighbor_client_temp - 1; i++)
320 {
321 memcpy(neighbor_client[i].mac_addr,
322 neighbor_client[i+1].mac_addr,
323 sizeof(neighbor_client[i].mac_addr));
324 neighbor_client[i].iface_index = neighbor_client[i+1].iface_index;
325 neighbor_client[i].v4_addr = neighbor_client[i+1].v4_addr;
326 neighbor_client[i].ipa_if_num = neighbor_client[i+1].ipa_if_num;
327 }
328 num_neighbor_client--;
329 IPACMDBG_H(" total number of left cased clients: %d\n", num_neighbor_client);
330 break;
331 }
332 }
333 /* not find client, no need clean-up */
334 }
335
336 data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
337 if (data_all == NULL)
338 {
339 IPACMERR("Unable to allocate memory\n");
340 return;
341 }
342 memcpy(data_all, data, sizeof(ipacm_event_data_all));
343 evt_data.evt_data = (void *)data_all;
344 IPACM_EvtDispatcher::PostEvt(&evt_data);
345 IPACMDBG_H("Posted event %d with %s for ipv4\n",
346 evt_data.event,
347 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
348 }
349 }
350 }
351 else
352 { //ipv6 starts
353
354 if ((data->ipv6_addr[0]) || (data->ipv6_addr[1]) || (data->ipv6_addr[2]) || (data->ipv6_addr[3]))
355 {
356 IPACMDBG("Got New_Neighbor event with ipv6 address \n");
357 /* check if iface is bridge interface*/
358 if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
359 {
360 /* searh if seen this client or not*/
361 for (i = 0; i < num_neighbor_client_temp; i++)
362 {
363 if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
364 {
365 data->if_index = neighbor_client[i].iface_index;
366 /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
367 if (event == IPA_NEW_NEIGH_EVENT) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
368 else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
369 data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
370 if (data_all == NULL)
371 {
372 IPACMERR("Unable to allocate memory\n");
373 return;
374 }
375 memcpy(data_all, data, sizeof(ipacm_event_data_all));
376 evt_data.evt_data = (void *)data_all;
377 IPACM_EvtDispatcher::PostEvt(&evt_data);
378 /* ask for replaced iface name*/
379 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
380 /* check for failure return */
381 if (IPACM_FAILURE == ipa_interface_index) {
382 IPACMERR("not supported iface id: %d\n", data_all->if_index);
383 } else {
384 IPACMDBG_H("Posted event %d,\
385 with %s for ipv6\n",
386 evt_data.event,
387 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
388 }
389 break;
390 };
391 }
392 }
393 else
394 {
395 /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
396 if (event == IPA_NEW_NEIGH_EVENT)
397 evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
398 else
399 evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
400 data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
401 if (data_all == NULL)
402 {
403 IPACMERR("Unable to allocate memory\n");
404 return;
405 }
406 memcpy(data_all, data, sizeof(ipacm_event_data_all));
407 evt_data.evt_data = (void *)data_all;
408 IPACM_EvtDispatcher::PostEvt(&evt_data);
409 IPACMDBG_H("Posted event %d with %s for ipv6\n",
410 evt_data.event,
411 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
412 }
413 }
414 else
415 {
416 IPACMDBG(" Got Neighbor event with no ipv6/ipv4 address \n");
417 /*no ipv6 in data searh if seen this client or not*/
418 for (i = 0; i < num_neighbor_client_temp; i++)
419 {
420 /* find the client */
421 if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
422 {
423 IPACMDBG_H(" find %d-st client, MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
424 i,
425 neighbor_client[i].mac_addr[0],
426 neighbor_client[i].mac_addr[1],
427 neighbor_client[i].mac_addr[2],
428 neighbor_client[i].mac_addr[3],
429 neighbor_client[i].mac_addr[4],
430 neighbor_client[i].mac_addr[5],
431 num_neighbor_client);
432 /* check if iface is not bridge interface*/
433 if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
434 {
435 /* use previous ipv4 first */
436 if(data->if_index != neighbor_client[i].iface_index)
437 {
438 IPACMDBG_H("update new kernel iface index \n");
439 neighbor_client[i].iface_index = data->if_index;
440 }
441
442 /* check if client associated with previous network interface */
443 if(ipa_interface_index != neighbor_client[i].ipa_if_num)
444 {
445 IPACMDBG_H("client associate to different AP \n");
446 }
447
448 if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */
449 {
450 /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
451 if (event == IPA_NEW_NEIGH_EVENT)
452 evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
453 else
454 evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
455 data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
456 if (data_all == NULL)
457 {
458 IPACMERR("Unable to allocate memory\n");
459 return;
460 }
461 data_all->iptype = IPA_IP_v4;
462 data_all->if_index = neighbor_client[i].iface_index;
463 data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address
464 memcpy(data_all->mac_addr,
465 neighbor_client[i].mac_addr,
466 sizeof(data_all->mac_addr));
467 evt_data.evt_data = (void *)data_all;
468 IPACM_EvtDispatcher::PostEvt(&evt_data);
469 /* ask for replaced iface name*/
470 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
471 /* check for failure return */
472 if (IPACM_FAILURE == ipa_interface_index) {
473 IPACMERR("not supported iface id: %d\n", data_all->if_index);
474 } else {
475 IPACMDBG_H("Posted event %d,\
476 with %s for ipv4 client re-connect\n",
477 evt_data.event,
478 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
479 }
480 }
481 }
482 /* delete cache neighbor entry */
483 if (event == IPA_DEL_NEIGH_EVENT)
484 {
485 IPACMDBG_H("Clean %d-st Cached client-MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
486 i,
487 neighbor_client[i].mac_addr[0],
488 neighbor_client[i].mac_addr[1],
489 neighbor_client[i].mac_addr[2],
490 neighbor_client[i].mac_addr[3],
491 neighbor_client[i].mac_addr[4],
492 neighbor_client[i].mac_addr[5],
493 num_neighbor_client);
494
495 memset(neighbor_client[i].mac_addr, 0, sizeof(neighbor_client[i].mac_addr));
496 neighbor_client[i].iface_index = 0;
497 neighbor_client[i].v4_addr = 0;
498 neighbor_client[i].ipa_if_num = 0;
499 for (; i < num_neighbor_client_temp - 1; i++)
500 {
501 memcpy(neighbor_client[i].mac_addr,
502 neighbor_client[i+1].mac_addr,
503 sizeof(neighbor_client[i].mac_addr));
504 neighbor_client[i].iface_index = neighbor_client[i+1].iface_index;
505 neighbor_client[i].v4_addr = neighbor_client[i+1].v4_addr;
506 neighbor_client[i].ipa_if_num = neighbor_client[i+1].ipa_if_num;
507 }
508 num_neighbor_client--;
509 IPACMDBG_H(" total number of left cased clients: %d\n", num_neighbor_client);
510 }
511 break;
512 }
513 }
514 /* not find client */
515 if ((i == num_neighbor_client_temp) && (event == IPA_NEW_NEIGH_EVENT))
516 {
517 /* check if iface is not bridge interface*/
518 if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
519 {
520 if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
521 {
522 memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
523 data->mac_addr,
524 sizeof(data->mac_addr));
525 neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
526 /* cache the network interface client associated */
527 neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
528 neighbor_client[num_neighbor_client_temp].v4_addr = 0;
529 num_neighbor_client++;
530 IPACMDBG_H("Copy client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
531 neighbor_client[num_neighbor_client_temp].mac_addr[0],
532 neighbor_client[num_neighbor_client_temp].mac_addr[1],
533 neighbor_client[num_neighbor_client_temp].mac_addr[2],
534 neighbor_client[num_neighbor_client_temp].mac_addr[3],
535 neighbor_client[num_neighbor_client_temp].mac_addr[4],
536 neighbor_client[num_neighbor_client_temp].mac_addr[5],
537 num_neighbor_client);
538 return;
539 }
540 else
541 {
542 IPACMERR("error: neighbor client oversize! recycle %d-st entry ! \n", circular_index);
543 memcpy(neighbor_client[circular_index].mac_addr,
544 data->mac_addr,
545 sizeof(data->mac_addr));
546 neighbor_client[circular_index].iface_index = data->if_index;
547 /* cache the network interface client associated */
548 neighbor_client[circular_index].ipa_if_num = ipa_interface_index;
549 neighbor_client[circular_index].v4_addr = 0;
550 IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d, circular %d\n",
551 neighbor_client[circular_index].mac_addr[0],
552 neighbor_client[circular_index].mac_addr[1],
553 neighbor_client[circular_index].mac_addr[2],
554 neighbor_client[circular_index].mac_addr[3],
555 neighbor_client[circular_index].mac_addr[4],
556 neighbor_client[circular_index].mac_addr[5],
557 num_neighbor_client,
558 circular_index);
559 circular_index++;
560 return;
561 }
562 }
563 }
564 }
565 } //ipv6 ends
566 }
567 break;
568 }
569 return;
570 }
571