aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-08 20:16:30 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:54:53 -0400
commit406ef77c893ebd882209be4e393d64b01fe72054 (patch)
tree815d753889769b355fba7e648abef7ad1422559e /net/ipv4
parentbc31d3b2c7d7f2a03721a05cb3c9a3ce8b1e2e5a (diff)
[IPSEC]: Move common output code to xfrm_output
Most of the code in xfrm4_output_one and xfrm6_output_one are identical so this patch moves them into a common xfrm_output function which will live in net/xfrm. In fact this would seem to fix a bug as on IPv4 we never reset the network header after a transform which may upset netfilter later on. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/xfrm4_output.c40
1 files changed, 4 insertions, 36 deletions
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 44ef208a75cb..04805c7d79c3 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -12,7 +12,6 @@
12#include <linux/if_ether.h> 12#include <linux/if_ether.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/spinlock.h>
16#include <linux/netfilter_ipv4.h> 15#include <linux/netfilter_ipv4.h>
17#include <net/ip.h> 16#include <net/ip.h>
18#include <net/xfrm.h> 17#include <net/xfrm.h>
@@ -41,58 +40,27 @@ out:
41 return ret; 40 return ret;
42} 41}
43 42
44static int xfrm4_output_one(struct sk_buff *skb) 43static inline int xfrm4_output_one(struct sk_buff *skb)
45{ 44{
46 struct dst_entry *dst = skb->dst; 45 struct dst_entry *dst = skb->dst;
47 struct xfrm_state *x = dst->xfrm; 46 struct xfrm_state *x = dst->xfrm;
48 int err; 47 int err;
49 48
50 if (skb->ip_summed == CHECKSUM_PARTIAL) {
51 err = skb_checksum_help(skb);
52 if (err)
53 goto error_nolock;
54 }
55
56 if (x->props.mode == XFRM_MODE_TUNNEL) { 49 if (x->props.mode == XFRM_MODE_TUNNEL) {
57 err = xfrm4_tunnel_check_size(skb); 50 err = xfrm4_tunnel_check_size(skb);
58 if (err) 51 if (err)
59 goto error_nolock; 52 goto error_nolock;
60 } 53 }
61 54
62 do { 55 err = xfrm_output(skb);
63 spin_lock_bh(&x->lock); 56 if (err)
64 err = xfrm_state_check(x, skb); 57 goto error_nolock;
65 if (err)
66 goto error;
67
68 err = x->mode->output(x, skb);
69 if (err)
70 goto error;
71
72 err = x->type->output(x, skb);
73 if (err)
74 goto error;
75
76 x->curlft.bytes += skb->len;
77 x->curlft.packets++;
78
79 spin_unlock_bh(&x->lock);
80
81 if (!(skb->dst = dst_pop(dst))) {
82 err = -EHOSTUNREACH;
83 goto error_nolock;
84 }
85 dst = skb->dst;
86 x = dst->xfrm;
87 } while (x && (x->props.mode != XFRM_MODE_TUNNEL));
88 58
89 IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; 59 IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
90 err = 0; 60 err = 0;
91 61
92out_exit: 62out_exit:
93 return err; 63 return err;
94error:
95 spin_unlock_bh(&x->lock);
96error_nolock: 64error_nolock:
97 kfree_skb(skb); 65 kfree_skb(skb);
98 goto out_exit; 66 goto out_exit;