1 --- a/include/linux/netdevice.h
2 +++ b/include/linux/netdevice.h
3 @@ -1260,6 +1260,7 @@ enum netdev_priv_flags {
4 IFF_XMIT_DST_RELEASE_PERM = 1<<22,
5 IFF_IPVLAN_MASTER = 1<<23,
6 IFF_IPVLAN_SLAVE = 1<<24,
7 + IFF_NO_IP_ALIGN = 1<<25,
10 #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
11 @@ -1287,6 +1288,7 @@ enum netdev_priv_flags {
12 #define IFF_XMIT_DST_RELEASE_PERM IFF_XMIT_DST_RELEASE_PERM
13 #define IFF_IPVLAN_MASTER IFF_IPVLAN_MASTER
14 #define IFF_IPVLAN_SLAVE IFF_IPVLAN_SLAVE
15 +#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN
18 * struct net_device - The DEVICE structure.
19 @@ -1559,6 +1561,11 @@ struct net_device {
20 const struct ethtool_ops *ethtool_ops;
21 const struct forwarding_accel_ops *fwd_ops;
23 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
24 + void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb);
25 + struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb);
28 const struct header_ops *header_ops;
31 @@ -1624,6 +1631,10 @@ struct net_device {
32 struct wireless_dev *ieee80211_ptr;
33 struct wpan_dev *ieee802154_ptr;
35 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
36 + void *phy_ptr; /* PHY device specific data */
40 * Cache lines mostly used on receive path (including eth_type_trans())
42 --- a/include/linux/skbuff.h
43 +++ b/include/linux/skbuff.h
44 @@ -2057,6 +2057,10 @@ static inline int pskb_trim(struct sk_bu
45 return (len < skb->len) ? __pskb_trim(skb, len) : 0;
48 +extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
49 + unsigned int length, gfp_t gfp);
53 * pskb_trim_unique - remove end from a paged unique (not cloned) buffer
54 * @skb: buffer to alter
55 @@ -2183,16 +2187,6 @@ static inline struct sk_buff *dev_alloc_
59 -static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
60 - unsigned int length, gfp_t gfp)
62 - struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
64 - if (NET_IP_ALIGN && skb)
65 - skb_reserve(skb, NET_IP_ALIGN);
69 static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
74 @@ -25,6 +25,12 @@ menuconfig NET
78 +config ETHERNET_PACKET_MANGLE
81 + This option can be selected by phy drivers that need to mangle
82 + packets going in or out of an ethernet device.
84 config WANT_COMPAT_NETLINK_MESSAGES
89 @@ -2618,10 +2618,20 @@ static int xmit_one(struct sk_buff *skb,
90 if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
91 dev_queue_xmit_nit(skb, dev);
94 - trace_net_dev_start_xmit(skb, dev);
95 - rc = netdev_start_xmit(skb, dev, txq, more);
96 - trace_net_dev_xmit(skb, rc, dev, len);
97 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
98 + if (!dev->eth_mangle_tx ||
99 + (skb = dev->eth_mangle_tx(dev, skb)) != NULL)
105 + trace_net_dev_start_xmit(skb, dev);
106 + rc = netdev_start_xmit(skb, dev, txq, more);
107 + trace_net_dev_xmit(skb, rc, dev, len);
114 --- a/net/core/skbuff.c
115 +++ b/net/core/skbuff.c
117 #include <linux/errqueue.h>
118 #include <linux/prefetch.h>
119 #include <linux/if_vlan.h>
120 +#include <linux/if.h>
122 #include <net/protocol.h>
124 @@ -550,6 +551,22 @@ struct sk_buff *__napi_alloc_skb(struct
126 EXPORT_SYMBOL(__napi_alloc_skb);
128 +struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
129 + unsigned int length, gfp_t gfp)
131 + struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
133 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
134 + if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN))
138 + if (NET_IP_ALIGN && skb)
139 + skb_reserve(skb, NET_IP_ALIGN);
142 +EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
144 void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
145 int size, unsigned int truesize)
147 --- a/net/ethernet/eth.c
148 +++ b/net/ethernet/eth.c
149 @@ -200,6 +200,12 @@ __be16 eth_type_trans(struct sk_buff *sk
150 const struct ethhdr *eth;
154 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
155 + if (dev->eth_mangle_rx)
156 + dev->eth_mangle_rx(dev, skb);
159 skb_reset_mac_header(skb);
160 skb_pull_inline(skb, ETH_HLEN);