Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Sep 2004 22:09:57 -0400
From:      Brian Fundakowski Feldman <green@FreeBSD.org>
To:        net@FreeBSD.org
Subject:   IPv6 route mutex recursion (crash) and fix
Message-ID:  <20040922020957.GE84424@green.homeunix.org>

next in thread | raw e-mail | index | archive | help
I've already made noise about this before, so I'll be brief.  I plan on
committing the following fix that prevents the routing code from being
recursed upon such that RTM_RESOLVE causes the embryonic new route to
be looked up again.  I realize that probably no one will bother trying
to see this bug in action, but all you need to do is send some UDP6 to
ff02::1%<if> as a user, with INVARIANTS turned on.

Are there any objections?  It would be nice to have this in 5-STABLE,
in case anyone actually wants to have IPv6.

Index: nd6.c
===================================================================
RCS file: /usr/ncvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.43
diff -u -r1.43 nd6.c
--- nd6.c	26 Apr 2004 20:31:46 -0000	1.43
+++ nd6.c	21 Sep 2004 21:15:05 -0000
@@ -105,6 +105,8 @@
 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,11 @@
 }
 
 /*
- * 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.
  */
-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 +920,23 @@
 		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 +1120,8 @@
 
 	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).

-- 
Brian Fundakowski Feldman                           \'[ FreeBSD ]''''''''''\
  <> green@FreeBSD.org                               \  The Power to Serve! \
 Opinions expressed are my own.                       \,,,,,,,,,,,,,,,,,,,,,,\



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040922020957.GE84424>