stp: Flush MAC table on topology change.
authorEthan Jackson <ethan@nicira.com>
Mon, 16 Jan 2012 23:07:55 +0000 (15:07 -0800)
committerEthan Jackson <ethan@nicira.com>
Wed, 25 Jan 2012 21:11:07 +0000 (13:11 -0800)
Signed-off-by: Ethan Jackson <ethan@nicira.com>
lib/stp.c
lib/stp.h
ofproto/ofproto-dpif.c

index 3e9a5b6a800104bd1c9d203f62c06f2bccc3d7d2..f7fe53cc9fe93e07a49bcfeb9dbbdc8b9e3095b5 100644 (file)
--- a/lib/stp.c
+++ b/lib/stp.c
@@ -131,6 +131,7 @@ struct stp {
     struct stp_port ports[STP_MAX_PORTS];
 
     /* Interface to client. */
+    bool fdb_needs_flush;          /* MAC learning tables needs flushing. */
     struct stp_port *first_changed_port;
     void (*send_bpdu)(struct ofpbuf *bpdu, int port_no, void *aux);
     void *aux;
@@ -448,6 +449,17 @@ stp_get_forward_delay(const struct stp *stp)
     return timer_to_ms(stp->bridge_forward_delay);
 }
 
+/* Returns true if something has happened to 'stp' which necessitates flushing
+ * the client's MAC learning table.  Calling this function resets 'stp' so that
+ * future calls will return false until flushing is required again. */
+bool
+stp_check_and_reset_fdb_flush(struct stp *stp)
+{
+    bool needs_flush = stp->fdb_needs_flush;
+    stp->fdb_needs_flush = false;
+    return needs_flush;
+}
+
 /* Returns the port in 'stp' with index 'port_no', which must be between 0 and
  * STP_MAX_PORTS. */
 struct stp_port *
@@ -1047,6 +1059,7 @@ stp_topology_change_detection(struct stp *stp)
         stp_transmit_tcn(stp);
         stp_start_timer(&stp->tcn_timer, 0);
     }
+    stp->fdb_needs_flush = true;
     stp->topology_change_detected = true;
 }
 
@@ -1095,6 +1108,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->fdb_needs_flush = true;
+                }
             }
         } else if (stp_is_designated_port(p)) {
             stp_transmit_config(p);
index ec29d9a77a9954d8dd54b4ee5bf5cc87828a54e9..f321dec9cd3bb2ce760ebf5f7f7fd2eed492303c 100644 (file)
--- a/lib/stp.h
+++ b/lib/stp.h
@@ -76,6 +76,7 @@ int stp_get_root_path_cost(const struct stp *);
 int stp_get_hello_time(const struct stp *);
 int stp_get_max_age(const struct stp *);
 int stp_get_forward_delay(const struct stp *);
+bool stp_check_and_reset_fdb_flush(struct stp *);
 
 /* Obtaining STP ports. */
 struct stp_port *stp_get_port(struct stp *, int port_no);
index 1e9b341c0b2a4746d247c4929985f30690c75818..344f9d4d5b3dadcbde5ae59bdffa22977a248cf2 100644 (file)
@@ -1296,6 +1296,10 @@ stp_run(struct ofproto_dpif *ofproto)
                 update_stp_port_state(ofport);
             }
         }
+
+        if (stp_check_and_reset_fdb_flush(ofproto->stp)) {
+            mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
+        }
     }
 }