ofproto: Change string sets in interface from svec to sset.
[sliver-openvswitch.git] / utilities / ovs-openflowd.c
index 5ed3268..f1c52f9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -57,6 +57,7 @@ struct ofsettings {
     struct ofproto_controller *controllers;
     size_t n_controllers;
     enum ofproto_fail_mode fail_mode;
+    bool run_forever;           /* Continue running even with no controller? */
 
     /* Datapath. */
     uint64_t datapath_id;       /* Datapath ID. */
@@ -72,15 +73,17 @@ struct ofsettings {
     const char *dp_desc;        /* Datapath description. */
 
     /* Related vconns and network devices. */
-    struct svec snoops;          /* Listen for controller snooping conns. */
+    struct sset snoops;          /* Listen for controller snooping conns. */
 
     /* Failure behavior. */
     int max_idle;             /* Idle time for flows in fail-open mode. */
 
     /* NetFlow. */
-    struct svec netflow;        /* NetFlow targets. */
+    struct sset netflow;        /* NetFlow targets. */
 };
 
+static unixctl_cb_func ovs_openflowd_exit;
+
 static void parse_options(int argc, char *argv[], struct ofsettings *);
 static void usage(void) NO_RETURN;
 
@@ -93,6 +96,7 @@ main(int argc, char *argv[])
     int error;
     struct dpif *dpif;
     struct netflow_options nf_options;
+    bool exiting;
 
     proctitle_init(argc, argv);
     set_program_name(argv[0]);
@@ -108,6 +112,8 @@ main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
+    unixctl_command_register("exit", ovs_openflowd_exit, &exiting);
+
     VLOG_INFO("Open vSwitch version %s", VERSION BUILDNR);
     VLOG_INFO("OpenFlow protocol version 0x%02x", OFP_VERSION);
 
@@ -122,10 +128,19 @@ main(int argc, char *argv[])
         size_t i;
 
         SVEC_FOR_EACH (i, port, &s.ports) {
-            error = dpif_port_add(dpif, port, 0, NULL);
+            struct netdev *netdev;
+
+            error = netdev_open_default(port, &netdev);
+            if (error) {
+                ovs_fatal(error, "%s: failed to open network device", port);
+            }
+
+            error = dpif_port_add(dpif, netdev, NULL);
             if (error) {
                 ovs_fatal(error, "failed to add %s as a port", port);
             }
+
+            netdev_close(netdev);
         }
     }
 
@@ -155,7 +170,8 @@ main(int argc, char *argv[])
 
     daemonize_complete();
 
-    while (ofproto_is_alive(ofproto)) {
+    exiting = false;
+    while (!exiting && (s.run_forever || ofproto_is_alive(ofproto))) {
         error = ofproto_run(ofproto);
         if (error) {
             ovs_fatal(error, "unrecoverable datapath error");
@@ -168,6 +184,9 @@ main(int argc, char *argv[])
         unixctl_server_wait(unixctl);
         dp_wait();
         netdev_wait();
+        if (exiting) {
+            poll_immediate_wake();
+        }
         poll_block();
     }
 
@@ -175,6 +194,15 @@ main(int argc, char *argv[])
 
     return 0;
 }
+
+static void
+ovs_openflowd_exit(struct unixctl_conn *conn, const char *args OVS_UNUSED,
+                   void *exiting_)
+{
+    bool *exiting = exiting_;
+    *exiting = true;
+    unixctl_command_reply(conn, 200, NULL);
+}
 \f
 /* User interface. */
 
@@ -188,8 +216,6 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
         OPT_SW_DESC,
         OPT_SERIAL_DESC,
         OPT_DP_DESC,
-        OPT_ACCEPT_VCONN,
-        OPT_NO_RESOLV_CONF,
         OPT_BR_NAME,
         OPT_FAIL_MODE,
         OPT_INACTIVITY_PROBE,
@@ -206,7 +232,8 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
         OPT_UNIXCTL,
         OPT_ENABLE_DUMMY,
         VLOG_OPTION_ENUMS,
-        LEAK_CHECKER_OPTION_ENUMS
+        LEAK_CHECKER_OPTION_ENUMS,
+        DAEMON_OPTION_ENUMS
     };
     static struct option long_options[] = {
         {"datapath-id", required_argument, 0, OPT_DATAPATH_ID},
@@ -215,8 +242,6 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
         {"sw-desc", required_argument, 0, OPT_SW_DESC},
         {"serial-desc", required_argument, 0, OPT_SERIAL_DESC},
         {"dp-desc", required_argument, 0, OPT_DP_DESC},
-        {"accept-vconn", required_argument, 0, OPT_ACCEPT_VCONN},
-        {"no-resolv-conf", no_argument, 0, OPT_NO_RESOLV_CONF},
         {"config",      required_argument, 0, 'F'},
         {"br-name",     required_argument, 0, OPT_BR_NAME},
         {"fail",        required_argument, 0, OPT_FAIL_MODE},
@@ -255,8 +280,6 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
     controller_opts.max_backoff = 8;
     controller_opts.probe_interval = 5;
     controller_opts.band = OFPROTO_IN_BAND;
-    controller_opts.accept_re = NULL;
-    controller_opts.update_resolv_conf = true;
     controller_opts.rate_limit = 0;
     controller_opts.burst_limit = 0;
     s->unixctl_path = NULL;
@@ -268,9 +291,9 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
     s->serial_desc = NULL;
     s->dp_desc = NULL;
     svec_init(&controllers);
-    svec_init(&s->snoops);
+    sset_init(&s->snoops);
     s->max_idle = 0;
-    svec_init(&s->netflow);
+    sset_init(&s->netflow);
     svec_init(&s->ports);
     for (;;) {
         int c;
@@ -308,14 +331,6 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
             s->dp_desc = optarg;
             break;
 
-        case OPT_ACCEPT_VCONN:
-            controller_opts.accept_re = optarg;
-            break;
-
-        case OPT_NO_RESOLV_CONF:
-            controller_opts.update_resolv_conf = false;
-            break;
-
         case OPT_FAIL_MODE:
             if (!strcmp(optarg, "open") || !strcmp(optarg, "standalone")) {
                 s->fail_mode = OFPROTO_FAIL_STANDALONE;
@@ -383,7 +398,7 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
             break;
 
         case OPT_NETFLOW:
-            svec_add(&s->netflow, optarg);
+            sset_add(&s->netflow, optarg);
             break;
 
         case 'l':
@@ -391,7 +406,7 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
             break;
 
         case OPT_SNOOP:
-            svec_add(&s->snoops, optarg);
+            sset_add(&s->snoops, optarg);
             break;
 
         case OPT_PORTS:
@@ -438,17 +453,11 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
 
     argc -= optind;
     argv += optind;
-    if (argc < 1) {
-        ovs_fatal(0, "need at least one non-option arguments; "
+    if (argc < 2) {
+        ovs_fatal(0, "need at least two non-option arguments; "
                   "use --help for usage");
     }
 
-    /* Set accept_controller_regex. */
-    if (!controller_opts.accept_re) {
-        controller_opts.accept_re
-            = stream_ssl_is_configured() ? "^ssl:.*" : "^tcp:.*";
-    }
-
     /* Rate limiting. */
     if (controller_opts.rate_limit && controller_opts.rate_limit < 100) {
         VLOG_WARN("Rate limit set to unusually low value %d",
@@ -459,15 +468,17 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
     dp_parse_name(argv[0], &s->dp_name, &s->dp_type);
 
     /* Figure out controller names. */
+    s->run_forever = false;
     if (!controllers.n) {
         svec_add_nocopy(&controllers, xasprintf("punix:%s/%s.mgmt",
                                                 ovs_rundir(), s->dp_name));
     }
     for (i = 1; i < argc; i++) {
-        svec_add(&controllers, argv[i]);
-    }
-    if (argc < 2) {
-        svec_add(&controllers, "discover");
+        if (!strcmp(argv[i], "none")) {
+            s->run_forever = true;
+        } else {
+            svec_add(&controllers, argv[i]);
+        }
     }
 
     /* Set up controllers. */
@@ -477,27 +488,16 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
         s->controllers[i] = controller_opts;
         s->controllers[i].target = controllers.names[i];
     }
-
-    /* Sanity check. */
-    if (controller_opts.band == OFPROTO_OUT_OF_BAND) {
-        for (i = 0; i < s->n_controllers; i++) {
-            if (!strcmp(s->controllers[i].target, "discover")) {
-                ovs_fatal(0, "Cannot perform discovery with out-of-band "
-                          "control");
-            }
-        }
-    }
 }
 
 static void
 usage(void)
 {
     printf("%s: an OpenFlow switch implementation.\n"
-           "usage: %s [OPTIONS] [TYPE@]DATAPATH [CONTROLLER...]\n"
+           "usage: %s [OPTIONS] [TYPE@]DATAPATH CONTROLLER...\n"
            "where DATAPATH is a local datapath (e.g. \"dp0\")\n"
            "optionally with an explicit TYPE (default: \"system\").\n"
-           "Each CONTROLLER is an active OpenFlow connection method.  If\n"
-           "none is given, ovs-openflowd performs controller discovery.\n",
+           "Each CONTROLLER is an active OpenFlow connection method.\n",
            program_name, program_name);
     vconn_usage(true, true, true);
     printf("\nOpenFlow options:\n"
@@ -508,9 +508,6 @@ usage(void)
            "  --sw-desc=SW            Identify software as SW\n"
            "  --serial-desc=SERIAL    Identify serial number as SERIAL\n"
            "  --dp-desc=DP_DESC       Identify dp description as DP_DESC\n"
-           "\nController discovery options:\n"
-           "  --accept-vconn=REGEX    accept matching discovered controllers\n"
-           "  --no-resolv-conf        do not update /etc/resolv.conf\n"
            "\nNetworking options:\n"
            "  --fail=open|closed      when controller connection fails:\n"
            "                            closed: drop all packets\n"