ofproto: Add user-specifiable datapath description (OpenFlow 1.0)
[sliver-openvswitch.git] / utilities / ovs-openflowd.c
index f60dea5..959ba2c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -64,12 +64,14 @@ struct ofsettings {
     /* Datapath. */
     uint64_t datapath_id;       /* Datapath ID. */
     const char *dp_name;        /* Name of local datapath. */
+    struct svec ports;          /* Set of ports to add to datapath (if any). */
 
     /* Description strings. */
     const char *mfr_desc;       /* Manufacturer. */
     const char *hw_desc;        /* Hardware. */
     const char *sw_desc;        /* Software version. */
     const char *serial_desc;    /* Serial number. */
+    const char *dp_desc;        /* Serial number. */
 
     /* Related vconns and network devices. */
     const char *controller_name; /* Controller (if not discovery mode). */
@@ -114,6 +116,7 @@ main(int argc, char *argv[])
     struct ofproto *ofproto;
     struct ofsettings s;
     int error;
+    struct netflow_options nf_options;
 
     set_program_name(argv[0]);
     register_fault_handlers();
@@ -134,6 +137,26 @@ main(int argc, char *argv[])
     VLOG_INFO("Open vSwitch version %s", VERSION BUILDNR);
     VLOG_INFO("OpenFlow protocol version 0x%02x", OFP_VERSION);
 
+    /* Create the datapath and add ports to it, if requested by the user. */
+    if (s.ports.n) {
+        struct dpif *dpif;
+        const char *port;
+        size_t i;
+
+        error = dpif_create_and_open(s.dp_name, &dpif);
+        if (error) {
+            ovs_fatal(error, "could not create datapath");
+        }
+
+        SVEC_FOR_EACH (i, port, &s.ports) {
+            error = dpif_port_add(dpif, port, 0, NULL);
+            if (error) {
+                ovs_fatal(error, "failed to add %s as a port", port);
+            }
+        }
+        dpif_close(dpif);
+    }
+
     /* Start OpenFlow processing. */
     error = ofproto_create(s.dp_name, NULL, NULL, &ofproto);
     if (error) {
@@ -154,7 +177,14 @@ main(int argc, char *argv[])
     if (s.mgmt_id) {
         ofproto_set_mgmt_id(ofproto, s.mgmt_id);
     }
-    ofproto_set_desc(ofproto, s.mfr_desc, s.hw_desc, s.sw_desc, s.serial_desc);
+    ofproto_set_desc(ofproto, s.mfr_desc, s.hw_desc, s.sw_desc,
+                     s.serial_desc, s.dp_desc);
+    if (!s.listeners.n) {
+        svec_add_nocopy(&s.listeners, xasprintf("punix:%s/%s.mgmt",
+                                              ovs_rundir, s.dp_name));
+    } else if (s.listeners.n == 1 && !strcmp(s.listeners.names[0], "none")) {
+        svec_clear(&s.listeners);
+    }
     error = ofproto_set_listeners(ofproto, &s.listeners);
     if (error) {
         ovs_fatal(error, "failed to configure management connections");
@@ -164,7 +194,9 @@ main(int argc, char *argv[])
         ovs_fatal(error,
                   "failed to configure controller snooping connections");
     }
-    error = ofproto_set_netflow(ofproto, &s.netflow, 0, 0, false);
+    memset(&nf_options, 0, sizeof nf_options);
+    nf_options.collectors = s.netflow;
+    error = ofproto_set_netflow(ofproto, &nf_options);
     if (error) {
         ovs_fatal(error, "failed to configure NetFlow collectors");
     }
@@ -195,10 +227,12 @@ main(int argc, char *argv[])
         }
         unixctl_server_run(unixctl);
         dp_run();
+        netdev_run();
 
         ofproto_wait(ofproto);
         unixctl_server_wait(unixctl);
         dp_wait();
+        netdev_wait();
         poll_block();
     }
 
@@ -216,6 +250,7 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
         OPT_HARDWARE,
         OPT_SOFTWARE,
         OPT_SERIAL,
+        OPT_DP_DESC,
         OPT_ACCEPT_VCONN,
         OPT_NO_RESOLV_CONF,
         OPT_BR_NAME,
@@ -235,6 +270,7 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
         OPT_COMMAND_DIR,
         OPT_NETFLOW,
         OPT_MGMT_ID,
+        OPT_PORTS,
         VLOG_OPTION_ENUMS,
         LEAK_CHECKER_OPTION_ENUMS
     };
@@ -244,6 +280,7 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
         {"hardware", required_argument, 0, OPT_HARDWARE},
         {"software", required_argument, 0, OPT_SOFTWARE},
         {"serial", required_argument, 0, OPT_SERIAL},
+        {"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'},
@@ -264,6 +301,7 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
         {"command-dir", required_argument, 0, OPT_COMMAND_DIR},
         {"netflow",     required_argument, 0, OPT_NETFLOW},
         {"mgmt-id",     required_argument, 0, OPT_MGMT_ID},
+        {"ports",       required_argument, 0, OPT_PORTS},
         {"verbose",     optional_argument, 0, 'v'},
         {"help",        no_argument, 0, 'h'},
         {"version",     no_argument, 0, 'V'},
@@ -284,12 +322,13 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
     s->hw_desc = NULL;
     s->sw_desc = NULL;
     s->serial_desc = NULL;
+    s->dp_desc = NULL;
     svec_init(&s->listeners);
     svec_init(&s->snoops);
     s->fail_mode = FAIL_OPEN;
     s->max_idle = 0;
     s->probe_interval = 0;
-    s->max_backoff = 15;
+    s->max_backoff = 8;
     s->update_resolv_conf = true;
     s->rate_limit = 0;
     s->burst_limit = 0;
@@ -300,6 +339,7 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
     s->command_dir = NULL;
     svec_init(&s->netflow);
     s->mgmt_id = 0;
+    svec_init(&s->ports);
     for (;;) {
         int c;
 
@@ -310,10 +350,10 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
 
         switch (c) {
         case OPT_DATAPATH_ID:
-            if (strlen(optarg) != 12
-                || strspn(optarg, "0123456789abcdefABCDEF") != 12) {
+            if (strlen(optarg) != 16
+                || strspn(optarg, "0123456789abcdefABCDEF") != 16) {
                 ovs_fatal(0, "argument to --datapath-id must be "
-                          "exactly 12 hex digits");
+                          "exactly 16 hex digits");
             }
             s->datapath_id = strtoll(optarg, NULL, 16);
             if (!s->datapath_id) {
@@ -337,6 +377,10 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
             s->serial_desc = optarg;
             break;
 
+        case OPT_DP_DESC:
+            s->dp_desc = optarg;
+            break;
+
         case OPT_ACCEPT_VCONN:
             s->accept_controller_re = optarg;
             break;
@@ -351,8 +395,7 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
             } else if (!strcmp(optarg, "closed")) {
                 s->fail_mode = FAIL_CLOSED;
             } else {
-                ovs_fatal(0, "-f or --fail argument must be \"open\" "
-                          "or \"closed\"");
+                ovs_fatal(0, "--fail argument must be \"open\" or \"closed\"");
             }
             break;
 
@@ -433,10 +476,10 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
             break;
 
         case OPT_MGMT_ID:
-            if (strlen(optarg) != 12
-                || strspn(optarg, "0123456789abcdefABCDEF") != 12) {
+            if (strlen(optarg) != 16
+                || strspn(optarg, "0123456789abcdefABCDEF") != 16) {
                 ovs_fatal(0, "argument to --mgmt-id must be "
-                          "exactly 12 hex digits");
+                          "exactly 16 hex digits");
             }
             s->mgmt_id = strtoll(optarg, NULL, 16);
             if (!s->mgmt_id) {
@@ -452,6 +495,10 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
             svec_add(&s->snoops, optarg);
             break;
 
+        case OPT_PORTS:
+            svec_split(&s->ports, optarg, ",");
+            break;
+
         case 'h':
             usage();
 
@@ -523,13 +570,14 @@ usage(void)
     vconn_usage(true, true, true);
     printf("\nOpenFlow options:\n"
            "  -d, --datapath-id=ID    Use ID as the OpenFlow switch ID\n"
-           "                          (ID must consist of 12 hex digits)\n"
+           "                          (ID must consist of 16 hex digits)\n"
            "  --mgmt-id=ID            Use ID as the management ID\n"
-           "                          (ID must consist of 12 hex digits)\n"
+           "                          (ID must consist of 16 hex digits)\n"
            "  --manufacturer=MFR      Identify manufacturer as MFR\n"
            "  --hardware=HW           Identify hardware as HW\n"
            "  --software=SW           Identify software as SW\n"
            "  --serial=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"
@@ -540,7 +588,7 @@ usage(void)
            "  --inactivity-probe=SECS time between inactivity probes\n"
            "  --max-idle=SECS         max idle for flows set up by switch\n"
            "  --max-backoff=SECS      max time between controller connection\n"
-           "                          attempts (default: 15 seconds)\n"
+           "                          attempts (default: 8 seconds)\n"
            "  -l, --listen=METHOD     allow management connections on METHOD\n"
            "                          (a passive OpenFlow connection method)\n"
            "  --snoop=METHOD          allow controller snooping on METHOD\n"