Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Jul 2001 11:01:58 +0300
From:      Ruslan Ermilov <ru@FreeBSD.org>
To:        JINMEI Tatuya <jinmei@isl.rdc.toshiba.co.jp>
Cc:        Garrett Wollman <wollman@FreeBSD.org>, net@FreeBSD.org
Subject:   Re: avoiding unnecessary route deletion in rt_fixchange()
Message-ID:  <20010718110158.A12171@sunbay.com>
In-Reply-To: <y7vvgkqenz6.wl@condor.jinmei.org>; from jinmei@isl.rdc.toshiba.co.jp on Wed, Jul 18, 2001 at 03:43:41PM %2B0900
References:  <y7vvgkqenz6.wl@condor.jinmei.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Yay, cool!  Unless Garrett commits this in a few days, I will
on Friday.  And yes, this fixes the "mysterious" problem when
gwroute was not allocated when adding the "default" route.

Thanks!

On Wed, Jul 18, 2001 at 03:43:41PM +0900, JINMEI Tatuya / ?$B?@L@C#:H?(B wrote:
> As commented in defined in sys/net/route.c, rt_fixchange() has a bad
> effect, which would cause unnecessary route deletion:
> 
>  * Unfortunately, this has the obnoxious
>  * property of also triggering for insertion /above/ a pre-existing network
>  * route and clones.  Sigh.  This may be fixed some day.
> 
> The effect has been even worse, because recent versions of route.c set
> the parent rtentry for cloned routes from an interface-direct route.
> For example, suppose that we have an interface "ne0" that has an IPv4
> subnet "10.0.0.0/24".  Then we may have a cloned route like 10.0.0.1
> on the interface, whose parent route is 10.0.0.0/24 (to the interface
> ne0).  Now, when we add the default route (i.e. 0.0.0.0/0),
> rt_fixchange() will remove the cloned route 10.0.0.1.  The (bad) effect
> also prevents rt_setgate from configuring rt_gwroute, which would not
> be an intended behavior.
> 
> As suggested in the comments to rt_fixchange(), we need stricter check
> in the function, to prevent unintentional route deletion.  The
> attached is a proposed fix to this problem (for FreeBSD4-STABLE).
> Please review it, and merge it to the repository if acceptable.
> 
> This fix will also solve the "IPV6 panic?" problem which was recently
> reported in this list.
> 
> Thanks,
> 
> 					JINMEI, Tatuya
> 					Communication Platform Lab.
> 					Corporate R&D Center, Toshiba Corp.
> 					jinmei@isl.rdc.toshiba.co.jp
> 
> *** route.c.orig	Wed Jul 18 15:13:18 2001
> --- route.c	Wed Jul 18 15:18:15 2001
> ***************
> *** 726,734 ****
>    * network route and (cloned) host routes.  For this reason, a simple check
>    * of rt->rt_parent is insufficient; each candidate route must be tested
>    * against the (mask, value) of the new route (passed as before in vp)
> !  * to see if the new route matches it.  Unfortunately, this has the obnoxious
> !  * property of also triggering for insertion /above/ a pre-existing network
> !  * route and clones.  Sigh.  This may be fixed some day.
>    *
>    * XXX - it may be possible to do fixdelete() for changes and reserve this
>    * routine just for adds.  I'm not sure why I thought it was necessary to do
> --- 726,732 ----
>    * network route and (cloned) host routes.  For this reason, a simple check
>    * of rt->rt_parent is insufficient; each candidate route must be tested
>    * against the (mask, value) of the new route (passed as before in vp)
> !  * to see if the new route matches it.
>    *
>    * XXX - it may be possible to do fixdelete() for changes and reserve this
>    * routine just for adds.  I'm not sure why I thought it was necessary to do
> ***************
> *** 747,754 ****
>   	struct rtfc_arg *ap = vp;
>   	struct rtentry *rt0 = ap->rt0;
>   	struct radix_node_head *rnh = ap->rnh;
> ! 	u_char *xk1, *xm1, *xk2;
> ! 	int i, len;
>   
>   #ifdef DEBUG
>   	if (rtfcdebug)
> --- 745,752 ----
>   	struct rtfc_arg *ap = vp;
>   	struct rtentry *rt0 = ap->rt0;
>   	struct radix_node_head *rnh = ap->rnh;
> ! 	u_char *xk1, *xm1, *xk2, *xmp;
> ! 	int i, len, mlen;
>   
>   #ifdef DEBUG
>   	if (rtfcdebug)
> ***************
> *** 781,786 ****
> --- 779,806 ----
>   	xk1 = (u_char *)rt_key(rt0);
>   	xm1 = (u_char *)rt_mask(rt0);
>   	xk2 = (u_char *)rt_key(rt);
> + 
> + 	/* avoid applying a less specific route */
> + 	xmp = (u_char *)rt_mask(rt->rt_parent);
> + 	mlen = ((struct sockaddr *)rt_key(rt->rt_parent))->sa_len;
> + 	if (mlen > ((struct sockaddr *)rt_key(rt0))->sa_len) {
> + #ifdef DEBUG
> + 		if (rtfcdebug)
> + 			printf("rt_fixchange: inserting a less "
> + 			       "specific route\n");
> + #endif
> + 		return 0;
> + 	}
> + 	for (i = rnh->rnh_treetop->rn_offset; i < mlen; i++) {
> + 		if ((xmp[i] & ~(xmp[i] ^ xm1[i])) != xmp[i]) {
> + #ifdef DEBUG
> + 			if (rtfcdebug)
> + 				printf("rt_fixchange: inserting a less "
> + 				       "specific route\n");
> + #endif
> + 			return 0;
> + 		}
> + 	}
>   
>   	for (i = rnh->rnh_treetop->rn_offset; i < len; i++) {
>   		if ((xk2[i] & xm1[i]) != xk1[i]) {

-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




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