forked from mirrors/linux
		
	ipv4: Cache ip_error() routes even when not forwarding.
And account for the fact that, when we are not forwarding, we should bump statistic counters rather than emit an ICMP response. RP-filter rejected lookups are still not cached. Since -EHOSTUNREACH and -ENETUNREACH can now no longer be seen in ip_rcv_finish(), remove those checks. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									df67e6c9a6
								
							
						
					
					
						commit
						251da41301
					
				
					 2 changed files with 20 additions and 18 deletions
				
			
		|  | @ -342,13 +342,7 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
| 			err = ip_route_input_noref(skb, iph->daddr, iph->saddr, | ||||
| 						   iph->tos, skb->dev); | ||||
| 			if (unlikely(err)) { | ||||
| 				if (err == -EHOSTUNREACH) | ||||
| 					IP_INC_STATS_BH(dev_net(skb->dev), | ||||
| 							IPSTATS_MIB_INADDRERRORS); | ||||
| 				else if (err == -ENETUNREACH) | ||||
| 					IP_INC_STATS_BH(dev_net(skb->dev), | ||||
| 							IPSTATS_MIB_INNOROUTES); | ||||
| 				else if (err == -EXDEV) | ||||
| 				if (err == -EXDEV) | ||||
| 					NET_INC_STATS_BH(dev_net(skb->dev), | ||||
| 							 LINUX_MIB_IPRPFILTER); | ||||
| 				goto drop; | ||||
|  |  | |||
|  | @ -1609,12 +1609,28 @@ void ip_rt_send_redirect(struct sk_buff *skb) | |||
| 
 | ||||
| static int ip_error(struct sk_buff *skb) | ||||
| { | ||||
| 	struct in_device *in_dev = __in_dev_get_rcu(skb->dev); | ||||
| 	struct rtable *rt = skb_rtable(skb); | ||||
| 	struct inet_peer *peer; | ||||
| 	unsigned long now; | ||||
| 	struct net *net; | ||||
| 	bool send; | ||||
| 	int code; | ||||
| 
 | ||||
| 	net = dev_net(rt->dst.dev); | ||||
| 	if (!IN_DEV_FORWARD(in_dev)) { | ||||
| 		switch (rt->dst.error) { | ||||
| 		case EHOSTUNREACH: | ||||
| 			IP_INC_STATS_BH(net, IPSTATS_MIB_INADDRERRORS); | ||||
| 			break; | ||||
| 
 | ||||
| 		case ENETUNREACH: | ||||
| 			IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES); | ||||
| 			break; | ||||
| 		} | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	switch (rt->dst.error) { | ||||
| 	case EINVAL: | ||||
| 	default: | ||||
|  | @ -1624,8 +1640,7 @@ static int ip_error(struct sk_buff *skb) | |||
| 		break; | ||||
| 	case ENETUNREACH: | ||||
| 		code = ICMP_NET_UNREACH; | ||||
| 		IP_INC_STATS_BH(dev_net(rt->dst.dev), | ||||
| 				IPSTATS_MIB_INNOROUTES); | ||||
| 		IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES); | ||||
| 		break; | ||||
| 	case EACCES: | ||||
| 		code = ICMP_PKT_FILTERED; | ||||
|  | @ -2255,11 +2270,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 	fl4.daddr = daddr; | ||||
| 	fl4.saddr = saddr; | ||||
| 	err = fib_lookup(net, &fl4, &res); | ||||
| 	if (err != 0) { | ||||
| 		if (!IN_DEV_FORWARD(in_dev)) | ||||
| 			goto e_hostunreach; | ||||
| 	if (err != 0) | ||||
| 		goto no_route; | ||||
| 	} | ||||
| 
 | ||||
| 	RT_CACHE_STAT_INC(in_slow_tot); | ||||
| 
 | ||||
|  | @ -2279,7 +2291,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 	} | ||||
| 
 | ||||
| 	if (!IN_DEV_FORWARD(in_dev)) | ||||
| 		goto e_hostunreach; | ||||
| 		goto no_route; | ||||
| 	if (res.type != RTN_UNICAST) | ||||
| 		goto martian_destination; | ||||
| 
 | ||||
|  | @ -2367,10 +2379,6 @@ out:	return err; | |||
| 				     &daddr, &saddr, dev->name); | ||||
| #endif | ||||
| 
 | ||||
| e_hostunreach: | ||||
| 	err = -EHOSTUNREACH; | ||||
| 	goto out; | ||||
| 
 | ||||
| e_inval: | ||||
| 	err = -EINVAL; | ||||
| 	goto out; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 David S. Miller
						David S. Miller