Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108666415
D48664.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D48664.diff
View Options
diff --git a/share/man/man4/udp.4 b/share/man/man4/udp.4
--- a/share/man/man4/udp.4
+++ b/share/man/man4/udp.4
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 1, 2022
+.Dd January 20, 2025
.Dt UDP 4
.Os
.Sh NAME
@@ -107,6 +107,19 @@
.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
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -105,6 +105,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
@@ -453,7 +458,7 @@
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;
@@ -575,7 +580,11 @@
/*
* 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) &&
@@ -589,7 +598,7 @@
* 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.
@@ -599,8 +608,8 @@
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);
@@ -608,7 +617,7 @@
} 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];
@@ -1242,8 +1251,8 @@
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;
@@ -1592,7 +1601,8 @@
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
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -155,13 +155,15 @@
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
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -357,6 +357,7 @@
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;
@@ -454,6 +455,8 @@
/*
* 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.
@@ -470,7 +473,7 @@
*/
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.
@@ -480,8 +483,8 @@
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);
@@ -489,7 +492,7 @@
} 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) {
@@ -1058,13 +1061,16 @@
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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 28, 4:28 AM (11 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16248308
Default Alt Text
D48664.diff (6 KB)
Attached To
Mode
D48664: udp: Add a sysctl to control binding
Attached
Detach File
Event Timeline
Log In to Comment