Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/netipsec/ipsec_output.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
5
* Copyright (c) 2016 Andrey V. Elsukov <[email protected]>
6
* All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*/
29
30
/*
31
* IPsec output processing.
32
*/
33
#include "opt_inet.h"
34
#include "opt_inet6.h"
35
#include "opt_ipsec.h"
36
#include "opt_sctp.h"
37
38
#include <sys/param.h>
39
#include <sys/systm.h>
40
#include <sys/mbuf.h>
41
#include <sys/domain.h>
42
#include <sys/protosw.h>
43
#include <sys/socket.h>
44
#include <sys/errno.h>
45
#include <sys/hhook.h>
46
#include <sys/syslog.h>
47
48
#include <net/if.h>
49
#include <net/if_enc.h>
50
#include <net/if_var.h>
51
#include <net/vnet.h>
52
53
#include <netinet/in.h>
54
#include <netinet/in_pcb.h>
55
#include <netinet/in_systm.h>
56
#include <netinet/ip.h>
57
#include <netinet/ip_var.h>
58
#include <netinet/in_var.h>
59
#include <netinet/ip_ecn.h>
60
#ifdef INET6
61
#include <netinet6/ip6_ecn.h>
62
#endif
63
#include <netinet/ip_icmp.h>
64
#include <netinet/tcp_var.h>
65
66
#include <netinet/ip6.h>
67
#ifdef INET6
68
#include <netinet6/ip6_var.h>
69
#include <netinet6/scope6_var.h>
70
#endif
71
#include <netinet/in_pcb.h>
72
#ifdef INET6
73
#include <netinet/icmp6.h>
74
#endif
75
#if defined(SCTP) || defined(SCTP_SUPPORT)
76
#include <netinet/sctp_crc32.h>
77
#endif
78
79
#include <netinet/udp.h>
80
#include <netipsec/ah.h>
81
#include <netipsec/esp.h>
82
#include <netipsec/ipsec.h>
83
#ifdef INET6
84
#include <netipsec/ipsec6.h>
85
#endif
86
#include <netipsec/ipsec_support.h>
87
#include <netipsec/ipsec_offload.h>
88
#include <netipsec/ah_var.h>
89
#include <netipsec/esp_var.h>
90
#include <netipsec/ipcomp_var.h>
91
92
#include <netipsec/xform.h>
93
94
#include <netipsec/key.h>
95
#include <netipsec/keydb.h>
96
#include <netipsec/key_debug.h>
97
98
#include <machine/in_cksum.h>
99
100
#define IPSEC_OSTAT_INC(proto, name) do { \
101
if ((proto) == IPPROTO_ESP) \
102
ESPSTAT_INC(esps_##name); \
103
else if ((proto) == IPPROTO_AH)\
104
AHSTAT_INC(ahs_##name); \
105
else \
106
IPCOMPSTAT_INC(ipcomps_##name); \
107
} while (0)
108
109
static int ipsec_encap(struct mbuf **mp, struct secasindex *saidx);
110
static size_t ipsec_get_pmtu(struct secasvar *sav);
111
112
#ifdef INET
113
static struct secasvar *
114
ipsec4_allocsa(struct ifnet *ifp, struct mbuf *m, const struct ip *ip,
115
struct secpolicy *sp, u_int *pidx, int *error)
116
{
117
struct secasindex *saidx, tmpsaidx;
118
struct ipsecrequest *isr;
119
struct sockaddr_in *sin;
120
struct secasvar *sav;
121
122
/*
123
* Check system global policy controls.
124
*/
125
next:
126
isr = sp->req[*pidx];
127
if ((isr->saidx.proto == IPPROTO_ESP && !V_esp_enable) ||
128
(isr->saidx.proto == IPPROTO_AH && !V_ah_enable) ||
129
(isr->saidx.proto == IPPROTO_IPCOMP && !V_ipcomp_enable)) {
130
DPRINTF(("%s: IPsec outbound packet dropped due"
131
" to policy (check your sysctls)\n", __func__));
132
IPSEC_OSTAT_INC(isr->saidx.proto, pdrops);
133
*error = EHOSTUNREACH;
134
return (NULL);
135
}
136
/*
137
* Craft SA index to search for proper SA. Note that
138
* we only initialize unspecified SA peers for transport
139
* mode; for tunnel mode they must already be filled in.
140
*/
141
if (isr->saidx.mode == IPSEC_MODE_TRANSPORT) {
142
saidx = &tmpsaidx;
143
*saidx = isr->saidx;
144
if (saidx->src.sa.sa_len == 0) {
145
sin = &saidx->src.sin;
146
sin->sin_len = sizeof(*sin);
147
sin->sin_family = AF_INET;
148
sin->sin_port = IPSEC_PORT_ANY;
149
sin->sin_addr = ip->ip_src;
150
}
151
if (saidx->dst.sa.sa_len == 0) {
152
sin = &saidx->dst.sin;
153
sin->sin_len = sizeof(*sin);
154
sin->sin_family = AF_INET;
155
sin->sin_port = IPSEC_PORT_ANY;
156
sin->sin_addr = ip->ip_dst;
157
}
158
} else
159
saidx = &sp->req[*pidx]->saidx;
160
/*
161
* Lookup SA and validate it.
162
*/
163
sav = key_allocsa_policy(sp, saidx, error);
164
if (sav == NULL) {
165
IPSECSTAT_INC(ips_out_nosa);
166
if (*error != 0)
167
return (NULL);
168
if (ipsec_get_reqlevel(sp, *pidx) != IPSEC_LEVEL_REQUIRE) {
169
/*
170
* We have no SA and policy that doesn't require
171
* this IPsec transform, thus we can continue w/o
172
* IPsec processing, i.e. return EJUSTRETURN.
173
* But first check if there is some bundled transform.
174
*/
175
if (sp->tcount > ++(*pidx))
176
goto next;
177
*error = EJUSTRETURN;
178
}
179
return (NULL);
180
}
181
IPSEC_ASSERT(sav->tdb_xform != NULL, ("SA with NULL tdb_xform"));
182
return (sav);
183
}
184
185
/*
186
* IPsec output logic for IPv4.
187
*/
188
static int
189
ipsec4_perform_request(struct ifnet *ifp, struct mbuf *m, struct ip *ip1,
190
struct secpolicy *sp, struct inpcb *inp, u_int idx, u_long mtu)
191
{
192
struct ipsec_ctx_data ctx;
193
union sockaddr_union *dst;
194
struct secasvar *sav;
195
struct ip *ip;
196
struct mbuf *m1;
197
int error, hwassist, i, off;
198
bool accel;
199
200
IPSEC_ASSERT(idx < sp->tcount, ("Wrong IPsec request index %d", idx));
201
202
/*
203
* We hold the reference to SP. Content of SP couldn't be changed.
204
* Craft secasindex and do lookup for suitable SA.
205
* Then do encapsulation if needed and call xform's output.
206
* We need to store SP in the xform callback parameters.
207
* In xform callback we will extract SP and it can be used to
208
* determine next transform. At the end of transform we can
209
* release reference to SP.
210
*/
211
sav = ipsec4_allocsa(ifp, m, ip1, sp, &idx, &error);
212
if (sav == NULL) {
213
if (error == EJUSTRETURN) { /* No IPsec required */
214
(void)ipsec_accel_output(ifp, m, inp, sp, NULL,
215
AF_INET, mtu, &hwassist);
216
key_freesp(&sp);
217
return (error);
218
}
219
goto bad;
220
}
221
/*
222
* XXXAE: most likely ip_sum at this point is wrong.
223
*/
224
IPSEC_INIT_CTX(&ctx, &m, inp, sav, AF_INET, IPSEC_ENC_BEFORE);
225
if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_OUT)) != 0)
226
goto bad;
227
/* Re-calculate *ip1 after potential change of m in the hook. */
228
m_copydata(m, 0, sizeof(*ip1), (char *)ip1);
229
230
hwassist = 0;
231
accel = ipsec_accel_output(ifp, m, inp, sp, sav, AF_INET, mtu,
232
&hwassist);
233
234
/*
235
* Do delayed checksums now because we send before
236
* this is done in the normal processing path.
237
*/
238
if ((m->m_pkthdr.csum_flags & CSUM_DELAY_DATA & ~hwassist) != 0) {
239
in_delayed_cksum(m);
240
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
241
}
242
#if defined(SCTP) || defined(SCTP_SUPPORT)
243
if ((m->m_pkthdr.csum_flags & CSUM_SCTP & ~hwassist) != 0) {
244
sctp_delayed_cksum(m, (uint32_t)(ip1->ip_hl << 2));
245
m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
246
}
247
#endif
248
if (accel)
249
return (EJUSTRETURN);
250
251
error = mb_unmapped_to_ext(m, &m1);
252
if (error != 0) {
253
if (error == EINVAL) {
254
if (bootverbose)
255
if_printf(ifp, "Tx TLS+IPSEC packet\n");
256
}
257
return (error);
258
}
259
m = m1;
260
261
ip = mtod(m, struct ip *);
262
dst = &sav->sah->saidx.dst;
263
/* Do the appropriate encapsulation, if necessary */
264
if (sp->req[idx]->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */
265
dst->sa.sa_family != AF_INET || /* PF mismatch */
266
(dst->sa.sa_family == AF_INET && /* Proxy */
267
dst->sin.sin_addr.s_addr != INADDR_ANY &&
268
dst->sin.sin_addr.s_addr != ip->ip_dst.s_addr)) {
269
/* Fix IPv4 header checksum and length */
270
ip->ip_len = htons(m->m_pkthdr.len);
271
ip->ip_sum = 0;
272
ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
273
error = ipsec_encap(&m, &sav->sah->saidx);
274
if (error != 0) {
275
DPRINTF(("%s: encapsulation for SPI 0x%08x failed "
276
"with error %d\n", __func__, ntohl(sav->spi),
277
error));
278
/* XXXAE: IPSEC_OSTAT_INC(tunnel); */
279
goto bad;
280
}
281
inp = NULL;
282
}
283
284
IPSEC_INIT_CTX(&ctx, &m, inp, sav, dst->sa.sa_family, IPSEC_ENC_AFTER);
285
if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_OUT)) != 0)
286
goto bad;
287
288
/*
289
* Dispatch to the appropriate IPsec transform logic. The
290
* packet will be returned for transmission after crypto
291
* processing, etc. are completed.
292
*
293
* NB: m & sav are ``passed to caller'' who's responsible for
294
* reclaiming their resources.
295
*/
296
switch(dst->sa.sa_family) {
297
case AF_INET:
298
ip = mtod(m, struct ip *);
299
i = ip->ip_hl << 2;
300
off = offsetof(struct ip, ip_p);
301
break;
302
#ifdef INET6
303
case AF_INET6:
304
i = sizeof(struct ip6_hdr);
305
off = offsetof(struct ip6_hdr, ip6_nxt);
306
break;
307
#endif /* INET6 */
308
default:
309
DPRINTF(("%s: unsupported protocol family %u\n",
310
__func__, dst->sa.sa_family));
311
error = EPFNOSUPPORT;
312
IPSEC_OSTAT_INC(sav->sah->saidx.proto, nopf);
313
goto bad;
314
}
315
error = (*sav->tdb_xform->xf_output)(m, sp, sav, idx, i, off);
316
return (error);
317
bad:
318
IPSECSTAT_INC(ips_out_inval);
319
if (m != NULL)
320
m_freem(m);
321
if (sav != NULL)
322
key_freesav(&sav);
323
key_freesp(&sp);
324
return (error);
325
}
326
327
int
328
ipsec4_process_packet(struct ifnet *ifp, struct mbuf *m, struct ip *ip1,
329
struct secpolicy *sp, struct inpcb *inp, u_long mtu)
330
{
331
332
return (ipsec4_perform_request(ifp, m, ip1, sp, inp, 0, mtu));
333
}
334
335
int
336
ipsec4_check_pmtu(struct ifnet *ifp, struct mbuf *m, struct ip *ip1,
337
struct secpolicy *sp, int forwarding)
338
{
339
struct secasvar *sav;
340
size_t hlen, pmtu;
341
uint32_t idx;
342
int error;
343
344
/* Don't check PMTU if the frame won't have DF bit set. */
345
if (!V_ip4_ipsec_dfbit)
346
return (0);
347
if (V_ip4_ipsec_dfbit == 1)
348
goto setdf;
349
350
/* V_ip4_ipsec_dfbit > 1 - we will copy it from inner header. */
351
if ((ip1->ip_off & htons(IP_DF)) == 0)
352
return (0);
353
354
setdf:
355
idx = sp->tcount - 1;
356
sav = ipsec4_allocsa(ifp, m, ip1, sp, &idx, &error);
357
if (sav == NULL) {
358
key_freesp(&sp);
359
/*
360
* No matching SA was found and SADB_ACQUIRE message was generated.
361
* Since we have matched a SP to this packet drop it silently.
362
*/
363
if (error == 0)
364
error = EINPROGRESS;
365
if (error != EJUSTRETURN)
366
m_freem(m);
367
368
return (error);
369
}
370
371
pmtu = ipsec_get_pmtu(sav);
372
if (pmtu == 0) {
373
key_freesav(&sav);
374
return (0);
375
}
376
377
hlen = ipsec_hdrsiz_internal(sp);
378
key_freesav(&sav);
379
380
if (m_length(m, NULL) + hlen > pmtu) {
381
/*
382
* If we're forwarding generate ICMP message here,
383
* so that it contains pmtu subtracted by header size.
384
* Set error to EINPROGRESS, in order for the frame
385
* to be dropped silently.
386
*/
387
if (forwarding) {
388
if (pmtu > hlen)
389
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
390
0, pmtu - hlen);
391
else
392
m_freem(m);
393
394
key_freesp(&sp);
395
return (EINPROGRESS); /* Pretend that we consumed it. */
396
} else {
397
m_freem(m);
398
key_freesp(&sp);
399
return (EMSGSIZE);
400
}
401
}
402
403
return (0);
404
}
405
406
static int
407
ipsec4_common_output1(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
408
struct ip *ip1, int forwarding, u_long mtu)
409
{
410
struct secpolicy *sp;
411
int error;
412
413
/* Lookup for the corresponding outbound security policy */
414
sp = ipsec4_checkpolicy(m, inp, ip1, &error, !forwarding);
415
if (sp == NULL) {
416
if (error == -EINVAL) {
417
/* Discarded by policy. */
418
m_freem(m);
419
return (EACCES);
420
}
421
return (0); /* No IPsec required. */
422
}
423
424
/*
425
* Usually we have to have tunnel mode IPsec security policy
426
* when we are forwarding a packet. Otherwise we could not handle
427
* encrypted replies, because they are not destined for us. But
428
* some users are doing source address translation for forwarded
429
* packets, and thus, even if they are forwarded, the replies will
430
* return back to us.
431
*/
432
433
/* NB: callee frees mbuf and releases reference to SP */
434
error = ipsec4_check_pmtu(ifp, m, ip1, sp, forwarding);
435
if (error != 0) {
436
if (error == EJUSTRETURN)
437
return (0);
438
439
return (error);
440
}
441
442
error = ipsec4_process_packet(ifp, m, ip1, sp, inp, mtu);
443
if (error == EJUSTRETURN) {
444
/*
445
* We had a SP with a level of 'use' and no SA. We
446
* will just continue to process the packet without
447
* IPsec processing and return without error.
448
*/
449
return (0);
450
}
451
if (error == 0)
452
return (EINPROGRESS); /* consumed by IPsec */
453
return (error);
454
}
455
456
static int
457
ipsec4_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
458
struct ip *ip1, int forwarding, u_long mtu)
459
{
460
struct ip ip_hdr;
461
struct ip *ip;
462
463
if (((m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.len < sizeof(*ip)) ||
464
((m->m_flags & M_PKTHDR) == 0 && m->m_len < sizeof(*ip))) {
465
m_free(m);
466
return (EACCES);
467
}
468
if (ip1 != NULL) {
469
ip = ip1;
470
} else {
471
ip = &ip_hdr;
472
m_copydata(m, 0, sizeof(*ip), (char *)ip);
473
}
474
475
return (ipsec4_common_output1(ifp, m, inp, ip, forwarding, mtu));
476
}
477
478
/*
479
* IPSEC_OUTPUT() method implementation for IPv4.
480
* 0 - no IPsec handling needed
481
* other values - mbuf consumed by IPsec.
482
*/
483
int
484
ipsec4_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp, u_long mtu)
485
{
486
487
/*
488
* If the packet is resubmitted to ip_output (e.g. after
489
* AH, ESP, etc. processing), there will be a tag to bypass
490
* the lookup and related policy checking.
491
*/
492
if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL)
493
return (0);
494
495
return (ipsec4_common_output(ifp, m, inp, NULL, 0, mtu));
496
}
497
498
/*
499
* IPSEC_FORWARD() method implementation for IPv4.
500
* 0 - no IPsec handling needed
501
* other values - mbuf consumed by IPsec.
502
*/
503
int
504
ipsec4_forward(struct mbuf *m)
505
{
506
struct ip ip_hdr;
507
508
m_copydata(m, 0, sizeof(ip_hdr), (char *)&ip_hdr);
509
510
/*
511
* Check if this packet has an active inbound SP and needs to be
512
* dropped instead of forwarded.
513
*/
514
if (ipsec4_in_reject1(m, &ip_hdr, NULL) != 0) {
515
m_freem(m);
516
return (EACCES);
517
}
518
return (ipsec4_common_output(NULL /* XXXKIB */, m, NULL, &ip_hdr,
519
1, 0));
520
}
521
#endif
522
523
#ifdef INET6
524
static int
525
in6_sa_equal_addrwithscope(const struct sockaddr_in6 *sa,
526
const struct in6_addr *ia)
527
{
528
struct in6_addr ia2;
529
530
if (IN6_IS_SCOPE_LINKLOCAL(&sa->sin6_addr)) {
531
memcpy(&ia2, &sa->sin6_addr, sizeof(ia2));
532
ia2.s6_addr16[1] = htons(sa->sin6_scope_id);
533
return (IN6_ARE_ADDR_EQUAL(ia, &ia2));
534
}
535
return (IN6_ARE_ADDR_EQUAL(&sa->sin6_addr, ia));
536
}
537
538
static struct secasvar *
539
ipsec6_allocsa(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
540
u_int *pidx, int *error)
541
{
542
struct secasindex *saidx, tmpsaidx;
543
struct ipsecrequest *isr;
544
struct sockaddr_in6 *sin6;
545
struct secasvar *sav;
546
struct ip6_hdr *ip6;
547
548
/*
549
* Check system global policy controls.
550
*/
551
next:
552
isr = sp->req[*pidx];
553
if ((isr->saidx.proto == IPPROTO_ESP && !V_esp_enable) ||
554
(isr->saidx.proto == IPPROTO_AH && !V_ah_enable) ||
555
(isr->saidx.proto == IPPROTO_IPCOMP && !V_ipcomp_enable)) {
556
DPRINTF(("%s: IPsec outbound packet dropped due"
557
" to policy (check your sysctls)\n", __func__));
558
IPSEC_OSTAT_INC(isr->saidx.proto, pdrops);
559
*error = EHOSTUNREACH;
560
return (NULL);
561
}
562
/*
563
* Craft SA index to search for proper SA. Note that
564
* we only fillin unspecified SA peers for transport
565
* mode; for tunnel mode they must already be filled in.
566
*/
567
if (isr->saidx.mode == IPSEC_MODE_TRANSPORT) {
568
saidx = &tmpsaidx;
569
*saidx = isr->saidx;
570
ip6 = mtod(m, struct ip6_hdr *);
571
if (saidx->src.sin6.sin6_len == 0) {
572
sin6 = (struct sockaddr_in6 *)&saidx->src;
573
sin6->sin6_len = sizeof(*sin6);
574
sin6->sin6_family = AF_INET6;
575
sin6->sin6_port = IPSEC_PORT_ANY;
576
sin6->sin6_addr = ip6->ip6_src;
577
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
578
/* fix scope id for comparing SPD */
579
sin6->sin6_addr.s6_addr16[1] = 0;
580
sin6->sin6_scope_id =
581
ntohs(ip6->ip6_src.s6_addr16[1]);
582
}
583
}
584
if (saidx->dst.sin6.sin6_len == 0) {
585
sin6 = (struct sockaddr_in6 *)&saidx->dst;
586
sin6->sin6_len = sizeof(*sin6);
587
sin6->sin6_family = AF_INET6;
588
sin6->sin6_port = IPSEC_PORT_ANY;
589
sin6->sin6_addr = ip6->ip6_dst;
590
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
591
/* fix scope id for comparing SPD */
592
sin6->sin6_addr.s6_addr16[1] = 0;
593
sin6->sin6_scope_id =
594
ntohs(ip6->ip6_dst.s6_addr16[1]);
595
}
596
}
597
} else
598
saidx = &sp->req[*pidx]->saidx;
599
/*
600
* Lookup SA and validate it.
601
*/
602
sav = key_allocsa_policy(sp, saidx, error);
603
if (sav == NULL) {
604
IPSEC6STAT_INC(ips_out_nosa);
605
if (*error != 0)
606
return (NULL);
607
if (ipsec_get_reqlevel(sp, *pidx) != IPSEC_LEVEL_REQUIRE) {
608
/*
609
* We have no SA and policy that doesn't require
610
* this IPsec transform, thus we can continue w/o
611
* IPsec processing, i.e. return EJUSTRETURN.
612
* But first check if there is some bundled transform.
613
*/
614
if (sp->tcount > ++(*pidx))
615
goto next;
616
*error = EJUSTRETURN;
617
}
618
return (NULL);
619
}
620
IPSEC_ASSERT(sav->tdb_xform != NULL, ("SA with NULL tdb_xform"));
621
return (sav);
622
}
623
624
/*
625
* IPsec output logic for IPv6.
626
*/
627
static int
628
ipsec6_perform_request(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
629
struct inpcb *inp, u_int idx, u_long mtu)
630
{
631
struct ipsec_ctx_data ctx;
632
union sockaddr_union *dst;
633
struct secasvar *sav;
634
struct ip6_hdr *ip6;
635
int error, hwassist, i, off;
636
bool accel;
637
638
IPSEC_ASSERT(idx < sp->tcount, ("Wrong IPsec request index %d", idx));
639
640
sav = ipsec6_allocsa(ifp, m, sp, &idx, &error);
641
if (sav == NULL) {
642
if (error == EJUSTRETURN) { /* No IPsec required */
643
(void)ipsec_accel_output(ifp, m, inp, sp, NULL,
644
AF_INET6, mtu, &hwassist);
645
key_freesp(&sp);
646
return (error);
647
}
648
goto bad;
649
}
650
651
/* Fix IP length in case if it is not set yet. */
652
ip6 = mtod(m, struct ip6_hdr *);
653
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
654
655
IPSEC_INIT_CTX(&ctx, &m, inp, sav, AF_INET6, IPSEC_ENC_BEFORE);
656
if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_OUT)) != 0)
657
goto bad;
658
659
hwassist = 0;
660
accel = ipsec_accel_output(ifp, m, inp, sp, sav, AF_INET6, mtu,
661
&hwassist);
662
663
/*
664
* Do delayed checksums now because we send before
665
* this is done in the normal processing path.
666
*/
667
if ((m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6 & ~hwassist) != 0) {
668
in6_delayed_cksum(m, m->m_pkthdr.len -
669
sizeof(struct ip6_hdr), sizeof(struct ip6_hdr));
670
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
671
}
672
#if defined(SCTP) || defined(SCTP_SUPPORT)
673
if ((m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6 & ~hwassist) != 0) {
674
sctp_delayed_cksum(m, sizeof(struct ip6_hdr));
675
m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6;
676
}
677
#endif
678
if (accel)
679
return (EJUSTRETURN);
680
681
ip6 = mtod(m, struct ip6_hdr *); /* pfil can change mbuf */
682
dst = &sav->sah->saidx.dst;
683
684
/* Do the appropriate encapsulation, if necessary */
685
if (sp->req[idx]->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */
686
dst->sa.sa_family != AF_INET6 || /* PF mismatch */
687
((dst->sa.sa_family == AF_INET6) &&
688
(!IN6_IS_ADDR_UNSPECIFIED(&dst->sin6.sin6_addr)) &&
689
(!in6_sa_equal_addrwithscope(&dst->sin6, &ip6->ip6_dst)))) {
690
if (m->m_pkthdr.len - sizeof(*ip6) > IPV6_MAXPACKET) {
691
/* No jumbogram support. */
692
error = ENXIO; /*XXX*/
693
goto bad;
694
}
695
error = ipsec_encap(&m, &sav->sah->saidx);
696
if (error != 0) {
697
DPRINTF(("%s: encapsulation for SPI 0x%08x failed "
698
"with error %d\n", __func__, ntohl(sav->spi),
699
error));
700
/* XXXAE: IPSEC_OSTAT_INC(tunnel); */
701
goto bad;
702
}
703
inp = NULL;
704
}
705
706
IPSEC_INIT_CTX(&ctx, &m, inp, sav, dst->sa.sa_family, IPSEC_ENC_AFTER);
707
if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_OUT)) != 0)
708
goto bad;
709
710
switch(dst->sa.sa_family) {
711
#ifdef INET
712
case AF_INET:
713
{
714
struct ip *ip;
715
ip = mtod(m, struct ip *);
716
i = ip->ip_hl << 2;
717
off = offsetof(struct ip, ip_p);
718
}
719
break;
720
#endif /* AF_INET */
721
case AF_INET6:
722
i = sizeof(struct ip6_hdr);
723
off = offsetof(struct ip6_hdr, ip6_nxt);
724
break;
725
default:
726
DPRINTF(("%s: unsupported protocol family %u\n",
727
__func__, dst->sa.sa_family));
728
error = EPFNOSUPPORT;
729
IPSEC_OSTAT_INC(sav->sah->saidx.proto, nopf);
730
goto bad;
731
}
732
error = (*sav->tdb_xform->xf_output)(m, sp, sav, idx, i, off);
733
return (error);
734
bad:
735
IPSEC6STAT_INC(ips_out_inval);
736
if (m != NULL)
737
m_freem(m);
738
if (sav != NULL)
739
key_freesav(&sav);
740
key_freesp(&sp);
741
return (error);
742
}
743
744
int
745
ipsec6_process_packet(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
746
struct inpcb *inp, u_long mtu)
747
{
748
749
return (ipsec6_perform_request(ifp, m, sp, inp, 0, mtu));
750
}
751
752
/*
753
* IPv6 implementation is based on IPv4 implementation.
754
*/
755
int
756
ipsec6_check_pmtu(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
757
int forwarding)
758
{
759
struct secasvar *sav;
760
size_t hlen, pmtu;
761
uint32_t idx;
762
int error;
763
764
/*
765
* According to RFC8200 L3 fragmentation is supposed to be done only on
766
* locally generated packets. During L3 forwarding packets that are too
767
* big are always supposed to be dropped, with an ICMPv6 packet being
768
* sent back.
769
*/
770
if (!forwarding)
771
return (0);
772
773
idx = sp->tcount - 1;
774
sav = ipsec6_allocsa(ifp, m, sp, &idx, &error);
775
if (sav == NULL) {
776
key_freesp(&sp);
777
/*
778
* No matching SA was found and SADB_ACQUIRE message was generated.
779
* Since we have matched a SP to this packet drop it silently.
780
*/
781
if (error == 0)
782
error = EINPROGRESS;
783
if (error != EJUSTRETURN)
784
m_freem(m);
785
786
return (error);
787
}
788
789
pmtu = ipsec_get_pmtu(sav);
790
if (pmtu == 0) {
791
key_freesav(&sav);
792
return (0);
793
}
794
795
hlen = ipsec_hdrsiz_internal(sp);
796
key_freesav(&sav);
797
798
if (m_length(m, NULL) + hlen > pmtu) {
799
/*
800
* If we're forwarding generate ICMPv6 message here,
801
* so that it contains pmtu subtracted by header size.
802
* Set error to EINPROGRESS, in order for the frame
803
* to be dropped silently.
804
*/
805
if (forwarding) {
806
if (pmtu > hlen)
807
icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0, pmtu - hlen);
808
else
809
m_freem(m);
810
811
key_freesp(&sp);
812
return (EINPROGRESS); /* Pretend that we consumed it. */
813
}
814
}
815
816
return (0);
817
}
818
819
static int
820
ipsec6_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
821
int forwarding, u_long mtu)
822
{
823
struct secpolicy *sp;
824
int error;
825
826
/* Lookup for the corresponding outbound security policy */
827
sp = ipsec6_checkpolicy(m, inp, &error, !forwarding);
828
if (sp == NULL) {
829
if (error == -EINVAL) {
830
/* Discarded by policy. */
831
m_freem(m);
832
return (EACCES);
833
}
834
return (0); /* No IPsec required. */
835
}
836
837
error = ipsec6_check_pmtu(ifp, m, sp, forwarding);
838
if (error != 0) {
839
if (error == EJUSTRETURN)
840
return (0);
841
842
return (error);
843
}
844
845
/* NB: callee frees mbuf and releases reference to SP */
846
error = ipsec6_process_packet(ifp, m, sp, inp, mtu);
847
if (error == EJUSTRETURN) {
848
/*
849
* We had a SP with a level of 'use' and no SA. We
850
* will just continue to process the packet without
851
* IPsec processing and return without error.
852
*/
853
return (0);
854
}
855
if (error == 0)
856
return (EINPROGRESS); /* consumed by IPsec */
857
return (error);
858
}
859
860
/*
861
* IPSEC_OUTPUT() method implementation for IPv6.
862
* 0 - no IPsec handling needed
863
* other values - mbuf consumed by IPsec.
864
*/
865
int
866
ipsec6_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp, u_long mtu)
867
{
868
869
/*
870
* If the packet is resubmitted to ip_output (e.g. after
871
* AH, ESP, etc. processing), there will be a tag to bypass
872
* the lookup and related policy checking.
873
*/
874
if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL)
875
return (0);
876
877
return (ipsec6_common_output(ifp, m, inp, 0, mtu));
878
}
879
880
/*
881
* IPSEC_FORWARD() method implementation for IPv6.
882
* 0 - no IPsec handling needed
883
* other values - mbuf consumed by IPsec.
884
*/
885
int
886
ipsec6_forward(struct mbuf *m)
887
{
888
889
/*
890
* Check if this packet has an active inbound SP and needs to be
891
* dropped instead of forwarded.
892
*/
893
if (ipsec6_in_reject(m, NULL) != 0) {
894
m_freem(m);
895
return (EACCES);
896
}
897
return (ipsec6_common_output(NULL /* XXXKIB */, m, NULL, 1, 0));
898
}
899
#endif /* INET6 */
900
901
int
902
ipsec_process_done(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
903
u_int idx)
904
{
905
struct epoch_tracker et;
906
struct xform_history *xh;
907
struct secasindex *saidx;
908
struct m_tag *mtag;
909
#ifdef INET
910
struct ip *ip;
911
#endif
912
int error;
913
914
if (sav->state >= SADB_SASTATE_DEAD) {
915
error = ESRCH;
916
goto bad;
917
}
918
saidx = &sav->sah->saidx;
919
switch (saidx->dst.sa.sa_family) {
920
#ifdef INET
921
case AF_INET:
922
ip = mtod(m, struct ip *);
923
/* Fix the header length, for AH processing. */
924
ip->ip_len = htons(m->m_pkthdr.len);
925
break;
926
#endif /* INET */
927
#ifdef INET6
928
case AF_INET6:
929
/* Fix the header length, for AH processing. */
930
if (m->m_pkthdr.len < sizeof (struct ip6_hdr)) {
931
error = ENXIO;
932
goto bad;
933
}
934
if (m->m_pkthdr.len - sizeof (struct ip6_hdr) > IPV6_MAXPACKET) {
935
/* No jumbogram support. */
936
error = ENXIO; /*?*/
937
goto bad;
938
}
939
mtod(m, struct ip6_hdr *)->ip6_plen =
940
htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
941
break;
942
#endif /* INET6 */
943
default:
944
DPRINTF(("%s: unknown protocol family %u\n", __func__,
945
saidx->dst.sa.sa_family));
946
error = ENXIO;
947
goto bad;
948
}
949
950
/*
951
* Add a record of what we've done to the packet.
952
*/
953
mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_DONE, sizeof(*xh), M_NOWAIT);
954
if (mtag == NULL) {
955
DPRINTF(("%s: could not get packet tag\n", __func__));
956
error = ENOMEM;
957
goto bad;
958
}
959
960
xh = (struct xform_history *)(mtag + 1);
961
xh->dst = saidx->dst;
962
xh->proto = saidx->proto;
963
xh->mode = saidx->mode;
964
xh->spi = sav->spi;
965
m_tag_prepend(m, mtag);
966
967
key_sa_recordxfer(sav, m); /* record data transfer */
968
969
/*
970
* If there's another (bundled) SA to apply, do so.
971
* Note that this puts a burden on the kernel stack size.
972
* If this is a problem we'll need to introduce a queue
973
* to set the packet on so we can unwind the stack before
974
* doing further processing.
975
*/
976
if (++idx < sp->tcount) {
977
switch (saidx->dst.sa.sa_family) {
978
#ifdef INET
979
case AF_INET:
980
key_freesav(&sav);
981
IPSECSTAT_INC(ips_out_bundlesa);
982
return (ipsec4_perform_request(NULL, m, ip, sp, NULL,
983
idx, 0));
984
/* NOTREACHED */
985
#endif
986
#ifdef INET6
987
case AF_INET6:
988
key_freesav(&sav);
989
IPSEC6STAT_INC(ips_out_bundlesa);
990
return (ipsec6_perform_request(NULL, m, sp, NULL,
991
idx, 0));
992
/* NOTREACHED */
993
#endif /* INET6 */
994
default:
995
DPRINTF(("%s: unknown protocol family %u\n", __func__,
996
saidx->dst.sa.sa_family));
997
error = EPFNOSUPPORT;
998
goto bad;
999
}
1000
}
1001
1002
key_freesp(&sp), sp = NULL; /* Release reference to SP */
1003
#if defined(INET) || defined(INET6)
1004
/*
1005
* Do UDP encapsulation if SA requires it.
1006
*/
1007
if (sav->natt != NULL) {
1008
error = udp_ipsec_output(m, sav);
1009
if (error != 0)
1010
goto bad;
1011
}
1012
#endif /* INET || INET6 */
1013
/*
1014
* We're done with IPsec processing, transmit the packet using the
1015
* appropriate network protocol (IP or IPv6).
1016
*/
1017
NET_EPOCH_ENTER(et);
1018
switch (saidx->dst.sa.sa_family) {
1019
#ifdef INET
1020
case AF_INET:
1021
key_freesav(&sav);
1022
error = ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL);
1023
break;
1024
#endif /* INET */
1025
#ifdef INET6
1026
case AF_INET6:
1027
key_freesav(&sav);
1028
error = ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
1029
break;
1030
#endif /* INET6 */
1031
default:
1032
panic("ipsec_process_done");
1033
}
1034
NET_EPOCH_EXIT(et);
1035
return (error);
1036
bad:
1037
m_freem(m);
1038
key_freesav(&sav);
1039
if (sp != NULL)
1040
key_freesp(&sp);
1041
return (error);
1042
}
1043
1044
/*
1045
* ipsec_prepend() is optimized version of M_PREPEND().
1046
* ipsec_encap() is called by IPsec output routine for tunnel mode SA.
1047
* It is expected that after IP encapsulation some IPsec transform will
1048
* be performed. Each IPsec transform inserts its variable length header
1049
* just after outer IP header using m_makespace(). If given mbuf has not
1050
* enough free space at the beginning, we allocate new mbuf and reserve
1051
* some space at the beginning and at the end.
1052
* This helps avoid allocating of new mbuf and data copying in m_makespace(),
1053
* we place outer header in the middle of mbuf's data with reserved leading
1054
* and trailing space:
1055
* [ LEADINGSPACE ][ Outer IP header ][ TRAILINGSPACE ]
1056
* LEADINGSPACE will be used to add ethernet header, TRAILINGSPACE will
1057
* be used to inject AH/ESP/IPCOMP header.
1058
*/
1059
#define IPSEC_TRAILINGSPACE (sizeof(struct udphdr) +/* NAT-T */ \
1060
max(sizeof(struct newesp) + EALG_MAX_BLOCK_LEN, /* ESP + IV */ \
1061
sizeof(struct newah) + HASH_MAX_LEN /* AH + ICV */))
1062
static struct mbuf *
1063
ipsec_prepend(struct mbuf *m, int len, int how)
1064
{
1065
struct mbuf *n;
1066
1067
M_ASSERTPKTHDR(m);
1068
IPSEC_ASSERT(len < MHLEN, ("wrong length"));
1069
if (M_LEADINGSPACE(m) >= len) {
1070
/* No need to allocate new mbuf. */
1071
m->m_data -= len;
1072
m->m_len += len;
1073
m->m_pkthdr.len += len;
1074
return (m);
1075
}
1076
n = m_gethdr(how, m->m_type);
1077
if (n == NULL) {
1078
m_freem(m);
1079
return (NULL);
1080
}
1081
m_move_pkthdr(n, m);
1082
n->m_next = m;
1083
if (len + IPSEC_TRAILINGSPACE < M_SIZE(n))
1084
m_align(n, len + IPSEC_TRAILINGSPACE);
1085
n->m_len = len;
1086
n->m_pkthdr.len += len;
1087
return (n);
1088
}
1089
1090
static size_t
1091
ipsec_get_pmtu(struct secasvar *sav)
1092
{
1093
union sockaddr_union *dst;
1094
struct in_conninfo inc;
1095
size_t pmtu;
1096
1097
dst = &sav->sah->saidx.dst;
1098
memset(&inc, 0, sizeof(inc));
1099
1100
switch (dst->sa.sa_family) {
1101
#ifdef INET
1102
case AF_INET:
1103
inc.inc_faddr = satosin(&dst->sa)->sin_addr;
1104
break;
1105
#endif
1106
#ifdef INET6
1107
case AF_INET6:
1108
inc.inc6_faddr = satosin6(&dst->sa)->sin6_addr;
1109
inc.inc_flags |= INC_ISIPV6;
1110
break;
1111
#endif
1112
default:
1113
return (0);
1114
}
1115
1116
pmtu = tcp_hc_getmtu(&inc);
1117
if (pmtu != 0)
1118
return (pmtu);
1119
1120
/* No entry in hostcache. Assume that PMTU is equal to link's MTU */
1121
switch (dst->sa.sa_family) {
1122
#ifdef INET
1123
case AF_INET:
1124
pmtu = tcp_maxmtu(&inc, NULL);
1125
break;
1126
#endif
1127
#ifdef INET6
1128
case AF_INET6:
1129
pmtu = tcp_maxmtu6(&inc, NULL);
1130
break;
1131
#endif
1132
default:
1133
return (0);
1134
}
1135
if (pmtu == 0)
1136
return (0);
1137
1138
tcp_hc_updatemtu(&inc, pmtu);
1139
1140
return (pmtu);
1141
}
1142
1143
static int
1144
ipsec_encap(struct mbuf **mp, struct secasindex *saidx)
1145
{
1146
#ifdef INET6
1147
struct ip6_hdr *ip6;
1148
#endif
1149
struct ip *ip;
1150
#ifdef INET
1151
int setdf = V_ip4_ipsec_dfbit == 1 ? 1: 0;
1152
#endif
1153
uint8_t itos, proto;
1154
1155
ip = mtod(*mp, struct ip *);
1156
switch (ip->ip_v) {
1157
#ifdef INET
1158
case IPVERSION:
1159
proto = IPPROTO_IPIP;
1160
/*
1161
* Copy IP_DF flag from the inner header if
1162
* system-wide control variable is greater than 1.
1163
*/
1164
if (V_ip4_ipsec_dfbit > 1)
1165
setdf = (ip->ip_off & htons(IP_DF)) != 0;
1166
itos = ip->ip_tos;
1167
break;
1168
#endif
1169
#ifdef INET6
1170
case (IPV6_VERSION >> 4):
1171
proto = IPPROTO_IPV6;
1172
ip6 = mtod(*mp, struct ip6_hdr *);
1173
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
1174
/* scoped address handling */
1175
in6_clearscope(&ip6->ip6_src);
1176
in6_clearscope(&ip6->ip6_dst);
1177
break;
1178
#endif
1179
default:
1180
return (EAFNOSUPPORT);
1181
}
1182
switch (saidx->dst.sa.sa_family) {
1183
#ifdef INET
1184
case AF_INET:
1185
if (saidx->src.sa.sa_family != AF_INET ||
1186
saidx->src.sin.sin_addr.s_addr == INADDR_ANY ||
1187
saidx->dst.sin.sin_addr.s_addr == INADDR_ANY)
1188
return (EINVAL);
1189
*mp = ipsec_prepend(*mp, sizeof(struct ip), M_NOWAIT);
1190
if (*mp == NULL)
1191
return (ENOBUFS);
1192
ip = mtod(*mp, struct ip *);
1193
ip->ip_v = IPVERSION;
1194
ip->ip_hl = sizeof(struct ip) >> 2;
1195
ip->ip_p = proto;
1196
ip->ip_len = htons((*mp)->m_pkthdr.len);
1197
ip->ip_ttl = V_ip_defttl;
1198
ip->ip_sum = 0;
1199
ip->ip_off = setdf ? htons(IP_DF): 0;
1200
ip->ip_src = saidx->src.sin.sin_addr;
1201
ip->ip_dst = saidx->dst.sin.sin_addr;
1202
ip_ecn_ingress(V_ip4_ipsec_ecn, &ip->ip_tos, &itos);
1203
ip_fillid(ip, V_ip4_ipsec_random_id);
1204
break;
1205
#endif /* INET */
1206
#ifdef INET6
1207
case AF_INET6:
1208
if (saidx->src.sa.sa_family != AF_INET6 ||
1209
IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr) ||
1210
IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr))
1211
return (EINVAL);
1212
*mp = ipsec_prepend(*mp, sizeof(struct ip6_hdr), M_NOWAIT);
1213
if (*mp == NULL)
1214
return (ENOBUFS);
1215
ip6 = mtod(*mp, struct ip6_hdr *);
1216
ip6->ip6_flow = 0;
1217
ip6->ip6_vfc = IPV6_VERSION;
1218
ip6->ip6_hlim = V_ip6_defhlim;
1219
ip6->ip6_nxt = proto;
1220
ip6->ip6_dst = saidx->dst.sin6.sin6_addr;
1221
/* For link-local address embed scope zone id */
1222
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
1223
ip6->ip6_dst.s6_addr16[1] =
1224
htons(saidx->dst.sin6.sin6_scope_id & 0xffff);
1225
ip6->ip6_src = saidx->src.sin6.sin6_addr;
1226
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
1227
ip6->ip6_src.s6_addr16[1] =
1228
htons(saidx->src.sin6.sin6_scope_id & 0xffff);
1229
ip6->ip6_plen = htons((*mp)->m_pkthdr.len - sizeof(*ip6));
1230
ip_ecn_ingress(V_ip6_ipsec_ecn, &proto, &itos);
1231
ip6->ip6_flow |= htonl((uint32_t)proto << 20);
1232
break;
1233
#endif /* INET6 */
1234
default:
1235
return (EAFNOSUPPORT);
1236
}
1237
(*mp)->m_flags &= ~(M_BCAST | M_MCAST);
1238
return (0);
1239
}
1240
1241