No empty .Rs/.Re
[netbsd-mini2440.git] / sys / netinet6 / ipsec.c
blobaa6284ae50a583d8804647f617869c2b54715a32
1 /* $NetBSD: ipsec.c,v 1.142 2009/05/07 21:51:47 elad Exp $ */
2 /* $KAME: ipsec.c,v 1.136 2002/05/19 00:36:39 itojun Exp $ */
4 /*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
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 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
34 * IPsec controller part.
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.142 2009/05/07 21:51:47 elad Exp $");
40 #include "opt_inet.h"
41 #include "opt_ipsec.h"
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/malloc.h>
46 #include <sys/mbuf.h>
47 #include <sys/domain.h>
48 #include <sys/protosw.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/errno.h>
52 #include <sys/time.h>
53 #include <sys/kernel.h>
54 #include <sys/syslog.h>
55 #include <sys/sysctl.h>
56 #include <sys/once.h>
57 #include <sys/uidinfo.h>
58 #include <sys/kauth.h>
60 #include <net/if.h>
61 #include <net/route.h>
63 #include <netinet/in.h>
64 #include <netinet/in_systm.h>
65 #include <netinet/ip.h>
66 #include <netinet/ip_var.h>
67 #include <netinet/ip_private.h>
68 #include <netinet/in_var.h>
69 #include <netinet/udp.h>
70 #include <netinet/udp_var.h>
71 #include <netinet/ip_ecn.h>
72 #include <netinet/tcp.h>
73 #include <netinet/ip_icmp.h>
75 #include <netinet/ip6.h>
76 #ifdef INET6
77 #include <netinet6/ip6_var.h>
78 #include <netinet6/ip6_private.h>
79 #endif
80 #include <netinet/in_pcb.h>
81 #ifdef INET6
82 #include <netinet6/in6_pcb.h>
83 #include <netinet/icmp6.h>
84 #include <netinet6/scope6_var.h>
85 #endif
87 #include <netinet6/ipsec.h>
88 #include <netinet6/ipsec_private.h>
89 #include <netinet6/ah.h>
90 #ifdef IPSEC_ESP
91 #include <netinet6/esp.h>
92 #endif
93 #include <netinet6/ipcomp.h>
94 #include <netkey/key.h>
95 #include <netkey/keydb.h>
96 #include <netkey/key_debug.h>
98 #include <net/net_osdep.h>
100 #ifdef IPSEC_DEBUG
101 int ipsec_debug = 1;
102 #else
103 int ipsec_debug = 0;
104 #endif
106 percpu_t *ipsecstat_percpu;
107 int ip4_ah_cleartos = 1;
108 int ip4_ah_offsetmask = 0; /* maybe IP_DF? */
109 int ip4_ipsec_dfbit = 2; /* DF bit on encap. 0: clear 1: set 2: copy */
110 int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
111 int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
112 int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
113 int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
114 struct secpolicy *ip4_def_policy;
115 int ip4_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
117 #ifdef INET6
118 percpu_t *ipsec6stat_percpu;
119 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
120 int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
121 int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
122 int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
123 struct secpolicy *ip6_def_policy;
124 int ip6_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
126 #endif /* INET6 */
128 u_int ipsec_spdgen = 1; /* SPD generation # */
130 #ifdef SADB_X_EXT_TAG
131 static struct pf_tag *ipsec_get_tag(struct mbuf *);
132 #endif
133 static struct secpolicy *ipsec_checkpcbcache(struct mbuf *,
134 struct inpcbpolicy *, int);
135 static int ipsec_fillpcbcache(struct inpcbpolicy *, struct mbuf *,
136 struct secpolicy *, int);
137 static int ipsec_invalpcbcache(struct inpcbpolicy *, int);
138 static int ipsec_setspidx_mbuf
139 (struct secpolicyindex *, int, struct mbuf *, int);
140 static int ipsec_setspidx(struct mbuf *, struct secpolicyindex *, int);
141 static void ipsec4_get_ulp(struct mbuf *, struct secpolicyindex *, int);
142 static int ipsec4_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
143 #ifdef INET6
144 static void ipsec6_get_ulp(struct mbuf *, struct secpolicyindex *, int);
145 static int ipsec6_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
146 #endif
147 static struct inpcbpolicy *ipsec_newpcbpolicy(void);
148 static void ipsec_delpcbpolicy(struct inpcbpolicy *);
149 #if 0
150 static int ipsec_deepcopy_pcbpolicy(struct inpcbpolicy *);
151 #endif
152 static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *);
153 static int ipsec_set_policy
154 (struct secpolicy **, int, void *, size_t, kauth_cred_t);
155 static int ipsec_get_policy(struct secpolicy *, struct mbuf **);
156 static void vshiftl(unsigned char *, int, int);
157 static int ipsec_in_reject(struct secpolicy *, struct mbuf *);
158 static size_t ipsec_hdrsiz(struct secpolicy *);
159 #ifdef INET
160 static struct mbuf *ipsec4_splithdr(struct mbuf *);
161 #endif
162 #ifdef INET6
163 static struct mbuf *ipsec6_splithdr(struct mbuf *);
164 #endif
165 #ifdef INET
166 static int ipsec4_encapsulate(struct mbuf *, struct secasvar *);
167 #endif
168 #ifdef INET6
169 static int ipsec6_encapsulate(struct mbuf *, struct secasvar *);
170 #endif
171 static struct m_tag *ipsec_addaux(struct mbuf *);
172 static struct m_tag *ipsec_findaux(struct mbuf *);
173 static void ipsec_optaux(struct mbuf *, struct m_tag *);
174 #ifdef INET
175 static int ipsec4_checksa(struct ipsecrequest *,
176 struct ipsec_output_state *);
177 #endif
178 #ifdef INET6
179 static int ipsec6_checksa(struct ipsecrequest *,
180 struct ipsec_output_state *, int);
181 #endif
183 #ifdef INET
184 static int
185 ipsec4_do_init(void)
188 ipsecstat_percpu = percpu_alloc(sizeof(uint64_t) * IPSEC_NSTATS);
189 return (0);
192 void
193 ipsec4_init(void)
195 static ONCE_DECL(ipsec4_init_once);
197 RUN_ONCE(&ipsec4_init_once, ipsec4_do_init);
199 #endif /* INET */
201 #ifdef INET6
202 static int
203 ipsec6_do_init(void)
206 ipsec6stat_percpu = percpu_alloc(sizeof(uint64_t) * IPSEC_NSTATS);
207 return (0);
210 void
211 ipsec6_init(void)
213 static ONCE_DECL(ipsec6_init_once);
215 RUN_ONCE(&ipsec6_init_once, ipsec6_do_init);
217 #endif /* INET6 */
220 * try to validate and use cached policy on a pcb.
222 static struct secpolicy *
223 ipsec_checkpcbcache(struct mbuf *m, struct inpcbpolicy *pcbsp, int dir)
225 struct secpolicyindex spidx;
226 struct bintime bt;
228 switch (dir) {
229 case IPSEC_DIR_INBOUND:
230 case IPSEC_DIR_OUTBOUND:
231 case IPSEC_DIR_ANY:
232 break;
233 default:
234 return NULL;
236 #ifdef DIAGNOSTIC
237 if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
238 panic("dir too big in ipsec_checkpcbcache");
239 #endif
240 /* SPD table change invalidates all the caches */
241 if (ipsec_spdgen != pcbsp->sp_cache[dir].cachegen) {
242 ipsec_invalpcbcache(pcbsp, dir);
243 return NULL;
245 if (!pcbsp->sp_cache[dir].cachesp)
246 return NULL;
247 if (pcbsp->sp_cache[dir].cachesp->state != IPSEC_SPSTATE_ALIVE) {
248 ipsec_invalpcbcache(pcbsp, dir);
249 return NULL;
251 if ((pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) == 0) {
252 if (!pcbsp->sp_cache[dir].cachesp)
253 return NULL;
254 if (ipsec_setspidx(m, &spidx, 1) != 0)
255 return NULL;
258 * We have to make an exact match here since the cached rule
259 * might have lower priority than a rule that would otherwise
260 * have matched the packet.
263 if (memcmp(&pcbsp->sp_cache[dir].cacheidx, &spidx, sizeof(spidx)))
264 return NULL;
266 } else {
268 * The pcb is connected, and the L4 code is sure that:
269 * - outgoing side uses inp_[lf]addr
270 * - incoming side looks up policy after inpcb lookup
271 * and address pair is known to be stable. We do not need
272 * to generate spidx again, nor check the address match again.
274 * For IPv4/v6 SOCK_STREAM sockets, this assumption holds
275 * and there are calls to ipsec_pcbconn() from in_pcbconnect().
279 getbinuptime(&bt);
280 pcbsp->sp_cache[dir].cachesp->lastused = bt.sec;
281 pcbsp->sp_cache[dir].cachesp->refcnt++;
282 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
283 printf("DP ipsec_checkpcbcache cause refcnt++:%d SP:%p\n",
284 pcbsp->sp_cache[dir].cachesp->refcnt,
285 pcbsp->sp_cache[dir].cachesp));
286 return pcbsp->sp_cache[dir].cachesp;
289 static int
290 ipsec_fillpcbcache(struct inpcbpolicy *pcbsp, struct mbuf *m,
291 struct secpolicy *sp, int dir)
294 switch (dir) {
295 case IPSEC_DIR_INBOUND:
296 case IPSEC_DIR_OUTBOUND:
297 break;
298 default:
299 return EINVAL;
301 #ifdef DIAGNOSTIC
302 if (dir >= sizeof(pcbsp->sp_cache)/sizeof(pcbsp->sp_cache[0]))
303 panic("dir too big in ipsec_checkpcbcache");
304 #endif
306 if (pcbsp->sp_cache[dir].cachesp)
307 key_freesp(pcbsp->sp_cache[dir].cachesp);
308 pcbsp->sp_cache[dir].cachesp = NULL;
309 pcbsp->sp_cache[dir].cachehint = IPSEC_PCBHINT_MAYBE;
310 if (ipsec_setspidx(m, &pcbsp->sp_cache[dir].cacheidx, 1) != 0) {
311 return EINVAL;
313 pcbsp->sp_cache[dir].cachesp = sp;
314 if (pcbsp->sp_cache[dir].cachesp) {
315 pcbsp->sp_cache[dir].cachesp->refcnt++;
316 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
317 printf("DP ipsec_fillpcbcache cause refcnt++:%d SP:%p\n",
318 pcbsp->sp_cache[dir].cachesp->refcnt,
319 pcbsp->sp_cache[dir].cachesp));
322 * If the PCB is connected, we can remember a hint to
323 * possibly short-circuit IPsec processing in other places.
325 if (pcbsp->sp_cacheflags & IPSEC_PCBSP_CONNECTED) {
326 switch (pcbsp->sp_cache[dir].cachesp->policy) {
327 case IPSEC_POLICY_NONE:
328 case IPSEC_POLICY_BYPASS:
329 pcbsp->sp_cache[dir].cachehint =
330 IPSEC_PCBHINT_NO;
331 break;
332 default:
333 pcbsp->sp_cache[dir].cachehint =
334 IPSEC_PCBHINT_YES;
338 pcbsp->sp_cache[dir].cachegen = ipsec_spdgen;
340 return 0;
343 static int
344 ipsec_invalpcbcache(struct inpcbpolicy *pcbsp, int dir)
346 int i;
348 for (i = IPSEC_DIR_INBOUND; i <= IPSEC_DIR_OUTBOUND; i++) {
349 if (dir != IPSEC_DIR_ANY && i != dir)
350 continue;
351 if (pcbsp->sp_cache[i].cachesp)
352 key_freesp(pcbsp->sp_cache[i].cachesp);
353 pcbsp->sp_cache[i].cachesp = NULL;
354 pcbsp->sp_cache[i].cachehint = IPSEC_PCBHINT_MAYBE;
355 pcbsp->sp_cache[i].cachegen = 0;
356 memset(&pcbsp->sp_cache[i].cacheidx, 0,
357 sizeof(pcbsp->sp_cache[i].cacheidx));
359 return 0;
363 ipsec_pcbconn(struct inpcbpolicy *pcbsp)
366 pcbsp->sp_cacheflags |= IPSEC_PCBSP_CONNECTED;
367 ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
368 return 0;
372 ipsec_pcbdisconn(struct inpcbpolicy *pcbsp)
375 pcbsp->sp_cacheflags &= ~IPSEC_PCBSP_CONNECTED;
376 ipsec_invalpcbcache(pcbsp, IPSEC_DIR_ANY);
377 return 0;
380 void
381 ipsec_invalpcbcacheall(void)
384 if (ipsec_spdgen == UINT_MAX)
385 ipsec_spdgen = 1;
386 else
387 ipsec_spdgen++;
390 #ifdef SADB_X_EXT_TAG
391 static struct pf_tag *
392 ipsec_get_tag(struct mbuf *m)
394 struct m_tag *mtag;
396 if ((mtag = m_tag_find(m, PACKET_TAG_PF_TAG, NULL)) != NULL)
397 return ((struct pf_tag *)(mtag + 1));
398 else
399 return (NULL);
401 #endif
404 * For OUTBOUND packet having a socket. Searching SPD for packet,
405 * and return a pointer to SP.
406 * OUT: NULL: no apropreate SP found, the following value is set to error.
407 * 0 : bypass
408 * EACCES : discard packet.
409 * ENOENT : ipsec_acquire() in progress, maybe.
410 * others : error occurred.
411 * others: a pointer to SP
413 * NOTE: IPv6 mapped address concern is implemented here.
415 struct secpolicy *
416 ipsec4_getpolicybysock(struct mbuf *m, u_int dir, struct socket *so,
417 int *error)
419 struct inpcbpolicy *pcbsp = NULL;
420 struct secpolicy *currsp = NULL; /* policy on socket */
421 struct secpolicy *kernsp = NULL; /* policy on kernel */
422 struct secpolicyindex spidx;
423 #ifdef SADB_X_EXT_TAG
424 struct pf_tag *t;
425 #endif
426 u_int16_t tag;
428 /* sanity check */
429 if (m == NULL || so == NULL || error == NULL)
430 panic("ipsec4_getpolicybysock: NULL pointer was passed.");
432 switch (so->so_proto->pr_domain->dom_family) {
433 case AF_INET:
434 pcbsp = sotoinpcb(so)->inp_sp;
435 break;
436 #ifdef INET6
437 case AF_INET6:
438 pcbsp = sotoin6pcb(so)->in6p_sp;
439 break;
440 #endif
441 default:
442 panic("ipsec4_getpolicybysock: unsupported address family");
445 #ifdef DIAGNOSTIC
446 if (pcbsp == NULL)
447 panic("ipsec4_getpolicybysock: pcbsp is NULL.");
448 #endif
450 #ifdef SADB_X_EXT_TAG
451 t = ipsec_get_tag(m);
452 tag = t ? t->tag : 0;
453 #else
454 tag = 0;
455 #endif
457 /* if we have a cached entry, and if it is still valid, use it. */
458 IPSEC_STATINC(IPSEC_STAT_SPDCACHELOOKUP);
459 currsp = ipsec_checkpcbcache(m, pcbsp, dir);
460 if (currsp) {
461 *error = 0;
462 return currsp;
464 IPSEC_STATINC(IPSEC_STAT_SPDCACHEMISS);
466 switch (dir) {
467 case IPSEC_DIR_INBOUND:
468 currsp = pcbsp->sp_in;
469 break;
470 case IPSEC_DIR_OUTBOUND:
471 currsp = pcbsp->sp_out;
472 break;
473 default:
474 panic("ipsec4_getpolicybysock: illegal direction.");
477 /* sanity check */
478 if (currsp == NULL)
479 panic("ipsec4_getpolicybysock: currsp is NULL.");
481 /* when privileged socket */
482 if (pcbsp->priv) {
483 switch (currsp->policy) {
484 case IPSEC_POLICY_BYPASS:
485 case IPSEC_POLICY_IPSEC:
486 currsp->refcnt++;
487 *error = 0;
488 ipsec_fillpcbcache(pcbsp, m, currsp, dir);
489 return currsp;
491 case IPSEC_POLICY_ENTRUST:
492 /* look for a policy in SPD */
493 if (ipsec_setspidx_mbuf(&spidx, AF_INET, m, 1) == 0 &&
494 (kernsp = key_allocsp(tag, &spidx, dir)) != NULL) {
495 /* SP found */
496 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
497 printf("DP ipsec4_getpolicybysock called "
498 "to allocate SP:%p\n", kernsp));
499 *error = 0;
500 ipsec_fillpcbcache(pcbsp, m, kernsp, dir);
501 return kernsp;
504 /* no SP found */
505 ip4_def_policy->refcnt++;
506 *error = 0;
507 ipsec_fillpcbcache(pcbsp, m, ip4_def_policy, dir);
508 return ip4_def_policy;
510 default:
511 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
512 "Invalid policy for PCB %d\n", currsp->policy));
513 *error = EINVAL;
514 return NULL;
516 /* NOTREACHED */
519 /* when non-privileged socket */
520 /* look for a policy in SPD */
521 if (ipsec_setspidx_mbuf(&spidx, AF_INET, m, 1) == 0 &&
522 (kernsp = key_allocsp(tag, &spidx, dir)) != NULL) {
523 /* SP found */
524 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
525 printf("DP ipsec4_getpolicybysock called "
526 "to allocate SP:%p\n", kernsp));
527 *error = 0;
528 ipsec_fillpcbcache(pcbsp, m, kernsp, dir);
529 return kernsp;
532 /* no SP found */
533 switch (currsp->policy) {
534 case IPSEC_POLICY_BYPASS:
535 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
536 "Illegal policy for non-privileged defined %d\n",
537 currsp->policy));
538 *error = EINVAL;
539 return NULL;
541 case IPSEC_POLICY_ENTRUST:
542 ip4_def_policy->refcnt++;
543 *error = 0;
544 ipsec_fillpcbcache(pcbsp, m, ip4_def_policy, dir);
545 return ip4_def_policy;
547 case IPSEC_POLICY_IPSEC:
548 currsp->refcnt++;
549 *error = 0;
550 ipsec_fillpcbcache(pcbsp, m, currsp, dir);
551 return currsp;
553 default:
554 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
555 "Invalid policy for PCB %d\n", currsp->policy));
556 *error = EINVAL;
557 return NULL;
559 /* NOTREACHED */
563 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
564 * and return a pointer to SP.
565 * OUT: positive: a pointer to the entry for security policy leaf matched.
566 * NULL: no apropreate SP found, the following value is set to error.
567 * 0 : bypass
568 * EACCES : discard packet.
569 * ENOENT : ipsec_acquire() in progress, maybe.
570 * others : error occurred.
572 struct secpolicy *
573 ipsec4_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
575 struct secpolicy *sp = NULL;
576 #ifdef SADB_X_EXT_TAG
577 struct pf_tag *t;
578 #endif
579 u_int16_t tag;
581 /* sanity check */
582 if (m == NULL || error == NULL)
583 panic("ipsec4_getpolicybyaddr: NULL pointer was passed.");
585 /* get a policy entry matched with the packet */
587 struct secpolicyindex spidx;
589 memset(&spidx, 0, sizeof(spidx));
591 /* make an index to look for a policy */
592 *error = ipsec_setspidx_mbuf(&spidx, AF_INET, m,
593 (flag & IP_FORWARDING) ? 0 : 1);
595 if (*error != 0)
596 return NULL;
598 #ifdef SADB_X_EXT_TAG
599 t = ipsec_get_tag(m);
600 tag = t ? t->tag : 0;
601 #else
602 tag = 0;
603 #endif
605 sp = key_allocsp(tag, &spidx, dir);
608 /* SP found */
609 if (sp != NULL) {
610 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
611 printf("DP ipsec4_getpolicybyaddr called "
612 "to allocate SP:%p\n", sp));
613 *error = 0;
614 return sp;
617 /* no SP found */
618 ip4_def_policy->refcnt++;
619 *error = 0;
620 return ip4_def_policy;
623 #ifdef INET6
625 * For OUTBOUND packet having a socket. Searching SPD for packet,
626 * and return a pointer to SP.
627 * OUT: NULL: no apropreate SP found, the following value is set to error.
628 * 0 : bypass
629 * EACCES : discard packet.
630 * ENOENT : ipsec_acquire() in progress, maybe.
631 * others : error occurred.
632 * others: a pointer to SP
634 struct secpolicy *
635 ipsec6_getpolicybysock(struct mbuf *m, u_int dir, struct socket *so,
636 int *error)
638 struct inpcbpolicy *pcbsp = NULL;
639 struct secpolicy *currsp = NULL; /* policy on socket */
640 struct secpolicy *kernsp = NULL; /* policy on kernel */
641 struct secpolicyindex spidx;
642 #ifdef SADB_X_EXT_TAG
643 struct pf_tag *t;
644 #endif
645 u_int16_t tag;
647 /* sanity check */
648 if (m == NULL || so == NULL || error == NULL)
649 panic("ipsec6_getpolicybysock: NULL pointer was passed.");
651 #ifdef DIAGNOSTIC
652 if (so->so_proto->pr_domain->dom_family != AF_INET6)
653 panic("ipsec6_getpolicybysock: socket domain != inet6");
654 #endif
656 pcbsp = sotoin6pcb(so)->in6p_sp;
658 #ifdef DIAGNOSTIC
659 if (pcbsp == NULL)
660 panic("ipsec6_getpolicybysock: pcbsp is NULL.");
661 #endif
663 #ifdef SADB_X_EXT_TAG
664 t = ipsec_get_tag(m);
665 tag = t ? t->tag : 0;
666 #else
667 tag = 0;
668 #endif
670 /* if we have a cached entry, and if it is still valid, use it. */
671 IPSEC6_STATINC(IPSEC_STAT_SPDCACHELOOKUP);
672 currsp = ipsec_checkpcbcache(m, pcbsp, dir);
673 if (currsp) {
674 *error = 0;
675 return currsp;
677 IPSEC6_STATINC(IPSEC_STAT_SPDCACHEMISS);
679 switch (dir) {
680 case IPSEC_DIR_INBOUND:
681 currsp = pcbsp->sp_in;
682 break;
683 case IPSEC_DIR_OUTBOUND:
684 currsp = pcbsp->sp_out;
685 break;
686 default:
687 panic("ipsec6_getpolicybysock: illegal direction.");
690 /* sanity check */
691 if (currsp == NULL)
692 panic("ipsec6_getpolicybysock: currsp is NULL.");
694 /* when privileged socket */
695 if (pcbsp->priv) {
696 switch (currsp->policy) {
697 case IPSEC_POLICY_BYPASS:
698 currsp->refcnt++;
699 *error = 0;
700 ipsec_fillpcbcache(pcbsp, m, currsp, dir);
701 return currsp;
703 case IPSEC_POLICY_ENTRUST:
704 /* look for a policy in SPD */
705 if (ipsec_setspidx_mbuf(&spidx, AF_INET6, m, 1) == 0 &&
706 (kernsp = key_allocsp(tag, &spidx, dir)) != NULL) {
707 /* SP found */
708 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
709 printf("DP ipsec6_getpolicybysock called "
710 "to allocate SP:%p\n", kernsp));
711 *error = 0;
712 ipsec_fillpcbcache(pcbsp, m, kernsp, dir);
713 return kernsp;
716 /* no SP found */
717 ip6_def_policy->refcnt++;
718 *error = 0;
719 ipsec_fillpcbcache(pcbsp, m, ip6_def_policy, dir);
720 return ip6_def_policy;
722 case IPSEC_POLICY_IPSEC:
723 currsp->refcnt++;
724 *error = 0;
725 ipsec_fillpcbcache(pcbsp, m, currsp, dir);
726 return currsp;
728 default:
729 ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
730 "Invalid policy for PCB %d\n", currsp->policy));
731 *error = EINVAL;
732 return NULL;
734 /* NOTREACHED */
737 /* when non-privileged socket */
738 /* look for a policy in SPD */
739 if (ipsec_setspidx_mbuf(&spidx, AF_INET6, m, 1) == 0 &&
740 (kernsp = key_allocsp(tag, &spidx, dir)) != NULL) {
741 /* SP found */
742 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
743 printf("DP ipsec6_getpolicybysock called "
744 "to allocate SP:%p\n", kernsp));
745 *error = 0;
746 ipsec_fillpcbcache(pcbsp, m, kernsp, dir);
747 return kernsp;
750 /* no SP found */
751 switch (currsp->policy) {
752 case IPSEC_POLICY_BYPASS:
753 ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
754 "Illegal policy for non-privileged defined %d\n",
755 currsp->policy));
756 *error = EINVAL;
757 return NULL;
759 case IPSEC_POLICY_ENTRUST:
760 ip6_def_policy->refcnt++;
761 *error = 0;
762 ipsec_fillpcbcache(pcbsp, m, ip6_def_policy, dir);
763 return ip6_def_policy;
765 case IPSEC_POLICY_IPSEC:
766 currsp->refcnt++;
767 *error = 0;
768 ipsec_fillpcbcache(pcbsp, m, currsp, dir);
769 return currsp;
771 default:
772 ipseclog((LOG_ERR,
773 "ipsec6_policybysock: Invalid policy for PCB %d\n",
774 currsp->policy));
775 *error = EINVAL;
776 return NULL;
778 /* NOTREACHED */
782 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
783 * and return a pointer to SP.
784 * `flag' means that packet is to be forwarded whether or not.
785 * flag = 1: forwad
786 * OUT: positive: a pointer to the entry for security policy leaf matched.
787 * NULL: no apropreate SP found, the following value is set to error.
788 * 0 : bypass
789 * EACCES : discard packet.
790 * ENOENT : ipsec_acquire() in progress, maybe.
791 * others : error occurred.
793 #ifndef IP_FORWARDING
794 #define IP_FORWARDING 1
795 #endif
797 struct secpolicy *
798 ipsec6_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
800 struct secpolicy *sp = NULL;
801 #ifdef SADB_X_EXT_TAG
802 struct pf_tag *t;
803 #endif
804 u_int16_t tag;
806 /* sanity check */
807 if (m == NULL || error == NULL)
808 panic("ipsec6_getpolicybyaddr: NULL pointer was passed.");
810 /* get a policy entry matched with the packet */
812 struct secpolicyindex spidx;
814 memset(&spidx, 0, sizeof(spidx));
816 /* make an index to look for a policy */
817 *error = ipsec_setspidx_mbuf(&spidx, AF_INET6, m,
818 (flag & IP_FORWARDING) ? 0 : 1);
820 if (*error != 0)
821 return NULL;
823 #ifdef SADB_X_EXT_TAG
824 t = ipsec_get_tag(m);
825 tag = t ? t->tag : 0;
826 #else
827 tag = 0;
828 #endif
830 sp = key_allocsp(tag, &spidx, dir);
833 /* SP found */
834 if (sp != NULL) {
835 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
836 printf("DP ipsec6_getpolicybyaddr called "
837 "to allocate SP:%p\n", sp));
838 *error = 0;
839 return sp;
842 /* no SP found */
843 ip6_def_policy->refcnt++;
844 *error = 0;
845 return ip6_def_policy;
847 #endif /* INET6 */
850 * set IP address into spidx from mbuf.
851 * When Forwarding packet and ICMP echo reply, this function is used.
853 * IN: get the followings from mbuf.
854 * protocol family, src, dst, next protocol
855 * OUT:
856 * 0: success.
857 * other: failure, and set errno.
860 ipsec_setspidx_mbuf(struct secpolicyindex *spidx, int family,
861 struct mbuf *m, int needport)
863 int error;
865 /* sanity check */
866 if (spidx == NULL || m == NULL)
867 panic("ipsec_setspidx_mbuf: NULL pointer was passed.");
869 memset(spidx, 0, sizeof(*spidx));
871 error = ipsec_setspidx(m, spidx, needport);
872 if (error)
873 goto bad;
875 return 0;
877 bad:
878 /* XXX initialize */
879 memset(spidx, 0, sizeof(*spidx));
880 return EINVAL;
884 * configure security policy index (src/dst/proto/sport/dport)
885 * by looking at the content of mbuf.
886 * the caller is responsible for error recovery (like clearing up spidx).
888 static int
889 ipsec_setspidx(struct mbuf *m, struct secpolicyindex *spidx, int needport)
891 struct ip *ip = NULL;
892 struct ip ipbuf;
893 u_int v;
894 struct mbuf *n;
895 int len;
896 int error;
898 if (m == NULL)
899 panic("ipsec_setspidx: m == 0 passed.");
901 memset(spidx, 0, sizeof(*spidx));
904 * validate m->m_pkthdr.len. we see incorrect length if we
905 * mistakenly call this function with inconsistent mbuf chain
906 * (like 4.4BSD tcp/udp processing). XXX should we panic here?
908 len = 0;
909 for (n = m; n; n = n->m_next)
910 len += n->m_len;
911 if (m->m_pkthdr.len != len) {
912 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
913 printf("ipsec_setspidx: "
914 "total of m_len(%d) != pkthdr.len(%d), "
915 "ignored.\n",
916 len, m->m_pkthdr.len));
917 return EINVAL;
920 if (m->m_pkthdr.len < sizeof(struct ip)) {
921 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
922 printf("ipsec_setspidx: "
923 "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
924 m->m_pkthdr.len));
925 return EINVAL;
928 if (m->m_len >= sizeof(*ip))
929 ip = mtod(m, struct ip *);
930 else {
931 m_copydata(m, 0, sizeof(ipbuf), (void *)&ipbuf);
932 ip = &ipbuf;
934 v = ip->ip_v;
935 switch (v) {
936 case 4:
937 error = ipsec4_setspidx_ipaddr(m, spidx);
938 if (error)
939 return error;
940 ipsec4_get_ulp(m, spidx, needport);
941 return 0;
942 #ifdef INET6
943 case 6:
944 if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
945 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
946 printf("ipsec_setspidx: "
947 "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
948 "ignored.\n", m->m_pkthdr.len));
949 return EINVAL;
951 error = ipsec6_setspidx_ipaddr(m, spidx);
952 if (error)
953 return error;
954 ipsec6_get_ulp(m, spidx, needport);
955 return 0;
956 #endif
957 default:
958 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
959 printf("ipsec_setspidx: "
960 "unknown IP version %u, ignored.\n", v));
961 return EINVAL;
965 static void
966 ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
968 struct ip ip;
969 struct ip6_ext ip6e;
970 u_int8_t nxt;
971 int off;
972 struct tcphdr th;
973 struct udphdr uh;
974 struct icmp icmph;
976 /* sanity check */
977 if (m == NULL)
978 panic("ipsec4_get_ulp: NULL pointer was passed.");
979 if (m->m_pkthdr.len < sizeof(ip))
980 panic("ipsec4_get_ulp: too short");
982 /* set default */
983 spidx->ul_proto = IPSEC_ULPROTO_ANY;
984 ((struct sockaddr_in *)&spidx->src)->sin_port = IPSEC_PORT_ANY;
985 ((struct sockaddr_in *)&spidx->dst)->sin_port = IPSEC_PORT_ANY;
987 m_copydata(m, 0, sizeof(ip), (void *)&ip);
988 if (ip.ip_off & htons(IP_MF | IP_OFFMASK))
989 return;
991 nxt = ip.ip_p;
992 off = ip.ip_hl << 2;
993 while (off < m->m_pkthdr.len) {
994 switch (nxt) {
995 case IPPROTO_TCP:
996 spidx->ul_proto = nxt;
997 if (!needport)
998 return;
999 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
1000 return;
1001 m_copydata(m, off, sizeof(th), (void *)&th);
1002 ((struct sockaddr_in *)&spidx->src)->sin_port =
1003 th.th_sport;
1004 ((struct sockaddr_in *)&spidx->dst)->sin_port =
1005 th.th_dport;
1006 return;
1007 case IPPROTO_UDP:
1008 spidx->ul_proto = nxt;
1009 if (!needport)
1010 return;
1011 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
1012 return;
1013 m_copydata(m, off, sizeof(uh), (void *)&uh);
1014 ((struct sockaddr_in *)&spidx->src)->sin_port =
1015 uh.uh_sport;
1016 ((struct sockaddr_in *)&spidx->dst)->sin_port =
1017 uh.uh_dport;
1018 return;
1019 case IPPROTO_AH:
1020 if (off + sizeof(ip6e) > m->m_pkthdr.len)
1021 return;
1022 m_copydata(m, off, sizeof(ip6e), (void *)&ip6e);
1023 off += (ip6e.ip6e_len + 2) << 2;
1024 nxt = ip6e.ip6e_nxt;
1025 break;
1026 case IPPROTO_ICMP:
1027 spidx->ul_proto = nxt;
1028 if (off + sizeof(struct icmp) > m->m_pkthdr.len)
1029 return;
1030 m_copydata(m, off, sizeof(icmph), &icmph);
1031 ((struct sockaddr_in *)&spidx->src)->sin_port =
1032 htons((uint16_t)icmph.icmp_type);
1033 ((struct sockaddr_in *)&spidx->dst)->sin_port =
1034 htons((uint16_t)icmph.icmp_code);
1035 return;
1036 default:
1037 /* XXX intermediate headers??? */
1038 spidx->ul_proto = nxt;
1039 return;
1044 /* assumes that m is sane */
1045 static int
1046 ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
1048 struct ip *ip = NULL;
1049 struct ip ipbuf;
1050 struct sockaddr_in *sin;
1052 if (m->m_len >= sizeof(*ip))
1053 ip = mtod(m, struct ip *);
1054 else {
1055 m_copydata(m, 0, sizeof(ipbuf), (void *)&ipbuf);
1056 ip = &ipbuf;
1059 sin = (struct sockaddr_in *)&spidx->src;
1060 memset(sin, 0, sizeof(*sin));
1061 sin->sin_family = AF_INET;
1062 sin->sin_len = sizeof(struct sockaddr_in);
1063 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
1064 spidx->prefs = sizeof(struct in_addr) << 3;
1066 sin = (struct sockaddr_in *)&spidx->dst;
1067 memset(sin, 0, sizeof(*sin));
1068 sin->sin_family = AF_INET;
1069 sin->sin_len = sizeof(struct sockaddr_in);
1070 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
1071 spidx->prefd = sizeof(struct in_addr) << 3;
1072 return 0;
1075 #ifdef INET6
1076 static void
1077 ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
1079 int off, nxt;
1080 struct tcphdr th;
1081 struct udphdr uh;
1082 struct icmp6_hdr icmph;
1084 /* sanity check */
1085 if (m == NULL)
1086 panic("ipsec6_get_ulp: NULL pointer was passed.");
1088 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1089 printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
1091 /* set default */
1092 spidx->ul_proto = IPSEC_ULPROTO_ANY;
1093 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
1094 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
1096 nxt = -1;
1097 off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
1098 if (off < 0 || m->m_pkthdr.len < off)
1099 return;
1101 switch (nxt) {
1102 case IPPROTO_TCP:
1103 spidx->ul_proto = nxt;
1104 if (!needport)
1105 break;
1106 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
1107 break;
1108 m_copydata(m, off, sizeof(th), (void *)&th);
1109 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
1110 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
1111 break;
1112 case IPPROTO_UDP:
1113 spidx->ul_proto = nxt;
1114 if (!needport)
1115 break;
1116 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
1117 break;
1118 m_copydata(m, off, sizeof(uh), (void *)&uh);
1119 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
1120 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
1121 break;
1122 case IPPROTO_ICMPV6:
1123 spidx->ul_proto = nxt;
1124 if (off + sizeof(struct icmp6_hdr) > m->m_pkthdr.len)
1125 break;
1126 m_copydata(m, off, sizeof(icmph), &icmph);
1127 ((struct sockaddr_in6 *)&spidx->src)->sin6_port =
1128 htons((uint16_t)icmph.icmp6_type);
1129 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port =
1130 htons((uint16_t)icmph.icmp6_code);
1131 break;
1132 default:
1133 /* XXX intermediate headers??? */
1134 spidx->ul_proto = nxt;
1135 break;
1139 /* assumes that m is sane */
1140 static int
1141 ipsec6_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
1143 struct ip6_hdr *ip6 = NULL;
1144 struct ip6_hdr ip6buf;
1145 struct sockaddr_in6 *sin6;
1147 if (m->m_len >= sizeof(*ip6))
1148 ip6 = mtod(m, struct ip6_hdr *);
1149 else {
1150 m_copydata(m, 0, sizeof(ip6buf), (void *)&ip6buf);
1151 ip6 = &ip6buf;
1154 sin6 = (struct sockaddr_in6 *)&spidx->src;
1155 memset(sin6, 0, sizeof(*sin6));
1156 sin6->sin6_family = AF_INET6;
1157 sin6->sin6_len = sizeof(struct sockaddr_in6);
1158 sin6->sin6_addr = ip6->ip6_src;
1159 spidx->prefs = sizeof(struct in6_addr) << 3;
1161 sin6 = (struct sockaddr_in6 *)&spidx->dst;
1162 memset(sin6, 0, sizeof(*sin6));
1163 sin6->sin6_family = AF_INET6;
1164 sin6->sin6_len = sizeof(struct sockaddr_in6);
1165 sin6->sin6_addr = ip6->ip6_dst;
1166 spidx->prefd = sizeof(struct in6_addr) << 3;
1168 return 0;
1170 #endif
1172 static struct inpcbpolicy *
1173 ipsec_newpcbpolicy(void)
1175 struct inpcbpolicy *p;
1177 p = (struct inpcbpolicy *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
1178 return p;
1181 static void
1182 ipsec_delpcbpolicy(struct inpcbpolicy *p)
1185 free(p, M_SECA);
1188 /* initialize policy in PCB */
1190 ipsec_init_pcbpolicy(struct socket *so, struct inpcbpolicy **pcb_sp)
1192 struct inpcbpolicy *new;
1193 static int initialized = 0;
1194 static struct secpolicy *in = NULL, *out = NULL;
1196 /* sanity check. */
1197 if (so == NULL || pcb_sp == NULL)
1198 panic("ipsec_init_pcbpolicy: NULL pointer was passed.");
1200 if (!initialized) {
1201 if ((in = key_newsp(0)) == NULL)
1202 return ENOBUFS;
1203 if ((out = key_newsp(0)) == NULL) {
1204 key_freesp(in);
1205 in = NULL;
1206 return ENOBUFS;
1209 in->state = IPSEC_SPSTATE_ALIVE;
1210 in->policy = IPSEC_POLICY_ENTRUST;
1211 in->dir = IPSEC_DIR_INBOUND;
1212 in->readonly = 1;
1213 in->persist = 1;
1214 in->so = NULL;
1216 out->state = IPSEC_SPSTATE_ALIVE;
1217 out->policy = IPSEC_POLICY_ENTRUST;
1218 out->dir = IPSEC_DIR_OUTBOUND;
1219 out->readonly = 1;
1220 out->persist = 1;
1221 out->so = NULL;
1223 initialized++;
1226 new = ipsec_newpcbpolicy();
1227 if (new == NULL) {
1228 ipseclog((LOG_DEBUG, "ipsec_init_pcbpolicy: No more memory.\n"));
1229 return ENOBUFS;
1231 memset(new, 0, sizeof(*new));
1233 if (so->so_uidinfo->ui_uid == 0) /* XXX-kauth */
1234 new->priv = 1;
1235 else
1236 new->priv = 0;
1238 new->sp_in = in;
1239 new->sp_in->refcnt++;
1240 new->sp_out = out;
1241 new->sp_out->refcnt++;
1243 *pcb_sp = new;
1245 return 0;
1248 /* copy old ipsec policy into new */
1250 ipsec_copy_pcbpolicy(struct inpcbpolicy *old, struct inpcbpolicy *new)
1253 if (new->sp_in)
1254 key_freesp(new->sp_in);
1255 if (old->sp_in->policy == IPSEC_POLICY_IPSEC)
1256 new->sp_in = ipsec_deepcopy_policy(old->sp_in);
1257 else {
1258 new->sp_in = old->sp_in;
1259 new->sp_in->refcnt++;
1262 if (new->sp_out)
1263 key_freesp(new->sp_out);
1264 if (old->sp_out->policy == IPSEC_POLICY_IPSEC)
1265 new->sp_out = ipsec_deepcopy_policy(old->sp_out);
1266 else {
1267 new->sp_out = old->sp_out;
1268 new->sp_out->refcnt++;
1271 new->priv = old->priv;
1273 return 0;
1276 #if 0
1277 static int
1278 ipsec_deepcopy_pcbpolicy(struct inpcbpolicy *pcb_sp)
1280 struct secpolicy *sp;
1282 sp = ipsec_deepcopy_policy(pcb_sp->sp_in);
1283 if (sp) {
1284 key_freesp(pcb_sp->sp_in);
1285 pcb_sp->sp_in = sp;
1286 } else
1287 return ENOBUFS;
1289 sp = ipsec_deepcopy_policy(pcb_sp->sp_out);
1290 if (sp) {
1291 key_freesp(pcb_sp->sp_out);
1292 pcb_sp->sp_out = sp;
1293 } else
1294 return ENOBUFS;
1296 return 0;
1298 #endif
1300 /* deep-copy a policy in PCB */
1301 static struct secpolicy *
1302 ipsec_deepcopy_policy(struct secpolicy *src)
1304 struct ipsecrequest *newchain = NULL;
1305 struct ipsecrequest *p;
1306 struct ipsecrequest **q;
1307 struct ipsecrequest *r;
1308 struct secpolicy *dst;
1310 if (src == NULL)
1311 return NULL;
1313 dst = key_newsp(0);
1314 if (dst == NULL)
1315 return NULL;
1318 * deep-copy IPsec request chain. This is required since struct
1319 * ipsecrequest is not reference counted.
1321 q = &newchain;
1322 for (p = src->req; p; p = p->next) {
1323 *q = (struct ipsecrequest *)malloc(sizeof(struct ipsecrequest),
1324 M_SECA, M_NOWAIT);
1325 if (*q == NULL)
1326 goto fail;
1327 memset(*q, 0, sizeof(**q));
1328 (*q)->next = NULL;
1330 (*q)->saidx.proto = p->saidx.proto;
1331 (*q)->saidx.mode = p->saidx.mode;
1332 (*q)->level = p->level;
1333 (*q)->saidx.reqid = p->saidx.reqid;
1335 memcpy(&(*q)->saidx.src, &p->saidx.src, sizeof((*q)->saidx.src));
1336 memcpy(&(*q)->saidx.dst, &p->saidx.dst, sizeof((*q)->saidx.dst));
1338 (*q)->sav = NULL;
1339 (*q)->sp = dst;
1341 q = &((*q)->next);
1344 if (src->spidx)
1345 if (keydb_setsecpolicyindex(dst, src->spidx) != 0)
1346 goto fail;
1348 dst->req = newchain;
1349 dst->state = src->state;
1350 dst->policy = src->policy;
1351 dst->dir = src->dir;
1352 dst->so = src->so;
1353 /* do not touch the refcnt fields */
1355 return dst;
1357 fail:
1358 for (p = newchain; p; p = r) {
1359 r = p->next;
1360 free(p, M_SECA);
1361 p = NULL;
1363 key_freesp(dst);
1364 return NULL;
1367 /* set policy and ipsec request if present. */
1368 static int
1369 ipsec_set_policy(struct secpolicy **spp, int optname, void *request,
1370 size_t len, kauth_cred_t cred)
1372 struct sadb_x_policy *xpl;
1373 struct secpolicy *newsp = NULL;
1374 int error;
1376 /* sanity check. */
1377 if (spp == NULL || *spp == NULL || request == NULL)
1378 return EINVAL;
1379 if (len < sizeof(*xpl))
1380 return EINVAL;
1381 xpl = (struct sadb_x_policy *)request;
1383 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1384 printf("ipsec_set_policy: passed policy\n");
1385 kdebug_sadb_x_policy((struct sadb_ext *)xpl));
1387 /* check policy type */
1388 /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1389 if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD ||
1390 xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
1391 return EINVAL;
1393 /* check privileged socket */
1394 if (xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS) {
1395 error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
1396 NULL);
1397 if (error)
1398 return (error);
1401 /* allocation new SP entry */
1402 if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
1403 return error;
1405 newsp->state = IPSEC_SPSTATE_ALIVE;
1407 /* clear old SP and set new SP */
1408 key_freesp(*spp);
1409 *spp = newsp;
1410 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1411 printf("ipsec_set_policy: new policy\n");
1412 kdebug_secpolicy(newsp));
1414 return 0;
1417 static int
1418 ipsec_get_policy(struct secpolicy *sp, struct mbuf **mp)
1421 /* sanity check. */
1422 if (sp == NULL || mp == NULL)
1423 return EINVAL;
1425 *mp = key_sp2msg(sp);
1426 if (!*mp) {
1427 ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
1428 return ENOBUFS;
1431 (*mp)->m_type = MT_SOOPTS;
1432 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1433 printf("ipsec_get_policy:\n");
1434 kdebug_mbuf(*mp));
1436 return 0;
1440 ipsec4_set_policy(struct inpcb *inp, int optname, void *request,
1441 size_t len, kauth_cred_t cred)
1443 struct sadb_x_policy *xpl;
1444 struct secpolicy **spp;
1446 /* sanity check. */
1447 if (inp == NULL || request == NULL)
1448 return EINVAL;
1449 if (len < sizeof(*xpl))
1450 return EINVAL;
1451 xpl = (struct sadb_x_policy *)request;
1453 /* select direction */
1454 switch (xpl->sadb_x_policy_dir) {
1455 case IPSEC_DIR_INBOUND:
1456 spp = &inp->inp_sp->sp_in;
1457 break;
1458 case IPSEC_DIR_OUTBOUND:
1459 spp = &inp->inp_sp->sp_out;
1460 break;
1461 default:
1462 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1463 xpl->sadb_x_policy_dir));
1464 return EINVAL;
1467 ipsec_invalpcbcache(inp->inp_sp, IPSEC_DIR_ANY);
1468 return ipsec_set_policy(spp, optname, request, len, cred);
1472 ipsec4_get_policy(struct inpcb *inp, void *request, size_t len,
1473 struct mbuf **mp)
1475 struct sadb_x_policy *xpl;
1476 struct secpolicy *sp;
1478 /* sanity check. */
1479 if (inp == NULL || request == NULL || mp == NULL)
1480 return EINVAL;
1481 if (inp->inp_sp == NULL)
1482 panic("policy in PCB is NULL");
1483 if (len < sizeof(*xpl))
1484 return EINVAL;
1485 xpl = (struct sadb_x_policy *)request;
1487 /* select direction */
1488 switch (xpl->sadb_x_policy_dir) {
1489 case IPSEC_DIR_INBOUND:
1490 sp = inp->inp_sp->sp_in;
1491 break;
1492 case IPSEC_DIR_OUTBOUND:
1493 sp = inp->inp_sp->sp_out;
1494 break;
1495 default:
1496 ipseclog((LOG_ERR, "ipsec4_get_policy: invalid direction=%u\n",
1497 xpl->sadb_x_policy_dir));
1498 return EINVAL;
1501 return ipsec_get_policy(sp, mp);
1504 /* delete policy in PCB */
1506 ipsec4_delete_pcbpolicy(struct inpcb *inp)
1508 /* sanity check. */
1509 if (inp == NULL)
1510 panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.");
1512 if (inp->inp_sp == NULL)
1513 return 0;
1515 if (inp->inp_sp->sp_in != NULL) {
1516 key_freesp(inp->inp_sp->sp_in);
1517 inp->inp_sp->sp_in = NULL;
1520 if (inp->inp_sp->sp_out != NULL) {
1521 key_freesp(inp->inp_sp->sp_out);
1522 inp->inp_sp->sp_out = NULL;
1525 ipsec_invalpcbcache(inp->inp_sp, IPSEC_DIR_ANY);
1527 ipsec_delpcbpolicy(inp->inp_sp);
1528 inp->inp_sp = NULL;
1530 return 0;
1533 #ifdef INET6
1535 ipsec6_set_policy(struct in6pcb *in6p, int optname, void *request,
1536 size_t len, kauth_cred_t cred)
1538 struct sadb_x_policy *xpl;
1539 struct secpolicy **spp;
1541 /* sanity check. */
1542 if (in6p == NULL || request == NULL)
1543 return EINVAL;
1544 if (len < sizeof(*xpl))
1545 return EINVAL;
1546 xpl = (struct sadb_x_policy *)request;
1548 /* select direction */
1549 switch (xpl->sadb_x_policy_dir) {
1550 case IPSEC_DIR_INBOUND:
1551 spp = &in6p->in6p_sp->sp_in;
1552 break;
1553 case IPSEC_DIR_OUTBOUND:
1554 spp = &in6p->in6p_sp->sp_out;
1555 break;
1556 default:
1557 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1558 xpl->sadb_x_policy_dir));
1559 return EINVAL;
1562 ipsec_invalpcbcache(in6p->in6p_sp, IPSEC_DIR_ANY);
1563 return ipsec_set_policy(spp, optname, request, len, cred);
1567 ipsec6_get_policy(struct in6pcb *in6p, void *request, size_t len,
1568 struct mbuf **mp)
1570 struct sadb_x_policy *xpl;
1571 struct secpolicy *sp;
1573 /* sanity check. */
1574 if (in6p == NULL || request == NULL || mp == NULL)
1575 return EINVAL;
1576 if (in6p->in6p_sp == NULL)
1577 panic("policy in PCB is NULL");
1578 if (len < sizeof(*xpl))
1579 return EINVAL;
1580 xpl = (struct sadb_x_policy *)request;
1582 /* select direction */
1583 switch (xpl->sadb_x_policy_dir) {
1584 case IPSEC_DIR_INBOUND:
1585 sp = in6p->in6p_sp->sp_in;
1586 break;
1587 case IPSEC_DIR_OUTBOUND:
1588 sp = in6p->in6p_sp->sp_out;
1589 break;
1590 default:
1591 ipseclog((LOG_ERR, "ipsec6_get_policy: invalid direction=%u\n",
1592 xpl->sadb_x_policy_dir));
1593 return EINVAL;
1596 return ipsec_get_policy(sp, mp);
1600 ipsec6_delete_pcbpolicy(struct in6pcb *in6p)
1602 /* sanity check. */
1603 if (in6p == NULL)
1604 panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.");
1606 if (in6p->in6p_sp == NULL)
1607 return 0;
1609 if (in6p->in6p_sp->sp_in != NULL) {
1610 key_freesp(in6p->in6p_sp->sp_in);
1611 in6p->in6p_sp->sp_in = NULL;
1614 if (in6p->in6p_sp->sp_out != NULL) {
1615 key_freesp(in6p->in6p_sp->sp_out);
1616 in6p->in6p_sp->sp_out = NULL;
1619 ipsec_invalpcbcache(in6p->in6p_sp, IPSEC_DIR_ANY);
1621 ipsec_delpcbpolicy(in6p->in6p_sp);
1622 in6p->in6p_sp = NULL;
1624 return 0;
1626 #endif
1629 * return current level.
1630 * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1632 u_int
1633 ipsec_get_reqlevel(struct ipsecrequest *isr, int af)
1635 u_int level = 0;
1636 u_int esp_trans_deflev, esp_net_deflev, ah_trans_deflev, ah_net_deflev;
1638 /* sanity check */
1639 if (isr == NULL || isr->sp == NULL)
1640 panic("ipsec_get_reqlevel: NULL pointer is passed.");
1642 /* set default level */
1643 switch (af) {
1644 #ifdef INET
1645 case AF_INET:
1646 esp_trans_deflev = ip4_esp_trans_deflev;
1647 esp_net_deflev = ip4_esp_net_deflev;
1648 ah_trans_deflev = ip4_ah_trans_deflev;
1649 ah_net_deflev = ip4_ah_net_deflev;
1650 break;
1651 #endif
1652 #ifdef INET6
1653 case AF_INET6:
1654 esp_trans_deflev = ip6_esp_trans_deflev;
1655 esp_net_deflev = ip6_esp_net_deflev;
1656 ah_trans_deflev = ip6_ah_trans_deflev;
1657 ah_net_deflev = ip6_ah_net_deflev;
1658 break;
1659 #endif /* INET6 */
1660 default:
1661 panic("key_get_reqlevel: Unknown family. %d",
1662 ((struct sockaddr *)&isr->sp->spidx->src)->sa_family);
1665 /* set level */
1666 switch (isr->level) {
1667 case IPSEC_LEVEL_DEFAULT:
1668 switch (isr->saidx.proto) {
1669 case IPPROTO_ESP:
1670 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1671 level = esp_net_deflev;
1672 else
1673 level = esp_trans_deflev;
1674 break;
1675 case IPPROTO_AH:
1676 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1677 level = ah_net_deflev;
1678 else
1679 level = ah_trans_deflev;
1680 break;
1681 case IPPROTO_IPCOMP:
1683 * we don't really care, as IPcomp document says that
1684 * we shouldn't compress small packets
1686 level = IPSEC_LEVEL_USE;
1687 break;
1688 case IPPROTO_IPV4:
1689 case IPPROTO_IPV6:
1690 /* should never go into here */
1691 level = IPSEC_LEVEL_REQUIRE;
1692 break;
1693 default:
1694 panic("ipsec_get_reqlevel: "
1695 "Illegal protocol defined %u\n",
1696 isr->saidx.proto);
1698 break;
1700 case IPSEC_LEVEL_USE:
1701 case IPSEC_LEVEL_REQUIRE:
1702 level = isr->level;
1703 break;
1704 case IPSEC_LEVEL_UNIQUE:
1705 level = IPSEC_LEVEL_REQUIRE;
1706 break;
1708 default:
1709 panic("ipsec_get_reqlevel: Illegal IPsec level %u",
1710 isr->level);
1713 return level;
1717 * Check AH/ESP integrity.
1718 * OUT:
1719 * 0: valid
1720 * 1: invalid
1722 static int
1723 ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
1725 struct ipsecrequest *isr;
1726 u_int level;
1727 int need_auth, need_conf, need_icv;
1729 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1730 printf("ipsec_in_reject: using SP\n");
1731 kdebug_secpolicy(sp));
1733 /* check policy */
1734 switch (sp->policy) {
1735 case IPSEC_POLICY_DISCARD:
1736 return 1;
1737 case IPSEC_POLICY_BYPASS:
1738 case IPSEC_POLICY_NONE:
1739 return 0;
1741 case IPSEC_POLICY_IPSEC:
1742 break;
1744 case IPSEC_POLICY_ENTRUST:
1745 default:
1746 panic("ipsec_in_reject: Invalid policy found. %d", sp->policy);
1749 need_auth = 0;
1750 need_conf = 0;
1751 need_icv = 0;
1753 /* XXX should compare policy against ipsec header history */
1755 for (isr = sp->req; isr != NULL; isr = isr->next) {
1756 /* get current level */
1757 level = ipsec_get_reqlevel(isr, AF_INET);
1759 switch (isr->saidx.proto) {
1760 case IPPROTO_ESP:
1761 if (level == IPSEC_LEVEL_REQUIRE) {
1762 need_conf++;
1764 if (isr->sav != NULL
1765 && isr->sav->flags == SADB_X_EXT_NONE
1766 && isr->sav->alg_auth != SADB_AALG_NONE)
1767 need_icv++;
1769 break;
1770 case IPPROTO_AH:
1771 if (level == IPSEC_LEVEL_REQUIRE) {
1772 need_auth++;
1773 need_icv++;
1775 break;
1776 case IPPROTO_IPCOMP:
1778 * we don't really care, as IPcomp document says that
1779 * we shouldn't compress small packets, IPComp policy
1780 * should always be treated as being in "use" level.
1782 break;
1783 case IPPROTO_IPV4:
1784 case IPPROTO_IPV6:
1786 * XXX what shall we do, until introducing more complex
1787 * policy checking code?
1789 break;
1793 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1794 printf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n",
1795 need_auth, need_conf, need_icv, m->m_flags));
1797 if ((need_conf && !(m->m_flags & M_DECRYPTED))
1798 || (!need_auth && need_icv && !(m->m_flags & M_AUTHIPDGM))
1799 || (need_auth && !(m->m_flags & M_AUTHIPHDR)))
1800 return 1;
1802 return 0;
1806 * Check AH/ESP integrity.
1807 * This function is called from tcp_input(), udp_input(),
1808 * and {ah,esp}4_input for tunnel mode
1811 ipsec4_in_reject_so(struct mbuf *m, struct socket *so)
1813 struct secpolicy *sp = NULL;
1814 int error;
1815 int result;
1817 /* sanity check */
1818 if (m == NULL)
1819 return 0; /* XXX should be panic ? */
1821 /* get SP for this packet.
1822 * When we are called from ip_forward(), we call
1823 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
1825 if (so == NULL)
1826 sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
1827 IP_FORWARDING, &error);
1828 else
1829 sp = ipsec4_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
1831 /* XXX should be panic ? -> No, there may be error. */
1832 if (sp == NULL)
1833 return 0;
1835 result = ipsec_in_reject(sp, m);
1836 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1837 printf("DP ipsec4_in_reject_so call free SP:%p\n", sp));
1838 key_freesp(sp);
1840 return result;
1844 ipsec4_in_reject(struct mbuf *m, struct inpcb *inp)
1846 if (inp == NULL)
1847 return ipsec4_in_reject_so(m, NULL);
1848 if (inp->inp_socket)
1849 return ipsec4_in_reject_so(m, inp->inp_socket);
1850 else
1851 panic("ipsec4_in_reject: invalid inpcb/socket");
1854 #ifdef INET6
1856 * Check AH/ESP integrity.
1857 * This function is called from tcp6_input(), udp6_input(),
1858 * and {ah,esp}6_input for tunnel mode
1861 ipsec6_in_reject_so(struct mbuf *m, struct socket *so)
1863 struct secpolicy *sp = NULL;
1864 int error;
1865 int result;
1867 /* sanity check */
1868 if (m == NULL)
1869 return 0; /* XXX should be panic ? */
1871 /* get SP for this packet.
1872 * When we are called from ip_forward(), we call
1873 * ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
1875 if (so == NULL)
1876 sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
1877 IP_FORWARDING, &error);
1878 else
1879 sp = ipsec6_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
1881 if (sp == NULL)
1882 return 0; /* XXX should be panic ? */
1884 result = ipsec_in_reject(sp, m);
1885 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1886 printf("DP ipsec6_in_reject_so call free SP:%p\n", sp));
1887 key_freesp(sp);
1889 return result;
1893 ipsec6_in_reject(struct mbuf *m, struct in6pcb *in6p)
1895 if (in6p == NULL)
1896 return ipsec6_in_reject_so(m, NULL);
1897 if (in6p->in6p_socket)
1898 return ipsec6_in_reject_so(m, in6p->in6p_socket);
1899 else
1900 panic("ipsec6_in_reject: invalid in6p/socket");
1902 #endif
1905 * compute the byte size to be occupied by IPsec header.
1906 * in case it is tunneled, it includes the size of outer IP header.
1907 * NOTE: SP passed is free in this function.
1909 static size_t
1910 ipsec_hdrsiz(struct secpolicy *sp)
1912 struct ipsecrequest *isr;
1913 size_t siz, clen;
1915 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1916 printf("ipsec_hdrsiz: using SP\n");
1917 kdebug_secpolicy(sp));
1919 /* check policy */
1920 switch (sp->policy) {
1921 case IPSEC_POLICY_DISCARD:
1922 case IPSEC_POLICY_BYPASS:
1923 case IPSEC_POLICY_NONE:
1924 return 0;
1926 case IPSEC_POLICY_IPSEC:
1927 break;
1929 case IPSEC_POLICY_ENTRUST:
1930 default:
1931 panic("ipsec_hdrsiz: Invalid policy found. %d", sp->policy);
1934 siz = 0;
1936 for (isr = sp->req; isr != NULL; isr = isr->next) {
1938 clen = 0;
1940 switch (isr->saidx.proto) {
1941 case IPPROTO_ESP:
1942 #ifdef IPSEC_ESP
1943 clen = esp_hdrsiz(isr);
1944 #else
1945 clen = 0; /* XXX */
1946 #endif
1947 break;
1948 case IPPROTO_AH:
1949 clen = ah_hdrsiz(isr);
1950 break;
1951 case IPPROTO_IPCOMP:
1952 clen = sizeof(struct ipcomp);
1953 break;
1954 case IPPROTO_IPV4:
1955 case IPPROTO_IPV6:
1956 /* the next "if" clause will compute it */
1957 clen = 0;
1958 break;
1961 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
1962 switch (((struct sockaddr *)&isr->saidx.dst)->sa_family) {
1963 case AF_INET:
1964 clen += sizeof(struct ip);
1965 break;
1966 #ifdef INET6
1967 case AF_INET6:
1968 clen += sizeof(struct ip6_hdr);
1969 break;
1970 #endif
1971 default:
1972 ipseclog((LOG_ERR, "ipsec_hdrsiz: "
1973 "unknown AF %d in IPsec tunnel SA\n",
1974 ((struct sockaddr *)&isr->saidx.dst)->sa_family));
1975 break;
1978 siz += clen;
1981 return siz;
1984 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
1985 size_t
1986 ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp)
1988 struct secpolicy *sp = NULL;
1989 int error;
1990 size_t size;
1992 /* sanity check */
1993 if (m == NULL)
1994 return 0; /* XXX should be panic ? */
1995 if (inp != NULL && inp->inp_socket == NULL)
1996 panic("ipsec4_hdrsize: why is socket NULL but there is PCB.");
1998 /* get SP for this packet.
1999 * When we are called from ip_forward(), we call
2000 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
2002 if (inp == NULL)
2003 sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
2004 else
2005 sp = ipsec4_getpolicybysock(m, dir, inp->inp_socket, &error);
2007 if (sp == NULL)
2008 return 0; /* XXX should be panic ? */
2010 size = ipsec_hdrsiz(sp);
2011 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2012 printf("DP ipsec4_hdrsiz call free SP:%p\n", sp));
2013 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2014 printf("ipsec4_hdrsiz: size:%lu.\n", (unsigned long)size));
2015 key_freesp(sp);
2017 return size;
2020 #ifdef INET6
2021 /* This function is called from ipsec6_hdrsize_tcp(),
2022 * and maybe from ip6_forward.()
2024 size_t
2025 ipsec6_hdrsiz(struct mbuf *m, u_int dir, struct in6pcb *in6p)
2027 struct secpolicy *sp = NULL;
2028 int error;
2029 size_t size;
2031 /* sanity check */
2032 if (m == NULL)
2033 return 0; /* XXX should be panic ? */
2034 if (in6p != NULL && in6p->in6p_socket == NULL)
2035 panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
2037 /* get SP for this packet */
2038 /* XXX Is it right to call with IP_FORWARDING. */
2039 if (in6p == NULL)
2040 sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
2041 else
2042 sp = ipsec6_getpolicybysock(m, dir, in6p->in6p_socket, &error);
2044 if (sp == NULL)
2045 return 0;
2046 size = ipsec_hdrsiz(sp);
2047 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2048 printf("DP ipsec6_hdrsiz call free SP:%p\n", sp));
2049 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2050 printf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
2051 key_freesp(sp);
2053 return size;
2055 #endif /* INET6 */
2057 #ifdef INET
2059 * encapsulate for ipsec tunnel.
2060 * ip->ip_src must be fixed later on.
2062 static int
2063 ipsec4_encapsulate(struct mbuf *m, struct secasvar *sav)
2065 struct ip *oip;
2066 struct ip *ip;
2067 size_t hlen;
2068 size_t plen;
2070 /* can't tunnel between different AFs */
2071 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2072 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2073 || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET) {
2074 m_freem(m);
2075 return EINVAL;
2077 #if 0
2078 /* XXX if the dst is myself, perform nothing. */
2079 if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
2080 m_freem(m);
2081 return EINVAL;
2083 #endif
2085 if (m->m_len < sizeof(*ip))
2086 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2088 ip = mtod(m, struct ip *);
2089 hlen = ip->ip_hl << 2;
2091 if (m->m_len != hlen)
2092 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2094 /* generate header checksum */
2095 ip->ip_sum = 0;
2096 ip->ip_sum = in_cksum(m, hlen);
2098 plen = m->m_pkthdr.len;
2101 * grow the mbuf to accomodate the new IPv4 header.
2102 * NOTE: IPv4 options will never be copied.
2104 if (M_LEADINGSPACE(m->m_next) < hlen) {
2105 struct mbuf *n;
2106 MGET(n, M_DONTWAIT, MT_DATA);
2107 if (!n) {
2108 m_freem(m);
2109 return ENOBUFS;
2111 n->m_len = hlen;
2112 n->m_next = m->m_next;
2113 m->m_next = n;
2114 } else {
2115 m->m_next->m_len += hlen;
2116 m->m_next->m_data -= hlen;
2118 oip = mtod(m->m_next, struct ip *);
2119 m->m_pkthdr.len += hlen;
2120 ip = mtod(m, struct ip *);
2121 ovbcopy((void *)ip, (void *)oip, hlen);
2122 m->m_len = sizeof(struct ip);
2123 m->m_pkthdr.len -= (hlen - sizeof(struct ip));
2125 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2126 /* ECN consideration. */
2127 ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2128 ip->ip_hl = sizeof(struct ip) >> 2;
2129 ip->ip_off &= htons(~IP_OFFMASK);
2130 ip->ip_off &= htons(~IP_MF);
2131 switch (ip4_ipsec_dfbit) {
2132 case 0: /* clear DF bit */
2133 ip->ip_off &= htons(~IP_DF);
2134 break;
2135 case 1: /* set DF bit */
2136 ip->ip_off |= htons(IP_DF);
2137 break;
2138 default: /* copy DF bit */
2139 break;
2141 ip->ip_p = IPPROTO_IPIP;
2142 if (plen + sizeof(struct ip) < IP_MAXPACKET)
2143 ip->ip_len = htons(plen + sizeof(struct ip));
2144 else {
2145 ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
2146 "leave ip_len as is (invalid packet)\n"));
2148 ip->ip_id = ip_newid(NULL);
2149 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr,
2150 &ip->ip_src, sizeof(ip->ip_src));
2151 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.dst)->sin_addr,
2152 &ip->ip_dst, sizeof(ip->ip_dst));
2153 ip->ip_ttl = IPDEFTTL;
2155 /* XXX Should ip_src be updated later ? */
2157 return 0;
2159 #endif /* INET */
2161 #ifdef INET6
2162 static int
2163 ipsec6_encapsulate(struct mbuf *m, struct secasvar *sav)
2165 struct ip6_hdr *oip6;
2166 struct ip6_hdr *ip6;
2167 size_t plen;
2168 int error;
2169 struct sockaddr_in6 sa6;
2171 /* can't tunnel between different AFs */
2172 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2173 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2174 || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET6) {
2175 m_freem(m);
2176 return EINVAL;
2178 #if 0
2179 /* XXX if the dst is myself, perform nothing. */
2180 if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
2181 m_freem(m);
2182 return EINVAL;
2184 #endif
2186 plen = m->m_pkthdr.len;
2189 * grow the mbuf to accomodate the new IPv6 header.
2191 if (m->m_len != sizeof(struct ip6_hdr))
2192 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2193 if (M_LEADINGSPACE(m->m_next) < sizeof(struct ip6_hdr)) {
2194 struct mbuf *n;
2195 MGET(n, M_DONTWAIT, MT_DATA);
2196 if (!n) {
2197 m_freem(m);
2198 return ENOBUFS;
2200 n->m_len = sizeof(struct ip6_hdr);
2201 n->m_next = m->m_next;
2202 m->m_next = n;
2203 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2204 oip6 = mtod(n, struct ip6_hdr *);
2205 } else {
2206 m->m_next->m_len += sizeof(struct ip6_hdr);
2207 m->m_next->m_data -= sizeof(struct ip6_hdr);
2208 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2209 oip6 = mtod(m->m_next, struct ip6_hdr *);
2211 ip6 = mtod(m, struct ip6_hdr *);
2212 ovbcopy((void *)ip6, (void *)oip6, sizeof(struct ip6_hdr));
2214 /* Fake link-local scope-class addresses */
2215 in6_clearscope(&oip6->ip6_src);
2216 in6_clearscope(&oip6->ip6_dst);
2218 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2219 /* ECN consideration. */
2220 ip6_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow);
2221 if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr))
2222 ip6->ip6_plen = htons(plen);
2223 else {
2224 /* ip6->ip6_plen will be updated in ip6_output() */
2226 ip6->ip6_nxt = IPPROTO_IPV6;
2228 sa6 = *(struct sockaddr_in6 *)&sav->sah->saidx.src;
2229 if ((error = sa6_embedscope(&sa6, 0)) != 0)
2230 return (error);
2231 ip6->ip6_src = sa6.sin6_addr;
2233 sa6 = *(struct sockaddr_in6 *)&sav->sah->saidx.dst;
2234 if ((error = sa6_embedscope(&sa6, 0)) != 0)
2235 return (error);
2236 ip6->ip6_dst = sa6.sin6_addr;
2238 ip6->ip6_hlim = IPV6_DEFHLIM;
2240 /* XXX Should ip6_src be updated later ? */
2242 return 0;
2244 #endif /* INET6 */
2247 * Check the variable replay window.
2248 * ipsec_chkreplay() performs replay check before ICV verification.
2249 * ipsec_updatereplay() updates replay bitmap. This must be called after
2250 * ICV verification (it also performs replay check, which is usually done
2251 * beforehand).
2252 * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
2254 * based on RFC 2401.
2256 * XXX need to update for 64bit sequence number - 2401bis
2259 ipsec_chkreplay(u_int32_t seq, struct secasvar *sav)
2261 const struct secreplay *replay;
2262 u_int32_t diff;
2263 int fr;
2264 u_int32_t wsizeb; /* constant: bits of window size */
2265 int frlast; /* constant: last frame */
2267 /* sanity check */
2268 if (sav == NULL)
2269 panic("ipsec_chkreplay: NULL pointer was passed.");
2271 replay = sav->replay;
2273 if (replay->wsize == 0)
2274 return 1; /* no need to check replay. */
2276 /* constant */
2277 frlast = replay->wsize - 1;
2278 wsizeb = replay->wsize << 3;
2280 /* sequence number of 0 is invalid */
2281 if (seq == 0)
2282 return 0;
2284 /* first time is always okay */
2285 if (replay->count == 0)
2286 return 1;
2288 if (seq > replay->lastseq) {
2289 /* larger sequences are okay */
2290 return 1;
2291 } else {
2292 /* seq is equal or less than lastseq. */
2293 diff = replay->lastseq - seq;
2295 /* over range to check, i.e. too old or wrapped */
2296 if (diff >= wsizeb)
2297 return 0;
2299 fr = frlast - diff / 8;
2301 /* this packet already seen ? */
2302 if (replay->bitmap[fr] & (1 << (diff % 8)))
2303 return 0;
2305 /* out of order but good */
2306 return 1;
2311 * check replay counter whether to update or not.
2312 * OUT: 0: OK
2313 * 1: NG
2314 * XXX need to update for 64bit sequence number - 2401bis
2317 ipsec_updatereplay(u_int32_t seq, struct secasvar *sav)
2319 struct secreplay *replay;
2320 u_int64_t diff;
2321 int fr;
2322 u_int32_t wsizeb; /* constant: bits of window size */
2323 int frlast; /* constant: last frame */
2325 /* sanity check */
2326 if (sav == NULL)
2327 panic("ipsec_chkreplay: NULL pointer was passed.");
2329 replay = sav->replay;
2331 if (replay->wsize == 0)
2332 goto ok; /* no need to check replay. */
2334 /* constant */
2335 frlast = replay->wsize - 1;
2336 wsizeb = replay->wsize << 3;
2338 /* sequence number of 0 is invalid */
2339 if (seq == 0)
2340 return 1;
2342 /* first time */
2343 if (replay->count == 0) {
2344 replay->lastseq = seq;
2345 memset(replay->bitmap, 0, replay->wsize);
2346 replay->bitmap[frlast] = 1;
2347 goto ok;
2350 if (seq > replay->lastseq) {
2351 /* seq is larger than lastseq. */
2352 diff = seq - replay->lastseq;
2354 /* new larger sequence number */
2355 if (diff < wsizeb) {
2356 /* In window */
2357 /* set bit for this packet */
2358 vshiftl(replay->bitmap, diff, replay->wsize);
2359 replay->bitmap[frlast] |= 1;
2360 } else {
2361 /* this packet has a "way larger" */
2362 memset(replay->bitmap, 0, replay->wsize);
2363 replay->bitmap[frlast] = 1;
2365 replay->lastseq = seq;
2367 /* larger is good */
2368 } else {
2369 /* seq is equal or less than lastseq. */
2370 diff = replay->lastseq - seq;
2372 /* over range to check, i.e. too old or wrapped */
2373 if (diff >= wsizeb)
2374 return 1;
2376 fr = frlast - diff / 8;
2378 /* this packet already seen ? */
2379 if (replay->bitmap[fr] & (1 << (diff % 8)))
2380 return 1;
2382 /* mark as seen */
2383 replay->bitmap[fr] |= (1 << (diff % 8));
2385 /* out of order but good */
2389 if (replay->count == 0xffffffff) {
2391 /* set overflow flag */
2392 replay->overflow++;
2394 /* don't increment, no more packets accepted */
2395 if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
2396 return 1;
2398 ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
2399 replay->overflow, ipsec_logsastr(sav)));
2402 replay->count++;
2404 return 0;
2408 * shift variable length buffer to left.
2409 * IN: bitmap: pointer to the buffer
2410 * nbit: the number of to shift.
2411 * wsize: buffer size (bytes).
2413 static void
2414 vshiftl(unsigned char *bitmap, int nbit, int wsize)
2416 int s, j, i;
2417 unsigned char over;
2419 for (j = 0; j < nbit; j += 8) {
2420 s = (nbit - j < 8) ? (nbit - j): 8;
2421 bitmap[0] <<= s;
2422 for (i = 1; i < wsize; i++) {
2423 over = (bitmap[i] >> (8 - s));
2424 bitmap[i] <<= s;
2425 bitmap[i - 1] |= over;
2429 return;
2432 const char *
2433 ipsec4_logpacketstr(struct ip *ip, u_int32_t spi)
2435 static char buf[256];
2436 char *p;
2437 u_int8_t *s, *d;
2439 s = (u_int8_t *)(&ip->ip_src);
2440 d = (u_int8_t *)(&ip->ip_dst);
2442 p = buf;
2443 snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
2444 while (p && *p)
2445 p++;
2446 snprintf(p, sizeof(buf) - (p - buf), "src=%u.%u.%u.%u",
2447 s[0], s[1], s[2], s[3]);
2448 while (p && *p)
2449 p++;
2450 snprintf(p, sizeof(buf) - (p - buf), " dst=%u.%u.%u.%u",
2451 d[0], d[1], d[2], d[3]);
2452 while (p && *p)
2453 p++;
2454 snprintf(p, sizeof(buf) - (p - buf), ")");
2456 return buf;
2459 #ifdef INET6
2460 const char *
2461 ipsec6_logpacketstr(struct ip6_hdr *ip6, u_int32_t spi)
2463 static char buf[256];
2464 char *p;
2466 p = buf;
2467 snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
2468 while (p && *p)
2469 p++;
2470 snprintf(p, sizeof(buf) - (p - buf), "src=%s",
2471 ip6_sprintf(&ip6->ip6_src));
2472 while (p && *p)
2473 p++;
2474 snprintf(p, sizeof(buf) - (p - buf), " dst=%s",
2475 ip6_sprintf(&ip6->ip6_dst));
2476 while (p && *p)
2477 p++;
2478 snprintf(p, sizeof(buf) - (p - buf), ")");
2480 return buf;
2482 #endif /* INET6 */
2484 const char *
2485 ipsec_logsastr(struct secasvar *sav)
2487 static char buf[256];
2488 char *p;
2489 struct secasindex *saidx = &sav->sah->saidx;
2491 /* validity check */
2492 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2493 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family)
2494 panic("ipsec_logsastr: family mismatched.");
2496 p = buf;
2497 snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
2498 while (p && *p)
2499 p++;
2500 if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET) {
2501 u_int8_t *s, *d;
2502 s = (u_int8_t *)&((struct sockaddr_in *)&saidx->src)->sin_addr;
2503 d = (u_int8_t *)&((struct sockaddr_in *)&saidx->dst)->sin_addr;
2504 snprintf(p, sizeof(buf) - (p - buf),
2505 "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
2506 s[0], s[1], s[2], s[3], d[0], d[1], d[2], d[3]);
2508 #ifdef INET6
2509 else if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET6) {
2510 snprintf(p, sizeof(buf) - (p - buf),
2511 "src=%s",
2512 ip6_sprintf(&((struct sockaddr_in6 *)&saidx->src)->sin6_addr));
2513 while (p && *p)
2514 p++;
2515 snprintf(p, sizeof(buf) - (p - buf),
2516 " dst=%s",
2517 ip6_sprintf(&((struct sockaddr_in6 *)&saidx->dst)->sin6_addr));
2519 #endif
2520 while (p && *p)
2521 p++;
2522 snprintf(p, sizeof(buf) - (p - buf), ")");
2524 return buf;
2527 void
2528 ipsec_dumpmbuf(struct mbuf *m)
2530 int totlen;
2531 int i;
2532 u_char *p;
2534 totlen = 0;
2535 printf("---\n");
2536 while (m) {
2537 p = mtod(m, u_char *);
2538 for (i = 0; i < m->m_len; i++) {
2539 printf("%02x ", p[i]);
2540 totlen++;
2541 if (totlen % 16 == 0)
2542 printf("\n");
2544 m = m->m_next;
2546 if (totlen % 16 != 0)
2547 printf("\n");
2548 printf("---\n");
2551 #ifdef INET
2552 static int
2553 ipsec4_checksa(struct ipsecrequest *isr,
2554 struct ipsec_output_state *state)
2556 struct ip *ip;
2557 struct secasindex saidx;
2558 struct sockaddr_in *sin;
2560 /* make SA index for search proper SA */
2561 ip = mtod(state->m, struct ip *);
2562 memcpy(&saidx, &isr->saidx, sizeof(saidx));
2563 saidx.mode = isr->saidx.mode;
2564 saidx.reqid = isr->saidx.reqid;
2565 sin = (struct sockaddr_in *)&saidx.src;
2566 if (sin->sin_len == 0) {
2567 memset(sin, 0, sizeof(*sin));
2568 sin->sin_len = sizeof(*sin);
2569 sin->sin_family = AF_INET;
2570 sin->sin_port = IPSEC_PORT_ANY;
2571 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(sin->sin_addr));
2573 sin = (struct sockaddr_in *)&saidx.dst;
2574 if (sin->sin_len == 0) {
2575 memset(sin, 0, sizeof(*sin));
2576 sin->sin_len = sizeof(*sin);
2577 sin->sin_family = AF_INET;
2578 sin->sin_port = IPSEC_PORT_ANY;
2579 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(sin->sin_addr));
2582 return key_checkrequest(isr, &saidx);
2585 * IPsec output logic for IPv4.
2588 ipsec4_output(struct ipsec_output_state *state, struct secpolicy *sp, int flags)
2590 struct rtentry *rt;
2591 struct ip *ip = NULL;
2592 struct ipsecrequest *isr = NULL;
2593 int s;
2594 int error;
2595 union {
2596 struct sockaddr dst;
2597 struct sockaddr_in dst4;
2598 } u;
2600 if (!state)
2601 panic("state == NULL in ipsec4_output");
2602 if (!state->m)
2603 panic("state->m == NULL in ipsec4_output");
2604 if (!state->ro)
2605 panic("state->ro == NULL in ipsec4_output");
2606 if (!state->dst)
2607 panic("state->dst == NULL in ipsec4_output");
2608 state->encap = 0;
2610 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2611 printf("ipsec4_output: applyed SP\n");
2612 kdebug_secpolicy(sp));
2614 for (isr = sp->req; isr != NULL; isr = isr->next) {
2616 #if 0 /* give up to check restriction of transport mode */
2617 /* XXX but should be checked somewhere */
2619 * some of the IPsec operation must be performed only in
2620 * originating case.
2622 if (isr->saidx.mode == IPSEC_MODE_TRANSPORT
2623 && (flags & IP_FORWARDING))
2624 continue;
2625 #endif
2626 error = ipsec4_checksa(isr, state);
2627 if (error != 0) {
2629 * IPsec processing is required, but no SA found.
2630 * I assume that key_acquire() had been called
2631 * to get/establish the SA. Here I discard
2632 * this packet because it is responsibility for
2633 * upper layer to retransmit the packet.
2635 IPSEC_STATINC(IPSEC_STAT_OUT_NOSA);
2636 goto bad;
2639 /* validity check */
2640 if (isr->sav == NULL) {
2641 switch (ipsec_get_reqlevel(isr, AF_INET)) {
2642 case IPSEC_LEVEL_USE:
2643 continue;
2644 case IPSEC_LEVEL_REQUIRE:
2645 if (isr->saidx.proto == AF_INET ||
2646 isr->saidx.proto == AF_INET6)
2647 break;
2648 /* must be not reached here. */
2649 panic("ipsec4_output: no SA found, but required.");
2654 * If there is no valid SA, we give up to process any
2655 * more. In such a case, the SA's status is changed
2656 * from DYING to DEAD after allocating. If a packet
2657 * send to the receiver by dead SA, the receiver can
2658 * not decode a packet because SA has been dead.
2660 if (isr->sav->state != SADB_SASTATE_MATURE
2661 && isr->sav->state != SADB_SASTATE_DYING) {
2662 IPSEC_STATINC(IPSEC_STAT_OUT_NOSA);
2663 error = EINVAL;
2664 goto bad;
2668 * There may be the case that SA status will be changed when
2669 * we are refering to one. So calling splsoftnet().
2671 s = splsoftnet();
2673 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2675 * build IPsec tunnel.
2677 /* XXX should be processed with other familiy */
2678 if (((struct sockaddr *)&isr->sav->sah->saidx.src)->sa_family != AF_INET) {
2679 ipseclog((LOG_ERR, "ipsec4_output: "
2680 "family mismatched between inner and outer spi=%u\n",
2681 (u_int32_t)ntohl(isr->sav->spi)));
2682 splx(s);
2683 error = EAFNOSUPPORT;
2684 goto bad;
2687 state->m = ipsec4_splithdr(state->m);
2688 if (!state->m) {
2689 splx(s);
2690 error = ENOMEM;
2691 goto bad;
2693 error = ipsec4_encapsulate(state->m, isr->sav);
2694 splx(s);
2695 if (error) {
2696 state->m = NULL;
2697 goto bad;
2699 ip = mtod(state->m, struct ip *);
2701 state->ro = &isr->sav->sah->sa_route;
2703 sockaddr_in_init(&u.dst4, &ip->ip_dst, 0);
2704 if ((rt = rtcache_lookup(state->ro, &u.dst)) == NULL) {
2705 rtcache_free(state->ro);
2706 IP_STATINC(IP_STAT_NOROUTE);
2707 error = EHOSTUNREACH;
2708 goto bad;
2711 /* XXX state->dst will dangle if the rtentry goes
2712 * away! I suggest sockaddr_dup()'ing it. --dyoung
2714 /* adjust state->dst if tunnel endpoint is offlink */
2715 if (rt->rt_flags & RTF_GATEWAY) {
2716 state->dst = rt->rt_gateway;
2717 } else {
2718 state->dst = rtcache_getdst(state->ro);
2721 state->encap++;
2722 } else
2723 splx(s);
2725 state->m = ipsec4_splithdr(state->m);
2726 if (!state->m) {
2727 error = ENOMEM;
2728 goto bad;
2730 switch (isr->saidx.proto) {
2731 case IPPROTO_ESP:
2732 #ifdef IPSEC_ESP
2733 if ((error = esp4_output(state->m, isr)) != 0) {
2734 state->m = NULL;
2735 goto bad;
2737 break;
2738 #else
2739 m_freem(state->m);
2740 state->m = NULL;
2741 error = EINVAL;
2742 goto bad;
2743 #endif
2744 case IPPROTO_AH:
2745 if ((error = ah4_output(state->m, isr)) != 0) {
2746 state->m = NULL;
2747 goto bad;
2749 break;
2750 case IPPROTO_IPCOMP:
2751 if ((error = ipcomp4_output(state->m, isr)) != 0) {
2752 state->m = NULL;
2753 goto bad;
2755 break;
2756 case IPPROTO_IPV4:
2757 break;
2758 case IPPROTO_IPV6:
2759 ipseclog((LOG_ERR, "ipsec4_output: "
2760 "family mismatched between inner and outer "
2761 "header\n"));
2762 error = EAFNOSUPPORT;
2763 goto bad;
2764 default:
2765 ipseclog((LOG_ERR,
2766 "ipsec4_output: unknown ipsec protocol %d\n",
2767 isr->saidx.proto));
2768 m_freem(state->m);
2769 state->m = NULL;
2770 error = EINVAL;
2771 goto bad;
2774 if (state->m == 0) {
2775 error = ENOMEM;
2776 goto bad;
2778 ip = mtod(state->m, struct ip *);
2781 return 0;
2783 bad:
2784 m_freem(state->m);
2785 state->m = NULL;
2786 return error;
2788 #endif
2790 #ifdef INET6
2791 static int
2792 ipsec6_checksa(struct ipsecrequest *isr,
2793 struct ipsec_output_state *state, int tunnel)
2795 struct ip6_hdr *ip6;
2796 struct secasindex saidx;
2797 struct sockaddr_in6 *sin6;
2799 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2800 #ifdef DIAGNOSTIC
2801 if (!tunnel)
2802 panic("ipsec6_checksa/inconsistent tunnel attribute");
2803 #endif
2804 /* When tunnel mode, SA peers must be specified. */
2805 return key_checkrequest(isr, &isr->saidx);
2808 /* make SA index for search proper SA */
2809 ip6 = mtod(state->m, struct ip6_hdr *);
2810 if (tunnel) {
2811 memset(&saidx, 0, sizeof(saidx));
2812 saidx.proto = isr->saidx.proto;
2813 } else
2814 memcpy(&saidx, &isr->saidx, sizeof(saidx));
2815 saidx.mode = isr->saidx.mode;
2816 saidx.reqid = isr->saidx.reqid;
2817 sin6 = (struct sockaddr_in6 *)&saidx.src;
2818 if (sin6->sin6_len == 0 || tunnel) {
2819 memset(sin6, 0, sizeof(*sin6));
2820 sin6->sin6_len = sizeof(*sin6);
2821 sin6->sin6_family = AF_INET6;
2822 sin6->sin6_port = IPSEC_PORT_ANY;
2823 sin6->sin6_addr = ip6->ip6_src;
2825 sin6 = (struct sockaddr_in6 *)&saidx.dst;
2826 if (sin6->sin6_len == 0 || tunnel) {
2827 memset(sin6, 0, sizeof(*sin6));
2828 sin6->sin6_len = sizeof(*sin6);
2829 sin6->sin6_family = AF_INET6;
2830 sin6->sin6_port = IPSEC_PORT_ANY;
2831 sin6->sin6_addr = ip6->ip6_dst;
2834 return key_checkrequest(isr, &saidx);
2837 * IPsec output logic for IPv6, transport mode.
2840 ipsec6_output_trans(struct ipsec_output_state *state, u_char *nexthdrp,
2841 struct mbuf *mprev, struct secpolicy *sp, int flags, int *tun)
2843 struct ip6_hdr *ip6;
2844 struct ipsecrequest *isr = NULL;
2845 int error = 0;
2846 int plen;
2848 if (!state)
2849 panic("state == NULL in ipsec6_output_trans");
2850 if (!state->m)
2851 panic("state->m == NULL in ipsec6_output_trans");
2852 if (!nexthdrp)
2853 panic("nexthdrp == NULL in ipsec6_output_trans");
2854 if (!mprev)
2855 panic("mprev == NULL in ipsec6_output_trans");
2856 if (!sp)
2857 panic("sp == NULL in ipsec6_output_trans");
2858 if (!tun)
2859 panic("tun == NULL in ipsec6_output_trans");
2861 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2862 printf("ipsec6_output_trans: applyed SP\n");
2863 kdebug_secpolicy(sp));
2865 *tun = 0;
2866 for (isr = sp->req; isr; isr = isr->next) {
2867 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2868 /* the rest will be handled by ipsec6_output_tunnel() */
2869 break;
2872 error = ipsec6_checksa(isr, state, 0);
2873 if (error == ENOENT) {
2875 * IPsec processing is required, but no SA found.
2876 * I assume that key_acquire() had been called
2877 * to get/establish the SA. Here I discard
2878 * this packet because it is responsibility for
2879 * upper layer to retransmit the packet.
2881 IPSEC6_STATINC(IPSEC_STAT_OUT_NOSA);
2884 * Notify the fact that the packet is discarded
2885 * to ourselves. I believe this is better than
2886 * just silently discarding. (jinmei@kame.net)
2887 * XXX: should we restrict the error to TCP packets?
2888 * XXX: should we directly notify sockets via
2889 * pfctlinputs?
2891 * Noone have initialized rcvif until this point,
2892 * so clear it.
2894 if ((state->m->m_flags & M_PKTHDR) != 0)
2895 state->m->m_pkthdr.rcvif = NULL;
2896 icmp6_error(state->m, ICMP6_DST_UNREACH,
2897 ICMP6_DST_UNREACH_ADMIN, 0);
2898 state->m = NULL; /* icmp6_error freed the mbuf */
2899 goto bad;
2902 /* validity check */
2903 if (isr->sav == NULL) {
2904 switch (ipsec_get_reqlevel(isr, AF_INET6)) {
2905 case IPSEC_LEVEL_USE:
2906 continue;
2907 case IPSEC_LEVEL_REQUIRE:
2908 /* must be not reached here. */
2909 panic("ipsec6_output_trans: no SA found, but required.");
2914 * If there is no valid SA, we give up to process.
2915 * see same place at ipsec4_output().
2917 if (isr->sav->state != SADB_SASTATE_MATURE
2918 && isr->sav->state != SADB_SASTATE_DYING) {
2919 IPSEC6_STATINC(IPSEC_STAT_OUT_NOSA);
2920 error = EINVAL;
2921 goto bad;
2924 switch (isr->saidx.proto) {
2925 case IPPROTO_ESP:
2926 #ifdef IPSEC_ESP
2927 error = esp6_output(state->m, nexthdrp, mprev->m_next, isr);
2928 #else
2929 m_freem(state->m);
2930 error = EINVAL;
2931 #endif
2932 break;
2933 case IPPROTO_AH:
2934 error = ah6_output(state->m, nexthdrp, mprev->m_next, isr);
2935 break;
2936 case IPPROTO_IPCOMP:
2937 error = ipcomp6_output(state->m, nexthdrp, mprev->m_next, isr);
2938 break;
2939 default:
2940 ipseclog((LOG_ERR, "ipsec6_output_trans: "
2941 "unknown ipsec protocol %d\n", isr->saidx.proto));
2942 m_freem(state->m);
2943 IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
2944 error = EINVAL;
2945 break;
2947 if (error) {
2948 state->m = NULL;
2949 goto bad;
2951 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
2952 if (plen > IPV6_MAXPACKET) {
2953 ipseclog((LOG_ERR, "ipsec6_output_trans: "
2954 "IPsec with IPv6 jumbogram is not supported\n"));
2955 IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
2956 error = EINVAL; /* XXX */
2957 goto bad;
2959 ip6 = mtod(state->m, struct ip6_hdr *);
2960 ip6->ip6_plen = htons(plen);
2963 /* if we have more to go, we need a tunnel mode processing */
2964 if (isr != NULL)
2965 *tun = 1;
2967 return 0;
2969 bad:
2970 m_freem(state->m);
2971 state->m = NULL;
2972 return error;
2976 * IPsec output logic for IPv6, tunnel mode.
2979 ipsec6_output_tunnel(struct ipsec_output_state *state, struct secpolicy *sp,
2980 int flags)
2982 struct rtentry *rt;
2983 struct ip6_hdr *ip6;
2984 struct ipsecrequest *isr = NULL;
2985 int error = 0;
2986 int plen;
2987 int s;
2989 if (!state)
2990 panic("state == NULL in ipsec6_output_tunnel");
2991 if (!state->m)
2992 panic("state->m == NULL in ipsec6_output_tunnel");
2993 if (!sp)
2994 panic("sp == NULL in ipsec6_output_tunnel");
2996 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2997 printf("ipsec6_output_tunnel: applyed SP\n");
2998 kdebug_secpolicy(sp));
3001 * transport mode ipsec (before the 1st tunnel mode) is already
3002 * processed by ipsec6_output_trans().
3004 for (isr = sp->req; isr; isr = isr->next) {
3005 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
3006 break;
3009 for (/* already initialized */; isr; isr = isr->next) {
3010 error = ipsec6_checksa(isr, state, 1);
3011 if (error == ENOENT) {
3013 * IPsec processing is required, but no SA found.
3014 * I assume that key_acquire() had been called
3015 * to get/establish the SA. Here I discard
3016 * this packet because it is responsibility for
3017 * upper layer to retransmit the packet.
3019 IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
3020 error = ENOENT;
3021 goto bad;
3024 /* validity check */
3025 if (isr->sav == NULL) {
3026 switch (ipsec_get_reqlevel(isr, AF_INET6)) {
3027 case IPSEC_LEVEL_USE:
3028 continue;
3029 case IPSEC_LEVEL_REQUIRE:
3030 /* must be not reached here. */
3031 panic("ipsec6_output_tunnel: no SA found, but required.");
3036 * If there is no valid SA, we give up to process.
3037 * see same place at ipsec4_output().
3039 if (isr->sav->state != SADB_SASTATE_MATURE
3040 && isr->sav->state != SADB_SASTATE_DYING) {
3041 IPSEC6_STATINC(IPSEC_STAT_OUT_NOSA);
3042 error = EINVAL;
3043 goto bad;
3047 * There may be the case that SA status will be changed when
3048 * we are refering to one. So calling splsoftnet().
3050 s = splsoftnet();
3052 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
3054 * build IPsec tunnel.
3056 /* XXX should be processed with other familiy */
3057 if (((struct sockaddr *)&isr->sav->sah->saidx.src)->sa_family != AF_INET6) {
3058 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3059 "family mismatched between inner and outer, spi=%u\n",
3060 (u_int32_t)ntohl(isr->sav->spi)));
3061 splx(s);
3062 IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
3063 error = EAFNOSUPPORT;
3064 goto bad;
3067 state->m = ipsec6_splithdr(state->m);
3068 if (!state->m) {
3069 splx(s);
3070 IPSEC6_STATINC(IPSEC_STAT_OUT_NOMEM);
3071 error = ENOMEM;
3072 goto bad;
3074 error = ipsec6_encapsulate(state->m, isr->sav);
3075 splx(s);
3076 if (error) {
3077 state->m = 0;
3078 goto bad;
3080 ip6 = mtod(state->m, struct ip6_hdr *);
3082 state->ro = &isr->sav->sah->sa_route;
3083 union {
3084 struct sockaddr dst;
3085 struct sockaddr_in6 dst6;
3086 } u;
3088 sockaddr_in6_init(&u.dst6, &ip6->ip6_dst, 0, 0, 0);
3089 if ((rt = rtcache_lookup(state->ro, &u.dst)) == NULL) {
3090 rtcache_free(state->ro);
3091 IP6_STATINC(IP6_STAT_NOROUTE);
3092 IPSEC6_STATINC(IPSEC_STAT_OUT_NOROUTE);
3093 error = EHOSTUNREACH;
3094 goto bad;
3097 /* XXX state->dst will dangle if the rtentry goes
3098 * away! I suggest sockaddr_dup()'ing it. --dyoung
3100 /* adjust state->dst if tunnel endpoint is offlink */
3101 if (rt->rt_flags & RTF_GATEWAY) {
3102 state->dst = rt->rt_gateway;
3103 } else
3104 state->dst = rtcache_getdst(state->ro);
3105 } else
3106 splx(s);
3108 state->m = ipsec6_splithdr(state->m);
3109 if (!state->m) {
3110 IPSEC6_STATINC(IPSEC_STAT_OUT_NOMEM);
3111 error = ENOMEM;
3112 goto bad;
3114 ip6 = mtod(state->m, struct ip6_hdr *);
3115 switch (isr->saidx.proto) {
3116 case IPPROTO_ESP:
3117 #ifdef IPSEC_ESP
3118 error = esp6_output(state->m, &ip6->ip6_nxt,
3119 state->m->m_next, isr);
3120 #else
3121 m_freem(state->m);
3122 error = EINVAL;
3123 #endif
3124 break;
3125 case IPPROTO_AH:
3126 error = ah6_output(state->m, &ip6->ip6_nxt,
3127 state->m->m_next, isr);
3128 break;
3129 case IPPROTO_IPCOMP:
3130 /* XXX code should be here */
3131 /* FALLTHROUGH */
3132 default:
3133 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3134 "unknown ipsec protocol %d\n", isr->saidx.proto));
3135 m_freem(state->m);
3136 IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
3137 error = EINVAL;
3138 break;
3140 if (error) {
3141 state->m = NULL;
3142 goto bad;
3144 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
3145 if (plen > IPV6_MAXPACKET) {
3146 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3147 "IPsec with IPv6 jumbogram is not supported\n"));
3148 IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
3149 error = EINVAL; /* XXX */
3150 goto bad;
3152 ip6 = mtod(state->m, struct ip6_hdr *);
3153 ip6->ip6_plen = htons(plen);
3156 return 0;
3158 bad:
3159 m_freem(state->m);
3160 state->m = NULL;
3161 return error;
3163 #endif /* INET6 */
3165 #ifdef INET
3167 * Chop IP header and option off from the payload.
3169 static struct mbuf *
3170 ipsec4_splithdr(struct mbuf *m)
3172 struct mbuf *mh;
3173 struct ip *ip;
3174 int hlen;
3176 if (m->m_len < sizeof(struct ip)) {
3177 /* XXX Print and drop until we understand. */
3178 printf("ipsec4_splithdr: m->m_len %d m_length %d < %zu\n",
3179 m->m_len, m_length(m), sizeof(struct ip));
3180 m_freem(m);
3181 return NULL;
3182 #if 0
3183 panic("ipsec4_splithdr: first mbuf too short");
3184 #endif
3186 ip = mtod(m, struct ip *);
3187 hlen = ip->ip_hl << 2;
3188 if (m->m_len > hlen) {
3189 MGETHDR(mh, M_DONTWAIT, MT_HEADER);
3190 if (!mh) {
3191 m_freem(m);
3192 return NULL;
3194 M_MOVE_PKTHDR(mh, m);
3195 MH_ALIGN(mh, hlen);
3196 m->m_len -= hlen;
3197 m->m_data += hlen;
3198 mh->m_next = m;
3199 m = mh;
3200 m->m_len = hlen;
3201 memcpy(mtod(m, void *), (void *)ip, hlen);
3202 } else if (m->m_len < hlen) {
3203 m = m_pullup(m, hlen);
3204 if (!m)
3205 return NULL;
3207 return m;
3209 #endif
3211 #ifdef INET6
3212 static struct mbuf *
3213 ipsec6_splithdr(struct mbuf *m)
3215 struct mbuf *mh;
3216 struct ip6_hdr *ip6;
3217 int hlen;
3219 if (m->m_len < sizeof(struct ip6_hdr))
3220 panic("ipsec6_splithdr: first mbuf too short");
3221 ip6 = mtod(m, struct ip6_hdr *);
3222 hlen = sizeof(struct ip6_hdr);
3223 if (m->m_len > hlen) {
3224 MGETHDR(mh, M_DONTWAIT, MT_HEADER);
3225 if (!mh) {
3226 m_freem(m);
3227 return NULL;
3229 M_MOVE_PKTHDR(mh, m);
3230 MH_ALIGN(mh, hlen);
3231 m->m_len -= hlen;
3232 m->m_data += hlen;
3233 mh->m_next = m;
3234 m = mh;
3235 m->m_len = hlen;
3236 memcpy(mtod(m, void *), (void *)ip6, hlen);
3237 } else if (m->m_len < hlen) {
3238 m = m_pullup(m, hlen);
3239 if (!m)
3240 return NULL;
3242 return m;
3244 #endif
3246 /* validate inbound IPsec tunnel packet. */
3248 ipsec4_tunnel_validate(struct ip *ip, u_int nxt0,
3249 struct secasvar *sav)
3251 u_int8_t nxt = nxt0 & 0xff;
3252 struct sockaddr_in *sin;
3253 int hlen;
3255 if (nxt != IPPROTO_IPV4)
3256 return 0;
3257 /* do not decapsulate if the SA is for transport mode only */
3258 if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
3259 return 0;
3260 hlen = ip->ip_hl << 2;
3261 if (hlen != sizeof(struct ip))
3262 return 0;
3263 switch (((struct sockaddr *)&sav->sah->saidx.dst)->sa_family) {
3264 case AF_INET:
3265 sin = (struct sockaddr_in *)&sav->sah->saidx.dst;
3266 if (memcmp(&ip->ip_dst, &sin->sin_addr, sizeof(ip->ip_dst)) != 0)
3267 return 0;
3268 break;
3269 #ifdef INET6
3270 case AF_INET6:
3271 /* should be supported, but at this moment we don't. */
3272 /*FALLTHROUGH*/
3273 #endif
3274 default:
3275 return 0;
3278 return 1;
3281 #ifdef INET6
3282 /* validate inbound IPsec tunnel packet. */
3284 ipsec6_tunnel_validate(struct ip6_hdr *ip6, u_int nxt0,
3285 struct secasvar *sav)
3287 u_int8_t nxt = nxt0 & 0xff;
3288 struct sockaddr_in6 sin6;
3290 if (nxt != IPPROTO_IPV6)
3291 return 0;
3292 /* do not decapsulate if the SA is for transport mode only */
3293 if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
3294 return 0;
3295 switch (((struct sockaddr *)&sav->sah->saidx.dst)->sa_family) {
3296 case AF_INET6:
3297 sin6 = *((struct sockaddr_in6 *)&sav->sah->saidx.dst);
3298 if (sa6_embedscope(&sin6, 0) != 0)
3299 return 0;
3300 if (!IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &sin6.sin6_addr))
3301 return 0;
3302 break;
3303 case AF_INET:
3304 /* should be supported, but at this moment we don't. */
3305 /*FALLTHROUGH*/
3306 default:
3307 return 0;
3310 return 1;
3312 #endif
3315 * Make a mbuf chain for encryption.
3316 * If the original mbuf chain contains a mbuf with a cluster,
3317 * allocate a new cluster and copy the data to the new cluster.
3318 * XXX: this hack is inefficient, but is necessary to handle cases
3319 * of TCP retransmission...
3321 struct mbuf *
3322 ipsec_copypkt(struct mbuf *m)
3324 struct mbuf *n, **mpp, *mnew;
3326 for (n = m, mpp = &m; n; n = n->m_next) {
3327 if (n->m_flags & M_EXT) {
3329 * Make a copy only if there is more than one
3330 * references to the cluster.
3331 * XXX: is this approach effective?
3333 if (M_READONLY(n))
3335 int remain, copied;
3336 struct mbuf *mm;
3338 if (n->m_flags & M_PKTHDR) {
3339 MGETHDR(mnew, M_DONTWAIT, MT_HEADER);
3340 if (mnew == NULL)
3341 goto fail;
3342 mnew->m_pkthdr = n->m_pkthdr;
3343 #if 0
3344 /* XXX: convert to m_tag or delete? */
3345 if (n->m_pkthdr.aux) {
3346 mnew->m_pkthdr.aux =
3347 m_copym(n->m_pkthdr.aux,
3348 0, M_COPYALL, M_DONTWAIT);
3350 #endif
3351 M_MOVE_PKTHDR(mnew, n);
3353 else {
3354 MGET(mnew, M_DONTWAIT, MT_DATA);
3355 if (mnew == NULL)
3356 goto fail;
3358 mnew->m_len = 0;
3359 mm = mnew;
3362 * Copy data. If we don't have enough space to
3363 * store the whole data, allocate a cluster
3364 * or additional mbufs.
3365 * XXX: we don't use m_copyback(), since the
3366 * function does not use clusters and thus is
3367 * inefficient.
3369 remain = n->m_len;
3370 copied = 0;
3371 while (1) {
3372 int len;
3373 struct mbuf *mn;
3375 if (remain <= (mm->m_flags & M_PKTHDR ? MHLEN : MLEN))
3376 len = remain;
3377 else { /* allocate a cluster */
3378 MCLGET(mm, M_DONTWAIT);
3379 if (!(mm->m_flags & M_EXT)) {
3380 m_free(mm);
3381 goto fail;
3383 len = remain < MCLBYTES ?
3384 remain : MCLBYTES;
3387 memcpy(mm->m_data, n->m_data + copied,
3388 len);
3390 copied += len;
3391 remain -= len;
3392 mm->m_len = len;
3394 if (remain <= 0) /* completed? */
3395 break;
3397 /* need another mbuf */
3398 MGETHDR(mn, M_DONTWAIT, MT_HEADER);
3399 if (mn == NULL)
3400 goto fail;
3401 mn->m_pkthdr.rcvif = NULL;
3402 mm->m_next = mn;
3403 mm = mn;
3406 /* adjust chain */
3407 mm->m_next = m_free(n);
3408 n = mm;
3409 *mpp = mnew;
3410 mpp = &n->m_next;
3412 continue;
3415 *mpp = n;
3416 mpp = &n->m_next;
3419 return (m);
3420 fail:
3421 m_freem(m);
3422 return (NULL);
3425 static struct m_tag *
3426 ipsec_addaux(struct mbuf *m)
3428 struct m_tag *mtag;
3430 mtag = m_tag_find(m, PACKET_TAG_ESP, NULL);
3431 if (mtag == NULL) {
3432 mtag = m_tag_get(PACKET_TAG_ESP, sizeof(struct ipsecaux),
3433 M_NOWAIT);
3434 if (mtag != NULL)
3435 m_tag_prepend(m, mtag);
3437 if (mtag == NULL)
3438 return NULL; /* ENOBUFS */
3439 /* XXX is this necessary? */
3440 memset((void *)(mtag + 1), 0, sizeof(struct ipsecaux));
3441 return mtag;
3444 static struct m_tag *
3445 ipsec_findaux(struct mbuf *m)
3447 return m_tag_find(m, PACKET_TAG_ESP, NULL);
3450 void
3451 ipsec_delaux(struct mbuf *m)
3453 struct m_tag *mtag;
3455 mtag = m_tag_find(m, PACKET_TAG_ESP, NULL);
3456 if (mtag != NULL)
3457 m_tag_delete(m, mtag);
3460 /* if the aux buffer is unnecessary, nuke it. */
3461 static void
3462 ipsec_optaux(struct mbuf *m, struct m_tag *mtag)
3464 struct ipsecaux *aux;
3466 if (mtag == NULL)
3467 return;
3468 aux = (struct ipsecaux *)(mtag + 1);
3469 if (!aux->so && !aux->sp)
3470 ipsec_delaux(m);
3474 ipsec_addhist(struct mbuf *m, int proto, u_int32_t spi)
3476 struct m_tag *mtag;
3477 struct ipsecaux *aux;
3479 mtag = ipsec_addaux(m);
3480 if (mtag == NULL)
3481 return ENOBUFS;
3482 aux = (struct ipsecaux *)(mtag + 1);
3483 aux->hdrs++;
3484 return 0;
3488 ipsec_getnhist(struct mbuf *m)
3490 struct m_tag *mtag;
3491 struct ipsecaux *aux;
3493 mtag = ipsec_findaux(m);
3494 if (mtag == NULL)
3495 return 0;
3496 aux = (struct ipsecaux *)(mtag + 1);
3497 return aux->hdrs;
3500 struct ipsec_history *
3501 ipsec_gethist(struct mbuf *m, int *lenp)
3504 panic("ipsec_gethist: obsolete API");
3507 void
3508 ipsec_clearhist(struct mbuf *m)
3510 struct m_tag *mtag;
3512 mtag = ipsec_findaux(m);
3513 ipsec_optaux(m, mtag);
3517 * System control for IPSEC
3519 u_char ipsecctlermap[PRC_NCMDS] = {
3520 0, 0, 0, 0,
3521 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH,
3522 EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED,
3523 EMSGSIZE, EHOSTUNREACH, 0, 0,
3524 0, 0, 0, 0,
3525 ENOPROTOOPT
3529 * sysctl helper routine for some net.inet.ipsec and net.inet6.ipnet6
3530 * nodes. ensures that the given value is correct and clears the
3531 * ipsec cache accordingly.
3533 static int
3534 sysctl_ipsec(SYSCTLFN_ARGS)
3536 int error, t;
3537 struct sysctlnode node;
3539 node = *rnode;
3540 if (rnode->sysctl_num == IPSECCTL_DEF_POLICY)
3541 t = (*((struct secpolicy**)rnode->sysctl_data))->policy;
3542 else
3543 t = *(int*)rnode->sysctl_data;
3544 node.sysctl_data = &t;
3545 error = sysctl_lookup(SYSCTLFN_CALL(&node));
3546 if (error || newp == NULL)
3547 return (error);
3549 switch (rnode->sysctl_num) {
3550 case IPSECCTL_DEF_ESP_TRANSLEV:
3551 case IPSECCTL_DEF_ESP_NETLEV:
3552 case IPSECCTL_DEF_AH_TRANSLEV:
3553 case IPSECCTL_DEF_AH_NETLEV:
3554 if (t != IPSEC_LEVEL_USE &&
3555 t != IPSEC_LEVEL_REQUIRE)
3556 return (EINVAL);
3557 ipsec_invalpcbcacheall();
3558 break;
3559 case IPSECCTL_DEF_POLICY:
3560 if (t != IPSEC_POLICY_DISCARD &&
3561 t != IPSEC_POLICY_NONE)
3562 return (EINVAL);
3563 ipsec_invalpcbcacheall();
3564 break;
3565 default:
3566 return (EINVAL);
3569 if (rnode->sysctl_num == IPSECCTL_DEF_POLICY)
3570 (*((struct secpolicy**)rnode->sysctl_data))->policy = t;
3571 else
3572 *(int*)rnode->sysctl_data = t;
3574 return (0);
3577 static int
3578 sysctl_net_inet_ipsec_stats(SYSCTLFN_ARGS)
3581 return (NETSTAT_SYSCTL(ipsecstat_percpu, IPSEC_NSTATS));
3584 SYSCTL_SETUP(sysctl_net_inet_ipsec_setup, "sysctl net.inet.ipsec subtree setup")
3587 sysctl_createv(clog, 0, NULL, NULL,
3588 CTLFLAG_PERMANENT,
3589 CTLTYPE_NODE, "net", NULL,
3590 NULL, 0, NULL, 0,
3591 CTL_NET, CTL_EOL);
3592 sysctl_createv(clog, 0, NULL, NULL,
3593 CTLFLAG_PERMANENT,
3594 CTLTYPE_NODE, "inet", NULL,
3595 NULL, 0, NULL, 0,
3596 CTL_NET, PF_INET, CTL_EOL);
3597 sysctl_createv(clog, 0, NULL, NULL,
3598 CTLFLAG_PERMANENT,
3599 CTLTYPE_NODE, "ipsec",
3600 SYSCTL_DESCR("IPv4 related IPSec settings"),
3601 NULL, 0, NULL, 0,
3602 CTL_NET, PF_INET, IPPROTO_AH, CTL_EOL);
3604 sysctl_createv(clog, 0, NULL, NULL,
3605 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3606 CTLTYPE_STRUCT, "stats",
3607 SYSCTL_DESCR("IPSec statistics and counters"),
3608 sysctl_net_inet_ipsec_stats, 0, NULL, 0,
3609 CTL_NET, PF_INET, IPPROTO_AH,
3610 IPSECCTL_STATS, CTL_EOL);
3611 sysctl_createv(clog, 0, NULL, NULL,
3612 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3613 CTLTYPE_INT, "def_policy",
3614 SYSCTL_DESCR("Default action for non-IPSec packets"),
3615 sysctl_ipsec, 0, &ip4_def_policy, 0,
3616 CTL_NET, PF_INET, IPPROTO_AH,
3617 IPSECCTL_DEF_POLICY, CTL_EOL);
3618 sysctl_createv(clog, 0, NULL, NULL,
3619 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3620 CTLTYPE_INT, "esp_trans_deflev",
3621 SYSCTL_DESCR("Default required security level for "
3622 "transport mode traffic"),
3623 sysctl_ipsec, 0, &ip4_esp_trans_deflev, 0,
3624 CTL_NET, PF_INET, IPPROTO_AH,
3625 IPSECCTL_DEF_ESP_TRANSLEV, CTL_EOL);
3626 sysctl_createv(clog, 0, NULL, NULL,
3627 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3628 CTLTYPE_INT, "esp_net_deflev",
3629 SYSCTL_DESCR("Default required security level for "
3630 "tunneled traffic"),
3631 sysctl_ipsec, 0, &ip4_esp_net_deflev, 0,
3632 CTL_NET, PF_INET, IPPROTO_AH,
3633 IPSECCTL_DEF_ESP_NETLEV, CTL_EOL);
3634 sysctl_createv(clog, 0, NULL, NULL,
3635 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3636 CTLTYPE_INT, "ah_trans_deflev",
3637 SYSCTL_DESCR("Default required security level for "
3638 "transport mode headers"),
3639 sysctl_ipsec, 0, &ip4_ah_trans_deflev, 0,
3640 CTL_NET, PF_INET, IPPROTO_AH,
3641 IPSECCTL_DEF_AH_TRANSLEV, CTL_EOL);
3642 sysctl_createv(clog, 0, NULL, NULL,
3643 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3644 CTLTYPE_INT, "ah_net_deflev",
3645 SYSCTL_DESCR("Default required security level for "
3646 "tunneled headers"),
3647 sysctl_ipsec, 0, &ip4_ah_net_deflev, 0,
3648 CTL_NET, PF_INET, IPPROTO_AH,
3649 IPSECCTL_DEF_AH_NETLEV, CTL_EOL);
3650 #if 0 /* obsolete, do not reuse */
3651 sysctl_createv(clog, 0, NULL, NULL,
3652 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3653 CTLTYPE_INT, "inbound_call_ike", NULL,
3654 NULL, 0, &ip4_inbound_call_ike, 0,
3655 CTL_NET, PF_INET, IPPROTO_AH,
3656 IPSECCTL_INBOUND_CALL_IKE, CTL_EOL);
3657 #endif
3658 sysctl_createv(clog, 0, NULL, NULL,
3659 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3660 CTLTYPE_INT, "ah_cleartos",
3661 SYSCTL_DESCR("Clear IP TOS field before calculating AH"),
3662 NULL, 0, &ip4_ah_cleartos, 0,
3663 CTL_NET, PF_INET, IPPROTO_AH,
3664 IPSECCTL_AH_CLEARTOS, CTL_EOL);
3665 sysctl_createv(clog, 0, NULL, NULL,
3666 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3667 CTLTYPE_INT, "ah_offsetmask",
3668 SYSCTL_DESCR("Mask for IP fragment offset field when "
3669 "calculating AH"),
3670 NULL, 0, &ip4_ah_offsetmask, 0,
3671 CTL_NET, PF_INET, IPPROTO_AH,
3672 IPSECCTL_AH_OFFSETMASK, CTL_EOL);
3673 sysctl_createv(clog, 0, NULL, NULL,
3674 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3675 CTLTYPE_INT, "dfbit",
3676 SYSCTL_DESCR("IP header DF bit setting for tunneled "
3677 "traffic"),
3678 NULL, 0, &ip4_ipsec_dfbit, 0,
3679 CTL_NET, PF_INET, IPPROTO_AH,
3680 IPSECCTL_DFBIT, CTL_EOL);
3681 sysctl_createv(clog, 0, NULL, NULL,
3682 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3683 CTLTYPE_INT, "ecn",
3684 SYSCTL_DESCR("Behavior of ECN for tunneled traffic"),
3685 NULL, 0, &ip4_ipsec_ecn, 0,
3686 CTL_NET, PF_INET, IPPROTO_AH,
3687 IPSECCTL_ECN, CTL_EOL);
3688 sysctl_createv(clog, 0, NULL, NULL,
3689 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3690 CTLTYPE_INT, "debug",
3691 SYSCTL_DESCR("Enable IPSec debugging output"),
3692 NULL, 0, &ipsec_debug, 0,
3693 CTL_NET, PF_INET, IPPROTO_AH,
3694 IPSECCTL_DEBUG, CTL_EOL);
3697 * "aliases" for the ipsec subtree
3699 sysctl_createv(clog, 0, NULL, NULL,
3700 CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
3701 CTLTYPE_NODE, "esp", NULL,
3702 NULL, IPPROTO_AH, NULL, 0,
3703 CTL_NET, PF_INET, IPPROTO_ESP, CTL_EOL);
3704 sysctl_createv(clog, 0, NULL, NULL,
3705 CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
3706 CTLTYPE_NODE, "ipcomp", NULL,
3707 NULL, IPPROTO_AH, NULL, 0,
3708 CTL_NET, PF_INET, IPPROTO_IPCOMP, CTL_EOL);
3709 sysctl_createv(clog, 0, NULL, NULL,
3710 CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
3711 CTLTYPE_NODE, "ah", NULL,
3712 NULL, IPPROTO_AH, NULL, 0,
3713 CTL_NET, PF_INET, CTL_CREATE, CTL_EOL);
3716 #ifdef INET6
3718 * System control for IPSEC6
3720 u_char ipsec6ctlermap[PRC_NCMDS] = {
3721 0, 0, 0, 0,
3722 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH,
3723 EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED,
3724 EMSGSIZE, EHOSTUNREACH, 0, 0,
3725 0, 0, 0, 0,
3726 ENOPROTOOPT
3729 static int
3730 sysctl_net_inet6_ipsec6_stats(SYSCTLFN_ARGS)
3733 return (NETSTAT_SYSCTL(ipsec6stat_percpu, IPSEC_NSTATS));
3736 SYSCTL_SETUP(sysctl_net_inet6_ipsec6_setup,
3737 "sysctl net.inet6.ipsec6 subtree setup")
3740 sysctl_createv(clog, 0, NULL, NULL,
3741 CTLFLAG_PERMANENT,
3742 CTLTYPE_NODE, "net", NULL,
3743 NULL, 0, NULL, 0,
3744 CTL_NET, CTL_EOL);
3745 sysctl_createv(clog, 0, NULL, NULL,
3746 CTLFLAG_PERMANENT,
3747 CTLTYPE_NODE, "inet6", NULL,
3748 NULL, 0, NULL, 0,
3749 CTL_NET, PF_INET6, CTL_EOL);
3750 sysctl_createv(clog, 0, NULL, NULL,
3751 CTLFLAG_PERMANENT,
3752 CTLTYPE_NODE, "ipsec6",
3753 SYSCTL_DESCR("IPv6 related IPSec settings"),
3754 NULL, 0, NULL, 0,
3755 CTL_NET, PF_INET6, IPPROTO_AH, CTL_EOL);
3757 sysctl_createv(clog, 0, NULL, NULL,
3758 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3759 CTLTYPE_STRUCT, "stats",
3760 SYSCTL_DESCR("IPSec statistics and counters"),
3761 sysctl_net_inet6_ipsec6_stats, 0, NULL, 0,
3762 CTL_NET, PF_INET6, IPPROTO_AH,
3763 IPSECCTL_STATS, CTL_EOL);
3764 sysctl_createv(clog, 0, NULL, NULL,
3765 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3766 CTLTYPE_INT, "def_policy",
3767 SYSCTL_DESCR("Default action for non-IPSec packets"),
3768 sysctl_ipsec, 0, &ip6_def_policy, 0,
3769 CTL_NET, PF_INET6, IPPROTO_AH,
3770 IPSECCTL_DEF_POLICY, CTL_EOL);
3771 sysctl_createv(clog, 0, NULL, NULL,
3772 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3773 CTLTYPE_INT, "esp_trans_deflev",
3774 SYSCTL_DESCR("Default required security level for "
3775 "transport mode traffic"),
3776 sysctl_ipsec, 0, &ip6_esp_trans_deflev, 0,
3777 CTL_NET, PF_INET6, IPPROTO_AH,
3778 IPSECCTL_DEF_ESP_TRANSLEV, CTL_EOL);
3779 sysctl_createv(clog, 0, NULL, NULL,
3780 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3781 CTLTYPE_INT, "esp_net_deflev",
3782 SYSCTL_DESCR("Default required security level for "
3783 "tunneled traffic"),
3784 sysctl_ipsec, 0, &ip6_esp_net_deflev, 0,
3785 CTL_NET, PF_INET6, IPPROTO_AH,
3786 IPSECCTL_DEF_ESP_NETLEV, CTL_EOL);
3787 sysctl_createv(clog, 0, NULL, NULL,
3788 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3789 CTLTYPE_INT, "ah_trans_deflev",
3790 SYSCTL_DESCR("Default required security level for "
3791 "transport mode headers"),
3792 sysctl_ipsec, 0, &ip6_ah_trans_deflev, 0,
3793 CTL_NET, PF_INET6, IPPROTO_AH,
3794 IPSECCTL_DEF_AH_TRANSLEV, CTL_EOL);
3795 sysctl_createv(clog, 0, NULL, NULL,
3796 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3797 CTLTYPE_INT, "ah_net_deflev",
3798 SYSCTL_DESCR("Default required security level for "
3799 "tunneled headers"),
3800 sysctl_ipsec, 0, &ip6_ah_net_deflev, 0,
3801 CTL_NET, PF_INET6, IPPROTO_AH,
3802 IPSECCTL_DEF_AH_NETLEV, CTL_EOL);
3803 sysctl_createv(clog, 0, NULL, NULL,
3804 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3805 CTLTYPE_INT, "ecn",
3806 SYSCTL_DESCR("Behavior of ECN for tunneled traffic"),
3807 NULL, 0, &ip6_ipsec_ecn, 0,
3808 CTL_NET, PF_INET6, IPPROTO_AH,
3809 IPSECCTL_ECN, CTL_EOL);
3810 sysctl_createv(clog, 0, NULL, NULL,
3811 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3812 CTLTYPE_INT, "debug",
3813 SYSCTL_DESCR("Enable IPSec debugging output"),
3814 NULL, 0, &ipsec_debug, 0,
3815 CTL_NET, PF_INET6, IPPROTO_AH,
3816 IPSECCTL_DEBUG, CTL_EOL);
3819 * "aliases" for the ipsec6 subtree
3821 sysctl_createv(clog, 0, NULL, NULL,
3822 CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
3823 CTLTYPE_NODE, "esp6", NULL,
3824 NULL, IPPROTO_AH, NULL, 0,
3825 CTL_NET, PF_INET6, IPPROTO_ESP, CTL_EOL);
3826 sysctl_createv(clog, 0, NULL, NULL,
3827 CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
3828 CTLTYPE_NODE, "ipcomp6", NULL,
3829 NULL, IPPROTO_AH, NULL, 0,
3830 CTL_NET, PF_INET6, IPPROTO_IPCOMP, CTL_EOL);
3831 sysctl_createv(clog, 0, NULL, NULL,
3832 CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
3833 CTLTYPE_NODE, "ah6", NULL,
3834 NULL, IPPROTO_AH, NULL, 0,
3835 CTL_NET, PF_INET6, CTL_CREATE, CTL_EOL);
3837 #endif /* INET6 */