Rename "controller" to "ovs-controller" and move to utilities.
authorBen Pfaff <blp@nicira.com>
Fri, 15 May 2009 18:02:08 +0000 (11:02 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 15 May 2009 18:09:33 +0000 (11:09 -0700)
The controller is unimportant and we don't want people thinking that it is
important.  (They should be using NOX, not the OpenVSwitch controller.)
So kill off its top-level directory.

20 files changed:
COPYING
INSTALL
Makefile.am
README
controller/.gitignore [deleted file]
controller/automake.mk [deleted file]
controller/controller.8.in [deleted file]
controller/controller.c [deleted file]
debian/openvswitch-controller.init
debian/openvswitch-controller.install
debian/openvswitch-controller.manpages
secchan/.gitignore
secchan/secchan.8.in
utilities/.gitignore
utilities/automake.mk
utilities/dpctl.8.in
utilities/ovs-controller.8.in [new file with mode: 0644]
utilities/ovs-controller.c [new file with mode: 0644]
utilities/vlogconf.8.in
xenserver/vswitch-xen.spec

diff --git a/COPYING b/COPYING
index c70d12658374ea2d9aa8c241299c2b9a935a7d6a..ee6072ef34f14f230ebe542970a54eb5cc0f6feb 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -2,8 +2,8 @@ This file is a summary of the licensing of files in this distribution.
 Some files may be marked specifically with a different license, in
 which case that license applies to the file in question.
 
-Files under the controller, debian, doc, include, lib, m4, secchan,
-tests, third-party, and utilities directories are licensed under the
+Files under the debian, doc, include, lib, m4, secchan, tests,
+third-party, and utilities directories are licensed under the
 following "OpenFlow license":
 
     We are making the OpenFlow specification and associated documentation
diff --git a/INSTALL b/INSTALL
index d8332352e2538bc027c1ceecf178af949ac350f2..888ab01664a7b2c26f8fadff95531f60e84e3960 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -22,9 +22,7 @@ The current version of this distribution requires a kernel module to
 be built and loaded.  An (optional) entirely userspace switch is on
 the roadmap for future versions.
 
-The reference implementation also contains a simple OpenFlow
-controller (built as controller/controller) and a number of related
-utilities.
+The distribution also contains a number of related utilities.
 
 Build Methods
 =============
@@ -158,7 +156,7 @@ distribution in the ordinary way using "configure" and "make".
 
    Some less important binaries will be built also:
 
-      - Controller executable: controller/controller.
+      - Simple OpenFlow controller: utilities/ovs-controller.
 
       - Secure channel executable: secchan/secchan.
 
@@ -303,12 +301,12 @@ Controller Setup
 ----------------
 
 On the machine that is to be the OpenFlow controller, start the
-"controller" program listening for connections from switches on TCP
-port 6633 (the default), as shown below.
+"ovs-controller" program listening for connections from switches on
+TCP port 6633 (the default), as shown below.
 
-   # controller -v ptcp:
+   # ovs-controller -v ptcp:
 
-(See controller(8) for more details)
+(See ovs-controller(8) for more details)
 
 Make sure the machine hosting the controller is reachable by the
 switch.
@@ -423,7 +421,7 @@ Public Key Infrastructure" below.
 To configure the controller to listen for SSL connections on port 6633
 (the default), invoke it as follows:
 
-      # controller -v pssl: --private-key=PRIVKEY --certificate=CERT \
+      # ovs-controller -v pssl: --private-key=PRIVKEY --certificate=CERT \
             --ca-cert=CACERT
 
 where PRIVKEY is a file containing the controller's private key, CERT
@@ -432,7 +430,7 @@ controller's public key, and CACERT is a file containing the root
 certificate for the switch CA.  If, for example, your PKI was created
 with the instructions below, then the invocation would look like:
 
-      # controller -v pssl: --private-key=ctl-privkey.pem \
+      # ovs-controller -v pssl: --private-key=ctl-privkey.pem \
             --certificate=ctl-cert.pem --ca-cert=pki/switchca/cacert.pem
 
 To configure a switch to connect to a controller running on port 6633
@@ -500,7 +498,7 @@ and ctl-cert.pem, for example, you could run:
 ctl-privkey.pem and ctl-cert.pem would need to be copied to the
 controller for its use at runtime (they could then be deleted from
 their original locations).  The --private-key and --certificate
-options of controller, respectively, would point to these files.
+options of ovs-controller, respectively, would point to these files.
 
 Analogously, to create a switch private key and certificate in files
 named sc-privkey.pem and sc-cert.pem, for example, you could run: 
index b3c98c8a55cb6b5c7b24c50b2d829a77bac6d64a..5a3be38e3b6c434606793a7e00d18237acfd4b00 100644 (file)
@@ -61,7 +61,6 @@ SUFFIXES = .in
 
 include lib/automake.mk
 include secchan/automake.mk
-include controller/automake.mk
 include utilities/automake.mk
 include tests/automake.mk
 include include/automake.mk
diff --git a/README b/README
index 44afd79887487498a7c346391a2bc1012c355f04..7b5cc9cddf0a5b42f0ad84a44ae4bcc7b40e5dd6 100644 (file)
--- a/README
+++ b/README
@@ -37,10 +37,10 @@ This distribution includes some additional software as well:
           (without the special features provided by vswitchd) using
           the same kernel module as vswitchd.
 
-       - controller, a simple OpenFlow switch
+       - ovs-controller, a simple OpenFlow switch
 
        - vlogconf, a utility that can adjust the logging levels of a
-          running secchan or controller.
+          running secchan, ovs-controller, or vswitchd.
 
        - ovs-pki, a utility for creating and managing the public-key
           infrastructure for OpenFlow switches.
diff --git a/controller/.gitignore b/controller/.gitignore
deleted file mode 100644 (file)
index 8736bbc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/Makefile
-/Makefile.in
-/controller
-/controller.8
diff --git a/controller/automake.mk b/controller/automake.mk
deleted file mode 100644 (file)
index 80b14da..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-bin_PROGRAMS += controller/controller
-man_MANS += controller/controller.8
-DISTCLEANFILES += controller/controller.8
-
-controller_controller_SOURCES = controller/controller.c
-controller_controller_LDADD = lib/libopenvswitch.a $(FAULT_LIBS) $(SSL_LIBS)
-
-EXTRA_DIST += controller/controller.8.in
diff --git a/controller/controller.8.in b/controller/controller.8.in
deleted file mode 100644 (file)
index 0e29566..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-.TH controller 8 "March 2009" "OpenVSwitch" "OpenVSwitch Manual"
-.ds PN controller
-
-.SH NAME
-controller \- simple OpenFlow controller reference implementation
-
-.SH SYNOPSIS
-.B controller
-[\fIoptions\fR] \fImethod\fR \fB[\fImethod\fR]\&...
-
-.SH DESCRIPTION
-\fBcontroller\fR manages any number of remote switches over OpenFlow
-protocol, causing them to function as L2 MAC-learning switches or hub.
-
-\fBcontroller\fR controls one or more OpenFlow switches, specified as
-one or more of the following OpenFlow connection methods:
-
-.TP
-\fBpssl:\fR[\fIport\fR]
-Listens for SSL connections from remote OpenFlow switches on
-\fIport\fR (default: 6633).  The \fB--private-key\fR,
-\fB--certificate\fR, and \fB--ca-cert\fR options are mandatory when
-this form is used.
-
-.TP
-\fBptcp:\fR[\fIport\fR]
-Listens for TCP connections from remote OpenFlow switches on
-\fIport\fR (default: 6633).
-
-.TP
-\fBpunix:\fIfile\fR
-Listens for connections from OpenFlow switches on the Unix domain
-server socket named \fIfile\fR.
-
-.TP
-\fBssl:\fIhost\fR[\fB:\fIport\fR]
-The specified SSL \fIport\fR (default: 6633) on the given remote
-\fIhost\fR.  The \fB--private-key\fR, \fB--certificate\fR, and
-\fB--ca-cert\fR options are mandatory when this form is used.
-
-.TP
-\fBtcp:\fIhost\fR[\fB:\fIport\fR]
-The specified TCP \fIport\fR (default: 6633) on the given remote
-\fIhost\fR.
-
-.TP
-\fBunix:\fIfile\fR
-The Unix domain server socket named \fIfile\fR.
-
-.SH OPTIONS
-.TP
-\fB-p\fR, \fB--private-key=\fIprivkey.pem\fR
-Specifies a PEM file containing the private key used as the switch's
-identity for SSL connections to the controller.
-
-.TP
-\fB-c\fR, \fB--certificate=\fIcert.pem\fR
-Specifies a PEM file containing a certificate, signed by the
-controller's certificate authority (CA), that certifies the switch's
-private key to identify a trustworthy switch.
-
-.TP
-\fB-C\fR, \fB--ca-cert=\fIswitch-cacert.pem\fR
-Specifies a PEM file containing the CA certificate used to verify that
-the switch is connected to a trustworthy controller.
-
-.TP
-\fB--peer-ca-cert=\fIcontroller-cacert.pem\fR
-Specifies a PEM file that contains one or more additional certificates
-to send to switches.  \fIcontroller-cacert.pem\fR should be the CA
-certificate used to sign the controller's own certificate (the
-certificate specified on \fB-c\fR or \fB--certificate\fR).
-
-This option is not useful in normal operation, because the switch must
-already have the controller CA certificate for it to have any
-confidence in the controller's identity.  However, this option allows
-a newly installed switch to obtain the controller CA certificate on
-first boot using, e.g., the \fB--bootstrap-ca-cert\fR option to
-\fBsecchan\fR(8).
-
-.IP "\fB-n\fR, \fB--noflow\fR"
-By default, the controller sets up a flow in each OpenFlow switch
-whenever it receives a packet whose destination is known due through
-MAC learning.  This option disables flow setup, so that every packet
-in the network passes through the controller.
-
-This option is most useful for debugging.  It reduces switching
-performance, so it should not be used in production.
-
-.TP
-\fB--max-idle=\fIsecs\fR|\fBpermanent\fR
-Sets \fIsecs\fR as the number of seconds that a flow set up by the
-controller will remain in the switch's flow table without any matching
-packets being seen.  If \fBpermanent\fR is specified, which is not
-recommended, flows will never expire.  The default is 60 seconds.
-
-This option affects only flows set up by the OpenFlow controller.  In
-some configurations, the switch can set up some flows
-on its own.  To set the idle time for those flows, pass
-\fB--max-idle\fR to \fBsecchan\fR (on the switch).
-
-This option has no effect when \fB-n\fR (or \fB--noflow\fR) is in use
-(because the controller does not set up flows in that case).
-
-.IP "\fB-H\fR, \fB--hub\fR"
-By default, the controller acts as an L2 MAC-learning switch.  This
-option changes its behavior to that of a hub that floods packets on
-all but the incoming port.
-
-If \fB-H\fR (or \fB--hub\fR) and \fB-n\fR (or \fB--noflow\fR) are used
-together, then the cumulative effect is that every packet passes
-through the controller and every packet is flooded.
-
-This option is most useful for debugging.  It reduces switching
-performance, so it should not be used in production.
-
-.so lib/daemon.man
-.so lib/vlog.man
-.so lib/common.man
-
-.SH EXAMPLES
-
-.TP
-To bind locally to port 6633 (the default) and wait for incoming connections from OpenFlow switches:
-
-.B % controller ptcp:
-
-.SH "SEE ALSO"
-
-.BR dpctl (8),
-.BR secchan (8),
-.BR udatapath (8),
-.BR vlogconf (8)
diff --git a/controller/controller.c b/controller/controller.c
deleted file mode 100644 (file)
index d67bc98..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-/* Copyright (c) 2008, 2009 The Board of Trustees of The Leland Stanford
- * Junior University
- * 
- * We are making the OpenFlow specification and associated documentation
- * (Software) available for public use and benefit with the expectation
- * that others will use, modify and enhance the Software and contribute
- * those enhancements back to the community. However, since we would
- * like to make the Software available for broadest use, with as few
- * restrictions as possible permission is hereby granted, free of
- * charge, to any person obtaining a copy of this Software to deal in
- * the Software under the copyrights without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- * 
- * The name and trademarks of copyright holder(s) may NOT be used in
- * advertising or publicity pertaining to the Software or any
- * derivatives without specific, written prior permission.
- */
-
-#include <config.h>
-
-#include <errno.h>
-#include <getopt.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "command-line.h"
-#include "compiler.h"
-#include "daemon.h"
-#include "fault.h"
-#include "learning-switch.h"
-#include "ofpbuf.h"
-#include "openflow/openflow.h"
-#include "poll-loop.h"
-#include "rconn.h"
-#include "timeval.h"
-#include "unixctl.h"
-#include "util.h"
-#include "vconn-ssl.h"
-#include "vconn.h"
-
-#include "vlog.h"
-#define THIS_MODULE VLM_controller
-
-#define MAX_SWITCHES 16
-#define MAX_LISTENERS 16
-
-struct switch_ {
-    struct lswitch *lswitch;
-    struct rconn *rconn;
-};
-
-/* Learn the ports on which MAC addresses appear? */
-static bool learn_macs = true;
-
-/* Set up flows?  (If not, every packet is processed at the controller.) */
-static bool setup_flows = true;
-
-/* --max-idle: Maximum idle time, in seconds, before flows expire. */
-static int max_idle = 60;
-
-static int do_switching(struct switch_ *);
-static void new_switch(struct switch_ *, struct vconn *, const char *name);
-static void parse_options(int argc, char *argv[]);
-static void usage(void) NO_RETURN;
-
-int
-main(int argc, char *argv[])
-{
-    struct unixctl_server *unixctl;
-    struct switch_ switches[MAX_SWITCHES];
-    struct pvconn *listeners[MAX_LISTENERS];
-    int n_switches, n_listeners;
-    int retval;
-    int i;
-
-    set_program_name(argv[0]);
-    register_fault_handlers();
-    time_init();
-    vlog_init();
-    parse_options(argc, argv);
-    signal(SIGPIPE, SIG_IGN);
-
-    if (argc - optind < 1) {
-        ovs_fatal(0, "at least one vconn argument required; "
-                  "use --help for usage");
-    }
-
-    n_switches = n_listeners = 0;
-    for (i = optind; i < argc; i++) {
-        const char *name = argv[i];
-        struct vconn *vconn;
-        int retval;
-
-        retval = vconn_open(name, OFP_VERSION, &vconn);
-        if (!retval) {
-            if (n_switches >= MAX_SWITCHES) {
-                ovs_fatal(0, "max %d switch connections", n_switches);
-            }
-            new_switch(&switches[n_switches++], vconn, name);
-            continue;
-        } else if (retval == EAFNOSUPPORT) {
-            struct pvconn *pvconn;
-            retval = pvconn_open(name, &pvconn);
-            if (!retval) {
-                if (n_listeners >= MAX_LISTENERS) {
-                    ovs_fatal(0, "max %d passive connections", n_listeners);
-                }
-                listeners[n_listeners++] = pvconn;
-            }
-        }
-        if (retval) {
-            VLOG_ERR("%s: connect: %s", name, strerror(retval));
-        }
-    }
-    if (n_switches == 0 && n_listeners == 0) {
-        ovs_fatal(0, "no active or passive switch connections");
-    }
-
-    die_if_already_running();
-    daemonize();
-
-    retval = unixctl_server_create(NULL, &unixctl);
-    if (retval) {
-        ovs_fatal(retval, "Could not listen for unixctl connections");
-    }
-
-    while (n_switches > 0 || n_listeners > 0) {
-        int iteration;
-        int i;
-
-        /* Accept connections on listening vconns. */
-        for (i = 0; i < n_listeners && n_switches < MAX_SWITCHES; ) {
-            struct vconn *new_vconn;
-            int retval;
-
-            retval = pvconn_accept(listeners[i], OFP_VERSION, &new_vconn);
-            if (!retval || retval == EAGAIN) {
-                if (!retval) {
-                    new_switch(&switches[n_switches++], new_vconn, "tcp");
-                }
-                i++;
-            } else {
-                pvconn_close(listeners[i]);
-                listeners[i] = listeners[--n_listeners];
-            }
-        }
-
-        /* Do some switching work.  Limit the number of iterations so that
-         * callbacks registered with the poll loop don't starve. */
-        for (iteration = 0; iteration < 50; iteration++) {
-            bool progress = false;
-            for (i = 0; i < n_switches; ) {
-                struct switch_ *this = &switches[i];
-                int retval = do_switching(this);
-                if (!retval || retval == EAGAIN) {
-                    if (!retval) {
-                        progress = true;
-                    }
-                    i++;
-                } else {
-                    rconn_destroy(this->rconn);
-                    lswitch_destroy(this->lswitch);
-                    switches[i] = switches[--n_switches];
-                }
-            }
-            if (!progress) {
-                break;
-            }
-        }
-        for (i = 0; i < n_switches; i++) {
-            struct switch_ *this = &switches[i];
-            lswitch_run(this->lswitch, this->rconn);
-        }
-
-        unixctl_server_run(unixctl);
-
-        /* Wait for something to happen. */
-        if (n_switches < MAX_SWITCHES) {
-            for (i = 0; i < n_listeners; i++) {
-                pvconn_wait(listeners[i]);
-            }
-        }
-        for (i = 0; i < n_switches; i++) {
-            struct switch_ *sw = &switches[i];
-            rconn_run_wait(sw->rconn);
-            rconn_recv_wait(sw->rconn);
-            lswitch_wait(sw->lswitch);
-        }
-        unixctl_server_wait(unixctl);
-        poll_block();
-    }
-
-    return 0;
-}
-
-static void
-new_switch(struct switch_ *sw, struct vconn *vconn, const char *name)
-{
-    sw->rconn = rconn_new_from_vconn(name, vconn);
-    sw->lswitch = lswitch_create(sw->rconn, learn_macs,
-                                 setup_flows ? max_idle : -1);
-}
-
-static int
-do_switching(struct switch_ *sw)
-{
-    unsigned int packets_sent;
-    struct ofpbuf *msg;
-
-    packets_sent = rconn_packets_sent(sw->rconn);
-
-    msg = rconn_recv(sw->rconn);
-    if (msg) {
-        lswitch_process_packet(sw->lswitch, sw->rconn, msg);
-        ofpbuf_delete(msg);
-    }
-    rconn_run(sw->rconn);
-
-    return (!rconn_is_alive(sw->rconn) ? EOF
-            : rconn_packets_sent(sw->rconn) != packets_sent ? 0
-            : EAGAIN);
-}
-
-static void
-parse_options(int argc, char *argv[])
-{
-    enum {
-        OPT_MAX_IDLE = UCHAR_MAX + 1,
-        OPT_PEER_CA_CERT,
-        VLOG_OPTION_ENUMS
-    };
-    static struct option long_options[] = {
-        {"hub",         no_argument, 0, 'H'},
-        {"noflow",      no_argument, 0, 'n'},
-        {"max-idle",    required_argument, 0, OPT_MAX_IDLE},
-        {"help",        no_argument, 0, 'h'},
-        {"version",     no_argument, 0, 'V'},
-        DAEMON_LONG_OPTIONS,
-        VLOG_LONG_OPTIONS,
-#ifdef HAVE_OPENSSL
-        VCONN_SSL_LONG_OPTIONS
-        {"peer-ca-cert", required_argument, 0, OPT_PEER_CA_CERT},
-#endif
-        {0, 0, 0, 0},
-    };
-    char *short_options = long_options_to_short_options(long_options);
-
-    for (;;) {
-        int indexptr;
-        int c;
-
-        c = getopt_long(argc, argv, short_options, long_options, &indexptr);
-        if (c == -1) {
-            break;
-        }
-
-        switch (c) {
-        case 'H':
-            learn_macs = false;
-            break;
-
-        case 'n':
-            setup_flows = false;
-            break;
-
-        case OPT_MAX_IDLE:
-            if (!strcmp(optarg, "permanent")) {
-                max_idle = OFP_FLOW_PERMANENT;
-            } else {
-                max_idle = atoi(optarg);
-                if (max_idle < 1 || max_idle > 65535) {
-                    ovs_fatal(0, "--max-idle argument must be between 1 and "
-                              "65535 or the word 'permanent'");
-                }
-            }
-            break;
-
-        case 'h':
-            usage();
-
-        case 'V':
-            printf("%s "VERSION" compiled "__DATE__" "__TIME__"\n", argv[0]);
-            exit(EXIT_SUCCESS);
-
-        VLOG_OPTION_HANDLERS
-        DAEMON_OPTION_HANDLERS
-
-#ifdef HAVE_OPENSSL
-        VCONN_SSL_OPTION_HANDLERS
-
-        case OPT_PEER_CA_CERT:
-            vconn_ssl_set_peer_ca_cert_file(optarg);
-            break;
-#endif
-
-        case '?':
-            exit(EXIT_FAILURE);
-
-        default:
-            abort();
-        }
-    }
-    free(short_options);
-}
-
-static void
-usage(void)
-{
-    printf("%s: OpenFlow controller\n"
-           "usage: %s [OPTIONS] METHOD\n"
-           "where METHOD is any OpenFlow connection method.\n",
-           program_name, program_name);
-    vconn_usage(true, true, false);
-    daemon_usage();
-    vlog_usage();
-    printf("\nOther options:\n"
-           "  -H, --hub               act as hub instead of learning switch\n"
-           "  -n, --noflow            pass traffic, but don't add flows\n"
-           "  --max-idle=SECS         max idle time for new flows\n"
-           "  -h, --help              display this help message\n"
-           "  -V, --version           display version information\n");
-    exit(EXIT_SUCCESS);
-}
index c4716a92a25949005d07631079a70214179da8b5..43a9c5334a80b2c140694691f099b93821ace024 100755 (executable)
@@ -31,8 +31,8 @@
 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
 DAEMON=/usr/sbin/controller # Introduce the server's location here
-NAME=controller             # Introduce the short server's name here
-DESC=controller             # Introduce a short description here
+NAME=ovs-controller         # Introduce the short server's name here
+DESC=ovs-controller         # Introduce a short description here
 LOGDIR=/var/log/openvswitch # Log directory to use
 
 PIDFILE=/var/run/$NAME.pid 
index 3932ab6a67eda12d48f2720795023195e46ee3a6..7d0edbbed01af4603e7eee54271f5c86c3e2c5a4 100644 (file)
@@ -1 +1 @@
-_debian/controller/controller usr/sbin
+_debian/utilities/ovs-controller usr/sbin
index 3fbaaeaf4e1f177cdf1fa95ba4cf762e3a7db6a5..6a9911e1e2745bd02bae836d943980d0d0e51de5 100644 (file)
@@ -1 +1 @@
-_debian/controller/controller.8
+_debian/utilities/ovs-controller.8
index 930a188e86ddc0168a6e868971d79352366571a1..ada6566557e099de113866bc285de839bbba4a38 100644 (file)
@@ -1,7 +1,4 @@
 /Makefile
 /Makefile.in
-/controller-lite
-/ctlpath-lite
-/dpctl-lite
 /secchan
 /secchan.8
index a9e5e5205b5b77c30b839e5f586b6b6d37154845..e813c29ebb125b7fbabadb5564e42ce7323aa958 100644 (file)
@@ -456,7 +456,7 @@ require the controller to send the CA certificate, but
 
 .BR dpctl (8),
 .BR ovs-discover (8),
-.BR controller (8),
+.BR ovs\-controller (8),
 .BR ovs-pki (8),
 .BR udatapath (8),
 .BR vlogconf (8),
index eed86ca267c717c784f82e365d0279573498e8e4..b54ac1c2824f122d469880772365abaa9b370bad 100644 (file)
@@ -5,6 +5,8 @@
 /dpctl
 /dpctl.8
 /nlmon
+/ovs-controller
+/ovs-controller.8
 /ovs-discover
 /ovs-discover.8
 /ovs-kill
index 5c7030fbb0e7a0900eb548ffe1bc8bbcc97c0a4c..8f3fb605f46ff5fdc4b55655f6635f8915d91e06 100644 (file)
@@ -2,6 +2,7 @@ bin_PROGRAMS += \
        utilities/vlogconf \
        utilities/cfg-mod \
        utilities/dpctl \
+       utilities/ovs-controller \
        utilities/ovs-discover \
        utilities/ovs-kill \
        utilities/ovs-wdt
@@ -13,6 +14,7 @@ dist_sbin_SCRIPTS += utilities/ovs-monitor
 EXTRA_DIST += \
        utilities/cfg-mod.8.in \
        utilities/dpctl.8.in \
+       utilities/ovs-controller.8.in \
        utilities/ovs-discover.8.in \
        utilities/ovs-kill.8.in \
        utilities/ovs-parse-leaks.in \
@@ -23,6 +25,7 @@ EXTRA_DIST += \
 DISTCLEANFILES += \
        utilities/cfg-mod.8 \
        utilities/dpctl.8 \
+       utilities/ovs-controller.8 \
        utilities/ovs-discover.8 \
        utilities/ovs-kill.8 \
        utilities/ovs-parse-leaks \
@@ -34,6 +37,7 @@ DISTCLEANFILES += \
 man_MANS += \
        utilities/cfg-mod.8 \
        utilities/dpctl.8 \
+       utilities/ovs-controller.8 \
        utilities/ovs-discover.8 \
        utilities/ovs-kill.8 \
        utilities/ovs-pki.8 \
@@ -48,6 +52,9 @@ utilities_dpctl_LDADD = lib/libopenvswitch.a $(FAULT_LIBS) $(SSL_LIBS)
 utilities_vlogconf_SOURCES = utilities/vlogconf.c
 utilities_vlogconf_LDADD = lib/libopenvswitch.a
 
+utilities_ovs_controller_SOURCES = utilities/ovs-controller.c
+utilities_ovs_controller_LDADD = lib/libopenvswitch.a $(FAULT_LIBS) $(SSL_LIBS)
+
 utilities_ovs_discover_SOURCES = utilities/ovs-discover.c
 utilities_ovs_discover_LDADD = lib/libopenvswitch.a
 
index 34f428122157f2e915503de82a4b1e5615d2d682..349587dbcb1c1c2924fc92a0db7ce71d3acd455c 100644 (file)
@@ -641,6 +641,6 @@ Prints the flow entries in the switch.
 
 .BR vswitchd (8),
 .BR secchan (8),
-.BR controller (8),
+.BR ovs\-controller (8),
 .BR udatapath (8),
 .BR vlogconf (8)
diff --git a/utilities/ovs-controller.8.in b/utilities/ovs-controller.8.in
new file mode 100644 (file)
index 0000000..4f715a0
--- /dev/null
@@ -0,0 +1,133 @@
+.TH ovs\-controller 8 "March 2009" "OpenVSwitch" "OpenVSwitch Manual"
+.ds PN ovs\-controller
+
+.SH NAME
+ovs\-controller \- simple OpenFlow controller reference implementation
+
+.SH SYNOPSIS
+.B ovs\-controller
+[\fIoptions\fR] \fImethod\fR \fB[\fImethod\fR]\&...
+
+.SH DESCRIPTION
+\fBovs\-controller\fR manages any number of remote switches over OpenFlow
+protocol, causing them to function as L2 MAC-learning switches or hub.
+
+\fBovs\-controller\fR controls one or more OpenFlow switches, specified as
+one or more of the following OpenFlow connection methods:
+
+.TP
+\fBpssl:\fR[\fIport\fR]
+Listens for SSL connections from remote OpenFlow switches on
+\fIport\fR (default: 6633).  The \fB--private-key\fR,
+\fB--certificate\fR, and \fB--ca-cert\fR options are mandatory when
+this form is used.
+
+.TP
+\fBptcp:\fR[\fIport\fR]
+Listens for TCP connections from remote OpenFlow switches on
+\fIport\fR (default: 6633).
+
+.TP
+\fBpunix:\fIfile\fR
+Listens for connections from OpenFlow switches on the Unix domain
+server socket named \fIfile\fR.
+
+.TP
+\fBssl:\fIhost\fR[\fB:\fIport\fR]
+The specified SSL \fIport\fR (default: 6633) on the given remote
+\fIhost\fR.  The \fB--private-key\fR, \fB--certificate\fR, and
+\fB--ca-cert\fR options are mandatory when this form is used.
+
+.TP
+\fBtcp:\fIhost\fR[\fB:\fIport\fR]
+The specified TCP \fIport\fR (default: 6633) on the given remote
+\fIhost\fR.
+
+.TP
+\fBunix:\fIfile\fR
+The Unix domain server socket named \fIfile\fR.
+
+.SH OPTIONS
+.TP
+\fB-p\fR, \fB--private-key=\fIprivkey.pem\fR
+Specifies a PEM file containing the private key used as the switch's
+identity for SSL connections to the controller.
+
+.TP
+\fB-c\fR, \fB--certificate=\fIcert.pem\fR
+Specifies a PEM file containing a certificate, signed by the
+controller's certificate authority (CA), that certifies the switch's
+private key to identify a trustworthy switch.
+
+.TP
+\fB-C\fR, \fB--ca-cert=\fIswitch-cacert.pem\fR
+Specifies a PEM file containing the CA certificate used to verify that
+the switch is connected to a trustworthy controller.
+
+.TP
+\fB--peer-ca-cert=\fIcontroller-cacert.pem\fR
+Specifies a PEM file that contains one or more additional certificates
+to send to switches.  \fIcontroller-cacert.pem\fR should be the CA
+certificate used to sign the controller's own certificate (the
+certificate specified on \fB-c\fR or \fB--certificate\fR).
+
+This option is not useful in normal operation, because the switch must
+already have the controller CA certificate for it to have any
+confidence in the controller's identity.  However, this option allows
+a newly installed switch to obtain the controller CA certificate on
+first boot using, e.g., the \fB--bootstrap-ca-cert\fR option to
+\fBsecchan\fR(8).
+
+.IP "\fB-n\fR, \fB--noflow\fR"
+By default, \fBovs\-controller\fR sets up a flow in each OpenFlow switch
+whenever it receives a packet whose destination is known due through
+MAC learning.  This option disables flow setup, so that every packet
+in the network passes through the controller.
+
+This option is most useful for debugging.  It reduces switching
+performance, so it should not be used in production.
+
+.TP
+\fB--max-idle=\fIsecs\fR|\fBpermanent\fR
+Sets \fIsecs\fR as the number of seconds that a flow set up by the
+controller will remain in the switch's flow table without any matching
+packets being seen.  If \fBpermanent\fR is specified, which is not
+recommended, flows will never expire.  The default is 60 seconds.
+
+This option affects only flows set up by the OpenFlow controller.  In
+some configurations, the switch can set up some flows
+on its own.  To set the idle time for those flows, pass
+\fB--max-idle\fR to \fBsecchan\fR (on the switch).
+
+This option has no effect when \fB-n\fR (or \fB--noflow\fR) is in use
+(because the controller does not set up flows in that case).
+
+.IP "\fB-H\fR, \fB--hub\fR"
+By default, the controller acts as an L2 MAC-learning switch.  This
+option changes its behavior to that of a hub that floods packets on
+all but the incoming port.
+
+If \fB-H\fR (or \fB--hub\fR) and \fB-n\fR (or \fB--noflow\fR) are used
+together, then the cumulative effect is that every packet passes
+through the controller and every packet is flooded.
+
+This option is most useful for debugging.  It reduces switching
+performance, so it should not be used in production.
+
+.so lib/daemon.man
+.so lib/vlog.man
+.so lib/common.man
+
+.SH EXAMPLES
+
+.TP
+To bind locally to port 6633 (the default) and wait for incoming connections from OpenFlow switches:
+
+.B % ovs\-controller ptcp:
+
+.SH "SEE ALSO"
+
+.BR dpctl (8),
+.BR secchan (8),
+.BR udatapath (8),
+.BR vlogconf (8)
diff --git a/utilities/ovs-controller.c b/utilities/ovs-controller.c
new file mode 100644 (file)
index 0000000..d67bc98
--- /dev/null
@@ -0,0 +1,340 @@
+/* Copyright (c) 2008, 2009 The Board of Trustees of The Leland Stanford
+ * Junior University
+ * 
+ * We are making the OpenFlow specification and associated documentation
+ * (Software) available for public use and benefit with the expectation
+ * that others will use, modify and enhance the Software and contribute
+ * those enhancements back to the community. However, since we would
+ * like to make the Software available for broadest use, with as few
+ * restrictions as possible permission is hereby granted, free of
+ * charge, to any person obtaining a copy of this Software to deal in
+ * the Software under the copyrights without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * 
+ * The name and trademarks of copyright holder(s) may NOT be used in
+ * advertising or publicity pertaining to the Software or any
+ * derivatives without specific, written prior permission.
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "command-line.h"
+#include "compiler.h"
+#include "daemon.h"
+#include "fault.h"
+#include "learning-switch.h"
+#include "ofpbuf.h"
+#include "openflow/openflow.h"
+#include "poll-loop.h"
+#include "rconn.h"
+#include "timeval.h"
+#include "unixctl.h"
+#include "util.h"
+#include "vconn-ssl.h"
+#include "vconn.h"
+
+#include "vlog.h"
+#define THIS_MODULE VLM_controller
+
+#define MAX_SWITCHES 16
+#define MAX_LISTENERS 16
+
+struct switch_ {
+    struct lswitch *lswitch;
+    struct rconn *rconn;
+};
+
+/* Learn the ports on which MAC addresses appear? */
+static bool learn_macs = true;
+
+/* Set up flows?  (If not, every packet is processed at the controller.) */
+static bool setup_flows = true;
+
+/* --max-idle: Maximum idle time, in seconds, before flows expire. */
+static int max_idle = 60;
+
+static int do_switching(struct switch_ *);
+static void new_switch(struct switch_ *, struct vconn *, const char *name);
+static void parse_options(int argc, char *argv[]);
+static void usage(void) NO_RETURN;
+
+int
+main(int argc, char *argv[])
+{
+    struct unixctl_server *unixctl;
+    struct switch_ switches[MAX_SWITCHES];
+    struct pvconn *listeners[MAX_LISTENERS];
+    int n_switches, n_listeners;
+    int retval;
+    int i;
+
+    set_program_name(argv[0]);
+    register_fault_handlers();
+    time_init();
+    vlog_init();
+    parse_options(argc, argv);
+    signal(SIGPIPE, SIG_IGN);
+
+    if (argc - optind < 1) {
+        ovs_fatal(0, "at least one vconn argument required; "
+                  "use --help for usage");
+    }
+
+    n_switches = n_listeners = 0;
+    for (i = optind; i < argc; i++) {
+        const char *name = argv[i];
+        struct vconn *vconn;
+        int retval;
+
+        retval = vconn_open(name, OFP_VERSION, &vconn);
+        if (!retval) {
+            if (n_switches >= MAX_SWITCHES) {
+                ovs_fatal(0, "max %d switch connections", n_switches);
+            }
+            new_switch(&switches[n_switches++], vconn, name);
+            continue;
+        } else if (retval == EAFNOSUPPORT) {
+            struct pvconn *pvconn;
+            retval = pvconn_open(name, &pvconn);
+            if (!retval) {
+                if (n_listeners >= MAX_LISTENERS) {
+                    ovs_fatal(0, "max %d passive connections", n_listeners);
+                }
+                listeners[n_listeners++] = pvconn;
+            }
+        }
+        if (retval) {
+            VLOG_ERR("%s: connect: %s", name, strerror(retval));
+        }
+    }
+    if (n_switches == 0 && n_listeners == 0) {
+        ovs_fatal(0, "no active or passive switch connections");
+    }
+
+    die_if_already_running();
+    daemonize();
+
+    retval = unixctl_server_create(NULL, &unixctl);
+    if (retval) {
+        ovs_fatal(retval, "Could not listen for unixctl connections");
+    }
+
+    while (n_switches > 0 || n_listeners > 0) {
+        int iteration;
+        int i;
+
+        /* Accept connections on listening vconns. */
+        for (i = 0; i < n_listeners && n_switches < MAX_SWITCHES; ) {
+            struct vconn *new_vconn;
+            int retval;
+
+            retval = pvconn_accept(listeners[i], OFP_VERSION, &new_vconn);
+            if (!retval || retval == EAGAIN) {
+                if (!retval) {
+                    new_switch(&switches[n_switches++], new_vconn, "tcp");
+                }
+                i++;
+            } else {
+                pvconn_close(listeners[i]);
+                listeners[i] = listeners[--n_listeners];
+            }
+        }
+
+        /* Do some switching work.  Limit the number of iterations so that
+         * callbacks registered with the poll loop don't starve. */
+        for (iteration = 0; iteration < 50; iteration++) {
+            bool progress = false;
+            for (i = 0; i < n_switches; ) {
+                struct switch_ *this = &switches[i];
+                int retval = do_switching(this);
+                if (!retval || retval == EAGAIN) {
+                    if (!retval) {
+                        progress = true;
+                    }
+                    i++;
+                } else {
+                    rconn_destroy(this->rconn);
+                    lswitch_destroy(this->lswitch);
+                    switches[i] = switches[--n_switches];
+                }
+            }
+            if (!progress) {
+                break;
+            }
+        }
+        for (i = 0; i < n_switches; i++) {
+            struct switch_ *this = &switches[i];
+            lswitch_run(this->lswitch, this->rconn);
+        }
+
+        unixctl_server_run(unixctl);
+
+        /* Wait for something to happen. */
+        if (n_switches < MAX_SWITCHES) {
+            for (i = 0; i < n_listeners; i++) {
+                pvconn_wait(listeners[i]);
+            }
+        }
+        for (i = 0; i < n_switches; i++) {
+            struct switch_ *sw = &switches[i];
+            rconn_run_wait(sw->rconn);
+            rconn_recv_wait(sw->rconn);
+            lswitch_wait(sw->lswitch);
+        }
+        unixctl_server_wait(unixctl);
+        poll_block();
+    }
+
+    return 0;
+}
+
+static void
+new_switch(struct switch_ *sw, struct vconn *vconn, const char *name)
+{
+    sw->rconn = rconn_new_from_vconn(name, vconn);
+    sw->lswitch = lswitch_create(sw->rconn, learn_macs,
+                                 setup_flows ? max_idle : -1);
+}
+
+static int
+do_switching(struct switch_ *sw)
+{
+    unsigned int packets_sent;
+    struct ofpbuf *msg;
+
+    packets_sent = rconn_packets_sent(sw->rconn);
+
+    msg = rconn_recv(sw->rconn);
+    if (msg) {
+        lswitch_process_packet(sw->lswitch, sw->rconn, msg);
+        ofpbuf_delete(msg);
+    }
+    rconn_run(sw->rconn);
+
+    return (!rconn_is_alive(sw->rconn) ? EOF
+            : rconn_packets_sent(sw->rconn) != packets_sent ? 0
+            : EAGAIN);
+}
+
+static void
+parse_options(int argc, char *argv[])
+{
+    enum {
+        OPT_MAX_IDLE = UCHAR_MAX + 1,
+        OPT_PEER_CA_CERT,
+        VLOG_OPTION_ENUMS
+    };
+    static struct option long_options[] = {
+        {"hub",         no_argument, 0, 'H'},
+        {"noflow",      no_argument, 0, 'n'},
+        {"max-idle",    required_argument, 0, OPT_MAX_IDLE},
+        {"help",        no_argument, 0, 'h'},
+        {"version",     no_argument, 0, 'V'},
+        DAEMON_LONG_OPTIONS,
+        VLOG_LONG_OPTIONS,
+#ifdef HAVE_OPENSSL
+        VCONN_SSL_LONG_OPTIONS
+        {"peer-ca-cert", required_argument, 0, OPT_PEER_CA_CERT},
+#endif
+        {0, 0, 0, 0},
+    };
+    char *short_options = long_options_to_short_options(long_options);
+
+    for (;;) {
+        int indexptr;
+        int c;
+
+        c = getopt_long(argc, argv, short_options, long_options, &indexptr);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+        case 'H':
+            learn_macs = false;
+            break;
+
+        case 'n':
+            setup_flows = false;
+            break;
+
+        case OPT_MAX_IDLE:
+            if (!strcmp(optarg, "permanent")) {
+                max_idle = OFP_FLOW_PERMANENT;
+            } else {
+                max_idle = atoi(optarg);
+                if (max_idle < 1 || max_idle > 65535) {
+                    ovs_fatal(0, "--max-idle argument must be between 1 and "
+                              "65535 or the word 'permanent'");
+                }
+            }
+            break;
+
+        case 'h':
+            usage();
+
+        case 'V':
+            printf("%s "VERSION" compiled "__DATE__" "__TIME__"\n", argv[0]);
+            exit(EXIT_SUCCESS);
+
+        VLOG_OPTION_HANDLERS
+        DAEMON_OPTION_HANDLERS
+
+#ifdef HAVE_OPENSSL
+        VCONN_SSL_OPTION_HANDLERS
+
+        case OPT_PEER_CA_CERT:
+            vconn_ssl_set_peer_ca_cert_file(optarg);
+            break;
+#endif
+
+        case '?':
+            exit(EXIT_FAILURE);
+
+        default:
+            abort();
+        }
+    }
+    free(short_options);
+}
+
+static void
+usage(void)
+{
+    printf("%s: OpenFlow controller\n"
+           "usage: %s [OPTIONS] METHOD\n"
+           "where METHOD is any OpenFlow connection method.\n",
+           program_name, program_name);
+    vconn_usage(true, true, false);
+    daemon_usage();
+    vlog_usage();
+    printf("\nOther options:\n"
+           "  -H, --hub               act as hub instead of learning switch\n"
+           "  -n, --noflow            pass traffic, but don't add flows\n"
+           "  --max-idle=SECS         max idle time for new flows\n"
+           "  -h, --help              display this help message\n"
+           "  -V, --version           display version information\n");
+    exit(EXIT_SUCCESS);
+}
index 0c251929e36e7226ac909af8e23c205e616edbde..279e778cf5697cecb386c9010934dbc7453d6a96 100644 (file)
@@ -154,4 +154,4 @@ error occurs.  Use \fB-e help\fR to print a list of available commands.
 
 .BR dpctl (8),
 .BR secchan (8),
-.BR controller (8)
+.BR ovs\-controller (8)
index 381619854ff013ed5c4971c71222a39b453dacd2..035e461786cc94f058592c31997937f88dffde3f 100644 (file)
@@ -72,12 +72,12 @@ install -d -m 755 $RPM_BUILD_ROOT%{_prefix}/kernel_modules
 find datapath/linux-2.6 -name *.ko -exec install -m 755  \{\} $RPM_BUILD_ROOT%{_prefix}/kernel_modules/ \;
 
 # Get rid of stuff we don't want to make RPM happy.
-rm -rf $RPM_BUILD_ROOT/root/vswitch/bin/controller \
+rm -rf $RPM_BUILD_ROOT/root/vswitch/bin/ovs-controller \
     $RPM_BUILD_ROOT/root/vswitch/bin/ovs-* \
     $RPM_BUILD_ROOT/root/vswitch/bin/secchan \
     $RPM_BUILD_ROOT/root/vswitch/bin/ovs-wdt \
     $RPM_BUILD_ROOT/root/vswitch/sbin/ovs-monitor \
-    $RPM_BUILD_ROOT/root/vswitch/share/man/man8/controller.8 \
+    $RPM_BUILD_ROOT/root/vswitch/share/man/man8/ovs-controller.8 \
     $RPM_BUILD_ROOT/root/vswitch/share/man/man8/ovs-*.8 \
     $RPM_BUILD_ROOT/root/vswitch/share/man/man8/secchan.8 \
     $RPM_BUILD_ROOT/root/vswitch/share/openvswitch