ospf6d: add 'log-adjacency-changes [detail]'

Similar to OSPFv2, add support for 'log-adjacency-changes [detail]' to log
changes in adjacency state of ospfv3 neighbors.

Signed-off-by: Pradosh Mohapatra <pmohapat at cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt at cumulusnetworks.com>
Reviewed-by: Scott Feldman <sfeldma at cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm at cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index b7d2e40..fb209fd 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -142,7 +142,7 @@
 }
 
 static void
-ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on)
+ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int event)
 {
   u_char prev_state;
 
@@ -158,11 +158,23 @@
   /* log */
   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
     {
-      zlog_debug ("Neighbor state change %s: [%s]->[%s]", on->name,
+      zlog_debug ("Neighbor state change %s: [%s]->[%s] (%s)", on->name,
 		  ospf6_neighbor_state_str[prev_state],
-		  ospf6_neighbor_state_str[next_state]);
+		  ospf6_neighbor_state_str[next_state],
+		  ospf6_neighbor_event_string(event));
     }
 
+  /* Optionally notify about adjacency changes */
+  if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
+		 OSPF6_LOG_ADJACENCY_CHANGES) &&
+      (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
+		  OSPF6_LOG_ADJACENCY_DETAIL) ||
+       (next_state == OSPF6_NEIGHBOR_FULL) || (next_state < prev_state)))
+    zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name,
+		ospf6_neighbor_state_str[prev_state],
+		ospf6_neighbor_state_str[next_state],
+		ospf6_neighbor_event_string(event));
+
   if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
     {
       OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
@@ -223,7 +235,8 @@
                                            on->ospf6_if->dead_interval);
 
   if (on->state <= OSPF6_NEIGHBOR_DOWN)
-    ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
+    ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
+				 OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
 
   return 0;
 }
@@ -246,11 +259,13 @@
 
   if (! need_adjacency (on))
     {
-      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
+      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on,
+				   OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
       return 0;
     }
 
-  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
+  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
+			       OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
@@ -327,7 +342,8 @@
     }
 
   UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
-  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on);
+  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on,
+			       OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
 
   return 0;
 }
@@ -355,10 +371,12 @@
 */
 
   if (on->request_list->count == 0)
-    ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
+    ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
+				 OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
   else
     {
-      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on);
+      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on,
+				   OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
 
       if (on->thread_send_lsreq == NULL)
 	on->thread_send_lsreq =
@@ -408,7 +426,8 @@
 
   assert (on->request_list->count == 0);
 
-  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
+  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
+			       OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
 
   return 0;
 }
@@ -427,7 +446,8 @@
 
   if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on))
     {
-      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
+      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
+				   OSPF6_NEIGHBOR_EVENT_ADJ_OK);
       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
@@ -440,7 +460,8 @@
   else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
            ! need_adjacency (on))
     {
-      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
+      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on,
+				   OSPF6_NEIGHBOR_EVENT_ADJ_OK);
       ospf6_lsdb_remove_all (on->summary_list);
       ospf6_lsdb_remove_all (on->request_list);
       for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
@@ -469,7 +490,8 @@
   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
     zlog_debug ("Neighbor Event %s: *SeqNumberMismatch*", on->name);
 
-  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
+  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
+			       OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH);
   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
@@ -507,7 +529,8 @@
   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
     zlog_debug ("Neighbor Event %s: *BadLSReq*", on->name);
 
-  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
+  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
+			       OSPF6_NEIGHBOR_EVENT_BAD_LSREQ);
   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
@@ -545,7 +568,8 @@
   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
     zlog_debug ("Neighbor Event %s: *1Way-Received*", on->name);
 
-  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
+  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
+			       OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
 
   ospf6_lsdb_remove_all (on->summary_list);
@@ -580,7 +604,8 @@
   on->drouter = on->prev_drouter = 0;
   on->bdrouter = on->prev_bdrouter = 0;
 
-  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on);
+  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on,
+			       OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
 
   listnode_delete (on->ospf6_if->neighbor_list, on);