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