xref: /titanic_44/usr/src/uts/common/inet/ip/spdsock.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
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_rule(spdsock_t *ss, ipsec_policy_head_t *iph)
1362 {
1363 	ipsec_policy_t *cur;
1364 
1365 	ASSERT(RW_READ_HELD(&iph->iph_lock));
1366 
1367 	cur = ss->spdsock_dump_cur_rule;
1368 
1369 	if (cur == NULL) {
1370 		int af = ss->spdsock_dump_cur_af;
1371 		int type = ss->spdsock_dump_cur_type;
1372 		do {
1373 			af++;
1374 			if (af >= IPSEC_NAF) {
1375 				af = IPSEC_AF_V4;
1376 				type++;
1377 				if (type >= IPSEC_NTYPES)
1378 					return (NULL);
1379 			}
1380 			cur = iph->iph_root[type].ipr[af];
1381 		} while (cur == NULL);
1382 		ss->spdsock_dump_cur_af = af;
1383 		ss->spdsock_dump_cur_type = type;
1384 	}
1385 	ss->spdsock_dump_count++;
1386 	ss->spdsock_dump_cur_rule = cur->ipsp_links.itl_next;
1387 	return (cur);
1388 }
1389 
1390 static mblk_t *
1391 spdsock_dump_next_record(spdsock_t *ss)
1392 {
1393 	ipsec_policy_head_t *iph;
1394 	ipsec_policy_t *rule;
1395 	mblk_t *m;
1396 	mblk_t *req = ss->spdsock_dump_req;
1397 
1398 	iph = ss->spdsock_dump_head;
1399 
1400 	ASSERT(iph != NULL);
1401 
1402 	rw_enter(&iph->iph_lock, RW_READER);
1403 
1404 	if (iph->iph_gen != ss->spdsock_dump_gen) {
1405 		rw_exit(&iph->iph_lock);
1406 		return (spdsock_dump_finish(ss, EAGAIN));
1407 	}
1408 
1409 	rule = spdsock_dump_next_rule(ss, iph);
1410 
1411 	if (!rule) {
1412 		rw_exit(&iph->iph_lock);
1413 		return (spdsock_dump_finish(ss, 0));
1414 	}
1415 
1416 	m = spdsock_encode_rule(req, rule, ss->spdsock_dump_cur_type,
1417 	    ss->spdsock_dump_cur_af);
1418 	rw_exit(&iph->iph_lock);
1419 
1420 	if (m == NULL)
1421 		return (spdsock_dump_finish(ss, ENOMEM));
1422 	return (m);
1423 }
1424 
1425 /*
1426  * Dump records until we run into flow-control back-pressure.
1427  */
1428 static void
1429 spdsock_dump_some(queue_t *q, spdsock_t *ss)
1430 {
1431 	mblk_t *m, *dataind;
1432 
1433 	while ((ss->spdsock_dump_req != NULL) && canputnext(q)) {
1434 		m = spdsock_dump_next_record(ss);
1435 		if (m == NULL)
1436 			return;
1437 		dataind = allocb(sizeof (struct T_data_req), BPRI_HI);
1438 		if (dataind == NULL) {
1439 			freemsg(m);
1440 			return;
1441 		}
1442 		dataind->b_cont = m;
1443 		dataind->b_wptr += sizeof (struct T_data_req);
1444 		((struct T_data_ind *)dataind->b_rptr)->PRIM_type = T_DATA_IND;
1445 		((struct T_data_ind *)dataind->b_rptr)->MORE_flag = 0;
1446 		dataind->b_datap->db_type = M_PROTO;
1447 		putnext(q, dataind);
1448 	}
1449 }
1450 
1451 /*
1452  * Start dumping.
1453  * Format a start-of-dump record, and set up the stream and kick the rsrv
1454  * procedure to continue the job..
1455  */
1456 /* ARGSUSED */
1457 static void
1458 spdsock_dump(queue_t *q, ipsec_policy_head_t *iph,
1459     mblk_t *mp, spd_ext_t **extv)
1460 {
1461 	spdsock_t *ss = (spdsock_t *)q->q_ptr;
1462 	mblk_t *mr;
1463 
1464 	rw_enter(&iph->iph_lock, RW_READER);
1465 
1466 	mr = spdsock_dump_ruleset(mp, iph, 0, 0);
1467 
1468 	if (!mr) {
1469 		rw_exit(&iph->iph_lock);
1470 		spdsock_error(q, mp, ENOMEM, 0);
1471 		return;
1472 	}
1473 
1474 	ss->spdsock_dump_req = mp;
1475 	ss->spdsock_dump_head = iph;
1476 	ss->spdsock_dump_gen = iph->iph_gen;
1477 	ss->spdsock_dump_cur_type = 0;
1478 	ss->spdsock_dump_cur_af = IPSEC_AF_V4;
1479 	ss->spdsock_dump_cur_rule = iph->iph_root[0].ipr[IPSEC_AF_V4];
1480 	ss->spdsock_dump_count = 0;
1481 
1482 	rw_exit(&iph->iph_lock);
1483 
1484 	qreply(q, mr);
1485 	qenable(OTHERQ(q));
1486 }
1487 
1488 void
1489 spdsock_clone(queue_t *q, mblk_t *mp)
1490 {
1491 	int error = ipsec_clone_system_policy();
1492 	if (error != 0)
1493 		spdsock_error(q, mp, error, 0);
1494 	else
1495 		spd_echo(q, mp);
1496 }
1497 
1498 /*
1499  * Process a SPD_ALGLIST request. The caller expects separate alg entries
1500  * for AH authentication, ESP authentication, and ESP encryption.
1501  * The same distinction is then used when setting the min and max key
1502  * sizes when defining policies.
1503  */
1504 
1505 #define	SPDSOCK_AH_AUTH		0
1506 #define	SPDSOCK_ESP_AUTH	1
1507 #define	SPDSOCK_ESP_ENCR	2
1508 #define	SPDSOCK_NTYPES		3
1509 
1510 static const uint_t algattr[SPDSOCK_NTYPES] = {
1511 	SPD_ATTR_AH_AUTH,
1512 	SPD_ATTR_ESP_AUTH,
1513 	SPD_ATTR_ESP_ENCR
1514 };
1515 static const uint_t minbitsattr[SPDSOCK_NTYPES] = {
1516 	SPD_ATTR_AH_MINBITS,
1517 	SPD_ATTR_ESPA_MINBITS,
1518 	SPD_ATTR_ENCR_MINBITS
1519 };
1520 static const uint_t maxbitsattr[SPDSOCK_NTYPES] = {
1521 	SPD_ATTR_AH_MAXBITS,
1522 	SPD_ATTR_ESPA_MAXBITS,
1523 	SPD_ATTR_ENCR_MAXBITS
1524 };
1525 static const uint_t defbitsattr[SPDSOCK_NTYPES] = {
1526 	SPD_ATTR_AH_DEFBITS,
1527 	SPD_ATTR_ESPA_DEFBITS,
1528 	SPD_ATTR_ENCR_DEFBITS
1529 };
1530 static const uint_t incrbitsattr[SPDSOCK_NTYPES] = {
1531 	SPD_ATTR_AH_INCRBITS,
1532 	SPD_ATTR_ESPA_INCRBITS,
1533 	SPD_ATTR_ENCR_INCRBITS
1534 };
1535 
1536 #define	ATTRPERALG	6	/* fixed attributes per algs */
1537 
1538 void
1539 spdsock_alglist(queue_t *q, mblk_t *mp)
1540 {
1541 	uint_t algtype;
1542 	uint_t algidx;
1543 	uint_t algcount;
1544 	uint_t size;
1545 	mblk_t *m;
1546 	uint8_t *cur;
1547 	spd_msg_t *msg;
1548 	struct spd_ext_actions *act;
1549 	struct spd_attribute *attr;
1550 
1551 	mutex_enter(&alg_lock);
1552 
1553 	/*
1554 	 * The SPD client expects to receive separate entries for
1555 	 * AH authentication and ESP authentication supported algorithms.
1556 	 *
1557 	 * Don't return the "any" algorithms, if defined, as no
1558 	 * kernel policies can be set for these algorithms.
1559 	 */
1560 	algcount = 2 * ipsec_nalgs[IPSEC_ALG_AUTH] +
1561 	    ipsec_nalgs[IPSEC_ALG_ENCR];
1562 
1563 	if (ipsec_alglists[IPSEC_ALG_AUTH][SADB_AALG_NONE] != NULL)
1564 		algcount--;
1565 	if (ipsec_alglists[IPSEC_ALG_ENCR][SADB_EALG_NONE] != NULL)
1566 		algcount--;
1567 
1568 	/*
1569 	 * For each algorithm, we encode:
1570 	 * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
1571 	 */
1572 
1573 	size = sizeof (spd_msg_t) + sizeof (struct spd_ext_actions) +
1574 	    ATTRPERALG * sizeof (struct spd_attribute) * algcount;
1575 
1576 	ASSERT(ALIGNED64(size));
1577 
1578 	m = allocb(size, BPRI_HI);
1579 	if (m == NULL) {
1580 		mutex_exit(&alg_lock);
1581 		spdsock_error(q, mp, ENOMEM, 0);
1582 		return;
1583 	}
1584 
1585 	m->b_wptr = m->b_rptr + size;
1586 	cur = m->b_rptr;
1587 
1588 	msg = (spd_msg_t *)cur;
1589 	bcopy(mp->b_rptr, cur, sizeof (*msg));
1590 
1591 	msg->spd_msg_len = SPD_8TO64(size);
1592 	msg->spd_msg_errno = 0;
1593 	msg->spd_msg_diagnostic = 0;
1594 
1595 	cur += sizeof (*msg);
1596 
1597 	act = (struct spd_ext_actions *)cur;
1598 	cur += sizeof (*act);
1599 
1600 	act->spd_actions_len = SPD_8TO64(size - sizeof (spd_msg_t));
1601 	act->spd_actions_exttype = SPD_EXT_ACTION;
1602 	act->spd_actions_count = algcount;
1603 	act->spd_actions_reserved = 0;
1604 
1605 	attr = (struct spd_attribute *)cur;
1606 
1607 #define	EMIT(tag, value) {					\
1608 		attr->spd_attr_tag = (tag); 			\
1609 		attr->spd_attr_value = (value); 		\
1610 		attr++;			  			\
1611 	}
1612 
1613 	/*
1614 	 * If you change the number of EMIT's here, change
1615 	 * ATTRPERALG above to match
1616 	 */
1617 #define	EMITALGATTRS(_type) {					\
1618 		EMIT(algattr[_type], algid); 		/* 1 */	\
1619 		EMIT(minbitsattr[_type], minbits);	/* 2 */	\
1620 		EMIT(maxbitsattr[_type], maxbits);	/* 3 */	\
1621 		EMIT(defbitsattr[_type], defbits);	/* 4 */	\
1622 		EMIT(incrbitsattr[_type], incr);	/* 5 */	\
1623 		EMIT(SPD_ATTR_NEXT, 0);			/* 6 */	\
1624 	}
1625 
1626 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
1627 		for (algidx = 0; algidx < ipsec_nalgs[algtype]; algidx++) {
1628 			int algid = ipsec_sortlist[algtype][algidx];
1629 			ipsec_alginfo_t *alg = ipsec_alglists[algtype][algid];
1630 			uint_t minbits = alg->alg_minbits;
1631 			uint_t maxbits = alg->alg_maxbits;
1632 			uint_t defbits = alg->alg_default_bits;
1633 			uint_t incr = alg->alg_increment;
1634 
1635 			if (algtype == IPSEC_ALG_AUTH) {
1636 				if (algid == SADB_AALG_NONE)
1637 					continue;
1638 				EMITALGATTRS(SPDSOCK_AH_AUTH);
1639 				EMITALGATTRS(SPDSOCK_ESP_AUTH);
1640 			} else {
1641 				if (algid == SADB_EALG_NONE)
1642 					continue;
1643 				ASSERT(algtype == IPSEC_ALG_ENCR);
1644 				EMITALGATTRS(SPDSOCK_ESP_ENCR);
1645 			}
1646 		}
1647 	}
1648 
1649 	mutex_exit(&alg_lock);
1650 
1651 #undef EMITALGATTRS
1652 #undef EMIT
1653 #undef ATTRPERALG
1654 
1655 	attr--;
1656 	attr->spd_attr_tag = SPD_ATTR_END;
1657 
1658 	freemsg(mp);
1659 	qreply(q, m);
1660 }
1661 
1662 /*
1663  * Process a SPD_DUMPALGS request.
1664  */
1665 
1666 #define	ATTRPERALG	7	/* fixed attributes per algs */
1667 
1668 void
1669 spdsock_dumpalgs(queue_t *q, mblk_t *mp)
1670 {
1671 	uint_t algtype;
1672 	uint_t algidx;
1673 	uint_t size;
1674 	mblk_t *m;
1675 	uint8_t *cur;
1676 	spd_msg_t *msg;
1677 	struct spd_ext_actions *act;
1678 	struct spd_attribute *attr;
1679 	ipsec_alginfo_t *alg;
1680 	uint_t algid;
1681 	uint_t i;
1682 	uint_t alg_size;
1683 
1684 	mutex_enter(&alg_lock);
1685 
1686 	/*
1687 	 * For each algorithm, we encode:
1688 	 * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
1689 	 *
1690 	 * ALG_ID / ALG_PROTO / ALG_INCRBITS / ALG_NKEYSIZES / ALG_KEYSIZE*
1691 	 * ALG_NBLOCKSIZES / ALG_BLOCKSIZE* / ALG_MECHNAME / {END, NEXT}
1692 	 */
1693 
1694 	/*
1695 	 * Compute the size of the SPD message.
1696 	 */
1697 	size = sizeof (spd_msg_t) + sizeof (struct spd_ext_actions);
1698 
1699 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
1700 		for (algidx = 0; algidx < ipsec_nalgs[algtype]; algidx++) {
1701 			algid = ipsec_sortlist[algtype][algidx];
1702 			alg = ipsec_alglists[algtype][algid];
1703 			alg_size = sizeof (struct spd_attribute) *
1704 			    (ATTRPERALG + alg->alg_nkey_sizes +
1705 			    alg->alg_nblock_sizes) + CRYPTO_MAX_MECH_NAME;
1706 			size += alg_size;
1707 		}
1708 	}
1709 
1710 	ASSERT(ALIGNED64(size));
1711 
1712 	m = allocb(size, BPRI_HI);
1713 	if (m == NULL) {
1714 		mutex_exit(&alg_lock);
1715 		spdsock_error(q, mp, ENOMEM, 0);
1716 		return;
1717 	}
1718 
1719 	m->b_wptr = m->b_rptr + size;
1720 	cur = m->b_rptr;
1721 
1722 	msg = (spd_msg_t *)cur;
1723 	bcopy(mp->b_rptr, cur, sizeof (*msg));
1724 
1725 	msg->spd_msg_len = SPD_8TO64(size);
1726 	msg->spd_msg_errno = 0;
1727 	msg->spd_msg_diagnostic = 0;
1728 
1729 	cur += sizeof (*msg);
1730 
1731 	act = (struct spd_ext_actions *)cur;
1732 	cur += sizeof (*act);
1733 
1734 	act->spd_actions_len = SPD_8TO64(size - sizeof (spd_msg_t));
1735 	act->spd_actions_exttype = SPD_EXT_ACTION;
1736 	act->spd_actions_count = ipsec_nalgs[IPSEC_ALG_AUTH] +
1737 	    ipsec_nalgs[IPSEC_ALG_ENCR];
1738 	act->spd_actions_reserved = 0;
1739 
1740 	attr = (struct spd_attribute *)cur;
1741 
1742 #define	EMIT(tag, value) {					\
1743 		attr->spd_attr_tag = (tag); 			\
1744 		attr->spd_attr_value = (value); 		\
1745 		attr++;			  			\
1746 	}
1747 
1748 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
1749 		for (algidx = 0; algidx < ipsec_nalgs[algtype]; algidx++) {
1750 
1751 			algid = ipsec_sortlist[algtype][algidx];
1752 			alg = ipsec_alglists[algtype][algid];
1753 
1754 			/*
1755 			 * If you change the number of EMIT's here, change
1756 			 * ATTRPERALG above to match
1757 			 */
1758 			EMIT(SPD_ATTR_ALG_ID, algid);
1759 			EMIT(SPD_ATTR_ALG_PROTO, algproto[algtype]);
1760 			EMIT(SPD_ATTR_ALG_INCRBITS, alg->alg_increment);
1761 
1762 			EMIT(SPD_ATTR_ALG_NKEYSIZES, alg->alg_nkey_sizes);
1763 			for (i = 0; i < alg->alg_nkey_sizes; i++)
1764 				EMIT(SPD_ATTR_ALG_KEYSIZE,
1765 				    alg->alg_key_sizes[i]);
1766 
1767 			EMIT(SPD_ATTR_ALG_NBLOCKSIZES, alg->alg_nblock_sizes);
1768 			for (i = 0; i < alg->alg_nblock_sizes; i++)
1769 				EMIT(SPD_ATTR_ALG_BLOCKSIZE,
1770 				    alg->alg_block_sizes[i]);
1771 
1772 			EMIT(SPD_ATTR_ALG_MECHNAME, CRYPTO_MAX_MECH_NAME);
1773 			bcopy(alg->alg_mech_name, attr, CRYPTO_MAX_MECH_NAME);
1774 			attr = (struct spd_attribute *)((char *)attr +
1775 			    CRYPTO_MAX_MECH_NAME);
1776 
1777 			EMIT(SPD_ATTR_NEXT, 0);
1778 		}
1779 	}
1780 
1781 	mutex_exit(&alg_lock);
1782 
1783 #undef EMITALGATTRS
1784 #undef EMIT
1785 #undef ATTRPERALG
1786 
1787 	attr--;
1788 	attr->spd_attr_tag = SPD_ATTR_END;
1789 
1790 	freemsg(mp);
1791 	qreply(q, m);
1792 }
1793 
1794 /*
1795  * Do the actual work of processing an SPD_UPDATEALGS request. Can
1796  * be invoked either once IPsec is loaded on a cached request, or
1797  * when a request is received while IPsec is loaded.
1798  */
1799 static void
1800 spdsock_do_updatealg(spd_ext_t *extv[], int *diag)
1801 {
1802 	struct spd_ext_actions *actp;
1803 	struct spd_attribute *attr, *endattr;
1804 	uint64_t *start, *end;
1805 	ipsec_alginfo_t *alg = NULL;
1806 	ipsec_algtype_t alg_type = 0;
1807 	boolean_t skip_alg = B_TRUE, doing_proto = B_FALSE;
1808 	uint_t i, cur_key, cur_block, algid;
1809 
1810 	*diag = -1;
1811 	ASSERT(MUTEX_HELD(&spdsock_alg_lock));
1812 
1813 	/* parse the message, building the list of algorithms */
1814 
1815 	actp = (struct spd_ext_actions *)extv[SPD_EXT_ACTION];
1816 	if (actp == NULL) {
1817 		*diag = SPD_DIAGNOSTIC_NO_ACTION_EXT;
1818 		return;
1819 	}
1820 
1821 	start = (uint64_t *)actp;
1822 	end = (start + actp->spd_actions_len);
1823 	endattr = (struct spd_attribute *)end;
1824 	attr = (struct spd_attribute *)&actp[1];
1825 
1826 	bzero(spdsock_algs, IPSEC_NALGTYPES * IPSEC_MAX_ALGS *
1827 	    sizeof (ipsec_alginfo_t *));
1828 
1829 	alg = kmem_zalloc(sizeof (*alg), KM_SLEEP);
1830 
1831 #define	ALG_KEY_SIZES(a)   (((a)->alg_nkey_sizes + 1) * sizeof (uint16_t))
1832 #define	ALG_BLOCK_SIZES(a) (((a)->alg_nblock_sizes + 1) * sizeof (uint16_t))
1833 
1834 	while (attr < endattr) {
1835 		switch (attr->spd_attr_tag) {
1836 		case SPD_ATTR_NOP:
1837 		case SPD_ATTR_EMPTY:
1838 			break;
1839 		case SPD_ATTR_END:
1840 			attr = endattr;
1841 			/* FALLTHRU */
1842 		case SPD_ATTR_NEXT:
1843 			if (doing_proto) {
1844 				doing_proto = B_FALSE;
1845 				break;
1846 			}
1847 			if (skip_alg) {
1848 				ipsec_alg_free(alg);
1849 			} else {
1850 				ipsec_alg_free(
1851 				    spdsock_algs[alg_type][alg->alg_id]);
1852 				spdsock_algs[alg_type][alg->alg_id] = alg;
1853 			}
1854 			alg = kmem_zalloc(sizeof (*alg), KM_SLEEP);
1855 			break;
1856 
1857 		case SPD_ATTR_ALG_ID:
1858 			if (attr->spd_attr_value >= IPSEC_MAX_ALGS) {
1859 				ss1dbg(("spdsock_do_updatealg: "
1860 				    "invalid alg id %d\n",
1861 				    attr->spd_attr_value));
1862 				*diag = SPD_DIAGNOSTIC_ALG_ID_RANGE;
1863 				goto bail;
1864 			}
1865 			alg->alg_id = attr->spd_attr_value;
1866 			break;
1867 
1868 		case SPD_ATTR_ALG_PROTO:
1869 			/* find the alg type */
1870 			for (i = 0; i < NALGPROTOS; i++)
1871 				if (algproto[i] == attr->spd_attr_value)
1872 					break;
1873 			skip_alg = (i == NALGPROTOS);
1874 			if (!skip_alg)
1875 				alg_type = i;
1876 			break;
1877 
1878 		case SPD_ATTR_ALG_INCRBITS:
1879 			alg->alg_increment = attr->spd_attr_value;
1880 			break;
1881 
1882 		case SPD_ATTR_ALG_NKEYSIZES:
1883 			if (alg->alg_key_sizes != NULL) {
1884 				kmem_free(alg->alg_key_sizes,
1885 				    ALG_KEY_SIZES(alg));
1886 			}
1887 			alg->alg_nkey_sizes = attr->spd_attr_value;
1888 			/*
1889 			 * Allocate room for the trailing zero key size
1890 			 * value as well.
1891 			 */
1892 			alg->alg_key_sizes = kmem_zalloc(ALG_KEY_SIZES(alg),
1893 			    KM_SLEEP);
1894 			cur_key = 0;
1895 			break;
1896 
1897 		case SPD_ATTR_ALG_KEYSIZE:
1898 			if (alg->alg_key_sizes == NULL ||
1899 			    cur_key >= alg->alg_nkey_sizes) {
1900 				ss1dbg(("spdsock_do_updatealg: "
1901 					"too many key sizes\n"));
1902 				*diag = SPD_DIAGNOSTIC_ALG_NUM_KEY_SIZES;
1903 				goto bail;
1904 			}
1905 			alg->alg_key_sizes[cur_key++] = attr->spd_attr_value;
1906 			break;
1907 
1908 		case SPD_ATTR_ALG_NBLOCKSIZES:
1909 			if (alg->alg_block_sizes != NULL) {
1910 				kmem_free(alg->alg_block_sizes,
1911 				    ALG_BLOCK_SIZES(alg));
1912 			}
1913 			alg->alg_nblock_sizes = attr->spd_attr_value;
1914 			/*
1915 			 * Allocate room for the trailing zero block size
1916 			 * value as well.
1917 			 */
1918 			alg->alg_block_sizes = kmem_zalloc(ALG_BLOCK_SIZES(alg),
1919 			    KM_SLEEP);
1920 			cur_block = 0;
1921 			break;
1922 
1923 		case SPD_ATTR_ALG_BLOCKSIZE:
1924 			if (alg->alg_block_sizes == NULL ||
1925 			    cur_block >= alg->alg_nblock_sizes) {
1926 				ss1dbg(("spdsock_do_updatealg: "
1927 					"too many block sizes\n"));
1928 				*diag = SPD_DIAGNOSTIC_ALG_NUM_BLOCK_SIZES;
1929 				goto bail;
1930 			}
1931 			alg->alg_block_sizes[cur_block++] =
1932 			    attr->spd_attr_value;
1933 			break;
1934 
1935 		case SPD_ATTR_ALG_MECHNAME: {
1936 			char *mech_name;
1937 
1938 			if (attr->spd_attr_value > CRYPTO_MAX_MECH_NAME) {
1939 				ss1dbg(("spdsock_do_updatealg: "
1940 					"mech name too long\n"));
1941 				*diag = SPD_DIAGNOSTIC_ALG_MECH_NAME_LEN;
1942 				goto bail;
1943 			}
1944 			mech_name = (char *)(attr + 1);
1945 			bcopy(mech_name, alg->alg_mech_name,
1946 			    attr->spd_attr_value);
1947 			alg->alg_mech_name[CRYPTO_MAX_MECH_NAME-1] = '\0';
1948 			attr = (struct spd_attribute *)((char *)attr +
1949 			    attr->spd_attr_value);
1950 			break;
1951 		}
1952 
1953 		case SPD_ATTR_PROTO_ID:
1954 			doing_proto = B_TRUE;
1955 			for (i = 0; i < NALGPROTOS; i++) {
1956 				if (algproto[i] == attr->spd_attr_value) {
1957 					alg_type = i;
1958 					break;
1959 				}
1960 			}
1961 			break;
1962 
1963 		case SPD_ATTR_PROTO_EXEC_MODE:
1964 			if (!doing_proto)
1965 				break;
1966 			for (i = 0; i < NEXECMODES; i++) {
1967 				if (execmodes[i] == attr->spd_attr_value) {
1968 					spdsock_algs_exec_mode[alg_type] = i;
1969 					break;
1970 				}
1971 			}
1972 			break;
1973 		}
1974 		attr++;
1975 	}
1976 
1977 #undef	ALG_KEY_SIZES
1978 #undef	ALG_BLOCK_SIZES
1979 
1980 	/* update the algorithm tables */
1981 	spdsock_merge_algs();
1982 bail:
1983 	/* cleanup */
1984 	ipsec_alg_free(alg);
1985 	for (alg_type = 0; alg_type < IPSEC_NALGTYPES; alg_type++)
1986 		for (algid = 0; algid < IPSEC_MAX_ALGS; algid++)
1987 			if (spdsock_algs[alg_type][algid] != NULL)
1988 				ipsec_alg_free(spdsock_algs[alg_type][algid]);
1989 }
1990 
1991 /*
1992  * Process an SPD_UPDATEALGS request. If IPsec is not loaded, queue
1993  * the request until IPsec loads. If IPsec is loaded, act on it
1994  * immediately.
1995  */
1996 
1997 static void
1998 spdsock_updatealg(queue_t *q, mblk_t *mp, spd_ext_t *extv[])
1999 {
2000 	if (!ipsec_loaded()) {
2001 		/*
2002 		 * IPsec is not loaded, save request and return nicely,
2003 		 * the message will be processed once IPsec loads.
2004 		 */
2005 		mblk_t *new_mp;
2006 
2007 		/* last update message wins */
2008 		if ((new_mp = copymsg(mp)) == NULL) {
2009 			spdsock_error(q, mp, ENOMEM, 0);
2010 			return;
2011 		}
2012 		mutex_enter(&spdsock_alg_lock);
2013 		bcopy(extv, spdsock_extv_algs,
2014 		    sizeof (spd_ext_t *) * (SPD_EXT_MAX + 1));
2015 		if (spdsock_mp_algs != NULL)
2016 			freemsg(spdsock_mp_algs);
2017 		spdsock_mp_algs = mp;
2018 		spdsock_algs_pending = B_TRUE;
2019 		mutex_exit(&spdsock_alg_lock);
2020 
2021 		spd_echo(q, new_mp);
2022 	} else {
2023 		/*
2024 		 * IPsec is loaded, act on the message immediately.
2025 		 */
2026 		int diag;
2027 
2028 		mutex_enter(&spdsock_alg_lock);
2029 		spdsock_do_updatealg(extv, &diag);
2030 		mutex_exit(&spdsock_alg_lock);
2031 		if (diag == -1)
2032 			spd_echo(q, mp);
2033 		else
2034 			spdsock_diag(q, mp, diag);
2035 	}
2036 }
2037 
2038 static void
2039 spdsock_parse(queue_t *q, mblk_t *mp)
2040 {
2041 	spd_msg_t *spmsg;
2042 	spd_ext_t *extv[SPD_EXT_MAX + 1];
2043 	uint_t msgsize;
2044 	ipsec_policy_head_t *iph;
2045 
2046 	/* Make sure nothing's below me. */
2047 	ASSERT(WR(q)->q_next == NULL);
2048 
2049 	spmsg = (spd_msg_t *)mp->b_rptr;
2050 
2051 	msgsize = SPD_64TO8(spmsg->spd_msg_len);
2052 
2053 	if (msgdsize(mp) != msgsize) {
2054 		/*
2055 		 * Message len incorrect w.r.t. actual size.  Send an error
2056 		 * (EMSGSIZE).	It may be necessary to massage things a
2057 		 * bit.	 For example, if the spd_msg_type is hosed,
2058 		 * I need to set it to SPD_RESERVED to get delivery to
2059 		 * do the right thing.	Then again, maybe just letting
2060 		 * the error delivery do the right thing.
2061 		 */
2062 		ss2dbg(("mblk (%lu) and base (%d) message sizes don't jibe.\n",
2063 		    msgdsize(mp), msgsize));
2064 		spdsock_error(q, mp, EMSGSIZE, SPD_DIAGNOSTIC_NONE);
2065 		return;
2066 	}
2067 
2068 	if (msgsize > (uint_t)(mp->b_wptr - mp->b_rptr)) {
2069 
2070 		/* Get all message into one mblk. */
2071 		if (pullupmsg(mp, -1) == 0) {
2072 			/*
2073 			 * Something screwy happened.
2074 			 */
2075 			ss3dbg(("spdsock_parse: pullupmsg() failed.\n"));
2076 			return;
2077 		} else {
2078 			spmsg = (spd_msg_t *)mp->b_rptr;
2079 		}
2080 	}
2081 
2082 	switch (spdsock_get_ext(extv, spmsg, msgsize)) {
2083 	case KGE_DUP:
2084 		/* Handle duplicate extension. */
2085 		ss1dbg(("Got duplicate extension of type %d.\n",
2086 		    extv[0]->spd_ext_type));
2087 		spdsock_diag(q, mp, dup_ext_diag[extv[0]->spd_ext_type]);
2088 		return;
2089 	case KGE_UNK:
2090 		/* Handle unknown extension. */
2091 		ss1dbg(("Got unknown extension of type %d.\n",
2092 		    extv[0]->spd_ext_type));
2093 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_UNKNOWN_EXT);
2094 		return;
2095 	case KGE_LEN:
2096 		/* Length error. */
2097 		ss1dbg(("Length %d on extension type %d overrun or 0.\n",
2098 		    extv[0]->spd_ext_len, extv[0]->spd_ext_type));
2099 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_BAD_EXTLEN);
2100 		return;
2101 	case KGE_CHK:
2102 		/* Reality check failed. */
2103 		ss1dbg(("Reality check failed on extension type %d.\n",
2104 		    extv[0]->spd_ext_type));
2105 		spdsock_diag(q, mp, bad_ext_diag[extv[0]->spd_ext_type]);
2106 		return;
2107 	default:
2108 		/* Default case is no errors. */
2109 		break;
2110 	}
2111 
2112 	/*
2113 	 * Which rule set are we operating on today?
2114 	 */
2115 
2116 	switch (spmsg->spd_msg_spdid) {
2117 	case SPD_ACTIVE:
2118 		iph = ipsec_system_policy();
2119 		break;
2120 
2121 	case SPD_STANDBY:
2122 		iph = ipsec_inactive_policy();
2123 		break;
2124 
2125 	default:
2126 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_BAD_SPDID);
2127 		return;
2128 	}
2129 
2130 	/*
2131 	 * Special-case SPD_UPDATEALGS so as not to load IPsec.
2132 	 */
2133 	if (!ipsec_loaded() && spmsg->spd_msg_type != SPD_UPDATEALGS) {
2134 		spdsock_t *ss = (spdsock_t *)q->q_ptr;
2135 
2136 		ASSERT(ss != NULL);
2137 		ipsec_loader_loadnow();
2138 		ss->spdsock_timeout_arg = mp;
2139 		ss->spdsock_timeout = qtimeout(q, spdsock_loadcheck,
2140 		    q, LOADCHECK_INTERVAL);
2141 		return;
2142 	}
2143 
2144 	switch (spmsg->spd_msg_type) {
2145 	case SPD_UPDATEALGS:
2146 		spdsock_updatealg(q, mp, extv);
2147 		return;
2148 	case SPD_FLUSH:
2149 		spdsock_flush(q, iph, mp, extv);
2150 		return;
2151 
2152 	case SPD_ADDRULE:
2153 		spdsock_addrule(q, iph, mp, extv);
2154 		return;
2155 
2156 	case SPD_DELETERULE:
2157 		spdsock_deleterule(q, iph, mp, extv);
2158 		return;
2159 
2160 	case SPD_FLIP:
2161 		spdsock_flip(q, mp);
2162 		return;
2163 
2164 	case SPD_LOOKUP:
2165 		spdsock_lookup(q, iph, mp, extv);
2166 		return;
2167 
2168 	case SPD_DUMP:
2169 		spdsock_dump(q, iph, mp, extv);
2170 		return;
2171 
2172 	case SPD_CLONE:
2173 		spdsock_clone(q, mp);
2174 		return;
2175 
2176 	case SPD_ALGLIST:
2177 		spdsock_alglist(q, mp);
2178 		return;
2179 
2180 	case SPD_DUMPALGS:
2181 		spdsock_dumpalgs(q, mp);
2182 		return;
2183 
2184 	default:
2185 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_BAD_MSG_TYPE);
2186 		return;
2187 	}
2188 }
2189 
2190 /*
2191  * If an algorithm mapping was received before IPsec was loaded, process it.
2192  * Called from the IPsec loader.
2193  */
2194 void
2195 spdsock_update_pending_algs(void)
2196 {
2197 	mutex_enter(&spdsock_alg_lock);
2198 	if (spdsock_algs_pending) {
2199 		int diag;
2200 		spdsock_do_updatealg(spdsock_extv_algs, &diag);
2201 		spdsock_algs_pending = B_FALSE;
2202 	}
2203 	mutex_exit(&spdsock_alg_lock);
2204 }
2205 
2206 static void
2207 spdsock_loadcheck(void *arg)
2208 {
2209 	queue_t *q = (queue_t *)arg;
2210 	spdsock_t *ss = (spdsock_t *)q->q_ptr;
2211 	mblk_t *mp;
2212 
2213 	ASSERT(ss != NULL);
2214 
2215 	ss->spdsock_timeout = 0;
2216 	mp = ss->spdsock_timeout_arg;
2217 	ASSERT(mp != NULL);
2218 	ss->spdsock_timeout_arg = NULL;
2219 	if (ipsec_failed())
2220 		spdsock_error(q, mp, EPROTONOSUPPORT, 0);
2221 	else
2222 		spdsock_parse(q, mp);
2223 }
2224 
2225 /*
2226  * Copy relevant state bits.
2227  */
2228 static void
2229 spdsock_copy_info(struct T_info_ack *tap, spdsock_t *ss)
2230 {
2231 	*tap = spdsock_g_t_info_ack;
2232 	tap->CURRENT_state = ss->spdsock_state;
2233 	tap->OPT_size = spdsock_max_optsize;
2234 }
2235 
2236 /*
2237  * This routine responds to T_CAPABILITY_REQ messages.  It is called by
2238  * spdsock_wput.  Much of the T_CAPABILITY_ACK information is copied from
2239  * spdsock_g_t_info_ack.  The current state of the stream is copied from
2240  * spdsock_state.
2241  */
2242 static void
2243 spdsock_capability_req(queue_t *q, mblk_t *mp)
2244 {
2245 	spdsock_t *ss = (spdsock_t *)q->q_ptr;
2246 	t_uscalar_t cap_bits1;
2247 	struct T_capability_ack	*tcap;
2248 
2249 	cap_bits1 = ((struct T_capability_req *)mp->b_rptr)->CAP_bits1;
2250 
2251 	mp = tpi_ack_alloc(mp, sizeof (struct T_capability_ack),
2252 		mp->b_datap->db_type, T_CAPABILITY_ACK);
2253 	if (mp == NULL)
2254 		return;
2255 
2256 	tcap = (struct T_capability_ack *)mp->b_rptr;
2257 	tcap->CAP_bits1 = 0;
2258 
2259 	if (cap_bits1 & TC1_INFO) {
2260 		spdsock_copy_info(&tcap->INFO_ack, ss);
2261 		tcap->CAP_bits1 |= TC1_INFO;
2262 	}
2263 
2264 	qreply(q, mp);
2265 }
2266 
2267 /*
2268  * This routine responds to T_INFO_REQ messages. It is called by
2269  * spdsock_wput_other.
2270  * Most of the T_INFO_ACK information is copied from spdsock_g_t_info_ack.
2271  * The current state of the stream is copied from spdsock_state.
2272  */
2273 static void
2274 spdsock_info_req(q, mp)
2275 	queue_t	*q;
2276 	mblk_t	*mp;
2277 {
2278 	mp = tpi_ack_alloc(mp, sizeof (struct T_info_ack), M_PCPROTO,
2279 	    T_INFO_ACK);
2280 	if (mp == NULL)
2281 		return;
2282 	spdsock_copy_info((struct T_info_ack *)mp->b_rptr,
2283 	    (spdsock_t *)q->q_ptr);
2284 	qreply(q, mp);
2285 }
2286 
2287 /*
2288  * spdsock_err_ack. This routine creates a
2289  * T_ERROR_ACK message and passes it
2290  * upstream.
2291  */
2292 static void
2293 spdsock_err_ack(q, mp, t_error, sys_error)
2294 	queue_t	*q;
2295 	mblk_t	*mp;
2296 	int	t_error;
2297 	int	sys_error;
2298 {
2299 	if ((mp = mi_tpi_err_ack_alloc(mp, t_error, sys_error)) != NULL)
2300 		qreply(q, mp);
2301 }
2302 
2303 /*
2304  * This routine retrieves the current status of socket options.
2305  * It returns the size of the option retrieved.
2306  */
2307 /* ARGSUSED */
2308 int
2309 spdsock_opt_get(queue_t *q, int level, int name, uchar_t *ptr)
2310 {
2311 	int *i1 = (int *)ptr;
2312 
2313 	switch (level) {
2314 	case SOL_SOCKET:
2315 		switch (name) {
2316 		case SO_TYPE:
2317 			*i1 = SOCK_RAW;
2318 			break;
2319 		/*
2320 		 * The following two items can be manipulated,
2321 		 * but changing them should do nothing.
2322 		 */
2323 		case SO_SNDBUF:
2324 			*i1 = (int)q->q_hiwat;
2325 			break;
2326 		case SO_RCVBUF:
2327 			*i1 = (int)(RD(q)->q_hiwat);
2328 			break;
2329 		}
2330 		break;
2331 	default:
2332 		return (0);
2333 	}
2334 	return (sizeof (int));
2335 }
2336 
2337 /*
2338  * This routine sets socket options.
2339  */
2340 /* ARGSUSED */
2341 int
2342 spdsock_opt_set(queue_t *q, uint_t mgmt_flags, int level, int name,
2343     uint_t inlen, uchar_t *invalp, uint_t *outlenp, uchar_t *outvalp,
2344     void *thisdg_attrs, cred_t *cr, mblk_t *mblk)
2345 {
2346 	int *i1 = (int *)invalp;
2347 
2348 	switch (level) {
2349 	case SOL_SOCKET:
2350 		switch (name) {
2351 		case SO_SNDBUF:
2352 			if (*i1 > spdsock_max_buf)
2353 				return (ENOBUFS);
2354 			q->q_hiwat = *i1;
2355 			break;
2356 		case SO_RCVBUF:
2357 			if (*i1 > spdsock_max_buf)
2358 				return (ENOBUFS);
2359 			RD(q)->q_hiwat = *i1;
2360 			(void) mi_set_sth_hiwat(RD(q), *i1);
2361 			break;
2362 		}
2363 		break;
2364 	}
2365 	return (0);
2366 }
2367 
2368 
2369 /*
2370  * Handle STREAMS messages.
2371  */
2372 static void
2373 spdsock_wput_other(queue_t *q, mblk_t *mp)
2374 {
2375 	struct iocblk *iocp;
2376 	int error;
2377 
2378 	switch (mp->b_datap->db_type) {
2379 	case M_PROTO:
2380 	case M_PCPROTO:
2381 		if ((mp->b_wptr - mp->b_rptr) < sizeof (long)) {
2382 			ss3dbg((
2383 			    "spdsock_wput_other: Not big enough M_PROTO\n"));
2384 			freemsg(mp);
2385 			return;
2386 		}
2387 		switch (((union T_primitives *)mp->b_rptr)->type) {
2388 		case T_CAPABILITY_REQ:
2389 			spdsock_capability_req(q, mp);
2390 			return;
2391 		case T_INFO_REQ:
2392 			spdsock_info_req(q, mp);
2393 			return;
2394 		case T_SVR4_OPTMGMT_REQ:
2395 			(void) svr4_optcom_req(q, mp, DB_CREDDEF(mp, kcred),
2396 			    &spdsock_opt_obj);
2397 			return;
2398 		case T_OPTMGMT_REQ:
2399 			(void) tpi_optcom_req(q, mp, DB_CREDDEF(mp, kcred),
2400 			    &spdsock_opt_obj);
2401 			return;
2402 		case T_DATA_REQ:
2403 		case T_EXDATA_REQ:
2404 		case T_ORDREL_REQ:
2405 			/* Illegal for spdsock. */
2406 			freemsg(mp);
2407 			(void) putnextctl1(RD(q), M_ERROR, EPROTO);
2408 			return;
2409 		default:
2410 			/* Not supported by spdsock. */
2411 			spdsock_err_ack(q, mp, TNOTSUPPORT, 0);
2412 			return;
2413 		}
2414 	case M_IOCTL:
2415 		iocp = (struct iocblk *)mp->b_rptr;
2416 		error = EINVAL;
2417 
2418 		switch (iocp->ioc_cmd) {
2419 		case ND_SET:
2420 		case ND_GET:
2421 			if (nd_getset(q, spdsock_g_nd, mp)) {
2422 				qreply(q, mp);
2423 				return;
2424 			} else
2425 				error = ENOENT;
2426 			/* FALLTHRU */
2427 		default:
2428 			miocnak(q, mp, 0, error);
2429 			return;
2430 		}
2431 	case M_FLUSH:
2432 		if (*mp->b_rptr & FLUSHW) {
2433 			flushq(q, FLUSHALL);
2434 			*mp->b_rptr &= ~FLUSHW;
2435 		}
2436 		if (*mp->b_rptr & FLUSHR) {
2437 			qreply(q, mp);
2438 			return;
2439 		}
2440 		/* Else FALLTHRU */
2441 	}
2442 
2443 	/* If fell through, just black-hole the message. */
2444 	freemsg(mp);
2445 }
2446 
2447 static void
2448 spdsock_wput(queue_t *q, mblk_t *mp)
2449 {
2450 	uint8_t *rptr = mp->b_rptr;
2451 	mblk_t *mp1;
2452 	spdsock_t *ss = (spdsock_t *)q->q_ptr;
2453 
2454 	/*
2455 	 * If we're dumping, defer processing other messages until the
2456 	 * dump completes.
2457 	 */
2458 	if (ss->spdsock_dump_req != NULL) {
2459 		if (!putq(q, mp))
2460 			freemsg(mp);
2461 		return;
2462 	}
2463 
2464 	switch (mp->b_datap->db_type) {
2465 	case M_DATA:
2466 		/*
2467 		 * Silently discard.
2468 		 */
2469 		ss2dbg(("raw M_DATA in spdsock.\n"));
2470 		freemsg(mp);
2471 		return;
2472 	case M_PROTO:
2473 	case M_PCPROTO:
2474 		if ((mp->b_wptr - rptr) >= sizeof (struct T_data_req)) {
2475 			if (((union T_primitives *)rptr)->type == T_DATA_REQ) {
2476 				if ((mp1 = mp->b_cont) == NULL) {
2477 					/* No data after T_DATA_REQ. */
2478 					ss2dbg(("No data after DATA_REQ.\n"));
2479 					freemsg(mp);
2480 					return;
2481 				}
2482 				freeb(mp);
2483 				mp = mp1;
2484 				ss2dbg(("T_DATA_REQ\n"));
2485 				break;	/* Out of switch. */
2486 			}
2487 		}
2488 		/* FALLTHRU */
2489 	default:
2490 		ss3dbg(("In default wput case (%d %d).\n",
2491 		    mp->b_datap->db_type, ((union T_primitives *)rptr)->type));
2492 		spdsock_wput_other(q, mp);
2493 		return;
2494 	}
2495 
2496 	/* I now have a PF_POLICY message in an M_DATA block. */
2497 	spdsock_parse(q, mp);
2498 }
2499 
2500 /*
2501  * Device open procedure, called when new queue pair created.
2502  * We are passed the read-side queue.
2503  */
2504 /* ARGSUSED */
2505 static int
2506 spdsock_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
2507 {
2508 	spdsock_t *ss;
2509 	queue_t *oq = OTHERQ(q);
2510 	minor_t ssminor;
2511 
2512 	if (secpolicy_net_config(credp, B_FALSE) != 0)
2513 		return (EPERM);
2514 
2515 	if (q->q_ptr != NULL)
2516 		return (0);  /* Re-open of an already open instance. */
2517 
2518 	if (sflag & MODOPEN)
2519 		return (EINVAL);
2520 
2521 	ss2dbg(("Made it into PF_POLICY socket open.\n"));
2522 
2523 	ssminor = (minor_t)(uintptr_t)vmem_alloc(spdsock_vmem, 1, VM_NOSLEEP);
2524 	if (ssminor == 0)
2525 		return (ENOMEM);
2526 
2527 	ss = kmem_zalloc(sizeof (spdsock_t), KM_NOSLEEP);
2528 	if (ss == NULL) {
2529 		vmem_free(spdsock_vmem, (void *)(uintptr_t)ssminor, 1);
2530 		return (ENOMEM);
2531 	}
2532 
2533 	ss->spdsock_minor = ssminor;
2534 	ss->spdsock_state = TS_UNBND;
2535 	ss->spdsock_dump_req = NULL;
2536 
2537 	q->q_ptr = ss;
2538 	oq->q_ptr = ss;
2539 
2540 	q->q_hiwat = spdsock_recv_hiwat;
2541 
2542 	oq->q_hiwat = spdsock_xmit_hiwat;
2543 	oq->q_lowat = spdsock_xmit_lowat;
2544 
2545 	qprocson(q);
2546 	(void) mi_set_sth_hiwat(q, spdsock_recv_hiwat);
2547 
2548 	*devp = makedevice(getmajor(*devp), ss->spdsock_minor);
2549 	return (0);
2550 }
2551 
2552 /*
2553  * Read-side service procedure, invoked when we get back-enabled
2554  * when buffer space becomes available.
2555  *
2556  * Dump another chunk if we were dumping before; when we finish, kick
2557  * the write-side queue in case it's waiting for read queue space.
2558  */
2559 void
2560 spdsock_rsrv(queue_t *q)
2561 {
2562 	spdsock_t *ss = q->q_ptr;
2563 
2564 	if (ss->spdsock_dump_req != NULL)
2565 		spdsock_dump_some(q, ss);
2566 
2567 	if (ss->spdsock_dump_req == NULL)
2568 		qenable(OTHERQ(q));
2569 }
2570 
2571 /*
2572  * Write-side service procedure, invoked when we defer processing
2573  * if another message is received while a dump is in progress.
2574  */
2575 void
2576 spdsock_wsrv(queue_t *q)
2577 {
2578 	spdsock_t *ss = q->q_ptr;
2579 	mblk_t *mp;
2580 
2581 	if (ss->spdsock_dump_req != NULL) {
2582 		qenable(OTHERQ(q));
2583 		return;
2584 	}
2585 
2586 	while ((mp = getq(q)) != NULL) {
2587 		if (ipsec_loaded()) {
2588 			spdsock_wput(q, mp);
2589 			if (ss->spdsock_dump_req != NULL)
2590 				return;
2591 		} else if (!ipsec_failed()) {
2592 			(void) putq(q, mp);
2593 		} else {
2594 			spdsock_error(q, mp, EPFNOSUPPORT, 0);
2595 		}
2596 	}
2597 }
2598 
2599 static int
2600 spdsock_close(queue_t *q)
2601 {
2602 	spdsock_t *ss = q->q_ptr;
2603 
2604 	qprocsoff(q);
2605 
2606 	/* Safe assumption. */
2607 	ASSERT(ss != NULL);
2608 
2609 	if (ss->spdsock_timeout != 0)
2610 		(void) quntimeout(q, ss->spdsock_timeout);
2611 
2612 	ss3dbg(("Driver close, PF_POLICY socket is going away.\n"));
2613 
2614 	vmem_free(spdsock_vmem, (void *)(uintptr_t)ss->spdsock_minor, 1);
2615 
2616 	kmem_free(ss, sizeof (spdsock_t));
2617 	return (0);
2618 }
2619 
2620 /*
2621  * Merge the IPsec algorithms tables with the received algorithm information.
2622  */
2623 void
2624 spdsock_merge_algs(void)
2625 {
2626 	ipsec_alginfo_t *alg, *oalg;
2627 	ipsec_algtype_t algtype;
2628 	uint_t algidx, algid, nalgs;
2629 	crypto_mech_name_t *mechs;
2630 	uint_t mech_count, mech_idx;
2631 
2632 	ASSERT(MUTEX_HELD(&spdsock_alg_lock));
2633 
2634 	/*
2635 	 * Get the list of supported mechanisms from the crypto framework.
2636 	 * If a mechanism is supported by KCF, resolve its mechanism
2637 	 * id and mark it as being valid. This operation must be done
2638 	 * without holding alg_lock, since it can cause a provider
2639 	 * module to be loaded and the provider notification callback to
2640 	 * be invoked.
2641 	 */
2642 	mechs = crypto_get_mech_list(&mech_count, KM_SLEEP);
2643 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2644 		for (algid = 0; algid < IPSEC_MAX_ALGS; algid++) {
2645 			int algflags = 0;
2646 			crypto_mech_type_t mt = CRYPTO_MECHANISM_INVALID;
2647 
2648 			if ((alg = spdsock_algs[algtype][algid]) == NULL)
2649 				continue;
2650 
2651 			/*
2652 			 * The NULL encryption algorithm is a special
2653 			 * case because there are no mechanisms, yet
2654 			 * the algorithm is still valid.
2655 			 */
2656 			if (alg->alg_id == SADB_EALG_NULL) {
2657 				alg->alg_mech_type = CRYPTO_MECHANISM_INVALID;
2658 				alg->alg_flags = ALG_FLAG_VALID;
2659 				continue;
2660 			}
2661 
2662 			for (mech_idx = 0; mech_idx < mech_count; mech_idx++) {
2663 				if (strncmp(alg->alg_mech_name, mechs[mech_idx],
2664 				    CRYPTO_MAX_MECH_NAME) == 0) {
2665 					mt = crypto_mech2id(alg->alg_mech_name);
2666 					ASSERT(mt != CRYPTO_MECHANISM_INVALID);
2667 					algflags = ALG_FLAG_VALID;
2668 					break;
2669 				}
2670 			}
2671 			alg->alg_mech_type = mt;
2672 			alg->alg_flags = algflags;
2673 		}
2674 	}
2675 
2676 	mutex_enter(&alg_lock);
2677 
2678 	/*
2679 	 * For each algorithm currently defined, check if it is
2680 	 * present in the new tables created from the SPD_UPDATEALGS
2681 	 * message received from user-space.
2682 	 * Delete the algorithm entries that are currently defined
2683 	 * but not part of the new tables.
2684 	 */
2685 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2686 		nalgs = ipsec_nalgs[algtype];
2687 		for (algidx = 0; algidx < nalgs; algidx++) {
2688 			algid = ipsec_sortlist[algtype][algidx];
2689 			if (spdsock_algs[algtype][algid] == NULL)
2690 				ipsec_alg_unreg(algtype, algid);
2691 		}
2692 	}
2693 
2694 	/*
2695 	 * For each algorithm we just received, check if it is
2696 	 * present in the currently defined tables. If it is, swap
2697 	 * the entry with the one we just allocated.
2698 	 * If the new algorithm is not in the current tables,
2699 	 * add it.
2700 	 */
2701 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2702 		for (algid = 0; algid < IPSEC_MAX_ALGS; algid++) {
2703 			if ((alg = spdsock_algs[algtype][algid]) == NULL)
2704 				continue;
2705 
2706 			if ((oalg = ipsec_alglists[algtype][algid]) == NULL) {
2707 				/*
2708 				 * New algorithm, add it to the algorithm
2709 				 * table.
2710 				 */
2711 				ipsec_alg_reg(algtype, alg);
2712 			} else {
2713 				/*
2714 				 * Algorithm is already in the table. Swap
2715 				 * the existing entry with the new one.
2716 				 */
2717 				ipsec_alg_fix_min_max(alg, algtype);
2718 				ipsec_alglists[algtype][algid] = alg;
2719 				ipsec_alg_free(oalg);
2720 			}
2721 			spdsock_algs[algtype][algid] = NULL;
2722 		}
2723 	}
2724 
2725 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++)
2726 		ipsec_algs_exec_mode[algtype] = spdsock_algs_exec_mode[algtype];
2727 
2728 	mutex_exit(&alg_lock);
2729 
2730 	crypto_free_mech_list(mechs, mech_count);
2731 
2732 	ipsecah_algs_changed();
2733 	ipsecesp_algs_changed();
2734 }
2735