summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>2004-10-03 00:49:33 +0000
committergreen <green@FreeBSD.org>2004-10-03 00:49:33 +0000
commitfb8e0f5c565014d25acf01392491739fb7bb3718 (patch)
tree8c0c7c0c477e29e87b7c4c10ce1d8e206342d888 /sys/netinet6
parentcb606898b9f83045c54ca6796b13313487916ac0 (diff)
downloadFreeBSD-src-fb8e0f5c565014d25acf01392491739fb7bb3718.zip
FreeBSD-src-fb8e0f5c565014d25acf01392491739fb7bb3718.tar.gz
Prevent reentrancy of the IPv6 routing code (leading to crash with
INVARIANTS on, who knows what with it off).
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/nd6.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 2461fc8..fef8855 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -104,6 +104,8 @@ struct nd_prhead nd_prefix = { 0 };
int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
static struct sockaddr_in6 all1_sa;
+static int nd6_is_new_addr_neighbor __P((struct sockaddr_in6 *,
+ struct ifnet *));
static void nd6_setmtu0 __P((struct ifnet *, struct nd_ifinfo *));
static void nd6_slowtimo __P((void *));
static int regen_tmpaddr __P((struct in6_ifaddr *));
@@ -869,11 +871,12 @@ nd6_lookup(addr6, create, ifp)
}
/*
- * Detect if a given IPv6 address identifies a neighbor on a given link.
- * XXX: should take care of the destination of a p2p link?
+ * Test whether a given IPv6 address is a neighbor or not, ignoring
+ * the actual neighbor cache. The neighbor cache is ignored in order
+ * to not reenter the routing code from within itself.
*/
-int
-nd6_is_addr_neighbor(addr, ifp)
+static int
+nd6_is_new_addr_neighbor(addr, ifp)
struct sockaddr_in6 *addr;
struct ifnet *ifp;
{
@@ -918,6 +921,23 @@ nd6_is_addr_neighbor(addr, ifp)
return (1);
}
+ return (0);
+}
+
+
+/*
+ * Detect if a given IPv6 address identifies a neighbor on a given link.
+ * XXX: should take care of the destination of a p2p link?
+ */
+int
+nd6_is_addr_neighbor(addr, ifp)
+ struct sockaddr_in6 *addr;
+ struct ifnet *ifp;
+{
+
+ if (nd6_is_new_addr_neighbor(addr, ifp))
+ return (1);
+
/*
* Even if the address matches none of our addresses, it might be
* in the neighbor cache.
@@ -1101,7 +1121,8 @@ nd6_rtrequest(req, rt, info)
if (req == RTM_RESOLVE &&
(nd6_need_cache(ifp) == 0 || /* stf case */
- !nd6_is_addr_neighbor((struct sockaddr_in6 *)rt_key(rt), ifp))) {
+ !nd6_is_new_addr_neighbor((struct sockaddr_in6 *)rt_key(rt),
+ ifp))) {
/*
* FreeBSD and BSD/OS often make a cloned host route based
* on a less-specific route (e.g. the default route).
OpenPOWER on IntegriCloud