vswitch: Implement unixctl command to reconnect OpenFlow connections.
authorBen Pfaff <blp@nicira.com>
Fri, 18 Jun 2010 20:58:42 +0000 (13:58 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 24 Jun 2010 19:49:17 +0000 (12:49 -0700)
This feature may be useful for debugging.

Feature #2222.

ofproto/ofproto.c
ofproto/ofproto.h
vswitchd/bridge.c
vswitchd/ovs-vswitchd.8.in

index 4c4df9493f5c90b44e923d797d149d84a0377e4d..481d50b845768941c0611bd552d6c2ba669f3151 100644 (file)
@@ -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)
index c3d71e8d1bd7a0566ef573b21e043a526396d577..9880e8250b5de82ecb81112c3117fa398fa81122 100644 (file)
@@ -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 *,
index 3768eb9c625657d858f1c2bad83c502f5fb67483..d4a08b92fd36a1c8513ec2f6902a40d7c4840cd0 100644 (file)
@@ -195,6 +195,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,
@@ -272,6 +273,8 @@ bridge_init(const char *remote)
     unixctl_command_register("fdb/show", bridge_unixctl_fdb_show, NULL);
     unixctl_command_register("bridge/dump-flows", bridge_unixctl_dump_flows,
                              NULL);
+    unixctl_command_register("bridge/reconnect", bridge_unixctl_reconnect,
+                             NULL);
     bond_init();
 }
 
@@ -1353,6 +1356,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)
 {
index 0e5d3188ef1d817aee0bc92bf20d05114547415b..79f17d3db6f52ecd50b379737146609e36263fe9 100644 (file)
@@ -118,6 +118,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