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

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
...@@ -342,13 +342,7 @@ static int ip_rcv_finish(struct sk_buff *skb) ...@@ -342,13 +342,7 @@ static int ip_rcv_finish(struct sk_buff *skb)
err = ip_route_input_noref(skb, iph->daddr, iph->saddr, err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
iph->tos, skb->dev); iph->tos, skb->dev);
if (unlikely(err)) { if (unlikely(err)) {
if (err == -EHOSTUNREACH) if (err == -EXDEV)
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)
NET_INC_STATS_BH(dev_net(skb->dev), NET_INC_STATS_BH(dev_net(skb->dev),
LINUX_MIB_IPRPFILTER); LINUX_MIB_IPRPFILTER);
goto drop; goto drop;
......
...@@ -1609,12 +1609,28 @@ void ip_rt_send_redirect(struct sk_buff *skb) ...@@ -1609,12 +1609,28 @@ void ip_rt_send_redirect(struct sk_buff *skb)
static int ip_error(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 rtable *rt = skb_rtable(skb);
struct inet_peer *peer; struct inet_peer *peer;
unsigned long now; unsigned long now;
struct net *net;
bool send; bool send;
int code; 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) { switch (rt->dst.error) {
case EINVAL: case EINVAL:
default: default:
...@@ -1624,8 +1640,7 @@ static int ip_error(struct sk_buff *skb) ...@@ -1624,8 +1640,7 @@ static int ip_error(struct sk_buff *skb)
break; break;
case ENETUNREACH: case ENETUNREACH:
code = ICMP_NET_UNREACH; code = ICMP_NET_UNREACH;
IP_INC_STATS_BH(dev_net(rt->dst.dev), IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES);
IPSTATS_MIB_INNOROUTES);
break; break;
case EACCES: case EACCES:
code = ICMP_PKT_FILTERED; code = ICMP_PKT_FILTERED;
...@@ -2255,11 +2270,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, ...@@ -2255,11 +2270,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
fl4.daddr = daddr; fl4.daddr = daddr;
fl4.saddr = saddr; fl4.saddr = saddr;
err = fib_lookup(net, &fl4, &res); err = fib_lookup(net, &fl4, &res);
if (err != 0) { if (err != 0)
if (!IN_DEV_FORWARD(in_dev))
goto e_hostunreach;
goto no_route; goto no_route;
}
RT_CACHE_STAT_INC(in_slow_tot); 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, ...@@ -2279,7 +2291,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
} }
if (!IN_DEV_FORWARD(in_dev)) if (!IN_DEV_FORWARD(in_dev))
goto e_hostunreach; goto no_route;
if (res.type != RTN_UNICAST) if (res.type != RTN_UNICAST)
goto martian_destination; goto martian_destination;
...@@ -2367,10 +2379,6 @@ out: return err; ...@@ -2367,10 +2379,6 @@ out: return err;
&daddr, &saddr, dev->name); &daddr, &saddr, dev->name);
#endif #endif
e_hostunreach:
err = -EHOSTUNREACH;
goto out;
e_inval: e_inval:
err = -EINVAL; err = -EINVAL;
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment