diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2025-02-06 14:14:09 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2025-02-06 14:14:09 +0000 |
| commit | 9a4131629bb3083ddc02a32950e4eb4806a07710 (patch) | |
| tree | 9914ccf2a4020044d8ee7db40eaa8955ae3ec064 /sys/netinet6 | |
| parent | 2f02ab8add0822e985ee2d936fc1ed70933e123e (diff) | |
Diffstat (limited to 'sys/netinet6')
| -rw-r--r-- | sys/netinet6/in6_pcb.c | 20 | ||||
| -rw-r--r-- | sys/netinet6/in6_pcb.h | 2 |
2 files changed, 14 insertions, 8 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index b44fe5ed3553..82ddd7ebad8c 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -249,7 +249,7 @@ in6_pcbbind_avail(struct inpcb *inp, const struct sockaddr_in6 *sin6, * which has a unique 4-tuple. */ t = in6_pcblookup_local(inp->inp_pcbinfo, laddr, lport, - INPLOOKUP_WILDCARD, cred); + RT_ALL_FIBS, INPLOOKUP_WILDCARD, cred); if (t != NULL && (inp->inp_socket->so_type != SOCK_STREAM || IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) && @@ -263,8 +263,8 @@ in6_pcbbind_avail(struct inpcb *inp, const struct sockaddr_in6 *sin6, in6_sin6_2_sin(&sin, sin6); t = in_pcblookup_local(inp->inp_pcbinfo, - sin.sin_addr, lport, INPLOOKUP_WILDCARD, - cred); + sin.sin_addr, lport, RT_ALL_FIBS, + INPLOOKUP_WILDCARD, cred); if (t != NULL && (inp->inp_socket->so_type != SOCK_STREAM || in_nullhost(t->inp_faddr)) && @@ -275,7 +275,7 @@ in6_pcbbind_avail(struct inpcb *inp, const struct sockaddr_in6 *sin6, #endif } t = in6_pcblookup_local(inp->inp_pcbinfo, laddr, lport, - lookupflags, cred); + RT_ALL_FIBS, lookupflags, cred); if (t != NULL && ((reuseport | reuseport_lb) & t->inp_socket->so_options) == 0) return (EADDRINUSE); @@ -286,7 +286,7 @@ in6_pcbbind_avail(struct inpcb *inp, const struct sockaddr_in6 *sin6, in6_sin6_2_sin(&sin, sin6); t = in_pcblookup_local(inp->inp_pcbinfo, sin.sin_addr, - lport, lookupflags, cred); + lport, RT_ALL_FIBS, lookupflags, cred); if (t != NULL && ((reuseport | reuseport_lb) & t->inp_socket->so_options) == 0 && (!in_nullhost(t->inp_laddr) || @@ -720,13 +720,15 @@ in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr_in6 *sa6_dst, */ struct inpcb * in6_pcblookup_local(struct inpcbinfo *pcbinfo, const struct in6_addr *laddr, - u_short lport, int lookupflags, struct ucred *cred) + u_short lport, int fib, int lookupflags, struct ucred *cred) { struct inpcb *inp; int matchwild = 3, wildcard; KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0, ("%s: invalid lookup flags %d", __func__, lookupflags)); + KASSERT(fib == RT_ALL_FIBS || (fib >= 0 && fib < V_rt_numfibs), + ("%s: invalid fib %d", __func__, fib)); INP_HASH_LOCK_ASSERT(pcbinfo); @@ -744,7 +746,8 @@ in6_pcblookup_local(struct inpcbinfo *pcbinfo, const struct in6_addr *laddr, continue; if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) && - inp->inp_lport == lport) { + inp->inp_lport == lport && (fib == RT_ALL_FIBS || + inp->inp_inc.inc_fibnum == fib)) { /* Found. */ if (prison_equal_ip6(cred->cr_prison, inp->inp_cred->cr_prison)) @@ -784,6 +787,9 @@ in6_pcblookup_local(struct inpcbinfo *pcbinfo, const struct in6_addr *laddr, /* XXX inp locking */ if ((inp->inp_vflag & INP_IPV6) == 0) continue; + if (fib != RT_ALL_FIBS && + inp->inp_inc.inc_fibnum != fib) + continue; if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) wildcard++; if (!IN6_IS_ADDR_UNSPECIFIED( diff --git a/sys/netinet6/in6_pcb.h b/sys/netinet6/in6_pcb.h index 98a4d27ddb35..eab095780a19 100644 --- a/sys/netinet6/in6_pcb.h +++ b/sys/netinet6/in6_pcb.h @@ -75,7 +75,7 @@ int in6_pcbconnect(struct inpcb *, struct sockaddr_in6 *, struct ucred *, bool); void in6_pcbdisconnect(struct inpcb *); struct inpcb *in6_pcblookup_local(struct inpcbinfo *, const struct in6_addr *, - u_short, int, struct ucred *); + u_short, int, int, struct ucred *); struct inpcb *in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, const struct in6_addr *faddr, u_int fport_arg, const struct in6_addr *laddr, u_int lport_arg, |
