summaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_frontend.c
diff options
context:
space:
mode:
authorMichael Smith <msmith@cbnco.com>2011-04-07 04:51:51 +0000
committerDavid S. Miller <davem@davemloft.net>2011-04-10 18:50:59 -0700
commit990078afbf90e0175e71da2df04595b99153514c (patch)
treeff61e3ab53f46ceca2ef280788982883b50cc669 /net/ipv4/fib_frontend.c
parent5c04c819a20af40adb7d282199f4e34e14fa05c5 (diff)
downloadlinux-990078afbf90e0175e71da2df04595b99153514c.tar.gz
linux-990078afbf90e0175e71da2df04595b99153514c.tar.bz2
linux-990078afbf90e0175e71da2df04595b99153514c.zip
Disable rp_filter for IPsec packets
The reverse path filter interferes with IPsec subnet-to-subnet tunnels, especially when the link to the IPsec peer is on an interface other than the one hosting the default route. With dynamic routing, where the peer might be reachable through eth0 today and eth1 tomorrow, it's difficult to keep rp_filter enabled unless fake routes to the remote subnets are configured on the interface currently used to reach the peer. IPsec provides a much stronger anti-spoofing policy than rp_filter, so this patch disables the rp_filter for packets with a security path. Signed-off-by: Michael Smith <msmith@cbnco.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_frontend.c')
-rw-r--r--net/ipv4/fib_frontend.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index f162f84b8d6d..22524716fe70 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -44,6 +44,7 @@
#include <net/arp.h>
#include <net/ip_fib.h>
#include <net/rtnetlink.h>
+#include <net/xfrm.h>
#ifndef CONFIG_IP_MULTIPLE_TABLES
@@ -211,7 +212,10 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos,
in_dev = __in_dev_get_rcu(dev);
if (in_dev) {
no_addr = in_dev->ifa_list == NULL;
- rpf = IN_DEV_RPFILTER(in_dev);
+
+ /* Ignore rp_filter for packets protected by IPsec. */
+ rpf = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(in_dev);
+
accept_local = IN_DEV_ACCEPT_LOCAL(in_dev);
fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
}