From: Ben Pfaff Date: Fri, 15 May 2009 18:02:08 +0000 (-0700) Subject: Rename "controller" to "ovs-controller" and move to utilities. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ddb59830ffa4f9e55ec007bbeb0e70671a33cae3;p=openvswitch Rename "controller" to "ovs-controller" and move to utilities. 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. --- diff --git a/COPYING b/COPYING index c70d1265..ee6072ef 100644 --- 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 d8332352..888ab016 100644 --- 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: diff --git a/Makefile.am b/Makefile.am index b3c98c8a..5a3be38e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 44afd798..7b5cc9cd 100644 --- 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 index 8736bbc1..00000000 --- a/controller/.gitignore +++ /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 index 80b14da7..00000000 --- a/controller/automake.mk +++ /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 index 0e29566e..00000000 --- a/controller/controller.8.in +++ /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 index d67bc98b..00000000 --- a/controller/controller.c +++ /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 - -#include -#include -#include -#include -#include -#include - -#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); -} diff --git a/debian/openvswitch-controller.init b/debian/openvswitch-controller.init index c4716a92..43a9c533 100755 --- a/debian/openvswitch-controller.init +++ b/debian/openvswitch-controller.init @@ -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 diff --git a/debian/openvswitch-controller.install b/debian/openvswitch-controller.install index 3932ab6a..7d0edbbe 100644 --- a/debian/openvswitch-controller.install +++ b/debian/openvswitch-controller.install @@ -1 +1 @@ -_debian/controller/controller usr/sbin +_debian/utilities/ovs-controller usr/sbin diff --git a/debian/openvswitch-controller.manpages b/debian/openvswitch-controller.manpages index 3fbaaeaf..6a9911e1 100644 --- a/debian/openvswitch-controller.manpages +++ b/debian/openvswitch-controller.manpages @@ -1 +1 @@ -_debian/controller/controller.8 +_debian/utilities/ovs-controller.8 diff --git a/secchan/.gitignore b/secchan/.gitignore index 930a188e..ada65665 100644 --- a/secchan/.gitignore +++ b/secchan/.gitignore @@ -1,7 +1,4 @@ /Makefile /Makefile.in -/controller-lite -/ctlpath-lite -/dpctl-lite /secchan /secchan.8 diff --git a/secchan/secchan.8.in b/secchan/secchan.8.in index a9e5e520..e813c29e 100644 --- a/secchan/secchan.8.in +++ b/secchan/secchan.8.in @@ -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), diff --git a/utilities/.gitignore b/utilities/.gitignore index eed86ca2..b54ac1c2 100644 --- a/utilities/.gitignore +++ b/utilities/.gitignore @@ -5,6 +5,8 @@ /dpctl /dpctl.8 /nlmon +/ovs-controller +/ovs-controller.8 /ovs-discover /ovs-discover.8 /ovs-kill diff --git a/utilities/automake.mk b/utilities/automake.mk index 5c7030fb..8f3fb605 100644 --- a/utilities/automake.mk +++ b/utilities/automake.mk @@ -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 diff --git a/utilities/dpctl.8.in b/utilities/dpctl.8.in index 34f42812..349587db 100644 --- a/utilities/dpctl.8.in +++ b/utilities/dpctl.8.in @@ -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 index 00000000..4f715a05 --- /dev/null +++ b/utilities/ovs-controller.8.in @@ -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 index 00000000..d67bc98b --- /dev/null +++ b/utilities/ovs-controller.c @@ -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 + +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/utilities/vlogconf.8.in b/utilities/vlogconf.8.in index 0c251929..279e778c 100644 --- a/utilities/vlogconf.8.in +++ b/utilities/vlogconf.8.in @@ -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) diff --git a/xenserver/vswitch-xen.spec b/xenserver/vswitch-xen.spec index 38161985..035e4617 100644 --- a/xenserver/vswitch-xen.spec +++ b/xenserver/vswitch-xen.spec @@ -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