diff options
Diffstat (limited to 'net/ipv4/xfrm4_output.c')
-rw-r--r-- | net/ipv4/xfrm4_output.c | 41 |
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 | ||
42 | int 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 | |||
53 | int 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 | } | ||
68 | EXPORT_SYMBOL(xfrm4_prepare_output); | ||
69 | |||
43 | static inline int xfrm4_output_one(struct sk_buff *skb) | 70 | static 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; |