1 #ifndef __LINUX_GSO_WRAPPER_H
2 #define __LINUX_GSO_WRAPPER_H
4 #include <linux/version.h>
5 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
7 #include <linux/netdevice.h>
8 #include <linux/skbuff.h>
9 #include <net/protocol.h>
12 typedef void (*gso_fix_segment_t)(struct sk_buff *);
15 struct ovs_skb_cb dp_cb;
16 gso_fix_segment_t fix_segment;
17 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
18 __be16 inner_protocol;
20 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
21 unsigned int inner_mac_header;
23 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
24 unsigned int inner_network_header;
27 #define OVS_GSO_CB(skb) ((struct ovs_gso_cb *)(skb)->cb)
29 static inline void skb_clear_ovs_gso_cb(struct sk_buff *skb)
31 OVS_GSO_CB(skb)->fix_segment = NULL;
34 static inline void skb_clear_ovs_gso_cb(struct sk_buff *skb)
40 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
41 static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
43 return skb->head + OVS_GSO_CB(skb)->inner_mac_header;
46 static inline void skb_set_inner_mac_header(const struct sk_buff *skb,
49 OVS_GSO_CB(skb)->inner_mac_header = (skb->data - skb->head) + offset;
53 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
54 static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
56 return skb->head + OVS_GSO_CB(skb)->inner_network_header;
59 static inline int skb_inner_network_offset(const struct sk_buff *skb)
61 return skb_inner_network_header(skb) - skb->data;
64 /* We don't actually store the transport offset on backports because
65 * we don't use it anywhere. Slightly rename this version to avoid
66 * future users from picking it up accidentially.
68 static inline int ovs_skb_inner_transport_offset(const struct sk_buff *skb)
73 static inline void skb_set_inner_network_header(const struct sk_buff *skb,
76 OVS_GSO_CB(skb)->inner_network_header = (skb->data - skb->head)
80 static inline void skb_set_inner_transport_header(const struct sk_buff *skb,
86 static inline int ovs_skb_inner_transport_offset(const struct sk_buff *skb)
88 return skb_inner_transport_header(skb) - skb->data;
93 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
94 static inline void ovs_skb_init_inner_protocol(struct sk_buff *skb) {
95 OVS_GSO_CB(skb)->inner_protocol = htons(0);
98 static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
100 OVS_GSO_CB(skb)->inner_protocol = ethertype;
103 static inline __be16 ovs_skb_get_inner_protocol(struct sk_buff *skb)
105 return OVS_GSO_CB(skb)->inner_protocol;
110 static inline void ovs_skb_init_inner_protocol(struct sk_buff *skb) {
111 /* Nothing to do. The inner_protocol is either zero or
112 * has been set to a value by another user.
113 * Either way it may be considered initialised.
117 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
118 static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
121 skb->inner_protocol = ethertype;
124 static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
127 skb_set_inner_protocol(skb, ethertype);
131 static inline __be16 ovs_skb_get_inner_protocol(struct sk_buff *skb)
133 return skb->inner_protocol;
137 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
138 #define ip_local_out rpl_ip_local_out
139 int rpl_ip_local_out(struct sk_buff *skb);
141 static inline int skb_inner_mac_offset(const struct sk_buff *skb)
143 return skb_inner_mac_header(skb) - skb->data;
146 #define skb_reset_inner_headers rpl_skb_reset_inner_headers
147 static inline void skb_reset_inner_headers(struct sk_buff *skb)
149 BUILD_BUG_ON(sizeof(struct ovs_gso_cb) > FIELD_SIZEOF(struct sk_buff, cb));
150 skb_set_inner_mac_header(skb, skb_mac_header(skb) - skb->data);
151 skb_set_inner_network_header(skb, skb_network_offset(skb));
152 skb_set_inner_transport_header(skb, skb_transport_offset(skb));