datapath: Add support for kernel 4.4
[cascardo/ovs.git] / datapath / linux / compat / gso.c
1 /*
2  * Copyright (c) 2007-2013 Nicira, Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of version 2 of the GNU General Public
6  * License as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16  * 02110-1301, USA
17  */
18
19 #include <linux/version.h>
20
21 #include <linux/module.h>
22 #include <linux/if.h>
23 #include <linux/if_tunnel.h>
24 #include <linux/if_vlan.h>
25 #include <linux/icmp.h>
26 #include <linux/in.h>
27 #include <linux/ip.h>
28 #include <linux/ipv6.h>
29 #include <linux/kernel.h>
30 #include <linux/kmod.h>
31 #include <linux/netdevice.h>
32 #include <linux/skbuff.h>
33 #include <linux/spinlock.h>
34
35 #include <net/gre.h>
36 #include <net/icmp.h>
37 #include <net/mpls.h>
38 #include <net/protocol.h>
39 #include <net/route.h>
40 #include <net/xfrm.h>
41
42 #include "gso.h"
43
44 #ifdef OVS_USE_COMPAT_GSO_SEGMENTATION
45 static bool dev_supports_vlan_tx(struct net_device *dev)
46 {
47 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
48         return true;
49 #elif defined(HAVE_VLAN_BUG_WORKAROUND)
50         return dev->features & NETIF_F_HW_VLAN_TX;
51 #else
52         /* Assume that the driver is buggy. */
53         return false;
54 #endif
55 }
56
57 /* Strictly this is not needed and will be optimised out
58  * as this code is guarded by if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0).
59  * It is here to make things explicit should the compatibility
60  * code be extended in some way prior extending its life-span
61  * beyond v3.19.
62  */
63 static bool supports_mpls_gso(void)
64 {
65 /* MPLS GSO was introduced in v3.11, however it was not correctly
66  * activated using mpls_features until v3.19. */
67 #ifdef OVS_USE_COMPAT_GSO_SEGMENTATION
68         return true;
69 #else
70         return false;
71 #endif
72 }
73
74 int rpl_dev_queue_xmit(struct sk_buff *skb)
75 {
76 #undef dev_queue_xmit
77         int err = -ENOMEM;
78         bool vlan, mpls;
79
80         vlan = mpls = false;
81
82         /* Avoid traversing any VLAN tags that are present to determine if
83          * the ethtype is MPLS. Instead compare the mac_len (end of L2) and
84          * skb_network_offset() (beginning of L3) whose inequality will
85          * indicate the presence of an MPLS label stack. */
86         if (skb->mac_len != skb_network_offset(skb) && !supports_mpls_gso())
87                 mpls = true;
88
89         if (skb_vlan_tag_present(skb) && !dev_supports_vlan_tx(skb->dev))
90                 vlan = true;
91
92         if (vlan || mpls) {
93                 int features;
94
95                 features = netif_skb_features(skb);
96
97                 if (vlan) {
98                         skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
99                                                         skb_vlan_tag_get(skb));
100                         if (unlikely(!skb))
101                                 return err;
102                         skb->vlan_tci = 0;
103                 }
104
105                 /* As of v3.11 the kernel provides an mpls_features field in
106                  * struct net_device which allows devices to advertise which
107                  * features its supports for MPLS. This value defaults to
108                  * NETIF_F_SG and as of v3.19.
109                  *
110                  * This compatibility code is intended for kernels older
111                  * than v3.19 that do not support MPLS GSO and do not
112                  * use mpls_features. Thus this code uses NETIF_F_SG
113                  * directly in place of mpls_features.
114                  */
115                 if (mpls)
116                         features &= NETIF_F_SG;
117
118                 if (netif_needs_gso(skb, features)) {
119                         struct sk_buff *nskb;
120
121                         nskb = skb_gso_segment(skb, features);
122                         if (!nskb) {
123                                 if (unlikely(skb_cloned(skb) &&
124                                     pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
125                                         goto drop;
126
127                                 skb_shinfo(skb)->gso_type &= ~SKB_GSO_DODGY;
128                                 goto xmit;
129                         }
130
131                         if (IS_ERR(nskb)) {
132                                 err = PTR_ERR(nskb);
133                                 goto drop;
134                         }
135                         consume_skb(skb);
136                         skb = nskb;
137
138                         do {
139                                 nskb = skb->next;
140                                 skb->next = NULL;
141                                 err = dev_queue_xmit(skb);
142                                 skb = nskb;
143                         } while (skb);
144
145                         return err;
146                 }
147         }
148 xmit:
149         return dev_queue_xmit(skb);
150
151 drop:
152         kfree_skb(skb);
153         return err;
154 }
155 EXPORT_SYMBOL_GPL(rpl_dev_queue_xmit);
156 #endif /* OVS_USE_COMPAT_GSO_SEGMENTATION */
157
158 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
159 static __be16 __skb_network_protocol(struct sk_buff *skb)
160 {
161         __be16 type = skb->protocol;
162         int vlan_depth = ETH_HLEN;
163
164         while (type == htons(ETH_P_8021Q) || type == htons(ETH_P_8021AD)) {
165                 struct vlan_hdr *vh;
166
167                 if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN)))
168                         return 0;
169
170                 vh = (struct vlan_hdr *)(skb->data + vlan_depth);
171                 type = vh->h_vlan_encapsulated_proto;
172                 vlan_depth += VLAN_HLEN;
173         }
174
175         if (eth_p_mpls(type))
176                 type = ovs_skb_get_inner_protocol(skb);
177
178         return type;
179 }
180
181 static struct sk_buff *tnl_skb_gso_segment(struct sk_buff *skb,
182                                            netdev_features_t features,
183                                            bool tx_path,
184                                            sa_family_t sa_family)
185 {
186         void *iph = skb_network_header(skb);
187         int pkt_hlen = skb_inner_network_offset(skb); /* inner l2 + tunnel hdr. */
188         int mac_offset = skb_inner_mac_offset(skb);
189         int outer_l3_offset = skb_network_offset(skb);
190         int outer_l4_offset = skb_transport_offset(skb);
191         struct sk_buff *skb1 = skb;
192         struct dst_entry *dst = skb_dst(skb);
193         struct sk_buff *segs;
194         __be16 proto = skb->protocol;
195         char cb[sizeof(skb->cb)];
196
197         OVS_GSO_CB(skb)->ipv6 = (sa_family == AF_INET6);
198         /* setup whole inner packet to get protocol. */
199         __skb_pull(skb, mac_offset);
200         skb->protocol = __skb_network_protocol(skb);
201
202         /* setup l3 packet to gso, to get around segmentation bug on older kernel.*/
203         __skb_pull(skb, (pkt_hlen - mac_offset));
204         skb_reset_mac_header(skb);
205         skb_reset_network_header(skb);
206         skb_reset_transport_header(skb);
207
208         /* From 3.9 kernel skb->cb is used by skb gso. Therefore
209          * make copy of it to restore it back. */
210         memcpy(cb, skb->cb, sizeof(cb));
211
212         /* We are handling offloads by segmenting l3 packet, so
213          * no need to call OVS compat segmentation function. */
214
215 #ifdef HAVE___SKB_GSO_SEGMENT
216 #undef __skb_gso_segment
217         segs = __skb_gso_segment(skb, 0, tx_path);
218 #else
219 #undef skb_gso_segment
220         segs = skb_gso_segment(skb, 0);
221 #endif
222
223         if (!segs || IS_ERR(segs))
224                 goto free;
225
226         skb = segs;
227         while (skb) {
228                 __skb_push(skb, pkt_hlen);
229                 skb_reset_mac_header(skb);
230                 skb_set_network_header(skb, outer_l3_offset);
231                 skb_set_transport_header(skb, outer_l4_offset);
232                 skb->mac_len = 0;
233
234                 memcpy(skb_network_header(skb), iph, pkt_hlen);
235                 memcpy(skb->cb, cb, sizeof(cb));
236
237                 skb->protocol = proto;
238                 if (skb->next)
239                         dst = dst_clone(dst);
240
241                 skb_dst_set(skb, dst);
242                 OVS_GSO_CB(skb)->fix_segment(skb);
243
244                 skb = skb->next;
245         }
246 free:
247         consume_skb(skb1);
248         return segs;
249 }
250
251 static int output_ip(struct sk_buff *skb)
252 {
253         int ret = NETDEV_TX_OK;
254         int err;
255
256         memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
257
258 #undef ip_local_out
259         err = ip_local_out(skb);
260         if (unlikely(net_xmit_eval(err)))
261                 ret = err;
262
263         return ret;
264 }
265
266 int rpl_ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
267 {
268         int ret = NETDEV_TX_OK;
269         int id = -1;
270
271         if (!OVS_GSO_CB(skb)->fix_segment)
272                 return output_ip(skb);
273
274         if (skb_is_gso(skb)) {
275                 struct iphdr *iph;
276
277                 iph = ip_hdr(skb);
278                 id = ntohs(iph->id);
279                 skb = tnl_skb_gso_segment(skb, 0, false, AF_INET);
280                 if (!skb || IS_ERR(skb))
281                         return 0;
282         }  else if (skb->ip_summed == CHECKSUM_PARTIAL) {
283                 int err;
284
285                 err = skb_checksum_help(skb);
286                 if (unlikely(err))
287                         return 0;
288         }
289
290         while (skb) {
291                 struct sk_buff *next_skb = skb->next;
292                 struct iphdr *iph;
293
294                 skb->next = NULL;
295
296                 iph = ip_hdr(skb);
297                 if (id >= 0)
298                         iph->id = htons(id++);
299
300                 ret = output_ip(skb);
301                 skb = next_skb;
302         }
303         return ret;
304 }
305 EXPORT_SYMBOL_GPL(rpl_ip_local_out);
306
307 static int output_ipv6(struct sk_buff *skb)
308 {
309         int ret = NETDEV_TX_OK;
310         int err;
311
312         memset(IP6CB(skb), 0, sizeof (*IP6CB(skb)));
313 #undef ip6_local_out
314         err = ip6_local_out(skb);
315         if (unlikely(net_xmit_eval(err)))
316                 ret = err;
317
318         return ret;
319 }
320
321 int rpl_ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
322 {
323         int ret = NETDEV_TX_OK;
324
325         if (!OVS_GSO_CB(skb)->fix_segment)
326                 return output_ipv6(skb);
327
328         if (skb_is_gso(skb)) {
329                 skb = tnl_skb_gso_segment(skb, 0, false, AF_INET6);
330                 if (!skb || IS_ERR(skb))
331                         return 0;
332         }  else if (skb->ip_summed == CHECKSUM_PARTIAL) {
333                 int err;
334
335                 err = skb_checksum_help(skb);
336                 if (unlikely(err))
337                         return 0;
338         }
339
340         while (skb) {
341                 struct sk_buff *next_skb = skb->next;
342
343                 skb->next = NULL;
344                 ret = output_ipv6(skb);
345                 skb = next_skb;
346         }
347         return ret;
348 }
349 EXPORT_SYMBOL_GPL(rpl_ip6_local_out);
350 #endif /* 3.18 */