[ovs-dev] [reconnect 1/2] vswitch: Implement unixctl command to reconnect OpenFlow connections.

Ben Pfaff blp at nicira.com
Fri Jun 18 21:00:13 UTC 2010


This feature may be useful for debugging.

Feature #2222.
---
 ofproto/ofproto.c          |   18 +++++++++++++-----
 ofproto/ofproto.h          |    1 +
 vswitchd/bridge.c          |   26 ++++++++++++++++++++++++++
 vswitchd/ovs-vswitchd.8.in |    6 ++++++
 4 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 4c4df94..481d50b 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -414,15 +414,11 @@ ofproto_set_datapath_id(struct ofproto *p, uint64_t datapath_id)
     uint64_t old_dpid = p->datapath_id;
     p->datapath_id = datapath_id ? datapath_id : pick_datapath_id(p);
     if (p->datapath_id != old_dpid) {
-        struct ofconn *ofconn;
-
         VLOG_INFO("datapath ID changed to %016"PRIx64, p->datapath_id);
 
         /* Force all active connections to reconnect, since there is no way to
          * notify a controller that the datapath ID has changed. */
-        LIST_FOR_EACH (ofconn, struct ofconn, node, &p->all_conns) {
-            rconn_reconnect(ofconn->rconn);
-        }
+        ofproto_reconnect_controllers(p);
     }
 }
 
@@ -667,6 +663,18 @@ ofproto_set_controllers(struct ofproto *p,
     }
 }
 
+/* Drops the connections between 'ofproto' and all of its controllers, forcing
+ * them to reconnect. */
+void
+ofproto_reconnect_controllers(struct ofproto *ofproto)
+{
+    struct ofconn *ofconn;
+
+    LIST_FOR_EACH (ofconn, struct ofconn, node, &ofproto->all_conns) {
+        rconn_reconnect(ofconn->rconn);
+    }
+}
+
 static bool
 any_extras_changed(const struct ofproto *ofproto,
                    const struct sockaddr_in *extras, size_t n)
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index c3d71e8..9880e82 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -104,6 +104,7 @@ bool ofproto_is_alive(const struct ofproto *);
 void ofproto_set_datapath_id(struct ofproto *, uint64_t datapath_id);
 void ofproto_set_controllers(struct ofproto *,
                              const struct ofproto_controller *, size_t n);
+void ofproto_reconnect_controllers(struct ofproto *);
 void ofproto_set_extra_in_band_remotes(struct ofproto *,
                                        const struct sockaddr_in *, size_t n);
 void ofproto_set_desc(struct ofproto *,
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 47f269f..ac93c87 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -196,6 +196,7 @@ static struct bridge *bridge_create(const struct ovsrec_bridge *br_cfg);
 static void bridge_destroy(struct bridge *);
 static struct bridge *bridge_lookup(const char *name);
 static unixctl_cb_func bridge_unixctl_dump_flows;
+static unixctl_cb_func bridge_unixctl_reconnect;
 static int bridge_run_one(struct bridge *);
 static size_t bridge_get_controllers(const struct ovsrec_open_vswitch *ovs_cfg,
                                      const struct bridge *br,
@@ -338,6 +339,8 @@ bridge_init(const struct ovsrec_open_vswitch *cfg)
 
     unixctl_command_register("bridge/dump-flows", bridge_unixctl_dump_flows,
                              NULL);
+    unixctl_command_register("bridge/reconnect", bridge_unixctl_reconnect,
+                             NULL);
 
     bond_init();
     bridge_reconfigure(cfg);
@@ -1288,6 +1291,29 @@ bridge_unixctl_dump_flows(struct unixctl_conn *conn,
     ds_destroy(&results);
 }
 
+/* "bridge/reconnect [BRIDGE]": makes BRIDGE drop all of its controller
+ * connections and reconnect.  If BRIDGE is not specified, then all bridges
+ * drop their controller connections and reconnect. */
+static void
+bridge_unixctl_reconnect(struct unixctl_conn *conn,
+                         const char *args, void *aux OVS_UNUSED)
+{
+    struct bridge *br;
+    if (args[0] != '\0') {
+        br = bridge_lookup(args);
+        if (!br) {
+            unixctl_command_reply(conn, 501, "Unknown bridge");
+            return;
+        }
+        ofproto_reconnect_controllers(br->ofproto);
+    } else {
+        LIST_FOR_EACH (br, struct bridge, node, &all_bridges) {
+            ofproto_reconnect_controllers(br->ofproto);
+        }
+    }
+    unixctl_command_reply(conn, 200, NULL);
+}
+
 static int
 bridge_run_one(struct bridge *br)
 {
diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in
index 0a7369e..468d125 100644
--- a/vswitchd/ovs-vswitchd.8.in
+++ b/vswitchd/ovs-vswitchd.8.in
@@ -117,6 +117,12 @@ These commands manage bridges.
 Lists each MAC address/VLAN pair learned by the specified \fIbridge\fR,
 along with the port on which it was learned and the age of the entry,
 in seconds.
+.IP "\fBbridge/reconnect\fR [\fIbridge\fR]"
+Makes \fIbridge\fR drop all of its OpenFlow controller connections and
+reconnect.  If \fIbridge\fR is not specified, then all bridges drop
+their controller connections and reconnect.
+.IP
+This command might be useful for debugging OpenFlow controller issues.
 .
 .IP "\fBbridge/dump-flows\fR \fIbridge\fR"
 Lists all flows in \fIbridge\fR, including those normally hidden to
-- 
1.7.1





More information about the dev mailing list