81 lines
2 KiB
Diff
81 lines
2 KiB
Diff
--- sys/netinet/in.c.orig
|
|
+++ sys/netinet/in.c
|
|
@@ -1372,15 +1372,13 @@
|
|
IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
|
|
KASSERT(l3addr->sa_family == AF_INET,
|
|
("sin_family %d", l3addr->sa_family));
|
|
+ KASSERT((flags & (LLE_UNLOCKED | LLE_EXCLUSIVE)) !=
|
|
+ (LLE_UNLOCKED | LLE_EXCLUSIVE),
|
|
+ ("wrong lle request flags: %#x", flags));
|
|
+
|
|
lle = in_lltable_find_dst(llt, sin->sin_addr);
|
|
-
|
|
if (lle == NULL)
|
|
return (NULL);
|
|
-
|
|
- KASSERT((flags & (LLE_UNLOCKED|LLE_EXCLUSIVE)) !=
|
|
- (LLE_UNLOCKED|LLE_EXCLUSIVE),("wrong lle request flags: 0x%X",
|
|
- flags));
|
|
-
|
|
if (flags & LLE_UNLOCKED)
|
|
return (lle);
|
|
|
|
@@ -1389,6 +1387,17 @@
|
|
else
|
|
LLE_RLOCK(lle);
|
|
|
|
+ /*
|
|
+ * If the afdata lock is not held, the LLE may have been unlinked while
|
|
+ * we were blocked on the LLE lock. Check for this case.
|
|
+ */
|
|
+ if (__predict_false((lle->la_flags & LLE_LINKED) == 0)) {
|
|
+ if (flags & LLE_EXCLUSIVE)
|
|
+ LLE_WUNLOCK(lle);
|
|
+ else
|
|
+ LLE_RUNLOCK(lle);
|
|
+ return (NULL);
|
|
+ }
|
|
return (lle);
|
|
}
|
|
|
|
--- sys/netinet6/in6.c.orig
|
|
+++ sys/netinet6/in6.c
|
|
@@ -2311,16 +2311,13 @@
|
|
IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
|
|
KASSERT(l3addr->sa_family == AF_INET6,
|
|
("sin_family %d", l3addr->sa_family));
|
|
+ KASSERT((flags & (LLE_UNLOCKED | LLE_EXCLUSIVE)) !=
|
|
+ (LLE_UNLOCKED | LLE_EXCLUSIVE),
|
|
+ ("wrong lle request flags: %#x", flags));
|
|
|
|
lle = in6_lltable_find_dst(llt, &sin6->sin6_addr);
|
|
-
|
|
if (lle == NULL)
|
|
return (NULL);
|
|
-
|
|
- KASSERT((flags & (LLE_UNLOCKED|LLE_EXCLUSIVE)) !=
|
|
- (LLE_UNLOCKED|LLE_EXCLUSIVE),("wrong lle request flags: 0x%X",
|
|
- flags));
|
|
-
|
|
if (flags & LLE_UNLOCKED)
|
|
return (lle);
|
|
|
|
@@ -2328,6 +2325,18 @@
|
|
LLE_WLOCK(lle);
|
|
else
|
|
LLE_RLOCK(lle);
|
|
+
|
|
+ /*
|
|
+ * If the afdata lock is not held, the LLE may have been unlinked while
|
|
+ * we were blocked on the LLE lock. Check for this case.
|
|
+ */
|
|
+ if (__predict_false((lle->la_flags & LLE_LINKED) == 0)) {
|
|
+ if (flags & LLE_EXCLUSIVE)
|
|
+ LLE_WUNLOCK(lle);
|
|
+ else
|
|
+ LLE_RUNLOCK(lle);
|
|
+ return (NULL);
|
|
+ }
|
|
return (lle);
|
|
}
|
|
|