[PATCH 1/3] kernel: 5.10: fix ar8216 vlans

Mathias Kresin dev at kresin.me
Sat Oct 23 12:14:02 PDT 2021


ar8216 switches have a hardware bug, which renders normal 802.1q support
unusable. Packet mangling is required to fix up the vlan for incoming
packets.

The patch was ommited at the time kernel 5.10 support was added but is
still required for ar8216 switches.

Signed-off-by: Mathias Kresin <dev at kresin.me>
---
 .../721-net-add-packet-mangeling.patch        | 182 ++++++++++++++++++
 .../hack-5.10/901-debloat_sock_diag.patch     |   2 +-
 2 files changed, 183 insertions(+), 1 deletion(-)
 create mode 100644 target/linux/generic/hack-5.10/721-net-add-packet-mangeling.patch

diff --git a/target/linux/generic/hack-5.10/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-5.10/721-net-add-packet-mangeling.patch
new file mode 100644
index 0000000000..f656472ef9
--- /dev/null
+++ b/target/linux/generic/hack-5.10/721-net-add-packet-mangeling.patch
@@ -0,0 +1,182 @@
+From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd at nbd.name>
+Date: Fri, 7 Jul 2017 17:25:00 +0200
+Subject: net: add packet mangeling
+
+ar8216 switches have a hardware bug, which renders normal 802.1q support
+unusable. Packet mangling is required to fix up the vlan for incoming
+packets.
+
+Signed-off-by: Felix Fietkau <nbd at nbd.name>
+---
+ include/linux/netdevice.h | 11 +++++++++++
+ include/linux/skbuff.h    | 14 ++++----------
+ net/Kconfig               |  6 ++++++
+ net/core/dev.c            | 20 +++++++++++++++-----
+ net/core/skbuff.c         | 17 +++++++++++++++++
+ net/ethernet/eth.c        |  6 ++++++
+ 6 files changed, 59 insertions(+), 15 deletions(-)
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -1618,6 +1618,7 @@ enum netdev_priv_flags {
+ 	IFF_FAILOVER_SLAVE		= 1<<28,
+ 	IFF_L3MDEV_RX_HANDLER		= 1<<29,
+ 	IFF_LIVE_RENAME_OK		= 1<<30,
++	IFF_NO_IP_ALIGN			= 1<<31,
+ };
+ 
+ #define IFF_802_1Q_VLAN			IFF_802_1Q_VLAN
+@@ -1650,6 +1651,7 @@ enum netdev_priv_flags {
+ #define IFF_FAILOVER_SLAVE		IFF_FAILOVER_SLAVE
+ #define IFF_L3MDEV_RX_HANDLER		IFF_L3MDEV_RX_HANDLER
+ #define IFF_LIVE_RENAME_OK		IFF_LIVE_RENAME_OK
++#define IFF_NO_IP_ALIGN			IFF_NO_IP_ALIGN
+ 
+ /* Specifies the type of the struct net_device::ml_priv pointer */
+ enum netdev_ml_priv_type {
+@@ -1990,6 +1992,11 @@ struct net_device {
+ 	const struct tlsdev_ops *tlsdev_ops;
+ #endif
+ 
++#ifdef CONFIG_ETHERNET_PACKET_MANGLE
++	void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb);
++	struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb);
++#endif
++
+ 	const struct header_ops *header_ops;
+ 
+ 	unsigned int		flags;
+@@ -2080,6 +2087,10 @@ struct net_device {
+ 	struct mpls_dev __rcu	*mpls_ptr;
+ #endif
+ 
++#ifdef CONFIG_ETHERNET_PACKET_MANGLE
++	void			*phy_ptr; /* PHY device specific data */
++#endif
++
+ /*
+  * Cache lines mostly used on receive path (including eth_type_trans())
+  */
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -2710,6 +2710,10 @@ static inline int pskb_trim(struct sk_bu
+ 	return (len < skb->len) ? __pskb_trim(skb, len) : 0;
+ }
+ 
++extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
++		unsigned int length, gfp_t gfp);
++
++
+ /**
+  *	pskb_trim_unique - remove end from a paged unique (not cloned) buffer
+  *	@skb: buffer to alter
+@@ -2841,16 +2845,6 @@ static inline struct sk_buff *dev_alloc_
+ }
+ 
+ 
+-static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
+-		unsigned int length, gfp_t gfp)
+-{
+-	struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
+-
+-	if (NET_IP_ALIGN && skb)
+-		skb_reserve(skb, NET_IP_ALIGN);
+-	return skb;
+-}
+-
+ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
+ 		unsigned int length)
+ {
+--- a/net/Kconfig
++++ b/net/Kconfig
+@@ -26,6 +26,12 @@ menuconfig NET
+ 
+ if NET
+ 
++config ETHERNET_PACKET_MANGLE
++	bool
++	help
++	  This option can be selected by phy drivers that need to mangle
++	  packets going in or out of an ethernet device.
++
+ config WANT_COMPAT_NETLINK_MESSAGES
+ 	bool
+ 	help
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3638,11 +3638,21 @@ static int xmit_one(struct sk_buff *skb,
+ 	if (dev_nit_active(dev))
+ 		dev_queue_xmit_nit(skb, dev);
+ 
+-	len = skb->len;
+-	PRANDOM_ADD_NOISE(skb, dev, txq, len + jiffies);
+-	trace_net_dev_start_xmit(skb, dev);
+-	rc = netdev_start_xmit(skb, dev, txq, more);
+-	trace_net_dev_xmit(skb, rc, dev, len);
++#ifdef CONFIG_ETHERNET_PACKET_MANGLE
++	if (!dev->eth_mangle_tx ||
++	    (skb = dev->eth_mangle_tx(dev, skb)) != NULL)
++#else
++	if (1)
++#endif
++	{
++		len = skb->len;
++		PRANDOM_ADD_NOISE(skb, dev, txq, len + jiffies);
++		trace_net_dev_start_xmit(skb, dev);
++		rc = netdev_start_xmit(skb, dev, txq, more);
++		trace_net_dev_xmit(skb, rc, dev, len);
++	} else {
++		rc = NETDEV_TX_OK;
++	}
+ 
+ 	return rc;
+ }
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -60,6 +60,7 @@
+ #include <linux/prefetch.h>
+ #include <linux/if_vlan.h>
+ #include <linux/mpls.h>
++#include <linux/if.h>
+ 
+ #include <net/protocol.h>
+ #include <net/dst.h>
+@@ -553,6 +554,22 @@ skb_fail:
+ }
+ EXPORT_SYMBOL(__napi_alloc_skb);
+ 
++struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
++		unsigned int length, gfp_t gfp)
++{
++	struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
++
++#ifdef CONFIG_ETHERNET_PACKET_MANGLE
++	if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN))
++		return skb;
++#endif
++
++	if (NET_IP_ALIGN && skb)
++		skb_reserve(skb, NET_IP_ALIGN);
++	return skb;
++}
++EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
++
+ void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
+ 		     int size, unsigned int truesize)
+ {
+--- a/net/ethernet/eth.c
++++ b/net/ethernet/eth.c
+@@ -171,6 +171,12 @@ __be16 eth_type_trans(struct sk_buff *sk
+ 	const struct ethhdr *eth;
+ 
+ 	skb->dev = dev;
++
++#ifdef CONFIG_ETHERNET_PACKET_MANGLE
++	if (dev->eth_mangle_rx)
++		dev->eth_mangle_rx(dev, skb);
++#endif
++
+ 	skb_reset_mac_header(skb);
+ 
+ 	eth = (struct ethhdr *)skb->data;
diff --git a/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch b/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch
index 78446d38c4..247b50d536 100644
--- a/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch
+++ b/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch
@@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 
 --- a/net/Kconfig
 +++ b/net/Kconfig
-@@ -98,6 +98,9 @@ source "net/mptcp/Kconfig"
+@@ -104,6 +104,9 @@ source "net/mptcp/Kconfig"
  
  endif # if INET
  
-- 
2.25.1




More information about the openwrt-devel mailing list