--- /dev/null
+From 408f56c6252f4ccfd141304089e12b8c8b6df147 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Oct 2024 22:48:02 +0800
+Subject: be2net: fix potential memory leak in be_xmit()
+
+From: Wang Hai <wanghai38@huawei.com>
+
+[ Upstream commit e4dd8bfe0f6a23acd305f9b892c00899089bd621 ]
+
+The be_xmit() returns NETDEV_TX_OK without freeing skb
+in case of be_xmit_enqueue() fails, add dev_kfree_skb_any() to fix it.
+
+Fixes: 760c295e0e8d ("be2net: Support for OS2BMC.")
+Signed-off-by: Wang Hai <wanghai38@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Message-ID: <20241015144802.12150-1-wanghai38@huawei.com>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index edd4dd73b3e32..f018379d13509 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1382,10 +1382,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
+ be_get_wrb_params_from_skb(adapter, skb, &wrb_params);
+
+ wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params);
+- if (unlikely(!wrb_cnt)) {
+- dev_kfree_skb_any(skb);
+- goto drop;
+- }
++ if (unlikely(!wrb_cnt))
++ goto drop_skb;
+
+ /* if os2bmc is enabled and if the pkt is destined to bmc,
+ * enqueue the pkt a 2nd time with mgmt bit set.
+@@ -1394,7 +1392,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
+ BE_WRB_F_SET(wrb_params.features, OS2BMC, 1);
+ wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params);
+ if (unlikely(!wrb_cnt))
+- goto drop;
++ goto drop_skb;
+ else
+ skb_get(skb);
+ }
+@@ -1408,6 +1406,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
+ be_xmit_flush(adapter, txo);
+
+ return NETDEV_TX_OK;
++drop_skb:
++ dev_kfree_skb_any(skb);
+ drop:
+ tx_stats(txo)->tx_drv_drops++;
+ /* Flush the already enqueued tx requests */
+--
+2.43.0
+
--- /dev/null
+From d93ac17726daa144a86efea8000f5c77a0016f85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Oct 2024 08:13:38 +0300
+Subject: net: sched: fix use-after-free in taprio_change()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit f504465970aebb2467da548f7c1efbbf36d0f44b ]
+
+In 'taprio_change()', 'admin' pointer may become dangling due to sched
+switch / removal caused by 'advance_sched()', and critical section
+protected by 'q->current_entry_lock' is too small to prevent from such
+a scenario (which causes use-after-free detected by KASAN). Fix this
+by prefer 'rcu_replace_pointer()' over 'rcu_assign_pointer()' to update
+'admin' immediately before an attempt to schedule freeing.
+
+Fixes: a3d43c0d56f1 ("taprio: Add support adding an admin schedule")
+Reported-by: syzbot+b65e0af58423fc8a73aa@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=b65e0af58423fc8a73aa
+Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Link: https://patch.msgid.link/20241018051339.418890-1-dmantipov@yandex.ru
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_taprio.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
+index 04ed23b5f21b4..16ab7b1480661 100644
+--- a/net/sched/sch_taprio.c
++++ b/net/sched/sch_taprio.c
+@@ -1590,7 +1590,8 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
+
+ taprio_start_sched(sch, start, new_admin);
+
+- rcu_assign_pointer(q->admin_sched, new_admin);
++ admin = rcu_replace_pointer(q->admin_sched, new_admin,
++ lockdep_rtnl_is_held());
+ if (admin)
+ call_rcu(&admin->rcu, taprio_free_sched_cb);
+
+--
+2.43.0
+
--- /dev/null
+From 14fc2725589e5c094d46152c0111b146b793ebdc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Oct 2024 22:41:48 +0800
+Subject: net/sun3_82586: fix potential memory leak in sun3_82586_send_packet()
+
+From: Wang Hai <wanghai38@huawei.com>
+
+[ Upstream commit 2cb3f56e827abb22c4168ad0c1bbbf401bb2f3b8 ]
+
+The sun3_82586_send_packet() returns NETDEV_TX_OK without freeing skb
+in case of skb->len being too long, add dev_kfree_skb() to fix it.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Wang Hai <wanghai38@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Message-ID: <20241015144148.7918-1-wanghai38@huawei.com>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/i825xx/sun3_82586.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c
+index 83a6114afbf90..3278e2126dc29 100644
+--- a/drivers/net/ethernet/i825xx/sun3_82586.c
++++ b/drivers/net/ethernet/i825xx/sun3_82586.c
+@@ -1015,6 +1015,7 @@ sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
+ if(skb->len > XMIT_BUFF_SIZE)
+ {
+ printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
++ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From b3caa93b42448ce3263caf5fec46a327a61aa871 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Oct 2024 09:18:37 +0200
+Subject: net: usb: usbnet: fix name regression
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 8a7d12d674ac6f2147c18f36d1e15f1a48060edf ]
+
+The fix for MAC addresses broke detection of the naming convention
+because it gave network devices no random MAC before bind()
+was called. This means that the check for the local assignment bit
+was always negative as the address was zeroed from allocation,
+instead of from overwriting the MAC with a unique hardware address.
+
+The correct check for whether bind() has altered the MAC is
+done with is_zero_ether_addr
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Reported-by: Greg Thelen <gthelen@google.com>
+Diagnosed-by: John Sperbeck <jsperbeck@google.com>
+Fixes: bab8eb0dd4cb9 ("usbnet: modern method to get random MAC")
+Link: https://patch.msgid.link/20241017071849.389636-1-oneukum@suse.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/usbnet.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 669cd20cfe00a..b3d363ebea26e 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -1717,7 +1717,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
+ // can rename the link if it knows better.
+ if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
+ ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
+- (net->dev_addr [0] & 0x02) == 0))
++ /* somebody touched it*/
++ !is_zero_ether_addr(net->dev_addr)))
+ strscpy(net->name, "eth%d", sizeof(net->name));
+ /* WLAN devices should always be named "wlan%d" */
+ if ((dev->driver_info->flags & FLAG_WLAN) != 0)
+--
+2.43.0
+
--- /dev/null
+From e269d6c2a8614f2ec167a69296b2f11770ddc3cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Oct 2024 18:07:48 +0800
+Subject: posix-clock: posix-clock: Fix unbalanced locking in
+ pc_clock_settime()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 6e62807c7fbb3c758d233018caf94dfea9c65dbd ]
+
+If get_clock_desc() succeeds, it calls fget() for the clockid's fd,
+and get the clk->rwsem read lock, so the error path should release
+the lock to make the lock balance and fput the clockid's fd to make
+the refcount balance and release the fd related resource.
+
+However the below commit left the error path locked behind resulting in
+unbalanced locking. Check timespec64_valid_strict() before
+get_clock_desc() to fix it, because the "ts" is not changed
+after that.
+
+Fixes: d8794ac20a29 ("posix-clock: Fix missing timespec64 check in pc_clock_settime()")
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Acked-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+[pabeni@redhat.com: fixed commit message typo]
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/posix-clock.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 8127673bfc45e..05e73d209aa87 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -290,6 +290,9 @@ static int pc_clock_settime(clockid_t id, const struct timespec64 *ts)
+ struct posix_clock_desc cd;
+ int err;
+
++ if (!timespec64_valid_strict(ts))
++ return -EINVAL;
++
+ err = get_clock_desc(id, &cd);
+ if (err)
+ return err;
+@@ -299,9 +302,6 @@ static int pc_clock_settime(clockid_t id, const struct timespec64 *ts)
+ goto out;
+ }
+
+- if (!timespec64_valid_strict(ts))
+- return -EINVAL;
+-
+ if (cd.clk->ops.clock_settime)
+ err = cd.clk->ops.clock_settime(cd.clk, ts);
+ else
+--
+2.43.0
+
--- /dev/null
+From cdb125f008f95152dcfbd8d1c4296504737e3273 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Oct 2024 11:08:16 +0200
+Subject: r8169: avoid unsolicited interrupts
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 10ce0db787004875f4dba068ea952207d1d8abeb ]
+
+It was reported that after resume from suspend a PCI error is logged
+and connectivity is broken. Error message is:
+PCI error (cmd = 0x0407, status_errs = 0x0000)
+The message seems to be a red herring as none of the error bits is set,
+and the PCI command register value also is normal. Exception handling
+for a PCI error includes a chip reset what apparently brakes connectivity
+here. The interrupt status bit triggering the PCI error handling isn't
+actually used on PCIe chip versions, so it's not clear why this bit is
+set by the chip. Fix this by ignoring this bit on PCIe chip versions.
+
+Fixes: 0e4851502f84 ("r8169: merge with version 8.001.00 of Realtek's r8168 driver")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219388
+Tested-by: Atlas Yu <atlas.yu@canonical.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/78e2f535-438f-4212-ad94-a77637ac6c9c@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index e9296d63450d8..3aa1dda3406cd 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4650,7 +4650,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
+ if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask))
+ return IRQ_NONE;
+
+- if (unlikely(status & SYSErr)) {
++ /* At least RTL8168fp may unexpectedly set the SYSErr bit */
++ if (unlikely(status & SYSErr &&
++ tp->mac_version <= RTL_GIGA_MAC_VER_06)) {
+ rtl8169_pcierr_interrupt(tp->dev);
+ goto out;
+ }
+--
+2.43.0
+
arm64-force-position-independent-veneers.patch
jfs-fix-sanity-check-in-dbmount.patch
tracing-consider-the-null-character-when-validating-.patch
+xfrm-extract-dst-lookup-parameters-into-a-struct.patch
+xfrm-respect-ip-protocols-rules-criteria-when-perfor.patch
+net-sun3_82586-fix-potential-memory-leak-in-sun3_825.patch
+be2net-fix-potential-memory-leak-in-be_xmit.patch
+net-usb-usbnet-fix-name-regression.patch
+net-sched-fix-use-after-free-in-taprio_change.patch
+r8169-avoid-unsolicited-interrupts.patch
+posix-clock-posix-clock-fix-unbalanced-locking-in-pc.patch
--- /dev/null
+From d3cece7317a8ae6446881914a4fb08a9bbb952a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Sep 2024 17:07:09 -0700
+Subject: xfrm: extract dst lookup parameters into a struct
+
+From: Eyal Birger <eyal.birger@gmail.com>
+
+[ Upstream commit e509996b16728e37d5a909a5c63c1bd64f23b306 ]
+
+Preparation for adding more fields to dst lookup functions without
+changing their signatures.
+
+Signed-off-by: Eyal Birger <eyal.birger@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Stable-dep-of: b84697210343 ("xfrm: respect ip protocols rules criteria when performing dst lookups")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xfrm.h | 26 +++++++++++++-------------
+ net/ipv4/xfrm4_policy.c | 38 ++++++++++++++++----------------------
+ net/ipv6/xfrm6_policy.c | 28 +++++++++++++---------------
+ net/xfrm/xfrm_device.c | 11 ++++++++---
+ net/xfrm/xfrm_policy.c | 35 +++++++++++++++++++++++------------
+ 5 files changed, 73 insertions(+), 65 deletions(-)
+
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index 6fbaf304648f6..142967e456b18 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -321,20 +321,23 @@ struct xfrm_if_cb {
+ void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
+ void xfrm_if_unregister_cb(void);
+
++struct xfrm_dst_lookup_params {
++ struct net *net;
++ int tos;
++ int oif;
++ xfrm_address_t *saddr;
++ xfrm_address_t *daddr;
++ u32 mark;
++};
++
+ struct net_device;
+ struct xfrm_type;
+ struct xfrm_dst;
+ struct xfrm_policy_afinfo {
+ struct dst_ops *dst_ops;
+- struct dst_entry *(*dst_lookup)(struct net *net,
+- int tos, int oif,
+- const xfrm_address_t *saddr,
+- const xfrm_address_t *daddr,
+- u32 mark);
+- int (*get_saddr)(struct net *net, int oif,
+- xfrm_address_t *saddr,
+- xfrm_address_t *daddr,
+- u32 mark);
++ struct dst_entry *(*dst_lookup)(const struct xfrm_dst_lookup_params *params);
++ int (*get_saddr)(xfrm_address_t *saddr,
++ const struct xfrm_dst_lookup_params *params);
+ int (*fill_dst)(struct xfrm_dst *xdst,
+ struct net_device *dev,
+ const struct flowi *fl);
+@@ -1658,10 +1661,7 @@ static inline int xfrm_user_policy(struct sock *sk, int optname,
+ }
+ #endif
+
+-struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
+- const xfrm_address_t *saddr,
+- const xfrm_address_t *daddr,
+- int family, u32 mark);
++struct dst_entry *__xfrm_dst_lookup(int family, const struct xfrm_dst_lookup_params *params);
+
+ struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
+
+diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
+index 4548a91acdc89..d1c2619e03740 100644
+--- a/net/ipv4/xfrm4_policy.c
++++ b/net/ipv4/xfrm4_policy.c
+@@ -17,47 +17,41 @@
+ #include <net/ip.h>
+ #include <net/l3mdev.h>
+
+-static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
+- int tos, int oif,
+- const xfrm_address_t *saddr,
+- const xfrm_address_t *daddr,
+- u32 mark)
++static struct dst_entry *__xfrm4_dst_lookup(struct flowi4 *fl4,
++ const struct xfrm_dst_lookup_params *params)
+ {
+ struct rtable *rt;
+
+ memset(fl4, 0, sizeof(*fl4));
+- fl4->daddr = daddr->a4;
+- fl4->flowi4_tos = tos;
+- fl4->flowi4_l3mdev = l3mdev_master_ifindex_by_index(net, oif);
+- fl4->flowi4_mark = mark;
+- if (saddr)
+- fl4->saddr = saddr->a4;
+-
+- rt = __ip_route_output_key(net, fl4);
++ fl4->daddr = params->daddr->a4;
++ fl4->flowi4_tos = params->tos;
++ fl4->flowi4_l3mdev = l3mdev_master_ifindex_by_index(params->net,
++ params->oif);
++ fl4->flowi4_mark = params->mark;
++ if (params->saddr)
++ fl4->saddr = params->saddr->a4;
++
++ rt = __ip_route_output_key(params->net, fl4);
+ if (!IS_ERR(rt))
+ return &rt->dst;
+
+ return ERR_CAST(rt);
+ }
+
+-static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, int oif,
+- const xfrm_address_t *saddr,
+- const xfrm_address_t *daddr,
+- u32 mark)
++static struct dst_entry *xfrm4_dst_lookup(const struct xfrm_dst_lookup_params *params)
+ {
+ struct flowi4 fl4;
+
+- return __xfrm4_dst_lookup(net, &fl4, tos, oif, saddr, daddr, mark);
++ return __xfrm4_dst_lookup(&fl4, params);
+ }
+
+-static int xfrm4_get_saddr(struct net *net, int oif,
+- xfrm_address_t *saddr, xfrm_address_t *daddr,
+- u32 mark)
++static int xfrm4_get_saddr(xfrm_address_t *saddr,
++ const struct xfrm_dst_lookup_params *params)
+ {
+ struct dst_entry *dst;
+ struct flowi4 fl4;
+
+- dst = __xfrm4_dst_lookup(net, &fl4, 0, oif, NULL, daddr, mark);
++ dst = __xfrm4_dst_lookup(&fl4, params);
+ if (IS_ERR(dst))
+ return -EHOSTUNREACH;
+
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index 492b9692c0dc0..40183fdf7da0e 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -23,23 +23,21 @@
+ #include <net/ip6_route.h>
+ #include <net/l3mdev.h>
+
+-static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
+- const xfrm_address_t *saddr,
+- const xfrm_address_t *daddr,
+- u32 mark)
++static struct dst_entry *xfrm6_dst_lookup(const struct xfrm_dst_lookup_params *params)
+ {
+ struct flowi6 fl6;
+ struct dst_entry *dst;
+ int err;
+
+ memset(&fl6, 0, sizeof(fl6));
+- fl6.flowi6_l3mdev = l3mdev_master_ifindex_by_index(net, oif);
+- fl6.flowi6_mark = mark;
+- memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
+- if (saddr)
+- memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr));
++ fl6.flowi6_l3mdev = l3mdev_master_ifindex_by_index(params->net,
++ params->oif);
++ fl6.flowi6_mark = params->mark;
++ memcpy(&fl6.daddr, params->daddr, sizeof(fl6.daddr));
++ if (params->saddr)
++ memcpy(&fl6.saddr, params->saddr, sizeof(fl6.saddr));
+
+- dst = ip6_route_output(net, NULL, &fl6);
++ dst = ip6_route_output(params->net, NULL, &fl6);
+
+ err = dst->error;
+ if (dst->error) {
+@@ -50,15 +48,14 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
+ return dst;
+ }
+
+-static int xfrm6_get_saddr(struct net *net, int oif,
+- xfrm_address_t *saddr, xfrm_address_t *daddr,
+- u32 mark)
++static int xfrm6_get_saddr(xfrm_address_t *saddr,
++ const struct xfrm_dst_lookup_params *params)
+ {
+ struct dst_entry *dst;
+ struct net_device *dev;
+ struct inet6_dev *idev;
+
+- dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr, mark);
++ dst = xfrm6_dst_lookup(params);
+ if (IS_ERR(dst))
+ return -EHOSTUNREACH;
+
+@@ -68,7 +65,8 @@ static int xfrm6_get_saddr(struct net *net, int oif,
+ return -EHOSTUNREACH;
+ }
+ dev = idev->dev;
+- ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
++ ipv6_dev_get_saddr(dev_net(dev), dev, ¶ms->daddr->in6, 0,
++ &saddr->in6);
+ dst_release(dst);
+ return 0;
+ }
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 8b8e957a69c36..4d13f7a372ab6 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -241,6 +241,8 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+
+ dev = dev_get_by_index(net, xuo->ifindex);
+ if (!dev) {
++ struct xfrm_dst_lookup_params params;
++
+ if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) {
+ saddr = &x->props.saddr;
+ daddr = &x->id.daddr;
+@@ -249,9 +251,12 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+ daddr = &x->props.saddr;
+ }
+
+- dst = __xfrm_dst_lookup(net, 0, 0, saddr, daddr,
+- x->props.family,
+- xfrm_smark_get(0, x));
++ memset(¶ms, 0, sizeof(params));
++ params.net = net;
++ params.saddr = saddr;
++ params.daddr = daddr;
++ params.mark = xfrm_smark_get(0, x);
++ dst = __xfrm_dst_lookup(x->props.family, ¶ms);
+ if (IS_ERR(dst))
+ return 0;
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 39910d4eff62b..a7f8da5241ae5 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -251,10 +251,8 @@ static const struct xfrm_if_cb *xfrm_if_get_cb(void)
+ return rcu_dereference(xfrm_if_cb);
+ }
+
+-struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
+- const xfrm_address_t *saddr,
+- const xfrm_address_t *daddr,
+- int family, u32 mark)
++struct dst_entry *__xfrm_dst_lookup(int family,
++ const struct xfrm_dst_lookup_params *params)
+ {
+ const struct xfrm_policy_afinfo *afinfo;
+ struct dst_entry *dst;
+@@ -263,7 +261,7 @@ struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
+ if (unlikely(afinfo == NULL))
+ return ERR_PTR(-EAFNOSUPPORT);
+
+- dst = afinfo->dst_lookup(net, tos, oif, saddr, daddr, mark);
++ dst = afinfo->dst_lookup(params);
+
+ rcu_read_unlock();
+
+@@ -277,6 +275,7 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x,
+ xfrm_address_t *prev_daddr,
+ int family, u32 mark)
+ {
++ struct xfrm_dst_lookup_params params;
+ struct net *net = xs_net(x);
+ xfrm_address_t *saddr = &x->props.saddr;
+ xfrm_address_t *daddr = &x->id.daddr;
+@@ -291,7 +290,14 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x,
+ daddr = x->coaddr;
+ }
+
+- dst = __xfrm_dst_lookup(net, tos, oif, saddr, daddr, family, mark);
++ params.net = net;
++ params.saddr = saddr;
++ params.daddr = daddr;
++ params.tos = tos;
++ params.oif = oif;
++ params.mark = mark;
++
++ dst = __xfrm_dst_lookup(family, ¶ms);
+
+ if (!IS_ERR(dst)) {
+ if (prev_saddr != saddr)
+@@ -2344,15 +2350,15 @@ int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
+ }
+
+ static int
+-xfrm_get_saddr(struct net *net, int oif, xfrm_address_t *local,
+- xfrm_address_t *remote, unsigned short family, u32 mark)
++xfrm_get_saddr(unsigned short family, xfrm_address_t *saddr,
++ const struct xfrm_dst_lookup_params *params)
+ {
+ int err;
+ const struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
+
+ if (unlikely(afinfo == NULL))
+ return -EINVAL;
+- err = afinfo->get_saddr(net, oif, local, remote, mark);
++ err = afinfo->get_saddr(saddr, params);
+ rcu_read_unlock();
+ return err;
+ }
+@@ -2381,9 +2387,14 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
+ remote = &tmpl->id.daddr;
+ local = &tmpl->saddr;
+ if (xfrm_addr_any(local, tmpl->encap_family)) {
+- error = xfrm_get_saddr(net, fl->flowi_oif,
+- &tmp, remote,
+- tmpl->encap_family, 0);
++ struct xfrm_dst_lookup_params params;
++
++ memset(¶ms, 0, sizeof(params));
++ params.net = net;
++ params.oif = fl->flowi_oif;
++ params.daddr = remote;
++ error = xfrm_get_saddr(tmpl->encap_family, &tmp,
++ ¶ms);
+ if (error)
+ goto fail;
+ local = &tmp;
+--
+2.43.0
+
--- /dev/null
+From 5faadc7886a4de0de7f8fe278160d9f4c83cd8a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Sep 2024 17:07:10 -0700
+Subject: xfrm: respect ip protocols rules criteria when performing dst lookups
+
+From: Eyal Birger <eyal.birger@gmail.com>
+
+[ Upstream commit b8469721034300bbb6dec5b4bf32492c95e16a0c ]
+
+The series in the "fixes" tag added the ability to consider L4 attributes
+in routing rules.
+
+The dst lookup on the outer packet of encapsulated traffic in the xfrm
+code was not adapted to this change, thus routing behavior that relies
+on L4 information is not respected.
+
+Pass the ip protocol information when performing dst lookups.
+
+Fixes: a25724b05af0 ("Merge branch 'fib_rules-support-sport-dport-and-proto-match'")
+Signed-off-by: Eyal Birger <eyal.birger@gmail.com>
+Tested-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xfrm.h | 2 ++
+ net/ipv4/xfrm4_policy.c | 2 ++
+ net/ipv6/xfrm6_policy.c | 3 +++
+ net/xfrm/xfrm_policy.c | 15 +++++++++++++++
+ 4 files changed, 22 insertions(+)
+
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index 142967e456b18..798df30c2d253 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -328,6 +328,8 @@ struct xfrm_dst_lookup_params {
+ xfrm_address_t *saddr;
+ xfrm_address_t *daddr;
+ u32 mark;
++ __u8 ipproto;
++ union flowi_uli uli;
+ };
+
+ struct net_device;
+diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
+index d1c2619e03740..5d8e38f4ecc07 100644
+--- a/net/ipv4/xfrm4_policy.c
++++ b/net/ipv4/xfrm4_policy.c
+@@ -30,6 +30,8 @@ static struct dst_entry *__xfrm4_dst_lookup(struct flowi4 *fl4,
+ fl4->flowi4_mark = params->mark;
+ if (params->saddr)
+ fl4->saddr = params->saddr->a4;
++ fl4->flowi4_proto = params->ipproto;
++ fl4->uli = params->uli;
+
+ rt = __ip_route_output_key(params->net, fl4);
+ if (!IS_ERR(rt))
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index 40183fdf7da0e..f5ef5e4c88df1 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -37,6 +37,9 @@ static struct dst_entry *xfrm6_dst_lookup(const struct xfrm_dst_lookup_params *p
+ if (params->saddr)
+ memcpy(&fl6.saddr, params->saddr, sizeof(fl6.saddr));
+
++ fl6.flowi4_proto = params->ipproto;
++ fl6.uli = params->uli;
++
+ dst = ip6_route_output(params->net, NULL, &fl6);
+
+ err = dst->error;
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index a7f8da5241ae5..a1a662a55c2ae 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -296,6 +296,21 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x,
+ params.tos = tos;
+ params.oif = oif;
+ params.mark = mark;
++ params.ipproto = x->id.proto;
++ if (x->encap) {
++ switch (x->encap->encap_type) {
++ case UDP_ENCAP_ESPINUDP:
++ params.ipproto = IPPROTO_UDP;
++ params.uli.ports.sport = x->encap->encap_sport;
++ params.uli.ports.dport = x->encap->encap_dport;
++ break;
++ case TCP_ENCAP_ESPINTCP:
++ params.ipproto = IPPROTO_TCP;
++ params.uli.ports.sport = x->encap->encap_sport;
++ params.uli.ports.dport = x->encap->encap_dport;
++ break;
++ }
++ }
+
+ dst = __xfrm_dst_lookup(family, ¶ms);
+
+--
+2.43.0
+