aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2025-02-06 14:14:09 +0000
committerMark Johnston <markj@FreeBSD.org>2025-02-06 14:14:09 +0000
commit9a4131629bb3083ddc02a32950e4eb4806a07710 (patch)
tree9914ccf2a4020044d8ee7db40eaa8955ae3ec064 /sys/netinet6
parent2f02ab8add0822e985ee2d936fc1ed70933e123e (diff)
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6_pcb.c20
-rw-r--r--sys/netinet6/in6_pcb.h2
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,