[ovs-dev] [stp_tcn 2/2] stp: Allow manual topology change events.
Ethan Jackson
ethan at nicira.com
Mon Jan 16 23:07:56 UTC 2012
Users may want to force the network to flush its MAC tables by
manually triggering a topology change event due to some event in
the system.
Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
lib/stp.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
lib/stp.h | 1 +
vswitchd/bridge.c | 1 +
vswitchd/ovs-vswitchd.8.in | 3 +++
4 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/lib/stp.c b/lib/stp.c
index 1f1f71c..54d4abe 100644
--- a/lib/stp.c
+++ b/lib/stp.c
@@ -29,6 +29,7 @@
#include "byte-order.h"
#include "ofpbuf.h"
#include "packets.h"
+#include "unixctl.h"
#include "util.h"
#include "vlog.h"
@@ -101,6 +102,8 @@ struct stp_port {
};
struct stp {
+ struct list node; /* Node in all_stps list. */
+
/* Static bridge data. */
char *name; /* Human-readable name for log messages. */
stp_identifier bridge_id; /* 8.5.3.7: This bridge. */
@@ -137,6 +140,8 @@ struct stp {
void *aux;
};
+static struct list all_stps = LIST_INITIALIZER(&all_stps);
+
#define FOR_EACH_ENABLED_PORT(PORT, STP) \
for ((PORT) = stp_next_enabled_port((STP), (STP)->ports); \
(PORT); \
@@ -199,6 +204,14 @@ static void stp_stop_timer(struct stp_timer *);
static bool stp_timer_expired(struct stp_timer *, int elapsed, int timeout);
static void stp_send_bpdu(struct stp_port *, const void *, size_t);
+static void stp_unixctl_tcn(struct unixctl_conn *, int argc,
+ const char *argv[], void *aux);
+
+void
+stp_init(void)
+{
+ unixctl_command_register("stp/tcn", "bridge", 1, 1, stp_unixctl_tcn, NULL);
+}
/* Creates and returns a new STP instance that initially has no ports enabled.
*
@@ -261,6 +274,7 @@ stp_create(const char *name, stp_identifier bridge_id,
p->path_cost = 19; /* Recommended default for 100 Mb/s link. */
stp_initialize_port(p, STP_DISABLED);
}
+ list_push_back(&all_stps, &stp->node);
return stp;
}
@@ -269,6 +283,7 @@ void
stp_destroy(struct stp *stp)
{
if (stp) {
+ list_remove(&stp->node);
free(stp->name);
free(stp);
}
@@ -1322,3 +1337,32 @@ stp_send_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
p->stp->send_bpdu(pkt, stp_port_no(p), p->stp->aux);
p->tx_count++;
}
+
+/* Unixctl. */
+
+static struct stp *
+stp_find(const char *name)
+{
+ struct stp *stp;
+
+ LIST_FOR_EACH (stp, node, &all_stps) {
+ if (!strcmp(stp->name, name)) {
+ return stp;
+ }
+ }
+ return NULL;
+}
+
+static void
+stp_unixctl_tcn(struct unixctl_conn *conn, int argc OVS_UNUSED,
+ const char *argv[], void *aux OVS_UNUSED)
+{
+ struct stp *stp = stp_find(argv[1]);
+
+ if (stp) {
+ stp_topology_change_detection(stp);
+ unixctl_command_reply(conn, 200, "OK");
+ } else {
+ unixctl_command_reply(conn, 501, "no such stp object");
+ }
+}
diff --git a/lib/stp.h b/lib/stp.h
index e60be01..acdaa6c 100644
--- a/lib/stp.h
+++ b/lib/stp.h
@@ -55,6 +55,7 @@ typedef uint64_t stp_identifier;
/* Basic STP functionality. */
#define STP_MAX_PORTS 255
+void stp_init(void);
struct stp *stp_create(const char *name, stp_identifier bridge_id,
void (*send_bpdu)(struct ofpbuf *bpdu, int port_no,
void *aux),
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index b45b972..7a08290 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -319,6 +319,7 @@ bridge_init(const char *remote)
lacp_init();
bond_init();
cfm_init();
+ stp_init();
}
void
diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in
index 314fe60..c540883 100644
--- a/vswitchd/ovs-vswitchd.8.in
+++ b/vswitchd/ovs-vswitchd.8.in
@@ -118,6 +118,9 @@ Displays detailed information about Connectivity Fault Management
configured on \fIinterface\fR. If \fIinterface\fR is not specified,
then displays detailed information about all interfaces with CFM
enabled.
+.IP "\fBstp/tcn\fR \fIbridge\fR"
+Forces a topology change event on \fIbridge\fR if it's running STP. This
+may cause it to send Topology Change Notifications to its peers.
.SS "BRIDGE COMMANDS"
These commands manage bridges.
.IP "\fBfdb/flush\fR \fIbridge\fR"
--
1.7.7.1
More information about the dev
mailing list