721-net-add-packet-mangeling.patch 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001
  2. From: Felix Fietkau <[email protected]>
  3. Date: Fri, 7 Jul 2017 17:25:00 +0200
  4. Subject: net: add packet mangeling
  5. ar8216 switches have a hardware bug, which renders normal 802.1q support
  6. unusable. Packet mangling is required to fix up the vlan for incoming
  7. packets.
  8. Signed-off-by: Felix Fietkau <[email protected]>
  9. ---
  10. include/linux/netdevice.h | 11 +++++++++++
  11. include/linux/skbuff.h | 14 ++++----------
  12. net/Kconfig | 6 ++++++
  13. net/core/dev.c | 20 +++++++++++++++-----
  14. net/core/skbuff.c | 17 +++++++++++++++++
  15. net/ethernet/eth.c | 6 ++++++
  16. 6 files changed, 59 insertions(+), 15 deletions(-)
  17. --- a/include/linux/netdevice.h
  18. +++ b/include/linux/netdevice.h
  19. @@ -1648,6 +1648,7 @@ enum netdev_priv_flags {
  20. IFF_FAILOVER_SLAVE = 1<<28,
  21. IFF_L3MDEV_RX_HANDLER = 1<<29,
  22. IFF_LIVE_RENAME_OK = 1<<30,
  23. + IFF_NO_IP_ALIGN = 1<<31,
  24. };
  25. #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
  26. @@ -1680,6 +1681,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. /* Specifies the type of the struct net_device::ml_priv pointer */
  32. enum netdev_ml_priv_type {
  33. @@ -2020,6 +2022,11 @@ struct net_device {
  34. const struct tlsdev_ops *tlsdev_ops;
  35. #endif
  36. +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
  37. + void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb);
  38. + struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb);
  39. +#endif
  40. +
  41. const struct header_ops *header_ops;
  42. unsigned int flags;
  43. @@ -2110,6 +2117,10 @@ struct net_device {
  44. struct mpls_dev __rcu *mpls_ptr;
  45. #endif
  46. +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
  47. + void *phy_ptr; /* PHY device specific data */
  48. +#endif
  49. +
  50. /*
  51. * Cache lines mostly used on receive path (including eth_type_trans())
  52. */
  53. --- a/include/linux/skbuff.h
  54. +++ b/include/linux/skbuff.h
  55. @@ -2728,6 +2728,10 @@ static inline int pskb_trim(struct sk_bu
  56. return (len < skb->len) ? __pskb_trim(skb, len) : 0;
  57. }
  58. +extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
  59. + unsigned int length, gfp_t gfp);
  60. +
  61. +
  62. /**
  63. * pskb_trim_unique - remove end from a paged unique (not cloned) buffer
  64. * @skb: buffer to alter
  65. @@ -2859,16 +2863,6 @@ static inline struct sk_buff *dev_alloc_
  66. }
  67. -static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
  68. - unsigned int length, gfp_t gfp)
  69. -{
  70. - struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
  71. -
  72. - if (NET_IP_ALIGN && skb)
  73. - skb_reserve(skb, NET_IP_ALIGN);
  74. - return skb;
  75. -}
  76. -
  77. static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
  78. unsigned int length)
  79. {
  80. --- a/net/Kconfig
  81. +++ b/net/Kconfig
  82. @@ -26,6 +26,12 @@ menuconfig NET
  83. if NET
  84. +config ETHERNET_PACKET_MANGLE
  85. + bool
  86. + help
  87. + This option can be selected by phy drivers that need to mangle
  88. + packets going in or out of an ethernet device.
  89. +
  90. config WANT_COMPAT_NETLINK_MESSAGES
  91. bool
  92. help
  93. --- a/net/core/dev.c
  94. +++ b/net/core/dev.c
  95. @@ -3656,6 +3656,11 @@ static int xmit_one(struct sk_buff *skb,
  96. if (dev_nit_active(dev))
  97. dev_queue_xmit_nit(skb, dev);
  98. +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
  99. + if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb)))
  100. + return NETDEV_TX_OK;
  101. +#endif
  102. +
  103. len = skb->len;
  104. PRANDOM_ADD_NOISE(skb, dev, txq, len + jiffies);
  105. trace_net_dev_start_xmit(skb, dev);
  106. --- a/net/core/skbuff.c
  107. +++ b/net/core/skbuff.c
  108. @@ -60,6 +60,7 @@
  109. #include <linux/prefetch.h>
  110. #include <linux/if_vlan.h>
  111. #include <linux/mpls.h>
  112. +#include <linux/if.h>
  113. #include <net/protocol.h>
  114. #include <net/dst.h>
  115. @@ -553,6 +554,22 @@ skb_fail:
  116. }
  117. EXPORT_SYMBOL(__napi_alloc_skb);
  118. +struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
  119. + unsigned int length, gfp_t gfp)
  120. +{
  121. + struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
  122. +
  123. +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
  124. + if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN))
  125. + return skb;
  126. +#endif
  127. +
  128. + if (NET_IP_ALIGN && skb)
  129. + skb_reserve(skb, NET_IP_ALIGN);
  130. + return skb;
  131. +}
  132. +EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
  133. +
  134. void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
  135. int size, unsigned int truesize)
  136. {
  137. --- a/net/ethernet/eth.c
  138. +++ b/net/ethernet/eth.c
  139. @@ -171,6 +171,12 @@ __be16 eth_type_trans(struct sk_buff *sk
  140. const struct ethhdr *eth;
  141. skb->dev = dev;
  142. +
  143. +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
  144. + if (dev->eth_mangle_rx)
  145. + dev->eth_mangle_rx(dev, skb);
  146. +#endif
  147. +
  148. skb_reset_mac_header(skb);
  149. eth = (struct ethhdr *)skb->data;