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