a7a23278d04567d25049f6cabba4081534fe01d5
[openwrt/openwrt.git] / target / linux / generic / pending-4.4 / 721-phy_packets.patch
1 --- a/include/linux/netdevice.h
2 +++ b/include/linux/netdevice.h
3 @@ -1297,6 +1297,7 @@ enum netdev_priv_flags {
4 IFF_NO_QUEUE = 1<<21,
5 IFF_OPENVSWITCH = 1<<22,
6 IFF_L3MDEV_SLAVE = 1<<23,
7 + IFF_NO_IP_ALIGN = 1<<24,
8 };
9
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
16
17 /**
18 * struct net_device - The DEVICE structure.
19 @@ -1603,6 +1605,11 @@ struct net_device {
20 const struct l3mdev_ops *l3mdev_ops;
21 #endif
22
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);
26 +#endif
27 +
28 const struct header_ops *header_ops;
29
30 unsigned int flags;
31 @@ -1670,6 +1677,10 @@ struct net_device {
32 struct mpls_dev __rcu *mpls_ptr;
33 #endif
34
35 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
36 + void *phy_ptr; /* PHY device specific data */
37 +#endif
38 +
39 /*
40 * Cache lines mostly used on receive path (including eth_type_trans())
41 */
42 --- a/include/linux/skbuff.h
43 +++ b/include/linux/skbuff.h
44 @@ -2208,6 +2208,10 @@ static inline int pskb_trim(struct sk_bu
45 return (len < skb->len) ? __pskb_trim(skb, len) : 0;
46 }
47
48 +extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
49 + unsigned int length, gfp_t gfp);
50 +
51 +
52 /**
53 * pskb_trim_unique - remove end from a paged unique (not cloned) buffer
54 * @skb: buffer to alter
55 @@ -2312,16 +2316,6 @@ static inline struct sk_buff *dev_alloc_
56 }
57
58
59 -static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
60 - unsigned int length, gfp_t gfp)
61 -{
62 - struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
63 -
64 - if (NET_IP_ALIGN && skb)
65 - skb_reserve(skb, NET_IP_ALIGN);
66 - return skb;
67 -}
68 -
69 static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
70 unsigned int length)
71 {
72 --- a/net/Kconfig
73 +++ b/net/Kconfig
74 @@ -25,6 +25,12 @@ menuconfig NET
75
76 if NET
77
78 +config ETHERNET_PACKET_MANGLE
79 + bool
80 + help
81 + This option can be selected by phy drivers that need to mangle
82 + packets going in or out of an ethernet device.
83 +
84 config WANT_COMPAT_NETLINK_MESSAGES
85 bool
86 help
87 --- a/net/core/dev.c
88 +++ b/net/core/dev.c
89 @@ -2746,10 +2746,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);
92
93 - len = skb->len;
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)
100 +#else
101 + if (1)
102 +#endif
103 + {
104 + len = skb->len;
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);
108 + } else {
109 + rc = NETDEV_TX_OK;
110 + }
111
112 return rc;
113 }
114 --- a/net/core/skbuff.c
115 +++ b/net/core/skbuff.c
116 @@ -63,6 +63,7 @@
117 #include <linux/errqueue.h>
118 #include <linux/prefetch.h>
119 #include <linux/if_vlan.h>
120 +#include <linux/if.h>
121
122 #include <net/protocol.h>
123 #include <net/dst.h>
124 @@ -520,6 +521,22 @@ skb_fail:
125 }
126 EXPORT_SYMBOL(__napi_alloc_skb);
127
128 +struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
129 + unsigned int length, gfp_t gfp)
130 +{
131 + struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
132 +
133 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
134 + if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN))
135 + return skb;
136 +#endif
137 +
138 + if (NET_IP_ALIGN && skb)
139 + skb_reserve(skb, NET_IP_ALIGN);
140 + return skb;
141 +}
142 +EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
143 +
144 void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
145 int size, unsigned int truesize)
146 {
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;
151
152 skb->dev = dev;
153 +
154 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
155 + if (dev->eth_mangle_rx)
156 + dev->eth_mangle_rx(dev, skb);
157 +#endif
158 +
159 skb_reset_mac_header(skb);
160
161 eth = (struct ethhdr *)skb->data;