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

Reply via email to