tunnel: test VXLAN receive and UDP checksum
[cascardo/ovs.git] / lib / netdev-vport.c
1 /*
2  * Copyright (c) 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18
19 #include "netdev-vport.h"
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <sys/socket.h>
24 #include <net/if.h>
25 #include <netinet/in.h>
26 #include <netinet/ip6.h>
27 #include <sys/ioctl.h>
28
29 #include "byte-order.h"
30 #include "csum.h"
31 #include "daemon.h"
32 #include "dirs.h"
33 #include "dpif.h"
34 #include "dp-packet.h"
35 #include "dynamic-string.h"
36 #include "flow.h"
37 #include "hash.h"
38 #include "hmap.h"
39 #include "list.h"
40 #include "netdev-provider.h"
41 #include "odp-netlink.h"
42 #include "dp-packet.h"
43 #include "ovs-router.h"
44 #include "packets.h"
45 #include "poll-loop.h"
46 #include "route-table.h"
47 #include "shash.h"
48 #include "socket-util.h"
49 #include "openvswitch/vlog.h"
50 #include "unaligned.h"
51 #include "unixctl.h"
52 #include "util.h"
53
54 VLOG_DEFINE_THIS_MODULE(netdev_vport);
55 static struct vlog_rate_limit err_rl = VLOG_RATE_LIMIT_INIT(60, 5);
56
57 #define GENEVE_DST_PORT 6081
58 #define VXLAN_DST_PORT 4789
59 #define LISP_DST_PORT 4341
60 #define STT_DST_PORT 7471
61
62 #define VXLAN_HLEN   (sizeof(struct udp_header) +         \
63                       sizeof(struct vxlanhdr))
64
65 #define GENEVE_BASE_HLEN   (sizeof(struct udp_header) +         \
66                             sizeof(struct genevehdr))
67
68 #define DEFAULT_TTL 64
69
70 struct netdev_vport {
71     struct netdev up;
72
73     /* Protects all members below. */
74     struct ovs_mutex mutex;
75
76     struct eth_addr etheraddr;
77     struct netdev_stats stats;
78
79     /* Tunnels. */
80     struct netdev_tunnel_config tnl_cfg;
81     char egress_iface[IFNAMSIZ];
82     bool carrier_status;
83
84     /* Patch Ports. */
85     char *peer;
86 };
87
88 struct vport_class {
89     const char *dpif_port;
90     struct netdev_class netdev_class;
91 };
92
93 /* Last read of the route-table's change number. */
94 static uint64_t rt_change_seqno;
95
96 static int netdev_vport_construct(struct netdev *);
97 static int get_patch_config(const struct netdev *netdev, struct smap *args);
98 static int get_tunnel_config(const struct netdev *, struct smap *args);
99 static bool tunnel_check_status_change__(struct netdev_vport *);
100
101 static uint16_t tnl_udp_port_min = 32768;
102 static uint16_t tnl_udp_port_max = 61000;
103
104 static bool
105 is_vport_class(const struct netdev_class *class)
106 {
107     return class->construct == netdev_vport_construct;
108 }
109
110 bool
111 netdev_vport_is_vport_class(const struct netdev_class *class)
112 {
113     return is_vport_class(class);
114 }
115
116 static const struct vport_class *
117 vport_class_cast(const struct netdev_class *class)
118 {
119     ovs_assert(is_vport_class(class));
120     return CONTAINER_OF(class, struct vport_class, netdev_class);
121 }
122
123 static struct netdev_vport *
124 netdev_vport_cast(const struct netdev *netdev)
125 {
126     ovs_assert(is_vport_class(netdev_get_class(netdev)));
127     return CONTAINER_OF(netdev, struct netdev_vport, up);
128 }
129
130 static const struct netdev_tunnel_config *
131 get_netdev_tunnel_config(const struct netdev *netdev)
132 {
133     return &netdev_vport_cast(netdev)->tnl_cfg;
134 }
135
136 bool
137 netdev_vport_is_patch(const struct netdev *netdev)
138 {
139     const struct netdev_class *class = netdev_get_class(netdev);
140
141     return class->get_config == get_patch_config;
142 }
143
144 bool
145 netdev_vport_is_layer3(const struct netdev *dev)
146 {
147     const char *type = netdev_get_type(dev);
148
149     return (!strcmp("lisp", type));
150 }
151
152 static bool
153 netdev_vport_needs_dst_port(const struct netdev *dev)
154 {
155     const struct netdev_class *class = netdev_get_class(dev);
156     const char *type = netdev_get_type(dev);
157
158     return (class->get_config == get_tunnel_config &&
159             (!strcmp("geneve", type) || !strcmp("vxlan", type) ||
160              !strcmp("lisp", type) || !strcmp("stt", type)) );
161 }
162
163 const char *
164 netdev_vport_class_get_dpif_port(const struct netdev_class *class)
165 {
166     return is_vport_class(class) ? vport_class_cast(class)->dpif_port : NULL;
167 }
168
169 const char *
170 netdev_vport_get_dpif_port(const struct netdev *netdev,
171                            char namebuf[], size_t bufsize)
172 {
173     const struct netdev_class *class = netdev_get_class(netdev);
174     const char *dpif_port = netdev_vport_class_get_dpif_port(class);
175
176     if (!dpif_port) {
177         return netdev_get_name(netdev);
178     }
179
180     if (netdev_vport_needs_dst_port(netdev)) {
181         const struct netdev_vport *vport = netdev_vport_cast(netdev);
182
183         /*
184          * Note: IFNAMSIZ is 16 bytes long. Implementations should choose
185          * a dpif port name that is short enough to fit including any
186          * port numbers but assert just in case.
187          */
188         BUILD_ASSERT(NETDEV_VPORT_NAME_BUFSIZE >= IFNAMSIZ);
189         ovs_assert(strlen(dpif_port) + 6 < IFNAMSIZ);
190         snprintf(namebuf, bufsize, "%s_%d", dpif_port,
191                  ntohs(vport->tnl_cfg.dst_port));
192         return namebuf;
193     } else {
194         return dpif_port;
195     }
196 }
197
198 char *
199 netdev_vport_get_dpif_port_strdup(const struct netdev *netdev)
200 {
201     char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
202
203     return xstrdup(netdev_vport_get_dpif_port(netdev, namebuf,
204                                               sizeof namebuf));
205 }
206
207 /* Whenever the route-table change number is incremented,
208  * netdev_vport_route_changed() should be called to update
209  * the corresponding tunnel interface status. */
210 static void
211 netdev_vport_route_changed(void)
212 {
213     struct netdev **vports;
214     size_t i, n_vports;
215
216     vports = netdev_get_vports(&n_vports);
217     for (i = 0; i < n_vports; i++) {
218         struct netdev *netdev_ = vports[i];
219         struct netdev_vport *netdev = netdev_vport_cast(netdev_);
220
221         ovs_mutex_lock(&netdev->mutex);
222         /* Finds all tunnel vports. */
223         if (ipv6_addr_is_set(&netdev->tnl_cfg.ipv6_dst)) {
224             if (tunnel_check_status_change__(netdev)) {
225                 netdev_change_seq_changed(netdev_);
226             }
227         }
228         ovs_mutex_unlock(&netdev->mutex);
229
230         netdev_close(netdev_);
231     }
232
233     free(vports);
234 }
235
236 static struct netdev *
237 netdev_vport_alloc(void)
238 {
239     struct netdev_vport *netdev = xzalloc(sizeof *netdev);
240     return &netdev->up;
241 }
242
243 static int
244 netdev_vport_construct(struct netdev *netdev_)
245 {
246     struct netdev_vport *dev = netdev_vport_cast(netdev_);
247     const char *type = netdev_get_type(netdev_);
248
249     ovs_mutex_init(&dev->mutex);
250     eth_addr_random(&dev->etheraddr);
251
252     /* Add a default destination port for tunnel ports if none specified. */
253     if (!strcmp(type, "geneve")) {
254         dev->tnl_cfg.dst_port = htons(GENEVE_DST_PORT);
255     } else if (!strcmp(type, "vxlan")) {
256         dev->tnl_cfg.dst_port = htons(VXLAN_DST_PORT);
257     } else if (!strcmp(type, "lisp")) {
258         dev->tnl_cfg.dst_port = htons(LISP_DST_PORT);
259     } else if (!strcmp(type, "stt")) {
260         dev->tnl_cfg.dst_port = htons(STT_DST_PORT);
261     }
262
263     dev->tnl_cfg.dont_fragment = true;
264     dev->tnl_cfg.ttl = DEFAULT_TTL;
265     return 0;
266 }
267
268 static void
269 netdev_vport_destruct(struct netdev *netdev_)
270 {
271     struct netdev_vport *netdev = netdev_vport_cast(netdev_);
272
273     free(netdev->peer);
274     ovs_mutex_destroy(&netdev->mutex);
275 }
276
277 static void
278 netdev_vport_dealloc(struct netdev *netdev_)
279 {
280     struct netdev_vport *netdev = netdev_vport_cast(netdev_);
281     free(netdev);
282 }
283
284 static int
285 netdev_vport_set_etheraddr(struct netdev *netdev_, const struct eth_addr mac)
286 {
287     struct netdev_vport *netdev = netdev_vport_cast(netdev_);
288
289     ovs_mutex_lock(&netdev->mutex);
290     netdev->etheraddr = mac;
291     ovs_mutex_unlock(&netdev->mutex);
292     netdev_change_seq_changed(netdev_);
293
294     return 0;
295 }
296
297 static int
298 netdev_vport_get_etheraddr(const struct netdev *netdev_, struct eth_addr *mac)
299 {
300     struct netdev_vport *netdev = netdev_vport_cast(netdev_);
301
302     ovs_mutex_lock(&netdev->mutex);
303     *mac = netdev->etheraddr;
304     ovs_mutex_unlock(&netdev->mutex);
305
306     return 0;
307 }
308
309 /* Checks if the tunnel status has changed and returns a boolean.
310  * Updates the tunnel status if it has changed. */
311 static bool
312 tunnel_check_status_change__(struct netdev_vport *netdev)
313     OVS_REQUIRES(netdev->mutex)
314 {
315     char iface[IFNAMSIZ];
316     bool status = false;
317     struct in6_addr *route;
318     struct in6_addr gw;
319
320     iface[0] = '\0';
321     route = &netdev->tnl_cfg.ipv6_dst;
322     if (ovs_router_lookup(route, iface, &gw)) {
323         struct netdev *egress_netdev;
324
325         if (!netdev_open(iface, "system", &egress_netdev)) {
326             status = netdev_get_carrier(egress_netdev);
327             netdev_close(egress_netdev);
328         }
329     }
330
331     if (strcmp(netdev->egress_iface, iface)
332         || netdev->carrier_status != status) {
333         ovs_strlcpy(netdev->egress_iface, iface, IFNAMSIZ);
334         netdev->carrier_status = status;
335
336         return true;
337     }
338
339     return false;
340 }
341
342 static int
343 tunnel_get_status(const struct netdev *netdev_, struct smap *smap)
344 {
345     struct netdev_vport *netdev = netdev_vport_cast(netdev_);
346
347     if (netdev->egress_iface[0]) {
348         smap_add(smap, "tunnel_egress_iface", netdev->egress_iface);
349
350         smap_add(smap, "tunnel_egress_iface_carrier",
351                  netdev->carrier_status ? "up" : "down");
352     }
353
354     return 0;
355 }
356
357 static int
358 netdev_vport_update_flags(struct netdev *netdev OVS_UNUSED,
359                           enum netdev_flags off,
360                           enum netdev_flags on OVS_UNUSED,
361                           enum netdev_flags *old_flagsp)
362 {
363     if (off & (NETDEV_UP | NETDEV_PROMISC)) {
364         return EOPNOTSUPP;
365     }
366
367     *old_flagsp = NETDEV_UP | NETDEV_PROMISC;
368     return 0;
369 }
370
371 static void
372 netdev_vport_run(void)
373 {
374     uint64_t seq;
375
376     route_table_run();
377     seq = route_table_get_change_seq();
378     if (rt_change_seqno != seq) {
379         rt_change_seqno = seq;
380         netdev_vport_route_changed();
381     }
382 }
383
384 static void
385 netdev_vport_wait(void)
386 {
387     uint64_t seq;
388
389     route_table_wait();
390     seq = route_table_get_change_seq();
391     if (rt_change_seqno != seq) {
392         poll_immediate_wake();
393     }
394 }
395 \f
396 /* Code specific to tunnel types. */
397
398 static ovs_be64
399 parse_key(const struct smap *args, const char *name,
400           bool *present, bool *flow)
401 {
402     const char *s;
403
404     *present = false;
405     *flow = false;
406
407     s = smap_get(args, name);
408     if (!s) {
409         s = smap_get(args, "key");
410         if (!s) {
411             return 0;
412         }
413     }
414
415     *present = true;
416
417     if (!strcmp(s, "flow")) {
418         *flow = true;
419         return 0;
420     } else {
421         return htonll(strtoull(s, NULL, 0));
422     }
423 }
424
425 static int
426 parse_tunnel_ip(const char *value, bool accept_mcast, bool *flow,
427                 struct in6_addr *ipv6, uint16_t *protocol)
428 {
429     if (!strcmp(value, "flow")) {
430         *flow = true;
431         *protocol = 0;
432         return 0;
433     }
434     if (addr_is_ipv6(value)) {
435         if (lookup_ipv6(value, ipv6)) {
436             return ENOENT;
437         }
438         if (!accept_mcast && ipv6_addr_is_multicast(ipv6)) {
439             return EINVAL;
440         }
441         *protocol = ETH_TYPE_IPV6;
442     } else {
443         struct in_addr ip;
444         if (lookup_ip(value, &ip)) {
445             return ENOENT;
446         }
447         if (!accept_mcast && ip_is_multicast(ip.s_addr)) {
448             return EINVAL;
449         }
450         in6_addr_set_mapped_ipv4(ipv6, ip.s_addr);
451         *protocol = ETH_TYPE_IP;
452     }
453     return 0;
454 }
455
456 static int
457 set_tunnel_config(struct netdev *dev_, const struct smap *args)
458 {
459     struct netdev_vport *dev = netdev_vport_cast(dev_);
460     const char *name = netdev_get_name(dev_);
461     const char *type = netdev_get_type(dev_);
462     bool ipsec_mech_set, needs_dst_port, has_csum;
463     uint16_t dst_proto = 0, src_proto = 0;
464     struct netdev_tunnel_config tnl_cfg;
465     struct smap_node *node;
466
467     has_csum = strstr(type, "gre") || strstr(type, "geneve") ||
468                strstr(type, "stt") || strstr(type, "vxlan");
469     ipsec_mech_set = false;
470     memset(&tnl_cfg, 0, sizeof tnl_cfg);
471
472     /* Add a default destination port for tunnel ports if none specified. */
473     if (!strcmp(type, "geneve")) {
474         tnl_cfg.dst_port = htons(GENEVE_DST_PORT);
475     }
476
477     if (!strcmp(type, "vxlan")) {
478         tnl_cfg.dst_port = htons(VXLAN_DST_PORT);
479     }
480
481     if (!strcmp(type, "lisp")) {
482         tnl_cfg.dst_port = htons(LISP_DST_PORT);
483     }
484
485     if (!strcmp(type, "stt")) {
486         tnl_cfg.dst_port = htons(STT_DST_PORT);
487     }
488
489     needs_dst_port = netdev_vport_needs_dst_port(dev_);
490     tnl_cfg.ipsec = strstr(type, "ipsec");
491     tnl_cfg.dont_fragment = true;
492
493     SMAP_FOR_EACH (node, args) {
494         if (!strcmp(node->key, "remote_ip")) {
495             int err;
496             err = parse_tunnel_ip(node->value, false, &tnl_cfg.ip_dst_flow,
497                                   &tnl_cfg.ipv6_dst, &dst_proto);
498             switch (err) {
499             case ENOENT:
500                 VLOG_WARN("%s: bad %s 'remote_ip'", name, type);
501                 break;
502             case EINVAL:
503                 VLOG_WARN("%s: multicast remote_ip=%s not allowed",
504                           name, node->value);
505                 return EINVAL;
506             }
507         } else if (!strcmp(node->key, "local_ip")) {
508             int err;
509             err = parse_tunnel_ip(node->value, true, &tnl_cfg.ip_src_flow,
510                                   &tnl_cfg.ipv6_src, &src_proto);
511             switch (err) {
512             case ENOENT:
513                 VLOG_WARN("%s: bad %s 'local_ip'", name, type);
514                 break;
515             }
516         } else if (!strcmp(node->key, "tos")) {
517             if (!strcmp(node->value, "inherit")) {
518                 tnl_cfg.tos_inherit = true;
519             } else {
520                 char *endptr;
521                 int tos;
522                 tos = strtol(node->value, &endptr, 0);
523                 if (*endptr == '\0' && tos == (tos & IP_DSCP_MASK)) {
524                     tnl_cfg.tos = tos;
525                 } else {
526                     VLOG_WARN("%s: invalid TOS %s", name, node->value);
527                 }
528             }
529         } else if (!strcmp(node->key, "ttl")) {
530             if (!strcmp(node->value, "inherit")) {
531                 tnl_cfg.ttl_inherit = true;
532             } else {
533                 tnl_cfg.ttl = atoi(node->value);
534             }
535         } else if (!strcmp(node->key, "dst_port") && needs_dst_port) {
536             tnl_cfg.dst_port = htons(atoi(node->value));
537         } else if (!strcmp(node->key, "csum") && has_csum) {
538             if (!strcmp(node->value, "true")) {
539                 tnl_cfg.csum = true;
540             }
541         } else if (!strcmp(node->key, "df_default")) {
542             if (!strcmp(node->value, "false")) {
543                 tnl_cfg.dont_fragment = false;
544             }
545         } else if (!strcmp(node->key, "peer_cert") && tnl_cfg.ipsec) {
546             if (smap_get(args, "certificate")) {
547                 ipsec_mech_set = true;
548             } else {
549                 const char *use_ssl_cert;
550
551                 /* If the "use_ssl_cert" is true, then "certificate" and
552                  * "private_key" will be pulled from the SSL table.  The
553                  * use of this option is strongly discouraged, since it
554                  * will like be removed when multiple SSL configurations
555                  * are supported by OVS.
556                  */
557                 use_ssl_cert = smap_get(args, "use_ssl_cert");
558                 if (!use_ssl_cert || strcmp(use_ssl_cert, "true")) {
559                     VLOG_ERR("%s: 'peer_cert' requires 'certificate' argument",
560                              name);
561                     return EINVAL;
562                 }
563                 ipsec_mech_set = true;
564             }
565         } else if (!strcmp(node->key, "psk") && tnl_cfg.ipsec) {
566             ipsec_mech_set = true;
567         } else if (tnl_cfg.ipsec
568                 && (!strcmp(node->key, "certificate")
569                     || !strcmp(node->key, "private_key")
570                     || !strcmp(node->key, "use_ssl_cert"))) {
571             /* Ignore options not used by the netdev. */
572         } else if (!strcmp(node->key, "key") ||
573                    !strcmp(node->key, "in_key") ||
574                    !strcmp(node->key, "out_key")) {
575             /* Handled separately below. */
576         } else if (!strcmp(node->key, "exts")) {
577             char *str = xstrdup(node->value);
578             char *ext, *save_ptr = NULL;
579
580             tnl_cfg.exts = 0;
581
582             ext = strtok_r(str, ",", &save_ptr);
583             while (ext) {
584                 if (!strcmp(type, "vxlan") && !strcmp(ext, "gbp")) {
585                     tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GBP);
586                 } else {
587                     VLOG_WARN("%s: unknown extension '%s'", name, ext);
588                 }
589
590                 ext = strtok_r(NULL, ",", &save_ptr);
591             }
592
593             free(str);
594         } else {
595             VLOG_WARN("%s: unknown %s argument '%s'", name, type, node->key);
596         }
597     }
598
599     if (tnl_cfg.ipsec) {
600         static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
601         static pid_t pid = 0;
602
603 #ifndef _WIN32
604         ovs_mutex_lock(&mutex);
605         if (pid <= 0) {
606             char *file_name = xasprintf("%s/%s", ovs_rundir(),
607                                         "ovs-monitor-ipsec.pid");
608             pid = read_pidfile(file_name);
609             free(file_name);
610         }
611         ovs_mutex_unlock(&mutex);
612 #endif
613
614         if (pid < 0) {
615             VLOG_ERR("%s: IPsec requires the ovs-monitor-ipsec daemon",
616                      name);
617             return EINVAL;
618         }
619
620         if (smap_get(args, "peer_cert") && smap_get(args, "psk")) {
621             VLOG_ERR("%s: cannot define both 'peer_cert' and 'psk'", name);
622             return EINVAL;
623         }
624
625         if (!ipsec_mech_set) {
626             VLOG_ERR("%s: IPsec requires an 'peer_cert' or psk' argument",
627                      name);
628             return EINVAL;
629         }
630     }
631
632     if (!ipv6_addr_is_set(&tnl_cfg.ipv6_dst) && !tnl_cfg.ip_dst_flow) {
633         VLOG_ERR("%s: %s type requires valid 'remote_ip' argument",
634                  name, type);
635         return EINVAL;
636     }
637     if (tnl_cfg.ip_src_flow && !tnl_cfg.ip_dst_flow) {
638         VLOG_ERR("%s: %s type requires 'remote_ip=flow' with 'local_ip=flow'",
639                  name, type);
640         return EINVAL;
641     }
642     if (src_proto && dst_proto && src_proto != dst_proto) {
643         VLOG_ERR("%s: 'remote_ip' and 'local_ip' has to be of the same address family",
644                  name);
645         return EINVAL;
646     }
647     if (!tnl_cfg.ttl) {
648         tnl_cfg.ttl = DEFAULT_TTL;
649     }
650
651     tnl_cfg.in_key = parse_key(args, "in_key",
652                                &tnl_cfg.in_key_present,
653                                &tnl_cfg.in_key_flow);
654
655     tnl_cfg.out_key = parse_key(args, "out_key",
656                                &tnl_cfg.out_key_present,
657                                &tnl_cfg.out_key_flow);
658
659     ovs_mutex_lock(&dev->mutex);
660     if (memcmp(&dev->tnl_cfg, &tnl_cfg, sizeof tnl_cfg)) {
661         dev->tnl_cfg = tnl_cfg;
662         tunnel_check_status_change__(dev);
663         netdev_change_seq_changed(dev_);
664     }
665     ovs_mutex_unlock(&dev->mutex);
666
667     return 0;
668 }
669
670 static int
671 get_tunnel_config(const struct netdev *dev, struct smap *args)
672 {
673     struct netdev_vport *netdev = netdev_vport_cast(dev);
674     struct netdev_tunnel_config tnl_cfg;
675
676     ovs_mutex_lock(&netdev->mutex);
677     tnl_cfg = netdev->tnl_cfg;
678     ovs_mutex_unlock(&netdev->mutex);
679
680     if (ipv6_addr_is_set(&tnl_cfg.ipv6_dst)) {
681         smap_add_ipv6(args, "remote_ip", &tnl_cfg.ipv6_dst);
682     } else if (tnl_cfg.ip_dst_flow) {
683         smap_add(args, "remote_ip", "flow");
684     }
685
686     if (ipv6_addr_is_set(&tnl_cfg.ipv6_src)) {
687         smap_add_ipv6(args, "local_ip", &tnl_cfg.ipv6_src);
688     } else if (tnl_cfg.ip_src_flow) {
689         smap_add(args, "local_ip", "flow");
690     }
691
692     if (tnl_cfg.in_key_flow && tnl_cfg.out_key_flow) {
693         smap_add(args, "key", "flow");
694     } else if (tnl_cfg.in_key_present && tnl_cfg.out_key_present
695                && tnl_cfg.in_key == tnl_cfg.out_key) {
696         smap_add_format(args, "key", "%"PRIu64, ntohll(tnl_cfg.in_key));
697     } else {
698         if (tnl_cfg.in_key_flow) {
699             smap_add(args, "in_key", "flow");
700         } else if (tnl_cfg.in_key_present) {
701             smap_add_format(args, "in_key", "%"PRIu64,
702                             ntohll(tnl_cfg.in_key));
703         }
704
705         if (tnl_cfg.out_key_flow) {
706             smap_add(args, "out_key", "flow");
707         } else if (tnl_cfg.out_key_present) {
708             smap_add_format(args, "out_key", "%"PRIu64,
709                             ntohll(tnl_cfg.out_key));
710         }
711     }
712
713     if (tnl_cfg.ttl_inherit) {
714         smap_add(args, "ttl", "inherit");
715     } else if (tnl_cfg.ttl != DEFAULT_TTL) {
716         smap_add_format(args, "ttl", "%"PRIu8, tnl_cfg.ttl);
717     }
718
719     if (tnl_cfg.tos_inherit) {
720         smap_add(args, "tos", "inherit");
721     } else if (tnl_cfg.tos) {
722         smap_add_format(args, "tos", "0x%x", tnl_cfg.tos);
723     }
724
725     if (tnl_cfg.dst_port) {
726         uint16_t dst_port = ntohs(tnl_cfg.dst_port);
727         const char *type = netdev_get_type(dev);
728
729         if ((!strcmp("geneve", type) && dst_port != GENEVE_DST_PORT) ||
730             (!strcmp("vxlan", type) && dst_port != VXLAN_DST_PORT) ||
731             (!strcmp("lisp", type) && dst_port != LISP_DST_PORT) ||
732             (!strcmp("stt", type) && dst_port != STT_DST_PORT)) {
733             smap_add_format(args, "dst_port", "%d", dst_port);
734         }
735     }
736
737     if (tnl_cfg.csum) {
738         smap_add(args, "csum", "true");
739     }
740
741     if (!tnl_cfg.dont_fragment) {
742         smap_add(args, "df_default", "false");
743     }
744
745     return 0;
746 }
747 \f
748 /* Code specific to patch ports. */
749
750 /* If 'netdev' is a patch port, returns the name of its peer as a malloc()'d
751  * string that the caller must free.
752  *
753  * If 'netdev' is not a patch port, returns NULL. */
754 char *
755 netdev_vport_patch_peer(const struct netdev *netdev_)
756 {
757     char *peer = NULL;
758
759     if (netdev_vport_is_patch(netdev_)) {
760         struct netdev_vport *netdev = netdev_vport_cast(netdev_);
761
762         ovs_mutex_lock(&netdev->mutex);
763         if (netdev->peer) {
764             peer = xstrdup(netdev->peer);
765         }
766         ovs_mutex_unlock(&netdev->mutex);
767     }
768
769     return peer;
770 }
771
772 void
773 netdev_vport_inc_rx(const struct netdev *netdev,
774                     const struct dpif_flow_stats *stats)
775 {
776     if (is_vport_class(netdev_get_class(netdev))) {
777         struct netdev_vport *dev = netdev_vport_cast(netdev);
778
779         ovs_mutex_lock(&dev->mutex);
780         dev->stats.rx_packets += stats->n_packets;
781         dev->stats.rx_bytes += stats->n_bytes;
782         ovs_mutex_unlock(&dev->mutex);
783     }
784 }
785
786 void
787 netdev_vport_inc_tx(const struct netdev *netdev,
788                     const struct dpif_flow_stats *stats)
789 {
790     if (is_vport_class(netdev_get_class(netdev))) {
791         struct netdev_vport *dev = netdev_vport_cast(netdev);
792
793         ovs_mutex_lock(&dev->mutex);
794         dev->stats.tx_packets += stats->n_packets;
795         dev->stats.tx_bytes += stats->n_bytes;
796         ovs_mutex_unlock(&dev->mutex);
797     }
798 }
799
800 static int
801 get_patch_config(const struct netdev *dev_, struct smap *args)
802 {
803     struct netdev_vport *dev = netdev_vport_cast(dev_);
804
805     ovs_mutex_lock(&dev->mutex);
806     if (dev->peer) {
807         smap_add(args, "peer", dev->peer);
808     }
809     ovs_mutex_unlock(&dev->mutex);
810
811     return 0;
812 }
813
814 static int
815 set_patch_config(struct netdev *dev_, const struct smap *args)
816 {
817     struct netdev_vport *dev = netdev_vport_cast(dev_);
818     const char *name = netdev_get_name(dev_);
819     const char *peer;
820
821     peer = smap_get(args, "peer");
822     if (!peer) {
823         VLOG_ERR("%s: patch type requires valid 'peer' argument", name);
824         return EINVAL;
825     }
826
827     if (smap_count(args) > 1) {
828         VLOG_ERR("%s: patch type takes only a 'peer' argument", name);
829         return EINVAL;
830     }
831
832     if (!strcmp(name, peer)) {
833         VLOG_ERR("%s: patch peer must not be self", name);
834         return EINVAL;
835     }
836
837     ovs_mutex_lock(&dev->mutex);
838     if (!dev->peer || strcmp(dev->peer, peer)) {
839         free(dev->peer);
840         dev->peer = xstrdup(peer);
841         netdev_change_seq_changed(dev_);
842     }
843     ovs_mutex_unlock(&dev->mutex);
844
845     return 0;
846 }
847
848 static int
849 get_stats(const struct netdev *netdev, struct netdev_stats *stats)
850 {
851     struct netdev_vport *dev = netdev_vport_cast(netdev);
852
853     ovs_mutex_lock(&dev->mutex);
854     *stats = dev->stats;
855     ovs_mutex_unlock(&dev->mutex);
856
857     return 0;
858 }
859
860 \f
861 /* Tunnel push pop ops. */
862
863 static struct ip_header *
864 ip_hdr(void *eth)
865 {
866     return (void *)((char *)eth + sizeof (struct eth_header));
867 }
868
869 static struct ovs_16aligned_ip6_hdr *
870 ipv6_hdr(void *eth)
871 {
872     return (void *)((char *)eth + sizeof (struct eth_header));
873 }
874
875 static void *
876 ip_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl,
877                   unsigned int *hlen)
878 {
879     void *nh;
880     struct ip_header *ip;
881     struct ovs_16aligned_ip6_hdr *ip6;
882     void *l4;
883     int l3_size;
884
885     nh = dp_packet_l3(packet);
886     ip = nh;
887     ip6 = nh;
888     l4 = dp_packet_l4(packet);
889
890     if (!nh || !l4) {
891         return NULL;
892     }
893
894     *hlen = sizeof(struct eth_header);
895
896     l3_size = dp_packet_size(packet) -
897               ((char *)nh - (char *)dp_packet_data(packet));
898
899     if (IP_VER(ip->ip_ihl_ver) == 4) {
900
901         ovs_be32 ip_src, ip_dst;
902
903         if (csum(ip, IP_IHL(ip->ip_ihl_ver) * 4)) {
904             VLOG_WARN_RL(&err_rl, "ip packet has invalid checksum");
905             return NULL;
906         }
907
908         if (ntohs(ip->ip_tot_len) > l3_size) {
909             VLOG_WARN_RL(&err_rl, "ip packet is truncated (IP length %d, actual %d)",
910                          ntohs(ip->ip_tot_len), l3_size);
911             return NULL;
912         }
913         if (IP_IHL(ip->ip_ihl_ver) * 4 > sizeof(struct ip_header)) {
914             VLOG_WARN_RL(&err_rl, "ip options not supported on tunnel packets "
915                          "(%d bytes)", IP_IHL(ip->ip_ihl_ver) * 4);
916             return NULL;
917         }
918
919         ip_src = get_16aligned_be32(&ip->ip_src);
920         ip_dst = get_16aligned_be32(&ip->ip_dst);
921
922         tnl->ip_src = ip_src;
923         tnl->ip_dst = ip_dst;
924         tnl->ip_tos = ip->ip_tos;
925         tnl->ip_ttl = ip->ip_ttl;
926
927         *hlen += IP_HEADER_LEN;
928
929     } else if (IP_VER(ip->ip_ihl_ver) == 6) {
930
931         memcpy(tnl->ipv6_src.s6_addr, ip6->ip6_src.be16, sizeof ip6->ip6_src);
932         memcpy(tnl->ipv6_dst.s6_addr, ip6->ip6_dst.be16, sizeof ip6->ip6_dst);
933         tnl->ip_tos = 0;
934         tnl->ip_ttl = ip6->ip6_hlim;
935
936         *hlen += IPV6_HEADER_LEN;
937
938     } else {
939         VLOG_WARN_RL(&err_rl, "ipv4 packet has invalid version (%d)",
940                      IP_VER(ip->ip_ihl_ver));
941         return NULL;
942     }
943
944     return l4;
945 }
946
947 static bool
948 is_header_ipv6(const void *header)
949 {
950     const struct eth_header *eth;
951     eth = header;
952     return eth->eth_type == htons(ETH_TYPE_IPV6);
953 }
954
955 /* Pushes the 'size' bytes of 'header' into the headroom of 'packet',
956  * reallocating the packet if necessary.  'header' should contain an Ethernet
957  * header, followed by an IPv4 header (without options), and an L4 header.
958  *
959  * This function sets the IP header's ip_tot_len field (which should be zeroed
960  * as part of 'header') and puts its value into '*ip_tot_size' as well.  Also
961  * updates IP header checksum.
962  *
963  * Return pointer to the L4 header added to 'packet'. */
964 static void *
965 push_ip_header(struct dp_packet *packet,
966                const void *header, int size, int *ip_tot_size)
967 {
968     struct eth_header *eth;
969     struct ip_header *ip;
970     struct ovs_16aligned_ip6_hdr *ip6;
971
972     eth = dp_packet_push_uninit(packet, size);
973     *ip_tot_size = dp_packet_size(packet) - sizeof (struct eth_header);
974
975     memcpy(eth, header, size);
976
977     if (is_header_ipv6(header)) {
978         ip6 = ipv6_hdr(eth);
979         *ip_tot_size -= IPV6_HEADER_LEN;
980         ip6->ip6_plen = htons(*ip_tot_size);
981         return ip6 + 1;
982     } else {
983         ip = ip_hdr(eth);
984         ip->ip_tot_len = htons(*ip_tot_size);
985         ip->ip_csum = recalc_csum16(ip->ip_csum, 0, ip->ip_tot_len);
986         *ip_tot_size -= IP_HEADER_LEN;
987         return ip + 1;
988     }
989 }
990
991 static void *
992 udp_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl,
993                    unsigned int *hlen)
994 {
995     struct udp_header *udp;
996
997     udp = ip_extract_tnl_md(packet, tnl, hlen);
998     if (!udp) {
999         return NULL;
1000     }
1001
1002     if (udp->udp_csum) {
1003         uint32_t csum;
1004         size_t udp_len;
1005         udp_len = dp_packet_size(packet) -
1006                   ((const unsigned char *) udp -
1007                    (const unsigned char *) dp_packet_l2(packet));
1008         if (is_header_ipv6(dp_packet_data(packet))) {
1009             csum = packet_csum_pseudoheader6(dp_packet_l3(packet),
1010                                              htonl(udp_len));
1011         } else {
1012             csum = packet_csum_pseudoheader(dp_packet_l3(packet));
1013         }
1014
1015         csum = csum_continue(csum, udp, udp_len);
1016         if (csum_finish(csum)) {
1017             return NULL;
1018         }
1019         tnl->flags |= FLOW_TNL_F_CSUM;
1020     }
1021
1022     tnl->tp_src = udp->udp_src;
1023     tnl->tp_dst = udp->udp_dst;
1024
1025     return udp + 1;
1026 }
1027
1028 static ovs_be16
1029 get_src_port(struct dp_packet *packet)
1030 {
1031     uint32_t hash;
1032
1033     hash = dp_packet_get_rss_hash(packet);
1034
1035     return htons((((uint64_t) hash * (tnl_udp_port_max - tnl_udp_port_min)) >> 32) +
1036                  tnl_udp_port_min);
1037 }
1038
1039 static void
1040 push_udp_header(struct dp_packet *packet,
1041                 const struct ovs_action_push_tnl *data)
1042 {
1043     struct udp_header *udp;
1044     int ip_tot_size;
1045
1046     udp = push_ip_header(packet, data->header, data->header_len, &ip_tot_size);
1047
1048     /* set udp src port */
1049     udp->udp_src = get_src_port(packet);
1050     udp->udp_len = htons(ip_tot_size);
1051
1052     if (udp->udp_csum) {
1053         uint32_t csum;
1054         if (is_header_ipv6(dp_packet_data(packet))) {
1055             csum = packet_csum_pseudoheader6(ipv6_hdr(dp_packet_data(packet)),
1056                                              htonl(ip_tot_size));
1057         } else {
1058             csum = packet_csum_pseudoheader(ip_hdr(dp_packet_data(packet)));
1059         }
1060
1061         csum = csum_continue(csum, udp, ip_tot_size);
1062         udp->udp_csum = csum_finish(csum);
1063
1064         if (!udp->udp_csum) {
1065             udp->udp_csum = htons(0xffff);
1066         }
1067     }
1068 }
1069
1070 static void *
1071 udp_build_header(struct netdev_tunnel_config *tnl_cfg,
1072                  const struct flow *tnl_flow,
1073                  struct ovs_action_push_tnl *data,
1074                  unsigned int *hlen)
1075 {
1076     struct ip_header *ip;
1077     struct ovs_16aligned_ip6_hdr *ip6;
1078     struct udp_header *udp;
1079     bool is_ipv6;
1080
1081     *hlen = sizeof(struct eth_header);
1082
1083     is_ipv6 = is_header_ipv6(data->header);
1084
1085     if (is_ipv6) {
1086         ip6 = ipv6_hdr(data->header);
1087         ip6->ip6_nxt = IPPROTO_UDP;
1088         udp = (struct udp_header *) (ip6 + 1);
1089         *hlen += IPV6_HEADER_LEN;
1090     } else {
1091         ip = ip_hdr(data->header);
1092         ip->ip_proto = IPPROTO_UDP;
1093         udp = (struct udp_header *) (ip + 1);
1094         *hlen += IP_HEADER_LEN;
1095     }
1096
1097     udp->udp_dst = tnl_cfg->dst_port;
1098
1099     if (is_ipv6 || tnl_flow->tunnel.flags & FLOW_TNL_F_CSUM) {
1100         /* Write a value in now to mark that we should compute the checksum
1101          * later. 0xffff is handy because it is transparent to the
1102          * calculation. */
1103         udp->udp_csum = htons(0xffff);
1104     }
1105
1106     return udp + 1;
1107 }
1108
1109 static int
1110 gre_header_len(ovs_be16 flags)
1111 {
1112     int hlen = 4;
1113
1114     if (flags & htons(GRE_CSUM)) {
1115         hlen += 4;
1116     }
1117     if (flags & htons(GRE_KEY)) {
1118         hlen += 4;
1119     }
1120     if (flags & htons(GRE_SEQ)) {
1121         hlen += 4;
1122     }
1123     return hlen;
1124 }
1125
1126 static int
1127 parse_gre_header(struct dp_packet *packet,
1128                  struct flow_tnl *tnl)
1129 {
1130     const struct gre_base_hdr *greh;
1131     ovs_16aligned_be32 *options;
1132     int hlen;
1133     unsigned int ulen;
1134
1135     greh = ip_extract_tnl_md(packet, tnl, &ulen);
1136     if (!greh) {
1137         return -EINVAL;
1138     }
1139
1140     if (greh->flags & ~(htons(GRE_CSUM | GRE_KEY | GRE_SEQ))) {
1141         return -EINVAL;
1142     }
1143
1144     if (greh->protocol != htons(ETH_TYPE_TEB)) {
1145         return -EINVAL;
1146     }
1147
1148     hlen = ulen + gre_header_len(greh->flags);
1149     if (hlen > dp_packet_size(packet)) {
1150         return -EINVAL;
1151     }
1152
1153     options = (ovs_16aligned_be32 *)(greh + 1);
1154     if (greh->flags & htons(GRE_CSUM)) {
1155         ovs_be16 pkt_csum;
1156
1157         pkt_csum = csum(greh, dp_packet_size(packet) -
1158                               ((const unsigned char *)greh -
1159                                (const unsigned char *)dp_packet_l2(packet)));
1160         if (pkt_csum) {
1161             return -EINVAL;
1162         }
1163         tnl->flags = FLOW_TNL_F_CSUM;
1164         options++;
1165     }
1166
1167     if (greh->flags & htons(GRE_KEY)) {
1168         tnl->tun_id = (OVS_FORCE ovs_be64) ((OVS_FORCE uint64_t)(get_16aligned_be32(options)) << 32);
1169         tnl->flags |= FLOW_TNL_F_KEY;
1170         options++;
1171     }
1172
1173     if (greh->flags & htons(GRE_SEQ)) {
1174         options++;
1175     }
1176
1177     return hlen;
1178 }
1179
1180 static void
1181 pkt_metadata_init_tnl(struct pkt_metadata *md)
1182 {
1183     /* Zero up through the tunnel metadata options. The length and table
1184      * are before this and as long as they are empty, the options won't
1185      * be looked at. */
1186     memset(md, 0, offsetof(struct pkt_metadata, tunnel.metadata.opts));
1187 }
1188
1189 static int
1190 netdev_gre_pop_header(struct dp_packet *packet)
1191 {
1192     struct pkt_metadata *md = &packet->md;
1193     struct flow_tnl *tnl = &md->tunnel;
1194     int hlen = sizeof(struct eth_header) + 4;
1195
1196     hlen += is_header_ipv6(dp_packet_data(packet)) ?
1197             IPV6_HEADER_LEN : IP_HEADER_LEN;
1198
1199     pkt_metadata_init_tnl(md);
1200     if (hlen > dp_packet_size(packet)) {
1201         return EINVAL;
1202     }
1203
1204     hlen = parse_gre_header(packet, tnl);
1205     if (hlen < 0) {
1206         return -hlen;
1207     }
1208
1209     dp_packet_reset_packet(packet, hlen);
1210
1211     return 0;
1212 }
1213
1214 static void
1215 netdev_gre_push_header(struct dp_packet *packet,
1216                        const struct ovs_action_push_tnl *data)
1217 {
1218     struct gre_base_hdr *greh;
1219     int ip_tot_size;
1220
1221     greh = push_ip_header(packet, data->header, data->header_len, &ip_tot_size);
1222
1223     if (greh->flags & htons(GRE_CSUM)) {
1224         ovs_be16 *csum_opt = (ovs_be16 *) (greh + 1);
1225         *csum_opt = csum(greh, ip_tot_size);
1226     }
1227 }
1228
1229 static int
1230 netdev_gre_build_header(const struct netdev *netdev,
1231                         struct ovs_action_push_tnl *data,
1232                         const struct flow *tnl_flow)
1233 {
1234     struct netdev_vport *dev = netdev_vport_cast(netdev);
1235     struct netdev_tunnel_config *tnl_cfg;
1236     struct ip_header *ip;
1237     struct ovs_16aligned_ip6_hdr *ip6;
1238     struct gre_base_hdr *greh;
1239     ovs_16aligned_be32 *options;
1240     int hlen;
1241     bool is_ipv6;
1242
1243     is_ipv6 = is_header_ipv6(data->header);
1244
1245     /* XXX: RCUfy tnl_cfg. */
1246     ovs_mutex_lock(&dev->mutex);
1247     tnl_cfg = &dev->tnl_cfg;
1248
1249     if (is_ipv6) {
1250         ip6 = ipv6_hdr(data->header);
1251         ip6->ip6_nxt = IPPROTO_GRE;
1252         greh = (struct gre_base_hdr *) (ip6 + 1);
1253     } else {
1254         ip = ip_hdr(data->header);
1255         ip->ip_proto = IPPROTO_GRE;
1256         greh = (struct gre_base_hdr *) (ip + 1);
1257     }
1258
1259     greh->protocol = htons(ETH_TYPE_TEB);
1260     greh->flags = 0;
1261
1262     options = (ovs_16aligned_be32 *) (greh + 1);
1263     if (tnl_flow->tunnel.flags & FLOW_TNL_F_CSUM) {
1264         greh->flags |= htons(GRE_CSUM);
1265         put_16aligned_be32(options, 0);
1266         options++;
1267     }
1268
1269     if (tnl_cfg->out_key_present) {
1270         greh->flags |= htons(GRE_KEY);
1271         put_16aligned_be32(options, (OVS_FORCE ovs_be32)
1272                                     ((OVS_FORCE uint64_t) tnl_flow->tunnel.tun_id >> 32));
1273         options++;
1274     }
1275
1276     ovs_mutex_unlock(&dev->mutex);
1277
1278     hlen = (uint8_t *) options - (uint8_t *) greh;
1279
1280     data->header_len = sizeof(struct eth_header) + hlen +
1281                        (is_ipv6 ? IPV6_HEADER_LEN : IP_HEADER_LEN);
1282     data->tnl_type = OVS_VPORT_TYPE_GRE;
1283     return 0;
1284 }
1285
1286 static int
1287 netdev_vxlan_pop_header(struct dp_packet *packet)
1288 {
1289     struct pkt_metadata *md = &packet->md;
1290     struct flow_tnl *tnl = &md->tunnel;
1291     struct vxlanhdr *vxh;
1292     unsigned int hlen;
1293
1294     pkt_metadata_init_tnl(md);
1295     if (VXLAN_HLEN > dp_packet_l4_size(packet)) {
1296         return EINVAL;
1297     }
1298
1299     vxh = udp_extract_tnl_md(packet, tnl, &hlen);
1300     if (!vxh) {
1301         return EINVAL;
1302     }
1303
1304     if (get_16aligned_be32(&vxh->vx_flags) != htonl(VXLAN_FLAGS) ||
1305        (get_16aligned_be32(&vxh->vx_vni) & htonl(0xff))) {
1306         VLOG_WARN_RL(&err_rl, "invalid vxlan flags=%#x vni=%#x\n",
1307                      ntohl(get_16aligned_be32(&vxh->vx_flags)),
1308                      ntohl(get_16aligned_be32(&vxh->vx_vni)));
1309         return EINVAL;
1310     }
1311     tnl->tun_id = htonll(ntohl(get_16aligned_be32(&vxh->vx_vni)) >> 8);
1312     tnl->flags |= FLOW_TNL_F_KEY;
1313
1314     dp_packet_reset_packet(packet, hlen + VXLAN_HLEN);
1315
1316     return 0;
1317 }
1318
1319 static int
1320 netdev_vxlan_build_header(const struct netdev *netdev,
1321                           struct ovs_action_push_tnl *data,
1322                           const struct flow *tnl_flow)
1323 {
1324     struct netdev_vport *dev = netdev_vport_cast(netdev);
1325     struct netdev_tunnel_config *tnl_cfg;
1326     struct vxlanhdr *vxh;
1327     unsigned int hlen;
1328
1329     /* XXX: RCUfy tnl_cfg. */
1330     ovs_mutex_lock(&dev->mutex);
1331     tnl_cfg = &dev->tnl_cfg;
1332
1333     vxh = udp_build_header(tnl_cfg, tnl_flow, data, &hlen);
1334
1335     put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS));
1336     put_16aligned_be32(&vxh->vx_vni, htonl(ntohll(tnl_flow->tunnel.tun_id) << 8));
1337
1338     ovs_mutex_unlock(&dev->mutex);
1339     data->header_len = hlen + VXLAN_HLEN;
1340     data->tnl_type = OVS_VPORT_TYPE_VXLAN;
1341     return 0;
1342 }
1343
1344 static int
1345 netdev_geneve_pop_header(struct dp_packet *packet)
1346 {
1347     struct pkt_metadata *md = &packet->md;
1348     struct flow_tnl *tnl = &md->tunnel;
1349     struct genevehdr *gnh;
1350     unsigned int hlen, opts_len, ulen;
1351
1352     pkt_metadata_init_tnl(md);
1353     if (GENEVE_BASE_HLEN > dp_packet_l4_size(packet)) {
1354         VLOG_WARN_RL(&err_rl, "geneve packet too small: min header=%u packet size=%"PRIuSIZE"\n",
1355                      (unsigned int)GENEVE_BASE_HLEN, dp_packet_l4_size(packet));
1356         return EINVAL;
1357     }
1358
1359     gnh = udp_extract_tnl_md(packet, tnl, &ulen);
1360     if (!gnh) {
1361         return EINVAL;
1362     }
1363
1364     opts_len = gnh->opt_len * 4;
1365     hlen = ulen + GENEVE_BASE_HLEN + opts_len;
1366     if (hlen > dp_packet_size(packet)) {
1367         VLOG_WARN_RL(&err_rl, "geneve packet too small: header len=%u packet size=%u\n",
1368                      hlen, dp_packet_size(packet));
1369         return EINVAL;
1370     }
1371
1372     if (gnh->ver != 0) {
1373         VLOG_WARN_RL(&err_rl, "unknown geneve version: %"PRIu8"\n", gnh->ver);
1374         return EINVAL;
1375     }
1376
1377     if (gnh->proto_type != htons(ETH_TYPE_TEB)) {
1378         VLOG_WARN_RL(&err_rl, "unknown geneve encapsulated protocol: %#x\n",
1379                      ntohs(gnh->proto_type));
1380         return EINVAL;
1381     }
1382
1383     tnl->flags |= gnh->oam ? FLOW_TNL_F_OAM : 0;
1384     tnl->tun_id = htonll(ntohl(get_16aligned_be32(&gnh->vni)) >> 8);
1385     tnl->flags |= FLOW_TNL_F_KEY;
1386
1387     memcpy(tnl->metadata.opts.gnv, gnh->options, opts_len);
1388     tnl->metadata.present.len = opts_len;
1389     tnl->flags |= FLOW_TNL_F_UDPIF;
1390
1391     dp_packet_reset_packet(packet, hlen);
1392
1393     return 0;
1394 }
1395
1396 static int
1397 netdev_geneve_build_header(const struct netdev *netdev,
1398                            struct ovs_action_push_tnl *data,
1399                            const struct flow *tnl_flow)
1400 {
1401     struct netdev_vport *dev = netdev_vport_cast(netdev);
1402     struct netdev_tunnel_config *tnl_cfg;
1403     struct genevehdr *gnh;
1404     int opt_len;
1405     bool crit_opt;
1406     unsigned int hlen;
1407
1408     /* XXX: RCUfy tnl_cfg. */
1409     ovs_mutex_lock(&dev->mutex);
1410     tnl_cfg = &dev->tnl_cfg;
1411
1412     gnh = udp_build_header(tnl_cfg, tnl_flow, data, &hlen);
1413
1414     put_16aligned_be32(&gnh->vni, htonl(ntohll(tnl_flow->tunnel.tun_id) << 8));
1415
1416     ovs_mutex_unlock(&dev->mutex);
1417
1418     opt_len = tun_metadata_to_geneve_header(&tnl_flow->tunnel,
1419                                             gnh->options, &crit_opt);
1420
1421     gnh->opt_len = opt_len / 4;
1422     gnh->oam = !!(tnl_flow->tunnel.flags & FLOW_TNL_F_OAM);
1423     gnh->critical = crit_opt ? 1 : 0;
1424     gnh->proto_type = htons(ETH_TYPE_TEB);
1425
1426     data->header_len = hlen + GENEVE_BASE_HLEN + opt_len;
1427     data->tnl_type = OVS_VPORT_TYPE_GENEVE;
1428     return 0;
1429 }
1430
1431 static void
1432 netdev_vport_range(struct unixctl_conn *conn, int argc,
1433                    const char *argv[], void *aux OVS_UNUSED)
1434 {
1435     int val1, val2;
1436
1437     if (argc < 3) {
1438         struct ds ds = DS_EMPTY_INITIALIZER;
1439
1440         ds_put_format(&ds, "Tunnel UDP source port range: %"PRIu16"-%"PRIu16"\n",
1441                             tnl_udp_port_min, tnl_udp_port_max);
1442
1443         unixctl_command_reply(conn, ds_cstr(&ds));
1444         ds_destroy(&ds);
1445         return;
1446     }
1447
1448     if (argc != 3) {
1449         return;
1450     }
1451
1452     val1 = atoi(argv[1]);
1453     if (val1 <= 0 || val1 > UINT16_MAX) {
1454         unixctl_command_reply(conn, "Invalid min.");
1455         return;
1456     }
1457     val2 = atoi(argv[2]);
1458     if (val2 <= 0 || val2 > UINT16_MAX) {
1459         unixctl_command_reply(conn, "Invalid max.");
1460         return;
1461     }
1462
1463     if (val1 > val2) {
1464         tnl_udp_port_min = val2;
1465         tnl_udp_port_max = val1;
1466     } else {
1467         tnl_udp_port_min = val1;
1468         tnl_udp_port_max = val2;
1469     }
1470     seq_change(tnl_conf_seq);
1471
1472     unixctl_command_reply(conn, "OK");
1473 }
1474
1475 \f
1476 #define VPORT_FUNCTIONS(GET_CONFIG, SET_CONFIG,             \
1477                         GET_TUNNEL_CONFIG, GET_STATUS,      \
1478                         BUILD_HEADER,                       \
1479                         PUSH_HEADER, POP_HEADER)            \
1480     NULL,                                                   \
1481     netdev_vport_run,                                       \
1482     netdev_vport_wait,                                      \
1483                                                             \
1484     netdev_vport_alloc,                                     \
1485     netdev_vport_construct,                                 \
1486     netdev_vport_destruct,                                  \
1487     netdev_vport_dealloc,                                   \
1488     GET_CONFIG,                                             \
1489     SET_CONFIG,                                             \
1490     GET_TUNNEL_CONFIG,                                      \
1491     BUILD_HEADER,                                           \
1492     PUSH_HEADER,                                            \
1493     POP_HEADER,                                             \
1494     NULL,                       /* get_numa_id */           \
1495     NULL,                       /* set_multiq */            \
1496                                                             \
1497     NULL,                       /* send */                  \
1498     NULL,                       /* send_wait */             \
1499                                                             \
1500     netdev_vport_set_etheraddr,                             \
1501     netdev_vport_get_etheraddr,                             \
1502     NULL,                       /* get_mtu */               \
1503     NULL,                       /* set_mtu */               \
1504     NULL,                       /* get_ifindex */           \
1505     NULL,                       /* get_carrier */           \
1506     NULL,                       /* get_carrier_resets */    \
1507     NULL,                       /* get_miimon */            \
1508     get_stats,                                              \
1509                                                             \
1510     NULL,                       /* get_features */          \
1511     NULL,                       /* set_advertisements */    \
1512                                                             \
1513     NULL,                       /* set_policing */          \
1514     NULL,                       /* get_qos_types */         \
1515     NULL,                       /* get_qos_capabilities */  \
1516     NULL,                       /* get_qos */               \
1517     NULL,                       /* set_qos */               \
1518     NULL,                       /* get_queue */             \
1519     NULL,                       /* set_queue */             \
1520     NULL,                       /* delete_queue */          \
1521     NULL,                       /* get_queue_stats */       \
1522     NULL,                       /* queue_dump_start */      \
1523     NULL,                       /* queue_dump_next */       \
1524     NULL,                       /* queue_dump_done */       \
1525     NULL,                       /* dump_queue_stats */      \
1526                                                             \
1527     NULL,                       /* get_in4 */               \
1528     NULL,                       /* set_in4 */               \
1529     NULL,                       /* get_in6 */               \
1530     NULL,                       /* add_router */            \
1531     NULL,                       /* get_next_hop */          \
1532     GET_STATUS,                                             \
1533     NULL,                       /* arp_lookup */            \
1534                                                             \
1535     netdev_vport_update_flags,                              \
1536                                                             \
1537     NULL,                   /* rx_alloc */                  \
1538     NULL,                   /* rx_construct */              \
1539     NULL,                   /* rx_destruct */               \
1540     NULL,                   /* rx_dealloc */                \
1541     NULL,                   /* rx_recv */                   \
1542     NULL,                   /* rx_wait */                   \
1543     NULL,                   /* rx_drain */
1544
1545
1546 #define TUNNEL_CLASS(NAME, DPIF_PORT, BUILD_HEADER, PUSH_HEADER, POP_HEADER)   \
1547     { DPIF_PORT,                                                               \
1548         { NAME, VPORT_FUNCTIONS(get_tunnel_config,                             \
1549                                 set_tunnel_config,                             \
1550                                 get_netdev_tunnel_config,                      \
1551                                 tunnel_get_status,                             \
1552                                 BUILD_HEADER, PUSH_HEADER, POP_HEADER) }}
1553
1554 void
1555 netdev_vport_tunnel_register(void)
1556 {
1557     /* The name of the dpif_port should be short enough to accomodate adding
1558      * a port number to the end if one is necessary. */
1559     static const struct vport_class vport_classes[] = {
1560         TUNNEL_CLASS("geneve", "genev_sys", netdev_geneve_build_header,
1561                                             push_udp_header,
1562                                             netdev_geneve_pop_header),
1563         TUNNEL_CLASS("gre", "gre_sys", netdev_gre_build_header,
1564                                        netdev_gre_push_header,
1565                                        netdev_gre_pop_header),
1566         TUNNEL_CLASS("ipsec_gre", "gre_sys", NULL, NULL, NULL),
1567         TUNNEL_CLASS("vxlan", "vxlan_sys", netdev_vxlan_build_header,
1568                                            push_udp_header,
1569                                            netdev_vxlan_pop_header),
1570         TUNNEL_CLASS("lisp", "lisp_sys", NULL, NULL, NULL),
1571         TUNNEL_CLASS("stt", "stt_sys", NULL, NULL, NULL),
1572     };
1573     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
1574
1575     if (ovsthread_once_start(&once)) {
1576         int i;
1577
1578         for (i = 0; i < ARRAY_SIZE(vport_classes); i++) {
1579             netdev_register_provider(&vport_classes[i].netdev_class);
1580         }
1581
1582         unixctl_command_register("tnl/egress_port_range", "min max", 0, 2,
1583                                  netdev_vport_range, NULL);
1584
1585         ovsthread_once_done(&once);
1586     }
1587 }
1588
1589 void
1590 netdev_vport_patch_register(void)
1591 {
1592     static const struct vport_class patch_class =
1593         { NULL,
1594             { "patch", VPORT_FUNCTIONS(get_patch_config,
1595                                        set_patch_config,
1596                                        NULL,
1597                                        NULL, NULL, NULL, NULL) }};
1598     netdev_register_provider(&patch_class.netdev_class);
1599 }