vlan_core.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. stats = &dev->stats;
  40. stats->rx_packets++;
  41. stats->rx_bytes += skb->len;
  42. switch (skb->pkt_type) {
  43. case PACKET_BROADCAST:
  44. break;
  45. case PACKET_MULTICAST:
  46. stats->multicast++;
  47. break;
  48. case PACKET_OTHERHOST:
  49. /* Our lower layer thinks this is not local, let's make sure.
  50. * This allows the VLAN to have a different MAC than the
  51. * underlying device, and still route correctly. */
  52. if (!compare_ether_addr(eth_hdr(skb)->h_dest,
  53. dev->dev_addr))
  54. skb->pkt_type = PACKET_HOST;
  55. break;
  56. };
  57. return 0;
  58. }
  59. struct net_device *vlan_dev_real_dev(const struct net_device *dev)
  60. {
  61. return vlan_dev_info(dev)->real_dev;
  62. }
  63. EXPORT_SYMBOL_GPL(vlan_dev_real_dev);
  64. u16 vlan_dev_vlan_id(const struct net_device *dev)
  65. {
  66. return vlan_dev_info(dev)->vlan_id;
  67. }
  68. EXPORT_SYMBOL_GPL(vlan_dev_vlan_id);