With this change there is no need to restart the DB or OVS on configuring a different value for the manager or controller connection respectively. On detecting a change in the dscp value on the socket, the previous socket is closed and a new socket is created and connection is established with the new configured dscp value.
Signed-off-by: Mehak Mahajan <mmaha...@nicira.com> --- lib/jsonrpc.c | 8 +++++- lib/jsonrpc.h | 4 ++- lib/rconn.c | 7 ++++++ lib/rconn.h | 1 + lib/socket-util.c | 1 + ofproto/connmgr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ ovsdb/jsonrpc-server.c | 22 ++++++++++++++++---- vswitchd/vswitch.ovsschema | 4 +- vswitchd/vswitch.xml | 14 +++++------- 9 files changed, 89 insertions(+), 18 deletions(-) diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c index 5c3359c..e9d096d 100644 --- a/lib/jsonrpc.c +++ b/lib/jsonrpc.c @@ -828,7 +828,7 @@ jsonrpc_session_disconnect(struct jsonrpc_session *s) } } -static void +void jsonrpc_session_connect(struct jsonrpc_session *s) { const char *name = reconnect_get_name(s->reconnect); @@ -1056,7 +1056,11 @@ jsonrpc_session_set_probe_interval(struct jsonrpc_session *s, void jsonrpc_session_set_dscp(struct jsonrpc_session *s, - uint8_t dscp) + uint8_t dscp, + bool *options_changed) { + if (s->dscp != dscp) { + *options_changed = true; + } s->dscp = dscp; } diff --git a/lib/jsonrpc.h b/lib/jsonrpc.h index cd78170..eb496bb 100644 --- a/lib/jsonrpc.h +++ b/lib/jsonrpc.h @@ -102,6 +102,7 @@ struct jsonrpc_session *jsonrpc_session_open_unreliably(struct jsonrpc *); void jsonrpc_session_close(struct jsonrpc_session *); void jsonrpc_session_run(struct jsonrpc_session *); +void jsonrpc_session_connect(struct jsonrpc_session *s); void jsonrpc_session_wait(struct jsonrpc_session *); size_t jsonrpc_session_get_backlog(const struct jsonrpc_session *); @@ -125,6 +126,7 @@ void jsonrpc_session_set_max_backoff(struct jsonrpc_session *, void jsonrpc_session_set_probe_interval(struct jsonrpc_session *, int probe_interval); void jsonrpc_session_set_dscp(struct jsonrpc_session *, - uint8_t dscp); + uint8_t dscp, + bool *options_changed); #endif /* jsonrpc.h */ diff --git a/lib/rconn.c b/lib/rconn.c index 2ddfc69..954835e 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -664,6 +664,13 @@ rconn_set_name(struct rconn *rc, const char *new_name) rc->name = xstrdup(new_name); } +/* Returns dscp value associated with the target in rconn. */ +const uint8_t +rconn_get_dscp(const struct rconn *rc) +{ + return rc->dscp; +} + /* Returns 'rc''s target. This is intended to be a string that may be passed * directly to, e.g., vconn_open(). */ const char * diff --git a/lib/rconn.h b/lib/rconn.h index 2b1332c..7c32232 100644 --- a/lib/rconn.h +++ b/lib/rconn.h @@ -67,6 +67,7 @@ void rconn_add_monitor(struct rconn *, struct vconn *); const char *rconn_get_name(const struct rconn *); void rconn_set_name(struct rconn *, const char *new_name); const char *rconn_get_target(const struct rconn *); +const uint8_t rconn_get_dscp(const struct rconn *); bool rconn_is_alive(const struct rconn *); bool rconn_is_connected(const struct rconn *); diff --git a/lib/socket-util.c b/lib/socket-util.c index 82a33c2..dd6123c 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -586,6 +586,7 @@ inet_open_active(int style, const char *target, uint16_t default_port, error = errno; goto exit; } + error = set_nonblocking(fd); if (error) { goto exit; diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index a0315b2..b0e6a5f 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -386,8 +386,13 @@ connmgr_retry(struct connmgr *mgr) /* OpenFlow configuration. */ static void add_controller(struct connmgr *, const char *target, uint8_t dscp); +static void +reconfigure_controller(struct connmgr *mgr, const char *target, uint8_t dscp); static struct ofconn *find_controller_by_target(struct connmgr *, const char *target); +static +bool has_controller_params_changed(struct connmgr *mgr, const char *target, + uint8_t dscp); static void update_fail_open(struct connmgr *); static int set_pvconns(struct pvconn ***pvconnsp, size_t *n_pvconnsp, const struct sset *); @@ -495,6 +500,10 @@ connmgr_set_controllers(struct connmgr *mgr, VLOG_INFO("%s: added primary controller \"%s\"", mgr->name, c->target); add_controller(mgr, c->target, c->dscp); + } else if (has_controller_params_changed(mgr, c->target, c->dscp)) { + VLOG_INFO("%s: reconfiguring the controller \"%s\"", + mgr->name, c->target); + reconfigure_controller(mgr, c->target, c->dscp); } } else if (!pvconn_verify_name(c->target)) { if (!ofservice_lookup(mgr, c->target)) { @@ -608,6 +617,26 @@ add_controller(struct connmgr *mgr, const char *target, uint8_t dscp) free(name); } +static void +reconfigure_controller(struct connmgr *mgr, const char *target, uint8_t dscp) +{ + struct ofconn *ofconn; + char *name = ofconn_make_name(mgr, target); + + HMAP_FOR_EACH_WITH_HASH (ofconn, hmap_node, + hash_string(target, 0), &mgr->controllers) { + if (!strcmp(ofconn_get_target(ofconn), target)) { + /* Some value used for configuring the connection between the + * controller and switch has changed. Set the new value in 'rconn' + * and re-connect. */ + rconn_set_dscp(ofconn->rconn, dscp); + rconn_connect(ofconn->rconn, target, name); + } else { + VLOG_ERR("error finding ofconn for target \"%s\"\n",target); + } + } +} + static struct ofconn * find_controller_by_target(struct connmgr *mgr, const char *target) { @@ -622,6 +651,23 @@ find_controller_by_target(struct connmgr *mgr, const char *target) return NULL; } +static bool +has_controller_params_changed(struct connmgr *mgr, const char *target, + uint8_t dscp) +{ + struct ofconn *ofconn; + + HMAP_FOR_EACH_WITH_HASH (ofconn, hmap_node, + hash_string(target, 0), &mgr->controllers) { + if (!strcmp(ofconn_get_target(ofconn), target)) { + if (rconn_get_dscp(ofconn) != dscp) { + return true; + } + } + } + return false; + } + static void update_in_band_remotes(struct connmgr *mgr) { diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index bb887d0..ebc8403 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -336,8 +336,10 @@ static int ovsdb_jsonrpc_session_run(struct ovsdb_jsonrpc_session *); static void ovsdb_jsonrpc_session_wait(struct ovsdb_jsonrpc_session *); static void ovsdb_jsonrpc_session_get_memory_usage( const struct ovsdb_jsonrpc_session *, struct simap *usage); -static void ovsdb_jsonrpc_session_set_options( - struct ovsdb_jsonrpc_session *, const struct ovsdb_jsonrpc_options *); +static void +ovsdb_jsonrpc_session_set_options(struct ovsdb_jsonrpc_session *session, + const struct ovsdb_jsonrpc_options *options, + bool *options_changed); static void ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *, struct jsonrpc_msg *); static void ovsdb_jsonrpc_session_got_notify(struct ovsdb_jsonrpc_session *, @@ -410,11 +412,12 @@ ovsdb_jsonrpc_session_run(struct ovsdb_jsonrpc_session *s) static void ovsdb_jsonrpc_session_set_options(struct ovsdb_jsonrpc_session *session, - const struct ovsdb_jsonrpc_options *options) + const struct ovsdb_jsonrpc_options *options, + bool *options_changed) { jsonrpc_session_set_max_backoff(session->js, options->max_backoff); jsonrpc_session_set_probe_interval(session->js, options->probe_interval); - jsonrpc_session_set_dscp(session->js, options->dscp); + jsonrpc_session_set_dscp(session->js, options->dscp, options_changed); } static void @@ -505,7 +508,16 @@ ovsdb_jsonrpc_session_set_all_options( struct ovsdb_jsonrpc_session *s; LIST_FOR_EACH (s, node, &remote->sessions) { - ovsdb_jsonrpc_session_set_options(s, options); + bool options_changed = false; + + ovsdb_jsonrpc_session_set_options(s, options, &options_changed); + /* If the options associated with the session have changed, reconnect + * the session. Currently this only checks if the values of dscp have + * changed. For the dscp values to take effect, the connection must + * be reset. */ + if (options_changed) { + jsonrpc_session_connect(s->js); + } } } diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema index 9712003..18bd62b 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,6 +1,6 @@ {"name": "Open_vSwitch", - "version": "6.9.3", - "cksum": "2110020336 16754", + "version": "6.9.4", + "cksum": "473114776 16754", "tables": { "Open_vSwitch": { "columns": { diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 32d4c59..780217c 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -2756,10 +2756,9 @@ Service (QoS) on IP networks. The DSCP value specified here is used when establishing the connection - between the controller and the Open vSwitch. The connection must be - reset for the new DSCP values to take effect. If no value is - specified, a default value of 48 is chosen. Valid DSCP values must be - in the range 0 to 63. + between the controller and the Open vSwitch. If no value is specified, + a default value of 48 is chosen. Valid DSCP values must be in the + range 0 to 63. </column> </group> @@ -3003,10 +3002,9 @@ Service (QoS) on IP networks. The DSCP value specified here is used when establishing the connection - between the manager and the Open vSwitch. The connection must be - reset for the new DSCP values to take effect. If no value is - specified, a default value of 48 is chosen. Valid DSCP values must be - in the range 0 to 63. + between the manager and the Open vSwitch. The new value is reflected + within a maximum of 8 seconds. If no value is specified, a default + value of 48 is chosen. Valid DSCP values must be in the range 0 to 63. </column> </group> -- 1.7.2.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev