From: Ben Pfaff Date: Mon, 14 Jul 2008 21:01:06 +0000 (-0700) Subject: vconn: Make errors in vconn names non-fatal errors. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d838ee2e03256bb3b116de6ed05548011ed97728;p=openvswitch vconn: Make errors in vconn names non-fatal errors. This prevents bad vconn names obtained via discovery from killing the secure channel. --- diff --git a/include/rconn.h b/include/rconn.h index 0e9f4a7a..228b8e89 100644 --- a/include/rconn.h +++ b/include/rconn.h @@ -59,7 +59,7 @@ struct rconn *rconn_new_from_vconn(const char *name, int txq_limit, struct vconn *); struct rconn *rconn_create(int txq_limit, int inactivity_probe_interval, int max_backoff); -void rconn_connect(struct rconn *, const char *name); +int rconn_connect(struct rconn *, const char *name); void rconn_connect_unreliably(struct rconn *, const char *name, struct vconn *vconn); void rconn_disconnect(struct rconn *); diff --git a/lib/rconn.c b/lib/rconn.c index 7f5a1dcf..a145e4e3 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -116,7 +116,7 @@ static unsigned int elapsed_in_this_state(const struct rconn *); static bool timeout(struct rconn *, unsigned int secs); static void state_transition(struct rconn *, enum state); static int try_send(struct rconn *); -static void reconnect(struct rconn *); +static int reconnect(struct rconn *); static void disconnect(struct rconn *, int error); static void question_connectivity(struct rconn *); @@ -187,14 +187,14 @@ rconn_create(int txq_limit, int probe_interval, int max_backoff) return rc; } -void +int rconn_connect(struct rconn *rc, const char *name) { rconn_disconnect(rc); free(rc->name); rc->name = xstrdup(name); rc->reliable = true; - reconnect(rc); + return reconnect(rc); } void @@ -246,7 +246,7 @@ run_VOID(struct rconn *rc) /* Nothing to do. */ } -static void +static int reconnect(struct rconn *rc) { int retval; @@ -260,6 +260,7 @@ reconnect(struct rconn *rc) VLOG_WARN("%s: connection failed (%s)", rc->name, strerror(retval)); disconnect(rc, 0); } + return retval; } static void @@ -273,18 +274,19 @@ run_BACKOFF(struct rconn *rc) static void run_CONNECTING(struct rconn *rc) { - int error = vconn_connect(rc->vconn); - if (!error) { + int retval = vconn_connect(rc->vconn); + if (!retval) { VLOG_WARN("%s: connected", rc->name); if (vconn_is_passive(rc->vconn)) { - fatal(0, "%s: passive vconn not supported in switch", - rc->name); + error(0, "%s: passive vconn not supported", rc->name); + state_transition(rc, S_VOID); + } else { + state_transition(rc, S_ACTIVE); + rc->last_connected = rc->state_entered; } - state_transition(rc, S_ACTIVE); - rc->last_connected = rc->state_entered; - } else if (error != EAGAIN) { - VLOG_WARN("%s: connection failed (%s)", rc->name, strerror(error)); - disconnect(rc, error); + } else if (retval != EAGAIN) { + VLOG_WARN("%s: connection failed (%s)", rc->name, strerror(retval)); + disconnect(rc, retval); } else if (timeout(rc, MAX(1, rc->backoff))) { VLOG_WARN("%s: connection timed out", rc->name); rc->backoff_deadline = TIME_MAX; /* Prevent resetting backoff. */ diff --git a/lib/vconn-netlink.c b/lib/vconn-netlink.c index 6e7e152e..84d7d354 100644 --- a/lib/vconn-netlink.c +++ b/lib/vconn-netlink.c @@ -77,7 +77,8 @@ netlink_open(const char *name, char *suffix, struct vconn **vconnp) subscribe = 1; if (sscanf(suffix, "%d:%d", &dp_idx, &subscribe) < 1) { - fatal(0, "%s: syntax error", name); + error(0, "%s: syntax error", name); + return EAFNOSUPPORT; } netlink = xmalloc(sizeof *netlink); diff --git a/lib/vconn-ssl.c b/lib/vconn-ssl.c index 0da4c578..a7060d74 100644 --- a/lib/vconn-ssl.c +++ b/lib/vconn-ssl.c @@ -270,7 +270,8 @@ ssl_open(const char *name, char *suffix, struct vconn **vconnp) host_name = strtok_r(suffix, "::", &save_ptr); port_string = strtok_r(NULL, "::", &save_ptr); if (!host_name) { - fatal(0, "%s: bad peer name format", name); + error(0, "%s: bad peer name format", name); + return EAFNOSUPPORT; } memset(&sin, 0, sizeof sin); diff --git a/lib/vconn-tcp.c b/lib/vconn-tcp.c index aaff9403..80c8f56c 100644 --- a/lib/vconn-tcp.c +++ b/lib/vconn-tcp.c @@ -117,7 +117,8 @@ tcp_open(const char *name, char *suffix, struct vconn **vconnp) host_name = strtok_r(suffix, "::", &save_ptr); port_string = strtok_r(NULL, "::", &save_ptr); if (!host_name) { - fatal(0, "%s: bad peer name format", name); + error(0, "%s: bad peer name format", name); + return EAFNOSUPPORT; } memset(&sin, 0, sizeof sin); diff --git a/lib/vconn.c b/lib/vconn.c index db1cc4c5..103c9df5 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -143,7 +143,8 @@ vconn_open(const char *name, struct vconn **vconnp) prefix_len = strcspn(name, ":"); if (prefix_len == strlen(name)) { - fatal(0, "`%s' not correct format for peer name", name); + error(0, "`%s' not correct format for peer name", name); + return EAFNOSUPPORT; } for (i = 0; i < ARRAY_SIZE(vconn_classes); i++) { struct vconn_class *class = vconn_classes[i]; @@ -161,8 +162,8 @@ vconn_open(const char *name, struct vconn **vconnp) return retval; } } - fatal(0, "unknown peer type `%.*s'", (int) prefix_len, name); - abort(); + error(0, "unknown peer type `%.*s'", (int) prefix_len, name); + return EAFNOSUPPORT; } int diff --git a/secchan/secchan.c b/secchan/secchan.c index 61039b5b..8638dc76 100644 --- a/secchan/secchan.c +++ b/secchan/secchan.c @@ -135,6 +135,7 @@ static bool fail_open_hook(struct relay *r); int main(int argc, char *argv[]) { + struct rconn *local_rconn, *remote_rconn; struct vconn *listen_vconn; struct relay *controller_relay; const char *nl_name; @@ -201,10 +202,18 @@ main(int argc, char *argv[]) daemonize(); - controller_relay = relay_create(rconn_new(argv[optind], 1, 0, max_backoff), - rconn_new(argv[optind + 1], 1, - probe_interval, max_backoff), - false); + local_rconn = rconn_create(1, 0, max_backoff); + retval = rconn_connect(local_rconn, nl_name); + if (retval == EAFNOSUPPORT) { + fatal(0, "No support for %s vconn", nl_name); + } + + remote_rconn = rconn_create(1, probe_interval, max_backoff); + retval = rconn_connect(remote_rconn, argv[optind + 1]); + if (retval == EAFNOSUPPORT) { + fatal(0, "No support for %s vconn", argv[optind + 1]); + } + controller_relay = relay_create(local_rconn, remote_rconn, false); for (;;) { struct relay *r, *n; diff --git a/switch/switch.c b/switch/switch.c index 77d43bb8..01fb4b82 100644 --- a/switch/switch.c +++ b/switch/switch.c @@ -71,6 +71,7 @@ static void add_ports(struct datapath *dp, char *port_list); int main(int argc, char *argv[]) { + struct rconn *rconn; int error; set_program_name(argv[0]); @@ -82,7 +83,12 @@ main(int argc, char *argv[]) fatal(0, "missing controller argument; use --help for usage"); } - error = dp_new(&dp, dpid, rconn_new(argv[optind], 128, 60, max_backoff)); + rconn = rconn_create(128, 60, max_backoff); + error = rconn_connect(rconn, argv[optind]); + if (error == EAFNOSUPPORT) { + fatal(0, "no support for %s vconn", argv[optind]); + } + error = dp_new(&dp, dpid, rconn); if (listen_vconn_name) { struct vconn *listen_vconn; int retval;