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