]> git.ipfire.org Git - people/ms/mstpd.git/commitdiff
Fix bug: MSTI role not changed on boundary ports
authordv1tas <dv1tas@fbe50366-0c72-4402-a84b-5d246361dba7>
Wed, 18 Apr 2012 09:20:27 +0000 (09:20 +0000)
committerdv1tas <dv1tas@fbe50366-0c72-4402-a84b-5d246361dba7>
Wed, 18 Apr 2012 09:20:27 +0000 (09:20 +0000)
git-svn-id: svn://svn.code.sf.net/p/mstpd/code/trunk@30 fbe50366-0c72-4402-a84b-5d246361dba7

mstp.c

diff --git a/mstp.c b/mstp.c
index 764253ae5a0a43cd08ffaf2cfcbe231e7cc2dc11..b3d7cdee24e3e0df32cf25ff998728e08748d46f 100644 (file)
--- a/mstp.c
+++ b/mstp.c
@@ -2221,6 +2221,18 @@ static void updtRolesDisabledTree(tree_t *tree)
         ptp->selectedRole = roleDisabled;
 }
 
+/* Aux function, not in standard.
+ * Sets reselect for all MSTIs in the case CIST state for the port changes
+ */
+static void reselectMSTIs(port_t *prt)
+{
+    per_tree_port_t *ptp = GET_CIST_PTP_FROM_PORT(prt);
+
+    /* For each non-CIST ptp */
+    list_for_each_entry_continue(ptp, &prt->trees, port_list)
+        ptp->reselect = true;
+}
+
 /* 13.26.23 updtRolesTree */
 static void updtRolesTree(tree_t *tree)
 {
@@ -2366,9 +2378,22 @@ static void updtRolesTree(tree_t *tree)
                     ptp->updtInfo = true;
                 continue;
             }
-            if(roleAlternate == cist_tree->selectedRole)
+            /* Bad IEEE again! It says in 13.26.23 g) 2) that
+             * MSTI state should follow CIST state only for the case of
+             * Alternate port. This is obviously wrong!
+             * In the descriptive clause 13.13 f) it says:
+             *  "At a Boundary Port frames allocated to the CIST and
+             *   all MSTIs are forwarded or not forwarded alike.
+             *   This is because Port Role assignments are such that
+             *   if the CIST Port Role is Root Port, the MSTI Port Role
+             *   will be Master Port, and if the CIST Port Role is
+             *   Designated Port, Alternate Port, Backup Port,
+             *   or Disabled Port, each MSTI’s Port Role will be the same."
+             * So, ignore wrong 13.26.23 g) 2) and do as stated in 13.13 f) !
+             */
+            /* if(roleAlternate == cist_tree->selectedRole) */
             {
-                ptp->selectedRole = roleAlternate;
+                ptp->selectedRole = cist_tree->selectedRole;
                 if(!samePriorityAndTimers(&ptp->portPriority,
                                           &ptp->designatedPriority,
                                           &ptp->portTimes,
@@ -2407,34 +2432,46 @@ static void updtRolesTree(tree_t *tree)
                 {
                     ptp->selectedRole = roleRoot;
                     ptp->updtInfo = false;
-                    continue;
                 }
-                if(betterorsamePriority(&ptp->portPriority,
-                                        &ptp->designatedPriority,
-                                        0, 0, cist))
+                else
                 {
-                    if(cmp(ptp->portPriority.DesignatedBridgeID, !=,
-                           tree->BridgeIdentifier))
+                    if(betterorsamePriority(&ptp->portPriority,
+                                             &ptp->designatedPriority,
+                                             0, 0, cist))
                     {
-                        /* k) Set Alternate role */
-                        ptp->selectedRole = roleAlternate;
+                        if(cmp(ptp->portPriority.DesignatedBridgeID, !=,
+                               tree->BridgeIdentifier))
+                        {
+                            /* k) Set Alternate role */
+                            ptp->selectedRole = roleAlternate;
+                        }
+                        else
+                        {
+                            /* l) Set Backup role */
+                            ptp->selectedRole = roleBackup;
+                        }
+                        /* reset updtInfo for both k) and l) */
+                        ptp->updtInfo = false;
                     }
-                    else
+                    else /* designatedPriority is better than portPriority */
                     {
-                        /* l) Set Backup role */
-                        ptp->selectedRole = roleBackup;
+                        /* m) Set Designated role */
+                        ptp->selectedRole = roleDesignated;
+                        ptp->updtInfo = true;
                     }
-                    /* reset updtInfo for both k) and l) */
-                    ptp->updtInfo = false;
-                    continue;
-                }
-                else /* designatedPriority is better than portPriority */
-                {
-                    /* m) Set Designated role */
-                    ptp->selectedRole = roleDesignated;
-                    ptp->updtInfo = true;
-                    continue;
                 }
+                /* This is not in standard. But we really should set here
+                 * reselect for all MSTIs so that updtRolesTree is called
+                 * for each MSTI and due to above clause g) MSTI role is
+                 * changed to Master or reflects CIST port role.
+                 * Because in 802.1Q-2005 this will not happen when BPDU arrives
+                 * at boundary port - the rcvdMsg is not set for the MSTIs and
+                 * updtRolesTree is not called.
+                 * Bad IEEE !!!
+                 */
+                if(cist && (ptp->selectedRole != ptp->role))
+                    reselectMSTIs(prt);
+                continue;
             }
         }
     }