X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=lib%2Frconn.c;h=a6b634bc702057fe6b43fd0073434044edb807d6;hb=bee6b8bc16b1c42fef8843cffe4d68b464cddadf;hp=ddf578c185aded6b2440d9b18e5b8141c46b41a8;hpb=1a126c0c6803db4e6c16ddc0a3369a6ad197d238;p=openvswitch diff --git a/lib/rconn.c b/lib/rconn.c index ddf578c1..a6b634bc 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -131,8 +131,15 @@ struct rconn { #define MAX_MONITORS 8 struct vconn *monitors[8]; size_t n_monitors; + + uint32_t allowed_versions; }; +uint32_t rconn_get_allowed_versions(const struct rconn *rconn) +{ + return rconn->allowed_versions; +} + static unsigned int elapsed_in_this_state(const struct rconn *); static unsigned int timeout(const struct rconn *); static bool timed_out(const struct rconn *); @@ -163,9 +170,17 @@ static bool rconn_logging_connection_attempts__(const struct rconn *); * 8 seconds is used. * * The new rconn is initially unconnected. Use rconn_connect() or - * rconn_connect_unreliably() to connect it. */ + * rconn_connect_unreliably() to connect it. + * + * Connections made by the rconn will automatically negotiate an OpenFlow + * protocol version acceptable to both peers on the connection. The version + * negotiated will be one of those in the 'allowed_versions' bitmap: + * version 'x' is allowed if allowed_versions & (1 << x) is nonzero. If + * 'allowed_versions' is zero, then OFPUTIL_DEFAULT_VERSIONS are allowed. + **/ struct rconn * -rconn_create(int probe_interval, int max_backoff, uint8_t dscp) +rconn_create(int probe_interval, int max_backoff, uint8_t dscp, + uint32_t allowed_versions) { struct rconn *rc = xzalloc(sizeof *rc); @@ -203,6 +218,9 @@ rconn_create(int probe_interval, int max_backoff, uint8_t dscp) rconn_set_dscp(rc, dscp); rc->n_monitors = 0; + rc->allowed_versions = allowed_versions + ? allowed_versions + : OFPUTIL_DEFAULT_VERSIONS; return rc; } @@ -354,7 +372,8 @@ reconnect(struct rconn *rc) VLOG_INFO("%s: connecting...", rc->name); } rc->n_attempted_connections++; - retval = vconn_open(rc->target, OFP10_VERSION, &rc->vconn, rc->dscp); + retval = vconn_open(rc->target, rc->allowed_versions, + &rc->vconn, rc->dscp); if (!retval) { rc->remote_ip = vconn_get_remote_ip(rc->vconn); rc->local_ip = vconn_get_local_ip(rc->vconn); @@ -657,6 +676,14 @@ void rconn_add_monitor(struct rconn *rc, struct vconn *vconn) { if (rc->n_monitors < ARRAY_SIZE(rc->monitors)) { + int version = vconn_get_version(rc->vconn); + + /* Override the allowed versions of the snoop vconn so that + * only the version of the controller connection is allowed. + * This is because the snoop will see the same messages as the + * controller */ + vconn_set_allowed_versions(vconn, 1u << version); + VLOG_INFO("new monitor connection from %s", vconn_get_name(vconn)); rc->monitors[rc->n_monitors++] = vconn; } else {