[ovs-dev] [PATCH] connmgr: fix flow-restore-wait not work with controller connects

wenxu at ucloud.cn wenxu at ucloud.cn
Sat May 9 09:32:22 UTC 2020


From: wenxu <wenxu at ucloud.cn>

When restart the vswitchd with flow-restore-wait. The Vswitch doesn't
connect to the controller util the flow-restore-wait finished.

Because when bridge_configure_remotes() calls bridge_get_controllers(),
it first checks if flow-restore-wait has been set, and if so,
it ignores any controllers in the controller database and
sets n_controllers to 0.

So after the flows restore in ovs and remove the flow-restore-wait.
The vswitchd will connect the controller. But it will flush all
the flows we restored.

In the connmgr_set_controllers if (had_controllers != connmgr_has_controllers(mgr))
it will flush all the flows through ofproto_flush_flows(mgr->ofproto);
This make flow-restore-wait feature not work at all with controller connects.

This patch record the flow-restore-wait event and it will avoid the flow
flush if it experience a flow-restore-wait event..

Signed-off-by: wenxu <wenxu at ucloud.cn>
---
 ofproto/connmgr.c | 16 ++++++++++++++--
 ofproto/connmgr.h |  3 ++-
 ofproto/ofproto.c |  5 +++--
 ofproto/ofproto.h |  3 ++-
 vswitchd/bridge.c |  9 ++++++---
 5 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
index 51d656c..4debc9f 100644
--- a/ofproto/connmgr.c
+++ b/ofproto/connmgr.c
@@ -231,6 +231,8 @@ struct connmgr {
     size_t n_extra_remotes;
     int in_band_queue;
 
+    bool flow_restore;
+
     ATOMIC(int) want_packet_in_on_miss;   /* Sum of ofconns' values. */
 };
 
@@ -571,7 +573,8 @@ connmgr_free_controller_info(struct shash *info)
 /* Changes 'mgr''s set of controllers to the 'n_controllers' controllers in
  * 'controllers'. */
 void
-connmgr_set_controllers(struct connmgr *mgr, struct shash *controllers)
+connmgr_set_controllers(struct connmgr *mgr, struct shash *controllers,
+                        bool flow_restore)
     OVS_EXCLUDED(ofproto_mutex)
 {
     bool had_controllers = connmgr_has_controllers(mgr);
@@ -611,8 +614,17 @@ connmgr_set_controllers(struct connmgr *mgr, struct shash *controllers)
     update_in_band_remotes(mgr);
     update_fail_open(mgr);
     if (had_controllers != connmgr_has_controllers(mgr)) {
-        ofproto_flush_flows(mgr->ofproto);
+        if (had_controllers == false &&
+            mgr->flow_restore == true &&
+            flow_restore == false) {
+            goto out;
+        } else {
+            ofproto_flush_flows(mgr->ofproto);
+        }
     }
+
+out:
+    mgr->flow_restore = flow_restore;
 }
 
 /* Drops the connections between 'mgr' and all of its primary and secondary
diff --git a/ofproto/connmgr.h b/ofproto/connmgr.h
index 079c843..e164ea1 100644
--- a/ofproto/connmgr.h
+++ b/ofproto/connmgr.h
@@ -74,7 +74,8 @@ void connmgr_retry(struct connmgr *);
 bool connmgr_has_controllers(const struct connmgr *);
 void connmgr_get_controller_info(struct connmgr *, struct shash *);
 void connmgr_free_controller_info(struct shash *);
-void connmgr_set_controllers(struct connmgr *, struct shash *);
+void connmgr_set_controllers(struct connmgr *, struct shash *,
+                             bool flow_restore);
 void connmgr_reconnect(const struct connmgr *);
 
 int connmgr_set_snoops(struct connmgr *, const struct sset *snoops);
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 0fbd6c3..f20d86a 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -643,9 +643,10 @@ ofproto_set_datapath_id(struct ofproto *p, uint64_t datapath_id)
 }
 
 void
-ofproto_set_controllers(struct ofproto *p, struct shash *controllers)
+ofproto_set_controllers(struct ofproto *p, struct shash *controllers,
+                        bool flow_restore)
 {
-    connmgr_set_controllers(p->connmgr, controllers);
+    connmgr_set_controllers(p->connmgr, controllers, flow_restore);
 }
 
 void
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index 2dd2531..be7097a 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -329,7 +329,8 @@ int ofproto_port_query_by_name(const struct ofproto *, const char *devname,
 /* Top-level configuration. */
 uint64_t ofproto_get_datapath_id(const struct ofproto *);
 void ofproto_set_datapath_id(struct ofproto *, uint64_t datapath_id);
-void ofproto_set_controllers(struct ofproto *, struct shash *controllers);
+void ofproto_set_controllers(struct ofproto *, struct shash *controllers,
+                             bool flow_restore);
 void ofproto_set_fail_mode(struct ofproto *, enum ofproto_fail_mode fail_mode);
 void ofproto_reconnect_controllers(struct ofproto *);
 void ofproto_set_extra_in_band_remotes(struct ofproto *,
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index fe73c38..d87de45 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -3867,6 +3867,8 @@ bridge_configure_remotes(struct bridge *br,
 
     enum ofproto_fail_mode fail_mode;
 
+    bool flow_restore;
+
     /* Check if we should disable in-band control on this bridge. */
     disable_in_band = smap_get_bool(&br->cfg->other_config, "disable-in-band",
                                     false);
@@ -3882,8 +3884,9 @@ bridge_configure_remotes(struct bridge *br,
         ofproto_set_extra_in_band_remotes(br->ofproto, managers, n_managers);
     }
 
-    n_controllers = (ofproto_get_flow_restore_wait() ? 0
-                     : bridge_get_controllers(br, &controllers));
+    flow_restore = ofproto_get_flow_restore_wait();
+    n_controllers = flow_restore ? 0
+                    : bridge_get_controllers(br, &controllers);
 
     /* The set of controllers to pass down to ofproto. */
     struct shash ocs = SHASH_INITIALIZER(&ocs);
@@ -3981,7 +3984,7 @@ bridge_configure_remotes(struct bridge *br,
         };
         shash_add(&ocs, c->target, oc);
     }
-    ofproto_set_controllers(br->ofproto, &ocs);
+    ofproto_set_controllers(br->ofproto, &ocs, flow_restore);
     shash_destroy_free_data(&ocs);
 
     /* Set the fail-mode. */
-- 
1.8.3.1



More information about the dev mailing list