diff options
Diffstat (limited to 'net/ipv4/route.c')
| -rw-r--r-- | net/ipv4/route.c | 18 | 
1 files changed, 12 insertions, 6 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 432f4bb7723..df251424d81 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1163,8 +1163,12 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,  	spin_lock_bh(&fnhe_lock);  	if (daddr == fnhe->fnhe_daddr) { -		struct rtable *orig; - +		struct rtable *orig = rcu_dereference(fnhe->fnhe_rth); +		if (orig && rt_is_expired(orig)) { +			fnhe->fnhe_gw = 0; +			fnhe->fnhe_pmtu = 0; +			fnhe->fnhe_expires = 0; +		}  		if (fnhe->fnhe_pmtu) {  			unsigned long expires = fnhe->fnhe_expires;  			unsigned long diff = expires - jiffies; @@ -1181,7 +1185,6 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,  		} else if (!rt->rt_gateway)  			rt->rt_gateway = daddr; -		orig = rcu_dereference(fnhe->fnhe_rth);  		rcu_assign_pointer(fnhe->fnhe_rth, rt);  		if (orig)  			rt_free(orig); @@ -1782,6 +1785,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,  	if (dev_out->flags & IFF_LOOPBACK)  		flags |= RTCF_LOCAL; +	do_cache = true;  	if (type == RTN_BROADCAST) {  		flags |= RTCF_BROADCAST | RTCF_LOCAL;  		fi = NULL; @@ -1790,6 +1794,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,  		if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr,  				     fl4->flowi4_proto))  			flags &= ~RTCF_LOCAL; +		else +			do_cache = false;  		/* If multicast route do not exist use  		 * default one, but do not gateway in this case.  		 * Yes, it is hack. @@ -1799,8 +1805,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,  	}  	fnhe = NULL; -	do_cache = fi != NULL; -	if (fi) { +	do_cache &= fi != NULL; +	if (do_cache) {  		struct rtable __rcu **prth;  		struct fib_nh *nh = &FIB_RES_NH(*res); @@ -2594,7 +2600,7 @@ int __init ip_rt_init(void)  		pr_err("Unable to create route proc files\n");  #ifdef CONFIG_XFRM  	xfrm_init(); -	xfrm4_init(ip_rt_max_size); +	xfrm4_init();  #endif  	rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL);  |