Signed-off-by: Ethan Jackson <[email protected]>
---
lib/stp.c | 12 +++++++++++-
lib/stp.h | 1 +
ofproto/ofproto-dpif.c | 11 ++++++++++-
tests/test-stp.c | 8 +++++++-
4 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/lib/stp.c b/lib/stp.c
index 3e9a5b6..1f1f71c 100644
--- a/lib/stp.c
+++ b/lib/stp.c
@@ -133,6 +133,7 @@ struct stp {
/* Interface to client. */
struct stp_port *first_changed_port;
void (*send_bpdu)(struct ofpbuf *bpdu, int port_no, void *aux);
+ void (*topology_change_cb)(void *aux);
void *aux;
};
@@ -211,10 +212,14 @@ static void stp_send_bpdu(struct stp_port *, const void
*, size_t);
* arguments to 'send_bpdu' are an STP BPDU encapsulated in 'bpdu',
* the spanning tree port number 'port_no' that should transmit the
* packet, and auxiliary data to be passed to the callback in 'aux'.
- */
+ *
+ * When the bridge needs to flush it's MAC table, it calls 'topology_change'.
+ * The argument to 'topology_change' is the auxillary data 'aux' provided to
+ * stp_create(). */
struct stp *
stp_create(const char *name, stp_identifier bridge_id,
void (*send_bpdu)(struct ofpbuf *bpdu, int port_no, void *aux),
+ void (*topology_change)(void *aux),
void *aux)
{
struct stp *stp;
@@ -246,6 +251,7 @@ stp_create(const char *name, stp_identifier bridge_id,
stp_start_timer(&stp->hello_timer, 0);
stp->send_bpdu = send_bpdu;
+ stp->topology_change_cb = topology_change;
stp->aux = aux;
stp->first_changed_port = &stp->ports[ARRAY_SIZE(stp->ports)];
@@ -1047,6 +1053,7 @@ stp_topology_change_detection(struct stp *stp)
stp_transmit_tcn(stp);
stp_start_timer(&stp->tcn_timer, 0);
}
+ stp->topology_change_cb(stp->aux);
stp->topology_change_detected = true;
}
@@ -1095,6 +1102,9 @@ stp_received_config_bpdu(struct stp *stp, struct stp_port
*p,
if (config->flags & STP_CONFIG_TOPOLOGY_CHANGE_ACK) {
stp_topology_change_acknowledged(stp);
}
+ if (config->flags & STP_CONFIG_TOPOLOGY_CHANGE) {
+ stp->topology_change_cb(stp->aux);
+ }
}
} else if (stp_is_designated_port(p)) {
stp_transmit_config(p);
diff --git a/lib/stp.h b/lib/stp.h
index ec29d9a..e60be01 100644
--- a/lib/stp.h
+++ b/lib/stp.h
@@ -58,6 +58,7 @@ typedef uint64_t stp_identifier;
struct stp *stp_create(const char *name, stp_identifier bridge_id,
void (*send_bpdu)(struct ofpbuf *bpdu, int port_no,
void *aux),
+ void (*topology_change)(void *aux),
void *aux);
void stp_destroy(struct stp *);
void stp_tick(struct stp *, int ms);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index d46fcf3..7809489 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1123,6 +1123,14 @@ send_bpdu_cb(struct ofpbuf *pkt, int port_num, void
*ofproto_)
ofpbuf_delete(pkt);
}
+static void
+topology_change_cb(void *ofproto_)
+{
+ struct ofproto_dpif *ofproto = ofproto_;
+ mac_learning_flush(ofproto->ml);
+ ofproto->need_revalidate = true;
+}
+
/* Configures STP on 'ofproto_' using the settings defined in 's'. */
static int
set_stp(struct ofproto *ofproto_, const struct ofproto_stp_settings *s)
@@ -1137,7 +1145,8 @@ set_stp(struct ofproto *ofproto_, const struct
ofproto_stp_settings *s)
if (s) {
if (!ofproto->stp) {
ofproto->stp = stp_create(ofproto_->name, s->system_id,
- send_bpdu_cb, ofproto);
+ send_bpdu_cb, topology_change_cb,
+ ofproto);
ofproto->stp_last_tick = time_msec();
}
diff --git a/tests/test-stp.c b/tests/test-stp.c
index fecada7..a5a6203 100644
--- a/tests/test-stp.c
+++ b/tests/test-stp.c
@@ -110,6 +110,12 @@ send_bpdu(struct ofpbuf *pkt, int port_no, void *b_)
ofpbuf_delete(pkt);
}
+static void
+topology_change(void *b OVS_UNUSED)
+{
+ /* XXX: Someday we should test topology change notifications. */
+}
+
static struct bridge *
new_bridge(struct test_case *tc, int id)
{
@@ -118,7 +124,7 @@ new_bridge(struct test_case *tc, int id)
b->tc = tc;
b->id = id;
snprintf(name, sizeof name, "stp%x", id);
- b->stp = stp_create(name, id, send_bpdu, b);
+ b->stp = stp_create(name, id, send_bpdu, topology_change, b);
assert(tc->n_bridges < ARRAY_SIZE(tc->bridges));
b->n_ports = 0;
b->rxq_head = b->rxq_tail = 0;
--
1.7.7.1
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev