bgpd: remove calls to peer_sort() from fast-path

  peer_sort() it's called so much as to be annoying. In the assumption
that the 'sort' of the peer doesn't change during an established session,
I have changed all calls to peer_sort() in the 'fast-path' to only check
the 'sort'. All the calls from the vty and such still recalculate the sort
and store it in the peer.

  There's a lot of other calls to peer_sort() that could be changed but some
maube tricky, someone more knowledgeable may try to reduce them.

  This hits peer_sort() from 5th out of the stadium^H^H list on a full
internet table loading profiling session.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 30fb091..31ce5a1 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -201,7 +201,7 @@
   /* Clear all IBGP peer. */
   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
     {
-      if (peer_sort (peer) != BGP_PEER_IBGP)
+      if (peer->sort != BGP_PEER_IBGP)
 	continue;
 
       if (peer->status == Established)
@@ -229,7 +229,7 @@
   /* Clear all IBGP peer. */
   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
     {
-      if (peer_sort (peer) != BGP_PEER_IBGP)
+      if (peer->sort != BGP_PEER_IBGP)
 	continue;
 
       if (peer->status == Established)
@@ -645,9 +645,9 @@
   peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
 }
 
-/* Check peer's AS number and determin is this peer IBGP or EBGP */
-int
-peer_sort (struct peer *peer)
+/* Check peer's AS number and determines if this peer is IBGP or EBGP */
+static bgp_peer_sort_t
+peer_calc_sort (struct peer *peer)
 {
   struct bgp *bgp;
 
@@ -696,6 +696,14 @@
     }
 }
 
+/* Calculate and cache the peer "sort" */
+bgp_peer_sort_t
+peer_sort (struct peer *peer)
+{
+  peer->sort = peer_calc_sort (peer);
+  return peer->sort;
+}
+
 static void
 peer_free (struct peer *peer)
 {
@@ -866,7 +874,7 @@
   peer->readtime = peer->resettime = bgp_clock ();
 
   /* Default TTL set. */
-  peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
+  peer->ttl = (peer->sort == BGP_PEER_IBGP) ? 255 : 1;
 
   /* Make peer's address string. */
   sockunion2str (su, buf, SU_ADDRSTRLEN);
@@ -897,7 +905,7 @@
 static void
 peer_as_change (struct peer *peer, as_t as)
 {
-  int type;
+  bgp_peer_sort_t type;
 
   /* Stop peer. */
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
@@ -2666,7 +2674,7 @@
   struct listnode *node, *nnode;
   struct peer *peer1;
 
-  if (peer_sort (peer) == BGP_PEER_IBGP)
+  if (peer->sort == BGP_PEER_IBGP)
     return 0;
 
   /* see comment in peer_ttl_security_hops_set() */
@@ -2680,7 +2688,7 @@
 
           for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
             {
-              if (peer_sort (peer1) == BGP_PEER_IBGP)
+              if (peer1->sort == BGP_PEER_IBGP)
                 continue;
 
               if (peer1->gtsm_hops != 0)
@@ -2698,7 +2706,7 @@
 
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {
-      if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
+      if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
 	sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
     }
   else
@@ -2706,7 +2714,7 @@
       group = peer->group;
       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 	{
-	  if (peer_sort (peer) == BGP_PEER_IBGP)
+	  if (peer->sort == BGP_PEER_IBGP)
 	    continue;
 
 	  peer->ttl = group->conf->ttl;
@@ -2724,7 +2732,7 @@
   struct peer_group *group;
   struct listnode *node, *nnode;
 
-  if (peer_sort (peer) == BGP_PEER_IBGP)
+  if (peer->sort == BGP_PEER_IBGP)
     return 0;
 
   if (peer->gtsm_hops != 0 && peer->ttl != MAXTTL)
@@ -2737,7 +2745,7 @@
 
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {
-      if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
+      if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
 	sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
     }
   else
@@ -2745,7 +2753,7 @@
       group = peer->group;
       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 	{
-	  if (peer_sort (peer) == BGP_PEER_IBGP)
+	  if (peer->sort == BGP_PEER_IBGP)
 	    continue;
 
 	  peer->ttl = 1;
@@ -3297,7 +3305,7 @@
   UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
   peer->routeadv = 0;
 
-  if (peer_sort (peer) == BGP_PEER_IBGP)
+  if (peer->sort == BGP_PEER_IBGP)
     peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
   else
     peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
@@ -4372,7 +4380,7 @@
 
   zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host);
 
-  if (peer_sort (peer) == BGP_PEER_IBGP)
+  if (peer->sort == BGP_PEER_IBGP)
     return BGP_ERR_NO_IBGP_WITH_TTLHACK;
 
   /* We cannot configure ttl-security hops when ebgp-multihop is already
@@ -4392,7 +4400,7 @@
 
         for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
           {
-            if (peer_sort (peer1) == BGP_PEER_IBGP)
+            if (peer1->sort == BGP_PEER_IBGP)
               continue;
 
             if (peer1->ttl != 1)
@@ -4414,7 +4422,7 @@
 
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {
-      if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
+      if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
 	sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - gtsm_hops);
     }
   else
@@ -4422,7 +4430,7 @@
       group = peer->group;
       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 	{
-	  if (peer_sort (peer) == BGP_PEER_IBGP)
+	  if (peer->sort == BGP_PEER_IBGP)
 	    continue;
 
 	  peer->gtsm_hops = group->conf->gtsm_hops;
@@ -4459,7 +4467,7 @@
 
   zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host);
 
-  if (peer_sort (peer) == BGP_PEER_IBGP)
+  if (peer->sort == BGP_PEER_IBGP)
       return 0;
 
   /* if a peer-group member, then reset to peer-group default rather than 0 */
@@ -4471,7 +4479,7 @@
   opeer = peer;
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {
-      if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
+      if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
 	sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
     }
   else
@@ -4479,7 +4487,7 @@
       group = peer->group;
       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 	{
-	  if (peer_sort (peer) == BGP_PEER_IBGP)
+	  if (peer->sort == BGP_PEER_IBGP)
 	    continue;
 
 	  peer->gtsm_hops = 0;
@@ -4794,7 +4802,7 @@
 	  vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
 
       /* EBGP multihop.  */
-      if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1 &&
+      if (peer->sort != BGP_PEER_IBGP && peer->ttl != 1 &&
                    !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL))
         if (! peer_group_active (peer) ||
 	    g_peer->ttl != peer->ttl)
@@ -4802,7 +4810,7 @@
 		   VTY_NEWLINE);
 
      /* ttl-security hops */
-      if (peer_sort (peer) != BGP_PEER_IBGP && peer->gtsm_hops != 0)
+      if (peer->sort != BGP_PEER_IBGP && peer->gtsm_hops != 0)
         if (! peer_group_active (peer) || g_peer->gtsm_hops != peer->gtsm_hops)
           vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,
                    peer->gtsm_hops, VTY_NEWLINE);