Date: Fri, 21 Feb 2025 01:57:14 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 062ca7e887e3 - stable/14 - inpcb: Imbue in(6)_pcblookup_local() with a FIB parameter Message-ID: <202502210157.51L1vEvA067351@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=062ca7e887e33267c85c698a6c318d5f29c3d786 commit 062ca7e887e33267c85c698a6c318d5f29c3d786 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2025-02-06 14:14:09 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2025-02-21 01:04:49 +0000 inpcb: Imbue in(6)_pcblookup_local() with a FIB parameter This is to enable a mode where duplicate inpcb bindings are permitted, and we want to look up an inpcb with a particular FIB. Thus, add a "fib" parameter to in_pcblookup() and related functions, and plumb it through. A fib value of RT_ALL_FIBS indicates that the lookup should ignore FIB numbers when searching. Otherwise, it should refer to a valid FIB number, and the returned inpcb should belong to the specific FIB. For now, just add the fib parameter where needed, as there are several layers to plumb through. No functional change intended. Reviewed by: glebius MFC after: 2 weeks Sponsored by: Klara, Inc. Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D48660 (cherry picked from commit 9a4131629bb3083ddc02a32950e4eb4806a07710) --- sys/netinet/in_pcb.c | 23 ++++++++++++++++------- sys/netinet/in_pcb_var.h | 4 ++-- sys/netinet6/in6_pcb.c | 20 +++++++++++++------- sys/netinet6/in6_pcb.h | 2 +- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 32b7f1f96492..84229ce39eb2 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -818,12 +818,14 @@ in_pcb_lport_dest(struct inpcb *inp, struct sockaddr *lsa, u_short *lportp, #ifdef INET6 if ((inp->inp_vflag & INP_IPV6) != 0) { tmpinp = in6_pcblookup_local(pcbinfo, - &inp->in6p_laddr, lport, lookupflags, cred); + &inp->in6p_laddr, lport, RT_ALL_FIBS, + lookupflags, cred); #ifdef INET if (tmpinp == NULL && (inp->inp_vflag & INP_IPV4)) tmpinp = in_pcblookup_local(pcbinfo, - laddr, lport, lookupflags, cred); + laddr, lport, RT_ALL_FIBS, + lookupflags, cred); #endif } #endif @@ -832,7 +834,7 @@ in_pcb_lport_dest(struct inpcb *inp, struct sockaddr *lsa, u_short *lportp, #endif #ifdef INET tmpinp = in_pcblookup_local(pcbinfo, laddr, - lport, lookupflags, cred); + lport, RT_ALL_FIBS, lookupflags, cred); #endif } } while (tmpinp != NULL); @@ -931,7 +933,7 @@ in_pcbbind_avail(struct inpcb *inp, const struct in_addr laddr, * which has a unique 4-tuple. */ t = in_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 || in_nullhost(t->inp_faddr)) && @@ -939,7 +941,7 @@ in_pcbbind_avail(struct inpcb *inp, const struct in_addr laddr, return (EADDRINUSE); } t = in_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) { #ifdef INET6 @@ -1991,7 +1993,7 @@ restart: #define INP_LOOKUP_MAPPED_PCB_COST 3 struct inpcb * in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr, - u_short lport, int lookupflags, struct ucred *cred) + u_short lport, int fib, int lookupflags, struct ucred *cred) { struct inpcb *inp; #ifdef INET6 @@ -2003,6 +2005,9 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr, 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); if ((lookupflags & INPLOOKUP_WILDCARD) == 0) { @@ -2021,7 +2026,8 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr, #endif if (inp->inp_faddr.s_addr == INADDR_ANY && inp->inp_laddr.s_addr == laddr.s_addr && - inp->inp_lport == lport) { + inp->inp_lport == lport && (fib == RT_ALL_FIBS || + inp->inp_inc.inc_fibnum == fib)) { /* * Found? */ @@ -2060,6 +2066,9 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr, if (!prison_equal_ip4(inp->inp_cred->cr_prison, cred->cr_prison)) continue; + if (fib != RT_ALL_FIBS && + inp->inp_inc.inc_fibnum != fib) + continue; #ifdef INET6 /* XXX inp locking */ if ((inp->inp_vflag & INP_IPV4) == 0) diff --git a/sys/netinet/in_pcb_var.h b/sys/netinet/in_pcb_var.h index f2191cf73386..1780a9859f5f 100644 --- a/sys/netinet/in_pcb_var.h +++ b/sys/netinet/in_pcb_var.h @@ -55,8 +55,8 @@ int in_pcb_lport(struct inpcb *, struct in_addr *, u_short *, int in_pcb_lport_dest(struct inpcb *inp, struct sockaddr *lsa, u_short *lportp, struct sockaddr *fsa, u_short fport, struct ucred *cred, int lookupflags); -struct inpcb * in_pcblookup_local(struct inpcbinfo *, struct in_addr, u_short, - int, struct ucred *); +struct inpcb *in_pcblookup_local(struct inpcbinfo *, struct in_addr, u_short, + int, int, struct ucred *); struct inpcbport { struct inpcbhead phd_pcblist; diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index c2cf856d0dfd..9584dcf7474c 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -251,7 +251,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)) && @@ -265,8 +265,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)) && @@ -277,7 +277,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); @@ -288,7 +288,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) || @@ -751,13 +751,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); @@ -775,7 +777,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)) @@ -815,6 +818,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 edf7023747bb..5118b4b412a4 100644 --- a/sys/netinet6/in6_pcb.h +++ b/sys/netinet6/in6_pcb.h @@ -77,7 +77,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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202502210157.51L1vEvA067351>