aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/xfrm4_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/xfrm4_output.c')
-rw-r--r--net/ipv4/xfrm4_output.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index c4a7156962bd..13fd11335e28 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -8,11 +8,12 @@
8 * 2 of the License, or (at your option) any later version. 8 * 2 of the License, or (at your option) any later version.
9 */ 9 */
10 10
11#include <linux/compiler.h>
12#include <linux/if_ether.h> 11#include <linux/if_ether.h>
13#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/netfilter_ipv4.h> 15#include <linux/netfilter_ipv4.h>
16#include <net/dst.h>
16#include <net/ip.h> 17#include <net/ip.h>
17#include <net/xfrm.h> 18#include <net/xfrm.h>
18#include <net/icmp.h> 19#include <net/icmp.h>
@@ -25,8 +26,6 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
25 if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE) 26 if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE)
26 goto out; 27 goto out;
27 28
28 IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
29
30 if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df) 29 if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df)
31 goto out; 30 goto out;
32 31
@@ -40,19 +39,39 @@ out:
40 return ret; 39 return ret;
41} 40}
42 41
42int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
43{
44 int err;
45
46 err = xfrm4_tunnel_check_size(skb);
47 if (err)
48 return err;
49
50 return xfrm4_extract_header(skb);
51}
52
53int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
54{
55 int err;
56
57 err = x->inner_mode->afinfo->extract_output(x, skb);
58 if (err)
59 return err;
60
61 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
62 IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
63
64 skb->protocol = htons(ETH_P_IP);
65
66 return x->outer_mode->output2(x, skb);
67}
68EXPORT_SYMBOL(xfrm4_prepare_output);
69
43static inline int xfrm4_output_one(struct sk_buff *skb) 70static inline int xfrm4_output_one(struct sk_buff *skb)
44{ 71{
45 struct dst_entry *dst = skb->dst;
46 struct xfrm_state *x = dst->xfrm;
47 struct iphdr *iph; 72 struct iphdr *iph;
48 int err; 73 int err;
49 74
50 if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
51 err = xfrm4_tunnel_check_size(skb);
52 if (err)
53 goto error_nolock;
54 }
55
56 err = xfrm_output(skb); 75 err = xfrm_output(skb);
57 if (err) 76 if (err)
58 goto error_nolock; 77 goto error_nolock;