diff options
Diffstat (limited to 'net/ipv6/xfrm6_output.c')
| -rw-r--r-- | net/ipv6/xfrm6_output.c | 39 | 
1 files changed, 30 insertions, 9 deletions
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 656976760ad..bc2e80e3b0b 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -10,10 +10,12 @@   */  #include <linux/if_ether.h> -#include <linux/compiler.h> +#include <linux/kernel.h> +#include <linux/module.h>  #include <linux/skbuff.h>  #include <linux/icmpv6.h>  #include <linux/netfilter_ipv6.h> +#include <net/dst.h>  #include <net/ipv6.h>  #include <net/xfrm.h> @@ -43,19 +45,38 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)  	return ret;  } +int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb) +{ +	int err; + +	err = xfrm6_tunnel_check_size(skb); +	if (err) +		return err; + +	return xfrm6_extract_header(skb); +} + +int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) +{ +	int err; + +	err = x->inner_mode->afinfo->extract_output(x, skb); +	if (err) +		return err; + +	memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); + +	skb->protocol = htons(ETH_P_IPV6); + +	return x->outer_mode->output2(x, skb); +} +EXPORT_SYMBOL(xfrm6_prepare_output); +  static inline int xfrm6_output_one(struct sk_buff *skb)  { -	struct dst_entry *dst = skb->dst; -	struct xfrm_state *x = dst->xfrm;  	struct ipv6hdr *iph;  	int err; -	if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { -		err = xfrm6_tunnel_check_size(skb); -		if (err) -			goto error_nolock; -	} -  	err = xfrm_output(skb);  	if (err)  		goto error_nolock;  |