Commit | Line | Data |
---|---|---|
7750f403 PM |
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, | |
9bb8582e | 8 | u16 vlan_tci, int polling) |
7750f403 PM |
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 | ||
bc1d0411 PM |
17 | skb->vlan_tci = vlan_tci; |
18 | netif_nit_deliver(skb); | |
19 | ||
9bb8582e | 20 | skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK); |
7750f403 PM |
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; | |
bc1d0411 | 28 | skb->vlan_tci = 0; |
7750f403 PM |
29 | |
30 | stats = &skb->dev->stats; | |
31 | stats->rx_packets++; | |
32 | stats->rx_bytes += skb->len; | |
33 | ||
9bb8582e | 34 | skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci); |
7750f403 PM |
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); | |
22d1ba74 PM |
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); |