datapath: compat: introduce ovs_iptunnel_handle_offloads()
[cascardo/ovs.git] / datapath / vport-geneve.c
1 /*
2  * Copyright (c) 2014 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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21 #include <linux/version.h>
22
23 #include <linux/in.h>
24 #include <linux/ip.h>
25 #include <linux/net.h>
26 #include <linux/rculist.h>
27 #include <linux/udp.h>
28
29 #include <net/geneve.h>
30 #include <net/icmp.h>
31 #include <net/ip.h>
32 #include <net/route.h>
33 #include <net/udp.h>
34 #include <net/xfrm.h>
35
36 #include "datapath.h"
37 #include "gso.h"
38 #include "vport.h"
39
40 /*
41  * Geneve Header:
42  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43  *  |Ver|  Opt Len  |O|C|    Rsvd.  |          Protocol Type        |
44  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45  *  |        Virtual Network Identifier (VNI)       |    Reserved   |
46  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47  *  |                    Variable Length Options                    |
48  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49  *
50  * Option Header:
51  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52  *  |          Option Class         |      Type     |R|R|R| Length  |
53  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54  *  |                      Variable Option Data                     |
55  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56  */
57
58 struct genevehdr {
59 #ifdef __LITTLE_ENDIAN_BITFIELD
60         u8 opt_len:6;
61         u8 ver:2;
62         u8 rsvd1:6;
63         u8 critical:1;
64         u8 oam:1;
65 #else
66         u8 ver:2;
67         u8 opt_len:6;
68         u8 oam:1;
69         u8 critical:1;
70         u8 rsvd1:6;
71 #endif
72         __be16 proto_type;
73         u8 vni[3];
74         u8 rsvd2;
75         struct geneve_opt options[];
76 };
77
78 #define GENEVE_VER 0
79
80 #define GENEVE_BASE_HLEN (sizeof(struct udphdr) + sizeof(struct genevehdr))
81
82 /**
83  * struct geneve_port - Keeps track of open UDP ports
84  * @sock: The socket created for this port number.
85  * @name: vport name.
86  */
87 struct geneve_port {
88         struct socket *sock;
89         char name[IFNAMSIZ];
90 };
91
92 static LIST_HEAD(geneve_ports);
93
94 static inline struct geneve_port *geneve_vport(const struct vport *vport)
95 {
96         return vport_priv(vport);
97 }
98
99 static inline struct genevehdr *geneve_hdr(const struct sk_buff *skb)
100 {
101         return (struct genevehdr *)(udp_hdr(skb) + 1);
102 }
103
104 /* Convert 64 bit tunnel ID to 24 bit VNI. */
105 static void tunnel_id_to_vni(__be64 tun_id, __u8 *vni)
106 {
107 #ifdef __BIG_ENDIAN
108         vni[0] = (__force __u8)(tun_id >> 16);
109         vni[1] = (__force __u8)(tun_id >> 8);
110         vni[2] = (__force __u8)tun_id;
111 #else
112         vni[0] = (__force __u8)((__force u64)tun_id >> 40);
113         vni[1] = (__force __u8)((__force u64)tun_id >> 48);
114         vni[2] = (__force __u8)((__force u64)tun_id >> 56);
115 #endif
116 }
117
118 /* Convert 24 bit VNI to 64 bit tunnel ID. */
119 static __be64 vni_to_tunnel_id(const __u8 *vni)
120 {
121 #ifdef __BIG_ENDIAN
122         return (vni[0] << 16) | (vni[1] << 8) | vni[2];
123 #else
124         return (__force __be64)(((__force u64)vni[0] << 40) |
125                                 ((__force u64)vni[1] << 48) |
126                                 ((__force u64)vni[2] << 56));
127 #endif
128 }
129
130 static void geneve_build_header(const struct vport *vport,
131                               struct sk_buff *skb)
132 {
133         struct geneve_port *geneve_port = geneve_vport(vport);
134         struct net *net = ovs_dp_get_net(vport->dp);
135         struct udphdr *udph = udp_hdr(skb);
136         struct genevehdr *geneveh = (struct genevehdr *)(udph + 1);
137         const struct ovs_tunnel_info *tun_info = OVS_CB(skb)->egress_tun_info;
138
139         udph->dest = inet_sport(geneve_port->sock->sk);
140         udph->source = udp_flow_src_port(net, skb, 0, 0, true);
141         udph->check = 0;
142         udph->len = htons(skb->len - skb_transport_offset(skb));
143
144         geneveh->ver = GENEVE_VER;
145         geneveh->opt_len = tun_info->options_len / 4;
146         geneveh->oam = !!(tun_info->tunnel.tun_flags & TUNNEL_OAM);
147         geneveh->critical = !!(tun_info->tunnel.tun_flags & TUNNEL_CRIT_OPT);
148         geneveh->rsvd1 = 0;
149         geneveh->proto_type = htons(ETH_P_TEB);
150         tunnel_id_to_vni(tun_info->tunnel.tun_id, geneveh->vni);
151         geneveh->rsvd2 = 0;
152
153         memcpy(geneveh->options, tun_info->options, tun_info->options_len);
154 }
155
156 static int geneve_rcv(struct sock *sk, struct sk_buff *skb)
157 {
158         struct geneve_port *geneve_port;
159         struct genevehdr *geneveh;
160         int opts_len;
161         struct ovs_tunnel_info tun_info;
162         __be64 key;
163         __be16 flags;
164
165 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
166         if (unlikely(udp_lib_checksum_complete(skb)))
167                 goto error;
168 #endif
169
170         if (unlikely(!pskb_may_pull(skb, GENEVE_BASE_HLEN)))
171                 goto error;
172
173         geneveh = geneve_hdr(skb);
174
175         if (unlikely(geneveh->ver != GENEVE_VER))
176                 goto error;
177
178         if (unlikely(geneveh->proto_type != htons(ETH_P_TEB)))
179                 goto error;
180
181         geneve_port = rcu_dereference_sk_user_data(sk);
182         if (unlikely(!geneve_port))
183                 goto error;
184
185         opts_len = geneveh->opt_len * 4;
186         if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len,
187                                  htons(ETH_P_TEB)))
188                 goto error;
189
190         geneveh = geneve_hdr(skb);
191
192         flags = TUNNEL_KEY | TUNNEL_OPTIONS_PRESENT |
193                 (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0) |
194                 (geneveh->oam ? TUNNEL_OAM : 0) |
195                 (geneveh->critical ? TUNNEL_CRIT_OPT : 0);
196
197         key = vni_to_tunnel_id(geneveh->vni);
198         ovs_flow_tun_info_init(&tun_info, ip_hdr(skb),
199                                 udp_hdr(skb)->source, udp_hdr(skb)->dest,
200                                 key, flags,
201                                 geneveh->options, opts_len);
202
203         ovs_vport_receive(vport_from_priv(geneve_port), skb, &tun_info);
204         goto out;
205
206 error:
207         kfree_skb(skb);
208 out:
209         return 0;
210 }
211
212 /* Arbitrary value.  Irrelevant as long as it's not 0 since we set the handler. */
213 #define UDP_ENCAP_GENEVE 1
214 static int geneve_socket_init(struct geneve_port *geneve_port, struct net *net,
215                               __be16 dst_port)
216 {
217         struct sockaddr_in sin;
218         int err;
219
220         err = sock_create_kern(AF_INET, SOCK_DGRAM, 0,
221                                &geneve_port->sock);
222         if (err)
223                 goto error;
224
225         /* release net ref. */
226         sk_change_net(geneve_port->sock->sk, net);
227
228         sin.sin_family = AF_INET;
229         sin.sin_addr.s_addr = htonl(INADDR_ANY);
230         sin.sin_port = dst_port;
231
232         err = kernel_bind(geneve_port->sock,
233                           (struct sockaddr *)&sin, sizeof(struct sockaddr_in));
234         if (err)
235                 goto error_sock;
236
237         rcu_assign_sk_user_data(geneve_port->sock->sk, geneve_port);
238         udp_sk(geneve_port->sock->sk)->encap_type = UDP_ENCAP_GENEVE;
239         udp_sk(geneve_port->sock->sk)->encap_rcv = geneve_rcv;
240
241         udp_encap_enable();
242
243         return 0;
244
245 error_sock:
246         sk_release_kernel(geneve_port->sock->sk);
247 error:
248         pr_warn("cannot register geneve protocol handler: %d\n", err);
249         return err;
250 }
251
252 static int geneve_get_options(const struct vport *vport,
253                               struct sk_buff *skb)
254 {
255         struct geneve_port *geneve_port = geneve_vport(vport);
256
257         if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT,
258                         ntohs(inet_sport(geneve_port->sock->sk))))
259                 return -EMSGSIZE;
260         return 0;
261 }
262
263 static void geneve_tnl_destroy(struct vport *vport)
264 {
265         struct geneve_port *geneve_port = geneve_vport(vport);
266
267         /* Release socket */
268         rcu_assign_sk_user_data(geneve_port->sock->sk, NULL);
269         sk_release_kernel(geneve_port->sock->sk);
270
271         ovs_vport_deferred_free(vport);
272 }
273
274 static struct vport *geneve_tnl_create(const struct vport_parms *parms)
275 {
276         struct net *net = ovs_dp_get_net(parms->dp);
277         struct nlattr *options = parms->options;
278         struct geneve_port *geneve_port;
279         struct vport *vport;
280         struct nlattr *a;
281         int err;
282         u16 dst_port;
283
284         if (!options) {
285                 err = -EINVAL;
286                 goto error;
287         }
288
289         a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT);
290         if (a && nla_len(a) == sizeof(u16)) {
291                 dst_port = nla_get_u16(a);
292         } else {
293                 /* Require destination port from userspace. */
294                 err = -EINVAL;
295                 goto error;
296         }
297
298         vport = ovs_vport_alloc(sizeof(struct geneve_port),
299                                 &ovs_geneve_vport_ops, parms);
300         if (IS_ERR(vport))
301                 return vport;
302
303         geneve_port = geneve_vport(vport);
304         strncpy(geneve_port->name, parms->name, IFNAMSIZ);
305
306         err = geneve_socket_init(geneve_port, net, htons(dst_port));
307         if (err)
308                 goto error_free;
309
310         return vport;
311
312 error_free:
313         ovs_vport_free(vport);
314 error:
315         return ERR_PTR(err);
316 }
317
318 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)
319
320 static void geneve_fix_segment(struct sk_buff *skb)
321 {
322         struct udphdr *udph = udp_hdr(skb);
323
324         udph->len = htons(skb->len - skb_transport_offset(skb));
325 }
326
327 static struct sk_buff *handle_offloads(struct sk_buff *skb)
328 {
329         return ovs_iptunnel_handle_offloads(skb, false, geneve_fix_segment);
330 }
331 #else
332
333 static struct sk_buff *handle_offloads(struct sk_buff *skb)
334 {
335         int err = 0;
336
337         if (skb_is_gso(skb)) {
338
339                 if (skb_is_encapsulated(skb)) {
340                         err = -ENOSYS;
341                         goto error;
342                 }
343
344                 err = skb_unclone(skb, GFP_ATOMIC);
345                 if (unlikely(err))
346                         goto error;
347
348                 skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
349         } else if (skb->ip_summed != CHECKSUM_PARTIAL)
350                 skb->ip_summed = CHECKSUM_NONE;
351
352         skb->encapsulation = 1;
353         return skb;
354 error:
355         kfree_skb(skb);
356         return ERR_PTR(err);
357 }
358 #endif
359
360 static int geneve_send(struct vport *vport, struct sk_buff *skb)
361 {
362         struct ovs_key_ipv4_tunnel *tun_key;
363         int network_offset = skb_network_offset(skb);
364         struct rtable *rt;
365         int min_headroom;
366         __be32 saddr;
367         __be16 df;
368         int sent_len;
369         int err;
370
371         if (unlikely(!OVS_CB(skb)->egress_tun_info))
372                 return -EINVAL;
373
374         tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
375
376         /* Route lookup */
377         saddr = tun_key->ipv4_src;
378         rt = find_route(ovs_dp_get_net(vport->dp),
379                         &saddr, tun_key->ipv4_dst,
380                         IPPROTO_UDP, tun_key->ipv4_tos,
381                         skb->mark);
382         if (IS_ERR(rt)) {
383                 err = PTR_ERR(rt);
384                 goto error;
385         }
386
387         min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
388                         + GENEVE_BASE_HLEN
389                         + OVS_CB(skb)->egress_tun_info->options_len
390                         + sizeof(struct iphdr)
391                         + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
392
393         if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
394                 int head_delta = SKB_DATA_ALIGN(min_headroom -
395                                                 skb_headroom(skb) +
396                                                 16);
397
398                 err = pskb_expand_head(skb, max_t(int, head_delta, 0),
399                                         0, GFP_ATOMIC);
400                 if (unlikely(err))
401                         goto err_free_rt;
402         }
403
404         if (vlan_tx_tag_present(skb)) {
405                 if (unlikely(!__vlan_put_tag(skb,
406                                              skb->vlan_proto,
407                                              vlan_tx_tag_get(skb)))) {
408                         err = -ENOMEM;
409                         goto err_free_rt;
410                 }
411                 vlan_set_tci(skb, 0);
412         }
413
414         skb_reset_inner_headers(skb);
415
416         __skb_push(skb, GENEVE_BASE_HLEN +
417                         OVS_CB(skb)->egress_tun_info->options_len);
418         skb_reset_transport_header(skb);
419
420         geneve_build_header(vport, skb);
421
422         /* Offloading */
423         skb = handle_offloads(skb);
424         if (IS_ERR(skb)) {
425                 err = 0;
426                 goto err_free_rt;
427         }
428
429         df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
430
431         sent_len = iptunnel_xmit(skb->sk, rt, skb,
432                              saddr, tun_key->ipv4_dst,
433                              IPPROTO_UDP, tun_key->ipv4_tos,
434                              tun_key->ipv4_ttl,
435                              df, false);
436
437         return sent_len > 0 ? sent_len + network_offset : sent_len;
438
439 err_free_rt:
440         ip_rt_put(rt);
441 error:
442         return err;
443 }
444
445 static const char *geneve_get_name(const struct vport *vport)
446 {
447         struct geneve_port *geneve_port = geneve_vport(vport);
448         return geneve_port->name;
449 }
450
451 static int geneve_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
452                                       struct ovs_tunnel_info *egress_tun_info)
453 {
454         struct geneve_port *geneve_port = geneve_vport(vport);
455         struct net *net = ovs_dp_get_net(vport->dp);
456
457         /*
458          * Get tp_src and tp_dst, refert to geneve_build_header().
459          */
460         return ovs_tunnel_get_egress_info(egress_tun_info,
461                                           ovs_dp_get_net(vport->dp),
462                                           OVS_CB(skb)->egress_tun_info,
463                                           IPPROTO_UDP, skb->mark,
464                                           udp_flow_src_port(net, skb, 0, 0, true),
465                                           inet_sport(geneve_port->sock->sk));
466
467 }
468
469 const struct vport_ops ovs_geneve_vport_ops = {
470         .type                   = OVS_VPORT_TYPE_GENEVE,
471         .create                 = geneve_tnl_create,
472         .destroy                = geneve_tnl_destroy,
473         .get_name               = geneve_get_name,
474         .get_options            = geneve_get_options,
475         .send                   = geneve_send,
476         .get_egress_tun_info    = geneve_get_egress_tun_info,
477 };