git: 4009a98fe80b - main - rawip: Add a bind_all_fibs sysctl
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 06 Feb 2025 16:27:31 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=4009a98fe80b8a51837d471076152e6ff505b675
commit 4009a98fe80b8a51837d471076152e6ff505b675
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-02-06 14:16:36 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-02-06 14:16:36 +0000
rawip: Add a bind_all_fibs sysctl
As with net.inet.{tcp,udp}.bind_all_fibs, this causes raw sockets to
accept only packets from the same FIB.
Reviewed by: glebius
Sponsored by: Klara, Inc.
Sponsored by: Stormshield
Differential Revision: https://reviews.freebsd.org/D48707
---
sys/netinet/raw_ip.c | 21 +++++++++++++++++++--
sys/netinet6/icmp6.c | 13 ++++++++++++-
sys/netinet6/raw_ip6.c | 14 ++++++++++++--
3 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 5f6acbaa5e6f..0d677d954f11 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -30,7 +30,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
@@ -128,6 +127,12 @@ int (*ip_rsvp_vif)(struct socket *, struct sockopt *);
void (*ip_rsvp_force_done)(struct socket *);
#endif /* INET */
+#define V_rip_bind_all_fibs VNET(rip_bind_all_fibs)
+VNET_DEFINE(int, rip_bind_all_fibs) = 1;
+SYSCTL_INT(_net_inet_raw, OID_AUTO, bind_all_fibs, CTLFLAG_VNET | CTLFLAG_RDTUN,
+ &VNET_NAME(rip_bind_all_fibs), 0,
+ "Bound sockets receive traffic from all FIBs");
+
u_long rip_sendspace = 9216;
SYSCTL_ULONG(_net_inet_raw, OID_AUTO, maxdgram, CTLFLAG_RW,
&rip_sendspace, 0, "Maximum outgoing raw IP datagram size");
@@ -302,7 +307,9 @@ rip_input(struct mbuf **mp, int *offp, int proto)
struct mbuf *m = *mp;
struct inpcb *inp;
struct sockaddr_in ripsrc;
- int appended;
+ int appended, fib;
+
+ M_ASSERTPKTHDR(m);
*mp = NULL;
appended = 0;
@@ -312,6 +319,7 @@ rip_input(struct mbuf **mp, int *offp, int proto)
ripsrc.sin_family = AF_INET;
ripsrc.sin_addr = ctx.ip->ip_src;
+ fib = M_GETFIB(m);
ifp = m->m_pkthdr.rcvif;
inpi.hash = INP_PCBHASH_RAW(proto, ctx.ip->ip_src.s_addr,
@@ -326,6 +334,12 @@ rip_input(struct mbuf **mp, int *offp, int proto)
*/
continue;
}
+ if (V_rip_bind_all_fibs == 0 && fib != inp->inp_inc.inc_fibnum)
+ /*
+ * Sockets bound to a specific FIB can only receive
+ * packets from that FIB.
+ */
+ continue;
appended += rip_append(inp, ctx.ip, m, &ripsrc);
}
@@ -343,6 +357,9 @@ rip_input(struct mbuf **mp, int *offp, int proto)
* and fall through into normal filter path if so.
*/
continue;
+ if (V_rip_bind_all_fibs == 0 && fib != inp->inp_inc.inc_fibnum)
+ continue;
+
/*
* If this raw socket has multicast state, and we
* have received a multicast, check if this socket
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index d1c2f2c85142..b962d39151e9 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -143,6 +143,9 @@ SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_NODEINFO, nodeinfo,
VNET_DECLARE(struct inpcbinfo, ripcbinfo);
#define V_ripcbinfo VNET(ripcbinfo)
+VNET_DECLARE(int, rip_bind_all_fibs);
+#define V_rip_bind_all_fibs VNET(rip_bind_all_fibs)
+
static void icmp6_errcount(int, int);
static int icmp6_rip6_input(struct mbuf **, int);
static void icmp6_reflect(struct mbuf *, size_t);
@@ -1934,7 +1937,7 @@ icmp6_rip6_input(struct mbuf **mp, int off)
struct sockaddr_in6 fromsa;
struct icmp6_hdr *icmp6;
struct mbuf *opts = NULL;
- int delivered = 0;
+ int delivered = 0, fib;
/* This is assumed to be safe; icmp6_input() does a pullup. */
icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off);
@@ -1953,7 +1956,15 @@ icmp6_rip6_input(struct mbuf **mp, int off)
return (IPPROTO_DONE);
}
+ fib = M_GETFIB(m);
+
while ((inp = inp_next(&inpi)) != NULL) {
+ if (V_rip_bind_all_fibs == 0 && fib != inp->inp_inc.inc_fibnum)
+ /*
+ * Sockets bound to a specific FIB can only receive
+ * packets from that FIB.
+ */
+ continue;
if (ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type,
inp->in6p_icmp6filt))
continue;
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index b761dc422feb..1bb0c0e835cf 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -59,7 +59,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "opt_ipsec.h"
#include "opt_inet6.h"
#include "opt_route.h"
@@ -118,6 +117,9 @@
VNET_DECLARE(struct inpcbinfo, ripcbinfo);
#define V_ripcbinfo VNET(ripcbinfo)
+VNET_DECLARE(int, rip_bind_all_fibs);
+#define V_rip_bind_all_fibs VNET(rip_bind_all_fibs)
+
extern u_long rip_sendspace;
extern u_long rip_recvspace;
@@ -190,14 +192,16 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
struct rip6_inp_match_ctx ctx = { .ip6 = ip6, .proto = proto };
struct inpcb_iterator inpi = INP_ITERATOR(&V_ripcbinfo,
INPLOOKUP_RLOCKPCB, rip6_inp_match, &ctx);
- int delivered = 0;
+ int delivered = 0, fib;
+ M_ASSERTPKTHDR(m);
NET_EPOCH_ASSERT();
RIP6STAT_INC(rip6s_ipackets);
init_sin6(&fromsa, m, 0); /* general init */
+ fib = M_GETFIB(m);
ifp = m->m_pkthdr.rcvif;
while ((inp = inp_next(&inpi)) != NULL) {
@@ -221,6 +225,12 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
* and fall through into normal filter path if so.
*/
continue;
+ if (V_rip_bind_all_fibs == 0 && fib != inp->inp_inc.inc_fibnum)
+ /*
+ * Sockets bound to a specific FIB can only receive
+ * packets from that FIB.
+ */
+ continue;
if (inp->in6p_cksum != -1) {
RIP6STAT_INC(rip6s_isum);
if (m->m_pkthdr.len - (*offp + inp->in6p_cksum) < 2 ||