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