IPv6 route mutex recursion (crash) and fix
Brian Fundakowski Feldman
green at FreeBSD.org
Tue Sep 21 19:10:00 PDT 2004
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 at FreeBSD.org \ The Power to Serve! \
Opinions expressed are my own. \,,,,,,,,,,,,,,,,,,,,,,\
More information about the freebsd-net
mailing list