Merge citrix branch into master.
authorBen Pfaff <blp@nicira.com>
Thu, 16 Jul 2009 18:54:37 +0000 (11:54 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 16 Jul 2009 18:54:37 +0000 (11:54 -0700)
26 files changed:
1  2 
datapath/brcompat.c
datapath/datapath.c
datapath/datapath.h
datapath/dp_dev.c
extras/ezio/ovs-switchui.c
lib/netdev.c
lib/netdev.h
lib/rconn.c
lib/socket-util.c
lib/socket-util.h
lib/vconn-ssl.c
lib/vconn-stream.c
lib/vconn-tcp.c
lib/vconn-unix.c
lib/vconn.c
ofproto/executer.c
ofproto/in-band.c
ofproto/in-band.h
ofproto/ofproto.c
ofproto/ofproto.h
ofproto/status.c
utilities/ovs-ofctl.8.in
utilities/ovs-ofctl.c
vswitchd/bridge.c
vswitchd/ovs-brcompatd.8.in
vswitchd/ovs-vswitchd.conf.5.in

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc lib/netdev.c
Simple merge
diff --cc lib/netdev.h
Simple merge
diff --cc lib/rconn.c
Simple merge
@@@ -300,172 -299,24 +300,190 @@@ 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). */
+ int
+ get_null_fd(void)
+ {
+     static int null_fd = -1;
+     if (null_fd < 0) {
+         null_fd = open("/dev/null", O_RDWR);
+         if (null_fd < 0) {
+             int error = errno;
+             VLOG_ERR("could not open /dev/null: %s", strerror(error));
+             return -error;
+         }
+     }
+     return null_fd;
+ }
  int
  read_fully(int fd, void *p_, size_t size, size_t *bytes_read)
  {
@@@ -32,11 -32,8 +32,12 @@@ int make_unix_socket(int style, bool no
                       const char *bind_path, const char *connect_path);
  int get_unix_name_len(socklen_t sun_len);
  uint32_t guess_netmask(uint32_t ip);
+ int get_null_fd(void);
  
 +int tcp_open_active(const char *target, uint16_t default_port,
 +                    struct sockaddr_in *sinp, int *fdp);
 +int tcp_open_passive(const char *target, uint16_t default_port);
 +
  int read_fully(int fd, void *, size_t, size_t *bytes_read);
  int write_fully(int fd, const void *, size_t, size_t *bytes_written);
  
diff --cc lib/vconn-ssl.c
Simple merge
Simple merge
diff --cc lib/vconn-tcp.c
Simple merge
Simple merge
diff --cc lib/vconn.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -275,31 -277,29 +277,33 @@@ bridge_get_ifaces(struct svec *svec
  void
  bridge_init(void)
  {
 -    int retval;
 -    int i;
 -
 -    bond_init();
 +    struct svec dpif_names;
 +    size_t i;
  
 -    for (i = 0; i < DP_MAX; i++) {
 -        struct dpif dpif;
 -        char devname[16];
+     unixctl_command_register("fdb/show", bridge_unixctl_fdb_show);
 +    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);
          }
      }
  
@@@ -1067,12 -1106,16 +1097,17 @@@ bridge_reconfigure_controller(struct br
          int rate_limit, burst_limit;
  
          if (!strcmp(controller, "discover")) {
+             bool update_resolv_conf = true;
+             if (cfg_has("%s.update-resolv.conf", pfx)) {
+                 update_resolv_conf = cfg_get_bool(0, "%s.update-resolv.conf",
+                         pfx);
+             }
              ofproto_set_discovery(br->ofproto, true,
                                    cfg_get_string(0, "%s.accept-regex", pfx),
-                                   cfg_get_bool(0, "%s.update-resolv.conf",
-                                                pfx));
+                                   update_resolv_conf);
          } else {
 +            char local_name[IF_NAMESIZE];
              struct netdev *netdev;
              bool in_band;
              int error;
Simple merge
Simple merge