Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 251da413 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parent df67e6c9
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -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;
+19 −11
Original line number Diff line number Diff line
@@ -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;