git: ce80cdeb1370 - stable/14 - rawip: Add a bind_all_fibs sysctl
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 21 Feb 2025 01:57:22 UTC
The branch stable/14 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=ce80cdeb1370705d72a7aa6c5784581592c89a61
commit ce80cdeb1370705d72a7aa6c5784581592c89a61
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-02-06 14:16:36 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-02-21 01:04:50 +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
(cherry picked from commit 4009a98fe80b8a51837d471076152e6ff505b675)
---
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 287a806845c4..36258b3283d6 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -32,7 +32,6 @@
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
*/
-#include <sys/cdefs.h>
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
@@ -130,6 +129,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");
@@ -304,7 +309,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;
@@ -314,6 +321,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,
@@ -328,6 +336,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);
}
@@ -345,6 +359,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 39c252e16b75..0a0ca80de721 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -145,6 +145,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);
@@ -1936,7 +1939,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);
@@ -1955,7 +1958,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 803dc3c1804e..caee18cab071 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -61,7 +61,6 @@
* @(#)raw_ip.c 8.2 (Berkeley) 1/4/94
*/
-#include <sys/cdefs.h>
#include "opt_ipsec.h"
#include "opt_inet6.h"
#include "opt_route.h"
@@ -120,6 +119,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;
@@ -192,14 +194,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) {
@@ -223,6 +227,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 ||