mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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