023d6d31076d96b8fbb3f08f3d68539e38181045
[cascardo/ovs.git] / datapath / linux / compat / gso.h
1 #ifndef __LINUX_GSO_WRAPPER_H
2 #define __LINUX_GSO_WRAPPER_H
3
4 #include <linux/version.h>
5 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) || \
6         !defined USE_UPSTREAM_VXLAN
7
8 #include <linux/netdevice.h>
9 #include <linux/skbuff.h>
10 #include <net/protocol.h>
11
12 #include "datapath.h"
13 typedef void (*gso_fix_segment_t)(struct sk_buff *);
14
15 struct ovs_gso_cb {
16         struct ovs_skb_cb dp_cb;
17         gso_fix_segment_t fix_segment;
18         sk_buff_data_t  inner_mac_header;       /* Offset from skb->head */
19 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
20         __be16          inner_protocol;
21 #endif
22         u16             inner_network_header;   /* Offset from
23                                                  * inner_mac_header */
24 };
25 #define OVS_GSO_CB(skb) ((struct ovs_gso_cb *)(skb)->cb)
26
27 #define skb_inner_network_header rpl_skb_inner_network_header
28
29 #ifdef NET_SKBUFF_DATA_USES_OFFSET
30 #define skb_inner_mac_header rpl_skb_inner_mac_header
31 static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
32 {
33         return skb->head + OVS_GSO_CB(skb)->inner_mac_header;
34 }
35
36 #else
37
38 #define skb_inner_mac_header rpl_skb_inner_mac_header
39 static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
40 {
41         return OVS_GSO_CB(skb)->inner_mac_header;
42 }
43
44 #endif
45
46 #define skb_inner_network_header rpl_skb_inner_network_header
47 static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
48 {
49         return skb_inner_mac_header(skb) +
50                 OVS_GSO_CB(skb)->inner_network_header;
51 }
52
53 #define skb_inner_network_offset rpl_skb_inner_network_offset
54 static inline int skb_inner_network_offset(const struct sk_buff *skb)
55 {
56         return skb_inner_network_header(skb) - skb->data;
57 }
58
59 #define skb_reset_inner_headers rpl_skb_reset_inner_headers
60 static inline void skb_reset_inner_headers(struct sk_buff *skb)
61 {
62         BUILD_BUG_ON(sizeof(struct ovs_gso_cb) > FIELD_SIZEOF(struct sk_buff, cb));
63         OVS_GSO_CB(skb)->inner_network_header = skb->network_header -
64                 skb->mac_header;
65         OVS_GSO_CB(skb)->inner_mac_header = skb->mac_header;
66
67         OVS_GSO_CB(skb)->fix_segment = NULL;
68 }
69
70 struct sk_buff *ovs_iptunnel_handle_offloads(struct sk_buff *skb,
71                                              bool csum_help,
72                                              gso_fix_segment_t fix_segment);
73
74
75 #endif /* 3.12 || !USE_UPSTREAM_VXLAN */
76
77 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
78 #define ip_local_out rpl_ip_local_out
79 int ip_local_out(struct sk_buff *skb);
80
81 #define skb_inner_mac_offset rpl_skb_inner_mac_offset
82 static inline int skb_inner_mac_offset(const struct sk_buff *skb)
83 {
84         return skb_inner_mac_header(skb) - skb->data;
85 }
86 #endif /* 3.16 */
87
88 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
89 static inline void ovs_skb_init_inner_protocol(struct sk_buff *skb) {
90         OVS_GSO_CB(skb)->inner_protocol = htons(0);
91 }
92
93 static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
94                                               __be16 ethertype) {
95         OVS_GSO_CB(skb)->inner_protocol = ethertype;
96 }
97
98 static inline __be16 ovs_skb_get_inner_protocol(struct sk_buff *skb)
99 {
100         return OVS_GSO_CB(skb)->inner_protocol;
101 }
102
103 #else
104
105 static inline void ovs_skb_init_inner_protocol(struct sk_buff *skb) {
106         /* Nothing to do. The inner_protocol is either zero or
107          * has been set to a value by another user.
108          * Either way it may be considered initialised.
109          */
110 }
111
112 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
113 static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
114                                               __be16 ethertype)
115 {
116         skb->inner_protocol = ethertype;
117 }
118 #else
119 static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
120                                               __be16 ethertype)
121 {
122         skb_set_inner_protocol(skb, ethertype);
123 }
124 #endif
125
126 static inline __be16 ovs_skb_get_inner_protocol(struct sk_buff *skb)
127 {
128         return skb->inner_protocol;
129 }
130 #endif /* 3.11 */
131 #endif