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