xref: /illumos-gate/usr/src/uts/common/inet/ip/conn_opt.c (revision e8d3efa1c56e5f2b5368600a2baeb7b1d54a07f8)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
25  * Copyright 2026 Oxide Computer Company
26  * Copyright 2026 Bill Sommerfeld <sommerfeld@hamachi.org>
27  */
28 /* Copyright (c) 1990 Mentat Inc. */
29 
30 #include <sys/types.h>
31 #include <sys/stream.h>
32 #include <sys/strsun.h>
33 #define	_SUN_TPI_VERSION 2
34 #include <sys/tihdr.h>
35 #include <sys/xti_inet.h>
36 #include <sys/ucred.h>
37 #include <sys/zone.h>
38 #include <sys/ddi.h>
39 #include <sys/sunddi.h>
40 #include <sys/cmn_err.h>
41 #include <sys/debug.h>
42 #include <sys/atomic.h>
43 #include <sys/policy.h>
44 
45 #include <sys/systm.h>
46 #include <sys/param.h>
47 #include <sys/kmem.h>
48 #include <sys/sdt.h>
49 #include <sys/socket.h>
50 #include <sys/ethernet.h>
51 #include <sys/mac.h>
52 #include <net/if.h>
53 #include <net/if_types.h>
54 #include <net/if_arp.h>
55 #include <net/route.h>
56 #include <sys/sockio.h>
57 #include <netinet/in.h>
58 #include <net/if_dl.h>
59 
60 #include <inet/common.h>
61 #include <inet/mi.h>
62 #include <inet/mib2.h>
63 #include <inet/nd.h>
64 #include <inet/arp.h>
65 #include <inet/snmpcom.h>
66 #include <inet/kstatcom.h>
67 
68 #include <netinet/igmp_var.h>
69 #include <netinet/ip6.h>
70 #include <netinet/icmp6.h>
71 #include <netinet/sctp.h>
72 
73 #include <inet/ip.h>
74 #include <inet/ip_impl.h>
75 #include <inet/ip6.h>
76 #include <inet/ip6_asp.h>
77 #include <inet/tcp.h>
78 #include <inet/ip_multi.h>
79 #include <inet/ip_if.h>
80 #include <inet/ip_ire.h>
81 #include <inet/ip_ftable.h>
82 #include <inet/ip_rts.h>
83 #include <inet/optcom.h>
84 #include <inet/ip_ndp.h>
85 #include <inet/ip_listutils.h>
86 #include <netinet/igmp.h>
87 #include <netinet/ip_mroute.h>
88 #include <netinet/udp.h>
89 #include <inet/ipp_common.h>
90 
91 #include <net/pfkeyv2.h>
92 #include <inet/sadb.h>
93 #include <inet/ipsec_impl.h>
94 #include <inet/ipdrop.h>
95 #include <inet/ip_netinfo.h>
96 
97 #include <inet/ipclassifier.h>
98 #include <inet/sctp_ip.h>
99 #include <inet/sctp/sctp_impl.h>
100 #include <inet/udp_impl.h>
101 #include <sys/sunddi.h>
102 
103 #include <sys/tsol/label.h>
104 #include <sys/tsol/tnet.h>
105 
106 /*
107  * Return how much size is needed for the different ancillary data items
108  */
109 uint_t
110 conn_recvancillary_size(conn_t *connp, crb_t recv_ancillary,
111     ip_recv_attr_t *ira, mblk_t *mp, ip_pkt_t *ipp)
112 {
113 	uint_t		ancil_size;
114 	ip_stack_t	*ipst = connp->conn_netstack->netstack_ip;
115 
116 	/*
117 	 * If IP_RECVDSTADDR is set we include the destination IP
118 	 * address as an option. With IP_RECVOPTS we include all
119 	 * the IP options.
120 	 */
121 	ancil_size = 0;
122 	if (recv_ancillary.crb_recvdstaddr &&
123 	    (ira->ira_flags & IRAF_IS_IPV4)) {
124 		ancil_size += sizeof (struct T_opthdr) +
125 		    sizeof (struct in_addr);
126 		IP_STAT(ipst, conn_in_recvdstaddr);
127 	}
128 
129 	/*
130 	 * ip_recvpktinfo is used for both AF_INET and AF_INET6 but
131 	 * are different
132 	 */
133 	if (recv_ancillary.crb_ip_recvpktinfo &&
134 	    connp->conn_family == AF_INET) {
135 		ancil_size += sizeof (struct T_opthdr) +
136 		    sizeof (struct in_pktinfo);
137 		IP_STAT(ipst, conn_in_recvpktinfo);
138 	}
139 
140 	if ((recv_ancillary.crb_recvopts) &&
141 	    (ipp->ipp_fields & IPPF_IPV4_OPTIONS)) {
142 		ancil_size += sizeof (struct T_opthdr) +
143 		    ipp->ipp_ipv4_options_len;
144 		IP_STAT(ipst, conn_in_recvopts);
145 	}
146 
147 	if (recv_ancillary.crb_recvslla) {
148 		ip_stack_t *ipst = connp->conn_netstack->netstack_ip;
149 		ill_t *ill;
150 
151 		/* Make sure ira_l2src is setup if not already */
152 		if (!(ira->ira_flags & IRAF_L2SRC_SET)) {
153 			ill = ill_lookup_on_ifindex(ira->ira_rifindex, B_FALSE,
154 			    ipst);
155 			if (ill != NULL) {
156 				ip_setl2src(mp, ira, ill);
157 				ill_refrele(ill);
158 			}
159 		}
160 		ancil_size += sizeof (struct T_opthdr) +
161 		    sizeof (struct sockaddr_dl);
162 		IP_STAT(ipst, conn_in_recvslla);
163 	}
164 
165 	if (recv_ancillary.crb_recvif) {
166 		ancil_size += sizeof (struct T_opthdr) + sizeof (uint_t);
167 		IP_STAT(ipst, conn_in_recvif);
168 	}
169 
170 	/*
171 	 * ip_recvpktinfo is used for both AF_INET and AF_INET6 but
172 	 * are different
173 	 */
174 	if (recv_ancillary.crb_ip_recvpktinfo &&
175 	    connp->conn_family == AF_INET6) {
176 		ancil_size += sizeof (struct T_opthdr) +
177 		    sizeof (struct in6_pktinfo);
178 		IP_STAT(ipst, conn_in_recvpktinfo);
179 	}
180 
181 	if (recv_ancillary.crb_ipv6_recvhoplimit) {
182 		ancil_size += sizeof (struct T_opthdr) + sizeof (int);
183 		IP_STAT(ipst, conn_in_recvhoplimit);
184 	}
185 
186 	if (recv_ancillary.crb_ipv6_recvtclass) {
187 		ancil_size += sizeof (struct T_opthdr) + sizeof (int);
188 		IP_STAT(ipst, conn_in_recvtclass);
189 	}
190 
191 	if (recv_ancillary.crb_ipv6_recvhopopts &&
192 	    (ipp->ipp_fields & IPPF_HOPOPTS)) {
193 		ancil_size += sizeof (struct T_opthdr) + ipp->ipp_hopoptslen;
194 		IP_STAT(ipst, conn_in_recvhopopts);
195 	}
196 	/*
197 	 * To honor RFC3542 when an application asks for both IPV6_RECVDSTOPTS
198 	 * and IPV6_RECVRTHDR, we pass up the item rthdrdstopts (the destination
199 	 * options that appear before a routing header.
200 	 * We also pass them up if IPV6_RECVRTHDRDSTOPTS is set.
201 	 */
202 	if (ipp->ipp_fields & IPPF_RTHDRDSTOPTS) {
203 		if (recv_ancillary.crb_ipv6_recvrthdrdstopts ||
204 		    (recv_ancillary.crb_ipv6_recvdstopts &&
205 		    recv_ancillary.crb_ipv6_recvrthdr)) {
206 			ancil_size += sizeof (struct T_opthdr) +
207 			    ipp->ipp_rthdrdstoptslen;
208 			IP_STAT(ipst, conn_in_recvrthdrdstopts);
209 		}
210 	}
211 	if ((recv_ancillary.crb_ipv6_recvrthdr) &&
212 	    (ipp->ipp_fields & IPPF_RTHDR)) {
213 		ancil_size += sizeof (struct T_opthdr) + ipp->ipp_rthdrlen;
214 		IP_STAT(ipst, conn_in_recvrthdr);
215 	}
216 	if ((recv_ancillary.crb_ipv6_recvdstopts ||
217 	    recv_ancillary.crb_old_ipv6_recvdstopts) &&
218 	    (ipp->ipp_fields & IPPF_DSTOPTS)) {
219 		ancil_size += sizeof (struct T_opthdr) + ipp->ipp_dstoptslen;
220 		IP_STAT(ipst, conn_in_recvdstopts);
221 	}
222 	if (recv_ancillary.crb_recvucred && ira->ira_cred != NULL) {
223 		ancil_size += sizeof (struct T_opthdr) +
224 		    ucredminsize(ira->ira_cred);
225 		IP_STAT(ipst, conn_in_recvucred);
226 	}
227 
228 	/*
229 	 * If SO_TIMESTAMP is set allocate the appropriate sized
230 	 * buffer. Since gethrestime() expects a pointer aligned
231 	 * argument, we allocate space necessary for extra
232 	 * alignment (even though it might not be used).
233 	 */
234 	if (recv_ancillary.crb_timestamp) {
235 		ancil_size += sizeof (struct T_opthdr) +
236 		    sizeof (timestruc_t) + _POINTER_ALIGNMENT;
237 		IP_STAT(ipst, conn_in_timestamp);
238 	}
239 
240 	/*
241 	 * If IP_RECVTOS is set allocate the appropriately sized buffer
242 	 */
243 	if (recv_ancillary.crb_recvtos &&
244 	    (ira->ira_flags & IRAF_IS_IPV4)) {
245 		ancil_size += sizeof (struct T_opthdr) +
246 		    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
247 		IP_STAT(ipst, conn_in_recvtos);
248 	}
249 
250 	/*
251 	 * If IP_RECVTTL is set allocate the appropriate sized buffer
252 	 */
253 	if (recv_ancillary.crb_recvttl &&
254 	    (ira->ira_flags & IRAF_IS_IPV4)) {
255 		ancil_size += sizeof (struct T_opthdr) +
256 		    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
257 		IP_STAT(ipst, conn_in_recvttl);
258 	}
259 
260 	return (ancil_size);
261 }
262 
263 /*
264  * Lay down the ancillary data items at "ancil_buf".
265  * Assumes caller has used conn_recvancillary_size to allocate a sufficiently
266  * large buffer - ancil_size.
267  */
268 void
269 conn_recvancillary_add(conn_t *connp, crb_t recv_ancillary,
270     ip_recv_attr_t *ira, ip_pkt_t *ipp, uchar_t *ancil_buf, uint_t ancil_size)
271 {
272 	/*
273 	 * Copy in destination address before options to avoid
274 	 * any padding issues.
275 	 */
276 	if (recv_ancillary.crb_recvdstaddr &&
277 	    (ira->ira_flags & IRAF_IS_IPV4)) {
278 		struct T_opthdr *toh;
279 		ipaddr_t *dstptr;
280 
281 		toh = (struct T_opthdr *)ancil_buf;
282 		toh->level = IPPROTO_IP;
283 		toh->name = IP_RECVDSTADDR;
284 		toh->len = sizeof (struct T_opthdr) + sizeof (ipaddr_t);
285 		toh->status = 0;
286 		ancil_buf += sizeof (struct T_opthdr);
287 		dstptr = (ipaddr_t *)ancil_buf;
288 		*dstptr = ipp->ipp_addr_v4;
289 		ancil_buf += sizeof (ipaddr_t);
290 		ancil_size -= toh->len;
291 	}
292 
293 	/*
294 	 * ip_recvpktinfo is used for both AF_INET and AF_INET6 but
295 	 * are different
296 	 */
297 	if (recv_ancillary.crb_ip_recvpktinfo &&
298 	    connp->conn_family == AF_INET) {
299 		ip_stack_t *ipst = connp->conn_netstack->netstack_ip;
300 		struct T_opthdr *toh;
301 		struct in_pktinfo *pktinfop;
302 		ill_t *ill;
303 		ipif_t *ipif;
304 
305 		toh = (struct T_opthdr *)ancil_buf;
306 		toh->level = IPPROTO_IP;
307 		toh->name = IP_PKTINFO;
308 		toh->len = sizeof (struct T_opthdr) + sizeof (*pktinfop);
309 		toh->status = 0;
310 		ancil_buf += sizeof (struct T_opthdr);
311 		pktinfop = (struct in_pktinfo *)ancil_buf;
312 
313 		pktinfop->ipi_ifindex = ira->ira_ruifindex;
314 		pktinfop->ipi_spec_dst.s_addr = INADDR_ANY;
315 
316 		/* Find a good address to report */
317 		ill = ill_lookup_on_ifindex(ira->ira_ruifindex, B_FALSE, ipst);
318 		if (ill != NULL) {
319 			ipif = ipif_good_addr(ill, IPCL_ZONEID(connp));
320 			if (ipif != NULL) {
321 				pktinfop->ipi_spec_dst.s_addr =
322 				    ipif->ipif_lcl_addr;
323 				ipif_refrele(ipif);
324 			}
325 			ill_refrele(ill);
326 		}
327 		pktinfop->ipi_addr.s_addr = ipp->ipp_addr_v4;
328 		ancil_buf += sizeof (struct in_pktinfo);
329 		ancil_size -= toh->len;
330 	}
331 
332 	if ((recv_ancillary.crb_recvopts) &&
333 	    (ipp->ipp_fields & IPPF_IPV4_OPTIONS)) {
334 		struct T_opthdr *toh;
335 
336 		toh = (struct T_opthdr *)ancil_buf;
337 		toh->level = IPPROTO_IP;
338 		toh->name = IP_RECVOPTS;
339 		toh->len = sizeof (struct T_opthdr) + ipp->ipp_ipv4_options_len;
340 		toh->status = 0;
341 		ancil_buf += sizeof (struct T_opthdr);
342 		bcopy(ipp->ipp_ipv4_options, ancil_buf,
343 		    ipp->ipp_ipv4_options_len);
344 		ancil_buf += ipp->ipp_ipv4_options_len;
345 		ancil_size -= toh->len;
346 	}
347 
348 	if (recv_ancillary.crb_recvslla) {
349 		ip_stack_t *ipst = connp->conn_netstack->netstack_ip;
350 		struct T_opthdr *toh;
351 		struct sockaddr_dl *dstptr;
352 		ill_t *ill;
353 		int alen = 0;
354 
355 		ill = ill_lookup_on_ifindex(ira->ira_rifindex, B_FALSE, ipst);
356 		if (ill != NULL)
357 			alen = ill->ill_phys_addr_length;
358 
359 		/*
360 		 * For loopback multicast and broadcast the packet arrives
361 		 * with ira_ruifdex being the physical interface, but
362 		 * ira_l2src is all zero since ip_postfrag_loopback doesn't
363 		 * know our l2src. We don't report the address in that case.
364 		 */
365 		if (ira->ira_flags & IRAF_LOOPBACK)
366 			alen = 0;
367 
368 		toh = (struct T_opthdr *)ancil_buf;
369 		toh->level = IPPROTO_IP;
370 		toh->name = IP_RECVSLLA;
371 		toh->len = sizeof (struct T_opthdr) +
372 		    sizeof (struct sockaddr_dl);
373 		toh->status = 0;
374 		ancil_buf += sizeof (struct T_opthdr);
375 		dstptr = (struct sockaddr_dl *)ancil_buf;
376 		dstptr->sdl_family = AF_LINK;
377 		dstptr->sdl_index = ira->ira_ruifindex;
378 		if (ill != NULL)
379 			dstptr->sdl_type = ill->ill_type;
380 		else
381 			dstptr->sdl_type = 0;
382 		dstptr->sdl_nlen = 0;
383 		dstptr->sdl_alen = alen;
384 		dstptr->sdl_slen = 0;
385 		bcopy(ira->ira_l2src, dstptr->sdl_data, alen);
386 		ancil_buf += sizeof (struct sockaddr_dl);
387 		ancil_size -= toh->len;
388 		if (ill != NULL)
389 			ill_refrele(ill);
390 	}
391 
392 	if (recv_ancillary.crb_recvif) {
393 		struct T_opthdr *toh;
394 		uint_t		*dstptr;
395 
396 		toh = (struct T_opthdr *)ancil_buf;
397 		toh->level = IPPROTO_IP;
398 		toh->name = IP_RECVIF;
399 		toh->len = sizeof (struct T_opthdr) + sizeof (uint_t);
400 		toh->status = 0;
401 		ancil_buf += sizeof (struct T_opthdr);
402 		dstptr = (uint_t *)ancil_buf;
403 		*dstptr = ira->ira_ruifindex;
404 		ancil_buf += sizeof (uint_t);
405 		ancil_size -= toh->len;
406 	}
407 
408 	/*
409 	 * ip_recvpktinfo is used for both AF_INET and AF_INET6 but
410 	 * are different
411 	 */
412 	if (recv_ancillary.crb_ip_recvpktinfo &&
413 	    connp->conn_family == AF_INET6) {
414 		struct T_opthdr *toh;
415 		struct in6_pktinfo *pkti;
416 
417 		toh = (struct T_opthdr *)ancil_buf;
418 		toh->level = IPPROTO_IPV6;
419 		toh->name = IPV6_PKTINFO;
420 		toh->len = sizeof (struct T_opthdr) + sizeof (*pkti);
421 		toh->status = 0;
422 		ancil_buf += sizeof (struct T_opthdr);
423 		pkti = (struct in6_pktinfo *)ancil_buf;
424 		if (ira->ira_flags & IRAF_IS_IPV4) {
425 			IN6_IPADDR_TO_V4MAPPED(ipp->ipp_addr_v4,
426 			    &pkti->ipi6_addr);
427 		} else {
428 			pkti->ipi6_addr = ipp->ipp_addr;
429 		}
430 		pkti->ipi6_ifindex = ira->ira_ruifindex;
431 
432 		ancil_buf += sizeof (*pkti);
433 		ancil_size -= toh->len;
434 	}
435 	if (recv_ancillary.crb_ipv6_recvhoplimit) {
436 		struct T_opthdr *toh;
437 
438 		toh = (struct T_opthdr *)ancil_buf;
439 		toh->level = IPPROTO_IPV6;
440 		toh->name = IPV6_HOPLIMIT;
441 		toh->len = sizeof (struct T_opthdr) + sizeof (uint_t);
442 		toh->status = 0;
443 		ancil_buf += sizeof (struct T_opthdr);
444 		*(uint_t *)ancil_buf = ipp->ipp_hoplimit;
445 		ancil_buf += sizeof (uint_t);
446 		ancil_size -= toh->len;
447 	}
448 	if (recv_ancillary.crb_ipv6_recvtclass) {
449 		struct T_opthdr *toh;
450 
451 		toh = (struct T_opthdr *)ancil_buf;
452 		toh->level = IPPROTO_IPV6;
453 		toh->name = IPV6_TCLASS;
454 		toh->len = sizeof (struct T_opthdr) + sizeof (uint_t);
455 		toh->status = 0;
456 		ancil_buf += sizeof (struct T_opthdr);
457 
458 		if (ira->ira_flags & IRAF_IS_IPV4)
459 			*(uint_t *)ancil_buf = ipp->ipp_type_of_service;
460 		else
461 			*(uint_t *)ancil_buf = ipp->ipp_tclass;
462 		ancil_buf += sizeof (uint_t);
463 		ancil_size -= toh->len;
464 	}
465 	if (recv_ancillary.crb_ipv6_recvhopopts &&
466 	    (ipp->ipp_fields & IPPF_HOPOPTS)) {
467 		struct T_opthdr *toh;
468 
469 		toh = (struct T_opthdr *)ancil_buf;
470 		toh->level = IPPROTO_IPV6;
471 		toh->name = IPV6_HOPOPTS;
472 		toh->len = sizeof (struct T_opthdr) + ipp->ipp_hopoptslen;
473 		toh->status = 0;
474 		ancil_buf += sizeof (struct T_opthdr);
475 		bcopy(ipp->ipp_hopopts, ancil_buf, ipp->ipp_hopoptslen);
476 		ancil_buf += ipp->ipp_hopoptslen;
477 		ancil_size -= toh->len;
478 	}
479 	/*
480 	 * To honor RFC3542 when an application asks for both IPV6_RECVDSTOPTS
481 	 * and IPV6_RECVRTHDR, we pass up the item rthdrdstopts (the destination
482 	 * options that appear before a routing header.
483 	 * We also pass them up if IPV6_RECVRTHDRDSTOPTS is set.
484 	 */
485 	if (ipp->ipp_fields & IPPF_RTHDRDSTOPTS) {
486 		if (recv_ancillary.crb_ipv6_recvrthdrdstopts ||
487 		    (recv_ancillary.crb_ipv6_recvdstopts &&
488 		    recv_ancillary.crb_ipv6_recvrthdr)) {
489 			struct T_opthdr *toh;
490 
491 			toh = (struct T_opthdr *)ancil_buf;
492 			toh->level = IPPROTO_IPV6;
493 			toh->name = IPV6_DSTOPTS;
494 			toh->len = sizeof (struct T_opthdr) +
495 			    ipp->ipp_rthdrdstoptslen;
496 			toh->status = 0;
497 			ancil_buf += sizeof (struct T_opthdr);
498 			bcopy(ipp->ipp_rthdrdstopts, ancil_buf,
499 			    ipp->ipp_rthdrdstoptslen);
500 			ancil_buf += ipp->ipp_rthdrdstoptslen;
501 			ancil_size -= toh->len;
502 		}
503 	}
504 	if (recv_ancillary.crb_ipv6_recvrthdr &&
505 	    (ipp->ipp_fields & IPPF_RTHDR)) {
506 		struct T_opthdr *toh;
507 
508 		toh = (struct T_opthdr *)ancil_buf;
509 		toh->level = IPPROTO_IPV6;
510 		toh->name = IPV6_RTHDR;
511 		toh->len = sizeof (struct T_opthdr) + ipp->ipp_rthdrlen;
512 		toh->status = 0;
513 		ancil_buf += sizeof (struct T_opthdr);
514 		bcopy(ipp->ipp_rthdr, ancil_buf, ipp->ipp_rthdrlen);
515 		ancil_buf += ipp->ipp_rthdrlen;
516 		ancil_size -= toh->len;
517 	}
518 	if ((recv_ancillary.crb_ipv6_recvdstopts ||
519 	    recv_ancillary.crb_old_ipv6_recvdstopts) &&
520 	    (ipp->ipp_fields & IPPF_DSTOPTS)) {
521 		struct T_opthdr *toh;
522 
523 		toh = (struct T_opthdr *)ancil_buf;
524 		toh->level = IPPROTO_IPV6;
525 		toh->name = IPV6_DSTOPTS;
526 		toh->len = sizeof (struct T_opthdr) + ipp->ipp_dstoptslen;
527 		toh->status = 0;
528 		ancil_buf += sizeof (struct T_opthdr);
529 		bcopy(ipp->ipp_dstopts, ancil_buf, ipp->ipp_dstoptslen);
530 		ancil_buf += ipp->ipp_dstoptslen;
531 		ancil_size -= toh->len;
532 	}
533 
534 	if (recv_ancillary.crb_recvucred && ira->ira_cred != NULL) {
535 		struct T_opthdr *toh;
536 		cred_t		*rcr = connp->conn_cred;
537 
538 		toh = (struct T_opthdr *)ancil_buf;
539 		toh->level = SOL_SOCKET;
540 		toh->name = SCM_UCRED;
541 		toh->len = sizeof (struct T_opthdr) +
542 		    ucredminsize(ira->ira_cred);
543 		toh->status = 0;
544 		(void) cred2ucred(ira->ira_cred, ira->ira_cpid, &toh[1], rcr);
545 		ancil_buf += toh->len;
546 		ancil_size -= toh->len;
547 	}
548 	if (recv_ancillary.crb_timestamp) {
549 		struct	T_opthdr *toh;
550 
551 		toh = (struct T_opthdr *)ancil_buf;
552 		toh->level = SOL_SOCKET;
553 		toh->name = SCM_TIMESTAMP;
554 		toh->len = sizeof (struct T_opthdr) +
555 		    sizeof (timestruc_t) + _POINTER_ALIGNMENT;
556 		toh->status = 0;
557 		ancil_buf += sizeof (struct T_opthdr);
558 		/* Align for gethrestime() */
559 		ancil_buf = (uchar_t *)P2ROUNDUP((intptr_t)ancil_buf,
560 		    sizeof (intptr_t));
561 		gethrestime((timestruc_t *)ancil_buf);
562 		ancil_buf = (uchar_t *)toh + toh->len;
563 		ancil_size -= toh->len;
564 	}
565 
566 	if (recv_ancillary.crb_recvtos &&
567 	    (ira->ira_flags & IRAF_IS_IPV4)) {
568 		struct	T_opthdr *toh;
569 		uint8_t	*dstptr;
570 
571 		toh = (struct T_opthdr *)ancil_buf;
572 		toh->level = IPPROTO_IP;
573 		toh->name = IP_RECVTOS;
574 		toh->len = sizeof (struct T_opthdr) +
575 		    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
576 		toh->status = 0;
577 		ancil_buf += sizeof (struct T_opthdr);
578 		dstptr = (uint8_t *)ancil_buf;
579 		*dstptr = ipp->ipp_type_of_service;
580 		ancil_buf = (uchar_t *)toh + toh->len;
581 		ancil_size -= toh->len;
582 		ASSERT(__TPI_TOPT_ISALIGNED(toh));
583 	}
584 
585 	if (recv_ancillary.crb_recvttl &&
586 	    (ira->ira_flags & IRAF_IS_IPV4)) {
587 		struct	T_opthdr *toh;
588 		uint8_t	*dstptr;
589 
590 		toh = (struct T_opthdr *)ancil_buf;
591 		toh->level = IPPROTO_IP;
592 		toh->name = IP_RECVTTL;
593 		toh->len = sizeof (struct T_opthdr) +
594 		    P2ROUNDUP(sizeof (uint8_t), __TPI_ALIGN_SIZE);
595 		toh->status = 0;
596 		ancil_buf += sizeof (struct T_opthdr);
597 		dstptr = (uint8_t *)ancil_buf;
598 		*dstptr = ipp->ipp_hoplimit;
599 		ancil_buf = (uchar_t *)toh + toh->len;
600 		ancil_size -= toh->len;
601 		ASSERT(__TPI_TOPT_ISALIGNED(toh));
602 	}
603 
604 	/* Consumed all of allocated space */
605 	ASSERT(ancil_size == 0);
606 
607 }
608 
609 /*
610  * This routine retrieves the current status of socket options.
611  * It returns the size of the option retrieved, or -1.
612  */
613 int
614 conn_opt_get(conn_opt_arg_t *coa, t_scalar_t level, t_scalar_t name,
615     uchar_t *ptr)
616 {
617 	int		*i1 = (int *)ptr;
618 	conn_t		*connp = coa->coa_connp;
619 	ip_xmit_attr_t	*ixa = coa->coa_ixa;
620 	ip_pkt_t	*ipp = coa->coa_ipp;
621 	ip_stack_t	*ipst = ixa->ixa_ipst;
622 	uint_t		len;
623 
624 	ASSERT(MUTEX_HELD(&coa->coa_connp->conn_lock));
625 
626 	switch (level) {
627 	case SOL_SOCKET:
628 		switch (name) {
629 		case SO_DEBUG:
630 			*i1 = connp->conn_debug ? SO_DEBUG : 0;
631 			break;	/* goto sizeof (int) option return */
632 		case SO_KEEPALIVE:
633 			*i1 = connp->conn_keepalive ? SO_KEEPALIVE : 0;
634 			break;
635 		case SO_LINGER:	{
636 			struct linger *lgr = (struct linger *)ptr;
637 
638 			lgr->l_onoff = connp->conn_linger ? SO_LINGER : 0;
639 			lgr->l_linger = connp->conn_lingertime;
640 			}
641 			return (sizeof (struct linger));
642 
643 		case SO_OOBINLINE:
644 			*i1 = connp->conn_oobinline ? SO_OOBINLINE : 0;
645 			break;
646 		case SO_REUSEADDR:
647 			*i1 = connp->conn_reuseaddr ? SO_REUSEADDR : 0;
648 			break;	/* goto sizeof (int) option return */
649 		case SO_TYPE:
650 			*i1 = connp->conn_so_type;
651 			break;	/* goto sizeof (int) option return */
652 		case SO_DONTROUTE:
653 			*i1 = (ixa->ixa_flags & IXAF_DONTROUTE) ?
654 			    SO_DONTROUTE : 0;
655 			break;	/* goto sizeof (int) option return */
656 		case SO_USELOOPBACK:
657 			*i1 = connp->conn_useloopback ? SO_USELOOPBACK : 0;
658 			break;	/* goto sizeof (int) option return */
659 		case SO_BROADCAST:
660 			*i1 = connp->conn_broadcast ? SO_BROADCAST : 0;
661 			break;	/* goto sizeof (int) option return */
662 
663 		case SO_SNDBUF:
664 			*i1 = connp->conn_sndbuf;
665 			break;	/* goto sizeof (int) option return */
666 		case SO_RCVBUF:
667 			*i1 = connp->conn_rcvbuf;
668 			break;	/* goto sizeof (int) option return */
669 		case SO_RCVTIMEO:
670 		case SO_SNDTIMEO:
671 			/*
672 			 * Pass these two options in order for third part
673 			 * protocol usage. Here just return directly.
674 			 */
675 			*i1 = 0;
676 			break;
677 		case SO_DGRAM_ERRIND:
678 			*i1 = connp->conn_dgram_errind ? SO_DGRAM_ERRIND : 0;
679 			break;	/* goto sizeof (int) option return */
680 		case SO_RECVUCRED:
681 			*i1 = connp->conn_recv_ancillary.crb_recvucred;
682 			break;	/* goto sizeof (int) option return */
683 		case SO_TIMESTAMP:
684 			*i1 = connp->conn_recv_ancillary.crb_timestamp;
685 			break;	/* goto sizeof (int) option return */
686 		case SO_VRRP:
687 			*i1 = connp->conn_isvrrp;
688 			break;	/* goto sizeof (int) option return */
689 		case SO_ANON_MLP:
690 			*i1 = connp->conn_anon_mlp;
691 			break;	/* goto sizeof (int) option return */
692 		case SO_MAC_EXEMPT:
693 			*i1 = (connp->conn_mac_mode == CONN_MAC_AWARE);
694 			break;	/* goto sizeof (int) option return */
695 		case SO_MAC_IMPLICIT:
696 			*i1 = (connp->conn_mac_mode == CONN_MAC_IMPLICIT);
697 			break;	/* goto sizeof (int) option return */
698 		case SO_ALLZONES:
699 			*i1 = connp->conn_allzones;
700 			break;	/* goto sizeof (int) option return */
701 		case SO_EXCLBIND:
702 			*i1 = connp->conn_exclbind ? SO_EXCLBIND : 0;
703 			break;
704 		case SO_PROTOTYPE:
705 			*i1 = connp->conn_proto;
706 			break;
707 
708 		case SO_DOMAIN:
709 			*i1 = connp->conn_family;
710 			break;
711 		default:
712 			return (-1);
713 		}
714 		break;
715 	case IPPROTO_IP:
716 		/*
717 		 * IPPROTO_IP options are supported whenever the connection
718 		 * uses IPv4 on the wire, which includes AF_INET6 sockets
719 		 * whose peers are IPv4-mapped IPv6 addresses.
720 		 */
721 		if (connp->conn_ipversion != IPV4_VERSION)
722 			return (-1);
723 		switch (name) {
724 		case IP_OPTIONS:
725 		case T_IP_OPTIONS:
726 			if (!(ipp->ipp_fields & IPPF_IPV4_OPTIONS))
727 				return (0);
728 
729 			len = ipp->ipp_ipv4_options_len;
730 			if (len > 0) {
731 				bcopy(ipp->ipp_ipv4_options, ptr, len);
732 			}
733 			return (len);
734 
735 		case IP_PKTINFO: {
736 			/*
737 			 * This also handles IP_RECVPKTINFO.
738 			 * IP_PKTINFO and IP_RECVPKTINFO have same value.
739 			 * Differentiation is based on the size of the
740 			 * argument passed in.
741 			 */
742 			struct in_pktinfo *pktinfo;
743 
744 #ifdef notdef
745 			/* optcom doesn't provide a length with "get" */
746 			if (inlen == sizeof (int)) {
747 				/* This is IP_RECVPKTINFO option. */
748 				*i1 = connp->conn_recv_ancillary.
749 				    crb_ip_recvpktinfo;
750 				return (sizeof (int));
751 			}
752 #endif
753 			/* XXX assumes that caller has room for max size! */
754 
755 			pktinfo = (struct in_pktinfo *)ptr;
756 			pktinfo->ipi_ifindex = ixa->ixa_ifindex;
757 			if (ipp->ipp_fields & IPPF_ADDR)
758 				pktinfo->ipi_spec_dst.s_addr = ipp->ipp_addr_v4;
759 			else
760 				pktinfo->ipi_spec_dst.s_addr = INADDR_ANY;
761 			return (sizeof (struct in_pktinfo));
762 		}
763 		case IP_DONTFRAG:
764 			*i1 = (ixa->ixa_flags & IXAF_DONTFRAG) != 0;
765 			return (sizeof (int));
766 		case IP_TOS:
767 		case T_IP_TOS:
768 			*i1 = (int)ipp->ipp_type_of_service;
769 			break;	/* goto sizeof (int) option return */
770 		case IP_TTL:
771 			*i1 = (int)ipp->ipp_unicast_hops;
772 			break;	/* goto sizeof (int) option return */
773 		case IP_DHCPINIT_IF:
774 			return (-1);
775 		case IP_NEXTHOP:
776 			if (ixa->ixa_flags & IXAF_NEXTHOP_SET) {
777 				*(ipaddr_t *)ptr = ixa->ixa_nexthop_v4;
778 				return (sizeof (ipaddr_t));
779 			} else {
780 				return (0);
781 			}
782 
783 		case IP_MULTICAST_IF:
784 			/* 0 address if not set */
785 			*(ipaddr_t *)ptr = ixa->ixa_multicast_ifaddr;
786 			return (sizeof (ipaddr_t));
787 		case IP_MULTICAST_TTL:
788 			*(uchar_t *)ptr = ixa->ixa_multicast_ttl;
789 			return (sizeof (uchar_t));
790 		case IP_MULTICAST_LOOP:
791 			*ptr = (ixa->ixa_flags & IXAF_MULTICAST_LOOP) ? 1 : 0;
792 			return (sizeof (uint8_t));
793 		case IP_RECVOPTS:
794 			*i1 = connp->conn_recv_ancillary.crb_recvopts;
795 			break;	/* goto sizeof (int) option return */
796 		case IP_RECVDSTADDR:
797 			*i1 = connp->conn_recv_ancillary.crb_recvdstaddr;
798 			break;	/* goto sizeof (int) option return */
799 		case IP_RECVIF:
800 			*i1 = connp->conn_recv_ancillary.crb_recvif;
801 			break;	/* goto sizeof (int) option return */
802 		case IP_RECVSLLA:
803 			*i1 = connp->conn_recv_ancillary.crb_recvslla;
804 			break;	/* goto sizeof (int) option return */
805 		case IP_RECVTTL:
806 			*i1 = connp->conn_recv_ancillary.crb_recvttl;
807 			break;	/* goto sizeof (int) option return */
808 		case IP_RECVTOS:
809 			*i1 = connp->conn_recv_ancillary.crb_recvtos;
810 			break;	/* goto sizeof (int) option return */
811 		case IP_ADD_MEMBERSHIP:
812 		case IP_DROP_MEMBERSHIP:
813 		case MCAST_JOIN_GROUP:
814 		case MCAST_LEAVE_GROUP:
815 		case IP_BLOCK_SOURCE:
816 		case IP_UNBLOCK_SOURCE:
817 		case IP_ADD_SOURCE_MEMBERSHIP:
818 		case IP_DROP_SOURCE_MEMBERSHIP:
819 		case MCAST_BLOCK_SOURCE:
820 		case MCAST_UNBLOCK_SOURCE:
821 		case MCAST_JOIN_SOURCE_GROUP:
822 		case MCAST_LEAVE_SOURCE_GROUP:
823 		case MRT_INIT:
824 		case MRT_DONE:
825 		case MRT_ADD_VIF:
826 		case MRT_DEL_VIF:
827 		case MRT_ADD_MFC:
828 		case MRT_DEL_MFC:
829 			/* cannot "get" the value for these */
830 			return (-1);
831 		case MRT_VERSION:
832 		case MRT_ASSERT:
833 			(void) ip_mrouter_get(name, connp, ptr);
834 			return (sizeof (int));
835 		case IP_SEC_OPT:
836 			return (ipsec_req_from_conn(connp, (ipsec_req_t	*)ptr,
837 			    IPSEC_AF_V4));
838 		case IP_BOUND_IF:
839 			/* Zero if not set */
840 			*i1 = connp->conn_bound_if;
841 			break;	/* goto sizeof (int) option return */
842 		case IP_UNSPEC_SRC:
843 			*i1 = connp->conn_unspec_src;
844 			break;	/* goto sizeof (int) option return */
845 		case IP_BROADCAST_TTL:
846 			if (ixa->ixa_flags & IXAF_BROADCAST_TTL_SET)
847 				*(uchar_t *)ptr = ixa->ixa_broadcast_ttl;
848 			else
849 				*(uchar_t *)ptr = ipst->ips_ip_broadcast_ttl;
850 			return (sizeof (uchar_t));
851 		case IP_MINTTL:
852 			*i1 = connp->conn_min_ttl;
853 			return (sizeof (int));
854 		default:
855 			return (-1);
856 		}
857 		break;
858 	case IPPROTO_IPV6:
859 		if (connp->conn_family != AF_INET6)
860 			return (-1);
861 		switch (name) {
862 		case IPV6_UNICAST_HOPS:
863 			*i1 = (int)ipp->ipp_unicast_hops;
864 			break;	/* goto sizeof (int) option return */
865 		case IPV6_MULTICAST_IF:
866 			/* 0 index if not set */
867 			*i1 = ixa->ixa_multicast_ifindex;
868 			break;	/* goto sizeof (int) option return */
869 		case IPV6_MULTICAST_HOPS:
870 			*i1 = ixa->ixa_multicast_ttl;
871 			break;	/* goto sizeof (int) option return */
872 		case IPV6_MULTICAST_LOOP:
873 			*i1 = (ixa->ixa_flags & IXAF_MULTICAST_LOOP) ? 1 : 0;
874 			break;	/* goto sizeof (int) option return */
875 		case IPV6_JOIN_GROUP:
876 		case IPV6_LEAVE_GROUP:
877 		case MCAST_JOIN_GROUP:
878 		case MCAST_LEAVE_GROUP:
879 		case MCAST_BLOCK_SOURCE:
880 		case MCAST_UNBLOCK_SOURCE:
881 		case MCAST_JOIN_SOURCE_GROUP:
882 		case MCAST_LEAVE_SOURCE_GROUP:
883 			/* cannot "get" the value for these */
884 			return (-1);
885 		case IPV6_BOUND_IF:
886 			/* Zero if not set */
887 			*i1 = connp->conn_bound_if;
888 			break;	/* goto sizeof (int) option return */
889 		case IPV6_UNSPEC_SRC:
890 			*i1 = connp->conn_unspec_src;
891 			break;	/* goto sizeof (int) option return */
892 		case IPV6_RECVPKTINFO:
893 			*i1 = connp->conn_recv_ancillary.crb_ip_recvpktinfo;
894 			break;	/* goto sizeof (int) option return */
895 		case IPV6_RECVTCLASS:
896 			*i1 = connp->conn_recv_ancillary.crb_ipv6_recvtclass;
897 			break;	/* goto sizeof (int) option return */
898 		case IPV6_RECVPATHMTU:
899 			*i1 = connp->conn_ipv6_recvpathmtu;
900 			break;	/* goto sizeof (int) option return */
901 		case IPV6_RECVHOPLIMIT:
902 			*i1 = connp->conn_recv_ancillary.crb_ipv6_recvhoplimit;
903 			break;	/* goto sizeof (int) option return */
904 		case IPV6_RECVHOPOPTS:
905 			*i1 = connp->conn_recv_ancillary.crb_ipv6_recvhopopts;
906 			break;	/* goto sizeof (int) option return */
907 		case IPV6_RECVDSTOPTS:
908 			*i1 = connp->conn_recv_ancillary.crb_ipv6_recvdstopts;
909 			break;	/* goto sizeof (int) option return */
910 		case _OLD_IPV6_RECVDSTOPTS:
911 			*i1 =
912 			    connp->conn_recv_ancillary.crb_old_ipv6_recvdstopts;
913 			break;	/* goto sizeof (int) option return */
914 		case IPV6_RECVRTHDRDSTOPTS:
915 			*i1 = connp->conn_recv_ancillary.
916 			    crb_ipv6_recvrthdrdstopts;
917 			break;	/* goto sizeof (int) option return */
918 		case IPV6_RECVRTHDR:
919 			*i1 = connp->conn_recv_ancillary.crb_ipv6_recvrthdr;
920 			break;	/* goto sizeof (int) option return */
921 		case IPV6_PKTINFO: {
922 			/* XXX assumes that caller has room for max size! */
923 			struct in6_pktinfo *pkti;
924 
925 			pkti = (struct in6_pktinfo *)ptr;
926 			pkti->ipi6_ifindex = ixa->ixa_ifindex;
927 			if (ipp->ipp_fields & IPPF_ADDR)
928 				pkti->ipi6_addr = ipp->ipp_addr;
929 			else
930 				pkti->ipi6_addr = ipv6_all_zeros;
931 			return (sizeof (struct in6_pktinfo));
932 		}
933 		case IPV6_TCLASS:
934 			/*
935 			 * When the connection uses IPv4 on the wire, the
936 			 * traffic class is carried in the Type of Service
937 			 * field of the IPv4 header, which is also set via
938 			 * IP_TOS. Report the current value of that field so
939 			 * that the two options always agree.
940 			 */
941 			if (connp->conn_ipversion == IPV4_VERSION)
942 				*i1 = (int)ipp->ipp_type_of_service;
943 			else
944 				*i1 = ipp->ipp_tclass;
945 			break;	/* goto sizeof (int) option return */
946 		case IPV6_NEXTHOP: {
947 			sin6_t *sin6 = (sin6_t *)ptr;
948 
949 			if (ixa->ixa_flags & IXAF_NEXTHOP_SET)
950 				return (0);
951 
952 			*sin6 = sin6_null;
953 			sin6->sin6_family = AF_INET6;
954 			sin6->sin6_addr = ixa->ixa_nexthop_v6;
955 
956 			return (sizeof (sin6_t));
957 		}
958 		case IPV6_HOPOPTS:
959 			if (!(ipp->ipp_fields & IPPF_HOPOPTS))
960 				return (0);
961 			bcopy(ipp->ipp_hopopts, ptr,
962 			    ipp->ipp_hopoptslen);
963 			return (ipp->ipp_hopoptslen);
964 		case IPV6_RTHDRDSTOPTS:
965 			if (!(ipp->ipp_fields & IPPF_RTHDRDSTOPTS))
966 				return (0);
967 			bcopy(ipp->ipp_rthdrdstopts, ptr,
968 			    ipp->ipp_rthdrdstoptslen);
969 			return (ipp->ipp_rthdrdstoptslen);
970 		case IPV6_RTHDR:
971 			if (!(ipp->ipp_fields & IPPF_RTHDR))
972 				return (0);
973 			bcopy(ipp->ipp_rthdr, ptr, ipp->ipp_rthdrlen);
974 			return (ipp->ipp_rthdrlen);
975 		case IPV6_DSTOPTS:
976 			if (!(ipp->ipp_fields & IPPF_DSTOPTS))
977 				return (0);
978 			bcopy(ipp->ipp_dstopts, ptr, ipp->ipp_dstoptslen);
979 			return (ipp->ipp_dstoptslen);
980 		case IPV6_PATHMTU:
981 			return (ip_fill_mtuinfo(connp, ixa,
982 			    (struct ip6_mtuinfo *)ptr));
983 		case IPV6_SEC_OPT:
984 			return (ipsec_req_from_conn(connp, (ipsec_req_t	*)ptr,
985 			    IPSEC_AF_V6));
986 		case IPV6_SRC_PREFERENCES:
987 			return (ip6_get_src_preferences(ixa, (uint32_t *)ptr));
988 		case IPV6_DONTFRAG:
989 			*i1 = (ixa->ixa_flags & IXAF_DONTFRAG) != 0;
990 			return (sizeof (int));
991 		case IPV6_USE_MIN_MTU:
992 			if (ixa->ixa_flags & IXAF_USE_MIN_MTU)
993 				*i1 = ixa->ixa_use_min_mtu;
994 			else
995 				*i1 = IPV6_USE_MIN_MTU_MULTICAST;
996 			break;
997 		case IPV6_V6ONLY:
998 			*i1 = connp->conn_ipv6_v6only;
999 			return (sizeof (int));
1000 		case IPV6_MINHOPCOUNT:
1001 			*i1 = connp->conn_min_ttl;
1002 			return (sizeof (int));
1003 		default:
1004 			return (-1);
1005 		}
1006 		break;
1007 	case IPPROTO_UDP:
1008 		switch (name) {
1009 		case UDP_ANONPRIVBIND:
1010 			*i1 = connp->conn_anon_priv_bind;
1011 			break;
1012 		case UDP_EXCLBIND:
1013 			*i1 = connp->conn_exclbind ? UDP_EXCLBIND : 0;
1014 			break;
1015 		default:
1016 			return (-1);
1017 		}
1018 		break;
1019 	case IPPROTO_TCP:
1020 		switch (name) {
1021 		case TCP_RECVDSTADDR:
1022 			*i1 = connp->conn_recv_ancillary.crb_recvdstaddr;
1023 			break;
1024 		case TCP_ANONPRIVBIND:
1025 			*i1 = connp->conn_anon_priv_bind;
1026 			break;
1027 		case TCP_EXCLBIND:
1028 			*i1 = connp->conn_exclbind ? TCP_EXCLBIND : 0;
1029 			break;
1030 		default:
1031 			return (-1);
1032 		}
1033 		break;
1034 	default:
1035 		return (-1);
1036 	}
1037 	return (sizeof (int));
1038 }
1039 
1040 static int conn_opt_set_socket(conn_opt_arg_t *coa, t_scalar_t name,
1041     uint_t inlen, uchar_t *invalp, boolean_t checkonly, cred_t *cr);
1042 static int conn_opt_set_ip(conn_opt_arg_t *coa, t_scalar_t name,
1043     uint_t inlen, uchar_t *invalp, boolean_t checkonly, cred_t *cr);
1044 static int conn_opt_set_ipv6(conn_opt_arg_t *coa, t_scalar_t name,
1045     uint_t inlen, uchar_t *invalp, boolean_t checkonly, cred_t *cr);
1046 static int conn_opt_set_udp(conn_opt_arg_t *coa, t_scalar_t name,
1047     uint_t inlen, uchar_t *invalp, boolean_t checkonly, cred_t *cr);
1048 static int conn_opt_set_tcp(conn_opt_arg_t *coa, t_scalar_t name,
1049     uint_t inlen, uchar_t *invalp, boolean_t checkonly, cred_t *cr);
1050 
1051 /*
1052  * This routine sets the most common socket options including some
1053  * that are transport/ULP specific.
1054  * It returns errno or zero.
1055  *
1056  * For fixed length options, there is no sanity check
1057  * of passed in length is done. It is assumed *_optcom_req()
1058  * routines do the right thing.
1059  */
1060 int
1061 conn_opt_set(conn_opt_arg_t *coa, t_scalar_t level, t_scalar_t name,
1062     uint_t inlen, uchar_t *invalp, boolean_t checkonly, cred_t *cr)
1063 {
1064 	ASSERT(MUTEX_NOT_HELD(&coa->coa_connp->conn_lock));
1065 
1066 	/* We have different functions for different levels */
1067 	switch (level) {
1068 	case SOL_SOCKET:
1069 		return (conn_opt_set_socket(coa, name, inlen, invalp,
1070 		    checkonly, cr));
1071 	case IPPROTO_IP:
1072 		return (conn_opt_set_ip(coa, name, inlen, invalp,
1073 		    checkonly, cr));
1074 	case IPPROTO_IPV6:
1075 		return (conn_opt_set_ipv6(coa, name, inlen, invalp,
1076 		    checkonly, cr));
1077 	case IPPROTO_UDP:
1078 		return (conn_opt_set_udp(coa, name, inlen, invalp,
1079 		    checkonly, cr));
1080 	case IPPROTO_TCP:
1081 		return (conn_opt_set_tcp(coa, name, inlen, invalp,
1082 		    checkonly, cr));
1083 	default:
1084 		return (0);
1085 	}
1086 }
1087 
1088 /*
1089  * Handle SOL_SOCKET
1090  * Note that we do not handle SO_PROTOTYPE here. The ULPs that support
1091  * it implement their own checks and setting of conn_proto.
1092  */
1093 /* ARGSUSED1 */
1094 static int
1095 conn_opt_set_socket(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen,
1096     uchar_t *invalp, boolean_t checkonly, cred_t *cr)
1097 {
1098 	conn_t		*connp = coa->coa_connp;
1099 	ip_xmit_attr_t	*ixa = coa->coa_ixa;
1100 	int		*i1 = (int *)invalp;
1101 	boolean_t	onoff = (*i1 == 0) ? 0 : 1;
1102 
1103 	switch (name) {
1104 	case SO_ALLZONES:
1105 		if (IPCL_IS_BOUND(connp))
1106 			return (EINVAL);
1107 		break;
1108 	case SO_VRRP:
1109 		if (secpolicy_ip_config(cr, checkonly) != 0)
1110 			return (EACCES);
1111 		break;
1112 	case SO_MAC_EXEMPT:
1113 		if (secpolicy_net_mac_aware(cr) != 0)
1114 			return (EACCES);
1115 		if (IPCL_IS_BOUND(connp))
1116 			return (EINVAL);
1117 		break;
1118 	case SO_MAC_IMPLICIT:
1119 		if (secpolicy_net_mac_implicit(cr) != 0)
1120 			return (EACCES);
1121 		break;
1122 	}
1123 	if (checkonly)
1124 		return (0);
1125 
1126 	mutex_enter(&connp->conn_lock);
1127 	/* Here we set the actual option value */
1128 	switch (name) {
1129 	case SO_DEBUG:
1130 		connp->conn_debug = onoff;
1131 		break;
1132 	case SO_KEEPALIVE:
1133 		connp->conn_keepalive = onoff;
1134 		break;
1135 	case SO_LINGER: {
1136 		struct linger *lgr = (struct linger *)invalp;
1137 
1138 		if (lgr->l_onoff) {
1139 			connp->conn_linger = 1;
1140 			connp->conn_lingertime = lgr->l_linger;
1141 		} else {
1142 			connp->conn_linger = 0;
1143 			connp->conn_lingertime = 0;
1144 		}
1145 		break;
1146 	}
1147 	case SO_OOBINLINE:
1148 		connp->conn_oobinline = onoff;
1149 		coa->coa_changed |= COA_OOBINLINE_CHANGED;
1150 		break;
1151 	case SO_REUSEADDR:
1152 		connp->conn_reuseaddr = onoff;
1153 		break;
1154 	case SO_DONTROUTE:
1155 		if (onoff)
1156 			ixa->ixa_flags |= IXAF_DONTROUTE;
1157 		else
1158 			ixa->ixa_flags &= ~IXAF_DONTROUTE;
1159 		coa->coa_changed |= COA_ROUTE_CHANGED;
1160 		break;
1161 	case SO_USELOOPBACK:
1162 		connp->conn_useloopback = onoff;
1163 		break;
1164 	case SO_BROADCAST:
1165 		connp->conn_broadcast = onoff;
1166 		break;
1167 	case SO_SNDBUF:
1168 		/* ULP has range checked the value */
1169 		connp->conn_sndbuf = *i1;
1170 		coa->coa_changed |= COA_SNDBUF_CHANGED;
1171 		break;
1172 	case SO_RCVBUF:
1173 		/* ULP has range checked the value */
1174 		connp->conn_rcvbuf = *i1;
1175 		coa->coa_changed |= COA_RCVBUF_CHANGED;
1176 		break;
1177 	case SO_RCVTIMEO:
1178 	case SO_SNDTIMEO:
1179 		/*
1180 		 * Pass these two options in order for third part
1181 		 * protocol usage.
1182 		 */
1183 		break;
1184 	case SO_DGRAM_ERRIND:
1185 		connp->conn_dgram_errind = onoff;
1186 		break;
1187 	case SO_RECVUCRED:
1188 		connp->conn_recv_ancillary.crb_recvucred = onoff;
1189 		break;
1190 	case SO_ALLZONES:
1191 		connp->conn_allzones = onoff;
1192 		coa->coa_changed |= COA_ROUTE_CHANGED;
1193 		if (onoff)
1194 			ixa->ixa_zoneid = ALL_ZONES;
1195 		else
1196 			ixa->ixa_zoneid = connp->conn_zoneid;
1197 		break;
1198 	case SO_TIMESTAMP:
1199 		connp->conn_recv_ancillary.crb_timestamp = onoff;
1200 		break;
1201 	case SO_VRRP:
1202 		connp->conn_isvrrp = onoff;
1203 		break;
1204 	case SO_ANON_MLP:
1205 		connp->conn_anon_mlp = onoff;
1206 		break;
1207 	case SO_MAC_EXEMPT:
1208 		connp->conn_mac_mode = onoff ?
1209 		    CONN_MAC_AWARE : CONN_MAC_DEFAULT;
1210 		break;
1211 	case SO_MAC_IMPLICIT:
1212 		connp->conn_mac_mode = onoff ?
1213 		    CONN_MAC_IMPLICIT : CONN_MAC_DEFAULT;
1214 		break;
1215 	case SO_EXCLBIND:
1216 		connp->conn_exclbind = onoff;
1217 		break;
1218 	}
1219 	mutex_exit(&connp->conn_lock);
1220 	return (0);
1221 }
1222 
1223 /* Handle IPPROTO_IP */
1224 static int
1225 conn_opt_set_ip(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen,
1226     uchar_t *invalp, boolean_t checkonly, cred_t *cr)
1227 {
1228 	conn_t		*connp = coa->coa_connp;
1229 	ip_xmit_attr_t	*ixa = coa->coa_ixa;
1230 	ip_pkt_t	*ipp = coa->coa_ipp;
1231 	int		*i1 = (int *)invalp;
1232 	boolean_t	onoff = (*i1 == 0) ? 0 : 1;
1233 	ipaddr_t	addr = (ipaddr_t)*i1;
1234 	uint_t		ifindex;
1235 	zoneid_t	zoneid = IPCL_ZONEID(connp);
1236 	ipif_t		*ipif;
1237 	ip_stack_t	*ipst = connp->conn_netstack->netstack_ip;
1238 	int		error;
1239 
1240 	/*
1241 	 * IPPROTO_IP options are supported whenever the connection uses
1242 	 * IPv4 on the wire, which includes AF_INET6 sockets whose peers
1243 	 * are IPv4-mapped IPv6 addresses.
1244 	 */
1245 	if (connp->conn_ipversion != IPV4_VERSION)
1246 		return (EINVAL);
1247 
1248 	ifindex = UINT_MAX;
1249 	switch (name) {
1250 	case IP_TTL:
1251 		/* Don't allow zero */
1252 		if (*i1 < 1 || *i1 > MAXTTL)
1253 			return (EINVAL);
1254 		break;
1255 	case IP_MULTICAST_IF:
1256 		if (addr == INADDR_ANY) {
1257 			/* Clear */
1258 			ifindex = 0;
1259 			break;
1260 		}
1261 		ipif = ipif_lookup_addr(addr, NULL, zoneid, ipst);
1262 		if (ipif == NULL)
1263 			return (EHOSTUNREACH);
1264 		/* not supported by the virtual network iface */
1265 		if (IS_VNI(ipif->ipif_ill)) {
1266 			ipif_refrele(ipif);
1267 			return (EINVAL);
1268 		}
1269 		ifindex = ipif->ipif_ill->ill_phyint->phyint_ifindex;
1270 		ipif_refrele(ipif);
1271 		break;
1272 	case IP_NEXTHOP: {
1273 		ire_t	*ire;
1274 
1275 		if (addr == INADDR_ANY) {
1276 			/* Clear */
1277 			break;
1278 		}
1279 		/* Verify that the next-hop is on-link */
1280 		ire = ire_ftable_lookup_v4(addr, 0, 0, IRE_ONLINK, NULL, zoneid,
1281 		    NULL, MATCH_IRE_TYPE, 0, ipst, NULL);
1282 		if (ire == NULL)
1283 			return (EHOSTUNREACH);
1284 		ire_refrele(ire);
1285 		break;
1286 	}
1287 	case IP_OPTIONS:
1288 	case T_IP_OPTIONS: {
1289 		uint_t newlen;
1290 
1291 		if (ipp->ipp_fields & IPPF_LABEL_V4)
1292 			newlen = inlen + (ipp->ipp_label_len_v4 + 3) & ~3;
1293 		else
1294 			newlen = inlen;
1295 		if ((inlen & 0x3) || newlen > IP_MAX_OPT_LENGTH) {
1296 			return (EINVAL);
1297 		}
1298 		break;
1299 	}
1300 	case IP_PKTINFO: {
1301 		struct in_pktinfo *pktinfo;
1302 
1303 		/* Two different valid lengths */
1304 		if (inlen != sizeof (int) &&
1305 		    inlen != sizeof (struct in_pktinfo))
1306 			return (EINVAL);
1307 		if (inlen == sizeof (int))
1308 			break;
1309 
1310 		pktinfo = (struct in_pktinfo *)invalp;
1311 		if (pktinfo->ipi_spec_dst.s_addr != INADDR_ANY) {
1312 			switch (ip_laddr_verify_v4(pktinfo->ipi_spec_dst.s_addr,
1313 			    zoneid, ipst, B_FALSE)) {
1314 			case IPVL_UNICAST_UP:
1315 			case IPVL_UNICAST_DOWN:
1316 				break;
1317 			default:
1318 				return (EADDRNOTAVAIL);
1319 			}
1320 		}
1321 		if (!ip_xmit_ifindex_valid(pktinfo->ipi_ifindex, zoneid,
1322 		    B_FALSE, ipst))
1323 			return (ENXIO);
1324 		break;
1325 	}
1326 	case IP_BOUND_IF:
1327 		ifindex = *(uint_t *)i1;
1328 
1329 		/* Just check it is ok. */
1330 		if (!ip_xmit_ifindex_valid(ifindex, zoneid, B_FALSE, ipst))
1331 			return (ENXIO);
1332 		break;
1333 	case IP_MINTTL:
1334 		if (*i1 < 0 || *i1 > MAXTTL)
1335 			return (EINVAL);
1336 		break;
1337 	}
1338 	if (checkonly)
1339 		return (0);
1340 
1341 	/* Here we set the actual option value */
1342 	/*
1343 	 * conn_lock protects the bitfields, and is used to
1344 	 * set the fields atomically. Not needed for ixa settings since
1345 	 * the caller has an exclusive copy of the ixa.
1346 	 * We can not hold conn_lock across the multicast options though.
1347 	 */
1348 	switch (name) {
1349 	case IP_OPTIONS:
1350 	case T_IP_OPTIONS:
1351 		/* Save options for use by IP. */
1352 		mutex_enter(&connp->conn_lock);
1353 		error = optcom_pkt_set(invalp, inlen,
1354 		    (uchar_t **)&ipp->ipp_ipv4_options,
1355 		    &ipp->ipp_ipv4_options_len);
1356 		if (error != 0) {
1357 			mutex_exit(&connp->conn_lock);
1358 			return (error);
1359 		}
1360 		if (ipp->ipp_ipv4_options_len == 0) {
1361 			ipp->ipp_fields &= ~IPPF_IPV4_OPTIONS;
1362 		} else {
1363 			ipp->ipp_fields |= IPPF_IPV4_OPTIONS;
1364 		}
1365 		mutex_exit(&connp->conn_lock);
1366 		coa->coa_changed |= COA_HEADER_CHANGED;
1367 		coa->coa_changed |= COA_WROFF_CHANGED;
1368 		break;
1369 
1370 	case IP_TTL:
1371 		mutex_enter(&connp->conn_lock);
1372 		ipp->ipp_unicast_hops = *i1;
1373 		mutex_exit(&connp->conn_lock);
1374 		coa->coa_changed |= COA_HEADER_CHANGED;
1375 		break;
1376 	case IP_TOS:
1377 	case T_IP_TOS:
1378 		mutex_enter(&connp->conn_lock);
1379 		if (*i1 == -1) {
1380 			ipp->ipp_type_of_service = 0;
1381 		} else {
1382 			ipp->ipp_type_of_service = *i1;
1383 		}
1384 		mutex_exit(&connp->conn_lock);
1385 		coa->coa_changed |= COA_HEADER_CHANGED;
1386 		break;
1387 	case IP_MULTICAST_IF:
1388 		ixa->ixa_multicast_ifindex = ifindex;
1389 		ixa->ixa_multicast_ifaddr = addr;
1390 		coa->coa_changed |= COA_ROUTE_CHANGED;
1391 		break;
1392 	case IP_MULTICAST_TTL:
1393 		ixa->ixa_multicast_ttl = *invalp;
1394 		/* Handled automatically by ip_output */
1395 		break;
1396 	case IP_MULTICAST_LOOP:
1397 		if (*invalp != 0)
1398 			ixa->ixa_flags |= IXAF_MULTICAST_LOOP;
1399 		else
1400 			ixa->ixa_flags &= ~IXAF_MULTICAST_LOOP;
1401 		/* Handled automatically by ip_output */
1402 		break;
1403 	case IP_RECVOPTS:
1404 		mutex_enter(&connp->conn_lock);
1405 		connp->conn_recv_ancillary.crb_recvopts = onoff;
1406 		mutex_exit(&connp->conn_lock);
1407 		break;
1408 	case IP_RECVDSTADDR:
1409 		mutex_enter(&connp->conn_lock);
1410 		connp->conn_recv_ancillary.crb_recvdstaddr = onoff;
1411 		mutex_exit(&connp->conn_lock);
1412 		break;
1413 	case IP_RECVIF:
1414 		mutex_enter(&connp->conn_lock);
1415 		connp->conn_recv_ancillary.crb_recvif = onoff;
1416 		mutex_exit(&connp->conn_lock);
1417 		break;
1418 	case IP_RECVSLLA:
1419 		mutex_enter(&connp->conn_lock);
1420 		connp->conn_recv_ancillary.crb_recvslla = onoff;
1421 		mutex_exit(&connp->conn_lock);
1422 		break;
1423 	case IP_RECVTTL:
1424 		mutex_enter(&connp->conn_lock);
1425 		connp->conn_recv_ancillary.crb_recvttl = onoff;
1426 		mutex_exit(&connp->conn_lock);
1427 		break;
1428 	case IP_RECVTOS:
1429 		mutex_enter(&connp->conn_lock);
1430 		connp->conn_recv_ancillary.crb_recvtos = onoff;
1431 		mutex_exit(&connp->conn_lock);
1432 		break;
1433 	case IP_PKTINFO: {
1434 		/*
1435 		 * This also handles IP_RECVPKTINFO.
1436 		 * IP_PKTINFO and IP_RECVPKTINFO have same value.
1437 		 * Differentiation is based on the size of the
1438 		 * argument passed in.
1439 		 */
1440 		struct in_pktinfo *pktinfo;
1441 
1442 		if (inlen == sizeof (int)) {
1443 			/* This is IP_RECVPKTINFO option. */
1444 			mutex_enter(&connp->conn_lock);
1445 			connp->conn_recv_ancillary.crb_ip_recvpktinfo =
1446 			    onoff;
1447 			mutex_exit(&connp->conn_lock);
1448 			break;
1449 		}
1450 
1451 		/* This is IP_PKTINFO option. */
1452 		mutex_enter(&connp->conn_lock);
1453 		pktinfo = (struct in_pktinfo *)invalp;
1454 		if (pktinfo->ipi_spec_dst.s_addr != INADDR_ANY) {
1455 			ipp->ipp_fields |= IPPF_ADDR;
1456 			IN6_INADDR_TO_V4MAPPED(&pktinfo->ipi_spec_dst,
1457 			    &ipp->ipp_addr);
1458 		} else {
1459 			ipp->ipp_fields &= ~IPPF_ADDR;
1460 			ipp->ipp_addr = ipv6_all_zeros;
1461 		}
1462 		mutex_exit(&connp->conn_lock);
1463 		ixa->ixa_ifindex = pktinfo->ipi_ifindex;
1464 		coa->coa_changed |= COA_ROUTE_CHANGED;
1465 		coa->coa_changed |= COA_HEADER_CHANGED;
1466 		break;
1467 	}
1468 	case IP_DONTFRAG:
1469 		if (onoff) {
1470 			ixa->ixa_flags |= (IXAF_DONTFRAG | IXAF_PMTU_IPV4_DF);
1471 			ixa->ixa_flags &= ~IXAF_PMTU_DISCOVERY;
1472 		} else {
1473 			ixa->ixa_flags &= ~(IXAF_DONTFRAG | IXAF_PMTU_IPV4_DF);
1474 			ixa->ixa_flags |= IXAF_PMTU_DISCOVERY;
1475 		}
1476 		/* Need to redo ip_attr_connect */
1477 		coa->coa_changed |= COA_ROUTE_CHANGED;
1478 		break;
1479 	case IP_ADD_MEMBERSHIP:
1480 	case IP_DROP_MEMBERSHIP:
1481 	case MCAST_JOIN_GROUP:
1482 	case MCAST_LEAVE_GROUP:
1483 		return (ip_opt_set_multicast_group(connp, name,
1484 		    invalp, B_FALSE, checkonly));
1485 
1486 	case IP_BLOCK_SOURCE:
1487 	case IP_UNBLOCK_SOURCE:
1488 	case IP_ADD_SOURCE_MEMBERSHIP:
1489 	case IP_DROP_SOURCE_MEMBERSHIP:
1490 	case MCAST_BLOCK_SOURCE:
1491 	case MCAST_UNBLOCK_SOURCE:
1492 	case MCAST_JOIN_SOURCE_GROUP:
1493 	case MCAST_LEAVE_SOURCE_GROUP:
1494 		return (ip_opt_set_multicast_sources(connp, name,
1495 		    invalp, B_FALSE, checkonly));
1496 
1497 	case IP_SEC_OPT:
1498 		mutex_enter(&connp->conn_lock);
1499 		error = ipsec_set_req(cr, connp, (ipsec_req_t *)invalp);
1500 		mutex_exit(&connp->conn_lock);
1501 		if (error != 0) {
1502 			return (error);
1503 		}
1504 		/* This is an IPsec policy change - redo ip_attr_connect */
1505 		coa->coa_changed |= COA_ROUTE_CHANGED;
1506 		break;
1507 	case IP_NEXTHOP:
1508 		ixa->ixa_nexthop_v4 = addr;
1509 		if (addr != INADDR_ANY)
1510 			ixa->ixa_flags |= IXAF_NEXTHOP_SET;
1511 		else
1512 			ixa->ixa_flags &= ~IXAF_NEXTHOP_SET;
1513 		coa->coa_changed |= COA_ROUTE_CHANGED;
1514 		break;
1515 
1516 	case IP_BOUND_IF:
1517 		ixa->ixa_ifindex = ifindex;		/* Send */
1518 		mutex_enter(&connp->conn_lock);
1519 		connp->conn_incoming_ifindex = ifindex;	/* Receive */
1520 		connp->conn_bound_if = ifindex;		/* getsockopt */
1521 		mutex_exit(&connp->conn_lock);
1522 		coa->coa_changed |= COA_ROUTE_CHANGED;
1523 		break;
1524 	case IP_UNSPEC_SRC:
1525 		mutex_enter(&connp->conn_lock);
1526 		connp->conn_unspec_src = onoff;
1527 		if (onoff)
1528 			ixa->ixa_flags &= ~IXAF_VERIFY_SOURCE;
1529 		else
1530 			ixa->ixa_flags |= IXAF_VERIFY_SOURCE;
1531 
1532 		mutex_exit(&connp->conn_lock);
1533 		break;
1534 	case IP_BROADCAST_TTL:
1535 		ixa->ixa_broadcast_ttl = *invalp;
1536 		ixa->ixa_flags |= IXAF_BROADCAST_TTL_SET;
1537 		/* Handled automatically by ip_output */
1538 		break;
1539 	case MRT_INIT:
1540 	case MRT_DONE:
1541 	case MRT_ADD_VIF:
1542 	case MRT_DEL_VIF:
1543 	case MRT_ADD_MFC:
1544 	case MRT_DEL_MFC:
1545 	case MRT_ASSERT:
1546 		if ((error = secpolicy_ip_config(cr, B_FALSE)) != 0) {
1547 			return (error);
1548 		}
1549 		error = ip_mrouter_set((int)name, connp, checkonly,
1550 		    (uchar_t *)invalp, inlen);
1551 		if (error) {
1552 			return (error);
1553 		}
1554 		return (0);
1555 	case IP_MINTTL:
1556 		mutex_enter(&connp->conn_lock);
1557 		connp->conn_min_ttl = *i1;
1558 		mutex_exit(&connp->conn_lock);
1559 		break;
1560 	}
1561 	return (0);
1562 }
1563 
1564 /* Handle IPPROTO_IPV6 */
1565 static int
1566 conn_opt_set_ipv6(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen,
1567     uchar_t *invalp, boolean_t checkonly, cred_t *cr)
1568 {
1569 	conn_t		*connp = coa->coa_connp;
1570 	ip_xmit_attr_t	*ixa = coa->coa_ixa;
1571 	ip_pkt_t	*ipp = coa->coa_ipp;
1572 	int		*i1 = (int *)invalp;
1573 	boolean_t	onoff = (*i1 == 0) ? 0 : 1;
1574 	uint_t		ifindex;
1575 	zoneid_t	zoneid = IPCL_ZONEID(connp);
1576 	ip_stack_t	*ipst = connp->conn_netstack->netstack_ip;
1577 	int		error;
1578 
1579 	if (connp->conn_family != AF_INET6)
1580 		return (EINVAL);
1581 
1582 	ifindex = UINT_MAX;
1583 	switch (name) {
1584 	case IPV6_MULTICAST_IF:
1585 		/*
1586 		 * The only possible error is EINVAL.
1587 		 * We call this option on both V4 and V6
1588 		 * If both fail, then this call returns
1589 		 * EINVAL. If at least one of them succeeds we
1590 		 * return success.
1591 		 */
1592 		ifindex = *(uint_t *)i1;
1593 
1594 		if (!ip_xmit_ifindex_valid(ifindex, zoneid, B_TRUE, ipst) &&
1595 		    !ip_xmit_ifindex_valid(ifindex, zoneid, B_FALSE, ipst))
1596 			return (EINVAL);
1597 		break;
1598 	case IPV6_UNICAST_HOPS:
1599 		/* Don't allow zero. -1 means to use default */
1600 		if (*i1 < -1 || *i1 == 0 || *i1 > IPV6_MAX_HOPS)
1601 			return (EINVAL);
1602 		break;
1603 	case IPV6_MULTICAST_HOPS:
1604 		/* -1 means use default */
1605 		if (*i1 < -1 || *i1 > IPV6_MAX_HOPS)
1606 			return (EINVAL);
1607 		break;
1608 	case IPV6_MULTICAST_LOOP:
1609 		if (*i1 != 0 && *i1 != 1)
1610 			return (EINVAL);
1611 		break;
1612 	case IPV6_BOUND_IF:
1613 		ifindex = *(uint_t *)i1;
1614 
1615 		if (!ip_xmit_ifindex_valid(ifindex, zoneid, B_TRUE, ipst))
1616 			return (ENXIO);
1617 		break;
1618 	case IPV6_PKTINFO: {
1619 		struct in6_pktinfo *pkti;
1620 		boolean_t isv6;
1621 
1622 		if (inlen != 0 && inlen != sizeof (struct in6_pktinfo))
1623 			return (EINVAL);
1624 		if (inlen == 0)
1625 			break;	/* Clear values below */
1626 
1627 		/*
1628 		 * Verify the source address and ifindex. Privileged users
1629 		 * can use any source address.
1630 		 */
1631 		pkti = (struct in6_pktinfo *)invalp;
1632 
1633 		/*
1634 		 * For link-local addresses we use the ipi6_ifindex when
1635 		 * we verify the local address.
1636 		 * If net_rawaccess then any source address can be used.
1637 		 */
1638 		if (!IN6_IS_ADDR_UNSPECIFIED(&pkti->ipi6_addr) &&
1639 		    secpolicy_net_rawaccess(cr) != 0) {
1640 			uint_t scopeid = 0;
1641 			in6_addr_t *v6src = &pkti->ipi6_addr;
1642 			ipaddr_t v4src;
1643 			ip_laddr_t laddr_type = IPVL_UNICAST_UP;
1644 
1645 			if (IN6_IS_ADDR_V4MAPPED(v6src)) {
1646 				IN6_V4MAPPED_TO_IPADDR(v6src, v4src);
1647 				if (v4src != INADDR_ANY) {
1648 					laddr_type = ip_laddr_verify_v4(v4src,
1649 					    zoneid, ipst, B_FALSE);
1650 				}
1651 			} else {
1652 				if (IN6_IS_ADDR_LINKSCOPE(v6src))
1653 					scopeid = pkti->ipi6_ifindex;
1654 
1655 				laddr_type = ip_laddr_verify_v6(v6src, zoneid,
1656 				    ipst, B_FALSE, scopeid);
1657 			}
1658 			switch (laddr_type) {
1659 			case IPVL_UNICAST_UP:
1660 			case IPVL_UNICAST_DOWN:
1661 				break;
1662 			default:
1663 				return (EADDRNOTAVAIL);
1664 			}
1665 			ixa->ixa_flags |= IXAF_VERIFY_SOURCE;
1666 		} else if (!IN6_IS_ADDR_UNSPECIFIED(&pkti->ipi6_addr)) {
1667 			/* Allow any source */
1668 			ixa->ixa_flags &= ~IXAF_VERIFY_SOURCE;
1669 		}
1670 		isv6 = !(IN6_IS_ADDR_V4MAPPED(&pkti->ipi6_addr));
1671 		if (!ip_xmit_ifindex_valid(pkti->ipi6_ifindex, zoneid, isv6,
1672 		    ipst))
1673 			return (ENXIO);
1674 		break;
1675 	}
1676 	case IPV6_HOPLIMIT:
1677 		/* It is only allowed as ancilary data */
1678 		if (!coa->coa_ancillary)
1679 			return (EINVAL);
1680 
1681 		if (inlen != 0 && inlen != sizeof (int))
1682 			return (EINVAL);
1683 		if (inlen == sizeof (int)) {
1684 			if (*i1 > IPV6_MAX_HOPS || *i1 < -1 || *i1 == 0)
1685 				return (EINVAL);
1686 		}
1687 		break;
1688 	case IPV6_TCLASS:
1689 		if (inlen != 0 && inlen != sizeof (int))
1690 			return (EINVAL);
1691 		if (inlen == sizeof (int)) {
1692 			if (*i1 > 255 || *i1 < -1)
1693 				return (EINVAL);
1694 		}
1695 		break;
1696 	case IPV6_NEXTHOP:
1697 		if (inlen != 0 && inlen != sizeof (sin6_t))
1698 			return (EINVAL);
1699 		if (inlen == sizeof (sin6_t)) {
1700 			sin6_t *sin6 = (sin6_t *)invalp;
1701 			ire_t	*ire;
1702 
1703 			if (sin6->sin6_family != AF_INET6)
1704 				return (EAFNOSUPPORT);
1705 			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
1706 				return (EADDRNOTAVAIL);
1707 
1708 			/* Verify that the next-hop is on-link */
1709 			ire = ire_ftable_lookup_v6(&sin6->sin6_addr,
1710 			    0, 0, IRE_ONLINK, NULL, zoneid,
1711 			    NULL, MATCH_IRE_TYPE, 0, ipst, NULL);
1712 			if (ire == NULL)
1713 				return (EHOSTUNREACH);
1714 			ire_refrele(ire);
1715 			break;
1716 		}
1717 		break;
1718 	case IPV6_RTHDR:
1719 	case IPV6_DSTOPTS:
1720 	case IPV6_RTHDRDSTOPTS:
1721 	case IPV6_HOPOPTS: {
1722 		/* All have the length field in the same place */
1723 		ip6_hbh_t *hopts = (ip6_hbh_t *)invalp;
1724 		/*
1725 		 * Sanity checks - minimum size, size a multiple of
1726 		 * eight bytes, and matching size passed in.
1727 		 */
1728 		if (inlen != 0 &&
1729 		    inlen != (8 * (hopts->ip6h_len + 1)))
1730 			return (EINVAL);
1731 		break;
1732 	}
1733 	case IPV6_PATHMTU:
1734 		/* Can't be set */
1735 		return (EINVAL);
1736 
1737 	case IPV6_USE_MIN_MTU:
1738 		if (inlen != sizeof (int))
1739 			return (EINVAL);
1740 		if (*i1 < -1 || *i1 > 1)
1741 			return (EINVAL);
1742 		break;
1743 	case IPV6_SRC_PREFERENCES:
1744 		if (inlen != sizeof (uint32_t))
1745 			return (EINVAL);
1746 		break;
1747 	case IPV6_V6ONLY:
1748 		if (*i1 < 0 || *i1 > 1) {
1749 			return (EINVAL);
1750 		}
1751 		break;
1752 	case IPV6_MINHOPCOUNT:
1753 		if (*i1 < 0 || *i1 > IPV6_MAX_HOPS)
1754 			return (EINVAL);
1755 		break;
1756 	}
1757 	if (checkonly)
1758 		return (0);
1759 
1760 	/* Here we set the actual option value */
1761 	/*
1762 	 * conn_lock protects the bitfields, and is used to
1763 	 * set the fields atomically. Not needed for ixa settings since
1764 	 * the caller has an exclusive copy of the ixa.
1765 	 * We can not hold conn_lock across the multicast options though.
1766 	 */
1767 	ASSERT(MUTEX_NOT_HELD(&coa->coa_connp->conn_lock));
1768 	switch (name) {
1769 	case IPV6_MULTICAST_IF:
1770 		ixa->ixa_multicast_ifindex = ifindex;
1771 		/* Need to redo ip_attr_connect */
1772 		coa->coa_changed |= COA_ROUTE_CHANGED;
1773 		break;
1774 	case IPV6_UNICAST_HOPS:
1775 		/* -1 means use default */
1776 		mutex_enter(&connp->conn_lock);
1777 		if (*i1 == -1) {
1778 			ipp->ipp_unicast_hops = connp->conn_default_ttl;
1779 		} else {
1780 			ipp->ipp_unicast_hops = (uint8_t)*i1;
1781 		}
1782 		mutex_exit(&connp->conn_lock);
1783 		coa->coa_changed |= COA_HEADER_CHANGED;
1784 		break;
1785 	case IPV6_MULTICAST_HOPS:
1786 		/* -1 means use default */
1787 		if (*i1 == -1) {
1788 			ixa->ixa_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
1789 		} else {
1790 			ixa->ixa_multicast_ttl = (uint8_t)*i1;
1791 		}
1792 		/* Handled automatically by ip_output */
1793 		break;
1794 	case IPV6_MULTICAST_LOOP:
1795 		if (*i1 != 0)
1796 			ixa->ixa_flags |= IXAF_MULTICAST_LOOP;
1797 		else
1798 			ixa->ixa_flags &= ~IXAF_MULTICAST_LOOP;
1799 		/* Handled automatically by ip_output */
1800 		break;
1801 	case IPV6_JOIN_GROUP:
1802 	case IPV6_LEAVE_GROUP:
1803 	case MCAST_JOIN_GROUP:
1804 	case MCAST_LEAVE_GROUP:
1805 		return (ip_opt_set_multicast_group(connp, name,
1806 		    invalp, B_TRUE, checkonly));
1807 
1808 	case MCAST_BLOCK_SOURCE:
1809 	case MCAST_UNBLOCK_SOURCE:
1810 	case MCAST_JOIN_SOURCE_GROUP:
1811 	case MCAST_LEAVE_SOURCE_GROUP:
1812 		return (ip_opt_set_multicast_sources(connp, name,
1813 		    invalp, B_TRUE, checkonly));
1814 
1815 	case IPV6_BOUND_IF:
1816 		ixa->ixa_ifindex = ifindex;		/* Send */
1817 		mutex_enter(&connp->conn_lock);
1818 		connp->conn_incoming_ifindex = ifindex;	/* Receive */
1819 		connp->conn_bound_if = ifindex;		/* getsockopt */
1820 		mutex_exit(&connp->conn_lock);
1821 		coa->coa_changed |= COA_ROUTE_CHANGED;
1822 		break;
1823 	case IPV6_UNSPEC_SRC:
1824 		mutex_enter(&connp->conn_lock);
1825 		connp->conn_unspec_src = onoff;
1826 		if (onoff)
1827 			ixa->ixa_flags &= ~IXAF_VERIFY_SOURCE;
1828 		else
1829 			ixa->ixa_flags |= IXAF_VERIFY_SOURCE;
1830 		mutex_exit(&connp->conn_lock);
1831 		break;
1832 	case IPV6_RECVPKTINFO:
1833 		mutex_enter(&connp->conn_lock);
1834 		connp->conn_recv_ancillary.crb_ip_recvpktinfo = onoff;
1835 		mutex_exit(&connp->conn_lock);
1836 		break;
1837 	case IPV6_RECVTCLASS:
1838 		mutex_enter(&connp->conn_lock);
1839 		connp->conn_recv_ancillary.crb_ipv6_recvtclass = onoff;
1840 		mutex_exit(&connp->conn_lock);
1841 		break;
1842 	case IPV6_RECVPATHMTU:
1843 		mutex_enter(&connp->conn_lock);
1844 		connp->conn_ipv6_recvpathmtu = onoff;
1845 		mutex_exit(&connp->conn_lock);
1846 		break;
1847 	case IPV6_RECVHOPLIMIT:
1848 		mutex_enter(&connp->conn_lock);
1849 		connp->conn_recv_ancillary.crb_ipv6_recvhoplimit =
1850 		    onoff;
1851 		mutex_exit(&connp->conn_lock);
1852 		break;
1853 	case IPV6_RECVHOPOPTS:
1854 		mutex_enter(&connp->conn_lock);
1855 		connp->conn_recv_ancillary.crb_ipv6_recvhopopts = onoff;
1856 		mutex_exit(&connp->conn_lock);
1857 		break;
1858 	case IPV6_RECVDSTOPTS:
1859 		mutex_enter(&connp->conn_lock);
1860 		connp->conn_recv_ancillary.crb_ipv6_recvdstopts = onoff;
1861 		mutex_exit(&connp->conn_lock);
1862 		break;
1863 	case _OLD_IPV6_RECVDSTOPTS:
1864 		mutex_enter(&connp->conn_lock);
1865 		connp->conn_recv_ancillary.crb_old_ipv6_recvdstopts =
1866 		    onoff;
1867 		mutex_exit(&connp->conn_lock);
1868 		break;
1869 	case IPV6_RECVRTHDRDSTOPTS:
1870 		mutex_enter(&connp->conn_lock);
1871 		connp->conn_recv_ancillary.crb_ipv6_recvrthdrdstopts =
1872 		    onoff;
1873 		mutex_exit(&connp->conn_lock);
1874 		break;
1875 	case IPV6_RECVRTHDR:
1876 		mutex_enter(&connp->conn_lock);
1877 		connp->conn_recv_ancillary.crb_ipv6_recvrthdr = onoff;
1878 		mutex_exit(&connp->conn_lock);
1879 		break;
1880 	case IPV6_PKTINFO:
1881 		mutex_enter(&connp->conn_lock);
1882 		if (inlen == 0) {
1883 			ipp->ipp_fields &= ~IPPF_ADDR;
1884 			ipp->ipp_addr = ipv6_all_zeros;
1885 			ixa->ixa_ifindex = 0;
1886 		} else {
1887 			struct in6_pktinfo *pkti;
1888 
1889 			pkti = (struct in6_pktinfo *)invalp;
1890 			ipp->ipp_addr = pkti->ipi6_addr;
1891 			if (!IN6_IS_ADDR_UNSPECIFIED(&ipp->ipp_addr))
1892 				ipp->ipp_fields |= IPPF_ADDR;
1893 			else
1894 				ipp->ipp_fields &= ~IPPF_ADDR;
1895 			ixa->ixa_ifindex = pkti->ipi6_ifindex;
1896 		}
1897 		mutex_exit(&connp->conn_lock);
1898 		/* Source and ifindex might have changed */
1899 		coa->coa_changed |= COA_HEADER_CHANGED;
1900 		coa->coa_changed |= COA_ROUTE_CHANGED;
1901 		break;
1902 	case IPV6_HOPLIMIT:
1903 		mutex_enter(&connp->conn_lock);
1904 		if (inlen == 0 || *i1 == -1) {
1905 			/* Revert to default */
1906 			ipp->ipp_fields &= ~IPPF_HOPLIMIT;
1907 			ixa->ixa_flags &= ~IXAF_NO_TTL_CHANGE;
1908 		} else {
1909 			ipp->ipp_hoplimit = *i1;
1910 			ipp->ipp_fields |= IPPF_HOPLIMIT;
1911 			/* Ensure that it sticks for multicast packets */
1912 			ixa->ixa_flags |= IXAF_NO_TTL_CHANGE;
1913 		}
1914 		mutex_exit(&connp->conn_lock);
1915 		coa->coa_changed |= COA_HEADER_CHANGED;
1916 		break;
1917 	case IPV6_TCLASS:
1918 		/*
1919 		 * IPV6_TCLASS accepts -1 as use kernel default
1920 		 * and [0, 255] as the actualy traffic class.
1921 		 */
1922 		mutex_enter(&connp->conn_lock);
1923 		if (inlen == 0 || *i1 == -1) {
1924 			ipp->ipp_tclass = 0;
1925 			ipp->ipp_fields &= ~IPPF_TCLASS;
1926 		} else {
1927 			ipp->ipp_tclass = *i1;
1928 			ipp->ipp_fields |= IPPF_TCLASS;
1929 		}
1930 		/*
1931 		 * When the connection uses IPv4 on the wire, the traffic
1932 		 * class is carried in the Type of Service field of the
1933 		 * IPv4 header. Mirror the value so that it is picked up
1934 		 * when the header is next built. IP_TOS and IPV6_TCLASS
1935 		 * share the field, and the most recent setting prevails.
1936 		 */
1937 		if (connp->conn_ipversion == IPV4_VERSION)
1938 			ipp->ipp_type_of_service = ipp->ipp_tclass;
1939 		mutex_exit(&connp->conn_lock);
1940 		coa->coa_changed |= COA_HEADER_CHANGED;
1941 		break;
1942 	case IPV6_NEXTHOP:
1943 		if (inlen == 0) {
1944 			ixa->ixa_flags &= ~IXAF_NEXTHOP_SET;
1945 		} else {
1946 			sin6_t *sin6 = (sin6_t *)invalp;
1947 
1948 			ixa->ixa_nexthop_v6 = sin6->sin6_addr;
1949 			if (!IN6_IS_ADDR_UNSPECIFIED(&ixa->ixa_nexthop_v6))
1950 				ixa->ixa_flags |= IXAF_NEXTHOP_SET;
1951 			else
1952 				ixa->ixa_flags &= ~IXAF_NEXTHOP_SET;
1953 		}
1954 		coa->coa_changed |= COA_ROUTE_CHANGED;
1955 		break;
1956 	case IPV6_HOPOPTS:
1957 		mutex_enter(&connp->conn_lock);
1958 		error = optcom_pkt_set(invalp, inlen,
1959 		    (uchar_t **)&ipp->ipp_hopopts, &ipp->ipp_hopoptslen);
1960 		if (error != 0) {
1961 			mutex_exit(&connp->conn_lock);
1962 			return (error);
1963 		}
1964 		if (ipp->ipp_hopoptslen == 0) {
1965 			ipp->ipp_fields &= ~IPPF_HOPOPTS;
1966 		} else {
1967 			ipp->ipp_fields |= IPPF_HOPOPTS;
1968 		}
1969 		mutex_exit(&connp->conn_lock);
1970 		coa->coa_changed |= COA_HEADER_CHANGED;
1971 		coa->coa_changed |= COA_WROFF_CHANGED;
1972 		break;
1973 	case IPV6_RTHDRDSTOPTS:
1974 		mutex_enter(&connp->conn_lock);
1975 		error = optcom_pkt_set(invalp, inlen,
1976 		    (uchar_t **)&ipp->ipp_rthdrdstopts,
1977 		    &ipp->ipp_rthdrdstoptslen);
1978 		if (error != 0) {
1979 			mutex_exit(&connp->conn_lock);
1980 			return (error);
1981 		}
1982 		if (ipp->ipp_rthdrdstoptslen == 0) {
1983 			ipp->ipp_fields &= ~IPPF_RTHDRDSTOPTS;
1984 		} else {
1985 			ipp->ipp_fields |= IPPF_RTHDRDSTOPTS;
1986 		}
1987 		mutex_exit(&connp->conn_lock);
1988 		coa->coa_changed |= COA_HEADER_CHANGED;
1989 		coa->coa_changed |= COA_WROFF_CHANGED;
1990 		break;
1991 	case IPV6_DSTOPTS:
1992 		mutex_enter(&connp->conn_lock);
1993 		error = optcom_pkt_set(invalp, inlen,
1994 		    (uchar_t **)&ipp->ipp_dstopts, &ipp->ipp_dstoptslen);
1995 		if (error != 0) {
1996 			mutex_exit(&connp->conn_lock);
1997 			return (error);
1998 		}
1999 		if (ipp->ipp_dstoptslen == 0) {
2000 			ipp->ipp_fields &= ~IPPF_DSTOPTS;
2001 		} else {
2002 			ipp->ipp_fields |= IPPF_DSTOPTS;
2003 		}
2004 		mutex_exit(&connp->conn_lock);
2005 		coa->coa_changed |= COA_HEADER_CHANGED;
2006 		coa->coa_changed |= COA_WROFF_CHANGED;
2007 		break;
2008 	case IPV6_RTHDR:
2009 		mutex_enter(&connp->conn_lock);
2010 		error = optcom_pkt_set(invalp, inlen,
2011 		    (uchar_t **)&ipp->ipp_rthdr, &ipp->ipp_rthdrlen);
2012 		if (error != 0) {
2013 			mutex_exit(&connp->conn_lock);
2014 			return (error);
2015 		}
2016 		if (ipp->ipp_rthdrlen == 0) {
2017 			ipp->ipp_fields &= ~IPPF_RTHDR;
2018 		} else {
2019 			ipp->ipp_fields |= IPPF_RTHDR;
2020 		}
2021 		mutex_exit(&connp->conn_lock);
2022 		coa->coa_changed |= COA_HEADER_CHANGED;
2023 		coa->coa_changed |= COA_WROFF_CHANGED;
2024 		break;
2025 
2026 	case IPV6_DONTFRAG:
2027 		if (onoff) {
2028 			ixa->ixa_flags |= IXAF_DONTFRAG;
2029 			ixa->ixa_flags &= ~IXAF_PMTU_DISCOVERY;
2030 		} else {
2031 			ixa->ixa_flags &= ~IXAF_DONTFRAG;
2032 			ixa->ixa_flags |= IXAF_PMTU_DISCOVERY;
2033 		}
2034 		/* Need to redo ip_attr_connect */
2035 		coa->coa_changed |= COA_ROUTE_CHANGED;
2036 		break;
2037 
2038 	case IPV6_USE_MIN_MTU:
2039 		ixa->ixa_flags |= IXAF_USE_MIN_MTU;
2040 		ixa->ixa_use_min_mtu = *i1;
2041 		/* Need to redo ip_attr_connect */
2042 		coa->coa_changed |= COA_ROUTE_CHANGED;
2043 		break;
2044 
2045 	case IPV6_SEC_OPT:
2046 		mutex_enter(&connp->conn_lock);
2047 		error = ipsec_set_req(cr, connp, (ipsec_req_t *)invalp);
2048 		mutex_exit(&connp->conn_lock);
2049 		if (error != 0) {
2050 			return (error);
2051 		}
2052 		/* This is an IPsec policy change - redo ip_attr_connect */
2053 		coa->coa_changed |= COA_ROUTE_CHANGED;
2054 		break;
2055 	case IPV6_SRC_PREFERENCES:
2056 		/*
2057 		 * This socket option only affects connected
2058 		 * sockets that haven't already bound to a specific
2059 		 * IPv6 address.  In other words, sockets that
2060 		 * don't call bind() with an address other than the
2061 		 * unspecified address and that call connect().
2062 		 * ip_set_destination_v6() passes these preferences
2063 		 * to the ipif_select_source_v6() function.
2064 		 */
2065 		mutex_enter(&connp->conn_lock);
2066 		error = ip6_set_src_preferences(ixa, *(uint32_t *)invalp);
2067 		mutex_exit(&connp->conn_lock);
2068 		if (error != 0) {
2069 			return (error);
2070 		}
2071 		break;
2072 	case IPV6_V6ONLY:
2073 		mutex_enter(&connp->conn_lock);
2074 		connp->conn_ipv6_v6only = onoff;
2075 		mutex_exit(&connp->conn_lock);
2076 		break;
2077 	case IPV6_MINHOPCOUNT:
2078 		mutex_enter(&connp->conn_lock);
2079 		connp->conn_min_ttl = *i1;
2080 		mutex_exit(&connp->conn_lock);
2081 		break;
2082 	}
2083 	return (0);
2084 }
2085 
2086 /* Handle IPPROTO_UDP */
2087 /* ARGSUSED1 */
2088 static int
2089 conn_opt_set_udp(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen,
2090     uchar_t *invalp, boolean_t checkonly, cred_t *cr)
2091 {
2092 	conn_t		*connp = coa->coa_connp;
2093 	int		*i1 = (int *)invalp;
2094 	boolean_t	onoff = (*i1 == 0) ? 0 : 1;
2095 	int		error;
2096 
2097 	switch (name) {
2098 	case UDP_ANONPRIVBIND:
2099 		if ((error = secpolicy_net_privaddr(cr, 0, IPPROTO_UDP)) != 0) {
2100 			return (error);
2101 		}
2102 		break;
2103 	}
2104 	if (checkonly)
2105 		return (0);
2106 
2107 	/* Here we set the actual option value */
2108 	mutex_enter(&connp->conn_lock);
2109 	switch (name) {
2110 	case UDP_ANONPRIVBIND:
2111 		connp->conn_anon_priv_bind = onoff;
2112 		break;
2113 	case UDP_EXCLBIND:
2114 		connp->conn_exclbind = onoff;
2115 		break;
2116 	}
2117 	mutex_exit(&connp->conn_lock);
2118 	return (0);
2119 }
2120 
2121 /* Handle IPPROTO_TCP */
2122 /* ARGSUSED1 */
2123 static int
2124 conn_opt_set_tcp(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen,
2125     uchar_t *invalp, boolean_t checkonly, cred_t *cr)
2126 {
2127 	conn_t		*connp = coa->coa_connp;
2128 	int		*i1 = (int *)invalp;
2129 	boolean_t	onoff = (*i1 == 0) ? 0 : 1;
2130 	int		error;
2131 
2132 	switch (name) {
2133 	case TCP_ANONPRIVBIND:
2134 		if ((error = secpolicy_net_privaddr(cr, 0, IPPROTO_TCP)) != 0) {
2135 			return (error);
2136 		}
2137 		break;
2138 	}
2139 	if (checkonly)
2140 		return (0);
2141 
2142 	/* Here we set the actual option value */
2143 	mutex_enter(&connp->conn_lock);
2144 	switch (name) {
2145 	case TCP_ANONPRIVBIND:
2146 		connp->conn_anon_priv_bind = onoff;
2147 		break;
2148 	case TCP_EXCLBIND:
2149 		connp->conn_exclbind = onoff;
2150 		break;
2151 	case TCP_RECVDSTADDR:
2152 		connp->conn_recv_ancillary.crb_recvdstaddr = onoff;
2153 		break;
2154 	}
2155 	mutex_exit(&connp->conn_lock);
2156 	return (0);
2157 }
2158 
2159 int
2160 conn_getsockname(conn_t *connp, struct sockaddr *sa, uint_t *salenp)
2161 {
2162 	sin_t		*sin;
2163 	sin6_t		*sin6;
2164 
2165 	if (connp->conn_family == AF_INET) {
2166 		if (*salenp < sizeof (sin_t))
2167 			return (EINVAL);
2168 
2169 		*salenp = sizeof (sin_t);
2170 		/* Fill zeroes and then initialize non-zero fields */
2171 		sin = (sin_t *)sa;
2172 		*sin = sin_null;
2173 		sin->sin_family = AF_INET;
2174 		if (!IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_saddr_v6) &&
2175 		    !IN6_IS_ADDR_UNSPECIFIED(&connp->conn_saddr_v6)) {
2176 			sin->sin_addr.s_addr = connp->conn_saddr_v4;
2177 		} else {
2178 			/*
2179 			 * INADDR_ANY
2180 			 * conn_saddr is not set, we might be bound to
2181 			 * broadcast/multicast. Use conn_bound_addr as
2182 			 * local address instead (that could
2183 			 * also still be INADDR_ANY)
2184 			 */
2185 			sin->sin_addr.s_addr = connp->conn_bound_addr_v4;
2186 		}
2187 		sin->sin_port = connp->conn_lport;
2188 	} else {
2189 		if (*salenp < sizeof (sin6_t))
2190 			return (EINVAL);
2191 
2192 		*salenp = sizeof (sin6_t);
2193 		/* Fill zeroes and then initialize non-zero fields */
2194 		sin6 = (sin6_t *)sa;
2195 		*sin6 = sin6_null;
2196 		sin6->sin6_family = AF_INET6;
2197 		if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_saddr_v6)) {
2198 			sin6->sin6_addr = connp->conn_saddr_v6;
2199 		} else {
2200 			/*
2201 			 * conn_saddr is not set, we might be bound to
2202 			 * broadcast/multicast. Use conn_bound_addr as
2203 			 * local address instead (which could
2204 			 * also still be unspecified)
2205 			 */
2206 			sin6->sin6_addr = connp->conn_bound_addr_v6;
2207 		}
2208 		sin6->sin6_port = connp->conn_lport;
2209 		if (IN6_IS_ADDR_LINKSCOPE(&sin6->sin6_addr) &&
2210 		    (connp->conn_ixa->ixa_flags & IXAF_SCOPEID_SET))
2211 			sin6->sin6_scope_id = connp->conn_ixa->ixa_scopeid;
2212 	}
2213 	return (0);
2214 }
2215 
2216 int
2217 conn_getpeername(conn_t *connp, struct sockaddr *sa, uint_t *salenp)
2218 {
2219 	struct sockaddr_in	*sin;
2220 	struct sockaddr_in6	*sin6;
2221 
2222 	if (connp->conn_family == AF_INET) {
2223 		if (*salenp < sizeof (sin_t))
2224 			return (EINVAL);
2225 
2226 		*salenp = sizeof (sin_t);
2227 		/* initialize */
2228 		sin = (sin_t *)sa;
2229 		*sin = sin_null;
2230 		sin->sin_family = AF_INET;
2231 		sin->sin_addr.s_addr = connp->conn_faddr_v4;
2232 		sin->sin_port = connp->conn_fport;
2233 	} else {
2234 		if (*salenp < sizeof (sin6_t))
2235 			return (EINVAL);
2236 
2237 		*salenp = sizeof (sin6_t);
2238 		/* initialize */
2239 		sin6 = (sin6_t *)sa;
2240 		*sin6 = sin6_null;
2241 		sin6->sin6_family = AF_INET6;
2242 		sin6->sin6_addr = connp->conn_faddr_v6;
2243 		sin6->sin6_port =  connp->conn_fport;
2244 		sin6->sin6_flowinfo = connp->conn_flowinfo;
2245 		if (IN6_IS_ADDR_LINKSCOPE(&sin6->sin6_addr) &&
2246 		    (connp->conn_ixa->ixa_flags & IXAF_SCOPEID_SET))
2247 			sin6->sin6_scope_id = connp->conn_ixa->ixa_scopeid;
2248 	}
2249 	return (0);
2250 }
2251 
2252 static uint32_t	cksum_massage_options_v4(ipha_t *, netstack_t *);
2253 static uint32_t cksum_massage_options_v6(ip6_t *, uint_t, netstack_t *);
2254 
2255 /*
2256  * Allocate and fill in conn_ht_iphc based on the current information
2257  * in the conn.
2258  * Normally used when we bind() and connect().
2259  * Returns failure if can't allocate memory, or if there is a problem
2260  * with a routing header/option.
2261  *
2262  * We allocate space for the transport header (ulp_hdr_len + extra) and
2263  * indicate the offset of the ulp header by setting ixa_ip_hdr_length.
2264  * The extra is there for transports that want some spare room for future
2265  * options. conn_ht_iphc_allocated is what was allocated; conn_ht_iphc_len
2266  * excludes the extra part.
2267  *
2268  * We massage an routing option/header and store the ckecksum difference
2269  * in conn_sum.
2270  *
2271  * Caller needs to update conn_wroff if desired.
2272  */
2273 int
2274 conn_build_hdr_template(conn_t *connp, uint_t ulp_hdr_length, uint_t extra,
2275     const in6_addr_t *v6src, const in6_addr_t *v6dst, uint32_t flowinfo)
2276 {
2277 	ip_xmit_attr_t	*ixa = connp->conn_ixa;
2278 	ip_pkt_t	*ipp = &connp->conn_xmit_ipp;
2279 	uint_t		ip_hdr_length;
2280 	uchar_t		*hdrs;
2281 	uint_t		hdrs_len;
2282 
2283 	ASSERT(MUTEX_HELD(&connp->conn_lock));
2284 
2285 	if (ixa->ixa_flags & IXAF_IS_IPV4) {
2286 		ip_hdr_length = ip_total_hdrs_len_v4(ipp);
2287 		/* In case of TX label and IP options it can be too much */
2288 		if (ip_hdr_length > IP_MAX_HDR_LENGTH) {
2289 			/* Preserves existing TX errno for this */
2290 			return (EHOSTUNREACH);
2291 		}
2292 	} else {
2293 		ip_hdr_length = ip_total_hdrs_len_v6(ipp);
2294 	}
2295 	ixa->ixa_ip_hdr_length = ip_hdr_length;
2296 	hdrs_len = ip_hdr_length + ulp_hdr_length + extra;
2297 	ASSERT(hdrs_len != 0);
2298 
2299 	if (hdrs_len != connp->conn_ht_iphc_allocated) {
2300 		/* Allocate new before we free any old */
2301 		hdrs = kmem_alloc(hdrs_len, KM_NOSLEEP);
2302 		if (hdrs == NULL)
2303 			return (ENOMEM);
2304 
2305 		if (connp->conn_ht_iphc != NULL) {
2306 			kmem_free(connp->conn_ht_iphc,
2307 			    connp->conn_ht_iphc_allocated);
2308 		}
2309 		connp->conn_ht_iphc = hdrs;
2310 		connp->conn_ht_iphc_allocated = hdrs_len;
2311 	} else {
2312 		hdrs = connp->conn_ht_iphc;
2313 	}
2314 	hdrs_len -= extra;
2315 	connp->conn_ht_iphc_len = hdrs_len;
2316 
2317 	connp->conn_ht_ulp = hdrs + ip_hdr_length;
2318 	connp->conn_ht_ulp_len = ulp_hdr_length;
2319 
2320 	if (ixa->ixa_flags & IXAF_IS_IPV4) {
2321 		ipha_t	*ipha = (ipha_t *)hdrs;
2322 
2323 		IN6_V4MAPPED_TO_IPADDR(v6src, ipha->ipha_src);
2324 		IN6_V4MAPPED_TO_IPADDR(v6dst, ipha->ipha_dst);
2325 		ip_build_hdrs_v4(hdrs, ip_hdr_length, ipp, connp->conn_proto);
2326 		ipha->ipha_length = htons(hdrs_len);
2327 		if (ixa->ixa_flags & IXAF_PMTU_IPV4_DF)
2328 			ipha->ipha_fragment_offset_and_flags |= IPH_DF_HTONS;
2329 		else
2330 			ipha->ipha_fragment_offset_and_flags &= ~IPH_DF_HTONS;
2331 
2332 		if (ipp->ipp_fields & IPPF_IPV4_OPTIONS) {
2333 			connp->conn_sum = cksum_massage_options_v4(ipha,
2334 			    connp->conn_netstack);
2335 		} else {
2336 			connp->conn_sum = 0;
2337 		}
2338 	} else {
2339 		ip6_t	*ip6h = (ip6_t *)hdrs;
2340 
2341 		ip6h->ip6_src = *v6src;
2342 		ip6h->ip6_dst = *v6dst;
2343 		ip_build_hdrs_v6(hdrs, ip_hdr_length, ipp, connp->conn_proto,
2344 		    flowinfo);
2345 		ip6h->ip6_plen = htons(hdrs_len - IPV6_HDR_LEN);
2346 
2347 		if (ipp->ipp_fields & IPPF_RTHDR) {
2348 			connp->conn_sum = cksum_massage_options_v6(ip6h,
2349 			    ip_hdr_length, connp->conn_netstack);
2350 
2351 			/*
2352 			 * Verify that the first hop isn't a mapped address.
2353 			 * Routers along the path need to do this verification
2354 			 * for subsequent hops.
2355 			 */
2356 			if (IN6_IS_ADDR_V4MAPPED(&ip6h->ip6_dst))
2357 				return (EADDRNOTAVAIL);
2358 
2359 		} else {
2360 			connp->conn_sum = 0;
2361 		}
2362 	}
2363 	return (0);
2364 }
2365 
2366 /*
2367  * Prepend a header template to data_mp based on the ip_pkt_t
2368  * and the passed in source, destination and protocol.
2369  *
2370  * Returns failure if can't allocate memory, in which case data_mp is freed.
2371  * We allocate space for the transport header (ulp_hdr_len) and
2372  * indicate the offset of the ulp header by setting ixa_ip_hdr_length.
2373  *
2374  * We massage an routing option/header and return the ckecksum difference
2375  * in *sump. This is in host byte order.
2376  *
2377  * Caller needs to update conn_wroff if desired.
2378  */
2379 mblk_t *
2380 conn_prepend_hdr(ip_xmit_attr_t *ixa, const ip_pkt_t *ipp,
2381     const in6_addr_t *v6src, const in6_addr_t *v6dst,
2382     uint8_t protocol, uint32_t flowinfo, uint_t ulp_hdr_length, mblk_t *data_mp,
2383     uint_t data_length, uint_t wroff_extra, uint32_t *sump, int *errorp)
2384 {
2385 	uint_t		ip_hdr_length;
2386 	uchar_t		*hdrs;
2387 	uint_t		hdrs_len;
2388 	mblk_t		*mp;
2389 
2390 	if (ixa->ixa_flags & IXAF_IS_IPV4) {
2391 		ip_hdr_length = ip_total_hdrs_len_v4(ipp);
2392 		ASSERT(ip_hdr_length <= IP_MAX_HDR_LENGTH);
2393 	} else {
2394 		ip_hdr_length = ip_total_hdrs_len_v6(ipp);
2395 	}
2396 	hdrs_len = ip_hdr_length + ulp_hdr_length;
2397 	ASSERT(hdrs_len != 0);
2398 
2399 	ixa->ixa_ip_hdr_length = ip_hdr_length;
2400 
2401 	/* Can we prepend to data_mp? */
2402 	if (data_mp != NULL &&
2403 	    data_mp->b_rptr - data_mp->b_datap->db_base >= hdrs_len &&
2404 	    data_mp->b_datap->db_ref == 1) {
2405 		hdrs = data_mp->b_rptr - hdrs_len;
2406 		data_mp->b_rptr = hdrs;
2407 		mp = data_mp;
2408 	} else {
2409 		mp = allocb(hdrs_len + wroff_extra, BPRI_MED);
2410 		if (mp == NULL) {
2411 			freemsg(data_mp);
2412 			*errorp = ENOMEM;
2413 			return (NULL);
2414 		}
2415 		mp->b_wptr = mp->b_datap->db_lim;
2416 		hdrs = mp->b_rptr = mp->b_wptr - hdrs_len;
2417 		mp->b_cont = data_mp;
2418 	}
2419 
2420 	/*
2421 	 * Set the source in the header. ip_build_hdrs_v4/v6 will overwrite it
2422 	 * if PKTINFO (aka IPPF_ADDR) was set.
2423 	 */
2424 	if (ixa->ixa_flags & IXAF_IS_IPV4) {
2425 		ipha_t *ipha = (ipha_t *)hdrs;
2426 
2427 		ASSERT(IN6_IS_ADDR_V4MAPPED(v6dst));
2428 		IN6_V4MAPPED_TO_IPADDR(v6src, ipha->ipha_src);
2429 		IN6_V4MAPPED_TO_IPADDR(v6dst, ipha->ipha_dst);
2430 		ip_build_hdrs_v4(hdrs, ip_hdr_length, ipp, protocol);
2431 		ipha->ipha_length = htons(hdrs_len + data_length);
2432 		if (ixa->ixa_flags & IXAF_PMTU_IPV4_DF)
2433 			ipha->ipha_fragment_offset_and_flags |= IPH_DF_HTONS;
2434 		else
2435 			ipha->ipha_fragment_offset_and_flags &= ~IPH_DF_HTONS;
2436 
2437 		if (ipp->ipp_fields & IPPF_IPV4_OPTIONS) {
2438 			*sump = cksum_massage_options_v4(ipha,
2439 			    ixa->ixa_ipst->ips_netstack);
2440 		} else {
2441 			*sump = 0;
2442 		}
2443 	} else {
2444 		ip6_t *ip6h = (ip6_t *)hdrs;
2445 
2446 		ip6h->ip6_src = *v6src;
2447 		ip6h->ip6_dst = *v6dst;
2448 		ip_build_hdrs_v6(hdrs, ip_hdr_length, ipp, protocol, flowinfo);
2449 		ip6h->ip6_plen = htons(hdrs_len + data_length - IPV6_HDR_LEN);
2450 
2451 		if (ipp->ipp_fields & IPPF_RTHDR) {
2452 			*sump = cksum_massage_options_v6(ip6h,
2453 			    ip_hdr_length, ixa->ixa_ipst->ips_netstack);
2454 
2455 			/*
2456 			 * Verify that the first hop isn't a mapped address.
2457 			 * Routers along the path need to do this verification
2458 			 * for subsequent hops.
2459 			 */
2460 			if (IN6_IS_ADDR_V4MAPPED(&ip6h->ip6_dst)) {
2461 				*errorp = EADDRNOTAVAIL;
2462 				freemsg(mp);
2463 				return (NULL);
2464 			}
2465 		} else {
2466 			*sump = 0;
2467 		}
2468 	}
2469 	return (mp);
2470 }
2471 
2472 /*
2473  * Massage a source route if any putting the first hop
2474  * in ipha_dst. Compute a starting value for the checksum which
2475  * takes into account that the original ipha_dst should be
2476  * included in the checksum but that IP will include the
2477  * first hop from the source route in the tcp checksum.
2478  */
2479 static uint32_t
2480 cksum_massage_options_v4(ipha_t *ipha, netstack_t *ns)
2481 {
2482 	in_addr_t	dst;
2483 	uint32_t	cksum;
2484 
2485 	/* Get last hop then diff against first hop */
2486 	cksum = ip_massage_options(ipha, ns);
2487 	cksum = (cksum & 0xFFFF) + (cksum >> 16);
2488 	dst = ipha->ipha_dst;
2489 	cksum -= ((dst >> 16) + (dst & 0xffff));
2490 	if ((int)cksum < 0)
2491 		cksum--;
2492 	cksum = (cksum & 0xFFFF) + (cksum >> 16);
2493 	cksum = (cksum & 0xFFFF) + (cksum >> 16);
2494 	ASSERT(cksum < 0x10000);
2495 	return (ntohs(cksum));
2496 }
2497 
2498 static uint32_t
2499 cksum_massage_options_v6(ip6_t *ip6h, uint_t ip_hdr_len, netstack_t *ns)
2500 {
2501 	uint8_t		*end;
2502 	ip6_rthdr_t	*rth;
2503 	uint32_t	cksum;
2504 
2505 	end = (uint8_t *)ip6h + ip_hdr_len;
2506 	rth = ip_find_rthdr_v6(ip6h, end);
2507 	if (rth == NULL)
2508 		return (0);
2509 
2510 	cksum = ip_massage_options_v6(ip6h, rth, ns);
2511 	cksum = (cksum & 0xFFFF) + (cksum >> 16);
2512 	ASSERT(cksum < 0x10000);
2513 	return (ntohs(cksum));
2514 }
2515 
2516 /*
2517  * ULPs that change the destination address need to call this for each
2518  * change to discard any state about a previous destination that might
2519  * have been multicast or multirt.
2520  */
2521 void
2522 ip_attr_newdst(ip_xmit_attr_t *ixa)
2523 {
2524 	ixa->ixa_flags &= ~(IXAF_LOOPBACK_COPY | IXAF_NO_HW_CKSUM |
2525 	    IXAF_NO_TTL_CHANGE | IXAF_IPV6_ADD_FRAGHDR |
2526 	    IXAF_NO_LOOP_ZONEID_SET);
2527 }
2528 
2529 /*
2530  * Determine the nexthop which will be used.
2531  * Normally this is just the destination, but if a IPv4 source route, or
2532  * IPv6 routing header, is in the ip_pkt_t then we extract the nexthop from
2533  * there.
2534  */
2535 void
2536 ip_attr_nexthop(const ip_pkt_t *ipp, const ip_xmit_attr_t *ixa,
2537     const in6_addr_t *dst, in6_addr_t *nexthop)
2538 {
2539 	if (!(ipp->ipp_fields & (IPPF_IPV4_OPTIONS|IPPF_RTHDR))) {
2540 		*nexthop = *dst;
2541 		return;
2542 	}
2543 	if (ixa->ixa_flags & IXAF_IS_IPV4) {
2544 		ipaddr_t v4dst;
2545 		ipaddr_t v4nexthop;
2546 
2547 		IN6_V4MAPPED_TO_IPADDR(dst, v4dst);
2548 		v4nexthop = ip_pkt_source_route_v4(ipp);
2549 		if (v4nexthop == INADDR_ANY)
2550 			v4nexthop = v4dst;
2551 
2552 		IN6_IPADDR_TO_V4MAPPED(v4nexthop, nexthop);
2553 	} else {
2554 		const in6_addr_t *v6nexthop;
2555 
2556 		v6nexthop = ip_pkt_source_route_v6(ipp);
2557 		if (v6nexthop == NULL)
2558 			v6nexthop = dst;
2559 
2560 		*nexthop = *v6nexthop;
2561 	}
2562 }
2563 
2564 /*
2565  * Update the ip_xmit_attr_t based the addresses, conn_xmit_ipp and conn_ixa.
2566  * If IPDF_IPSEC is set we cache the IPsec policy to handle the unconnected
2567  * case (connected latching is done in conn_connect).
2568  * Note that IPsec policy lookup requires conn_proto and conn_laddr to be
2569  * set, but doesn't otherwise use the conn_t.
2570  *
2571  * Caller must set/clear IXAF_IS_IPV4 as appropriately.
2572  * Caller must use ip_attr_nexthop() to determine the nexthop argument.
2573  *
2574  * The caller must NOT hold conn_lock (to avoid problems with ill_refrele
2575  * causing the squeue to run doing ipcl_walk grabbing conn_lock.)
2576  *
2577  * Updates laddrp and uinfo if they are non-NULL.
2578  *
2579  * TSOL notes: The callers if ip_attr_connect must check if the destination
2580  * is different than before and in that case redo conn_update_label.
2581  * The callers of conn_connect do not need that since conn_connect
2582  * performs the conn_update_label.
2583  */
2584 int
2585 ip_attr_connect(const conn_t *connp, ip_xmit_attr_t *ixa,
2586     const in6_addr_t *v6src, const in6_addr_t *v6dst,
2587     const in6_addr_t *v6nexthop, in_port_t dstport, in6_addr_t *laddrp,
2588     iulp_t *uinfo, uint32_t flags)
2589 {
2590 	in6_addr_t		laddr = *v6src;
2591 	int			error;
2592 
2593 	ASSERT(MUTEX_NOT_HELD(&connp->conn_lock));
2594 
2595 	if (connp->conn_zone_is_global)
2596 		flags |= IPDF_ZONE_IS_GLOBAL;
2597 	else
2598 		flags &= ~IPDF_ZONE_IS_GLOBAL;
2599 
2600 	/*
2601 	 * Lookup the route to determine a source address and the uinfo.
2602 	 * If the ULP has a source route option then the caller will
2603 	 * have set v6nexthop to be the first hop.
2604 	 */
2605 	if (ixa->ixa_flags & IXAF_IS_IPV4) {
2606 		ipaddr_t v4dst;
2607 		ipaddr_t v4src, v4nexthop;
2608 
2609 		IN6_V4MAPPED_TO_IPADDR(v6dst, v4dst);
2610 		IN6_V4MAPPED_TO_IPADDR(v6nexthop, v4nexthop);
2611 		IN6_V4MAPPED_TO_IPADDR(v6src, v4src);
2612 
2613 		if (connp->conn_unspec_src || v4src != INADDR_ANY)
2614 			flags &= ~IPDF_SELECT_SRC;
2615 		else
2616 			flags |= IPDF_SELECT_SRC;
2617 
2618 		error = ip_set_destination_v4(&v4src, v4dst, v4nexthop, ixa,
2619 		    uinfo, flags, connp->conn_mac_mode);
2620 		IN6_IPADDR_TO_V4MAPPED(v4src, &laddr);
2621 	} else {
2622 		if (connp->conn_unspec_src || !IN6_IS_ADDR_UNSPECIFIED(v6src))
2623 			flags &= ~IPDF_SELECT_SRC;
2624 		else
2625 			flags |= IPDF_SELECT_SRC;
2626 
2627 		error = ip_set_destination_v6(&laddr, v6dst, v6nexthop, ixa,
2628 		    uinfo, flags, connp->conn_mac_mode);
2629 	}
2630 	/* Pass out some address even if we hit a RTF_REJECT etc */
2631 	if (laddrp != NULL)
2632 		*laddrp = laddr;
2633 
2634 	if (error != 0)
2635 		return (error);
2636 
2637 	if (flags & IPDF_IPSEC) {
2638 		/*
2639 		 * Set any IPsec policy in ixa. Routine also looks at ULP
2640 		 * ports.
2641 		 */
2642 		ipsec_cache_outbound_policy(connp, v6src, v6dst, dstport, ixa);
2643 	}
2644 	return (0);
2645 }
2646 
2647 /*
2648  * Connect the conn based on the addresses, conn_xmit_ipp and conn_ixa.
2649  * Assumes that conn_faddr and conn_fport are already set. As such it is not
2650  * usable for SCTP, since SCTP has multiple faddrs.
2651  *
2652  * Caller must hold conn_lock to provide atomic constency between the
2653  * conn_t's addresses and the ixa.
2654  * NOTE: this function drops and reaquires conn_lock since it can't be
2655  * held across ip_attr_connect/ip_set_destination.
2656  *
2657  * The caller needs to handle inserting in the receive-side fanout when
2658  * appropriate after conn_connect returns.
2659  */
2660 int
2661 conn_connect(conn_t *connp, iulp_t *uinfo, uint32_t flags)
2662 {
2663 	ip_xmit_attr_t	*ixa = connp->conn_ixa;
2664 	in6_addr_t	nexthop;
2665 	in6_addr_t	saddr, faddr;
2666 	in_port_t	fport;
2667 	int		error;
2668 
2669 	ASSERT(MUTEX_HELD(&connp->conn_lock));
2670 
2671 	if (connp->conn_ipversion == IPV4_VERSION)
2672 		ixa->ixa_flags |= IXAF_IS_IPV4;
2673 	else
2674 		ixa->ixa_flags &= ~IXAF_IS_IPV4;
2675 
2676 	/* We do IPsec latching below - hence no caching in ip_attr_connect */
2677 	flags &= ~IPDF_IPSEC;
2678 
2679 	/* In case we had previously done an ip_attr_connect */
2680 	ip_attr_newdst(ixa);
2681 
2682 	/*
2683 	 * Determine the nexthop and copy the addresses before dropping
2684 	 * conn_lock.
2685 	 */
2686 	ip_attr_nexthop(&connp->conn_xmit_ipp, connp->conn_ixa,
2687 	    &connp->conn_faddr_v6, &nexthop);
2688 	saddr = connp->conn_saddr_v6;
2689 	faddr = connp->conn_faddr_v6;
2690 	fport = connp->conn_fport;
2691 
2692 	mutex_exit(&connp->conn_lock);
2693 	error = ip_attr_connect(connp, ixa, &saddr, &faddr, &nexthop, fport,
2694 	    &saddr, uinfo, flags | IPDF_VERIFY_DST);
2695 	mutex_enter(&connp->conn_lock);
2696 
2697 	/* Could have changed even if an error */
2698 	connp->conn_saddr_v6 = saddr;
2699 	if (error != 0)
2700 		return (error);
2701 
2702 	/*
2703 	 * Check whether Trusted Solaris policy allows communication with this
2704 	 * host, and pretend that the destination is unreachable if not.
2705 	 * Compute any needed label and place it in ipp_label_v4/v6.
2706 	 *
2707 	 * Later conn_build_hdr_template() takes ipp_label_v4/v6 to form
2708 	 * the packet.
2709 	 *
2710 	 * TSOL Note: Any concurrent threads would pick a different ixa
2711 	 * (and ipp if they are to change the ipp)  so we
2712 	 * don't have to worry about concurrent threads.
2713 	 */
2714 	if (is_system_labeled()) {
2715 		if (connp->conn_mlp_type != mlptSingle)
2716 			return (ECONNREFUSED);
2717 
2718 		/*
2719 		 * conn_update_label will set ipp_label* which will later
2720 		 * be used by conn_build_hdr_template.
2721 		 */
2722 		error = conn_update_label(connp, ixa,
2723 		    &connp->conn_faddr_v6, &connp->conn_xmit_ipp);
2724 		if (error != 0)
2725 			return (error);
2726 	}
2727 
2728 	/*
2729 	 * Ensure that we match on the selected local address.
2730 	 * This overrides conn_laddr in the case we had earlier bound to a
2731 	 * multicast or broadcast address.
2732 	 */
2733 	connp->conn_laddr_v6 = connp->conn_saddr_v6;
2734 
2735 	/*
2736 	 * Allow setting new policies.
2737 	 * The addresses/ports are already set, thus the IPsec policy calls
2738 	 * can handle their passed-in conn's.
2739 	 */
2740 	connp->conn_policy_cached = B_FALSE;
2741 
2742 	/*
2743 	 * Cache IPsec policy in this conn.  If we have per-socket policy,
2744 	 * we'll cache that.  If we don't, we'll inherit global policy.
2745 	 *
2746 	 * This is done before the caller inserts in the receive-side fanout.
2747 	 * Note that conn_policy_cached is set by ipsec_conn_cache_policy() even
2748 	 * for connections where we don't have a policy. This is to prevent
2749 	 * global policy lookups in the inbound path.
2750 	 *
2751 	 * If we insert before we set conn_policy_cached,
2752 	 * CONN_INBOUND_POLICY_PRESENT() check can still evaluate true
2753 	 * because global policy cound be non-empty. We normally call
2754 	 * ipsec_check_policy() for conn_policy_cached connections only if
2755 	 * conn_in_enforce_policy is set. But in this case,
2756 	 * conn_policy_cached can get set anytime since we made the
2757 	 * CONN_INBOUND_POLICY_PRESENT() check and ipsec_check_policy() is
2758 	 * called, which will make the above assumption false.  Thus, we
2759 	 * need to insert after we set conn_policy_cached.
2760 	 */
2761 	error = ipsec_conn_cache_policy(connp,
2762 	    connp->conn_ipversion == IPV4_VERSION);
2763 	if (error != 0)
2764 		return (error);
2765 
2766 	/*
2767 	 * We defer to do LSO check until here since now we have better idea
2768 	 * whether IPsec is present. If the underlying ill is LSO capable,
2769 	 * copy its capability in so the ULP can decide whether to enable LSO
2770 	 * on this connection.
2771 	 *
2772 	 * Currently, won't enable LSO for IRE_LOOPBACK or IRE_LOCAL, because
2773 	 * the receiver can not handle it. Also won't enable LSO for MULTIRT.
2774 	 */
2775 	ixa->ixa_flags &= ~IXAF_LSO_CAPAB;
2776 
2777 	ASSERT(ixa->ixa_ire != NULL);
2778 	if (dohwcksum &&
2779 	    ixa->ixa_ipst->ips_ip_lso_outbound && (flags & IPDF_LSO) &&
2780 	    !(ixa->ixa_flags & IXAF_IPSEC_SECURE) &&
2781 	    !(ixa->ixa_ire->ire_type & (IRE_LOCAL | IRE_LOOPBACK)) &&
2782 	    !(ixa->ixa_ire->ire_flags & RTF_MULTIRT) &&
2783 	    (ixa->ixa_nce != NULL) &&
2784 	    ((ixa->ixa_flags & IXAF_IS_IPV4) ?
2785 	    ILL_LSO_TCP_IPV4_USABLE(ixa->ixa_nce->nce_ill) :
2786 	    ILL_LSO_TCP_IPV6_USABLE(ixa->ixa_nce->nce_ill))) {
2787 		ixa->ixa_lso_capab = *ixa->ixa_nce->nce_ill->ill_lso_capab;
2788 		ixa->ixa_flags |= IXAF_LSO_CAPAB;
2789 	}
2790 
2791 	/* Check whether ZEROCOPY capability is usable for this connection. */
2792 	ixa->ixa_flags &= ~IXAF_ZCOPY_CAPAB;
2793 
2794 	if ((flags & IPDF_ZCOPY) &&
2795 	    !(ixa->ixa_flags & IXAF_IPSEC_SECURE) &&
2796 	    !(ixa->ixa_ire->ire_type & (IRE_LOCAL | IRE_LOOPBACK)) &&
2797 	    !(ixa->ixa_ire->ire_flags & RTF_MULTIRT) &&
2798 	    (ixa->ixa_nce != NULL) &&
2799 	    ILL_ZCOPY_USABLE(ixa->ixa_nce->nce_ill)) {
2800 		ixa->ixa_flags |= IXAF_ZCOPY_CAPAB;
2801 	}
2802 	return (0);
2803 }
2804 
2805 /*
2806  * Predicates to check if the addresses match conn_last*
2807  */
2808 
2809 /*
2810  * Compare the conn against an address.
2811  * If using mapped addresses on AF_INET6 sockets, use the _v6 function
2812  */
2813 boolean_t
2814 conn_same_as_last_v4(conn_t *connp, sin_t *sin)
2815 {
2816 	ASSERT(connp->conn_family == AF_INET);
2817 	return (sin->sin_addr.s_addr == connp->conn_v4lastdst &&
2818 	    sin->sin_port == connp->conn_lastdstport);
2819 }
2820 
2821 /*
2822  * Compare, including for mapped addresses
2823  */
2824 boolean_t
2825 conn_same_as_last_v6(conn_t *connp, sin6_t *sin6)
2826 {
2827 	return (IN6_ARE_ADDR_EQUAL(&connp->conn_v6lastdst, &sin6->sin6_addr) &&
2828 	    sin6->sin6_port == connp->conn_lastdstport &&
2829 	    sin6->sin6_flowinfo == connp->conn_lastflowinfo &&
2830 	    sin6->sin6_scope_id == connp->conn_lastscopeid);
2831 }
2832 
2833 /*
2834  * Compute a label and place it in the ip_packet_t.
2835  * Handles IPv4 and IPv6.
2836  * The caller should have a correct ixa_tsl and ixa_zoneid and have
2837  * already called conn_connect or ip_attr_connect to ensure that tsol_check_dest
2838  * has been called.
2839  */
2840 int
2841 conn_update_label(const conn_t *connp, const ip_xmit_attr_t *ixa,
2842     const in6_addr_t *v6dst, ip_pkt_t *ipp)
2843 {
2844 	int		err;
2845 	ipaddr_t	v4dst;
2846 
2847 	if (IN6_IS_ADDR_V4MAPPED(v6dst)) {
2848 		uchar_t		opt_storage[IP_MAX_OPT_LENGTH];
2849 
2850 		IN6_V4MAPPED_TO_IPADDR(v6dst, v4dst);
2851 
2852 		err = tsol_compute_label_v4(ixa->ixa_tsl, ixa->ixa_zoneid,
2853 		    v4dst, opt_storage, ixa->ixa_ipst);
2854 		if (err == 0) {
2855 			/* Length contained in opt_storage[IPOPT_OLEN] */
2856 			err = optcom_pkt_set(opt_storage,
2857 			    opt_storage[IPOPT_OLEN],
2858 			    (uchar_t **)&ipp->ipp_label_v4,
2859 			    &ipp->ipp_label_len_v4);
2860 		}
2861 		if (err != 0) {
2862 			DTRACE_PROBE4(tx__ip__log__info__updatelabel,
2863 			    char *, "conn(1) failed to update options(2) "
2864 			    "on ixa(3)",
2865 			    conn_t *, connp, char *, opt_storage,
2866 			    ip_xmit_attr_t *, ixa);
2867 		}
2868 		if (ipp->ipp_label_len_v4 != 0)
2869 			ipp->ipp_fields |= IPPF_LABEL_V4;
2870 		else
2871 			ipp->ipp_fields &= ~IPPF_LABEL_V4;
2872 	} else {
2873 		uchar_t		opt_storage[TSOL_MAX_IPV6_OPTION];
2874 		uint_t		optlen;
2875 
2876 		err = tsol_compute_label_v6(ixa->ixa_tsl, ixa->ixa_zoneid,
2877 		    v6dst, opt_storage, ixa->ixa_ipst);
2878 		if (err == 0) {
2879 			/*
2880 			 * Note that ipp_label_v6 is just the option - not
2881 			 * the hopopts extension header.
2882 			 *
2883 			 * Length contained in opt_storage[IPOPT_OLEN], but
2884 			 * that doesn't include the two byte options header.
2885 			 */
2886 			optlen = opt_storage[IPOPT_OLEN];
2887 			if (optlen != 0)
2888 				optlen += 2;
2889 
2890 			err = optcom_pkt_set(opt_storage, optlen,
2891 			    (uchar_t **)&ipp->ipp_label_v6,
2892 			    &ipp->ipp_label_len_v6);
2893 		}
2894 		if (err != 0) {
2895 			DTRACE_PROBE4(tx__ip__log__info__updatelabel,
2896 			    char *, "conn(1) failed to update options(2) "
2897 			    "on ixa(3)",
2898 			    conn_t *, connp, char *, opt_storage,
2899 			    ip_xmit_attr_t *, ixa);
2900 		}
2901 		if (ipp->ipp_label_len_v6 != 0)
2902 			ipp->ipp_fields |= IPPF_LABEL_V6;
2903 		else
2904 			ipp->ipp_fields &= ~IPPF_LABEL_V6;
2905 	}
2906 	return (err);
2907 }
2908 
2909 /*
2910  * Inherit all options settings from the parent/listener to the eager.
2911  * Returns zero on success; ENOMEM if memory allocation failed.
2912  *
2913  * We assume that the eager has not had any work done i.e., the conn_ixa
2914  * and conn_xmit_ipp are all zero.
2915  * Furthermore we assume that no other thread can access the eager (because
2916  * it isn't inserted in any fanout list).
2917  */
2918 int
2919 conn_inherit_parent(conn_t *lconnp, conn_t *econnp)
2920 {
2921 	cred_t	*credp;
2922 	int	err;
2923 	void	*notify_cookie;
2924 	uint32_t xmit_hint;
2925 
2926 	econnp->conn_family = lconnp->conn_family;
2927 	econnp->conn_ipv6_v6only = lconnp->conn_ipv6_v6only;
2928 	econnp->conn_wq = lconnp->conn_wq;
2929 	econnp->conn_rq = lconnp->conn_rq;
2930 
2931 	/*
2932 	 * Make a safe copy of the transmit attributes.
2933 	 * conn_connect will later be used by the caller to setup the ire etc.
2934 	 */
2935 	ASSERT(econnp->conn_ixa->ixa_refcnt == 1);
2936 	ASSERT(econnp->conn_ixa->ixa_ire == NULL);
2937 	ASSERT(econnp->conn_ixa->ixa_dce == NULL);
2938 	ASSERT(econnp->conn_ixa->ixa_nce == NULL);
2939 
2940 	/* Preserve ixa_notify_cookie and xmit_hint */
2941 	notify_cookie = econnp->conn_ixa->ixa_notify_cookie;
2942 	xmit_hint = econnp->conn_ixa->ixa_xmit_hint;
2943 	ixa_safe_copy(lconnp->conn_ixa, econnp->conn_ixa);
2944 	econnp->conn_ixa->ixa_notify_cookie = notify_cookie;
2945 	econnp->conn_ixa->ixa_xmit_hint = xmit_hint;
2946 
2947 	econnp->conn_bound_if = lconnp->conn_bound_if;
2948 	econnp->conn_incoming_ifindex = lconnp->conn_incoming_ifindex;
2949 
2950 	/* Inherit all RECV options */
2951 	econnp->conn_recv_ancillary = lconnp->conn_recv_ancillary;
2952 
2953 	err = ip_pkt_copy(&lconnp->conn_xmit_ipp, &econnp->conn_xmit_ipp,
2954 	    KM_NOSLEEP);
2955 	if (err != 0)
2956 		return (err);
2957 
2958 	econnp->conn_zoneid = lconnp->conn_zoneid;
2959 	econnp->conn_allzones = lconnp->conn_allzones;
2960 
2961 	/* This is odd. Pick a flowlabel for each connection instead? */
2962 	econnp->conn_flowinfo = lconnp->conn_flowinfo;
2963 
2964 	econnp->conn_default_ttl = lconnp->conn_default_ttl;
2965 	econnp->conn_min_ttl = lconnp->conn_min_ttl;
2966 
2967 	/*
2968 	 * TSOL: tsol_input_proc() needs the eager's cred before the
2969 	 * eager is accepted
2970 	 */
2971 	ASSERT(lconnp->conn_cred != NULL);
2972 	econnp->conn_cred = credp = lconnp->conn_cred;
2973 	crhold(credp);
2974 	econnp->conn_cpid = lconnp->conn_cpid;
2975 	econnp->conn_open_time = ddi_get_lbolt64();
2976 
2977 	/*
2978 	 * Cache things in the ixa without any refhold.
2979 	 * Listener might not have set up ixa_cred
2980 	 */
2981 	ASSERT(!(econnp->conn_ixa->ixa_free_flags & IXA_FREE_CRED));
2982 	econnp->conn_ixa->ixa_cred = econnp->conn_cred;
2983 	econnp->conn_ixa->ixa_cpid = econnp->conn_cpid;
2984 	if (is_system_labeled())
2985 		econnp->conn_ixa->ixa_tsl = crgetlabel(econnp->conn_cred);
2986 
2987 	/*
2988 	 * If the caller has the process-wide flag set, then default to MAC
2989 	 * exempt mode.  This allows read-down to unlabeled hosts.
2990 	 */
2991 	if (getpflags(NET_MAC_AWARE, credp) != 0)
2992 		econnp->conn_mac_mode = CONN_MAC_AWARE;
2993 
2994 	econnp->conn_zone_is_global = lconnp->conn_zone_is_global;
2995 
2996 	/*
2997 	 * We eliminate the need for sockfs to send down a T_SVR4_OPTMGMT_REQ
2998 	 * via soaccept()->soinheritoptions() which essentially applies
2999 	 * all the listener options to the new connection. The options that we
3000 	 * need to take care of are:
3001 	 * SO_DEBUG, SO_REUSEADDR, SO_KEEPALIVE, SO_DONTROUTE, SO_BROADCAST,
3002 	 * SO_USELOOPBACK, SO_OOBINLINE, SO_DGRAM_ERRIND, SO_LINGER,
3003 	 * SO_SNDBUF, SO_RCVBUF.
3004 	 *
3005 	 * SO_RCVBUF:	conn_rcvbuf is set.
3006 	 * SO_SNDBUF:	conn_sndbuf is set.
3007 	 */
3008 
3009 	/* Could we define a struct and use a struct copy for this? */
3010 	econnp->conn_sndbuf = lconnp->conn_sndbuf;
3011 	econnp->conn_rcvbuf = lconnp->conn_rcvbuf;
3012 	econnp->conn_sndlowat = lconnp->conn_sndlowat;
3013 	econnp->conn_rcvlowat = lconnp->conn_rcvlowat;
3014 	econnp->conn_dgram_errind = lconnp->conn_dgram_errind;
3015 	econnp->conn_oobinline = lconnp->conn_oobinline;
3016 	econnp->conn_debug = lconnp->conn_debug;
3017 	econnp->conn_keepalive = lconnp->conn_keepalive;
3018 	econnp->conn_linger = lconnp->conn_linger;
3019 	econnp->conn_lingertime = lconnp->conn_lingertime;
3020 
3021 	/* Set the IP options */
3022 	econnp->conn_broadcast = lconnp->conn_broadcast;
3023 	econnp->conn_useloopback = lconnp->conn_useloopback;
3024 	econnp->conn_reuseaddr = lconnp->conn_reuseaddr;
3025 	return (0);
3026 }
3027