xref: /illumos-gate/usr/src/uts/common/inet/ip/spdsock.c (revision d6555420322a42c16b93414c29a62f8e841abc7b)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <sys/stream.h>
32 #include <sys/strsubr.h>
33 #include <sys/strsun.h>
34 #include <sys/stropts.h>
35 #include <sys/vnode.h>
36 #include <sys/sysmacros.h>
37 #define	_SUN_TPI_VERSION 2
38 #include <sys/tihdr.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 #include <sys/mkdev.h>
42 #include <sys/debug.h>
43 #include <sys/kmem.h>
44 #include <sys/cmn_err.h>
45 #include <sys/proc.h>
46 #include <sys/suntpi.h>
47 #include <sys/policy.h>
48 
49 #include <sys/socket.h>
50 #include <netinet/in.h>
51 #include <net/pfkeyv2.h>
52 #include <net/pfpolicy.h>
53 
54 #include <inet/common.h>
55 #include <netinet/ip6.h>
56 #include <inet/ip.h>
57 #include <inet/ip6.h>
58 #include <inet/mi.h>
59 #include <inet/nd.h>
60 #include <inet/optcom.h>
61 #include <inet/ipsec_info.h>
62 #include <inet/ipsec_impl.h>
63 #include <inet/spdsock.h>
64 #include <inet/sadb.h>
65 
66 #include <sys/isa_defs.h>
67 
68 /*
69  * This is a transport provider for the PF_POLICY IPsec policy
70  * management socket, which provides a management interface into the
71  * SPD, allowing policy rules to be added, deleted, and queried.
72  *
73  * This effectively replaces the old private SIOC*IPSECONFIG ioctls
74  * with an extensible interface which will hopefully be public some
75  * day.
76  *
77  * See <net/pfpolicy.h> for more details on the protocol.
78  *
79  * We link against drv/ip and call directly into it to manipulate the
80  * SPD; see ipsec_impl.h for the policy data structures and spd.c for
81  * the code which maintains them.
82  *
83  * The MT model of this is QPAIR with the addition of some explicit
84  * locking to protect system-wide policy data structures.
85  */
86 
87 static vmem_t *spdsock_vmem;		/* for minor numbers. */
88 
89 #define	ALIGNED64(x) IS_P2ALIGNED((x), sizeof (uint64_t))
90 
91 /* Default structure copied into T_INFO_ACK messages (from rts.c...) */
92 static struct T_info_ack spdsock_g_t_info_ack = {
93 	T_INFO_ACK,
94 	T_INFINITE,	/* TSDU_size. Maximum size messages. */
95 	T_INVALID,	/* ETSDU_size. No expedited data. */
96 	T_INVALID,	/* CDATA_size. No connect data. */
97 	T_INVALID,	/* DDATA_size. No disconnect data. */
98 	0,		/* ADDR_size. */
99 	0,		/* OPT_size. No user-settable options */
100 	64 * 1024,	/* TIDU_size. spdsock allows maximum size messages. */
101 	T_COTS,		/* SERV_type. spdsock supports connection oriented. */
102 	TS_UNBND,	/* CURRENT_state. This is set from spdsock_state. */
103 	(XPG4_1)	/* Provider flags */
104 };
105 
106 /* Named Dispatch Parameter Management Structure */
107 typedef struct spdsockpparam_s {
108 	uint_t	spdsock_param_min;
109 	uint_t	spdsock_param_max;
110 	uint_t	spdsock_param_value;
111 	char *spdsock_param_name;
112 } spdsockparam_t;
113 
114 /*
115  * Table of NDD variables supported by spdsock. These are loaded into
116  * spdsock_g_nd in spdsock_init_nd.
117  * All of these are alterable, within the min/max values given, at run time.
118  */
119 static	spdsockparam_t	spdsock_param_arr[] = {
120 	/* min	max	value	name */
121 	{ 4096, 65536,	8192,	"spdsock_xmit_hiwat"},
122 	{ 0,	65536,	1024,	"spdsock_xmit_lowat"},
123 	{ 4096, 65536,	8192,	"spdsock_recv_hiwat"},
124 	{ 65536, 1024*1024*1024, 256*1024,	"spdsock_max_buf"},
125 	{ 0,	3,	0,	"spdsock_debug"},
126 };
127 #define	spdsock_xmit_hiwat	spdsock_param_arr[0].spdsock_param_value
128 #define	spdsock_xmit_lowat	spdsock_param_arr[1].spdsock_param_value
129 #define	spdsock_recv_hiwat	spdsock_param_arr[2].spdsock_param_value
130 #define	spdsock_max_buf		spdsock_param_arr[3].spdsock_param_value
131 #define	spdsock_debug		spdsock_param_arr[4].spdsock_param_value
132 
133 kmutex_t spdsock_param_lock;	/* Protects the NDD variables. */
134 
135 /*
136  * To save algorithm update messages that are processed only after IPsec
137  * is loaded.
138  */
139 static spd_ext_t *spdsock_extv_algs[SPD_EXT_MAX + 1];
140 static mblk_t *spdsock_mp_algs = NULL;
141 static boolean_t spdsock_algs_pending = B_FALSE;
142 static ipsec_alginfo_t *spdsock_algs[IPSEC_NALGTYPES][IPSEC_MAX_ALGS];
143 static ipsec_algs_exec_mode_t spdsock_algs_exec_mode[IPSEC_NALGTYPES];
144 static kmutex_t spdsock_alg_lock;
145 
146 #define	ss0dbg(a)	printf a
147 /* NOTE:  != 0 instead of > 0 so lint doesn't complain. */
148 #define	ss1dbg(a)	if (spdsock_debug != 0) printf a
149 #define	ss2dbg(a)	if (spdsock_debug > 1) printf a
150 #define	ss3dbg(a)	if (spdsock_debug > 2) printf a
151 
152 static IDP spdsock_g_nd;
153 
154 static int spdsock_close(queue_t *);
155 static int spdsock_open(queue_t *, dev_t *, int, int, cred_t *);
156 static void spdsock_wput(queue_t *, mblk_t *);
157 static void spdsock_wsrv(queue_t *);
158 static void spdsock_rsrv(queue_t *);
159 static void spdsock_loadcheck(void *);
160 static void spdsock_merge_algs(void);
161 
162 static struct module_info info = {
163 	5138, "spdsock", 1, INFPSZ, 512, 128
164 };
165 
166 static struct qinit rinit = {
167 	NULL, (pfi_t)spdsock_rsrv, spdsock_open, spdsock_close,
168 	NULL, &info
169 };
170 
171 static struct qinit winit = {
172 	(pfi_t)spdsock_wput, (pfi_t)spdsock_wsrv, NULL, NULL, NULL, &info
173 };
174 
175 struct streamtab spdsockinfo = {
176 	&rinit, &winit
177 };
178 
179 /* mapping from alg type to protocol number, as per RFC 2407 */
180 static const uint_t algproto[] = {
181 	PROTO_IPSEC_AH,
182 	PROTO_IPSEC_ESP,
183 };
184 
185 #define	NALGPROTOS	(sizeof (algproto) / sizeof (algproto[0]))
186 
187 /* mapping from kernel exec mode to spdsock exec mode */
188 static const uint_t execmodes[] = {
189 	SPD_ALG_EXEC_MODE_SYNC,
190 	SPD_ALG_EXEC_MODE_ASYNC
191 };
192 
193 #define	NEXECMODES	(sizeof (execmodes) / sizeof (execmodes[0]))
194 
195 /* ARGSUSED */
196 static int
197 spdsock_param_get(q, mp, cp, cr)
198 	queue_t	*q;
199 	mblk_t	*mp;
200 	caddr_t	cp;
201 	cred_t *cr;
202 {
203 	spdsockparam_t	*spdsockpa = (spdsockparam_t *)cp;
204 	uint_t value;
205 
206 	mutex_enter(&spdsock_param_lock);
207 	value = spdsockpa->spdsock_param_value;
208 	mutex_exit(&spdsock_param_lock);
209 
210 	(void) mi_mpprintf(mp, "%u", value);
211 	return (0);
212 }
213 
214 /* This routine sets an NDD variable in a spdsockparam_t structure. */
215 /* ARGSUSED */
216 static int
217 spdsock_param_set(q, mp, value, cp, cr)
218 	queue_t	*q;
219 	mblk_t	*mp;
220 	char *value;
221 	caddr_t	cp;
222 	cred_t *cr;
223 {
224 	ulong_t	new_value;
225 	spdsockparam_t	*spdsockpa = (spdsockparam_t *)cp;
226 
227 	/* Convert the value from a string into a long integer. */
228 	if (ddi_strtoul(value, NULL, 10, &new_value) != 0)
229 		return (EINVAL);
230 
231 	mutex_enter(&spdsock_param_lock);
232 	/*
233 	 * Fail the request if the new value does not lie within the
234 	 * required bounds.
235 	 */
236 	if (new_value < spdsockpa->spdsock_param_min ||
237 	    new_value > spdsockpa->spdsock_param_max) {
238 		mutex_exit(&spdsock_param_lock);
239 		return (EINVAL);
240 	}
241 
242 	/* Set the new value */
243 	spdsockpa->spdsock_param_value = new_value;
244 	mutex_exit(&spdsock_param_lock);
245 
246 	return (0);
247 }
248 
249 boolean_t
250 spdsock_ddi_init(void)
251 {
252 	spdsockparam_t *ssp = spdsock_param_arr;
253 	int count = A_CNT(spdsock_param_arr);
254 
255 	if (!spdsock_g_nd) {
256 		for (; count-- > 0; ssp++) {
257 			if (ssp->spdsock_param_name != NULL &&
258 			    (ssp->spdsock_param_name[0] != '\0')) {
259 				if (!nd_load(&spdsock_g_nd,
260 				    ssp->spdsock_param_name,
261 				    spdsock_param_get, spdsock_param_set,
262 				    (caddr_t)ssp)) {
263 					nd_free(&spdsock_g_nd);
264 					return (B_FALSE);
265 				}
266 			}
267 		}
268 	}
269 
270 	spdsock_max_optsize = optcom_max_optsize(
271 	    spdsock_opt_obj.odb_opt_des_arr, spdsock_opt_obj.odb_opt_arr_cnt);
272 
273 	spdsock_vmem = vmem_create("spdsock", (void *)1, MAXMIN, 1,
274 	    NULL, NULL, NULL, 1, VM_SLEEP | VMC_IDENTIFIER);
275 
276 	mutex_init(&spdsock_param_lock, NULL, MUTEX_DEFAULT, NULL);
277 	mutex_init(&spdsock_alg_lock, NULL, MUTEX_DEFAULT, NULL);
278 
279 	return (B_TRUE);
280 }
281 
282 void
283 spdsock_ddi_destroy(void)
284 {
285 	vmem_destroy(spdsock_vmem);
286 	mutex_destroy(&spdsock_param_lock);
287 	mutex_destroy(&spdsock_alg_lock);
288 	nd_free(&spdsock_g_nd);
289 }
290 
291 /*
292  * NOTE: large quantities of this should be shared with keysock.
293  * Would be nice to combine some of this into a common module, but
294  * not possible given time pressures.
295  */
296 
297 /*
298  * High-level reality checking of extensions.
299  */
300 /* ARGSUSED */ /* XXX */
301 static boolean_t
302 ext_check(spd_ext_t *ext)
303 {
304 
305 	return (B_TRUE);	/* For now... */
306 }
307 
308 
309 
310 /* Return values for spdsock_get_ext(). */
311 #define	KGE_OK	0
312 #define	KGE_DUP	1
313 #define	KGE_UNK	2
314 #define	KGE_LEN	3
315 #define	KGE_CHK	4
316 
317 /*
318  * Parse basic extension headers and return in the passed-in pointer vector.
319  * Return values include:
320  *
321  *	KGE_OK	Everything's nice and parsed out.
322  *		If there are no extensions, place NULL in extv[0].
323  *	KGE_DUP	There is a duplicate extension.
324  *		First instance in appropriate bin.  First duplicate in
325  *		extv[0].
326  *	KGE_UNK	Unknown extension type encountered.  extv[0] contains
327  *		unknown header.
328  *	KGE_LEN	Extension length error.
329  *	KGE_CHK	High-level reality check failed on specific extension.
330  *
331  * My apologies for some of the pointer arithmetic in here.  I'm thinking
332  * like an assembly programmer, yet trying to make the compiler happy.
333  */
334 static int
335 spdsock_get_ext(spd_ext_t *extv[], spd_msg_t *basehdr, uint_t msgsize)
336 {
337 	bzero(extv, sizeof (spd_ext_t *) * (SPD_EXT_MAX + 1));
338 
339 	/* Use extv[0] as the "current working pointer". */
340 
341 	extv[0] = (spd_ext_t *)(basehdr + 1);
342 
343 	while (extv[0] < (spd_ext_t *)(((uint8_t *)basehdr) + msgsize)) {
344 		/* Check for unknown headers. */
345 		if (extv[0]->spd_ext_type == 0 ||
346 		    extv[0]->spd_ext_type > SPD_EXT_MAX)
347 			return (KGE_UNK);
348 
349 		/*
350 		 * Check length.  Use uint64_t because extlen is in units
351 		 * of 64-bit words.  If length goes beyond the msgsize,
352 		 * return an error.  (Zero length also qualifies here.)
353 		 */
354 		if (extv[0]->spd_ext_len == 0 ||
355 		    (void *)((uint64_t *)extv[0] + extv[0]->spd_ext_len) >
356 		    (void *)((uint8_t *)basehdr + msgsize))
357 			return (KGE_LEN);
358 
359 		/* Check for redundant headers. */
360 		if (extv[extv[0]->spd_ext_type] != NULL)
361 			return (KGE_DUP);
362 
363 		/*
364 		 * Reality check the extension if possible at the spdsock
365 		 * level.
366 		 */
367 		if (!ext_check(extv[0]))
368 			return (KGE_CHK);
369 
370 		/* If I make it here, assign the appropriate bin. */
371 		extv[extv[0]->spd_ext_type] = extv[0];
372 
373 		/* Advance pointer (See above for uint64_t ptr reasoning.) */
374 		extv[0] = (spd_ext_t *)
375 		    ((uint64_t *)extv[0] + extv[0]->spd_ext_len);
376 	}
377 
378 	/* Everything's cool. */
379 
380 	/*
381 	 * If extv[0] == NULL, then there are no extension headers in this
382 	 * message.  Ensure that this is the case.
383 	 */
384 	if (extv[0] == (spd_ext_t *)(basehdr + 1))
385 		extv[0] = NULL;
386 
387 	return (KGE_OK);
388 }
389 
390 static const int bad_ext_diag[] = {
391 	SPD_DIAGNOSTIC_MALFORMED_LCLPORT,
392 	SPD_DIAGNOSTIC_MALFORMED_REMPORT,
393 	SPD_DIAGNOSTIC_MALFORMED_PROTO,
394 	SPD_DIAGNOSTIC_MALFORMED_LCLADDR,
395 	SPD_DIAGNOSTIC_MALFORMED_REMADDR,
396 	SPD_DIAGNOSTIC_MALFORMED_ACTION,
397 	SPD_DIAGNOSTIC_MALFORMED_RULE,
398 	SPD_DIAGNOSTIC_MALFORMED_RULESET,
399 	SPD_DIAGNOSTIC_MALFORMED_ICMP_TYPECODE
400 };
401 
402 static const int dup_ext_diag[] = {
403 	SPD_DIAGNOSTIC_DUPLICATE_LCLPORT,
404 	SPD_DIAGNOSTIC_DUPLICATE_REMPORT,
405 	SPD_DIAGNOSTIC_DUPLICATE_PROTO,
406 	SPD_DIAGNOSTIC_DUPLICATE_LCLADDR,
407 	SPD_DIAGNOSTIC_DUPLICATE_REMADDR,
408 	SPD_DIAGNOSTIC_DUPLICATE_ACTION,
409 	SPD_DIAGNOSTIC_DUPLICATE_RULE,
410 	SPD_DIAGNOSTIC_DUPLICATE_RULESET,
411 	SPD_DIAGNOSTIC_DUPLICATE_ICMP_TYPECODE
412 };
413 
414 /*
415  * Transmit a PF_POLICY error message to the instance either pointed to
416  * by ks, the instance with serial number serial, or more, depending.
417  *
418  * The faulty message (or a reasonable facsimile thereof) is in mp.
419  * This function will free mp or recycle it for delivery, thereby causing
420  * the stream head to free it.
421  */
422 static void
423 spdsock_error(queue_t *q, mblk_t *mp, int error, int diagnostic)
424 {
425 	spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
426 
427 	ASSERT(mp->b_datap->db_type == M_DATA);
428 
429 	if (spmsg->spd_msg_type < SPD_MIN ||
430 	    spmsg->spd_msg_type > SPD_MAX)
431 		spmsg->spd_msg_type = SPD_RESERVED;
432 
433 	/*
434 	 * Strip out extension headers.
435 	 */
436 	ASSERT(mp->b_rptr + sizeof (*spmsg) <= mp->b_datap->db_lim);
437 	mp->b_wptr = mp->b_rptr + sizeof (*spmsg);
438 	spmsg->spd_msg_len = SPD_8TO64(sizeof (spd_msg_t));
439 	spmsg->spd_msg_errno = (uint8_t)error;
440 	spmsg->spd_msg_diagnostic = (uint16_t)diagnostic;
441 
442 	qreply(q, mp);
443 }
444 
445 static void
446 spdsock_diag(queue_t *q, mblk_t *mp, int diagnostic)
447 {
448 	spdsock_error(q, mp, EINVAL, diagnostic);
449 }
450 
451 static void
452 spd_echo(queue_t *q, mblk_t *mp)
453 {
454 	qreply(q, mp);
455 }
456 
457 /* ARGSUSED */
458 static void
459 spdsock_flush(queue_t *q, ipsec_policy_head_t *iph,
460     mblk_t *mp, spd_ext_t **extv)
461 {
462 	rw_enter(&iph->iph_lock, RW_WRITER);
463 	ipsec_polhead_flush(iph);
464 	rw_exit(&iph->iph_lock);
465 
466 	spd_echo(q, mp);
467 }
468 
469 static boolean_t
470 spdsock_ext_to_sel(spd_ext_t **extv, ipsec_selkey_t *sel, int *diag)
471 {
472 	bzero(sel, sizeof (*sel));
473 
474 	if (extv[SPD_EXT_PROTO] != NULL) {
475 		struct spd_proto *pr =
476 		    (struct spd_proto *)extv[SPD_EXT_PROTO];
477 		sel->ipsl_proto = pr->spd_proto_number;
478 		sel->ipsl_valid |= IPSL_PROTOCOL;
479 	}
480 	if (extv[SPD_EXT_LCLPORT] != NULL) {
481 		struct spd_portrange *pr =
482 		    (struct spd_portrange *)extv[SPD_EXT_LCLPORT];
483 		sel->ipsl_lport = pr->spd_ports_minport;
484 		sel->ipsl_valid |= IPSL_LOCAL_PORT;
485 	}
486 	if (extv[SPD_EXT_REMPORT] != NULL) {
487 		struct spd_portrange *pr =
488 		    (struct spd_portrange *)extv[SPD_EXT_REMPORT];
489 		sel->ipsl_rport = pr->spd_ports_minport;
490 		sel->ipsl_valid |= IPSL_REMOTE_PORT;
491 	}
492 
493 	if (extv[SPD_EXT_ICMP_TYPECODE] != NULL) {
494 		struct spd_typecode *tc=
495 		    (struct spd_typecode *)extv[SPD_EXT_ICMP_TYPECODE];
496 
497 		sel->ipsl_valid |= IPSL_ICMP_TYPE;
498 		sel->ipsl_icmp_type = tc->spd_typecode_type;
499 		if (tc->spd_typecode_type_end < tc->spd_typecode_type)
500 			sel->ipsl_icmp_type_end = tc->spd_typecode_type;
501 		else
502 			sel->ipsl_icmp_type_end = tc->spd_typecode_type_end;
503 
504 		if (tc->spd_typecode_code != 255) {
505 			sel->ipsl_valid |= IPSL_ICMP_CODE;
506 			sel->ipsl_icmp_code = tc->spd_typecode_code;
507 			if (tc->spd_typecode_code_end < tc->spd_typecode_code)
508 				sel->ipsl_icmp_code_end = tc->spd_typecode_code;
509 			else
510 				sel->ipsl_icmp_code_end =
511 				    tc->spd_typecode_code_end;
512 		}
513 	}
514 #define	ADDR2SEL(sel, extv, field, pfield, extn, bit)			      \
515 	if ((extv)[(extn)] != NULL) {					      \
516 		uint_t addrlen;						      \
517 		struct spd_address *ap = 				      \
518 			(struct spd_address *)((extv)[(extn)]); 	      \
519 		addrlen = (ap->spd_address_af == AF_INET6) ? 		      \
520 			IPV6_ADDR_LEN : IP_ADDR_LEN;			      \
521 		if (SPD_64TO8(ap->spd_address_len) < 			      \
522 			(addrlen + sizeof (*ap))) {			      \
523 			*diag = SPD_DIAGNOSTIC_BAD_ADDR_LEN;		      \
524 			return (B_FALSE);				      \
525 		}							      \
526 		bcopy((ap+1), &((sel)->field), addrlen);		      \
527 		(sel)->pfield = ap->spd_address_prefixlen;		      \
528 		(sel)->ipsl_valid |= (bit);				      \
529 		(sel)->ipsl_valid |= (ap->spd_address_af == AF_INET6) ?	      \
530 			IPSL_IPV6 : IPSL_IPV4;				      \
531 	}
532 
533 	ADDR2SEL(sel, extv, ipsl_local, ipsl_local_pfxlen,
534 	    SPD_EXT_LCLADDR, IPSL_LOCAL_ADDR);
535 	ADDR2SEL(sel, extv, ipsl_remote, ipsl_remote_pfxlen,
536 	    SPD_EXT_REMADDR, IPSL_REMOTE_ADDR);
537 
538 	if ((sel->ipsl_valid & (IPSL_IPV6|IPSL_IPV4)) ==
539 	    (IPSL_IPV6|IPSL_IPV4)) {
540 		*diag = SPD_DIAGNOSTIC_MIXED_AF;
541 		return (B_FALSE);
542 	}
543 
544 #undef ADDR2SEL
545 
546 	return (B_TRUE);
547 }
548 
549 static boolean_t
550 spd_convert_type(uint32_t type, ipsec_act_t *act)
551 {
552 	switch (type) {
553 	case SPD_ACTTYPE_DROP:
554 		act->ipa_type = IPSEC_ACT_DISCARD;
555 		return (B_TRUE);
556 
557 	case SPD_ACTTYPE_PASS:
558 		act->ipa_type = IPSEC_ACT_CLEAR;
559 		return (B_TRUE);
560 
561 	case SPD_ACTTYPE_IPSEC:
562 		act->ipa_type = IPSEC_ACT_APPLY;
563 		return (B_TRUE);
564 	}
565 	return (B_FALSE);
566 }
567 
568 static boolean_t
569 spd_convert_flags(uint32_t flags, ipsec_act_t *act)
570 {
571 	/*
572 	 * Note use of !! for boolean canonicalization.
573 	 */
574 	act->ipa_apply.ipp_use_ah = !!(flags & SPD_APPLY_AH);
575 	act->ipa_apply.ipp_use_esp = !!(flags & SPD_APPLY_ESP);
576 	act->ipa_apply.ipp_use_espa = !!(flags & SPD_APPLY_ESPA);
577 	act->ipa_apply.ipp_use_se = !!(flags & SPD_APPLY_SE);
578 	act->ipa_apply.ipp_use_unique = !!(flags & SPD_APPLY_UNIQUE);
579 	return (B_TRUE);
580 }
581 
582 static void
583 spdsock_reset_act(ipsec_act_t *act)
584 {
585 	bzero(act, sizeof (*act));
586 	act->ipa_apply.ipp_espe_maxbits = IPSEC_MAX_KEYBITS;
587 	act->ipa_apply.ipp_espa_maxbits = IPSEC_MAX_KEYBITS;
588 	act->ipa_apply.ipp_ah_maxbits = IPSEC_MAX_KEYBITS;
589 }
590 
591 /*
592  * Sanity check action against reality, and shrink-wrap key sizes..
593  */
594 static boolean_t
595 spdsock_check_action(ipsec_act_t *act, int *diag)
596 {
597 	if ((act->ipa_type != IPSEC_ACT_APPLY) &&
598 	    (act->ipa_apply.ipp_use_ah ||
599 		act->ipa_apply.ipp_use_esp ||
600 		act->ipa_apply.ipp_use_espa ||
601 		act->ipa_apply.ipp_use_se ||
602 		act->ipa_apply.ipp_use_unique)) {
603 		*diag = SPD_DIAGNOSTIC_ADD_INCON_FLAGS;
604 		return (B_FALSE);
605 	}
606 	if ((act->ipa_type == IPSEC_ACT_APPLY) &&
607 	    !act->ipa_apply.ipp_use_ah &&
608 	    !act->ipa_apply.ipp_use_esp) {
609 		*diag = SPD_DIAGNOSTIC_ADD_INCON_FLAGS;
610 		return (B_FALSE);
611 	}
612 	return (ipsec_check_action(act, diag));
613 }
614 
615 /*
616  * We may be short a few error checks here..
617  */
618 static boolean_t
619 spdsock_ext_to_actvec(spd_ext_t **extv, ipsec_act_t **actpp, uint_t *nactp,
620     int *diag)
621 {
622 	struct spd_ext_actions *sactp =
623 	    (struct spd_ext_actions *)extv[SPD_EXT_ACTION];
624 	ipsec_act_t act, *actp, *endactp;
625 	struct spd_attribute *attrp, *endattrp;
626 	uint64_t *endp;
627 	int nact;
628 
629 	*actpp = NULL;
630 	*nactp = 0;
631 
632 	if (sactp == NULL) {
633 		*diag = SPD_DIAGNOSTIC_NO_ACTION_EXT;
634 		return (B_FALSE);
635 	}
636 
637 	/*
638 	 * Parse the "action" extension and convert into an action chain.
639 	 */
640 
641 	nact = sactp->spd_actions_count;
642 
643 	endp = (uint64_t *)sactp;
644 	endp += sactp->spd_actions_len;
645 	endattrp = (struct spd_attribute *)endp;
646 
647 	actp = kmem_alloc(sizeof (*actp) * nact, KM_NOSLEEP);
648 	if (actp == NULL) {
649 		*diag = SPD_DIAGNOSTIC_ADD_NO_MEM;
650 		return (B_FALSE);
651 	}
652 	*actpp = actp;
653 	*nactp = nact;
654 	endactp = actp + nact;
655 
656 	spdsock_reset_act(&act);
657 	attrp = (struct spd_attribute *)(&sactp[1]);
658 
659 	for (; attrp < endattrp; attrp++) {
660 		switch (attrp->spd_attr_tag) {
661 		case SPD_ATTR_NOP:
662 			break;
663 
664 		case SPD_ATTR_EMPTY:
665 			spdsock_reset_act(&act);
666 			break;
667 
668 		case SPD_ATTR_END:
669 			attrp = endattrp;
670 			/* FALLTHRU */
671 		case SPD_ATTR_NEXT:
672 			if (actp >= endactp) {
673 				*diag = SPD_DIAGNOSTIC_ADD_WRONG_ACT_COUNT;
674 				goto fail;
675 			}
676 			if (!spdsock_check_action(&act, diag))
677 				goto fail;
678 			*actp++ = act;
679 			break;
680 
681 		case SPD_ATTR_TYPE:
682 			if (!spd_convert_type(attrp->spd_attr_value, &act)) {
683 				*diag = SPD_DIAGNOSTIC_ADD_BAD_TYPE;
684 				goto fail;
685 			}
686 			break;
687 
688 		case SPD_ATTR_FLAGS:
689 			if (!spd_convert_flags(attrp->spd_attr_value, &act)) {
690 				*diag = SPD_DIAGNOSTIC_ADD_BAD_FLAGS;
691 				goto fail;
692 			}
693 			break;
694 
695 		case SPD_ATTR_AH_AUTH:
696 			act.ipa_apply.ipp_auth_alg = attrp->spd_attr_value;
697 			break;
698 
699 		case SPD_ATTR_ESP_ENCR:
700 			act.ipa_apply.ipp_encr_alg = attrp->spd_attr_value;
701 			break;
702 
703 		case SPD_ATTR_ESP_AUTH:
704 			act.ipa_apply.ipp_esp_auth_alg = attrp->spd_attr_value;
705 			break;
706 
707 		case SPD_ATTR_ENCR_MINBITS:
708 			act.ipa_apply.ipp_espe_minbits = attrp->spd_attr_value;
709 			break;
710 
711 		case SPD_ATTR_ENCR_MAXBITS:
712 			act.ipa_apply.ipp_espe_maxbits = attrp->spd_attr_value;
713 			break;
714 
715 		case SPD_ATTR_AH_MINBITS:
716 			act.ipa_apply.ipp_ah_minbits = attrp->spd_attr_value;
717 			break;
718 
719 		case SPD_ATTR_AH_MAXBITS:
720 			act.ipa_apply.ipp_ah_maxbits = attrp->spd_attr_value;
721 			break;
722 
723 		case SPD_ATTR_ESPA_MINBITS:
724 			act.ipa_apply.ipp_espa_minbits = attrp->spd_attr_value;
725 			break;
726 
727 		case SPD_ATTR_ESPA_MAXBITS:
728 			act.ipa_apply.ipp_espa_maxbits = attrp->spd_attr_value;
729 			break;
730 
731 		case SPD_ATTR_LIFE_SOFT_TIME:
732 		case SPD_ATTR_LIFE_HARD_TIME:
733 		case SPD_ATTR_LIFE_SOFT_BYTES:
734 		case SPD_ATTR_LIFE_HARD_BYTES:
735 			break;
736 
737 		case SPD_ATTR_KM_PROTO:
738 			act.ipa_apply.ipp_km_proto = attrp->spd_attr_value;
739 			break;
740 
741 		case SPD_ATTR_KM_COOKIE:
742 			act.ipa_apply.ipp_km_cookie = attrp->spd_attr_value;
743 			break;
744 
745 		case SPD_ATTR_REPLAY_DEPTH:
746 			act.ipa_apply.ipp_replay_depth = attrp->spd_attr_value;
747 			break;
748 		}
749 	}
750 	if (actp != endactp) {
751 		*diag = SPD_DIAGNOSTIC_ADD_WRONG_ACT_COUNT;
752 		goto fail;
753 	}
754 
755 	return (B_TRUE);
756 fail:
757 	ipsec_actvec_free(*actpp, nact);
758 	*actpp = NULL;
759 	return (B_FALSE);
760 }
761 
762 typedef struct
763 {
764 	ipsec_policy_t *pol;
765 	int dir;
766 } tmprule_t;
767 
768 static int
769 mkrule(ipsec_policy_head_t *iph, struct spd_rule *rule,
770     ipsec_selkey_t *sel, ipsec_act_t *actp, int nact, uint_t dir, uint_t af,
771     tmprule_t **rp)
772 {
773 	ipsec_policy_t *pol;
774 
775 	sel->ipsl_valid &= ~(IPSL_IPV6|IPSL_IPV4);
776 	sel->ipsl_valid |= af;
777 
778 	pol = ipsec_policy_create(sel, actp, nact, rule->spd_rule_priority);
779 	if (pol == NULL)
780 		return (ENOMEM);
781 
782 	(*rp)->pol = pol;
783 	(*rp)->dir = dir;
784 	(*rp)++;
785 
786 	if (!ipsec_check_policy(iph, pol, dir))
787 		return (EEXIST);
788 
789 	rule->spd_rule_index = pol->ipsp_index;
790 	return (0);
791 }
792 
793 static int
794 mkrulepair(ipsec_policy_head_t *iph, struct spd_rule *rule,
795     ipsec_selkey_t *sel, ipsec_act_t *actp, int nact, uint_t dir, uint_t afs,
796     tmprule_t **rp)
797 {
798 	int error;
799 
800 	if (afs & IPSL_IPV4) {
801 		error = mkrule(iph, rule, sel, actp, nact, dir, IPSL_IPV4, rp);
802 		if (error != 0)
803 			return (error);
804 	}
805 	if (afs & IPSL_IPV6) {
806 		error = mkrule(iph, rule, sel, actp, nact, dir, IPSL_IPV6, rp);
807 		if (error != 0)
808 			return (error);
809 	}
810 	return (0);
811 }
812 
813 
814 static void
815 spdsock_addrule(queue_t *q, ipsec_policy_head_t *iph,
816     mblk_t *mp, spd_ext_t **extv)
817 {
818 	ipsec_selkey_t sel;
819 	ipsec_act_t *actp;
820 	uint_t nact;
821 	int diag, error, afs;
822 	struct spd_rule *rule = (struct spd_rule *)extv[SPD_EXT_RULE];
823 	tmprule_t rules[4], *rulep = &rules[0];
824 
825 	if (rule == NULL) {
826 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_NO_RULE_EXT);
827 		return;
828 	}
829 
830 	if (rule->spd_rule_index != 0) {
831 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_INVALID_RULE_INDEX);
832 		return;
833 	}
834 
835 	if (!spdsock_ext_to_sel(extv, &sel, &diag)) {
836 		spdsock_diag(q, mp, diag);
837 		return;
838 	}
839 
840 	if (!spdsock_ext_to_actvec(extv, &actp, &nact, &diag)) {
841 		spdsock_diag(q, mp, diag);
842 		return;
843 	}
844 	/*
845 	 * If no addresses were specified, add both.
846 	 */
847 	afs = sel.ipsl_valid & (IPSL_IPV6|IPSL_IPV4);
848 	if (afs == 0)
849 		afs = (IPSL_IPV6|IPSL_IPV4);
850 
851 	rw_enter(&iph->iph_lock, RW_WRITER);
852 
853 	if (rule->spd_rule_flags & SPD_RULE_FLAG_OUTBOUND) {
854 		error = mkrulepair(iph, rule, &sel, actp, nact,
855 		    IPSEC_TYPE_OUTBOUND, afs, &rulep);
856 		if (error != 0)
857 			goto fail;
858 	}
859 
860 	if (rule->spd_rule_flags & SPD_RULE_FLAG_INBOUND) {
861 		error = mkrulepair(iph, rule, &sel, actp, nact,
862 		    IPSEC_TYPE_INBOUND, afs, &rulep);
863 		if (error != 0)
864 			goto fail;
865 	}
866 
867 	while ((--rulep) >= &rules[0])
868 		ipsec_enter_policy(iph, rulep->pol, rulep->dir);
869 
870 	rw_exit(&iph->iph_lock);
871 
872 	ipsec_actvec_free(actp, nact);
873 	spd_echo(q, mp);
874 	return;
875 
876 fail:
877 	rw_exit(&iph->iph_lock);
878 	while ((--rulep) >= &rules[0]) {
879 		IPPOL_REFRELE(rulep->pol);
880 	}
881 	ipsec_actvec_free(actp, nact);
882 	spdsock_error(q, mp, error, 0);
883 }
884 
885 void
886 spdsock_deleterule(queue_t *q, ipsec_policy_head_t *iph,
887     mblk_t *mp, spd_ext_t **extv)
888 {
889 	ipsec_selkey_t sel;
890 	struct spd_rule *rule = (struct spd_rule *)extv[SPD_EXT_RULE];
891 	int diag;
892 
893 	if (rule == NULL) {
894 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_NO_RULE_EXT);
895 		return;
896 	}
897 
898 	if (rule->spd_rule_index != 0) {
899 		if (ipsec_policy_delete_index(iph, rule->spd_rule_index) != 0) {
900 			spdsock_error(q, mp, ESRCH, 0);
901 			return;
902 		}
903 	} else {
904 		if (!spdsock_ext_to_sel(extv, &sel, &diag)) {
905 			spdsock_diag(q, mp, diag);
906 			return;
907 		}
908 
909 		if (rule->spd_rule_flags & SPD_RULE_FLAG_INBOUND) {
910 			if (!ipsec_policy_delete(iph, &sel,
911 			    IPSEC_TYPE_INBOUND))
912 				goto fail;
913 		}
914 
915 		if (rule->spd_rule_flags & SPD_RULE_FLAG_OUTBOUND) {
916 			if (!ipsec_policy_delete(iph, &sel,
917 			    IPSEC_TYPE_OUTBOUND))
918 				goto fail;
919 		}
920 	}
921 	spd_echo(q, mp);
922 	return;
923 fail:
924 	spdsock_error(q, mp, ESRCH, 0);
925 }
926 
927 void
928 spdsock_flip(queue_t *q, mblk_t *mp)
929 {
930 	ipsec_swap_policy();	/* can't fail */
931 	spd_echo(q, mp);
932 }
933 
934 /*
935  * Unimplemented feature
936  */
937 /* ARGSUSED */
938 static void
939 spdsock_lookup(queue_t *q, ipsec_policy_head_t *iph,
940     mblk_t *mp, spd_ext_t **extv)
941 {
942 	spdsock_error(q, mp, EINVAL, 0);
943 }
944 
945 
946 static mblk_t *
947 spdsock_dump_ruleset(mblk_t *req, ipsec_policy_head_t *iph,
948     uint32_t count, uint16_t error)
949 {
950 	size_t len = sizeof (spd_ruleset_ext_t) + sizeof (spd_msg_t);
951 	spd_msg_t *msg;
952 	spd_ruleset_ext_t *ruleset;
953 	mblk_t *m = allocb(len, BPRI_HI);
954 
955 	ASSERT(RW_READ_HELD(&iph->iph_lock));
956 
957 	if (m == NULL) {
958 		return (NULL);
959 	}
960 	msg = (spd_msg_t *)m->b_rptr;
961 	ruleset = (spd_ruleset_ext_t *)(&msg[1]);
962 
963 	m->b_wptr = (uint8_t *)&ruleset[1];
964 
965 	*msg = *(spd_msg_t *)(req->b_rptr);
966 	msg->spd_msg_len = SPD_8TO64(len);
967 	msg->spd_msg_errno = error;
968 
969 	ruleset->spd_ruleset_len = SPD_8TO64(sizeof (*ruleset));
970 	ruleset->spd_ruleset_type = SPD_EXT_RULESET;
971 	ruleset->spd_ruleset_count = count;
972 	ruleset->spd_ruleset_version = iph->iph_gen;
973 	return (m);
974 }
975 
976 static mblk_t *
977 spdsock_dump_finish(spdsock_t *ss, int error)
978 {
979 	mblk_t *m;
980 	ipsec_policy_head_t *iph = ss->spdsock_dump_head;
981 	mblk_t *req = ss->spdsock_dump_req;
982 
983 	rw_enter(&iph->iph_lock, RW_READER);
984 	m = spdsock_dump_ruleset(req, iph, ss->spdsock_dump_count, error);
985 	rw_exit(&iph->iph_lock);
986 
987 	ss->spdsock_dump_req = NULL;
988 	freemsg(req);
989 
990 	return (m);
991 }
992 
993 /*
994  * Rule encoding functions.
995  * We do a two-pass encode.
996  * If base != NULL, fill in encoded rule part starting at base+offset.
997  * Always return "offset" plus length of to-be-encoded data.
998  */
999 static uint_t
1000 spdsock_encode_typecode(uint8_t *base, uint_t offset, uint8_t type,
1001     uint8_t type_end, uint8_t code, uint8_t code_end)
1002 {
1003 	struct spd_typecode *tcp;
1004 
1005 	ASSERT(ALIGNED64(offset));
1006 
1007 	if (base != NULL) {
1008 		tcp = (struct spd_typecode *)(base + offset);
1009 		tcp->spd_typecode_len = SPD_8TO64(sizeof (*tcp));
1010 		tcp->spd_typecode_exttype = SPD_EXT_ICMP_TYPECODE;
1011 		tcp->spd_typecode_code = code;
1012 		tcp->spd_typecode_type = type;
1013 		tcp->spd_typecode_type_end = type_end;
1014 		tcp->spd_typecode_code_end = code_end;
1015 	}
1016 	offset += sizeof (*tcp);
1017 
1018 	ASSERT(ALIGNED64(offset));
1019 
1020 	return (offset);
1021 }
1022 
1023 static uint_t
1024 spdsock_encode_proto(uint8_t *base, uint_t offset, uint8_t proto)
1025 {
1026 	struct spd_proto *spp;
1027 
1028 	ASSERT(ALIGNED64(offset));
1029 
1030 	if (base != NULL) {
1031 		spp = (struct spd_proto *)(base + offset);
1032 		spp->spd_proto_len = SPD_8TO64(sizeof (*spp));
1033 		spp->spd_proto_exttype = SPD_EXT_PROTO;
1034 		spp->spd_proto_number = proto;
1035 		spp->spd_proto_reserved1 = 0;
1036 		spp->spd_proto_reserved2 = 0;
1037 	}
1038 	offset += sizeof (*spp);
1039 
1040 	ASSERT(ALIGNED64(offset));
1041 
1042 	return (offset);
1043 }
1044 
1045 static uint_t
1046 spdsock_encode_port(uint8_t *base, uint_t offset, uint16_t ext, uint16_t port)
1047 {
1048 	struct spd_portrange *spp;
1049 
1050 	ASSERT(ALIGNED64(offset));
1051 
1052 	if (base != NULL) {
1053 		spp = (struct spd_portrange *)(base + offset);
1054 		spp->spd_ports_len = SPD_8TO64(sizeof (*spp));
1055 		spp->spd_ports_exttype = ext;
1056 		spp->spd_ports_minport = port;
1057 		spp->spd_ports_maxport = port;
1058 	}
1059 	offset += sizeof (*spp);
1060 
1061 	ASSERT(ALIGNED64(offset));
1062 
1063 	return (offset);
1064 }
1065 
1066 static uint_t
1067 spdsock_encode_addr(uint8_t *base, uint_t offset, uint16_t ext,
1068     const ipsec_selkey_t *sel, const ipsec_addr_t *addr, uint_t pfxlen)
1069 {
1070 	struct spd_address *sae;
1071 	ipsec_addr_t *spdaddr;
1072 	uint_t start = offset;
1073 	uint_t addrlen;
1074 	uint_t af;
1075 
1076 	if (sel->ipsl_valid & IPSL_IPV4) {
1077 		af = AF_INET;
1078 		addrlen = IP_ADDR_LEN;
1079 	} else {
1080 		af = AF_INET6;
1081 		addrlen = IPV6_ADDR_LEN;
1082 	}
1083 
1084 	ASSERT(ALIGNED64(offset));
1085 
1086 	if (base != NULL) {
1087 		sae = (struct spd_address *)(base + offset);
1088 		sae->spd_address_exttype = ext;
1089 		sae->spd_address_af = af;
1090 		sae->spd_address_prefixlen = pfxlen;
1091 		sae->spd_address_reserved2 = 0;
1092 
1093 		spdaddr = (ipsec_addr_t *)(&sae[1]);
1094 		bcopy(addr, spdaddr, addrlen);
1095 	}
1096 	offset += sizeof (*sae);
1097 	addrlen = roundup(addrlen, sizeof (uint64_t));
1098 	offset += addrlen;
1099 
1100 	ASSERT(ALIGNED64(offset));
1101 
1102 	if (base != NULL)
1103 		sae->spd_address_len = SPD_8TO64(offset - start);
1104 	return (offset);
1105 }
1106 
1107 static uint_t
1108 spdsock_encode_sel(uint8_t *base, uint_t offset, const ipsec_sel_t *sel)
1109 {
1110 	const ipsec_selkey_t *selkey = &sel->ipsl_key;
1111 
1112 	if (selkey->ipsl_valid & IPSL_PROTOCOL)
1113 		offset = spdsock_encode_proto(base, offset, selkey->ipsl_proto);
1114 	if (selkey->ipsl_valid & IPSL_LOCAL_PORT)
1115 		offset = spdsock_encode_port(base, offset, SPD_EXT_LCLPORT,
1116 		    selkey->ipsl_lport);
1117 	if (selkey->ipsl_valid & IPSL_REMOTE_PORT)
1118 		offset = spdsock_encode_port(base, offset, SPD_EXT_REMPORT,
1119 		    selkey->ipsl_rport);
1120 	if (selkey->ipsl_valid & IPSL_REMOTE_ADDR)
1121 		offset = spdsock_encode_addr(base, offset, SPD_EXT_REMADDR,
1122 		    selkey, &selkey->ipsl_remote, selkey->ipsl_remote_pfxlen);
1123 	if (selkey->ipsl_valid & IPSL_LOCAL_ADDR)
1124 		offset = spdsock_encode_addr(base, offset, SPD_EXT_LCLADDR,
1125 		    selkey, &selkey->ipsl_local, selkey->ipsl_local_pfxlen);
1126 	if (selkey->ipsl_valid & IPSL_ICMP_TYPE) {
1127 		offset = spdsock_encode_typecode(base, offset,
1128 		    selkey->ipsl_icmp_type, selkey->ipsl_icmp_type_end,
1129 		    (selkey->ipsl_valid & IPSL_ICMP_CODE) ?
1130 			selkey->ipsl_icmp_code : 255,
1131 		    (selkey->ipsl_valid & IPSL_ICMP_CODE) ?
1132 			selkey->ipsl_icmp_code_end : 255);
1133 	}
1134 	return (offset);
1135 }
1136 
1137 static uint_t
1138 spdsock_encode_actattr(uint8_t *base, uint_t offset, uint32_t tag,
1139     uint32_t value)
1140 {
1141 	struct spd_attribute *attr;
1142 
1143 	ASSERT(ALIGNED64(offset));
1144 
1145 	if (base != NULL) {
1146 		attr = (struct spd_attribute *)(base + offset);
1147 		attr->spd_attr_tag = tag;
1148 		attr->spd_attr_value = value;
1149 	}
1150 	offset += sizeof (struct spd_attribute);
1151 
1152 	ASSERT(ALIGNED64(offset));
1153 
1154 	return (offset);
1155 }
1156 
1157 
1158 #define	EMIT(t, v) offset = spdsock_encode_actattr(base, offset, (t), (v))
1159 
1160 static uint_t
1161 spdsock_encode_action(uint8_t *base, uint_t offset, const ipsec_action_t *ap)
1162 {
1163 	const struct ipsec_act *act = &(ap->ipa_act);
1164 	uint_t flags;
1165 
1166 	EMIT(SPD_ATTR_EMPTY, 0);
1167 	switch (act->ipa_type) {
1168 	case IPSEC_ACT_DISCARD:
1169 	case IPSEC_ACT_REJECT:
1170 		EMIT(SPD_ATTR_TYPE, SPD_ACTTYPE_DROP);
1171 		break;
1172 	case IPSEC_ACT_BYPASS:
1173 	case IPSEC_ACT_CLEAR:
1174 		EMIT(SPD_ATTR_TYPE, SPD_ACTTYPE_PASS);
1175 		break;
1176 
1177 	case IPSEC_ACT_APPLY:
1178 		EMIT(SPD_ATTR_TYPE, SPD_ACTTYPE_IPSEC);
1179 		flags = 0;
1180 		if (act->ipa_apply.ipp_use_ah)
1181 			flags |= SPD_APPLY_AH;
1182 		if (act->ipa_apply.ipp_use_esp)
1183 			flags |= SPD_APPLY_ESP;
1184 		if (act->ipa_apply.ipp_use_espa)
1185 			flags |= SPD_APPLY_ESPA;
1186 		if (act->ipa_apply.ipp_use_se)
1187 			flags |= SPD_APPLY_SE;
1188 		if (act->ipa_apply.ipp_use_unique)
1189 			flags |= SPD_APPLY_UNIQUE;
1190 		EMIT(SPD_ATTR_FLAGS, flags);
1191 		if (flags & SPD_APPLY_AH) {
1192 			EMIT(SPD_ATTR_AH_AUTH, act->ipa_apply.ipp_auth_alg);
1193 			EMIT(SPD_ATTR_AH_MINBITS,
1194 			    act->ipa_apply.ipp_ah_minbits);
1195 			EMIT(SPD_ATTR_AH_MAXBITS,
1196 			    act->ipa_apply.ipp_ah_maxbits);
1197 		}
1198 		if (flags & SPD_APPLY_ESP) {
1199 			EMIT(SPD_ATTR_ESP_ENCR, act->ipa_apply.ipp_encr_alg);
1200 			EMIT(SPD_ATTR_ENCR_MINBITS,
1201 			    act->ipa_apply.ipp_espe_minbits);
1202 			EMIT(SPD_ATTR_ENCR_MAXBITS,
1203 			    act->ipa_apply.ipp_espe_maxbits);
1204 			if (flags & SPD_APPLY_ESPA) {
1205 				EMIT(SPD_ATTR_ESP_AUTH,
1206 				    act->ipa_apply.ipp_esp_auth_alg);
1207 				EMIT(SPD_ATTR_ESPA_MINBITS,
1208 				    act->ipa_apply.ipp_espa_minbits);
1209 				EMIT(SPD_ATTR_ESPA_MAXBITS,
1210 				    act->ipa_apply.ipp_espa_maxbits);
1211 			}
1212 		}
1213 		if (act->ipa_apply.ipp_km_proto != 0)
1214 			EMIT(SPD_ATTR_KM_PROTO, act->ipa_apply.ipp_km_proto);
1215 		if (act->ipa_apply.ipp_km_cookie != 0)
1216 			EMIT(SPD_ATTR_KM_PROTO, act->ipa_apply.ipp_km_cookie);
1217 		if (act->ipa_apply.ipp_replay_depth != 0)
1218 			EMIT(SPD_ATTR_REPLAY_DEPTH,
1219 			    act->ipa_apply.ipp_replay_depth);
1220 		/* Add more here */
1221 		break;
1222 	}
1223 
1224 	return (offset);
1225 }
1226 
1227 static uint_t
1228 spdsock_encode_action_list(uint8_t *base, uint_t offset,
1229     const ipsec_action_t *ap)
1230 {
1231 	struct spd_ext_actions *act;
1232 	uint_t nact = 0;
1233 	uint_t start = offset;
1234 
1235 	ASSERT(ALIGNED64(offset));
1236 
1237 	if (base != NULL) {
1238 		act = (struct spd_ext_actions *)(base + offset);
1239 		act->spd_actions_len = 0;
1240 		act->spd_actions_exttype = SPD_EXT_ACTION;
1241 		act->spd_actions_count = 0;
1242 		act->spd_actions_reserved = 0;
1243 	}
1244 
1245 	offset += sizeof (*act);
1246 
1247 	ASSERT(ALIGNED64(offset));
1248 
1249 	while (ap != NULL) {
1250 		offset = spdsock_encode_action(base, offset, ap);
1251 		ap = ap->ipa_next;
1252 		nact++;
1253 		if (ap != NULL) {
1254 			EMIT(SPD_ATTR_NEXT, 0);
1255 		}
1256 	}
1257 	EMIT(SPD_ATTR_END, 0);
1258 
1259 	ASSERT(ALIGNED64(offset));
1260 
1261 	if (base != NULL) {
1262 		act->spd_actions_count = nact;
1263 		act->spd_actions_len = SPD_8TO64(offset - start);
1264 	}
1265 
1266 	return (offset);
1267 }
1268 
1269 #undef EMIT
1270 
1271 /* ARGSUSED */
1272 static uint_t
1273 spdsock_rule_flags(uint_t dir, uint_t af)
1274 {
1275 	uint_t flags = 0;
1276 
1277 	if (dir == IPSEC_TYPE_INBOUND)
1278 		flags |= SPD_RULE_FLAG_INBOUND;
1279 	if (dir == IPSEC_TYPE_OUTBOUND)
1280 		flags |= SPD_RULE_FLAG_OUTBOUND;
1281 
1282 	return (flags);
1283 }
1284 
1285 
1286 static uint_t
1287 spdsock_encode_rule_head(uint8_t *base, uint_t offset,
1288     spd_msg_t *req, const ipsec_policy_t *rule, uint_t dir, uint_t af)
1289 {
1290 	struct spd_msg *spmsg;
1291 	struct spd_rule *spr;
1292 
1293 	uint_t start = offset;
1294 
1295 	ASSERT(ALIGNED64(offset));
1296 
1297 	if (base != NULL) {
1298 		spmsg = (struct spd_msg *)(base + offset);
1299 		bzero(spmsg, sizeof (*spmsg));
1300 		spmsg->spd_msg_version = PF_POLICY_V1;
1301 		spmsg->spd_msg_type = SPD_DUMP;
1302 		spmsg->spd_msg_seq = req->spd_msg_seq;
1303 		spmsg->spd_msg_pid = req->spd_msg_pid;
1304 	}
1305 	offset += sizeof (struct spd_msg);
1306 
1307 	ASSERT(ALIGNED64(offset));
1308 
1309 	if (base != NULL) {
1310 		spr = (struct spd_rule *)(base + offset);
1311 		spr->spd_rule_type = SPD_EXT_RULE;
1312 		spr->spd_rule_priority = rule->ipsp_prio;
1313 		spr->spd_rule_flags = spdsock_rule_flags(dir, af);
1314 		spr->spd_rule_unused = 0;
1315 		spr->spd_rule_len = SPD_8TO64(sizeof (*spr));
1316 		spr->spd_rule_index = rule->ipsp_index;
1317 	}
1318 	offset += sizeof (struct spd_rule);
1319 	offset = spdsock_encode_sel(base, offset, rule->ipsp_sel);
1320 	offset = spdsock_encode_action_list(base, offset, rule->ipsp_act);
1321 
1322 	ASSERT(ALIGNED64(offset));
1323 
1324 	if (base != NULL) {
1325 		spmsg->spd_msg_len = SPD_8TO64(offset - start);
1326 	}
1327 	return (offset);
1328 }
1329 
1330 /* ARGSUSED */
1331 static mblk_t *
1332 spdsock_encode_rule(mblk_t *req, const ipsec_policy_t *rule,
1333     uint_t dir, uint_t af)
1334 {
1335 	mblk_t *m;
1336 	uint_t len;
1337 	spd_msg_t *mreq = (spd_msg_t *)req->b_rptr;
1338 
1339 	/*
1340 	 * Figure out how much space we'll need.
1341 	 */
1342 	len = spdsock_encode_rule_head(NULL, 0, mreq, rule, dir, af);
1343 
1344 	/*
1345 	 * Allocate mblk.
1346 	 */
1347 	m = allocb(len, BPRI_HI);
1348 	if (m == NULL)
1349 		return (NULL);
1350 
1351 	/*
1352 	 * Fill it in..
1353 	 */
1354 	m->b_wptr = m->b_rptr + len;
1355 	bzero(m->b_rptr, len);
1356 	(void) spdsock_encode_rule_head(m->b_rptr, 0, mreq, rule, dir, af);
1357 	return (m);
1358 }
1359 
1360 static ipsec_policy_t *
1361 spdsock_dump_next_in_chain(spdsock_t *ss, ipsec_policy_head_t *iph,
1362     ipsec_policy_t *cur)
1363 {
1364 	ASSERT(RW_READ_HELD(&iph->iph_lock));
1365 
1366 	ss->spdsock_dump_count++;
1367 	ss->spdsock_dump_cur_rule = cur->ipsp_hash.hash_next;
1368 	return (cur);
1369 }
1370 
1371 static ipsec_policy_t *
1372 spdsock_dump_next_rule(spdsock_t *ss, ipsec_policy_head_t *iph)
1373 {
1374 	ipsec_policy_t *cur;
1375 	ipsec_policy_root_t *ipr;
1376 	int chain, nchains, type, af;
1377 
1378 	ASSERT(RW_READ_HELD(&iph->iph_lock));
1379 
1380 	cur = ss->spdsock_dump_cur_rule;
1381 
1382 	if (cur != NULL)
1383 		return (spdsock_dump_next_in_chain(ss, iph, cur));
1384 
1385 	type = ss->spdsock_dump_cur_type;
1386 
1387 next:
1388 	chain = ss->spdsock_dump_cur_chain;
1389 	ipr = &iph->iph_root[type];
1390 	nchains = ipr->ipr_nchains;
1391 
1392 	while (chain < nchains) {
1393 		cur = ipr->ipr_hash[chain].hash_head;
1394 		chain++;
1395 		if (cur != NULL) {
1396 			ss->spdsock_dump_cur_chain = chain;
1397 			return (spdsock_dump_next_in_chain(ss, iph, cur));
1398 		}
1399 	}
1400 	ss->spdsock_dump_cur_chain = nchains;
1401 
1402 	af = ss->spdsock_dump_cur_af;
1403 	while (af < IPSEC_NAF) {
1404 		cur = ipr->ipr_nonhash[af];
1405 		af++;
1406 		if (cur != NULL) {
1407 			ss->spdsock_dump_cur_af = af;
1408 			return (spdsock_dump_next_in_chain(ss, iph, cur));
1409 		}
1410 	}
1411 
1412 	type++;
1413 	if (type >= IPSEC_NTYPES)
1414 		return (NULL);
1415 
1416 	ss->spdsock_dump_cur_chain = 0;
1417 	ss->spdsock_dump_cur_type = type;
1418 	ss->spdsock_dump_cur_af = IPSEC_AF_V4;
1419 	goto next;
1420 
1421 }
1422 
1423 static mblk_t *
1424 spdsock_dump_next_record(spdsock_t *ss)
1425 {
1426 	ipsec_policy_head_t *iph;
1427 	ipsec_policy_t *rule;
1428 	mblk_t *m;
1429 	mblk_t *req = ss->spdsock_dump_req;
1430 
1431 	iph = ss->spdsock_dump_head;
1432 
1433 	ASSERT(iph != NULL);
1434 
1435 	rw_enter(&iph->iph_lock, RW_READER);
1436 
1437 	if (iph->iph_gen != ss->spdsock_dump_gen) {
1438 		rw_exit(&iph->iph_lock);
1439 		return (spdsock_dump_finish(ss, EAGAIN));
1440 	}
1441 
1442 	rule = spdsock_dump_next_rule(ss, iph);
1443 
1444 	if (!rule) {
1445 		rw_exit(&iph->iph_lock);
1446 		return (spdsock_dump_finish(ss, 0));
1447 	}
1448 
1449 	m = spdsock_encode_rule(req, rule, ss->spdsock_dump_cur_type,
1450 	    ss->spdsock_dump_cur_af);
1451 	rw_exit(&iph->iph_lock);
1452 
1453 	if (m == NULL)
1454 		return (spdsock_dump_finish(ss, ENOMEM));
1455 	return (m);
1456 }
1457 
1458 /*
1459  * Dump records until we run into flow-control back-pressure.
1460  */
1461 static void
1462 spdsock_dump_some(queue_t *q, spdsock_t *ss)
1463 {
1464 	mblk_t *m, *dataind;
1465 
1466 	while ((ss->spdsock_dump_req != NULL) && canputnext(q)) {
1467 		m = spdsock_dump_next_record(ss);
1468 		if (m == NULL)
1469 			return;
1470 		dataind = allocb(sizeof (struct T_data_req), BPRI_HI);
1471 		if (dataind == NULL) {
1472 			freemsg(m);
1473 			return;
1474 		}
1475 		dataind->b_cont = m;
1476 		dataind->b_wptr += sizeof (struct T_data_req);
1477 		((struct T_data_ind *)dataind->b_rptr)->PRIM_type = T_DATA_IND;
1478 		((struct T_data_ind *)dataind->b_rptr)->MORE_flag = 0;
1479 		dataind->b_datap->db_type = M_PROTO;
1480 		putnext(q, dataind);
1481 	}
1482 }
1483 
1484 /*
1485  * Start dumping.
1486  * Format a start-of-dump record, and set up the stream and kick the rsrv
1487  * procedure to continue the job..
1488  */
1489 /* ARGSUSED */
1490 static void
1491 spdsock_dump(queue_t *q, ipsec_policy_head_t *iph,
1492     mblk_t *mp, spd_ext_t **extv)
1493 {
1494 	spdsock_t *ss = (spdsock_t *)q->q_ptr;
1495 	mblk_t *mr;
1496 
1497 	rw_enter(&iph->iph_lock, RW_READER);
1498 
1499 	mr = spdsock_dump_ruleset(mp, iph, 0, 0);
1500 
1501 	if (!mr) {
1502 		rw_exit(&iph->iph_lock);
1503 		spdsock_error(q, mp, ENOMEM, 0);
1504 		return;
1505 	}
1506 
1507 	ss->spdsock_dump_req = mp;
1508 	ss->spdsock_dump_head = iph;
1509 	ss->spdsock_dump_gen = iph->iph_gen;
1510 	ss->spdsock_dump_cur_type = 0;
1511 	ss->spdsock_dump_cur_af = IPSEC_AF_V4;
1512 	ss->spdsock_dump_cur_rule = iph->iph_root[0].ipr_nonhash[IPSEC_AF_V4];
1513 	ss->spdsock_dump_count = 0;
1514 	ss->spdsock_dump_cur_chain = 0;
1515 	rw_exit(&iph->iph_lock);
1516 
1517 	qreply(q, mr);
1518 	qenable(OTHERQ(q));
1519 }
1520 
1521 void
1522 spdsock_clone(queue_t *q, mblk_t *mp)
1523 {
1524 	int error = ipsec_clone_system_policy();
1525 	if (error != 0)
1526 		spdsock_error(q, mp, error, 0);
1527 	else
1528 		spd_echo(q, mp);
1529 }
1530 
1531 /*
1532  * Process a SPD_ALGLIST request. The caller expects separate alg entries
1533  * for AH authentication, ESP authentication, and ESP encryption.
1534  * The same distinction is then used when setting the min and max key
1535  * sizes when defining policies.
1536  */
1537 
1538 #define	SPDSOCK_AH_AUTH		0
1539 #define	SPDSOCK_ESP_AUTH	1
1540 #define	SPDSOCK_ESP_ENCR	2
1541 #define	SPDSOCK_NTYPES		3
1542 
1543 static const uint_t algattr[SPDSOCK_NTYPES] = {
1544 	SPD_ATTR_AH_AUTH,
1545 	SPD_ATTR_ESP_AUTH,
1546 	SPD_ATTR_ESP_ENCR
1547 };
1548 static const uint_t minbitsattr[SPDSOCK_NTYPES] = {
1549 	SPD_ATTR_AH_MINBITS,
1550 	SPD_ATTR_ESPA_MINBITS,
1551 	SPD_ATTR_ENCR_MINBITS
1552 };
1553 static const uint_t maxbitsattr[SPDSOCK_NTYPES] = {
1554 	SPD_ATTR_AH_MAXBITS,
1555 	SPD_ATTR_ESPA_MAXBITS,
1556 	SPD_ATTR_ENCR_MAXBITS
1557 };
1558 static const uint_t defbitsattr[SPDSOCK_NTYPES] = {
1559 	SPD_ATTR_AH_DEFBITS,
1560 	SPD_ATTR_ESPA_DEFBITS,
1561 	SPD_ATTR_ENCR_DEFBITS
1562 };
1563 static const uint_t incrbitsattr[SPDSOCK_NTYPES] = {
1564 	SPD_ATTR_AH_INCRBITS,
1565 	SPD_ATTR_ESPA_INCRBITS,
1566 	SPD_ATTR_ENCR_INCRBITS
1567 };
1568 
1569 #define	ATTRPERALG	6	/* fixed attributes per algs */
1570 
1571 void
1572 spdsock_alglist(queue_t *q, mblk_t *mp)
1573 {
1574 	uint_t algtype;
1575 	uint_t algidx;
1576 	uint_t algcount;
1577 	uint_t size;
1578 	mblk_t *m;
1579 	uint8_t *cur;
1580 	spd_msg_t *msg;
1581 	struct spd_ext_actions *act;
1582 	struct spd_attribute *attr;
1583 
1584 	mutex_enter(&alg_lock);
1585 
1586 	/*
1587 	 * The SPD client expects to receive separate entries for
1588 	 * AH authentication and ESP authentication supported algorithms.
1589 	 *
1590 	 * Don't return the "any" algorithms, if defined, as no
1591 	 * kernel policies can be set for these algorithms.
1592 	 */
1593 	algcount = 2 * ipsec_nalgs[IPSEC_ALG_AUTH] +
1594 	    ipsec_nalgs[IPSEC_ALG_ENCR];
1595 
1596 	if (ipsec_alglists[IPSEC_ALG_AUTH][SADB_AALG_NONE] != NULL)
1597 		algcount--;
1598 	if (ipsec_alglists[IPSEC_ALG_ENCR][SADB_EALG_NONE] != NULL)
1599 		algcount--;
1600 
1601 	/*
1602 	 * For each algorithm, we encode:
1603 	 * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
1604 	 */
1605 
1606 	size = sizeof (spd_msg_t) + sizeof (struct spd_ext_actions) +
1607 	    ATTRPERALG * sizeof (struct spd_attribute) * algcount;
1608 
1609 	ASSERT(ALIGNED64(size));
1610 
1611 	m = allocb(size, BPRI_HI);
1612 	if (m == NULL) {
1613 		mutex_exit(&alg_lock);
1614 		spdsock_error(q, mp, ENOMEM, 0);
1615 		return;
1616 	}
1617 
1618 	m->b_wptr = m->b_rptr + size;
1619 	cur = m->b_rptr;
1620 
1621 	msg = (spd_msg_t *)cur;
1622 	bcopy(mp->b_rptr, cur, sizeof (*msg));
1623 
1624 	msg->spd_msg_len = SPD_8TO64(size);
1625 	msg->spd_msg_errno = 0;
1626 	msg->spd_msg_diagnostic = 0;
1627 
1628 	cur += sizeof (*msg);
1629 
1630 	act = (struct spd_ext_actions *)cur;
1631 	cur += sizeof (*act);
1632 
1633 	act->spd_actions_len = SPD_8TO64(size - sizeof (spd_msg_t));
1634 	act->spd_actions_exttype = SPD_EXT_ACTION;
1635 	act->spd_actions_count = algcount;
1636 	act->spd_actions_reserved = 0;
1637 
1638 	attr = (struct spd_attribute *)cur;
1639 
1640 #define	EMIT(tag, value) {					\
1641 		attr->spd_attr_tag = (tag); 			\
1642 		attr->spd_attr_value = (value); 		\
1643 		attr++;			  			\
1644 	}
1645 
1646 	/*
1647 	 * If you change the number of EMIT's here, change
1648 	 * ATTRPERALG above to match
1649 	 */
1650 #define	EMITALGATTRS(_type) {					\
1651 		EMIT(algattr[_type], algid); 		/* 1 */	\
1652 		EMIT(minbitsattr[_type], minbits);	/* 2 */	\
1653 		EMIT(maxbitsattr[_type], maxbits);	/* 3 */	\
1654 		EMIT(defbitsattr[_type], defbits);	/* 4 */	\
1655 		EMIT(incrbitsattr[_type], incr);	/* 5 */	\
1656 		EMIT(SPD_ATTR_NEXT, 0);			/* 6 */	\
1657 	}
1658 
1659 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
1660 		for (algidx = 0; algidx < ipsec_nalgs[algtype]; algidx++) {
1661 			int algid = ipsec_sortlist[algtype][algidx];
1662 			ipsec_alginfo_t *alg = ipsec_alglists[algtype][algid];
1663 			uint_t minbits = alg->alg_minbits;
1664 			uint_t maxbits = alg->alg_maxbits;
1665 			uint_t defbits = alg->alg_default_bits;
1666 			uint_t incr = alg->alg_increment;
1667 
1668 			if (algtype == IPSEC_ALG_AUTH) {
1669 				if (algid == SADB_AALG_NONE)
1670 					continue;
1671 				EMITALGATTRS(SPDSOCK_AH_AUTH);
1672 				EMITALGATTRS(SPDSOCK_ESP_AUTH);
1673 			} else {
1674 				if (algid == SADB_EALG_NONE)
1675 					continue;
1676 				ASSERT(algtype == IPSEC_ALG_ENCR);
1677 				EMITALGATTRS(SPDSOCK_ESP_ENCR);
1678 			}
1679 		}
1680 	}
1681 
1682 	mutex_exit(&alg_lock);
1683 
1684 #undef EMITALGATTRS
1685 #undef EMIT
1686 #undef ATTRPERALG
1687 
1688 	attr--;
1689 	attr->spd_attr_tag = SPD_ATTR_END;
1690 
1691 	freemsg(mp);
1692 	qreply(q, m);
1693 }
1694 
1695 /*
1696  * Process a SPD_DUMPALGS request.
1697  */
1698 
1699 #define	ATTRPERALG	7	/* fixed attributes per algs */
1700 
1701 void
1702 spdsock_dumpalgs(queue_t *q, mblk_t *mp)
1703 {
1704 	uint_t algtype;
1705 	uint_t algidx;
1706 	uint_t size;
1707 	mblk_t *m;
1708 	uint8_t *cur;
1709 	spd_msg_t *msg;
1710 	struct spd_ext_actions *act;
1711 	struct spd_attribute *attr;
1712 	ipsec_alginfo_t *alg;
1713 	uint_t algid;
1714 	uint_t i;
1715 	uint_t alg_size;
1716 
1717 	mutex_enter(&alg_lock);
1718 
1719 	/*
1720 	 * For each algorithm, we encode:
1721 	 * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
1722 	 *
1723 	 * ALG_ID / ALG_PROTO / ALG_INCRBITS / ALG_NKEYSIZES / ALG_KEYSIZE*
1724 	 * ALG_NBLOCKSIZES / ALG_BLOCKSIZE* / ALG_MECHNAME / {END, NEXT}
1725 	 */
1726 
1727 	/*
1728 	 * Compute the size of the SPD message.
1729 	 */
1730 	size = sizeof (spd_msg_t) + sizeof (struct spd_ext_actions);
1731 
1732 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
1733 		for (algidx = 0; algidx < ipsec_nalgs[algtype]; algidx++) {
1734 			algid = ipsec_sortlist[algtype][algidx];
1735 			alg = ipsec_alglists[algtype][algid];
1736 			alg_size = sizeof (struct spd_attribute) *
1737 			    (ATTRPERALG + alg->alg_nkey_sizes +
1738 			    alg->alg_nblock_sizes) + CRYPTO_MAX_MECH_NAME;
1739 			size += alg_size;
1740 		}
1741 	}
1742 
1743 	ASSERT(ALIGNED64(size));
1744 
1745 	m = allocb(size, BPRI_HI);
1746 	if (m == NULL) {
1747 		mutex_exit(&alg_lock);
1748 		spdsock_error(q, mp, ENOMEM, 0);
1749 		return;
1750 	}
1751 
1752 	m->b_wptr = m->b_rptr + size;
1753 	cur = m->b_rptr;
1754 
1755 	msg = (spd_msg_t *)cur;
1756 	bcopy(mp->b_rptr, cur, sizeof (*msg));
1757 
1758 	msg->spd_msg_len = SPD_8TO64(size);
1759 	msg->spd_msg_errno = 0;
1760 	msg->spd_msg_diagnostic = 0;
1761 
1762 	cur += sizeof (*msg);
1763 
1764 	act = (struct spd_ext_actions *)cur;
1765 	cur += sizeof (*act);
1766 
1767 	act->spd_actions_len = SPD_8TO64(size - sizeof (spd_msg_t));
1768 	act->spd_actions_exttype = SPD_EXT_ACTION;
1769 	act->spd_actions_count = ipsec_nalgs[IPSEC_ALG_AUTH] +
1770 	    ipsec_nalgs[IPSEC_ALG_ENCR];
1771 	act->spd_actions_reserved = 0;
1772 
1773 	attr = (struct spd_attribute *)cur;
1774 
1775 #define	EMIT(tag, value) {					\
1776 		attr->spd_attr_tag = (tag); 			\
1777 		attr->spd_attr_value = (value); 		\
1778 		attr++;			  			\
1779 	}
1780 
1781 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
1782 		for (algidx = 0; algidx < ipsec_nalgs[algtype]; algidx++) {
1783 
1784 			algid = ipsec_sortlist[algtype][algidx];
1785 			alg = ipsec_alglists[algtype][algid];
1786 
1787 			/*
1788 			 * If you change the number of EMIT's here, change
1789 			 * ATTRPERALG above to match
1790 			 */
1791 			EMIT(SPD_ATTR_ALG_ID, algid);
1792 			EMIT(SPD_ATTR_ALG_PROTO, algproto[algtype]);
1793 			EMIT(SPD_ATTR_ALG_INCRBITS, alg->alg_increment);
1794 
1795 			EMIT(SPD_ATTR_ALG_NKEYSIZES, alg->alg_nkey_sizes);
1796 			for (i = 0; i < alg->alg_nkey_sizes; i++)
1797 				EMIT(SPD_ATTR_ALG_KEYSIZE,
1798 				    alg->alg_key_sizes[i]);
1799 
1800 			EMIT(SPD_ATTR_ALG_NBLOCKSIZES, alg->alg_nblock_sizes);
1801 			for (i = 0; i < alg->alg_nblock_sizes; i++)
1802 				EMIT(SPD_ATTR_ALG_BLOCKSIZE,
1803 				    alg->alg_block_sizes[i]);
1804 
1805 			EMIT(SPD_ATTR_ALG_MECHNAME, CRYPTO_MAX_MECH_NAME);
1806 			bcopy(alg->alg_mech_name, attr, CRYPTO_MAX_MECH_NAME);
1807 			attr = (struct spd_attribute *)((char *)attr +
1808 			    CRYPTO_MAX_MECH_NAME);
1809 
1810 			EMIT(SPD_ATTR_NEXT, 0);
1811 		}
1812 	}
1813 
1814 	mutex_exit(&alg_lock);
1815 
1816 #undef EMITALGATTRS
1817 #undef EMIT
1818 #undef ATTRPERALG
1819 
1820 	attr--;
1821 	attr->spd_attr_tag = SPD_ATTR_END;
1822 
1823 	freemsg(mp);
1824 	qreply(q, m);
1825 }
1826 
1827 /*
1828  * Do the actual work of processing an SPD_UPDATEALGS request. Can
1829  * be invoked either once IPsec is loaded on a cached request, or
1830  * when a request is received while IPsec is loaded.
1831  */
1832 static void
1833 spdsock_do_updatealg(spd_ext_t *extv[], int *diag)
1834 {
1835 	struct spd_ext_actions *actp;
1836 	struct spd_attribute *attr, *endattr;
1837 	uint64_t *start, *end;
1838 	ipsec_alginfo_t *alg = NULL;
1839 	ipsec_algtype_t alg_type = 0;
1840 	boolean_t skip_alg = B_TRUE, doing_proto = B_FALSE;
1841 	uint_t i, cur_key, cur_block, algid;
1842 
1843 	*diag = -1;
1844 	ASSERT(MUTEX_HELD(&spdsock_alg_lock));
1845 
1846 	/* parse the message, building the list of algorithms */
1847 
1848 	actp = (struct spd_ext_actions *)extv[SPD_EXT_ACTION];
1849 	if (actp == NULL) {
1850 		*diag = SPD_DIAGNOSTIC_NO_ACTION_EXT;
1851 		return;
1852 	}
1853 
1854 	start = (uint64_t *)actp;
1855 	end = (start + actp->spd_actions_len);
1856 	endattr = (struct spd_attribute *)end;
1857 	attr = (struct spd_attribute *)&actp[1];
1858 
1859 	bzero(spdsock_algs, IPSEC_NALGTYPES * IPSEC_MAX_ALGS *
1860 	    sizeof (ipsec_alginfo_t *));
1861 
1862 	alg = kmem_zalloc(sizeof (*alg), KM_SLEEP);
1863 
1864 #define	ALG_KEY_SIZES(a)   (((a)->alg_nkey_sizes + 1) * sizeof (uint16_t))
1865 #define	ALG_BLOCK_SIZES(a) (((a)->alg_nblock_sizes + 1) * sizeof (uint16_t))
1866 
1867 	while (attr < endattr) {
1868 		switch (attr->spd_attr_tag) {
1869 		case SPD_ATTR_NOP:
1870 		case SPD_ATTR_EMPTY:
1871 			break;
1872 		case SPD_ATTR_END:
1873 			attr = endattr;
1874 			/* FALLTHRU */
1875 		case SPD_ATTR_NEXT:
1876 			if (doing_proto) {
1877 				doing_proto = B_FALSE;
1878 				break;
1879 			}
1880 			if (skip_alg) {
1881 				ipsec_alg_free(alg);
1882 			} else {
1883 				ipsec_alg_free(
1884 				    spdsock_algs[alg_type][alg->alg_id]);
1885 				spdsock_algs[alg_type][alg->alg_id] = alg;
1886 			}
1887 			alg = kmem_zalloc(sizeof (*alg), KM_SLEEP);
1888 			break;
1889 
1890 		case SPD_ATTR_ALG_ID:
1891 			if (attr->spd_attr_value >= IPSEC_MAX_ALGS) {
1892 				ss1dbg(("spdsock_do_updatealg: "
1893 				    "invalid alg id %d\n",
1894 				    attr->spd_attr_value));
1895 				*diag = SPD_DIAGNOSTIC_ALG_ID_RANGE;
1896 				goto bail;
1897 			}
1898 			alg->alg_id = attr->spd_attr_value;
1899 			break;
1900 
1901 		case SPD_ATTR_ALG_PROTO:
1902 			/* find the alg type */
1903 			for (i = 0; i < NALGPROTOS; i++)
1904 				if (algproto[i] == attr->spd_attr_value)
1905 					break;
1906 			skip_alg = (i == NALGPROTOS);
1907 			if (!skip_alg)
1908 				alg_type = i;
1909 			break;
1910 
1911 		case SPD_ATTR_ALG_INCRBITS:
1912 			alg->alg_increment = attr->spd_attr_value;
1913 			break;
1914 
1915 		case SPD_ATTR_ALG_NKEYSIZES:
1916 			if (alg->alg_key_sizes != NULL) {
1917 				kmem_free(alg->alg_key_sizes,
1918 				    ALG_KEY_SIZES(alg));
1919 			}
1920 			alg->alg_nkey_sizes = attr->spd_attr_value;
1921 			/*
1922 			 * Allocate room for the trailing zero key size
1923 			 * value as well.
1924 			 */
1925 			alg->alg_key_sizes = kmem_zalloc(ALG_KEY_SIZES(alg),
1926 			    KM_SLEEP);
1927 			cur_key = 0;
1928 			break;
1929 
1930 		case SPD_ATTR_ALG_KEYSIZE:
1931 			if (alg->alg_key_sizes == NULL ||
1932 			    cur_key >= alg->alg_nkey_sizes) {
1933 				ss1dbg(("spdsock_do_updatealg: "
1934 					"too many key sizes\n"));
1935 				*diag = SPD_DIAGNOSTIC_ALG_NUM_KEY_SIZES;
1936 				goto bail;
1937 			}
1938 			alg->alg_key_sizes[cur_key++] = attr->spd_attr_value;
1939 			break;
1940 
1941 		case SPD_ATTR_ALG_NBLOCKSIZES:
1942 			if (alg->alg_block_sizes != NULL) {
1943 				kmem_free(alg->alg_block_sizes,
1944 				    ALG_BLOCK_SIZES(alg));
1945 			}
1946 			alg->alg_nblock_sizes = attr->spd_attr_value;
1947 			/*
1948 			 * Allocate room for the trailing zero block size
1949 			 * value as well.
1950 			 */
1951 			alg->alg_block_sizes = kmem_zalloc(ALG_BLOCK_SIZES(alg),
1952 			    KM_SLEEP);
1953 			cur_block = 0;
1954 			break;
1955 
1956 		case SPD_ATTR_ALG_BLOCKSIZE:
1957 			if (alg->alg_block_sizes == NULL ||
1958 			    cur_block >= alg->alg_nblock_sizes) {
1959 				ss1dbg(("spdsock_do_updatealg: "
1960 					"too many block sizes\n"));
1961 				*diag = SPD_DIAGNOSTIC_ALG_NUM_BLOCK_SIZES;
1962 				goto bail;
1963 			}
1964 			alg->alg_block_sizes[cur_block++] =
1965 			    attr->spd_attr_value;
1966 			break;
1967 
1968 		case SPD_ATTR_ALG_MECHNAME: {
1969 			char *mech_name;
1970 
1971 			if (attr->spd_attr_value > CRYPTO_MAX_MECH_NAME) {
1972 				ss1dbg(("spdsock_do_updatealg: "
1973 					"mech name too long\n"));
1974 				*diag = SPD_DIAGNOSTIC_ALG_MECH_NAME_LEN;
1975 				goto bail;
1976 			}
1977 			mech_name = (char *)(attr + 1);
1978 			bcopy(mech_name, alg->alg_mech_name,
1979 			    attr->spd_attr_value);
1980 			alg->alg_mech_name[CRYPTO_MAX_MECH_NAME-1] = '\0';
1981 			attr = (struct spd_attribute *)((char *)attr +
1982 			    attr->spd_attr_value);
1983 			break;
1984 		}
1985 
1986 		case SPD_ATTR_PROTO_ID:
1987 			doing_proto = B_TRUE;
1988 			for (i = 0; i < NALGPROTOS; i++) {
1989 				if (algproto[i] == attr->spd_attr_value) {
1990 					alg_type = i;
1991 					break;
1992 				}
1993 			}
1994 			break;
1995 
1996 		case SPD_ATTR_PROTO_EXEC_MODE:
1997 			if (!doing_proto)
1998 				break;
1999 			for (i = 0; i < NEXECMODES; i++) {
2000 				if (execmodes[i] == attr->spd_attr_value) {
2001 					spdsock_algs_exec_mode[alg_type] = i;
2002 					break;
2003 				}
2004 			}
2005 			break;
2006 		}
2007 		attr++;
2008 	}
2009 
2010 #undef	ALG_KEY_SIZES
2011 #undef	ALG_BLOCK_SIZES
2012 
2013 	/* update the algorithm tables */
2014 	spdsock_merge_algs();
2015 bail:
2016 	/* cleanup */
2017 	ipsec_alg_free(alg);
2018 	for (alg_type = 0; alg_type < IPSEC_NALGTYPES; alg_type++)
2019 		for (algid = 0; algid < IPSEC_MAX_ALGS; algid++)
2020 			if (spdsock_algs[alg_type][algid] != NULL)
2021 				ipsec_alg_free(spdsock_algs[alg_type][algid]);
2022 }
2023 
2024 /*
2025  * Process an SPD_UPDATEALGS request. If IPsec is not loaded, queue
2026  * the request until IPsec loads. If IPsec is loaded, act on it
2027  * immediately.
2028  */
2029 
2030 static void
2031 spdsock_updatealg(queue_t *q, mblk_t *mp, spd_ext_t *extv[])
2032 {
2033 	if (!ipsec_loaded()) {
2034 		/*
2035 		 * IPsec is not loaded, save request and return nicely,
2036 		 * the message will be processed once IPsec loads.
2037 		 */
2038 		mblk_t *new_mp;
2039 
2040 		/* last update message wins */
2041 		if ((new_mp = copymsg(mp)) == NULL) {
2042 			spdsock_error(q, mp, ENOMEM, 0);
2043 			return;
2044 		}
2045 		mutex_enter(&spdsock_alg_lock);
2046 		bcopy(extv, spdsock_extv_algs,
2047 		    sizeof (spd_ext_t *) * (SPD_EXT_MAX + 1));
2048 		if (spdsock_mp_algs != NULL)
2049 			freemsg(spdsock_mp_algs);
2050 		spdsock_mp_algs = mp;
2051 		spdsock_algs_pending = B_TRUE;
2052 		mutex_exit(&spdsock_alg_lock);
2053 
2054 		spd_echo(q, new_mp);
2055 	} else {
2056 		/*
2057 		 * IPsec is loaded, act on the message immediately.
2058 		 */
2059 		int diag;
2060 
2061 		mutex_enter(&spdsock_alg_lock);
2062 		spdsock_do_updatealg(extv, &diag);
2063 		mutex_exit(&spdsock_alg_lock);
2064 		if (diag == -1)
2065 			spd_echo(q, mp);
2066 		else
2067 			spdsock_diag(q, mp, diag);
2068 	}
2069 }
2070 
2071 static void
2072 spdsock_parse(queue_t *q, mblk_t *mp)
2073 {
2074 	spd_msg_t *spmsg;
2075 	spd_ext_t *extv[SPD_EXT_MAX + 1];
2076 	uint_t msgsize;
2077 	ipsec_policy_head_t *iph;
2078 
2079 	/* Make sure nothing's below me. */
2080 	ASSERT(WR(q)->q_next == NULL);
2081 
2082 	spmsg = (spd_msg_t *)mp->b_rptr;
2083 
2084 	msgsize = SPD_64TO8(spmsg->spd_msg_len);
2085 
2086 	if (msgdsize(mp) != msgsize) {
2087 		/*
2088 		 * Message len incorrect w.r.t. actual size.  Send an error
2089 		 * (EMSGSIZE).	It may be necessary to massage things a
2090 		 * bit.	 For example, if the spd_msg_type is hosed,
2091 		 * I need to set it to SPD_RESERVED to get delivery to
2092 		 * do the right thing.	Then again, maybe just letting
2093 		 * the error delivery do the right thing.
2094 		 */
2095 		ss2dbg(("mblk (%lu) and base (%d) message sizes don't jibe.\n",
2096 		    msgdsize(mp), msgsize));
2097 		spdsock_error(q, mp, EMSGSIZE, SPD_DIAGNOSTIC_NONE);
2098 		return;
2099 	}
2100 
2101 	if (msgsize > (uint_t)(mp->b_wptr - mp->b_rptr)) {
2102 
2103 		/* Get all message into one mblk. */
2104 		if (pullupmsg(mp, -1) == 0) {
2105 			/*
2106 			 * Something screwy happened.
2107 			 */
2108 			ss3dbg(("spdsock_parse: pullupmsg() failed.\n"));
2109 			return;
2110 		} else {
2111 			spmsg = (spd_msg_t *)mp->b_rptr;
2112 		}
2113 	}
2114 
2115 	switch (spdsock_get_ext(extv, spmsg, msgsize)) {
2116 	case KGE_DUP:
2117 		/* Handle duplicate extension. */
2118 		ss1dbg(("Got duplicate extension of type %d.\n",
2119 		    extv[0]->spd_ext_type));
2120 		spdsock_diag(q, mp, dup_ext_diag[extv[0]->spd_ext_type]);
2121 		return;
2122 	case KGE_UNK:
2123 		/* Handle unknown extension. */
2124 		ss1dbg(("Got unknown extension of type %d.\n",
2125 		    extv[0]->spd_ext_type));
2126 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_UNKNOWN_EXT);
2127 		return;
2128 	case KGE_LEN:
2129 		/* Length error. */
2130 		ss1dbg(("Length %d on extension type %d overrun or 0.\n",
2131 		    extv[0]->spd_ext_len, extv[0]->spd_ext_type));
2132 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_BAD_EXTLEN);
2133 		return;
2134 	case KGE_CHK:
2135 		/* Reality check failed. */
2136 		ss1dbg(("Reality check failed on extension type %d.\n",
2137 		    extv[0]->spd_ext_type));
2138 		spdsock_diag(q, mp, bad_ext_diag[extv[0]->spd_ext_type]);
2139 		return;
2140 	default:
2141 		/* Default case is no errors. */
2142 		break;
2143 	}
2144 
2145 	/*
2146 	 * Which rule set are we operating on today?
2147 	 */
2148 
2149 	switch (spmsg->spd_msg_spdid) {
2150 	case SPD_ACTIVE:
2151 		iph = ipsec_system_policy();
2152 		break;
2153 
2154 	case SPD_STANDBY:
2155 		iph = ipsec_inactive_policy();
2156 		break;
2157 
2158 	default:
2159 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_BAD_SPDID);
2160 		return;
2161 	}
2162 
2163 	/*
2164 	 * Special-case SPD_UPDATEALGS so as not to load IPsec.
2165 	 */
2166 	if (!ipsec_loaded() && spmsg->spd_msg_type != SPD_UPDATEALGS) {
2167 		spdsock_t *ss = (spdsock_t *)q->q_ptr;
2168 
2169 		ASSERT(ss != NULL);
2170 		ipsec_loader_loadnow();
2171 		ss->spdsock_timeout_arg = mp;
2172 		ss->spdsock_timeout = qtimeout(q, spdsock_loadcheck,
2173 		    q, LOADCHECK_INTERVAL);
2174 		return;
2175 	}
2176 
2177 	switch (spmsg->spd_msg_type) {
2178 	case SPD_UPDATEALGS:
2179 		spdsock_updatealg(q, mp, extv);
2180 		return;
2181 	case SPD_FLUSH:
2182 		spdsock_flush(q, iph, mp, extv);
2183 		return;
2184 
2185 	case SPD_ADDRULE:
2186 		spdsock_addrule(q, iph, mp, extv);
2187 		return;
2188 
2189 	case SPD_DELETERULE:
2190 		spdsock_deleterule(q, iph, mp, extv);
2191 		return;
2192 
2193 	case SPD_FLIP:
2194 		spdsock_flip(q, mp);
2195 		return;
2196 
2197 	case SPD_LOOKUP:
2198 		spdsock_lookup(q, iph, mp, extv);
2199 		return;
2200 
2201 	case SPD_DUMP:
2202 		spdsock_dump(q, iph, mp, extv);
2203 		return;
2204 
2205 	case SPD_CLONE:
2206 		spdsock_clone(q, mp);
2207 		return;
2208 
2209 	case SPD_ALGLIST:
2210 		spdsock_alglist(q, mp);
2211 		return;
2212 
2213 	case SPD_DUMPALGS:
2214 		spdsock_dumpalgs(q, mp);
2215 		return;
2216 
2217 	default:
2218 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_BAD_MSG_TYPE);
2219 		return;
2220 	}
2221 }
2222 
2223 /*
2224  * If an algorithm mapping was received before IPsec was loaded, process it.
2225  * Called from the IPsec loader.
2226  */
2227 void
2228 spdsock_update_pending_algs(void)
2229 {
2230 	mutex_enter(&spdsock_alg_lock);
2231 	if (spdsock_algs_pending) {
2232 		int diag;
2233 		spdsock_do_updatealg(spdsock_extv_algs, &diag);
2234 		spdsock_algs_pending = B_FALSE;
2235 	}
2236 	mutex_exit(&spdsock_alg_lock);
2237 }
2238 
2239 static void
2240 spdsock_loadcheck(void *arg)
2241 {
2242 	queue_t *q = (queue_t *)arg;
2243 	spdsock_t *ss = (spdsock_t *)q->q_ptr;
2244 	mblk_t *mp;
2245 
2246 	ASSERT(ss != NULL);
2247 
2248 	ss->spdsock_timeout = 0;
2249 	mp = ss->spdsock_timeout_arg;
2250 	ASSERT(mp != NULL);
2251 	ss->spdsock_timeout_arg = NULL;
2252 	if (ipsec_failed())
2253 		spdsock_error(q, mp, EPROTONOSUPPORT, 0);
2254 	else
2255 		spdsock_parse(q, mp);
2256 }
2257 
2258 /*
2259  * Copy relevant state bits.
2260  */
2261 static void
2262 spdsock_copy_info(struct T_info_ack *tap, spdsock_t *ss)
2263 {
2264 	*tap = spdsock_g_t_info_ack;
2265 	tap->CURRENT_state = ss->spdsock_state;
2266 	tap->OPT_size = spdsock_max_optsize;
2267 }
2268 
2269 /*
2270  * This routine responds to T_CAPABILITY_REQ messages.  It is called by
2271  * spdsock_wput.  Much of the T_CAPABILITY_ACK information is copied from
2272  * spdsock_g_t_info_ack.  The current state of the stream is copied from
2273  * spdsock_state.
2274  */
2275 static void
2276 spdsock_capability_req(queue_t *q, mblk_t *mp)
2277 {
2278 	spdsock_t *ss = (spdsock_t *)q->q_ptr;
2279 	t_uscalar_t cap_bits1;
2280 	struct T_capability_ack	*tcap;
2281 
2282 	cap_bits1 = ((struct T_capability_req *)mp->b_rptr)->CAP_bits1;
2283 
2284 	mp = tpi_ack_alloc(mp, sizeof (struct T_capability_ack),
2285 		mp->b_datap->db_type, T_CAPABILITY_ACK);
2286 	if (mp == NULL)
2287 		return;
2288 
2289 	tcap = (struct T_capability_ack *)mp->b_rptr;
2290 	tcap->CAP_bits1 = 0;
2291 
2292 	if (cap_bits1 & TC1_INFO) {
2293 		spdsock_copy_info(&tcap->INFO_ack, ss);
2294 		tcap->CAP_bits1 |= TC1_INFO;
2295 	}
2296 
2297 	qreply(q, mp);
2298 }
2299 
2300 /*
2301  * This routine responds to T_INFO_REQ messages. It is called by
2302  * spdsock_wput_other.
2303  * Most of the T_INFO_ACK information is copied from spdsock_g_t_info_ack.
2304  * The current state of the stream is copied from spdsock_state.
2305  */
2306 static void
2307 spdsock_info_req(q, mp)
2308 	queue_t	*q;
2309 	mblk_t	*mp;
2310 {
2311 	mp = tpi_ack_alloc(mp, sizeof (struct T_info_ack), M_PCPROTO,
2312 	    T_INFO_ACK);
2313 	if (mp == NULL)
2314 		return;
2315 	spdsock_copy_info((struct T_info_ack *)mp->b_rptr,
2316 	    (spdsock_t *)q->q_ptr);
2317 	qreply(q, mp);
2318 }
2319 
2320 /*
2321  * spdsock_err_ack. This routine creates a
2322  * T_ERROR_ACK message and passes it
2323  * upstream.
2324  */
2325 static void
2326 spdsock_err_ack(q, mp, t_error, sys_error)
2327 	queue_t	*q;
2328 	mblk_t	*mp;
2329 	int	t_error;
2330 	int	sys_error;
2331 {
2332 	if ((mp = mi_tpi_err_ack_alloc(mp, t_error, sys_error)) != NULL)
2333 		qreply(q, mp);
2334 }
2335 
2336 /*
2337  * This routine retrieves the current status of socket options.
2338  * It returns the size of the option retrieved.
2339  */
2340 /* ARGSUSED */
2341 int
2342 spdsock_opt_get(queue_t *q, int level, int name, uchar_t *ptr)
2343 {
2344 	int *i1 = (int *)ptr;
2345 
2346 	switch (level) {
2347 	case SOL_SOCKET:
2348 		switch (name) {
2349 		case SO_TYPE:
2350 			*i1 = SOCK_RAW;
2351 			break;
2352 		/*
2353 		 * The following two items can be manipulated,
2354 		 * but changing them should do nothing.
2355 		 */
2356 		case SO_SNDBUF:
2357 			*i1 = (int)q->q_hiwat;
2358 			break;
2359 		case SO_RCVBUF:
2360 			*i1 = (int)(RD(q)->q_hiwat);
2361 			break;
2362 		}
2363 		break;
2364 	default:
2365 		return (0);
2366 	}
2367 	return (sizeof (int));
2368 }
2369 
2370 /*
2371  * This routine sets socket options.
2372  */
2373 /* ARGSUSED */
2374 int
2375 spdsock_opt_set(queue_t *q, uint_t mgmt_flags, int level, int name,
2376     uint_t inlen, uchar_t *invalp, uint_t *outlenp, uchar_t *outvalp,
2377     void *thisdg_attrs, cred_t *cr, mblk_t *mblk)
2378 {
2379 	int *i1 = (int *)invalp;
2380 
2381 	switch (level) {
2382 	case SOL_SOCKET:
2383 		switch (name) {
2384 		case SO_SNDBUF:
2385 			if (*i1 > spdsock_max_buf)
2386 				return (ENOBUFS);
2387 			q->q_hiwat = *i1;
2388 			break;
2389 		case SO_RCVBUF:
2390 			if (*i1 > spdsock_max_buf)
2391 				return (ENOBUFS);
2392 			RD(q)->q_hiwat = *i1;
2393 			(void) mi_set_sth_hiwat(RD(q), *i1);
2394 			break;
2395 		}
2396 		break;
2397 	}
2398 	return (0);
2399 }
2400 
2401 
2402 /*
2403  * Handle STREAMS messages.
2404  */
2405 static void
2406 spdsock_wput_other(queue_t *q, mblk_t *mp)
2407 {
2408 	struct iocblk *iocp;
2409 	int error;
2410 
2411 	switch (mp->b_datap->db_type) {
2412 	case M_PROTO:
2413 	case M_PCPROTO:
2414 		if ((mp->b_wptr - mp->b_rptr) < sizeof (long)) {
2415 			ss3dbg((
2416 			    "spdsock_wput_other: Not big enough M_PROTO\n"));
2417 			freemsg(mp);
2418 			return;
2419 		}
2420 		switch (((union T_primitives *)mp->b_rptr)->type) {
2421 		case T_CAPABILITY_REQ:
2422 			spdsock_capability_req(q, mp);
2423 			return;
2424 		case T_INFO_REQ:
2425 			spdsock_info_req(q, mp);
2426 			return;
2427 		case T_SVR4_OPTMGMT_REQ:
2428 			(void) svr4_optcom_req(q, mp, DB_CREDDEF(mp, kcred),
2429 			    &spdsock_opt_obj);
2430 			return;
2431 		case T_OPTMGMT_REQ:
2432 			(void) tpi_optcom_req(q, mp, DB_CREDDEF(mp, kcred),
2433 			    &spdsock_opt_obj);
2434 			return;
2435 		case T_DATA_REQ:
2436 		case T_EXDATA_REQ:
2437 		case T_ORDREL_REQ:
2438 			/* Illegal for spdsock. */
2439 			freemsg(mp);
2440 			(void) putnextctl1(RD(q), M_ERROR, EPROTO);
2441 			return;
2442 		default:
2443 			/* Not supported by spdsock. */
2444 			spdsock_err_ack(q, mp, TNOTSUPPORT, 0);
2445 			return;
2446 		}
2447 	case M_IOCTL:
2448 		iocp = (struct iocblk *)mp->b_rptr;
2449 		error = EINVAL;
2450 
2451 		switch (iocp->ioc_cmd) {
2452 		case ND_SET:
2453 		case ND_GET:
2454 			if (nd_getset(q, spdsock_g_nd, mp)) {
2455 				qreply(q, mp);
2456 				return;
2457 			} else
2458 				error = ENOENT;
2459 			/* FALLTHRU */
2460 		default:
2461 			miocnak(q, mp, 0, error);
2462 			return;
2463 		}
2464 	case M_FLUSH:
2465 		if (*mp->b_rptr & FLUSHW) {
2466 			flushq(q, FLUSHALL);
2467 			*mp->b_rptr &= ~FLUSHW;
2468 		}
2469 		if (*mp->b_rptr & FLUSHR) {
2470 			qreply(q, mp);
2471 			return;
2472 		}
2473 		/* Else FALLTHRU */
2474 	}
2475 
2476 	/* If fell through, just black-hole the message. */
2477 	freemsg(mp);
2478 }
2479 
2480 static void
2481 spdsock_wput(queue_t *q, mblk_t *mp)
2482 {
2483 	uint8_t *rptr = mp->b_rptr;
2484 	mblk_t *mp1;
2485 	spdsock_t *ss = (spdsock_t *)q->q_ptr;
2486 
2487 	/*
2488 	 * If we're dumping, defer processing other messages until the
2489 	 * dump completes.
2490 	 */
2491 	if (ss->spdsock_dump_req != NULL) {
2492 		if (!putq(q, mp))
2493 			freemsg(mp);
2494 		return;
2495 	}
2496 
2497 	switch (mp->b_datap->db_type) {
2498 	case M_DATA:
2499 		/*
2500 		 * Silently discard.
2501 		 */
2502 		ss2dbg(("raw M_DATA in spdsock.\n"));
2503 		freemsg(mp);
2504 		return;
2505 	case M_PROTO:
2506 	case M_PCPROTO:
2507 		if ((mp->b_wptr - rptr) >= sizeof (struct T_data_req)) {
2508 			if (((union T_primitives *)rptr)->type == T_DATA_REQ) {
2509 				if ((mp1 = mp->b_cont) == NULL) {
2510 					/* No data after T_DATA_REQ. */
2511 					ss2dbg(("No data after DATA_REQ.\n"));
2512 					freemsg(mp);
2513 					return;
2514 				}
2515 				freeb(mp);
2516 				mp = mp1;
2517 				ss2dbg(("T_DATA_REQ\n"));
2518 				break;	/* Out of switch. */
2519 			}
2520 		}
2521 		/* FALLTHRU */
2522 	default:
2523 		ss3dbg(("In default wput case (%d %d).\n",
2524 		    mp->b_datap->db_type, ((union T_primitives *)rptr)->type));
2525 		spdsock_wput_other(q, mp);
2526 		return;
2527 	}
2528 
2529 	/* I now have a PF_POLICY message in an M_DATA block. */
2530 	spdsock_parse(q, mp);
2531 }
2532 
2533 /*
2534  * Device open procedure, called when new queue pair created.
2535  * We are passed the read-side queue.
2536  */
2537 /* ARGSUSED */
2538 static int
2539 spdsock_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
2540 {
2541 	spdsock_t *ss;
2542 	queue_t *oq = OTHERQ(q);
2543 	minor_t ssminor;
2544 
2545 	if (secpolicy_net_config(credp, B_FALSE) != 0)
2546 		return (EPERM);
2547 
2548 	if (q->q_ptr != NULL)
2549 		return (0);  /* Re-open of an already open instance. */
2550 
2551 	if (sflag & MODOPEN)
2552 		return (EINVAL);
2553 
2554 	ss2dbg(("Made it into PF_POLICY socket open.\n"));
2555 
2556 	ssminor = (minor_t)(uintptr_t)vmem_alloc(spdsock_vmem, 1, VM_NOSLEEP);
2557 	if (ssminor == 0)
2558 		return (ENOMEM);
2559 
2560 	ss = kmem_zalloc(sizeof (spdsock_t), KM_NOSLEEP);
2561 	if (ss == NULL) {
2562 		vmem_free(spdsock_vmem, (void *)(uintptr_t)ssminor, 1);
2563 		return (ENOMEM);
2564 	}
2565 
2566 	ss->spdsock_minor = ssminor;
2567 	ss->spdsock_state = TS_UNBND;
2568 	ss->spdsock_dump_req = NULL;
2569 
2570 	q->q_ptr = ss;
2571 	oq->q_ptr = ss;
2572 
2573 	q->q_hiwat = spdsock_recv_hiwat;
2574 
2575 	oq->q_hiwat = spdsock_xmit_hiwat;
2576 	oq->q_lowat = spdsock_xmit_lowat;
2577 
2578 	qprocson(q);
2579 	(void) mi_set_sth_hiwat(q, spdsock_recv_hiwat);
2580 
2581 	*devp = makedevice(getmajor(*devp), ss->spdsock_minor);
2582 	return (0);
2583 }
2584 
2585 /*
2586  * Read-side service procedure, invoked when we get back-enabled
2587  * when buffer space becomes available.
2588  *
2589  * Dump another chunk if we were dumping before; when we finish, kick
2590  * the write-side queue in case it's waiting for read queue space.
2591  */
2592 void
2593 spdsock_rsrv(queue_t *q)
2594 {
2595 	spdsock_t *ss = q->q_ptr;
2596 
2597 	if (ss->spdsock_dump_req != NULL)
2598 		spdsock_dump_some(q, ss);
2599 
2600 	if (ss->spdsock_dump_req == NULL)
2601 		qenable(OTHERQ(q));
2602 }
2603 
2604 /*
2605  * Write-side service procedure, invoked when we defer processing
2606  * if another message is received while a dump is in progress.
2607  */
2608 void
2609 spdsock_wsrv(queue_t *q)
2610 {
2611 	spdsock_t *ss = q->q_ptr;
2612 	mblk_t *mp;
2613 
2614 	if (ss->spdsock_dump_req != NULL) {
2615 		qenable(OTHERQ(q));
2616 		return;
2617 	}
2618 
2619 	while ((mp = getq(q)) != NULL) {
2620 		if (ipsec_loaded()) {
2621 			spdsock_wput(q, mp);
2622 			if (ss->spdsock_dump_req != NULL)
2623 				return;
2624 		} else if (!ipsec_failed()) {
2625 			(void) putq(q, mp);
2626 		} else {
2627 			spdsock_error(q, mp, EPFNOSUPPORT, 0);
2628 		}
2629 	}
2630 }
2631 
2632 static int
2633 spdsock_close(queue_t *q)
2634 {
2635 	spdsock_t *ss = q->q_ptr;
2636 
2637 	qprocsoff(q);
2638 
2639 	/* Safe assumption. */
2640 	ASSERT(ss != NULL);
2641 
2642 	if (ss->spdsock_timeout != 0)
2643 		(void) quntimeout(q, ss->spdsock_timeout);
2644 
2645 	ss3dbg(("Driver close, PF_POLICY socket is going away.\n"));
2646 
2647 	vmem_free(spdsock_vmem, (void *)(uintptr_t)ss->spdsock_minor, 1);
2648 
2649 	kmem_free(ss, sizeof (spdsock_t));
2650 	return (0);
2651 }
2652 
2653 /*
2654  * Merge the IPsec algorithms tables with the received algorithm information.
2655  */
2656 void
2657 spdsock_merge_algs(void)
2658 {
2659 	ipsec_alginfo_t *alg, *oalg;
2660 	ipsec_algtype_t algtype;
2661 	uint_t algidx, algid, nalgs;
2662 	crypto_mech_name_t *mechs;
2663 	uint_t mech_count, mech_idx;
2664 
2665 	ASSERT(MUTEX_HELD(&spdsock_alg_lock));
2666 
2667 	/*
2668 	 * Get the list of supported mechanisms from the crypto framework.
2669 	 * If a mechanism is supported by KCF, resolve its mechanism
2670 	 * id and mark it as being valid. This operation must be done
2671 	 * without holding alg_lock, since it can cause a provider
2672 	 * module to be loaded and the provider notification callback to
2673 	 * be invoked.
2674 	 */
2675 	mechs = crypto_get_mech_list(&mech_count, KM_SLEEP);
2676 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2677 		for (algid = 0; algid < IPSEC_MAX_ALGS; algid++) {
2678 			int algflags = 0;
2679 			crypto_mech_type_t mt = CRYPTO_MECHANISM_INVALID;
2680 
2681 			if ((alg = spdsock_algs[algtype][algid]) == NULL)
2682 				continue;
2683 
2684 			/*
2685 			 * The NULL encryption algorithm is a special
2686 			 * case because there are no mechanisms, yet
2687 			 * the algorithm is still valid.
2688 			 */
2689 			if (alg->alg_id == SADB_EALG_NULL) {
2690 				alg->alg_mech_type = CRYPTO_MECHANISM_INVALID;
2691 				alg->alg_flags = ALG_FLAG_VALID;
2692 				continue;
2693 			}
2694 
2695 			for (mech_idx = 0; mech_idx < mech_count; mech_idx++) {
2696 				if (strncmp(alg->alg_mech_name, mechs[mech_idx],
2697 				    CRYPTO_MAX_MECH_NAME) == 0) {
2698 					mt = crypto_mech2id(alg->alg_mech_name);
2699 					ASSERT(mt != CRYPTO_MECHANISM_INVALID);
2700 					algflags = ALG_FLAG_VALID;
2701 					break;
2702 				}
2703 			}
2704 			alg->alg_mech_type = mt;
2705 			alg->alg_flags = algflags;
2706 		}
2707 	}
2708 
2709 	mutex_enter(&alg_lock);
2710 
2711 	/*
2712 	 * For each algorithm currently defined, check if it is
2713 	 * present in the new tables created from the SPD_UPDATEALGS
2714 	 * message received from user-space.
2715 	 * Delete the algorithm entries that are currently defined
2716 	 * but not part of the new tables.
2717 	 */
2718 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2719 		nalgs = ipsec_nalgs[algtype];
2720 		for (algidx = 0; algidx < nalgs; algidx++) {
2721 			algid = ipsec_sortlist[algtype][algidx];
2722 			if (spdsock_algs[algtype][algid] == NULL)
2723 				ipsec_alg_unreg(algtype, algid);
2724 		}
2725 	}
2726 
2727 	/*
2728 	 * For each algorithm we just received, check if it is
2729 	 * present in the currently defined tables. If it is, swap
2730 	 * the entry with the one we just allocated.
2731 	 * If the new algorithm is not in the current tables,
2732 	 * add it.
2733 	 */
2734 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2735 		for (algid = 0; algid < IPSEC_MAX_ALGS; algid++) {
2736 			if ((alg = spdsock_algs[algtype][algid]) == NULL)
2737 				continue;
2738 
2739 			if ((oalg = ipsec_alglists[algtype][algid]) == NULL) {
2740 				/*
2741 				 * New algorithm, add it to the algorithm
2742 				 * table.
2743 				 */
2744 				ipsec_alg_reg(algtype, alg);
2745 			} else {
2746 				/*
2747 				 * Algorithm is already in the table. Swap
2748 				 * the existing entry with the new one.
2749 				 */
2750 				ipsec_alg_fix_min_max(alg, algtype);
2751 				ipsec_alglists[algtype][algid] = alg;
2752 				ipsec_alg_free(oalg);
2753 			}
2754 			spdsock_algs[algtype][algid] = NULL;
2755 		}
2756 	}
2757 
2758 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++)
2759 		ipsec_algs_exec_mode[algtype] = spdsock_algs_exec_mode[algtype];
2760 
2761 	mutex_exit(&alg_lock);
2762 
2763 	crypto_free_mech_list(mechs, mech_count);
2764 
2765 	ipsecah_algs_changed();
2766 	ipsecesp_algs_changed();
2767 }
2768