Signed-off-by: Ethan Jackson <et...@nicira.com> --- 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 dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev