diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-06-02 08:05:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-03 06:18:19 -0400 |
commit | b5f7e7554753e2cc3ef3bef0271fdb32027df2ba (patch) | |
tree | e7908b1ccf1cfef6bdeb7cac4c83f6d2ad2be54e /net/ipv4/route.c | |
parent | 8cbccbe76168a0c627d2274e4a322116804db30f (diff) |
ipv4: add LINUX_MIB_IPRPFILTER snmp counter
Christoph Lameter mentioned that packets could be dropped in input path
because of rp_filter settings, without any SNMP counter being
incremented. System administrator can have a hard time to track the
problem.
This patch introduces a new counter, LINUX_MIB_IPRPFILTER, incremented
each time we drop a packet because Reverse Path Filter triggers.
(We receive an IPv4 datagram on a given interface, and find the route to
send an answer would use another interface)
netstat -s | grep IPReversePathFilter
IPReversePathFilter: 21714
Reported-by: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 8495bceec764..d377b45005fc 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1851,6 +1851,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1851 | __be32 spec_dst; | 1851 | __be32 spec_dst; |
1852 | struct in_device *in_dev = in_dev_get(dev); | 1852 | struct in_device *in_dev = in_dev_get(dev); |
1853 | u32 itag = 0; | 1853 | u32 itag = 0; |
1854 | int err; | ||
1854 | 1855 | ||
1855 | /* Primary sanity checks. */ | 1856 | /* Primary sanity checks. */ |
1856 | 1857 | ||
@@ -1865,10 +1866,12 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1865 | if (!ipv4_is_local_multicast(daddr)) | 1866 | if (!ipv4_is_local_multicast(daddr)) |
1866 | goto e_inval; | 1867 | goto e_inval; |
1867 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); | 1868 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); |
1868 | } else if (fib_validate_source(saddr, 0, tos, 0, | 1869 | } else { |
1869 | dev, &spec_dst, &itag, 0) < 0) | 1870 | err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, |
1870 | goto e_inval; | 1871 | &itag, 0); |
1871 | 1872 | if (err < 0) | |
1873 | goto e_err; | ||
1874 | } | ||
1872 | rth = dst_alloc(&ipv4_dst_ops); | 1875 | rth = dst_alloc(&ipv4_dst_ops); |
1873 | if (!rth) | 1876 | if (!rth) |
1874 | goto e_nobufs; | 1877 | goto e_nobufs; |
@@ -1920,8 +1923,10 @@ e_nobufs: | |||
1920 | return -ENOBUFS; | 1923 | return -ENOBUFS; |
1921 | 1924 | ||
1922 | e_inval: | 1925 | e_inval: |
1926 | err = -EINVAL; | ||
1927 | e_err: | ||
1923 | in_dev_put(in_dev); | 1928 | in_dev_put(in_dev); |
1924 | return -EINVAL; | 1929 | return err; |
1925 | } | 1930 | } |
1926 | 1931 | ||
1927 | 1932 | ||
@@ -1985,7 +1990,6 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1985 | ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, | 1990 | ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, |
1986 | saddr); | 1991 | saddr); |
1987 | 1992 | ||
1988 | err = -EINVAL; | ||
1989 | goto cleanup; | 1993 | goto cleanup; |
1990 | } | 1994 | } |
1991 | 1995 | ||
@@ -2157,13 +2161,12 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2157 | goto brd_input; | 2161 | goto brd_input; |
2158 | 2162 | ||
2159 | if (res.type == RTN_LOCAL) { | 2163 | if (res.type == RTN_LOCAL) { |
2160 | int result; | 2164 | err = fib_validate_source(saddr, daddr, tos, |
2161 | result = fib_validate_source(saddr, daddr, tos, | ||
2162 | net->loopback_dev->ifindex, | 2165 | net->loopback_dev->ifindex, |
2163 | dev, &spec_dst, &itag, skb->mark); | 2166 | dev, &spec_dst, &itag, skb->mark); |
2164 | if (result < 0) | 2167 | if (err < 0) |
2165 | goto martian_source; | 2168 | goto martian_source_keep_err; |
2166 | if (result) | 2169 | if (err) |
2167 | flags |= RTCF_DIRECTSRC; | 2170 | flags |= RTCF_DIRECTSRC; |
2168 | spec_dst = daddr; | 2171 | spec_dst = daddr; |
2169 | goto local_input; | 2172 | goto local_input; |
@@ -2191,7 +2194,7 @@ brd_input: | |||
2191 | err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, | 2194 | err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, |
2192 | &itag, skb->mark); | 2195 | &itag, skb->mark); |
2193 | if (err < 0) | 2196 | if (err < 0) |
2194 | goto martian_source; | 2197 | goto martian_source_keep_err; |
2195 | if (err) | 2198 | if (err) |
2196 | flags |= RTCF_DIRECTSRC; | 2199 | flags |= RTCF_DIRECTSRC; |
2197 | } | 2200 | } |
@@ -2272,8 +2275,10 @@ e_nobufs: | |||
2272 | goto done; | 2275 | goto done; |
2273 | 2276 | ||
2274 | martian_source: | 2277 | martian_source: |
2278 | err = -EINVAL; | ||
2279 | martian_source_keep_err: | ||
2275 | ip_handle_martian_source(dev, in_dev, skb, daddr, saddr); | 2280 | ip_handle_martian_source(dev, in_dev, skb, daddr, saddr); |
2276 | goto e_inval; | 2281 | goto done; |
2277 | } | 2282 | } |
2278 | 2283 | ||
2279 | int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, | 2284 | int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, |