Initial import
[sliver-openvswitch.git] / datapath / linux-2.4 / compat-2.4 / 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 #ifdef __KERNEL__
7 #include <linux/skbuff.h>
8 #include <linux/if_vlan.h>
9 #include <linux/version.h>
10
11 static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
12 {
13         return (struct vlan_ethhdr *)skb_mac_header(skb);
14 }
15
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)
18 {
19         struct vlan_ethhdr *veth;
20
21         if (skb_headroom(skb) < VLAN_HLEN) {
22                 struct sk_buff *sk_tmp = skb;
23                 skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
24                 kfree_skb(sk_tmp);
25                 if (!skb) {
26                         printk(KERN_ERR "vlan: failed to realloc headroom\n");
27                         return NULL;
28                 }
29         } else {
30                 skb = skb_unshare(skb, GFP_ATOMIC);
31                 if (!skb) {
32                         printk(KERN_ERR "vlan: failed to unshare skbuff\n");
33                         return NULL;
34                 }
35         }
36
37         veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
38
39         /* Move the mac addresses to the beginning of the new header. */
40         memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
41
42         /* first, the ethernet type */
43         veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
44
45         /* now, the tag */
46         veth->h_vlan_TCI = htons(tag);
47
48         skb_reset_mac_header(skb);
49
50         return skb;
51 }
52
53 #else
54
55 #define vlan_put_tag(x,y) fix_vlan_put_tag((x),(y));
56
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
59  * this hack.  Ugh.  */
60 static inline struct sk_buff *fix_vlan_put_tag(struct sk_buff *skb, unsigned short tag)
61 {
62         skb = (vlan_put_tag)(skb, tag);
63         skb_reset_mac_header(skb);
64
65         return skb;
66 }
67 #endif
68
69 #endif
70
71 #endif