1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (c) 2010-2011 Juniper Networks, Inc. 6 * All rights reserved. 7 * 8 * Portions of this software were developed by Robert N. M. Watson under 9 * contract to Juniper Networks, Inc. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the project nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * $KAME: in6_pcb.c,v 1.31 2001/05/21 05:45:10 jinmei Exp $ 36 */ 37 38 /*- 39 * Copyright (c) 1982, 1986, 1991, 1993 40 * The Regents of the University of California. All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. Neither the name of the University nor the names of its contributors 51 * may be used to endorse or promote products derived from this software 52 * without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * SUCH DAMAGE. 65 * 66 * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94 67 */ 68 69 #include <sys/cdefs.h> 70 __FBSDID("$FreeBSD$"); 71 72 #include "opt_inet.h" 73 #include "opt_inet6.h" 74 #include "opt_ipsec.h" 75 #include "opt_pcbgroup.h" 76 #include "opt_rss.h" 77 78 #include <sys/param.h> 79 #include <sys/systm.h> 80 #include <sys/malloc.h> 81 #include <sys/mbuf.h> 82 #include <sys/domain.h> 83 #include <sys/protosw.h> 84 #include <sys/socket.h> 85 #include <sys/socketvar.h> 86 #include <sys/sockio.h> 87 #include <sys/errno.h> 88 #include <sys/time.h> 89 #include <sys/priv.h> 90 #include <sys/proc.h> 91 #include <sys/jail.h> 92 93 #include <vm/uma.h> 94 95 #include <net/if.h> 96 #include <net/if_var.h> 97 #include <net/if_llatbl.h> 98 #include <net/if_types.h> 99 #include <net/route.h> 100 #include <net/route/nhop.h> 101 102 #include <netinet/in.h> 103 #include <netinet/in_var.h> 104 #include <netinet/in_systm.h> 105 #include <netinet/tcp_var.h> 106 #include <netinet/ip6.h> 107 #include <netinet/ip_var.h> 108 109 #include <netinet6/ip6_var.h> 110 #include <netinet6/nd6.h> 111 #include <netinet/in_pcb.h> 112 #include <netinet6/in6_pcb.h> 113 #include <netinet6/in6_fib.h> 114 #include <netinet6/scope6_var.h> 115 116 int 117 in6_pcbbind(struct inpcb *inp, struct sockaddr *nam, 118 struct ucred *cred) 119 { 120 struct socket *so = inp->inp_socket; 121 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL; 122 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 123 u_short lport = 0; 124 int error, lookupflags = 0; 125 int reuseport = (so->so_options & SO_REUSEPORT); 126 127 /* 128 * XXX: Maybe we could let SO_REUSEPORT_LB set SO_REUSEPORT bit here 129 * so that we don't have to add to the (already messy) code below. 130 */ 131 int reuseport_lb = (so->so_options & SO_REUSEPORT_LB); 132 133 INP_WLOCK_ASSERT(inp); 134 INP_HASH_WLOCK_ASSERT(pcbinfo); 135 136 if (CK_STAILQ_EMPTY(&V_in6_ifaddrhead)) /* XXX broken! */ 137 return (EADDRNOTAVAIL); 138 if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) 139 return (EINVAL); 140 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT|SO_REUSEPORT_LB)) == 0) 141 lookupflags = INPLOOKUP_WILDCARD; 142 if (nam == NULL) { 143 if ((error = prison_local_ip6(cred, &inp->in6p_laddr, 144 ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0) 145 return (error); 146 } else { 147 sin6 = (struct sockaddr_in6 *)nam; 148 if (nam->sa_len != sizeof(*sin6)) 149 return (EINVAL); 150 /* 151 * family check. 152 */ 153 if (nam->sa_family != AF_INET6) 154 return (EAFNOSUPPORT); 155 156 if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0) 157 return(error); 158 159 if ((error = prison_local_ip6(cred, &sin6->sin6_addr, 160 ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0) 161 return (error); 162 163 lport = sin6->sin6_port; 164 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { 165 /* 166 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 167 * allow compepte duplication of binding if 168 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 169 * and a multicast address is bound on both 170 * new and duplicated sockets. 171 */ 172 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) != 0) 173 reuseport = SO_REUSEADDR|SO_REUSEPORT; 174 /* 175 * XXX: How to deal with SO_REUSEPORT_LB here? 176 * Treat same as SO_REUSEPORT for now. 177 */ 178 if ((so->so_options & 179 (SO_REUSEADDR|SO_REUSEPORT_LB)) != 0) 180 reuseport_lb = SO_REUSEADDR|SO_REUSEPORT_LB; 181 } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 182 struct epoch_tracker et; 183 struct ifaddr *ifa; 184 185 sin6->sin6_port = 0; /* yech... */ 186 NET_EPOCH_ENTER(et); 187 if ((ifa = ifa_ifwithaddr((struct sockaddr *)sin6)) == 188 NULL && 189 (inp->inp_flags & INP_BINDANY) == 0) { 190 NET_EPOCH_EXIT(et); 191 return (EADDRNOTAVAIL); 192 } 193 194 /* 195 * XXX: bind to an anycast address might accidentally 196 * cause sending a packet with anycast source address. 197 * We should allow to bind to a deprecated address, since 198 * the application dares to use it. 199 */ 200 if (ifa != NULL && 201 ((struct in6_ifaddr *)ifa)->ia6_flags & 202 (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|IN6_IFF_DETACHED)) { 203 NET_EPOCH_EXIT(et); 204 return (EADDRNOTAVAIL); 205 } 206 NET_EPOCH_EXIT(et); 207 } 208 if (lport) { 209 struct inpcb *t; 210 struct tcptw *tw; 211 212 /* GROSS */ 213 if (ntohs(lport) <= V_ipport_reservedhigh && 214 ntohs(lport) >= V_ipport_reservedlow && 215 priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT)) 216 return (EACCES); 217 if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) && 218 priv_check_cred(inp->inp_cred, PRIV_NETINET_REUSEPORT) != 0) { 219 t = in6_pcblookup_local(pcbinfo, 220 &sin6->sin6_addr, lport, 221 INPLOOKUP_WILDCARD, cred); 222 if (t && 223 ((inp->inp_flags2 & INP_BINDMULTI) == 0) && 224 ((t->inp_flags & INP_TIMEWAIT) == 0) && 225 (so->so_type != SOCK_STREAM || 226 IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) && 227 (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || 228 !IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) || 229 (t->inp_flags2 & INP_REUSEPORT) || 230 (t->inp_flags2 & INP_REUSEPORT_LB) == 0) && 231 (inp->inp_cred->cr_uid != 232 t->inp_cred->cr_uid)) 233 return (EADDRINUSE); 234 235 /* 236 * If the socket is a BINDMULTI socket, then 237 * the credentials need to match and the 238 * original socket also has to have been bound 239 * with BINDMULTI. 240 */ 241 if (t && (! in_pcbbind_check_bindmulti(inp, t))) 242 return (EADDRINUSE); 243 244 #ifdef INET 245 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 && 246 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 247 struct sockaddr_in sin; 248 249 in6_sin6_2_sin(&sin, sin6); 250 t = in_pcblookup_local(pcbinfo, 251 sin.sin_addr, lport, 252 INPLOOKUP_WILDCARD, cred); 253 if (t && 254 ((inp->inp_flags2 & INP_BINDMULTI) == 0) && 255 ((t->inp_flags & 256 INP_TIMEWAIT) == 0) && 257 (so->so_type != SOCK_STREAM || 258 ntohl(t->inp_faddr.s_addr) == 259 INADDR_ANY) && 260 (inp->inp_cred->cr_uid != 261 t->inp_cred->cr_uid)) 262 return (EADDRINUSE); 263 264 if (t && (! in_pcbbind_check_bindmulti(inp, t))) 265 return (EADDRINUSE); 266 } 267 #endif 268 } 269 t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr, 270 lport, lookupflags, cred); 271 if (t && (t->inp_flags & INP_TIMEWAIT)) { 272 /* 273 * XXXRW: If an incpb has had its timewait 274 * state recycled, we treat the address as 275 * being in use (for now). This is better 276 * than a panic, but not desirable. 277 */ 278 tw = intotw(t); 279 if (tw == NULL || 280 ((reuseport & tw->tw_so_options) == 0 && 281 (reuseport_lb & tw->tw_so_options) == 0)) 282 return (EADDRINUSE); 283 } else if (t && (reuseport & inp_so_options(t)) == 0 && 284 (reuseport_lb & inp_so_options(t)) == 0) { 285 return (EADDRINUSE); 286 } 287 #ifdef INET 288 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 && 289 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 290 struct sockaddr_in sin; 291 292 in6_sin6_2_sin(&sin, sin6); 293 t = in_pcblookup_local(pcbinfo, sin.sin_addr, 294 lport, lookupflags, cred); 295 if (t && t->inp_flags & INP_TIMEWAIT) { 296 tw = intotw(t); 297 if (tw == NULL) 298 return (EADDRINUSE); 299 if ((reuseport & tw->tw_so_options) == 0 300 && (reuseport_lb & tw->tw_so_options) == 0 301 && (ntohl(t->inp_laddr.s_addr) != 302 INADDR_ANY || ((inp->inp_vflag & 303 INP_IPV6PROTO) == 304 (t->inp_vflag & INP_IPV6PROTO)))) 305 return (EADDRINUSE); 306 } else if (t && 307 (reuseport & inp_so_options(t)) == 0 && 308 (reuseport_lb & inp_so_options(t)) == 0 && 309 (ntohl(t->inp_laddr.s_addr) != INADDR_ANY || 310 (t->inp_vflag & INP_IPV6PROTO) != 0)) { 311 return (EADDRINUSE); 312 } 313 } 314 #endif 315 } 316 inp->in6p_laddr = sin6->sin6_addr; 317 } 318 if (lport == 0) { 319 if ((error = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0) { 320 /* Undo an address bind that may have occurred. */ 321 inp->in6p_laddr = in6addr_any; 322 return (error); 323 } 324 } else { 325 inp->inp_lport = lport; 326 if (in_pcbinshash(inp) != 0) { 327 inp->in6p_laddr = in6addr_any; 328 inp->inp_lport = 0; 329 return (EAGAIN); 330 } 331 } 332 return (0); 333 } 334 335 /* 336 * Transform old in6_pcbconnect() into an inner subroutine for new 337 * in6_pcbconnect(): Do some validity-checking on the remote 338 * address (in mbuf 'nam') and then determine local host address 339 * (i.e., which interface) to use to access that remote host. 340 * 341 * This preserves definition of in6_pcbconnect(), while supporting a 342 * slightly different version for T/TCP. (This is more than 343 * a bit of a kludge, but cleaning up the internal interfaces would 344 * have forced minor changes in every protocol). 345 */ 346 static int 347 in6_pcbladdr(struct inpcb *inp, struct sockaddr *nam, 348 struct in6_addr *plocal_addr6) 349 { 350 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; 351 int error = 0; 352 int scope_ambiguous = 0; 353 struct in6_addr in6a; 354 355 INP_WLOCK_ASSERT(inp); 356 INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo); /* XXXRW: why? */ 357 358 if (nam->sa_len != sizeof (*sin6)) 359 return (EINVAL); 360 if (sin6->sin6_family != AF_INET6) 361 return (EAFNOSUPPORT); 362 if (sin6->sin6_port == 0) 363 return (EADDRNOTAVAIL); 364 365 if (sin6->sin6_scope_id == 0 && !V_ip6_use_defzone) 366 scope_ambiguous = 1; 367 if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0) 368 return(error); 369 370 if (!CK_STAILQ_EMPTY(&V_in6_ifaddrhead)) { 371 /* 372 * If the destination address is UNSPECIFIED addr, 373 * use the loopback addr, e.g ::1. 374 */ 375 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) 376 sin6->sin6_addr = in6addr_loopback; 377 } 378 if ((error = prison_remote_ip6(inp->inp_cred, &sin6->sin6_addr)) != 0) 379 return (error); 380 381 error = in6_selectsrc_socket(sin6, inp->in6p_outputopts, 382 inp, inp->inp_cred, scope_ambiguous, &in6a, NULL); 383 if (error) 384 return (error); 385 386 /* 387 * Do not update this earlier, in case we return with an error. 388 * 389 * XXX: this in6_selectsrc_socket result might replace the bound local 390 * address with the address specified by setsockopt(IPV6_PKTINFO). 391 * Is it the intended behavior? 392 */ 393 *plocal_addr6 = in6a; 394 395 /* 396 * Don't do pcblookup call here; return interface in 397 * plocal_addr6 398 * and exit to caller, that will do the lookup. 399 */ 400 401 return (0); 402 } 403 404 /* 405 * Outer subroutine: 406 * Connect from a socket to a specified address. 407 * Both address and port must be specified in argument sin. 408 * If don't have a local address for this socket yet, 409 * then pick one. 410 */ 411 int 412 in6_pcbconnect_mbuf(struct inpcb *inp, struct sockaddr *nam, 413 struct ucred *cred, struct mbuf *m, bool rehash) 414 { 415 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 416 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; 417 struct sockaddr_in6 laddr6; 418 int error; 419 420 bzero(&laddr6, sizeof(laddr6)); 421 laddr6.sin6_family = AF_INET6; 422 423 INP_WLOCK_ASSERT(inp); 424 INP_HASH_WLOCK_ASSERT(pcbinfo); 425 426 /* 427 * Call inner routine, to assign local interface address. 428 * in6_pcbladdr() may automatically fill in sin6_scope_id. 429 */ 430 if ((error = in6_pcbladdr(inp, nam, &laddr6.sin6_addr)) != 0) 431 return (error); 432 433 if (in6_pcblookup_hash_locked(pcbinfo, &sin6->sin6_addr, 434 sin6->sin6_port, 435 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) 436 ? &laddr6.sin6_addr : &inp->in6p_laddr, 437 inp->inp_lport, 0, NULL) != NULL) { 438 return (EADDRINUSE); 439 } 440 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) { 441 if (inp->inp_lport == 0) { 442 /* 443 * rehash was required to be true in the past for 444 * this case; retain that convention. However, 445 * we now call in_pcb_lport_dest rather than 446 * in6_pcbbind; the former does not insert into 447 * the hash table, the latter does. Change rehash 448 * to false to do the in_pcbinshash below. 449 */ 450 KASSERT(rehash == true, 451 ("Rehashing required for unbound inps")); 452 rehash = false; 453 error = in_pcb_lport_dest(inp, 454 (struct sockaddr *) &laddr6, &inp->inp_lport, 455 (struct sockaddr *) sin6, sin6->sin6_port, cred, 0); 456 if (error) 457 return (error); 458 } 459 inp->in6p_laddr = laddr6.sin6_addr; 460 } 461 inp->in6p_faddr = sin6->sin6_addr; 462 inp->inp_fport = sin6->sin6_port; 463 /* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */ 464 inp->inp_flow &= ~IPV6_FLOWLABEL_MASK; 465 if (inp->inp_flags & IN6P_AUTOFLOWLABEL) 466 inp->inp_flow |= 467 (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK); 468 469 if (rehash) { 470 in_pcbrehash_mbuf(inp, m); 471 } else { 472 in_pcbinshash_mbuf(inp, m); 473 } 474 475 return (0); 476 } 477 478 int 479 in6_pcbconnect(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred) 480 { 481 482 return (in6_pcbconnect_mbuf(inp, nam, cred, NULL, true)); 483 } 484 485 void 486 in6_pcbdisconnect(struct inpcb *inp) 487 { 488 489 INP_WLOCK_ASSERT(inp); 490 INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo); 491 492 bzero((caddr_t)&inp->in6p_faddr, sizeof(inp->in6p_faddr)); 493 inp->inp_fport = 0; 494 /* clear flowinfo - draft-itojun-ipv6-flowlabel-api-00 */ 495 inp->inp_flow &= ~IPV6_FLOWLABEL_MASK; 496 in_pcbrehash(inp); 497 } 498 499 struct sockaddr * 500 in6_sockaddr(in_port_t port, struct in6_addr *addr_p) 501 { 502 struct sockaddr_in6 *sin6; 503 504 sin6 = malloc(sizeof *sin6, M_SONAME, M_WAITOK); 505 bzero(sin6, sizeof *sin6); 506 sin6->sin6_family = AF_INET6; 507 sin6->sin6_len = sizeof(*sin6); 508 sin6->sin6_port = port; 509 sin6->sin6_addr = *addr_p; 510 (void)sa6_recoverscope(sin6); /* XXX: should catch errors */ 511 512 return (struct sockaddr *)sin6; 513 } 514 515 struct sockaddr * 516 in6_v4mapsin6_sockaddr(in_port_t port, struct in_addr *addr_p) 517 { 518 struct sockaddr_in sin; 519 struct sockaddr_in6 *sin6_p; 520 521 bzero(&sin, sizeof sin); 522 sin.sin_family = AF_INET; 523 sin.sin_len = sizeof(sin); 524 sin.sin_port = port; 525 sin.sin_addr = *addr_p; 526 527 sin6_p = malloc(sizeof *sin6_p, M_SONAME, 528 M_WAITOK); 529 in6_sin_2_v4mapsin6(&sin, sin6_p); 530 531 return (struct sockaddr *)sin6_p; 532 } 533 534 int 535 in6_getsockaddr(struct socket *so, struct sockaddr **nam) 536 { 537 struct inpcb *inp; 538 struct in6_addr addr; 539 in_port_t port; 540 541 inp = sotoinpcb(so); 542 KASSERT(inp != NULL, ("in6_getsockaddr: inp == NULL")); 543 544 INP_RLOCK(inp); 545 port = inp->inp_lport; 546 addr = inp->in6p_laddr; 547 INP_RUNLOCK(inp); 548 549 *nam = in6_sockaddr(port, &addr); 550 return 0; 551 } 552 553 int 554 in6_getpeeraddr(struct socket *so, struct sockaddr **nam) 555 { 556 struct inpcb *inp; 557 struct in6_addr addr; 558 in_port_t port; 559 560 inp = sotoinpcb(so); 561 KASSERT(inp != NULL, ("in6_getpeeraddr: inp == NULL")); 562 563 INP_RLOCK(inp); 564 port = inp->inp_fport; 565 addr = inp->in6p_faddr; 566 INP_RUNLOCK(inp); 567 568 *nam = in6_sockaddr(port, &addr); 569 return 0; 570 } 571 572 int 573 in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam) 574 { 575 struct inpcb *inp; 576 int error; 577 578 inp = sotoinpcb(so); 579 KASSERT(inp != NULL, ("in6_mapped_sockaddr: inp == NULL")); 580 581 #ifdef INET 582 if ((inp->inp_vflag & (INP_IPV4 | INP_IPV6)) == INP_IPV4) { 583 error = in_getsockaddr(so, nam); 584 if (error == 0) 585 in6_sin_2_v4mapsin6_in_sock(nam); 586 } else 587 #endif 588 { 589 /* scope issues will be handled in in6_getsockaddr(). */ 590 error = in6_getsockaddr(so, nam); 591 } 592 593 return error; 594 } 595 596 int 597 in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam) 598 { 599 struct inpcb *inp; 600 int error; 601 602 inp = sotoinpcb(so); 603 KASSERT(inp != NULL, ("in6_mapped_peeraddr: inp == NULL")); 604 605 #ifdef INET 606 if ((inp->inp_vflag & (INP_IPV4 | INP_IPV6)) == INP_IPV4) { 607 error = in_getpeeraddr(so, nam); 608 if (error == 0) 609 in6_sin_2_v4mapsin6_in_sock(nam); 610 } else 611 #endif 612 /* scope issues will be handled in in6_getpeeraddr(). */ 613 error = in6_getpeeraddr(so, nam); 614 615 return error; 616 } 617 618 /* 619 * Pass some notification to all connections of a protocol 620 * associated with address dst. The local address and/or port numbers 621 * may be specified to limit the search. The "usual action" will be 622 * taken, depending on the ctlinput cmd. The caller must filter any 623 * cmds that are uninteresting (e.g., no error in the map). 624 * Call the protocol specific routine (if any) to report 625 * any errors for each matching socket. 626 */ 627 void 628 in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst, 629 u_int fport_arg, const struct sockaddr *src, u_int lport_arg, 630 int cmd, void *cmdarg, 631 struct inpcb *(*notify)(struct inpcb *, int)) 632 { 633 struct inpcb *inp, *inp_temp; 634 struct sockaddr_in6 sa6_src, *sa6_dst; 635 u_short fport = fport_arg, lport = lport_arg; 636 u_int32_t flowinfo; 637 int errno; 638 639 if ((unsigned)cmd >= PRC_NCMDS || dst->sa_family != AF_INET6) 640 return; 641 642 sa6_dst = (struct sockaddr_in6 *)dst; 643 if (IN6_IS_ADDR_UNSPECIFIED(&sa6_dst->sin6_addr)) 644 return; 645 646 /* 647 * note that src can be NULL when we get notify by local fragmentation. 648 */ 649 sa6_src = (src == NULL) ? sa6_any : *(const struct sockaddr_in6 *)src; 650 flowinfo = sa6_src.sin6_flowinfo; 651 652 /* 653 * Redirects go to all references to the destination, 654 * and use in6_rtchange to invalidate the route cache. 655 * Dead host indications: also use in6_rtchange to invalidate 656 * the cache, and deliver the error to all the sockets. 657 * Otherwise, if we have knowledge of the local port and address, 658 * deliver only to that socket. 659 */ 660 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) { 661 fport = 0; 662 lport = 0; 663 bzero((caddr_t)&sa6_src.sin6_addr, sizeof(sa6_src.sin6_addr)); 664 665 if (cmd != PRC_HOSTDEAD) 666 notify = in6_rtchange; 667 } 668 errno = inet6ctlerrmap[cmd]; 669 INP_INFO_WLOCK(pcbinfo); 670 CK_LIST_FOREACH_SAFE(inp, pcbinfo->ipi_listhead, inp_list, inp_temp) { 671 INP_WLOCK(inp); 672 if ((inp->inp_vflag & INP_IPV6) == 0) { 673 INP_WUNLOCK(inp); 674 continue; 675 } 676 677 /* 678 * If the error designates a new path MTU for a destination 679 * and the application (associated with this socket) wanted to 680 * know the value, notify. 681 * XXX: should we avoid to notify the value to TCP sockets? 682 */ 683 if (cmd == PRC_MSGSIZE && cmdarg != NULL) 684 ip6_notify_pmtu(inp, (struct sockaddr_in6 *)dst, 685 *(u_int32_t *)cmdarg); 686 687 /* 688 * Detect if we should notify the error. If no source and 689 * destination ports are specifed, but non-zero flowinfo and 690 * local address match, notify the error. This is the case 691 * when the error is delivered with an encrypted buffer 692 * by ESP. Otherwise, just compare addresses and ports 693 * as usual. 694 */ 695 if (lport == 0 && fport == 0 && flowinfo && 696 inp->inp_socket != NULL && 697 flowinfo == (inp->inp_flow & IPV6_FLOWLABEL_MASK) && 698 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, &sa6_src.sin6_addr)) 699 goto do_notify; 700 else if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, 701 &sa6_dst->sin6_addr) || 702 inp->inp_socket == 0 || 703 (lport && inp->inp_lport != lport) || 704 (!IN6_IS_ADDR_UNSPECIFIED(&sa6_src.sin6_addr) && 705 !IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, 706 &sa6_src.sin6_addr)) || 707 (fport && inp->inp_fport != fport)) { 708 INP_WUNLOCK(inp); 709 continue; 710 } 711 712 do_notify: 713 if (notify) { 714 if ((*notify)(inp, errno)) 715 INP_WUNLOCK(inp); 716 } else 717 INP_WUNLOCK(inp); 718 } 719 INP_INFO_WUNLOCK(pcbinfo); 720 } 721 722 /* 723 * Lookup a PCB based on the local address and port. Caller must hold the 724 * hash lock. No inpcb locks or references are acquired. 725 */ 726 struct inpcb * 727 in6_pcblookup_local(struct inpcbinfo *pcbinfo, struct in6_addr *laddr, 728 u_short lport, int lookupflags, struct ucred *cred) 729 { 730 struct inpcb *inp; 731 int matchwild = 3, wildcard; 732 733 KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0, 734 ("%s: invalid lookup flags %d", __func__, lookupflags)); 735 736 INP_HASH_LOCK_ASSERT(pcbinfo); 737 738 if ((lookupflags & INPLOOKUP_WILDCARD) == 0) { 739 struct inpcbhead *head; 740 /* 741 * Look for an unconnected (wildcard foreign addr) PCB that 742 * matches the local address and port we're looking for. 743 */ 744 head = &pcbinfo->ipi_hashbase[INP_PCBHASH( 745 INP6_PCBHASHKEY(&in6addr_any), lport, 0, 746 pcbinfo->ipi_hashmask)]; 747 CK_LIST_FOREACH(inp, head, inp_hash) { 748 /* XXX inp locking */ 749 if ((inp->inp_vflag & INP_IPV6) == 0) 750 continue; 751 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && 752 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) && 753 inp->inp_lport == lport) { 754 /* Found. */ 755 if (cred == NULL || 756 prison_equal_ip6(cred->cr_prison, 757 inp->inp_cred->cr_prison)) 758 return (inp); 759 } 760 } 761 /* 762 * Not found. 763 */ 764 return (NULL); 765 } else { 766 struct inpcbporthead *porthash; 767 struct inpcbport *phd; 768 struct inpcb *match = NULL; 769 /* 770 * Best fit PCB lookup. 771 * 772 * First see if this local port is in use by looking on the 773 * port hash list. 774 */ 775 porthash = &pcbinfo->ipi_porthashbase[INP_PCBPORTHASH(lport, 776 pcbinfo->ipi_porthashmask)]; 777 CK_LIST_FOREACH(phd, porthash, phd_hash) { 778 if (phd->phd_port == lport) 779 break; 780 } 781 if (phd != NULL) { 782 /* 783 * Port is in use by one or more PCBs. Look for best 784 * fit. 785 */ 786 CK_LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) { 787 wildcard = 0; 788 if (cred != NULL && 789 !prison_equal_ip6(cred->cr_prison, 790 inp->inp_cred->cr_prison)) 791 continue; 792 /* XXX inp locking */ 793 if ((inp->inp_vflag & INP_IPV6) == 0) 794 continue; 795 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) 796 wildcard++; 797 if (!IN6_IS_ADDR_UNSPECIFIED( 798 &inp->in6p_laddr)) { 799 if (IN6_IS_ADDR_UNSPECIFIED(laddr)) 800 wildcard++; 801 else if (!IN6_ARE_ADDR_EQUAL( 802 &inp->in6p_laddr, laddr)) 803 continue; 804 } else { 805 if (!IN6_IS_ADDR_UNSPECIFIED(laddr)) 806 wildcard++; 807 } 808 if (wildcard < matchwild) { 809 match = inp; 810 matchwild = wildcard; 811 if (matchwild == 0) 812 break; 813 } 814 } 815 } 816 return (match); 817 } 818 } 819 820 void 821 in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) 822 { 823 struct inpcb *inp; 824 struct in6_multi *inm; 825 struct in6_mfilter *imf; 826 struct ip6_moptions *im6o; 827 828 INP_INFO_WLOCK(pcbinfo); 829 CK_LIST_FOREACH(inp, pcbinfo->ipi_listhead, inp_list) { 830 INP_WLOCK(inp); 831 if (__predict_false(inp->inp_flags2 & INP_FREED)) { 832 INP_WUNLOCK(inp); 833 continue; 834 } 835 im6o = inp->in6p_moptions; 836 if ((inp->inp_vflag & INP_IPV6) && im6o != NULL) { 837 /* 838 * Unselect the outgoing ifp for multicast if it 839 * is being detached. 840 */ 841 if (im6o->im6o_multicast_ifp == ifp) 842 im6o->im6o_multicast_ifp = NULL; 843 /* 844 * Drop multicast group membership if we joined 845 * through the interface being detached. 846 */ 847 restart: 848 IP6_MFILTER_FOREACH(imf, &im6o->im6o_head) { 849 if ((inm = imf->im6f_in6m) == NULL) 850 continue; 851 if (inm->in6m_ifp != ifp) 852 continue; 853 ip6_mfilter_remove(&im6o->im6o_head, imf); 854 IN6_MULTI_LOCK_ASSERT(); 855 in6_leavegroup_locked(inm, NULL); 856 ip6_mfilter_free(imf); 857 goto restart; 858 } 859 } 860 INP_WUNLOCK(inp); 861 } 862 INP_INFO_WUNLOCK(pcbinfo); 863 } 864 865 /* 866 * Check for alternatives when higher level complains 867 * about service problems. For now, invalidate cached 868 * routing information. If the route was created dynamically 869 * (by a redirect), time to try a default gateway again. 870 */ 871 void 872 in6_losing(struct inpcb *inp) 873 { 874 875 RO_INVALIDATE_CACHE(&inp->inp_route6); 876 } 877 878 /* 879 * After a routing change, flush old routing 880 * and allocate a (hopefully) better one. 881 */ 882 struct inpcb * 883 in6_rtchange(struct inpcb *inp, int errno __unused) 884 { 885 886 RO_INVALIDATE_CACHE(&inp->inp_route6); 887 return inp; 888 } 889 890 static struct inpcb * 891 in6_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo, 892 const struct in6_addr *laddr, uint16_t lport, const struct in6_addr *faddr, 893 uint16_t fport, int lookupflags) 894 { 895 struct inpcb *local_wild; 896 const struct inpcblbgrouphead *hdr; 897 struct inpcblbgroup *grp; 898 uint32_t idx; 899 900 INP_HASH_LOCK_ASSERT(pcbinfo); 901 902 hdr = &pcbinfo->ipi_lbgrouphashbase[ 903 INP_PCBPORTHASH(lport, pcbinfo->ipi_lbgrouphashmask)]; 904 905 /* 906 * Order of socket selection: 907 * 1. non-wild. 908 * 2. wild (if lookupflags contains INPLOOKUP_WILDCARD). 909 * 910 * NOTE: 911 * - Load balanced group does not contain jailed sockets. 912 * - Load balanced does not contain IPv4 mapped INET6 wild sockets. 913 */ 914 local_wild = NULL; 915 CK_LIST_FOREACH(grp, hdr, il_list) { 916 #ifdef INET 917 if (!(grp->il_vflag & INP_IPV6)) 918 continue; 919 #endif 920 if (grp->il_lport != lport) 921 continue; 922 923 idx = INP_PCBLBGROUP_PKTHASH(INP6_PCBHASHKEY(faddr), lport, 924 fport) % grp->il_inpcnt; 925 if (IN6_ARE_ADDR_EQUAL(&grp->il6_laddr, laddr)) 926 return (grp->il_inp[idx]); 927 if (IN6_IS_ADDR_UNSPECIFIED(&grp->il6_laddr) && 928 (lookupflags & INPLOOKUP_WILDCARD) != 0) 929 local_wild = grp->il_inp[idx]; 930 } 931 return (local_wild); 932 } 933 934 #ifdef PCBGROUP 935 /* 936 * Lookup PCB in hash list, using pcbgroup tables. 937 */ 938 static struct inpcb * 939 in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, 940 struct in6_addr *faddr, u_int fport_arg, struct in6_addr *laddr, 941 u_int lport_arg, int lookupflags, struct ifnet *ifp) 942 { 943 struct inpcbhead *head; 944 struct inpcb *inp, *tmpinp; 945 u_short fport = fport_arg, lport = lport_arg; 946 bool locked; 947 948 /* 949 * First look for an exact match. 950 */ 951 tmpinp = NULL; 952 INP_GROUP_LOCK(pcbgroup); 953 head = &pcbgroup->ipg_hashbase[INP_PCBHASH( 954 INP6_PCBHASHKEY(faddr), lport, fport, pcbgroup->ipg_hashmask)]; 955 CK_LIST_FOREACH(inp, head, inp_pcbgrouphash) { 956 /* XXX inp locking */ 957 if ((inp->inp_vflag & INP_IPV6) == 0) 958 continue; 959 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) && 960 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) && 961 inp->inp_fport == fport && 962 inp->inp_lport == lport) { 963 /* 964 * XXX We should be able to directly return 965 * the inp here, without any checks. 966 * Well unless both bound with SO_REUSEPORT? 967 */ 968 if (prison_flag(inp->inp_cred, PR_IP6)) 969 goto found; 970 if (tmpinp == NULL) 971 tmpinp = inp; 972 } 973 } 974 if (tmpinp != NULL) { 975 inp = tmpinp; 976 goto found; 977 } 978 979 /* 980 * Then look for a wildcard match in the pcbgroup. 981 */ 982 if ((lookupflags & INPLOOKUP_WILDCARD) != 0) { 983 struct inpcb *local_wild = NULL, *local_exact = NULL; 984 struct inpcb *jail_wild = NULL; 985 int injail; 986 987 /* 988 * Order of socket selection - we always prefer jails. 989 * 1. jailed, non-wild. 990 * 2. jailed, wild. 991 * 3. non-jailed, non-wild. 992 * 4. non-jailed, wild. 993 */ 994 head = &pcbgroup->ipg_hashbase[ 995 INP_PCBHASH(INADDR_ANY, lport, 0, pcbgroup->ipg_hashmask)]; 996 CK_LIST_FOREACH(inp, head, inp_pcbgrouphash) { 997 /* XXX inp locking */ 998 if ((inp->inp_vflag & INP_IPV6) == 0) 999 continue; 1000 1001 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) || 1002 inp->inp_lport != lport) { 1003 continue; 1004 } 1005 1006 injail = prison_flag(inp->inp_cred, PR_IP6); 1007 if (injail) { 1008 if (prison_check_ip6(inp->inp_cred, 1009 laddr) != 0) 1010 continue; 1011 } else { 1012 if (local_exact != NULL) 1013 continue; 1014 } 1015 1016 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr)) { 1017 if (injail) 1018 goto found; 1019 else 1020 local_exact = inp; 1021 } else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) { 1022 if (injail) 1023 jail_wild = inp; 1024 else 1025 local_wild = inp; 1026 } 1027 } /* LIST_FOREACH */ 1028 1029 inp = jail_wild; 1030 if (inp == NULL) 1031 inp = jail_wild; 1032 if (inp == NULL) 1033 inp = local_exact; 1034 if (inp == NULL) 1035 inp = local_wild; 1036 if (inp != NULL) 1037 goto found; 1038 } 1039 1040 /* 1041 * Then look for a wildcard match, if requested. 1042 */ 1043 if ((lookupflags & INPLOOKUP_WILDCARD) != 0) { 1044 struct inpcb *local_wild = NULL, *local_exact = NULL; 1045 struct inpcb *jail_wild = NULL; 1046 int injail; 1047 1048 /* 1049 * Order of socket selection - we always prefer jails. 1050 * 1. jailed, non-wild. 1051 * 2. jailed, wild. 1052 * 3. non-jailed, non-wild. 1053 * 4. non-jailed, wild. 1054 */ 1055 head = &pcbinfo->ipi_wildbase[INP_PCBHASH( 1056 INP6_PCBHASHKEY(&in6addr_any), lport, 0, 1057 pcbinfo->ipi_wildmask)]; 1058 CK_LIST_FOREACH(inp, head, inp_pcbgroup_wild) { 1059 /* XXX inp locking */ 1060 if ((inp->inp_vflag & INP_IPV6) == 0) 1061 continue; 1062 1063 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) || 1064 inp->inp_lport != lport) { 1065 continue; 1066 } 1067 1068 injail = prison_flag(inp->inp_cred, PR_IP6); 1069 if (injail) { 1070 if (prison_check_ip6(inp->inp_cred, 1071 laddr) != 0) 1072 continue; 1073 } else { 1074 if (local_exact != NULL) 1075 continue; 1076 } 1077 1078 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr)) { 1079 if (injail) 1080 goto found; 1081 else 1082 local_exact = inp; 1083 } else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) { 1084 if (injail) 1085 jail_wild = inp; 1086 else 1087 local_wild = inp; 1088 } 1089 } /* LIST_FOREACH */ 1090 1091 inp = jail_wild; 1092 if (inp == NULL) 1093 inp = jail_wild; 1094 if (inp == NULL) 1095 inp = local_exact; 1096 if (inp == NULL) 1097 inp = local_wild; 1098 if (inp != NULL) 1099 goto found; 1100 } /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */ 1101 INP_GROUP_UNLOCK(pcbgroup); 1102 return (NULL); 1103 1104 found: 1105 if (lookupflags & INPLOOKUP_WLOCKPCB) 1106 locked = INP_TRY_WLOCK(inp); 1107 else if (lookupflags & INPLOOKUP_RLOCKPCB) 1108 locked = INP_TRY_RLOCK(inp); 1109 else 1110 panic("%s: locking buf", __func__); 1111 if (!locked) 1112 in_pcbref(inp); 1113 INP_GROUP_UNLOCK(pcbgroup); 1114 if (!locked) { 1115 if (lookupflags & INPLOOKUP_WLOCKPCB) { 1116 INP_WLOCK(inp); 1117 if (in_pcbrele_wlocked(inp)) 1118 return (NULL); 1119 } else { 1120 INP_RLOCK(inp); 1121 if (in_pcbrele_rlocked(inp)) 1122 return (NULL); 1123 } 1124 } 1125 #ifdef INVARIANTS 1126 if (lookupflags & INPLOOKUP_WLOCKPCB) 1127 INP_WLOCK_ASSERT(inp); 1128 else 1129 INP_RLOCK_ASSERT(inp); 1130 #endif 1131 return (inp); 1132 } 1133 #endif /* PCBGROUP */ 1134 1135 /* 1136 * Lookup PCB in hash list. Used in in_pcb.c as well as here. 1137 */ 1138 struct inpcb * 1139 in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, 1140 u_int fport_arg, struct in6_addr *laddr, u_int lport_arg, 1141 int lookupflags, struct ifnet *ifp) 1142 { 1143 struct inpcbhead *head; 1144 struct inpcb *inp, *tmpinp; 1145 u_short fport = fport_arg, lport = lport_arg; 1146 1147 KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0, 1148 ("%s: invalid lookup flags %d", __func__, lookupflags)); 1149 1150 INP_HASH_LOCK_ASSERT(pcbinfo); 1151 1152 /* 1153 * First look for an exact match. 1154 */ 1155 tmpinp = NULL; 1156 head = &pcbinfo->ipi_hashbase[INP_PCBHASH( 1157 INP6_PCBHASHKEY(faddr), lport, fport, pcbinfo->ipi_hashmask)]; 1158 CK_LIST_FOREACH(inp, head, inp_hash) { 1159 /* XXX inp locking */ 1160 if ((inp->inp_vflag & INP_IPV6) == 0) 1161 continue; 1162 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) && 1163 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) && 1164 inp->inp_fport == fport && 1165 inp->inp_lport == lport) { 1166 /* 1167 * XXX We should be able to directly return 1168 * the inp here, without any checks. 1169 * Well unless both bound with SO_REUSEPORT? 1170 */ 1171 if (prison_flag(inp->inp_cred, PR_IP6)) 1172 return (inp); 1173 if (tmpinp == NULL) 1174 tmpinp = inp; 1175 } 1176 } 1177 if (tmpinp != NULL) 1178 return (tmpinp); 1179 1180 /* 1181 * Then look in lb group (for wildcard match). 1182 */ 1183 if ((lookupflags & INPLOOKUP_WILDCARD) != 0) { 1184 inp = in6_pcblookup_lbgroup(pcbinfo, laddr, lport, faddr, 1185 fport, lookupflags); 1186 if (inp != NULL) 1187 return (inp); 1188 } 1189 1190 /* 1191 * Then look for a wildcard match, if requested. 1192 */ 1193 if ((lookupflags & INPLOOKUP_WILDCARD) != 0) { 1194 struct inpcb *local_wild = NULL, *local_exact = NULL; 1195 struct inpcb *jail_wild = NULL; 1196 int injail; 1197 1198 /* 1199 * Order of socket selection - we always prefer jails. 1200 * 1. jailed, non-wild. 1201 * 2. jailed, wild. 1202 * 3. non-jailed, non-wild. 1203 * 4. non-jailed, wild. 1204 */ 1205 head = &pcbinfo->ipi_hashbase[INP_PCBHASH( 1206 INP6_PCBHASHKEY(&in6addr_any), lport, 0, 1207 pcbinfo->ipi_hashmask)]; 1208 CK_LIST_FOREACH(inp, head, inp_hash) { 1209 /* XXX inp locking */ 1210 if ((inp->inp_vflag & INP_IPV6) == 0) 1211 continue; 1212 1213 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) || 1214 inp->inp_lport != lport) { 1215 continue; 1216 } 1217 1218 injail = prison_flag(inp->inp_cred, PR_IP6); 1219 if (injail) { 1220 if (prison_check_ip6(inp->inp_cred, 1221 laddr) != 0) 1222 continue; 1223 } else { 1224 if (local_exact != NULL) 1225 continue; 1226 } 1227 1228 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr)) { 1229 if (injail) 1230 return (inp); 1231 else 1232 local_exact = inp; 1233 } else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) { 1234 if (injail) 1235 jail_wild = inp; 1236 else 1237 local_wild = inp; 1238 } 1239 } /* LIST_FOREACH */ 1240 1241 if (jail_wild != NULL) 1242 return (jail_wild); 1243 if (local_exact != NULL) 1244 return (local_exact); 1245 if (local_wild != NULL) 1246 return (local_wild); 1247 } /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */ 1248 1249 /* 1250 * Not found. 1251 */ 1252 return (NULL); 1253 } 1254 1255 /* 1256 * Lookup PCB in hash list, using pcbinfo tables. This variation locks the 1257 * hash list lock, and will return the inpcb locked (i.e., requires 1258 * INPLOOKUP_LOCKPCB). 1259 */ 1260 static struct inpcb * 1261 in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, 1262 u_int fport, struct in6_addr *laddr, u_int lport, int lookupflags, 1263 struct ifnet *ifp) 1264 { 1265 struct inpcb *inp; 1266 1267 inp = in6_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport, 1268 (lookupflags & ~(INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)), ifp); 1269 if (inp != NULL) { 1270 if (lookupflags & INPLOOKUP_WLOCKPCB) { 1271 INP_WLOCK(inp); 1272 if (__predict_false(inp->inp_flags2 & INP_FREED)) { 1273 INP_WUNLOCK(inp); 1274 inp = NULL; 1275 } 1276 } else if (lookupflags & INPLOOKUP_RLOCKPCB) { 1277 INP_RLOCK(inp); 1278 if (__predict_false(inp->inp_flags2 & INP_FREED)) { 1279 INP_RUNLOCK(inp); 1280 inp = NULL; 1281 } 1282 } else 1283 panic("%s: locking bug", __func__); 1284 #ifdef INVARIANTS 1285 if (inp != NULL) { 1286 if (lookupflags & INPLOOKUP_WLOCKPCB) 1287 INP_WLOCK_ASSERT(inp); 1288 else 1289 INP_RLOCK_ASSERT(inp); 1290 } 1291 #endif 1292 } 1293 return (inp); 1294 } 1295 1296 /* 1297 * Public inpcb lookup routines, accepting a 4-tuple, and optionally, an mbuf 1298 * from which a pre-calculated hash value may be extracted. 1299 * 1300 * Possibly more of this logic should be in in6_pcbgroup.c. 1301 */ 1302 struct inpcb * 1303 in6_pcblookup(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, u_int fport, 1304 struct in6_addr *laddr, u_int lport, int lookupflags, struct ifnet *ifp) 1305 { 1306 #if defined(PCBGROUP) && !defined(RSS) 1307 struct inpcbgroup *pcbgroup; 1308 #endif 1309 1310 KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0, 1311 ("%s: invalid lookup flags %d", __func__, lookupflags)); 1312 KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)) != 0, 1313 ("%s: LOCKPCB not set", __func__)); 1314 1315 /* 1316 * When not using RSS, use connection groups in preference to the 1317 * reservation table when looking up 4-tuples. When using RSS, just 1318 * use the reservation table, due to the cost of the Toeplitz hash 1319 * in software. 1320 * 1321 * XXXRW: This policy belongs in the pcbgroup code, as in principle 1322 * we could be doing RSS with a non-Toeplitz hash that is affordable 1323 * in software. 1324 */ 1325 #if defined(PCBGROUP) && !defined(RSS) 1326 if (in_pcbgroup_enabled(pcbinfo)) { 1327 pcbgroup = in6_pcbgroup_bytuple(pcbinfo, laddr, lport, faddr, 1328 fport); 1329 return (in6_pcblookup_group(pcbinfo, pcbgroup, faddr, fport, 1330 laddr, lport, lookupflags, ifp)); 1331 } 1332 #endif 1333 return (in6_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport, 1334 lookupflags, ifp)); 1335 } 1336 1337 struct inpcb * 1338 in6_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, 1339 u_int fport, struct in6_addr *laddr, u_int lport, int lookupflags, 1340 struct ifnet *ifp, struct mbuf *m) 1341 { 1342 #ifdef PCBGROUP 1343 struct inpcbgroup *pcbgroup; 1344 #endif 1345 1346 KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0, 1347 ("%s: invalid lookup flags %d", __func__, lookupflags)); 1348 KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)) != 0, 1349 ("%s: LOCKPCB not set", __func__)); 1350 1351 #ifdef PCBGROUP 1352 /* 1353 * If we can use a hardware-generated hash to look up the connection 1354 * group, use that connection group to find the inpcb. Otherwise 1355 * fall back on a software hash -- or the reservation table if we're 1356 * using RSS. 1357 * 1358 * XXXRW: As above, that policy belongs in the pcbgroup code. 1359 */ 1360 if (in_pcbgroup_enabled(pcbinfo) && 1361 M_HASHTYPE_TEST(m, M_HASHTYPE_NONE) == 0) { 1362 pcbgroup = in6_pcbgroup_byhash(pcbinfo, M_HASHTYPE_GET(m), 1363 m->m_pkthdr.flowid); 1364 if (pcbgroup != NULL) 1365 return (in6_pcblookup_group(pcbinfo, pcbgroup, faddr, 1366 fport, laddr, lport, lookupflags, ifp)); 1367 #ifndef RSS 1368 pcbgroup = in6_pcbgroup_bytuple(pcbinfo, laddr, lport, faddr, 1369 fport); 1370 return (in6_pcblookup_group(pcbinfo, pcbgroup, faddr, fport, 1371 laddr, lport, lookupflags, ifp)); 1372 #endif 1373 } 1374 #endif 1375 return (in6_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport, 1376 lookupflags, ifp)); 1377 } 1378 1379 void 1380 init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int srcordst) 1381 { 1382 struct ip6_hdr *ip; 1383 1384 ip = mtod(m, struct ip6_hdr *); 1385 bzero(sin6, sizeof(*sin6)); 1386 sin6->sin6_len = sizeof(*sin6); 1387 sin6->sin6_family = AF_INET6; 1388 sin6->sin6_addr = srcordst ? ip->ip6_dst : ip->ip6_src; 1389 1390 (void)sa6_recoverscope(sin6); /* XXX: should catch errors... */ 1391 1392 return; 1393 } 1394