3bede9302b580e4e7bc20a036534298cda6d16fb
[sliver-openvswitch.git] / datapath / linux-2.6 / compat-2.6 / include / linux / if_vlan.h
1 #ifndef __LINUX_IF_VLAN_WRAPPER_H
2 #define __LINUX_IF_VLAN_WRAPPER_H 1
3
4 #include_next <linux/if_vlan.h>
5
6 /*
7  * The behavior of __vlan_put_tag() has changed over time:
8  *
9  *      - In 2.6.26 and earlier, it adjusted both MAC and network header
10  *        pointers.  (The latter didn't make any sense.)
11  *
12  *      - In 2.6.27 and 2.6.28, it did not adjust any header pointers at all.
13  *
14  *      - In 2.6.29 and later, it adjusts the MAC header pointer only.
15  *
16  * This is the version from 2.6.33.  We unconditionally substitute this version
17  * to avoid the need to guess whether the version in the kernel tree is
18  * acceptable.
19  */
20 #define __vlan_put_tag rpl_vlan_put_tag
21 static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
22 {
23         struct vlan_ethhdr *veth;
24
25         if (skb_cow_head(skb, VLAN_HLEN) < 0) {
26                 kfree_skb(skb);
27                 return NULL;
28         }
29         veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
30
31         /* Move the mac addresses to the beginning of the new header. */
32         memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
33         skb->mac_header -= VLAN_HLEN;
34
35         /* first, the ethernet type */
36         veth->h_vlan_proto = htons(ETH_P_8021Q);
37
38         /* now, the TCI */
39         veth->h_vlan_TCI = htons(vlan_tci);
40
41         skb->protocol = htons(ETH_P_8021Q);
42
43         return skb;
44 }
45
46 #endif  /* linux/if_vlan.h wrapper */