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