diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-21 09:39:55 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:40 +0200 |
commit | 2df56dbd60bb5d925d2ce0ddbdefdbe6107ea783 (patch) | |
tree | bd7bad558534db4a1f400bc38a2c9aa7ea4f411e /freebsd/sys/netinet6/nd6_nbr.c | |
parent | Update to FreeBSD head 2018-02-01 (diff) | |
download | rtems-libbsd-2df56dbd60bb5d925d2ce0ddbdefdbe6107ea783.tar.bz2 |
Update to FreeBSD head 2018-04-01
Git mirror commit 8dfb1ccc26d1cea7e2529303003ff61f9f1784c4.
Update #3472.
Diffstat (limited to 'freebsd/sys/netinet6/nd6_nbr.c')
-rw-r--r-- | freebsd/sys/netinet6/nd6_nbr.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c index 0c875324..e5b37877 100644 --- a/freebsd/sys/netinet6/nd6_nbr.c +++ b/freebsd/sys/netinet6/nd6_nbr.c @@ -1099,7 +1099,6 @@ nd6_ifptomac(struct ifnet *ifp) case IFT_L2VLAN: case IFT_INFINIBAND: case IFT_BRIDGE: - case IFT_ISO88025: return IF_LLADDR(ifp); default: return NULL; @@ -1122,6 +1121,7 @@ struct dadq { #define ND_OPT_NONCE_LEN32 \ ((ND_OPT_NONCE_LEN + sizeof(uint32_t) - 1)/sizeof(uint32_t)) uint32_t dad_nonce[ND_OPT_NONCE_LEN32]; + bool dad_ondadq; /* on dadq? Protected by DADQ_WLOCK. */ }; static VNET_DEFINE(TAILQ_HEAD(, dadq), dadq); @@ -1140,6 +1140,7 @@ nd6_dad_add(struct dadq *dp) DADQ_WLOCK(); TAILQ_INSERT_TAIL(&V_dadq, dp, dad_list); + dp->dad_ondadq = true; DADQ_WUNLOCK(); } @@ -1148,9 +1149,17 @@ nd6_dad_del(struct dadq *dp) { DADQ_WLOCK(); - TAILQ_REMOVE(&V_dadq, dp, dad_list); - DADQ_WUNLOCK(); - nd6_dad_rele(dp); + if (dp->dad_ondadq) { + /* + * Remove dp from the dadq and release the dadq's + * reference. + */ + TAILQ_REMOVE(&V_dadq, dp, dad_list); + dp->dad_ondadq = false; + DADQ_WUNLOCK(); + nd6_dad_rele(dp); + } else + DADQ_WUNLOCK(); } static struct dadq * @@ -1283,6 +1292,8 @@ nd6_dad_start(struct ifaddr *ifa, int delay) dp->dad_ns_icount = dp->dad_na_icount = 0; dp->dad_ns_ocount = dp->dad_ns_tcount = 0; dp->dad_ns_lcount = dp->dad_loopbackprobe = 0; + + /* Add this to the dadq and add a reference for the dadq. */ refcount_init(&dp->dad_refcnt, 1); nd6_dad_add(dp); nd6_dad_starttimer(dp, delay, 0); @@ -1303,17 +1314,9 @@ nd6_dad_stop(struct ifaddr *ifa) } nd6_dad_stoptimer(dp); - - /* - * The DAD queue entry may have been removed by nd6_dad_timer() while - * we were waiting for it to stop, so re-do the lookup. - */ - nd6_dad_rele(dp); - dp = nd6_dad_find(ifa, NULL); - if (dp == NULL) - return; - nd6_dad_del(dp); + + /* Release this function's reference, acquired by nd6_dad_find(). */ nd6_dad_rele(dp); } |