: [IPV4/6]: Netfilter IPsec output hooks
Subsystems (4)
PATCH 5/10 : [IPV4/6]: Netfilter IPsec output hooks
[IPV4/6]: Netfilter IPsec output hooks
Add alternative ip_dst_output/ip6_dst_output functions to call netfilter hooks between xfrm transforms. Packets visit FORWARD/LOCAL_OUT->POST_ROUTING before encapsulation and LOCAL_OUT->POST_ROUTING after each tunnel mode transform.
Signed-off-by Patrick McHardy <[email protected]>
---
commit 193f15d5698b56a568f284a460ce38734ed84e24
tree f6032d5c28c630af1fc8a55f0e77eca749b4e87f
parent acfa963b047cbda6a8350f122da90f1e84bf4938
author Patrick McHardy <[email protected]> Fri, 11 Nov 2005 02:15:08 +0100 committer Patrick McHardy <[email protected]> Fri, 11 Nov 2005 02:15:08 +0100
include/net/dst.h | 5 +++++ net/ipv4/netfilter.c | 31 ++++++++++++++++++++++++++++++- net/ipv4/xfrm4_output.c | 1 + net/ipv6/netfilter.c | 29 +++++++++++++++++++++++++++++ net/ipv6/xfrm6_output.c | 1 + 5 files changed, 66 insertions(+), 1 deletions(-)
include/net/dst.h +5 -0
@@ -236,8 +236,13 @@ static inline int dst_output(struct sk_b } } +#if defined(CONFIG_XFRM ) && defined(CONFIG_NETFILTER ) +extern int ip_dst_output (struct sk_buff *skb); +extern int ip6_dst_output (struct sk_buff *skb); +#else #define ip_dst_output dst_output#define ip6_dst_output dst_output +#endif /* Input packet from network to transport. */ static inline int dst_input (struct sk_buff *skb)
net/ipv4/netfilter.c +30 -1
@@ -10,8 +10,9 @@#include <linux/tcp.h> #include <linux/udp.h> #include <linux/icmp.h> -#include <net/route.h> #include <linux/ip.h> +#include <net/route.h> +#include <net/xfrm.h> /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ int ip_route_me_harder (struct sk_buff **pskb)
@@ -78,6 +79,34 @@ int ip_route_me_harder(struct sk_buff ** }EXPORT_SYMBOL (ip_route_me_harder); +#ifdef CONFIG_XFRM +static inline int __ip_dst_output (struct sk_buff *skb) +{ +int err; + +do { + err = skb->dst->output (skb); + +if (likely (err ==0 )) +return err; +if (unlikely (err !=NET_XMIT_BYPASS )) +return err; + }while (skb->dst->xfrm && !skb->dst->xfrm->props.mode); + +return NF_HOOK (PF_INET ,NF_IP_LOCAL_OUT , skb,NULL , skb->dst->dev, + ip_dst_output); +} + +int ip_dst_output (struct sk_buff *skb) +{ +if (skb->dst->xfrm !=NULL ) +return NF_HOOK (PF_INET ,NF_IP_POST_ROUTING , skb,NULL , + skb->dst->dev, __ip_dst_output); +return dst_output (skb); +} +EXPORT_SYMBOL (ip_dst_output); +#endif /* CONFIG_XFRM */ +/* * Extra routing may needed on local out, as the QUEUE target never * returns control to the table.
net/ipv4/xfrm4_output.c +1 -0
@@ -133,6 +133,7 @@ int xfrm4_output(struct sk_buff *skb) err = -EHOSTUNREACH ; goto error_nolock; } +nf_reset (skb); err =NET_XMIT_BYPASS ; out_exit:
net/ipv6/netfilter.c +29 -0
@@ -10,6 +10,7 @@#include <net/dst.h> #include <net/ipv6.h> #include <net/ip6_route.h> +#include <net/xfrm.h> int ip6_route_me_harder (struct sk_buff *skb) {
@@ -41,6 +42,34 @@ int ip6_route_me_harder(struct sk_buff * }EXPORT_SYMBOL (ip6_route_me_harder); +#ifdef CONFIG_XFRM +static inline int __ip6_dst_output (struct sk_buff *skb) +{ +int err; + +do { + err = skb->dst->output (skb); + +if (likely (err ==0 )) +return err; +if (unlikely (err !=NET_XMIT_BYPASS )) +return err; + }while (skb->dst->xfrm && !skb->dst->xfrm->props.mode); + +return NF_HOOK (PF_INET6 ,NF_IP6_LOCAL_OUT , skb,NULL , skb->dst->dev, + ip6_dst_output); +} + +int ip6_dst_output (struct sk_buff *skb) +{ +if (skb->dst->xfrm !=NULL ) +return NF_HOOK (PF_INET6 ,NF_IP6_POST_ROUTING , skb,NULL , + skb->dst->dev, __ip6_dst_output); +return dst_output (skb); +} +EXPORT_SYMBOL (ip6_dst_output); +#endif /* CONFIG_XFRM */ +/* * Extra routing may needed on local out, as the QUEUE target never * returns control to the table.
net/ipv6/xfrm6_output.c +1 -0
@@ -132,6 +132,7 @@ int xfrm6_output(struct sk_buff *skb) err = -EHOSTUNREACH ; goto error_nolock; } +nf_reset (skb); err =NET_XMIT_BYPASS ; out_exit: