aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/ah4.c2
-rw-r--r--net/ipv4/esp4.c7
-rw-r--r--net/ipv4/ipcomp.c22
-rw-r--r--net/ipv4/xfrm4_mode_beet.c3
-rw-r--r--net/ipv4/xfrm4_mode_tunnel.c5
-rw-r--r--net/ipv4/xfrm4_output.c5
-rw-r--r--net/ipv4/xfrm4_tunnel.c5
-rw-r--r--net/ipv6/esp6.c3
-rw-r--r--net/ipv6/ipcomp6.c19
-rw-r--r--net/ipv6/mip6.c2
-rw-r--r--net/ipv6/xfrm6_mode_beet.c2
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c4
-rw-r--r--net/ipv6/xfrm6_output.c4
-rw-r--r--net/ipv6/xfrm6_tunnel.c5
14 files changed, 23 insertions, 65 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index d69706405d58..60925fedbf16 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -115,8 +115,6 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
115 memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr)); 115 memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr));
116 } 116 }
117 117
118 ip_send_check(top_iph);
119
120 err = 0; 118 err = 0;
121 119
122error: 120error:
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 66eb4968b910..8377bedf3f66 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -16,7 +16,6 @@
16static int esp_output(struct xfrm_state *x, struct sk_buff *skb) 16static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
17{ 17{
18 int err; 18 int err;
19 struct iphdr *top_iph;
20 struct ip_esp_hdr *esph; 19 struct ip_esp_hdr *esph;
21 struct crypto_blkcipher *tfm; 20 struct crypto_blkcipher *tfm;
22 struct blkcipher_desc desc; 21 struct blkcipher_desc desc;
@@ -59,9 +58,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
59 pskb_put(skb, trailer, clen - skb->len); 58 pskb_put(skb, trailer, clen - skb->len);
60 59
61 skb_push(skb, -skb_network_offset(skb)); 60 skb_push(skb, -skb_network_offset(skb));
62 top_iph = ip_hdr(skb);
63 esph = ip_esp_hdr(skb); 61 esph = ip_esp_hdr(skb);
64 top_iph->tot_len = htons(skb->len + alen);
65 *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb); 62 *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
66 *skb_mac_header(skb) = IPPROTO_ESP; 63 *skb_mac_header(skb) = IPPROTO_ESP;
67 64
@@ -76,7 +73,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
76 uh = (struct udphdr *)esph; 73 uh = (struct udphdr *)esph;
77 uh->source = encap->encap_sport; 74 uh->source = encap->encap_sport;
78 uh->dest = encap->encap_dport; 75 uh->dest = encap->encap_dport;
79 uh->len = htons(skb->len + alen - top_iph->ihl*4); 76 uh->len = htons(skb->len + alen - skb_transport_offset(skb));
80 uh->check = 0; 77 uh->check = 0;
81 78
82 switch (encap->encap_type) { 79 switch (encap->encap_type) {
@@ -136,8 +133,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
136unlock: 133unlock:
137 spin_unlock_bh(&x->lock); 134 spin_unlock_bh(&x->lock);
138 135
139 ip_send_check(top_iph);
140
141error: 136error:
142 return err; 137 return err;
143} 138}
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 78d6ddb02d1d..32b02deca2ec 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -98,10 +98,9 @@ out:
98static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) 98static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
99{ 99{
100 struct ipcomp_data *ipcd = x->data; 100 struct ipcomp_data *ipcd = x->data;
101 const int ihlen = skb_transport_offset(skb); 101 const int plen = skb->len;
102 const int plen = skb->len - ihlen;
103 int dlen = IPCOMP_SCRATCH_SIZE; 102 int dlen = IPCOMP_SCRATCH_SIZE;
104 u8 *start = skb_transport_header(skb); 103 u8 *start = skb->data;
105 const int cpu = get_cpu(); 104 const int cpu = get_cpu();
106 u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); 105 u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu);
107 struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); 106 struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu);
@@ -118,7 +117,7 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
118 memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); 117 memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen);
119 put_cpu(); 118 put_cpu();
120 119
121 pskb_trim(skb, ihlen + dlen + sizeof(struct ip_comp_hdr)); 120 pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr));
122 return 0; 121 return 0;
123 122
124out: 123out:
@@ -131,13 +130,8 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb)
131 int err; 130 int err;
132 struct ip_comp_hdr *ipch; 131 struct ip_comp_hdr *ipch;
133 struct ipcomp_data *ipcd = x->data; 132 struct ipcomp_data *ipcd = x->data;
134 int hdr_len = 0;
135 struct iphdr *iph = ip_hdr(skb);
136 133
137 skb_push(skb, -skb_network_offset(skb)); 134 if (skb->len < ipcd->threshold) {
138 iph->tot_len = htons(skb->len);
139 hdr_len = iph->ihl * 4;
140 if ((skb->len - hdr_len) < ipcd->threshold) {
141 /* Don't bother compressing */ 135 /* Don't bother compressing */
142 goto out_ok; 136 goto out_ok;
143 } 137 }
@@ -146,25 +140,19 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb)
146 goto out_ok; 140 goto out_ok;
147 141
148 err = ipcomp_compress(x, skb); 142 err = ipcomp_compress(x, skb);
149 iph = ip_hdr(skb);
150 143
151 if (err) { 144 if (err) {
152 goto out_ok; 145 goto out_ok;
153 } 146 }
154 147
155 /* Install ipcomp header, convert into ipcomp datagram. */ 148 /* Install ipcomp header, convert into ipcomp datagram. */
156 iph->tot_len = htons(skb->len);
157 ipch = ip_comp_hdr(skb); 149 ipch = ip_comp_hdr(skb);
158 ipch->nexthdr = *skb_mac_header(skb); 150 ipch->nexthdr = *skb_mac_header(skb);
159 ipch->flags = 0; 151 ipch->flags = 0;
160 ipch->cpi = htons((u16 )ntohl(x->id.spi)); 152 ipch->cpi = htons((u16 )ntohl(x->id.spi));
161 *skb_mac_header(skb) = IPPROTO_COMP; 153 *skb_mac_header(skb) = IPPROTO_COMP;
162 ip_send_check(iph);
163 return 0;
164
165out_ok: 154out_ok:
166 if (x->props.mode == XFRM_MODE_TUNNEL) 155 skb_push(skb, -skb_network_offset(skb));
167 ip_send_check(iph);
168 return 0; 156 return 0;
169} 157}
170 158
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 7226c6486c01..73d2338bec55 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -20,9 +20,6 @@
20/* Add encapsulation header. 20/* Add encapsulation header.
21 * 21 *
22 * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt. 22 * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
23 * The following fields in it shall be filled in by x->type->output:
24 * tot_len
25 * check
26 */ 23 */
27static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) 24static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
28{ 25{
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index f1d41ea34785..1ae9d32276f0 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -31,10 +31,7 @@ static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
31 31
32/* Add encapsulation header. 32/* Add encapsulation header.
33 * 33 *
34 * The top IP header will be constructed per RFC 2401. The following fields 34 * The top IP header will be constructed per RFC 2401.
35 * in it shall be filled in by x->type->output:
36 * tot_len
37 * check
38 */ 35 */
39static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) 36static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
40{ 37{
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 04805c7d79c3..434ef302ba83 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -44,6 +44,7 @@ static inline int xfrm4_output_one(struct sk_buff *skb)
44{ 44{
45 struct dst_entry *dst = skb->dst; 45 struct dst_entry *dst = skb->dst;
46 struct xfrm_state *x = dst->xfrm; 46 struct xfrm_state *x = dst->xfrm;
47 struct iphdr *iph;
47 int err; 48 int err;
48 49
49 if (x->props.mode == XFRM_MODE_TUNNEL) { 50 if (x->props.mode == XFRM_MODE_TUNNEL) {
@@ -56,6 +57,10 @@ static inline int xfrm4_output_one(struct sk_buff *skb)
56 if (err) 57 if (err)
57 goto error_nolock; 58 goto error_nolock;
58 59
60 iph = ip_hdr(skb);
61 iph->tot_len = htons(skb->len);
62 ip_send_check(iph);
63
59 IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; 64 IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
60 err = 0; 65 err = 0;
61 66
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index be572f918b5e..e1fafc1562d8 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -12,12 +12,7 @@
12 12
13static int ipip_output(struct xfrm_state *x, struct sk_buff *skb) 13static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
14{ 14{
15 struct iphdr *iph = ip_hdr(skb);
16
17 skb_push(skb, -skb_network_offset(skb)); 15 skb_push(skb, -skb_network_offset(skb));
18 iph->tot_len = htons(skb->len);
19 ip_send_check(iph);
20
21 return 0; 16 return 0;
22} 17}
23 18
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index a64295d164ea..9eb928598351 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -43,7 +43,6 @@
43static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) 43static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
44{ 44{
45 int err; 45 int err;
46 struct ipv6hdr *top_iph;
47 struct ip_esp_hdr *esph; 46 struct ip_esp_hdr *esph;
48 struct crypto_blkcipher *tfm; 47 struct crypto_blkcipher *tfm;
49 struct blkcipher_desc desc; 48 struct blkcipher_desc desc;
@@ -85,9 +84,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
85 pskb_put(skb, trailer, clen - skb->len); 84 pskb_put(skb, trailer, clen - skb->len);
86 85
87 skb_push(skb, -skb_network_offset(skb)); 86 skb_push(skb, -skb_network_offset(skb));
88 top_iph = ipv6_hdr(skb);
89 esph = ip_esp_hdr(skb); 87 esph = ip_esp_hdr(skb);
90 top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph));
91 *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb); 88 *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
92 *skb_mac_header(skb) = IPPROTO_ESP; 89 *skb_mac_header(skb) = IPPROTO_ESP;
93 90
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 8f3f32faaf4c..28fc8edfdc3a 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -119,20 +119,15 @@ out:
119static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) 119static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
120{ 120{
121 int err; 121 int err;
122 struct ipv6hdr *top_iph;
123 struct ip_comp_hdr *ipch; 122 struct ip_comp_hdr *ipch;
124 struct ipcomp_data *ipcd = x->data; 123 struct ipcomp_data *ipcd = x->data;
125 int plen, dlen; 124 int plen, dlen;
126 u8 *start, *scratch; 125 u8 *start, *scratch;
127 struct crypto_comp *tfm; 126 struct crypto_comp *tfm;
128 int cpu; 127 int cpu;
129 int hdr_len;
130
131 skb_push(skb, -skb_network_offset(skb));
132 hdr_len = skb_transport_offset(skb);
133 128
134 /* check whether datagram len is larger than threshold */ 129 /* check whether datagram len is larger than threshold */
135 if ((skb->len - hdr_len) < ipcd->threshold) { 130 if (skb->len < ipcd->threshold) {
136 goto out_ok; 131 goto out_ok;
137 } 132 }
138 133
@@ -140,9 +135,9 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
140 goto out_ok; 135 goto out_ok;
141 136
142 /* compression */ 137 /* compression */
143 plen = skb->len - hdr_len; 138 plen = skb->len;
144 dlen = IPCOMP_SCRATCH_SIZE; 139 dlen = IPCOMP_SCRATCH_SIZE;
145 start = skb_transport_header(skb); 140 start = skb->data;
146 141
147 cpu = get_cpu(); 142 cpu = get_cpu();
148 scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); 143 scratch = *per_cpu_ptr(ipcomp6_scratches, cpu);
@@ -155,13 +150,9 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
155 } 150 }
156 memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); 151 memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen);
157 put_cpu(); 152 put_cpu();
158 pskb_trim(skb, hdr_len + dlen + sizeof(struct ip_comp_hdr)); 153 pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr));
159 154
160 /* insert ipcomp header and replace datagram */ 155 /* insert ipcomp header and replace datagram */
161 top_iph = ipv6_hdr(skb);
162
163 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
164
165 ipch = ip_comp_hdr(skb); 156 ipch = ip_comp_hdr(skb);
166 ipch->nexthdr = *skb_mac_header(skb); 157 ipch->nexthdr = *skb_mac_header(skb);
167 ipch->flags = 0; 158 ipch->flags = 0;
@@ -169,6 +160,8 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
169 *skb_mac_header(skb) = IPPROTO_COMP; 160 *skb_mac_header(skb) = IPPROTO_COMP;
170 161
171out_ok: 162out_ok:
163 skb_push(skb, -skb_network_offset(skb));
164
172 return 0; 165 return 0;
173} 166}
174 167
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 0e7a60f7393a..7fd841d41019 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -155,7 +155,6 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb)
155 155
156 skb_push(skb, -skb_network_offset(skb)); 156 skb_push(skb, -skb_network_offset(skb));
157 iph = ipv6_hdr(skb); 157 iph = ipv6_hdr(skb);
158 iph->payload_len = htons(skb->len - sizeof(*iph));
159 158
160 nexthdr = *skb_mac_header(skb); 159 nexthdr = *skb_mac_header(skb);
161 *skb_mac_header(skb) = IPPROTO_DSTOPTS; 160 *skb_mac_header(skb) = IPPROTO_DSTOPTS;
@@ -370,7 +369,6 @@ static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb)
370 369
371 skb_push(skb, -skb_network_offset(skb)); 370 skb_push(skb, -skb_network_offset(skb));
372 iph = ipv6_hdr(skb); 371 iph = ipv6_hdr(skb);
373 iph->payload_len = htons(skb->len - sizeof(*iph));
374 372
375 nexthdr = *skb_mac_header(skb); 373 nexthdr = *skb_mac_header(skb);
376 *skb_mac_header(skb) = IPPROTO_ROUTING; 374 *skb_mac_header(skb) = IPPROTO_ROUTING;
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index 42c6ef839e59..13bb1e856764 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -22,8 +22,6 @@
22/* Add encapsulation header. 22/* Add encapsulation header.
23 * 23 *
24 * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt. 24 * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
25 * The following fields in it shall be filled in by x->type->output:
26 * payload_len
27 */ 25 */
28static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) 26static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
29{ 27{
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index e79c6bdf71c1..ea2283879112 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -33,9 +33,7 @@ static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb)
33 33
34/* Add encapsulation header. 34/* Add encapsulation header.
35 * 35 *
36 * The top IP header will be constructed per RFC 2401. The following fields 36 * The top IP header will be constructed per RFC 2401.
37 * in it shall be filled in by x->type->output:
38 * payload_len
39 */ 37 */
40static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) 38static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
41{ 39{
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index f21596f89984..4618c18e611d 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -47,6 +47,7 @@ static inline int xfrm6_output_one(struct sk_buff *skb)
47{ 47{
48 struct dst_entry *dst = skb->dst; 48 struct dst_entry *dst = skb->dst;
49 struct xfrm_state *x = dst->xfrm; 49 struct xfrm_state *x = dst->xfrm;
50 struct ipv6hdr *iph;
50 int err; 51 int err;
51 52
52 if (x->props.mode == XFRM_MODE_TUNNEL) { 53 if (x->props.mode == XFRM_MODE_TUNNEL) {
@@ -59,6 +60,9 @@ static inline int xfrm6_output_one(struct sk_buff *skb)
59 if (err) 60 if (err)
60 goto error_nolock; 61 goto error_nolock;
61 62
63 iph = ipv6_hdr(skb);
64 iph->payload_len = htons(skb->len - sizeof(*iph));
65
62 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; 66 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
63 err = 0; 67 err = 0;
64 68
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 00a1a3e5237c..3f8a3abde67e 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -242,12 +242,7 @@ EXPORT_SYMBOL(xfrm6_tunnel_free_spi);
242 242
243static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) 243static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
244{ 244{
245 struct ipv6hdr *top_iph;
246
247 skb_push(skb, -skb_network_offset(skb)); 245 skb_push(skb, -skb_network_offset(skb));
248 top_iph = ipv6_hdr(skb);
249 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
250
251 return 0; 246 return 0;
252} 247}
253 248