xref: /openbsd-src/sys/net/pfkeyv2.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /* $OpenBSD: pfkeyv2.c,v 1.133 2014/07/12 18:44:22 tedu 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, NULL)))
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 #ifdef INET
373 	case SENT_IP4:
374 		i += 4 * PADUP(sizeof(struct sockaddr_in));
375 		sunion.sa.sa_family = AF_INET;
376 		sunion.sa.sa_len = sizeof(struct sockaddr_in);
377 		dir = ipa->ipa_info.sen_direction;
378 		break;
379 #endif /* INET */
380 
381 #ifdef INET6
382 	case SENT_IP6:
383 		i += 4 * PADUP(sizeof(struct sockaddr_in6));
384 		sunion.sa.sa_family = AF_INET6;
385 		sunion.sa.sa_len = sizeof(struct sockaddr_in6);
386 		dir = ipa->ipa_info.sen_ip6_direction;
387 		break;
388 #endif /* INET6 */
389 
390 	default:
391 		return (EINVAL);
392 	}
393 
394 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
395 		rval = ENOMEM;
396 		goto ret;
397 	} else
398 		*buffer = p;
399 
400 	if (dir == IPSP_DIRECTION_OUT)
401 		headers[SADB_X_EXT_SRC_FLOW] = p;
402 	else
403 		headers[SADB_X_EXT_DST_FLOW] = p;
404 	switch (sunion.sa.sa_family) {
405 #ifdef INET
406 	case AF_INET:
407 		sunion.sin.sin_addr = ipa->ipa_info.sen_ip_src;
408 		sunion.sin.sin_port = ipa->ipa_info.sen_sport;
409 		break;
410 #endif /* INET */
411 
412 #ifdef INET6
413 	case AF_INET6:
414 		sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_src;
415 		sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_sport;
416 		break;
417 #endif /* INET6 */
418 	}
419 	export_address(&p, (struct sockaddr *) &sunion);
420 
421 	if (dir == IPSP_DIRECTION_OUT)
422 		headers[SADB_X_EXT_SRC_MASK] = p;
423 	else
424 		headers[SADB_X_EXT_DST_MASK] = p;
425 	switch (sunion.sa.sa_family) {
426 #ifdef INET
427 	case AF_INET:
428 		sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_src;
429 		sunion.sin.sin_port = ipa->ipa_mask.sen_sport;
430 		break;
431 #endif /* INET */
432 
433 #ifdef INET6
434 	case AF_INET6:
435 		sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_src;
436 		sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_sport;
437 		break;
438 #endif /* INET6 */
439 	}
440 	export_address(&p, (struct sockaddr *) &sunion);
441 
442 	if (dir == IPSP_DIRECTION_OUT)
443 		headers[SADB_X_EXT_DST_FLOW] = p;
444 	else
445 		headers[SADB_X_EXT_SRC_FLOW] = p;
446 	switch (sunion.sa.sa_family) {
447 #ifdef INET
448 	case AF_INET:
449 		sunion.sin.sin_addr = ipa->ipa_info.sen_ip_dst;
450 		sunion.sin.sin_port = ipa->ipa_info.sen_dport;
451 		break;
452 #endif /* INET */
453 
454 #ifdef INET6
455 	case AF_INET6:
456 		sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_dst;
457 		sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_dport;
458 		break;
459 #endif /* INET6 */
460 	}
461 	export_address(&p, (struct sockaddr *) &sunion);
462 
463 	if (dir == IPSP_DIRECTION_OUT)
464 		headers[SADB_X_EXT_DST_MASK] = p;
465 	else
466 		headers[SADB_X_EXT_SRC_MASK] = p;
467 	switch (sunion.sa.sa_family) {
468 #ifdef INET
469 	case AF_INET:
470 		sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_dst;
471 		sunion.sin.sin_port = ipa->ipa_mask.sen_dport;
472 		break;
473 #endif /* INET */
474 
475 #ifdef INET6
476 	case AF_INET6:
477 		sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_dst;
478 		sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_dport;
479 		break;
480 #endif /* INET6 */
481 	}
482 	export_address(&p, (struct sockaddr *) &sunion);
483 
484 	headers[SADB_X_EXT_FLOW_TYPE] = p;
485 	sp = p;
486 	sp->sadb_protocol_len = sizeof(struct sadb_protocol) /
487 	    sizeof(u_int64_t);
488 	switch (sunion.sa.sa_family) {
489 #ifdef INET
490 	case AF_INET:
491 		if (ipa->ipa_mask.sen_proto)
492 			sp->sadb_protocol_proto = ipa->ipa_info.sen_proto;
493 		sp->sadb_protocol_direction = ipa->ipa_info.sen_direction;
494 		break;
495 #endif /* INET */
496 
497 #ifdef INET6
498 	case AF_INET6:
499 		if (ipa->ipa_mask.sen_ip6_proto)
500 			sp->sadb_protocol_proto = ipa->ipa_info.sen_ip6_proto;
501 		sp->sadb_protocol_direction = ipa->ipa_info.sen_ip6_direction;
502 		break;
503 #endif /* INET6 */
504 	}
505 
506 	rval = 0;
507 
508 ret:
509 	return (rval);
510 }
511 
512 /*
513  * Get all the information contained in an SA to a PFKEYV2 message.
514  */
515 int
516 pfkeyv2_get(struct tdb *sa, void **headers, void **buffer, int *lenp)
517 {
518 	int rval, i;
519 	void *p;
520 
521 	/* Find how much space we need */
522 	i = sizeof(struct sadb_sa) + sizeof(struct sadb_lifetime);
523 
524 	if (sa->tdb_soft_allocations || sa->tdb_soft_bytes ||
525 	    sa->tdb_soft_timeout || sa->tdb_soft_first_use)
526 		i += sizeof(struct sadb_lifetime);
527 
528 	if (sa->tdb_exp_allocations || sa->tdb_exp_bytes ||
529 	    sa->tdb_exp_timeout || sa->tdb_exp_first_use)
530 		i += sizeof(struct sadb_lifetime);
531 
532 	if (sa->tdb_last_used)
533 		i += sizeof(struct sadb_lifetime);
534 
535 	i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_src.sa));
536 	i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_dst.sa));
537 
538 	if (sa->tdb_proxy.sa.sa_family)
539 		i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_proxy.sa));
540 
541 	if (sa->tdb_srcid)
542 		i += sizeof(struct sadb_ident) + PADUP(sa->tdb_srcid->ref_len);
543 
544 	if (sa->tdb_dstid)
545 		i += sizeof(struct sadb_ident) + PADUP(sa->tdb_dstid->ref_len);
546 
547 	if (sa->tdb_local_cred)
548 		i += sizeof(struct sadb_x_cred) + PADUP(sa->tdb_local_cred->ref_len);
549 
550 	if (sa->tdb_remote_cred)
551 		i += sizeof(struct sadb_x_cred) + PADUP(sa->tdb_remote_cred->ref_len);
552 
553 	if (sa->tdb_local_auth)
554 		i += sizeof(struct sadb_x_cred) + PADUP(sa->tdb_local_auth->ref_len);
555 
556 	if (sa->tdb_remote_auth)
557 		i += sizeof(struct sadb_x_cred) + PADUP(sa->tdb_remote_auth->ref_len);
558 
559 	if (sa->tdb_amxkey)
560 		i += sizeof(struct sadb_key) + PADUP(sa->tdb_amxkeylen);
561 
562 	if (sa->tdb_emxkey)
563 		i += sizeof(struct sadb_key) + PADUP(sa->tdb_emxkeylen);
564 
565 	if (sa->tdb_filter.sen_type) {
566 		i += 2 * sizeof(struct sadb_protocol);
567 
568 		/* We'll need four of them: src, src mask, dst, dst mask. */
569 		switch (sa->tdb_filter.sen_type) {
570 #ifdef INET
571 		case SENT_IP4:
572 			i += 4 * PADUP(sizeof(struct sockaddr_in));
573 			i += 4 * sizeof(struct sadb_address);
574 			break;
575 #endif /* INET */
576 #ifdef INET6
577 		case SENT_IP6:
578 			i += 4 * PADUP(sizeof(struct sockaddr_in6));
579 			i += 4 * sizeof(struct sadb_address);
580 			break;
581 #endif /* INET6 */
582 		default:
583 			rval = EINVAL;
584 			goto ret;
585 		}
586 	}
587 
588 	if (sa->tdb_udpencap_port)
589 		i += sizeof(struct sadb_x_udpencap);
590 
591 #if NPF > 0
592 	if (sa->tdb_tag)
593 		i += sizeof(struct sadb_x_tag) + PADUP(PF_TAG_NAME_SIZE);
594 	if (sa->tdb_tap)
595 		i += sizeof(struct sadb_x_tap);
596 #endif
597 
598 	if (lenp)
599 		*lenp = i;
600 
601 	if (buffer == NULL) {
602 		rval = 0;
603 		goto ret;
604 	}
605 
606 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
607 		rval = ENOMEM;
608 		goto ret;
609 	} else
610 		*buffer = p;
611 
612 	headers[SADB_EXT_SA] = p;
613 
614 	export_sa(&p, sa);  /* Export SA information (mostly flags) */
615 
616 	/* Export lifetimes where applicable */
617 	headers[SADB_EXT_LIFETIME_CURRENT] = p;
618 	export_lifetime(&p, sa, PFKEYV2_LIFETIME_CURRENT);
619 
620 	if (sa->tdb_soft_allocations || sa->tdb_soft_bytes ||
621 	    sa->tdb_soft_first_use || sa->tdb_soft_timeout) {
622 		headers[SADB_EXT_LIFETIME_SOFT] = p;
623 		export_lifetime(&p, sa, PFKEYV2_LIFETIME_SOFT);
624 	}
625 
626 	if (sa->tdb_exp_allocations || sa->tdb_exp_bytes ||
627 	    sa->tdb_exp_first_use || sa->tdb_exp_timeout) {
628 		headers[SADB_EXT_LIFETIME_HARD] = p;
629 		export_lifetime(&p, sa, PFKEYV2_LIFETIME_HARD);
630 	}
631 
632 	if (sa->tdb_last_used) {
633 		headers[SADB_X_EXT_LIFETIME_LASTUSE] = p;
634 		export_lifetime(&p, sa, PFKEYV2_LIFETIME_LASTUSE);
635 	}
636 
637 	/* Export TDB source address */
638 	headers[SADB_EXT_ADDRESS_SRC] = p;
639 	export_address(&p, (struct sockaddr *) &sa->tdb_src);
640 
641 	/* Export TDB destination address */
642 	headers[SADB_EXT_ADDRESS_DST] = p;
643 	export_address(&p, (struct sockaddr *) &sa->tdb_dst);
644 
645 	/* Export TDB proxy address, if present */
646 	if (SA_LEN(&sa->tdb_proxy.sa)) {
647 		headers[SADB_EXT_ADDRESS_PROXY] = p;
648 		export_address(&p, (struct sockaddr *) &sa->tdb_proxy);
649 	}
650 
651 	/* Export source identity, if present */
652 	if (sa->tdb_srcid) {
653 		headers[SADB_EXT_IDENTITY_SRC] = p;
654 		export_identity(&p, sa, PFKEYV2_IDENTITY_SRC);
655 	}
656 
657 	/* Export destination identity, if present */
658 	if (sa->tdb_dstid) {
659 		headers[SADB_EXT_IDENTITY_DST] = p;
660 		export_identity(&p, sa, PFKEYV2_IDENTITY_DST);
661 	}
662 
663 	/* Export credentials, if present */
664 	if (sa->tdb_local_cred) {
665 		headers[SADB_X_EXT_LOCAL_CREDENTIALS] = p;
666 		export_credentials(&p, sa, PFKEYV2_CRED_LOCAL);
667 	}
668 
669 	if (sa->tdb_remote_cred) {
670 		headers[SADB_X_EXT_REMOTE_CREDENTIALS] = p;
671 		export_credentials(&p, sa, PFKEYV2_CRED_REMOTE);
672 	}
673 
674 	/* Export authentication information, if present */
675 	if (sa->tdb_local_auth) {
676 		headers[SADB_X_EXT_LOCAL_AUTH] = p;
677 		export_auth(&p, sa, PFKEYV2_AUTH_LOCAL);
678 	}
679 
680 	if (sa->tdb_remote_auth) {
681 		headers[SADB_X_EXT_REMOTE_AUTH] = p;
682 		export_auth(&p, sa, PFKEYV2_AUTH_REMOTE);
683 	}
684 
685 	/* Export authentication key, if present */
686 	if (sa->tdb_amxkey) {
687 		headers[SADB_EXT_KEY_AUTH] = p;
688 		export_key(&p, sa, PFKEYV2_AUTHENTICATION_KEY);
689 	}
690 
691 	/* Export encryption key, if present */
692 	if (sa->tdb_emxkey) {
693 		headers[SADB_EXT_KEY_ENCRYPT] = p;
694 		export_key(&p, sa, PFKEYV2_ENCRYPTION_KEY);
695 	}
696 
697 	/* Export flow/filter, if present */
698 	if (sa->tdb_filter.sen_type)
699 		export_flow(&p, IPSP_IPSEC_USE, &sa->tdb_filter,
700 		    &sa->tdb_filtermask, headers);
701 
702 	/* Export UDP encapsulation port, if present */
703 	if (sa->tdb_udpencap_port) {
704 		headers[SADB_X_EXT_UDPENCAP] = p;
705 		export_udpencap(&p, sa);
706 	}
707 
708 #if NPF > 0
709 	/* Export tag information, if present */
710 	if (sa->tdb_tag) {
711 		headers[SADB_X_EXT_TAG] = p;
712 		export_tag(&p, sa);
713 	}
714 
715 	/* Export tap enc(4) device information, if present */
716 	if (sa->tdb_tap) {
717 		headers[SADB_X_EXT_TAP] = p;
718 		export_tap(&p, sa);
719 	}
720 #endif
721 
722 	rval = 0;
723 
724  ret:
725 	return (rval);
726 }
727 
728 /*
729  * Dump a TDB.
730  */
731 int
732 pfkeyv2_dump_walker(struct tdb *sa, void *state, int last)
733 {
734 	struct dump_state *dump_state = (struct dump_state *) state;
735 	void *headers[SADB_EXT_MAX+1], *buffer;
736 	int rval;
737 
738 	/* If not satype was specified, dump all TDBs */
739 	if (!dump_state->sadb_msg->sadb_msg_satype ||
740 	    (sa->tdb_satype == dump_state->sadb_msg->sadb_msg_satype)) {
741 		bzero(headers, sizeof(headers));
742 		headers[0] = (void *) dump_state->sadb_msg;
743 
744 		/* Get the information from the TDB to a PFKEYv2 message */
745 		if ((rval = pfkeyv2_get(sa, headers, &buffer, NULL)) != 0)
746 			return (rval);
747 
748 		if (last)
749 			((struct sadb_msg *)headers[0])->sadb_msg_seq = 0;
750 
751 		/* Send the message to the specified socket */
752 		rval = pfkeyv2_sendmessage(headers,
753 		    PFKEYV2_SENDMESSAGE_UNICAST, dump_state->socket, 0, 0,
754 		    sa->tdb_rdomain);
755 
756 		free(buffer, M_PFKEY, 0);
757 		if (rval)
758 			return (rval);
759 	}
760 
761 	return (0);
762 }
763 
764 /*
765  * Delete an SA.
766  */
767 int
768 pfkeyv2_flush_walker(struct tdb *sa, void *satype_vp, int last)
769 {
770 	if (!(*((u_int8_t *) satype_vp)) ||
771 	    sa->tdb_satype == *((u_int8_t *) satype_vp))
772 		tdb_delete(sa);
773 	return (0);
774 }
775 
776 /*
777  * Convert between SATYPEs and IPsec protocols, taking into consideration
778  * sysctl variables enabling/disabling ESP/AH and the presence of the old
779  * IPsec transforms.
780  */
781 int
782 pfkeyv2_get_proto_alg(u_int8_t satype, u_int8_t *sproto, int *alg)
783 {
784 	switch (satype) {
785 #ifdef IPSEC
786 	case SADB_SATYPE_AH:
787 		if (!ah_enable)
788 			return (EOPNOTSUPP);
789 
790 		*sproto = IPPROTO_AH;
791 
792 		if(alg != NULL)
793 			*alg = satype = XF_AH;
794 
795 		break;
796 
797 	case SADB_SATYPE_ESP:
798 		if (!esp_enable)
799 			return (EOPNOTSUPP);
800 
801 		*sproto = IPPROTO_ESP;
802 
803 		if(alg != NULL)
804 			*alg = satype = XF_ESP;
805 
806 		break;
807 
808 	case SADB_X_SATYPE_IPIP:
809 		*sproto = IPPROTO_IPIP;
810 
811 		if (alg != NULL)
812 			*alg = XF_IP4;
813 
814 		break;
815 
816 	case SADB_X_SATYPE_IPCOMP:
817 		if (!ipcomp_enable)
818 			return (EOPNOTSUPP);
819 
820 		*sproto = IPPROTO_IPCOMP;
821 
822 		if(alg != NULL)
823 			*alg = satype = XF_IPCOMP;
824 
825 		break;
826 #endif /* IPSEC */
827 #ifdef TCP_SIGNATURE
828 	case SADB_X_SATYPE_TCPSIGNATURE:
829 		*sproto = IPPROTO_TCP;
830 
831 		if (alg != NULL)
832 			*alg = XF_TCPSIGNATURE;
833 
834 		break;
835 #endif /* TCP_SIGNATURE */
836 
837 	default: /* Nothing else supported */
838 		return (EOPNOTSUPP);
839 	}
840 
841 	return (0);
842 }
843 
844 /*
845  * Handle all messages from userland to kernel.
846  */
847 int
848 pfkeyv2_send(struct socket *socket, void *message, int len)
849 {
850 	int i, j, rval = 0, mode = PFKEYV2_SENDMESSAGE_BROADCAST;
851 	int delflag = 0, s;
852 	struct sockaddr_encap encapdst, encapnetmask, encapgw;
853 	struct ipsec_policy *ipo, *tmpipo;
854 	struct ipsec_acquire *ipa;
855 
856 	struct pfkeyv2_socket *pfkeyv2_socket, *so = NULL;
857 
858 	void *freeme = NULL, *bckptr = NULL;
859 	void *headers[SADB_EXT_MAX + 1];
860 
861 	union sockaddr_union *sunionp;
862 
863 	struct tdb *sa1 = NULL, *sa2 = NULL;
864 
865 	struct sadb_msg *smsg;
866 	struct sadb_spirange *sprng;
867 	struct sadb_sa *ssa;
868 	struct sadb_supported *ssup;
869 	struct sadb_ident *sid;
870 
871 	u_int rdomain;
872 
873 	/* Verify that we received this over a legitimate pfkeyv2 socket */
874 	bzero(headers, sizeof(headers));
875 
876 	for (pfkeyv2_socket = pfkeyv2_sockets; pfkeyv2_socket;
877 	    pfkeyv2_socket = pfkeyv2_socket->next)
878 		if (pfkeyv2_socket->socket == socket)
879 			break;
880 
881 	if (!pfkeyv2_socket) {
882 		rval = EINVAL;
883 		goto ret;
884 	}
885 
886 	rdomain = pfkeyv2_socket->rdomain;
887 
888 	/* If we have any promiscuous listeners, send them a copy of the message */
889 	if (npromisc) {
890 		struct mbuf *packet;
891 
892 		if (!(freeme = malloc(sizeof(struct sadb_msg) + len, M_PFKEY,
893 		    M_NOWAIT))) {
894 			rval = ENOMEM;
895 			goto ret;
896 		}
897 
898 		/* Initialize encapsulating header */
899 		bzero(freeme, sizeof(struct sadb_msg));
900 		smsg = (struct sadb_msg *) freeme;
901 		smsg->sadb_msg_version = PF_KEY_V2;
902 		smsg->sadb_msg_type = SADB_X_PROMISC;
903 		smsg->sadb_msg_len = (sizeof(struct sadb_msg) + len) /
904 		    sizeof(uint64_t);
905 		smsg->sadb_msg_seq = curproc->p_p->ps_pid;
906 
907 		bcopy(message, freeme + sizeof(struct sadb_msg), len);
908 
909 		/* Convert to mbuf chain */
910 		if ((rval = pfdatatopacket(freeme,
911 		    sizeof(struct sadb_msg) + len, &packet)) != 0)
912 			goto ret;
913 
914 		/* Send to all promiscuous listeners */
915 		for (so = pfkeyv2_sockets; so; so = so->next) {
916 			if ((so->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
917 			    (so->rdomain == rdomain))
918 				pfkey_sendup(so->socket, packet, 1);
919 		}
920 
921 		m_freem(packet);
922 
923 		/* Paranoid */
924 		explicit_bzero(freeme, sizeof(struct sadb_msg) + len);
925 		free(freeme, M_PFKEY, 0);
926 		freeme = NULL;
927 	}
928 
929 	/* Validate message format */
930 	if ((rval = pfkeyv2_parsemessage(message, len, headers)) != 0)
931 		goto ret;
932 
933 	smsg = (struct sadb_msg *) headers[0];
934 	switch (smsg->sadb_msg_type) {
935 	case SADB_GETSPI:  /* Reserve an SPI */
936 		sa1 = malloc(sizeof (*sa1), M_PFKEY, M_NOWAIT | M_ZERO);
937 		if (sa1 == NULL) {
938 			rval = ENOMEM;
939 			goto ret;
940 		}
941 
942 		sa1->tdb_satype = smsg->sadb_msg_satype;
943 		if ((rval = pfkeyv2_get_proto_alg(sa1->tdb_satype,
944 		    &sa1->tdb_sproto, 0)))
945 			goto ret;
946 
947 		import_address((struct sockaddr *) &sa1->tdb_src,
948 		    headers[SADB_EXT_ADDRESS_SRC]);
949 		import_address((struct sockaddr *) &sa1->tdb_dst,
950 		    headers[SADB_EXT_ADDRESS_DST]);
951 
952 		/* Find an unused SA identifier */
953 		sprng = (struct sadb_spirange *) headers[SADB_EXT_SPIRANGE];
954 		sa1->tdb_spi = reserve_spi(rdomain,
955 		    sprng->sadb_spirange_min, sprng->sadb_spirange_max,
956 		    &sa1->tdb_src, &sa1->tdb_dst, sa1->tdb_sproto, &rval);
957 		if (sa1->tdb_spi == 0)
958 			goto ret;
959 
960 		/* Send a message back telling what the SA (the SPI really) is */
961 		if (!(freeme = malloc(sizeof(struct sadb_sa), M_PFKEY,
962 		    M_NOWAIT | M_ZERO))) {
963 			rval = ENOMEM;
964 			goto ret;
965 		}
966 
967 		headers[SADB_EXT_SPIRANGE] = NULL;
968 		headers[SADB_EXT_SA] = freeme;
969 		bckptr = freeme;
970 
971 		/* We really only care about the SPI, but we'll export the SA */
972 		export_sa((void **) &bckptr, sa1);
973 		break;
974 
975 	case SADB_UPDATE:
976 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
977 		sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
978 		    sizeof(struct sadb_address));
979 
980 		/* Either all or none of the flow must be included */
981 		if ((headers[SADB_X_EXT_SRC_FLOW] ||
982 		    headers[SADB_X_EXT_PROTOCOL] ||
983 		    headers[SADB_X_EXT_FLOW_TYPE] ||
984 		    headers[SADB_X_EXT_DST_FLOW] ||
985 		    headers[SADB_X_EXT_SRC_MASK] ||
986 		    headers[SADB_X_EXT_DST_MASK]) &&
987 		    !(headers[SADB_X_EXT_SRC_FLOW] &&
988 		    headers[SADB_X_EXT_PROTOCOL] &&
989 		    headers[SADB_X_EXT_FLOW_TYPE] &&
990 		    headers[SADB_X_EXT_DST_FLOW] &&
991 		    headers[SADB_X_EXT_SRC_MASK] &&
992 		    headers[SADB_X_EXT_DST_MASK])) {
993 			rval = EINVAL;
994 			goto ret;
995 		}
996 #ifdef IPSEC
997 		/* UDP encap has to be enabled and is only supported for ESP */
998 		if (headers[SADB_X_EXT_UDPENCAP] &&
999 		    (!udpencap_enable ||
1000 		    smsg->sadb_msg_satype != SADB_SATYPE_ESP)) {
1001 			rval = EINVAL;
1002 			goto ret;
1003 		}
1004 #endif /* IPSEC */
1005 
1006 		s = splsoftnet();
1007 
1008 		/* Find TDB */
1009 		sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1010 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
1011 
1012 		/* If there's no such SA, we're done */
1013 		if (sa2 == NULL) {
1014 			rval = ESRCH;
1015 			goto splxret;
1016 		}
1017 
1018 		/* If this is a reserved SA */
1019 		if (sa2->tdb_flags & TDBF_INVALID) {
1020 			struct tdb *newsa;
1021 			struct ipsecinit ii;
1022 			int alg;
1023 
1024 			/* Create new TDB */
1025 			freeme = tdb_alloc(rdomain);
1026 			bzero(&ii, sizeof(struct ipsecinit));
1027 
1028 			newsa = (struct tdb *) freeme;
1029 			newsa->tdb_satype = smsg->sadb_msg_satype;
1030 
1031 			if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype,
1032 			    &newsa->tdb_sproto, &alg))) {
1033 				tdb_free(freeme);
1034 				freeme = NULL;
1035 				goto splxret;
1036 			}
1037 
1038 			/* Initialize SA */
1039 			import_sa(newsa, headers[SADB_EXT_SA], &ii);
1040 			import_address((struct sockaddr *) &newsa->tdb_src,
1041 			    headers[SADB_EXT_ADDRESS_SRC]);
1042 			import_address((struct sockaddr *) &newsa->tdb_dst,
1043 			    headers[SADB_EXT_ADDRESS_DST]);
1044 			import_address((struct sockaddr *) &newsa->tdb_proxy,
1045 			    headers[SADB_EXT_ADDRESS_PROXY]);
1046 			import_lifetime(newsa,
1047 			    headers[SADB_EXT_LIFETIME_CURRENT],
1048 			    PFKEYV2_LIFETIME_CURRENT);
1049 			import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT],
1050 			    PFKEYV2_LIFETIME_SOFT);
1051 			import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD],
1052 			    PFKEYV2_LIFETIME_HARD);
1053 			import_key(&ii, headers[SADB_EXT_KEY_AUTH],
1054 			    PFKEYV2_AUTHENTICATION_KEY);
1055 			import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT],
1056 			    PFKEYV2_ENCRYPTION_KEY);
1057 			import_identity(newsa, headers[SADB_EXT_IDENTITY_SRC],
1058 			    PFKEYV2_IDENTITY_SRC);
1059 			import_identity(newsa, headers[SADB_EXT_IDENTITY_DST],
1060 			    PFKEYV2_IDENTITY_DST);
1061 			import_credentials(newsa,
1062 			    headers[SADB_X_EXT_LOCAL_CREDENTIALS],
1063 			    PFKEYV2_CRED_LOCAL);
1064 			import_credentials(newsa,
1065 			    headers[SADB_X_EXT_REMOTE_CREDENTIALS],
1066 			    PFKEYV2_CRED_REMOTE);
1067 			import_auth(newsa, headers[SADB_X_EXT_LOCAL_AUTH],
1068 			    PFKEYV2_AUTH_LOCAL);
1069 			import_auth(newsa, headers[SADB_X_EXT_REMOTE_AUTH],
1070 			    PFKEYV2_AUTH_REMOTE);
1071 			import_flow(&newsa->tdb_filter, &newsa->tdb_filtermask,
1072 			    headers[SADB_X_EXT_SRC_FLOW],
1073 			    headers[SADB_X_EXT_SRC_MASK],
1074 			    headers[SADB_X_EXT_DST_FLOW],
1075 			    headers[SADB_X_EXT_DST_MASK],
1076 			    headers[SADB_X_EXT_PROTOCOL],
1077 			    headers[SADB_X_EXT_FLOW_TYPE]);
1078 			import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
1079 #if NPF > 0
1080 			import_tag(newsa, headers[SADB_X_EXT_TAG]);
1081 			import_tap(newsa, headers[SADB_X_EXT_TAP]);
1082 #endif
1083 
1084 			/* Exclude sensitive data from reply message. */
1085 			headers[SADB_EXT_KEY_AUTH] = NULL;
1086 			headers[SADB_EXT_KEY_ENCRYPT] = NULL;
1087 			headers[SADB_X_EXT_LOCAL_AUTH] = NULL;
1088 			headers[SADB_X_EXT_REMOTE_AUTH] = NULL;
1089 
1090 			newsa->tdb_seq = smsg->sadb_msg_seq;
1091 
1092 			rval = tdb_init(newsa, alg, &ii);
1093 			if (rval) {
1094 				rval = EINVAL;
1095 				tdb_free(freeme);
1096 				freeme = NULL;
1097 				goto splxret;
1098 			}
1099 
1100 			newsa->tdb_cur_allocations = sa2->tdb_cur_allocations;
1101 
1102 			/* Delete old version of the SA, insert new one */
1103 			tdb_delete(sa2);
1104 			puttdb((struct tdb *) freeme);
1105 			sa2 = freeme = NULL;
1106 		} else {
1107 			/*
1108 			 * The SA is already initialized, so we're only allowed to
1109 			 * change lifetimes and some other information; we're
1110 			 * not allowed to change keys, addresses or identities.
1111 			 */
1112 			if (headers[SADB_EXT_ADDRESS_PROXY] ||
1113 			    headers[SADB_EXT_KEY_AUTH] ||
1114 			    headers[SADB_EXT_KEY_ENCRYPT] ||
1115 			    headers[SADB_EXT_IDENTITY_SRC] ||
1116 			    headers[SADB_EXT_IDENTITY_DST] ||
1117 			    headers[SADB_EXT_SENSITIVITY]) {
1118 				rval = EINVAL;
1119 				goto splxret;
1120 			}
1121 
1122 			import_sa(sa2, headers[SADB_EXT_SA], NULL);
1123 			import_lifetime(sa2,
1124 			    headers[SADB_EXT_LIFETIME_CURRENT],
1125 			    PFKEYV2_LIFETIME_CURRENT);
1126 			import_lifetime(sa2, headers[SADB_EXT_LIFETIME_SOFT],
1127 			    PFKEYV2_LIFETIME_SOFT);
1128 			import_lifetime(sa2, headers[SADB_EXT_LIFETIME_HARD],
1129 			    PFKEYV2_LIFETIME_HARD);
1130 			import_udpencap(sa2, headers[SADB_X_EXT_UDPENCAP]);
1131 #if NPF > 0
1132 			import_tag(sa2, headers[SADB_X_EXT_TAG]);
1133 			import_tap(sa2, headers[SADB_X_EXT_TAP]);
1134 #endif
1135 		}
1136 
1137 		splx(s);
1138 		break;
1139 	case SADB_ADD:
1140 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
1141 		sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
1142 		    sizeof(struct sadb_address));
1143 
1144 		/* Either all or none of the flow must be included */
1145 		if ((headers[SADB_X_EXT_SRC_FLOW] ||
1146 		    headers[SADB_X_EXT_PROTOCOL] ||
1147 		    headers[SADB_X_EXT_FLOW_TYPE] ||
1148 		    headers[SADB_X_EXT_DST_FLOW] ||
1149 		    headers[SADB_X_EXT_SRC_MASK] ||
1150 		    headers[SADB_X_EXT_DST_MASK]) &&
1151 		    !(headers[SADB_X_EXT_SRC_FLOW] &&
1152 		    headers[SADB_X_EXT_PROTOCOL] &&
1153 		    headers[SADB_X_EXT_FLOW_TYPE] &&
1154 		    headers[SADB_X_EXT_DST_FLOW] &&
1155 		    headers[SADB_X_EXT_SRC_MASK] &&
1156 		    headers[SADB_X_EXT_DST_MASK])) {
1157 			rval = EINVAL;
1158 			goto ret;
1159 		}
1160 #ifdef IPSEC
1161 		/* UDP encap has to be enabled and is only supported for ESP */
1162 		if (headers[SADB_X_EXT_UDPENCAP] &&
1163 		    (!udpencap_enable ||
1164 		    smsg->sadb_msg_satype != SADB_SATYPE_ESP)) {
1165 			rval = EINVAL;
1166 			goto ret;
1167 		}
1168 #endif /* IPSEC */
1169 
1170 		s = splsoftnet();
1171 
1172 		sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1173 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
1174 
1175 		/* We can't add an existing SA! */
1176 		if (sa2 != NULL) {
1177 			rval = EEXIST;
1178 			goto splxret;
1179 		}
1180 
1181 		/* We can only add "mature" SAs */
1182 		if (ssa->sadb_sa_state != SADB_SASTATE_MATURE) {
1183 			rval = EINVAL;
1184 			goto splxret;
1185 		}
1186 
1187 		/* Allocate and initialize new TDB */
1188 		freeme = tdb_alloc(rdomain);
1189 
1190 		{
1191 			struct tdb *newsa = (struct tdb *) freeme;
1192 			struct ipsecinit ii;
1193 			int alg;
1194 
1195 			bzero(&ii, sizeof(struct ipsecinit));
1196 
1197 			newsa->tdb_satype = smsg->sadb_msg_satype;
1198 			if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype,
1199 			    &newsa->tdb_sproto, &alg))) {
1200 				tdb_free(freeme);
1201 				freeme = NULL;
1202 				goto splxret;
1203 			}
1204 
1205 			import_sa(newsa, headers[SADB_EXT_SA], &ii);
1206 			import_address((struct sockaddr *) &newsa->tdb_src,
1207 			    headers[SADB_EXT_ADDRESS_SRC]);
1208 			import_address((struct sockaddr *) &newsa->tdb_dst,
1209 			    headers[SADB_EXT_ADDRESS_DST]);
1210 			import_address((struct sockaddr *) &newsa->tdb_proxy,
1211 			    headers[SADB_EXT_ADDRESS_PROXY]);
1212 
1213 			import_lifetime(newsa,
1214 			    headers[SADB_EXT_LIFETIME_CURRENT],
1215 			    PFKEYV2_LIFETIME_CURRENT);
1216 			import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT],
1217 			    PFKEYV2_LIFETIME_SOFT);
1218 			import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD],
1219 			    PFKEYV2_LIFETIME_HARD);
1220 
1221 			import_key(&ii, headers[SADB_EXT_KEY_AUTH],
1222 			    PFKEYV2_AUTHENTICATION_KEY);
1223 			import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT],
1224 			    PFKEYV2_ENCRYPTION_KEY);
1225 
1226 			import_identity(newsa, headers[SADB_EXT_IDENTITY_SRC],
1227 			    PFKEYV2_IDENTITY_SRC);
1228 			import_identity(newsa, headers[SADB_EXT_IDENTITY_DST],
1229 			    PFKEYV2_IDENTITY_DST);
1230 
1231 			import_credentials(newsa,
1232 			    headers[SADB_X_EXT_LOCAL_CREDENTIALS],
1233 			    PFKEYV2_CRED_LOCAL);
1234 			import_credentials(newsa,
1235 			    headers[SADB_X_EXT_REMOTE_CREDENTIALS],
1236 			    PFKEYV2_CRED_REMOTE);
1237 			import_auth(newsa, headers[SADB_X_EXT_LOCAL_AUTH],
1238 			    PFKEYV2_AUTH_LOCAL);
1239 			import_auth(newsa, headers[SADB_X_EXT_REMOTE_AUTH],
1240 			    PFKEYV2_AUTH_REMOTE);
1241 			import_flow(&newsa->tdb_filter, &newsa->tdb_filtermask,
1242 			    headers[SADB_X_EXT_SRC_FLOW],
1243 			    headers[SADB_X_EXT_SRC_MASK],
1244 			    headers[SADB_X_EXT_DST_FLOW],
1245 			    headers[SADB_X_EXT_DST_MASK],
1246 			    headers[SADB_X_EXT_PROTOCOL],
1247 			    headers[SADB_X_EXT_FLOW_TYPE]);
1248 			import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
1249 #if NPF > 0
1250 			import_tag(newsa, headers[SADB_X_EXT_TAG]);
1251 			import_tap(newsa, headers[SADB_X_EXT_TAP]);
1252 #endif
1253 
1254 			/* Exclude sensitive data from reply message. */
1255 			headers[SADB_EXT_KEY_AUTH] = NULL;
1256 			headers[SADB_EXT_KEY_ENCRYPT] = NULL;
1257 			headers[SADB_X_EXT_LOCAL_AUTH] = NULL;
1258 			headers[SADB_X_EXT_REMOTE_AUTH] = NULL;
1259 
1260 			newsa->tdb_seq = smsg->sadb_msg_seq;
1261 
1262 			rval = tdb_init(newsa, alg, &ii);
1263 			if (rval) {
1264 				rval = EINVAL;
1265 				tdb_free(freeme);
1266 				freeme = NULL;
1267 				goto splxret;
1268 			}
1269 		}
1270 
1271 		/* Add TDB in table */
1272 		puttdb((struct tdb *) freeme);
1273 
1274 		splx(s);
1275 
1276 		freeme = NULL;
1277 		break;
1278 
1279 	case SADB_DELETE:
1280 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
1281 		sunionp =
1282 		    (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
1283 			sizeof(struct sadb_address));
1284 		s = splsoftnet();
1285 
1286 		sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1287 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
1288 		if (sa2 == NULL) {
1289 			rval = ESRCH;
1290 			goto splxret;
1291 		}
1292 
1293 		tdb_delete(sa2);
1294 
1295 		splx(s);
1296 
1297 		sa2 = NULL;
1298 		break;
1299 
1300 	case SADB_X_ASKPOLICY:
1301 		/* Get the relevant policy */
1302 		ipa = ipsec_get_acquire(((struct sadb_x_policy *) headers[SADB_X_EXT_POLICY])->sadb_x_policy_seq);
1303 		if (ipa == NULL) {
1304 			rval = ESRCH;
1305 			goto ret;
1306 		}
1307 
1308 		rval = pfkeyv2_policy(ipa, headers, &freeme);
1309 		if (rval)
1310 			mode = PFKEYV2_SENDMESSAGE_UNICAST;
1311 
1312 		break;
1313 
1314 	case SADB_GET:
1315 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
1316 		sunionp =
1317 		    (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
1318 			sizeof(struct sadb_address));
1319 
1320 		s = splsoftnet();
1321 
1322 		sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1323 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
1324 		if (sa2 == NULL) {
1325 			rval = ESRCH;
1326 			goto splxret;
1327 		}
1328 
1329 		rval = pfkeyv2_get(sa2, headers, &freeme, NULL);
1330 		if (rval)
1331 			mode = PFKEYV2_SENDMESSAGE_UNICAST;
1332 
1333 		splx(s);
1334 
1335 		break;
1336 
1337 	case SADB_REGISTER:
1338 		if (!(pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) {
1339 			pfkeyv2_socket->flags |= PFKEYV2_SOCKETFLAGS_REGISTERED;
1340 			nregistered++;
1341 		}
1342 
1343 		i = sizeof(struct sadb_supported) + sizeof(ealgs);
1344 
1345 		if (!(freeme = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
1346 			rval = ENOMEM;
1347 			goto ret;
1348 		}
1349 
1350 		ssup = (struct sadb_supported *) freeme;
1351 		ssup->sadb_supported_len = i / sizeof(uint64_t);
1352 
1353 		{
1354 			void *p = freeme + sizeof(struct sadb_supported);
1355 
1356 			bcopy(&ealgs[0], p, sizeof(ealgs));
1357 		}
1358 
1359 		headers[SADB_EXT_SUPPORTED_ENCRYPT] = freeme;
1360 
1361 		i = sizeof(struct sadb_supported) + sizeof(aalgs);
1362 
1363 		if (!(freeme = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
1364 			rval = ENOMEM;
1365 			goto ret;
1366 		}
1367 
1368 		/* Keep track what this socket has registered for */
1369 		pfkeyv2_socket->registration |= (1 << ((struct sadb_msg *)message)->sadb_msg_satype);
1370 
1371 		ssup = (struct sadb_supported *) freeme;
1372 		ssup->sadb_supported_len = i / sizeof(uint64_t);
1373 
1374 		{
1375 			void *p = freeme + sizeof(struct sadb_supported);
1376 
1377 			bcopy(&aalgs[0], p, sizeof(aalgs));
1378 		}
1379 
1380 		headers[SADB_EXT_SUPPORTED_AUTH] = freeme;
1381 
1382 		i = sizeof(struct sadb_supported) + sizeof(calgs);
1383 
1384 		if (!(freeme = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
1385 			rval = ENOMEM;
1386 			goto ret;
1387 		}
1388 
1389 		ssup = (struct sadb_supported *) freeme;
1390 		ssup->sadb_supported_len = i / sizeof(uint64_t);
1391 
1392 		{
1393 			void *p = freeme + sizeof(struct sadb_supported);
1394 
1395 			bcopy(&calgs[0], p, sizeof(calgs));
1396 		}
1397 
1398 		headers[SADB_X_EXT_SUPPORTED_COMP] = freeme;
1399 
1400 		break;
1401 
1402 	case SADB_ACQUIRE:
1403 	case SADB_EXPIRE:
1404 		/* Nothing to handle */
1405 		rval = 0;
1406 		break;
1407 
1408 	case SADB_FLUSH:
1409 		rval = 0;
1410 
1411 		switch (smsg->sadb_msg_satype) {
1412 		case SADB_SATYPE_UNSPEC:
1413 			s = splsoftnet();
1414 
1415 			/*
1416 			 * Go through the list of policies, delete those that
1417 			 * are not socket-attached.
1418 			 */
1419 			for (ipo = TAILQ_FIRST(&ipsec_policy_head);
1420 			    ipo != NULL; ipo = tmpipo) {
1421 				tmpipo = TAILQ_NEXT(ipo, ipo_list);
1422 				if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET) &&
1423 				    ipo->ipo_rdomain == rdomain)
1424 					ipsec_delete_policy(ipo);
1425 			}
1426 			splx(s);
1427 			/* FALLTHROUGH */
1428 		case SADB_SATYPE_AH:
1429 		case SADB_SATYPE_ESP:
1430 		case SADB_X_SATYPE_IPIP:
1431 		case SADB_X_SATYPE_IPCOMP:
1432 #ifdef TCP_SIGNATURE
1433 		case SADB_X_SATYPE_TCPSIGNATURE:
1434 #endif /* TCP_SIGNATURE */
1435 			s = splsoftnet();
1436 
1437 			tdb_walk(rdomain, pfkeyv2_flush_walker,
1438 			    (u_int8_t *) &(smsg->sadb_msg_satype));
1439 
1440 			splx(s);
1441 			break;
1442 
1443 		default:
1444 			rval = EINVAL; /* Unknown/unsupported type */
1445 		}
1446 
1447 		break;
1448 
1449 	case SADB_DUMP:
1450 	{
1451 		struct dump_state dump_state;
1452 		dump_state.sadb_msg = (struct sadb_msg *) headers[0];
1453 		dump_state.socket = socket;
1454 
1455 		s = splsoftnet();
1456 		rval = tdb_walk(rdomain, pfkeyv2_dump_walker, &dump_state);
1457 		splx(s);
1458 
1459 		if (!rval)
1460 			goto realret;
1461 
1462 		if ((rval == ENOMEM) || (rval == ENOBUFS))
1463 			rval = 0;
1464 	}
1465 	break;
1466 
1467 	case SADB_X_GRPSPIS:
1468 	{
1469 		struct tdb *tdb1, *tdb2, *tdb3;
1470 		struct sadb_protocol *sa_proto;
1471 
1472 		ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
1473 		sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
1474 		    sizeof(struct sadb_address));
1475 
1476 		s = splsoftnet();
1477 
1478 		tdb1 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1479 		    SADB_X_GETSPROTO(smsg->sadb_msg_satype));
1480 		if (tdb1 == NULL) {
1481 			rval = ESRCH;
1482 			goto splxret;
1483 		}
1484 
1485 		ssa = (struct sadb_sa *) headers[SADB_X_EXT_SA2];
1486 		sunionp = (union sockaddr_union *) (headers[SADB_X_EXT_DST2] +
1487 		    sizeof(struct sadb_address));
1488 		sa_proto = ((struct sadb_protocol *) headers[SADB_X_EXT_PROTOCOL]);
1489 
1490 		tdb2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
1491 		    SADB_X_GETSPROTO(sa_proto->sadb_protocol_proto));
1492 		if (tdb2 == NULL) {
1493 			rval = ESRCH;
1494 			goto splxret;
1495 		}
1496 
1497 		/* Detect cycles */
1498 		for (tdb3 = tdb2; tdb3; tdb3 = tdb3->tdb_onext)
1499 			if (tdb3 == tdb1) {
1500 				rval = ESRCH;
1501 				goto splxret;
1502 			}
1503 
1504 		/* Maintenance */
1505 		if ((tdb1->tdb_onext) &&
1506 		    (tdb1->tdb_onext->tdb_inext == tdb1))
1507 			tdb1->tdb_onext->tdb_inext = NULL;
1508 
1509 		if ((tdb2->tdb_inext) &&
1510 		    (tdb2->tdb_inext->tdb_onext == tdb2))
1511 			tdb2->tdb_inext->tdb_onext = NULL;
1512 
1513 		/* Link them */
1514 		tdb1->tdb_onext = tdb2;
1515 		tdb2->tdb_inext = tdb1;
1516 
1517 		splx(s);
1518 	}
1519 	break;
1520 
1521 	case SADB_X_DELFLOW:
1522 		delflag = 1;
1523 		/*FALLTHROUGH*/
1524 	case SADB_X_ADDFLOW:
1525 	{
1526 		struct sadb_protocol *sab;
1527 		union sockaddr_union *ssrc;
1528 		struct route_enc re;
1529 		int exists = 0;
1530 
1531 		sab = (struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE];
1532 
1533 		if ((sab->sadb_protocol_direction != IPSP_DIRECTION_IN) &&
1534 		    (sab->sadb_protocol_direction != IPSP_DIRECTION_OUT)) {
1535 			rval = EINVAL;
1536 			goto ret;
1537 		}
1538 
1539 		/* If the security protocol wasn't specified, pretend it was ESP */
1540 		if (smsg->sadb_msg_satype == 0)
1541 			smsg->sadb_msg_satype = SADB_SATYPE_ESP;
1542 
1543 		if (headers[SADB_EXT_ADDRESS_DST])
1544 			sunionp = (union sockaddr_union *)
1545 			    (headers[SADB_EXT_ADDRESS_DST] +
1546 				sizeof(struct sadb_address));
1547 		else
1548 			sunionp = NULL;
1549 
1550 		if (headers[SADB_EXT_ADDRESS_SRC])
1551 			ssrc = (union sockaddr_union *)
1552 			    (headers[SADB_EXT_ADDRESS_SRC] +
1553 				sizeof(struct sadb_address));
1554 		else
1555 			ssrc = NULL;
1556 
1557 		import_flow(&encapdst, &encapnetmask,
1558 		    headers[SADB_X_EXT_SRC_FLOW], headers[SADB_X_EXT_SRC_MASK],
1559 		    headers[SADB_X_EXT_DST_FLOW], headers[SADB_X_EXT_DST_MASK],
1560 		    headers[SADB_X_EXT_PROTOCOL], headers[SADB_X_EXT_FLOW_TYPE]);
1561 
1562 		/* Determine whether the exact same SPD entry already exists. */
1563 		bzero(&encapgw, sizeof(struct sockaddr_encap));
1564 		bzero(&re, sizeof(struct route_enc));
1565 		bcopy(&encapdst, &re.re_dst, sizeof(struct sockaddr_encap));
1566 
1567 		s = splsoftnet();
1568 
1569 		/* Set the rdomain that was obtained from the socket */
1570 		re.re_tableid = rdomain;
1571 
1572 		rtalloc((struct route *) &re);
1573 		if (re.re_rt != NULL) {
1574 			ipo = ((struct sockaddr_encap *) re.re_rt->rt_gateway)->sen_ipsp;
1575 			RTFREE(re.re_rt);
1576 
1577 			/* Verify that the entry is identical */
1578 			if (bcmp(&ipo->ipo_addr, &encapdst,
1579 				sizeof(struct sockaddr_encap)) ||
1580 			    bcmp(&ipo->ipo_mask, &encapnetmask,
1581 				sizeof(struct sockaddr_encap)))
1582 				ipo = NULL; /* Fall through */
1583 			else
1584 				exists = 1;
1585 		} else
1586 			ipo = NULL;
1587 
1588 		/*
1589 		 * If the existing policy is static, only delete or update
1590 		 * it if the new one is also static.
1591 		 */
1592 		if (exists && (ipo->ipo_flags & IPSP_POLICY_STATIC)) {
1593 			if (!(sab->sadb_protocol_flags &
1594 				SADB_X_POLICYFLAGS_POLICY)) {
1595 				splx(s);
1596 				goto ret;
1597 			}
1598 		}
1599 
1600 		/* Delete ? */
1601 		if (delflag) {
1602 			if (exists) {
1603 				rval = ipsec_delete_policy(ipo);
1604 				splx(s);
1605 				goto ret;
1606 			}
1607 
1608 			/* If we were asked to delete something non-existent, error. */
1609 			splx(s);
1610 			rval = ESRCH;
1611 			break;
1612 		}
1613 
1614 		if (!exists) {
1615 			if (ipsec_policy_pool_initialized == 0) {
1616 				ipsec_policy_pool_initialized = 1;
1617 				pool_init(&ipsec_policy_pool,
1618 				    sizeof(struct ipsec_policy), 0, 0, 0,
1619 				    "ipsec policy", NULL);
1620 			}
1621 
1622 			/* Allocate policy entry */
1623 			ipo = pool_get(&ipsec_policy_pool, PR_NOWAIT);
1624 			if (ipo == NULL) {
1625 				splx(s);
1626 				rval = ENOMEM;
1627 				goto ret;
1628 			}
1629 
1630 			bzero(ipo, sizeof(struct ipsec_policy));
1631 			ipo->ipo_ref_count = 1;
1632 			TAILQ_INIT(&ipo->ipo_acquires);
1633 
1634 			/* Finish initialization of SPD entry */
1635 			encapgw.sen_len = SENT_LEN;
1636 			encapgw.sen_family = PF_KEY;
1637 			encapgw.sen_type = SENT_IPSP;
1638 			encapgw.sen_ipsp = ipo;
1639 
1640 			/* Initialize policy entry */
1641 			bcopy(&encapdst, &ipo->ipo_addr,
1642 			    sizeof(struct sockaddr_encap));
1643 			bcopy(&encapnetmask, &ipo->ipo_mask,
1644 			    sizeof(struct sockaddr_encap));
1645 
1646 			ipo->ipo_rdomain = rdomain;
1647 		}
1648 
1649 		switch (((struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE])->sadb_protocol_proto) {
1650 		case SADB_X_FLOW_TYPE_USE:
1651 			ipo->ipo_type = IPSP_IPSEC_USE;
1652 			break;
1653 
1654 		case SADB_X_FLOW_TYPE_ACQUIRE:
1655 			ipo->ipo_type = IPSP_IPSEC_ACQUIRE;
1656 			break;
1657 
1658 		case SADB_X_FLOW_TYPE_REQUIRE:
1659 			ipo->ipo_type = IPSP_IPSEC_REQUIRE;
1660 			break;
1661 
1662 		case SADB_X_FLOW_TYPE_DENY:
1663 			ipo->ipo_type = IPSP_DENY;
1664 			break;
1665 
1666 		case SADB_X_FLOW_TYPE_BYPASS:
1667 			ipo->ipo_type = IPSP_PERMIT;
1668 			break;
1669 
1670 		case SADB_X_FLOW_TYPE_DONTACQ:
1671 			ipo->ipo_type = IPSP_IPSEC_DONTACQ;
1672 			break;
1673 
1674 		default:
1675 			if (!exists)
1676 				pool_put(&ipsec_policy_pool, ipo);
1677 			else
1678 				ipsec_delete_policy(ipo);
1679 
1680 			splx(s);
1681 			rval = EINVAL;
1682 			goto ret;
1683 		}
1684 
1685 		if (sab->sadb_protocol_flags & SADB_X_POLICYFLAGS_POLICY)
1686 			ipo->ipo_flags |= IPSP_POLICY_STATIC;
1687 
1688 		if (sunionp)
1689 			bcopy(sunionp, &ipo->ipo_dst,
1690 			    sizeof(union sockaddr_union));
1691 		else
1692 			bzero(&ipo->ipo_dst, sizeof(union sockaddr_union));
1693 
1694 		if (ssrc)
1695 			bcopy(ssrc, &ipo->ipo_src,
1696 			    sizeof(union sockaddr_union));
1697 		else
1698 			bzero(&ipo->ipo_src, sizeof(union sockaddr_union));
1699 
1700 		ipo->ipo_sproto = SADB_X_GETSPROTO(smsg->sadb_msg_satype);
1701 
1702 		if (ipo->ipo_srcid) {
1703 			ipsp_reffree(ipo->ipo_srcid);
1704 			ipo->ipo_srcid = NULL;
1705 		}
1706 
1707 		if (ipo->ipo_dstid) {
1708 			ipsp_reffree(ipo->ipo_dstid);
1709 			ipo->ipo_dstid = NULL;
1710 		}
1711 
1712 		if ((sid = headers[SADB_EXT_IDENTITY_SRC]) != NULL) {
1713 			int clen =  (sid->sadb_ident_len * sizeof(u_int64_t)) -
1714 			    sizeof(struct sadb_ident);
1715 
1716 			ipo->ipo_srcid = malloc(clen + sizeof(struct ipsec_ref),
1717 			    M_CREDENTIALS, M_NOWAIT);
1718 			if (ipo->ipo_srcid == NULL) {
1719 				if (exists)
1720 					ipsec_delete_policy(ipo);
1721 				else
1722 					pool_put(&ipsec_policy_pool, ipo);
1723 				splx(s);
1724 				rval = ENOBUFS;
1725 				goto ret;
1726 			}
1727 			ipo->ipo_srcid->ref_type = sid->sadb_ident_type;
1728 			ipo->ipo_srcid->ref_len = clen;
1729 			ipo->ipo_srcid->ref_count = 1;
1730 			ipo->ipo_srcid->ref_malloctype = M_CREDENTIALS;
1731 			bcopy(sid + 1, ipo->ipo_srcid + 1, ipo->ipo_srcid->ref_len);
1732 		}
1733 
1734 		if ((sid = headers[SADB_EXT_IDENTITY_DST]) != NULL) {
1735 			int clen =  (sid->sadb_ident_len * sizeof(u_int64_t)) -
1736 			    sizeof(struct sadb_ident);
1737 
1738 			ipo->ipo_dstid = malloc(clen + sizeof(struct ipsec_ref),
1739 			    M_CREDENTIALS, M_NOWAIT);
1740 			if (ipo->ipo_dstid == NULL) {
1741 				if (exists)
1742 					ipsec_delete_policy(ipo);
1743 				else {
1744 					if (ipo->ipo_dstid)
1745 						ipsp_reffree(ipo->ipo_dstid);
1746 					pool_put(&ipsec_policy_pool, ipo);
1747 				}
1748 
1749 				splx(s);
1750 				rval = ENOBUFS;
1751 				goto ret;
1752 			}
1753 			ipo->ipo_dstid->ref_type = sid->sadb_ident_type;
1754 			ipo->ipo_dstid->ref_len = clen;
1755 			ipo->ipo_dstid->ref_count = 1;
1756 			ipo->ipo_dstid->ref_malloctype = M_CREDENTIALS;
1757 			bcopy(sid + 1, ipo->ipo_dstid + 1,
1758 			    ipo->ipo_dstid->ref_len);
1759 		}
1760 
1761 		/* Flow type */
1762 		if (!exists) {
1763 			/* Add SPD entry */
1764 			struct rt_addrinfo info;
1765 
1766 			bzero(&info, sizeof(info));
1767 			info.rti_info[RTAX_DST] = (struct sockaddr *)&encapdst;
1768 			info.rti_info[RTAX_GATEWAY] =
1769 			    (struct sockaddr *)&encapgw;
1770 			info.rti_info[RTAX_NETMASK] =
1771 			    (struct sockaddr *)&encapnetmask;
1772 			info.rti_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
1773 			if ((rval = rtrequest1(RTM_ADD, &info, RTP_DEFAULT,
1774 			    NULL, rdomain)) != 0) {
1775 				/* Remove from linked list of policies on TDB */
1776 				if (ipo->ipo_tdb)
1777 					TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head,
1778 					    ipo, ipo_tdb_next);
1779 
1780 				if (ipo->ipo_srcid)
1781 					ipsp_reffree(ipo->ipo_srcid);
1782 				if (ipo->ipo_dstid)
1783 					ipsp_reffree(ipo->ipo_dstid);
1784 				pool_put(&ipsec_policy_pool, ipo);
1785 
1786 				splx(s);
1787 				goto ret;
1788 			}
1789 
1790 			TAILQ_INSERT_HEAD(&ipsec_policy_head, ipo, ipo_list);
1791 			ipsec_in_use++;
1792 		} else {
1793 			ipo->ipo_last_searched = ipo->ipo_flags = 0;
1794 		}
1795 
1796 		splx(s);
1797 	}
1798 	break;
1799 
1800 	case SADB_X_PROMISC:
1801 		if (len >= 2 * sizeof(struct sadb_msg)) {
1802 			struct mbuf *packet;
1803 
1804 			if ((rval = pfdatatopacket(message, len, &packet)) != 0)
1805 				goto ret;
1806 
1807 			for (so = pfkeyv2_sockets; so; so = so->next)
1808 				if ((so != pfkeyv2_socket) &&
1809 				    (so->rdomain == rdomain) &&
1810 				    (!smsg->sadb_msg_seq ||
1811 				    (smsg->sadb_msg_seq == pfkeyv2_socket->pid)))
1812 					pfkey_sendup(so->socket, packet, 1);
1813 
1814 			m_freem(packet);
1815 		} else {
1816 			if (len != sizeof(struct sadb_msg)) {
1817 				rval = EINVAL;
1818 				goto ret;
1819 			}
1820 
1821 			i = (pfkeyv2_socket->flags &
1822 			    PFKEYV2_SOCKETFLAGS_PROMISC) ? 1 : 0;
1823 			j = smsg->sadb_msg_satype ? 1 : 0;
1824 
1825 			if (i ^ j) {
1826 				if (j) {
1827 					pfkeyv2_socket->flags |=
1828 					    PFKEYV2_SOCKETFLAGS_PROMISC;
1829 					npromisc++;
1830 				} else {
1831 					pfkeyv2_socket->flags &=
1832 					    ~PFKEYV2_SOCKETFLAGS_PROMISC;
1833 					npromisc--;
1834 				}
1835 			}
1836 		}
1837 
1838 
1839 		break;
1840 
1841 	default:
1842 		rval = EINVAL;
1843 		goto ret;
1844 	}
1845 
1846 ret:
1847 	if (rval) {
1848 		if ((rval == EINVAL) || (rval == ENOMEM) || (rval == ENOBUFS))
1849 			goto realret;
1850 
1851 		for (i = 1; i <= SADB_EXT_MAX; i++)
1852 			headers[i] = NULL;
1853 
1854 		smsg->sadb_msg_errno = abs(rval);
1855 	} else {
1856 		uint64_t seen = 0LL;
1857 
1858 		for (i = 1; i <= SADB_EXT_MAX; i++)
1859 			if (headers[i])
1860 				seen |= (1LL << i);
1861 
1862 		if ((seen & sadb_exts_allowed_out[smsg->sadb_msg_type])
1863 		    != seen)
1864 			goto realret;
1865 
1866 		if ((seen & sadb_exts_required_out[smsg->sadb_msg_type]) !=
1867 		    sadb_exts_required_out[smsg->sadb_msg_type])
1868 			goto realret;
1869 	}
1870 
1871 	rval = pfkeyv2_sendmessage(headers, mode, socket, 0, 0, rdomain);
1872 
1873 realret:
1874 	if (freeme)
1875 		free(freeme, M_PFKEY, 0);
1876 
1877 	explicit_bzero(message, len);
1878 	free(message, M_PFKEY, 0);
1879 
1880 	if (sa1)
1881 		free(sa1, M_PFKEY, 0);
1882 
1883 	return (rval);
1884 
1885 splxret:
1886 	splx(s);
1887 	goto ret;
1888 }
1889 
1890 /*
1891  * Send an ACQUIRE message to key management, to get a new SA.
1892  */
1893 int
1894 pfkeyv2_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw,
1895     union sockaddr_union *laddr, u_int32_t *seq, struct sockaddr_encap *ddst)
1896 {
1897 	void *p, *headers[SADB_EXT_MAX + 1], *buffer = NULL;
1898 	struct sadb_ident *srcid, *dstid;
1899 	struct sadb_x_cred *lcred, *lauth;
1900 	struct sadb_comb *sadb_comb;
1901 	struct sadb_address *sadd;
1902 	struct sadb_prop *sa_prop;
1903 	struct sadb_msg *smsg;
1904 	int rval = 0;
1905 	int i, j;
1906 
1907 	*seq = pfkeyv2_seq++;
1908 
1909 	if (!nregistered) {
1910 		rval = ESRCH;
1911 		goto ret;
1912 	}
1913 
1914 	/* How large a buffer do we need... XXX we only do one proposal for now */
1915 	i = sizeof(struct sadb_msg) +
1916 	    (laddr == NULL ? 0 : sizeof(struct sadb_address) +
1917 		PADUP(SA_LEN(&ipo->ipo_src.sa))) +
1918 	    sizeof(struct sadb_address) + PADUP(SA_LEN(&gw->sa)) +
1919 	    sizeof(struct sadb_prop) + 1 * sizeof(struct sadb_comb);
1920 
1921 	if (ipo->ipo_srcid)
1922 		i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
1923 
1924 	if (ipo->ipo_dstid)
1925 		i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
1926 
1927 	if (ipo->ipo_local_cred)
1928 		i += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_cred->ref_len);
1929 
1930 	if (ipo->ipo_local_auth)
1931 		i += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_auth->ref_len);
1932 
1933 	/* Allocate */
1934 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
1935 		rval = ENOMEM;
1936 		goto ret;
1937 	}
1938 
1939 	bzero(headers, sizeof(headers));
1940 
1941 	buffer = p;
1942 
1943 	headers[0] = p;
1944 	p += sizeof(struct sadb_msg);
1945 
1946 	smsg = (struct sadb_msg *) headers[0];
1947 	smsg->sadb_msg_version = PF_KEY_V2;
1948 	smsg->sadb_msg_type = SADB_ACQUIRE;
1949 	smsg->sadb_msg_len = i / sizeof(uint64_t);
1950 	smsg->sadb_msg_seq = *seq;
1951 
1952 	if (ipo->ipo_sproto == IPPROTO_ESP)
1953 		smsg->sadb_msg_satype = SADB_SATYPE_ESP;
1954 	else if (ipo->ipo_sproto == IPPROTO_AH)
1955 		smsg->sadb_msg_satype = SADB_SATYPE_AH;
1956 	else if (ipo->ipo_sproto == IPPROTO_IPCOMP)
1957 		smsg->sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
1958 
1959 	if (laddr) {
1960 		headers[SADB_EXT_ADDRESS_SRC] = p;
1961 		p += sizeof(struct sadb_address) + PADUP(SA_LEN(&laddr->sa));
1962 		sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_SRC];
1963 		sadd->sadb_address_len = (sizeof(struct sadb_address) +
1964 		    SA_LEN(&laddr->sa) + sizeof(uint64_t) - 1) /
1965 		    sizeof(uint64_t);
1966 		bcopy(laddr, headers[SADB_EXT_ADDRESS_SRC] +
1967 		    sizeof(struct sadb_address), SA_LEN(&laddr->sa));
1968 	}
1969 
1970 	headers[SADB_EXT_ADDRESS_DST] = p;
1971 	p += sizeof(struct sadb_address) + PADUP(SA_LEN(&gw->sa));
1972 	sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_DST];
1973 	sadd->sadb_address_len = (sizeof(struct sadb_address) +
1974 	    SA_LEN(&gw->sa) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
1975 	bcopy(gw, headers[SADB_EXT_ADDRESS_DST] + sizeof(struct sadb_address),
1976 	    SA_LEN(&gw->sa));
1977 
1978 	if (ipo->ipo_srcid) {
1979 		headers[SADB_EXT_IDENTITY_SRC] = p;
1980 		p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
1981 		srcid = (struct sadb_ident *) headers[SADB_EXT_IDENTITY_SRC];
1982 		srcid->sadb_ident_len = (sizeof(struct sadb_ident) +
1983 		    PADUP(ipo->ipo_srcid->ref_len)) / sizeof(u_int64_t);
1984 		srcid->sadb_ident_type = ipo->ipo_srcid->ref_type;
1985 		bcopy(ipo->ipo_srcid + 1, headers[SADB_EXT_IDENTITY_SRC] +
1986 		    sizeof(struct sadb_ident), ipo->ipo_srcid->ref_len);
1987 	}
1988 
1989 	if (ipo->ipo_dstid) {
1990 		headers[SADB_EXT_IDENTITY_DST] = p;
1991 		p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
1992 		dstid = (struct sadb_ident *) headers[SADB_EXT_IDENTITY_DST];
1993 		dstid->sadb_ident_len = (sizeof(struct sadb_ident) +
1994 		    PADUP(ipo->ipo_dstid->ref_len)) / sizeof(u_int64_t);
1995 		dstid->sadb_ident_type = ipo->ipo_dstid->ref_type;
1996 		bcopy(ipo->ipo_dstid + 1, headers[SADB_EXT_IDENTITY_DST] +
1997 		    sizeof(struct sadb_ident), ipo->ipo_dstid->ref_len);
1998 	}
1999 
2000 	if (ipo->ipo_local_cred) {
2001 		headers[SADB_X_EXT_LOCAL_CREDENTIALS] = p;
2002 		p += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_cred->ref_len);
2003 		lcred = (struct sadb_x_cred *) headers[SADB_X_EXT_LOCAL_CREDENTIALS];
2004 		lcred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
2005 		    PADUP(ipo->ipo_local_cred->ref_len)) / sizeof(u_int64_t);
2006 		switch (ipo->ipo_local_cred->ref_type) {
2007 		case IPSP_CRED_KEYNOTE:
2008 			lcred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
2009 			break;
2010 		case IPSP_CRED_X509:
2011 			lcred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
2012 			break;
2013 		}
2014 		bcopy(ipo->ipo_local_cred + 1, headers[SADB_X_EXT_LOCAL_CREDENTIALS] +
2015 		    sizeof(struct sadb_x_cred), ipo->ipo_local_cred->ref_len);
2016 	}
2017 
2018 	if (ipo->ipo_local_auth) {
2019 		headers[SADB_X_EXT_LOCAL_AUTH] = p;
2020 		p += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_auth->ref_len);
2021 		lauth = (struct sadb_x_cred *) headers[SADB_X_EXT_LOCAL_AUTH];
2022 		lauth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
2023 		    PADUP(ipo->ipo_local_auth->ref_len)) / sizeof(u_int64_t);
2024 		switch (ipo->ipo_local_auth->ref_type) {
2025 		case IPSP_AUTH_PASSPHRASE:
2026 			lauth->sadb_x_cred_type = SADB_X_AUTHTYPE_PASSPHRASE;
2027 			break;
2028 		case IPSP_AUTH_RSA:
2029 			lauth->sadb_x_cred_type = SADB_X_AUTHTYPE_RSA;
2030 			break;
2031 		}
2032 
2033 		bcopy(ipo->ipo_local_auth + 1, headers[SADB_X_EXT_LOCAL_AUTH] +
2034 		    sizeof(struct sadb_x_cred), ipo->ipo_local_auth->ref_len);
2035 	}
2036 
2037 	headers[SADB_EXT_PROPOSAL] = p;
2038 	p += sizeof(struct sadb_prop);
2039 	sa_prop = (struct sadb_prop *) headers[SADB_EXT_PROPOSAL];
2040 	sa_prop->sadb_prop_num = 1; /* XXX One proposal only */
2041 	sa_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
2042 	    (sizeof(struct sadb_comb) * sa_prop->sadb_prop_num)) /
2043 	    sizeof(uint64_t);
2044 
2045 	sadb_comb = p;
2046 
2047 	/* XXX Should actually ask the crypto layer what's supported */
2048 	for (j = 0; j < sa_prop->sadb_prop_num; j++) {
2049 		sadb_comb->sadb_comb_flags = 0;
2050 
2051 		if (ipsec_require_pfs)
2052 			sadb_comb->sadb_comb_flags |= SADB_SAFLAGS_PFS;
2053 
2054 		/* Set the encryption algorithm */
2055 		if (ipo->ipo_sproto == IPPROTO_ESP) {
2056 			if (!strncasecmp(ipsec_def_enc, "aes",
2057 			    sizeof("aes"))) {
2058 				sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AES;
2059 				sadb_comb->sadb_comb_encrypt_minbits = 128;
2060 				sadb_comb->sadb_comb_encrypt_maxbits = 256;
2061 			} else if (!strncasecmp(ipsec_def_enc, "aesctr",
2062 			    sizeof("aesctr"))) {
2063 				sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AESCTR;
2064 				sadb_comb->sadb_comb_encrypt_minbits = 128+32;
2065 				sadb_comb->sadb_comb_encrypt_maxbits = 256+32;
2066 			} else if (!strncasecmp(ipsec_def_enc, "3des",
2067 			    sizeof("3des"))) {
2068 				sadb_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC;
2069 				sadb_comb->sadb_comb_encrypt_minbits = 192;
2070 				sadb_comb->sadb_comb_encrypt_maxbits = 192;
2071 			} else if (!strncasecmp(ipsec_def_enc, "des",
2072 			    sizeof("des"))) {
2073 				sadb_comb->sadb_comb_encrypt = SADB_EALG_DESCBC;
2074 				sadb_comb->sadb_comb_encrypt_minbits = 64;
2075 				sadb_comb->sadb_comb_encrypt_maxbits = 64;
2076 			} else if (!strncasecmp(ipsec_def_enc, "blowfish",
2077 			    sizeof("blowfish"))) {
2078 				sadb_comb->sadb_comb_encrypt = SADB_X_EALG_BLF;
2079 				sadb_comb->sadb_comb_encrypt_minbits = 40;
2080 				sadb_comb->sadb_comb_encrypt_maxbits = BLF_MAXKEYLEN * 8;
2081 			} else if (!strncasecmp(ipsec_def_enc, "cast128",
2082 			    sizeof("cast128"))) {
2083 				sadb_comb->sadb_comb_encrypt = SADB_X_EALG_CAST;
2084 				sadb_comb->sadb_comb_encrypt_minbits = 40;
2085 				sadb_comb->sadb_comb_encrypt_maxbits = 128;
2086 			}
2087 		} else if (ipo->ipo_sproto == IPPROTO_IPCOMP) {
2088 			/* Set the compression algorithm */
2089 			if (!strncasecmp(ipsec_def_comp, "deflate",
2090 			    sizeof("deflate"))) {
2091 				sadb_comb->sadb_comb_encrypt = SADB_X_CALG_DEFLATE;
2092 				sadb_comb->sadb_comb_encrypt_minbits = 0;
2093 				sadb_comb->sadb_comb_encrypt_maxbits = 0;
2094 			} else if (!strncasecmp(ipsec_def_comp, "lzs",
2095 			    sizeof("lzs"))) {
2096 				sadb_comb->sadb_comb_encrypt = SADB_X_CALG_LZS;
2097 				sadb_comb->sadb_comb_encrypt_minbits = 0;
2098 				sadb_comb->sadb_comb_encrypt_maxbits = 0;
2099 			}
2100 		}
2101 
2102 		/* Set the authentication algorithm */
2103 		if (!strncasecmp(ipsec_def_auth, "hmac-sha1",
2104 		    sizeof("hmac-sha1"))) {
2105 			sadb_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC;
2106 			sadb_comb->sadb_comb_auth_minbits = 160;
2107 			sadb_comb->sadb_comb_auth_maxbits = 160;
2108 		} else if (!strncasecmp(ipsec_def_auth, "hmac-ripemd160",
2109 		    sizeof("hmac_ripemd160"))) {
2110 			sadb_comb->sadb_comb_auth = SADB_X_AALG_RIPEMD160HMAC;
2111 			sadb_comb->sadb_comb_auth_minbits = 160;
2112 			sadb_comb->sadb_comb_auth_maxbits = 160;
2113 		} else if (!strncasecmp(ipsec_def_auth, "hmac-md5",
2114 		    sizeof("hmac-md5"))) {
2115 			sadb_comb->sadb_comb_auth = SADB_AALG_MD5HMAC;
2116 			sadb_comb->sadb_comb_auth_minbits = 128;
2117 			sadb_comb->sadb_comb_auth_maxbits = 128;
2118 		} else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-256",
2119 		    sizeof("hmac-sha2-256"))) {
2120 			sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256;
2121 			sadb_comb->sadb_comb_auth_minbits = 256;
2122 			sadb_comb->sadb_comb_auth_maxbits = 256;
2123 		} else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-384",
2124 		    sizeof("hmac-sha2-384"))) {
2125 			sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_384;
2126 			sadb_comb->sadb_comb_auth_minbits = 384;
2127 			sadb_comb->sadb_comb_auth_maxbits = 384;
2128 		} else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-512",
2129 		    sizeof("hmac-sha2-512"))) {
2130 			sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_512;
2131 			sadb_comb->sadb_comb_auth_minbits = 512;
2132 			sadb_comb->sadb_comb_auth_maxbits = 512;
2133 		}
2134 
2135 		sadb_comb->sadb_comb_soft_allocations = ipsec_soft_allocations;
2136 		sadb_comb->sadb_comb_hard_allocations = ipsec_exp_allocations;
2137 
2138 		sadb_comb->sadb_comb_soft_bytes = ipsec_soft_bytes;
2139 		sadb_comb->sadb_comb_hard_bytes = ipsec_exp_bytes;
2140 
2141 		sadb_comb->sadb_comb_soft_addtime = ipsec_soft_timeout;
2142 		sadb_comb->sadb_comb_hard_addtime = ipsec_exp_timeout;
2143 
2144 		sadb_comb->sadb_comb_soft_usetime = ipsec_soft_first_use;
2145 		sadb_comb->sadb_comb_hard_usetime = ipsec_exp_first_use;
2146 		sadb_comb++;
2147 	}
2148 
2149 	/* Send the ACQUIRE message to all compliant registered listeners. */
2150 	if ((rval = pfkeyv2_sendmessage(headers,
2151 	    PFKEYV2_SENDMESSAGE_REGISTERED, NULL, smsg->sadb_msg_satype, 0,
2152 	    ipo->ipo_rdomain)) != 0)
2153 		goto ret;
2154 
2155 	rval = 0;
2156 ret:
2157 	if (buffer != NULL) {
2158 		bzero(buffer, i);
2159 		free(buffer, M_PFKEY, 0);
2160 	}
2161 
2162 	return (rval);
2163 }
2164 
2165 /*
2166  * Notify key management that an expiration went off. The second argument
2167  * specifies the type of expiration (soft or hard).
2168  */
2169 int
2170 pfkeyv2_expire(struct tdb *sa, u_int16_t type)
2171 {
2172 	void *p, *headers[SADB_EXT_MAX+1], *buffer = NULL;
2173 	struct sadb_msg *smsg;
2174 	int rval = 0;
2175 	int i;
2176 
2177 	switch (sa->tdb_sproto) {
2178 	case IPPROTO_AH:
2179 	case IPPROTO_ESP:
2180 	case IPPROTO_IPIP:
2181 	case IPPROTO_IPCOMP:
2182 #ifdef TCP_SIGNATURE
2183 	case IPPROTO_TCP:
2184 #endif /* TCP_SIGNATURE */
2185 		break;
2186 
2187 	default:
2188 		rval = EOPNOTSUPP;
2189 		goto ret;
2190 	}
2191 
2192 	i = sizeof(struct sadb_msg) + sizeof(struct sadb_sa) +
2193 	    2 * sizeof(struct sadb_lifetime) +
2194 	    sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_src.sa)) +
2195 	    sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_dst.sa));
2196 
2197 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
2198 		rval = ENOMEM;
2199 		goto ret;
2200 	}
2201 
2202 	bzero(headers, sizeof(headers));
2203 
2204 	buffer = p;
2205 
2206 	headers[0] = p;
2207 	p += sizeof(struct sadb_msg);
2208 
2209 	smsg = (struct sadb_msg *) headers[0];
2210 	smsg->sadb_msg_version = PF_KEY_V2;
2211 	smsg->sadb_msg_type = SADB_EXPIRE;
2212 	smsg->sadb_msg_satype = sa->tdb_satype;
2213 	smsg->sadb_msg_len = i / sizeof(uint64_t);
2214 	smsg->sadb_msg_seq = pfkeyv2_seq++;
2215 
2216 	headers[SADB_EXT_SA] = p;
2217 	export_sa(&p, sa);
2218 
2219 	headers[SADB_EXT_LIFETIME_CURRENT] = p;
2220 	export_lifetime(&p, sa, 2);
2221 
2222 	headers[type] = p;
2223 	export_lifetime(&p, sa, type == SADB_EXT_LIFETIME_SOFT ?
2224 	    PFKEYV2_LIFETIME_SOFT : PFKEYV2_LIFETIME_HARD);
2225 
2226 	headers[SADB_EXT_ADDRESS_SRC] = p;
2227 	export_address(&p, (struct sockaddr *) &sa->tdb_src);
2228 
2229 	headers[SADB_EXT_ADDRESS_DST] = p;
2230 	export_address(&p, (struct sockaddr *) &sa->tdb_dst);
2231 
2232 	if ((rval = pfkeyv2_sendmessage(headers, PFKEYV2_SENDMESSAGE_BROADCAST,
2233 	    NULL, 0, 0, sa->tdb_rdomain)) != 0)
2234 		goto ret;
2235 
2236 	rval = 0;
2237 
2238  ret:
2239 	if (buffer != NULL) {
2240 		bzero(buffer, i);
2241 		free(buffer, M_PFKEY, 0);
2242 	}
2243 
2244 	return (rval);
2245 }
2246 
2247 struct pfkeyv2_sysctl_walk {
2248 	void		*w_where;
2249 	size_t		 w_len;
2250 	int		 w_op;
2251 	u_int8_t	 w_satype;
2252 };
2253 
2254 int
2255 pfkeyv2_sysctl_walker(struct tdb *sa, void *arg, int last)
2256 {
2257 	struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
2258 	void *buffer = NULL;
2259 	int error = 0;
2260 	int buflen, i;
2261 
2262 	if (w->w_satype != SADB_SATYPE_UNSPEC &&
2263 	    w->w_satype != sa->tdb_satype)
2264 		return (0);
2265 
2266 	if (w->w_where) {
2267 		void *headers[SADB_EXT_MAX+1];
2268 		struct sadb_msg msg;
2269 
2270 		bzero(headers, sizeof(headers));
2271 		if ((error = pfkeyv2_get(sa, headers, &buffer, &buflen)) != 0)
2272 			goto done;
2273 		if (w->w_len < sizeof(msg) + buflen) {
2274 			error = ENOMEM;
2275 			goto done;
2276 		}
2277 		/* prepend header */
2278 		bzero(&msg, sizeof(msg));
2279 		msg.sadb_msg_version = PF_KEY_V2;
2280 		msg.sadb_msg_satype = sa->tdb_satype;
2281 		msg.sadb_msg_type = SADB_DUMP;
2282 		msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t);
2283 		if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0)
2284 			goto done;
2285 		w->w_where += sizeof(msg);
2286 		w->w_len -= sizeof(msg);
2287 		/* set extension type */
2288 		for (i = 1; i <= SADB_EXT_MAX; i++)
2289 			if (headers[i])
2290 				((struct sadb_ext *)
2291 				    headers[i])->sadb_ext_type = i;
2292 		if ((error = copyout(buffer, w->w_where, buflen)) != 0)
2293 			goto done;
2294 		w->w_where += buflen;
2295 		w->w_len -= buflen;
2296 	} else {
2297 		if ((error = pfkeyv2_get(sa, NULL, NULL, &buflen)) != 0)
2298 			return (error);
2299 		w->w_len += buflen;
2300 		w->w_len += sizeof(struct sadb_msg);
2301 	}
2302 
2303 done:
2304 	if (buffer)
2305 		free(buffer, M_PFKEY, 0);
2306 	return (error);
2307 }
2308 
2309 int
2310 pfkeyv2_dump_policy(struct ipsec_policy *ipo, void **headers, void **buffer,
2311     int *lenp)
2312 {
2313 	struct sadb_ident *ident;
2314 	int i, rval, perm;
2315 	void *p;
2316 
2317 	/* Find how much space we need. */
2318 	i = 2 * sizeof(struct sadb_protocol);
2319 
2320 	/* We'll need four of them: src, src mask, dst, dst mask. */
2321 	switch (ipo->ipo_addr.sen_type) {
2322 #ifdef INET
2323 	case SENT_IP4:
2324 		i += 4 * PADUP(sizeof(struct sockaddr_in));
2325 		i += 4 * sizeof(struct sadb_address);
2326 		break;
2327 #endif /* INET */
2328 #ifdef INET6
2329 	case SENT_IP6:
2330 		i += 4 * PADUP(sizeof(struct sockaddr_in6));
2331 		i += 4 * sizeof(struct sadb_address);
2332 		break;
2333 #endif /* INET6 */
2334 	default:
2335 		return (EINVAL);
2336 	}
2337 
2338 	/* Local address, might be zeroed. */
2339 	switch (ipo->ipo_src.sa.sa_family) {
2340 	case 0:
2341 		break;
2342 #ifdef INET
2343 	case AF_INET:
2344 		i += PADUP(sizeof(struct sockaddr_in));
2345 		i += sizeof(struct sadb_address);
2346 		break;
2347 #endif /* INET */
2348 #ifdef INET6
2349 	case AF_INET6:
2350 		i += PADUP(sizeof(struct sockaddr_in6));
2351 		i += sizeof(struct sadb_address);
2352 		break;
2353 #endif /* INET6 */
2354 	default:
2355 		return (EINVAL);
2356 	}
2357 
2358 	/* Remote address, might be zeroed. XXX ??? */
2359 	switch (ipo->ipo_dst.sa.sa_family) {
2360 	case 0:
2361 		break;
2362 #ifdef INET
2363 	case AF_INET:
2364 		i += PADUP(sizeof(struct sockaddr_in));
2365 		i += sizeof(struct sadb_address);
2366 		break;
2367 #endif /* INET */
2368 #ifdef INET6
2369 	case AF_INET6:
2370 		i += PADUP(sizeof(struct sockaddr_in6));
2371 		i += sizeof(struct sadb_address);
2372 		break;
2373 #endif /* INET6 */
2374 	default:
2375 		return (EINVAL);
2376 	}
2377 
2378 	if (ipo->ipo_srcid)
2379 		i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
2380 	if (ipo->ipo_dstid)
2381 		i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
2382 
2383 	if (lenp)
2384 		*lenp = i;
2385 
2386 	if (buffer == NULL) {
2387 		rval = 0;
2388 		goto ret;
2389 	}
2390 
2391 	if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) {
2392 		rval = ENOMEM;
2393 		goto ret;
2394 	} else
2395 		*buffer = p;
2396 
2397 	/* Local address. */
2398 	if (ipo->ipo_src.sa.sa_family) {
2399 		headers[SADB_EXT_ADDRESS_SRC] = p;
2400 		export_address(&p, (struct sockaddr *)&ipo->ipo_src);
2401 	}
2402 
2403 	/* Remote address. */
2404 	if (ipo->ipo_dst.sa.sa_family) {
2405 		headers[SADB_EXT_ADDRESS_DST] = p;
2406 		export_address(&p, (struct sockaddr *)&ipo->ipo_dst);
2407 	}
2408 
2409 	/* Get actual flow. */
2410 	export_flow(&p, ipo->ipo_type, &ipo->ipo_addr, &ipo->ipo_mask,
2411 	    headers);
2412 
2413 	/* Add ids only when we are root. */
2414 	perm = suser(curproc, 0);
2415 	if (perm == 0 && ipo->ipo_srcid) {
2416 		headers[SADB_EXT_IDENTITY_SRC] = p;
2417 		p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
2418 		ident = (struct sadb_ident *)headers[SADB_EXT_IDENTITY_SRC];
2419 		ident->sadb_ident_len = (sizeof(struct sadb_ident) +
2420 		    PADUP(ipo->ipo_srcid->ref_len)) / sizeof(uint64_t);
2421 		ident->sadb_ident_type = ipo->ipo_srcid->ref_type;
2422 		bcopy(ipo->ipo_srcid + 1, headers[SADB_EXT_IDENTITY_SRC] +
2423 		    sizeof(struct sadb_ident), ipo->ipo_srcid->ref_len);
2424 	}
2425 	if (perm == 0 && ipo->ipo_dstid) {
2426 		headers[SADB_EXT_IDENTITY_DST] = p;
2427 		p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
2428 		ident = (struct sadb_ident *)headers[SADB_EXT_IDENTITY_DST];
2429 		ident->sadb_ident_len = (sizeof(struct sadb_ident) +
2430 		    PADUP(ipo->ipo_dstid->ref_len)) / sizeof(uint64_t);
2431 		ident->sadb_ident_type = ipo->ipo_dstid->ref_type;
2432 		bcopy(ipo->ipo_dstid + 1, headers[SADB_EXT_IDENTITY_DST] +
2433 		    sizeof(struct sadb_ident), ipo->ipo_dstid->ref_len);
2434 	}
2435 
2436 	rval = 0;
2437 ret:
2438 	return (rval);
2439 }
2440 
2441 /*
2442  * Caller is responsible for setting at least splsoftnet().
2443  */
2444 int
2445 pfkeyv2_ipo_walk(u_int rdomain, int (*walker)(struct ipsec_policy *, void *),
2446     void *arg)
2447 {
2448 	int rval = 0;
2449 	struct ipsec_policy *ipo;
2450 
2451 	TAILQ_FOREACH(ipo, &ipsec_policy_head, ipo_list) {
2452 		if (ipo->ipo_rdomain != rdomain)
2453 			continue;
2454 		rval = walker(ipo, (void *)arg);
2455 	}
2456 	return (rval);
2457 }
2458 
2459 int
2460 pfkeyv2_sysctl_policydumper(struct ipsec_policy *ipo, void *arg)
2461 {
2462 	struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
2463 	void *buffer = 0;
2464 	int i, buflen, error = 0;
2465 
2466 	/* Do not dump policies attached to a socket. */
2467 	if (ipo->ipo_flags & IPSP_POLICY_SOCKET)
2468 		return (0);
2469 
2470 	if (w->w_where) {
2471 		void *headers[SADB_EXT_MAX + 1];
2472 		struct sadb_msg msg;
2473 
2474 		bzero(headers, sizeof(headers));
2475 		if ((error = pfkeyv2_dump_policy(ipo, headers, &buffer,
2476 		    &buflen)) != 0)
2477 			goto done;
2478 		if (w->w_len < buflen) {
2479 			error = ENOMEM;
2480 			goto done;
2481 		}
2482 		/* prepend header */
2483 		bzero(&msg, sizeof(msg));
2484 		msg.sadb_msg_version = PF_KEY_V2;
2485 		if (ipo->ipo_sproto == IPPROTO_ESP)
2486 			msg.sadb_msg_satype = SADB_SATYPE_ESP;
2487 		else if (ipo->ipo_sproto == IPPROTO_AH)
2488 			msg.sadb_msg_satype = SADB_SATYPE_AH;
2489 		else if (ipo->ipo_sproto == IPPROTO_IPCOMP)
2490 			msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
2491 		else if (ipo->ipo_sproto == IPPROTO_IPIP)
2492 			msg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
2493 		msg.sadb_msg_type = SADB_X_SPDDUMP;
2494 		msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t);
2495 		if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0)
2496 			goto done;
2497 		w->w_where += sizeof(msg);
2498 		w->w_len -= sizeof(msg);
2499 		/* set extension type */
2500 		for (i = 1; i < SADB_EXT_MAX; i++)
2501 			if (headers[i])
2502 				((struct sadb_ext *)
2503 				    headers[i])->sadb_ext_type = i;
2504 		if ((error = copyout(buffer, w->w_where, buflen)) != 0)
2505 			goto done;
2506 		w->w_where += buflen;
2507 		w->w_len -= buflen;
2508 	} else {
2509 		if ((error = pfkeyv2_dump_policy(ipo, NULL, NULL,
2510 		    &buflen)) != 0)
2511 			goto done;
2512 		w->w_len += buflen;
2513 		w->w_len += sizeof(struct sadb_msg);
2514 	}
2515 
2516 done:
2517 	if (buffer)
2518 		free(buffer, M_PFKEY, 0);
2519 	return (error);
2520 }
2521 
2522 int
2523 pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2524     void *new, size_t newlen)
2525 {
2526 	struct pfkeyv2_sysctl_walk w;
2527 	int s, error = EINVAL;
2528 	u_int rdomain;
2529 
2530 	if (new)
2531 		return (EPERM);
2532 	if (namelen < 1)
2533 		return (EINVAL);
2534 	w.w_op = name[0];
2535 	w.w_satype = name[1];
2536 	w.w_where = oldp;
2537 	w.w_len = oldp ? *oldlenp : 0;
2538 
2539 	rdomain = rtable_l2(curproc->p_p->ps_rtableid);
2540 
2541 	switch(w.w_op) {
2542 	case NET_KEY_SADB_DUMP:
2543 		if ((error = suser(curproc, 0)) != 0)
2544 			return (error);
2545 		s = splsoftnet();
2546 		error = tdb_walk(rdomain, pfkeyv2_sysctl_walker, &w);
2547 		splx(s);
2548 		if (oldp)
2549 			*oldlenp = w.w_where - oldp;
2550 		else
2551 			*oldlenp = w.w_len;
2552 		break;
2553 
2554 	case NET_KEY_SPD_DUMP:
2555 		s = splsoftnet();
2556 		error = pfkeyv2_ipo_walk(rdomain,
2557 		    pfkeyv2_sysctl_policydumper, &w);
2558 		splx(s);
2559 		if (oldp)
2560 			*oldlenp = w.w_where - oldp;
2561 		else
2562 			*oldlenp = w.w_len;
2563 		break;
2564 	}
2565 
2566 	return (error);
2567 }
2568 
2569 int
2570 pfkeyv2_init(void)
2571 {
2572 	int rval;
2573 
2574 	bzero(&pfkeyv2_version, sizeof(struct pfkey_version));
2575 	pfkeyv2_version.protocol = PFKEYV2_PROTOCOL;
2576 	pfkeyv2_version.create = &pfkeyv2_create;
2577 	pfkeyv2_version.release = &pfkeyv2_release;
2578 	pfkeyv2_version.send = &pfkeyv2_send;
2579 	pfkeyv2_version.sysctl = &pfkeyv2_sysctl;
2580 
2581 	rval = pfkey_register(&pfkeyv2_version);
2582 	return (rval);
2583 }
2584 
2585 int
2586 pfkeyv2_cleanup(void)
2587 {
2588 	pfkey_unregister(&pfkeyv2_version);
2589 	return (0);
2590 }
2591