From e3e9370bf9ee0fde67b3d94acf119cec5dc3701d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 23 Nov 2009 11:32:08 -0800 Subject: [PATCH] ovs-openflowd: Add support for userspace-only switching. --- INSTALL.userspace | 16 ++++++++++++++-- utilities/ovs-openflowd.8.in | 16 ++++++++++++++++ utilities/ovs-openflowd.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/INSTALL.userspace b/INSTALL.userspace index a0c6a266..241d79cb 100644 --- a/INSTALL.userspace +++ b/INSTALL.userspace @@ -31,8 +31,8 @@ The tun device must also exist as /dev/net/tun. If it does not exist, then create /dev/net (if necessary) with "mkdir /dev/net", then create /dev/net/tun with "mknod /dev/net/tun c 10 200". -Using the Userspace Datapath ----------------------------- +Using the Userspace Datapath with ovs-vswitchd +---------------------------------------------- To use ovs-vswitchd in userspace mode, give the bridge a name that begins with "netdev:" in the configuration file. For example: @@ -45,6 +45,18 @@ ovs-vswitchd will create a TAP device as the bridge's local interface, named the same as the bridge minus the "netdev:" prefix, as well as for each configured internal interface. +Using the Userspace Datapath with ovs-openflowd +----------------------------------------------- + +To use ovs-openflowd in userspace mode, specify a datapath name that +begins with "netdev:", and specify --ports with the names of the ports +that should be included in the datapath as argument. For example: + + ovs-openflowd netdev:br0 --ports=eth0,eth1,eth2 + +ovs-openflowd will create a TAP device as the bridge's local +interface, named the same as the bridge minus the "netdev:" prefix. + Bug Reporting ------------- diff --git a/utilities/ovs-openflowd.8.in b/utilities/ovs-openflowd.8.in index 312e7f73..25b222f4 100644 --- a/utilities/ovs-openflowd.8.in +++ b/utilities/ovs-openflowd.8.in @@ -416,6 +416,22 @@ Sets the directory searched for remote command execution to \fBdirectory\fR. The default directory is \fB@pkgdatadir@/commands\fR. +.SS "Datapath Options" +. +.IP "\fB\-\-ports=\fIport\fR[\fB,\fIport\fR...]" +Ordinarily, \fBovs\-openflowd\fR expects the administrator to create +the specified \fIdatapath\fR and add ports to it externally with a +utility such as \fBovs\-dpctl\fR. However, the userspace switch +datapath is implemented inside \fBovs\-openflowd\fR itself and does +not (currently) have any external interface for \fBovs\-dpctl\fR to +access. As a stopgap measure, this option specifies one or more ports +to add to the datapath at \fBovs\-openflowd\fR startup time. Multiple +ports may be specified as a comma-separated list or by specifying +\fB\-\-ports\fR multiple times. +.IP +See \fBINSTALL.userspace\fR for more information about userspace +switching. + .SS "Daemon Options" .so lib/daemon.man diff --git a/utilities/ovs-openflowd.c b/utilities/ovs-openflowd.c index d6b2c51f..c275cd6a 100644 --- a/utilities/ovs-openflowd.c +++ b/utilities/ovs-openflowd.c @@ -64,6 +64,7 @@ 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. */ @@ -135,6 +136,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) { @@ -246,6 +267,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 }; @@ -275,6 +297,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'}, @@ -311,6 +334,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; @@ -462,6 +486,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(); -- 2.30.2