1 --- a/include/linux/netdevice.h
2 +++ b/include/linux/netdevice.h
3 @@ -1297,6 +1297,7 @@ enum netdev_priv_flags {
5 IFF_OPENVSWITCH = 1<<22,
6 IFF_L3MDEV_SLAVE = 1<<23,
7 + IFF_NO_IP_ALIGN = 1<<24,
10 #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
11 @@ -1323,6 +1324,7 @@ enum netdev_priv_flags {
12 #define IFF_NO_QUEUE IFF_NO_QUEUE
13 #define IFF_OPENVSWITCH IFF_OPENVSWITCH
14 #define IFF_L3MDEV_SLAVE IFF_L3MDEV_SLAVE
15 +#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN
18 * struct net_device - The DEVICE structure.
19 @@ -1603,6 +1605,11 @@ struct net_device {
20 const struct l3mdev_ops *l3mdev_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 @@ -1670,6 +1677,10 @@ struct net_device {
32 struct mpls_dev __rcu *mpls_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 @@ -2211,6 +2211,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 @@ -2315,16 +2319,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 @@ -2735,10 +2735,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 @@ -520,6 +521,22 @@ skb_fail:
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 @@ -168,6 +168,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);
161 eth = (struct ethhdr *)skb->data;