ospfd: trap on state change seems to send incorrect value for ospfNbrState

The ospfNbrState in the ospf trap sent from ospfd shows an incorrect state.

For example, when the connection goes down, the ospfNbrState in the trap is
sent as '8' (full).  When the connection is reestablished, the state is sent
as '7' (loading).

The reason seems to be that the trap is sent from nsm_notice_state_change()
before the state is actually updated by calling nsm_change_state().

After applying the attached patch, the traps are sent with nbrState '1' when
the connection goes down and '8' when it goes back up.

Bugzilla #833 https://bugzilla.quagga.net/show_bug.cgi?id=833
diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c
index 0e6814e..4fecb59 100644
--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -621,23 +621,6 @@
       nbr->last_regress_str = ospf_nsm_event_str [event];
     }
 
-#ifdef HAVE_SNMP
-  /* Terminal state or regression */ 
-  if ((next_state == NSM_Full) 
-      || (next_state == NSM_TwoWay)
-      || (next_state < nbr->state))
-    {
-      /* ospfVirtNbrStateChange */
-      if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK)
-        ospfTrapVirtNbrStateChange(nbr);
-      /* ospfNbrStateChange trap  */
-      else	
-        /* To/From FULL, only managed by DR */
-        if (((next_state != NSM_Full) && (nbr->state != NSM_Full)) 
-            || (nbr->oi->state == ISM_DR))
-          ospfTrapNbrStateChange(nbr);
-    }
-#endif
 }
 
 static void
@@ -830,7 +813,34 @@
   if (next_state != nbr->state)
     {
       nsm_notice_state_change (nbr, next_state, event);
+#ifdef HAVE_SNMP
+      int send_trap_virt = 0;
+      int send_trap = 0;
+      /* Terminal state or regression */ 
+      if ((next_state == NSM_Full) 
+	      || (next_state == NSM_TwoWay)
+	      || (next_state < nbr->state))
+      {
+	  /* ospfVirtNbrStateChange */
+	  if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK)
+	      send_trap_virt = 1;
+	  /* ospfNbrStateChange trap  */
+	  else	
+	      /* To/From FULL, only managed by DR */
+	      if (((next_state != NSM_Full) && (nbr->state != NSM_Full)) 
+		      || (nbr->oi->state == ISM_DR))
+		  send_trap = 1;
+      }
+#endif
       nsm_change_state (nbr, next_state);
+
+#ifdef HAVE_SNMP
+      if (send_trap_virt) {
+	  ospfTrapVirtNbrStateChange(nbr);
+      } else if (send_trap) {
+	  ospfTrapNbrStateChange(nbr);
+      }
+#endif
     }
 
   /* Make sure timer is set. */