bfb4f50e7928407c9703698337b4688113c48854
[openwrt/staging/stintel.git] / target / linux / generic / hack-6.1 / 721-net-add-packet-mangeling.patch
1 From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001
2 From: Felix Fietkau <nbd@nbd.name>
3 Date: Fri, 7 Jul 2017 17:25:00 +0200
4 Subject: net: add packet mangeling
5
6 ar8216 switches have a hardware bug, which renders normal 802.1q support
7 unusable. Packet mangling is required to fix up the vlan for incoming
8 packets.
9
10 Signed-off-by: Felix Fietkau <nbd@nbd.name>
11 ---
12 include/linux/netdevice.h | 11 +++++++++++
13 include/linux/skbuff.h | 14 ++++----------
14 net/Kconfig | 6 ++++++
15 net/core/dev.c | 20 +++++++++++++++-----
16 net/core/skbuff.c | 17 +++++++++++++++++
17 net/ethernet/eth.c | 6 ++++++
18 6 files changed, 59 insertions(+), 15 deletions(-)
19
20 --- a/include/linux/netdevice.h
21 +++ b/include/linux/netdevice.h
22 @@ -1706,6 +1706,7 @@ enum netdev_priv_flags {
23 /* was IFF_LIVE_RENAME_OK */
24 IFF_TX_SKB_NO_LINEAR = BIT_ULL(31),
25 IFF_CHANGE_PROTO_DOWN = BIT_ULL(32),
26 + IFF_NO_IP_ALIGN = BIT_ULL(33),
27 };
28
29 #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
30 @@ -1739,6 +1740,7 @@ enum netdev_priv_flags {
31 #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE
32 #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
33 #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR
34 +#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN
35
36 /* Specifies the type of the struct net_device::ml_priv pointer */
37 enum netdev_ml_priv_type {
38 @@ -2107,6 +2109,11 @@ struct net_device {
39 const struct tlsdev_ops *tlsdev_ops;
40 #endif
41
42 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
43 + void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb);
44 + struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb);
45 +#endif
46 +
47 const struct header_ops *header_ops;
48
49 unsigned char operstate;
50 @@ -2182,6 +2189,10 @@ struct net_device {
51 struct mctp_dev __rcu *mctp_ptr;
52 #endif
53
54 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
55 + void *phy_ptr; /* PHY device specific data */
56 +#endif
57 +
58 /*
59 * Cache lines mostly used on receive path (including eth_type_trans())
60 */
61 --- a/include/linux/skbuff.h
62 +++ b/include/linux/skbuff.h
63 @@ -3032,6 +3032,10 @@ static inline int pskb_trim(struct sk_bu
64 return (len < skb->len) ? __pskb_trim(skb, len) : 0;
65 }
66
67 +extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
68 + unsigned int length, gfp_t gfp);
69 +
70 +
71 /**
72 * pskb_trim_unique - remove end from a paged unique (not cloned) buffer
73 * @skb: buffer to alter
74 @@ -3181,16 +3185,6 @@ static inline struct sk_buff *dev_alloc_
75 }
76
77
78 -static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
79 - unsigned int length, gfp_t gfp)
80 -{
81 - struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
82 -
83 - if (NET_IP_ALIGN && skb)
84 - skb_reserve(skb, NET_IP_ALIGN);
85 - return skb;
86 -}
87 -
88 static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
89 unsigned int length)
90 {
91 --- a/net/Kconfig
92 +++ b/net/Kconfig
93 @@ -26,6 +26,12 @@ menuconfig NET
94
95 if NET
96
97 +config ETHERNET_PACKET_MANGLE
98 + bool
99 + help
100 + This option can be selected by phy drivers that need to mangle
101 + packets going in or out of an ethernet device.
102 +
103 config WANT_COMPAT_NETLINK_MESSAGES
104 bool
105 help
106 --- a/net/core/dev.c
107 +++ b/net/core/dev.c
108 @@ -3575,6 +3575,11 @@ static int xmit_one(struct sk_buff *skb,
109 if (dev_nit_active(dev))
110 dev_queue_xmit_nit(skb, dev);
111
112 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
113 + if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb)))
114 + return NETDEV_TX_OK;
115 +#endif
116 +
117 len = skb->len;
118 trace_net_dev_start_xmit(skb, dev);
119 rc = netdev_start_xmit(skb, dev, txq, more);
120 --- a/net/core/skbuff.c
121 +++ b/net/core/skbuff.c
122 @@ -61,6 +61,7 @@
123 #include <linux/if_vlan.h>
124 #include <linux/mpls.h>
125 #include <linux/kcov.h>
126 +#include <linux/if.h>
127
128 #include <net/protocol.h>
129 #include <net/dst.h>
130 @@ -707,6 +708,22 @@ skb_fail:
131 }
132 EXPORT_SYMBOL(__napi_alloc_skb);
133
134 +struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
135 + unsigned int length, gfp_t gfp)
136 +{
137 + struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
138 +
139 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
140 + if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN))
141 + return skb;
142 +#endif
143 +
144 + if (NET_IP_ALIGN && skb)
145 + skb_reserve(skb, NET_IP_ALIGN);
146 + return skb;
147 +}
148 +EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
149 +
150 void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
151 int size, unsigned int truesize)
152 {
153 --- a/net/ethernet/eth.c
154 +++ b/net/ethernet/eth.c
155 @@ -171,6 +171,12 @@ __be16 eth_type_trans(struct sk_buff *sk
156 const struct ethhdr *eth;
157
158 skb->dev = dev;
159 +
160 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
161 + if (dev->eth_mangle_rx)
162 + dev->eth_mangle_rx(dev, skb);
163 +#endif
164 +
165 skb_reset_mac_header(skb);
166
167 eth = (struct ethhdr *)skb->data;