vlan_core.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include <linux/skbuff.h>
  2. #include <linux/netdevice.h>
  3. #include <linux/if_vlan.h>
  4. #include <linux/netpoll.h>
  5. #include "vlan.h"
  6. bool vlan_hwaccel_do_receive(struct sk_buff **skbp)
  7. {
  8. struct sk_buff *skb = *skbp;
  9. u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
  10. struct net_device *vlan_dev;
  11. struct vlan_pcpu_stats *rx_stats;
  12. vlan_dev = vlan_find_dev(skb->dev, vlan_id);
  13. if (!vlan_dev) {
  14. if (vlan_id)
  15. skb->pkt_type = PACKET_OTHERHOST;
  16. return false;
  17. }
  18. skb = *skbp = skb_share_check(skb, GFP_ATOMIC);
  19. if (unlikely(!skb))
  20. return false;
  21. skb->dev = vlan_dev;
  22. skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
  23. skb->vlan_tci = 0;
  24. rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_pcpu_stats);
  25. u64_stats_update_begin(&rx_stats->syncp);
  26. rx_stats->rx_packets++;
  27. rx_stats->rx_bytes += skb->len;
  28. switch (skb->pkt_type) {
  29. case PACKET_BROADCAST:
  30. break;
  31. case PACKET_MULTICAST:
  32. rx_stats->rx_multicast++;
  33. break;
  34. case PACKET_OTHERHOST:
  35. /* Our lower layer thinks this is not local, let's make sure.
  36. * This allows the VLAN to have a different MAC than the
  37. * underlying device, and still route correctly. */
  38. if (!compare_ether_addr(eth_hdr(skb)->h_dest,
  39. vlan_dev->dev_addr))
  40. skb->pkt_type = PACKET_HOST;
  41. break;
  42. }
  43. u64_stats_update_end(&rx_stats->syncp);
  44. return true;
  45. }
  46. struct net_device *vlan_dev_real_dev(const struct net_device *dev)
  47. {
  48. return vlan_dev_info(dev)->real_dev;
  49. }
  50. EXPORT_SYMBOL(vlan_dev_real_dev);
  51. u16 vlan_dev_vlan_id(const struct net_device *dev)
  52. {
  53. return vlan_dev_info(dev)->vlan_id;
  54. }
  55. EXPORT_SYMBOL(vlan_dev_vlan_id);
  56. /* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */
  57. int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
  58. u16 vlan_tci, int polling)
  59. {
  60. __vlan_hwaccel_put_tag(skb, vlan_tci);
  61. return polling ? netif_receive_skb(skb) : netif_rx(skb);
  62. }
  63. EXPORT_SYMBOL(__vlan_hwaccel_rx);
  64. gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
  65. unsigned int vlan_tci, struct sk_buff *skb)
  66. {
  67. __vlan_hwaccel_put_tag(skb, vlan_tci);
  68. return napi_gro_receive(napi, skb);
  69. }
  70. EXPORT_SYMBOL(vlan_gro_receive);
  71. gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
  72. unsigned int vlan_tci)
  73. {
  74. __vlan_hwaccel_put_tag(napi->skb, vlan_tci);
  75. return napi_gro_frags(napi);
  76. }
  77. EXPORT_SYMBOL(vlan_gro_frags);