summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet6/nd6_nbr.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-21 09:39:55 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:40 +0200
commit2df56dbd60bb5d925d2ce0ddbdefdbe6107ea783 (patch)
treebd7bad558534db4a1f400bc38a2c9aa7ea4f411e /freebsd/sys/netinet6/nd6_nbr.c
parentUpdate to FreeBSD head 2018-02-01 (diff)
downloadrtems-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.c31
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);
}