]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Disable rp_filter for IPsec packets
authorMichael Smith <msmith@cbnco.com>
Thu, 7 Apr 2011 04:51:51 +0000 (04:51 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 11 Apr 2011 01:50:59 +0000 (18:50 -0700)
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>
include/net/xfrm.h
net/ipv4/fib_frontend.c

index 6ae4bc5ce8a712796774e32637f875f4e98b173e..65ea313486313f91d4ee35ce2402b4c8e5695c6e 100644 (file)
@@ -957,6 +957,15 @@ struct sec_path {
        struct xfrm_state       *xvec[XFRM_MAX_DEPTH];
 };
 
+static inline int secpath_exists(struct sk_buff *skb)
+{
+#ifdef CONFIG_XFRM
+       return skb->sp != NULL;
+#else
+       return 0;
+#endif
+}
+
 static inline struct sec_path *
 secpath_get(struct sec_path *sp)
 {
index f162f84b8d6d24bfba42bb7dbbef8651507f9d48..22524716fe7063c7cb0861bcce0dfba92f4effab 100644 (file)
@@ -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;
        }