Merge commit 'origin/citrix'
authorJustin Pettit <jpettit@nicira.com>
Wed, 29 Jul 2009 05:16:50 +0000 (22:16 -0700)
committerJustin Pettit <jpettit@nicira.com>
Wed, 29 Jul 2009 05:16:50 +0000 (22:16 -0700)
Conflicts:

configure.ac

1  2 
debian/openvswitch-switch-config.templates
debian/openvswitch-switch.init
debian/openvswitch-switch.template
debian/po/templates.pot
lib/socket-util.c
lib/vconn.c
utilities/ovs-controller.8.in
utilities/ovs-ofctl.8.in
utilities/ovs-openflowd.8.in
vswitchd/bridge.c
vswitchd/ovs-vswitchd.conf.5.in

@@@ -64,7 -64,7 +64,7 @@@ _Description: Preparing to discover con
   The setup program will now attempt to discover the OpenFlow controller.
   Controller discovery may take up to 30 seconds.  Please be patient.
   .
 - See secchan(8) for instructions on how to configure a DHCP server for
 + See ovs-openflowd(8) for instructions on how to configure a DHCP server for
   controller discovery.
  
  Template: openvswitch-switch/discovery-failure
@@@ -73,7 -73,7 +73,7 @@@ _Description: Controller discovery fail
   The controller's location could not be determined automatically.
   .
   Ensure that the OpenFlow DHCP server is properly configured.  See
 - secchan(8) for instructions on how to configure a DHCP server for
 + ovs-openflowd(8) for instructions on how to configure a DHCP server for
   controller discovery.
  
  Template: openvswitch-switch/discovery-success
@@@ -113,16 -113,16 +113,16 @@@ Template: openvswitch-switch/controller
  Type: string
  _Description: Controller location:
   Specify how the OpenFlow switch should connect to the OpenFlow controller.
-  The value should be in form "ssl:HOST[:PORT]" to connect to the controller
-  over SSL (recommended for security) or "tcp:HOST[:PORT]" to connect over
+  The value should be in form "ssl:IP[:PORT]" to connect to the controller
+  over SSL (recommended for security) or "tcp:IP[:PORT]" to connect over
   cleartext TCP.
  
  Template: openvswitch-switch/controller-vconn-error
  Type: error
  _Description: The controller location is invalid.
-  The controller location must be specifed as "ssl:HOST[:PORT]" to
+  The controller location must be specifed as "ssl:IP[:PORT]" to
   connect to the controller over SSL (recommended for security) or
-  "tcp:HOST[:PORT]" to connect over cleartext TCP.
+  "tcp:IP[:PORT]" to connect over cleartext TCP.
  
  Template: openvswitch-switch/pki-uri
  Type: string
@@@ -19,9 -19,9 +19,9 @@@
  ### END INIT INFO
  
  PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 -DAEMON=/usr/sbin/secchan
 -NAME=secchan
 -DESC=secchan
 +DAEMON=/usr/sbin/ovs-openflowd
 +NAME=ovs-openflowd
 +DESC=ovs-openflowd
  
  test -x $DAEMON || exit 0
  
@@@ -35,7 -35,7 +35,7 @@@ DODTIME=1                   # Time to w
                              # let some servers to die gracefully and
                              # 'restart' will not work
  
 -# Include secchan defaults if available
 +# Include ovs-openflowd defaults if available
  unset NETDEVS
  unset MODE
  unset SWITCH_IP
@@@ -220,7 -220,7 +220,7 @@@ case "$1" i
                  configure_ssl
                  ;;
              *)
-                 echo "$default: CONTROLLER must be in the form 'ssl:HOST[:PORT]' or 'tcp:HOST[:PORT]' when not in discovery mode" >&2
+                 echo "$default: CONTROLLER must be in the form 'ssl:IP[:PORT]' or 'tcp:IP[:PORT]' when not in discovery mode" >&2
                  echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2
                  exit 1
          esac
              check_op "Setting core limit to $CORE_LIMIT" ulimit -c "$CORE_LIMIT"
          fi
  
 -        # Compose secchan options.
 +        # Compose ovs-openflowd options.
          set --
          set -- "$@" --verbose=ANY:console:emer --verbose=ANY:syslog:err
          set -- "$@" --log-file
@@@ -1,7 -1,7 +1,7 @@@
  # This is a POSIX shell fragment                -*- sh -*-
  
 -# To configure the secure channel, fill in the following properly and
 -# uncomment them.  Afterward, the secure channel will come up
 +# To configure the OpenFlow switch, fill in the following properly and
 +# uncomment them.  Afterward, the switch will come up
  # automatically at boot time.  It can be started immediately with
  #       /etc/init.d/openvswitch-switch start
  # Alternatively, use the ovs-switch-setup program (from the
@@@ -69,8 -69,8 +69,8 @@@ SWITCH_IP=dhc
  
  # CONTROLLER: Location of controller.
  # One of the following formats:
- #  tcp:HOST[:PORT]         via TCP to PORT (default: 6633) on HOST
- #  ssl:HOST[:PORT]         via SSL to PORT (default: 6633) on HOST
+ #  tcp:IP[:PORT]         via TCP to PORT (default: 6633) at IP
+ #  ssl:IP[:PORT]         via SSL to PORT (default: 6633) at IP
  # The default below assumes that the controller is running locally.
  # This setting has no effect when MODE is set to 'discovery'.
  #CONTROLLER="tcp:127.0.0.1"
  # Set CACERT_MODE to 'secure' or 'bootstrap' for these respective cases.
  #CACERT_MODE=secure
  
 -# MGMT_VCONNS: List of vconns (space-separated) on which secchan
 +# MGMT_VCONNS: List of vconns (space-separated) on which ovs-openflowd
  # should listen for management connections from ovs-ofctl, etc.
  # openvswitch-switchui by default connects to
 -# unix:/var/run/secchan.mgmt, so do not disable this if you want to
 +# unix:/var/run/ovs-openflowd.mgmt, so do not disable this if you want to
  # use openvswitch-switchui.
 -MGMT_VCONNS="punix:/var/run/secchan.mgmt"
 +MGMT_VCONNS="punix:/var/run/ovs-openflowd.mgmt"
  
  # COMMANDS: Access control list for the commands that can be executed
  # remotely over the OpenFlow protocol, as a comma-separated list of
  #DISCONNECTED_MODE=switch
  
  # STP: Enable or disabled 802.1D-1998 Spanning Tree Protocol.  Set to
 -# 'yes' to enable STP, 'no' to disable it.  If unset, secchan's
 +# 'yes' to enable STP, 'no' to disable it.  If unset, ovs-openflowd's
  # current default is 'no' (but this may change in the future).
  #STP=no
  
  #RATE_LIMIT=1000
  
  # INACTIVITY_PROBE: The maximum number of seconds of inactivity on the
 -# controller connection before secchan sends an inactivity probe
 +# controller connection before ovs-openflowd sends an inactivity probe
  # message to the controller.  The valid range is 5 and up.  If unset,
 -# secchan defaults to 15 seconds.
 +# ovs-openflowd defaults to 15 seconds.
  #INACTIVITY_PROBE=5
  
 -# MAX_BACKOFF: The maximum time that secchan will wait between
 +# MAX_BACKOFF: The maximum time that ovs-openflowd will wait between
  # attempts to connect to the controller.  The valid range is 1 and up.
 -# If unset, secchan defaults to 15 seconds.
 +# If unset, ovs-openflowd defaults to 15 seconds.
  #MAX_BACKOFF=15
  
 -# DAEMON_OPTS: Additional options to pass to secchan, e.g. "--fail=open"
 +# DAEMON_OPTS: Additional options to pass to ovs-openflowd, e.g. "--fail=open"
  DAEMON_OPTS=""
  
  # CORE_LIMIT: Maximum size for core dumps.
diff --combined debian/po/templates.pot
@@@ -7,7 -7,7 +7,7 @@@
  msgid ""
  msgstr ""
  "Project-Id-Version: PACKAGE VERSION\n"
 -"Report-Msgid-Bugs-To: ovs-dev@openvswitch.org\n"
 +"Report-Msgid-Bugs-To: dev@openvswitch.org\n"
  "POT-Creation-Date: 2009-05-11 13:38-0700\n"
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
@@@ -168,7 -168,7 +168,7 @@@ msgstr "
  #. Description
  #: ../openvswitch-switch-config.templates:5001
  msgid ""
 -"See secchan(8) for instructions on how to configure a DHCP server for "
 +"See ovs-openflowd(8) for instructions on how to configure a DHCP server for "
  "controller discovery."
  msgstr ""
  
@@@ -188,7 -188,7 +188,7 @@@ msgstr "
  #. Description
  #: ../openvswitch-switch-config.templates:6001
  msgid ""
 -"Ensure that the OpenFlow DHCP server is properly configured.  See secchan(8) "
 +"Ensure that the OpenFlow DHCP server is properly configured.  See ovs-openflowd(8) "
  "for instructions on how to configure a DHCP server for controller discovery."
  msgstr ""
  
@@@ -278,8 -278,8 +278,8 @@@ msgstr "
  #: ../openvswitch-switch-config.templates:10001
  msgid ""
  "Specify how the OpenFlow switch should connect to the OpenFlow controller. "
- "The value should be in form \"ssl:HOST[:PORT]\" to connect to the controller "
- "over SSL (recommended for security) or \"tcp:HOST[:PORT]\" to connect over "
+ "The value should be in form \"ssl:IP[:PORT]\" to connect to the controller "
+ "over SSL (recommended for security) or \"tcp:IP[:PORT]\" to connect over "
  "cleartext TCP."
  msgstr ""
  
@@@ -293,8 -293,8 +293,8 @@@ msgstr "
  #. Description
  #: ../openvswitch-switch-config.templates:11001
  msgid ""
- "The controller location must be specifed as \"ssl:HOST[:PORT]\" to connect "
- "to the controller over SSL (recommended for security) or \"tcp:HOST[:PORT]\" "
+ "The controller location must be specifed as \"ssl:IP[:PORT]\" to connect "
+ "to the controller over SSL (recommended for security) or \"tcp:IP[:PORT]\" "
  "to connect over cleartext TCP."
  msgstr ""
  
diff --combined lib/socket-util.c
@@@ -23,7 -23,6 +23,7 @@@
  #include <poll.h>
  #include <stddef.h>
  #include <stdio.h>
 +#include <stdlib.h>
  #include <string.h>
  #include <sys/resource.h>
  #include <sys/un.h>
@@@ -73,25 -72,16 +73,16 @@@ get_max_fds(void
      return max_fds;
  }
  
- /* Translates 'host_name', which may be a DNS name or an IP address, into a
-  * numeric IP address in '*addr'.  Returns 0 if successful, otherwise a
-  * positive errno value. */
+ /* Translates 'host_name', which must be a string representation of an IP
+  * address, into a numeric IP address in '*addr'.  Returns 0 if successful,
+  * otherwise a positive errno value. */
  int
  lookup_ip(const char *host_name, struct in_addr *addr) 
  {
      if (!inet_aton(host_name, addr)) {
-         struct hostent *he = gethostbyname(host_name);
-         if (he == NULL) {
-             struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
-             VLOG_ERR_RL(&rl, "gethostbyname(%s): %s", host_name,
-                         (h_errno == HOST_NOT_FOUND ? "host not found"
-                          : h_errno == TRY_AGAIN ? "try again"
-                          : h_errno == NO_RECOVERY ? "non-recoverable error"
-                          : h_errno == NO_ADDRESS ? "no address"
-                          : "unknown error"));
-             return ENOENT;
-         }
-         addr->s_addr = *(uint32_t *) he->h_addr;
+         struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+         VLOG_ERR_RL(&rl, "\"%s\" is not a valid IP address", host_name);
+         return ENOENT;
      }
      return 0;
  }
@@@ -300,172 -290,6 +291,172 @@@ guess_netmask(uint32_t ip
              : htonl(0));                          /* ??? */
  }
  
 +/* Opens a non-blocking TCP socket and connects to 'target', which should be a
 + * string in the format "<host>[:<port>]", where <host> is required and <port>
 + * is optional, with 'default_port' assumed if <port> is omitted.
 + *
 + * On success, returns 0 (indicating connection complete) or EAGAIN (indicating
 + * connection in progress), in which case the new file descriptor is stored
 + * into '*fdp'.  On failure, returns a positive errno value other than EAGAIN
 + * and stores -1 into '*fdp'.
 + *
 + * If 'sinp' is non-null, then on success the target address is stored into
 + * '*sinp'. */
 +int
 +tcp_open_active(const char *target_, uint16_t default_port,
 +                struct sockaddr_in *sinp, int *fdp)
 +{
 +    char *target = xstrdup(target_);
 +    char *save_ptr = NULL;
 +    const char *host_name;
 +    const char *port_string;
 +    struct sockaddr_in sin;
 +    int fd = -1;
 +    int error;
 +
 +    /* Defaults. */
 +    memset(&sin, 0, sizeof sin);
 +    sin.sin_family = AF_INET;
 +    sin.sin_port = htons(default_port);
 +
 +    /* Tokenize. */
 +    host_name = strtok_r(target, ":", &save_ptr);
 +    port_string = strtok_r(NULL, ":", &save_ptr);
 +    if (!host_name) {
 +        ovs_error(0, "%s: bad peer name format", target_);
 +        error = EAFNOSUPPORT;
 +        goto exit;
 +    }
 +
 +    /* Look up IP, port. */
 +    error = lookup_ip(host_name, &sin.sin_addr);
 +    if (error) {
 +        goto exit;
 +    }
 +    if (port_string && atoi(port_string)) {
 +        sin.sin_port = htons(atoi(port_string));
 +    }
 +
 +    /* Create non-blocking socket. */
 +    fd = socket(AF_INET, SOCK_STREAM, 0);
 +    if (fd < 0) {
 +        VLOG_ERR("%s: socket: %s", target_, strerror(errno));
 +        error = errno;
 +        goto exit;
 +    }
 +    error = set_nonblocking(fd);
 +    if (error) {
 +        goto exit_close;
 +    }
 +
 +    /* Connect. */
 +    error = connect(fd, (struct sockaddr *) &sin, sizeof sin) == 0 ? 0 : errno;
 +    if (error == EINPROGRESS) {
 +        error = EAGAIN;
 +    } else if (error && error != EAGAIN) {
 +        goto exit_close;
 +    }
 +
 +    /* Success: error is 0 or EAGAIN. */
 +    goto exit;
 +
 +exit_close:
 +    close(fd);
 +exit:
 +    if (!error || error == EAGAIN) {
 +        if (sinp) {
 +            *sinp = sin;
 +        }
 +        *fdp = fd;
 +    } else {
 +        *fdp = -1;
 +    }
 +    free(target);
 +    return error;
 +}
 +
 +/* Opens a non-blocking TCP socket, binds to 'target', and listens for incoming
 + * connections.  'target' should be a string in the format "[<port>][:<ip>]",
 + * where both <port> and <ip> are optional.  If <port> is omitted, it defaults
 + * to 'default_port'; if <ip> is omitted it defaults to the wildcard IP
 + * address.
 + *
 + * The socket will have SO_REUSEADDR turned on.
 + *
 + * On success, returns a non-negative file descriptor.  On failure, returns a
 + * negative errno value. */
 +int
 +tcp_open_passive(const char *target_, uint16_t default_port)
 +{
 +    char *target = xstrdup(target_);
 +    char *string_ptr = target;
 +    struct sockaddr_in sin;
 +    const char *host_name;
 +    const char *port_string;
 +    int fd, error;
 +    unsigned int yes  = 1;
 +
 +    /* Address defaults. */
 +    memset(&sin, 0, sizeof sin);
 +    sin.sin_family = AF_INET;
 +    sin.sin_addr.s_addr = htonl(INADDR_ANY);
 +    sin.sin_port = htons(default_port);
 +
 +    /* Parse optional port number. */
 +    port_string = strsep(&string_ptr, ":");
 +    if (port_string && atoi(port_string)) {
 +        sin.sin_port = htons(atoi(port_string));
 +    }
 +
 +    /* Parse optional bind IP. */
 +    host_name = strsep(&string_ptr, ":");
 +    if (host_name && host_name[0]) {
 +        error = lookup_ip(host_name, &sin.sin_addr);
 +        if (error) {
 +            goto exit;
 +        }
 +    }
 +
 +    /* Create non-blocking socket, set SO_REUSEADDR. */
 +    fd = socket(AF_INET, SOCK_STREAM, 0);
 +    if (fd < 0) {
 +        error = errno;
 +        VLOG_ERR("%s: socket: %s", target_, strerror(error));
 +        goto exit;
 +    }
 +    error = set_nonblocking(fd);
 +    if (error) {
 +        goto exit_close;
 +    }
 +    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) < 0) {
 +        error = errno;
 +        VLOG_ERR("%s: setsockopt(SO_REUSEADDR): %s", target_, strerror(error));
 +        goto exit_close;
 +    }
 +
 +    /* Bind. */
 +    if (bind(fd, (struct sockaddr *) &sin, sizeof sin) < 0) {
 +        error = errno;
 +        VLOG_ERR("%s: bind: %s", target_, strerror(error));
 +        goto exit_close;
 +    }
 +
 +    /* Listen. */
 +    if (listen(fd, 10) < 0) {
 +        error = errno;
 +        VLOG_ERR("%s: listen: %s", target_, strerror(error));
 +        goto exit_close;
 +    }
 +    error = 0;
 +    goto exit;
 +
 +exit_close:
 +    close(fd);
 +exit:
 +    free(target);
 +    return error ? -error : fd;
 +}
 +
  /* Returns a readable and writable fd for /dev/null, if successful, otherwise
   * a negative errno value.  The caller must not close the returned fd (because
   * the same fd will be handed out to subsequent callers). */
diff --combined lib/vconn.c
@@@ -128,23 -128,23 +128,23 @@@ vconn_usage(bool active, bool passive, 
      printf("\n");
      if (active) {
          printf("Active OpenFlow connection methods:\n");
-         printf("  tcp:HOST[:PORT]         "
-                "PORT (default: %d) on remote TCP HOST\n", OFP_TCP_PORT);
+         printf("  tcp:IP[:PORT]         "
+                "PORT (default: %d) at remote IP\n", OFP_TCP_PORT);
  #ifdef HAVE_OPENSSL
-         printf("  ssl:HOST[:PORT]         "
-                "SSL PORT (default: %d) on remote HOST\n", OFP_SSL_PORT);
+         printf("  ssl:IP[:PORT]         "
+                "SSL PORT (default: %d) at remote IP\n", OFP_SSL_PORT);
  #endif
          printf("  unix:FILE               Unix domain socket named FILE\n");
      }
  
      if (passive) {
          printf("Passive OpenFlow connection methods:\n");
 -        printf("  ptcp:[PORT]             "
 -               "listen to TCP PORT (default: %d)\n",
 +        printf("  ptcp:[PORT][:IP]        "
 +               "listen to TCP PORT (default: %d) on IP\n",
                 OFP_TCP_PORT);
  #ifdef HAVE_OPENSSL
 -        printf("  pssl:[PORT]             "
 -               "listen for SSL on PORT (default: %d)\n",
 +        printf("  pssl:[PORT][:IP]        "
 +               "listen for SSL on PORT (default: %d) on IP\n",
                 OFP_SSL_PORT);
  #endif
          printf("  punix:FILE              "
@@@ -364,7 -364,7 +364,7 @@@ vcs_recv_hello(struct vconn *vconn
  
      if (retval != EAGAIN) {
          vconn->state = VCS_DISCONNECTED;
 -        vconn->error = retval;
 +        vconn->error = retval == EOF ? ECONNRESET : retval;
      }
  }
  
@@@ -458,7 -458,10 +458,7 @@@ vconn_recv(struct vconn *vconn, struct 
  static int
  do_recv(struct vconn *vconn, struct ofpbuf **msgp)
  {
 -    int retval;
 -
 -again:
 -    retval = (vconn->class->recv)(vconn, msgp);
 +    int retval = (vconn->class->recv)(vconn, msgp);
      if (!retval) {
          struct ofp_header *oh;
  
              && oh->type != OFPT_VENDOR)
          {
              if (vconn->version < 0) {
 -                if (oh->type == OFPT_PACKET_IN
 -                    || oh->type == OFPT_FLOW_EXPIRED
 -                    || oh->type == OFPT_PORT_STATUS) {
 -                    /* The kernel datapath is stateless and doesn't really
 -                     * support version negotiation, so it can end up sending
 -                     * these asynchronous message before version negotiation
 -                     * is complete.  Just ignore them.
 -                     *
 -                     * (After we move OFPT_PORT_STATUS messages from the kernel
 -                     * into secchan, we won't get those here, since secchan
 -                     * does proper version negotiation.) */
 -                    ofpbuf_delete(*msgp);
 -                    goto again;
 -                }
                  VLOG_ERR_RL(&bad_ofmsg_rl,
                              "%s: received OpenFlow message type %"PRIu8" "
                              "before version negotiation complete",
@@@ -16,38 -16,31 +16,37 @@@ protocol, causing them to function as L
  one or more of the following OpenFlow connection methods:
  
  .TP
 -\fBpssl:\fR[\fIport\fR]
 +\fBpssl:\fR[\fIport\fR][\fB:\fIip\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.
 +By default, \fB\*(PN\fR listens for connections to any local IP
 +address, but \fIip\fR may be specified to listen only for connections
 +to the given \fIip\fR.
  
  .TP
 -\fBptcp:\fR[\fIport\fR]
 +\fBptcp:\fR[\fIport\fR][\fB:\fIip\fR]
  Listens for TCP connections from remote OpenFlow switches on
  \fIport\fR (default: 6633).
 +By default, \fB\*(PN\fR listens for connections to any local IP
 +address, but \fIip\fR may be specified to listen only for connections
 +to the given \fIip\fR.
  
  .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.
+ .IP "\fBssl:\fIip\fR[\fB:\fIport\fR]"
+ The specified SSL \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
+ The \fB--private-key\fR, \fB--certificate\fR, and \fB--ca-cert\fR
+ options are mandatory when this form is used.
+ .IP "\fBtcp:\fIip\fR[\fB:\fIport\fR]"
+ The specified TCP \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
  
  .TP
  \fBunix:\fIfile\fR
@@@ -82,7 -75,7 +81,7 @@@ already have the controller CA certific
  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).
 +\fBovs\-openflowd\fR(8).
  
  .IP "\fB-n\fR, \fB--noflow\fR"
  By default, \fBovs\-controller\fR sets up a flow in each OpenFlow switch
@@@ -103,7 -96,7 +102,7 @@@ recommended, flows will never expire.  
  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).
 +\fB--max-idle\fR to \fBovs\-openflowd\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).
@@@ -133,6 -126,6 +132,6 @@@ To bind locally to port 6633 (the defau
  
  .SH "SEE ALSO"
  
 -.BR secchan (8),
 +.BR ovs\-openflowd (8),
  .BR ovs\-appctl (8),
  .BR ovs\-dpctl (8)
diff --combined utilities/ovs-ofctl.8.in
@@@ -1,4 -1,4 +1,4 @@@
 -.TH ovs\-ofctl 8 "March 2009" "Open vSwitch" "Open vSwitch Manual"
 +.TH ovs\-ofctl 8 "June 2009" "Open vSwitch" "Open vSwitch Manual"
  .ds PN ovs\-ofctl
  
  .SH NAME
@@@ -26,16 -26,15 +26,15 @@@ connecting to an OpenFlow switch.  The 
  are supported:
  
  .RS
- .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.
+ .IP "\fBssl:\fIip\fR[\fB:\fIport\fR]"
+ The specified SSL \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
+ The \fB--private-key\fR, \fB--certificate\fR, and \fB--ca-cert\fR
+ options are mandatory when this form is used.
+ .IP "\fBtcp:\fIip\fR[\fB:\fIport\fR]"
+ The specified TCP \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
  
  .TP
  \fBunix:\fIfile\fR
@@@ -147,7 -146,7 +146,7 @@@ syntax of \fIflows\fR
  \fBmonitor \fIswitch\fR [\fImiss-len\fR [\fIsend-exp]]
  Connects to \fIswitch\fR and prints to the console all OpenFlow
  messages received.  Usually, \fIswitch\fR should specify a connection
 -named on \fBsecchan\fR(8)'s \fB-l\fR or \fB--listen\fR command line
 +named on \fBovs\-openflowd\fR(8)'s \fB-l\fR or \fB--listen\fR command line
  option.
  
  If \fImiss-len\fR is provided, \fBovs\-ofctl\fR sends an OpenFlow ``set
@@@ -224,8 -223,8 +223,8 @@@ Matches physical port \fIport_no\fR.  S
  displayed by \fBovs\-ofctl show\fR.
  
  .IP \fBdl_vlan=\fIvlan\fR
 -Matches IEEE 802.1q virtual LAN tag \fIvlan\fR.  Specify \fB0xffff\fR
 -as \fIvlan\fR to match packets that are not tagged with a virtual LAN;
 +Matches IEEE 802.1q Virtual LAN tag \fIvlan\fR.  Specify \fB0xffff\fR
 +as \fIvlan\fR to match packets that are not tagged with a Virtual LAN;
  otherwise, specify a number between 0 and 4095, inclusive, as the
  12-bit VLAN ID to match.
  
@@@ -327,7 -326,7 +326,7 @@@ omitted, then the entire packet is sent
  .IP \fBlocal\fR
  Outputs the packet on the ``local port,'' which corresponds to the
  \fBof\fIn\fR network device (see \fBCONTACTING THE CONTROLLER\fR in
 -\fBsecchan\fR(8) for information on the \fBof\fIn\fR network device).
 +\fBovs\-openflowd\fR(8) for information on the \fBof\fIn\fR network device).
  
  .IP \fBdrop\fR
  Discards the packet, so no further processing or forwarding takes place.
@@@ -471,7 -470,7 +470,7 @@@ The following examples assume that an O
  host has been configured to listen for management connections on a
  Unix domain socket named \fB@RUNDIR@/openflow.sock\fR, e.g. by
  specifying \fB--listen=punix:@RUNDIR@/openflow.sock\fR on the
 -\fBsecchan\fR(8) command line.
 +\fBovs\-openflowd\fR(8) command line.
  
  .TP
  \fBovs\-ofctl dump-tables unix:@RUNDIR@/openflow.sock\fR
@@@ -1,16 -1,16 +1,16 @@@
 -.TH secchan 8 "March 2009" "Open vSwitch" "Open vSwitch Manual"
 -.ds PN secchan
 +.TH ovs\-openflowd 8 "March 2009" "Open vSwitch" "Open vSwitch Manual"
 +.ds PN ovs\-openflowd
  
  .SH NAME
 -secchan \- OpenFlow switch implementation
 +ovs\-openflowd \- OpenFlow switch implementation
  
  .SH SYNOPSIS
 -.B secchan
 +.B ovs\-openflowd
  [\fIoptions\fR] \fIdatapath\fR [\fIcontroller\fR]
  
  .SH DESCRIPTION
 -The \fBsecchan\fR program implements an OpenFlow switch using a
 -flow-based datapath.  \fBsecchan\fR connects to an OpenFlow controller
 +The \fBovs\-openflowd\fR program implements an OpenFlow switch using a
 +flow-based datapath.  \fBovs\-openflowd\fR connects to an OpenFlow controller
  over TCP or SSL.
  
  The mandatory \fIdatapath\fR argument argument specifies the local datapath
@@@ -23,16 -23,15 +23,15 @@@ The optional \fIcontroller\fR argument 
  the OpenFlow controller.  It takes one of the following forms:
  
  .RS
- .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.
+ .IP "\fBssl:\fIip\fR[\fB:\fIport\fR]"
+ The specified SSL \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
+ 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.
+ .IP "\fBtcp:\fIip\fR[\fB:\fIport\fR]"
+ The specified TCP \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
  
  .TP
  \fBunix:\fIfile\fR
@@@ -40,7 -39,7 +39,7 @@@ The Unix domain server socket named \fI
  .RE
  
  .PP
 -If \fIcontroller\fR is omitted, \fBsecchan\fR attempts to discover the
 +If \fIcontroller\fR is omitted, \fBovs\-openflowd\fR attempts to discover the
  location of the controller automatically (see below).
  
  .SS "Contacting the Controller"
@@@ -53,9 -52,9 +52,9 @@@ the data traffic that it controls, tha
  any of the network devices added to the datapath with \fBovs\-dpctl
  add\-if\fR in its communication with the controller.
  
 -To use \fBsecchan\fR in a network with out-of-band control, specify
 -\fB--out-of-band\fR on the \fBsecchan\fR command line.  The control
 -network must be configured separately, before or after \fBsecchan\fR
 +To use \fBovs\-openflowd\fR in a network with out-of-band control, specify
 +\fB--out-of-band\fR on the \fBovs\-openflowd\fR command line.  The control
 +network must be configured separately, before or after \fBovs\-openflowd\fR
  is started.
  
  .IP in-band
@@@ -66,7 -65,7 +65,7 @@@ add\-if\fR.  This configuration is ofte
  out-of-band control, because it is not necessary to maintain two
  independent networks.
  
 -In-band control is the default for \fBsecchan\fR, so no special
 +In-band control is the default for \fBovs\-openflowd\fR, so no special
  command-line option is required.
  
  With in-band control, the location of the controller can be configured
@@@ -74,23 -73,23 +73,23 @@@ manually or discovered automatically
  
  .RS
  .IP "controller discovery"
 -To make \fBsecchan\fR discover the location of the controller
 +To make \fBovs\-openflowd\fR discover the location of the controller
  automatically, do not specify the location of the controller on the
 -\fBsecchan\fR command line.
 +\fBovs\-openflowd\fR command line.
  
 -In this mode, \fBsecchan\fR will broadcast a DHCP request with vendor
 +In this mode, \fBovs\-openflowd\fR will broadcast a DHCP request with vendor
  class identifier \fBOpenFlow\fR across the network devices added to
  the datapath with \fBovs\-dpctl add\-if\fR.  It will accept any valid DHCP
  reply that has the same vendor class identifier and includes a
  vendor-specific option with code 1 whose contents are a string
  specifying the location of the controller in the same format used on
 -the \fBsecchan\fR command line (e.g. \fBssl:192.168.0.1\fR).
 +the \fBovs\-openflowd\fR command line (e.g. \fBssl:192.168.0.1\fR).
  
  The DHCP reply may also, optionally, include a vendor-specific option
  with code 2 whose contents are a string specifying the URI to the base
  of the OpenFlow PKI (e.g. \fBhttp://192.168.0.1/openflow/pki\fR).
  This URI is used only for bootstrapping the OpenFlow PKI at initial
 -switch setup; \fBsecchan\fR does not use it at all.
 +switch setup; \fBovs\-openflowd\fR does not use it at all.
  
  The following ISC DHCP server configuration file assigns the IP
  address range 192.168.0.20 through 192.168.0.30 to OpenFlow switches
@@@ -144,28 -143,28 +143,28 @@@ subnet 192.168.0.0 netmask 255.255.255.
  
  .IP "manual configuration"
  To configure in-band control manually, specify the location of the
 -controller on the \fBsecchan\fR command line as the \fIcontroller\fR
 +controller on the \fBovs\-openflowd\fR command line as the \fIcontroller\fR
  argument.  You must also configure the network device for the OpenFlow
 -``local port'' to allow \fBsecchan\fR to connect to that controller.
 -The OpenFlow local port is a virtual network port that \fBsecchan\fR
 +``local port'' to allow \fBovs\-openflowd\fR to connect to that controller.
 +The OpenFlow local port is a virtual network port that \fBovs\-openflowd\fR
  bridges to the physical switch ports.  The name of the local port for
  a given \fIdatapath\fR may be seen by running \fBovs\-dpctl show
  \fIdatapath\fR; the local port is listed as port 0 in \fBshow\fR's
  output.
  
  .IP
 -Before \fBsecchan\fR starts, the local port network device is not
 +Before \fBovs\-openflowd\fR starts, the local port network device is not
  bridged to any physical network, so the next step depends on whether
  connectivity is required to configure the device's IP address.  If the
  switch has a static IP address, you may configure its IP address now
  with a command such as 
  .B ifconfig of0 192.168.1.1
 -and then invoke \fBsecchan\fR.
 +and then invoke \fBovs\-openflowd\fR.
  
  On the other hand, if the switch does not have a static IP address,
  e.g. it obtains its IP address dynamically via DHCP, the DHCP client
 -will not be able to contact the DHCP server until the secure channel
 -has started up.  Thus, start \fBsecchan\fR without configuring
 +will not be able to contact the DHCP server until the OpenFlow switch
 +has started up.  Thus, start \fBovs\-openflowd\fR without configuring
  the local port network device, and start the DHCP client afterward.
  .RE
  
  .SS "Controller Discovery Options"
  .TP
  \fB--accept-vconn=\fIregex\fR
 -When \fBsecchan\fR performs controller discovery (see \fBContacting
 +When \fBovs\-openflowd\fR performs controller discovery (see \fBContacting
  the Controller\fR, above, for more information about controller
  discovery), it validates the controller location obtained via DHCP
  with a POSIX extended regular expression.  Only controllers whose
@@@ -182,8 -181,8 +181,8 @@@ names match the regular expression wil
  The default regular expression is \fBssl:.*\fR (meaning that only SSL
  controller connections will be accepted) when any of the SSL
  configuration options \fB--private-key\fR, \fB--certificate\fR, or
 -\fB--ca-cert\fR is specified.  The default is \fB.*\fR otherwise
 -(meaning that any controller will be accepted).
 +\fB--ca-cert\fR is specified.  The default is \fB^tcp:.*\fR otherwise
 +(meaning that only TCP controller connections will be accepted).
  
  The \fIregex\fR is implicitly anchored at the beginning of the
  controller location string, as if it begins with \fB^\fR.
@@@ -192,7 -191,7 +191,7 @@@ When controller discovery is not perfor
  
  .TP
  \fB--no-resolv-conf\fR
 -When \fBsecchan\fR performs controller discovery (see \fBContacting
 +When \fBovs\-openflowd\fR performs controller discovery (see \fBContacting
  the Controller\fR, above, for more information about controller
  discovery), by default it overwrites the system's
  \fB/etc/resolv.conf\fR with domain information and DNS servers
@@@ -200,10 -199,10 +199,10 @@@ obtained via DHCP.  If the location of 
  using a hostname, rather than an IP address, and the network's DNS
  servers ever change, this behavior is essential.  But because it also
  interferes with any administrator or process that manages
 -\fB/etc/resolv.conf\fR, when this option is specified, \fBsecchan\fR
 +\fB/etc/resolv.conf\fR, when this option is specified, \fBovs\-openflowd\fR
  will not modify \fB/etc/resolv.conf\fR.
  
 -\fBsecchan\fR will only modify \fBresolv.conf\fR if the DHCP response
 +\fBovs\-openflowd\fR will only modify \fBresolv.conf\fR if the DHCP response
  that it receives specifies one or more DNS servers.
  
  When controller discovery is not performed, this option has no effect.
@@@ -235,25 -234,25 +234,25 @@@ no new network connections can be set u
  controller stays down long enough, no packets can pass through the
  switch at all.
  
 -If this option is set to \fBopen\fR (the default), \fBsecchan\fR will
 +If this option is set to \fBopen\fR (the default), \fBovs\-openflowd\fR will
  take over responsibility for setting up flows in the local datapath
  when no message has been received from the controller for three times
  the inactivity probe interval (see below), or 45 seconds by default.
 -In this ``fail open'' mode, \fBsecchan\fR causes the datapath to act
 -like an ordinary MAC-learning switch.  \fBsecchan\fR will continue to
 +In this ``fail open'' mode, \fBovs\-openflowd\fR causes the datapath to act
 +like an ordinary MAC-learning switch.  \fBovs\-openflowd\fR will continue to
  retry connection to the controller in the background and, when the
  connection succeeds, it discontinues its fail-open behavior.
  
 -If this option is set to \fBclosed\fR, then \fBsecchan\fR will not
 +If this option is set to \fBclosed\fR, then \fBovs\-openflowd\fR will not
  set up flows on its own when the controller connection fails.
  
  .TP
  \fB--inactivity-probe=\fIsecs\fR
 -When the secure channel is connected to the controller, the secure
 -channel waits for a message to be received from the controller for
 +When the OpenFlow switch is connected to the controller, the
 +switch waits for a message to be received from the controller for
  \fIsecs\fR seconds before it sends a inactivity probe to the
  controller.  After sending the inactivity probe, if no response is
 -received for an additional \fIsecs\fR seconds, the secure channel
 +received for an additional \fIsecs\fR seconds, the switch
  assumes that the connection has been broken and attempts to reconnect.
  The default is 15 seconds, and the minimum value is 5 seconds.
  
@@@ -264,19 -263,19 +263,19 @@@ above)
  .TP
  \fB--max-idle=\fIsecs\fR|\fBpermanent\fR
  Sets \fIsecs\fR as the number of seconds that a flow set up by the
 -secure channel will remain in the switch's flow table without any
 +OpenFlow switch will remain in the switch's flow table without any
  matching packets being seen.  If \fBpermanent\fR is specified, which
 -is not recommended, flows set up by the secure channel will never
 +is not recommended, flows set up by the switch will never
  expire.  The default is 15 seconds.
  
 -Most flows are set up by the OpenFlow controller, not by the secure
 -channel.  This option affects only the following flows, which the
 -secure channel sets up itself:
 +Most flows are set up by the OpenFlow controller, not by the
 +switch.  This option affects only the following flows, which the
 +OpenFlow switch sets up itself:
  
  .RS
  .IP \(bu
 -When \fB--fail=open\fR is specified, flows set up when the secure
 -channel has not been able to contact the controller for the configured
 +When \fB--fail=open\fR is specified, flows set up when the
 +switch has not been able to contact the controller for the configured
  fail-open delay.
  
  .IP \(bu
@@@ -307,20 -306,14 +306,20 @@@ multiple connection methods
  
  .RS
  .TP
 -\fBpssl:\fR[\fIport\fR]
 +\fBpssl:\fR[\fIport\fR][\fB:\fIip\fR]
  Listens for SSL connections 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.
 +By default, \fB\*(PN\fR listens for connections to any local IP
 +address, but \fIip\fR may be specified to listen only for connections
 +to the given \fIip\fR.
  
  .TP
 -\fBptcp:\fR[\fIport\fR]
 +\fBptcp:\fR[\fIport\fR][\fB:\fIip\fR]
  Listens for TCP connections on \fIport\fR (default: 6633).
 +By default, \fB\*(PN\fR listens for connections to any local IP
 +address, but \fIip\fR may be specified to listen only for connections
 +to the given \fIip\fR.
  
  .TP
  \fBpunix:\fIfile\fR
@@@ -343,14 -336,15 +342,15 @@@ problems
  
  .TP
  \fB--in-band\fR, \fB--out-of-band\fR
 -Configures \fBsecchan\fR to operate in in-band or out-of-band control
 +Configures \fBovs\-openflowd\fR to operate in in-band or out-of-band control
  mode (see \fBContacting the Controller\fR above).  When neither option
  is given, the default is in-band control.
  
  .TP
- \fB--netflow=\fIhost\fB:\fIport\fR
- Configures the given UDP \fIport\fR on the specified IP \fIhost\fR as
- a recipient of NetFlow messages for expired flows.
+ \fB--netflow=\fIip\fB:\fIport\fR
+ Configures the given UDP \fIport\fR on the specified IP \fIip\fR as
+ a recipient of NetFlow messages for expired flows.  The \fIip\fR must
+ be specified numerically, not as a DNS name.
  
  This option may be specified multiple times to configure additional
  NetFlow collectors.
@@@ -401,7 -395,7 +401,7 @@@ Command names that include characters o
  English letters, digits, and the underscore and hyphen characters are
  unconditionally disallowed.
  
 -When the whitelist and blacklist permit a command name, \fBsecchan\fR
 +When the whitelist and blacklist permit a command name, \fBovs\-openflowd\fR
  looks for a program with the same name as the command in the commands
  directory (see below).  Other directories are not searched.
  
@@@ -435,7 -429,7 +435,7 @@@ the switch is connected to a trustworth
  .TP
  \fB--bootstrap-ca-cert=\fIcacert.pem\fR
  When \fIcacert.pem\fR exists, this option has the same effect as
 -\fB-C\fR or \fB--ca-cert\fR.  If it does not exist, then \fBsecchan\fR
 +\fB-C\fR or \fB--ca-cert\fR.  If it does not exist, then \fBovs\-openflowd\fR
  will attempt to obtain the CA certificate from the controller on its
  first SSL connection and save it to the named PEM file.  If it is
  successful, it will immediately drop the connection and reconnect, and
diff --combined vswitchd/bridge.c
  #include "odp-util.h"
  #include "ofp-print.h"
  #include "ofpbuf.h"
 +#include "ofproto/ofproto.h"
  #include "packets.h"
  #include "poll-loop.h"
  #include "port-array.h"
  #include "proc-net-compat.h"
  #include "process.h"
 -#include "secchan/ofproto.h"
  #include "socket-util.h"
  #include "stp.h"
  #include "svec.h"
@@@ -158,7 -158,7 +158,7 @@@ struct bridge 
      struct ofproto *ofproto;    /* OpenFlow switch. */
  
      /* Kernel datapath information. */
 -    struct dpif dpif;           /* Kernel datapath. */
 +    struct dpif *dpif;          /* Datapath. */
      struct port_array ifaces;   /* Indexed by kernel datapath port number. */
  
      /* Bridge ports. */
@@@ -261,8 -261,8 +261,8 @@@ bridge_get_ifaces(struct svec *svec
              for (j = 0; j < port->n_ifaces; j++) {
                  struct iface *iface = port->ifaces[j];
                  if (iface->dp_ifidx < 0) {
 -                    VLOG_ERR("%s interface not in dp%u, ignoring",
 -                             iface->name, dpif_id(&br->dpif));
 +                    VLOG_ERR("%s interface not in datapath %s, ignoring",
 +                             iface->name, dpif_name(br->dpif));
                  } else {
                      if (iface->dp_ifidx != ODPP_LOCAL) {
                          svec_add(svec, iface->name);
  void
  bridge_init(void)
  {
 -    int retval;
 -    int i;
 -
 -    bond_init();
 +    struct svec dpif_names;
 +    size_t i;
  
      unixctl_command_register("fdb/show", bridge_unixctl_fdb_show);
  
 -    for (i = 0; i < DP_MAX; i++) {
 -        struct dpif dpif;
 -        char devname[16];
 +    dp_enumerate(&dpif_names);
 +    for (i = 0; i < dpif_names.n; i++) {
 +        const char *dpif_name = dpif_names.names[i];
 +        struct dpif *dpif;
 +        int retval;
  
 -        sprintf(devname, "dp%d", i);
 -        retval = dpif_open(devname, &dpif);
 +        retval = dpif_open(dpif_name, &dpif);
          if (!retval) {
 -            char dpif_name[IF_NAMESIZE];
 -            if (dpif_get_name(&dpif, dpif_name, sizeof dpif_name)
 -                || !cfg_has("bridge.%s.port", dpif_name)) {
 -                dpif_delete(&dpif);
 +            struct svec all_names;
 +            size_t j;
 +
 +            svec_init(&all_names);
 +            dpif_get_all_names(dpif, &all_names);
 +            for (j = 0; j < all_names.n; j++) {
 +                if (cfg_has("bridge.%s.port", all_names.names[j])) {
 +                    goto found;
 +                }
              }
 -            dpif_close(&dpif);
 -        } else if (retval != ENODEV) {
 -            VLOG_ERR("failed to delete datapath dp%d: %s",
 -                     i, strerror(retval));
 +            dpif_delete(dpif);
 +        found:
 +            svec_destroy(&all_names);
 +            dpif_close(dpif);
          }
      }
  
 +    bond_init();
      bridge_reconfigure();
  }
  
@@@ -349,7 -344,7 +349,7 @@@ bridge_configure_ssl(void
       * the old certificate will still be trusted until vSwitch is
       * restarted.  We may want to address this in vconn's SSL library. */
      if (config_string_change("ssl.ca-cert", &cacert_file)
 -            || (stat(cacert_file, &s) && errno == ENOENT)) {
 +        || (cacert_file && stat(cacert_file, &s) && errno == ENOENT)) {
          vconn_ssl_set_ca_cert_file(cacert_file,
                                     cfg_get_bool(0, "ssl.bootstrap-ca-cert"));
      }
  void
  bridge_reconfigure(void)
  {
 -    struct svec old_br, new_br, raw_new_br;
 +    struct svec old_br, new_br;
      struct bridge *br, *next;
      size_t i, j;
  
      COVERAGE_INC(bridge_reconfigure);
  
 -    /* Collect old bridges. */
 +    /* Collect old and new bridges. */
      svec_init(&old_br);
 +    svec_init(&new_br);
      LIST_FOR_EACH (br, struct bridge, node, &all_bridges) {
          svec_add(&old_br, br->name);
      }
 -
 -    /* Collect new bridges. */
 -    svec_init(&raw_new_br);
 -    cfg_get_subsections(&raw_new_br, "bridge");
 -    svec_init(&new_br);
 -    for (i = 0; i < raw_new_br.n; i++) {
 -        const char *name = raw_new_br.names[i];
 -        if ((!strncmp(name, "dp", 2) && isdigit(name[2])) ||
 -            (!strncmp(name, "nl:", 3) && isdigit(name[3]))) {
 -            VLOG_ERR("%s is not a valid bridge name (bridges may not be "
 -                     "named \"dp\" or \"nl:\" followed by a digit)", name);
 -        } else {
 -            svec_add(&new_br, name);
 -        }
 -    }
 -    svec_destroy(&raw_new_br);
 +    cfg_get_subsections(&new_br, "bridge");
  
      /* Get rid of deleted bridges and add new bridges. */
      svec_sort(&old_br);
          size_t n_dpif_ports;
          struct svec want_ifaces;
  
 -        dpif_port_list(&br->dpif, &dpif_ports, &n_dpif_ports);
 +        dpif_port_list(br->dpif, &dpif_ports, &n_dpif_ports);
          bridge_get_all_ifaces(br, &want_ifaces);
          for (i = 0; i < n_dpif_ports; i++) {
              const struct odp_port *p = &dpif_ports[i];
              if (!svec_contains(&want_ifaces, p->devname)
                  && strcmp(p->devname, br->name)) {
 -                int retval = dpif_port_del(&br->dpif, p->port);
 +                int retval = dpif_port_del(br->dpif, p->port);
                  if (retval) {
 -                    VLOG_ERR("failed to remove %s interface from dp%u: %s",
 -                             p->devname, dpif_id(&br->dpif), strerror(retval));
 +                    VLOG_ERR("failed to remove %s interface from %s: %s",
 +                             p->devname, dpif_name(br->dpif),
 +                             strerror(retval));
                  }
              }
          }
          struct odp_port *dpif_ports;
          size_t n_dpif_ports;
          struct svec cur_ifaces, want_ifaces, add_ifaces;
 -        int next_port_no;
  
 -        dpif_port_list(&br->dpif, &dpif_ports, &n_dpif_ports);
 +        dpif_port_list(br->dpif, &dpif_ports, &n_dpif_ports);
          svec_init(&cur_ifaces);
          for (i = 0; i < n_dpif_ports; i++) {
              svec_add(&cur_ifaces, dpif_ports[i].devname);
          bridge_get_all_ifaces(br, &want_ifaces);
          svec_diff(&want_ifaces, &cur_ifaces, &add_ifaces, NULL, NULL);
  
 -        next_port_no = 1;
          for (i = 0; i < add_ifaces.n; i++) {
              const char *if_name = add_ifaces.names[i];
 -            for (;;) {
 -                int internal = cfg_get_bool(0, "iface.%s.internal", if_name);
 -                int error = dpif_port_add(&br->dpif, if_name, next_port_no++,
 -                                          internal ? ODP_PORT_INTERNAL : 0);
 -                if (error != EEXIST) {
 -                    if (next_port_no >= 256) {
 -                        VLOG_ERR("ran out of valid port numbers on dp%u",
 -                                 dpif_id(&br->dpif));
 -                        goto out;
 -                    }
 -                    if (error) {
 -                        VLOG_ERR("failed to add %s interface to dp%u: %s",
 -                                 if_name, dpif_id(&br->dpif), strerror(error));
 -                    }
 -                    break;
 -                }
 +            int internal = cfg_get_bool(0, "iface.%s.internal", if_name);
 +            int flags = internal ? ODP_PORT_INTERNAL : 0;
 +            int error = dpif_port_add(br->dpif, if_name, flags, NULL);
 +            if (error == EXFULL) {
 +                VLOG_ERR("ran out of valid port numbers on %s",
 +                         dpif_name(br->dpif));
 +                break;
 +            } else if (error) {
 +                VLOG_ERR("failed to add %s interface to %s: %s",
 +                         if_name, dpif_name(br->dpif), strerror(error));
              }
          }
 -    out:
          svec_destroy(&cur_ifaces);
          svec_destroy(&want_ifaces);
          svec_destroy(&add_ifaces);
          uint64_t dpid;
          struct iface *local_iface = NULL;
          const char *devname;
 -        uint8_t engine_type = br->dpif.minor;
 -        uint8_t engine_id = br->dpif.minor;
 +        uint8_t engine_type, engine_id;
          bool add_id_to_iface = false;
          struct svec nf_hosts;
  
              for (j = 0; j < port->n_ifaces; ) {
                  struct iface *iface = port->ifaces[j];
                  if (iface->dp_ifidx < 0) {
 -                    VLOG_ERR("%s interface not in dp%u, dropping",
 -                             iface->name, dpif_id(&br->dpif));
 +                    VLOG_ERR("%s interface not in %s, dropping",
 +                             iface->name, dpif_name(br->dpif));
                      iface_destroy(iface);
                  } else {
                      if (iface->dp_ifidx == ODPP_LOCAL) {
                          local_iface = iface;
                      }
 -                    VLOG_DBG("dp%u has interface %s on port %d",
 -                             dpif_id(&br->dpif), iface->name, iface->dp_ifidx);
 +                    VLOG_DBG("%s has interface %s on port %d",
 +                             dpif_name(br->dpif),
 +                             iface->name, iface->dp_ifidx);
                      j++;
                  }
              }
          ofproto_set_datapath_id(br->ofproto, dpid);
  
          /* Set NetFlow configuration on this bridge. */
 +        dpif_get_netflow_ids(br->dpif, &engine_type, &engine_id);
          if (cfg_has("netflow.%s.engine-type", br->name)) {
              engine_type = cfg_get_int(0, "netflow.%s.engine-type", 
                      br->name);
@@@ -793,9 -809,12 +793,12 @@@ bridge_unixctl_fdb_show(struct unixctl_
      if (br->ml) {
          const struct mac_entry *e;
          LIST_FOR_EACH (e, struct mac_entry, lru_node, &br->ml->lrus) {
+             if (e->port < 0 || e->port >= br->n_ports) {
+                 continue;
+             }
              ds_put_format(&ds, "%5d  %4d  "ETH_ADDR_FMT"  %3d\n",
-                           e->port, e->vlan, ETH_ADDR_ARGS(e->mac),
-                           mac_entry_age(e));
+                           br->ports[e->port]->ifaces[0]->dp_ifidx,
+                           e->vlan, ETH_ADDR_ARGS(e->mac), mac_entry_age(e));
          }
      }
      unixctl_command_reply(conn, 200, ds_cstr(&ds));
@@@ -814,7 -833,7 +817,7 @@@ bridge_create(const char *name
      br = xcalloc(1, sizeof *br);
  
      error = dpif_create(name, &br->dpif);
 -    if (error == EEXIST) {
 +    if (error == EEXIST || error == EBUSY) {
          error = dpif_open(name, &br->dpif);
          if (error) {
              VLOG_ERR("datapath %s already exists but cannot be opened: %s",
              free(br);
              return NULL;
          }
 -        dpif_flow_flush(&br->dpif);
 +        dpif_flow_flush(br->dpif);
      } else if (error) {
          VLOG_ERR("failed to create datapath %s: %s", name, strerror(error));
          free(br);
      error = ofproto_create(name, &bridge_ofhooks, br, &br->ofproto);
      if (error) {
          VLOG_ERR("failed to create switch %s: %s", name, strerror(error));
 -        dpif_delete(&br->dpif);
 -        dpif_close(&br->dpif);
 +        dpif_delete(br->dpif);
 +        dpif_close(br->dpif);
          free(br);
          return NULL;
      }
  
      list_push_back(&all_bridges, &br->node);
  
 -    VLOG_INFO("created bridge %s on dp%u", br->name, dpif_id(&br->dpif));
 +    VLOG_INFO("created bridge %s on %s", br->name, dpif_name(br->dpif));
  
      return br;
  }
@@@ -865,12 -884,12 +868,12 @@@ bridge_destroy(struct bridge *br
              port_destroy(br->ports[br->n_ports - 1]);
          }
          list_remove(&br->node);
 -        error = dpif_delete(&br->dpif);
 +        error = dpif_delete(br->dpif);
          if (error && error != ENOENT) {
 -            VLOG_ERR("failed to delete dp%u: %s",
 -                     dpif_id(&br->dpif), strerror(error));
 +            VLOG_ERR("failed to delete %s: %s",
 +                     dpif_name(br->dpif), strerror(error));
          }
 -        dpif_close(&br->dpif);
 +        dpif_close(br->dpif);
          ofproto_destroy(br->ofproto);
          free(br->controller);
          mac_learning_destroy(br->ml);
@@@ -961,16 -980,9 +964,16 @@@ bridge_reconfigure_one(struct bridge *b
      svec_init(&new_ports);
      cfg_get_all_keys(&new_ports, "bridge.%s.port", br->name);
      svec_sort(&new_ports);
 -    if (bridge_get_controller(br) && !svec_contains(&new_ports, br->name)) {
 -        svec_add(&new_ports, br->name);
 -        svec_sort(&new_ports);
 +    if (bridge_get_controller(br)) {
 +        char local_name[IF_NAMESIZE];
 +        int error;
 +
 +        error = dpif_port_get_name(br->dpif, ODPP_LOCAL,
 +                                   local_name, sizeof local_name);
 +        if (!error && !svec_contains(&new_ports, local_name)) {
 +            svec_add(&new_ports, local_name);
 +            svec_sort(&new_ports);
 +        }
      }
      if (!svec_is_unique(&new_ports)) {
          VLOG_WARN("bridge %s: %s specified twice as bridge port",
@@@ -1107,7 -1119,6 +1110,7 @@@ bridge_reconfigure_controller(struct br
                                    cfg_get_string(0, "%s.accept-regex", pfx),
                                    update_resolv_conf);
          } else {
 +            char local_name[IF_NAMESIZE];
              struct netdev *netdev;
              bool in_band;
              int error;
              ofproto_set_discovery(br->ofproto, false, NULL, NULL);
              ofproto_set_in_band(br->ofproto, in_band);
  
 -            error = netdev_open(br->name, NETDEV_ETH_TYPE_NONE, &netdev);
 +            error = dpif_port_get_name(br->dpif, ODPP_LOCAL,
 +                                       local_name, sizeof local_name);
 +            if (!error) {
 +                error = netdev_open(local_name, NETDEV_ETH_TYPE_NONE, &netdev);
 +            }
              if (!error) {
                  if (cfg_is_valid(CFG_IP | CFG_REQUIRED, "%s.ip", pfx)) {
                      struct in_addr ip, mask, gateway;
@@@ -1275,17 -1282,17 +1278,17 @@@ bridge_fetch_dp_ifaces(struct bridge *b
      }
      port_array_clear(&br->ifaces);
  
 -    dpif_port_list(&br->dpif, &dpif_ports, &n_dpif_ports);
 +    dpif_port_list(br->dpif, &dpif_ports, &n_dpif_ports);
      for (i = 0; i < n_dpif_ports; i++) {
          struct odp_port *p = &dpif_ports[i];
          struct iface *iface = iface_lookup(br, p->devname);
          if (iface) {
              if (iface->dp_ifidx >= 0) {
 -                VLOG_WARN("dp%u reported interface %s twice",
 -                          dpif_id(&br->dpif), p->devname);
 +                VLOG_WARN("%s reported interface %s twice",
 +                          dpif_name(br->dpif), p->devname);
              } else if (iface_from_dp_ifidx(br, p->port)) {
 -                VLOG_WARN("dp%u reported interface %"PRIu16" twice",
 -                          dpif_id(&br->dpif), p->port);
 +                VLOG_WARN("%s reported interface %"PRIu16" twice",
 +                          dpif_name(br->dpif), p->port);
              } else {
                  port_array_set(&br->ifaces, p->port, iface);
                  iface->dp_ifidx = p->port;
  .  RE
  .  PP
  ..
 -.TH ovs\-vswitchd.conf 5 "April 2009" "Open vSwitch" "OpenVSwitch Manual"
 +.TH ovs\-vswitchd.conf 5 "June 2009" "Open vSwitch" "Open vSwitch Manual"
  .
  .SH NAME
  ovs\-vswitchd.conf \- configuration file for \fBovs\-vswitchd\fR
  .
  .SH DESCRIPTION
  This manual page describes the syntax for the configuration file used 
 -by \fBovs\-vswitchd\fR(8), the virtual switch daemon.
 +by \fBovs\-vswitchd\fR(8), the Open vSwitch daemon.
  .PP
  The configuration file is based on key-value pairs, which are given
  one per line in the form \fIkey\fB=\fIvalue\fR.  Each \fIkey\fR
@@@ -50,13 -50,14 +50,13 @@@ configure \fBovs\-vswitchd\fR
  .SS "Bridge Configuration"
  A bridge (switch) with a given \fIname\fR is configured by specifying
  the names of its network devices as values for key
 -\fBbridge.\fIname\fB.port\fR.  (The specified \fIname\fR may not begin
 -with \fBdp\fR or \fBnl:\fR followed by a digit.)
 +\fBbridge.\fIname\fB.port\fR.
  .PP
  The names given on \fBbridge.\fIname\fB.port\fR must be the names of
  existing network devices, except for ``internal ports.''  An internal
  port is a simulated network device that receives traffic only
 -through the virtual switch and switches any traffic sent it through
 -virtual switch.  An internal port may configured with an IP address,
 +through the switch and switches any traffic sent it through the
 +switch.  An internal port may configured with an IP address,
  etc. using the usual system tools (e.g. \fBifconfig\fR, \fBip\fR).  To
  designate network device \fInetdev\fR as an internal port, add
  \fBiface.\fInetdev\fB.internal=true\fR to the configuration file.
@@@ -317,15 -318,16 +317,16 @@@ NetFlow is a protocol that exports a nu
  IP flows, such as the principals involved and duration.  A bridge may be 
  configured to send NetFlow v5 records to NetFlow collectors when flows 
  end.  To enable, define the key \fBnetflow.\fIbridge\fB.host\fR for each 
- collector in the form \fIhost\fB:\fIport\fR.  Records from \fIbridge\fR 
- will be sent to each \fIhost\fR on UDP \fIport\fR.
+ collector in the form \fIip\fB:\fIport\fR.  Records from \fIbridge\fR 
+ will be sent to each \fIip\fR on UDP \fIport\fR.  The \fIip\fR must
+ be specified numerically, not as a DNS name.
  
  The NetFlow messages will use the datapath index for the engine type and id.  
  This can be overridden with the \fBnetflow.\fIbridge\fB.engine-type\fR and 
  \fBnetflow.\fIbridge\fB.engine-id\fR, respectively.  Each takes a value
  between 0 and 255, inclusive. 
  
 -Many NetFlow collectors do not expect multiple virtual switches to be
 +Many NetFlow collectors do not expect multiple switches to be
  sending messages from the same host, and they do not store the engine
  information which could be used to disambiguate the traffic.  To prevent
  flows from multiple switches appearing as if they came on the interface,
@@@ -350,16 -352,15 +351,15 @@@ supports the OpenFlow Management Protoc
  functionality is enabled by setting the key \fBmgmt.controller\fR to one 
  of the following values:
  .
- .TP
- \fBssl:\fIhost\fR[\fB:\fIport\fR]
- The specified SSL \fIport\fR (default: 6633) on the given remote
\fIhost\fR.  SSL must be configured when this form is used (see \fBSSL
+ .IP "\fBssl:\fIip\fR[\fB:\fIport\fR]"
+ The specified SSL \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
+ SSL must be configured when this form is used (see \fBSSL
  Configuration\fR, below).
  .
- .TP
- \fBtcp:\fIhost\fR[\fB:\fIport\fR]
- The specified TCP \fIport\fR (default: 6633) on the given remote
- \fIhost\fR.
+ .IP "\fBtcp:\fIip\fR[\fB:\fIport\fR]"
+ The specified TCP \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
  .PP
  The maximum time between attempts to connect to the controller may be
  specified in integral seconds with the \fBmgmt.max-backoff\fR key.  The
@@@ -400,7 -401,7 +400,7 @@@ switch will perform all configured brid
  .TP
  \fBdiscover\fR
  Use controller discovery to find the local OpenFlow controller.
 -Refer to \fBsecchan\fR(8) for information on how to configure a DHCP
 +Refer to \fB\ovs\-openflowd\fR(8) for information on how to configure a DHCP
  server to support controller discovery.  The following additional
  options control the discovery process:
  .
@@@ -413,8 -414,8 +413,8 @@@ the regular expression will be accepted
  .IP
  The default regular expression is \fBssl:.*\fR, meaning that only SSL
  controller connections will be accepted, when SSL is configured (see
 -\fBSSL Configuration\fR), and \fB.*\fR otherwise, meaning that any
 -controller will be accepted.
 +\fBSSL Configuration\fR), and \fBtcp:.*\fR otherwise, meaning that only
 +TCP controller connections will be accepted.
  .IP
  The regular expression is implicitly anchored at the beginning of the
  controller location string, as if it begins with \fB^\fR.
@@@ -430,15 -431,16 +430,16 @@@ that it receives specifies one or more 
  .RE
  .
  .TP
- \fBssl:\fIhost\fR[\fB:\fIport\fR]
- The specified SSL \fIport\fR (default: 6633) on the given remote
- \fIhost\fR.  SSL must be configured when this form is used (see \fBSSL
+ \fBssl:\fIip\fR[\fB:\fIport\fR]
+ The specified SSL \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
+ SSL must be configured when this form is used (see \fBSSL
  Configuration\fR, below).
  .
  .TP
- \fBtcp:\fIhost\fR[\fB:\fIport\fR]
- The specified TCP \fIport\fR (default: 6633) on the given remote
- \fIhost\fR.
+ \fBtcp:\fIip\fR[\fB:\fIport\fR]
+ The specified TCP \fIport\fR (default: 6633) on the host at the given
+ \fIip\fR, which must be expressed as an IP address (not a DNS name).
  .
  .TP
  \fBunix:\fIfile\fR
@@@ -458,7 -460,7 +459,7 @@@ not in use, the following additional se
  By default, or if this is set to \fBtrue\fR, \fBovs\-vswitchd\fR connects
  to the controller in-band.  If this is set to \fBfalse\fR,
  \fBovs\-vswitchd\fR connects to the controller out-of-band.  Refer to
 -\fBsecchan\fR(8) for a description of in-band and out-of-band control.
 +\fBovs\-openflowd\fR(8) for a description of in-band and out-of-band control.
  .IP "\fBbridge.\fIname\fB.controller.ip=\fIip\fR"
  If specified, the IP address to configure on the bridge's local port.
  .IP "\fBbridge.\fIname\fB.controller.netmask=\fInetmask\fR"
@@@ -476,11 -478,11 +477,11 @@@ This optional setting may be set to \fI
  The minimum value of \fIsecs\fR is 5 seconds.  The default is taken
  from \fBmgmt.inactivity-probe\fR (see above).
  .IP
 -When the virtual switch is connected to the controller, it waits for a
 +When the switch is connected to the controller, it waits for a
  message to be received from the controller for \fIsecs\fR seconds
  before it sends a inactivity probe to the controller.  After sending
  the inactivity probe, if no response is received for an additional
 -\fIsecs\fR seconds, the secure channel assumes that the connection has
 +\fIsecs\fR seconds, \fBovs-vswitchd\fR assumes that the connection has
  been broken and attempts to reconnect.
  .IP
  Changing the inactivity probe interval also changes the interval
@@@ -488,7 -490,7 +489,7 @@@ before entering standalone mode (see be
  .IP "\fBbridge.\fIname\fB.controller.fail-mode=\fBstandalone\fR|\fBsecure\fR"
  .IQ "\fBmgmt.fail-mode=standalone\fR|\fBsecure\fR"
  When a controller is configured, it is, ordinarily, responsible for
 -setting up all flows on the virtual switch.  Thus, if the connection to
 +setting up all flows on the switch.  Thus, if the connection to
  the controller fails, no new network connections can be set up.  If
  the connection to the controller stays down long enough, no packets
  can pass through the switch at all.
@@@ -513,7 -515,7 +514,7 @@@ connection attempts starts at 1 second 
  attempt until it reaches the maximum.  The default maximum backoff
  time is taken from \fBmgmt.max-backoff\fR.
  .ST "Controller Rate-Limiting"
 -These settings configure how the virtual switch applies a ``token
 +These settings configure how the switch applies a ``token
  bucket'' to limit the rate at which packets in unknown flows are
  forwarded to the OpenFlow controller for flow-setup processing.  This
  feature prevents a single bridge from overwhelming a controller.
@@@ -566,23 -568,24 +567,23 @@@ When \fBovs\-vswitchd\fR is configured 
  for controller connectivity, the following settings are required:
  .TP
  \fBssl.private-key=\fIprivkey.pem\fR
 -Specifies a PEM file containing the private key used as the virtual
 +Specifies a PEM file containing the private key used as the 
  switch's identity for SSL connections to the controller.
  .TP
  \fBssl.certificate=\fIcert.pem\fR
  Specifies a PEM file containing a certificate, signed by the
  certificate authority (CA) used by the controller and manager, that
 -certifies the virtual switch's private key, identifying a trustworthy
 +certifies the switch's private key, identifying a trustworthy
  switch.
  .TP
  \fBssl.ca-cert=\fIcacert.pem\fR
  Specifies a PEM file containing the CA certificate used to verify that
 -the virtual switch is connected to a trustworthy controller.
 +the switch is connected to a trustworthy controller.
  .PP
  These files are read only once, at \fBovs\-vswitchd\fR startup time.  If
  their contents change, \fBovs\-vswitchd\fR must be killed and restarted.
  .PP
 -These SSL settings apply to all SSL connections made by the virtual
 -switch.
 +These SSL settings apply to all SSL connections made by the switch.
  .ST "CA Certificate Bootstrap"
  Ordinarily, all of the files named in the SSL configuration must exist
  when \fBovs\-vswitchd\fR starts.  However, if \fBssl.bootstrap-ca-cert\fR
@@@ -620,11 -623,8 +621,11 @@@ Listens for connections on the Unix dom
  Listens for SSL connections on \fIport\fR (default: 6633).  SSL must
  be configured when this form is used (see \fBSSL Configuration\fR,
  above).
 -.IP "\fBptcp:\fR[\fIport\fR]"
 +.IP "\fBptcp:\fR[\fIport\fR][\fB:\fIip\fR]"
  Listens for TCP connections on \fIport\fR (default: 6633).
 +By default, \fB\ovs\-vswitchd\fR listens for connections to any local
 +IP address, but \fIip\fR may be specified to limit connections to the
 +specified local \fIip\fR.
  .RE
  To entirely disable listening for management connections, set
  \fBbridge.\fIname\fB.openflow.listeners\fR to the single value