summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-03-11 17:53:40 -0700
committerJakub Kicinski <kuba@kernel.org>2026-03-11 17:53:41 -0700
commit20c1be4cc86fa34bd68496a1b8168f1af0a2ee72 (patch)
tree03864ff6b9d721b605319cb1c19f6aa77154e40b
parent908c344d5cfac4160f49715da9efacdf5b6a28bd (diff)
parentd56b5d163458c45ab8fa1f00bd875af01b3ce28c (diff)
downloadlinux-20c1be4cc86fa34bd68496a1b8168f1af0a2ee72.tar.gz
linux-20c1be4cc86fa34bd68496a1b8168f1af0a2ee72.zip
Merge branch 'net-bpf-nd_tbl-fixes-for-when-ipv6-disable-1'
Ricardo B. Marlière says: ==================== {net,bpf}: nd_tbl fixes for when ipv6.disable=1 Please consider merging these four patches to fix three crashes that were found after this report: https://lore.kernel.org/all/CAHXs0ORzd62QOG-Fttqa2Cx_A_VFp=utE2H2VTX5nqfgs7LDxQ@mail.gmail.com The first patch from Jakub Kicinski is a preparation in order to enable the use ipv6_mod_enabled() even when CONFIG_IPV6=n. ==================== Link: https://patch.msgid.link/20260307-net-nd_tbl_fixes-v4-0-e2677e85628c@suse.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--include/linux/ipv6.h7
-rw-r--r--net/core/filter.c7
-rw-r--r--net/ipv4/af_inet.c6
-rw-r--r--net/ipv6/af_inet6.c8
5 files changed, 20 insertions, 10 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c1fb92602e46..707419270ebf 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3428,7 +3428,7 @@ int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond,
} else if (is_arp) {
return bond_arp_rcv(skb, bond, slave);
#if IS_ENABLED(CONFIG_IPV6)
- } else if (is_ipv6) {
+ } else if (is_ipv6 && likely(ipv6_mod_enabled())) {
return bond_na_rcv(skb, bond, slave);
#endif
} else {
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 443053a76dcf..a7421382a916 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -333,7 +333,12 @@ struct tcp6_timewait_sock {
};
#if IS_ENABLED(CONFIG_IPV6)
-bool ipv6_mod_enabled(void);
+extern int disable_ipv6_mod;
+
+static inline bool ipv6_mod_enabled(void)
+{
+ return disable_ipv6_mod == 0;
+}
static inline struct ipv6_pinfo *inet6_sk(const struct sock *__sk)
{
diff --git a/net/core/filter.c b/net/core/filter.c
index a77d23fe2359..78b548158fb0 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2228,6 +2228,9 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb,
return -ENOMEM;
}
+ if (unlikely(!ipv6_mod_enabled()))
+ goto out_drop;
+
rcu_read_lock();
if (!nh) {
dst = skb_dst(skb);
@@ -2335,6 +2338,10 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb,
neigh = ip_neigh_for_gw(rt, skb, &is_v6gw);
} else if (nh->nh_family == AF_INET6) {
+ if (unlikely(!ipv6_mod_enabled())) {
+ rcu_read_unlock();
+ goto out_drop;
+ }
neigh = ip_neigh_gw6(dev, &nh->ipv6_nh);
is_v6gw = true;
} else if (nh->nh_family == AF_INET) {
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 8036e76aa1e4..c7731e300a44 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -124,6 +124,12 @@
#include <trace/events/sock.h>
+/* Keep the definition of IPv6 disable here for now, to avoid annoying linker
+ * issues in case IPv6=m
+ */
+int disable_ipv6_mod;
+EXPORT_SYMBOL(disable_ipv6_mod);
+
/* The inetsw table contains everything that inet_create needs to
* build a new socket.
*/
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 23cc9b4cb2f1..4cbd45b68088 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -86,8 +86,6 @@ struct ipv6_params ipv6_defaults = {
.autoconf = 1,
};
-static int disable_ipv6_mod;
-
module_param_named(disable, disable_ipv6_mod, int, 0444);
MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional");
@@ -97,12 +95,6 @@ MODULE_PARM_DESC(disable_ipv6, "Disable IPv6 on all interfaces");
module_param_named(autoconf, ipv6_defaults.autoconf, int, 0444);
MODULE_PARM_DESC(autoconf, "Enable IPv6 address autoconfiguration on all interfaces");
-bool ipv6_mod_enabled(void)
-{
- return disable_ipv6_mod == 0;
-}
-EXPORT_SYMBOL_GPL(ipv6_mod_enabled);
-
static struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
{
const int offset = sk->sk_prot->ipv6_pinfo_offset;