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