From nobody Fri Feb 21 01:57:18 2025 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YzYD000P0z5nmW2; Fri, 21 Feb 2025 01:57:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YzYCz15G5z3ngn; Fri, 21 Feb 2025 01:57:19 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1740103039; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3nZ4vYSNmy/+mxmRH7LayY9qyMivX05wJ9u5Iog7UUs=; b=mCWmgyd4lusvSI3x8m86hs5T8ptvMldqzewPggdJ8e16ur9FrbboZeKe5Z2bvUZ9gl2Ped oy+DowU46AI5+lo6MICwmwsZ4jN/mI5/qfQg1/FGztHkKAIwsIj+5B1mGpSNz3/Fmvkcxz VEfioFvdPlHAJ8yjZbai1FUE/tq2L76+zA+AvLdXwM8zah2IE4kovvEZV8FxO3nNN0numv niQ6LfeOKiKKhYct/sshrdOLpsB8uPRhfEAMFLg9g1xi8ZtJZZYl++XYAO1yleWAr5Qo5L NLHYabaVi1benxdWJT5ulk8CEdzzvvmmKUdozFjqcOoCWeQYvSBRqfoGMn7xqg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1740103039; a=rsa-sha256; cv=none; b=V4F0Y+DWnJ8aZ407QqDiebguFIBWULPVc+Np/UAi1jWo5nnVIAs9krJqNUw9uZ2LDgE6zr VnixVSpMSmchpG2HOshnxgsqz9M8/EzC1A6b3me1dJJ/fNd626yjbOPhDpbmu5NVVeVhAz o4a5kCjJBf9NvAoAnXAO5Ek66oi+dzQgOs+BsUzdmmGA1cRtJsTiRn84wWgOp06KfcrL5l qP1jaFW4pSXb5vQs2CCQeQamHpKLtpgei3MlCmtJiyCpz+IcKon8c7bibqpwtMPQIkSFa8 Y+AlAIVkPoyrQb+3hls02bPK09BdjU8NIU948vMteO6UM/65GQF6qI5BHfu+9Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1740103039; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3nZ4vYSNmy/+mxmRH7LayY9qyMivX05wJ9u5Iog7UUs=; b=N1JLVzDEymDc70bATq165QWG4lsCszEUXxSKwH0/1ioccsPgm5E8ABS5vKEz62o6NgNSJj Ri/rBToFQqiwggzu7eJQ939r5WTISdge7tqohvyfldH+dWN3+wMoCUkO3LomcYBxzl/PRP EEVbJu3pWKNsFI12WOiEZ6qNKkR+eCsbb0pnj5G7sBa8M+Fg8XGuTBt3wztAoAhR834+2H bpOY6SC25SPM7qkeTuIiK6h+JqL5o5l44G3oX3yJU+X6n1u0WNLp3nRYYUer6eUmqSPnLw 3/U1Hp0I6ddDFisI6lLTYjPbnbqhgrvDf0dh/gOFXRwtKtunQoYG1Rq2BqAYHQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YzYCz0ZVCz1Gjx; Fri, 21 Feb 2025 01:57:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 51L1vIvT067489; Fri, 21 Feb 2025 01:57:18 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 51L1vIEQ067486; Fri, 21 Feb 2025 01:57:18 GMT (envelope-from git) Date: Fri, 21 Feb 2025 01:57:18 GMT Message-Id: <202502210157.51L1vIEQ067486@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: e83d93bb28ac - stable/14 - udp: Add a sysctl to modify listening socket FIB inheritance List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: e83d93bb28ac84fe10c23191212e2c53e344132d Auto-Submitted: auto-generated The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=e83d93bb28ac84fe10c23191212e2c53e344132d commit e83d93bb28ac84fe10c23191212e2c53e344132d Author: Mark Johnston AuthorDate: 2025-02-06 14:15:41 +0000 Commit: Mark Johnston CommitDate: 2025-02-21 01:04:50 +0000 udp: Add a sysctl to modify listening socket FIB inheritance Introduce the net.inet.udp.bind_all_fibs tunable, set to 1 by default for compatibility with current behaviour. When set to 0, all received datagrams will be dropped unless an inpcb bound to the same FIB exists. No functional change intended, as the new behaviour is not enabled by default. Reviewed by: glebius MFC after: 2 weeks Sponsored by: Klara, Inc. Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D48664 (cherry picked from commit 08e638c089ab57531f08994d03c9dde54c4744f9) --- share/man/man4/udp.4 | 15 ++++++++++++++- sys/netinet/udp_usrreq.c | 40 ++++++++++++++++++++++++++++++---------- sys/netinet/udp_var.h | 6 ++++-- sys/netinet6/udp6_usrreq.c | 18 ++++++++++++------ 4 files changed, 60 insertions(+), 19 deletions(-) diff --git a/share/man/man4/udp.4 b/share/man/man4/udp.4 index 1edfe1519156..3973708a259f 100644 --- a/share/man/man4/udp.4 +++ b/share/man/man4/udp.4 @@ -27,7 +27,7 @@ .\" .\" @(#)udp.4 8.1 (Berkeley) 6/5/93 .\" -.Dd August 1, 2022 +.Dd January 20, 2025 .Dt UDP 4 .Os .Sh NAME @@ -109,6 +109,19 @@ Only one value is supported for this option: .Tn UDP_ENCAP_ESPINUDP from RFC 3948, defined in .In netinet/udp.h . +.Sh FIB support +UDP sockets are FIB-aware. +They inherit the FIB of the process which created the socket. +By default, a UDP socket bound to an address can receive datagrams originating +from any FIB. +If the +.Va net.inet.udp.bind_all_fibs +tunable is set to 0, all UDP sockets will receive only datagrams originating +from the same FIB as the socket. +In this mode, multiple sockets can be bound to the same address, so long as +each socket belongs to a different FIB, similar to the behavior of the +.Dv SO_REUSEPORT +option. .Sh MIB (sysctl) Variables The .Nm diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 75af0055c680..9a3d9a810481 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -107,6 +107,11 @@ * Per RFC 3828, July, 2004. */ +VNET_DEFINE(int, udp_bind_all_fibs) = 1; +SYSCTL_INT(_net_inet_udp, OID_AUTO, bind_all_fibs, CTLFLAG_VNET | CTLFLAG_RDTUN, + &VNET_NAME(udp_bind_all_fibs), 0, + "Bound sockets receive traffic from all FIBs"); + /* * BSD 4.2 defaulted the udp checksum to be off. Turning off udp checksums * removes the only data integrity mechanism for packets and malformed @@ -361,10 +366,12 @@ udp_multi_input(struct mbuf *m, int proto, struct sockaddr_in *udp_in) #endif struct inpcb *inp; struct mbuf *n; - int appends = 0; + int appends = 0, fib; MPASS(ip->ip_hl == sizeof(struct ip) >> 2); + fib = M_GETFIB(m); + while ((inp = inp_next(&inpi)) != NULL) { /* * XXXRW: Because we weren't holding either the inpcb @@ -372,6 +379,14 @@ udp_multi_input(struct mbuf *m, int proto, struct sockaddr_in *udp_in) * before, we should probably recheck now that the * inpcb lock is held. */ + + if (V_udp_bind_all_fibs == 0 && fib != inp->inp_inc.inc_fibnum) + /* + * Sockets bound to a specific FIB can only receive + * packets from that FIB. + */ + continue; + /* * Handle socket delivery policy for any-source * and source-specific multicast. [RFC3678] @@ -455,7 +470,7 @@ udp_input(struct mbuf **mp, int *offp, int proto) struct sockaddr_in udp_in[2]; struct mbuf *m; struct m_tag *fwd_tag; - int cscov_partial, iphlen; + int cscov_partial, iphlen, lookupflags; m = *mp; iphlen = *offp; @@ -577,7 +592,11 @@ udp_input(struct mbuf **mp, int *offp, int proto) /* * Locate pcb for datagram. - * + */ + lookupflags = INPLOOKUP_RLOCKPCB | + (V_udp_bind_all_fibs ? 0 : INPLOOKUP_FIB); + + /* * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain. */ if ((m->m_flags & M_IP_NEXTHOP) && @@ -591,7 +610,7 @@ udp_input(struct mbuf **mp, int *offp, int proto) * Already got one like this? */ inp = in_pcblookup_mbuf(pcbinfo, ip->ip_src, uh->uh_sport, - ip->ip_dst, uh->uh_dport, INPLOOKUP_RLOCKPCB, ifp, m); + ip->ip_dst, uh->uh_dport, lookupflags, ifp, m); if (!inp) { /* * It's new. Try to find the ambushing socket. @@ -601,8 +620,8 @@ udp_input(struct mbuf **mp, int *offp, int proto) inp = in_pcblookup(pcbinfo, ip->ip_src, uh->uh_sport, next_hop->sin_addr, next_hop->sin_port ? htons(next_hop->sin_port) : - uh->uh_dport, INPLOOKUP_WILDCARD | - INPLOOKUP_RLOCKPCB, ifp); + uh->uh_dport, INPLOOKUP_WILDCARD | lookupflags, + ifp); } /* Remove the tag from the packet. We don't need it anymore. */ m_tag_delete(m, fwd_tag); @@ -610,7 +629,7 @@ udp_input(struct mbuf **mp, int *offp, int proto) } else inp = in_pcblookup_mbuf(pcbinfo, ip->ip_src, uh->uh_sport, ip->ip_dst, uh->uh_dport, INPLOOKUP_WILDCARD | - INPLOOKUP_RLOCKPCB, ifp, m); + lookupflags, ifp, m); if (inp == NULL) { if (V_udp_log_in_vain) { char src[INET_ADDRSTRLEN]; @@ -1218,8 +1237,8 @@ udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, inp->inp_vflag &= ~INP_IPV6; } INP_HASH_WLOCK(pcbinfo); - error = in_pcbbind_setup(inp, &src, &laddr.s_addr, &lport, 0, - td->td_ucred); + error = in_pcbbind_setup(inp, &src, &laddr.s_addr, &lport, + V_udp_bind_all_fibs ? 0 : INPBIND_FIB, td->td_ucred); INP_HASH_WUNLOCK(pcbinfo); if ((flags & PRUS_IPV6) != 0) inp->inp_vflag = vflagsav; @@ -1568,7 +1587,8 @@ udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td) INP_WLOCK(inp); INP_HASH_WLOCK(pcbinfo); - error = in_pcbbind(inp, sinp, 0, td->td_ucred); + error = in_pcbbind(inp, sinp, V_udp_bind_all_fibs ? 0 : INPBIND_FIB, + td->td_ucred); INP_HASH_WUNLOCK(pcbinfo); INP_WUNLOCK(inp); return (error); diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index a2e9c3388160..51272e7c9349 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -149,13 +149,15 @@ VNET_DECLARE(struct inpcbinfo, ulitecbinfo); extern u_long udp_sendspace; extern u_long udp_recvspace; -VNET_DECLARE(int, udp_cksum); +VNET_DECLARE(int, udp_bind_all_fibs); VNET_DECLARE(int, udp_blackhole); VNET_DECLARE(bool, udp_blackhole_local); +VNET_DECLARE(int, udp_cksum); VNET_DECLARE(int, udp_log_in_vain); -#define V_udp_cksum VNET(udp_cksum) +#define V_udp_bind_all_fibs VNET(udp_bind_all_fibs) #define V_udp_blackhole VNET(udp_blackhole) #define V_udp_blackhole_local VNET(udp_blackhole_local) +#define V_udp_cksum VNET(udp_cksum) #define V_udp_log_in_vain VNET(udp_log_in_vain) VNET_DECLARE(int, zero_checksum_port); diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 5b902129920b..a23bbabab236 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -349,6 +349,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) int off = *offp; int cscov_partial; int plen, ulen; + int lookupflags; struct sockaddr_in6 fromsa[2]; struct m_tag *fwd_tag; uint16_t uh_sum; @@ -446,6 +447,8 @@ skip_checksum: /* * Locate pcb for datagram. */ + lookupflags = INPLOOKUP_RLOCKPCB | + (V_udp_bind_all_fibs ? 0 : INPLOOKUP_FIB); /* * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain. @@ -462,7 +465,7 @@ skip_checksum: */ inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_src, uh->uh_sport, &ip6->ip6_dst, uh->uh_dport, - INPLOOKUP_RLOCKPCB, m->m_pkthdr.rcvif, m); + lookupflags, m->m_pkthdr.rcvif, m); if (!inp) { /* * It's new. Try to find the ambushing socket. @@ -472,8 +475,8 @@ skip_checksum: inp = in6_pcblookup(pcbinfo, &ip6->ip6_src, uh->uh_sport, &next_hop6->sin6_addr, next_hop6->sin6_port ? htons(next_hop6->sin6_port) : - uh->uh_dport, INPLOOKUP_WILDCARD | - INPLOOKUP_RLOCKPCB, m->m_pkthdr.rcvif); + uh->uh_dport, INPLOOKUP_WILDCARD | lookupflags, + m->m_pkthdr.rcvif); } /* Remove the tag from the packet. We don't need it anymore. */ m_tag_delete(m, fwd_tag); @@ -481,7 +484,7 @@ skip_checksum: } else inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_src, uh->uh_sport, &ip6->ip6_dst, uh->uh_dport, - INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, + INPLOOKUP_WILDCARD | lookupflags, m->m_pkthdr.rcvif, m); if (inp == NULL) { if (V_udp_log_in_vain) { @@ -1050,13 +1053,16 @@ udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td) in6_sin6_2_sin(&sin, sin6_p); inp->inp_vflag |= INP_IPV4; inp->inp_vflag &= ~INP_IPV6; - error = in_pcbbind(inp, &sin, 0, td->td_ucred); + error = in_pcbbind(inp, &sin, + V_udp_bind_all_fibs ? 0 : INPBIND_FIB, + td->td_ucred); goto out; } #endif } - error = in6_pcbbind(inp, sin6_p, 0, td->td_ucred); + error = in6_pcbbind(inp, sin6_p, V_udp_bind_all_fibs ? 0 : INPBIND_FIB, + td->td_ucred); #ifdef INET out: #endif