--- v2.4.7/linux/net/ipv4/fib_frontend.c Sat Jul 7 12:20:10 2001 +++ linux/net/ipv4/fib_frontend.c Thu Jul 26 22:12:24 2001 @@ -613,9 +613,7 @@ for_ifa(in_dev) { fib_add_ifaddr(ifa); } endfor_ifa(in_dev); -#ifdef CONFIG_IP_ROUTE_MULTIPATH fib_sync_up(dev); -#endif rt_cache_flush(-1); break; case NETDEV_DOWN: --- v2.4.7/linux/net/ipv4/fib_semantics.c Tue Oct 17 20:43:14 2000 +++ linux/net/ipv4/fib_semantics.c Fri Jul 27 01:23:24 2001 @@ -581,6 +581,10 @@ #ifdef CONFIG_IP_ROUTE_NAT case RTN_NAT: FIB_RES_RESET(*res); + if (FIB_RES_NH(*res).nh_flags & RTNH_F_DEAD) { + res->fi = NULL; + return 1; + } atomic_inc(&fi->fib_clntref); return 0; #endif @@ -867,16 +871,28 @@ int dead = 0; change_nexthops(fi) { - if (nh->nh_flags&RTNH_F_DEAD) - dead++; - else if (nh->nh_dev == dev && + if (nh->nh_flags&RTNH_F_DEAD) { + if (fi->fib_protocol!=RTPROT_STATIC || + nh->nh_dev == NULL || + !__in_dev_get(nh->nh_dev) || + nh->nh_dev->flags&IFF_UP) + dead++; + } else if (nh->nh_dev == dev && nh->nh_scope != scope) { nh->nh_flags |= RTNH_F_DEAD; #ifdef CONFIG_IP_ROUTE_MULTIPATH fi->fib_power -= nh->nh_power; nh->nh_power = 0; #endif - dead++; + if (fi->fib_protocol!=RTPROT_STATIC || + force || + __in_dev_get(dev) == NULL) + dead++; + } + if (nh->nh_flags&RTNH_F_DEAD && force && + nh->nh_dev == dev) { + dev_put(nh->nh_dev); + nh->nh_dev = NULL; } } endfor_nexthops(fi) if (dead == fi->fib_nhs) { @@ -888,11 +904,8 @@ return ret; } -#ifdef CONFIG_IP_ROUTE_MULTIPATH - /* Dead device goes up. We wake up dead nexthops. - It takes sense only on multipath routes. */ int fib_sync_up(struct net_device *dev) @@ -906,10 +919,8 @@ int alive = 0; change_nexthops(fi) { - if (!(nh->nh_flags&RTNH_F_DEAD)) { - alive++; + if (!(nh->nh_flags&RTNH_F_DEAD)) continue; - } if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP)) continue; if (nh->nh_dev != dev || __in_dev_get(dev) == NULL) @@ -926,6 +937,8 @@ } endfor_fib_info(); return ret; } + +#ifdef CONFIG_IP_ROUTE_MULTIPATH /* The algorithm is suboptimal, but it provides really