xref: /titanic_50/usr/src/uts/common/inet/ip/sadb.c (revision 8ad60789b9913d5b2118fe76d8cd7a661d8ae8b6)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/types.h>
30 #include <sys/stream.h>
31 #include <sys/stropts.h>
32 #include <sys/ddi.h>
33 #include <sys/debug.h>
34 #include <sys/cmn_err.h>
35 #include <sys/stream.h>
36 #include <sys/strlog.h>
37 #include <sys/kmem.h>
38 #include <sys/sunddi.h>
39 #include <sys/tihdr.h>
40 #include <sys/atomic.h>
41 #include <sys/socket.h>
42 #include <sys/sysmacros.h>
43 #include <sys/crypto/common.h>
44 #include <sys/crypto/api.h>
45 #include <sys/zone.h>
46 #include <netinet/in.h>
47 #include <net/if.h>
48 #include <net/pfkeyv2.h>
49 #include <inet/common.h>
50 #include <netinet/ip6.h>
51 #include <inet/ip.h>
52 #include <inet/ip6.h>
53 #include <inet/ipsec_info.h>
54 #include <inet/ipsec_impl.h>
55 #include <inet/tcp.h>
56 #include <inet/sadb.h>
57 #include <inet/ipsecah.h>
58 #include <inet/ipsecesp.h>
59 #include <sys/random.h>
60 #include <sys/dlpi.h>
61 #include <sys/iphada.h>
62 #include <inet/ip_if.h>
63 #include <inet/ipdrop.h>
64 #include <inet/ipclassifier.h>
65 #include <inet/sctp_ip.h>
66 
67 /*
68  * This source file contains Security Association Database (SADB) common
69  * routines.  They are linked in with the AH module.  Since AH has no chance
70  * of falling under export control, it was safe to link it in there.
71  */
72 
73 /* Packet dropper for generic SADB drops. */
74 static ipdropper_t sadb_dropper;
75 
76 static mblk_t *sadb_extended_acquire(ipsec_selector_t *, ipsec_policy_t *,
77     ipsec_action_t *, uint32_t, uint32_t);
78 static void sadb_ill_df(ill_t *, mblk_t *, isaf_t *, int, boolean_t);
79 static ipsa_t *sadb_torch_assoc(isaf_t *, ipsa_t *, boolean_t, mblk_t **);
80 static void sadb_drain_torchq(queue_t *q, mblk_t *);
81 
82 static time_t sadb_add_time(time_t base, uint64_t delta);
83 
84 #define	SET_EXPIRE(sa, delta, exp) {				\
85 	if (((sa)->ipsa_ ## delta) != 0) {				\
86 		(sa)->ipsa_ ## exp = sadb_add_time((sa)->ipsa_addtime,	\
87 			(sa)->ipsa_ ## delta);				\
88 	}								\
89 }
90 
91 #define	UPDATE_EXPIRE(sa, delta, exp) {					\
92 	if (((sa)->ipsa_ ## delta) != 0) {				\
93 		time_t tmp = sadb_add_time((sa)->ipsa_usetime,		\
94 			(sa)->ipsa_ ## delta);				\
95 		if (((sa)->ipsa_ ## exp) == 0)				\
96 			(sa)->ipsa_ ## exp = tmp;			\
97 		else							\
98 			(sa)->ipsa_ ## exp = 				\
99 			    MIN((sa)->ipsa_ ## exp, tmp); 		\
100 	}								\
101 }
102 
103 
104 /* wrap the macro so we can pass it as a function pointer */
105 void
106 sadb_sa_refrele(void *target)
107 {
108 	IPSA_REFRELE(((ipsa_t *)target));
109 }
110 
111 /*
112  * We presume that sizeof (long) == sizeof (time_t) and that time_t is
113  * a signed type.
114  */
115 #define	TIME_MAX LONG_MAX
116 
117 /*
118  * PF_KEY gives us lifetimes in uint64_t seconds.  We presume that
119  * time_t is defined to be a signed type with the same range as
120  * "long".  On ILP32 systems, we thus run the risk of wrapping around
121  * at end of time, as well as "overwrapping" the clock back around
122  * into a seemingly valid but incorrect future date earlier than the
123  * desired expiration.
124  *
125  * In order to avoid odd behavior (either negative lifetimes or loss
126  * of high order bits) when someone asks for bizarrely long SA
127  * lifetimes, we do a saturating add for expire times.
128  *
129  * We presume that ILP32 systems will be past end of support life when
130  * the 32-bit time_t overflows (a dangerous assumption, mind you..).
131  *
132  * On LP64, 2^64 seconds are about 5.8e11 years, at which point we
133  * will hopefully have figured out clever ways to avoid the use of
134  * fixed-sized integers in computation.
135  */
136 static time_t
137 sadb_add_time(time_t base, uint64_t delta)
138 {
139 	time_t sum;
140 
141 	/*
142 	 * Clip delta to the maximum possible time_t value to
143 	 * prevent "overwrapping" back into a shorter-than-desired
144 	 * future time.
145 	 */
146 	if (delta > TIME_MAX)
147 		delta = TIME_MAX;
148 	/*
149 	 * This sum may still overflow.
150 	 */
151 	sum = base + delta;
152 
153 	/*
154 	 * .. so if the result is less than the base, we overflowed.
155 	 */
156 	if (sum < base)
157 		sum = TIME_MAX;
158 
159 	return (sum);
160 }
161 
162 /*
163  * Callers of this function have already created a working security
164  * association, and have found the appropriate table & hash chain.  All this
165  * function does is check duplicates, and insert the SA.  The caller needs to
166  * hold the hash bucket lock and increment the refcnt before insertion.
167  *
168  * Return 0 if success, EEXIST if collision.
169  */
170 int
171 sadb_insertassoc(ipsa_t *ipsa, isaf_t *bucket)
172 {
173 	ipsa_t **ptpn = NULL;
174 	ipsa_t *walker;
175 	boolean_t unspecsrc;
176 
177 	ASSERT(MUTEX_HELD(&bucket->isaf_lock));
178 
179 	unspecsrc = IPSA_IS_ADDR_UNSPEC(ipsa->ipsa_srcaddr, ipsa->ipsa_addrfam);
180 
181 	walker = bucket->isaf_ipsa;
182 	ASSERT(walker == NULL || ipsa->ipsa_addrfam == walker->ipsa_addrfam);
183 
184 	/*
185 	 * Find insertion point (pointed to with **ptpn).  Insert at the head
186 	 * of the list unless there's an unspecified source address, then
187 	 * insert it after the last SA with a specified source address.
188 	 *
189 	 * BTW, you'll have to walk the whole chain, matching on {DST, SPI}
190 	 * checking for collisions.
191 	 */
192 
193 	while (walker != NULL) {
194 		if (IPSA_ARE_ADDR_EQUAL(walker->ipsa_dstaddr,
195 		    ipsa->ipsa_dstaddr, ipsa->ipsa_addrfam)) {
196 			if (walker->ipsa_spi == ipsa->ipsa_spi)
197 				return (EEXIST);
198 
199 			mutex_enter(&walker->ipsa_lock);
200 			if (ipsa->ipsa_state == IPSA_STATE_MATURE &&
201 			    (walker->ipsa_flags & IPSA_F_USED) &&
202 			    ((walker->ipsa_unique_id &
203 				walker->ipsa_unique_mask) ==
204 				(ipsa->ipsa_unique_id &
205 				    ipsa->ipsa_unique_mask))) {
206 				walker->ipsa_flags |= IPSA_F_CINVALID;
207 			}
208 			mutex_exit(&walker->ipsa_lock);
209 		}
210 
211 		if (ptpn == NULL && unspecsrc) {
212 			if (IPSA_IS_ADDR_UNSPEC(walker->ipsa_srcaddr,
213 			    walker->ipsa_addrfam))
214 				ptpn = walker->ipsa_ptpn;
215 			else if (walker->ipsa_next == NULL)
216 				ptpn = &walker->ipsa_next;
217 		}
218 
219 		walker = walker->ipsa_next;
220 	}
221 
222 	if (ptpn == NULL)
223 		ptpn = &bucket->isaf_ipsa;
224 	ipsa->ipsa_next = *ptpn;
225 	ipsa->ipsa_ptpn = ptpn;
226 	if (ipsa->ipsa_next != NULL)
227 		ipsa->ipsa_next->ipsa_ptpn = &ipsa->ipsa_next;
228 	*ptpn = ipsa;
229 	ipsa->ipsa_linklock = &bucket->isaf_lock;
230 
231 	return (0);
232 }
233 
234 /*
235  * Free a security association.  Its reference count is 0, which means
236  * I must free it.  The SA must be unlocked and must not be linked into
237  * any fanout list.
238  */
239 static void
240 sadb_freeassoc(ipsa_t *ipsa)
241 {
242 	ASSERT(!MUTEX_HELD(&ipsa->ipsa_lock));
243 	ASSERT(ipsa->ipsa_refcnt == 0);
244 	ASSERT(ipsa->ipsa_next == NULL);
245 	ASSERT(ipsa->ipsa_ptpn == NULL);
246 
247 	ip_drop_packet(sadb_clear_lpkt(ipsa), B_TRUE, NULL, NULL,
248 	    &ipdrops_sadb_inlarval_timeout, &sadb_dropper);
249 
250 	mutex_enter(&ipsa->ipsa_lock);
251 
252 	if (ipsa->ipsa_natt_ka_timer != 0)
253 		(void) quntimeout(ipsa->ipsa_natt_q, ipsa->ipsa_natt_ka_timer);
254 
255 	ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_AUTH);
256 	ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_ENCR);
257 	mutex_exit(&ipsa->ipsa_lock);
258 
259 	/* bzero() these fields for paranoia's sake. */
260 	if (ipsa->ipsa_authkey != NULL) {
261 		bzero(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
262 		kmem_free(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
263 	}
264 	if (ipsa->ipsa_encrkey != NULL) {
265 		bzero(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
266 		kmem_free(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
267 	}
268 	if (ipsa->ipsa_src_cid != NULL) {
269 		IPSID_REFRELE(ipsa->ipsa_src_cid);
270 	}
271 	if (ipsa->ipsa_dst_cid != NULL) {
272 		IPSID_REFRELE(ipsa->ipsa_dst_cid);
273 	}
274 	if (ipsa->ipsa_proxy_cid != NULL) {
275 		IPSID_REFRELE(ipsa->ipsa_proxy_cid);
276 	}
277 	if (ipsa->ipsa_integ != NULL)
278 		kmem_free(ipsa->ipsa_integ, ipsa->ipsa_integlen);
279 	if (ipsa->ipsa_sens != NULL)
280 		kmem_free(ipsa->ipsa_sens, ipsa->ipsa_senslen);
281 
282 	mutex_destroy(&ipsa->ipsa_lock);
283 	kmem_free(ipsa, sizeof (*ipsa));
284 }
285 
286 /*
287  * Unlink a security association from a hash bucket.  Assume the hash bucket
288  * lock is held, but the association's lock is not.
289  *
290  * Note that we do not bump the bucket's generation number here because
291  * we might not be making a visible change to the set of visible SA's.
292  * All callers MUST bump the bucket's generation number before they unlock
293  * the bucket if they use sadb_unlinkassoc to permanetly remove an SA which
294  * was present in the bucket at the time it was locked.
295  */
296 void
297 sadb_unlinkassoc(ipsa_t *ipsa)
298 {
299 	ASSERT(ipsa->ipsa_linklock != NULL);
300 	ASSERT(MUTEX_HELD(ipsa->ipsa_linklock));
301 
302 	/* These fields are protected by the link lock. */
303 	*(ipsa->ipsa_ptpn) = ipsa->ipsa_next;
304 	if (ipsa->ipsa_next != NULL) {
305 		ipsa->ipsa_next->ipsa_ptpn = ipsa->ipsa_ptpn;
306 		ipsa->ipsa_next = NULL;
307 	}
308 
309 	ipsa->ipsa_ptpn = NULL;
310 
311 	/* This may destroy the SA. */
312 	IPSA_REFRELE(ipsa);
313 }
314 
315 /*
316  * Create a larval security association with the specified SPI.	 All other
317  * fields are zeroed.
318  */
319 static ipsa_t *
320 sadb_makelarvalassoc(uint32_t spi, uint32_t *src, uint32_t *dst, int addrfam)
321 {
322 	ipsa_t *newbie;
323 
324 	/*
325 	 * Allocate...
326 	 */
327 
328 	newbie = (ipsa_t *)kmem_zalloc(sizeof (ipsa_t), KM_NOSLEEP);
329 	if (newbie == NULL) {
330 		/* Can't make new larval SA. */
331 		return (NULL);
332 	}
333 
334 	/* Assigned requested SPI, assume caller does SPI allocation magic. */
335 	newbie->ipsa_spi = spi;
336 
337 	/*
338 	 * Copy addresses...
339 	 */
340 
341 	IPSA_COPY_ADDR(newbie->ipsa_srcaddr, src, addrfam);
342 	IPSA_COPY_ADDR(newbie->ipsa_dstaddr, dst, addrfam);
343 
344 	newbie->ipsa_addrfam = addrfam;
345 
346 	/*
347 	 * Set common initialization values, including refcnt.
348 	 */
349 	mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
350 	newbie->ipsa_state = IPSA_STATE_LARVAL;
351 	newbie->ipsa_refcnt = 1;
352 	newbie->ipsa_freefunc = sadb_freeassoc;
353 
354 	/*
355 	 * There aren't a lot of other common initialization values, as
356 	 * they are copied in from the PF_KEY message.
357 	 */
358 
359 	return (newbie);
360 }
361 
362 /*
363  * Call me to initialize a security association fanout.
364  */
365 static void
366 sadb_init_fanout(isaf_t **tablep, uint_t numentries)
367 {
368 	isaf_t *table;
369 	int i;
370 
371 	table = (isaf_t *)kmem_alloc(numentries * sizeof (*table), KM_SLEEP);
372 	*tablep = table;
373 
374 	for (i = 0; i < numentries; i++) {
375 		mutex_init(&(table[i].isaf_lock), NULL, MUTEX_DEFAULT, NULL);
376 		table[i].isaf_ipsa = NULL;
377 		table[i].isaf_gen = 0;
378 	}
379 }
380 
381 static void
382 sadb_init_acfanout(iacqf_t **tablep, uint_t numentries)
383 {
384 	iacqf_t *table;
385 	int i;
386 
387 	table = (iacqf_t *)kmem_alloc(numentries * sizeof (*table), KM_SLEEP);
388 	*tablep = table;
389 
390 	for (i = 0; i < numentries; i++) {
391 		mutex_init(&(table[i].iacqf_lock), NULL, MUTEX_DEFAULT, NULL);
392 		table[i].iacqf_ipsacq = NULL;
393 	}
394 }
395 
396 /*
397  * call me to initialize an SADB instance.
398  */
399 
400 static void
401 sadb_init(sadb_t *sp)
402 {
403 	sadb_init_fanout(&sp->sdb_of, OUTBOUND_BUCKETS);
404 	sadb_init_fanout(&sp->sdb_if, INBOUND_BUCKETS);
405 	sadb_init_acfanout(&sp->sdb_acq, OUTBOUND_BUCKETS);
406 }
407 
408 /*
409  * Initialize an SADB-pair.
410  */
411 void
412 sadbp_init(sadbp_t *sp, int type)
413 {
414 	sadb_init(&sp->s_v4);
415 	sadb_init(&sp->s_v6);
416 
417 	sp->s_satype = type;
418 
419 	ASSERT((type == SADB_SATYPE_AH) || (type == SADB_SATYPE_ESP));
420 	if (type == SADB_SATYPE_AH)
421 		ip_drop_register(&sadb_dropper, "IPsec SADB");
422 }
423 
424 /*
425  * Deliver a single SADB_DUMP message representing a single SA.  This is
426  * called many times by sadb_dump().
427  *
428  * If the return value of this is ENOBUFS (not the same as ENOMEM), then
429  * the caller should take that as a hint that dupb() on the "original answer"
430  * failed, and that perhaps the caller should try again with a copyb()ed
431  * "original answer".
432  */
433 static int
434 sadb_dump_deliver(queue_t *pfkey_q, mblk_t *original_answer, ipsa_t *ipsa,
435     sadb_msg_t *samsg)
436 {
437 	mblk_t *answer;
438 
439 	answer = dupb(original_answer);
440 	if (answer == NULL)
441 		return (ENOBUFS);
442 	answer->b_cont = sadb_sa2msg(ipsa, samsg);
443 	if (answer->b_cont == NULL) {
444 		freeb(answer);
445 		return (ENOMEM);
446 	}
447 
448 	/* Just do a putnext, and let keysock deal with flow control. */
449 	putnext(pfkey_q, answer);
450 	return (0);
451 }
452 
453 /*
454  * Common function to allocate and prepare a keysock_out_t M_CTL message.
455  */
456 mblk_t *
457 sadb_keysock_out(minor_t serial)
458 {
459 	mblk_t *mp;
460 	keysock_out_t *kso;
461 
462 	mp = allocb(sizeof (ipsec_info_t), BPRI_HI);
463 	if (mp != NULL) {
464 		mp->b_datap->db_type = M_CTL;
465 		mp->b_wptr += sizeof (ipsec_info_t);
466 		kso = (keysock_out_t *)mp->b_rptr;
467 		kso->ks_out_type = KEYSOCK_OUT;
468 		kso->ks_out_len = sizeof (*kso);
469 		kso->ks_out_serial = serial;
470 	}
471 
472 	return (mp);
473 }
474 
475 /*
476  * Perform an SADB_DUMP, spewing out every SA in an array of SA fanouts
477  * to keysock.
478  */
479 static int
480 sadb_dump_fanout(queue_t *pfkey_q, mblk_t *mp, minor_t serial, isaf_t *fanout,
481     int num_entries, boolean_t do_peers)
482 {
483 	int i, error = 0;
484 	mblk_t *original_answer;
485 	ipsa_t *walker;
486 	sadb_msg_t *samsg;
487 
488 	/*
489 	 * For each IPSA hash bucket do:
490 	 *	- Hold the mutex
491 	 *	- Walk each entry, doing an sadb_dump_deliver() on it.
492 	 */
493 	ASSERT(mp->b_cont != NULL);
494 	samsg = (sadb_msg_t *)mp->b_cont->b_rptr;
495 
496 	original_answer = sadb_keysock_out(serial);
497 	if (original_answer == NULL)
498 		return (ENOMEM);
499 
500 	for (i = 0; i < num_entries; i++) {
501 		mutex_enter(&fanout[i].isaf_lock);
502 		for (walker = fanout[i].isaf_ipsa; walker != NULL;
503 		    walker = walker->ipsa_next) {
504 			if (!do_peers && walker->ipsa_haspeer)
505 				continue;
506 			error = sadb_dump_deliver(pfkey_q, original_answer,
507 			    walker, samsg);
508 			if (error == ENOBUFS) {
509 				mblk_t *new_original_answer;
510 
511 				/* Ran out of dupb's.  Try a copyb. */
512 				new_original_answer = copyb(original_answer);
513 				if (new_original_answer == NULL) {
514 					error = ENOMEM;
515 				} else {
516 					freeb(original_answer);
517 					original_answer = new_original_answer;
518 					error = sadb_dump_deliver(pfkey_q,
519 					    original_answer, walker, samsg);
520 				}
521 			}
522 			if (error != 0)
523 				break;	/* out of for loop. */
524 		}
525 		mutex_exit(&fanout[i].isaf_lock);
526 		if (error != 0)
527 			break;	/* out of for loop. */
528 	}
529 
530 	freeb(original_answer);
531 	return (error);
532 }
533 
534 /*
535  * Dump an entire SADB; outbound first, then inbound.
536  */
537 
538 int
539 sadb_dump(queue_t *pfkey_q, mblk_t *mp, minor_t serial, sadb_t *sp)
540 {
541 	int error;
542 
543 	/* Dump outbound */
544 	error = sadb_dump_fanout(pfkey_q, mp, serial, sp->sdb_of,
545 	    OUTBOUND_BUCKETS, B_TRUE);
546 	if (error)
547 		return (error);
548 
549 	/* Dump inbound */
550 	return sadb_dump_fanout(pfkey_q, mp, serial, sp->sdb_if,
551 	    INBOUND_BUCKETS, B_FALSE);
552 }
553 
554 /*
555  * Generic sadb table walker.
556  *
557  * Call "walkfn" for each SA in each bucket in "table"; pass the
558  * bucket, the entry and "cookie" to the callback function.
559  * Take care to ensure that walkfn can delete the SA without screwing
560  * up our traverse.
561  *
562  * The bucket is locked for the duration of the callback, both so that the
563  * callback can just call sadb_unlinkassoc() when it wants to delete something,
564  * and so that no new entries are added while we're walking the list.
565  */
566 static void
567 sadb_walker(isaf_t *table, uint_t numentries,
568     void (*walkfn)(isaf_t *head, ipsa_t *entry, void *cookie),
569     void *cookie)
570 {
571 	int i;
572 	for (i = 0; i < numentries; i++) {
573 		ipsa_t *entry, *next;
574 
575 		mutex_enter(&table[i].isaf_lock);
576 
577 		for (entry = table[i].isaf_ipsa; entry != NULL;
578 		    entry = next) {
579 			next = entry->ipsa_next;
580 			(*walkfn)(&table[i], entry, cookie);
581 		}
582 		mutex_exit(&table[i].isaf_lock);
583 	}
584 }
585 
586 /*
587  * From the given SA, construct a dl_ct_ipsec_key and
588  * a dl_ct_ipsec structures to be sent to the adapter as part
589  * of a DL_CONTROL_REQ.
590  *
591  * ct_sa must point to the storage allocated for the key
592  * structure and must be followed by storage allocated
593  * for the SA information that must be sent to the driver
594  * as part of the DL_CONTROL_REQ request.
595  *
596  * The is_inbound boolean indicates whether the specified
597  * SA is part of an inbound SA table.
598  *
599  * Returns B_TRUE if the corresponding SA must be passed to
600  * a provider, B_FALSE otherwise; frees *mp if it returns B_FALSE.
601  */
602 static boolean_t
603 sadb_req_from_sa(ipsa_t *sa, mblk_t *mp, boolean_t is_inbound)
604 {
605 	dl_ct_ipsec_key_t *keyp;
606 	dl_ct_ipsec_t *sap;
607 	void *ct_sa = mp->b_wptr;
608 
609 	ASSERT(MUTEX_HELD(&sa->ipsa_lock));
610 
611 	keyp = (dl_ct_ipsec_key_t *)(ct_sa);
612 	sap = (dl_ct_ipsec_t *)(keyp + 1);
613 
614 	IPSECHW_DEBUG(IPSECHW_CAPAB, ("sadb_req_from_sa: "
615 	    "is_inbound = %d\n", is_inbound));
616 
617 	/* initialize flag */
618 	sap->sadb_sa_flags = 0;
619 	if (is_inbound) {
620 		sap->sadb_sa_flags |= DL_CT_IPSEC_INBOUND;
621 		/*
622 		 * If an inbound SA has a peer, then mark it has being
623 		 * an outbound SA as well.
624 		 */
625 		if (sa->ipsa_haspeer)
626 			sap->sadb_sa_flags |= DL_CT_IPSEC_OUTBOUND;
627 	} else {
628 		/*
629 		 * If an outbound SA has a peer, then don't send it,
630 		 * since we will send the copy from the inbound table.
631 		 */
632 		if (sa->ipsa_haspeer) {
633 			freemsg(mp);
634 			return (B_FALSE);
635 		}
636 		sap->sadb_sa_flags |= DL_CT_IPSEC_OUTBOUND;
637 	}
638 
639 	keyp->dl_key_spi = sa->ipsa_spi;
640 	bcopy(sa->ipsa_dstaddr, keyp->dl_key_dest_addr,
641 	    DL_CTL_IPSEC_ADDR_LEN);
642 	keyp->dl_key_addr_family = sa->ipsa_addrfam;
643 
644 	sap->sadb_sa_auth = sa->ipsa_auth_alg;
645 	sap->sadb_sa_encrypt = sa->ipsa_encr_alg;
646 
647 	sap->sadb_key_len_a = sa->ipsa_authkeylen;
648 	sap->sadb_key_bits_a = sa->ipsa_authkeybits;
649 	bcopy(sa->ipsa_authkey,
650 	    sap->sadb_key_data_a, sap->sadb_key_len_a);
651 
652 	sap->sadb_key_len_e = sa->ipsa_encrkeylen;
653 	sap->sadb_key_bits_e = sa->ipsa_encrkeybits;
654 	bcopy(sa->ipsa_encrkey,
655 	    sap->sadb_key_data_e, sap->sadb_key_len_e);
656 
657 	mp->b_wptr += sizeof (dl_ct_ipsec_t) + sizeof (dl_ct_ipsec_key_t);
658 	return (B_TRUE);
659 }
660 
661 /*
662  * Called from AH or ESP to format a message which will be used to inform
663  * IPsec-acceleration-capable ills of a SADB change.
664  * (It is not possible to send the message to IP directly from this function
665  * since the SA, if any, is locked during the call).
666  *
667  * dl_operation: DL_CONTROL_REQ operation (add, delete, update, etc)
668  * sa_type: identifies whether the operation applies to AH or ESP
669  *	(must be one of SADB_SATYPE_AH or SADB_SATYPE_ESP)
670  * sa: Pointer to an SA.  Must be non-NULL and locked
671  *	for ADD, DELETE, GET, and UPDATE operations.
672  * This function returns an mblk chain that must be passed to IP
673  * for forwarding to the IPsec capable providers.
674  */
675 mblk_t *
676 sadb_fmt_sa_req(uint_t dl_operation, uint_t sa_type, ipsa_t *sa,
677     boolean_t is_inbound)
678 {
679 	mblk_t *mp;
680 	dl_control_req_t *ctrl;
681 	boolean_t need_key = B_FALSE;
682 	mblk_t *ctl_mp = NULL;
683 	ipsec_ctl_t *ctl;
684 
685 	/*
686 	 * 1 allocate and initialize DL_CONTROL_REQ M_PROTO
687 	 * 2 if a key is needed for the operation
688 	 *    2.1 initialize key
689 	 *    2.2 if a full SA is needed for the operation
690 	 *	2.2.1 initialize full SA info
691 	 * 3 return message; caller will call ill_ipsec_capab_send_all()
692 	 * to send the resulting message to IPsec capable ills.
693 	 */
694 
695 	ASSERT(sa_type == SADB_SATYPE_AH || sa_type == SADB_SATYPE_ESP);
696 
697 	/*
698 	 * Allocate DL_CONTROL_REQ M_PROTO
699 	 * We allocate room for the SA even if it's not needed
700 	 * by some of the operations (for example flush)
701 	 */
702 	mp = allocb(sizeof (dl_control_req_t) +
703 	    sizeof (dl_ct_ipsec_key_t) + sizeof (dl_ct_ipsec_t), BPRI_HI);
704 	if (mp == NULL)
705 		return (NULL);
706 	mp->b_datap->db_type = M_PROTO;
707 
708 	/* initialize dl_control_req_t */
709 	ctrl = (dl_control_req_t *)mp->b_wptr;
710 	ctrl->dl_primitive = DL_CONTROL_REQ;
711 	ctrl->dl_operation = dl_operation;
712 	ctrl->dl_type = sa_type == SADB_SATYPE_AH ? DL_CT_IPSEC_AH :
713 	    DL_CT_IPSEC_ESP;
714 	ctrl->dl_key_offset = sizeof (dl_control_req_t);
715 	ctrl->dl_key_length = sizeof (dl_ct_ipsec_key_t);
716 	ctrl->dl_data_offset = sizeof (dl_control_req_t) +
717 	    sizeof (dl_ct_ipsec_key_t);
718 	ctrl->dl_data_length = sizeof (dl_ct_ipsec_t);
719 	mp->b_wptr += sizeof (dl_control_req_t);
720 
721 	if ((dl_operation == DL_CO_SET) || (dl_operation == DL_CO_DELETE)) {
722 		ASSERT(sa != NULL);
723 		ASSERT(MUTEX_HELD(&sa->ipsa_lock));
724 
725 		need_key = B_TRUE;
726 
727 		/*
728 		 * Initialize key and SA data. Note that for some
729 		 * operations the SA data is ignored by the provider
730 		 * (delete, etc.)
731 		 */
732 		if (!sadb_req_from_sa(sa, mp, is_inbound))
733 			return (NULL);
734 	}
735 
736 	/* construct control message */
737 	ctl_mp = allocb(sizeof (ipsec_ctl_t), BPRI_HI);
738 	if (ctl_mp == NULL) {
739 		cmn_err(CE_WARN, "sadb_fmt_sa_req: allocb failed\n");
740 		freemsg(mp);
741 		return (NULL);
742 	}
743 
744 	ctl_mp->b_datap->db_type = M_CTL;
745 	ctl_mp->b_wptr += sizeof (ipsec_ctl_t);
746 	ctl_mp->b_cont = mp;
747 
748 	ctl = (ipsec_ctl_t *)ctl_mp->b_rptr;
749 	ctl->ipsec_ctl_type = IPSEC_CTL;
750 	ctl->ipsec_ctl_len  = sizeof (ipsec_ctl_t);
751 	ctl->ipsec_ctl_sa_type = sa_type;
752 
753 	if (need_key) {
754 		/*
755 		 * Keep an additional reference on SA, since it will be
756 		 * needed by IP to send control messages corresponding
757 		 * to that SA from its perimeter. IP will do a
758 		 * IPSA_REFRELE when done with the request.
759 		 */
760 		ASSERT(MUTEX_HELD(&sa->ipsa_lock));
761 		IPSA_REFHOLD(sa);
762 		ctl->ipsec_ctl_sa = sa;
763 	} else
764 		ctl->ipsec_ctl_sa = NULL;
765 
766 	return (ctl_mp);
767 }
768 
769 
770 /*
771  * Called by sadb_ill_download() to dump the entries for a specific
772  * fanout table.  For each SA entry in the table passed as argument,
773  * use mp as a template and constructs a full DL_CONTROL message, and
774  * call ill_dlpi_send(), provided by IP, to send the resulting
775  * messages to the ill.
776  */
777 static void
778 sadb_ill_df(ill_t *ill, mblk_t *mp, isaf_t *fanout, int num_entries,
779     boolean_t is_inbound)
780 {
781 	ipsa_t *walker;
782 	mblk_t *nmp, *salist;
783 	int i, error = 0;
784 
785 	IPSECHW_DEBUG(IPSECHW_SADB, ("sadb_ill_df: fanout at 0x%p ne=%d\n",
786 	    (void *)fanout, num_entries));
787 	/*
788 	 * For each IPSA hash bucket do:
789 	 *	- Hold the mutex
790 	 *	- Walk each entry, sending a corresponding request to IP
791 	 *	  for it.
792 	 */
793 	ASSERT(mp->b_datap->db_type == M_PROTO);
794 
795 	for (i = 0; i < num_entries; i++) {
796 		mutex_enter(&fanout[i].isaf_lock);
797 		salist = NULL;
798 
799 		for (walker = fanout[i].isaf_ipsa; walker != NULL;
800 		    walker = walker->ipsa_next) {
801 			IPSECHW_DEBUG(IPSECHW_SADB,
802 			    ("sadb_ill_df: sending SA to ill via IP \n"));
803 			/*
804 			 * Duplicate the template mp passed and
805 			 * complete DL_CONTROL_REQ data.
806 			 * To be more memory efficient, we could use
807 			 * dupb() for the M_CTL and copyb() for the M_PROTO
808 			 * as the M_CTL, since the M_CTL is the same for
809 			 * every SA entry passed down to IP for the same ill.
810 			 *
811 			 * Note that copymsg/copyb ensure that the new mblk
812 			 * is at least as large as the source mblk even if it's
813 			 * not using all its storage -- therefore, nmp
814 			 * has trailing space for sadb_req_from_sa to add
815 			 * the SA-specific bits.
816 			 */
817 			mutex_enter(&walker->ipsa_lock);
818 			if (ipsec_capab_match(ill,
819 			    ill->ill_phyint->phyint_ifindex, ill->ill_isv6,
820 			    walker)) {
821 				nmp = copymsg(mp);
822 				if (nmp == NULL) {
823 					IPSECHW_DEBUG(IPSECHW_SADB,
824 					    ("sadb_ill_df: alloc error\n"));
825 					error = ENOMEM;
826 					mutex_exit(&walker->ipsa_lock);
827 					break;
828 				}
829 				if (sadb_req_from_sa(walker, nmp, is_inbound)) {
830 					nmp->b_next = salist;
831 					salist = nmp;
832 				}
833 			}
834 			mutex_exit(&walker->ipsa_lock);
835 		}
836 		mutex_exit(&fanout[i].isaf_lock);
837 		while (salist != NULL) {
838 			nmp = salist;
839 			salist = nmp->b_next;
840 			nmp->b_next = NULL;
841 			ill_dlpi_send(ill, nmp);
842 		}
843 		if (error != 0)
844 			break;	/* out of for loop. */
845 	}
846 }
847 
848 /*
849  * Called by ill_ipsec_capab_add(). Sends a copy of the SADB of
850  * the type specified by sa_type to the specified ill.
851  *
852  * We call for each fanout table defined by the SADB (one per
853  * protocol). sadb_ill_df() finally calls ill_dlpi_send() for
854  * each SADB entry in order to send a corresponding DL_CONTROL_REQ
855  * message to the ill.
856  */
857 void
858 sadb_ill_download(ill_t *ill, uint_t sa_type)
859 {
860 	mblk_t *protomp;	/* prototype message */
861 	dl_control_req_t *ctrl;
862 	sadbp_t *spp;
863 	sadb_t *sp;
864 	int dlt;
865 
866 	ASSERT(sa_type == SADB_SATYPE_AH || sa_type == SADB_SATYPE_ESP);
867 
868 	/*
869 	 * Allocate and initialize prototype answer. A duplicate for
870 	 * each SA is sent down to the interface.
871 	 */
872 
873 	/* DL_CONTROL_REQ M_PROTO mblk_t */
874 	protomp = allocb(sizeof (dl_control_req_t) +
875 	    sizeof (dl_ct_ipsec_key_t) + sizeof (dl_ct_ipsec_t), BPRI_HI);
876 	if (protomp == NULL)
877 		return;
878 	protomp->b_datap->db_type = M_PROTO;
879 
880 	dlt = (sa_type == SADB_SATYPE_AH) ? DL_CT_IPSEC_AH : DL_CT_IPSEC_ESP;
881 	spp = (sa_type == SADB_SATYPE_ESP) ? &esp_sadb : &ah_sadb;
882 
883 	ctrl = (dl_control_req_t *)protomp->b_wptr;
884 	ctrl->dl_primitive = DL_CONTROL_REQ;
885 	ctrl->dl_operation = DL_CO_SET;
886 	ctrl->dl_type = dlt;
887 	ctrl->dl_key_offset = sizeof (dl_control_req_t);
888 	ctrl->dl_key_length = sizeof (dl_ct_ipsec_key_t);
889 	ctrl->dl_data_offset = sizeof (dl_control_req_t) +
890 	    sizeof (dl_ct_ipsec_key_t);
891 	ctrl->dl_data_length = sizeof (dl_ct_ipsec_t);
892 	protomp->b_wptr += sizeof (dl_control_req_t);
893 
894 	/*
895 	 * then for each SADB entry, we fill out the dl_ct_ipsec_key_t
896 	 * and dl_ct_ipsec_t
897 	 */
898 	sp = ill->ill_isv6 ? &(spp->s_v6) : &(spp->s_v4);
899 	sadb_ill_df(ill, protomp, sp->sdb_of, OUTBOUND_BUCKETS, B_FALSE);
900 	sadb_ill_df(ill, protomp, sp->sdb_if, INBOUND_BUCKETS, B_TRUE);
901 	freemsg(protomp);
902 }
903 
904 /*
905  * Call me to free up a security association fanout.  Use the forever
906  * variable to indicate freeing up the SAs (forever == B_FALSE, e.g.
907  * an SADB_FLUSH message), or destroying everything (forever == B_TRUE,
908  * when a module is unloaded).
909  */
910 static void
911 sadb_destroyer(isaf_t *table, uint_t numentries, boolean_t forever)
912 {
913 	int i;
914 
915 	for (i = 0; i < numentries; i++) {
916 		mutex_enter(&table[i].isaf_lock);
917 		while (table[i].isaf_ipsa != NULL)
918 			sadb_unlinkassoc(table[i].isaf_ipsa);
919 		table[i].isaf_gen++;
920 		mutex_exit(&table[i].isaf_lock);
921 		if (forever)
922 			mutex_destroy(&(table[i].isaf_lock));
923 	}
924 
925 	if (forever)
926 		kmem_free(table, numentries * sizeof (*table));
927 }
928 
929 /*
930  * Entry points to sadb_destroyer().
931  */
932 static void
933 sadb_flush(sadb_t *sp)
934 {
935 	/*
936 	 * Flush out each bucket, one at a time.  Were it not for keysock's
937 	 * enforcement, there would be a subtlety where I could add on the
938 	 * heels of a flush.  With keysock's enforcement, however, this
939 	 * makes ESP's job easy.
940 	 */
941 	sadb_destroyer(sp->sdb_of, OUTBOUND_BUCKETS, B_FALSE);
942 	sadb_destroyer(sp->sdb_if, INBOUND_BUCKETS, B_FALSE);
943 
944 	/* For each acquire, destroy it; leave the bucket mutex alone. */
945 	sadb_destroy_acqlist(sp->sdb_acq, OUTBOUND_BUCKETS, B_FALSE);
946 }
947 
948 static void
949 sadb_destroy(sadb_t *sp)
950 {
951 	sadb_destroyer(sp->sdb_of, OUTBOUND_BUCKETS, B_TRUE);
952 	sadb_destroyer(sp->sdb_if, INBOUND_BUCKETS, B_TRUE);
953 
954 	/* For each acquire, destroy it, including the bucket mutex. */
955 	sadb_destroy_acqlist(sp->sdb_acq, OUTBOUND_BUCKETS, B_TRUE);
956 }
957 
958 static void
959 sadb_send_flush_req(sadbp_t *spp)
960 {
961 	mblk_t *ctl_mp;
962 
963 	/*
964 	 * we've been unplumbed, or never were plumbed; don't go there.
965 	 */
966 	if (spp->s_ip_q == NULL)
967 		return;
968 
969 	/* have IP send a flush msg to the IPsec accelerators */
970 	ctl_mp = sadb_fmt_sa_req(DL_CO_FLUSH, spp->s_satype, NULL, B_TRUE);
971 	if (ctl_mp != NULL)
972 		putnext(spp->s_ip_q, ctl_mp);
973 }
974 
975 void
976 sadbp_flush(sadbp_t *spp)
977 {
978 	sadb_flush(&spp->s_v4);
979 	sadb_flush(&spp->s_v6);
980 
981 	sadb_send_flush_req(spp);
982 }
983 
984 void
985 sadbp_destroy(sadbp_t *spp)
986 {
987 	sadb_destroy(&spp->s_v4);
988 	sadb_destroy(&spp->s_v6);
989 
990 	sadb_send_flush_req(spp);
991 	if (spp->s_satype == SADB_SATYPE_AH)
992 		ip_drop_unregister(&sadb_dropper);
993 }
994 
995 
996 /*
997  * Check hard vs. soft lifetimes.  If there's a reality mismatch (e.g.
998  * soft lifetimes > hard lifetimes) return an appropriate diagnostic for
999  * EINVAL.
1000  */
1001 int
1002 sadb_hardsoftchk(sadb_lifetime_t *hard, sadb_lifetime_t *soft)
1003 {
1004 	if (hard == NULL || soft == NULL)
1005 		return (0);
1006 
1007 	if (hard->sadb_lifetime_allocations != 0 &&
1008 	    soft->sadb_lifetime_allocations != 0 &&
1009 	    hard->sadb_lifetime_allocations < soft->sadb_lifetime_allocations)
1010 		return (SADB_X_DIAGNOSTIC_ALLOC_HSERR);
1011 
1012 	if (hard->sadb_lifetime_bytes != 0 &&
1013 	    soft->sadb_lifetime_bytes != 0 &&
1014 	    hard->sadb_lifetime_bytes < soft->sadb_lifetime_bytes)
1015 		return (SADB_X_DIAGNOSTIC_BYTES_HSERR);
1016 
1017 	if (hard->sadb_lifetime_addtime != 0 &&
1018 	    soft->sadb_lifetime_addtime != 0 &&
1019 	    hard->sadb_lifetime_addtime < soft->sadb_lifetime_addtime)
1020 		return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
1021 
1022 	if (hard->sadb_lifetime_usetime != 0 &&
1023 	    soft->sadb_lifetime_usetime != 0 &&
1024 	    hard->sadb_lifetime_usetime < soft->sadb_lifetime_usetime)
1025 		return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
1026 
1027 	return (0);
1028 }
1029 
1030 /*
1031  * Clone a security association for the purposes of inserting a single SA
1032  * into inbound and outbound tables respectively.
1033  */
1034 static ipsa_t *
1035 sadb_cloneassoc(ipsa_t *ipsa)
1036 {
1037 	ipsa_t *newbie;
1038 	boolean_t error = B_FALSE;
1039 
1040 	ASSERT(!MUTEX_HELD(&(ipsa->ipsa_lock)));
1041 
1042 	newbie = kmem_alloc(sizeof (ipsa_t), KM_NOSLEEP);
1043 	if (newbie == NULL)
1044 		return (NULL);
1045 
1046 	/* Copy over what we can. */
1047 	*newbie = *ipsa;
1048 
1049 	/* bzero and initialize locks, in case *_init() allocates... */
1050 	mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
1051 
1052 	/*
1053 	 * While somewhat dain-bramaged, the most graceful way to
1054 	 * recover from errors is to keep plowing through the
1055 	 * allocations, and getting what I can.  It's easier to call
1056 	 * sadb_freeassoc() on the stillborn clone when all the
1057 	 * pointers aren't pointing to the parent's data.
1058 	 */
1059 
1060 	if (ipsa->ipsa_authkey != NULL) {
1061 		newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
1062 		    KM_NOSLEEP);
1063 		if (newbie->ipsa_authkey == NULL) {
1064 			error = B_TRUE;
1065 		} else {
1066 			bcopy(ipsa->ipsa_authkey, newbie->ipsa_authkey,
1067 			    newbie->ipsa_authkeylen);
1068 
1069 			newbie->ipsa_kcfauthkey.ck_data =
1070 			    newbie->ipsa_authkey;
1071 		}
1072 
1073 		if (newbie->ipsa_amech.cm_param != NULL) {
1074 			newbie->ipsa_amech.cm_param =
1075 			    (char *)&newbie->ipsa_mac_len;
1076 		}
1077 	}
1078 
1079 	if (ipsa->ipsa_encrkey != NULL) {
1080 		newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
1081 		    KM_NOSLEEP);
1082 		if (newbie->ipsa_encrkey == NULL) {
1083 			error = B_TRUE;
1084 		} else {
1085 			bcopy(ipsa->ipsa_encrkey, newbie->ipsa_encrkey,
1086 			    newbie->ipsa_encrkeylen);
1087 
1088 			newbie->ipsa_kcfencrkey.ck_data =
1089 			    newbie->ipsa_encrkey;
1090 		}
1091 	}
1092 
1093 	newbie->ipsa_authtmpl = NULL;
1094 	newbie->ipsa_encrtmpl = NULL;
1095 
1096 	if (ipsa->ipsa_integ != NULL) {
1097 		newbie->ipsa_integ = kmem_alloc(newbie->ipsa_integlen,
1098 		    KM_NOSLEEP);
1099 		if (newbie->ipsa_integ == NULL) {
1100 			error = B_TRUE;
1101 		} else {
1102 			bcopy(ipsa->ipsa_integ, newbie->ipsa_integ,
1103 			    newbie->ipsa_integlen);
1104 		}
1105 	}
1106 
1107 	if (ipsa->ipsa_sens != NULL) {
1108 		newbie->ipsa_sens = kmem_alloc(newbie->ipsa_senslen,
1109 		    KM_NOSLEEP);
1110 		if (newbie->ipsa_sens == NULL) {
1111 			error = B_TRUE;
1112 		} else {
1113 			bcopy(ipsa->ipsa_sens, newbie->ipsa_sens,
1114 			    newbie->ipsa_senslen);
1115 		}
1116 	}
1117 
1118 	if (ipsa->ipsa_src_cid != NULL) {
1119 		newbie->ipsa_src_cid = ipsa->ipsa_src_cid;
1120 		IPSID_REFHOLD(ipsa->ipsa_src_cid);
1121 	}
1122 
1123 	if (ipsa->ipsa_dst_cid != NULL) {
1124 		newbie->ipsa_dst_cid = ipsa->ipsa_dst_cid;
1125 		IPSID_REFHOLD(ipsa->ipsa_dst_cid);
1126 	}
1127 
1128 #if 0 /* XXX PROXY  - Proxy identities not supported yet. */
1129 	if (ipsa->ipsa_proxy_cid != NULL) {
1130 		newbie->ipsa_proxy_cid = ipsa->ipsa_proxy_cid;
1131 		IPSID_REFHOLD(ipsa->ipsa_proxy_cid);
1132 	}
1133 #endif /* XXX PROXY */
1134 
1135 	if (error) {
1136 		sadb_freeassoc(newbie);
1137 		return (NULL);
1138 	}
1139 
1140 	return (newbie);
1141 }
1142 
1143 /*
1144  * Initialize a SADB address extension at the address specified by addrext.
1145  * Return a pointer to the end of the new address extension.
1146  */
1147 static uint8_t *
1148 sadb_make_addr_ext(uint8_t *start, uint8_t *end, uint16_t exttype,
1149     sa_family_t af, uint32_t *addr, uint16_t port, uint8_t proto)
1150 {
1151 	struct sockaddr_in *sin;
1152 	struct sockaddr_in6 *sin6;
1153 	uint8_t *cur = start;
1154 	int addrext_len;
1155 	int sin_len;
1156 	sadb_address_t *addrext	= (sadb_address_t *)cur;
1157 
1158 	if (cur == NULL)
1159 		return (NULL);
1160 
1161 	cur += sizeof (*addrext);
1162 	if (cur > end)
1163 		return (NULL);
1164 
1165 	addrext->sadb_address_proto = proto;
1166 	addrext->sadb_address_prefixlen = 0;
1167 	addrext->sadb_address_reserved = 0;
1168 	addrext->sadb_address_exttype = exttype;
1169 
1170 	switch (af) {
1171 	case AF_INET:
1172 		sin = (struct sockaddr_in *)cur;
1173 		sin_len = sizeof (*sin);
1174 		cur += sin_len;
1175 		if (cur > end)
1176 			return (NULL);
1177 
1178 		sin->sin_family = af;
1179 		bzero(sin->sin_zero, sizeof (sin->sin_zero));
1180 		sin->sin_port = port;
1181 		IPSA_COPY_ADDR(&sin->sin_addr, addr, af);
1182 		break;
1183 	case AF_INET6:
1184 		sin6 = (struct sockaddr_in6 *)cur;
1185 		sin_len = sizeof (*sin6);
1186 		cur += sin_len;
1187 		if (cur > end)
1188 			return (NULL);
1189 
1190 		bzero(sin6, sizeof (*sin6));
1191 		sin6->sin6_family = af;
1192 		sin6->sin6_port = port;
1193 		IPSA_COPY_ADDR(&sin6->sin6_addr, addr, af);
1194 		break;
1195 	}
1196 
1197 	addrext_len = roundup(cur - start, sizeof (uint64_t));
1198 	addrext->sadb_address_len = SADB_8TO64(addrext_len);
1199 
1200 	cur = start + addrext_len;
1201 	if (cur > end)
1202 		cur = NULL;
1203 
1204 	return (cur);
1205 }
1206 
1207 /*
1208  * Construct a key management cookie extension.
1209  */
1210 
1211 static uint8_t *
1212 sadb_make_kmc_ext(uint8_t *cur, uint8_t *end, uint32_t kmp, uint32_t kmc)
1213 {
1214 	sadb_x_kmc_t *kmcext = (sadb_x_kmc_t *)cur;
1215 
1216 	if (cur == NULL)
1217 		return (NULL);
1218 
1219 	cur += sizeof (*kmcext);
1220 
1221 	if (cur > end)
1222 		return (NULL);
1223 
1224 	kmcext->sadb_x_kmc_len = SADB_8TO64(sizeof (*kmcext));
1225 	kmcext->sadb_x_kmc_exttype = SADB_X_EXT_KM_COOKIE;
1226 	kmcext->sadb_x_kmc_proto = kmp;
1227 	kmcext->sadb_x_kmc_cookie = kmc;
1228 	kmcext->sadb_x_kmc_reserved = 0;
1229 
1230 	return (cur);
1231 }
1232 
1233 /*
1234  * Given an original message header with sufficient space following it, and an
1235  * SA, construct a full PF_KEY message with all of the relevant extensions.
1236  * This is mostly used for SADB_GET, and SADB_DUMP.
1237  */
1238 mblk_t *
1239 sadb_sa2msg(ipsa_t *ipsa, sadb_msg_t *samsg)
1240 {
1241 	int alloclen, addrsize, paddrsize, authsize, encrsize;
1242 	int srcidsize, dstidsize;
1243 	sa_family_t fam, pfam;	/* Address family for SADB_EXT_ADDRESS */
1244 				/* src/dst and proxy sockaddrs. */
1245 	/*
1246 	 * The following are pointers into the PF_KEY message this PF_KEY
1247 	 * message creates.
1248 	 */
1249 	sadb_msg_t *newsamsg;
1250 	sadb_sa_t *assoc;
1251 	sadb_lifetime_t *lt;
1252 	sadb_key_t *key;
1253 	sadb_ident_t *ident;
1254 	sadb_sens_t *sens;
1255 	sadb_ext_t *walker;	/* For when we need a generic ext. pointer. */
1256 	mblk_t *mp;
1257 	uint64_t *bitmap;
1258 	uint8_t *cur, *end;
1259 	/* These indicate the presence of the above extension fields. */
1260 	boolean_t soft, hard, proxy, auth, encr, sensinteg, srcid, dstid;
1261 #if 0 /* XXX PROXY see below... */
1262 	boolean_t proxyid, iv;
1263 	int proxyidsize, ivsize;
1264 #endif /* XXX PROXY */
1265 
1266 	/* First off, figure out the allocation length for this message. */
1267 
1268 	/*
1269 	 * Constant stuff.  This includes base, SA, address (src, dst),
1270 	 * and lifetime (current).
1271 	 */
1272 	alloclen = sizeof (sadb_msg_t) + sizeof (sadb_sa_t) +
1273 	    sizeof (sadb_lifetime_t);
1274 
1275 	fam = ipsa->ipsa_addrfam;
1276 	switch (fam) {
1277 	case AF_INET:
1278 		addrsize = roundup(sizeof (struct sockaddr_in) +
1279 		    sizeof (sadb_address_t), sizeof (uint64_t));
1280 		break;
1281 	case AF_INET6:
1282 		addrsize = roundup(sizeof (struct sockaddr_in6) +
1283 		    sizeof (sadb_address_t), sizeof (uint64_t));
1284 		break;
1285 	default:
1286 		return (NULL);
1287 	}
1288 	/*
1289 	 * Allocate TWO address extensions, for source and destination.
1290 	 * (Thus, the * 2.)
1291 	 */
1292 	alloclen += addrsize * 2;
1293 	if (ipsa->ipsa_flags & IPSA_F_NATT_REM)
1294 	    alloclen += addrsize;
1295 	if (ipsa->ipsa_flags & IPSA_F_NATT_LOC)
1296 	    alloclen += addrsize;
1297 
1298 
1299 	/* How 'bout other lifetimes? */
1300 	if (ipsa->ipsa_softaddlt != 0 || ipsa->ipsa_softuselt != 0 ||
1301 	    ipsa->ipsa_softbyteslt != 0 || ipsa->ipsa_softalloc != 0) {
1302 		alloclen += sizeof (sadb_lifetime_t);
1303 		soft = B_TRUE;
1304 	} else {
1305 		soft = B_FALSE;
1306 	}
1307 
1308 	if (ipsa->ipsa_hardaddlt != 0 || ipsa->ipsa_harduselt != 0 ||
1309 	    ipsa->ipsa_hardbyteslt != 0 || ipsa->ipsa_hardalloc != 0) {
1310 		alloclen += sizeof (sadb_lifetime_t);
1311 		hard = B_TRUE;
1312 	} else {
1313 		hard = B_FALSE;
1314 	}
1315 
1316 	/* Proxy address? */
1317 	if (!IPSA_IS_ADDR_UNSPEC(ipsa->ipsa_proxysrc, ipsa->ipsa_proxyfam)) {
1318 		pfam = ipsa->ipsa_proxyfam;
1319 		switch (pfam) {
1320 		case AF_INET6:
1321 			paddrsize = roundup(sizeof (struct sockaddr_in6) +
1322 			    sizeof (sadb_address_t), sizeof (uint64_t));
1323 			break;
1324 		case AF_INET:
1325 			paddrsize = roundup(sizeof (struct sockaddr_in) +
1326 			    sizeof (sadb_address_t), sizeof (uint64_t));
1327 			break;
1328 		default:
1329 			cmn_err(CE_PANIC,
1330 			    "IPsec SADB: Proxy length failure.\n");
1331 			break;
1332 		}
1333 		proxy = B_TRUE;
1334 		alloclen += paddrsize;
1335 	} else {
1336 		proxy = B_FALSE;
1337 	}
1338 
1339 	/* For the following fields, assume that length != 0 ==> stuff */
1340 	if (ipsa->ipsa_authkeylen != 0) {
1341 		authsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_authkeylen,
1342 		    sizeof (uint64_t));
1343 		alloclen += authsize;
1344 		auth = B_TRUE;
1345 	} else {
1346 		auth = B_FALSE;
1347 	}
1348 
1349 	if (ipsa->ipsa_encrkeylen != 0) {
1350 		encrsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_encrkeylen,
1351 		    sizeof (uint64_t));
1352 		alloclen += encrsize;
1353 		encr = B_TRUE;
1354 	} else {
1355 		encr = B_FALSE;
1356 	}
1357 
1358 	/* No need for roundup on sens and integ. */
1359 	if (ipsa->ipsa_integlen != 0 || ipsa->ipsa_senslen != 0) {
1360 		alloclen += sizeof (sadb_key_t) + ipsa->ipsa_integlen +
1361 		    ipsa->ipsa_senslen;
1362 		sensinteg = B_TRUE;
1363 	} else {
1364 		sensinteg = B_FALSE;
1365 	}
1366 
1367 	/*
1368 	 * Must use strlen() here for lengths.	Identities use NULL
1369 	 * pointers to indicate their nonexistence.
1370 	 */
1371 	if (ipsa->ipsa_src_cid != NULL) {
1372 		srcidsize = roundup(sizeof (sadb_ident_t) +
1373 		    strlen(ipsa->ipsa_src_cid->ipsid_cid) + 1,
1374 		    sizeof (uint64_t));
1375 		alloclen += srcidsize;
1376 		srcid = B_TRUE;
1377 	} else {
1378 		srcid = B_FALSE;
1379 	}
1380 
1381 	if (ipsa->ipsa_dst_cid != NULL) {
1382 		dstidsize = roundup(sizeof (sadb_ident_t) +
1383 		    strlen(ipsa->ipsa_dst_cid->ipsid_cid) + 1,
1384 		    sizeof (uint64_t));
1385 		alloclen += dstidsize;
1386 		dstid = B_TRUE;
1387 	} else {
1388 		dstid = B_FALSE;
1389 	}
1390 
1391 #if 0 /* XXX PROXY not yet. */
1392 	if (ipsa->ipsa_proxy_cid != NULL) {
1393 		proxyidsize = roundup(sizeof (sadb_ident_t) +
1394 		    strlen(ipsa->ipsa_proxy_cid->ipsid_cid) + 1,
1395 		    sizeof (uint64_t));
1396 		alloclen += proxyidsize;
1397 		proxyid = B_TRUE;
1398 	} else {
1399 		proxyid = B_FALSE;
1400 	}
1401 #endif /* XXX PROXY */
1402 	if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0))
1403 		alloclen += sizeof (sadb_x_kmc_t);
1404 
1405 	/* Make sure the allocation length is a multiple of 8 bytes. */
1406 	ASSERT((alloclen & 0x7) == 0);
1407 
1408 	/* XXX Possibly make it esballoc, with a bzero-ing free_ftn. */
1409 	mp = allocb(alloclen, BPRI_HI);
1410 	if (mp == NULL)
1411 		return (NULL);
1412 
1413 	mp->b_wptr += alloclen;
1414 	end = mp->b_wptr;
1415 	newsamsg = (sadb_msg_t *)mp->b_rptr;
1416 	*newsamsg = *samsg;
1417 	newsamsg->sadb_msg_len = (uint16_t)SADB_8TO64(alloclen);
1418 
1419 	mutex_enter(&ipsa->ipsa_lock);	/* Since I'm grabbing SA fields... */
1420 
1421 	newsamsg->sadb_msg_satype = ipsa->ipsa_type;
1422 
1423 	assoc = (sadb_sa_t *)(newsamsg + 1);
1424 	assoc->sadb_sa_len = SADB_8TO64(sizeof (*assoc));
1425 	assoc->sadb_sa_exttype = SADB_EXT_SA;
1426 	assoc->sadb_sa_spi = ipsa->ipsa_spi;
1427 	assoc->sadb_sa_replay = ipsa->ipsa_replay_wsize;
1428 	assoc->sadb_sa_state = ipsa->ipsa_state;
1429 	assoc->sadb_sa_auth = ipsa->ipsa_auth_alg;
1430 	assoc->sadb_sa_encrypt = ipsa->ipsa_encr_alg;
1431 	assoc->sadb_sa_flags = ipsa->ipsa_flags;
1432 
1433 	lt = (sadb_lifetime_t *)(assoc + 1);
1434 	lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1435 	lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
1436 	lt->sadb_lifetime_allocations = ipsa->ipsa_alloc;
1437 	lt->sadb_lifetime_bytes = ipsa->ipsa_bytes;
1438 	lt->sadb_lifetime_addtime = ipsa->ipsa_addtime;
1439 	lt->sadb_lifetime_usetime = ipsa->ipsa_usetime;
1440 
1441 	if (hard) {
1442 		lt++;
1443 		lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1444 		lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1445 		lt->sadb_lifetime_allocations = ipsa->ipsa_hardalloc;
1446 		lt->sadb_lifetime_bytes = ipsa->ipsa_hardbyteslt;
1447 		lt->sadb_lifetime_addtime = ipsa->ipsa_hardaddlt;
1448 		lt->sadb_lifetime_usetime = ipsa->ipsa_harduselt;
1449 	}
1450 
1451 	if (soft) {
1452 		lt++;
1453 		lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1454 		lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1455 		lt->sadb_lifetime_allocations = ipsa->ipsa_softalloc;
1456 		lt->sadb_lifetime_bytes = ipsa->ipsa_softbyteslt;
1457 		lt->sadb_lifetime_addtime = ipsa->ipsa_softaddlt;
1458 		lt->sadb_lifetime_usetime = ipsa->ipsa_softuselt;
1459 	}
1460 
1461 	cur = (uint8_t *)(lt + 1);
1462 
1463 	cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, fam,
1464 	    ipsa->ipsa_srcaddr, SA_SRCPORT(ipsa), SA_PROTO(ipsa));
1465 	if (cur == NULL) {
1466 		freemsg(mp);
1467 		mp = NULL;
1468 		goto bail;
1469 	}
1470 
1471 	cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, fam,
1472 	    ipsa->ipsa_dstaddr, SA_DSTPORT(ipsa), SA_PROTO(ipsa));
1473 	if (cur == NULL) {
1474 		freemsg(mp);
1475 		mp = NULL;
1476 		goto bail;
1477 	}
1478 
1479 	if (ipsa->ipsa_flags & IPSA_F_NATT_LOC) {
1480 		cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_LOC,
1481 		    fam, ipsa->ipsa_natt_addr_loc, 0, 0);
1482 		if (cur == NULL) {
1483 			freemsg(mp);
1484 			mp = NULL;
1485 			goto bail;
1486 		}
1487 	}
1488 
1489 	if (ipsa->ipsa_flags & IPSA_F_NATT_REM) {
1490 		cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_REM,
1491 		    fam, ipsa->ipsa_natt_addr_rem, ipsa->ipsa_remote_port,
1492 		    IPPROTO_UDP);
1493 		if (cur == NULL) {
1494 			freemsg(mp);
1495 			mp = NULL;
1496 			goto bail;
1497 		}
1498 	}
1499 
1500 	if (proxy) {
1501 		/*
1502 		 * XXX PROXY When we expand the definition of proxy to include
1503 		 * both inner and outer IP addresses, this will have to
1504 		 * be expanded.
1505 		 */
1506 		cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_PROXY,
1507 		    pfam, ipsa->ipsa_proxysrc, 0, 0);
1508 		if (cur == NULL) {
1509 			freemsg(mp);
1510 			mp = NULL;
1511 			goto bail;
1512 		}
1513 	}
1514 
1515 	if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0)) {
1516 		cur = sadb_make_kmc_ext(cur, end,
1517 		    ipsa->ipsa_kmp, ipsa->ipsa_kmc);
1518 		if (cur == NULL) {
1519 			freemsg(mp);
1520 			mp = NULL;
1521 			goto bail;
1522 		}
1523 	}
1524 
1525 	walker = (sadb_ext_t *)cur;
1526 	if (auth) {
1527 		key = (sadb_key_t *)walker;
1528 		key->sadb_key_len = SADB_8TO64(authsize);
1529 		key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
1530 		key->sadb_key_bits = ipsa->ipsa_authkeybits;
1531 		key->sadb_key_reserved = 0;
1532 		bcopy(ipsa->ipsa_authkey, key + 1, ipsa->ipsa_authkeylen);
1533 		walker = (sadb_ext_t *)((uint64_t *)walker +
1534 		    walker->sadb_ext_len);
1535 	}
1536 
1537 	if (encr) {
1538 		key = (sadb_key_t *)walker;
1539 		key->sadb_key_len = SADB_8TO64(encrsize);
1540 		key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1541 		key->sadb_key_bits = ipsa->ipsa_encrkeybits;
1542 		key->sadb_key_reserved = 0;
1543 		bcopy(ipsa->ipsa_encrkey, key + 1, ipsa->ipsa_encrkeylen);
1544 		walker = (sadb_ext_t *)((uint64_t *)walker +
1545 		    walker->sadb_ext_len);
1546 	}
1547 
1548 	if (srcid) {
1549 		ident = (sadb_ident_t *)walker;
1550 		ident->sadb_ident_len = SADB_8TO64(srcidsize);
1551 		ident->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
1552 		ident->sadb_ident_type = ipsa->ipsa_src_cid->ipsid_type;
1553 		ident->sadb_ident_id = 0;
1554 		ident->sadb_ident_reserved = 0;
1555 		(void) strcpy((char *)(ident + 1),
1556 		    ipsa->ipsa_src_cid->ipsid_cid);
1557 		walker = (sadb_ext_t *)((uint64_t *)walker +
1558 		    walker->sadb_ext_len);
1559 	}
1560 
1561 	if (dstid) {
1562 		ident = (sadb_ident_t *)walker;
1563 		ident->sadb_ident_len = SADB_8TO64(dstidsize);
1564 		ident->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
1565 		ident->sadb_ident_type = ipsa->ipsa_dst_cid->ipsid_type;
1566 		ident->sadb_ident_id = 0;
1567 		ident->sadb_ident_reserved = 0;
1568 		(void) strcpy((char *)(ident + 1),
1569 		    ipsa->ipsa_dst_cid->ipsid_cid);
1570 		walker = (sadb_ext_t *)((uint64_t *)walker +
1571 		    walker->sadb_ext_len);
1572 	}
1573 
1574 #if 0 /* XXX PROXY not yet */
1575 	if (proxyid) {
1576 		ident = (sadb_ident_t *)walker;
1577 		ident->sadb_ident_len = SADB_8TO64(proxyidsize);
1578 		ident->sadb_ident_exttype = SADB_EXT_IDENTITY_PROXY;
1579 		ident->sadb_ident_type = ipsa->ipsa_pcid_type;
1580 		ident->sadb_ident_id = 0;
1581 		ident->sadb_ident_reserved = 0;
1582 		(void) strcpy((char *)(ident + 1), ipsa->ipsa_proxy_cid);
1583 		walker = (sadb_ext_t *)((uint64_t *)walker +
1584 		    walker->sadb_ext_len);
1585 	}
1586 #endif /* XXX PROXY */
1587 
1588 	if (sensinteg) {
1589 		sens = (sadb_sens_t *)walker;
1590 		sens->sadb_sens_len = SADB_8TO64(sizeof (sadb_sens_t *) +
1591 		    ipsa->ipsa_senslen + ipsa->ipsa_integlen);
1592 		sens->sadb_sens_dpd = ipsa->ipsa_dpd;
1593 		sens->sadb_sens_sens_level = ipsa->ipsa_senslevel;
1594 		sens->sadb_sens_integ_level = ipsa->ipsa_integlevel;
1595 		sens->sadb_sens_sens_len = SADB_8TO64(ipsa->ipsa_senslen);
1596 		sens->sadb_sens_integ_len = SADB_8TO64(ipsa->ipsa_integlen);
1597 		sens->sadb_sens_reserved = 0;
1598 		bitmap = (uint64_t *)(sens + 1);
1599 		if (ipsa->ipsa_sens != NULL) {
1600 			bcopy(ipsa->ipsa_sens, bitmap, ipsa->ipsa_senslen);
1601 			bitmap += sens->sadb_sens_sens_len;
1602 		}
1603 		if (ipsa->ipsa_integ != NULL)
1604 			bcopy(ipsa->ipsa_integ, bitmap, ipsa->ipsa_integlen);
1605 		walker = (sadb_ext_t *)((uint64_t *)walker +
1606 		    walker->sadb_ext_len);
1607 	}
1608 
1609 bail:
1610 	/* Pardon any delays... */
1611 	mutex_exit(&ipsa->ipsa_lock);
1612 
1613 	return (mp);
1614 }
1615 
1616 /*
1617  * Strip out key headers or unmarked headers (SADB_EXT_KEY_*, SADB_EXT_UNKNOWN)
1618  * and adjust base message accordingly.
1619  *
1620  * Assume message is pulled up in one piece of contiguous memory.
1621  *
1622  * Say if we start off with:
1623  *
1624  * +------+----+-------------+-----------+---------------+---------------+
1625  * | base | SA | source addr | dest addr | rsrvd. or key | soft lifetime |
1626  * +------+----+-------------+-----------+---------------+---------------+
1627  *
1628  * we will end up with
1629  *
1630  * +------+----+-------------+-----------+---------------+
1631  * | base | SA | source addr | dest addr | soft lifetime |
1632  * +------+----+-------------+-----------+---------------+
1633  */
1634 static void
1635 sadb_strip(sadb_msg_t *samsg)
1636 {
1637 	sadb_ext_t *ext;
1638 	uint8_t *target = NULL;
1639 	uint8_t *msgend;
1640 	int sofar = SADB_8TO64(sizeof (*samsg));
1641 	int copylen;
1642 
1643 	ext = (sadb_ext_t *)(samsg + 1);
1644 	msgend = (uint8_t *)samsg;
1645 	msgend += SADB_64TO8(samsg->sadb_msg_len);
1646 	while ((uint8_t *)ext < msgend) {
1647 		if (ext->sadb_ext_type == SADB_EXT_RESERVED ||
1648 		    ext->sadb_ext_type == SADB_EXT_KEY_AUTH ||
1649 		    ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) {
1650 			/*
1651 			 * Aha!	 I found a header to be erased.
1652 			 */
1653 
1654 			if (target != NULL) {
1655 				/*
1656 				 * If I had a previous header to be erased,
1657 				 * copy over it.  I can get away with just
1658 				 * copying backwards because the target will
1659 				 * always be 8 bytes behind the source.
1660 				 */
1661 				copylen = ((uint8_t *)ext) - (target +
1662 				    SADB_64TO8(
1663 					((sadb_ext_t *)target)->sadb_ext_len));
1664 				ovbcopy(((uint8_t *)ext - copylen), target,
1665 				    copylen);
1666 				target += copylen;
1667 				((sadb_ext_t *)target)->sadb_ext_len =
1668 				    SADB_8TO64(((uint8_t *)ext) - target +
1669 					SADB_64TO8(ext->sadb_ext_len));
1670 			} else {
1671 				target = (uint8_t *)ext;
1672 			}
1673 		} else {
1674 			sofar += ext->sadb_ext_len;
1675 		}
1676 
1677 		ext = (sadb_ext_t *)(((uint64_t *)ext) + ext->sadb_ext_len);
1678 	}
1679 
1680 	ASSERT((uint8_t *)ext == msgend);
1681 
1682 	if (target != NULL) {
1683 		copylen = ((uint8_t *)ext) - (target +
1684 		    SADB_64TO8(((sadb_ext_t *)target)->sadb_ext_len));
1685 		if (copylen != 0)
1686 			ovbcopy(((uint8_t *)ext - copylen), target, copylen);
1687 	}
1688 
1689 	/* Adjust samsg. */
1690 	samsg->sadb_msg_len = (uint16_t)sofar;
1691 
1692 	/* Assume all of the rest is cleared by caller in sadb_pfkey_echo(). */
1693 }
1694 
1695 /*
1696  * AH needs to send an error to PF_KEY.	 Assume mp points to an M_CTL
1697  * followed by an M_DATA with a PF_KEY message in it.  The serial of
1698  * the sending keysock instance is included.
1699  */
1700 void
1701 sadb_pfkey_error(queue_t *pfkey_q, mblk_t *mp, int error, int diagnostic,
1702     uint_t serial)
1703 {
1704 	mblk_t *msg = mp->b_cont;
1705 	sadb_msg_t *samsg;
1706 	keysock_out_t *kso;
1707 
1708 	/*
1709 	 * Enough functions call this to merit a NULL queue check.
1710 	 */
1711 	if (pfkey_q == NULL) {
1712 		freemsg(mp);
1713 		return;
1714 	}
1715 
1716 	ASSERT(msg != NULL);
1717 	ASSERT((mp->b_wptr - mp->b_rptr) == sizeof (ipsec_info_t));
1718 	ASSERT((msg->b_wptr - msg->b_rptr) >= sizeof (sadb_msg_t));
1719 	samsg = (sadb_msg_t *)msg->b_rptr;
1720 	kso = (keysock_out_t *)mp->b_rptr;
1721 
1722 	kso->ks_out_type = KEYSOCK_OUT;
1723 	kso->ks_out_len = sizeof (*kso);
1724 	kso->ks_out_serial = serial;
1725 
1726 	/*
1727 	 * Only send the base message up in the event of an error.
1728 	 * Don't worry about bzero()-ing, because it was probably bogus
1729 	 * anyway.
1730 	 */
1731 	msg->b_wptr = msg->b_rptr + sizeof (*samsg);
1732 	samsg = (sadb_msg_t *)msg->b_rptr;
1733 	samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg));
1734 	samsg->sadb_msg_errno = (uint8_t)error;
1735 	if (diagnostic != SADB_X_DIAGNOSTIC_PRESET)
1736 		samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
1737 
1738 	putnext(pfkey_q, mp);
1739 }
1740 
1741 /*
1742  * Send a successful return packet back to keysock via the queue in pfkey_q.
1743  *
1744  * Often, an SA is associated with the reply message, it's passed in if needed,
1745  * and NULL if not.  BTW, that ipsa will have its refcnt appropriately held,
1746  * and the caller will release said refcnt.
1747  */
1748 void
1749 sadb_pfkey_echo(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
1750     keysock_in_t *ksi, ipsa_t *ipsa)
1751 {
1752 	keysock_out_t *kso;
1753 	mblk_t *mp1;
1754 	sadb_msg_t *newsamsg;
1755 	uint8_t *oldend;
1756 
1757 	ASSERT((mp->b_cont != NULL) &&
1758 	    ((void *)samsg == (void *)mp->b_cont->b_rptr) &&
1759 	    ((void *)mp->b_rptr == (void *)ksi));
1760 
1761 	switch (samsg->sadb_msg_type) {
1762 	case SADB_ADD:
1763 	case SADB_UPDATE:
1764 	case SADB_FLUSH:
1765 	case SADB_DUMP:
1766 		/*
1767 		 * I have all of the message already.  I just need to strip
1768 		 * out the keying material and echo the message back.
1769 		 *
1770 		 * NOTE: for SADB_DUMP, the function sadb_dump() did the
1771 		 * work.  When DUMP reaches here, it should only be a base
1772 		 * message.
1773 		 */
1774 	justecho:
1775 		ASSERT(samsg->sadb_msg_type != SADB_DUMP ||
1776 		    samsg->sadb_msg_len == SADB_8TO64(sizeof (sadb_msg_t)));
1777 
1778 		if (ksi->ks_in_extv[SADB_EXT_KEY_AUTH] != NULL ||
1779 		    ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT] != NULL) {
1780 			sadb_strip(samsg);
1781 			/* Assume PF_KEY message is contiguous. */
1782 			ASSERT(mp->b_cont->b_cont == NULL);
1783 			oldend = mp->b_cont->b_wptr;
1784 			mp->b_cont->b_wptr = mp->b_cont->b_rptr +
1785 			    SADB_64TO8(samsg->sadb_msg_len);
1786 			bzero(mp->b_cont->b_wptr, oldend - mp->b_cont->b_wptr);
1787 		}
1788 		break;
1789 	case SADB_GET:
1790 		/*
1791 		 * Do a lot of work here, because of the ipsa I just found.
1792 		 * First abandon the PF_KEY message, then construct
1793 		 * the new one.
1794 		 */
1795 		mp1 = sadb_sa2msg(ipsa, samsg);
1796 		if (mp1 == NULL) {
1797 			sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1798 			    SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1799 			return;
1800 		}
1801 		freemsg(mp->b_cont);
1802 		mp->b_cont = mp1;
1803 		break;
1804 	case SADB_DELETE:
1805 		if (ipsa == NULL)
1806 			goto justecho;
1807 		/*
1808 		 * Because listening KMds may require more info, treat
1809 		 * DELETE like a special case of GET.
1810 		 */
1811 		mp1 = sadb_sa2msg(ipsa, samsg);
1812 		if (mp1 == NULL) {
1813 			sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1814 			    SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1815 			return;
1816 		}
1817 		newsamsg = (sadb_msg_t *)mp1->b_rptr;
1818 		sadb_strip(newsamsg);
1819 		oldend = mp1->b_wptr;
1820 		mp1->b_wptr = mp1->b_rptr + SADB_64TO8(newsamsg->sadb_msg_len);
1821 		bzero(mp1->b_wptr, oldend - mp1->b_wptr);
1822 		freemsg(mp->b_cont);
1823 		mp->b_cont = mp1;
1824 		break;
1825 	default:
1826 		if (mp != NULL)
1827 			freemsg(mp);
1828 		return;
1829 	}
1830 
1831 	/* ksi is now null and void. */
1832 	kso = (keysock_out_t *)ksi;
1833 	kso->ks_out_type = KEYSOCK_OUT;
1834 	kso->ks_out_len = sizeof (*kso);
1835 	kso->ks_out_serial = ksi->ks_in_serial;
1836 	/* We're ready to send... */
1837 	putnext(pfkey_q, mp);
1838 }
1839 
1840 /*
1841  * Set up a global pfkey_q instance for AH, ESP, or some other consumer.
1842  */
1843 void
1844 sadb_keysock_hello(queue_t **pfkey_qp, queue_t *q, mblk_t *mp,
1845     void (*ager)(void *), timeout_id_t *top, int satype)
1846 {
1847 	keysock_hello_ack_t *kha;
1848 	queue_t *oldq;
1849 
1850 	ASSERT(OTHERQ(q) != NULL);
1851 
1852 	/*
1853 	 * First, check atomically that I'm the first and only keysock
1854 	 * instance.
1855 	 *
1856 	 * Use OTHERQ(q), because qreply(q, mp) == putnext(OTHERQ(q), mp),
1857 	 * and I want this module to say putnext(*_pfkey_q, mp) for PF_KEY
1858 	 * messages.
1859 	 */
1860 
1861 	oldq = casptr((void **)pfkey_qp, NULL, OTHERQ(q));
1862 	if (oldq != NULL) {
1863 		ASSERT(oldq != q);
1864 		cmn_err(CE_WARN, "Danger!  Multiple keysocks on top of %s.\n",
1865 		    (satype == SADB_SATYPE_ESP)? "ESP" : "AH or other");
1866 		freemsg(mp);
1867 		return;
1868 	}
1869 
1870 	kha = (keysock_hello_ack_t *)mp->b_rptr;
1871 	kha->ks_hello_len = sizeof (keysock_hello_ack_t);
1872 	kha->ks_hello_type = KEYSOCK_HELLO_ACK;
1873 	kha->ks_hello_satype = (uint8_t)satype;
1874 
1875 	/*
1876 	 * If we made it past the casptr, then we have "exclusive" access
1877 	 * to the timeout handle.  Fire it off in 4 seconds, because it
1878 	 * just seems like a good interval.
1879 	 */
1880 	*top = qtimeout(*pfkey_qp, ager, NULL, drv_usectohz(4000000));
1881 
1882 	putnext(*pfkey_qp, mp);
1883 }
1884 
1885 /*
1886  * Send IRE_DB_REQ down to IP to get properties of address.
1887  * If I can determine the address, return the proper type.  If an error
1888  * occurs, or if I have to send down an IRE_DB_REQ, return UNKNOWN, and
1889  * the caller will just let go of mp w/o freeing it.
1890  *
1891  * To handle the compatible IPv6 addresses (i.e. ::FFFF:<v4-address>),
1892  * this function will also convert such AF_INET6 addresses into AF_INET
1893  * addresses.
1894  *
1895  * Whomever called the function will handle the return message that IP sends
1896  * in response to the message this function generates.
1897  */
1898 int
1899 sadb_addrcheck(queue_t *ip_q, queue_t *pfkey_q, mblk_t *mp, sadb_ext_t *ext,
1900     uint_t serial)
1901 {
1902 	sadb_address_t *addr = (sadb_address_t *)ext;
1903 	struct sockaddr_in *sin;
1904 	struct sockaddr_in6 *sin6;
1905 	mblk_t *ire_db_req_mp;
1906 	ire_t *ire;
1907 	int diagnostic;
1908 
1909 	ASSERT(ext != NULL);
1910 	ASSERT((ext->sadb_ext_type == SADB_EXT_ADDRESS_SRC) ||
1911 	    (ext->sadb_ext_type == SADB_EXT_ADDRESS_DST) ||
1912 	    (ext->sadb_ext_type == SADB_EXT_ADDRESS_PROXY));
1913 
1914 	ire_db_req_mp = allocb(sizeof (ire_t), BPRI_HI);
1915 	if (ire_db_req_mp == NULL) {
1916 		/* cmn_err(CE_WARN, "sadb_addrcheck: allocb() failed.\n"); */
1917 		sadb_pfkey_error(pfkey_q, mp, ENOMEM, SADB_X_DIAGNOSTIC_NONE,
1918 		    serial);
1919 		return (KS_IN_ADDR_UNKNOWN);
1920 	}
1921 
1922 	ire_db_req_mp->b_datap->db_type = IRE_DB_REQ_TYPE;
1923 	ire_db_req_mp->b_wptr += sizeof (ire_t);
1924 	ire = (ire_t *)ire_db_req_mp->b_rptr;
1925 
1926 	/* Assign both sockaddrs, the compiler will do the right thing. */
1927 	sin = (struct sockaddr_in *)(addr + 1);
1928 	sin6 = (struct sockaddr_in6 *)(addr + 1);
1929 
1930 	switch (sin->sin_family) {
1931 	case AF_INET6:
1932 		/* Because of the longer IPv6 addrs, do check first. */
1933 		if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1934 			if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
1935 				freemsg(ire_db_req_mp);
1936 				return (KS_IN_ADDR_MBCAST);
1937 			}
1938 			if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1939 				freemsg(ire_db_req_mp);
1940 				return (KS_IN_ADDR_UNSPEC);
1941 			}
1942 			ire->ire_ipversion = IPV6_VERSION;
1943 			ire->ire_addr_v6 = sin6->sin6_addr;
1944 			break;	/* Out of switch. */
1945 		}
1946 		/*
1947 		 * Convert to an AF_INET sockaddr.  This means
1948 		 * the return messages will have the extra space, but
1949 		 * have AF_INET sockaddrs instead of AF_INET6.
1950 		 *
1951 		 * Yes, RFC 2367 isn't clear on what to do here w.r.t.
1952 		 * mapped addresses, but since AF_INET6 ::ffff:<v4> is
1953 		 * equal to AF_INET <v4>, it shouldnt be a huge
1954 		 * problem.
1955 		 */
1956 		ASSERT(&sin->sin_port == &sin6->sin6_port);
1957 		sin->sin_family = AF_INET;
1958 		IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr, &sin->sin_addr);
1959 		bzero(&sin->sin_zero, sizeof (sin->sin_zero));
1960 		/* FALLTHRU */
1961 	case AF_INET:
1962 		ire->ire_ipversion = IPV4_VERSION;
1963 		ire->ire_addr = sin->sin_addr.s_addr;
1964 		if (ire->ire_addr == INADDR_ANY) {
1965 			freemsg(ire_db_req_mp);
1966 			return (KS_IN_ADDR_UNSPEC);
1967 		}
1968 		if (CLASSD(ire->ire_addr)) {
1969 			freemsg(ire_db_req_mp);
1970 			return (KS_IN_ADDR_MBCAST);
1971 		}
1972 		break;
1973 	default:
1974 		freemsg(ire_db_req_mp);
1975 
1976 		switch (ext->sadb_ext_type) {
1977 		case SADB_EXT_ADDRESS_SRC:
1978 			diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC_AF;
1979 			break;
1980 		case SADB_EXT_ADDRESS_DST:
1981 			diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
1982 			break;
1983 		case SADB_EXT_ADDRESS_PROXY:
1984 			diagnostic = SADB_X_DIAGNOSTIC_BAD_PROXY_AF;
1985 			break;
1986 			/* There is no default, see above ASSERT. */
1987 		}
1988 
1989 		sadb_pfkey_error(pfkey_q, mp, EINVAL, diagnostic, serial);
1990 		return (KS_IN_ADDR_UNKNOWN);
1991 	}
1992 	ire_db_req_mp->b_cont = mp;
1993 
1994 	ASSERT(ip_q != NULL);
1995 	putnext(ip_q, ire_db_req_mp);
1996 	return (KS_IN_ADDR_UNKNOWN);
1997 }
1998 
1999 /*
2000  * For the case of src == unspecified AF_INET6, and dst == AF_INET, convert
2001  * the source to AF_INET.
2002  */
2003 void
2004 sadb_srcaddrfix(keysock_in_t *ksi)
2005 {
2006 	struct sockaddr_in *src;
2007 	struct sockaddr_in6 *dst;
2008 	sadb_address_t *srcext, *dstext;
2009 
2010 	if (ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC ||
2011 	    ksi->ks_in_dsttype == KS_IN_ADDR_NOTTHERE)
2012 		return;
2013 
2014 	dstext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2015 	dst = (struct sockaddr_in6 *)(dstext + 1);
2016 	srcext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2017 	src = (struct sockaddr_in *)(srcext + 1);
2018 
2019 	/*
2020 	 * If unspecified IPv4 source, but an IPv6 dest, don't bother
2021 	 * fixing, as it should be an error.
2022 	 */
2023 	if (dst->sin6_family == src->sin_family ||
2024 	    src->sin_family == AF_INET)
2025 		return;
2026 
2027 	/* Convert "src" to AF_INET INADDR_ANY. */
2028 	bzero(src, sizeof (*src));
2029 	src->sin_family = AF_INET;
2030 }
2031 
2032 /*
2033  * Set the results in "addrtype", given an IRE as requested by
2034  * sadb_addrcheck().
2035  */
2036 int
2037 sadb_addrset(ire_t *ire)
2038 {
2039 	if ((ire->ire_type & IRE_BROADCAST) ||
2040 	    (ire->ire_ipversion == IPV4_VERSION && CLASSD(ire->ire_addr)) ||
2041 	    (ire->ire_ipversion == IPV6_VERSION &&
2042 		IN6_IS_ADDR_MULTICAST(&(ire->ire_addr_v6))))
2043 		return (KS_IN_ADDR_MBCAST);
2044 	if (ire->ire_type & (IRE_LOCAL | IRE_LOOPBACK))
2045 		return (KS_IN_ADDR_ME);
2046 	return (KS_IN_ADDR_NOTME);
2047 }
2048 
2049 
2050 /*
2051  * Walker callback function to delete sa's based on src/dst address.
2052  * Assumes that we're called with *head locked, no other locks held;
2053  * Conveniently, and not coincidentally, this is both what sadb_walker
2054  * gives us and also what sadb_unlinkassoc expects.
2055  */
2056 
2057 struct sadb_purge_state
2058 {
2059 	uint32_t *src;
2060 	uint32_t *dst;
2061 	sa_family_t af;
2062 	boolean_t inbnd;
2063 	char *sidstr;
2064 	char *didstr;
2065 	uint16_t sidtype;
2066 	uint16_t didtype;
2067 	uint32_t kmproto;
2068 	mblk_t *mq;
2069 };
2070 
2071 static void
2072 sadb_purge_cb(isaf_t *head, ipsa_t *entry, void *cookie)
2073 {
2074 	struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2075 
2076 	ASSERT(MUTEX_HELD(&head->isaf_lock));
2077 
2078 	mutex_enter(&entry->ipsa_lock);
2079 
2080 	if ((entry->ipsa_state == IPSA_STATE_LARVAL) ||
2081 	    (ps->src != NULL &&
2082 		!IPSA_ARE_ADDR_EQUAL(entry->ipsa_srcaddr, ps->src, ps->af)) ||
2083 	    (ps->dst != NULL &&
2084 		!IPSA_ARE_ADDR_EQUAL(entry->ipsa_dstaddr, ps->dst, ps->af)) ||
2085 	    (ps->didstr != NULL &&
2086 		!(ps->didtype == entry->ipsa_dst_cid->ipsid_type &&
2087 		    strcmp(ps->didstr, entry->ipsa_dst_cid->ipsid_cid) == 0)) ||
2088 	    (ps->sidstr != NULL &&
2089 		!(ps->sidtype == entry->ipsa_src_cid->ipsid_type &&
2090 		    strcmp(ps->sidstr, entry->ipsa_src_cid->ipsid_cid) == 0)) ||
2091 	    (ps->kmproto <= SADB_X_KMP_MAX && ps->kmproto != entry->ipsa_kmp)) {
2092 		mutex_exit(&entry->ipsa_lock);
2093 		return;
2094 	}
2095 
2096 	entry->ipsa_state = IPSA_STATE_DEAD;
2097 	(void) sadb_torch_assoc(head, entry, ps->inbnd, &ps->mq);
2098 }
2099 
2100 /*
2101  * Common code to purge an SA with a matching src or dst address.
2102  * Don't kill larval SA's in such a purge.
2103  */
2104 int
2105 sadb_purge_sa(mblk_t *mp, keysock_in_t *ksi, sadb_t *sp,
2106     int *diagnostic, queue_t *pfkey_q, queue_t *ip_q)
2107 {
2108 	sadb_address_t *dstext =
2109 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2110 	sadb_address_t *srcext =
2111 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2112 	sadb_ident_t *dstid =
2113 	    (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
2114 	sadb_ident_t *srcid =
2115 	    (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
2116 	sadb_x_kmc_t *kmc =
2117 	    (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
2118 	struct sockaddr_in *src, *dst;
2119 	struct sockaddr_in6 *src6, *dst6;
2120 	struct sadb_purge_state ps;
2121 
2122 	/*
2123 	 * Don't worry about IPv6 v4-mapped addresses, sadb_addrcheck()
2124 	 * takes care of them.
2125 	 */
2126 
2127 	/* enforced by caller */
2128 	ASSERT((dstext != NULL) || (srcext != NULL));
2129 
2130 	ps.src = NULL;
2131 	ps.dst = NULL;
2132 #ifdef DEBUG
2133 	ps.af = (sa_family_t)-1;
2134 #endif
2135 	ps.mq = NULL;
2136 	ps.sidstr = NULL;
2137 	ps.didstr = NULL;
2138 	ps.kmproto = SADB_X_KMP_MAX + 1;
2139 
2140 	if (dstext != NULL) {
2141 		dst = (struct sockaddr_in *)(dstext + 1);
2142 		ps.af = dst->sin_family;
2143 		if (dst->sin_family == AF_INET6) {
2144 			dst6 = (struct sockaddr_in6 *)dst;
2145 			ps.dst = (uint32_t *)&dst6->sin6_addr;
2146 		} else {
2147 			ps.dst = (uint32_t *)&dst->sin_addr;
2148 		}
2149 	}
2150 
2151 	if (srcext != NULL) {
2152 		src = (struct sockaddr_in *)(srcext + 1);
2153 		ps.af = src->sin_family;
2154 		if (src->sin_family == AF_INET6) {
2155 			src6 = (struct sockaddr_in6 *)(srcext + 1);
2156 			ps.src = (uint32_t *)&src6->sin6_addr;
2157 		} else {
2158 			ps.src = (uint32_t *)&src->sin_addr;
2159 		}
2160 
2161 		if (dstext != NULL) {
2162 			if (src->sin_family != dst->sin_family) {
2163 				*diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2164 				return (EINVAL);
2165 			}
2166 		}
2167 	}
2168 	ASSERT(ps.af != (sa_family_t)-1);
2169 
2170 	if (dstid != NULL) {
2171 		/*
2172 		 * NOTE:  May need to copy string in the future
2173 		 * if the inbound keysock message disappears for some strange
2174 		 * reason.
2175 		 */
2176 		ps.didstr = (char *)(dstid + 1);
2177 		ps.didtype = dstid->sadb_ident_type;
2178 	}
2179 
2180 	if (srcid != NULL) {
2181 		/*
2182 		 * NOTE:  May need to copy string in the future
2183 		 * if the inbound keysock message disappears for some strange
2184 		 * reason.
2185 		 */
2186 		ps.sidstr = (char *)(srcid + 1);
2187 		ps.sidtype = srcid->sadb_ident_type;
2188 	}
2189 
2190 	if (kmc != NULL)
2191 		ps.kmproto = kmc->sadb_x_kmc_proto;
2192 
2193 	/*
2194 	 * This is simple, crude, and effective.
2195 	 * Unimplemented optimizations (TBD):
2196 	 * - we can limit how many places we search based on where we
2197 	 * think the SA is filed.
2198 	 * - if we get a dst address, we can hash based on dst addr to find
2199 	 * the correct bucket in the outbound table.
2200 	 */
2201 	ps.inbnd = B_TRUE;
2202 	sadb_walker(sp->sdb_if, INBOUND_BUCKETS, sadb_purge_cb, &ps);
2203 	ps.inbnd = B_FALSE;
2204 	sadb_walker(sp->sdb_of, OUTBOUND_BUCKETS, sadb_purge_cb, &ps);
2205 
2206 	if (ps.mq != NULL)
2207 		sadb_drain_torchq(ip_q, ps.mq);
2208 
2209 	ASSERT(mp->b_cont != NULL);
2210 	sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
2211 	    NULL);
2212 	return (0);
2213 }
2214 
2215 /*
2216  * Common code to delete/get an SA.
2217  */
2218 int
2219 sadb_delget_sa(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2220     int *diagnostic, queue_t *pfkey_q, boolean_t delete)
2221 {
2222 	sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2223 	sadb_address_t *srcext =
2224 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2225 	sadb_address_t *dstext =
2226 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2227 	struct sockaddr_in *src, *dst;
2228 	struct sockaddr_in6 *src6, *dst6;
2229 	sadb_t *sp;
2230 	ipsa_t *outbound_target, *inbound_target;
2231 	isaf_t *inbound, *outbound;
2232 	uint32_t *srcaddr, *dstaddr;
2233 	mblk_t *torchq = NULL;
2234 	sa_family_t af;
2235 
2236 	if (dstext == NULL) {
2237 		*diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
2238 		return (EINVAL);
2239 	}
2240 	if (assoc == NULL) {
2241 		*diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
2242 		return (EINVAL);
2243 	}
2244 
2245 	/*
2246 	 * Don't worry about IPv6 v4-mapped addresses, sadb_addrcheck()
2247 	 * takes care of them.
2248 	 */
2249 
2250 	dst = (struct sockaddr_in *)(dstext + 1);
2251 	af = dst->sin_family;
2252 	if (af == AF_INET6) {
2253 		sp = &spp->s_v6;
2254 		dst6 = (struct sockaddr_in6 *)dst;
2255 		dstaddr = (uint32_t *)&dst6->sin6_addr;
2256 		if (srcext != NULL) {
2257 			src6 = (struct sockaddr_in6 *)(srcext + 1);
2258 			srcaddr = (uint32_t *)&src6->sin6_addr;
2259 			if (src6->sin6_family != AF_INET6) {
2260 				*diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2261 				return (EINVAL);
2262 			}
2263 		} else {
2264 			srcaddr = ALL_ZEROES_PTR;
2265 		}
2266 
2267 		outbound = &sp->sdb_of[OUTBOUND_HASH_V6(*(uint32_t *)dstaddr)];
2268 	} else {
2269 		sp = &spp->s_v4;
2270 		dstaddr = (uint32_t *)&dst->sin_addr;
2271 		if (srcext != NULL) {
2272 			src = (struct sockaddr_in *)(srcext + 1);
2273 			srcaddr = (uint32_t *)&src->sin_addr;
2274 			if (src->sin_family != AF_INET) {
2275 				*diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2276 				return (EINVAL);
2277 			}
2278 		} else {
2279 			srcaddr = ALL_ZEROES_PTR;
2280 		}
2281 		outbound = &sp->sdb_of[OUTBOUND_HASH_V4(*(uint32_t *)dstaddr)];
2282 	}
2283 
2284 	inbound = &sp->sdb_if[INBOUND_HASH(assoc->sadb_sa_spi)];
2285 
2286 	/* Lock down both buckets. */
2287 	mutex_enter(&outbound->isaf_lock);
2288 	mutex_enter(&inbound->isaf_lock);
2289 
2290 	/* Try outbound first. */
2291 	outbound_target = ipsec_getassocbyspi(outbound, assoc->sadb_sa_spi,
2292 	    srcaddr, dstaddr, af);
2293 
2294 	if (outbound_target == NULL || outbound_target->ipsa_haspeer) {
2295 		inbound_target = ipsec_getassocbyspi(inbound,
2296 		    assoc->sadb_sa_spi, srcaddr, dstaddr, af);
2297 	} else {
2298 		inbound_target = NULL;
2299 	}
2300 
2301 	if (outbound_target == NULL && inbound_target == NULL) {
2302 		mutex_exit(&inbound->isaf_lock);
2303 		mutex_exit(&outbound->isaf_lock);
2304 		return (ESRCH);
2305 	}
2306 
2307 	if (delete) {
2308 		/* At this point, I have one or two SAs to be deleted. */
2309 		if (outbound_target != NULL) {
2310 			mutex_enter(&outbound_target->ipsa_lock);
2311 			outbound_target->ipsa_state = IPSA_STATE_DEAD;
2312 			(void) sadb_torch_assoc(outbound, outbound_target,
2313 			    B_FALSE, &torchq);
2314 		}
2315 
2316 		if (inbound_target != NULL) {
2317 			mutex_enter(&inbound_target->ipsa_lock);
2318 			inbound_target->ipsa_state = IPSA_STATE_DEAD;
2319 			(void) sadb_torch_assoc(inbound, inbound_target,
2320 			    B_TRUE, &torchq);
2321 		}
2322 	}
2323 
2324 	mutex_exit(&inbound->isaf_lock);
2325 	mutex_exit(&outbound->isaf_lock);
2326 
2327 	if (torchq != NULL)
2328 		sadb_drain_torchq(spp->s_ip_q, torchq);
2329 
2330 	/*
2331 	 * Because of the multi-line macro nature of IPSA_REFRELE, keep
2332 	 * them in { }.
2333 	 */
2334 	ASSERT(mp->b_cont != NULL);
2335 	sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
2336 	    (outbound_target != NULL ? outbound_target : inbound_target));
2337 
2338 	if (outbound_target != NULL) {
2339 		IPSA_REFRELE(outbound_target);
2340 	}
2341 	if (inbound_target != NULL) {
2342 		IPSA_REFRELE(inbound_target);
2343 	}
2344 
2345 	return (0);
2346 }
2347 
2348 /*
2349  * Common code to set ipsa_unique_id; used from both add and update paths.
2350  */
2351 static void
2352 sadb_set_unique(ipsa_t *sa, uint8_t proto,
2353     struct sockaddr_in *src, struct sockaddr_in *dst)
2354 {
2355 	/* Assume that ports are in the same place for INET and INET6 */
2356 	uint16_t srcport = src->sin_port;
2357 	uint16_t dstport = dst->sin_port;
2358 
2359 	if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
2360 		srcport = dstport = 0;
2361 	}
2362 
2363 	sa->ipsa_unique_id = SA_UNIQUE_ID(srcport, dstport, proto);
2364 	sa->ipsa_unique_mask = SA_UNIQUE_MASK(srcport, dstport, proto);
2365 	sa->ipsa_flags |= IPSA_F_UNIQUE;
2366 }
2367 
2368 
2369 /*
2370  * Initialize the mechanism parameters associated with an SA.
2371  * These parameters can be shared by multiple packets, which saves
2372  * us from the overhead of consulting the algorithm table for
2373  * each packet.
2374  */
2375 static void
2376 sadb_init_alginfo(ipsa_t *sa)
2377 {
2378 	ipsec_alginfo_t *alg;
2379 
2380 	mutex_enter(&alg_lock);
2381 
2382 	if (sa->ipsa_encrkey != NULL) {
2383 		alg = ipsec_alglists[IPSEC_ALG_ENCR][sa->ipsa_encr_alg];
2384 		if (alg != NULL && ALG_VALID(alg)) {
2385 			sa->ipsa_emech.cm_type = alg->alg_mech_type;
2386 			sa->ipsa_emech.cm_param = NULL;
2387 			sa->ipsa_emech.cm_param_len = 0;
2388 			sa->ipsa_iv_len = alg->alg_datalen;
2389 		} else
2390 			sa->ipsa_emech.cm_type = CRYPTO_MECHANISM_INVALID;
2391 	}
2392 
2393 	if (sa->ipsa_authkey != NULL) {
2394 		alg = ipsec_alglists[IPSEC_ALG_AUTH][sa->ipsa_auth_alg];
2395 		if (alg != NULL && ALG_VALID(alg)) {
2396 			sa->ipsa_amech.cm_type = alg->alg_mech_type;
2397 			sa->ipsa_amech.cm_param = (char *)&sa->ipsa_mac_len;
2398 			sa->ipsa_amech.cm_param_len = sizeof (size_t);
2399 			sa->ipsa_mac_len = (size_t)alg->alg_datalen;
2400 		} else
2401 			sa->ipsa_amech.cm_type = CRYPTO_MECHANISM_INVALID;
2402 	}
2403 
2404 	mutex_exit(&alg_lock);
2405 }
2406 
2407 
2408 /*
2409  * This function is called from consumers that need to insert a fully-grown
2410  * security association into its tables.  This function takes into account that
2411  * SAs can be "inbound", "outbound", or "both".	 The "primary" and "secondary"
2412  * hash bucket parameters are set in order of what the SA will be most of the
2413  * time.  (For example, an SA with an unspecified source, and a multicast
2414  * destination will primarily be an outbound SA.  OTOH, if that destination
2415  * is unicast for this node, then the SA will primarily be inbound.)
2416  *
2417  * It takes a lot of parameters because even if clone is B_FALSE, this needs
2418  * to check both buckets for purposes of collision.
2419  *
2420  * Return 0 upon success.  Return various errnos (ENOMEM, EEXIST) for
2421  * various error conditions.  No need to set samsg->sadb_x_msg_diagnostic with
2422  * additional diagnostic information because ENOMEM and EEXIST are self-
2423  * explanitory.
2424  */
2425 int
2426 sadb_common_add(queue_t *ip_q, queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
2427     keysock_in_t *ksi, isaf_t *primary, isaf_t *secondary,
2428     ipsa_t *newbie, boolean_t clone, boolean_t is_inbound)
2429 {
2430 	ipsa_t *newbie_clone = NULL, *scratch;
2431 	sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2432 	sadb_address_t *srcext =
2433 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2434 	sadb_address_t *dstext =
2435 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2436 	sadb_address_t *proxyext =
2437 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_PROXY];
2438 	sadb_address_t *natt_loc_ext =
2439 	    (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC];
2440 	sadb_address_t *natt_rem_ext =
2441 	    (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM];
2442 	sadb_x_kmc_t *kmcext =
2443 	    (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
2444 	sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
2445 	sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
2446 #if 0
2447 	/*
2448 	 * XXXMLS - When Trusted Solaris or Multi-Level Secure functionality
2449 	 * comes to ON, examine these if 0'ed fragments.  Look for XXXMLS.
2450 	 */
2451 	sadb_sens_t *sens = (sadb_sens_t *);
2452 #endif
2453 	struct sockaddr_in *src, *dst, *proxy, *natt_loc, *natt_rem;
2454 	struct sockaddr_in6 *src6, *dst6, *proxy6, *natt_loc6, *natt_rem6;
2455 	sadb_lifetime_t *soft =
2456 	    (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
2457 	sadb_lifetime_t *hard =
2458 	    (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
2459 	sa_family_t af;
2460 	int error = 0;
2461 	boolean_t isupdate = (newbie != NULL);
2462 	uint32_t *src_addr_ptr, *dst_addr_ptr, *proxy_addr_ptr;
2463 	uint32_t *natt_loc_ptr = NULL, *natt_rem_ptr = NULL;
2464 	uint32_t running_sum = 0;
2465 	mblk_t *ctl_mp = NULL;
2466 
2467 	src = (struct sockaddr_in *)(srcext + 1);
2468 	src6 = (struct sockaddr_in6 *)(srcext + 1);
2469 	dst = (struct sockaddr_in *)(dstext + 1);
2470 	dst6 = (struct sockaddr_in6 *)(dstext + 1);
2471 	if (proxyext != NULL) {
2472 		proxy = (struct sockaddr_in *)(proxyext + 1);
2473 		proxy6 = (struct sockaddr_in6 *)(proxyext + 1);
2474 	} else {
2475 		proxy = NULL;
2476 		proxy6 = NULL;
2477 	}
2478 
2479 	af = src->sin_family;
2480 
2481 	if (af == AF_INET) {
2482 		src_addr_ptr = (uint32_t *)&src->sin_addr;
2483 		dst_addr_ptr = (uint32_t *)&dst->sin_addr;
2484 	} else {
2485 		ASSERT(af == AF_INET6);
2486 		src_addr_ptr = (uint32_t *)&src6->sin6_addr;
2487 		dst_addr_ptr = (uint32_t *)&dst6->sin6_addr;
2488 	}
2489 
2490 	if (!isupdate) {
2491 		newbie = sadb_makelarvalassoc(assoc->sadb_sa_spi,
2492 		    src_addr_ptr, dst_addr_ptr, af);
2493 		if (newbie == NULL)
2494 			return (ENOMEM);
2495 	}
2496 
2497 	mutex_enter(&newbie->ipsa_lock);
2498 
2499 	if (proxy != NULL) {
2500 		if (proxy->sin_family == AF_INET) {
2501 			proxy_addr_ptr = (uint32_t *)&proxy->sin_addr;
2502 		} else {
2503 			ASSERT(proxy->sin_family == AF_INET6);
2504 			proxy_addr_ptr = (uint32_t *)&proxy6->sin6_addr;
2505 		}
2506 		newbie->ipsa_proxyfam = proxy->sin_family;
2507 
2508 		IPSA_COPY_ADDR(newbie->ipsa_proxysrc, proxy_addr_ptr,
2509 		    newbie->ipsa_proxyfam);
2510 	}
2511 
2512 #define	DOWN_SUM(x) (x) = ((x) & 0xFFFF) +	 ((x) >> 16)
2513 
2514 
2515 	if (natt_rem_ext != NULL) {
2516 		uint32_t l_src;
2517 		uint32_t l_rem;
2518 
2519 		natt_rem = (struct sockaddr_in *)(natt_rem_ext + 1);
2520 		natt_rem6 = (struct sockaddr_in6 *)(natt_rem_ext + 1);
2521 
2522 		if (natt_rem->sin_family == AF_INET) {
2523 			natt_rem_ptr = (uint32_t *)(&natt_rem->sin_addr);
2524 			newbie->ipsa_remote_port = natt_rem->sin_port;
2525 			l_src = *src_addr_ptr;
2526 			l_rem = *natt_rem_ptr;
2527 		} else {
2528 			if (!IN6_IS_ADDR_V4MAPPED(&natt_rem6->sin6_addr)) {
2529 				goto error;
2530 			}
2531 			ASSERT(natt_rem->sin_family == AF_INET6);
2532 
2533 			natt_rem_ptr = ((uint32_t *)
2534 			    (&natt_rem6->sin6_addr)) + 3;
2535 			newbie->ipsa_remote_port = natt_rem6->sin6_port;
2536 			l_src = *src_addr_ptr;
2537 			l_rem = *natt_rem_ptr;
2538 		}
2539 		IPSA_COPY_ADDR(newbie->ipsa_natt_addr_rem, natt_rem_ptr, af);
2540 
2541 		l_src = ntohl(l_src);
2542 		DOWN_SUM(l_src);
2543 		DOWN_SUM(l_src);
2544 		l_rem = ntohl(l_rem);
2545 		DOWN_SUM(l_rem);
2546 		DOWN_SUM(l_rem);
2547 
2548 		/*
2549 		 * We're 1's complement for checksums, so check for wraparound
2550 		 * here.
2551 		 */
2552 		if (l_rem > l_src)
2553 			l_src--;
2554 
2555 		running_sum += l_src - l_rem;
2556 
2557 		DOWN_SUM(running_sum);
2558 		DOWN_SUM(running_sum);
2559 	}
2560 
2561 	if (natt_loc_ext != NULL) {
2562 		uint32_t l_dst;
2563 		uint32_t l_loc;
2564 
2565 		natt_loc = (struct sockaddr_in *)(natt_loc_ext + 1);
2566 		natt_loc6 = (struct sockaddr_in6 *)(natt_loc_ext + 1);
2567 
2568 		if (natt_loc->sin_family == AF_INET) {
2569 			natt_loc_ptr = (uint32_t *)&natt_loc->sin_addr;
2570 			l_dst = *dst_addr_ptr;
2571 			l_loc = *natt_loc_ptr;
2572 
2573 		} else {
2574 			if (!IN6_IS_ADDR_V4MAPPED(&natt_loc6->sin6_addr)) {
2575 				goto error;
2576 			}
2577 			ASSERT(natt_loc->sin_family == AF_INET6);
2578 			natt_loc_ptr = ((uint32_t *)&natt_loc6->sin6_addr) + 3;
2579 			l_dst = *dst_addr_ptr;
2580 			l_loc = *natt_loc_ptr;
2581 
2582 		}
2583 		IPSA_COPY_ADDR(newbie->ipsa_natt_addr_loc, natt_loc_ptr, af);
2584 
2585 		l_loc = ntohl(l_loc);
2586 		DOWN_SUM(l_loc);
2587 		DOWN_SUM(l_loc);
2588 		l_dst = ntohl(l_dst);
2589 		DOWN_SUM(l_dst);
2590 		DOWN_SUM(l_dst);
2591 
2592 		/*
2593 		 * We're 1's complement for checksums, so check for wraparound
2594 		 * here.
2595 		 */
2596 		if (l_loc > l_dst)
2597 			l_dst--;
2598 
2599 		running_sum += l_dst - l_loc;
2600 		DOWN_SUM(running_sum);
2601 		DOWN_SUM(running_sum);
2602 	}
2603 
2604 	newbie->ipsa_inbound_cksum = running_sum;
2605 #undef DOWN_SUM
2606 
2607 	newbie->ipsa_type = samsg->sadb_msg_satype;
2608 	ASSERT(assoc->sadb_sa_state == SADB_SASTATE_MATURE);
2609 	newbie->ipsa_auth_alg = assoc->sadb_sa_auth;
2610 	newbie->ipsa_encr_alg = assoc->sadb_sa_encrypt;
2611 	newbie->ipsa_flags = assoc->sadb_sa_flags;
2612 	/*
2613 	 * If unspecified source address, force replay_wsize to 0.
2614 	 * This is because an SA that has multiple sources of secure
2615 	 * traffic cannot enforce a replay counter w/o synchronizing the
2616 	 * senders.
2617 	 */
2618 	if (ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC)
2619 		newbie->ipsa_replay_wsize = assoc->sadb_sa_replay;
2620 	else
2621 		newbie->ipsa_replay_wsize = 0;
2622 
2623 	(void) drv_getparm(TIME, &newbie->ipsa_addtime);
2624 
2625 	/* Set unique value */
2626 	if (dstext->sadb_address_proto != 0)
2627 		sadb_set_unique(newbie, dstext->sadb_address_proto, src, dst);
2628 
2629 	if (kmcext != NULL) {
2630 		newbie->ipsa_kmp = kmcext->sadb_x_kmc_proto;
2631 		newbie->ipsa_kmc = kmcext->sadb_x_kmc_cookie;
2632 	}
2633 
2634 	/*
2635 	 * XXX CURRENT lifetime checks MAY BE needed for an UPDATE.
2636 	 * The spec says that one can update current lifetimes, but
2637 	 * that seems impractical, especially in the larval-to-mature
2638 	 * update that this function performs.
2639 	 */
2640 	if (soft != NULL) {
2641 		newbie->ipsa_softaddlt = soft->sadb_lifetime_addtime;
2642 		newbie->ipsa_softuselt = soft->sadb_lifetime_usetime;
2643 		newbie->ipsa_softbyteslt = soft->sadb_lifetime_bytes;
2644 		newbie->ipsa_softalloc = soft->sadb_lifetime_allocations;
2645 		SET_EXPIRE(newbie, softaddlt, softexpiretime);
2646 	}
2647 	if (hard != NULL) {
2648 		newbie->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
2649 		newbie->ipsa_harduselt = hard->sadb_lifetime_usetime;
2650 		newbie->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
2651 		newbie->ipsa_hardalloc = hard->sadb_lifetime_allocations;
2652 		SET_EXPIRE(newbie, hardaddlt, hardexpiretime);
2653 	}
2654 
2655 	newbie->ipsa_authtmpl = NULL;
2656 	newbie->ipsa_encrtmpl = NULL;
2657 
2658 	if (akey != NULL) {
2659 		newbie->ipsa_authkeybits = akey->sadb_key_bits;
2660 		newbie->ipsa_authkeylen = SADB_1TO8(akey->sadb_key_bits);
2661 		/* In case we have to round up to the next byte... */
2662 		if ((akey->sadb_key_bits & 0x7) != 0)
2663 			newbie->ipsa_authkeylen++;
2664 		newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
2665 		    KM_NOSLEEP);
2666 		if (newbie->ipsa_authkey == NULL) {
2667 			error = ENOMEM;
2668 			mutex_exit(&newbie->ipsa_lock);
2669 			goto error;
2670 		}
2671 		bcopy(akey + 1, newbie->ipsa_authkey, newbie->ipsa_authkeylen);
2672 		bzero(akey + 1, newbie->ipsa_authkeylen);
2673 
2674 		/*
2675 		 * Pre-initialize the kernel crypto framework key
2676 		 * structure.
2677 		 */
2678 		newbie->ipsa_kcfauthkey.ck_format = CRYPTO_KEY_RAW;
2679 		newbie->ipsa_kcfauthkey.ck_length = newbie->ipsa_authkeybits;
2680 		newbie->ipsa_kcfauthkey.ck_data = newbie->ipsa_authkey;
2681 
2682 		mutex_enter(&alg_lock);
2683 		error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_AUTH);
2684 		mutex_exit(&alg_lock);
2685 		if (error != 0) {
2686 			mutex_exit(&newbie->ipsa_lock);
2687 			goto error;
2688 		}
2689 	}
2690 
2691 	if (ekey != NULL) {
2692 		newbie->ipsa_encrkeybits = ekey->sadb_key_bits;
2693 		newbie->ipsa_encrkeylen = SADB_1TO8(ekey->sadb_key_bits);
2694 		/* In case we have to round up to the next byte... */
2695 		if ((ekey->sadb_key_bits & 0x7) != 0)
2696 			newbie->ipsa_encrkeylen++;
2697 		newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
2698 		    KM_NOSLEEP);
2699 		if (newbie->ipsa_encrkey == NULL) {
2700 			error = ENOMEM;
2701 			mutex_exit(&newbie->ipsa_lock);
2702 			goto error;
2703 		}
2704 		bcopy(ekey + 1, newbie->ipsa_encrkey, newbie->ipsa_encrkeylen);
2705 		/* XXX is this safe w.r.t db_ref, etc? */
2706 		bzero(ekey + 1, newbie->ipsa_encrkeylen);
2707 
2708 		/*
2709 		 * Pre-initialize the kernel crypto framework key
2710 		 * structure.
2711 		 */
2712 		newbie->ipsa_kcfencrkey.ck_format = CRYPTO_KEY_RAW;
2713 		newbie->ipsa_kcfencrkey.ck_length = newbie->ipsa_encrkeybits;
2714 		newbie->ipsa_kcfencrkey.ck_data = newbie->ipsa_encrkey;
2715 
2716 		mutex_enter(&alg_lock);
2717 		error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_ENCR);
2718 		mutex_exit(&alg_lock);
2719 		if (error != 0) {
2720 			mutex_exit(&newbie->ipsa_lock);
2721 			goto error;
2722 		}
2723 	}
2724 
2725 	sadb_init_alginfo(newbie);
2726 
2727 	/*
2728 	 * Ptrs to processing functions.
2729 	 */
2730 	if (newbie->ipsa_type == SADB_SATYPE_ESP)
2731 		ipsecesp_init_funcs(newbie);
2732 	else
2733 		ipsecah_init_funcs(newbie);
2734 	ASSERT(newbie->ipsa_output_func != NULL &&
2735 	    newbie->ipsa_input_func != NULL);
2736 
2737 	/*
2738 	 * Certificate ID stuff.
2739 	 */
2740 	if (ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC] != NULL) {
2741 		sadb_ident_t *id =
2742 		    (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
2743 
2744 		/*
2745 		 * Can assume strlen() will return okay because ext_check() in
2746 		 * keysock.c prepares the string for us.
2747 		 */
2748 		newbie->ipsa_src_cid = ipsid_lookup(id->sadb_ident_type,
2749 		    (char *)(id+1));
2750 		if (newbie->ipsa_src_cid == NULL) {
2751 			error = ENOMEM;
2752 			mutex_exit(&newbie->ipsa_lock);
2753 			goto error;
2754 		}
2755 	}
2756 
2757 	if (ksi->ks_in_extv[SADB_EXT_IDENTITY_DST] != NULL) {
2758 		sadb_ident_t *id =
2759 		    (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
2760 
2761 		/*
2762 		 * Can assume strlen() will return okay because ext_check() in
2763 		 * keysock.c prepares the string for us.
2764 		 */
2765 		newbie->ipsa_dst_cid = ipsid_lookup(id->sadb_ident_type,
2766 		    (char *)(id+1));
2767 		if (newbie->ipsa_dst_cid == NULL) {
2768 			error = ENOMEM;
2769 			mutex_exit(&newbie->ipsa_lock);
2770 			goto error;
2771 		}
2772 	}
2773 
2774 #if 0
2775 	/* XXXMLS  SENSITIVITY handling code. */
2776 	if (sens != NULL) {
2777 		int i;
2778 		uint64_t *bitmap = (uint64_t *)(sens + 1);
2779 
2780 		newbie->ipsa_dpd = sens->sadb_sens_dpd;
2781 		newbie->ipsa_senslevel = sens->sadb_sens_sens_level;
2782 		newbie->ipsa_integlevel = sens->sadb_sens_integ_level;
2783 		newbie->ipsa_senslen = SADB_64TO8(sens->sadb_sens_sens_len);
2784 		newbie->ipsa_integlen = SADB_64TO8(sens->sadb_sens_integ_len);
2785 		newbie->ipsa_integ = kmem_alloc(newbie->ipsa_integlen,
2786 		    KM_NOSLEEP);
2787 		if (newbie->ipsa_integ == NULL) {
2788 			error = ENOMEM;
2789 			mutex_exit(&newbie->ipsa_lock);
2790 			goto error;
2791 		}
2792 		newbie->ipsa_sens = kmem_alloc(newbie->ipsa_senslen,
2793 		    KM_NOSLEEP);
2794 		if (newbie->ipsa_sens == NULL) {
2795 			error = ENOMEM;
2796 			mutex_exit(&newbie->ipsa_lock);
2797 			goto error;
2798 		}
2799 		for (i = 0; i < sens->sadb_sens_sens_len; i++) {
2800 			newbie->ipsa_sens[i] = *bitmap;
2801 			bitmap++;
2802 		}
2803 		for (i = 0; i < sens->sadb_sens_integ_len; i++) {
2804 			newbie->ipsa_integ[i] = *bitmap;
2805 			bitmap++;
2806 		}
2807 	}
2808 
2809 #endif
2810 
2811 	/* now that the SA has been updated, set its new state */
2812 	newbie->ipsa_state = assoc->sadb_sa_state;
2813 
2814 	/*
2815 	 * The less locks I hold when doing an insertion and possible cloning,
2816 	 * the better!
2817 	 */
2818 	mutex_exit(&newbie->ipsa_lock);
2819 
2820 	if (clone) {
2821 		newbie_clone = sadb_cloneassoc(newbie);
2822 
2823 		if (newbie_clone == NULL) {
2824 			error = ENOMEM;
2825 			goto error;
2826 		}
2827 		newbie->ipsa_haspeer = B_TRUE;
2828 		newbie_clone->ipsa_haspeer = B_TRUE;
2829 	}
2830 
2831 	/*
2832 	 * Enter the bucket locks.  The order of entry is outbound,
2833 	 * inbound.  We map "primary" and "secondary" into outbound and inbound
2834 	 * based on the destination address type.  If the destination address
2835 	 * type is for a node that isn't mine (or potentially mine), the
2836 	 * "primary" bucket is the outbound one.
2837 	 */
2838 	if (ksi->ks_in_dsttype == KS_IN_ADDR_NOTME) {
2839 		/* primary == outbound */
2840 		mutex_enter(&primary->isaf_lock);
2841 		mutex_enter(&secondary->isaf_lock);
2842 	} else {
2843 		/* primary == inbound */
2844 		mutex_enter(&secondary->isaf_lock);
2845 		mutex_enter(&primary->isaf_lock);
2846 	}
2847 
2848 	IPSECHW_DEBUG(IPSECHW_SADB, ("sadb_common_add: spi = 0x%x\n",
2849 	    newbie->ipsa_spi));
2850 
2851 	/*
2852 	 * sadb_insertassoc() doesn't increment the reference
2853 	 * count.  We therefore have to increment the
2854 	 * reference count one more time to reflect the
2855 	 * pointers of the table that reference this SA.
2856 	 */
2857 	IPSA_REFHOLD(newbie);
2858 
2859 	if (isupdate) {
2860 		/*
2861 		 * Unlink from larval holding cell in the "inbound" fanout.
2862 		 */
2863 		ASSERT(newbie->ipsa_linklock == &primary->isaf_lock ||
2864 		    newbie->ipsa_linklock == &secondary->isaf_lock);
2865 		sadb_unlinkassoc(newbie);
2866 	}
2867 
2868 	mutex_enter(&newbie->ipsa_lock);
2869 	error = sadb_insertassoc(newbie, primary);
2870 	if (error == 0) {
2871 		ctl_mp = sadb_fmt_sa_req(DL_CO_SET, newbie->ipsa_type, newbie,
2872 		    is_inbound);
2873 	}
2874 	mutex_exit(&newbie->ipsa_lock);
2875 
2876 	if (error != 0) {
2877 		/*
2878 		 * Since sadb_insertassoc() failed, we must decrement the
2879 		 * refcount again so the cleanup code will actually free
2880 		 * the offending SA.
2881 		 */
2882 		IPSA_REFRELE(newbie);
2883 		goto error_unlock;
2884 	}
2885 
2886 	if (newbie_clone != NULL) {
2887 		mutex_enter(&newbie_clone->ipsa_lock);
2888 		error = sadb_insertassoc(newbie_clone, secondary);
2889 		mutex_exit(&newbie_clone->ipsa_lock);
2890 		if (error != 0) {
2891 			/* Collision in secondary table. */
2892 			sadb_unlinkassoc(newbie);  /* This does REFRELE. */
2893 			goto error_unlock;
2894 		}
2895 		IPSA_REFHOLD(newbie_clone);
2896 	} else {
2897 		ASSERT(primary != secondary);
2898 		scratch = ipsec_getassocbyspi(secondary, newbie->ipsa_spi,
2899 		    ALL_ZEROES_PTR, newbie->ipsa_dstaddr, af);
2900 		if (scratch != NULL) {
2901 			/* Collision in secondary table. */
2902 			sadb_unlinkassoc(newbie);  /* This does REFRELE. */
2903 			/* Set the error, since ipsec_getassocbyspi() can't. */
2904 			error = EEXIST;
2905 			goto error_unlock;
2906 		}
2907 	}
2908 
2909 	/* OKAY!  So let's do some reality check assertions. */
2910 
2911 	ASSERT(!MUTEX_HELD(&newbie->ipsa_lock));
2912 	ASSERT(newbie_clone == NULL || (!MUTEX_HELD(&newbie_clone->ipsa_lock)));
2913 	/*
2914 	 * If hardware acceleration could happen, send it.
2915 	 */
2916 	if (ctl_mp != NULL) {
2917 		putnext(ip_q, ctl_mp);
2918 		ctl_mp = NULL;
2919 	}
2920 
2921 error_unlock:
2922 
2923 	/*
2924 	 * We can exit the locks in any order.	Only entrance needs to
2925 	 * follow any protocol.
2926 	 */
2927 	mutex_exit(&secondary->isaf_lock);
2928 	mutex_exit(&primary->isaf_lock);
2929 
2930 	/* Common error point for this routine. */
2931 error:
2932 	if (newbie != NULL) {
2933 		IPSA_REFRELE(newbie);
2934 	}
2935 	if (newbie_clone != NULL) {
2936 		IPSA_REFRELE(newbie_clone);
2937 	}
2938 	if (ctl_mp != NULL)
2939 		freemsg(ctl_mp);
2940 
2941 	if (error == 0) {
2942 		/*
2943 		 * Construct favorable PF_KEY return message and send to
2944 		 * keysock.  (Q:  Do I need to pass "newbie"?  If I do,
2945 		 * make sure to REFHOLD, call, then REFRELE.)
2946 		 */
2947 		sadb_pfkey_echo(pfkey_q, mp, samsg, ksi, NULL);
2948 	}
2949 
2950 	return (error);
2951 }
2952 
2953 /*
2954  * Set the time of first use for a security association.  Update any
2955  * expiration times as a result.
2956  */
2957 void
2958 sadb_set_usetime(ipsa_t *assoc)
2959 {
2960 	mutex_enter(&assoc->ipsa_lock);
2961 	/*
2962 	 * Caller does check usetime before calling me usually, and
2963 	 * double-checking is better than a mutex_enter/exit hit.
2964 	 */
2965 	if (assoc->ipsa_usetime == 0) {
2966 		/*
2967 		 * This is redundant for outbound SA's, as
2968 		 * ipsec_getassocbyconn() sets the IPSA_F_USED flag already.
2969 		 * Inbound SAs, however, have no such protection.
2970 		 */
2971 		assoc->ipsa_flags |= IPSA_F_USED;
2972 
2973 		(void) drv_getparm(TIME, &assoc->ipsa_usetime);
2974 
2975 		/*
2976 		 * After setting the use time, see if we have a use lifetime
2977 		 * that would cause the actual SA expiration time to shorten.
2978 		 */
2979 		UPDATE_EXPIRE(assoc, softuselt, softexpiretime);
2980 		UPDATE_EXPIRE(assoc, harduselt, hardexpiretime);
2981 	}
2982 	mutex_exit(&assoc->ipsa_lock);
2983 }
2984 
2985 /*
2986  * Send up a PF_KEY expire message for this association.
2987  */
2988 static void
2989 sadb_expire_assoc(queue_t *pfkey_q, ipsa_t *assoc)
2990 {
2991 	mblk_t *mp, *mp1;
2992 	int alloclen, af;
2993 	sadb_msg_t *samsg;
2994 	sadb_lifetime_t *current, *expire;
2995 	sadb_sa_t *saext;
2996 	uint8_t *end;
2997 
2998 	ASSERT(MUTEX_HELD(&assoc->ipsa_lock));
2999 
3000 	/* Don't bother sending if there's no queue. */
3001 	if (pfkey_q == NULL)
3002 		return;
3003 
3004 	mp = sadb_keysock_out(0);
3005 	if (mp == NULL) {
3006 		/* cmn_err(CE_WARN, */
3007 		/*	"sadb_expire_assoc: Can't allocate KEYSOCK_OUT.\n"); */
3008 		return;
3009 	}
3010 
3011 	alloclen = sizeof (*samsg) + sizeof (*current) + sizeof (*expire) +
3012 	    2*sizeof (sadb_address_t) + sizeof (*saext);
3013 
3014 	af = assoc->ipsa_addrfam;
3015 	switch (af) {
3016 	case AF_INET:
3017 		alloclen += 2 * sizeof (struct sockaddr_in);
3018 		break;
3019 	case AF_INET6:
3020 		alloclen += 2 * sizeof (struct sockaddr_in6);
3021 		break;
3022 	default:
3023 		/* Won't happen unless there's a kernel bug. */
3024 		freeb(mp);
3025 		cmn_err(CE_WARN,
3026 		    "sadb_expire_assoc: Unknown address length.\n");
3027 		return;
3028 	}
3029 
3030 	mp->b_cont = allocb(alloclen, BPRI_HI);
3031 	if (mp->b_cont == NULL) {
3032 		freeb(mp);
3033 		/* cmn_err(CE_WARN, */
3034 		/*	"sadb_expire_assoc: Can't allocate message.\n"); */
3035 		return;
3036 	}
3037 
3038 	mp1 = mp;
3039 	mp = mp->b_cont;
3040 	end = mp->b_wptr + alloclen;
3041 
3042 	samsg = (sadb_msg_t *)mp->b_wptr;
3043 	mp->b_wptr += sizeof (*samsg);
3044 	samsg->sadb_msg_version = PF_KEY_V2;
3045 	samsg->sadb_msg_type = SADB_EXPIRE;
3046 	samsg->sadb_msg_errno = 0;
3047 	samsg->sadb_msg_satype = assoc->ipsa_type;
3048 	samsg->sadb_msg_len = SADB_8TO64(alloclen);
3049 	samsg->sadb_msg_reserved = 0;
3050 	samsg->sadb_msg_seq = 0;
3051 	samsg->sadb_msg_pid = 0;
3052 
3053 	saext = (sadb_sa_t *)mp->b_wptr;
3054 	mp->b_wptr += sizeof (*saext);
3055 	saext->sadb_sa_len = SADB_8TO64(sizeof (*saext));
3056 	saext->sadb_sa_exttype = SADB_EXT_SA;
3057 	saext->sadb_sa_spi = assoc->ipsa_spi;
3058 	saext->sadb_sa_replay = assoc->ipsa_replay_wsize;
3059 	saext->sadb_sa_state = assoc->ipsa_state;
3060 	saext->sadb_sa_auth = assoc->ipsa_auth_alg;
3061 	saext->sadb_sa_encrypt = assoc->ipsa_encr_alg;
3062 	saext->sadb_sa_flags = assoc->ipsa_flags;
3063 
3064 	current = (sadb_lifetime_t *)mp->b_wptr;
3065 	mp->b_wptr += sizeof (sadb_lifetime_t);
3066 	current->sadb_lifetime_len = SADB_8TO64(sizeof (*current));
3067 	current->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
3068 	current->sadb_lifetime_allocations = assoc->ipsa_alloc;
3069 	current->sadb_lifetime_bytes = assoc->ipsa_bytes;
3070 	current->sadb_lifetime_addtime = assoc->ipsa_addtime;
3071 	current->sadb_lifetime_usetime = assoc->ipsa_usetime;
3072 
3073 	expire = (sadb_lifetime_t *)mp->b_wptr;
3074 	mp->b_wptr += sizeof (*expire);
3075 	expire->sadb_lifetime_len = SADB_8TO64(sizeof (*expire));
3076 
3077 	if (assoc->ipsa_state == IPSA_STATE_DEAD) {
3078 		expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
3079 		expire->sadb_lifetime_allocations = assoc->ipsa_hardalloc;
3080 		expire->sadb_lifetime_bytes = assoc->ipsa_hardbyteslt;
3081 		expire->sadb_lifetime_addtime = assoc->ipsa_hardaddlt;
3082 		expire->sadb_lifetime_usetime = assoc->ipsa_harduselt;
3083 	} else {
3084 		ASSERT(assoc->ipsa_state == IPSA_STATE_DYING);
3085 		expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
3086 		expire->sadb_lifetime_allocations = assoc->ipsa_softalloc;
3087 		expire->sadb_lifetime_bytes = assoc->ipsa_softbyteslt;
3088 		expire->sadb_lifetime_addtime = assoc->ipsa_softaddlt;
3089 		expire->sadb_lifetime_usetime = assoc->ipsa_softuselt;
3090 	}
3091 
3092 	mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_SRC,
3093 	    af, assoc->ipsa_srcaddr, SA_SRCPORT(assoc), SA_PROTO(assoc));
3094 	ASSERT(mp->b_wptr != NULL);
3095 
3096 	mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_DST,
3097 	    af, assoc->ipsa_dstaddr, SA_DSTPORT(assoc), SA_PROTO(assoc));
3098 	ASSERT(mp->b_wptr != NULL);
3099 
3100 	/* Can just putnext, we're ready to go! */
3101 	putnext(pfkey_q, mp1);
3102 }
3103 
3104 /*
3105  * "Age" the SA with the number of bytes that was used to protect traffic.
3106  * Send an SADB_EXPIRE message if appropriate.	Return B_TRUE if there was
3107  * enough "charge" left in the SA to protect the data.	Return B_FALSE
3108  * otherwise.  (If B_FALSE is returned, the association either was, or became
3109  * DEAD.)
3110  */
3111 boolean_t
3112 sadb_age_bytes(queue_t *pfkey_q, ipsa_t *assoc, uint64_t bytes,
3113     boolean_t sendmsg)
3114 {
3115 	boolean_t rc = B_TRUE;
3116 	uint64_t newtotal;
3117 
3118 	mutex_enter(&assoc->ipsa_lock);
3119 	newtotal = assoc->ipsa_bytes + bytes;
3120 	if (assoc->ipsa_hardbyteslt != 0 &&
3121 	    newtotal >= assoc->ipsa_hardbyteslt) {
3122 		if (assoc->ipsa_state < IPSA_STATE_DEAD) {
3123 			/*
3124 			 * Send EXPIRE message to PF_KEY.  May wish to pawn
3125 			 * this off on another non-interrupt thread.  Also
3126 			 * unlink this SA immediately.
3127 			 */
3128 			assoc->ipsa_state = IPSA_STATE_DEAD;
3129 			if (sendmsg)
3130 				sadb_expire_assoc(pfkey_q, assoc);
3131 			/*
3132 			 * Set non-zero expiration time so sadb_age_assoc()
3133 			 * will work when reaping.
3134 			 */
3135 			assoc->ipsa_hardexpiretime = (time_t)1;
3136 		} /* Else someone beat me to it! */
3137 		rc = B_FALSE;
3138 	} else if (assoc->ipsa_softbyteslt != 0 &&
3139 	    (newtotal >= assoc->ipsa_softbyteslt)) {
3140 		if (assoc->ipsa_state < IPSA_STATE_DYING) {
3141 			/*
3142 			 * Send EXPIRE message to PF_KEY.  May wish to pawn
3143 			 * this off on another non-interrupt thread.
3144 			 */
3145 			assoc->ipsa_state = IPSA_STATE_DYING;
3146 			if (sendmsg)
3147 				sadb_expire_assoc(pfkey_q, assoc);
3148 		} /* Else someone beat me to it! */
3149 	}
3150 	if (rc == B_TRUE)
3151 		assoc->ipsa_bytes = newtotal;
3152 	mutex_exit(&assoc->ipsa_lock);
3153 	return (rc);
3154 }
3155 
3156 /*
3157  * Push one or more DL_CO_DELETE messages queued up by
3158  * sadb_torch_assoc down to the underlying driver now that it's a
3159  * convenient time for it (i.e., ipsa bucket locks not held).
3160  */
3161 static void
3162 sadb_drain_torchq(queue_t *q, mblk_t *mp)
3163 {
3164 	while (mp != NULL) {
3165 		mblk_t *next = mp->b_next;
3166 		mp->b_next = NULL;
3167 		if (q != NULL)
3168 			putnext(q, mp);
3169 		else
3170 			freemsg(mp);
3171 		mp = next;
3172 	}
3173 }
3174 
3175 /*
3176  * "Torch" an individual SA.  Returns NULL, so it can be tail-called from
3177  *     sadb_age_assoc().
3178  *
3179  * If SA is hardware-accelerated, and we can't allocate the mblk
3180  * containing the DL_CO_DELETE, just return; it will remain in the
3181  * table and be swept up by sadb_ager() in a subsequent pass.
3182  */
3183 static ipsa_t *
3184 sadb_torch_assoc(isaf_t *head, ipsa_t *sa, boolean_t inbnd, mblk_t **mq)
3185 {
3186 	mblk_t *mp;
3187 
3188 	ASSERT(MUTEX_HELD(&head->isaf_lock));
3189 	ASSERT(MUTEX_HELD(&sa->ipsa_lock));
3190 	ASSERT(sa->ipsa_state == IPSA_STATE_DEAD);
3191 
3192 	/*
3193 	 * Force cached SAs to be revalidated..
3194 	 */
3195 	head->isaf_gen++;
3196 
3197 	if (sa->ipsa_flags & IPSA_F_HW) {
3198 		mp = sadb_fmt_sa_req(DL_CO_DELETE, sa->ipsa_type, sa, inbnd);
3199 		if (mp == NULL) {
3200 			mutex_exit(&sa->ipsa_lock);
3201 			return (NULL);
3202 		}
3203 		mp->b_next = *mq;
3204 		*mq = mp;
3205 	}
3206 	mutex_exit(&sa->ipsa_lock);
3207 	sadb_unlinkassoc(sa);
3208 
3209 	return (NULL);
3210 }
3211 
3212 /*
3213  * Return "assoc" iff haspeer is true and I send an expire.  This allows
3214  * the consumers' aging functions to tidy up an expired SA's peer.
3215  */
3216 static ipsa_t *
3217 sadb_age_assoc(isaf_t *head, queue_t *pfkey_q, ipsa_t *assoc,
3218     time_t current, int reap_delay, boolean_t inbnd, mblk_t **mq)
3219 {
3220 	ipsa_t *retval = NULL;
3221 
3222 	ASSERT(MUTEX_HELD(&head->isaf_lock));
3223 
3224 	mutex_enter(&assoc->ipsa_lock);
3225 
3226 	if ((assoc->ipsa_state == IPSA_STATE_LARVAL) &&
3227 	    (assoc->ipsa_hardexpiretime <= current)) {
3228 		assoc->ipsa_state = IPSA_STATE_DEAD;
3229 		return (sadb_torch_assoc(head, assoc, inbnd, mq));
3230 	}
3231 
3232 	/*
3233 	 * Check lifetimes.  Fortunately, SA setup is done
3234 	 * such that there are only two times to look at,
3235 	 * softexpiretime, and hardexpiretime.
3236 	 *
3237 	 * Check hard first.
3238 	 */
3239 
3240 	if (assoc->ipsa_hardexpiretime != 0 &&
3241 	    assoc->ipsa_hardexpiretime <= current) {
3242 		if (assoc->ipsa_state == IPSA_STATE_DEAD)
3243 			return (sadb_torch_assoc(head, assoc, inbnd, mq));
3244 
3245 		/*
3246 		 * Send SADB_EXPIRE with hard lifetime, delay for unlinking.
3247 		 */
3248 		assoc->ipsa_state = IPSA_STATE_DEAD;
3249 		if (assoc->ipsa_haspeer) {
3250 			/*
3251 			 * If I return assoc, I have to bump up its
3252 			 * reference count to keep with the ipsa_t reference
3253 			 * count semantics.
3254 			 */
3255 			IPSA_REFHOLD(assoc);
3256 			retval = assoc;
3257 		}
3258 		sadb_expire_assoc(pfkey_q, assoc);
3259 		assoc->ipsa_hardexpiretime = current + reap_delay;
3260 	} else if (assoc->ipsa_softexpiretime != 0 &&
3261 	    assoc->ipsa_softexpiretime <= current &&
3262 	    assoc->ipsa_state < IPSA_STATE_DYING) {
3263 		/*
3264 		 * Send EXPIRE message to PF_KEY.  May wish to pawn
3265 		 * this off on another non-interrupt thread.
3266 		 */
3267 		assoc->ipsa_state = IPSA_STATE_DYING;
3268 		if (assoc->ipsa_haspeer) {
3269 			/*
3270 			 * If I return assoc, I have to bump up its
3271 			 * reference count to keep with the ipsa_t reference
3272 			 * count semantics.
3273 			 */
3274 			IPSA_REFHOLD(assoc);
3275 			retval = assoc;
3276 		}
3277 		sadb_expire_assoc(pfkey_q, assoc);
3278 	}
3279 
3280 	mutex_exit(&assoc->ipsa_lock);
3281 	return (retval);
3282 }
3283 
3284 /*
3285  * Called by a consumer protocol to do ther dirty work of reaping dead
3286  * Security Associations.
3287  */
3288 void
3289 sadb_ager(sadb_t *sp, queue_t *pfkey_q, queue_t *ip_q, int reap_delay)
3290 {
3291 	int i;
3292 	isaf_t *bucket;
3293 	ipsa_t *assoc, *spare;
3294 	iacqf_t *acqlist;
3295 	ipsacq_t *acqrec, *spareacq;
3296 	struct templist {
3297 		ipsa_t *ipsa;
3298 		struct templist *next;
3299 	} *haspeerlist = NULL, *newbie;
3300 	time_t current;
3301 	int outhash;
3302 	mblk_t *mq = NULL;
3303 
3304 	/*
3305 	 * Do my dirty work.  This includes aging real entries, aging
3306 	 * larvals, and aging outstanding ACQUIREs.
3307 	 *
3308 	 * I hope I don't tie up resources for too long.
3309 	 */
3310 
3311 	/* Snapshot current time now. */
3312 	(void) drv_getparm(TIME, &current);
3313 
3314 	/* Age acquires. */
3315 
3316 	for (i = 0; i < OUTBOUND_BUCKETS; i++) {
3317 		acqlist = &sp->sdb_acq[i];
3318 		mutex_enter(&acqlist->iacqf_lock);
3319 		for (acqrec = acqlist->iacqf_ipsacq; acqrec != NULL;
3320 		    acqrec = spareacq) {
3321 			spareacq = acqrec->ipsacq_next;
3322 			if (current > acqrec->ipsacq_expire)
3323 				sadb_destroy_acquire(acqrec);
3324 		}
3325 		mutex_exit(&acqlist->iacqf_lock);
3326 	}
3327 
3328 	/* Age inbound associations. */
3329 	for (i = 0; i < INBOUND_BUCKETS; i++) {
3330 		bucket = &(sp->sdb_if[i]);
3331 		mutex_enter(&bucket->isaf_lock);
3332 		for (assoc = bucket->isaf_ipsa; assoc != NULL;
3333 		    assoc = spare) {
3334 			spare = assoc->ipsa_next;
3335 			if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
3336 			    reap_delay, B_TRUE, &mq) != NULL) {
3337 				/*
3338 				 * sadb_age_assoc() increments the refcnt,
3339 				 * effectively doing an IPSA_REFHOLD().
3340 				 */
3341 				newbie = kmem_alloc(sizeof (*newbie),
3342 				    KM_NOSLEEP);
3343 				if (newbie == NULL) {
3344 					/*
3345 					 * Don't forget to REFRELE().
3346 					 */
3347 					IPSA_REFRELE(assoc);
3348 					continue;	/* for loop... */
3349 				}
3350 				newbie->next = haspeerlist;
3351 				newbie->ipsa = assoc;
3352 				haspeerlist = newbie;
3353 			}
3354 		}
3355 		mutex_exit(&bucket->isaf_lock);
3356 	}
3357 
3358 	if (mq != NULL) {
3359 		sadb_drain_torchq(ip_q, mq);
3360 		mq = NULL;
3361 	}
3362 	/*
3363 	 * Haspeer cases will contain both IPv4 and IPv6.  This code
3364 	 * is address independent.
3365 	 */
3366 	while (haspeerlist != NULL) {
3367 		/* "spare" contains the SA that has a peer. */
3368 		spare = haspeerlist->ipsa;
3369 		newbie = haspeerlist;
3370 		haspeerlist = newbie->next;
3371 		kmem_free(newbie, sizeof (*newbie));
3372 		/*
3373 		 * Pick peer bucket based on addrfam.
3374 		 */
3375 		if (spare->ipsa_addrfam == AF_INET6) {
3376 			outhash = OUTBOUND_HASH_V6(*((in6_addr_t *)
3377 			    &spare->ipsa_dstaddr));
3378 		} else {
3379 			outhash = OUTBOUND_HASH_V4(*((ipaddr_t *)
3380 			    &spare->ipsa_dstaddr));
3381 		}
3382 		bucket = &(sp->sdb_of[outhash]);
3383 
3384 		mutex_enter(&bucket->isaf_lock);
3385 		assoc = ipsec_getassocbyspi(bucket, spare->ipsa_spi,
3386 		    spare->ipsa_srcaddr, spare->ipsa_dstaddr,
3387 		    spare->ipsa_addrfam);
3388 		mutex_exit(&bucket->isaf_lock);
3389 		if (assoc != NULL) {
3390 			mutex_enter(&assoc->ipsa_lock);
3391 			mutex_enter(&spare->ipsa_lock);
3392 			assoc->ipsa_state = spare->ipsa_state;
3393 			if (assoc->ipsa_state == IPSA_STATE_DEAD)
3394 				assoc->ipsa_hardexpiretime = 1;
3395 			mutex_exit(&spare->ipsa_lock);
3396 			mutex_exit(&assoc->ipsa_lock);
3397 			IPSA_REFRELE(assoc);
3398 		}
3399 		IPSA_REFRELE(spare);
3400 	}
3401 
3402 	/* Age outbound associations. */
3403 	for (i = 0; i < OUTBOUND_BUCKETS; i++) {
3404 		bucket = &(sp->sdb_of[i]);
3405 		mutex_enter(&bucket->isaf_lock);
3406 		for (assoc = bucket->isaf_ipsa; assoc != NULL;
3407 		    assoc = spare) {
3408 			spare = assoc->ipsa_next;
3409 			if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
3410 			    reap_delay, B_FALSE, &mq) != NULL) {
3411 				/*
3412 				 * sadb_age_assoc() increments the refcnt,
3413 				 * effectively doing an IPSA_REFHOLD().
3414 				 */
3415 				newbie = kmem_alloc(sizeof (*newbie),
3416 				    KM_NOSLEEP);
3417 				if (newbie == NULL) {
3418 					/*
3419 					 * Don't forget to REFRELE().
3420 					 */
3421 					IPSA_REFRELE(assoc);
3422 					continue;	/* for loop... */
3423 				}
3424 				newbie->next = haspeerlist;
3425 				newbie->ipsa = assoc;
3426 				haspeerlist = newbie;
3427 			}
3428 		}
3429 		mutex_exit(&bucket->isaf_lock);
3430 	}
3431 	if (mq != NULL) {
3432 		sadb_drain_torchq(ip_q, mq);
3433 		mq = NULL;
3434 	}
3435 	/*
3436 	 * Haspeer cases will contain both IPv4 and IPv6.  This code
3437 	 * is address independent.
3438 	 */
3439 	while (haspeerlist != NULL) {
3440 		/* "spare" contains the SA that has a peer. */
3441 		spare = haspeerlist->ipsa;
3442 		newbie = haspeerlist;
3443 		haspeerlist = newbie->next;
3444 		kmem_free(newbie, sizeof (*newbie));
3445 		/*
3446 		 * Pick peer bucket based on addrfam.
3447 		 */
3448 		bucket = &(sp->sdb_if[INBOUND_HASH(spare->ipsa_spi)]);
3449 		mutex_enter(&bucket->isaf_lock);
3450 		assoc = ipsec_getassocbyspi(bucket, spare->ipsa_spi,
3451 		    spare->ipsa_srcaddr, spare->ipsa_dstaddr,
3452 		    spare->ipsa_addrfam);
3453 		mutex_exit(&bucket->isaf_lock);
3454 		if (assoc != NULL) {
3455 			mutex_enter(&assoc->ipsa_lock);
3456 			mutex_enter(&spare->ipsa_lock);
3457 			assoc->ipsa_state = spare->ipsa_state;
3458 			if (assoc->ipsa_state == IPSA_STATE_DEAD)
3459 				assoc->ipsa_hardexpiretime = 1;
3460 			mutex_exit(&spare->ipsa_lock);
3461 			mutex_exit(&assoc->ipsa_lock);
3462 			IPSA_REFRELE(assoc);
3463 		}
3464 		IPSA_REFRELE(spare);
3465 	}
3466 	/*
3467 	 * Run a GC pass to clean out dead identities.
3468 	 */
3469 	ipsid_gc();
3470 }
3471 
3472 /*
3473  * Figure out when to reschedule the ager.
3474  */
3475 timeout_id_t
3476 sadb_retimeout(hrtime_t begin, queue_t *pfkey_q, void (*ager)(void *),
3477     uint_t *intp, uint_t intmax, short mid)
3478 {
3479 	hrtime_t end = gethrtime();
3480 	uint_t interval = *intp;
3481 
3482 	/*
3483 	 * See how long this took.  If it took too long, increase the
3484 	 * aging interval.
3485 	 */
3486 	if ((end - begin) > interval * 1000000) {
3487 		if (interval >= intmax) {
3488 			/* XXX Rate limit this?  Or recommend flush? */
3489 			(void) strlog(mid, 0, 0, SL_ERROR | SL_WARN,
3490 			    "Too many SA's to age out in %d msec.\n",
3491 			    intmax);
3492 		} else {
3493 			/* Double by shifting by one bit. */
3494 			interval <<= 1;
3495 			interval = min(interval, intmax);
3496 		}
3497 	} else if ((end - begin) <= interval * 500000 &&
3498 		interval > SADB_AGE_INTERVAL_DEFAULT) {
3499 		/*
3500 		 * If I took less than half of the interval, then I should
3501 		 * ratchet the interval back down.  Never automatically
3502 		 * shift below the default aging interval.
3503 		 *
3504 		 * NOTE:This even overrides manual setting of the age
3505 		 *	interval using NDD.
3506 		 */
3507 		/* Halve by shifting one bit. */
3508 		interval >>= 1;
3509 		interval = max(interval, SADB_AGE_INTERVAL_DEFAULT);
3510 	}
3511 	*intp = interval;
3512 	return (qtimeout(pfkey_q, ager, NULL, interval * drv_usectohz(1000)));
3513 }
3514 
3515 
3516 /*
3517  * Update the lifetime values of an SA.	 This is the path an SADB_UPDATE
3518  * message takes when updating a MATURE or DYING SA.
3519  */
3520 static void
3521 sadb_update_lifetimes(ipsa_t *assoc, sadb_lifetime_t *hard,
3522     sadb_lifetime_t *soft)
3523 {
3524 	mutex_enter(&assoc->ipsa_lock);
3525 
3526 	assoc->ipsa_state = IPSA_STATE_MATURE;
3527 
3528 	/*
3529 	 * XXX RFC 2367 mentions how an SADB_EXT_LIFETIME_CURRENT can be
3530 	 * passed in during an update message.	We currently don't handle
3531 	 * these.
3532 	 */
3533 
3534 	if (hard != NULL) {
3535 		if (hard->sadb_lifetime_bytes != 0)
3536 			assoc->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
3537 		if (hard->sadb_lifetime_usetime != 0)
3538 			assoc->ipsa_harduselt = hard->sadb_lifetime_usetime;
3539 		if (hard->sadb_lifetime_addtime != 0)
3540 			assoc->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
3541 		if (assoc->ipsa_hardaddlt != 0) {
3542 			assoc->ipsa_hardexpiretime =
3543 			    assoc->ipsa_addtime + assoc->ipsa_hardaddlt;
3544 		}
3545 		if (assoc->ipsa_harduselt != 0) {
3546 			if (assoc->ipsa_hardexpiretime != 0) {
3547 				assoc->ipsa_hardexpiretime =
3548 				    min(assoc->ipsa_hardexpiretime,
3549 					assoc->ipsa_usetime +
3550 					assoc->ipsa_harduselt);
3551 			} else {
3552 				assoc->ipsa_hardexpiretime =
3553 				    assoc->ipsa_usetime + assoc->ipsa_harduselt;
3554 			}
3555 		}
3556 
3557 		if (hard->sadb_lifetime_allocations != 0)
3558 			assoc->ipsa_hardalloc = hard->sadb_lifetime_allocations;
3559 	}
3560 
3561 	if (soft != NULL) {
3562 		if (soft->sadb_lifetime_bytes != 0)
3563 			assoc->ipsa_softbyteslt = soft->sadb_lifetime_bytes;
3564 		if (soft->sadb_lifetime_usetime != 0)
3565 			assoc->ipsa_softuselt = soft->sadb_lifetime_usetime;
3566 		if (soft->sadb_lifetime_addtime != 0)
3567 			assoc->ipsa_softaddlt = soft->sadb_lifetime_addtime;
3568 		if (assoc->ipsa_softaddlt != 0) {
3569 			assoc->ipsa_softexpiretime =
3570 			    assoc->ipsa_addtime + assoc->ipsa_softaddlt;
3571 		}
3572 		if (assoc->ipsa_softuselt != 0) {
3573 			if (assoc->ipsa_softexpiretime != 0) {
3574 				assoc->ipsa_softexpiretime =
3575 				    min(assoc->ipsa_softexpiretime,
3576 					assoc->ipsa_usetime +
3577 					assoc->ipsa_softuselt);
3578 			} else {
3579 				assoc->ipsa_softexpiretime =
3580 				    assoc->ipsa_usetime + assoc->ipsa_softuselt;
3581 			}
3582 		}
3583 
3584 		if (soft->sadb_lifetime_allocations != 0)
3585 			assoc->ipsa_softalloc = soft->sadb_lifetime_allocations;
3586 	}
3587 
3588 	mutex_exit(&assoc->ipsa_lock);
3589 }
3590 
3591 /*
3592  * Common code to update an SA.
3593  */
3594 
3595 int
3596 sadb_update_sa(mblk_t *mp, keysock_in_t *ksi,
3597     sadb_t *sp, int *diagnostic, queue_t *pfkey_q,
3598     int (*add_sa_func)(mblk_t *, keysock_in_t *, int *))
3599 {
3600 	sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
3601 	sadb_address_t *srcext =
3602 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
3603 	sadb_address_t *dstext =
3604 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
3605 	sadb_x_kmc_t *kmcext =
3606 	    (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
3607 	sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
3608 	sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
3609 	struct sockaddr_in *src, *dst;
3610 	struct sockaddr_in6 *src6, *dst6;
3611 	sadb_lifetime_t *soft =
3612 	    (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
3613 	sadb_lifetime_t *hard =
3614 	    (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
3615 	isaf_t *inbound, *outbound;
3616 	ipsa_t *outbound_target = NULL, *inbound_target = NULL;
3617 	int error = 0;
3618 	uint32_t *srcaddr, *dstaddr;
3619 	sa_family_t af;
3620 	uint32_t kmp = 0, kmc = 0;
3621 
3622 	/* I need certain extensions present for either UPDATE message. */
3623 	if (srcext == NULL) {
3624 		*diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
3625 		return (EINVAL);
3626 	}
3627 	if (dstext == NULL) {
3628 		*diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
3629 		return (EINVAL);
3630 	}
3631 	if (assoc == NULL) {
3632 		*diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
3633 		return (EINVAL);
3634 	}
3635 
3636 	if (kmcext != NULL) {
3637 		kmp = kmcext->sadb_x_kmc_proto;
3638 		kmc = kmcext->sadb_x_kmc_cookie;
3639 	}
3640 
3641 	dst = (struct sockaddr_in *)(dstext + 1);
3642 	src = (struct sockaddr_in *)(srcext + 1);
3643 	af = dst->sin_family;
3644 	if (af == AF_INET6) {
3645 		dst6 = (struct sockaddr_in6 *)dst;
3646 		src6 = (struct sockaddr_in6 *)src;
3647 		srcaddr = (uint32_t *)&src6->sin6_addr;
3648 		dstaddr = (uint32_t *)&dst6->sin6_addr;
3649 		outbound = &sp->sdb_of[OUTBOUND_HASH_V6(*(uint32_t *)dstaddr)];
3650 #if 0
3651 		/* Not used for now... */
3652 		if (proxyext != NULL)
3653 			proxy6 = (struct sockaddr_in6 *)(proxyext + 1);
3654 #endif
3655 	} else {
3656 		srcaddr = (uint32_t *)&src->sin_addr;
3657 		dstaddr = (uint32_t *)&dst->sin_addr;
3658 		outbound = &sp->sdb_of[OUTBOUND_HASH_V4(*(uint32_t *)dstaddr)];
3659 	}
3660 	inbound = &sp->sdb_if[INBOUND_HASH(assoc->sadb_sa_spi)];
3661 
3662 	/* Lock down both buckets. */
3663 	mutex_enter(&outbound->isaf_lock);
3664 	mutex_enter(&inbound->isaf_lock);
3665 
3666 	/* Try outbound first. */
3667 	outbound_target = ipsec_getassocbyspi(outbound, assoc->sadb_sa_spi,
3668 	    srcaddr, dstaddr, af);
3669 	inbound_target = ipsec_getassocbyspi(inbound, assoc->sadb_sa_spi,
3670 	    srcaddr, dstaddr, af);
3671 
3672 	mutex_exit(&inbound->isaf_lock);
3673 	mutex_exit(&outbound->isaf_lock);
3674 
3675 	if (outbound_target == NULL) {
3676 		if (inbound_target == NULL) {
3677 			return (ESRCH);
3678 		} else if (inbound_target->ipsa_state == IPSA_STATE_LARVAL) {
3679 			/*
3680 			 * REFRELE the target and let the add_sa_func()
3681 			 * deal with updating a larval SA.
3682 			 */
3683 			IPSA_REFRELE(inbound_target);
3684 			return (add_sa_func(mp, ksi, diagnostic));
3685 		}
3686 	}
3687 
3688 	/*
3689 	 * Reality checks for updates of active associations.
3690 	 * Sundry first-pass UPDATE-specific reality checks.
3691 	 * Have to do the checks here, because it's after the add_sa code.
3692 	 * XXX STATS : logging/stats here?
3693 	 */
3694 
3695 	if (assoc->sadb_sa_state != SADB_SASTATE_MATURE) {
3696 		*diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
3697 		error = EINVAL;
3698 		goto bail;
3699 	}
3700 	if (assoc->sadb_sa_flags & ~(SADB_SAFLAGS_NOREPLAY |
3701 		SADB_X_SAFLAGS_NATT_LOC | SADB_X_SAFLAGS_NATT_REM)) {
3702 		*diagnostic = SADB_X_DIAGNOSTIC_BAD_SAFLAGS;
3703 		error = EINVAL;
3704 		goto bail;
3705 	}
3706 	if (ksi->ks_in_extv[SADB_EXT_LIFETIME_CURRENT] != NULL) {
3707 		error = EOPNOTSUPP;
3708 		goto bail;
3709 	}
3710 	if ((*diagnostic = sadb_hardsoftchk(hard, soft)) != 0) {
3711 		error = EINVAL;
3712 		goto bail;
3713 	}
3714 	if (src->sin_family != dst->sin_family) {
3715 		*diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
3716 		error = EINVAL;
3717 		goto bail;
3718 	}
3719 	if (akey != NULL) {
3720 		*diagnostic = SADB_X_DIAGNOSTIC_AKEY_PRESENT;
3721 		error = EINVAL;
3722 		goto bail;
3723 	}
3724 	if (ekey != NULL) {
3725 		*diagnostic = SADB_X_DIAGNOSTIC_EKEY_PRESENT;
3726 		error = EINVAL;
3727 		goto bail;
3728 	}
3729 
3730 	if (outbound_target != NULL) {
3731 		if (outbound_target->ipsa_state == IPSA_STATE_DEAD) {
3732 			error = ESRCH;	/* DEAD == Not there, in this case. */
3733 			goto bail;
3734 		}
3735 		if ((kmp != 0) &&
3736 		    ((outbound_target->ipsa_kmp != 0) ||
3737 			(outbound_target->ipsa_kmp != kmp))) {
3738 			*diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMP;
3739 			error = EINVAL;
3740 			goto bail;
3741 		}
3742 		if ((kmc != 0) &&
3743 		    ((outbound_target->ipsa_kmc != 0) ||
3744 			(outbound_target->ipsa_kmc != kmc))) {
3745 			*diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMC;
3746 			error = EINVAL;
3747 			goto bail;
3748 		}
3749 	}
3750 
3751 	if (inbound_target != NULL) {
3752 		if (inbound_target->ipsa_state == IPSA_STATE_DEAD) {
3753 			error = ESRCH;	/* DEAD == Not there, in this case. */
3754 			goto bail;
3755 		}
3756 		if ((kmp != 0) &&
3757 		    ((inbound_target->ipsa_kmp != 0) ||
3758 			(inbound_target->ipsa_kmp != kmp))) {
3759 			*diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMP;
3760 			error = EINVAL;
3761 			goto bail;
3762 		}
3763 		if ((kmc != 0) &&
3764 		    ((inbound_target->ipsa_kmc != 0) ||
3765 			(inbound_target->ipsa_kmc != kmc))) {
3766 			*diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMC;
3767 			error = EINVAL;
3768 			goto bail;
3769 		}
3770 	}
3771 
3772 	if (outbound_target != NULL) {
3773 		if (dstext->sadb_address_proto != 0)
3774 			sadb_set_unique(outbound_target,
3775 			    dstext->sadb_address_proto, src, dst);
3776 		sadb_update_lifetimes(outbound_target, hard, soft);
3777 		if (kmp != 0)
3778 			outbound_target->ipsa_kmp = kmp;
3779 		if (kmc != 0)
3780 			outbound_target->ipsa_kmc = kmc;
3781 	}
3782 
3783 	if (inbound_target != NULL) {
3784 		if (dstext->sadb_address_proto != 0)
3785 			sadb_set_unique(inbound_target,
3786 			    dstext->sadb_address_proto, src, dst);
3787 		sadb_update_lifetimes(inbound_target, hard, soft);
3788 		if (kmp != 0)
3789 			inbound_target->ipsa_kmp = kmp;
3790 		if (kmc != 0)
3791 			inbound_target->ipsa_kmc = kmc;
3792 	}
3793 
3794 	sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
3795 	    ksi, (outbound_target == NULL) ? inbound_target : outbound_target);
3796 
3797 bail:
3798 	/*
3799 	 * Because of the multi-line macro nature of IPSA_REFRELE, keep
3800 	 * them in { }.
3801 	 */
3802 	if (outbound_target != NULL) {
3803 		IPSA_REFRELE(outbound_target);
3804 	}
3805 	if (inbound_target != NULL) {
3806 		IPSA_REFRELE(inbound_target);
3807 	}
3808 
3809 	return (error);
3810 }
3811 
3812 /*
3813  * The following functions deal with ACQUIRE LISTS.  An ACQUIRE list is
3814  * a list of outstanding SADB_ACQUIRE messages.	 If ipsec_getassocbyconn() fails
3815  * for an outbound datagram, that datagram is queued up on an ACQUIRE record,
3816  * and an SADB_ACQUIRE message is sent up.  Presumably, a user-space key
3817  * management daemon will process the ACQUIRE, use a SADB_GETSPI to reserve
3818  * an SPI value and a larval SA, then SADB_UPDATE the larval SA, and ADD the
3819  * other direction's SA.
3820  */
3821 
3822 /*
3823  * Check the ACQUIRE lists.  If there's an existing ACQUIRE record,
3824  * grab it, lock it, and return it.  Otherwise return NULL.
3825  */
3826 static ipsacq_t *
3827 sadb_checkacquire(iacqf_t *bucket, ipsec_action_t *ap, ipsec_policy_t *pp,
3828     uint32_t *src, uint32_t *dst, uint64_t unique_id)
3829 {
3830 	ipsacq_t *walker;
3831 	sa_family_t fam;
3832 
3833 	/*
3834 	 * Scan list for duplicates.  Check for UNIQUE, src/dest, policy.
3835 	 *
3836 	 * XXX May need search for duplicates based on other things too!
3837 	 */
3838 	for (walker = bucket->iacqf_ipsacq; walker != NULL;
3839 	    walker = walker->ipsacq_next) {
3840 		mutex_enter(&walker->ipsacq_lock);
3841 		fam = walker->ipsacq_addrfam;
3842 		if (IPSA_ARE_ADDR_EQUAL(dst, walker->ipsacq_dstaddr, fam) &&
3843 		    IPSA_ARE_ADDR_EQUAL(src, walker->ipsacq_srcaddr, fam) &&
3844 		    /* XXX PROXY should check for proxy addr here */
3845 		    (ap == walker->ipsacq_act) &&
3846 		    (pp == walker->ipsacq_policy) &&
3847 		    /* XXX do deep compares of ap/pp? */
3848 		    (unique_id == walker->ipsacq_unique_id))
3849 			break;			/* everything matched */
3850 		mutex_exit(&walker->ipsacq_lock);
3851 	}
3852 
3853 	return (walker);
3854 }
3855 
3856 /*
3857  * For this mblk, insert a new acquire record.  Assume bucket contains addrs
3858  * of all of the same length.  Give up (and drop) if memory
3859  * cannot be allocated for a new one; otherwise, invoke callback to
3860  * send the acquire up..
3861  *
3862  * In cases where we need both AH and ESP, add the SA to the ESP ACQUIRE
3863  * list.  The ah_add_sa_finish() routines can look at the packet's ipsec_out_t
3864  * and handle this case specially.
3865  */
3866 void
3867 sadb_acquire(mblk_t *mp, ipsec_out_t *io, boolean_t need_ah, boolean_t need_esp)
3868 {
3869 	sadbp_t *spp;
3870 	sadb_t *sp;
3871 	ipsacq_t *newbie;
3872 	iacqf_t *bucket;
3873 	mblk_t *datamp = mp->b_cont;
3874 	mblk_t *extended;
3875 	ipha_t *ipha = (ipha_t *)datamp->b_rptr;
3876 	ip6_t *ip6h = (ip6_t *)datamp->b_rptr;
3877 	uint32_t *src, *dst;
3878 	ipsec_policy_t *pp = io->ipsec_out_policy;
3879 	ipsec_action_t *ap = io->ipsec_out_act;
3880 	sa_family_t af;
3881 	int hashoffset;
3882 	uint32_t seq;
3883 	uint64_t unique_id = 0;
3884 	ipsec_selector_t sel;
3885 
3886 	ASSERT((pp != NULL) || (ap != NULL));
3887 
3888 	ASSERT(need_ah != NULL || need_esp != NULL);
3889 	/* Assign sadb pointers */
3890 	spp = need_esp ? &esp_sadb : &ah_sadb; /* ESP for AH+ESP */
3891 	sp = io->ipsec_out_v4 ? &spp->s_v4 : &spp->s_v6;
3892 
3893 	if (ap == NULL)
3894 		ap = pp->ipsp_act;
3895 
3896 	ASSERT(ap != NULL);
3897 
3898 	if (ap->ipa_act.ipa_apply.ipp_use_unique)
3899 		unique_id = SA_FORM_UNIQUE_ID(io);
3900 
3901 	/*
3902 	 * Set up an ACQUIRE record.
3903 	 *
3904 	 * Will eventually want to pull the PROXY source address from
3905 	 * either the inner IP header, or from a future extension to the
3906 	 * IPSEC_OUT message.
3907 	 *
3908 	 * Actually, we'll also want to check for duplicates.
3909 	 *
3910 	 * Immediately, make sure the ACQUIRE sequence number doesn't slip
3911 	 * below the lowest point allowed in the kernel.  (In other words,
3912 	 * make sure the high bit on the sequence number is set.)
3913 	 */
3914 
3915 	seq = keysock_next_seq() | IACQF_LOWEST_SEQ;
3916 
3917 	sel.ips_isv4 = io->ipsec_out_v4;
3918 	sel.ips_protocol = io->ipsec_out_proto;
3919 	sel.ips_local_port = io->ipsec_out_src_port;
3920 	sel.ips_remote_port = io->ipsec_out_dst_port;
3921 	sel.ips_icmp_type = io->ipsec_out_icmp_type;
3922 	sel.ips_icmp_code = io->ipsec_out_icmp_code;
3923 	sel.ips_is_icmp_inv_acq = 0;
3924 	if (IPH_HDR_VERSION(ipha) == IP_VERSION) {
3925 		src = (uint32_t *)&ipha->ipha_src;
3926 		dst = (uint32_t *)&ipha->ipha_dst;
3927 		/* No compiler dain-bramage (4438087) for IPv4 addresses. */
3928 		sel.ips_local_addr_v4 = ipha->ipha_src;
3929 		sel.ips_remote_addr_v4 = ipha->ipha_dst;
3930 		af = AF_INET;
3931 		hashoffset = OUTBOUND_HASH_V4(ipha->ipha_dst);
3932 		ASSERT(io->ipsec_out_v4 == B_TRUE);
3933 	} else {
3934 		ASSERT(IPH_HDR_VERSION(ipha) == IPV6_VERSION);
3935 		src = (uint32_t *)&ip6h->ip6_src;
3936 		dst = (uint32_t *)&ip6h->ip6_dst;
3937 		sel.ips_local_addr_v6 = ip6h->ip6_src;
3938 		sel.ips_remote_addr_v6 = ip6h->ip6_dst;
3939 		af = AF_INET6;
3940 		hashoffset = OUTBOUND_HASH_V6(ip6h->ip6_dst);
3941 		ASSERT(io->ipsec_out_v4 == B_FALSE);
3942 	}
3943 
3944 	/*
3945 	 * Check buckets to see if there is an existing entry.  If so,
3946 	 * grab it.  sadb_checkacquire locks newbie if found.
3947 	 */
3948 	bucket = &(sp->sdb_acq[hashoffset]);
3949 	mutex_enter(&bucket->iacqf_lock);
3950 	newbie = sadb_checkacquire(bucket, ap, pp, src, dst, unique_id);
3951 
3952 	if (newbie == NULL) {
3953 		/*
3954 		 * Otherwise, allocate a new one.
3955 		 */
3956 		newbie = kmem_zalloc(sizeof (*newbie), KM_NOSLEEP);
3957 		if (newbie == NULL) {
3958 			mutex_exit(&bucket->iacqf_lock);
3959 			ip_drop_packet(mp, B_FALSE, NULL, NULL,
3960 			    &ipdrops_sadb_acquire_nomem, &sadb_dropper);
3961 			return;
3962 		}
3963 		newbie->ipsacq_policy = pp;
3964 		if (pp != NULL) {
3965 			IPPOL_REFHOLD(pp);
3966 		}
3967 		IPACT_REFHOLD(ap);
3968 		newbie->ipsacq_act = ap;
3969 		newbie->ipsacq_linklock = &bucket->iacqf_lock;
3970 		newbie->ipsacq_next = bucket->iacqf_ipsacq;
3971 		newbie->ipsacq_ptpn = &bucket->iacqf_ipsacq;
3972 		if (newbie->ipsacq_next != NULL)
3973 			newbie->ipsacq_next->ipsacq_ptpn = &newbie->ipsacq_next;
3974 		bucket->iacqf_ipsacq = newbie;
3975 		mutex_init(&newbie->ipsacq_lock, NULL, MUTEX_DEFAULT, NULL);
3976 		mutex_enter(&newbie->ipsacq_lock);
3977 	}
3978 
3979 	mutex_exit(&bucket->iacqf_lock);
3980 
3981 	/*
3982 	 * This assert looks silly for now, but we may need to enter newbie's
3983 	 * mutex during a search.
3984 	 */
3985 	ASSERT(MUTEX_HELD(&newbie->ipsacq_lock));
3986 
3987 	mp->b_next = NULL;
3988 	/* Queue up packet.  Use b_next. */
3989 	if (newbie->ipsacq_numpackets == 0) {
3990 		/* First one. */
3991 		newbie->ipsacq_mp = mp;
3992 		newbie->ipsacq_numpackets = 1;
3993 		(void) drv_getparm(TIME, &newbie->ipsacq_expire);
3994 		/*
3995 		 * Extended ACQUIRE with both AH+ESP will use ESP's timeout
3996 		 * value.
3997 		 */
3998 		newbie->ipsacq_expire += *spp->s_acquire_timeout;
3999 		newbie->ipsacq_seq = seq;
4000 		newbie->ipsacq_addrfam = af;
4001 
4002 		newbie->ipsacq_srcport = io->ipsec_out_src_port;
4003 		newbie->ipsacq_dstport = io->ipsec_out_dst_port;
4004 		newbie->ipsacq_icmp_type = io->ipsec_out_icmp_type;
4005 		newbie->ipsacq_icmp_code = io->ipsec_out_icmp_code;
4006 		newbie->ipsacq_proto = io->ipsec_out_proto;
4007 		newbie->ipsacq_unique_id = unique_id;
4008 	} else {
4009 		/* Scan to the end of the list & insert. */
4010 		mblk_t *lastone = newbie->ipsacq_mp;
4011 
4012 		while (lastone->b_next != NULL)
4013 			lastone = lastone->b_next;
4014 		lastone->b_next = mp;
4015 		if (newbie->ipsacq_numpackets++ == IPSACQ_MAXPACKETS) {
4016 			newbie->ipsacq_numpackets = IPSACQ_MAXPACKETS;
4017 			lastone = newbie->ipsacq_mp;
4018 			newbie->ipsacq_mp = lastone->b_next;
4019 			lastone->b_next = NULL;
4020 			ip_drop_packet(lastone, B_FALSE, NULL, NULL,
4021 			    &ipdrops_sadb_acquire_toofull, &sadb_dropper);
4022 		}
4023 	}
4024 
4025 	/*
4026 	 * Reset addresses.  Set them to the most recently added mblk chain,
4027 	 * so that the address pointers in the acquire record will point
4028 	 * at an mblk still attached to the acquire list.
4029 	 */
4030 
4031 	newbie->ipsacq_srcaddr = src;
4032 	newbie->ipsacq_dstaddr = dst;
4033 
4034 	/*
4035 	 * If the acquire record has more than one queued packet, we've
4036 	 * already sent an ACQUIRE, and don't need to repeat ourself.
4037 	 */
4038 	if (newbie->ipsacq_seq != seq || newbie->ipsacq_numpackets > 1) {
4039 		/* I have an acquire outstanding already! */
4040 		mutex_exit(&newbie->ipsacq_lock);
4041 		return;
4042 	}
4043 
4044 	if (keysock_extended_reg()) {
4045 		/*
4046 		 * Construct an extended ACQUIRE.  There are logging
4047 		 * opportunities here in failure cases.
4048 		 */
4049 
4050 		extended = sadb_keysock_out(0);
4051 		if (extended != NULL) {
4052 			extended->b_cont = sadb_extended_acquire(&sel, pp, ap,
4053 			    seq, 0);
4054 			if (extended->b_cont == NULL) {
4055 				freeb(extended);
4056 				extended = NULL;
4057 			}
4058 		}
4059 	} else
4060 		extended = NULL;
4061 
4062 	/*
4063 	 * Send an ACQUIRE message (and possible an extended ACQUIRE) based on
4064 	 * this new record.  The send-acquire callback assumes that acqrec is
4065 	 * already locked.
4066 	 */
4067 	(*spp->s_acqfn)(newbie, extended);
4068 }
4069 
4070 /*
4071  * Unlink and free an acquire record.
4072  */
4073 void
4074 sadb_destroy_acquire(ipsacq_t *acqrec)
4075 {
4076 	mblk_t *mp;
4077 
4078 	ASSERT(MUTEX_HELD(acqrec->ipsacq_linklock));
4079 
4080 	if (acqrec->ipsacq_policy != NULL) {
4081 		IPPOL_REFRELE(acqrec->ipsacq_policy);
4082 	}
4083 	if (acqrec->ipsacq_act != NULL) {
4084 		IPACT_REFRELE(acqrec->ipsacq_act);
4085 	}
4086 
4087 	/* Unlink */
4088 	*(acqrec->ipsacq_ptpn) = acqrec->ipsacq_next;
4089 	if (acqrec->ipsacq_next != NULL)
4090 		acqrec->ipsacq_next->ipsacq_ptpn = acqrec->ipsacq_ptpn;
4091 
4092 	/*
4093 	 * Free hanging mp's.
4094 	 *
4095 	 * XXX Instead of freemsg(), perhaps use IPSEC_REQ_FAILED.
4096 	 */
4097 
4098 	mutex_enter(&acqrec->ipsacq_lock);
4099 	while (acqrec->ipsacq_mp != NULL) {
4100 		mp = acqrec->ipsacq_mp;
4101 		acqrec->ipsacq_mp = mp->b_next;
4102 		mp->b_next = NULL;
4103 		ip_drop_packet(mp, B_FALSE, NULL, NULL,
4104 		    &ipdrops_sadb_acquire_timeout, &sadb_dropper);
4105 	}
4106 	mutex_exit(&acqrec->ipsacq_lock);
4107 
4108 	/* Free */
4109 	mutex_destroy(&acqrec->ipsacq_lock);
4110 	kmem_free(acqrec, sizeof (*acqrec));
4111 }
4112 
4113 /*
4114  * Destroy an acquire list fanout.
4115  */
4116 void
4117 sadb_destroy_acqlist(iacqf_t *list, uint_t numentries, boolean_t forever)
4118 {
4119 	int i;
4120 
4121 	for (i = 0; i < numentries; i++) {
4122 		mutex_enter(&(list[i].iacqf_lock));
4123 		while (list[i].iacqf_ipsacq != NULL)
4124 			sadb_destroy_acquire(list[i].iacqf_ipsacq);
4125 		mutex_exit(&(list[i].iacqf_lock));
4126 		if (forever)
4127 			mutex_destroy(&(list[i].iacqf_lock));
4128 	}
4129 
4130 	if (forever)
4131 		kmem_free(list, numentries * sizeof (*list));
4132 }
4133 
4134 static uint8_t *
4135 sadb_new_algdesc(uint8_t *start, uint8_t *limit,
4136     sadb_x_ecomb_t *ecomb, uint8_t satype, uint8_t algtype,
4137     uint8_t alg, uint16_t minbits, uint16_t maxbits)
4138 {
4139 	uint8_t *cur = start;
4140 
4141 	sadb_x_algdesc_t *algdesc = (sadb_x_algdesc_t *)cur;
4142 	cur += sizeof (*algdesc);
4143 	if (cur >= limit)
4144 		return (NULL);
4145 
4146 	ecomb->sadb_x_ecomb_numalgs++;
4147 
4148 	algdesc->sadb_x_algdesc_satype = satype;
4149 	algdesc->sadb_x_algdesc_algtype = algtype;
4150 	algdesc->sadb_x_algdesc_alg = alg;
4151 	algdesc->sadb_x_algdesc_minbits = minbits;
4152 	algdesc->sadb_x_algdesc_maxbits = maxbits;
4153 	algdesc->sadb_x_algdesc_reserved = 0;
4154 	return (cur);
4155 }
4156 
4157 /*
4158  * Convert the given ipsec_action_t into an ecomb starting at *ecomb
4159  * which must fit before *limit
4160  *
4161  * return NULL if we ran out of room or a pointer to the end of the ecomb.
4162  */
4163 static uint8_t *
4164 sadb_action_to_ecomb(uint8_t *start, uint8_t *limit, ipsec_action_t *act)
4165 {
4166 	uint8_t *cur = start;
4167 	sadb_x_ecomb_t *ecomb = (sadb_x_ecomb_t *)cur;
4168 	ipsec_prot_t *ipp;
4169 
4170 	cur += sizeof (*ecomb);
4171 	if (cur >= limit)
4172 		return (NULL);
4173 
4174 	ASSERT(act->ipa_act.ipa_type == IPSEC_ACT_APPLY);
4175 
4176 	ipp = &act->ipa_act.ipa_apply;
4177 
4178 	ecomb->sadb_x_ecomb_numalgs = 0;
4179 	ecomb->sadb_x_ecomb_reserved = 0;
4180 	ecomb->sadb_x_ecomb_reserved2 = 0;
4181 	/*
4182 	 * No limits on allocations, since we really don't support that
4183 	 * concept currently.
4184 	 */
4185 	ecomb->sadb_x_ecomb_soft_allocations = 0;
4186 	ecomb->sadb_x_ecomb_hard_allocations = 0;
4187 
4188 	/*
4189 	 * XXX TBD: Policy or global parameters will eventually be
4190 	 * able to fill in some of these.
4191 	 */
4192 	ecomb->sadb_x_ecomb_flags = 0;
4193 	ecomb->sadb_x_ecomb_soft_bytes = 0;
4194 	ecomb->sadb_x_ecomb_hard_bytes = 0;
4195 	ecomb->sadb_x_ecomb_soft_addtime = 0;
4196 	ecomb->sadb_x_ecomb_hard_addtime = 0;
4197 	ecomb->sadb_x_ecomb_soft_usetime = 0;
4198 	ecomb->sadb_x_ecomb_hard_usetime = 0;
4199 
4200 	if (ipp->ipp_use_ah) {
4201 		cur = sadb_new_algdesc(cur, limit, ecomb,
4202 		    SADB_SATYPE_AH, SADB_X_ALGTYPE_AUTH, ipp->ipp_auth_alg,
4203 		    ipp->ipp_ah_minbits, ipp->ipp_ah_maxbits);
4204 		if (cur == NULL)
4205 			return (NULL);
4206 		ipsecah_fill_defs(ecomb);
4207 	}
4208 
4209 	if (ipp->ipp_use_esp) {
4210 		if (ipp->ipp_use_espa) {
4211 			cur = sadb_new_algdesc(cur, limit, ecomb,
4212 			    SADB_SATYPE_ESP, SADB_X_ALGTYPE_AUTH,
4213 			    ipp->ipp_esp_auth_alg,
4214 			    ipp->ipp_espa_minbits,
4215 			    ipp->ipp_espa_maxbits);
4216 			if (cur == NULL)
4217 				return (NULL);
4218 		}
4219 
4220 		cur = sadb_new_algdesc(cur, limit, ecomb,
4221 		    SADB_SATYPE_ESP, SADB_X_ALGTYPE_CRYPT,
4222 		    ipp->ipp_encr_alg,
4223 		    ipp->ipp_espe_minbits,
4224 		    ipp->ipp_espe_maxbits);
4225 		if (cur == NULL)
4226 			return (NULL);
4227 		/* Fill in lifetimes if and only if AH didn't already... */
4228 		if (!ipp->ipp_use_ah)
4229 			ipsecesp_fill_defs(ecomb);
4230 	}
4231 
4232 	return (cur);
4233 }
4234 
4235 /*
4236  * Construct an extended ACQUIRE message based on a selector and the resulting
4237  * IPsec action.
4238  *
4239  * NOTE: This is used by both inverse ACQUIRE and actual ACQUIRE
4240  * generation. As a consequence, expect this function to evolve
4241  * rapidly.
4242  */
4243 static mblk_t *
4244 sadb_extended_acquire(ipsec_selector_t *sel, ipsec_policy_t *pol,
4245     ipsec_action_t *act, uint32_t seq, uint32_t pid)
4246 {
4247 	mblk_t *mp;
4248 	sadb_msg_t *samsg;
4249 	uint8_t *start, *cur, *end;
4250 	uint32_t *saddrptr, *daddrptr;
4251 	sa_family_t af;
4252 	sadb_prop_t *eprop;
4253 	ipsec_action_t *ap, *an;
4254 	uint8_t proto;
4255 	uint16_t lport, rport;
4256 	uint32_t kmp, kmc;
4257 
4258 	/*
4259 	 * Find the action we want sooner rather than later..
4260 	 */
4261 	an = NULL;
4262 	if (pol == NULL) {
4263 		ap = act;
4264 	} else {
4265 		ap = pol->ipsp_act;
4266 
4267 		if (ap != NULL)
4268 			an = ap->ipa_next;
4269 	}
4270 
4271 	/*
4272 	 * Just take a swag for the allocation for now.	 We can always
4273 	 * alter it later.
4274 	 */
4275 #define	SADB_EXTENDED_ACQUIRE_SIZE	2048
4276 	mp = allocb(SADB_EXTENDED_ACQUIRE_SIZE, BPRI_HI);
4277 	if (mp == NULL)
4278 		return (NULL);
4279 	if (sel->ips_isv4) {
4280 		af = AF_INET;
4281 		saddrptr = (uint32_t *)(&sel->ips_local_addr_v4);
4282 		daddrptr = (uint32_t *)(&sel->ips_remote_addr_v4);
4283 	} else {
4284 		af = AF_INET6;
4285 		saddrptr = (uint32_t *)(&sel->ips_local_addr_v6);
4286 		daddrptr = (uint32_t *)(&sel->ips_remote_addr_v6);
4287 	}
4288 
4289 	start = mp->b_rptr;
4290 	end = start + SADB_EXTENDED_ACQUIRE_SIZE;
4291 
4292 	cur = start;
4293 
4294 	samsg = (sadb_msg_t *)cur;
4295 	cur += sizeof (*samsg);
4296 
4297 	samsg->sadb_msg_version = PF_KEY_V2;
4298 	samsg->sadb_msg_type = SADB_ACQUIRE;
4299 	samsg->sadb_msg_errno = 0;
4300 	samsg->sadb_msg_reserved = 0;
4301 	samsg->sadb_msg_satype = 0;
4302 	samsg->sadb_msg_seq = seq;
4303 	samsg->sadb_msg_pid = pid;
4304 
4305 	proto = sel->ips_protocol;
4306 	lport = sel->ips_local_port;
4307 	rport = sel->ips_remote_port;
4308 
4309 	/*
4310 	 * Unless our policy says "sa unique", drop port/proto
4311 	 * selectors, then add them back if policy rule includes them..
4312 	 */
4313 
4314 	if ((ap != NULL) && (!ap->ipa_want_unique)) {
4315 		proto = 0;
4316 		lport = 0;
4317 		rport = 0;
4318 		if (pol != NULL) {
4319 			ipsec_selkey_t *psel = &pol->ipsp_sel->ipsl_key;
4320 			if (psel->ipsl_valid & IPSL_PROTOCOL)
4321 				proto = psel->ipsl_proto;
4322 			if (psel->ipsl_valid & IPSL_REMOTE_PORT)
4323 				rport = psel->ipsl_rport;
4324 			if (psel->ipsl_valid & IPSL_LOCAL_PORT)
4325 				lport = psel->ipsl_lport;
4326 		}
4327 	}
4328 
4329 	cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
4330 	    saddrptr, lport, proto);
4331 
4332 	if (cur == NULL) {
4333 		freeb(mp);
4334 		return (NULL);
4335 	}
4336 
4337 	cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
4338 	    daddrptr, rport, proto);
4339 
4340 	if (cur == NULL) {
4341 		freeb(mp);
4342 		return (NULL);
4343 	}
4344 
4345 	/*
4346 	 * This section will change a lot as policy evolves.
4347 	 * For now, it'll be relatively simple.
4348 	 */
4349 	eprop = (sadb_prop_t *)cur;
4350 	cur += sizeof (*eprop);
4351 	if (cur > end) {
4352 		/* no space left */
4353 		freeb(mp);
4354 		return (NULL);
4355 	}
4356 
4357 	eprop->sadb_prop_exttype = SADB_X_EXT_EPROP;
4358 	eprop->sadb_x_prop_ereserved = 0;
4359 	eprop->sadb_x_prop_numecombs = 0;
4360 	eprop->sadb_prop_replay = 32;	/* default */
4361 
4362 	kmc = kmp = 0;
4363 
4364 	for (; ap != NULL; ap = an) {
4365 		an = (pol != NULL) ? ap->ipa_next : NULL;
4366 
4367 		/*
4368 		 * Skip non-IPsec policies
4369 		 */
4370 		if (ap->ipa_act.ipa_type != IPSEC_ACT_APPLY)
4371 			continue;
4372 
4373 		if (ap->ipa_act.ipa_apply.ipp_km_proto)
4374 			kmp = ap->ipa_act.ipa_apply.ipp_km_proto;
4375 		if (ap->ipa_act.ipa_apply.ipp_km_cookie)
4376 			kmc = ap->ipa_act.ipa_apply.ipp_km_cookie;
4377 		if (ap->ipa_act.ipa_apply.ipp_replay_depth) {
4378 			eprop->sadb_prop_replay =
4379 			    ap->ipa_act.ipa_apply.ipp_replay_depth;
4380 		}
4381 
4382 		cur = sadb_action_to_ecomb(cur, end, ap);
4383 		if (cur == NULL) { /* no space */
4384 			freeb(mp);
4385 			return (NULL);
4386 		}
4387 		eprop->sadb_x_prop_numecombs++;
4388 	}
4389 
4390 	if (eprop->sadb_x_prop_numecombs == 0) {
4391 		/*
4392 		 * This will happen if we fail to find a policy
4393 		 * allowing for IPsec processing.
4394 		 * Construct an error message.
4395 		 */
4396 		samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg));
4397 		samsg->sadb_msg_errno = ENOENT;
4398 		samsg->sadb_x_msg_diagnostic = 0;
4399 		return (mp);
4400 	}
4401 
4402 	if ((kmp != 0) || (kmc != 0)) {
4403 		cur = sadb_make_kmc_ext(cur, end, kmp, kmc);
4404 		if (cur == NULL) {
4405 			freeb(mp);
4406 			return (NULL);
4407 		}
4408 	}
4409 
4410 	eprop->sadb_prop_len = SADB_8TO64(cur - (uint8_t *)eprop);
4411 	samsg->sadb_msg_len = SADB_8TO64(cur-start);
4412 	mp->b_wptr = cur;
4413 
4414 	return (mp);
4415 }
4416 
4417 /*
4418  * Generic setup of an ACQUIRE message.	 Caller sets satype.
4419  */
4420 uint8_t *
4421 sadb_setup_acquire(uint8_t *start, uint8_t *end, ipsacq_t *acqrec)
4422 {
4423 	sa_family_t af;
4424 	uint8_t *cur = start;
4425 	sadb_msg_t *samsg = (sadb_msg_t *)cur;
4426 	uint16_t sport_typecode;
4427 	uint16_t dport_typecode;
4428 	uint8_t check_proto;
4429 
4430 	cur += sizeof (sadb_msg_t);
4431 	if (cur > end)
4432 		return (NULL);
4433 
4434 	/* use the address length to find the address family */
4435 	af = acqrec->ipsacq_addrfam;
4436 	switch (af) {
4437 	case AF_INET:
4438 		check_proto = IPPROTO_ICMP;
4439 		break;
4440 	case AF_INET6:
4441 		check_proto = IPPROTO_ICMPV6;
4442 		break;
4443 	default:
4444 		/* This should never happen unless we have kernel bugs. */
4445 		cmn_err(CE_WARN,
4446 		    "sadb_setup_acquire:  corrupt ACQUIRE record.\n");
4447 		ASSERT(0);
4448 		return (NULL);
4449 	}
4450 
4451 	samsg->sadb_msg_version = PF_KEY_V2;
4452 	samsg->sadb_msg_type = SADB_ACQUIRE;
4453 	samsg->sadb_msg_errno = 0;
4454 	samsg->sadb_msg_pid = 0;
4455 	samsg->sadb_msg_reserved = 0;
4456 	samsg->sadb_msg_seq = acqrec->ipsacq_seq;
4457 
4458 	ASSERT(MUTEX_HELD(&acqrec->ipsacq_lock));
4459 
4460 	if (acqrec->ipsacq_proto == check_proto) {
4461 		sport_typecode = dport_typecode = 0;
4462 	} else {
4463 		sport_typecode = acqrec->ipsacq_srcport;
4464 		dport_typecode = acqrec->ipsacq_dstport;
4465 	}
4466 
4467 	cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
4468 	    acqrec->ipsacq_srcaddr, sport_typecode, acqrec->ipsacq_proto);
4469 
4470 	cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
4471 	    acqrec->ipsacq_dstaddr, dport_typecode, acqrec->ipsacq_proto);
4472 
4473 	if (cur != NULL)
4474 		samsg->sadb_msg_len = SADB_8TO64(cur - start);
4475 
4476 	return (cur);
4477 }
4478 
4479 /*
4480  * Given an SADB_GETSPI message, find an appropriately ranged SA and
4481  * allocate an SA.  If there are message improprieties, return (ipsa_t *)-1.
4482  * If there was a memory allocation error, return NULL.	 (Assume NULL !=
4483  * (ipsa_t *)-1).
4484  *
4485  * master_spi is passed in host order.
4486  */
4487 ipsa_t *
4488 sadb_getspi(keysock_in_t *ksi, uint32_t master_spi, int *diagnostic)
4489 {
4490 	sadb_address_t *src =
4491 	    (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC],
4492 	    *dst = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
4493 	sadb_spirange_t *range =
4494 	    (sadb_spirange_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
4495 	struct sockaddr_in *ssa, *dsa;
4496 	struct sockaddr_in6 *ssa6, *dsa6;
4497 	uint32_t *srcaddr, *dstaddr;
4498 	sa_family_t af;
4499 	uint32_t add, min, max;
4500 
4501 	if (src == NULL) {
4502 		*diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
4503 		return ((ipsa_t *)-1);
4504 	}
4505 	if (dst == NULL) {
4506 		*diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
4507 		return ((ipsa_t *)-1);
4508 	}
4509 	if (range == NULL) {
4510 		*diagnostic = SADB_X_DIAGNOSTIC_MISSING_RANGE;
4511 		return ((ipsa_t *)-1);
4512 	}
4513 
4514 	min = ntohl(range->sadb_spirange_min);
4515 	max = ntohl(range->sadb_spirange_max);
4516 	dsa = (struct sockaddr_in *)(dst + 1);
4517 	dsa6 = (struct sockaddr_in6 *)dsa;
4518 
4519 	ssa = (struct sockaddr_in *)(src + 1);
4520 	ssa6 = (struct sockaddr_in6 *)ssa;
4521 	if (dsa->sin_family != ssa->sin_family) {
4522 		*diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
4523 		return ((ipsa_t *)-1);
4524 	}
4525 
4526 	srcaddr = ALL_ZEROES_PTR;
4527 	af = dsa->sin_family;
4528 	switch (af) {
4529 	case AF_INET:
4530 		if (src != NULL)
4531 			srcaddr = (uint32_t *)(&ssa->sin_addr);
4532 		dstaddr = (uint32_t *)(&dsa->sin_addr);
4533 		break;
4534 	case AF_INET6:
4535 		if (src != NULL)
4536 			srcaddr = (uint32_t *)(&ssa6->sin6_addr);
4537 		dstaddr = (uint32_t *)(&dsa6->sin6_addr);
4538 		break;
4539 	default:
4540 		*diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
4541 		return ((ipsa_t *)-1);
4542 	}
4543 
4544 	if (master_spi < min || master_spi > max) {
4545 		/* Return a random value in the range. */
4546 		(void) random_get_pseudo_bytes((uint8_t *)&add, sizeof (add));
4547 		master_spi = min + (add % (max - min + 1));
4548 	}
4549 
4550 	/*
4551 	 * Since master_spi is passed in host order, we need to htonl() it
4552 	 * for the purposes of creating a new SA.
4553 	 */
4554 	return (sadb_makelarvalassoc(htonl(master_spi), srcaddr, dstaddr, af));
4555 }
4556 
4557 /*
4558  *
4559  * Locate an ACQUIRE and nuke it.  If I have an samsg that's larger than the
4560  * base header, just ignore it.	 Otherwise, lock down the whole ACQUIRE list
4561  * and scan for the sequence number in question.  I may wish to accept an
4562  * address pair with it, for easier searching.
4563  *
4564  * Caller frees the message, so we don't have to here.
4565  *
4566  * NOTE:	The ip_q parameter may be used in the future for ACQUIRE
4567  *		failures.
4568  */
4569 /* ARGSUSED */
4570 void
4571 sadb_in_acquire(sadb_msg_t *samsg, sadbp_t *sp, queue_t *ip_q)
4572 {
4573 	int i;
4574 	ipsacq_t *acqrec;
4575 	iacqf_t *bucket;
4576 
4577 	/*
4578 	 * I only accept the base header for this!
4579 	 * Though to be honest, requiring the dst address would help
4580 	 * immensely.
4581 	 *
4582 	 * XXX	There are already cases where I can get the dst address.
4583 	 */
4584 	if (samsg->sadb_msg_len > SADB_8TO64(sizeof (*samsg)))
4585 		return;
4586 
4587 	/*
4588 	 * Using the samsg->sadb_msg_seq, find the ACQUIRE record, delete it,
4589 	 * (and in the future send a message to IP with the appropriate error
4590 	 * number).
4591 	 *
4592 	 * Q: Do I want to reject if pid != 0?
4593 	 */
4594 
4595 	for (i = 0; i < OUTBOUND_BUCKETS; i++) {
4596 		bucket = &sp->s_v4.sdb_acq[i];
4597 		mutex_enter(&bucket->iacqf_lock);
4598 		for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
4599 		    acqrec = acqrec->ipsacq_next) {
4600 			if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
4601 				break;	/* for acqrec... loop. */
4602 		}
4603 		if (acqrec != NULL)
4604 			break;	/* for i = 0... loop. */
4605 
4606 		mutex_exit(&bucket->iacqf_lock);
4607 
4608 		/* And then check the corresponding v6 bucket. */
4609 		bucket = &sp->s_v6.sdb_acq[i];
4610 		mutex_enter(&bucket->iacqf_lock);
4611 		for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
4612 		    acqrec = acqrec->ipsacq_next) {
4613 			if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
4614 				break;	/* for acqrec... loop. */
4615 		}
4616 		if (acqrec != NULL)
4617 			break;	/* for i = 0... loop. */
4618 
4619 		mutex_exit(&bucket->iacqf_lock);
4620 	}
4621 
4622 	if (acqrec == NULL)
4623 		return;
4624 
4625 	/*
4626 	 * What do I do with the errno and IP?	I may need mp's services a
4627 	 * little more.	 See sadb_destroy_acquire() for future directions
4628 	 * beyond free the mblk chain on the acquire record.
4629 	 */
4630 
4631 	ASSERT(&bucket->iacqf_lock == acqrec->ipsacq_linklock);
4632 	sadb_destroy_acquire(acqrec);
4633 	/* Have to exit mutex here, because of breaking out of for loop. */
4634 	mutex_exit(&bucket->iacqf_lock);
4635 }
4636 
4637 /*
4638  * The following functions work with the replay windows of an SA.  They assume
4639  * the ipsa->ipsa_replay_arr is an array of uint64_t, and that the bit vector
4640  * represents the highest sequence number packet received, and back
4641  * (ipsa->ipsa_replay_wsize) packets.
4642  */
4643 
4644 /*
4645  * Is the replay bit set?
4646  */
4647 static boolean_t
4648 ipsa_is_replay_set(ipsa_t *ipsa, uint32_t offset)
4649 {
4650 	uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
4651 
4652 	return ((bit & ipsa->ipsa_replay_arr[offset >> 6]) ? B_TRUE : B_FALSE);
4653 }
4654 
4655 /*
4656  * Shift the bits of the replay window over.
4657  */
4658 static void
4659 ipsa_shift_replay(ipsa_t *ipsa, uint32_t shift)
4660 {
4661 	int i;
4662 	int jump = ((shift - 1) >> 6) + 1;
4663 
4664 	if (shift == 0)
4665 		return;
4666 
4667 	for (i = (ipsa->ipsa_replay_wsize - 1) >> 6; i >= 0; i--) {
4668 		if (i + jump <= (ipsa->ipsa_replay_wsize - 1) >> 6) {
4669 			ipsa->ipsa_replay_arr[i + jump] |=
4670 			    ipsa->ipsa_replay_arr[i] >> (64 - (shift & 63));
4671 		}
4672 		ipsa->ipsa_replay_arr[i] <<= shift;
4673 	}
4674 }
4675 
4676 /*
4677  * Set a bit in the bit vector.
4678  */
4679 static void
4680 ipsa_set_replay(ipsa_t *ipsa, uint32_t offset)
4681 {
4682 	uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
4683 
4684 	ipsa->ipsa_replay_arr[offset >> 6] |= bit;
4685 }
4686 
4687 #define	SADB_MAX_REPLAY_VALUE 0xffffffff
4688 
4689 /*
4690  * Assume caller has NOT done ntohl() already on seq.  Check to see
4691  * if replay sequence number "seq" has been seen already.
4692  */
4693 boolean_t
4694 sadb_replay_check(ipsa_t *ipsa, uint32_t seq)
4695 {
4696 	boolean_t rc;
4697 	uint32_t diff;
4698 
4699 	if (ipsa->ipsa_replay_wsize == 0)
4700 		return (B_TRUE);
4701 
4702 	/*
4703 	 * NOTE:  I've already checked for 0 on the wire in sadb_replay_peek().
4704 	 */
4705 
4706 	/* Convert sequence number into host order before holding the mutex. */
4707 	seq = ntohl(seq);
4708 
4709 	mutex_enter(&ipsa->ipsa_lock);
4710 
4711 	/* Initialize inbound SA's ipsa_replay field to last one received. */
4712 	if (ipsa->ipsa_replay == 0)
4713 		ipsa->ipsa_replay = 1;
4714 
4715 	if (seq > ipsa->ipsa_replay) {
4716 		/*
4717 		 * I have received a new "highest value received".  Shift
4718 		 * the replay window over.
4719 		 */
4720 		diff = seq - ipsa->ipsa_replay;
4721 		if (diff < ipsa->ipsa_replay_wsize) {
4722 			/* In replay window, shift bits over. */
4723 			ipsa_shift_replay(ipsa, diff);
4724 		} else {
4725 			/* WAY FAR AHEAD, clear bits and start again. */
4726 			bzero(ipsa->ipsa_replay_arr,
4727 			    sizeof (ipsa->ipsa_replay_arr));
4728 		}
4729 		ipsa_set_replay(ipsa, 0);
4730 		ipsa->ipsa_replay = seq;
4731 		rc = B_TRUE;
4732 		goto done;
4733 	}
4734 	diff = ipsa->ipsa_replay - seq;
4735 	if (diff >= ipsa->ipsa_replay_wsize || ipsa_is_replay_set(ipsa, diff)) {
4736 		rc = B_FALSE;
4737 		goto done;
4738 	}
4739 	/* Set this packet as seen. */
4740 	ipsa_set_replay(ipsa, diff);
4741 
4742 	rc = B_TRUE;
4743 done:
4744 	mutex_exit(&ipsa->ipsa_lock);
4745 	return (rc);
4746 }
4747 
4748 /*
4749  * "Peek" and see if we should even bother going through the effort of
4750  * running an authentication check on the sequence number passed in.
4751  * this takes into account packets that are below the replay window,
4752  * and collisions with already replayed packets.  Return B_TRUE if it
4753  * is okay to proceed, B_FALSE if this packet should be dropped immeidately.
4754  * Assume same byte-ordering as sadb_replay_check.
4755  */
4756 boolean_t
4757 sadb_replay_peek(ipsa_t *ipsa, uint32_t seq)
4758 {
4759 	boolean_t rc = B_FALSE;
4760 	uint32_t diff;
4761 
4762 	if (ipsa->ipsa_replay_wsize == 0)
4763 		return (B_TRUE);
4764 
4765 	/*
4766 	 * 0 is 0, regardless of byte order... :)
4767 	 *
4768 	 * If I get 0 on the wire (and there is a replay window) then the
4769 	 * sender most likely wrapped.	This ipsa may need to be marked or
4770 	 * something.
4771 	 */
4772 	if (seq == 0)
4773 		return (B_FALSE);
4774 
4775 	seq = ntohl(seq);
4776 	mutex_enter(&ipsa->ipsa_lock);
4777 	if (seq < ipsa->ipsa_replay - ipsa->ipsa_replay_wsize &&
4778 	    ipsa->ipsa_replay >= ipsa->ipsa_replay_wsize)
4779 		goto done;
4780 
4781 	/*
4782 	 * If I've hit 0xffffffff, then quite honestly, I don't need to
4783 	 * bother with formalities.  I'm not accepting any more packets
4784 	 * on this SA.
4785 	 */
4786 	if (ipsa->ipsa_replay == SADB_MAX_REPLAY_VALUE) {
4787 		/*
4788 		 * Since we're already holding the lock, update the
4789 		 * expire time ala. sadb_replay_delete() and return.
4790 		 */
4791 		ipsa->ipsa_hardexpiretime = (time_t)1;
4792 		goto done;
4793 	}
4794 
4795 	if (seq <= ipsa->ipsa_replay) {
4796 		/*
4797 		 * This seq is in the replay window.  I'm not below it,
4798 		 * because I already checked for that above!
4799 		 */
4800 		diff = ipsa->ipsa_replay - seq;
4801 		if (ipsa_is_replay_set(ipsa, diff))
4802 			goto done;
4803 	}
4804 	/* Else return B_TRUE, I'm going to advance the window. */
4805 
4806 	rc = B_TRUE;
4807 done:
4808 	mutex_exit(&ipsa->ipsa_lock);
4809 	return (rc);
4810 }
4811 
4812 /*
4813  * Delete a single SA.
4814  *
4815  * For now, use the quick-and-dirty trick of making the association's
4816  * hard-expire lifetime (time_t)1, ensuring deletion by the *_ager().
4817  */
4818 void
4819 sadb_replay_delete(ipsa_t *assoc)
4820 {
4821 	mutex_enter(&assoc->ipsa_lock);
4822 	assoc->ipsa_hardexpiretime = (time_t)1;
4823 	mutex_exit(&assoc->ipsa_lock);
4824 }
4825 
4826 /*
4827  * Given a queue that presumably points to IP, send a T_BIND_REQ for _proto_
4828  * down.  The caller will handle the T_BIND_ACK locally.
4829  */
4830 boolean_t
4831 sadb_t_bind_req(queue_t *q, int proto)
4832 {
4833 	struct T_bind_req *tbr;
4834 	mblk_t *mp;
4835 
4836 	mp = allocb(sizeof (struct T_bind_req) + 1, BPRI_HI);
4837 	if (mp == NULL) {
4838 		/* cmn_err(CE_WARN, */
4839 		/* "sadb_t_bind_req(%d): couldn't allocate mblk\n", proto); */
4840 		return (B_FALSE);
4841 	}
4842 	mp->b_datap->db_type = M_PCPROTO;
4843 	tbr = (struct T_bind_req *)mp->b_rptr;
4844 	mp->b_wptr += sizeof (struct T_bind_req);
4845 	tbr->PRIM_type = T_BIND_REQ;
4846 	tbr->ADDR_length = 0;
4847 	tbr->ADDR_offset = 0;
4848 	tbr->CONIND_number = 0;
4849 	*mp->b_wptr = (uint8_t)proto;
4850 	mp->b_wptr++;
4851 
4852 	putnext(q, mp);
4853 	return (B_TRUE);
4854 }
4855 
4856 /*
4857  * Rate-limiting front-end to strlog() for AH and ESP.	Uses the ndd variables
4858  * in /dev/ip and the same rate-limiting clock so that there's a single
4859  * knob to turn to throttle the rate of messages.
4860  *
4861  * This function needs to be kept in synch with ipsec_log_policy_failure() in
4862  * ip.c.  Eventually, ipsec_log_policy_failure() should use this function.
4863  */
4864 void
4865 ipsec_rl_strlog(short mid, short sid, char level, ushort_t sl, char *fmt, ...)
4866 {
4867 	va_list adx;
4868 	hrtime_t current = gethrtime();
4869 
4870 	/* Convert interval (in msec) to hrtime (in nsec), which means * 10^6 */
4871 	if (ipsec_policy_failure_last +
4872 	    ((hrtime_t)ipsec_policy_log_interval * (hrtime_t)1000000) <=
4873 	    current) {
4874 		/*
4875 		 * Throttle the logging such that I only log one
4876 		 * message every 'ipsec_policy_log_interval' amount
4877 		 * of time.
4878 		 */
4879 		va_start(adx, fmt);
4880 		(void) vstrlog(mid, sid, level, sl, fmt, adx);
4881 		va_end(adx);
4882 		ipsec_policy_failure_last = current;
4883 	}
4884 }
4885 
4886 /*
4887  * Special front-end to ipsec_rl_strlog() dealing with SA failure.
4888  * this is designed to take only a format string with "* %x * %s *", so
4889  * that "spi" is printed first, then "addr" is converted using inet_pton().
4890  *
4891  * This is abstracted out to save the stack space for only when inet_pton()
4892  * is called.  Make sure "spi" is in network order; it usually is when this
4893  * would get called.
4894  */
4895 void
4896 ipsec_assocfailure(short mid, short sid, char level, ushort_t sl, char *fmt,
4897     uint32_t spi, void *addr, int af)
4898 {
4899 	char buf[INET6_ADDRSTRLEN];
4900 
4901 	ASSERT(af == AF_INET6 || af == AF_INET);
4902 
4903 	ipsec_rl_strlog(mid, sid, level, sl, fmt, ntohl(spi),
4904 	    inet_ntop(af, addr, buf, sizeof (buf)));
4905 }
4906 
4907 /*
4908  * Fills in a reference to the policy, if any, from the conn, in *ppp
4909  * Releases a reference to the passed conn_t.
4910  */
4911 
4912 /* ARGSUSED */
4913 static void
4914 ipsec_conn_pol(ipsec_selector_t *sel, conn_t *connp, ipsec_policy_t **ppp,
4915     ipsec_action_t **app)
4916 {
4917 	ipsec_policy_t	*pp;
4918 	ipsec_latch_t	*ipl = connp->conn_latch;
4919 
4920 	if ((ipl != NULL) && (ipl->ipl_out_policy != NULL)) {
4921 		pp = ipl->ipl_out_policy;
4922 		IPPOL_REFHOLD(pp);
4923 	} else {
4924 		pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, connp, NULL, sel);
4925 	}
4926 	*ppp = pp;
4927 	CONN_DEC_REF(connp);
4928 }
4929 
4930 /*
4931  * The following functions scan through active conn_t structures
4932  * and return a reference to the best-matching policy it can find.
4933  * Caller must release the reference.
4934  */
4935 static void
4936 ipsec_udp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ipsec_action_t **app)
4937 {
4938 	connf_t *connfp;
4939 	conn_t *connp = NULL;
4940 	ipsec_selector_t portonly;
4941 
4942 	bzero((void*)&portonly, sizeof (portonly));
4943 
4944 	if (sel->ips_local_port == 0)
4945 		return;
4946 
4947 	connfp = &ipcl_udp_fanout[IPCL_UDP_HASH(sel->ips_local_port)];
4948 	mutex_enter(&connfp->connf_lock);
4949 
4950 	if (sel->ips_isv4) {
4951 		connp = connfp->connf_head;
4952 		while (connp != NULL) {
4953 			if (IPCL_UDP_MATCH(connp, sel->ips_local_port,
4954 			    sel->ips_local_addr_v4, sel->ips_remote_port,
4955 			    sel->ips_remote_addr_v4))
4956 				break;
4957 			connp = connp->conn_next;
4958 		}
4959 
4960 		if (connp == NULL) {
4961 			/* Try port-only match in IPv6. */
4962 			portonly.ips_local_port = sel->ips_local_port;
4963 			sel = &portonly;
4964 		}
4965 	}
4966 
4967 	if (connp == NULL) {
4968 		connp = connfp->connf_head;
4969 		while (connp != NULL) {
4970 			if (IPCL_UDP_MATCH_V6(connp, sel->ips_local_port,
4971 			    sel->ips_local_addr_v6, sel->ips_remote_port,
4972 			    sel->ips_remote_addr_v6))
4973 				break;
4974 			connp = connp->conn_next;
4975 		}
4976 
4977 		if (connp == NULL) {
4978 			mutex_exit(&connfp->connf_lock);
4979 			return;
4980 		}
4981 	}
4982 
4983 	CONN_INC_REF(connp);
4984 	mutex_exit(&connfp->connf_lock);
4985 
4986 	ipsec_conn_pol(sel, connp, ppp, app);
4987 }
4988 
4989 static conn_t *
4990 ipsec_find_listen_conn(uint16_t *pptr, ipsec_selector_t *sel)
4991 {
4992 	connf_t *connfp;
4993 	conn_t *connp = NULL;
4994 	const in6_addr_t *v6addrmatch = &sel->ips_local_addr_v6;
4995 
4996 	if (sel->ips_local_port == 0)
4997 		return (NULL);
4998 
4999 	connfp = &ipcl_bind_fanout[IPCL_BIND_HASH(sel->ips_local_port)];
5000 	mutex_enter(&connfp->connf_lock);
5001 
5002 	if (sel->ips_isv4) {
5003 		connp = connfp->connf_head;
5004 		while (connp != NULL) {
5005 			if (IPCL_BIND_MATCH(connp, IPPROTO_TCP,
5006 			    sel->ips_local_addr_v4, pptr[1]))
5007 				break;
5008 			connp = connp->conn_next;
5009 		}
5010 
5011 		if (connp == NULL) {
5012 			/* Match to all-zeroes. */
5013 			v6addrmatch = &ipv6_all_zeros;
5014 		}
5015 	}
5016 
5017 	if (connp == NULL) {
5018 		connp = connfp->connf_head;
5019 		while (connp != NULL) {
5020 			if (IPCL_BIND_MATCH_V6(connp, IPPROTO_TCP,
5021 			    *v6addrmatch, pptr[1]))
5022 				break;
5023 			connp = connp->conn_next;
5024 		}
5025 
5026 		if (connp == NULL) {
5027 			mutex_exit(&connfp->connf_lock);
5028 			return (NULL);
5029 		}
5030 	}
5031 
5032 	CONN_INC_REF(connp);
5033 	mutex_exit(&connfp->connf_lock);
5034 	return (connp);
5035 }
5036 
5037 static void
5038 ipsec_tcp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ipsec_action_t **app)
5039 {
5040 	connf_t 	*connfp;
5041 	conn_t		*connp;
5042 	uint32_t	ports;
5043 	uint16_t	*pptr = (uint16_t *)&ports;
5044 
5045 	/*
5046 	 * Find TCP state in the following order:
5047 	 * 1.) Connected conns.
5048 	 * 2.) Listeners.
5049 	 *
5050 	 * Even though #2 will be the common case for inbound traffic, only
5051 	 * following this order insures correctness.
5052 	 */
5053 
5054 	if (sel->ips_local_port == 0)
5055 		return;
5056 
5057 	/*
5058 	 * 0 should be fport, 1 should be lport.  SRC is the local one here.
5059 	 * See ipsec_construct_inverse_acquire() for details.
5060 	 */
5061 	pptr[0] = sel->ips_remote_port;
5062 	pptr[1] = sel->ips_local_port;
5063 
5064 	connfp = &ipcl_conn_fanout[IPCL_CONN_HASH(sel->ips_remote_addr_v4,
5065 	    ports)];
5066 	mutex_enter(&connfp->connf_lock);
5067 	connp = connfp->connf_head;
5068 
5069 	if (sel->ips_isv4) {
5070 		while (connp != NULL) {
5071 			if (IPCL_CONN_MATCH(connp, IPPROTO_TCP,
5072 			    sel->ips_remote_addr_v4, sel->ips_local_addr_v4,
5073 			    ports))
5074 				break;
5075 			connp = connp->conn_next;
5076 		}
5077 	} else {
5078 		while (connp != NULL) {
5079 			if (IPCL_CONN_MATCH_V6(connp, IPPROTO_TCP,
5080 			    sel->ips_remote_addr_v6, sel->ips_local_addr_v6,
5081 			    ports))
5082 				break;
5083 			connp = connp->conn_next;
5084 		}
5085 	}
5086 
5087 	if (connp != NULL) {
5088 		CONN_INC_REF(connp);
5089 		mutex_exit(&connfp->connf_lock);
5090 	} else {
5091 		mutex_exit(&connfp->connf_lock);
5092 
5093 		/* Try the listen hash. */
5094 		if ((connp = ipsec_find_listen_conn(pptr, sel)) == NULL)
5095 			return;
5096 	}
5097 
5098 	ipsec_conn_pol(sel, connp, ppp, app);
5099 }
5100 
5101 static void
5102 ipsec_sctp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
5103     ipsec_action_t **app)
5104 {
5105 	conn_t		*connp;
5106 	uint32_t	ports;
5107 	uint16_t	*pptr = (uint16_t *)&ports;
5108 
5109 	/*
5110 	 * Find SCP state in the following order:
5111 	 * 1.) Connected conns.
5112 	 * 2.) Listeners.
5113 	 *
5114 	 * Even though #2 will be the common case for inbound traffic, only
5115 	 * following this order insures correctness.
5116 	 */
5117 
5118 	if (sel->ips_local_port == 0)
5119 		return;
5120 
5121 	/*
5122 	 * 0 should be fport, 1 should be lport.  SRC is the local one here.
5123 	 * See ipsec_construct_inverse_acquire() for details.
5124 	 */
5125 	pptr[0] = sel->ips_remote_port;
5126 	pptr[1] = sel->ips_local_port;
5127 
5128 	if (sel->ips_isv4) {
5129 		in6_addr_t	src, dst;
5130 
5131 		IN6_IPADDR_TO_V4MAPPED(sel->ips_remote_addr_v4, &dst);
5132 		IN6_IPADDR_TO_V4MAPPED(sel->ips_local_addr_v4, &src);
5133 		connp = sctp_find_conn(&dst, &src, ports, 0, ALL_ZONES);
5134 	} else {
5135 		connp = sctp_find_conn(&sel->ips_remote_addr_v6,
5136 		    &sel->ips_local_addr_v6, ports, 0, ALL_ZONES);
5137 	}
5138 	if (connp == NULL)
5139 		return;
5140 	ipsec_conn_pol(sel, connp, ppp, app);
5141 }
5142 
5143 static void
5144 ipsec_oth_pol(ipsec_selector_t *sel,
5145     ipsec_policy_t **ppp, ipsec_action_t **app)
5146 {
5147 	boolean_t	isv4 = sel->ips_isv4;
5148 	connf_t		*connfp;
5149 	conn_t		*connp;
5150 
5151 	if (isv4) {
5152 		connfp = &ipcl_proto_fanout[sel->ips_protocol];
5153 	} else {
5154 		connfp = &ipcl_proto_fanout_v6[sel->ips_protocol];
5155 	}
5156 
5157 	mutex_enter(&connfp->connf_lock);
5158 	for (connp = connfp->connf_head; connp != NULL;
5159 	    connp = connp->conn_next) {
5160 		if (!((isv4 && !((connp->conn_src == 0 ||
5161 		    connp->conn_src == sel->ips_local_addr_v4) &&
5162 		    (connp->conn_rem == 0 ||
5163 		    connp->conn_rem == sel->ips_remote_addr_v4))) ||
5164 		    (!isv4 && !((IN6_IS_ADDR_UNSPECIFIED(&connp->conn_srcv6) ||
5165 		    IN6_ARE_ADDR_EQUAL(&connp->conn_srcv6,
5166 		    &sel->ips_local_addr_v6)) &&
5167 		    (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_remv6) ||
5168 		    IN6_ARE_ADDR_EQUAL(&connp->conn_remv6,
5169 			&sel->ips_remote_addr_v6)))))) {
5170 			break;
5171 		}
5172 	}
5173 	if (connp == NULL) {
5174 		mutex_exit(&connfp->connf_lock);
5175 		return;
5176 	}
5177 
5178 	CONN_INC_REF(connp);
5179 	mutex_exit(&connfp->connf_lock);
5180 
5181 	ipsec_conn_pol(sel, connp, ppp, app);
5182 }
5183 
5184 /*
5185  * Construct an inverse ACQUIRE reply based on:
5186  *
5187  * 1.) Current global policy.
5188  * 2.) An conn_t match depending on what all was passed in the extv[].
5189  * ...
5190  * N.) Other stuff TBD (e.g. identities)
5191  *
5192  * If there is an error, set sadb_msg_errno and sadb_x_msg_diagnostic
5193  * in this function so the caller can extract them where appropriately.
5194  *
5195  * The SRC address is the local one - just like an outbound ACQUIRE message.
5196  */
5197 mblk_t *
5198 ipsec_construct_inverse_acquire(sadb_msg_t *samsg, sadb_ext_t *extv[])
5199 {
5200 	int err;
5201 	int diagnostic;
5202 	sadb_address_t *srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC],
5203 	    *dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST];
5204 	struct sockaddr_in *src, *dst;
5205 	struct sockaddr_in6 *src6, *dst6;
5206 	ipsec_policy_t *pp;
5207 	ipsec_action_t *ap;
5208 	ipsec_selector_t sel;
5209 	mblk_t *retmp;
5210 
5211 	bzero(&sel, sizeof (sel));
5212 	sel.ips_protocol = srcext->sadb_address_proto;
5213 	dst = (struct sockaddr_in *)(dstext + 1);
5214 	if (dst->sin_family == AF_INET6) {
5215 		dst6 = (struct sockaddr_in6 *)dst;
5216 		src6 = (struct sockaddr_in6 *)(srcext + 1);
5217 		if (src6->sin6_family != AF_INET6) {
5218 			diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
5219 			err = EINVAL;
5220 			goto bail;
5221 		}
5222 		sel.ips_remote_addr_v6 = dst6->sin6_addr;
5223 		sel.ips_local_addr_v6 = src6->sin6_addr;
5224 		if (sel.ips_protocol == IPPROTO_ICMPV6) {
5225 			sel.ips_is_icmp_inv_acq = 1;
5226 		} else {
5227 			sel.ips_remote_port = dst6->sin6_port;
5228 			sel.ips_local_port = src6->sin6_port;
5229 		}
5230 		sel.ips_isv4 = B_FALSE;
5231 	} else {
5232 		src = (struct sockaddr_in *)(srcext + 1);
5233 		if (src->sin_family != AF_INET) {
5234 			diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
5235 			err = EINVAL;
5236 			goto bail;
5237 		}
5238 		sel.ips_remote_addr_v4 = dst->sin_addr.s_addr;
5239 		sel.ips_local_addr_v4 = src->sin_addr.s_addr;
5240 		if (sel.ips_protocol == IPPROTO_ICMP) {
5241 			sel.ips_is_icmp_inv_acq = 1;
5242 		} else {
5243 			sel.ips_remote_port = dst->sin_port;
5244 			sel.ips_local_port = src->sin_port;
5245 		}
5246 		sel.ips_isv4 = B_TRUE;
5247 	}
5248 
5249 	/*
5250 	 * Okay, we have the addresses and other selector information.
5251 	 * Let's first find a conn...
5252 	 */
5253 	pp = NULL; ap = NULL;
5254 	switch (sel.ips_protocol) {
5255 	case IPPROTO_TCP:
5256 		ipsec_tcp_pol(&sel, &pp, &ap);
5257 		break;
5258 	case IPPROTO_UDP:
5259 		ipsec_udp_pol(&sel, &pp, &ap);
5260 		break;
5261 	case IPPROTO_SCTP:
5262 		ipsec_sctp_pol(&sel, &pp, &ap);
5263 		break;
5264 	default:
5265 		ipsec_oth_pol(&sel, &pp, &ap);
5266 		break;
5267 	}
5268 
5269 	/*
5270 	 * If we didn't find a matching conn_t, take a look in the global
5271 	 * policy.
5272 	 */
5273 	if ((pp == NULL) && (ap == NULL)) {
5274 		pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, NULL, NULL, &sel);
5275 		if (pp == NULL) {
5276 			/* There's no global policy. */
5277 			err = ENOENT;
5278 			diagnostic = 0;
5279 			goto bail;
5280 		}
5281 	}
5282 
5283 	/*
5284 	 * Now that we have a policy entry/widget, construct an ACQUIRE
5285 	 * message based on that, fix fields where appropriate,
5286 	 * and return the message.
5287 	 */
5288 	retmp = sadb_extended_acquire(&sel, pp, ap, samsg->sadb_msg_seq,
5289 	    samsg->sadb_msg_pid);
5290 	if (pp != NULL) {
5291 		IPPOL_REFRELE(pp);
5292 	}
5293 	if (ap != NULL) {
5294 		IPACT_REFRELE(ap);
5295 	}
5296 	if (retmp != NULL) {
5297 		return (retmp);
5298 	} else {
5299 		err = ENOMEM;
5300 		diagnostic = 0;
5301 	bail:
5302 		samsg->sadb_msg_errno = (uint8_t)err;
5303 		samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
5304 		return (NULL);
5305 	}
5306 }
5307 
5308 /*
5309  * ipsa_lpkt is a one-element queue, only manipulated by casptr within
5310  * the next two functions.
5311  *
5312  * These functions loop calling casptr() until the swap "happens",
5313  * turning a compare-and-swap op into an atomic swap operation.
5314  */
5315 
5316 /*
5317  * sadb_set_lpkt: Atomically swap in a value to ipsa->ipsa_lpkt and
5318  * freemsg the previous value.  free clue: freemsg(NULL) is safe.
5319  */
5320 
5321 void
5322 sadb_set_lpkt(ipsa_t *ipsa, mblk_t *npkt)
5323 {
5324 	mblk_t *opkt;
5325 
5326 	membar_producer();
5327 	do
5328 		opkt = ipsa->ipsa_lpkt;
5329 	while (casptr(&ipsa->ipsa_lpkt, opkt, npkt) != opkt);
5330 
5331 	ip_drop_packet(opkt, B_TRUE, NULL, NULL, &ipdrops_sadb_inlarval_replace,
5332 	    &sadb_dropper);
5333 }
5334 
5335 /*
5336  * sadb_clear_lpkt: Atomically clear ipsa->ipsa_lpkt and return the
5337  * previous value.
5338  */
5339 
5340 mblk_t *
5341 sadb_clear_lpkt(ipsa_t *ipsa)
5342 {
5343 	mblk_t *opkt;
5344 
5345 	do
5346 		opkt = ipsa->ipsa_lpkt;
5347 	while (casptr(&ipsa->ipsa_lpkt, opkt, NULL) != opkt);
5348 
5349 	return (opkt);
5350 }
5351 
5352 /*
5353  * Walker callback used by sadb_alg_update() to free/create crypto
5354  * context template when a crypto software provider is removed or
5355  * added.
5356  */
5357 
5358 struct sadb_update_alg_state {
5359 	ipsec_algtype_t alg_type;
5360 	uint8_t alg_id;
5361 	boolean_t is_added;
5362 };
5363 
5364 static void
5365 sadb_alg_update_cb(isaf_t *head, ipsa_t *entry, void *cookie)
5366 {
5367 	struct sadb_update_alg_state *update_state =
5368 	    (struct sadb_update_alg_state *)cookie;
5369 	crypto_ctx_template_t *ctx_tmpl = NULL;
5370 
5371 	ASSERT(MUTEX_HELD(&head->isaf_lock));
5372 
5373 	if (entry->ipsa_state == IPSA_STATE_LARVAL)
5374 		return;
5375 
5376 	mutex_enter(&entry->ipsa_lock);
5377 
5378 	switch (update_state->alg_type) {
5379 	case IPSEC_ALG_AUTH:
5380 		if (entry->ipsa_auth_alg == update_state->alg_id)
5381 			ctx_tmpl = &entry->ipsa_authtmpl;
5382 		break;
5383 	case IPSEC_ALG_ENCR:
5384 		if (entry->ipsa_encr_alg == update_state->alg_id)
5385 			ctx_tmpl = &entry->ipsa_encrtmpl;
5386 		break;
5387 	default:
5388 		ctx_tmpl = NULL;
5389 	}
5390 
5391 	if (ctx_tmpl == NULL) {
5392 		mutex_exit(&entry->ipsa_lock);
5393 		return;
5394 	}
5395 
5396 	/*
5397 	 * The context template of the SA may be affected by the change
5398 	 * of crypto provider.
5399 	 */
5400 	if (update_state->is_added) {
5401 		/* create the context template if not already done */
5402 		if (*ctx_tmpl == NULL) {
5403 			(void) ipsec_create_ctx_tmpl(entry,
5404 			    update_state->alg_type);
5405 		}
5406 	} else {
5407 		/*
5408 		 * The crypto provider was removed. If the context template
5409 		 * exists but it is no longer valid, free it.
5410 		 */
5411 		if (*ctx_tmpl != NULL)
5412 			ipsec_destroy_ctx_tmpl(entry, update_state->alg_type);
5413 	}
5414 
5415 	mutex_exit(&entry->ipsa_lock);
5416 }
5417 
5418 /*
5419  * Invoked by IP when an software crypto provider has been updated.
5420  * The type and id of the corresponding algorithm is passed as argument.
5421  * is_added is B_TRUE if the provider was added, B_FALSE if it was
5422  * removed. The function updates the SADB and free/creates the
5423  * context templates associated with SAs if needed.
5424  */
5425 
5426 #define	SADB_ALG_UPDATE_WALK(table, numentries) \
5427     sadb_walker(table, numentries, sadb_alg_update_cb, &update_state);
5428 
5429 void
5430 sadb_alg_update(ipsec_algtype_t alg_type, uint8_t alg_id, boolean_t is_added)
5431 {
5432 	struct sadb_update_alg_state update_state;
5433 
5434 	update_state.alg_type = alg_type;
5435 	update_state.alg_id = alg_id;
5436 	update_state.is_added = is_added;
5437 
5438 	if (alg_type == IPSEC_ALG_AUTH) {
5439 		/* walk the AH tables only for auth. algorithm changes */
5440 		SADB_ALG_UPDATE_WALK(ah_sadb.s_v4.sdb_of, OUTBOUND_BUCKETS);
5441 		SADB_ALG_UPDATE_WALK(ah_sadb.s_v4.sdb_if, INBOUND_BUCKETS);
5442 		SADB_ALG_UPDATE_WALK(ah_sadb.s_v6.sdb_of, OUTBOUND_BUCKETS);
5443 		SADB_ALG_UPDATE_WALK(ah_sadb.s_v6.sdb_if, INBOUND_BUCKETS);
5444 	}
5445 
5446 	/* walk the ESP tables */
5447 	SADB_ALG_UPDATE_WALK(esp_sadb.s_v4.sdb_of, OUTBOUND_BUCKETS);
5448 	SADB_ALG_UPDATE_WALK(esp_sadb.s_v4.sdb_if, INBOUND_BUCKETS);
5449 	SADB_ALG_UPDATE_WALK(esp_sadb.s_v6.sdb_of, OUTBOUND_BUCKETS);
5450 	SADB_ALG_UPDATE_WALK(esp_sadb.s_v6.sdb_if, INBOUND_BUCKETS);
5451 }
5452 
5453 /*
5454  * Creates a context template for the specified SA. This function
5455  * is called when an SA is created and when a context template needs
5456  * to be created due to a change of software provider.
5457  */
5458 int
5459 ipsec_create_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
5460 {
5461 	ipsec_alginfo_t *alg;
5462 	crypto_mechanism_t mech;
5463 	crypto_key_t *key;
5464 	crypto_ctx_template_t *sa_tmpl;
5465 	int rv;
5466 
5467 	ASSERT(MUTEX_HELD(&alg_lock));
5468 	ASSERT(MUTEX_HELD(&sa->ipsa_lock));
5469 
5470 	/* get pointers to the algorithm info, context template, and key */
5471 	switch (alg_type) {
5472 	case IPSEC_ALG_AUTH:
5473 		key = &sa->ipsa_kcfauthkey;
5474 		sa_tmpl = &sa->ipsa_authtmpl;
5475 		alg = ipsec_alglists[alg_type][sa->ipsa_auth_alg];
5476 		break;
5477 	case IPSEC_ALG_ENCR:
5478 		key = &sa->ipsa_kcfencrkey;
5479 		sa_tmpl = &sa->ipsa_encrtmpl;
5480 		alg = ipsec_alglists[alg_type][sa->ipsa_encr_alg];
5481 		break;
5482 	default:
5483 		alg = NULL;
5484 	}
5485 
5486 	if (alg == NULL || !ALG_VALID(alg))
5487 		return (EINVAL);
5488 
5489 	/* initialize the mech info structure for the framework */
5490 	ASSERT(alg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
5491 	mech.cm_type = alg->alg_mech_type;
5492 	mech.cm_param = NULL;
5493 	mech.cm_param_len = 0;
5494 
5495 	/* create a new context template */
5496 	rv = crypto_create_ctx_template(&mech, key, sa_tmpl, KM_NOSLEEP);
5497 
5498 	/*
5499 	 * CRYPTO_MECH_NOT_SUPPORTED can be returned if only hardware
5500 	 * providers are available for that mechanism. In that case
5501 	 * we don't fail, and will generate the context template from
5502 	 * the framework callback when a software provider for that
5503 	 * mechanism registers.
5504 	 *
5505 	 * The context template is assigned the special value
5506 	 * IPSEC_CTX_TMPL_ALLOC if the allocation failed due to a
5507 	 * lack of memory. No attempt will be made to use
5508 	 * the context template if it is set to this value.
5509 	 */
5510 	if (rv == CRYPTO_HOST_MEMORY) {
5511 		*sa_tmpl = IPSEC_CTX_TMPL_ALLOC;
5512 	} else if (rv != CRYPTO_SUCCESS) {
5513 		*sa_tmpl = NULL;
5514 		if (rv != CRYPTO_MECH_NOT_SUPPORTED)
5515 			return (EINVAL);
5516 	}
5517 
5518 	return (0);
5519 }
5520 
5521 /*
5522  * Destroy the context template of the specified algorithm type
5523  * of the specified SA. Must be called while holding the SA lock.
5524  */
5525 void
5526 ipsec_destroy_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
5527 {
5528 	ASSERT(MUTEX_HELD(&sa->ipsa_lock));
5529 
5530 	if (alg_type == IPSEC_ALG_AUTH) {
5531 		if (sa->ipsa_authtmpl == IPSEC_CTX_TMPL_ALLOC)
5532 			sa->ipsa_authtmpl = NULL;
5533 		else if (sa->ipsa_authtmpl != NULL) {
5534 			crypto_destroy_ctx_template(sa->ipsa_authtmpl);
5535 			sa->ipsa_authtmpl = NULL;
5536 		}
5537 	} else {
5538 		ASSERT(alg_type == IPSEC_ALG_ENCR);
5539 		if (sa->ipsa_encrtmpl == IPSEC_CTX_TMPL_ALLOC)
5540 			sa->ipsa_encrtmpl = NULL;
5541 		else if (sa->ipsa_encrtmpl != NULL) {
5542 			crypto_destroy_ctx_template(sa->ipsa_encrtmpl);
5543 			sa->ipsa_encrtmpl = NULL;
5544 		}
5545 	}
5546 }
5547 
5548 /*
5549  * Use the kernel crypto framework to check the validity of a key received
5550  * via keysock. Returns 0 if the key is OK, -1 otherwise.
5551  */
5552 int
5553 ipsec_check_key(crypto_mech_type_t mech_type, sadb_key_t *sadb_key,
5554     boolean_t is_auth, int *diag)
5555 {
5556 	crypto_mechanism_t mech;
5557 	crypto_key_t crypto_key;
5558 	int crypto_rc;
5559 
5560 	mech.cm_type = mech_type;
5561 	mech.cm_param = NULL;
5562 	mech.cm_param_len = 0;
5563 
5564 	crypto_key.ck_format = CRYPTO_KEY_RAW;
5565 	crypto_key.ck_data = sadb_key + 1;
5566 	crypto_key.ck_length = sadb_key->sadb_key_bits;
5567 
5568 	crypto_rc = crypto_key_check(&mech, &crypto_key);
5569 
5570 	switch (crypto_rc) {
5571 	case CRYPTO_SUCCESS:
5572 		return (0);
5573 	case CRYPTO_MECHANISM_INVALID:
5574 	case CRYPTO_MECH_NOT_SUPPORTED:
5575 		*diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AALG :
5576 		    SADB_X_DIAGNOSTIC_BAD_EALG;
5577 		break;
5578 	case CRYPTO_KEY_SIZE_RANGE:
5579 		*diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AKEYBITS :
5580 		    SADB_X_DIAGNOSTIC_BAD_EKEYBITS;
5581 		break;
5582 	case CRYPTO_WEAK_KEY:
5583 		*diag = is_auth ? SADB_X_DIAGNOSTIC_WEAK_AKEY :
5584 		    SADB_X_DIAGNOSTIC_WEAK_EKEY;
5585 		break;
5586 	}
5587 
5588 	return (-1);
5589 }
5590 
5591 /* ARGSUSED */
5592 static void
5593 sadb_clear_timeouts_walker(isaf_t *head, ipsa_t *ipsa, void *q)
5594 {
5595 	if (!(ipsa->ipsa_flags & IPSA_F_NATT))
5596 		return;
5597 
5598 	mutex_enter(&ipsa->ipsa_lock);
5599 	if (ipsa->ipsa_natt_q != q) {
5600 		mutex_exit(&ipsa->ipsa_lock);
5601 		return;
5602 	}
5603 
5604 	(void) quntimeout(ipsa->ipsa_natt_q, ipsa->ipsa_natt_ka_timer);
5605 
5606 	ipsa->ipsa_natt_ka_timer = 0;
5607 	ipsa->ipsa_natt_q = NULL;
5608 	mutex_exit(&ipsa->ipsa_lock);
5609 }
5610 
5611 void
5612 sadb_clear_timeouts(queue_t *q)
5613 {
5614 	sadb_walker(esp_sadb.s_v4.sdb_if, INBOUND_BUCKETS,
5615 	    sadb_clear_timeouts_walker, q);
5616 }
5617