IPv6 route mutex recursion (crash) and fix

From: Brian Fundakowski Feldman (green_at_FreeBSD.org)
Date: 09/22/04

  • Next message: George V. Neville-Neil: "Re: IPv6 route mutex recursion (crash) and fix"
    Date: Tue, 21 Sep 2004 22:09:57 -0400
    To: net@FreeBSD.org
    
    

    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.                       \,,,,,,,,,,,,,,,,,,,,,,\
    _______________________________________________
    freebsd-net@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-net
    To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"
    

  • Next message: George V. Neville-Neil: "Re: IPv6 route mutex recursion (crash) and fix"