Backport upstream patch to fix downstream patch collision in RPi 6.6 kernel (#3856)

Because of refactoring/code quality improvements in upstream, IPv6 reachability
patch no longer applied on 6.12 kernel. We added two versions of the patch to
address this initially, however, this requires updating of the patch directory
name on every kernel bump. Backport the patch causing collision instead to RPi
kernel, so we can carry only one version of the patch.

This also requires swapping of the patching order - now we first apply
board-specific patches, then the global ones. Unless there are collisions,
these operations should be idempontent, so at this point it shouldn't have any
side-effects.
This commit is contained in:
Jan Čermák 2025-02-04 13:13:40 +01:00 committed by GitHub
parent b5b2f5da07
commit 47309b4a10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 204 additions and 58 deletions

View File

@ -1,52 +0,0 @@
From 76591e4075194cf717dc085b8285912f706bcd46 Mon Sep 17 00:00:00 2001
From: Stefan Agner <stefan@agner.ch>
Date: Tue, 28 Mar 2023 12:02:10 +0200
Subject: [PATCH] ipv6: add option to explicitly enable reachability test
Systems which act as host as well as router might prefer the host
behavior. Currently the kernel does not allow to use IPv6 forwarding
globally and at the same time use route reachability probing.
Add a compile time flag to enable route reachability probe in any
case.
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
net/ipv6/Kconfig | 9 +++++++++
net/ipv6/route.c | 3 ++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 08d4b7132d4c..242bf2eeb7ae 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -48,6 +48,15 @@ config IPV6_OPTIMISTIC_DAD
If unsure, say N.
+config IPV6_REACHABILITY_PROBE
+ bool "IPv6: Always use reachability probing (RFC 4191)"
+ help
+ By default reachability probing is disabled on router devices (when
+ IPv6 forwarding is enabled). This option explicitly enables
+ reachability probing always.
+
+ If unsure, say N.
+
config INET6_AH
tristate "IPv6: AH transformation"
select XFRM_AH
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 56525b5b95a2..916769b9a772 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2211,7 +2211,8 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
strict |= flags & RT6_LOOKUP_F_IFACE;
strict |= flags & RT6_LOOKUP_F_IGNORE_LINKSTATE;
- if (net->ipv6.devconf_all->forwarding == 0)
+ if (net->ipv6.devconf_all->forwarding == 0 ||
+ IS_ENABLED(CONFIG_IPV6_REACHABILITY_PROBE))
strict |= RT6_LOOKUP_F_REACHABLE;
rcu_read_lock();

View File

@ -0,0 +1,198 @@
From 93ddda43441baefd98267c671ce2ec7e5527906b Mon Sep 17 00:00:00 2001
From: Eric Dumazet <edumazet@google.com>
Date: Wed, 28 Feb 2024 13:54:30 +0000
Subject: [PATCH] ipv6: annotate data-races around cnf.forwarding
idev->cnf.forwarding and net->ipv6.devconf_all->forwarding
might be read locklessly, add appropriate READ_ONCE()
and WRITE_ONCE() annotations.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/usb/cdc_mbim.c | 2 +-
include/net/ipv6.h | 8 +++++---
net/core/filter.c | 2 +-
net/ipv6/addrconf.c | 10 ++++++----
net/ipv6/ip6_output.c | 2 +-
net/ipv6/ndisc.c | 11 ++++++-----
net/ipv6/route.c | 4 ++--
7 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index cd4083e0b3b9e..e13e4920ee9b2 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -339,7 +339,7 @@ static void do_neigh_solicit(struct usbnet *dev, u8 *buf, u16 tci)
in6_dev = in6_dev_get(netdev);
if (!in6_dev)
goto out;
- is_router = !!in6_dev->cnf.forwarding;
+ is_router = !!READ_ONCE(in6_dev->cnf.forwarding);
in6_dev_put(in6_dev);
/* ipv6_stub != NULL if in6_dev_get returned an inet6_dev */
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index c6932d1a3fa80..0185ca1617c1a 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -534,13 +534,15 @@ static inline int ipv6_hopopt_jumbo_remove(struct sk_buff *skb)
return 0;
}
-static inline bool ipv6_accept_ra(struct inet6_dev *idev)
+static inline bool ipv6_accept_ra(const struct inet6_dev *idev)
{
+ s32 accept_ra = READ_ONCE(idev->cnf.accept_ra);
+
/* If forwarding is enabled, RA are not accepted unless the special
* hybrid mode (accept_ra=2) is enabled.
*/
- return idev->cnf.forwarding ? idev->cnf.accept_ra == 2 :
- idev->cnf.accept_ra;
+ return READ_ONCE(idev->cnf.forwarding) ? accept_ra == 2 :
+ accept_ra;
}
#define IPV6_FRAG_HIGH_THRESH (4 * 1024*1024) /* 4194304 */
diff --git a/net/core/filter.c b/net/core/filter.c
index 5881944f1681c..4288f45ff54ce 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -6021,7 +6021,7 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
return -ENODEV;
idev = __in6_dev_get_safely(dev);
- if (unlikely(!idev || !idev->cnf.forwarding))
+ if (unlikely(!idev || !READ_ONCE(idev->cnf.forwarding)))
return BPF_FIB_LKUP_RET_FWD_DISABLED;
if (flags & BPF_FIB_LOOKUP_OUTPUT) {
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8360939acf85a..12c0b1e85cea1 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -547,7 +547,8 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
goto out;
if ((all || type == NETCONFA_FORWARDING) &&
- nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0)
+ nla_put_s32(skb, NETCONFA_FORWARDING,
+ READ_ONCE(devconf->forwarding)) < 0)
goto nla_put_failure;
#ifdef CONFIG_IPV6_MROUTE
if ((all || type == NETCONFA_MC_FORWARDING) &&
@@ -865,7 +866,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
idev = __in6_dev_get(dev);
if (idev) {
int changed = (!idev->cnf.forwarding) ^ (!newf);
- idev->cnf.forwarding = newf;
+
+ WRITE_ONCE(idev->cnf.forwarding, newf);
if (changed)
dev_forward_change(idev);
}
@@ -882,7 +884,7 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
net = (struct net *)table->extra2;
old = *p;
- *p = newf;
+ WRITE_ONCE(*p, newf);
if (p == &net->ipv6.devconf_dflt->forwarding) {
if ((!newf) ^ (!old))
@@ -897,7 +899,7 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
if (p == &net->ipv6.devconf_all->forwarding) {
int old_dflt = net->ipv6.devconf_dflt->forwarding;
- net->ipv6.devconf_dflt->forwarding = newf;
+ WRITE_ONCE(net->ipv6.devconf_dflt->forwarding, newf);
if ((!newf) ^ (!old_dflt))
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
NETCONFA_FORWARDING,
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 2341a4373bb94..46c0dfa8c6f88 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -508,7 +508,7 @@ int ip6_forward(struct sk_buff *skb)
u32 mtu;
idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif));
- if (net->ipv6.devconf_all->forwarding == 0)
+ if (READ_ONCE(net->ipv6.devconf_all->forwarding) == 0)
goto error;
if (skb->pkt_type != PACKET_HOST)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 23b46b5705c53..bd73484de3818 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -905,7 +905,7 @@ static enum skb_drop_reason ndisc_recv_ns(struct sk_buff *skb)
}
if (ipv6_chk_acast_addr(net, dev, &msg->target) ||
- (idev->cnf.forwarding &&
+ (READ_ONCE(idev->cnf.forwarding) &&
(net->ipv6.devconf_all->proxy_ndp || idev->cnf.proxy_ndp) &&
(is_router = pndisc_is_router(&msg->target, dev)) >= 0)) {
if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
@@ -931,7 +931,7 @@ static enum skb_drop_reason ndisc_recv_ns(struct sk_buff *skb)
}
if (is_router < 0)
- is_router = idev->cnf.forwarding;
+ is_router = READ_ONCE(idev->cnf.forwarding);
if (dad) {
ndisc_send_na(dev, &in6addr_linklocal_allnodes, &msg->target,
@@ -1082,7 +1082,7 @@ static enum skb_drop_reason ndisc_recv_na(struct sk_buff *skb)
* Note that we don't do a (daddr == all-routers-mcast) check.
*/
new_state = msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE;
- if (!neigh && lladdr && idev && idev->cnf.forwarding) {
+ if (!neigh && lladdr && idev && READ_ONCE(idev->cnf.forwarding)) {
if (accept_untracked_na(dev, saddr)) {
neigh = neigh_create(&nd_tbl, &msg->target, dev);
new_state = NUD_STALE;
@@ -1102,7 +1102,8 @@ static enum skb_drop_reason ndisc_recv_na(struct sk_buff *skb)
* has already sent a NA to us.
*/
if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
- net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp &&
+ READ_ONCE(net->ipv6.devconf_all->forwarding) &&
+ net->ipv6.devconf_all->proxy_ndp &&
pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) {
/* XXX: idev->cnf.proxy_ndp */
goto out;
@@ -1150,7 +1151,7 @@ static enum skb_drop_reason ndisc_recv_rs(struct sk_buff *skb)
}
/* Don't accept RS if we're not in router mode */
- if (!idev->cnf.forwarding)
+ if (!READ_ONCE(idev->cnf.forwarding))
goto out;
/*
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index fc5c534620253..4a0b12651777b 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2215,7 +2215,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
strict |= flags & RT6_LOOKUP_F_IFACE;
strict |= flags & RT6_LOOKUP_F_IGNORE_LINKSTATE;
- if (net->ipv6.devconf_all->forwarding == 0)
+ if (READ_ONCE(net->ipv6.devconf_all->forwarding) == 0)
strict |= RT6_LOOKUP_F_REACHABLE;
rcu_read_lock();
@@ -4146,7 +4146,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
in6_dev = __in6_dev_get(skb->dev);
if (!in6_dev)
return;
- if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects)
+ if (READ_ONCE(in6_dev->cnf.forwarding) || !in6_dev->cnf.accept_redirects)
return;
/* RFC2461 8.1:

View File

@ -6,7 +6,7 @@ BR2_DL_DIR="/cache/dl"
BR2_CCACHE=y
BR2_CCACHE_DIR="/cache/cc"
BR2_ENABLE_LTO=y
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches"
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches $(BR2_EXTERNAL_HASSOS_PATH)/patches"
BR2_SSP_REGULAR=y
BR2_TARGET_GENERIC_HOSTNAME="homeassistant"
BR2_TARGET_GENERIC_ISSUE="Welcome to Home Assistant"

View File

@ -5,7 +5,7 @@ BR2_DL_DIR="/cache/dl"
BR2_CCACHE=y
BR2_CCACHE_DIR="/cache/cc"
BR2_ENABLE_LTO=y
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches"
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches $(BR2_EXTERNAL_HASSOS_PATH)/patches"
BR2_SSP_REGULAR=y
BR2_TARGET_GENERIC_HOSTNAME="homeassistant"
BR2_TARGET_GENERIC_ISSUE="Welcome to Home Assistant"

View File

@ -6,7 +6,7 @@ BR2_DL_DIR="/cache/dl"
BR2_CCACHE=y
BR2_CCACHE_DIR="/cache/cc"
BR2_ENABLE_LTO=y
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches"
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches $(BR2_EXTERNAL_HASSOS_PATH)/patches"
BR2_SSP_REGULAR=y
BR2_TARGET_GENERIC_HOSTNAME="homeassistant"
BR2_TARGET_GENERIC_ISSUE="Welcome to Home Assistant"

View File

@ -5,7 +5,7 @@ BR2_DL_DIR="/cache/dl"
BR2_CCACHE=y
BR2_CCACHE_DIR="/cache/cc"
BR2_ENABLE_LTO=y
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches"
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches $(BR2_EXTERNAL_HASSOS_PATH)/patches"
BR2_SSP_REGULAR=y
BR2_TARGET_GENERIC_HOSTNAME="homeassistant"
BR2_TARGET_GENERIC_ISSUE="Welcome to Home Assistant"

View File

@ -6,7 +6,7 @@ BR2_DL_DIR="/cache/dl"
BR2_CCACHE=y
BR2_CCACHE_DIR="/cache/cc"
BR2_ENABLE_LTO=y
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches"
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches $(BR2_EXTERNAL_HASSOS_PATH)/patches"
BR2_SSP_REGULAR=y
BR2_TARGET_GENERIC_HOSTNAME="homeassistant"
BR2_TARGET_GENERIC_ISSUE="Welcome to Home Assistant"

View File

@ -5,7 +5,7 @@ BR2_DL_DIR="/cache/dl"
BR2_CCACHE=y
BR2_CCACHE_DIR="/cache/cc"
BR2_ENABLE_LTO=y
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches $(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches"
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/board/raspberrypi/patches $(BR2_EXTERNAL_HASSOS_PATH)/patches"
BR2_SSP_REGULAR=y
BR2_TARGET_GENERIC_HOSTNAME="homeassistant"
BR2_TARGET_GENERIC_ISSUE="Welcome to Home Assistant"