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