1 #include <linux/skbuff.h>
2 #include <linux/netdevice.h>
3 #include <linux/if_vlan.h>
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
)
10 struct net_device_stats
*stats
;
12 if (skb_bond_should_drop(skb
)) {
13 dev_kfree_skb_any(skb
);
17 skb
->vlan_tci
= vlan_tci
;
18 netif_nit_deliver(skb
);
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
;
27 skb
->dev
->last_rx
= jiffies
;
30 stats
= &skb
->dev
->stats
;
32 stats
->rx_bytes
+= skb
->len
;
34 skb
->priority
= vlan_get_ingress_priority(skb
->dev
, vlan_tci
);
35 switch (skb
->pkt_type
) {
36 case PACKET_BROADCAST
:
38 case PACKET_MULTICAST
:
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
,
47 skb
->pkt_type
= PACKET_HOST
;
50 return (polling
? netif_receive_skb(skb
) : netif_rx(skb
));
52 EXPORT_SYMBOL(__vlan_hwaccel_rx
);
54 struct net_device
*vlan_dev_real_dev(const struct net_device
*dev
)
56 return vlan_dev_info(dev
)->real_dev
;
58 EXPORT_SYMBOL_GPL(vlan_dev_real_dev
);
60 u16
vlan_dev_vlan_id(const struct net_device
*dev
)
62 return vlan_dev_info(dev
)->vlan_id
;
64 EXPORT_SYMBOL_GPL(vlan_dev_vlan_id
);