openwrt/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
John Audia d6d8851d12 kernel: bump 5.15 to 5.15.100
Manually rebased:
        bcm27xx/patches-5.15/950-0421-Support-RPi-DPI-interface-in-mode6-for-18-bit-color.patch
        bcm27xx/patches-5.15/950-0706-media-i2c-imx219-Scale-the-pixel-clock-rate-for-the-.patch
        ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch

Removed upstreamed:
        bcm27xx/patches-5.15/950-0707-drm-vc4-For-DPI-MEDIA_BUS_FMT_RGB565_1X16-is-mode-1-.patch[1]
        bcm27xx/patches-5.15/950-0596-drm-vc4-dpi-Add-option-for-inverting-pixel-clock-and.patch[2]
        ipq807x/0006-v5.16-arm64-dts-qcom-Fix-IPQ8074-PCIe-PHY-nodes.patch [3]
        ipq807x/0034-v6.1-arm64-dts-qcom-ipq8074-fix-PCIe-PHY-serdes-size.patch [4]
        ipq807x/0103-arm64-dts-qcom-ipq8074-fix-Gen2-PCIe-QMP-PHY.patch [5]
        ipq807x/0104-arm64-dts-qcom-ipq8074-fix-Gen3-PCIe-QMP-PHY.patch [6]
        ipq807x/0105-arm64-dts-qcom-ipq8074-correct-Gen2-PCIe-ranges.patch [7]
        ipq807x/0108-arm64-dts-qcom-ipq8074-fix-Gen3-PCIe-node.patch [8]
        ipq807x/0109-arm64-dts-qcom-ipq8074-correct-PCIe-QMP-PHY-output-c.patch [9]
        ipq807x/0132-arm64-dts-qcom-ipq8074-correct-USB3-QMP-PHY-s-clock-.patch [10]

All other patches automatically rebased.

1. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v5.15.99&id=d2991e6b30020e286f2dd9d3b4f43548c547caa6
2. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/drivers/gpu/drm/vc4/vc4_dpi.c?h=v5.15.100&id=8e04aaffb6de5f1ae61de7b671c1531172ccf429
3. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/arm64/boot/dts/qcom/ipq8074.dtsi?h=v5.15.99&id=a55a645aa303a3f7ec37db69822d5420657626da
4. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/arm64/boot/dts/qcom/ipq8074.dtsi?h=v5.15.99&id=d9df682bcea57fa25f37bbf17eae56fa05662635
5. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/arm64/boot/dts/qcom/ipq8074.dtsi?h=v5.15.99&id=7e6eeb5fb3aa9e5feffdb6e137dcc06f5f6410e1
6. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/arm64/boot/dts/qcom/ipq8074.dtsi?h=v5.15.99&id=e88204931d9a60634cd50bbc679f045439c4b91d
7.  https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/arm64/boot/dts/qcom/ipq8074.dtsi?h=v5.15.99&id=1563af0f28afd3b6d64ac79a2aecced3969c90bf
8. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/arm64/boot/dts/qcom/ipq8074.dtsi?h=v5.15.99&id=feb8c71f015d416f1afe90e1f62cf51e47376c67
9. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/arm64/boot/dts/qcom/ipq8074.dtsi?h=v5.15.99&id=69c7a270357a7d50ffd3471b14c60250041200e3
10. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/arch/arm64/boot/dts/qcom/ipq8074.dtsi?h=v5.15.99&id=dd3d021ae5471d98adf81f1e897431c8657d0a18

Build system: x86_64
Build-tested: bcm2711/RPi4B, ramips/tplink_archer-a6-v3
Run-tested: bcm2711/RPi4B, ramips/tplink_archer-a6-v3

Signed-off-by: John Audia <therealgraysky@proton.me>
Tested-by: Robert Marko <robimarko@gmail.com> #ipq807x/Dynalink WRX36
Tested-by: Stefan Lippers-Hollmann <s.l-h@gmx.de> #ipq807x/ax3600, x86_64/FW-7543B, ath79/tl-wdr3600, ipq806x/g10, ipq806x/nbg6817
2023-03-18 12:52:17 +01:00

150 lines
4.0 KiB
Diff

From: Felix Fietkau <nbd@nbd.name>
Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
include/linux/netdevice.h | 2 ++
include/linux/skbuff.h | 3 ++-
net/core/dev.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++
net/ethernet/eth.c | 18 +++++++++++++++++-
4 files changed, 69 insertions(+), 2 deletions(-)
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2096,6 +2096,8 @@ struct net_device {
struct netdev_hw_addr_list mc;
struct netdev_hw_addr_list dev_addrs;
+ unsigned char local_addr_mask[MAX_ADDR_LEN];
+
#ifdef CONFIG_SYSFS
struct kset *queues_kset;
#endif
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -892,6 +892,7 @@ struct sk_buff {
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2;
#endif
+ __u8 gro_skip:1;
__u8 ipvs_property:1;
__u8 inner_protocol_type:1;
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6065,6 +6065,9 @@ static enum gro_result dev_gro_receive(s
int same_flow;
int grow;
+ if (skb->gro_skip)
+ goto normal;
+
if (netif_elide_gro(skb->dev))
goto normal;
@@ -8079,6 +8082,48 @@ static void __netdev_adjacent_dev_unlink
&upper_dev->adj_list.lower);
}
+static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr,
+ struct net_device *dev)
+{
+ int i;
+
+ for (i = 0; i < dev->addr_len; i++)
+ mask[i] |= addr[i] ^ dev->dev_addr[i];
+}
+
+static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev,
+ struct net_device *lower)
+{
+ struct net_device *cur;
+ struct list_head *iter;
+
+ netdev_for_each_upper_dev_rcu(dev, cur, iter) {
+ __netdev_addr_mask(mask, cur->dev_addr, lower);
+ __netdev_upper_mask(mask, cur, lower);
+ }
+}
+
+static void __netdev_update_addr_mask(struct net_device *dev)
+{
+ unsigned char mask[MAX_ADDR_LEN];
+ struct net_device *cur;
+ struct list_head *iter;
+
+ memset(mask, 0, sizeof(mask));
+ __netdev_upper_mask(mask, dev, dev);
+ memcpy(dev->local_addr_mask, mask, dev->addr_len);
+
+ netdev_for_each_lower_dev(dev, cur, iter)
+ __netdev_update_addr_mask(cur);
+}
+
+static void netdev_update_addr_mask(struct net_device *dev)
+{
+ rcu_read_lock();
+ __netdev_update_addr_mask(dev);
+ rcu_read_unlock();
+}
+
static int __netdev_upper_dev_link(struct net_device *dev,
struct net_device *upper_dev, bool master,
void *upper_priv, void *upper_info,
@@ -8130,6 +8175,7 @@ static int __netdev_upper_dev_link(struc
if (ret)
return ret;
+ netdev_update_addr_mask(dev);
ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
&changeupper_info.info);
ret = notifier_to_errno(ret);
@@ -8226,6 +8272,7 @@ static void __netdev_upper_dev_unlink(st
__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
+ netdev_update_addr_mask(dev);
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
&changeupper_info.info);
@@ -9045,6 +9092,7 @@ int dev_set_mac_address(struct net_devic
if (err)
return err;
dev->addr_assign_type = NET_ADDR_SET;
+ netdev_update_addr_mask(dev);
call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
add_device_randomness(dev->dev_addr, dev->addr_len);
return 0;
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -142,6 +142,18 @@ u32 eth_get_headlen(const struct net_dev
}
EXPORT_SYMBOL(eth_get_headlen);
+static inline bool
+eth_check_local_mask(const void *addr1, const void *addr2, const void *mask)
+{
+ const u16 *a1 = addr1;
+ const u16 *a2 = addr2;
+ const u16 *m = mask;
+
+ return (((a1[0] ^ a2[0]) & ~m[0]) |
+ ((a1[1] ^ a2[1]) & ~m[1]) |
+ ((a1[2] ^ a2[2]) & ~m[2]));
+}
+
/**
* eth_type_trans - determine the packet's protocol ID.
* @skb: received socket data
@@ -173,6 +185,10 @@ __be16 eth_type_trans(struct sk_buff *sk
} else {
skb->pkt_type = PACKET_OTHERHOST;
}
+
+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr,
+ dev->local_addr_mask))
+ skb->gro_skip = 1;
}
/*