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