xref: /netbsd-src/sys/netipsec/ipsec_netbsd.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: ipsec_netbsd.c,v 1.29 2007/10/19 12:16:46 ad Exp $	*/
2 /*	$KAME: esp_input.c,v 1.60 2001/09/04 08:43:19 itojun Exp $	*/
3 /*	$KAME: ah_input.c,v 1.64 2001/09/04 08:43:19 itojun Exp $	*/
4 
5 /*
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: ipsec_netbsd.c,v 1.29 2007/10/19 12:16:46 ad Exp $");
36 
37 #include "opt_inet.h"
38 #include "opt_ipsec.h"
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/malloc.h>
43 #include <sys/mbuf.h>
44 #include <sys/domain.h>
45 #include <sys/protosw.h>
46 #include <sys/socket.h>
47 #include <sys/errno.h>
48 #include <sys/time.h>
49 #include <sys/kernel.h>
50 #include <sys/sysctl.h>
51 
52 #include <net/if.h>
53 #include <net/route.h>
54 #include <net/netisr.h>
55 #include <sys/cpu.h>
56 
57 #include <netinet/in.h>
58 #include <netinet/in_systm.h>
59 #include <netinet/in_var.h>
60 #include <netinet/ip.h>
61 #include <netinet/ip_var.h>
62 #include <netinet/ip_ecn.h>
63 #include <netinet/ip_icmp.h>
64 
65 
66 #include <netipsec/ipsec.h>
67 #include <netipsec/ipsec_var.h>
68 #include <netipsec/key.h>
69 #include <netipsec/keydb.h>
70 #include <netipsec/key_debug.h>
71 #include <netipsec/ah.h>
72 #include <netipsec/ah_var.h>
73 #include <netipsec/esp.h>
74 #include <netipsec/esp_var.h>
75 #include <netipsec/ipip_var.h>
76 #include <netipsec/ipcomp_var.h>
77 
78 #ifdef INET6
79 #include <netipsec/ipsec6.h>
80 #include <netinet6/ip6protosw.h>
81 #include <netinet/icmp6.h>
82 #endif
83 
84 #include <machine/stdarg.h>
85 
86 
87 
88 #include <netipsec/key.h>
89 
90 /* assumes that ip header and ah header are contiguous on mbuf */
91 void*
92 ah4_ctlinput(int cmd, const struct sockaddr *sa, void *v)
93 {
94 	struct ip *ip = v;
95 	struct ah *ah;
96 	struct icmp *icp;
97 	struct secasvar *sav;
98 
99 	if (sa->sa_family != AF_INET ||
100 		sa->sa_len != sizeof(struct sockaddr_in))
101 		return NULL;
102 	if ((unsigned)cmd >= PRC_NCMDS)
103 		return NULL;
104 
105 	if (cmd == PRC_MSGSIZE && ip_mtudisc && ip && ip->ip_v == 4) {
106 		/*
107 		 * Check to see if we have a valid SA corresponding to
108 		 * the address in the ICMP message payload.
109 		 */
110 		ah = (struct ah *)((char *)ip + (ip->ip_hl << 2));
111 		sav = KEY_ALLOCSA((const union sockaddr_union *)sa,
112 					   	IPPROTO_AH, ah->ah_spi, 0, 0);
113 
114 		if (sav) {
115         	if (sav->state == SADB_SASTATE_MATURE ||
116                 sav->state == SADB_SASTATE_DYING) {
117 
118 				/*
119 				 * Now that we've validated that we are actually
120 				 * communicating with the host indicated in the
121 				 * ICMP message, locate the ICMP header,
122 				 * recalculate the new MTU, and create the
123 		 		 * corresponding routing entry.
124 		 		 */
125 				icp = (struct icmp *)((char *)ip -
126 									  offsetof(struct icmp, icmp_ip));
127 				icmp_mtudisc(icp, ip->ip_dst);
128 
129 			}
130 			KEY_FREESAV(&sav);
131 		}
132 	}
133 	return NULL;
134 }
135 
136 
137 
138 /* assumes that ip header and esp header are contiguous on mbuf */
139 void*
140 esp4_ctlinput(int cmd, const struct sockaddr *sa, void *v)
141 {
142 	struct ip *ip = v;
143 	struct esp *esp;
144 	struct icmp *icp;
145 	struct secasvar *sav;
146 
147 	if (sa->sa_family != AF_INET ||
148 	    sa->sa_len != sizeof(struct sockaddr_in))
149 		return NULL;
150 	if ((unsigned)cmd >= PRC_NCMDS)
151 		return NULL;
152 
153 	if (cmd == PRC_MSGSIZE && ip_mtudisc && ip && ip->ip_v == 4) {
154 		/*
155 		 * Check to see if we have a valid SA corresponding to
156 		 * the address in the ICMP message payload.
157 		 */
158 		esp = (struct esp *)((char *)ip + (ip->ip_hl << 2));
159 		sav = KEY_ALLOCSA((const union sockaddr_union *)sa,
160 					   	IPPROTO_ESP, esp->esp_spi, 0, 0);
161 
162 		if (sav) {
163         	if (sav->state == SADB_SASTATE_MATURE ||
164                 sav->state == SADB_SASTATE_DYING) {
165 
166 				/*
167 				 * Now that we've validated that we are actually
168 				 * communicating with the host indicated in the
169 				 * ICMP message, locate the ICMP header,
170 				 * recalculate the new MTU, and create the
171 		 		 * corresponding routing entry.
172 		 		 */
173 
174 				icp = (struct icmp *)((char *)ip -
175 									   offsetof(struct icmp, icmp_ip));
176 				icmp_mtudisc(icp, ip->ip_dst);
177 
178 			}
179 			KEY_FREESAV(&sav);
180 		}
181 	}
182 	return NULL;
183 }
184 
185 #ifdef INET6
186 void
187 ah6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
188 {
189        const struct newah *ahp;
190        struct newah ah;
191        struct secasvar *sav;
192        struct ip6_hdr *ip6;
193        struct mbuf *m;
194        struct ip6ctlparam *ip6cp = NULL;
195        int off;
196 
197        if (sa->sa_family != AF_INET6 ||
198            sa->sa_len != sizeof(struct sockaddr_in6))
199                return;
200        if ((unsigned)cmd >= PRC_NCMDS)
201                return;
202 
203        /* if the parameter is from icmp6, decode it. */
204        if (d != NULL) {
205                ip6cp = (struct ip6ctlparam *)d;
206                m = ip6cp->ip6c_m;
207                ip6 = ip6cp->ip6c_ip6;
208                off = ip6cp->ip6c_off;
209        } else {
210                m = NULL;
211                ip6 = NULL;
212                off = 0;
213        }
214 
215        if (ip6) {
216                /*
217                 * XXX: We assume that when ip6 is non NULL,
218                 * M and OFF are valid.
219                 */
220 
221                /* check if we can safely examine src and dst ports */
222                if (m->m_pkthdr.len < off + sizeof(ah))
223                        return;
224 
225                if (m->m_len < off + sizeof(ah)) {
226                        /*
227                         * this should be rare case,
228                         * so we compromise on this copy...
229                         */
230                        m_copydata(m, off, sizeof(ah), &ah);
231                        ahp = &ah;
232                } else
233                        ahp = (struct newah *)(mtod(m, char *) + off);
234 
235                if (cmd == PRC_MSGSIZE) {
236                        int valid = 0;
237 
238                        /*
239                         * Check to see if we have a valid SA corresponding
240                         * to the address in the ICMP message payload.
241                         */
242                        sav = KEY_ALLOCSA((const union sockaddr_union*)sa,
243                                          IPPROTO_AH, ahp->ah_spi, 0, 0);
244 
245                        if (sav) {
246                                if (sav->state == SADB_SASTATE_MATURE ||
247                                    sav->state == SADB_SASTATE_DYING)
248                                        valid++;
249                                KEY_FREESAV(&sav);
250                        }
251 
252                        /* XXX Further validation? */
253 
254                        /*
255                         * Depending on the value of "valid" and routing
256                         * table size (mtudisc_{hi,lo}wat), we will:
257                         * - recalcurate the new MTU and create the
258                         *   corresponding routing entry, or
259                         * - ignore the MTU change notification.
260                         */
261                        icmp6_mtudisc_update((struct ip6ctlparam *)d,valid);
262                }
263 
264                /* we normally notify single pcb here */
265        } else {
266                /* we normally notify any pcb here */
267        }
268 }
269 
270 
271 
272 void
273 esp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
274 {
275 	const struct newesp *espp;
276 	struct newesp esp;
277 	struct ip6ctlparam *ip6cp = NULL, ip6cp1;
278 	struct secasvar *sav;
279 	struct ip6_hdr *ip6;
280 	struct mbuf *m;
281 	int off;
282 
283 	if (sa->sa_family != AF_INET6 ||
284 	    sa->sa_len != sizeof(struct sockaddr_in6))
285 		return;
286 	if ((unsigned)cmd >= PRC_NCMDS)
287 		return;
288 
289 	/* if the parameter is from icmp6, decode it. */
290 	if (d != NULL) {
291 		ip6cp = (struct ip6ctlparam *)d;
292 		m = ip6cp->ip6c_m;
293 		ip6 = ip6cp->ip6c_ip6;
294 		off = ip6cp->ip6c_off;
295 	} else {
296 		m = NULL;
297 		ip6 = NULL;
298 		off = 0;
299 	}
300 
301 	if (ip6) {
302 		/*
303 		 * Notify the error to all possible sockets via pfctlinput2.
304 		 * Since the upper layer information (such as protocol type,
305 		 * source and destination ports) is embedded in the encrypted
306 		 * data and might have been cut, we can't directly call
307 		 * an upper layer ctlinput function. However, the pcbnotify
308 		 * function will consider source and destination addresses
309 		 * as well as the flow info value, and may be able to find
310 		 * some PCB that should be notified.
311 		 * Although pfctlinput2 will call esp6_ctlinput(), there is
312 		 * no possibility of an infinite loop of function calls,
313 		 * because we don't pass the inner IPv6 header.
314 		 */
315 		memset(&ip6cp1, 0, sizeof(ip6cp1));
316 		ip6cp1.ip6c_src = ip6cp->ip6c_src;
317 		pfctlinput2(cmd, sa, &ip6cp1);
318 
319 		/*
320 		 * Then go to special cases that need ESP header information.
321 		 * XXX: We assume that when ip6 is non NULL,
322 		 * M and OFF are valid.
323 		 */
324 
325 		/* check if we can safely examine src and dst ports */
326 		if (m->m_pkthdr.len < off + sizeof(esp))
327 			return;
328 
329 		if (m->m_len < off + sizeof(esp)) {
330 			/*
331 			 * this should be rare case,
332 			 * so we compromise on this copy...
333 			 */
334 			m_copydata(m, off, sizeof(esp), &esp);
335 			espp = &esp;
336 		} else
337 			espp = (struct newesp*)(mtod(m, char *) + off);
338 
339 		if (cmd == PRC_MSGSIZE) {
340 			int valid = 0;
341 
342 			/*
343 			 * Check to see if we have a valid SA corresponding to
344 			 * the address in the ICMP message payload.
345 			 */
346 
347 			sav = KEY_ALLOCSA((const union sockaddr_union*)sa,
348 					  IPPROTO_ESP, espp->esp_spi, 0, 0);
349 
350 			if (sav) {
351 				if (sav->state == SADB_SASTATE_MATURE ||
352 				    sav->state == SADB_SASTATE_DYING)
353 					valid++;
354 				KEY_FREESAV(&sav);
355 			}
356 
357 			/* XXX Further validation? */
358 
359 			/*
360 			 * Depending on the value of "valid" and routing table
361 			 * size (mtudisc_{hi,lo}wat), we will:
362 			 * - recalcurate the new MTU and create the
363 			 *   corresponding routing entry, or
364 			 * - ignore the MTU change notification.
365 			 */
366 			icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
367 		}
368 	} else {
369 		/* we normally notify any pcb here */
370 	}
371 }
372 #endif /* INET6 */
373 
374 static int
375 sysctl_fast_ipsec(SYSCTLFN_ARGS)
376 {
377 	int error, t;
378 	struct sysctlnode node;
379 
380 	node = *rnode;
381 	t = *(int*)rnode->sysctl_data;
382 	node.sysctl_data = &t;
383 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
384 	if (error || newp == NULL)
385 		return (error);
386 
387 	switch (rnode->sysctl_num) {
388 	case IPSECCTL_DEF_ESP_TRANSLEV:
389 	case IPSECCTL_DEF_ESP_NETLEV:
390 	case IPSECCTL_DEF_AH_TRANSLEV:
391 	case IPSECCTL_DEF_AH_NETLEV:
392 		if (t != IPSEC_LEVEL_USE &&
393 		    t != IPSEC_LEVEL_REQUIRE)
394 			return (EINVAL);
395 		ipsec_invalpcbcacheall();
396 		break;
397       	case IPSECCTL_DEF_POLICY:
398 		if (t != IPSEC_POLICY_DISCARD &&
399 		    t != IPSEC_POLICY_NONE)
400 			return (EINVAL);
401 		ipsec_invalpcbcacheall();
402 		break;
403 	default:
404 		return (EINVAL);
405 	}
406 
407 	*(int*)rnode->sysctl_data = t;
408 
409 	return (0);
410 }
411 
412 #ifdef IPSEC_DEBUG
413 static int
414 sysctl_fast_ipsec_test(SYSCTLFN_ARGS)
415 {
416 	int t, error;
417 	struct sysctlnode node;
418 
419 	node = *rnode;
420 	t = *(int*)rnode->sysctl_data;
421 	node.sysctl_data = &t;
422 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
423 	if (error || newp == NULL)
424 		return (error);
425 
426 	if (t < 0 || t > 1)
427 		return EINVAL;
428 
429 	if (rnode->sysctl_data == &ipsec_replay)
430 		printf("fast_ipsec: Anti-Replay service %s\n",
431 		    (t == 1) ? "deactivated" : "activated");
432 	else if (rnode->sysctl_data == &ipsec_integrity)
433 		 printf("fast_ipsec: HMAC corruption %s\n",
434 		     (t == 0) ? "deactivated" : "activated");
435 
436 	*(int*)rnode->sysctl_data = t;
437 
438 	return 0;
439 }
440 #endif
441 
442 /* XXX will need a different oid at parent */
443 SYSCTL_SETUP(sysctl_net_inet_fast_ipsec_setup, "sysctl net.inet.ipsec subtree setup")
444 {
445 	const struct sysctlnode *_ipsec;
446 	int ipproto_ipsec;
447 
448 	sysctl_createv(clog, 0, NULL, NULL,
449 		       CTLFLAG_PERMANENT,
450 		       CTLTYPE_NODE, "net", NULL,
451 		       NULL, 0, NULL, 0,
452 		       CTL_NET, CTL_EOL);
453 	sysctl_createv(clog, 0, NULL, NULL,
454 		       CTLFLAG_PERMANENT,
455 		       CTLTYPE_NODE, "inet", NULL,
456 		       NULL, 0, NULL, 0,
457 		       CTL_NET, PF_INET, CTL_EOL);
458 
459 	/*
460 	 * in numerical order:
461 	 *
462 	 * net.inet.ipip:	CTL_NET.PF_INET.IPPROTO_IPIP
463 	 * net.inet.esp:	CTL_NET.PF_INET.IPPROTO_ESP
464 	 * net.inet.ah:		CTL_NET.PF_INET.IPPROTO_AH
465 	 * net.inet.ipcomp:	CTL_NET.PF_INET.IPPROTO_IPCOMP
466 	 * net.inet.ipsec:	CTL_NET.PF_INET.CTL_CREATE
467 	 *
468 	 * this creates separate trees by name, but maintains that the
469 	 * ipsec name leads to all the old leaves.
470 	 */
471 
472 	/* create net.inet.ipip */
473 	sysctl_createv(clog, 0, NULL, NULL,
474 		       CTLFLAG_PERMANENT,
475 		       CTLTYPE_NODE, "ipip", NULL,
476 		       NULL, 0, NULL, 0,
477 		       CTL_NET, PF_INET, IPPROTO_IPIP, CTL_EOL);
478 	sysctl_createv(clog, 0, NULL, NULL,
479 		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
480 		       CTLTYPE_STRUCT, "ipip_stats", NULL,
481 		       NULL, 0, &ipipstat, sizeof(ipipstat),
482 		       CTL_NET, PF_INET, IPPROTO_IPIP,
483 		       CTL_CREATE, CTL_EOL);
484 
485 	/* create net.inet.esp subtree under IPPROTO_ESP */
486 	sysctl_createv(clog, 0, NULL, NULL,
487 		       CTLFLAG_PERMANENT,
488 		       CTLTYPE_NODE, "esp", NULL,
489 		       NULL, 0, NULL, 0,
490 		       CTL_NET, PF_INET, IPPROTO_ESP, CTL_EOL);
491 	sysctl_createv(clog, 0, NULL, NULL,
492 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
493 		       CTLTYPE_INT, "trans_deflev", NULL,
494 		       sysctl_fast_ipsec, 0, &ip4_esp_trans_deflev, 0,
495 		       CTL_NET, PF_INET, IPPROTO_ESP,
496 		       IPSECCTL_DEF_ESP_TRANSLEV, CTL_EOL);
497 	sysctl_createv(clog, 0, NULL, NULL,
498 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
499 		       CTLTYPE_INT, "net_deflev", NULL,
500 		       sysctl_fast_ipsec, 0, &ip4_esp_net_deflev, 0,
501 		       CTL_NET, PF_INET, IPPROTO_ESP,
502 		       IPSECCTL_DEF_ESP_NETLEV, CTL_EOL);
503 	sysctl_createv(clog, 0, NULL, NULL,
504 		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
505 		       CTLTYPE_STRUCT, "esp_stats", NULL,
506 		       NULL, 0, &espstat, sizeof(espstat),
507 		       CTL_NET, PF_INET, IPPROTO_ESP,
508 		       CTL_CREATE, CTL_EOL);
509 
510 	/* create net.inet.ah subtree under IPPROTO_AH */
511 	sysctl_createv(clog, 0, NULL, NULL,
512 		       CTLFLAG_PERMANENT,
513 		       CTLTYPE_NODE, "ah", NULL,
514 		       NULL, 0, NULL, 0,
515 		       CTL_NET, PF_INET, IPPROTO_AH, CTL_EOL);
516 	sysctl_createv(clog, 0, NULL, NULL,
517 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
518 		       CTLTYPE_INT, "cleartos", NULL,
519 		       NULL, 0, &ip4_ah_cleartos, 0,
520 		       CTL_NET, PF_INET, IPPROTO_AH,
521 		       IPSECCTL_AH_CLEARTOS, CTL_EOL);
522 	sysctl_createv(clog, 0, NULL, NULL,
523 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
524 		       CTLTYPE_INT, "offsetmask", NULL,
525 		       NULL, 0, &ip4_ah_offsetmask, 0,
526 		       CTL_NET, PF_INET, IPPROTO_AH,
527 		       IPSECCTL_AH_OFFSETMASK, CTL_EOL);
528 	sysctl_createv(clog, 0, NULL, NULL,
529 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
530 		       CTLTYPE_INT, "trans_deflev", NULL,
531 		       sysctl_fast_ipsec, 0, &ip4_ah_trans_deflev, 0,
532 		       CTL_NET, PF_INET, IPPROTO_AH,
533 		       IPSECCTL_DEF_AH_TRANSLEV, CTL_EOL);
534 	sysctl_createv(clog, 0, NULL, NULL,
535 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
536 		       CTLTYPE_INT, "net_deflev", NULL,
537 		       sysctl_fast_ipsec, 0, &ip4_ah_net_deflev, 0,
538 		       CTL_NET, PF_INET, IPPROTO_AH,
539 		       IPSECCTL_DEF_AH_NETLEV, CTL_EOL);
540 	sysctl_createv(clog, 0, NULL, NULL,
541 		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
542 		       CTLTYPE_STRUCT, "ah_stats", NULL,
543 		       NULL, 0, &ahstat, sizeof(ahstat),
544 		       CTL_NET, PF_INET, IPPROTO_AH,
545 		       CTL_CREATE, CTL_EOL);
546 
547 	/* create net.inet.ipcomp */
548 	sysctl_createv(clog, 0, NULL, NULL,
549 		       CTLFLAG_PERMANENT,
550 		       CTLTYPE_NODE, "ipcomp", NULL,
551 		       NULL, 0, NULL, 0,
552 		       CTL_NET, PF_INET, IPPROTO_IPCOMP, CTL_EOL);
553 	sysctl_createv(clog, 0, NULL, NULL,
554 		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
555 		       CTLTYPE_STRUCT, "ipcomp_stats", NULL,
556 		       NULL, 0, &ipcompstat, sizeof(ipcompstat),
557 		       CTL_NET, PF_INET, IPPROTO_IPCOMP,
558 		       CTL_CREATE, CTL_EOL);
559 
560 	/* create net.inet.ipsec subtree under dynamic oid */
561 	sysctl_createv(clog, 0, NULL, &_ipsec,
562 		       CTLFLAG_PERMANENT,
563 		       CTLTYPE_NODE, "ipsec", NULL,
564 		       NULL, 0, NULL, 0,
565 		       CTL_NET, PF_INET, CTL_CREATE, CTL_EOL);
566 	ipproto_ipsec = (_ipsec != NULL) ? _ipsec->sysctl_num : 0;
567 
568 	sysctl_createv(clog, 0, NULL, NULL,
569 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
570 		       CTLTYPE_INT, "def_policy", NULL,
571 		       sysctl_fast_ipsec, 0, &ip4_def_policy.policy, 0,
572 		       CTL_NET, PF_INET, ipproto_ipsec,
573 		       IPSECCTL_DEF_POLICY, CTL_EOL);
574 	sysctl_createv(clog, 0, NULL, NULL,
575 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
576 		       CTLTYPE_INT, "esp_trans_deflev", NULL,
577 		       sysctl_fast_ipsec, 0, &ip4_esp_trans_deflev, 0,
578 		       CTL_NET, PF_INET, ipproto_ipsec,
579 		       IPSECCTL_DEF_ESP_TRANSLEV, CTL_EOL);
580 	sysctl_createv(clog, 0, NULL, NULL,
581 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
582 		       CTLTYPE_INT, "esp_net_deflev", NULL,
583 		       sysctl_fast_ipsec, 0, &ip4_esp_net_deflev, 0,
584 		       CTL_NET, PF_INET, ipproto_ipsec,
585 		       IPSECCTL_DEF_ESP_NETLEV, CTL_EOL);
586 	sysctl_createv(clog, 0, NULL, NULL,
587 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
588 		       CTLTYPE_INT, "ah_trans_deflev", NULL,
589 		       sysctl_fast_ipsec, 0, &ip4_ah_trans_deflev, 0,
590 		       CTL_NET, PF_INET, ipproto_ipsec,
591 		       IPSECCTL_DEF_AH_TRANSLEV, CTL_EOL);
592 	sysctl_createv(clog, 0, NULL, NULL,
593 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
594 		       CTLTYPE_INT, "ah_net_deflev", NULL,
595 		       sysctl_fast_ipsec, 0, &ip4_ah_net_deflev, 0,
596 		       CTL_NET, PF_INET, ipproto_ipsec,
597 		       IPSECCTL_DEF_AH_NETLEV, CTL_EOL);
598 	sysctl_createv(clog, 0, NULL, NULL,
599 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
600 		       CTLTYPE_INT, "ah_cleartos", NULL,
601 		       NULL, 0, &ip4_ah_cleartos, 0,
602 		       CTL_NET, PF_INET, ipproto_ipsec,
603 		       IPSECCTL_AH_CLEARTOS, CTL_EOL);
604 	sysctl_createv(clog, 0, NULL, NULL,
605 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
606 		       CTLTYPE_INT, "ah_offsetmask", NULL,
607 		       NULL, 0, &ip4_ah_offsetmask, 0,
608 		       CTL_NET, PF_INET, ipproto_ipsec,
609 		       IPSECCTL_AH_OFFSETMASK, CTL_EOL);
610 	sysctl_createv(clog, 0, NULL, NULL,
611 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
612 		       CTLTYPE_INT, "dfbit", NULL,
613 		       NULL, 0, &ip4_ipsec_dfbit, 0,
614 		       CTL_NET, PF_INET, ipproto_ipsec,
615 		       IPSECCTL_DFBIT, CTL_EOL);
616 	sysctl_createv(clog, 0, NULL, NULL,
617 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
618 		       CTLTYPE_INT, "ecn", NULL,
619 		       NULL, 0, &ip4_ipsec_ecn, 0,
620 		       CTL_NET, PF_INET, ipproto_ipsec,
621 		       IPSECCTL_ECN, CTL_EOL);
622 	sysctl_createv(clog, 0, NULL, NULL,
623 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
624 		       CTLTYPE_INT, "debug", NULL,
625 		       NULL, 0, &ipsec_debug, 0,
626 		       CTL_NET, PF_INET, ipproto_ipsec,
627 		       IPSECCTL_DEBUG, CTL_EOL);
628 	sysctl_createv(clog, 0, NULL, NULL,
629 		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
630 		       CTLTYPE_STRUCT, "ipsecstats", NULL,
631 		       NULL, 0, &ipsecstat, sizeof(ipsecstat),
632 		       CTL_NET, PF_INET, ipproto_ipsec,
633 		       CTL_CREATE, CTL_EOL);
634 #ifdef IPSEC_DEBUG
635 	sysctl_createv(clog, 0, NULL, NULL,
636 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
637 		       CTLTYPE_INT, "test_replay",
638 		       SYSCTL_DESCR("Emulate replay attack"),
639 		       sysctl_fast_ipsec_test, 0, &ipsec_replay, 0,
640 		       CTL_NET, PF_INET, ipproto_ipsec,
641 		       CTL_CREATE, CTL_EOL);
642 	sysctl_createv(clog, 0, NULL, NULL,
643 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
644 		       CTLTYPE_INT, "test_integrity",
645 		       SYSCTL_DESCR("Emulate man-in-the-middle attack"),
646 		       sysctl_fast_ipsec_test, 0, &ipsec_integrity, 0,
647 		       CTL_NET, PF_INET, ipproto_ipsec,
648 		       CTL_CREATE, CTL_EOL);
649 #endif
650 }
651 
652 #ifdef INET6
653 SYSCTL_SETUP(sysctl_net_inet6_fast_ipsec6_setup,
654 	     "sysctl net.inet6.ipsec6 subtree setup")
655 {
656 
657 	sysctl_createv(clog, 0, NULL, NULL,
658 		       CTLFLAG_PERMANENT,
659 		       CTLTYPE_NODE, "net", NULL,
660 		       NULL, 0, NULL, 0,
661 		       CTL_NET, CTL_EOL);
662 	sysctl_createv(clog, 0, NULL, NULL,
663 		       CTLFLAG_PERMANENT,
664 		       CTLTYPE_NODE, "inet6", NULL,
665 		       NULL, 0, NULL, 0,
666 		       CTL_NET, PF_INET6, CTL_EOL);
667 	sysctl_createv(clog, 0, NULL, NULL,
668 		       CTLFLAG_PERMANENT,
669 		       CTLTYPE_NODE, "ipsec6",
670 		       SYSCTL_DESCR("IPv6 related IPSec settings"),
671 		       NULL, 0, NULL, 0,
672 		       CTL_NET, PF_INET6, IPPROTO_AH, CTL_EOL);
673 
674 	sysctl_createv(clog, 0, NULL, NULL,
675 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
676 		       CTLTYPE_STRUCT, "stats",
677 		       SYSCTL_DESCR("IPSec statistics and counters"),
678 		       NULL, 0, &ipsec6stat, sizeof(ipsec6stat),
679 		       CTL_NET, PF_INET6, IPPROTO_AH,
680 		       IPSECCTL_STATS, CTL_EOL);
681 	sysctl_createv(clog, 0, NULL, NULL,
682 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
683 		       CTLTYPE_INT, "def_policy",
684 		       SYSCTL_DESCR("Default action for non-IPSec packets"),
685 		       sysctl_fast_ipsec, 0, &ip6_def_policy, 0,
686 		       CTL_NET, PF_INET6, IPPROTO_AH,
687 		       IPSECCTL_DEF_POLICY, CTL_EOL);
688 	sysctl_createv(clog, 0, NULL, NULL,
689 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
690 		       CTLTYPE_INT, "esp_trans_deflev",
691 		       SYSCTL_DESCR("Default required security level for "
692 				    "transport mode traffic"),
693 		       sysctl_fast_ipsec, 0, &ip6_esp_trans_deflev, 0,
694 		       CTL_NET, PF_INET6, IPPROTO_AH,
695 		       IPSECCTL_DEF_ESP_TRANSLEV, CTL_EOL);
696 	sysctl_createv(clog, 0, NULL, NULL,
697 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
698 		       CTLTYPE_INT, "esp_net_deflev",
699 		       SYSCTL_DESCR("Default required security level for "
700 				    "tunneled traffic"),
701 		       sysctl_fast_ipsec, 0, &ip6_esp_net_deflev, 0,
702 		       CTL_NET, PF_INET6, IPPROTO_AH,
703 		       IPSECCTL_DEF_ESP_NETLEV, CTL_EOL);
704 	sysctl_createv(clog, 0, NULL, NULL,
705 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
706 		       CTLTYPE_INT, "ah_trans_deflev",
707 		       SYSCTL_DESCR("Default required security level for "
708 				    "transport mode headers"),
709 		       sysctl_fast_ipsec, 0, &ip6_ah_trans_deflev, 0,
710 		       CTL_NET, PF_INET6, IPPROTO_AH,
711 		       IPSECCTL_DEF_AH_TRANSLEV, CTL_EOL);
712 	sysctl_createv(clog, 0, NULL, NULL,
713 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
714 		       CTLTYPE_INT, "ah_net_deflev",
715 		       SYSCTL_DESCR("Default required security level for "
716 				    "tunneled headers"),
717 		       sysctl_fast_ipsec, 0, &ip6_ah_net_deflev, 0,
718 		       CTL_NET, PF_INET6, IPPROTO_AH,
719 		       IPSECCTL_DEF_AH_NETLEV, CTL_EOL);
720 	sysctl_createv(clog, 0, NULL, NULL,
721 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
722 		       CTLTYPE_INT, "ecn",
723 		       SYSCTL_DESCR("Behavior of ECN for tunneled traffic"),
724 		       NULL, 0, &ip6_ipsec_ecn, 0,
725 		       CTL_NET, PF_INET6, IPPROTO_AH,
726 		       IPSECCTL_ECN, CTL_EOL);
727 	sysctl_createv(clog, 0, NULL, NULL,
728 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
729 		       CTLTYPE_INT, "debug",
730 		       SYSCTL_DESCR("Enable IPSec debugging output"),
731 		       NULL, 0, &ipsec_debug, 0,
732 		       CTL_NET, PF_INET6, IPPROTO_AH,
733 		       IPSECCTL_DEBUG, CTL_EOL);
734 
735 	/*
736 	 * "aliases" for the ipsec6 subtree
737 	 */
738 	sysctl_createv(clog, 0, NULL, NULL,
739 		       CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
740 		       CTLTYPE_NODE, "esp6", NULL,
741 		       NULL, IPPROTO_AH, NULL, 0,
742 		       CTL_NET, PF_INET6, IPPROTO_ESP, CTL_EOL);
743 	sysctl_createv(clog, 0, NULL, NULL,
744 		       CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
745 		       CTLTYPE_NODE, "ipcomp6", NULL,
746 		       NULL, IPPROTO_AH, NULL, 0,
747 		       CTL_NET, PF_INET6, IPPROTO_IPCOMP, CTL_EOL);
748 	sysctl_createv(clog, 0, NULL, NULL,
749 		       CTLFLAG_PERMANENT|CTLFLAG_ALIAS,
750 		       CTLTYPE_NODE, "ah6", NULL,
751 		       NULL, IPPROTO_AH, NULL, 0,
752 		       CTL_NET, PF_INET6, CTL_CREATE, CTL_EOL);
753 }
754 #endif /* INET6 */
755