aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-06-26 19:27:09 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-26 19:27:09 -0400
commit251da4130115b29403a57096fa0988249f31fc55 (patch)
tree8bc64a855cc330048989d30c0082c838e70a9d29 /net/ipv4/route.c
parentdf67e6c9a6ca59ca96bdd46a500ae9dd596f427c (diff)
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>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 846961c6cbe..81533e3a23d 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1609,12 +1609,28 @@ void ip_rt_send_redirect(struct sk_buff *skb)
1609 1609
1610static int ip_error(struct sk_buff *skb) 1610static int ip_error(struct sk_buff *skb)
1611{ 1611{
1612 struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
1612 struct rtable *rt = skb_rtable(skb); 1613 struct rtable *rt = skb_rtable(skb);
1613 struct inet_peer *peer; 1614 struct inet_peer *peer;
1614 unsigned long now; 1615 unsigned long now;
1616 struct net *net;
1615 bool send; 1617 bool send;
1616 int code; 1618 int code;
1617 1619
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
1618 switch (rt->dst.error) { 1634 switch (rt->dst.error) {
1619 case EINVAL: 1635 case EINVAL:
1620 default: 1636 default:
@@ -1624,8 +1640,7 @@ static int ip_error(struct sk_buff *skb)
1624 break; 1640 break;
1625 case ENETUNREACH: 1641 case ENETUNREACH:
1626 code = ICMP_NET_UNREACH; 1642 code = ICMP_NET_UNREACH;
1627 IP_INC_STATS_BH(dev_net(rt->dst.dev), 1643 IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES);
1628 IPSTATS_MIB_INNOROUTES);
1629 break; 1644 break;
1630 case EACCES: 1645 case EACCES:
1631 code = ICMP_PKT_FILTERED; 1646 code = ICMP_PKT_FILTERED;
@@ -2255,11 +2270,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
2255 fl4.daddr = daddr; 2270 fl4.daddr = daddr;
2256 fl4.saddr = saddr; 2271 fl4.saddr = saddr;
2257 err = fib_lookup(net, &fl4, &res); 2272 err = fib_lookup(net, &fl4, &res);
2258 if (err != 0) { 2273 if (err != 0)
2259 if (!IN_DEV_FORWARD(in_dev))
2260 goto e_hostunreach;
2261 goto no_route; 2274 goto no_route;
2262 }
2263 2275
2264 RT_CACHE_STAT_INC(in_slow_tot); 2276 RT_CACHE_STAT_INC(in_slow_tot);
2265 2277
@@ -2279,7 +2291,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
2279 } 2291 }
2280 2292
2281 if (!IN_DEV_FORWARD(in_dev)) 2293 if (!IN_DEV_FORWARD(in_dev))
2282 goto e_hostunreach; 2294 goto no_route;
2283 if (res.type != RTN_UNICAST) 2295 if (res.type != RTN_UNICAST)
2284 goto martian_destination; 2296 goto martian_destination;
2285 2297
@@ -2367,10 +2379,6 @@ martian_destination:
2367 &daddr, &saddr, dev->name); 2379 &daddr, &saddr, dev->name);
2368#endif 2380#endif
2369 2381
2370e_hostunreach:
2371 err = -EHOSTUNREACH;
2372 goto out;
2373
2374e_inval: 2382e_inval:
2375 err = -EINVAL; 2383 err = -EINVAL;
2376 goto out; 2384 goto out;