Hi,

Applied.  I'll let you (and the list) know if I have any issues.

Thanks,

skd

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.
>                                       [EMAIL PROTECTED]
> 
> *** 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]) {
> 
> To Unsubscribe: send mail to [EMAIL PROTECTED]
> with "unsubscribe freebsd-net" in the body of the message

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-net" in the body of the message

Reply via email to