Improve secchan.8 manpage.
[sliver-openvswitch.git] / lib / stp.c
index 6f7f09a..0847f57 100644 (file)
--- a/lib/stp.c
+++ b/lib/stp.c
@@ -230,13 +230,17 @@ stp_create(const char *name, stp_identifier bridge_id,
     if (!(stp->bridge_id >> 48)) {
         stp->bridge_id |= UINT64_C(32768) << 48;
     }
-    stp->max_age = SECONDS_TO_TIMER(20);
+    stp->max_age = SECONDS_TO_TIMER(6);
     stp->hello_time = SECONDS_TO_TIMER(2);
-    stp->forward_delay = SECONDS_TO_TIMER(15);
+    stp->forward_delay = SECONDS_TO_TIMER(4);
     stp->bridge_max_age = stp->max_age;
     stp->bridge_hello_time = stp->hello_time;
     stp->bridge_forward_delay = stp->forward_delay;
 
+    /* Verify constraints stated by 802.1D. */
+    assert(2 * (stp->forward_delay - SECONDS_TO_TIMER(1)) >= stp->max_age);
+    assert(stp->max_age >= 2 * (stp->hello_time + SECONDS_TO_TIMER(1)));
+
     stp->designated_root = stp->bridge_id;
     stp->root_path_cost = 0;
     stp->root_port = NULL;
@@ -298,27 +302,42 @@ stp_tick(struct stp *stp, int elapsed)
     }
 }
 
-void
-stp_set_bridge_priority(struct stp *stp, uint16_t new_priority)
+static void
+set_bridge_id(struct stp *stp, stp_identifier new_bridge_id)
 {
-    stp_identifier new_bridge_id;
-    bool root;
-    struct stp_port *p;
-
-    new_bridge_id = ((stp->bridge_id & UINT64_C(0xffffffffffff))
-                     | ((uint64_t) new_priority << 48));
-    root = stp_is_root_bridge(stp);
-    FOR_EACH_ENABLED_PORT (p, stp) {
-        if (stp_is_designated_port(p)) {
-            p->designated_bridge = new_bridge_id;
+    if (new_bridge_id != stp->bridge_id) {
+        bool root;
+        struct stp_port *p;
+
+        root = stp_is_root_bridge(stp);
+        FOR_EACH_ENABLED_PORT (p, stp) {
+            if (stp_is_designated_port(p)) {
+                p->designated_bridge = new_bridge_id;
+            }
+        }
+        stp->bridge_id = new_bridge_id;
+        stp_configuration_update(stp);
+        stp_port_state_selection(stp);
+        if (stp_is_root_bridge(stp) && !root) {
+            stp_become_root_bridge(stp);
         }
     }
-    stp->bridge_id = new_bridge_id;
-    stp_configuration_update(stp);
-    stp_port_state_selection(stp);
-    if (stp_is_root_bridge(stp) && !root) {
-        stp_become_root_bridge(stp);
-    }
+}
+
+void
+stp_set_bridge_id(struct stp *stp, stp_identifier bridge_id)
+{
+    const uint64_t mac_bits = (UINT64_C(1) << 48) - 1;
+    const uint64_t pri_bits = ~mac_bits;
+    set_bridge_id(stp, (stp->bridge_id & pri_bits) | (bridge_id & mac_bits));
+}
+
+void
+stp_set_bridge_priority(struct stp *stp, uint16_t new_priority)
+{
+    const uint64_t mac_bits = (UINT64_C(1) << 48) - 1;
+    set_bridge_id(stp, ((stp->bridge_id & mac_bits)
+                        | ((uint64_t) new_priority << 48)));
 }
 
 /* Returns the name given to 'stp' in the call to stp_create(). */