Skip to content

Commit

Permalink
ipv4: Cache ip_error() routes even when not forwarding.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
davem330 committed Jun 26, 2012
1 parent df67e6c commit 251da41
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 18 deletions.
8 changes: 1 addition & 7 deletions net/ipv4/ip_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
30 changes: 19 additions & 11 deletions net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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;

Expand Down Expand Up @@ -2367,10 +2379,6 @@ out: return err;
&daddr, &saddr, dev->name);
#endif

e_hostunreach:
err = -EHOSTUNREACH;
goto out;

e_inval:
err = -EINVAL;
goto out;
Expand Down

0 comments on commit 251da41

Please sign in to comment.