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)
31 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
32 static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
34 return skb->head + OVS_GSO_CB(skb)->inner_mac_header;
37 static inline void skb_set_inner_mac_header(const struct sk_buff *skb,
40 OVS_GSO_CB(skb)->inner_mac_header = (skb->data - skb->head) + offset;
44 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
45 static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
47 return skb->head + OVS_GSO_CB(skb)->inner_network_header;
50 static inline int skb_inner_network_offset(const struct sk_buff *skb)
52 return skb_inner_network_header(skb) - skb->data;
55 /* We don't actually store the transport offset on backports because
56 * we don't use it anywhere. Slightly rename this version to avoid
57 * future users from picking it up accidentially.
59 static inline int ovs_skb_inner_transport_offset(const struct sk_buff *skb)
64 static inline void skb_set_inner_network_header(const struct sk_buff *skb,
67 OVS_GSO_CB(skb)->inner_network_header = (skb->data - skb->head)
71 static inline void skb_set_inner_transport_header(const struct sk_buff *skb,
77 static inline int ovs_skb_inner_transport_offset(const struct sk_buff *skb)
79 return skb_inner_transport_header(skb) - skb->data;
84 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
85 static inline void ovs_skb_init_inner_protocol(struct sk_buff *skb) {
86 OVS_GSO_CB(skb)->inner_protocol = htons(0);
89 static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
91 OVS_GSO_CB(skb)->inner_protocol = ethertype;
94 static inline __be16 ovs_skb_get_inner_protocol(struct sk_buff *skb)
96 return OVS_GSO_CB(skb)->inner_protocol;
101 static inline void ovs_skb_init_inner_protocol(struct sk_buff *skb) {
102 /* Nothing to do. The inner_protocol is either zero or
103 * has been set to a value by another user.
104 * Either way it may be considered initialised.
108 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
109 static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
112 skb->inner_protocol = ethertype;
115 static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
118 skb_set_inner_protocol(skb, ethertype);
122 static inline __be16 ovs_skb_get_inner_protocol(struct sk_buff *skb)
124 return skb->inner_protocol;
128 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
129 #define ip_local_out rpl_ip_local_out
130 int rpl_ip_local_out(struct sk_buff *skb);
132 static inline int skb_inner_mac_offset(const struct sk_buff *skb)
134 return skb_inner_mac_header(skb) - skb->data;
137 #define skb_reset_inner_headers rpl_skb_reset_inner_headers
138 static inline void skb_reset_inner_headers(struct sk_buff *skb)
140 BUILD_BUG_ON(sizeof(struct ovs_gso_cb) > FIELD_SIZEOF(struct sk_buff, cb));
141 skb_set_inner_mac_header(skb, skb_mac_header(skb) - skb->data);
142 skb_set_inner_network_header(skb, skb_network_offset(skb));
143 skb_set_inner_transport_header(skb, skb_transport_offset(skb));