diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2026-03-11 17:53:40 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-03-11 17:53:41 -0700 |
| commit | 20c1be4cc86fa34bd68496a1b8168f1af0a2ee72 (patch) | |
| tree | 03864ff6b9d721b605319cb1c19f6aa77154e40b | |
| parent | 908c344d5cfac4160f49715da9efacdf5b6a28bd (diff) | |
| parent | d56b5d163458c45ab8fa1f00bd875af01b3ce28c (diff) | |
| download | linux-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.c | 2 | ||||
| -rw-r--r-- | include/linux/ipv6.h | 7 | ||||
| -rw-r--r-- | net/core/filter.c | 7 | ||||
| -rw-r--r-- | net/ipv4/af_inet.c | 6 | ||||
| -rw-r--r-- | net/ipv6/af_inet6.c | 8 |
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; |
