1 #ifndef __LINUX_IF_VLAN_WRAPPER_H
2 #define __LINUX_IF_VLAN_WRAPPER_H 1
4 #include_next <linux/if_vlan.h>
7 #include <linux/skbuff.h>
8 #include <linux/if_vlan.h>
9 #include <linux/version.h>
11 static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
13 return (struct vlan_ethhdr *)skb_mac_header(skb);
16 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,26)
17 static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, unsigned short tag)
19 struct vlan_ethhdr *veth;
21 if (skb_headroom(skb) < VLAN_HLEN) {
22 struct sk_buff *sk_tmp = skb;
23 skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
26 printk(KERN_ERR "vlan: failed to realloc headroom\n");
30 skb = skb_unshare(skb, GFP_ATOMIC);
32 printk(KERN_ERR "vlan: failed to unshare skbuff\n");
37 veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
39 /* Move the mac addresses to the beginning of the new header. */
40 memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
42 /* first, the ethernet type */
43 veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
46 veth->h_vlan_TCI = htons(tag);
48 skb_reset_mac_header(skb);
55 #define vlan_put_tag(x,y) fix_vlan_put_tag((x),(y));
57 /* For some reason, older versions of vlan_put_tag do not adjust the
58 * pointer to the beginning of the MAC header. We get around that by
60 static inline struct sk_buff *fix_vlan_put_tag(struct sk_buff *skb, unsigned short tag)
62 skb = (vlan_put_tag)(skb, tag);
63 skb_reset_mac_header(skb);