| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_arp.c,v 1.187 2015/10/13 12:33:07 roy Exp $ */ | | 1 | /* $NetBSD: if_arp.c,v 1.188 2015/10/14 11:17:57 roy Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Public Access Networks Corporation ("Panix"). It was developed under | | 8 | * by Public Access Networks Corporation ("Panix"). It was developed under |
9 | * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. | | 9 | * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -58,27 +58,27 @@ | | | @@ -58,27 +58,27 @@ |
58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
59 | * SUCH DAMAGE. | | 59 | * SUCH DAMAGE. |
60 | * | | 60 | * |
61 | * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 | | 61 | * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 |
62 | */ | | 62 | */ |
63 | | | 63 | |
64 | /* | | 64 | /* |
65 | * Ethernet address resolution protocol. | | 65 | * Ethernet address resolution protocol. |
66 | * TODO: | | 66 | * TODO: |
67 | * add "inuse/lock" bit (or ref. count) along with valid bit | | 67 | * add "inuse/lock" bit (or ref. count) along with valid bit |
68 | */ | | 68 | */ |
69 | | | 69 | |
70 | #include <sys/cdefs.h> | | 70 | #include <sys/cdefs.h> |
71 | __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.187 2015/10/13 12:33:07 roy Exp $"); | | 71 | __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.188 2015/10/14 11:17:57 roy Exp $"); |
72 | | | 72 | |
73 | #ifdef _KERNEL_OPT | | 73 | #ifdef _KERNEL_OPT |
74 | #include "opt_ddb.h" | | 74 | #include "opt_ddb.h" |
75 | #include "opt_inet.h" | | 75 | #include "opt_inet.h" |
76 | #endif | | 76 | #endif |
77 | | | 77 | |
78 | #ifdef INET | | 78 | #ifdef INET |
79 | | | 79 | |
80 | #include "bridge.h" | | 80 | #include "bridge.h" |
81 | | | 81 | |
82 | #include <sys/param.h> | | 82 | #include <sys/param.h> |
83 | #include <sys/systm.h> | | 83 | #include <sys/systm.h> |
84 | #include <sys/callout.h> | | 84 | #include <sys/callout.h> |
| @@ -305,26 +305,27 @@ arp_drainstub(void) | | | @@ -305,26 +305,27 @@ arp_drainstub(void) |
305 | */ | | 305 | */ |
306 | void | | 306 | void |
307 | arp_drain(void) | | 307 | arp_drain(void) |
308 | { | | 308 | { |
309 | | | 309 | |
310 | lltable_drain(AF_INET); | | 310 | lltable_drain(AF_INET); |
311 | } | | 311 | } |
312 | | | 312 | |
313 | static void | | 313 | static void |
314 | arptimer(void *arg) | | 314 | arptimer(void *arg) |
315 | { | | 315 | { |
316 | struct llentry *lle = arg; | | 316 | struct llentry *lle = arg; |
317 | struct ifnet *ifp; | | 317 | struct ifnet *ifp; |
| | | 318 | struct rtentry *rt; |
318 | | | 319 | |
319 | mutex_enter(softnet_lock); | | 320 | mutex_enter(softnet_lock); |
320 | | | 321 | |
321 | if (lle == NULL) | | 322 | if (lle == NULL) |
322 | goto out; | | 323 | goto out; |
323 | | | 324 | |
324 | if (lle->la_flags & LLE_STATIC) | | 325 | if (lle->la_flags & LLE_STATIC) |
325 | goto out; | | 326 | goto out; |
326 | | | 327 | |
327 | LLE_WLOCK(lle); | | 328 | LLE_WLOCK(lle); |
328 | if (callout_pending(&lle->la_timer)) { | | 329 | if (callout_pending(&lle->la_timer)) { |
329 | /* | | 330 | /* |
330 | * Here we are a bit odd here in the treatment of | | 331 | * Here we are a bit odd here in the treatment of |
| @@ -335,36 +336,37 @@ arptimer(void *arg) | | | @@ -335,36 +336,37 @@ arptimer(void *arg) |
335 | * it would have return 0 so the code would | | 336 | * it would have return 0 so the code would |
336 | * not have deleted it since the callout could | | 337 | * not have deleted it since the callout could |
337 | * not be stopped so we want to go through | | 338 | * not be stopped so we want to go through |
338 | * with the delete here now. If the callout | | 339 | * with the delete here now. If the callout |
339 | * was restarted, the pending bit will be back on and | | 340 | * was restarted, the pending bit will be back on and |
340 | * we just want to bail since the callout_reset would | | 341 | * we just want to bail since the callout_reset would |
341 | * return 1 and our reference would have been removed | | 342 | * return 1 and our reference would have been removed |
342 | * by arpresolve() below. | | 343 | * by arpresolve() below. |
343 | */ | | 344 | */ |
344 | LLE_WUNLOCK(lle); | | 345 | LLE_WUNLOCK(lle); |
345 | goto out; | | 346 | goto out; |
346 | } | | 347 | } |
347 | ifp = lle->lle_tbl->llt_ifp; | | 348 | ifp = lle->lle_tbl->llt_ifp; |
| | | 349 | rt = lle->la_rt; |
| | | 350 | lle->la_rt = NULL; |
348 | | | 351 | |
349 | callout_stop(&lle->la_timer); | | 352 | callout_stop(&lle->la_timer); |
350 | | | 353 | |
351 | /* XXX: LOR avoidance. We still have ref on lle. */ | | 354 | /* XXX: LOR avoidance. We still have ref on lle. */ |
352 | LLE_WUNLOCK(lle); | | 355 | LLE_WUNLOCK(lle); |
353 | | | 356 | |
354 | if (lle->la_rt != NULL) { | | 357 | if (rt != NULL) { |
355 | /* We have to call arptfree w/o IF_AFDATA_LOCK */ | | 358 | /* We have to call arptfree w/o IF_AFDATA_LOCK */ |
356 | arptfree(lle->la_rt); | | 359 | arptfree(rt); |
357 | lle->la_rt = NULL; | | | |
358 | } | | 360 | } |
359 | | | 361 | |
360 | IF_AFDATA_LOCK(ifp); | | 362 | IF_AFDATA_LOCK(ifp); |
361 | LLE_WLOCK(lle); | | 363 | LLE_WLOCK(lle); |
362 | | | 364 | |
363 | /* Guard against race with other llentry_free(). */ | | 365 | /* Guard against race with other llentry_free(). */ |
364 | if (lle->la_flags & LLE_LINKED) { | | 366 | if (lle->la_flags & LLE_LINKED) { |
365 | size_t pkts_dropped; | | 367 | size_t pkts_dropped; |
366 | | | 368 | |
367 | LLE_REMREF(lle); | | 369 | LLE_REMREF(lle); |
368 | pkts_dropped = llentry_free(lle); | | 370 | pkts_dropped = llentry_free(lle); |
369 | ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped); | | 371 | ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped); |
370 | } else { | | 372 | } else { |