bgpd: Rejiggle exported nht function names and consolidate some code

* bgp_nht.h: Tweak the API a bit to simplify and make names a bit clearer on
  function. Remove AFI argument, it's implied in both bgp_infos and peers.

  (bgp_find_nexthop) this doesn't so much find a bnc, as check the bnc
  for the given bgp_info is valid. Rename to (bgp_nexthop_check).

  (bgp_find_or_add_nexthop) This ensures a bnc exists, so call it
  (bgp_ensure_nexthop).

  (bgp_unlink_nexthop_by_peer) Remove via peer.

* bgp_nht.c: Adjust to above.
  (bgp_get_nexthop_rn) helper to get the rn.
  (bgp_find_nexthop) further helper to get the bnc for path or peer.
  (bgp_unlink_nexthop_check) helper to check whether a bnc should go.
  (bgp_ensure_nexthop) Use the helpers.

* bgp_{route,fsm}.c: s/bgp_find_or_add_nexthop/bgp_ensure_nexthop/
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 67c50c4..9d86655 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -507,7 +507,7 @@
       /* Reset peer synctime */
       peer->synctime = 0;
     }
-
+  
   /* Stop read and write threads when exists. */
   BGP_READ_OFF (peer->t_read);
   BGP_WRITE_OFF (peer->t_write);
@@ -720,8 +720,7 @@
       ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
     connected = 1;
 
-  bgp_find_or_add_nexthop(family2afi(peer->su.sa.sa_family), NULL, peer,
-			  connected);
+  bgp_ensure_nexthop (NULL, peer, connected);
   status = bgp_connect (peer);
 
   switch (status)
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 7808505..8c87a64 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -53,13 +53,21 @@
 			int keep);
 
 int
-bgp_find_nexthop (struct bgp_info *path, int connected)
+bgp_nexthop_check (struct bgp_info *path, int connected)
 {
   struct bgp_nexthop_cache *bnc = path->nexthop;
 
   if (!bnc)
     return 0;
 
+  if (BGP_DEBUG(nht, NHT))
+    {
+      char buf[INET6_ADDRSTRLEN];
+      zlog_debug("%s: NHT checking %s", 
+                 __FUNCTION__,
+                 bnc_str (bnc, buf, INET6_ADDRSTRLEN));
+    }
+
   if (connected && !(CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)))
     return 0;
 
@@ -67,89 +75,32 @@
           CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
 }
 
-static void
-bgp_unlink_nexthop_check (struct bgp_nexthop_cache *bnc)
-{
-  if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info)
-    {
-      if (BGP_DEBUG(nht, NHT))
-	{
-	  char buf[INET6_ADDRSTRLEN];
-	  zlog_debug("bgp_unlink_nexthop: freeing bnc %s",
-		     bnc_str(bnc, buf, INET6_ADDRSTRLEN));
-	}
-      unregister_nexthop(bnc);
-      bnc->node->info = NULL;
-      bgp_unlock_node(bnc->node);
-      bnc->node = NULL;
-      bnc_free(bnc);
-    }
-}
-
-void
-bgp_unlink_nexthop (struct bgp_info *path)
-{
-  struct bgp_nexthop_cache *bnc = path->nexthop;
-
-  if (!bnc)
-    return;
-
-  path_nh_map(path, NULL, 0);
-  
-  bgp_unlink_nexthop_check (bnc);
-}
-
-void
-bgp_unlink_nexthop_by_peer (struct peer *peer)
+/* Helper to get the rn for the appropriate nexthop for path or peer.
+ * returns the locked rn - caller must bump down the refcnt.
+ *
+ * may return NULL in error cases.
+ */
+static
+struct bgp_node *
+bgp_get_nexthop_rn (struct bgp_info *path, struct peer *peer)
 {
   struct prefix p;
-  struct bgp_node *rn;
-  struct bgp_nexthop_cache *bnc;
-  afi_t afi = family2afi(peer->su.sa.sa_family);
-
-  if (afi == AFI_IP)
+  afi_t afi;
+  
+  assert (path || peer);
+  
+  if (!(path || peer))
+    return NULL;
+  
+  if (path)
     {
-      p.family = AF_INET;
-      p.prefixlen = IPV4_MAX_BITLEN;
-      p.u.prefix4 = peer->su.sin.sin_addr;
-    }
-  else if (afi == AFI_IP6)
-    {
-      p.family = AF_INET6;
-      p.prefixlen = IPV6_MAX_BITLEN;
-      p.u.prefix6 = peer->su.sin6.sin6_addr;
+      afi = family2afi (path->net->p.family);
+      if (make_prefix(afi, path, &p) < 0)
+	return NULL;
     }
   else
-    return;
-
-  rn = bgp_node_get (bgp_nexthop_cache_table[afi], &p);
-
-  if (!rn->info)
-    return;
-  
-  bnc = rn->info;
-  
-  /* cleanup the peer reference */
-  bnc->nht_info = NULL;
-  
-  bgp_unlink_nexthop_check (bnc);
-}
-
-int
-bgp_find_or_add_nexthop (afi_t afi, struct bgp_info *ri, struct peer *peer,
-			 int connected)
-{
-  struct bgp_node *rn;
-  struct bgp_nexthop_cache *bnc;
-  struct prefix p;
-
-  if (ri)
     {
-      if (make_prefix(afi, ri, &p) < 0)
-	return 1;
-    }
-  else if (peer)
-    {
+      afi = family2afi(peer->su.sa.sa_family);
       if (afi == AFI_IP)
 	{
 	  p.family = AF_INET;
@@ -162,10 +113,101 @@
 	  p.prefixlen = IPV6_MAX_BITLEN;
 	  p.u.prefix6 = peer->su.sin6.sin6_addr;
 	}
+      else
+        return NULL;
     }
+  
+  return bgp_node_get (bgp_nexthop_cache_table[afi], &p);
+}
 
-  rn = bgp_node_get (bgp_nexthop_cache_table[afi], &p);
+static
+struct bgp_nexthop_cache *
+bgp_find_nexthop (struct bgp_info *path, struct peer *peer)
+{
+  struct bgp_nexthop_cache *bnc = NULL;
+  struct bgp_node *rn = bgp_get_nexthop_rn (path, peer);
+  
+  if (!rn)
+    return NULL;
+  
+  bnc = rn->info;
+  bgp_unlock_node (rn);
+  
+  return bnc;
+}
 
+static void
+bgp_unlink_nexthop_check (struct bgp_nexthop_cache *bnc)
+{
+  if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info)
+    {
+      if (BGP_DEBUG(nht, NHT))
+	{
+	  char buf[INET6_ADDRSTRLEN];
+	  zlog_debug("bgp_unlink_nexthop: freeing bnc %s",
+		     bnc_str (bnc, buf, INET6_ADDRSTRLEN));
+ 	}
+      unregister_nexthop(bnc);
+      bnc->node->info = NULL;
+      bgp_unlock_node (bnc->node);
+      bnc->node = NULL;
+      bnc_free (bnc);
+    }
+}
+
+void
+bgp_unlink_nexthop (struct bgp_info *path)
+{
+  struct bgp_nexthop_cache *bnc = path->nexthop;
+
+  if (!bnc)
+    return;
+
+  if (BGP_DEBUG(nht, NHT))
+    {
+      char buf[INET6_ADDRSTRLEN];
+      zlog_debug("%s: NHT unlinking %s", 
+                 __FUNCTION__, bnc_str (bnc, buf, INET6_ADDRSTRLEN));
+    }
+  
+  path_nh_map(path, NULL, 0);
+  
+  bgp_unlink_nexthop_check (bnc);
+}
+
+void
+bgp_unlink_nexthop_by_peer (struct peer *peer)
+{
+  struct bgp_nexthop_cache *bnc = bgp_find_nexthop (NULL, peer);
+     
+  if (!bnc)
+    return;
+
+  if (BGP_DEBUG(nht, NHT))
+    zlog_debug("%s: NHT unlinking %s", 
+                __FUNCTION__, peer->host);
+  
+  bnc->nht_info = NULL;
+  
+  bgp_unlink_nexthop_check (bnc);
+}
+
+int
+bgp_ensure_nexthop (struct bgp_info *ri, struct peer *peer,
+                    int connected)
+{
+  struct bgp_node *rn;
+  struct bgp_nexthop_cache *bnc;
+  
+  rn = bgp_get_nexthop_rn (ri, peer);
+  
+  if (!rn)
+    {
+      zlog_debug("%s: NHT could not ensure, failed to get rn!", 
+                 __FUNCTION__);
+      return 0;
+    }
+  
   if (!rn->info)
     {
       bnc = bnc_new();
@@ -194,6 +236,13 @@
   else if (peer)
     bnc->nht_info = (void *)peer; /* NHT peer reference */
 
+  if (BGP_DEBUG(nht, NHT))
+    {
+      char buf[INET6_ADDRSTRLEN];
+      zlog_debug("%s: NHT ensured %s", 
+                 __FUNCTION__, bnc_str (bnc, buf, INET6_ADDRSTRLEN));
+    }
+  
   return (bgp_zebra_num_connects() == 0 ||
           CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
 }
diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h
index 5086b08..dd6300e 100644
--- a/bgpd/bgp_nht.h
+++ b/bgpd/bgp_nht.h
@@ -25,33 +25,40 @@
 /**
  * bgp_parse_nexthop_update() - parse a nexthop update message from Zebra.
  */
-extern void bgp_parse_nexthop_update(void);
+void bgp_parse_nexthop_update (void);
 
 /**
- * bgp_find_nexthop() - lookup the nexthop cache table for the bnc object
+ * bgp_nexthop_check() - check if the bnc object is valid.
  * ARGUMENTS:
  *   p - path for which the nexthop object is being looked up
  *   connected - True if NH MUST be a connected route
  */
-extern int bgp_find_nexthop(struct bgp_info *p, int connected);
+int bgp_nexthop_check (struct bgp_info *, int connected);
 
 /**
- * bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc
- *  object. If not found, create a new object and register with ZEBRA for
- *  nexthop notification.
+ * bgp_ensure_nexthop() - Ensure a bgp_nexthop_cache object exists for 
+ *  the given prefix or peer.  If an existing one is not found,
+ *  create a new object and register with ZEBRA for nexthop
+ *  notification.
  * ARGUMENTS:
- *   a - afi: AFI_IP or AF_IP6
- *   p - path for which the nexthop object is being looked up
- *   peer - The BGP peer associated with this NHT
+ *   afi: AFI_IP or AF_IP6
+ *     struct bgp_info *: path for which the nexthop object is 
+ *                        being looked up
+ *   OR
+ *     struct peer The BGP peer associated with this NHT
  *   connected - True if NH MUST be a connected route
  */
-extern int bgp_find_or_add_nexthop(afi_t a, struct bgp_info *p,
-				   struct peer *peer, int connected);
+int bgp_ensure_nexthop (struct bgp_info *, struct peer *, int connected);
 
 /**
  * bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
  * ARGUMENTS:
- *   p - path structure.
+ *   struct bgp_info *: path structure.
+ */
+void bgp_unlink_nexthop (struct bgp_info *);
+
+/**
+ * bgp_unlink_nexthop() - Unlink the nexthop object for the given peer.
  */
 extern void bgp_unlink_nexthop(struct bgp_info *p);
 void bgp_unlink_nexthop_by_peer (struct peer *);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 476ef05..9137143 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -134,7 +134,7 @@
   if (binfo->attr)
     bgp_attr_unintern (&binfo->attr);
 
-  bgp_unlink_nexthop(binfo);
+  bgp_unlink_nexthop (binfo);
   bgp_info_extra_free (&binfo->extra);
   bgp_info_mpath_free (&binfo->mpath);
 
@@ -2345,7 +2345,7 @@
 	  else
 	    connected = 0;
 
-	  if (bgp_find_or_add_nexthop (afi, ri, NULL, connected))
+	  if (bgp_ensure_nexthop (ri, NULL, connected))
 	    bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
 	  else
 	    {
@@ -2397,7 +2397,7 @@
       else
 	connected = 0;
 
-      if (bgp_find_or_add_nexthop (afi, new, NULL, connected))
+      if (bgp_ensure_nexthop (new, NULL, connected))
 	bgp_info_set_flag (rn, new, BGP_INFO_VALID);
       else
 	{
@@ -3543,7 +3543,7 @@
 	  /* Nexthop reachability check. */
 	  if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
 	    {
-	      if (bgp_find_or_add_nexthop (afi, ri, NULL, 0))
+	      if (bgp_ensure_nexthop (ri, NULL, 0))
 		bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
 	      else
 		{
@@ -3572,7 +3572,7 @@
   /* Nexthop reachability check. */
   if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
     {
-      if (bgp_find_or_add_nexthop (afi, new, NULL, 0))
+      if (bgp_ensure_nexthop (new, NULL, 0))
 	bgp_info_set_flag (rn, new, BGP_INFO_VALID);
       else
 	{
@@ -3692,7 +3692,7 @@
 	  /* Nexthop reachability check. */
 	  if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
 	    {
-	      if (bgp_find_or_add_nexthop (afi, ri, NULL, 0))
+	      if (bgp_ensure_nexthop (ri, NULL, 0))
 		bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
 	      else
 		{
@@ -3722,7 +3722,7 @@
   /* Nexthop reachability check. */
   if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
     {
-      if (bgp_find_or_add_nexthop (afi, new, NULL, 0))
+      if (bgp_ensure_nexthop (new, NULL, 0))
 	bgp_info_set_flag (rn, new, BGP_INFO_VALID);
       else
 	{