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