3aa019f41cd487e90d22b16704aa69623ee31661
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-3.18 / 721-phy_packets.patch
1 --- a/include/linux/netdevice.h
2 +++ b/include/linux/netdevice.h
3 @@ -1216,6 +1216,7 @@ enum netdev_priv_flags {
4 IFF_LIVE_ADDR_CHANGE = 1<<20,
5 IFF_MACVLAN = 1<<21,
6 IFF_XMIT_DST_RELEASE_PERM = 1<<22,
7 + IFF_NO_IP_ALIGN = 1<<23,
8 };
9
10 #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
11 --- a/include/linux/skbuff.h
12 +++ b/include/linux/skbuff.h
13 @@ -2044,6 +2044,10 @@ static inline int pskb_trim(struct sk_bu
14 return (len < skb->len) ? __pskb_trim(skb, len) : 0;
15 }
16
17 +extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
18 + unsigned int length, gfp_t gfp);
19 +
20 +
21 /**
22 * pskb_trim_unique - remove end from a paged unique (not cloned) buffer
23 * @skb: buffer to alter
24 @@ -2170,16 +2174,6 @@ static inline struct sk_buff *dev_alloc_
25 }
26
27
28 -static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
29 - unsigned int length, gfp_t gfp)
30 -{
31 - struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
32 -
33 - if (NET_IP_ALIGN && skb)
34 - skb_reserve(skb, NET_IP_ALIGN);
35 - return skb;
36 -}
37 -
38 static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
39 unsigned int length)
40 {
41 --- a/net/Kconfig
42 +++ b/net/Kconfig
43 @@ -25,6 +25,12 @@ menuconfig NET
44
45 if NET
46
47 +config ETHERNET_PACKET_MANGLE
48 + bool
49 + help
50 + This option can be selected by phy drivers that need to mangle
51 + packets going in or out of an ethernet device.
52 +
53 config WANT_COMPAT_NETLINK_MESSAGES
54 bool
55 help
56 --- a/net/core/dev.c
57 +++ b/net/core/dev.c
58 @@ -2607,10 +2607,20 @@ static int xmit_one(struct sk_buff *skb,
59 if (!list_empty(&ptype_all))
60 dev_queue_xmit_nit(skb, dev);
61
62 - len = skb->len;
63 - trace_net_dev_start_xmit(skb, dev);
64 - rc = netdev_start_xmit(skb, dev, txq, more);
65 - trace_net_dev_xmit(skb, rc, dev, len);
66 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
67 + if (!dev->eth_mangle_tx ||
68 + (skb = dev->eth_mangle_tx(dev, skb)) != NULL)
69 +#else
70 + if (1)
71 +#endif
72 + {
73 + len = skb->len;
74 + trace_net_dev_start_xmit(skb, dev);
75 + rc = netdev_start_xmit(skb, dev, txq, more);
76 + trace_net_dev_xmit(skb, rc, dev, len);
77 + } else {
78 + rc = NETDEV_TX_OK;
79 + }
80
81 return rc;
82 }
83 --- a/net/core/skbuff.c
84 +++ b/net/core/skbuff.c
85 @@ -63,6 +63,7 @@
86 #include <linux/errqueue.h>
87 #include <linux/prefetch.h>
88 #include <linux/if_vlan.h>
89 +#include <linux/if.h>
90
91 #include <net/protocol.h>
92 #include <net/dst.h>
93 @@ -451,6 +452,22 @@ struct sk_buff *__netdev_alloc_skb(struc
94 }
95 EXPORT_SYMBOL(__netdev_alloc_skb);
96
97 +struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
98 + unsigned int length, gfp_t gfp)
99 +{
100 + struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
101 +
102 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
103 + if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN))
104 + return skb;
105 +#endif
106 +
107 + if (NET_IP_ALIGN && skb)
108 + skb_reserve(skb, NET_IP_ALIGN);
109 + return skb;
110 +}
111 +EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
112 +
113 void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
114 int size, unsigned int truesize)
115 {
116 --- a/net/ethernet/eth.c
117 +++ b/net/ethernet/eth.c
118 @@ -188,6 +188,12 @@ __be16 eth_type_trans(struct sk_buff *sk
119 const struct ethhdr *eth;
120
121 skb->dev = dev;
122 +
123 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
124 + if (dev->eth_mangle_rx)
125 + dev->eth_mangle_rx(dev, skb);
126 +#endif
127 +
128 skb_reset_mac_header(skb);
129 skb_pull_inline(skb, ETH_HLEN);
130 eth = eth_hdr(skb);