From owner-freebsd-net@FreeBSD.ORG Wed Sep 22 02:10:00 2004 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 030C016A4CE for ; Wed, 22 Sep 2004 02:10:00 +0000 (GMT) Received: from green.homeunix.org (pcp04368961pcs.nrockv01.md.comcast.net [69.140.212.7]) by mx1.FreeBSD.org (Postfix) with ESMTP id 37B4843D1D for ; Wed, 22 Sep 2004 02:09:59 +0000 (GMT) (envelope-from green@green.homeunix.org) Received: from green.homeunix.org (green@localhost [127.0.0.1]) by green.homeunix.org (8.13.1/8.13.1) with ESMTP id i8M29wVV069323 for ; Tue, 21 Sep 2004 22:09:58 -0400 (EDT) (envelope-from green@green.homeunix.org) Received: (from green@localhost) by green.homeunix.org (8.13.1/8.13.1/Submit) id i8M29v0s069322 for net@FreeBSD.org; Tue, 21 Sep 2004 22:09:57 -0400 (EDT) (envelope-from green) Date: Tue, 21 Sep 2004 22:09:57 -0400 From: Brian Fundakowski Feldman To: net@FreeBSD.org Message-ID: <20040922020957.GE84424@green.homeunix.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6i Subject: IPv6 route mutex recursion (crash) and fix X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Sep 2004 02:10:00 -0000 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% 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. \,,,,,,,,,,,,,,,,,,,,,,\