netdev-vport: Warn on IPsec tunnels when ovs-monitor-ipsec not running.
[sliver-openvswitch.git] / lib / netdev-vport.c
1 /*
2  * Copyright (c) 2010, 2011 Nicira Networks.
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 <linux/rtnetlink.h>
25 #include <net/if.h>
26 #include <sys/ioctl.h>
27
28 #include "byte-order.h"
29 #include "daemon.h"
30 #include "dirs.h"
31 #include "dpif-linux.h"
32 #include "hash.h"
33 #include "hmap.h"
34 #include "list.h"
35 #include "netdev-provider.h"
36 #include "netlink.h"
37 #include "netlink-socket.h"
38 #include "ofpbuf.h"
39 #include "openvswitch/datapath-protocol.h"
40 #include "openvswitch/tunnel.h"
41 #include "packets.h"
42 #include "route-table.h"
43 #include "rtnetlink.h"
44 #include "shash.h"
45 #include "socket-util.h"
46 #include "vlog.h"
47
48 VLOG_DEFINE_THIS_MODULE(netdev_vport);
49
50 struct netdev_vport_notifier {
51     struct netdev_notifier notifier;
52     struct list list_node;
53     struct shash_node *shash_node;
54 };
55
56 struct netdev_dev_vport {
57     struct netdev_dev netdev_dev;
58     struct ofpbuf *options;
59 };
60
61 struct netdev_vport {
62     struct netdev netdev;
63 };
64
65 struct vport_class {
66     enum odp_vport_type type;
67     struct netdev_class netdev_class;
68     int (*parse_config)(const char *name, const char *type,
69                         const struct shash *args, struct ofpbuf *options);
70     int (*unparse_config)(const char *name, const char *type,
71                           const struct nlattr *options, size_t options_len,
72                           struct shash *args);
73 };
74
75 static struct shash netdev_vport_notifiers =
76                                     SHASH_INITIALIZER(&netdev_vport_notifiers);
77
78 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
79
80 static int netdev_vport_create(const struct netdev_class *, const char *,
81                                const struct shash *, struct netdev_dev **);
82 static void netdev_vport_poll_notify(const struct netdev *);
83 static int tnl_port_config_from_nlattr(const struct nlattr *options,
84                                        size_t options_len,
85                                        struct nlattr *a[ODP_TUNNEL_ATTR_MAX + 1]);
86
87 static const char *netdev_vport_get_tnl_iface(const struct netdev *netdev);
88
89 static bool
90 is_vport_class(const struct netdev_class *class)
91 {
92     return class->create == netdev_vport_create;
93 }
94
95 static const struct vport_class *
96 vport_class_cast(const struct netdev_class *class)
97 {
98     assert(is_vport_class(class));
99     return CONTAINER_OF(class, struct vport_class, netdev_class);
100 }
101
102 static struct netdev_dev_vport *
103 netdev_dev_vport_cast(const struct netdev_dev *netdev_dev)
104 {
105     assert(is_vport_class(netdev_dev_get_class(netdev_dev)));
106     return CONTAINER_OF(netdev_dev, struct netdev_dev_vport, netdev_dev);
107 }
108
109 static struct netdev_vport *
110 netdev_vport_cast(const struct netdev *netdev)
111 {
112     struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
113     assert(is_vport_class(netdev_dev_get_class(netdev_dev)));
114     return CONTAINER_OF(netdev, struct netdev_vport, netdev);
115 }
116
117 /* If 'netdev' is a vport netdev, returns an ofpbuf that contains Netlink
118  * options to include in ODP_VPORT_ATTR_OPTIONS for configuring that vport.
119  * Otherwise returns NULL. */
120 const struct ofpbuf *
121 netdev_vport_get_options(const struct netdev *netdev)
122 {
123     const struct netdev_dev *dev = netdev_get_dev(netdev);
124
125     return (is_vport_class(netdev_dev_get_class(dev))
126             ? netdev_dev_vport_cast(dev)->options
127             : NULL);
128 }
129
130 enum odp_vport_type
131 netdev_vport_get_vport_type(const struct netdev *netdev)
132 {
133     const struct netdev_dev *dev = netdev_get_dev(netdev);
134     const struct netdev_class *class = netdev_dev_get_class(dev);
135
136     return (is_vport_class(class) ? vport_class_cast(class)->type
137             : class == &netdev_internal_class ? ODP_VPORT_TYPE_INTERNAL
138             : class == &netdev_linux_class ? ODP_VPORT_TYPE_NETDEV
139             : ODP_VPORT_TYPE_UNSPEC);
140 }
141
142 const char *
143 netdev_vport_get_netdev_type(const struct dpif_linux_vport *vport)
144 {
145     struct nlattr *a[ODP_TUNNEL_ATTR_MAX + 1];
146
147     switch (vport->type) {
148     case ODP_VPORT_TYPE_UNSPEC:
149         break;
150
151     case ODP_VPORT_TYPE_NETDEV:
152         return "system";
153
154     case ODP_VPORT_TYPE_INTERNAL:
155         return "internal";
156
157     case ODP_VPORT_TYPE_PATCH:
158         return "patch";
159
160     case ODP_VPORT_TYPE_GRE:
161         if (tnl_port_config_from_nlattr(vport->options, vport->options_len,
162                                         a)) {
163             break;
164         }
165         return (nl_attr_get_u32(a[ODP_TUNNEL_ATTR_FLAGS]) & TNL_F_IPSEC
166                 ? "ipsec_gre" : "gre");
167
168     case ODP_VPORT_TYPE_CAPWAP:
169         return "capwap";
170
171     case __ODP_VPORT_TYPE_MAX:
172         break;
173     }
174
175     VLOG_WARN_RL(&rl, "dp%d: port `%s' has unsupported type %u",
176                  vport->dp_ifindex, vport->name, (unsigned int) vport->type);
177     return "unknown";
178 }
179
180 static int
181 netdev_vport_create(const struct netdev_class *netdev_class, const char *name,
182                     const struct shash *args,
183                     struct netdev_dev **netdev_devp)
184 {
185     const struct vport_class *vport_class = vport_class_cast(netdev_class);
186     struct ofpbuf *options = NULL;
187     struct shash fetched_args;
188     int error;
189
190     shash_init(&fetched_args);
191
192     if (!shash_is_empty(args)) {
193         /* Parse the provided configuration. */
194         options = ofpbuf_new(64);
195         error = vport_class->parse_config(name, netdev_class->type,
196                                           args, options);
197     } else {
198         /* Fetch an existing configuration from the kernel.
199          *
200          * This case could be ambiguous with initializing a new vport with an
201          * empty configuration, but none of the existing vport classes accept
202          * an empty configuration. */
203         struct dpif_linux_vport reply;
204         struct ofpbuf *buf;
205
206         error = dpif_linux_vport_get(name, &reply, &buf);
207         if (!error) {
208             /* XXX verify correct type */
209             error = vport_class->unparse_config(name, netdev_class->type,
210                                                 reply.options,
211                                                 reply.options_len,
212                                                 &fetched_args);
213             if (error) {
214                 VLOG_ERR_RL(&rl, "%s: failed to parse kernel config (%s)",
215                             name, strerror(error));
216             } else {
217                 options = ofpbuf_clone_data(reply.options, reply.options_len);
218             }
219             ofpbuf_delete(buf);
220         } else {
221             VLOG_ERR_RL(&rl, "%s: vport query failed (%s)",
222                         name, strerror(error));
223         }
224     }
225
226     if (!error) {
227         struct netdev_dev_vport *dev;
228
229         dev = xmalloc(sizeof *dev);
230         netdev_dev_init(&dev->netdev_dev, name,
231                         shash_is_empty(&fetched_args) ? args : &fetched_args,
232                         netdev_class);
233         dev->options = options;
234
235         *netdev_devp = &dev->netdev_dev;
236         route_table_register();
237     } else {
238         ofpbuf_delete(options);
239     }
240
241     shash_destroy(&fetched_args);
242
243     return error;
244 }
245
246 static void
247 netdev_vport_destroy(struct netdev_dev *netdev_dev_)
248 {
249     struct netdev_dev_vport *netdev_dev = netdev_dev_vport_cast(netdev_dev_);
250
251     route_table_unregister();
252     free(netdev_dev);
253 }
254
255 static int
256 netdev_vport_open(struct netdev_dev *netdev_dev_, int ethertype OVS_UNUSED,
257                 struct netdev **netdevp)
258 {
259     struct netdev_vport *netdev;
260
261     netdev = xmalloc(sizeof *netdev);
262     netdev_init(&netdev->netdev, netdev_dev_);
263
264     *netdevp = &netdev->netdev;
265     return 0;
266 }
267
268 static void
269 netdev_vport_close(struct netdev *netdev_)
270 {
271     struct netdev_vport *netdev = netdev_vport_cast(netdev_);
272     free(netdev);
273 }
274
275 static int
276 netdev_vport_set_config(struct netdev_dev *dev_, const struct shash *args)
277 {
278     const struct netdev_class *netdev_class = netdev_dev_get_class(dev_);
279     const struct vport_class *vport_class = vport_class_cast(netdev_class);
280     struct netdev_dev_vport *dev = netdev_dev_vport_cast(dev_);
281     const char *name = netdev_dev_get_name(dev_);
282     struct ofpbuf *options;
283     int error;
284
285     options = ofpbuf_new(64);
286     error = vport_class->parse_config(name, netdev_dev_get_type(dev_),
287                                       args, options);
288     if (!error
289         && (options->size != dev->options->size
290             || memcmp(options->data, dev->options->data, options->size))) {
291         struct dpif_linux_vport vport;
292
293         dpif_linux_vport_init(&vport);
294         vport.cmd = ODP_VPORT_CMD_SET;
295         vport.name = name;
296         vport.options = options->data;
297         vport.options_len = options->size;
298         error = dpif_linux_vport_transact(&vport, NULL, NULL);
299         if (!error || error == ENODEV) {
300             /* Either reconfiguration succeeded or this vport is not installed
301              * in the kernel (e.g. it hasn't been added to a dpif yet with
302              * dpif_port_add()). */
303             ofpbuf_delete(dev->options);
304             dev->options = options;
305             options = NULL;
306             error = 0;
307         }
308     }
309     ofpbuf_delete(options);
310
311     return error;
312 }
313
314 static int
315 netdev_vport_set_etheraddr(struct netdev *netdev,
316                            const uint8_t mac[ETH_ADDR_LEN])
317 {
318     struct dpif_linux_vport vport;
319     int error;
320
321     dpif_linux_vport_init(&vport);
322     vport.cmd = ODP_VPORT_CMD_SET;
323     vport.name = netdev_get_name(netdev);
324     vport.address = mac;
325
326     error = dpif_linux_vport_transact(&vport, NULL, NULL);
327     if (!error) {
328         netdev_vport_poll_notify(netdev);
329     }
330     return error;
331 }
332
333 static int
334 netdev_vport_get_etheraddr(const struct netdev *netdev,
335                            uint8_t mac[ETH_ADDR_LEN])
336 {
337     struct dpif_linux_vport reply;
338     struct ofpbuf *buf;
339     int error;
340
341     error = dpif_linux_vport_get(netdev_get_name(netdev), &reply, &buf);
342     if (!error) {
343         if (reply.address) {
344             memcpy(mac, reply.address, ETH_ADDR_LEN);
345         } else {
346             error = EOPNOTSUPP;
347         }
348         ofpbuf_delete(buf);
349     }
350     return error;
351 }
352
353 static int
354 netdev_vport_get_mtu(const struct netdev *netdev, int *mtup)
355 {
356     struct dpif_linux_vport reply;
357     struct ofpbuf *buf;
358     int error;
359
360     error = dpif_linux_vport_get(netdev_get_name(netdev), &reply, &buf);
361     if (!error) {
362         *mtup = reply.mtu;
363         ofpbuf_delete(buf);
364     }
365     return error;
366 }
367
368 int
369 netdev_vport_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
370 {
371     struct dpif_linux_vport reply;
372     struct ofpbuf *buf;
373     int error;
374
375     error = dpif_linux_vport_get(netdev_get_name(netdev), &reply, &buf);
376     if (error) {
377         return error;
378     } else if (!reply.stats) {
379         ofpbuf_delete(buf);
380         return EOPNOTSUPP;
381     }
382
383     stats->rx_packets = reply.stats->rx_packets;
384     stats->tx_packets = reply.stats->tx_packets;
385     stats->rx_bytes = reply.stats->rx_bytes;
386     stats->tx_bytes = reply.stats->tx_bytes;
387     stats->rx_errors = reply.stats->rx_errors;
388     stats->tx_errors = reply.stats->tx_errors;
389     stats->rx_dropped = reply.stats->rx_dropped;
390     stats->tx_dropped = reply.stats->tx_dropped;
391     stats->multicast = reply.stats->multicast;
392     stats->collisions = reply.stats->collisions;
393     stats->rx_length_errors = reply.stats->rx_length_errors;
394     stats->rx_over_errors = reply.stats->rx_over_errors;
395     stats->rx_crc_errors = reply.stats->rx_crc_errors;
396     stats->rx_frame_errors = reply.stats->rx_frame_errors;
397     stats->rx_fifo_errors = reply.stats->rx_fifo_errors;
398     stats->rx_missed_errors = reply.stats->rx_missed_errors;
399     stats->tx_aborted_errors = reply.stats->tx_aborted_errors;
400     stats->tx_carrier_errors = reply.stats->tx_carrier_errors;
401     stats->tx_fifo_errors = reply.stats->tx_fifo_errors;
402     stats->tx_heartbeat_errors = reply.stats->tx_heartbeat_errors;
403     stats->tx_window_errors = reply.stats->tx_window_errors;
404
405     ofpbuf_delete(buf);
406
407     return 0;
408 }
409
410 int
411 netdev_vport_set_stats(struct netdev *netdev, const struct netdev_stats *stats)
412 {
413     struct rtnl_link_stats64 rtnl_stats;
414     struct dpif_linux_vport vport;
415     int err;
416
417     rtnl_stats.rx_packets = stats->rx_packets;
418     rtnl_stats.tx_packets = stats->tx_packets;
419     rtnl_stats.rx_bytes = stats->rx_bytes;
420     rtnl_stats.tx_bytes = stats->tx_bytes;
421     rtnl_stats.rx_errors = stats->rx_errors;
422     rtnl_stats.tx_errors = stats->tx_errors;
423     rtnl_stats.rx_dropped = stats->rx_dropped;
424     rtnl_stats.tx_dropped = stats->tx_dropped;
425     rtnl_stats.multicast = stats->multicast;
426     rtnl_stats.collisions = stats->collisions;
427     rtnl_stats.rx_length_errors = stats->rx_length_errors;
428     rtnl_stats.rx_over_errors = stats->rx_over_errors;
429     rtnl_stats.rx_crc_errors = stats->rx_crc_errors;
430     rtnl_stats.rx_frame_errors = stats->rx_frame_errors;
431     rtnl_stats.rx_fifo_errors = stats->rx_fifo_errors;
432     rtnl_stats.rx_missed_errors = stats->rx_missed_errors;
433     rtnl_stats.tx_aborted_errors = stats->tx_aborted_errors;
434     rtnl_stats.tx_carrier_errors = stats->tx_carrier_errors;
435     rtnl_stats.tx_fifo_errors = stats->tx_fifo_errors;
436     rtnl_stats.tx_heartbeat_errors = stats->tx_heartbeat_errors;
437     rtnl_stats.tx_window_errors = stats->tx_window_errors;
438
439     dpif_linux_vport_init(&vport);
440     vport.cmd = ODP_VPORT_CMD_SET;
441     vport.name = netdev_get_name(netdev);
442     vport.stats = &rtnl_stats;
443
444     err = dpif_linux_vport_transact(&vport, NULL, NULL);
445
446     /* If the vport layer doesn't know about the device, that doesn't mean it
447      * doesn't exist (after all were able to open it when netdev_open() was
448      * called), it just means that it isn't attached and we'll be getting
449      * stats a different way. */
450     if (err == ENODEV) {
451         err = EOPNOTSUPP;
452     }
453
454     return err;
455 }
456
457 static int
458 netdev_vport_get_status(const struct netdev *netdev, struct shash *sh)
459 {
460     const char *iface = netdev_vport_get_tnl_iface(netdev);
461
462     if (iface) {
463         struct netdev *egress_netdev;
464
465         shash_add(sh, "tunnel_egress_iface", xstrdup(iface));
466
467         if (!netdev_open_default(iface, &egress_netdev)) {
468             shash_add(sh, "tunnel_egress_iface_carrier",
469                       xstrdup(netdev_get_carrier(egress_netdev)
470                               ? "up" : "down"));
471             netdev_close(egress_netdev);
472         }
473     }
474
475     return 0;
476 }
477
478 static int
479 netdev_vport_update_flags(struct netdev *netdev OVS_UNUSED,
480                         enum netdev_flags off, enum netdev_flags on OVS_UNUSED,
481                         enum netdev_flags *old_flagsp)
482 {
483     if (off & (NETDEV_UP | NETDEV_PROMISC)) {
484         return EOPNOTSUPP;
485     }
486
487     *old_flagsp = NETDEV_UP | NETDEV_PROMISC;
488     return 0;
489 }
490
491 static char *
492 make_poll_name(const struct netdev *netdev)
493 {
494     return xasprintf("%s:%s", netdev_get_type(netdev), netdev_get_name(netdev));
495 }
496
497 static int
498 netdev_vport_poll_add(struct netdev *netdev,
499                       void (*cb)(struct netdev_notifier *), void *aux,
500                       struct netdev_notifier **notifierp)
501 {
502     char *poll_name = make_poll_name(netdev);
503     struct netdev_vport_notifier *notifier;
504     struct list *list;
505     struct shash_node *shash_node;
506
507     shash_node = shash_find(&netdev_vport_notifiers, poll_name);
508     if (!shash_node) {
509         list = xmalloc(sizeof *list);
510         list_init(list);
511         shash_node = shash_add(&netdev_vport_notifiers, poll_name, list);
512     } else {
513         list = shash_node->data;
514     }
515
516     notifier = xmalloc(sizeof *notifier);
517     netdev_notifier_init(&notifier->notifier, netdev, cb, aux);
518     list_push_back(list, &notifier->list_node);
519     notifier->shash_node = shash_node;
520
521     *notifierp = &notifier->notifier;
522     free(poll_name);
523
524     return 0;
525 }
526
527 static void
528 netdev_vport_poll_remove(struct netdev_notifier *notifier_)
529 {
530     struct netdev_vport_notifier *notifier =
531                 CONTAINER_OF(notifier_, struct netdev_vport_notifier, notifier);
532
533     struct list *list;
534
535     list = list_remove(&notifier->list_node);
536     if (list_is_empty(list)) {
537         shash_delete(&netdev_vport_notifiers, notifier->shash_node);
538         free(list);
539     }
540
541     free(notifier);
542 }
543
544 static void
545 netdev_vport_run(void)
546 {
547     route_table_run();
548 }
549
550 static void
551 netdev_vport_wait(void)
552 {
553     route_table_wait();
554 }
555 \f
556 /* get_tnl_iface() implementation. */
557 static const char *
558 netdev_vport_get_tnl_iface(const struct netdev *netdev)
559 {
560     struct nlattr *a[ODP_TUNNEL_ATTR_MAX + 1];
561     uint32_t route;
562     struct netdev_dev_vport *ndv;
563     static char name[IFNAMSIZ];
564
565     ndv = netdev_dev_vport_cast(netdev_get_dev(netdev));
566     if (tnl_port_config_from_nlattr(ndv->options->data, ndv->options->size,
567                                     a)) {
568         return NULL;
569     }
570     route = nl_attr_get_be32(a[ODP_TUNNEL_ATTR_DST_IPV4]);
571
572     if (route_table_get_name(route, name)) {
573         return name;
574     }
575
576     return NULL;
577 }
578 \f
579 /* Helper functions. */
580
581 static void
582 netdev_vport_poll_notify(const struct netdev *netdev)
583 {
584     char *poll_name = make_poll_name(netdev);
585     struct list *list = shash_find_data(&netdev_vport_notifiers,
586                                         poll_name);
587
588     if (list) {
589         struct netdev_vport_notifier *notifier;
590
591         LIST_FOR_EACH (notifier, list_node, list) {
592             struct netdev_notifier *n = &notifier->notifier;
593             n->cb(n);
594         }
595     }
596
597     free(poll_name);
598 }
599 \f
600 /* Code specific to individual vport types. */
601
602 static void
603 set_key(const struct shash *args, const char *name, uint16_t type,
604         struct ofpbuf *options)
605 {
606     const char *s;
607
608     s = shash_find_data(args, name);
609     if (!s) {
610         s = shash_find_data(args, "key");
611         if (!s) {
612             s = "0";
613         }
614     }
615
616     if (!strcmp(s, "flow")) {
617         /* This is the default if no attribute is present. */
618     } else {
619         nl_msg_put_be64(options, type, htonll(strtoull(s, NULL, 0)));
620     }
621 }
622
623 static int
624 parse_tunnel_config(const char *name, const char *type,
625                     const struct shash *args, struct ofpbuf *options)
626 {
627     bool is_gre = false;
628     bool is_ipsec = false;
629     struct shash_node *node;
630     bool ipsec_mech_set = false;
631     ovs_be32 daddr = htonl(0);
632     uint32_t flags;
633
634     flags = TNL_F_PMTUD | TNL_F_HDR_CACHE;
635     if (!strcmp(type, "gre")) {
636         is_gre = true;
637     } else if (!strcmp(type, "ipsec_gre")) {
638         is_gre = true;
639         is_ipsec = true;
640         flags |= TNL_F_IPSEC;
641         flags &= ~TNL_F_HDR_CACHE;
642     }
643
644     SHASH_FOR_EACH (node, args) {
645         if (!strcmp(node->name, "remote_ip")) {
646             struct in_addr in_addr;
647             if (lookup_ip(node->data, &in_addr)) {
648                 VLOG_WARN("%s: bad %s 'remote_ip'", name, type);
649             } else {
650                 daddr = in_addr.s_addr;
651             }
652         } else if (!strcmp(node->name, "local_ip")) {
653             struct in_addr in_addr;
654             if (lookup_ip(node->data, &in_addr)) {
655                 VLOG_WARN("%s: bad %s 'local_ip'", name, type);
656             } else {
657                 nl_msg_put_be32(options, ODP_TUNNEL_ATTR_SRC_IPV4,
658                                 in_addr.s_addr);
659             }
660         } else if (!strcmp(node->name, "tos")) {
661             if (!strcmp(node->data, "inherit")) {
662                 flags |= TNL_F_TOS_INHERIT;
663             } else {
664                 nl_msg_put_u8(options, ODP_TUNNEL_ATTR_TOS, atoi(node->data));
665             }
666         } else if (!strcmp(node->name, "ttl")) {
667             if (!strcmp(node->data, "inherit")) {
668                 flags |= TNL_F_TTL_INHERIT;
669             } else {
670                 nl_msg_put_u8(options, ODP_TUNNEL_ATTR_TTL, atoi(node->data));
671             }
672         } else if (!strcmp(node->name, "csum") && is_gre) {
673             if (!strcmp(node->data, "true")) {
674                 flags |= TNL_F_CSUM;
675             }
676         } else if (!strcmp(node->name, "pmtud")) {
677             if (!strcmp(node->data, "false")) {
678                 flags &= ~TNL_F_PMTUD;
679             }
680         } else if (!strcmp(node->name, "header_cache")) {
681             if (!strcmp(node->data, "false")) {
682                 flags &= ~TNL_F_HDR_CACHE;
683             }
684         } else if (!strcmp(node->name, "peer_cert") && is_ipsec) {
685             if (shash_find(args, "certificate")) {
686                 ipsec_mech_set = true;
687             } else {
688                 const char *use_ssl_cert;
689
690                 /* If the "use_ssl_cert" is true, then "certificate" and
691                  * "private_key" will be pulled from the SSL table.  The
692                  * use of this option is strongly discouraged, since it
693                  * will like be removed when multiple SSL configurations
694                  * are supported by OVS.
695                  */
696                 use_ssl_cert = shash_find_data(args, "use_ssl_cert");
697                 if (!use_ssl_cert || strcmp(use_ssl_cert, "true")) {
698                     VLOG_WARN("%s: 'peer_cert' requires 'certificate' argument",
699                               name);
700                     return EINVAL;
701                 }
702                 ipsec_mech_set = true;
703             }
704         } else if (!strcmp(node->name, "psk") && is_ipsec) {
705             ipsec_mech_set = true;
706         } else if (is_ipsec
707                 && (!strcmp(node->name, "certificate")
708                     || !strcmp(node->name, "private_key")
709                     || !strcmp(node->name, "use_ssl_cert"))) {
710             /* Ignore options not used by the netdev. */
711         } else if (is_gre && (!strcmp(node->name, "key") ||
712                               !strcmp(node->name, "in_key") ||
713                               !strcmp(node->name, "out_key"))) {
714             /* Handled separately below. */
715         } else {
716             VLOG_WARN("%s: unknown %s argument '%s'", name, type, node->name);
717         }
718     }
719
720     if (is_ipsec) {
721         char *file_name = xasprintf("%s/%s", ovs_rundir(),
722                 "ovs-monitor-ipsec.pid");
723         if (read_pidfile(file_name) < 0) {
724             VLOG_WARN("%s: ovs-monitor-ipsec doesn't appear to be running, "
725                     "traffic may not pass", name);
726         }
727         free(file_name);
728
729         if (shash_find(args, "peer_cert") && shash_find(args, "psk")) {
730             VLOG_WARN("%s: cannot define both 'peer_cert' and 'psk'", name);
731             return EINVAL;
732         }
733
734         if (!ipsec_mech_set) {
735             VLOG_WARN("%s: IPsec requires an 'peer_cert' or psk' argument",
736                       name);
737             return EINVAL;
738         }
739     }
740
741     if (is_gre) {
742         set_key(args, "in_key", ODP_TUNNEL_ATTR_IN_KEY, options);
743         set_key(args, "out_key", ODP_TUNNEL_ATTR_OUT_KEY, options);
744     }
745
746     if (!daddr) {
747         VLOG_WARN("%s: %s type requires valid 'remote_ip' argument",
748                   name, type);
749         return EINVAL;
750     }
751     nl_msg_put_be32(options, ODP_TUNNEL_ATTR_DST_IPV4, daddr);
752
753     nl_msg_put_u32(options, ODP_TUNNEL_ATTR_FLAGS, flags);
754
755     return 0;
756 }
757
758 static int
759 tnl_port_config_from_nlattr(const struct nlattr *options, size_t options_len,
760                             struct nlattr *a[ODP_TUNNEL_ATTR_MAX + 1])
761 {
762     static const struct nl_policy odp_tunnel_policy[] = {
763         [ODP_TUNNEL_ATTR_FLAGS] = { .type = NL_A_U32 },
764         [ODP_TUNNEL_ATTR_DST_IPV4] = { .type = NL_A_BE32 },
765         [ODP_TUNNEL_ATTR_SRC_IPV4] = { .type = NL_A_BE32, .optional = true },
766         [ODP_TUNNEL_ATTR_IN_KEY] = { .type = NL_A_BE64, .optional = true },
767         [ODP_TUNNEL_ATTR_OUT_KEY] = { .type = NL_A_BE64, .optional = true },
768         [ODP_TUNNEL_ATTR_TOS] = { .type = NL_A_U8, .optional = true },
769         [ODP_TUNNEL_ATTR_TTL] = { .type = NL_A_U8, .optional = true },
770     };
771     struct ofpbuf buf;
772
773     ofpbuf_use_const(&buf, options, options_len);
774     if (!nl_policy_parse(&buf, 0, odp_tunnel_policy,
775                          a, ARRAY_SIZE(odp_tunnel_policy))) {
776         return EINVAL;
777     }
778     return 0;
779 }
780
781 static uint64_t
782 get_be64_or_zero(const struct nlattr *a)
783 {
784     return a ? ntohll(nl_attr_get_be64(a)) : 0;
785 }
786
787 static int
788 unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
789                       const struct nlattr *options, size_t options_len,
790                       struct shash *args)
791 {
792     struct nlattr *a[ODP_TUNNEL_ATTR_MAX + 1];
793     ovs_be32 daddr;
794     uint32_t flags;
795     int error;
796
797     error = tnl_port_config_from_nlattr(options, options_len, a);
798     if (error) {
799         return error;
800     }
801
802     flags = nl_attr_get_u32(a[ODP_TUNNEL_ATTR_FLAGS]);
803     if (!(flags & TNL_F_HDR_CACHE) == !(flags & TNL_F_IPSEC)) {
804         smap_add(args, "header_cache",
805                  flags & TNL_F_HDR_CACHE ? "true" : "false");
806     }
807
808     daddr = nl_attr_get_be32(a[ODP_TUNNEL_ATTR_DST_IPV4]);
809     shash_add(args, "remote_ip", xasprintf(IP_FMT, IP_ARGS(&daddr)));
810
811     if (a[ODP_TUNNEL_ATTR_SRC_IPV4]) {
812         ovs_be32 saddr = nl_attr_get_be32(a[ODP_TUNNEL_ATTR_SRC_IPV4]);
813         shash_add(args, "local_ip", xasprintf(IP_FMT, IP_ARGS(&saddr)));
814     }
815
816     if (!a[ODP_TUNNEL_ATTR_IN_KEY] && !a[ODP_TUNNEL_ATTR_OUT_KEY]) {
817         smap_add(args, "key", "flow");
818     } else {
819         uint64_t in_key = get_be64_or_zero(a[ODP_TUNNEL_ATTR_IN_KEY]);
820         uint64_t out_key = get_be64_or_zero(a[ODP_TUNNEL_ATTR_OUT_KEY]);
821
822         if (in_key && in_key == out_key) {
823             shash_add(args, "key", xasprintf("%"PRIu64, in_key));
824         } else {
825             if (!a[ODP_TUNNEL_ATTR_IN_KEY]) {
826                 smap_add(args, "in_key", "flow");
827             } else if (in_key) {
828                 shash_add(args, "in_key", xasprintf("%"PRIu64, in_key));
829             }
830
831             if (!a[ODP_TUNNEL_ATTR_OUT_KEY]) {
832                 smap_add(args, "out_key", "flow");
833             } else if (out_key) {
834                 shash_add(args, "out_key", xasprintf("%"PRIu64, out_key));
835             }
836         }
837     }
838
839     if (flags & TNL_F_TTL_INHERIT) {
840         smap_add(args, "tos", "inherit");
841     } else if (a[ODP_TUNNEL_ATTR_TTL]) {
842         int ttl = nl_attr_get_u8(a[ODP_TUNNEL_ATTR_TTL]);
843         shash_add(args, "tos", xasprintf("%d", ttl));
844     }
845
846     if (flags & TNL_F_TOS_INHERIT) {
847         smap_add(args, "tos", "inherit");
848     } else if (a[ODP_TUNNEL_ATTR_TOS]) {
849         int tos = nl_attr_get_u8(a[ODP_TUNNEL_ATTR_TOS]);
850         shash_add(args, "tos", xasprintf("%d", tos));
851     }
852
853     if (flags & TNL_F_CSUM) {
854         smap_add(args, "csum", "true");
855     }
856     if (!(flags & TNL_F_PMTUD)) {
857         smap_add(args, "pmtud", "false");
858     }
859
860     return 0;
861 }
862
863 static int
864 parse_patch_config(const char *name, const char *type OVS_UNUSED,
865                    const struct shash *args, struct ofpbuf *options)
866 {
867     const char *peer;
868
869     peer = shash_find_data(args, "peer");
870     if (!peer) {
871         VLOG_WARN("%s: patch type requires valid 'peer' argument", name);
872         return EINVAL;
873     }
874
875     if (shash_count(args) > 1) {
876         VLOG_WARN("%s: patch type takes only a 'peer' argument", name);
877         return EINVAL;
878     }
879
880     if (strlen(peer) >= IFNAMSIZ) {
881         VLOG_WARN("%s: patch 'peer' arg too long", name);
882         return EINVAL;
883     }
884
885     if (!strcmp(name, peer)) {
886         VLOG_WARN("%s: patch peer must not be self", name);
887         return EINVAL;
888     }
889
890     nl_msg_put_string(options, ODP_PATCH_ATTR_PEER, peer);
891
892     return 0;
893 }
894
895 static int
896 unparse_patch_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
897                      const struct nlattr *options, size_t options_len,
898                      struct shash *args)
899 {
900     static const struct nl_policy odp_patch_policy[] = {
901         [ODP_PATCH_ATTR_PEER] = { .type = NL_A_STRING,
902                                .max_len = IFNAMSIZ,
903                                .optional = false }
904     };
905
906     struct nlattr *a[ARRAY_SIZE(odp_patch_policy)];
907     struct ofpbuf buf;
908
909     ofpbuf_use_const(&buf, options, options_len);
910     if (!nl_policy_parse(&buf, 0, odp_patch_policy,
911                          a, ARRAY_SIZE(odp_patch_policy))) {
912         return EINVAL;
913     }
914
915     smap_add(args, "peer", nl_attr_get_string(a[ODP_PATCH_ATTR_PEER]));
916     return 0;
917 }
918 \f
919 #define VPORT_FUNCTIONS(GET_STATUS)                         \
920     NULL,                                                   \
921     netdev_vport_run,                                       \
922     netdev_vport_wait,                                      \
923                                                             \
924     netdev_vport_create,                                    \
925     netdev_vport_destroy,                                   \
926     netdev_vport_set_config,                                \
927                                                             \
928     netdev_vport_open,                                      \
929     netdev_vport_close,                                     \
930                                                             \
931     NULL,                       /* enumerate */             \
932                                                             \
933     NULL,                       /* recv */                  \
934     NULL,                       /* recv_wait */             \
935     NULL,                       /* drain */                 \
936                                                             \
937     NULL,                       /* send */                  \
938     NULL,                       /* send_wait */             \
939                                                             \
940     netdev_vport_set_etheraddr,                             \
941     netdev_vport_get_etheraddr,                             \
942     netdev_vport_get_mtu,                                   \
943     NULL,                       /* get_ifindex */           \
944     NULL,                       /* get_carrier */           \
945     NULL,                       /* get_miimon */            \
946     netdev_vport_get_stats,                                 \
947     netdev_vport_set_stats,                                 \
948                                                             \
949     NULL,                       /* get_features */          \
950     NULL,                       /* set_advertisements */    \
951     NULL,                       /* get_vlan_vid */          \
952                                                             \
953     NULL,                       /* set_policing */          \
954     NULL,                       /* get_qos_types */         \
955     NULL,                       /* get_qos_capabilities */  \
956     NULL,                       /* get_qos */               \
957     NULL,                       /* set_qos */               \
958     NULL,                       /* get_queue */             \
959     NULL,                       /* set_queue */             \
960     NULL,                       /* delete_queue */          \
961     NULL,                       /* get_queue_stats */       \
962     NULL,                       /* dump_queues */           \
963     NULL,                       /* dump_queue_stats */      \
964                                                             \
965     NULL,                       /* get_in4 */               \
966     NULL,                       /* set_in4 */               \
967     NULL,                       /* get_in6 */               \
968     NULL,                       /* add_router */            \
969     NULL,                       /* get_next_hop */          \
970     GET_STATUS,                                             \
971     NULL,                       /* arp_lookup */            \
972                                                             \
973     netdev_vport_update_flags,                              \
974                                                             \
975     netdev_vport_poll_add,                                  \
976     netdev_vport_poll_remove,
977
978 void
979 netdev_vport_register(void)
980 {
981     static const struct vport_class vport_classes[] = {
982         { ODP_VPORT_TYPE_GRE,
983           { "gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
984           parse_tunnel_config, unparse_tunnel_config },
985
986         { ODP_VPORT_TYPE_GRE,
987           { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
988           parse_tunnel_config, unparse_tunnel_config },
989
990         { ODP_VPORT_TYPE_CAPWAP,
991           { "capwap", VPORT_FUNCTIONS(netdev_vport_get_status) },
992           parse_tunnel_config, unparse_tunnel_config },
993
994         { ODP_VPORT_TYPE_PATCH,
995           { "patch", VPORT_FUNCTIONS(NULL) },
996           parse_patch_config, unparse_patch_config }
997     };
998
999     int i;
1000
1001     for (i = 0; i < ARRAY_SIZE(vport_classes); i++) {
1002         netdev_register_provider(&vport_classes[i].netdev_class);
1003     }
1004 }