[ospfd] Allow ospf_lsa_unlock to NULL out callers' LSA pointers upon free

2006-07-26 Paul Jakma <paul.jakma@sun.com>

	* ospf_lsa.{c,h}: (ospf_lsa_unlock) Change to take a double pointer
	  to the LSA to be 'unlocked', so that, if the LSA is freed, the
	  callers pointer to the LSA can be NULLed out, allowing any further
	  use of that pointer to provoke a crash sooner rather than later.
	* ospf_*.c: (general) Adjust callers of ospf_lsa_unlock to match
	  previous. Try annotate 'locking' somewhat to show which 'locks'
	  are protecting what LSA reference, if not obvious.
	* ospf_opaque.c: (ospf_opaque_lsa_install) Trivial: remove useless
	  goto, replace with return.
	* ospf_packet.c: (ospf_make_ls_ack) Trivial: merge two list loops,
	  the dual-loop predated the delete-safe list-loop macro.
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 8b5c6eb..b99b931 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -294,20 +294,21 @@
 
 /* Unlock LSA. */
 void
-ospf_lsa_unlock (struct ospf_lsa *lsa)
+ospf_lsa_unlock (struct ospf_lsa **lsa)
 {
   /* This is sanity check. */
-  if (!lsa)
+  if (!lsa || !*lsa)
     return;
   
-  lsa->lock--;
+  (*lsa)->lock--;
 
-  assert (lsa->lock >= 0);
+  assert ((*lsa)->lock >= 0);
 
-  if (lsa->lock == 0)
+  if ((*lsa)->lock == 0)
     {
-      assert (CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD));
-      ospf_lsa_free (lsa);
+      assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
+      ospf_lsa_free (*lsa);
+      *lsa = NULL;
     }
 }
 
@@ -318,7 +319,7 @@
   if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
     {
       SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
-      ospf_lsa_unlock (lsa);
+      ospf_lsa_unlock (&lsa);
     }
 }
 
@@ -1044,7 +1045,7 @@
 	    zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
 		      lsa->data->type, inet_ntoa (lsa->data->id), area_str);
 	  ospf_lsa_flush_area (lsa, area);
-	  ospf_lsa_unlock (area->router_lsa_self);
+	  ospf_lsa_unlock (&area->router_lsa_self);
 	  area->router_lsa_self = NULL;
 
 	  /* Refresh router-LSA, (not install) and flood through area. */
@@ -1850,7 +1851,7 @@
 	  {
 	    if (IS_DEBUG_OSPF_NSSA)
 	      zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
-	    ospf_lsa_discard(new);
+	    ospf_lsa_discard (new);
 	    return;
 	  }
 	}
@@ -2518,7 +2519,7 @@
                           ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
       
       /* Set self-originated router-LSA. */
-      ospf_lsa_unlock (area->router_lsa_self);
+      ospf_lsa_unlock (&area->router_lsa_self);
       area->router_lsa_self = ospf_lsa_lock (new);
 
       if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
@@ -2562,7 +2563,7 @@
 			       ospf_network_lsa_refresh_timer,
 			       OSPF_LS_REFRESH_TIME);
 
-      ospf_lsa_unlock (oi->network_lsa_self);
+      ospf_lsa_unlock (&oi->network_lsa_self);
       oi->network_lsa_self = ospf_lsa_lock (new);
     }
 
@@ -3067,7 +3068,7 @@
   if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
     {
       list_delete_node (ospf->maxage_lsa, n);
-      ospf_lsa_unlock (lsa);
+      ospf_lsa_unlock (&lsa); /* maxage_lsa */
     }
 }
 
@@ -3482,7 +3483,7 @@
             zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
 
           ospf_lsa_flush_area (lsa, area);
-          ospf_lsa_unlock (area->router_lsa_self);
+          ospf_lsa_unlock (&area->router_lsa_self);
           area->router_lsa_self = NULL;
           OSPF_TIMER_OFF (area->t_router_lsa_self);
         }
@@ -3497,7 +3498,7 @@
                 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
 
               ospf_lsa_flush_area (oi->network_lsa_self, area);
-              ospf_lsa_unlock (oi->network_lsa_self);
+              ospf_lsa_unlock (&oi->network_lsa_self);
               oi->network_lsa_self = NULL;
               OSPF_TIMER_OFF (oi->t_network_lsa_self);
             }
@@ -3666,7 +3667,7 @@
       break;
     }
 
-  ospf_lsa_unlock (data->lsa);
+  ospf_lsa_unlock (&data->lsa); /* Message */
   XFREE (MTYPE_OSPF_MESSAGE, data);
   return 0;
 }
@@ -3681,7 +3682,7 @@
 
   data->action = LSA_ACTION_FLOOD_AREA;
   data->area = area;
-  data->lsa  = ospf_lsa_lock (lsa);
+  data->lsa  = ospf_lsa_lock (lsa); /* Message / Flood area */
 
   thread_add_event (master, ospf_lsa_action, data, 0);
 }
@@ -3696,7 +3697,7 @@
 
   data->action = LSA_ACTION_FLUSH_AREA;
   data->area = area;
-  data->lsa  = ospf_lsa_lock (lsa);
+  data->lsa  = ospf_lsa_lock (lsa); /* Message / Flush area */
 
   thread_add_event (master, ospf_lsa_action, data, 0);
 }
@@ -3779,7 +3780,8 @@
 		   inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
       if (!ospf->lsa_refresh_queue.qs[index])
 	ospf->lsa_refresh_queue.qs[index] = list_new ();
-      listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
+      listnode_add (ospf->lsa_refresh_queue.qs[index],
+                    ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
       lsa->refresh_list = index;
       if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
         zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
@@ -3801,7 +3803,7 @@
 	  list_free (refresh_list);
 	  ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
 	}
-      ospf_lsa_unlock (lsa);
+      ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
       lsa->refresh_list = -1;
     }
 }
@@ -3855,7 +3857,7 @@
 		           inet_ntoa (lsa->data->id), lsa, i);
 	      
 	      list_delete_node (refresh_list, node);
-	      ospf_lsa_unlock (lsa);
+	      ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
 	      lsa->refresh_list = -1;
 	      listnode_add (lsa_to_refresh, lsa);
 	    }