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