hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/ipv6/esp6.c
....@@ -1,18 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C)2002 USAGI/WIDE Project
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License as published by
6
- * the Free Software Foundation; either version 2 of the License, or
7
- * (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
164 *
175 * Authors
186 *
....@@ -38,11 +26,16 @@
3826 #include <linux/random.h>
3927 #include <linux/slab.h>
4028 #include <linux/spinlock.h>
29
+#include <net/ip6_checksum.h>
4130 #include <net/ip6_route.h>
4231 #include <net/icmp.h>
4332 #include <net/ipv6.h>
4433 #include <net/protocol.h>
34
+#include <net/udp.h>
4535 #include <linux/icmpv6.h>
36
+#include <net/tcp.h>
37
+#include <net/espintcp.h>
38
+#include <net/inet6_hashtables.h>
4639
4740 #include <linux/highmem.h>
4841
....@@ -51,9 +44,12 @@
5144 void *tmp;
5245 };
5346
54
-#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
47
+struct esp_output_extra {
48
+ __be32 seqhi;
49
+ u32 esphoff;
50
+};
5551
56
-static u32 esp6_get_mtu(struct xfrm_state *x, int mtu);
52
+#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
5753
5854 /*
5955 * Allocate an AEAD request structure with extra space for SG and IV.
....@@ -86,9 +82,9 @@
8682 return kmalloc(len, GFP_ATOMIC);
8783 }
8884
89
-static inline __be32 *esp_tmp_seqhi(void *tmp)
85
+static inline void *esp_tmp_extra(void *tmp)
9086 {
91
- return PTR_ALIGN((__be32 *)tmp, __alignof__(__be32));
87
+ return PTR_ALIGN(tmp, __alignof__(struct esp_output_extra));
9288 }
9389
9490 static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int seqhilen)
....@@ -118,16 +114,17 @@
118114
119115 static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
120116 {
117
+ struct esp_output_extra *extra = esp_tmp_extra(tmp);
121118 struct crypto_aead *aead = x->data;
122
- int seqhilen = 0;
119
+ int extralen = 0;
123120 u8 *iv;
124121 struct aead_request *req;
125122 struct scatterlist *sg;
126123
127124 if (x->props.flags & XFRM_STATE_ESN)
128
- seqhilen += sizeof(__be32);
125
+ extralen += sizeof(*extra);
129126
130
- iv = esp_tmp_iv(aead, tmp, seqhilen);
127
+ iv = esp_tmp_iv(aead, tmp, extralen);
131128 req = esp_tmp_req(aead, iv);
132129
133130 /* Unref skb_frag_pages in the src scatterlist if necessary.
....@@ -138,6 +135,149 @@
138135 put_page(sg_page(sg));
139136 }
140137
138
+#ifdef CONFIG_INET6_ESPINTCP
139
+struct esp_tcp_sk {
140
+ struct sock *sk;
141
+ struct rcu_head rcu;
142
+};
143
+
144
+static void esp_free_tcp_sk(struct rcu_head *head)
145
+{
146
+ struct esp_tcp_sk *esk = container_of(head, struct esp_tcp_sk, rcu);
147
+
148
+ sock_put(esk->sk);
149
+ kfree(esk);
150
+}
151
+
152
+static struct sock *esp6_find_tcp_sk(struct xfrm_state *x)
153
+{
154
+ struct xfrm_encap_tmpl *encap = x->encap;
155
+ struct esp_tcp_sk *esk;
156
+ __be16 sport, dport;
157
+ struct sock *nsk;
158
+ struct sock *sk;
159
+
160
+ sk = rcu_dereference(x->encap_sk);
161
+ if (sk && sk->sk_state == TCP_ESTABLISHED)
162
+ return sk;
163
+
164
+ spin_lock_bh(&x->lock);
165
+ sport = encap->encap_sport;
166
+ dport = encap->encap_dport;
167
+ nsk = rcu_dereference_protected(x->encap_sk,
168
+ lockdep_is_held(&x->lock));
169
+ if (sk && sk == nsk) {
170
+ esk = kmalloc(sizeof(*esk), GFP_ATOMIC);
171
+ if (!esk) {
172
+ spin_unlock_bh(&x->lock);
173
+ return ERR_PTR(-ENOMEM);
174
+ }
175
+ RCU_INIT_POINTER(x->encap_sk, NULL);
176
+ esk->sk = sk;
177
+ call_rcu(&esk->rcu, esp_free_tcp_sk);
178
+ }
179
+ spin_unlock_bh(&x->lock);
180
+
181
+ sk = __inet6_lookup_established(xs_net(x), &tcp_hashinfo, &x->id.daddr.in6,
182
+ dport, &x->props.saddr.in6, ntohs(sport), 0, 0);
183
+ if (!sk)
184
+ return ERR_PTR(-ENOENT);
185
+
186
+ if (!tcp_is_ulp_esp(sk)) {
187
+ sock_put(sk);
188
+ return ERR_PTR(-EINVAL);
189
+ }
190
+
191
+ spin_lock_bh(&x->lock);
192
+ nsk = rcu_dereference_protected(x->encap_sk,
193
+ lockdep_is_held(&x->lock));
194
+ if (encap->encap_sport != sport ||
195
+ encap->encap_dport != dport) {
196
+ sock_put(sk);
197
+ sk = nsk ?: ERR_PTR(-EREMCHG);
198
+ } else if (sk == nsk) {
199
+ sock_put(sk);
200
+ } else {
201
+ rcu_assign_pointer(x->encap_sk, sk);
202
+ }
203
+ spin_unlock_bh(&x->lock);
204
+
205
+ return sk;
206
+}
207
+
208
+static int esp_output_tcp_finish(struct xfrm_state *x, struct sk_buff *skb)
209
+{
210
+ struct sock *sk;
211
+ int err;
212
+
213
+ rcu_read_lock();
214
+
215
+ sk = esp6_find_tcp_sk(x);
216
+ err = PTR_ERR_OR_ZERO(sk);
217
+ if (err)
218
+ goto out;
219
+
220
+ bh_lock_sock(sk);
221
+ if (sock_owned_by_user(sk))
222
+ err = espintcp_queue_out(sk, skb);
223
+ else
224
+ err = espintcp_push_skb(sk, skb);
225
+ bh_unlock_sock(sk);
226
+
227
+out:
228
+ rcu_read_unlock();
229
+ return err;
230
+}
231
+
232
+static int esp_output_tcp_encap_cb(struct net *net, struct sock *sk,
233
+ struct sk_buff *skb)
234
+{
235
+ struct dst_entry *dst = skb_dst(skb);
236
+ struct xfrm_state *x = dst->xfrm;
237
+
238
+ return esp_output_tcp_finish(x, skb);
239
+}
240
+
241
+static int esp_output_tail_tcp(struct xfrm_state *x, struct sk_buff *skb)
242
+{
243
+ int err;
244
+
245
+ local_bh_disable();
246
+ err = xfrm_trans_queue_net(xs_net(x), skb, esp_output_tcp_encap_cb);
247
+ local_bh_enable();
248
+
249
+ /* EINPROGRESS just happens to do the right thing. It
250
+ * actually means that the skb has been consumed and
251
+ * isn't coming back.
252
+ */
253
+ return err ?: -EINPROGRESS;
254
+}
255
+#else
256
+static int esp_output_tail_tcp(struct xfrm_state *x, struct sk_buff *skb)
257
+{
258
+ kfree_skb(skb);
259
+
260
+ return -EOPNOTSUPP;
261
+}
262
+#endif
263
+
264
+static void esp_output_encap_csum(struct sk_buff *skb)
265
+{
266
+ /* UDP encap with IPv6 requires a valid checksum */
267
+ if (*skb_mac_header(skb) == IPPROTO_UDP) {
268
+ struct udphdr *uh = udp_hdr(skb);
269
+ struct ipv6hdr *ip6h = ipv6_hdr(skb);
270
+ int len = ntohs(uh->len);
271
+ unsigned int offset = skb_transport_offset(skb);
272
+ __wsum csum = skb_checksum(skb, offset, skb->len - offset, 0);
273
+
274
+ uh->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
275
+ len, IPPROTO_UDP, csum);
276
+ if (uh->check == 0)
277
+ uh->check = CSUM_MANGLED_0;
278
+ }
279
+}
280
+
141281 static void esp_output_done(struct crypto_async_request *base, int err)
142282 {
143283 struct sk_buff *skb = base->data;
....@@ -145,14 +285,19 @@
145285 void *tmp;
146286 struct xfrm_state *x;
147287
148
- if (xo && (xo->flags & XFRM_DEV_RESUME))
149
- x = skb->sp->xvec[skb->sp->len - 1];
150
- else
288
+ if (xo && (xo->flags & XFRM_DEV_RESUME)) {
289
+ struct sec_path *sp = skb_sec_path(skb);
290
+
291
+ x = sp->xvec[sp->len - 1];
292
+ } else {
151293 x = skb_dst(skb)->xfrm;
294
+ }
152295
153296 tmp = ESP_SKB_CB(skb)->tmp;
154297 esp_ssg_unref(x, tmp);
155298 kfree(tmp);
299
+
300
+ esp_output_encap_csum(skb);
156301
157302 if (xo && (xo->flags & XFRM_DEV_RESUME)) {
158303 if (err) {
....@@ -165,7 +310,11 @@
165310 secpath_reset(skb);
166311 xfrm_dev_resume(skb);
167312 } else {
168
- xfrm_output_resume(skb, err);
313
+ if (!err &&
314
+ x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
315
+ esp_output_tail_tcp(x, skb);
316
+ else
317
+ xfrm_output_resume(skb, err);
169318 }
170319 }
171320
....@@ -174,7 +323,7 @@
174323 {
175324 struct ip_esp_hdr *esph = (void *)(skb->data + offset);
176325 void *tmp = ESP_SKB_CB(skb)->tmp;
177
- __be32 *seqhi = esp_tmp_seqhi(tmp);
326
+ __be32 *seqhi = esp_tmp_extra(tmp);
178327
179328 esph->seq_no = esph->spi;
180329 esph->spi = *seqhi;
....@@ -182,27 +331,36 @@
182331
183332 static void esp_output_restore_header(struct sk_buff *skb)
184333 {
185
- esp_restore_header(skb, skb_transport_offset(skb) - sizeof(__be32));
334
+ void *tmp = ESP_SKB_CB(skb)->tmp;
335
+ struct esp_output_extra *extra = esp_tmp_extra(tmp);
336
+
337
+ esp_restore_header(skb, skb_transport_offset(skb) + extra->esphoff -
338
+ sizeof(__be32));
186339 }
187340
188341 static struct ip_esp_hdr *esp_output_set_esn(struct sk_buff *skb,
189342 struct xfrm_state *x,
190343 struct ip_esp_hdr *esph,
191
- __be32 *seqhi)
344
+ struct esp_output_extra *extra)
192345 {
193346 /* For ESN we move the header forward by 4 bytes to
194347 * accomodate the high bits. We will move it back after
195348 * encryption.
196349 */
197350 if ((x->props.flags & XFRM_STATE_ESN)) {
351
+ __u32 seqhi;
198352 struct xfrm_offload *xo = xfrm_offload(skb);
199353
200
- esph = (void *)(skb_transport_header(skb) - sizeof(__be32));
201
- *seqhi = esph->spi;
202354 if (xo)
203
- esph->seq_no = htonl(xo->seq.hi);
355
+ seqhi = xo->seq.hi;
204356 else
205
- esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.hi);
357
+ seqhi = XFRM_SKB_CB(skb)->seq.output.hi;
358
+
359
+ extra->esphoff = (unsigned char *)esph -
360
+ skb_transport_header(skb);
361
+ esph = (struct ip_esp_hdr *)((unsigned char *)esph - 4);
362
+ extra->seqhi = esph->spi;
363
+ esph->seq_no = htonl(seqhi);
206364 }
207365
208366 esph->spi = x->id.spi;
....@@ -218,29 +376,124 @@
218376 esp_output_done(base, err);
219377 }
220378
221
-static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto)
379
+static struct ip_esp_hdr *esp6_output_udp_encap(struct sk_buff *skb,
380
+ int encap_type,
381
+ struct esp_info *esp,
382
+ __be16 sport,
383
+ __be16 dport)
222384 {
223
- /* Fill padding... */
224
- if (tfclen) {
225
- memset(tail, 0, tfclen);
226
- tail += tfclen;
385
+ struct udphdr *uh;
386
+ __be32 *udpdata32;
387
+ unsigned int len;
388
+
389
+ len = skb->len + esp->tailen - skb_transport_offset(skb);
390
+ if (len > U16_MAX)
391
+ return ERR_PTR(-EMSGSIZE);
392
+
393
+ uh = (struct udphdr *)esp->esph;
394
+ uh->source = sport;
395
+ uh->dest = dport;
396
+ uh->len = htons(len);
397
+ uh->check = 0;
398
+
399
+ *skb_mac_header(skb) = IPPROTO_UDP;
400
+
401
+ if (encap_type == UDP_ENCAP_ESPINUDP_NON_IKE) {
402
+ udpdata32 = (__be32 *)(uh + 1);
403
+ udpdata32[0] = udpdata32[1] = 0;
404
+ return (struct ip_esp_hdr *)(udpdata32 + 2);
227405 }
228
- do {
229
- int i;
230
- for (i = 0; i < plen - 2; i++)
231
- tail[i] = i + 1;
232
- } while (0);
233
- tail[plen - 2] = plen - 2;
234
- tail[plen - 1] = proto;
406
+
407
+ return (struct ip_esp_hdr *)(uh + 1);
408
+}
409
+
410
+#ifdef CONFIG_INET6_ESPINTCP
411
+static struct ip_esp_hdr *esp6_output_tcp_encap(struct xfrm_state *x,
412
+ struct sk_buff *skb,
413
+ struct esp_info *esp)
414
+{
415
+ __be16 *lenp = (void *)esp->esph;
416
+ struct ip_esp_hdr *esph;
417
+ unsigned int len;
418
+ struct sock *sk;
419
+
420
+ len = skb->len + esp->tailen - skb_transport_offset(skb);
421
+ if (len > IP_MAX_MTU)
422
+ return ERR_PTR(-EMSGSIZE);
423
+
424
+ rcu_read_lock();
425
+ sk = esp6_find_tcp_sk(x);
426
+ rcu_read_unlock();
427
+
428
+ if (IS_ERR(sk))
429
+ return ERR_CAST(sk);
430
+
431
+ *lenp = htons(len);
432
+ esph = (struct ip_esp_hdr *)(lenp + 1);
433
+
434
+ return esph;
435
+}
436
+#else
437
+static struct ip_esp_hdr *esp6_output_tcp_encap(struct xfrm_state *x,
438
+ struct sk_buff *skb,
439
+ struct esp_info *esp)
440
+{
441
+ return ERR_PTR(-EOPNOTSUPP);
442
+}
443
+#endif
444
+
445
+static int esp6_output_encap(struct xfrm_state *x, struct sk_buff *skb,
446
+ struct esp_info *esp)
447
+{
448
+ struct xfrm_encap_tmpl *encap = x->encap;
449
+ struct ip_esp_hdr *esph;
450
+ __be16 sport, dport;
451
+ int encap_type;
452
+
453
+ spin_lock_bh(&x->lock);
454
+ sport = encap->encap_sport;
455
+ dport = encap->encap_dport;
456
+ encap_type = encap->encap_type;
457
+ spin_unlock_bh(&x->lock);
458
+
459
+ switch (encap_type) {
460
+ default:
461
+ case UDP_ENCAP_ESPINUDP:
462
+ case UDP_ENCAP_ESPINUDP_NON_IKE:
463
+ esph = esp6_output_udp_encap(skb, encap_type, esp, sport, dport);
464
+ break;
465
+ case TCP_ENCAP_ESPINTCP:
466
+ esph = esp6_output_tcp_encap(x, skb, esp);
467
+ break;
468
+ }
469
+
470
+ if (IS_ERR(esph))
471
+ return PTR_ERR(esph);
472
+
473
+ esp->esph = esph;
474
+
475
+ return 0;
235476 }
236477
237478 int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
238479 {
239480 u8 *tail;
240481 int nfrags;
482
+ int esph_offset;
241483 struct page *page;
242484 struct sk_buff *trailer;
243485 int tailen = esp->tailen;
486
+
487
+ if (x->encap) {
488
+ int err = esp6_output_encap(x, skb, esp);
489
+
490
+ if (err < 0)
491
+ return err;
492
+ }
493
+
494
+ if (ALIGN(tailen, L1_CACHE_BYTES) > PAGE_SIZE ||
495
+ ALIGN(skb->data_len, L1_CACHE_BYTES) > PAGE_SIZE)
496
+ goto cow;
244497
245498 if (!skb_cloned(skb)) {
246499 if (tailen <= skb_tailroom(skb)) {
....@@ -296,10 +549,13 @@
296549 }
297550
298551 cow:
552
+ esph_offset = (unsigned char *)esp->esph - skb_transport_header(skb);
553
+
299554 nfrags = skb_cow_data(skb, tailen, &trailer);
300555 if (nfrags < 0)
301556 goto out;
302557 tail = skb_tail_pointer(trailer);
558
+ esp->esph = (struct ip_esp_hdr *)(skb_transport_header(skb) + esph_offset);
303559
304560 skip_cow:
305561 esp_output_fill_trailer(tail, esp->tfclen, esp->plen, esp->proto);
....@@ -317,20 +573,20 @@
317573 void *tmp;
318574 int ivlen;
319575 int assoclen;
320
- int seqhilen;
321
- __be32 *seqhi;
576
+ int extralen;
322577 struct page *page;
323578 struct ip_esp_hdr *esph;
324579 struct aead_request *req;
325580 struct crypto_aead *aead;
326581 struct scatterlist *sg, *dsg;
582
+ struct esp_output_extra *extra;
327583 int err = -ENOMEM;
328584
329585 assoclen = sizeof(struct ip_esp_hdr);
330
- seqhilen = 0;
586
+ extralen = 0;
331587
332588 if (x->props.flags & XFRM_STATE_ESN) {
333
- seqhilen += sizeof(__be32);
589
+ extralen += sizeof(*extra);
334590 assoclen += sizeof(__be32);
335591 }
336592
....@@ -338,12 +594,12 @@
338594 alen = crypto_aead_authsize(aead);
339595 ivlen = crypto_aead_ivsize(aead);
340596
341
- tmp = esp_alloc_tmp(aead, esp->nfrags + 2, seqhilen);
597
+ tmp = esp_alloc_tmp(aead, esp->nfrags + 2, extralen);
342598 if (!tmp)
343599 goto error;
344600
345
- seqhi = esp_tmp_seqhi(tmp);
346
- iv = esp_tmp_iv(aead, tmp, seqhilen);
601
+ extra = esp_tmp_extra(tmp);
602
+ iv = esp_tmp_iv(aead, tmp, extralen);
347603 req = esp_tmp_req(aead, iv);
348604 sg = esp_req_sg(aead, req);
349605
....@@ -352,7 +608,8 @@
352608 else
353609 dsg = &sg[esp->nfrags];
354610
355
- esph = esp_output_set_esn(skb, x, ip_esp_hdr(skb), seqhi);
611
+ esph = esp_output_set_esn(skb, x, esp->esph, extra);
612
+ esp->esph = esph;
356613
357614 sg_init_table(sg, esp->nfrags);
358615 err = skb_to_sgvec(skb, sg,
....@@ -416,10 +673,14 @@
416673 case 0:
417674 if ((x->props.flags & XFRM_STATE_ESN))
418675 esp_output_restore_header(skb);
676
+ esp_output_encap_csum(skb);
419677 }
420678
421679 if (sg != dsg)
422680 esp_ssg_unref(x, tmp);
681
+
682
+ if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
683
+ err = esp_output_tail_tcp(x, skb);
423684
424685 error_free:
425686 kfree(tmp);
....@@ -451,7 +712,7 @@
451712 struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
452713 u32 padto;
453714
454
- padto = min(x->tfcpad, esp6_get_mtu(x, dst->child_mtu_cached));
715
+ padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached));
455716 if (skb->len < padto)
456717 esp.tfclen = padto - skb->len;
457718 }
....@@ -460,11 +721,13 @@
460721 esp.plen = esp.clen - skb->len - esp.tfclen;
461722 esp.tailen = esp.tfclen + esp.plen + alen;
462723
724
+ esp.esph = ip_esp_hdr(skb);
725
+
463726 esp.nfrags = esp6_output_head(x, skb, &esp);
464727 if (esp.nfrags < 0)
465728 return esp.nfrags;
466729
467
- esph = ip_esp_hdr(skb);
730
+ esph = esp.esph;
468731 esph->spi = x->id.spi;
469732
470733 esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.low);
....@@ -539,6 +802,72 @@
539802 if (unlikely(err < 0))
540803 goto out;
541804
805
+ if (x->encap) {
806
+ const struct ipv6hdr *ip6h = ipv6_hdr(skb);
807
+ int offset = skb_network_offset(skb) + sizeof(*ip6h);
808
+ struct xfrm_encap_tmpl *encap = x->encap;
809
+ u8 nexthdr = ip6h->nexthdr;
810
+ __be16 frag_off, source;
811
+ struct udphdr *uh;
812
+ struct tcphdr *th;
813
+
814
+ offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
815
+ if (offset == -1) {
816
+ err = -EINVAL;
817
+ goto out;
818
+ }
819
+
820
+ uh = (void *)(skb->data + offset);
821
+ th = (void *)(skb->data + offset);
822
+ hdr_len += offset;
823
+
824
+ switch (x->encap->encap_type) {
825
+ case TCP_ENCAP_ESPINTCP:
826
+ source = th->source;
827
+ break;
828
+ case UDP_ENCAP_ESPINUDP:
829
+ case UDP_ENCAP_ESPINUDP_NON_IKE:
830
+ source = uh->source;
831
+ break;
832
+ default:
833
+ WARN_ON_ONCE(1);
834
+ err = -EINVAL;
835
+ goto out;
836
+ }
837
+
838
+ /*
839
+ * 1) if the NAT-T peer's IP or port changed then
840
+ * advertize the change to the keying daemon.
841
+ * This is an inbound SA, so just compare
842
+ * SRC ports.
843
+ */
844
+ if (!ipv6_addr_equal(&ip6h->saddr, &x->props.saddr.in6) ||
845
+ source != encap->encap_sport) {
846
+ xfrm_address_t ipaddr;
847
+
848
+ memcpy(&ipaddr.a6, &ip6h->saddr.s6_addr, sizeof(ipaddr.a6));
849
+ km_new_mapping(x, &ipaddr, source);
850
+
851
+ /* XXX: perhaps add an extra
852
+ * policy check here, to see
853
+ * if we should allow or
854
+ * reject a packet from a
855
+ * different source
856
+ * address/port.
857
+ */
858
+ }
859
+
860
+ /*
861
+ * 2) ignore UDP/TCP checksums in case
862
+ * of NAT-T in Transport Mode, or
863
+ * perform other post-processing fixes
864
+ * as per draft-ietf-ipsec-udp-encaps-06,
865
+ * section 3.1.2
866
+ */
867
+ if (x->props.mode == XFRM_MODE_TRANSPORT)
868
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
869
+ }
870
+
542871 skb_postpull_rcsum(skb, skb_network_header(skb),
543872 skb_network_header_len(skb));
544873 skb_pull_rcsum(skb, hlen);
....@@ -596,12 +925,11 @@
596925
597926 static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
598927 {
599
- struct ip_esp_hdr *esph;
600928 struct crypto_aead *aead = x->data;
601929 struct aead_request *req;
602930 struct sk_buff *trailer;
603931 int ivlen = crypto_aead_ivsize(aead);
604
- int elen = skb->len - sizeof(*esph) - ivlen;
932
+ int elen = skb->len - sizeof(struct ip_esp_hdr) - ivlen;
605933 int nfrags;
606934 int assoclen;
607935 int seqhilen;
....@@ -611,7 +939,7 @@
611939 u8 *iv;
612940 struct scatterlist *sg;
613941
614
- if (!pskb_may_pull(skb, sizeof(*esph) + ivlen)) {
942
+ if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) {
615943 ret = -EINVAL;
616944 goto out;
617945 }
....@@ -621,7 +949,7 @@
621949 goto out;
622950 }
623951
624
- assoclen = sizeof(*esph);
952
+ assoclen = sizeof(struct ip_esp_hdr);
625953 seqhilen = 0;
626954
627955 if (x->props.flags & XFRM_STATE_ESN) {
....@@ -655,7 +983,7 @@
655983 goto out;
656984
657985 ESP_SKB_CB(skb)->tmp = tmp;
658
- seqhi = esp_tmp_seqhi(tmp);
986
+ seqhi = esp_tmp_extra(tmp);
659987 iv = esp_tmp_iv(aead, tmp, seqhilen);
660988 req = esp_tmp_req(aead, iv);
661989 sg = esp_req_sg(aead, req);
....@@ -690,21 +1018,6 @@
6901018
6911019 out:
6921020 return ret;
693
-}
694
-
695
-static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
696
-{
697
- struct crypto_aead *aead = x->data;
698
- u32 blksize = ALIGN(crypto_aead_blocksize(aead), 4);
699
- unsigned int net_adj;
700
-
701
- if (x->props.mode != XFRM_MODE_TUNNEL)
702
- net_adj = sizeof(struct ipv6hdr);
703
- else
704
- net_adj = 0;
705
-
706
- return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
707
- net_adj) & ~(blksize - 1)) + net_adj - 2;
7081021 }
7091022
7101023 static int esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
....@@ -874,9 +1187,6 @@
8741187 u32 align;
8751188 int err;
8761189
877
- if (x->encap)
878
- return -EINVAL;
879
-
8801190 x->data = NULL;
8811191
8821192 if (x->aead)
....@@ -905,6 +1215,30 @@
9051215 break;
9061216 }
9071217
1218
+ if (x->encap) {
1219
+ struct xfrm_encap_tmpl *encap = x->encap;
1220
+
1221
+ switch (encap->encap_type) {
1222
+ default:
1223
+ err = -EINVAL;
1224
+ goto error;
1225
+ case UDP_ENCAP_ESPINUDP:
1226
+ x->props.header_len += sizeof(struct udphdr);
1227
+ break;
1228
+ case UDP_ENCAP_ESPINUDP_NON_IKE:
1229
+ x->props.header_len += sizeof(struct udphdr) + 2 * sizeof(u32);
1230
+ break;
1231
+#ifdef CONFIG_INET6_ESPINTCP
1232
+ case TCP_ENCAP_ESPINTCP:
1233
+ /* only the length field, TCP encap is done by
1234
+ * the socket
1235
+ */
1236
+ x->props.header_len += 2;
1237
+ break;
1238
+#endif
1239
+ }
1240
+ }
1241
+
9081242 align = ALIGN(crypto_aead_blocksize(aead), 4);
9091243 x->props.trailer_len = align + 1 + crypto_aead_authsize(aead);
9101244
....@@ -924,7 +1258,6 @@
9241258 .flags = XFRM_TYPE_REPLAY_PROT,
9251259 .init_state = esp6_init_state,
9261260 .destructor = esp6_destroy,
927
- .get_mtu = esp6_get_mtu,
9281261 .input = esp6_input,
9291262 .output = esp6_output,
9301263 .hdr_offset = xfrm6_find_1stfragopt,
....@@ -932,6 +1265,7 @@
9321265
9331266 static struct xfrm6_protocol esp6_protocol = {
9341267 .handler = xfrm6_rcv,
1268
+ .input_handler = xfrm_input,
9351269 .cb_handler = esp6_rcv_cb,
9361270 .err_handler = esp6_err,
9371271 .priority = 0,
....@@ -956,8 +1290,7 @@
9561290 {
9571291 if (xfrm6_protocol_deregister(&esp6_protocol, IPPROTO_ESP) < 0)
9581292 pr_info("%s: can't remove protocol\n", __func__);
959
- if (xfrm_unregister_type(&esp6_type, AF_INET6) < 0)
960
- pr_info("%s: can't remove xfrm type\n", __func__);
1293
+ xfrm_unregister_type(&esp6_type, AF_INET6);
9611294 }
9621295
9631296 module_init(esp6_init);