xref: /openbsd/sys/net/pfkeyv2.c (revision cecf84d4)
1 /* $OpenBSD: pfkeyv2.c,v 1.143 2015/04/16 19:24:13 markus Exp $ */
2 
3 /*
4  *	@(#)COPYRIGHT	1.1 (NRL) 17 January 1995
5  *
6  * NRL grants permission for redistribution and use in source and binary
7  * forms, with or without modification, of the software and documentation
8  * created at NRL provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgements:
17  * 	This product includes software developed by the University of
18  * 	California, Berkeley and its contributors.
19  * 	This product includes software developed at the Information
20  * 	Technology Division, US Naval Research Laboratory.
21  * 4. Neither the name of the NRL nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
26  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
28  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * The views and conclusions contained in the software and documentation
38  * are those of the authors and should not be interpreted as representing
39  * official policies, either expressed or implied, of the US Naval
40  * Research Laboratory (NRL).
41  */
42 
43 /*
44  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions
48  * are met:
49  * 1. Redistributions of source code must retain the above copyright
50  *    notice, this list of conditions and the following disclaimer.
51  * 2. Redistributions in binary form must reproduce the above copyright
52  *    notice, this list of conditions and the following disclaimer in the
53  *    documentation and/or other materials provided with the distribution.
54  * 3. Neither the name of the author nor the names of any contributors
55  *    may be used to endorse or promote products derived from this software
56  *    without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68  * SUCH DAMAGE.
69  */
70 
71 #include "pf.h"
72 
73 #include <sys/types.h>
74 #include <sys/param.h>
75 #include <sys/socket.h>
76 #include <sys/systm.h>
77 #include <sys/mbuf.h>
78 #include <sys/kernel.h>
79 #include <sys/proc.h>
80 #include <sys/pool.h>
81 #include <net/route.h>
82 #include <netinet/ip_ipsp.h>
83 #include <net/pfkeyv2.h>
84 #include <netinet/ip_ah.h>
85 #include <netinet/ip_esp.h>
86 #include <netinet/ip_ipcomp.h>
87 #include <crypto/blf.h>
88 
89 #if NPF > 0
90 #include <net/if.h>
91 #include <net/pfvar.h>
92 #endif
93 
94 #define PFKEYV2_PROTOCOL 2
95 #define GETSPI_TRIES 10
96 
97 /* Static globals */
98 static struct pfkeyv2_socket *pfkeyv2_sockets = NULL;
99 static struct pfkey_version pfkeyv2_version;
100 static uint32_t pfkeyv2_seq = 1;
101 static int nregistered = 0;
102 static int npromisc = 0;
103 
104 static const struct sadb_alg ealgs[] = {
105 	{ SADB_EALG_NULL, 0, 0, 0 },
106 	{ SADB_EALG_DESCBC, 64, 64, 64 },
107 	{ SADB_EALG_3DESCBC, 64, 192, 192 },
108 	{ SADB_X_EALG_BLF, 64, 40, BLF_MAXKEYLEN * 8},
109 	{ SADB_X_EALG_CAST, 64, 40, 128},
110 	{ SADB_X_EALG_AES, 128, 128, 256},
111 	{ SADB_X_EALG_AESCTR, 128, 128 + 32, 256 + 32}
112 };
113 
114 static const struct sadb_alg aalgs[] = {
115 	{ SADB_AALG_SHA1HMAC, 0, 160, 160 },
116 	{ SADB_AALG_MD5HMAC, 0, 128, 128 },
117 	{ SADB_X_AALG_RIPEMD160HMAC, 0, 160, 160 },
118 	{ SADB_X_AALG_SHA2_256, 0, 256, 256 },
119 	{ SADB_X_AALG_SHA2_384, 0, 384, 384 },
120 	{ SADB_X_AALG_SHA2_512, 0, 512, 512 }
121 };
122 
123 static const struct sadb_alg calgs[] = {
124 	{ SADB_X_CALG_DEFLATE, 0, 0, 0},
125 	{ SADB_X_CALG_LZS, 0, 0, 0}
126 };
127 
128 extern uint64_t sadb_exts_allowed_out[SADB_MAX+1];
129 extern uint64_t sadb_exts_required_out[SADB_MAX+1];
130 
131 extern struct pool ipsec_policy_pool;
132 
133 /*
134  * Wrapper around m_devget(); copy data from contiguous buffer to mbuf
135  * chain.
136  */
137 int
138 pfdatatopacket(void *data, int len, struct mbuf **packet)
139 {
140 	if (!(*packet = m_devget(data, len, 0)))
141 		return (ENOMEM);
142 
143 	/* Make sure, all data gets zeroized on free */
144 	(*packet)->m_flags |= M_ZEROIZE;
145 
146 	return (0);
147 }
148 
149 /*
150  * Create a new PF_KEYv2 socket.
151  */
152 int
153 pfkeyv2_create(struct socket *socket)
154 {
155 	struct pfkeyv2_socket *pfkeyv2_socket;
156 
157 	if (!(pfkeyv2_socket = malloc(sizeof(struct pfkeyv2_socket),
158 	    M_PFKEY, M_NOWAIT | M_ZERO)))
159 		return (ENOMEM);
160 
161 	pfkeyv2_socket->next = pfkeyv2_sockets;
162 	pfkeyv2_socket->socket = socket;
163 	pfkeyv2_socket->pid = curproc->p_p->ps_pid;
164 
165 	/*
166 	 * XXX we should get this from the socket instead but
167 	 * XXX rawcb doesn't store the rdomain like inpcb does.
168 	 */
169 	pfkeyv2_socket->rdomain = rtable_l2(curproc->p_p->ps_rtableid);
170 
171 	pfkeyv2_sockets = pfkeyv2_socket;
172 
173 	return (0);
174 }
175 
176 /*
177  * Close a PF_KEYv2 socket.
178  */
179 int
180 pfkeyv2_release(struct socket *socket)
181 {
182 	struct pfkeyv2_socket **pp;
183 
184 	for (pp = &pfkeyv2_sockets; *pp && ((*pp)->socket != socket);
185 	    pp = &((*pp)->next))
186 		/*EMPTY*/;
187 
188 	if (*pp) {
189 		struct pfkeyv2_socket *pfkeyv2_socket;
190 
191 		pfkeyv2_socket = *pp;
192 		*pp = (*pp)->next;
193 
194 		if (pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)
195 			nregistered--;
196 
197 		if (pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_PROMISC)
198 			npromisc--;
199 
200 		free(pfkeyv2_socket, M_PFKEY, 0);
201 	}
202 
203 	return (0);
204 }
205 
206 /*
207  * Send a PFKEYv2 message, possibly to many receivers, based on the
208  * satype of the socket (which is set by the REGISTER message), and the
209  * third argument.
210  */
211 int
212 pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
213     u_int8_t satype, int count, u_int rdomain)
214 {
215 	int i, j, rval;
216 	void *p, *buffer = NULL;
217 	struct mbuf *packet;
218 	struct pfkeyv2_socket *s;
219 	struct sadb_msg *smsg;
220 
221 	/* Find out how much space we'll need... */
222 	j = sizeof(struct sadb_msg);
223 
224 	for (i = 1; i <= SADB_EXT_MAX; i++)
225 		if (headers[i])
226 			j += ((struct sadb_ext *)headers[i])->sadb_ext_len *
227 			    sizeof(uint64_t);
228 
229 	/* ...and allocate it */
230 	if (!(buffer = malloc(j + sizeof(struct sadb_msg), M_PFKEY,
231 	    M_NOWAIT))) {
232 		rval = ENOMEM;
233 		goto ret;
234 	}
235 
236 	p = buffer + sizeof(struct sadb_msg);
237 	bcopy(headers[0], p, sizeof(struct sadb_msg));
238 	((struct sadb_msg *) p)->sadb_msg_len = j / sizeof(uint64_t);
239 	p += sizeof(struct sadb_msg);
240 
241 	/* Copy payloads in the packet */
242 	for (i = 1; i <= SADB_EXT_MAX; i++)
243 		if (headers[i]) {
244 			((struct sadb_ext *) headers[i])->sadb_ext_type = i;
245 			bcopy(headers[i], p, EXTLEN(headers[i]));
246 			p += EXTLEN(headers[i]);
247 		}
248 
249 	if ((rval = pfdatatopacket(buffer + sizeof(struct sadb_msg),
250 	    j, &packet)) != 0)
251 		goto ret;
252 
253 	switch (mode) {
254 	case PFKEYV2_SENDMESSAGE_UNICAST:
255 		/*
256 		 * Send message to the specified socket, plus all
257 		 * promiscuous listeners.
258 		 */
259 		pfkey_sendup(socket, packet, 0);
260 
261 		/*
262 		 * Promiscuous messages contain the original message
263 		 * encapsulated in another sadb_msg header.
264 		 */
265 		bzero(buffer, sizeof(struct sadb_msg));
266 		smsg = (struct sadb_msg *) buffer;
267 		smsg->sadb_msg_version = PF_KEY_V2;
268 		smsg->sadb_msg_type = SADB_X_PROMISC;
269 		smsg->sadb_msg_len = (sizeof(struct sadb_msg) + j) /
270 		    sizeof(uint64_t);
271 		smsg->sadb_msg_seq = 0;
272 
273 		/* Copy to mbuf chain */
274 		if ((rval = pfdatatopacket(buffer, sizeof(struct sadb_msg) + j,
275 		    &packet)) != 0)
276 			goto ret;
277 
278 		/*
279 		 * Search for promiscuous listeners, skipping the
280 		 * original destination.
281 		 */
282 		for (s = pfkeyv2_sockets; s; s = s->next)
283 			if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
284 			    (s->socket != socket) &&
285 			    (s->rdomain == rdomain))
286 				pfkey_sendup(s->socket, packet, 1);
287 
288 		m_freem(packet);
289 		break;
290 
291 	case PFKEYV2_SENDMESSAGE_REGISTERED:
292 		/*
293 		 * Send the message to all registered sockets that match
294 		 * the specified satype (e.g., all IPSEC-ESP negotiators)
295 		 */
296 		for (s = pfkeyv2_sockets; s; s = s->next)
297 			if ((s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED) &&
298 			    (s->rdomain == rdomain)) {
299 				if (!satype)    /* Just send to everyone registered */
300 					pfkey_sendup(s->socket, packet, 1);
301 				else {
302 					/* Check for specified satype */
303 					if ((1 << satype) & s->registration)
304 						pfkey_sendup(s->socket, packet, 1);
305 				}
306 			}
307 
308 		/* Free last/original copy of the packet */
309 		m_freem(packet);
310 
311 		/* Encapsulate the original message "inside" an sadb_msg header */
312 		bzero(buffer, sizeof(struct sadb_msg));
313 		smsg = (struct sadb_msg *) buffer;
314 		smsg->sadb_msg_version = PF_KEY_V2;
315 		smsg->sadb_msg_type = SADB_X_PROMISC;
316 		smsg->sadb_msg_len = (sizeof(struct sadb_msg) + j) /
317 		    sizeof(uint64_t);
318 		smsg->sadb_msg_seq = 0;
319 
320 		/* Convert to mbuf chain */
321 		if ((rval = pfdatatopacket(buffer, sizeof(struct sadb_msg) + j,
322 		    &packet)) != 0)
323 			goto ret;
324 
325 		/* Send to all registered promiscuous listeners */
326 		for (s = pfkeyv2_sockets; s; s = s->next)
327 			if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
328 			    !(s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED) &&
329 			    (s->rdomain == rdomain))
330 				pfkey_sendup(s->socket, packet, 1);
331 
332 		m_freem(packet);
333 		break;
334 
335 	case PFKEYV2_SENDMESSAGE_BROADCAST:
336 		/* Send message to all sockets */
337 		for (s = pfkeyv2_sockets; s; s = s->next) {
338 			if (s->rdomain == rdomain)
339 				pfkey_sendup(s->socket, packet, 1);
340 		}
341 		m_freem(packet);
342 		break;
343 	}
344 
345 ret:
346 	if (buffer != NULL) {
347 		bzero(buffer, j + sizeof(struct sadb_msg));
348 		free(buffer, M_PFKEY, 0);
349 	}
350 
351 	return (rval);
352 }
353 
354 /*
355  * Get SPD information for an ACQUIRE. We setup the message such that
356  * the SRC/DST payloads are relative to us (regardless of whether the
357  * SPD rule was for incoming or outgoing packets).
358  */
359 int
360 pfkeyv2_policy(struct ipsec_acquire *ipa, void **headers, void **buffer)
361 {
362 	union sockaddr_union sunion;
363 	struct sadb_protocol *sp;
364 	int rval, i, dir;
365 	void *p;
366 
367 	/* Find out how big a buffer we need */
368 	i = 4 * sizeof(struct sadb_address) + sizeof(struct sadb_protocol);
369 	bzero(&sunion, sizeof(union sockaddr_union));
370 
371 	switch (ipa->ipa_info.sen_type) {
372 	case SENT_IP4:
373 		i += 4 * PADUP(sizeof(struct sockaddr_in));
374 		sunion.sa.sa_family = AF_INET;
375 		sunion.sa.sa_len = sizeof(struct sockaddr_in);
376 		dir = ipa->ipa_info.sen_direction;
377 		break;
378 
379 #ifdef INET6
380 	case SENT_IP6:
381 		i += 4 * PADUP(sizeof(struct sockaddr_in6));
382 		sunion.sa.sa_family = AF_INET6;
383 		sunion.sa.sa_len = sizeof(struct sockaddr_in6);
384 		dir = ipa->ipa_info.sen_ip6_direction;
385 		break;
386 #endif /* INET6 */
387 
388 	default:
389 		return (EINVAL);
390 	}
391 
392 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
393 		rval = ENOMEM;
394 		goto ret;
395 	} else
396 		*buffer = p;
397 
398 	if (dir == IPSP_DIRECTION_OUT)
399 		headers[SADB_X_EXT_SRC_FLOW] = p;
400 	else
401 		headers[SADB_X_EXT_DST_FLOW] = p;
402 	switch (sunion.sa.sa_family) {
403 	case AF_INET:
404 		sunion.sin.sin_addr = ipa->ipa_info.sen_ip_src;
405 		sunion.sin.sin_port = ipa->ipa_info.sen_sport;
406 		break;
407 
408 #ifdef INET6
409 	case AF_INET6:
410 		sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_src;
411 		sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_sport;
412 		break;
413 #endif /* INET6 */
414 	}
415 	export_address(&p, (struct sockaddr *) &sunion);
416 
417 	if (dir == IPSP_DIRECTION_OUT)
418 		headers[SADB_X_EXT_SRC_MASK] = p;
419 	else
420 		headers[SADB_X_EXT_DST_MASK] = p;
421 	switch (sunion.sa.sa_family) {
422 	case AF_INET:
423 		sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_src;
424 		sunion.sin.sin_port = ipa->ipa_mask.sen_sport;
425 		break;
426 
427 #ifdef INET6
428 	case AF_INET6:
429 		sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_src;
430 		sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_sport;
431 		break;
432 #endif /* INET6 */
433 	}
434 	export_address(&p, (struct sockaddr *) &sunion);
435 
436 	if (dir == IPSP_DIRECTION_OUT)
437 		headers[SADB_X_EXT_DST_FLOW] = p;
438 	else
439 		headers[SADB_X_EXT_SRC_FLOW] = p;
440 	switch (sunion.sa.sa_family) {
441 	case AF_INET:
442 		sunion.sin.sin_addr = ipa->ipa_info.sen_ip_dst;
443 		sunion.sin.sin_port = ipa->ipa_info.sen_dport;
444 		break;
445 
446 #ifdef INET6
447 	case AF_INET6:
448 		sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_dst;
449 		sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_dport;
450 		break;
451 #endif /* INET6 */
452 	}
453 	export_address(&p, (struct sockaddr *) &sunion);
454 
455 	if (dir == IPSP_DIRECTION_OUT)
456 		headers[SADB_X_EXT_DST_MASK] = p;
457 	else
458 		headers[SADB_X_EXT_SRC_MASK] = p;
459 	switch (sunion.sa.sa_family) {
460 	case AF_INET:
461 		sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_dst;
462 		sunion.sin.sin_port = ipa->ipa_mask.sen_dport;
463 		break;
464 
465 #ifdef INET6
466 	case AF_INET6:
467 		sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_dst;
468 		sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_dport;
469 		break;
470 #endif /* INET6 */
471 	}
472 	export_address(&p, (struct sockaddr *) &sunion);
473 
474 	headers[SADB_X_EXT_FLOW_TYPE] = p;
475 	sp = p;
476 	sp->sadb_protocol_len = sizeof(struct sadb_protocol) /
477 	    sizeof(u_int64_t);
478 	switch (sunion.sa.sa_family) {
479 	case AF_INET:
480 		if (ipa->ipa_mask.sen_proto)
481 			sp->sadb_protocol_proto = ipa->ipa_info.sen_proto;
482 		sp->sadb_protocol_direction = ipa->ipa_info.sen_direction;
483 		break;
484 
485 #ifdef INET6
486 	case AF_INET6:
487 		if (ipa->ipa_mask.sen_ip6_proto)
488 			sp->sadb_protocol_proto = ipa->ipa_info.sen_ip6_proto;
489 		sp->sadb_protocol_direction = ipa->ipa_info.sen_ip6_direction;
490 		break;
491 #endif /* INET6 */
492 	}
493 
494 	rval = 0;
495 
496 ret:
497 	return (rval);
498 }
499 
500 /*
501  * Get all the information contained in an SA to a PFKEYV2 message.
502  */
503 int
504 pfkeyv2_get(struct tdb *sa, void **headers, void **buffer, int *lenp)
505 {
506 	int rval, i;
507 	void *p;
508 
509 	/* Find how much space we need */
510 	i = sizeof(struct sadb_sa) + sizeof(struct sadb_lifetime);
511 
512 	if (sa->tdb_soft_allocations || sa->tdb_soft_bytes ||
513 	    sa->tdb_soft_timeout || sa->tdb_soft_first_use)
514 		i += sizeof(struct sadb_lifetime);
515 
516 	if (sa->tdb_exp_allocations || sa->tdb_exp_bytes ||
517 	    sa->tdb_exp_timeout || sa->tdb_exp_first_use)
518 		i += sizeof(struct sadb_lifetime);
519 
520 	if (sa->tdb_last_used)
521 		i += sizeof(struct sadb_lifetime);
522 
523 	i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_src.sa));
524 	i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_dst.sa));
525 
526 	if (sa->tdb_srcid)
527 		i += sizeof(struct sadb_ident) + PADUP(sa->tdb_srcid->ref_len);
528 
529 	if (sa->tdb_dstid)
530 		i += sizeof(struct sadb_ident) + PADUP(sa->tdb_dstid->ref_len);
531 
532 	if (sa->tdb_amxkey)
533 		i += sizeof(struct sadb_key) + PADUP(sa->tdb_amxkeylen);
534 
535 	if (sa->tdb_emxkey)
536 		i += sizeof(struct sadb_key) + PADUP(sa->tdb_emxkeylen);
537 
538 	if (sa->tdb_filter.sen_type) {
539 		i += 2 * sizeof(struct sadb_protocol);
540 
541 		/* We'll need four of them: src, src mask, dst, dst mask. */
542 		switch (sa->tdb_filter.sen_type) {
543 		case SENT_IP4:
544 			i += 4 * PADUP(sizeof(struct sockaddr_in));
545 			i += 4 * sizeof(struct sadb_address);
546 			break;
547 #ifdef INET6
548 		case SENT_IP6:
549 			i += 4 * PADUP(sizeof(struct sockaddr_in6));
550 			i += 4 * sizeof(struct sadb_address);
551 			break;
552 #endif /* INET6 */
553 		default:
554 			rval = EINVAL;
555 			goto ret;
556 		}
557 	}
558 
559 	if (sa->tdb_udpencap_port)
560 		i += sizeof(struct sadb_x_udpencap);
561 
562 #if NPF > 0
563 	if (sa->tdb_tag)
564 		i += sizeof(struct sadb_x_tag) + PADUP(PF_TAG_NAME_SIZE);
565 	if (sa->tdb_tap)
566 		i += sizeof(struct sadb_x_tap);
567 #endif
568 
569 	if (lenp)
570 		*lenp = i;
571 
572 	if (buffer == NULL) {
573 		rval = 0;
574 		goto ret;
575 	}
576 
577 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
578 		rval = ENOMEM;
579 		goto ret;
580 	} else
581 		*buffer = p;
582 
583 	headers[SADB_EXT_SA] = p;
584 
585 	export_sa(&p, sa);  /* Export SA information (mostly flags) */
586 
587 	/* Export lifetimes where applicable */
588 	headers[SADB_EXT_LIFETIME_CURRENT] = p;
589 	export_lifetime(&p, sa, PFKEYV2_LIFETIME_CURRENT);
590 
591 	if (sa->tdb_soft_allocations || sa->tdb_soft_bytes ||
592 	    sa->tdb_soft_first_use || sa->tdb_soft_timeout) {
593 		headers[SADB_EXT_LIFETIME_SOFT] = p;
594 		export_lifetime(&p, sa, PFKEYV2_LIFETIME_SOFT);
595 	}
596 
597 	if (sa->tdb_exp_allocations || sa->tdb_exp_bytes ||
598 	    sa->tdb_exp_first_use || sa->tdb_exp_timeout) {
599 		headers[SADB_EXT_LIFETIME_HARD] = p;
600 		export_lifetime(&p, sa, PFKEYV2_LIFETIME_HARD);
601 	}
602 
603 	if (sa->tdb_last_used) {
604 		headers[SADB_X_EXT_LIFETIME_LASTUSE] = p;
605 		export_lifetime(&p, sa, PFKEYV2_LIFETIME_LASTUSE);
606 	}
607 
608 	/* Export TDB source address */
609 	headers[SADB_EXT_ADDRESS_SRC] = p;
610 	export_address(&p, (struct sockaddr *) &sa->tdb_src);
611 
612 	/* Export TDB destination address */
613 	headers[SADB_EXT_ADDRESS_DST] = p;
614 	export_address(&p, (struct sockaddr *) &sa->tdb_dst);
615 
616 	/* Export source identity, if present */
617 	if (sa->tdb_srcid) {
618 		headers[SADB_EXT_IDENTITY_SRC] = p;
619 		export_identity(&p, &sa->tdb_srcid);
620 	}
621 
622 	/* Export destination identity, if present */
623 	if (sa->tdb_dstid) {
624 		headers[SADB_EXT_IDENTITY_DST] = p;
625 		export_identity(&p, &sa->tdb_dstid);
626 	}
627 
628 	/* Export authentication key, if present */
629 	if (sa->tdb_amxkey) {
630 		headers[SADB_EXT_KEY_AUTH] = p;
631 		export_key(&p, sa, PFKEYV2_AUTHENTICATION_KEY);
632 	}
633 
634 	/* Export encryption key, if present */
635 	if (sa->tdb_emxkey) {
636 		headers[SADB_EXT_KEY_ENCRYPT] = p;
637 		export_key(&p, sa, PFKEYV2_ENCRYPTION_KEY);
638 	}
639 
640 	/* Export flow/filter, if present */
641 	if (sa->tdb_filter.sen_type)
642 		export_flow(&p, IPSP_IPSEC_USE, &sa->tdb_filter,
643 		    &sa->tdb_filtermask, headers);
644 
645 	/* Export UDP encapsulation port, if present */
646 	if (sa->tdb_udpencap_port) {
647 		headers[SADB_X_EXT_UDPENCAP] = p;
648 		export_udpencap(&p, sa);
649 	}
650 
651 #if NPF > 0
652 	/* Export tag information, if present */
653 	if (sa->tdb_tag) {
654 		headers[SADB_X_EXT_TAG] = p;
655 		export_tag(&p, sa);
656 	}
657 
658 	/* Export tap enc(4) device information, if present */
659 	if (sa->tdb_tap) {
660 		headers[SADB_X_EXT_TAP] = p;
661 		export_tap(&p, sa);
662 	}
663 #endif
664 
665 	rval = 0;
666 
667  ret:
668 	return (rval);
669 }
670 
671 /*
672  * Dump a TDB.
673  */
674 int
675 pfkeyv2_dump_walker(struct tdb *sa, void *state, int last)
676 {
677 	struct dump_state *dump_state = (struct dump_state *) state;
678 	void *headers[SADB_EXT_MAX+1], *buffer;
679 	int rval;
680 
681 	/* If not satype was specified, dump all TDBs */
682 	if (!dump_state->sadb_msg->sadb_msg_satype ||
683 	    (sa->tdb_satype == dump_state->sadb_msg->sadb_msg_satype)) {
684 		bzero(headers, sizeof(headers));
685 		headers[0] = (void *) dump_state->sadb_msg;
686 
687 		/* Get the information from the TDB to a PFKEYv2 message */
688 		if ((rval = pfkeyv2_get(sa, headers, &buffer, NULL)) != 0)
689 			return (rval);
690 
691 		if (last)
692 			((struct sadb_msg *)headers[0])->sadb_msg_seq = 0;
693 
694 		/* Send the message to the specified socket */
695 		rval = pfkeyv2_sendmessage(headers,
696 		    PFKEYV2_SENDMESSAGE_UNICAST, dump_state->socket, 0, 0,
697 		    sa->tdb_rdomain);
698 
699 		free(buffer, M_PFKEY, 0);
700 		if (rval)
701 			return (rval);
702 	}
703 
704 	return (0);
705 }
706 
707 /*
708  * Delete an SA.
709  */
710 int
711 pfkeyv2_flush_walker(struct tdb *sa, void *satype_vp, int last)
712 {
713 	if (!(*((u_int8_t *) satype_vp)) ||
714 	    sa->tdb_satype == *((u_int8_t *) satype_vp))
715 		tdb_delete(sa);
716 	return (0);
717 }
718 
719 /*
720  * Convert between SATYPEs and IPsec protocols, taking into consideration
721  * sysctl variables enabling/disabling ESP/AH and the presence of the old
722  * IPsec transforms.
723  */
724 int
725 pfkeyv2_get_proto_alg(u_int8_t satype, u_int8_t *sproto, int *alg)
726 {
727 	switch (satype) {
728 #ifdef IPSEC
729 	case SADB_SATYPE_AH:
730 		if (!ah_enable)
731 			return (EOPNOTSUPP);
732 
733 		*sproto = IPPROTO_AH;
734 
735 		if(alg != NULL)
736 			*alg = satype = XF_AH;
737 
738 		break;
739 
740 	case SADB_SATYPE_ESP:
741 		if (!esp_enable)
742 			return (EOPNOTSUPP);
743 
744 		*sproto = IPPROTO_ESP;
745 
746 		if(alg != NULL)
747 			*alg = satype = XF_ESP;
748 
749 		break;
750 
751 	case SADB_X_SATYPE_IPIP:
752 		*sproto = IPPROTO_IPIP;
753 
754 		if (alg != NULL)
755 			*alg = XF_IP4;
756 
757 		break;
758 
759 	case SADB_X_SATYPE_IPCOMP:
760 		if (!ipcomp_enable)
761 			return (EOPNOTSUPP);
762 
763 		*sproto = IPPROTO_IPCOMP;
764 
765 		if(alg != NULL)
766 			*alg = satype = XF_IPCOMP;
767 
768 		break;
769 #endif /* IPSEC */
770 #ifdef TCP_SIGNATURE
771 	case SADB_X_SATYPE_TCPSIGNATURE:
772 		*sproto = IPPROTO_TCP;
773 
774 		if (alg != NULL)
775 			*alg = XF_TCPSIGNATURE;
776 
777 		break;
778 #endif /* TCP_SIGNATURE */
779 
780 	default: /* Nothing else supported */
781 		return (EOPNOTSUPP);
782 	}
783 
784 	return (0);
785 }
786 
787 /*
788  * Handle all messages from userland to kernel.
789  */
790 int
791 pfkeyv2_send(struct socket *socket, void *message, int len)
792 {
793 	int i, j, rval = 0, mode = PFKEYV2_SENDMESSAGE_BROADCAST;
794 	int delflag = 0, s;
795 	struct sockaddr_encap encapdst, encapnetmask, encapgw;
796 	struct ipsec_policy *ipo, *tmpipo;
797 	struct ipsec_acquire *ipa;
798 
799 	struct pfkeyv2_socket *pfkeyv2_socket, *so = NULL;
800 
801 	void *freeme = NULL, *bckptr = NULL;
802 	void *headers[SADB_EXT_MAX + 1];
803 
804 	union sockaddr_union *sunionp;
805 
806 	struct tdb *sa1 = NULL, *sa2 = NULL;
807 
808 	struct sadb_msg *smsg;
809 	struct sadb_spirange *sprng;
810 	struct sadb_sa *ssa;
811 	struct sadb_supported *ssup;
812 	struct sadb_ident *sid;
813 
814 	u_int rdomain;
815 
816 	/* Verify that we received this over a legitimate pfkeyv2 socket */
817 	bzero(headers, sizeof(headers));
818 
819 	for (pfkeyv2_socket = pfkeyv2_sockets; pfkeyv2_socket;
820 	    pfkeyv2_socket = pfkeyv2_socket->next)
821 		if (pfkeyv2_socket->socket == socket)
822 			break;
823 
824 	if (!pfkeyv2_socket) {
825 		rval = EINVAL;
826 		goto ret;
827 	}
828 
829 	rdomain = pfkeyv2_socket->rdomain;
830 
831 	/* If we have any promiscuous listeners, send them a copy of the message */
832 	if (npromisc) {
833 		struct mbuf *packet;
834 
835 		if (!(freeme = malloc(sizeof(struct sadb_msg) + len, M_PFKEY,
836 		    M_NOWAIT))) {
837 			rval = ENOMEM;
838 			goto ret;
839 		}
840 
841 		/* Initialize encapsulating header */
842 		bzero(freeme, sizeof(struct sadb_msg));
843 		smsg = (struct sadb_msg *) freeme;
844 		smsg->sadb_msg_version = PF_KEY_V2;
845 		smsg->sadb_msg_type = SADB_X_PROMISC;
846 		smsg->sadb_msg_len = (sizeof(struct sadb_msg) + len) /
847 		    sizeof(uint64_t);
848 		smsg->sadb_msg_seq = curproc->p_p->ps_pid;
849 
850 		bcopy(message, freeme + sizeof(struct sadb_msg), len);
851 
852 		/* Convert to mbuf chain */
853 		if ((rval = pfdatatopacket(freeme,
854 		    sizeof(struct sadb_msg) + len, &packet)) != 0)
855 			goto ret;
856 
857 		/* Send to all promiscuous listeners */
858 		for (so = pfkeyv2_sockets; so; so = so->next) {
859 			if ((so->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
860 			    (so->rdomain == rdomain))
861 				pfkey_sendup(so->socket, packet, 1);
862 		}
863 
864 		m_freem(packet);
865 
866 		/* Paranoid */
867 		explicit_bzero(freeme, sizeof(struct sadb_msg) + len);
868 		free(freeme, M_PFKEY, 0);
869 		freeme = NULL;
870 	}
871 
872 	/* Validate message format */
873 	if ((rval = pfkeyv2_parsemessage(message, len, headers)) != 0)
874 		goto ret;
875 
876 	smsg = (struct sadb_msg *) headers[0];
877 	switch (smsg->sadb_msg_type) {
878 	case SADB_GETSPI:  /* Reserve an SPI */
879 		sa1 = malloc(sizeof (*sa1), M_PFKEY, M_NOWAIT | M_ZERO);
880 		if (sa1 == NULL) {
881 			rval = ENOMEM;
882 			goto ret;
883 		}
884 
885 		sa1->tdb_satype = smsg->sadb_msg_satype;
886 		if ((rval = pfkeyv2_get_proto_alg(sa1->tdb_satype,
887 		    &sa1->tdb_sproto, 0)))
888 			goto ret;
889 
890 		import_address((struct sockaddr *) &sa1->tdb_src,
891 		    headers[SADB_EXT_ADDRESS_SRC]);
892 		import_address((struct sockaddr *) &sa1->tdb_dst,
893 		    headers[SADB_EXT_ADDRESS_DST]);
894 
895 		/* Find an unused SA identifier */
896 		sprng = (struct sadb_spirange *) headers[SADB_EXT_SPIRANGE];
897 		sa1->tdb_spi = reserve_spi(rdomain,
898 		    sprng->sadb_spirange_min, sprng->sadb_spirange_max,
899 		    &sa1->tdb_src, &sa1->tdb_dst, sa1->tdb_sproto, &rval);
900 		if (sa1->tdb_spi == 0)
901 			goto ret;
902 
903 		/* Send a message back telling what the SA (the SPI really) is */
904 		if (!(freeme = malloc(sizeof(struct sadb_sa), M_PFKEY,
905 		    M_NOWAIT | M_ZERO))) {
906 			rval = ENOMEM;
907 			goto ret;
908 		}
909 
910 		headers[SADB_EXT_SPIRANGE] = NULL;
911 		headers[SADB_EXT_SA] = freeme;
912 		bckptr = freeme;
913 
914 		/* We really only care about the SPI, but we'll export the SA */
915 		export_sa((void **) &bckptr, sa1);
916 		break;
917 
918 	case SADB_UPDATE:
919 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
920 		sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
921 		    sizeof(struct sadb_address));
922 
923 		/* Either all or none of the flow must be included */
924 		if ((headers[SADB_X_EXT_SRC_FLOW] ||
925 		    headers[SADB_X_EXT_PROTOCOL] ||
926 		    headers[SADB_X_EXT_FLOW_TYPE] ||
927 		    headers[SADB_X_EXT_DST_FLOW] ||
928 		    headers[SADB_X_EXT_SRC_MASK] ||
929 		    headers[SADB_X_EXT_DST_MASK]) &&
930 		    !(headers[SADB_X_EXT_SRC_FLOW] &&
931 		    headers[SADB_X_EXT_PROTOCOL] &&
932 		    headers[SADB_X_EXT_FLOW_TYPE] &&
933 		    headers[SADB_X_EXT_DST_FLOW] &&
934 		    headers[SADB_X_EXT_SRC_MASK] &&
935 		    headers[SADB_X_EXT_DST_MASK])) {
936 			rval = EINVAL;
937 			goto ret;
938 		}
939 #ifdef IPSEC
940 		/* UDP encap has to be enabled and is only supported for ESP */
941 		if (headers[SADB_X_EXT_UDPENCAP] &&
942 		    (!udpencap_enable ||
943 		    smsg->sadb_msg_satype != SADB_SATYPE_ESP)) {
944 			rval = EINVAL;
945 			goto ret;
946 		}
947 #endif /* IPSEC */
948 
949 		s = splsoftnet();
950 
951 		/* Find TDB */
952 		sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
953 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
954 
955 		/* If there's no such SA, we're done */
956 		if (sa2 == NULL) {
957 			rval = ESRCH;
958 			goto splxret;
959 		}
960 
961 		/* If this is a reserved SA */
962 		if (sa2->tdb_flags & TDBF_INVALID) {
963 			struct tdb *newsa;
964 			struct ipsecinit ii;
965 			int alg;
966 
967 			/* Create new TDB */
968 			freeme = tdb_alloc(rdomain);
969 			bzero(&ii, sizeof(struct ipsecinit));
970 
971 			newsa = (struct tdb *) freeme;
972 			newsa->tdb_satype = smsg->sadb_msg_satype;
973 
974 			if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype,
975 			    &newsa->tdb_sproto, &alg))) {
976 				tdb_free(freeme);
977 				freeme = NULL;
978 				goto splxret;
979 			}
980 
981 			/* Initialize SA */
982 			import_sa(newsa, headers[SADB_EXT_SA], &ii);
983 			import_address((struct sockaddr *) &newsa->tdb_src,
984 			    headers[SADB_EXT_ADDRESS_SRC]);
985 			import_address((struct sockaddr *) &newsa->tdb_dst,
986 			    headers[SADB_EXT_ADDRESS_DST]);
987 			import_lifetime(newsa,
988 			    headers[SADB_EXT_LIFETIME_CURRENT],
989 			    PFKEYV2_LIFETIME_CURRENT);
990 			import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT],
991 			    PFKEYV2_LIFETIME_SOFT);
992 			import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD],
993 			    PFKEYV2_LIFETIME_HARD);
994 			import_key(&ii, headers[SADB_EXT_KEY_AUTH],
995 			    PFKEYV2_AUTHENTICATION_KEY);
996 			import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT],
997 			    PFKEYV2_ENCRYPTION_KEY);
998 			import_identity(&newsa->tdb_srcid,
999 			    headers[SADB_EXT_IDENTITY_SRC]);
1000 			import_identity(&newsa->tdb_dstid,
1001 			    headers[SADB_EXT_IDENTITY_DST]);
1002 			import_flow(&newsa->tdb_filter, &newsa->tdb_filtermask,
1003 			    headers[SADB_X_EXT_SRC_FLOW],
1004 			    headers[SADB_X_EXT_SRC_MASK],
1005 			    headers[SADB_X_EXT_DST_FLOW],
1006 			    headers[SADB_X_EXT_DST_MASK],
1007 			    headers[SADB_X_EXT_PROTOCOL],
1008 			    headers[SADB_X_EXT_FLOW_TYPE]);
1009 			import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
1010 #if NPF > 0
1011 			import_tag(newsa, headers[SADB_X_EXT_TAG]);
1012 			import_tap(newsa, headers[SADB_X_EXT_TAP]);
1013 #endif
1014 
1015 			/* Exclude sensitive data from reply message. */
1016 			headers[SADB_EXT_KEY_AUTH] = NULL;
1017 			headers[SADB_EXT_KEY_ENCRYPT] = NULL;
1018 			headers[SADB_X_EXT_LOCAL_AUTH] = NULL;
1019 			headers[SADB_X_EXT_REMOTE_AUTH] = NULL;
1020 
1021 			newsa->tdb_seq = smsg->sadb_msg_seq;
1022 
1023 			rval = tdb_init(newsa, alg, &ii);
1024 			if (rval) {
1025 				rval = EINVAL;
1026 				tdb_free(freeme);
1027 				freeme = NULL;
1028 				goto splxret;
1029 			}
1030 
1031 			newsa->tdb_cur_allocations = sa2->tdb_cur_allocations;
1032 
1033 			/* Delete old version of the SA, insert new one */
1034 			tdb_delete(sa2);
1035 			puttdb((struct tdb *) freeme);
1036 			sa2 = freeme = NULL;
1037 		} else {
1038 			/*
1039 			 * The SA is already initialized, so we're only allowed to
1040 			 * change lifetimes and some other information; we're
1041 			 * not allowed to change keys, addresses or identities.
1042 			 */
1043 			if (headers[SADB_EXT_KEY_AUTH] ||
1044 			    headers[SADB_EXT_KEY_ENCRYPT] ||
1045 			    headers[SADB_EXT_IDENTITY_SRC] ||
1046 			    headers[SADB_EXT_IDENTITY_DST] ||
1047 			    headers[SADB_EXT_SENSITIVITY]) {
1048 				rval = EINVAL;
1049 				goto splxret;
1050 			}
1051 
1052 			import_sa(sa2, headers[SADB_EXT_SA], NULL);
1053 			import_lifetime(sa2,
1054 			    headers[SADB_EXT_LIFETIME_CURRENT],
1055 			    PFKEYV2_LIFETIME_CURRENT);
1056 			import_lifetime(sa2, headers[SADB_EXT_LIFETIME_SOFT],
1057 			    PFKEYV2_LIFETIME_SOFT);
1058 			import_lifetime(sa2, headers[SADB_EXT_LIFETIME_HARD],
1059 			    PFKEYV2_LIFETIME_HARD);
1060 			import_udpencap(sa2, headers[SADB_X_EXT_UDPENCAP]);
1061 #if NPF > 0
1062 			import_tag(sa2, headers[SADB_X_EXT_TAG]);
1063 			import_tap(sa2, headers[SADB_X_EXT_TAP]);
1064 #endif
1065 		}
1066 
1067 		splx(s);
1068 		break;
1069 	case SADB_ADD:
1070 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
1071 		sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
1072 		    sizeof(struct sadb_address));
1073 
1074 		/* Either all or none of the flow must be included */
1075 		if ((headers[SADB_X_EXT_SRC_FLOW] ||
1076 		    headers[SADB_X_EXT_PROTOCOL] ||
1077 		    headers[SADB_X_EXT_FLOW_TYPE] ||
1078 		    headers[SADB_X_EXT_DST_FLOW] ||
1079 		    headers[SADB_X_EXT_SRC_MASK] ||
1080 		    headers[SADB_X_EXT_DST_MASK]) &&
1081 		    !(headers[SADB_X_EXT_SRC_FLOW] &&
1082 		    headers[SADB_X_EXT_PROTOCOL] &&
1083 		    headers[SADB_X_EXT_FLOW_TYPE] &&
1084 		    headers[SADB_X_EXT_DST_FLOW] &&
1085 		    headers[SADB_X_EXT_SRC_MASK] &&
1086 		    headers[SADB_X_EXT_DST_MASK])) {
1087 			rval = EINVAL;
1088 			goto ret;
1089 		}
1090 #ifdef IPSEC
1091 		/* UDP encap has to be enabled and is only supported for ESP */
1092 		if (headers[SADB_X_EXT_UDPENCAP] &&
1093 		    (!udpencap_enable ||
1094 		    smsg->sadb_msg_satype != SADB_SATYPE_ESP)) {
1095 			rval = EINVAL;
1096 			goto ret;
1097 		}
1098 #endif /* IPSEC */
1099 
1100 		s = splsoftnet();
1101 
1102 		sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1103 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
1104 
1105 		/* We can't add an existing SA! */
1106 		if (sa2 != NULL) {
1107 			rval = EEXIST;
1108 			goto splxret;
1109 		}
1110 
1111 		/* We can only add "mature" SAs */
1112 		if (ssa->sadb_sa_state != SADB_SASTATE_MATURE) {
1113 			rval = EINVAL;
1114 			goto splxret;
1115 		}
1116 
1117 		/* Allocate and initialize new TDB */
1118 		freeme = tdb_alloc(rdomain);
1119 
1120 		{
1121 			struct tdb *newsa = (struct tdb *) freeme;
1122 			struct ipsecinit ii;
1123 			int alg;
1124 
1125 			bzero(&ii, sizeof(struct ipsecinit));
1126 
1127 			newsa->tdb_satype = smsg->sadb_msg_satype;
1128 			if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype,
1129 			    &newsa->tdb_sproto, &alg))) {
1130 				tdb_free(freeme);
1131 				freeme = NULL;
1132 				goto splxret;
1133 			}
1134 
1135 			import_sa(newsa, headers[SADB_EXT_SA], &ii);
1136 			import_address((struct sockaddr *) &newsa->tdb_src,
1137 			    headers[SADB_EXT_ADDRESS_SRC]);
1138 			import_address((struct sockaddr *) &newsa->tdb_dst,
1139 			    headers[SADB_EXT_ADDRESS_DST]);
1140 
1141 			import_lifetime(newsa,
1142 			    headers[SADB_EXT_LIFETIME_CURRENT],
1143 			    PFKEYV2_LIFETIME_CURRENT);
1144 			import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT],
1145 			    PFKEYV2_LIFETIME_SOFT);
1146 			import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD],
1147 			    PFKEYV2_LIFETIME_HARD);
1148 
1149 			import_key(&ii, headers[SADB_EXT_KEY_AUTH],
1150 			    PFKEYV2_AUTHENTICATION_KEY);
1151 			import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT],
1152 			    PFKEYV2_ENCRYPTION_KEY);
1153 
1154 			import_identity(&newsa->tdb_srcid,
1155 			    headers[SADB_EXT_IDENTITY_SRC]);
1156 			import_identity(&newsa->tdb_dstid,
1157 			    headers[SADB_EXT_IDENTITY_DST]);
1158 
1159 			import_flow(&newsa->tdb_filter, &newsa->tdb_filtermask,
1160 			    headers[SADB_X_EXT_SRC_FLOW],
1161 			    headers[SADB_X_EXT_SRC_MASK],
1162 			    headers[SADB_X_EXT_DST_FLOW],
1163 			    headers[SADB_X_EXT_DST_MASK],
1164 			    headers[SADB_X_EXT_PROTOCOL],
1165 			    headers[SADB_X_EXT_FLOW_TYPE]);
1166 			import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
1167 #if NPF > 0
1168 			import_tag(newsa, headers[SADB_X_EXT_TAG]);
1169 			import_tap(newsa, headers[SADB_X_EXT_TAP]);
1170 #endif
1171 
1172 			/* Exclude sensitive data from reply message. */
1173 			headers[SADB_EXT_KEY_AUTH] = NULL;
1174 			headers[SADB_EXT_KEY_ENCRYPT] = NULL;
1175 			headers[SADB_X_EXT_LOCAL_AUTH] = NULL;
1176 			headers[SADB_X_EXT_REMOTE_AUTH] = NULL;
1177 
1178 			newsa->tdb_seq = smsg->sadb_msg_seq;
1179 
1180 			rval = tdb_init(newsa, alg, &ii);
1181 			if (rval) {
1182 				rval = EINVAL;
1183 				tdb_free(freeme);
1184 				freeme = NULL;
1185 				goto splxret;
1186 			}
1187 		}
1188 
1189 		/* Add TDB in table */
1190 		puttdb((struct tdb *) freeme);
1191 
1192 		splx(s);
1193 
1194 		freeme = NULL;
1195 		break;
1196 
1197 	case SADB_DELETE:
1198 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
1199 		sunionp =
1200 		    (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
1201 			sizeof(struct sadb_address));
1202 		s = splsoftnet();
1203 
1204 		sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1205 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
1206 		if (sa2 == NULL) {
1207 			rval = ESRCH;
1208 			goto splxret;
1209 		}
1210 
1211 		tdb_delete(sa2);
1212 
1213 		splx(s);
1214 
1215 		sa2 = NULL;
1216 		break;
1217 
1218 	case SADB_X_ASKPOLICY:
1219 		/* Get the relevant policy */
1220 		ipa = ipsec_get_acquire(((struct sadb_x_policy *) headers[SADB_X_EXT_POLICY])->sadb_x_policy_seq);
1221 		if (ipa == NULL) {
1222 			rval = ESRCH;
1223 			goto ret;
1224 		}
1225 
1226 		rval = pfkeyv2_policy(ipa, headers, &freeme);
1227 		if (rval)
1228 			mode = PFKEYV2_SENDMESSAGE_UNICAST;
1229 
1230 		break;
1231 
1232 	case SADB_GET:
1233 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
1234 		sunionp =
1235 		    (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
1236 			sizeof(struct sadb_address));
1237 
1238 		s = splsoftnet();
1239 
1240 		sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1241 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
1242 		if (sa2 == NULL) {
1243 			rval = ESRCH;
1244 			goto splxret;
1245 		}
1246 
1247 		rval = pfkeyv2_get(sa2, headers, &freeme, NULL);
1248 		if (rval)
1249 			mode = PFKEYV2_SENDMESSAGE_UNICAST;
1250 
1251 		splx(s);
1252 
1253 		break;
1254 
1255 	case SADB_REGISTER:
1256 		if (!(pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) {
1257 			pfkeyv2_socket->flags |= PFKEYV2_SOCKETFLAGS_REGISTERED;
1258 			nregistered++;
1259 		}
1260 
1261 		i = sizeof(struct sadb_supported) + sizeof(ealgs);
1262 
1263 		if (!(freeme = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
1264 			rval = ENOMEM;
1265 			goto ret;
1266 		}
1267 
1268 		ssup = (struct sadb_supported *) freeme;
1269 		ssup->sadb_supported_len = i / sizeof(uint64_t);
1270 
1271 		{
1272 			void *p = freeme + sizeof(struct sadb_supported);
1273 
1274 			bcopy(&ealgs[0], p, sizeof(ealgs));
1275 		}
1276 
1277 		headers[SADB_EXT_SUPPORTED_ENCRYPT] = freeme;
1278 
1279 		i = sizeof(struct sadb_supported) + sizeof(aalgs);
1280 
1281 		if (!(freeme = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
1282 			rval = ENOMEM;
1283 			goto ret;
1284 		}
1285 
1286 		/* Keep track what this socket has registered for */
1287 		pfkeyv2_socket->registration |= (1 << ((struct sadb_msg *)message)->sadb_msg_satype);
1288 
1289 		ssup = (struct sadb_supported *) freeme;
1290 		ssup->sadb_supported_len = i / sizeof(uint64_t);
1291 
1292 		{
1293 			void *p = freeme + sizeof(struct sadb_supported);
1294 
1295 			bcopy(&aalgs[0], p, sizeof(aalgs));
1296 		}
1297 
1298 		headers[SADB_EXT_SUPPORTED_AUTH] = freeme;
1299 
1300 		i = sizeof(struct sadb_supported) + sizeof(calgs);
1301 
1302 		if (!(freeme = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
1303 			rval = ENOMEM;
1304 			goto ret;
1305 		}
1306 
1307 		ssup = (struct sadb_supported *) freeme;
1308 		ssup->sadb_supported_len = i / sizeof(uint64_t);
1309 
1310 		{
1311 			void *p = freeme + sizeof(struct sadb_supported);
1312 
1313 			bcopy(&calgs[0], p, sizeof(calgs));
1314 		}
1315 
1316 		headers[SADB_X_EXT_SUPPORTED_COMP] = freeme;
1317 
1318 		break;
1319 
1320 	case SADB_ACQUIRE:
1321 	case SADB_EXPIRE:
1322 		/* Nothing to handle */
1323 		rval = 0;
1324 		break;
1325 
1326 	case SADB_FLUSH:
1327 		rval = 0;
1328 
1329 		switch (smsg->sadb_msg_satype) {
1330 		case SADB_SATYPE_UNSPEC:
1331 			s = splsoftnet();
1332 
1333 			for (ipo = TAILQ_FIRST(&ipsec_policy_head);
1334 			    ipo != NULL; ipo = tmpipo) {
1335 				tmpipo = TAILQ_NEXT(ipo, ipo_list);
1336 				if (ipo->ipo_rdomain == rdomain)
1337 					ipsec_delete_policy(ipo);
1338 			}
1339 			splx(s);
1340 			/* FALLTHROUGH */
1341 		case SADB_SATYPE_AH:
1342 		case SADB_SATYPE_ESP:
1343 		case SADB_X_SATYPE_IPIP:
1344 		case SADB_X_SATYPE_IPCOMP:
1345 #ifdef TCP_SIGNATURE
1346 		case SADB_X_SATYPE_TCPSIGNATURE:
1347 #endif /* TCP_SIGNATURE */
1348 			s = splsoftnet();
1349 
1350 			tdb_walk(rdomain, pfkeyv2_flush_walker,
1351 			    (u_int8_t *) &(smsg->sadb_msg_satype));
1352 
1353 			splx(s);
1354 			break;
1355 
1356 		default:
1357 			rval = EINVAL; /* Unknown/unsupported type */
1358 		}
1359 
1360 		break;
1361 
1362 	case SADB_DUMP:
1363 	{
1364 		struct dump_state dump_state;
1365 		dump_state.sadb_msg = (struct sadb_msg *) headers[0];
1366 		dump_state.socket = socket;
1367 
1368 		s = splsoftnet();
1369 		rval = tdb_walk(rdomain, pfkeyv2_dump_walker, &dump_state);
1370 		splx(s);
1371 
1372 		if (!rval)
1373 			goto realret;
1374 
1375 		if ((rval == ENOMEM) || (rval == ENOBUFS))
1376 			rval = 0;
1377 	}
1378 	break;
1379 
1380 	case SADB_X_GRPSPIS:
1381 	{
1382 		struct tdb *tdb1, *tdb2, *tdb3;
1383 		struct sadb_protocol *sa_proto;
1384 
1385 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
1386 		sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
1387 		    sizeof(struct sadb_address));
1388 
1389 		s = splsoftnet();
1390 
1391 		tdb1 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1392 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
1393 		if (tdb1 == NULL) {
1394 			rval = ESRCH;
1395 			goto splxret;
1396 		}
1397 
1398 		ssa = (struct sadb_sa *) headers[SADB_X_EXT_SA2];
1399 		sunionp = (union sockaddr_union *) (headers[SADB_X_EXT_DST2] +
1400 		    sizeof(struct sadb_address));
1401 		sa_proto = ((struct sadb_protocol *) headers[SADB_X_EXT_PROTOCOL]);
1402 
1403 		tdb2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1404 		    SADB_X_GETSPROTO(sa_proto->sadb_protocol_proto));
1405 		if (tdb2 == NULL) {
1406 			rval = ESRCH;
1407 			goto splxret;
1408 		}
1409 
1410 		/* Detect cycles */
1411 		for (tdb3 = tdb2; tdb3; tdb3 = tdb3->tdb_onext)
1412 			if (tdb3 == tdb1) {
1413 				rval = ESRCH;
1414 				goto splxret;
1415 			}
1416 
1417 		/* Maintenance */
1418 		if ((tdb1->tdb_onext) &&
1419 		    (tdb1->tdb_onext->tdb_inext == tdb1))
1420 			tdb1->tdb_onext->tdb_inext = NULL;
1421 
1422 		if ((tdb2->tdb_inext) &&
1423 		    (tdb2->tdb_inext->tdb_onext == tdb2))
1424 			tdb2->tdb_inext->tdb_onext = NULL;
1425 
1426 		/* Link them */
1427 		tdb1->tdb_onext = tdb2;
1428 		tdb2->tdb_inext = tdb1;
1429 
1430 		splx(s);
1431 	}
1432 	break;
1433 
1434 	case SADB_X_DELFLOW:
1435 		delflag = 1;
1436 		/*FALLTHROUGH*/
1437 	case SADB_X_ADDFLOW:
1438 	{
1439 		struct sadb_protocol *sab;
1440 		union sockaddr_union *ssrc;
1441 		struct rtentry *rt;
1442 		int exists = 0;
1443 
1444 		sab = (struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE];
1445 
1446 		if ((sab->sadb_protocol_direction != IPSP_DIRECTION_IN) &&
1447 		    (sab->sadb_protocol_direction != IPSP_DIRECTION_OUT)) {
1448 			rval = EINVAL;
1449 			goto ret;
1450 		}
1451 
1452 		/* If the security protocol wasn't specified, pretend it was ESP */
1453 		if (smsg->sadb_msg_satype == 0)
1454 			smsg->sadb_msg_satype = SADB_SATYPE_ESP;
1455 
1456 		if (headers[SADB_EXT_ADDRESS_DST])
1457 			sunionp = (union sockaddr_union *)
1458 			    (headers[SADB_EXT_ADDRESS_DST] +
1459 				sizeof(struct sadb_address));
1460 		else
1461 			sunionp = NULL;
1462 
1463 		if (headers[SADB_EXT_ADDRESS_SRC])
1464 			ssrc = (union sockaddr_union *)
1465 			    (headers[SADB_EXT_ADDRESS_SRC] +
1466 				sizeof(struct sadb_address));
1467 		else
1468 			ssrc = NULL;
1469 
1470 		import_flow(&encapdst, &encapnetmask,
1471 		    headers[SADB_X_EXT_SRC_FLOW], headers[SADB_X_EXT_SRC_MASK],
1472 		    headers[SADB_X_EXT_DST_FLOW], headers[SADB_X_EXT_DST_MASK],
1473 		    headers[SADB_X_EXT_PROTOCOL], headers[SADB_X_EXT_FLOW_TYPE]);
1474 
1475 		/* Determine whether the exact same SPD entry already exists. */
1476 		bzero(&encapgw, sizeof(struct sockaddr_encap));
1477 
1478 		s = splsoftnet();
1479 		rt = rtalloc((struct sockaddr *)&encapdst, RT_REPORT|RT_RESOLVE,
1480 		    rdomain);
1481 		if (rt != NULL) {
1482 			ipo = ((struct sockaddr_encap *)rt->rt_gateway)->sen_ipsp;
1483 			rtfree(rt);
1484 
1485 			/* Verify that the entry is identical */
1486 			if (bcmp(&ipo->ipo_addr, &encapdst,
1487 				sizeof(struct sockaddr_encap)) ||
1488 			    bcmp(&ipo->ipo_mask, &encapnetmask,
1489 				sizeof(struct sockaddr_encap)))
1490 				ipo = NULL; /* Fall through */
1491 			else
1492 				exists = 1;
1493 		} else
1494 			ipo = NULL;
1495 
1496 		/*
1497 		 * If the existing policy is static, only delete or update
1498 		 * it if the new one is also static.
1499 		 */
1500 		if (exists && (ipo->ipo_flags & IPSP_POLICY_STATIC)) {
1501 			if (!(sab->sadb_protocol_flags &
1502 				SADB_X_POLICYFLAGS_POLICY)) {
1503 				splx(s);
1504 				goto ret;
1505 			}
1506 		}
1507 
1508 		/* Delete ? */
1509 		if (delflag) {
1510 			if (exists) {
1511 				rval = ipsec_delete_policy(ipo);
1512 				splx(s);
1513 				goto ret;
1514 			}
1515 
1516 			/* If we were asked to delete something non-existent, error. */
1517 			splx(s);
1518 			rval = ESRCH;
1519 			break;
1520 		}
1521 
1522 		if (!exists) {
1523 			if (ipsec_policy_pool_initialized == 0) {
1524 				ipsec_policy_pool_initialized = 1;
1525 				pool_init(&ipsec_policy_pool,
1526 				    sizeof(struct ipsec_policy), 0, 0, 0,
1527 				    "ipsec policy", NULL);
1528 			}
1529 
1530 			/* Allocate policy entry */
1531 			ipo = pool_get(&ipsec_policy_pool, PR_NOWAIT);
1532 			if (ipo == NULL) {
1533 				splx(s);
1534 				rval = ENOMEM;
1535 				goto ret;
1536 			}
1537 
1538 			bzero(ipo, sizeof(struct ipsec_policy));
1539 			ipo->ipo_ref_count = 1;
1540 			TAILQ_INIT(&ipo->ipo_acquires);
1541 
1542 			/* Finish initialization of SPD entry */
1543 			encapgw.sen_len = SENT_LEN;
1544 			encapgw.sen_family = PF_KEY;
1545 			encapgw.sen_type = SENT_IPSP;
1546 			encapgw.sen_ipsp = ipo;
1547 
1548 			/* Initialize policy entry */
1549 			bcopy(&encapdst, &ipo->ipo_addr,
1550 			    sizeof(struct sockaddr_encap));
1551 			bcopy(&encapnetmask, &ipo->ipo_mask,
1552 			    sizeof(struct sockaddr_encap));
1553 
1554 			ipo->ipo_rdomain = rdomain;
1555 		}
1556 
1557 		switch (((struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE])->sadb_protocol_proto) {
1558 		case SADB_X_FLOW_TYPE_USE:
1559 			ipo->ipo_type = IPSP_IPSEC_USE;
1560 			break;
1561 
1562 		case SADB_X_FLOW_TYPE_ACQUIRE:
1563 			ipo->ipo_type = IPSP_IPSEC_ACQUIRE;
1564 			break;
1565 
1566 		case SADB_X_FLOW_TYPE_REQUIRE:
1567 			ipo->ipo_type = IPSP_IPSEC_REQUIRE;
1568 			break;
1569 
1570 		case SADB_X_FLOW_TYPE_DENY:
1571 			ipo->ipo_type = IPSP_DENY;
1572 			break;
1573 
1574 		case SADB_X_FLOW_TYPE_BYPASS:
1575 			ipo->ipo_type = IPSP_PERMIT;
1576 			break;
1577 
1578 		case SADB_X_FLOW_TYPE_DONTACQ:
1579 			ipo->ipo_type = IPSP_IPSEC_DONTACQ;
1580 			break;
1581 
1582 		default:
1583 			if (!exists)
1584 				pool_put(&ipsec_policy_pool, ipo);
1585 			else
1586 				ipsec_delete_policy(ipo);
1587 
1588 			splx(s);
1589 			rval = EINVAL;
1590 			goto ret;
1591 		}
1592 
1593 		if (sab->sadb_protocol_flags & SADB_X_POLICYFLAGS_POLICY)
1594 			ipo->ipo_flags |= IPSP_POLICY_STATIC;
1595 
1596 		if (sunionp)
1597 			bcopy(sunionp, &ipo->ipo_dst,
1598 			    sizeof(union sockaddr_union));
1599 		else
1600 			bzero(&ipo->ipo_dst, sizeof(union sockaddr_union));
1601 
1602 		if (ssrc)
1603 			bcopy(ssrc, &ipo->ipo_src,
1604 			    sizeof(union sockaddr_union));
1605 		else
1606 			bzero(&ipo->ipo_src, sizeof(union sockaddr_union));
1607 
1608 		ipo->ipo_sproto = SADB_X_GETSPROTO(smsg->sadb_msg_satype);
1609 
1610 		if (ipo->ipo_srcid) {
1611 			ipsp_reffree(ipo->ipo_srcid);
1612 			ipo->ipo_srcid = NULL;
1613 		}
1614 
1615 		if (ipo->ipo_dstid) {
1616 			ipsp_reffree(ipo->ipo_dstid);
1617 			ipo->ipo_dstid = NULL;
1618 		}
1619 
1620 		if ((sid = headers[SADB_EXT_IDENTITY_SRC]) != NULL) {
1621 			import_identity(&ipo->ipo_srcid, sid);
1622 			if (ipo->ipo_srcid == NULL) {
1623 				if (exists)
1624 					ipsec_delete_policy(ipo);
1625 				else
1626 					pool_put(&ipsec_policy_pool, ipo);
1627 				splx(s);
1628 				rval = ENOBUFS;
1629 				goto ret;
1630 			}
1631 		}
1632 
1633 		if ((sid = headers[SADB_EXT_IDENTITY_DST]) != NULL) {
1634 			import_identity(&ipo->ipo_dstid, sid);
1635 			if (ipo->ipo_dstid == NULL) {
1636 				if (exists)
1637 					ipsec_delete_policy(ipo);
1638 				else {
1639 					if (ipo->ipo_dstid)
1640 						ipsp_reffree(ipo->ipo_dstid);
1641 					pool_put(&ipsec_policy_pool, ipo);
1642 				}
1643 
1644 				splx(s);
1645 				rval = ENOBUFS;
1646 				goto ret;
1647 			}
1648 		}
1649 
1650 		/* Flow type */
1651 		if (!exists) {
1652 			/* Add SPD entry */
1653 			struct rt_addrinfo info;
1654 
1655 			bzero(&info, sizeof(info));
1656 			info.rti_info[RTAX_DST] = (struct sockaddr *)&encapdst;
1657 			info.rti_info[RTAX_GATEWAY] =
1658 			    (struct sockaddr *)&encapgw;
1659 			info.rti_info[RTAX_NETMASK] =
1660 			    (struct sockaddr *)&encapnetmask;
1661 			info.rti_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
1662 			if ((rval = rtrequest1(RTM_ADD, &info, RTP_DEFAULT,
1663 			    NULL, rdomain)) != 0) {
1664 				/* Remove from linked list of policies on TDB */
1665 				if (ipo->ipo_tdb)
1666 					TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head,
1667 					    ipo, ipo_tdb_next);
1668 
1669 				if (ipo->ipo_srcid)
1670 					ipsp_reffree(ipo->ipo_srcid);
1671 				if (ipo->ipo_dstid)
1672 					ipsp_reffree(ipo->ipo_dstid);
1673 				pool_put(&ipsec_policy_pool, ipo);
1674 
1675 				splx(s);
1676 				goto ret;
1677 			}
1678 
1679 			TAILQ_INSERT_HEAD(&ipsec_policy_head, ipo, ipo_list);
1680 			ipsec_in_use++;
1681 		} else {
1682 			ipo->ipo_last_searched = ipo->ipo_flags = 0;
1683 		}
1684 
1685 		splx(s);
1686 	}
1687 	break;
1688 
1689 	case SADB_X_PROMISC:
1690 		if (len >= 2 * sizeof(struct sadb_msg)) {
1691 			struct mbuf *packet;
1692 
1693 			if ((rval = pfdatatopacket(message, len, &packet)) != 0)
1694 				goto ret;
1695 
1696 			for (so = pfkeyv2_sockets; so; so = so->next)
1697 				if ((so != pfkeyv2_socket) &&
1698 				    (so->rdomain == rdomain) &&
1699 				    (!smsg->sadb_msg_seq ||
1700 				    (smsg->sadb_msg_seq == pfkeyv2_socket->pid)))
1701 					pfkey_sendup(so->socket, packet, 1);
1702 
1703 			m_freem(packet);
1704 		} else {
1705 			if (len != sizeof(struct sadb_msg)) {
1706 				rval = EINVAL;
1707 				goto ret;
1708 			}
1709 
1710 			i = (pfkeyv2_socket->flags &
1711 			    PFKEYV2_SOCKETFLAGS_PROMISC) ? 1 : 0;
1712 			j = smsg->sadb_msg_satype ? 1 : 0;
1713 
1714 			if (i ^ j) {
1715 				if (j) {
1716 					pfkeyv2_socket->flags |=
1717 					    PFKEYV2_SOCKETFLAGS_PROMISC;
1718 					npromisc++;
1719 				} else {
1720 					pfkeyv2_socket->flags &=
1721 					    ~PFKEYV2_SOCKETFLAGS_PROMISC;
1722 					npromisc--;
1723 				}
1724 			}
1725 		}
1726 
1727 
1728 		break;
1729 
1730 	default:
1731 		rval = EINVAL;
1732 		goto ret;
1733 	}
1734 
1735 ret:
1736 	if (rval) {
1737 		if ((rval == EINVAL) || (rval == ENOMEM) || (rval == ENOBUFS))
1738 			goto realret;
1739 
1740 		for (i = 1; i <= SADB_EXT_MAX; i++)
1741 			headers[i] = NULL;
1742 
1743 		smsg->sadb_msg_errno = abs(rval);
1744 	} else {
1745 		uint64_t seen = 0LL;
1746 
1747 		for (i = 1; i <= SADB_EXT_MAX; i++)
1748 			if (headers[i])
1749 				seen |= (1LL << i);
1750 
1751 		if ((seen & sadb_exts_allowed_out[smsg->sadb_msg_type])
1752 		    != seen)
1753 			goto realret;
1754 
1755 		if ((seen & sadb_exts_required_out[smsg->sadb_msg_type]) !=
1756 		    sadb_exts_required_out[smsg->sadb_msg_type])
1757 			goto realret;
1758 	}
1759 
1760 	rval = pfkeyv2_sendmessage(headers, mode, socket, 0, 0, rdomain);
1761 
1762 realret:
1763 	if (freeme)
1764 		free(freeme, M_PFKEY, 0);
1765 
1766 	explicit_bzero(message, len);
1767 	free(message, M_PFKEY, 0);
1768 
1769 	if (sa1)
1770 		free(sa1, M_PFKEY, 0);
1771 
1772 	return (rval);
1773 
1774 splxret:
1775 	splx(s);
1776 	goto ret;
1777 }
1778 
1779 /*
1780  * Send an ACQUIRE message to key management, to get a new SA.
1781  */
1782 int
1783 pfkeyv2_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw,
1784     union sockaddr_union *laddr, u_int32_t *seq, struct sockaddr_encap *ddst)
1785 {
1786 	void *p, *headers[SADB_EXT_MAX + 1], *buffer = NULL;
1787 	struct sadb_comb *sadb_comb;
1788 	struct sadb_address *sadd;
1789 	struct sadb_prop *sa_prop;
1790 	struct sadb_msg *smsg;
1791 	int rval = 0;
1792 	int i, j;
1793 
1794 	*seq = pfkeyv2_seq++;
1795 
1796 	if (!nregistered) {
1797 		rval = ESRCH;
1798 		goto ret;
1799 	}
1800 
1801 	/* How large a buffer do we need... XXX we only do one proposal for now */
1802 	i = sizeof(struct sadb_msg) +
1803 	    (laddr == NULL ? 0 : sizeof(struct sadb_address) +
1804 		PADUP(SA_LEN(&ipo->ipo_src.sa))) +
1805 	    sizeof(struct sadb_address) + PADUP(SA_LEN(&gw->sa)) +
1806 	    sizeof(struct sadb_prop) + 1 * sizeof(struct sadb_comb);
1807 
1808 	if (ipo->ipo_srcid)
1809 		i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
1810 
1811 	if (ipo->ipo_dstid)
1812 		i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
1813 
1814 	/* Allocate */
1815 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
1816 		rval = ENOMEM;
1817 		goto ret;
1818 	}
1819 
1820 	bzero(headers, sizeof(headers));
1821 
1822 	buffer = p;
1823 
1824 	headers[0] = p;
1825 	p += sizeof(struct sadb_msg);
1826 
1827 	smsg = (struct sadb_msg *) headers[0];
1828 	smsg->sadb_msg_version = PF_KEY_V2;
1829 	smsg->sadb_msg_type = SADB_ACQUIRE;
1830 	smsg->sadb_msg_len = i / sizeof(uint64_t);
1831 	smsg->sadb_msg_seq = *seq;
1832 
1833 	if (ipo->ipo_sproto == IPPROTO_ESP)
1834 		smsg->sadb_msg_satype = SADB_SATYPE_ESP;
1835 	else if (ipo->ipo_sproto == IPPROTO_AH)
1836 		smsg->sadb_msg_satype = SADB_SATYPE_AH;
1837 	else if (ipo->ipo_sproto == IPPROTO_IPCOMP)
1838 		smsg->sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
1839 
1840 	if (laddr) {
1841 		headers[SADB_EXT_ADDRESS_SRC] = p;
1842 		p += sizeof(struct sadb_address) + PADUP(SA_LEN(&laddr->sa));
1843 		sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_SRC];
1844 		sadd->sadb_address_len = (sizeof(struct sadb_address) +
1845 		    SA_LEN(&laddr->sa) + sizeof(uint64_t) - 1) /
1846 		    sizeof(uint64_t);
1847 		bcopy(laddr, headers[SADB_EXT_ADDRESS_SRC] +
1848 		    sizeof(struct sadb_address), SA_LEN(&laddr->sa));
1849 	}
1850 
1851 	headers[SADB_EXT_ADDRESS_DST] = p;
1852 	p += sizeof(struct sadb_address) + PADUP(SA_LEN(&gw->sa));
1853 	sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_DST];
1854 	sadd->sadb_address_len = (sizeof(struct sadb_address) +
1855 	    SA_LEN(&gw->sa) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
1856 	bcopy(gw, headers[SADB_EXT_ADDRESS_DST] + sizeof(struct sadb_address),
1857 	    SA_LEN(&gw->sa));
1858 
1859 	if (ipo->ipo_srcid) {
1860 		headers[SADB_EXT_IDENTITY_SRC] = p;
1861 		export_identity(&p, &ipo->ipo_srcid);
1862 	}
1863 
1864 	if (ipo->ipo_dstid) {
1865 		headers[SADB_EXT_IDENTITY_DST] = p;
1866 		export_identity(&p, &ipo->ipo_dstid);
1867 	}
1868 
1869 	headers[SADB_EXT_PROPOSAL] = p;
1870 	p += sizeof(struct sadb_prop);
1871 	sa_prop = (struct sadb_prop *) headers[SADB_EXT_PROPOSAL];
1872 	sa_prop->sadb_prop_num = 1; /* XXX One proposal only */
1873 	sa_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
1874 	    (sizeof(struct sadb_comb) * sa_prop->sadb_prop_num)) /
1875 	    sizeof(uint64_t);
1876 
1877 	sadb_comb = p;
1878 
1879 	/* XXX Should actually ask the crypto layer what's supported */
1880 	for (j = 0; j < sa_prop->sadb_prop_num; j++) {
1881 		sadb_comb->sadb_comb_flags = 0;
1882 
1883 		if (ipsec_require_pfs)
1884 			sadb_comb->sadb_comb_flags |= SADB_SAFLAGS_PFS;
1885 
1886 		/* Set the encryption algorithm */
1887 		if (ipo->ipo_sproto == IPPROTO_ESP) {
1888 			if (!strncasecmp(ipsec_def_enc, "aes",
1889 			    sizeof("aes"))) {
1890 				sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AES;
1891 				sadb_comb->sadb_comb_encrypt_minbits = 128;
1892 				sadb_comb->sadb_comb_encrypt_maxbits = 256;
1893 			} else if (!strncasecmp(ipsec_def_enc, "aesctr",
1894 			    sizeof("aesctr"))) {
1895 				sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AESCTR;
1896 				sadb_comb->sadb_comb_encrypt_minbits = 128+32;
1897 				sadb_comb->sadb_comb_encrypt_maxbits = 256+32;
1898 			} else if (!strncasecmp(ipsec_def_enc, "3des",
1899 			    sizeof("3des"))) {
1900 				sadb_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC;
1901 				sadb_comb->sadb_comb_encrypt_minbits = 192;
1902 				sadb_comb->sadb_comb_encrypt_maxbits = 192;
1903 			} else if (!strncasecmp(ipsec_def_enc, "des",
1904 			    sizeof("des"))) {
1905 				sadb_comb->sadb_comb_encrypt = SADB_EALG_DESCBC;
1906 				sadb_comb->sadb_comb_encrypt_minbits = 64;
1907 				sadb_comb->sadb_comb_encrypt_maxbits = 64;
1908 			} else if (!strncasecmp(ipsec_def_enc, "blowfish",
1909 			    sizeof("blowfish"))) {
1910 				sadb_comb->sadb_comb_encrypt = SADB_X_EALG_BLF;
1911 				sadb_comb->sadb_comb_encrypt_minbits = 40;
1912 				sadb_comb->sadb_comb_encrypt_maxbits = BLF_MAXKEYLEN * 8;
1913 			} else if (!strncasecmp(ipsec_def_enc, "cast128",
1914 			    sizeof("cast128"))) {
1915 				sadb_comb->sadb_comb_encrypt = SADB_X_EALG_CAST;
1916 				sadb_comb->sadb_comb_encrypt_minbits = 40;
1917 				sadb_comb->sadb_comb_encrypt_maxbits = 128;
1918 			}
1919 		} else if (ipo->ipo_sproto == IPPROTO_IPCOMP) {
1920 			/* Set the compression algorithm */
1921 			if (!strncasecmp(ipsec_def_comp, "deflate",
1922 			    sizeof("deflate"))) {
1923 				sadb_comb->sadb_comb_encrypt = SADB_X_CALG_DEFLATE;
1924 				sadb_comb->sadb_comb_encrypt_minbits = 0;
1925 				sadb_comb->sadb_comb_encrypt_maxbits = 0;
1926 			} else if (!strncasecmp(ipsec_def_comp, "lzs",
1927 			    sizeof("lzs"))) {
1928 				sadb_comb->sadb_comb_encrypt = SADB_X_CALG_LZS;
1929 				sadb_comb->sadb_comb_encrypt_minbits = 0;
1930 				sadb_comb->sadb_comb_encrypt_maxbits = 0;
1931 			}
1932 		}
1933 
1934 		/* Set the authentication algorithm */
1935 		if (!strncasecmp(ipsec_def_auth, "hmac-sha1",
1936 		    sizeof("hmac-sha1"))) {
1937 			sadb_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC;
1938 			sadb_comb->sadb_comb_auth_minbits = 160;
1939 			sadb_comb->sadb_comb_auth_maxbits = 160;
1940 		} else if (!strncasecmp(ipsec_def_auth, "hmac-ripemd160",
1941 		    sizeof("hmac_ripemd160"))) {
1942 			sadb_comb->sadb_comb_auth = SADB_X_AALG_RIPEMD160HMAC;
1943 			sadb_comb->sadb_comb_auth_minbits = 160;
1944 			sadb_comb->sadb_comb_auth_maxbits = 160;
1945 		} else if (!strncasecmp(ipsec_def_auth, "hmac-md5",
1946 		    sizeof("hmac-md5"))) {
1947 			sadb_comb->sadb_comb_auth = SADB_AALG_MD5HMAC;
1948 			sadb_comb->sadb_comb_auth_minbits = 128;
1949 			sadb_comb->sadb_comb_auth_maxbits = 128;
1950 		} else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-256",
1951 		    sizeof("hmac-sha2-256"))) {
1952 			sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256;
1953 			sadb_comb->sadb_comb_auth_minbits = 256;
1954 			sadb_comb->sadb_comb_auth_maxbits = 256;
1955 		} else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-384",
1956 		    sizeof("hmac-sha2-384"))) {
1957 			sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_384;
1958 			sadb_comb->sadb_comb_auth_minbits = 384;
1959 			sadb_comb->sadb_comb_auth_maxbits = 384;
1960 		} else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-512",
1961 		    sizeof("hmac-sha2-512"))) {
1962 			sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_512;
1963 			sadb_comb->sadb_comb_auth_minbits = 512;
1964 			sadb_comb->sadb_comb_auth_maxbits = 512;
1965 		}
1966 
1967 		sadb_comb->sadb_comb_soft_allocations = ipsec_soft_allocations;
1968 		sadb_comb->sadb_comb_hard_allocations = ipsec_exp_allocations;
1969 
1970 		sadb_comb->sadb_comb_soft_bytes = ipsec_soft_bytes;
1971 		sadb_comb->sadb_comb_hard_bytes = ipsec_exp_bytes;
1972 
1973 		sadb_comb->sadb_comb_soft_addtime = ipsec_soft_timeout;
1974 		sadb_comb->sadb_comb_hard_addtime = ipsec_exp_timeout;
1975 
1976 		sadb_comb->sadb_comb_soft_usetime = ipsec_soft_first_use;
1977 		sadb_comb->sadb_comb_hard_usetime = ipsec_exp_first_use;
1978 		sadb_comb++;
1979 	}
1980 
1981 	/* Send the ACQUIRE message to all compliant registered listeners. */
1982 	if ((rval = pfkeyv2_sendmessage(headers,
1983 	    PFKEYV2_SENDMESSAGE_REGISTERED, NULL, smsg->sadb_msg_satype, 0,
1984 	    ipo->ipo_rdomain)) != 0)
1985 		goto ret;
1986 
1987 	rval = 0;
1988 ret:
1989 	if (buffer != NULL) {
1990 		bzero(buffer, i);
1991 		free(buffer, M_PFKEY, 0);
1992 	}
1993 
1994 	return (rval);
1995 }
1996 
1997 /*
1998  * Notify key management that an expiration went off. The second argument
1999  * specifies the type of expiration (soft or hard).
2000  */
2001 int
2002 pfkeyv2_expire(struct tdb *sa, u_int16_t type)
2003 {
2004 	void *p, *headers[SADB_EXT_MAX+1], *buffer = NULL;
2005 	struct sadb_msg *smsg;
2006 	int rval = 0;
2007 	int i;
2008 
2009 	switch (sa->tdb_sproto) {
2010 	case IPPROTO_AH:
2011 	case IPPROTO_ESP:
2012 	case IPPROTO_IPIP:
2013 	case IPPROTO_IPCOMP:
2014 #ifdef TCP_SIGNATURE
2015 	case IPPROTO_TCP:
2016 #endif /* TCP_SIGNATURE */
2017 		break;
2018 
2019 	default:
2020 		rval = EOPNOTSUPP;
2021 		goto ret;
2022 	}
2023 
2024 	i = sizeof(struct sadb_msg) + sizeof(struct sadb_sa) +
2025 	    2 * sizeof(struct sadb_lifetime) +
2026 	    sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_src.sa)) +
2027 	    sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_dst.sa));
2028 
2029 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
2030 		rval = ENOMEM;
2031 		goto ret;
2032 	}
2033 
2034 	bzero(headers, sizeof(headers));
2035 
2036 	buffer = p;
2037 
2038 	headers[0] = p;
2039 	p += sizeof(struct sadb_msg);
2040 
2041 	smsg = (struct sadb_msg *) headers[0];
2042 	smsg->sadb_msg_version = PF_KEY_V2;
2043 	smsg->sadb_msg_type = SADB_EXPIRE;
2044 	smsg->sadb_msg_satype = sa->tdb_satype;
2045 	smsg->sadb_msg_len = i / sizeof(uint64_t);
2046 	smsg->sadb_msg_seq = pfkeyv2_seq++;
2047 
2048 	headers[SADB_EXT_SA] = p;
2049 	export_sa(&p, sa);
2050 
2051 	headers[SADB_EXT_LIFETIME_CURRENT] = p;
2052 	export_lifetime(&p, sa, 2);
2053 
2054 	headers[type] = p;
2055 	export_lifetime(&p, sa, type == SADB_EXT_LIFETIME_SOFT ?
2056 	    PFKEYV2_LIFETIME_SOFT : PFKEYV2_LIFETIME_HARD);
2057 
2058 	headers[SADB_EXT_ADDRESS_SRC] = p;
2059 	export_address(&p, (struct sockaddr *) &sa->tdb_src);
2060 
2061 	headers[SADB_EXT_ADDRESS_DST] = p;
2062 	export_address(&p, (struct sockaddr *) &sa->tdb_dst);
2063 
2064 	if ((rval = pfkeyv2_sendmessage(headers, PFKEYV2_SENDMESSAGE_BROADCAST,
2065 	    NULL, 0, 0, sa->tdb_rdomain)) != 0)
2066 		goto ret;
2067 
2068 	rval = 0;
2069 
2070  ret:
2071 	if (buffer != NULL) {
2072 		bzero(buffer, i);
2073 		free(buffer, M_PFKEY, 0);
2074 	}
2075 
2076 	return (rval);
2077 }
2078 
2079 struct pfkeyv2_sysctl_walk {
2080 	void		*w_where;
2081 	size_t		 w_len;
2082 	int		 w_op;
2083 	u_int8_t	 w_satype;
2084 };
2085 
2086 int
2087 pfkeyv2_sysctl_walker(struct tdb *sa, void *arg, int last)
2088 {
2089 	struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
2090 	void *buffer = NULL;
2091 	int error = 0;
2092 	int buflen, i;
2093 
2094 	if (w->w_satype != SADB_SATYPE_UNSPEC &&
2095 	    w->w_satype != sa->tdb_satype)
2096 		return (0);
2097 
2098 	if (w->w_where) {
2099 		void *headers[SADB_EXT_MAX+1];
2100 		struct sadb_msg msg;
2101 
2102 		bzero(headers, sizeof(headers));
2103 		if ((error = pfkeyv2_get(sa, headers, &buffer, &buflen)) != 0)
2104 			goto done;
2105 		if (w->w_len < sizeof(msg) + buflen) {
2106 			error = ENOMEM;
2107 			goto done;
2108 		}
2109 		/* prepend header */
2110 		bzero(&msg, sizeof(msg));
2111 		msg.sadb_msg_version = PF_KEY_V2;
2112 		msg.sadb_msg_satype = sa->tdb_satype;
2113 		msg.sadb_msg_type = SADB_DUMP;
2114 		msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t);
2115 		if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0)
2116 			goto done;
2117 		w->w_where += sizeof(msg);
2118 		w->w_len -= sizeof(msg);
2119 		/* set extension type */
2120 		for (i = 1; i <= SADB_EXT_MAX; i++)
2121 			if (headers[i])
2122 				((struct sadb_ext *)
2123 				    headers[i])->sadb_ext_type = i;
2124 		if ((error = copyout(buffer, w->w_where, buflen)) != 0)
2125 			goto done;
2126 		w->w_where += buflen;
2127 		w->w_len -= buflen;
2128 	} else {
2129 		if ((error = pfkeyv2_get(sa, NULL, NULL, &buflen)) != 0)
2130 			return (error);
2131 		w->w_len += buflen;
2132 		w->w_len += sizeof(struct sadb_msg);
2133 	}
2134 
2135 done:
2136 	if (buffer)
2137 		free(buffer, M_PFKEY, 0);
2138 	return (error);
2139 }
2140 
2141 int
2142 pfkeyv2_dump_policy(struct ipsec_policy *ipo, void **headers, void **buffer,
2143     int *lenp)
2144 {
2145 	int i, rval, perm;
2146 	void *p;
2147 
2148 	/* Find how much space we need. */
2149 	i = 2 * sizeof(struct sadb_protocol);
2150 
2151 	/* We'll need four of them: src, src mask, dst, dst mask. */
2152 	switch (ipo->ipo_addr.sen_type) {
2153 	case SENT_IP4:
2154 		i += 4 * PADUP(sizeof(struct sockaddr_in));
2155 		i += 4 * sizeof(struct sadb_address);
2156 		break;
2157 #ifdef INET6
2158 	case SENT_IP6:
2159 		i += 4 * PADUP(sizeof(struct sockaddr_in6));
2160 		i += 4 * sizeof(struct sadb_address);
2161 		break;
2162 #endif /* INET6 */
2163 	default:
2164 		return (EINVAL);
2165 	}
2166 
2167 	/* Local address, might be zeroed. */
2168 	switch (ipo->ipo_src.sa.sa_family) {
2169 	case 0:
2170 		break;
2171 	case AF_INET:
2172 		i += PADUP(sizeof(struct sockaddr_in));
2173 		i += sizeof(struct sadb_address);
2174 		break;
2175 #ifdef INET6
2176 	case AF_INET6:
2177 		i += PADUP(sizeof(struct sockaddr_in6));
2178 		i += sizeof(struct sadb_address);
2179 		break;
2180 #endif /* INET6 */
2181 	default:
2182 		return (EINVAL);
2183 	}
2184 
2185 	/* Remote address, might be zeroed. XXX ??? */
2186 	switch (ipo->ipo_dst.sa.sa_family) {
2187 	case 0:
2188 		break;
2189 	case AF_INET:
2190 		i += PADUP(sizeof(struct sockaddr_in));
2191 		i += sizeof(struct sadb_address);
2192 		break;
2193 #ifdef INET6
2194 	case AF_INET6:
2195 		i += PADUP(sizeof(struct sockaddr_in6));
2196 		i += sizeof(struct sadb_address);
2197 		break;
2198 #endif /* INET6 */
2199 	default:
2200 		return (EINVAL);
2201 	}
2202 
2203 	if (ipo->ipo_srcid)
2204 		i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
2205 	if (ipo->ipo_dstid)
2206 		i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
2207 
2208 	if (lenp)
2209 		*lenp = i;
2210 
2211 	if (buffer == NULL) {
2212 		rval = 0;
2213 		goto ret;
2214 	}
2215 
2216 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
2217 		rval = ENOMEM;
2218 		goto ret;
2219 	} else
2220 		*buffer = p;
2221 
2222 	/* Local address. */
2223 	if (ipo->ipo_src.sa.sa_family) {
2224 		headers[SADB_EXT_ADDRESS_SRC] = p;
2225 		export_address(&p, (struct sockaddr *)&ipo->ipo_src);
2226 	}
2227 
2228 	/* Remote address. */
2229 	if (ipo->ipo_dst.sa.sa_family) {
2230 		headers[SADB_EXT_ADDRESS_DST] = p;
2231 		export_address(&p, (struct sockaddr *)&ipo->ipo_dst);
2232 	}
2233 
2234 	/* Get actual flow. */
2235 	export_flow(&p, ipo->ipo_type, &ipo->ipo_addr, &ipo->ipo_mask,
2236 	    headers);
2237 
2238 	/* Add ids only when we are root. */
2239 	perm = suser(curproc, 0);
2240 	if (perm == 0 && ipo->ipo_srcid) {
2241 		headers[SADB_EXT_IDENTITY_SRC] = p;
2242 		export_identity(&p, &ipo->ipo_srcid);
2243 	}
2244 	if (perm == 0 && ipo->ipo_dstid) {
2245 		headers[SADB_EXT_IDENTITY_DST] = p;
2246 		export_identity(&p, &ipo->ipo_dstid);
2247 	}
2248 
2249 	rval = 0;
2250 ret:
2251 	return (rval);
2252 }
2253 
2254 /*
2255  * Caller is responsible for setting at least splsoftnet().
2256  */
2257 int
2258 pfkeyv2_ipo_walk(u_int rdomain, int (*walker)(struct ipsec_policy *, void *),
2259     void *arg)
2260 {
2261 	int rval = 0;
2262 	struct ipsec_policy *ipo;
2263 
2264 	TAILQ_FOREACH(ipo, &ipsec_policy_head, ipo_list) {
2265 		if (ipo->ipo_rdomain != rdomain)
2266 			continue;
2267 		rval = walker(ipo, (void *)arg);
2268 	}
2269 	return (rval);
2270 }
2271 
2272 int
2273 pfkeyv2_sysctl_policydumper(struct ipsec_policy *ipo, void *arg)
2274 {
2275 	struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
2276 	void *buffer = 0;
2277 	int i, buflen, error = 0;
2278 
2279 	if (w->w_where) {
2280 		void *headers[SADB_EXT_MAX + 1];
2281 		struct sadb_msg msg;
2282 
2283 		bzero(headers, sizeof(headers));
2284 		if ((error = pfkeyv2_dump_policy(ipo, headers, &buffer,
2285 		    &buflen)) != 0)
2286 			goto done;
2287 		if (w->w_len < buflen) {
2288 			error = ENOMEM;
2289 			goto done;
2290 		}
2291 		/* prepend header */
2292 		bzero(&msg, sizeof(msg));
2293 		msg.sadb_msg_version = PF_KEY_V2;
2294 		if (ipo->ipo_sproto == IPPROTO_ESP)
2295 			msg.sadb_msg_satype = SADB_SATYPE_ESP;
2296 		else if (ipo->ipo_sproto == IPPROTO_AH)
2297 			msg.sadb_msg_satype = SADB_SATYPE_AH;
2298 		else if (ipo->ipo_sproto == IPPROTO_IPCOMP)
2299 			msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
2300 		else if (ipo->ipo_sproto == IPPROTO_IPIP)
2301 			msg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
2302 		msg.sadb_msg_type = SADB_X_SPDDUMP;
2303 		msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t);
2304 		if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0)
2305 			goto done;
2306 		w->w_where += sizeof(msg);
2307 		w->w_len -= sizeof(msg);
2308 		/* set extension type */
2309 		for (i = 1; i < SADB_EXT_MAX; i++)
2310 			if (headers[i])
2311 				((struct sadb_ext *)
2312 				    headers[i])->sadb_ext_type = i;
2313 		if ((error = copyout(buffer, w->w_where, buflen)) != 0)
2314 			goto done;
2315 		w->w_where += buflen;
2316 		w->w_len -= buflen;
2317 	} else {
2318 		if ((error = pfkeyv2_dump_policy(ipo, NULL, NULL,
2319 		    &buflen)) != 0)
2320 			goto done;
2321 		w->w_len += buflen;
2322 		w->w_len += sizeof(struct sadb_msg);
2323 	}
2324 
2325 done:
2326 	if (buffer)
2327 		free(buffer, M_PFKEY, 0);
2328 	return (error);
2329 }
2330 
2331 int
2332 pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2333     void *new, size_t newlen)
2334 {
2335 	struct pfkeyv2_sysctl_walk w;
2336 	int s, error = EINVAL;
2337 	u_int rdomain;
2338 
2339 	if (new)
2340 		return (EPERM);
2341 	if (namelen < 1)
2342 		return (EINVAL);
2343 	w.w_op = name[0];
2344 	w.w_satype = name[1];
2345 	w.w_where = oldp;
2346 	w.w_len = oldp ? *oldlenp : 0;
2347 
2348 	rdomain = rtable_l2(curproc->p_p->ps_rtableid);
2349 
2350 	switch(w.w_op) {
2351 	case NET_KEY_SADB_DUMP:
2352 		if ((error = suser(curproc, 0)) != 0)
2353 			return (error);
2354 		s = splsoftnet();
2355 		error = tdb_walk(rdomain, pfkeyv2_sysctl_walker, &w);
2356 		splx(s);
2357 		if (oldp)
2358 			*oldlenp = w.w_where - oldp;
2359 		else
2360 			*oldlenp = w.w_len;
2361 		break;
2362 
2363 	case NET_KEY_SPD_DUMP:
2364 		s = splsoftnet();
2365 		error = pfkeyv2_ipo_walk(rdomain,
2366 		    pfkeyv2_sysctl_policydumper, &w);
2367 		splx(s);
2368 		if (oldp)
2369 			*oldlenp = w.w_where - oldp;
2370 		else
2371 			*oldlenp = w.w_len;
2372 		break;
2373 	}
2374 
2375 	return (error);
2376 }
2377 
2378 int
2379 pfkeyv2_init(void)
2380 {
2381 	int rval;
2382 
2383 	bzero(&pfkeyv2_version, sizeof(struct pfkey_version));
2384 	pfkeyv2_version.protocol = PFKEYV2_PROTOCOL;
2385 	pfkeyv2_version.create = &pfkeyv2_create;
2386 	pfkeyv2_version.release = &pfkeyv2_release;
2387 	pfkeyv2_version.send = &pfkeyv2_send;
2388 	pfkeyv2_version.sysctl = &pfkeyv2_sysctl;
2389 
2390 	rval = pfkey_register(&pfkeyv2_version);
2391 	return (rval);
2392 }
2393 
2394 int
2395 pfkeyv2_cleanup(void)
2396 {
2397 	pfkey_unregister(&pfkeyv2_version);
2398 	return (0);
2399 }
2400