diff options
-rw-r--r-- | include/net/xfrm.h | 9 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 6 |
2 files changed, 14 insertions, 1 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 6ae4bc5ce8a7..65ea31348631 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -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) { 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; } |