Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Dec 1997 02:06:38 +0100
From:      pb@fasterix.freenix.org (Pierre Beyssac)
To:        wollman@khavrinen.lcs.mit.edu (Garrett Wollman)
Cc:        pb@fasterix.freenix.org (Pierre Beyssac), tlambert@primenet.com (Terry Lambert), totii@est.is (?or?ur Ivarsson), freebsd-current@FreeBSD.ORG
Subject:   Re: panics when stopping pppd
Message-ID:  <19971215020638.WG24374@@>
In-Reply-To: <199712141929.OAA04089@khavrinen.lcs.mit.edu>; from Garrett Wollman on Dec 14, 1997 14:29:59 -0500
References:  <3492A8DE.27B270DB@est.is> <199712132150.OAA03369@usr06.primenet.com> <19971214024134.PL39369@@> <199712141929.OAA04089@khavrinen.lcs.mit.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
Garrett Wollman writes:
> Another thing that might be worth taking a look at... rn_walktree() is
> supposed to be written such that it is resilient to deletes happening
> in its callback.  But, I'm not sure if it can deal with the case of
> multiple records being deleted at once, particularly if one of those
> records turns out to be the place it was going next.

That's apparently a good idea since the fix I've made from that
seems to work :-)

Add to that that gated is trying to remove the routes itself at
the same time since that's its job...

I've made the following somewhat ugly patch. It just gets the
RTM_DELETE out of the tree walk, and recalls rn_walktree() until
there's no route found. in_ifadownkill() could probably be improved
by returning a fake non-zero error to prune the tree walk.

>From a few tries, it seems to correct the problem (not a single
panic yet in 3 tries, while it panic'ed every time before). I'm
still testing to make sure.

BTW, I don't know what arg.rnh is supposed to do since it's
apparently used nowhere.

If the problem is indeed rn_treewalk() having callbacks delete
nodes in his back, it looks like rtqkill() could cause problems
too.

--- in_rmx.c.orig	Sat Aug 23 02:48:53 1997
+++ in_rmx.c	Mon Dec 15 01:43:26 1997
@@ -368,6 +368,7 @@
 struct in_ifadown_arg {
 	struct radix_node_head *rnh;
 	struct ifaddr *ifa;
+	struct rtentry *rt;
 };
 
 static int
@@ -375,14 +376,9 @@
 {
 	struct in_ifadown_arg *ap = xap;
 	struct rtentry *rt = (struct rtentry *)rn;
-	int err;
 
 	if (rt->rt_ifa == ap->ifa && !(rt->rt_flags & RTF_STATIC)) {
-		err = rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt),
-				rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
-		if (err) {
-			log(LOG_WARNING, "in_ifadownkill: error %d\n", err);
-		}
+		if (ap->rt == NULL) ap->rt = rt;
 	}
 	return 0;
 }
@@ -392,13 +388,29 @@
 {
 	struct in_ifadown_arg arg;
 	struct radix_node_head *rnh;
+	int err;
 
 	if (ifa->ifa_addr->sa_family != AF_INET)
 		return 1;
 
 	arg.rnh = rnh = rt_tables[AF_INET];
 	arg.ifa = ifa;
-	rnh->rnh_walktree(rnh, in_ifadownkill, &arg);
+	do {
+		arg.rt = NULL;
+		rnh->rnh_walktree(rnh, in_ifadownkill, &arg);
+		if (arg.rt) {
+			err = rtrequest(RTM_DELETE,
+					(struct sockaddr *)rt_key(arg.rt),
+					arg.rt->rt_gateway,
+					rt_mask(arg.rt), arg.rt->rt_flags, 0);
+			if (err) {
+				log(LOG_WARNING,
+				    "in_ifadownkill: error %d\n", err);
+				break;
+			}
+		}
+	} while (arg.rt);
+
 	ifa->ifa_flags &= ~IFA_ROUTE;
 	return 0;
 }
-- 
Pierre Beyssac	      pb@fasterix.frmug.org pb@fasterix.freenix.org
{Free,Net,Open}BSD, Linux : il y a moins bien, mais c'est plus cher
    Free domains: http://www.eu.org/ or mail dns-manager@EU.org



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