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 ]''''''''''\
  <> [EMAIL PROTECTED]                               \  The Power to Serve! \
 Opinions expressed are my own.                       \,,,,,,,,,,,,,,,,,,,,,,\
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to