datapath: Support for Linux kernel 3.10
[cascardo/ovs.git] / datapath / linux / compat / include / linux / if_vlan.h
1 #ifndef __LINUX_IF_VLAN_WRAPPER_H
2 #define __LINUX_IF_VLAN_WRAPPER_H 1
3
4 #include <linux/skbuff.h>
5 #include <linux/version.h>
6 #include_next <linux/if_vlan.h>
7
8 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
9 /*
10  * The behavior of __vlan_put_tag() has changed over time:
11  *
12  *      - In 2.6.26 and earlier, it adjusted both MAC and network header
13  *        pointers.  (The latter didn't make any sense.)
14  *
15  *      - In 2.6.27 and 2.6.28, it did not adjust any header pointers at all.
16  *
17  *      - In 2.6.29 and later, it adjusts the MAC header pointer only.
18  *
19  * This is the version from 2.6.33.  We unconditionally substitute this version
20  * to avoid the need to guess whether the version in the kernel tree is
21  * acceptable.
22  */
23 #define __vlan_put_tag(skb, proto, tag)  rpl__vlan_put_tag(skb, tag)
24
25 static inline struct sk_buff *rpl__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
26 {
27         struct vlan_ethhdr *veth;
28
29         if (skb_cow_head(skb, VLAN_HLEN) < 0) {
30                 kfree_skb(skb);
31                 return NULL;
32         }
33         veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
34
35         /* Move the mac addresses to the beginning of the new header. */
36         memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
37         skb->mac_header -= VLAN_HLEN;
38
39         /* first, the ethernet type */
40         veth->h_vlan_proto = htons(ETH_P_8021Q);
41
42         /* now, the TCI */
43         veth->h_vlan_TCI = htons(vlan_tci);
44
45         skb->protocol = htons(ETH_P_8021Q);
46
47         return skb;
48 }
49
50 static inline struct sk_buff *rpl___vlan_hwaccel_put_tag(struct sk_buff *skb,
51                                                      __be16 vlan_proto,
52                                                      u16 vlan_tci)
53 {
54         return __vlan_hwaccel_put_tag(skb, vlan_tci);
55 }
56
57 #define __vlan_hwaccel_put_tag rpl___vlan_hwaccel_put_tag
58
59 #endif
60
61 /* All of these were introduced in a single commit preceding 2.6.33, so
62  * presumably all of them or none of them are present. */
63 #ifndef VLAN_PRIO_MASK
64 #define VLAN_PRIO_MASK          0xe000 /* Priority Code Point */
65 #define VLAN_PRIO_SHIFT         13
66 #define VLAN_CFI_MASK           0x1000 /* Canonical Format Indicator */
67 #define VLAN_TAG_PRESENT        VLAN_CFI_MASK
68 #endif
69
70 #ifndef HAVE_VLAN_SET_ENCAP_PROTO
71 static inline void vlan_set_encap_proto(struct sk_buff *skb, struct vlan_hdr *vhdr)
72 {
73         __be16 proto;
74         unsigned char *rawp;
75
76         /*
77          * Was a VLAN packet, grab the encapsulated protocol, which the layer
78          * three protocols care about.
79          */
80
81         proto = vhdr->h_vlan_encapsulated_proto;
82         if (ntohs(proto) >= 1536) {
83                 skb->protocol = proto;
84                 return;
85         }
86
87         rawp = skb->data;
88         if (*(unsigned short *) rawp == 0xFFFF)
89                 /*
90                  * This is a magic hack to spot IPX packets. Older Novell
91                  * breaks the protocol design and runs IPX over 802.3 without
92                  * an 802.2 LLC layer. We look for FFFF which isn't a used
93                  * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
94                  * but does for the rest.
95                  */
96                 skb->protocol = htons(ETH_P_802_3);
97         else
98                 /*
99                  * Real 802.2 LLC
100                  */
101                 skb->protocol = htons(ETH_P_802_2);
102 }
103 #endif
104 #endif  /* linux/if_vlan.h wrapper */