]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/xfrm4_output.c
[IPSEC]: Separate inner/outer mode processing on output
[linux-2.6-omap-h63xx.git] / net / ipv4 / xfrm4_output.c
index c4a7156962bd58797d93b7c21051bcc797c98de9..13fd11335e28ecbb303b8725fa93294a221733b8 100644 (file)
@@ -8,11 +8,12 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/compiler.h>
 #include <linux/if_ether.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4.h>
+#include <net/dst.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/icmp.h>
@@ -25,8 +26,6 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
        if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE)
                goto out;
 
-       IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
-
        if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df)
                goto out;
 
@@ -40,19 +39,39 @@ out:
        return ret;
 }
 
+int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+       int err;
+
+       err = xfrm4_tunnel_check_size(skb);
+       if (err)
+               return err;
+
+       return xfrm4_extract_header(skb);
+}
+
+int xfrm4_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(IPCB(skb), 0, sizeof(*IPCB(skb)));
+       IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
+
+       skb->protocol = htons(ETH_P_IP);
+
+       return x->outer_mode->output2(x, skb);
+}
+EXPORT_SYMBOL(xfrm4_prepare_output);
+
 static inline int xfrm4_output_one(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
-       struct xfrm_state *x = dst->xfrm;
        struct iphdr *iph;
        int err;
 
-       if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
-               err = xfrm4_tunnel_check_size(skb);
-               if (err)
-                       goto error_nolock;
-       }
-
        err = xfrm_output(skb);
        if (err)
                goto error_nolock;