vlan_core.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include <linux/skbuff.h>
  2. #include <linux/netdevice.h>
  3. #include <linux/if_vlan.h>
  4. #include "vlan.h"
  5. struct vlan_hwaccel_cb {
  6. struct net_device *dev;
  7. };
  8. static inline struct vlan_hwaccel_cb *vlan_hwaccel_cb(struct sk_buff *skb)
  9. {
  10. return (struct vlan_hwaccel_cb *)skb->cb;
  11. }
  12. /* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */
  13. int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
  14. u16 vlan_tci, int polling)
  15. {
  16. struct vlan_hwaccel_cb *cb = vlan_hwaccel_cb(skb);
  17. if (skb_bond_should_drop(skb)) {
  18. dev_kfree_skb_any(skb);
  19. return NET_RX_DROP;
  20. }
  21. skb->vlan_tci = vlan_tci;
  22. cb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
  23. return (polling ? netif_receive_skb(skb) : netif_rx(skb));
  24. }
  25. EXPORT_SYMBOL(__vlan_hwaccel_rx);
  26. int vlan_hwaccel_do_receive(struct sk_buff *skb)
  27. {
  28. struct vlan_hwaccel_cb *cb = vlan_hwaccel_cb(skb);
  29. struct net_device *dev = cb->dev;
  30. struct net_device_stats *stats;
  31. netif_nit_deliver(skb);
  32. if (dev == NULL) {
  33. kfree_skb(skb);
  34. return -1;
  35. }
  36. skb->dev = dev;
  37. skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci);
  38. skb->vlan_tci = 0;
  39. dev->last_rx = jiffies;
  40. stats = &dev->stats;
  41. stats->rx_packets++;
  42. stats->rx_bytes += skb->len;
  43. switch (skb->pkt_type) {
  44. case PACKET_BROADCAST:
  45. break;
  46. case PACKET_MULTICAST:
  47. stats->multicast++;
  48. break;
  49. case PACKET_OTHERHOST:
  50. /* Our lower layer thinks this is not local, let's make sure.
  51. * This allows the VLAN to have a different MAC than the
  52. * underlying device, and still route correctly. */
  53. if (!compare_ether_addr(eth_hdr(skb)->h_dest,
  54. dev->dev_addr))
  55. skb->pkt_type = PACKET_HOST;
  56. break;
  57. };
  58. return 0;
  59. }
  60. struct net_device *vlan_dev_real_dev(const struct net_device *dev)
  61. {
  62. return vlan_dev_info(dev)->real_dev;
  63. }
  64. EXPORT_SYMBOL_GPL(vlan_dev_real_dev);
  65. u16 vlan_dev_vlan_id(const struct net_device *dev)
  66. {
  67. return vlan_dev_info(dev)->vlan_id;
  68. }
  69. EXPORT_SYMBOL_GPL(vlan_dev_vlan_id);