Skip to content

Commit 251da41

Browse files
committed
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>
1 parent df67e6c commit 251da41

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

net/ipv4/ip_input.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,13 +342,7 @@ static int ip_rcv_finish(struct sk_buff *skb)
342342
err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
343343
iph->tos, skb->dev);
344344
if (unlikely(err)) {
345-
if (err == -EHOSTUNREACH)
346-
IP_INC_STATS_BH(dev_net(skb->dev),
347-
IPSTATS_MIB_INADDRERRORS);
348-
else if (err == -ENETUNREACH)
349-
IP_INC_STATS_BH(dev_net(skb->dev),
350-
IPSTATS_MIB_INNOROUTES);
351-
else if (err == -EXDEV)
345+
if (err == -EXDEV)
352346
NET_INC_STATS_BH(dev_net(skb->dev),
353347
LINUX_MIB_IPRPFILTER);
354348
goto drop;

net/ipv4/route.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,12 +1609,28 @@ void ip_rt_send_redirect(struct sk_buff *skb)
16091609

16101610
static int ip_error(struct sk_buff *skb)
16111611
{
1612+
struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
16121613
struct rtable *rt = skb_rtable(skb);
16131614
struct inet_peer *peer;
16141615
unsigned long now;
1616+
struct net *net;
16151617
bool send;
16161618
int code;
16171619

1620+
net = dev_net(rt->dst.dev);
1621+
if (!IN_DEV_FORWARD(in_dev)) {
1622+
switch (rt->dst.error) {
1623+
case EHOSTUNREACH:
1624+
IP_INC_STATS_BH(net, IPSTATS_MIB_INADDRERRORS);
1625+
break;
1626+
1627+
case ENETUNREACH:
1628+
IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES);
1629+
break;
1630+
}
1631+
goto out;
1632+
}
1633+
16181634
switch (rt->dst.error) {
16191635
case EINVAL:
16201636
default:
@@ -1624,8 +1640,7 @@ static int ip_error(struct sk_buff *skb)
16241640
break;
16251641
case ENETUNREACH:
16261642
code = ICMP_NET_UNREACH;
1627-
IP_INC_STATS_BH(dev_net(rt->dst.dev),
1628-
IPSTATS_MIB_INNOROUTES);
1643+
IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES);
16291644
break;
16301645
case EACCES:
16311646
code = ICMP_PKT_FILTERED;
@@ -2255,11 +2270,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
22552270
fl4.daddr = daddr;
22562271
fl4.saddr = saddr;
22572272
err = fib_lookup(net, &fl4, &res);
2258-
if (err != 0) {
2259-
if (!IN_DEV_FORWARD(in_dev))
2260-
goto e_hostunreach;
2273+
if (err != 0)
22612274
goto no_route;
2262-
}
22632275

22642276
RT_CACHE_STAT_INC(in_slow_tot);
22652277

@@ -2279,7 +2291,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
22792291
}
22802292

22812293
if (!IN_DEV_FORWARD(in_dev))
2282-
goto e_hostunreach;
2294+
goto no_route;
22832295
if (res.type != RTN_UNICAST)
22842296
goto martian_destination;
22852297

@@ -2367,10 +2379,6 @@ out: return err;
23672379
&daddr, &saddr, dev->name);
23682380
#endif
23692381

2370-
e_hostunreach:
2371-
err = -EHOSTUNREACH;
2372-
goto out;
2373-
23742382
e_inval:
23752383
err = -EINVAL;
23762384
goto out;

0 commit comments

Comments
 (0)