Browse Source

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>
Jorge Boncompte [DTI2] 8 years ago
parent
commit
6d85b15bbb
9 changed files with 104 additions and 96 deletions
  1. 14 16
      bgpd/bgp_attr.c
  2. 1 1
      bgpd/bgp_mpath.c
  3. 2 2
      bgpd/bgp_network.c
  4. 1 1
      bgpd/bgp_nexthop.c
  5. 35 35
      bgpd/bgp_route.c
  6. 2 2
      bgpd/bgp_vty.c
  7. 4 4
      bgpd/bgp_zebra.c
  8. 32 24
      bgpd/bgpd.c
  9. 13 11
      bgpd/bgpd.h

+ 14 - 16
bgpd/bgp_attr.c

@@ -722,7 +722,7 @@ bgp_attr_malformed (struct bgp_attr_parser_args *args, u_char subcode,
   u_char *notify_datap = (length > 0 ? args->startp : NULL);
   
   /* Only relax error handling for eBGP peers */
-  if (peer_sort (peer) != BGP_PEER_EBGP)
+  if (peer->sort != BGP_PEER_EBGP)
     {
       bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, subcode,
                                  notify_datap, length);
@@ -996,11 +996,9 @@ bgp_attr_aspath_check (struct peer *const peer, struct attr *const attr)
   struct bgp *bgp = peer->bgp;
   struct aspath *aspath;
 
-  bgp = peer->bgp;
-    
   /* Confederation sanity check. */
-  if ((peer_sort (peer) == BGP_PEER_CONFED && ! aspath_left_confed_check (attr->aspath)) ||
-     (peer_sort (peer) == BGP_PEER_EBGP && aspath_confed_check (attr->aspath)))
+  if ((peer->sort == BGP_PEER_CONFED && ! aspath_left_confed_check (attr->aspath)) ||
+     (peer->sort == BGP_PEER_EBGP && aspath_confed_check (attr->aspath)))
     {
       zlog (peer->log, LOG_ERR, "Malformed AS path from %s", peer->host);
       bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
@@ -1011,7 +1009,7 @@ bgp_attr_aspath_check (struct peer *const peer, struct attr *const attr)
   /* First AS check for EBGP. */
   if (bgp != NULL && bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
     {
-      if (peer_sort (peer) == BGP_PEER_EBGP 
+      if (peer->sort == BGP_PEER_EBGP
 	  && ! aspath_firstas_check (attr->aspath, peer->as))
  	{
  	  zlog (peer->log, LOG_ERR,
@@ -1155,7 +1153,7 @@ bgp_attr_local_pref (struct bgp_attr_parser_args *args)
   /* If it is contained in an UPDATE message that is received from an
      external peer, then this attribute MUST be ignored by the
      receiving speaker. */
-  if (peer_sort (peer) == BGP_PEER_EBGP)
+  if (peer->sort == BGP_PEER_EBGP)
     {
       stream_forward_getp (peer->ibuf, length);
       return BGP_ATTR_PARSE_PROCEED;
@@ -2020,7 +2018,7 @@ bgp_attr_check (struct peer *peer, struct attr *attr)
   if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP)))
     type = BGP_ATTR_NEXT_HOP;
 
-  if (peer_sort (peer) == BGP_PEER_IBGP
+  if (peer->sort == BGP_PEER_IBGP
       && ! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
     type = BGP_ATTR_LOCAL_PREF;
 
@@ -2069,7 +2067,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
   /* AS path attribute. */
 
   /* If remote-peer is EBGP */
-  if (peer_sort (peer) == BGP_PEER_EBGP
+  if (peer->sort == BGP_PEER_EBGP
       && (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
 	  || attr->aspath->segments == NULL)
       && (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)))
@@ -2090,7 +2088,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
 	    aspath = aspath_add_seq (aspath, peer->change_local_as);
 	}
     }
-  else if (peer_sort (peer) == BGP_PEER_CONFED)
+  else if (peer->sort == BGP_PEER_CONFED)
     {
       /* A confed member, so we need to do the AS_CONFED_SEQUENCE thing */
       aspath = aspath_dup (attr->aspath);
@@ -2147,8 +2145,8 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
     }
 
   /* Local preference. */
-  if (peer_sort (peer) == BGP_PEER_IBGP ||
-      peer_sort (peer) == BGP_PEER_CONFED)
+  if (peer->sort == BGP_PEER_IBGP ||
+      peer->sort == BGP_PEER_CONFED)
     {
       stream_putc (s, BGP_ATTR_FLAG_TRANS);
       stream_putc (s, BGP_ATTR_LOCAL_PREF);
@@ -2221,9 +2219,9 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
     }
 
   /* Route Reflector. */
-  if (peer_sort (peer) == BGP_PEER_IBGP
+  if (peer->sort == BGP_PEER_IBGP
       && from
-      && peer_sort (from) == BGP_PEER_IBGP)
+      && from->sort == BGP_PEER_IBGP)
     {
       /* Originator ID. */
       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
@@ -2359,8 +2357,8 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
       
       assert (attre);
       
-      if (peer_sort (peer) == BGP_PEER_IBGP 
-          || peer_sort (peer) == BGP_PEER_CONFED)
+      if (peer->sort == BGP_PEER_IBGP
+          || peer->sort == BGP_PEER_CONFED)
 	{
 	  if (attre->ecommunity->size * 8 > 255)
 	    {

+ 1 - 1
bgpd/bgp_mpath.c

@@ -420,7 +420,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
       mpath_count++;
       if (new_best != old_best)
         bgp_info_mpath_dequeue (new_best);
-      maxpaths = (peer_sort (new_best->peer) == BGP_PEER_IBGP) ?
+      maxpaths = (new_best->peer->sort == BGP_PEER_IBGP) ?
         mpath_cfg->maxpaths_ibgp : mpath_cfg->maxpaths_ebgp;
     }
 

+ 2 - 2
bgpd/bgp_network.c

@@ -174,7 +174,7 @@ bgp_accept (struct thread *thread)
     }
 
   /* In case of peer is EBGP, we should set TTL for this connection.  */
-  if (peer_sort (peer1) == BGP_PEER_EBGP) {
+  if (peer1->sort == BGP_PEER_EBGP) {
     sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl);
     if (peer1->gtsm_hops)
       sockopt_minttl (peer1->su.sa.sa_family, bgp_sock, MAXTTL + 1 - peer1->gtsm_hops);
@@ -307,7 +307,7 @@ bgp_connect (struct peer *peer)
     return -1;
 
   /* If we can get socket for the peer, adjest TTL and make connection. */
-  if (peer_sort (peer) == BGP_PEER_EBGP) {
+  if (peer->sort == BGP_PEER_EBGP) {
     sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
     if (peer->gtsm_hops)
       sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - peer->gtsm_hops);

+ 1 - 1
bgpd/bgp_nexthop.c

@@ -453,7 +453,7 @@ bgp_scan (afi_t afi, safi_t safi)
 	      changed = 0;
 	      metricchanged = 0;
 
-	      if (peer_sort (bi->peer) == BGP_PEER_EBGP && bi->peer->ttl == 1)
+	      if (bi->peer->sort == BGP_PEER_EBGP && bi->peer->ttl == 1)
 		valid = bgp_nexthop_onlink (afi, bi->attr);
 	      else
 		valid = bgp_nexthop_lookup (afi, bi->peer, bi,

+ 35 - 35
bgpd/bgp_route.c

@@ -447,17 +447,17 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
     }
 
   /* 7. Peer type check. */
-  if (peer_sort (new->peer) == BGP_PEER_EBGP 
-      && peer_sort (exist->peer) == BGP_PEER_IBGP)
+  if (new->peer->sort == BGP_PEER_EBGP
+      && exist->peer->sort == BGP_PEER_IBGP)
     return 1;
-  if (peer_sort (new->peer) == BGP_PEER_EBGP 
-      && peer_sort (exist->peer) == BGP_PEER_CONFED)
+  if (new->peer->sort == BGP_PEER_EBGP
+      && exist->peer->sort == BGP_PEER_CONFED)
     return 1;
-  if (peer_sort (new->peer) == BGP_PEER_IBGP 
-      && peer_sort (exist->peer) == BGP_PEER_EBGP)
+  if (new->peer->sort == BGP_PEER_IBGP
+      && exist->peer->sort == BGP_PEER_EBGP)
     return 0;
-  if (peer_sort (new->peer) == BGP_PEER_CONFED 
-      && peer_sort (exist->peer) == BGP_PEER_EBGP)
+  if (new->peer->sort == BGP_PEER_CONFED
+      && exist->peer->sort == BGP_PEER_EBGP)
     return 0;
 
   /* 8. IGP metric check. */
@@ -471,7 +471,7 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
   /* 9. Maximum path check. */
   if (newm == existm)
     {
-      if ((peer_sort (new->peer) == BGP_PEER_IBGP))
+      if (new->peer->sort == BGP_PEER_IBGP)
 	{
 	  if (aspath_cmp (new->attr->aspath, exist->attr->aspath))
 	    *paths_eq = 1;
@@ -493,8 +493,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
      newer path won't displace an older one, even if it was the
      preferred route based on the additional decision criteria below.  */
   if (! bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID)
-      && peer_sort (new->peer) == BGP_PEER_EBGP
-      && peer_sort (exist->peer) == BGP_PEER_EBGP)
+      && new->peer->sort == BGP_PEER_EBGP
+      && exist->peer->sort == BGP_PEER_EBGP)
     {
       if (CHECK_FLAG (new->flags, BGP_INFO_SELECTED))
 	return 1;
@@ -632,13 +632,13 @@ bgp_community_filter (struct peer *peer, struct attr *attr)
 	return 1;
 
       /* NO_EXPORT check. */
-      if (peer_sort (peer) == BGP_PEER_EBGP &&
+      if (peer->sort == BGP_PEER_EBGP &&
 	  community_include (attr->community, COMMUNITY_NO_EXPORT))
 	return 1;
 
       /* NO_EXPORT_SUBCONFED check. */
-      if (peer_sort (peer) == BGP_PEER_EBGP 
-	  || peer_sort (peer) == BGP_PEER_CONFED)
+      if (peer->sort == BGP_PEER_EBGP
+	  || peer->sort == BGP_PEER_CONFED)
 	if (community_include (attr->community, COMMUNITY_NO_EXPORT_SUBCONFED))
 	  return 1;
     }
@@ -905,7 +905,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
     }
 
   /* Route-Reflect check. */
-  if (peer_sort (from) == BGP_PEER_IBGP && peer_sort (peer) == BGP_PEER_IBGP)
+  if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
     reflect = 1;
   else
     reflect = 0;
@@ -937,8 +937,8 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
   bgp_attr_dup (attr, riattr);
   
   /* If local-preference is not set. */
-  if ((peer_sort (peer) == BGP_PEER_IBGP 
-       || peer_sort (peer) == BGP_PEER_CONFED) 
+  if ((peer->sort == BGP_PEER_IBGP
+       || peer->sort == BGP_PEER_CONFED)
       && (! (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))))
     {
       attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
@@ -946,7 +946,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
     }
 
   /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
-  if (peer_sort (peer) == BGP_PEER_EBGP 
+  if (peer->sort == BGP_PEER_EBGP
       && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
     {
       if (ri->peer != bgp->peer_self && ! transparent
@@ -972,7 +972,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
 	   || (p->family == AF_INET6 && 
                IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
 #endif /* HAVE_IPV6 */
-	   || (peer_sort (peer) == BGP_PEER_EBGP
+	   || (peer->sort == BGP_PEER_EBGP
 	       && bgp_multiaccess_check_v4 (attr->nexthop, peer->host) == 0))
     {
       /* Set IPv4 nexthop. */
@@ -1038,7 +1038,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
 #endif /* HAVE_IPV6 */
 
   /* If this is EBGP peer and remove-private-AS is set.  */
-  if (peer_sort (peer) == BGP_PEER_EBGP
+  if (peer->sort == BGP_PEER_EBGP
       && peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
       && aspath_private_as_check (attr->aspath))
     attr->aspath = aspath_empty_get ();
@@ -1055,8 +1055,8 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
 
       /* The route reflector is not allowed to modify the attributes
 	 of the reflected IBGP routes. */
-      if (peer_sort (from) == BGP_PEER_IBGP 
-	  && peer_sort (peer) == BGP_PEER_IBGP)
+      if (from->sort == BGP_PEER_IBGP
+	  && peer->sort == BGP_PEER_IBGP)
 	{
 	  bgp_attr_dup (&dummy_attr, attr);
 	  info.attr = &dummy_attr;
@@ -1253,7 +1253,7 @@ bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
 
 
   /* If this is EBGP peer and remove-private-AS is set.  */
-  if (peer_sort (rsclient) == BGP_PEER_EBGP
+  if (rsclient->sort == BGP_PEER_EBGP
       && peer_af_flag_check (rsclient, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
       && aspath_private_as_check (attr->aspath))
     attr->aspath = aspath_empty_get ();
@@ -1809,7 +1809,7 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
    * the bgp_info in the RIB for historical reference.
    */
   if (CHECK_FLAG (peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
-      && peer_sort (peer) == BGP_PEER_EBGP)
+      && peer->sort == BGP_PEER_EBGP)
     if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0)) 
          == BGP_DAMP_SUPPRESSED)
       {
@@ -2137,7 +2137,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
     {
       /* If the peer is EBGP and nexthop is not on connected route,
 	 discard it.  */
-      if (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl == 1
+      if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
 	  && ! bgp_nexthop_onlink (afi, &new_attr)
 	  && ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
 	{
@@ -2170,7 +2170,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
 	  bgp_info_unset_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
 
 	  if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
-	      && peer_sort (peer) == BGP_PEER_EBGP
+	      && peer->sort == BGP_PEER_EBGP
 	      && CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
 	    {
 	      if (BGP_DEBUG (update, UPDATE_IN))  
@@ -2241,7 +2241,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
       
       /* Update bgp route dampening information.  */
       if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
-	  && peer_sort (peer) == BGP_PEER_EBGP)
+	  && peer->sort == BGP_PEER_EBGP)
 	{
 	  /* This is implicit withdraw so we should update dampening
 	     information.  */
@@ -2259,7 +2259,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
 
       /* Update bgp route dampening information.  */
       if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
-	  && peer_sort (peer) == BGP_PEER_EBGP)
+	  && peer->sort == BGP_PEER_EBGP)
 	{
 	  /* Now we do normal update dampening.  */
 	  ret = bgp_damp_update (ri, rn, afi, safi);
@@ -2274,9 +2274,9 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
       /* Nexthop reachability check. */
       if ((afi == AFI_IP || afi == AFI_IP6)
 	  && safi == SAFI_UNICAST 
-	  && (peer_sort (peer) == BGP_PEER_IBGP
-              || peer_sort (peer) == BGP_PEER_CONFED
-	      || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
+	  && (peer->sort == BGP_PEER_IBGP
+              || peer->sort == BGP_PEER_CONFED
+	      || (peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
 	      || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
 	{
 	  if (bgp_nexthop_lookup (afi, peer, ri, NULL, NULL))
@@ -2321,9 +2321,9 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
   /* Nexthop reachability check. */
   if ((afi == AFI_IP || afi == AFI_IP6)
       && safi == SAFI_UNICAST
-      && (peer_sort (peer) == BGP_PEER_IBGP
-          || peer_sort (peer) == BGP_PEER_CONFED
-	  || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
+      && (peer->sort == BGP_PEER_IBGP
+          || peer->sort == BGP_PEER_CONFED
+	  || (peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
 	  || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
     {
       if (bgp_nexthop_lookup (afi, peer, new, NULL, NULL))
@@ -11794,7 +11794,7 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
 	}
     }
 
-  if (peer_sort (peer) == BGP_PEER_EBGP)
+  if (peer->sort == BGP_PEER_EBGP)
     {
       if (bgp->distance_ebgp)
 	return bgp->distance_ebgp;

+ 2 - 2
bgpd/bgp_vty.c

@@ -4340,7 +4340,7 @@ bgp_clear (struct vty *vty, struct bgp *bgp,  afi_t afi, safi_t safi,
     {
       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 	{
-	  if (peer_sort (peer) == BGP_PEER_IBGP) 
+	  if (peer->sort == BGP_PEER_IBGP)
 	    continue;
 
 	  if (stype == BGP_CLEAR_SOFT_NONE)
@@ -7781,7 +7781,7 @@ bgp_show_peer (struct vty *vty, struct peer *p)
     }
 
   /* EBGP Multihop and GTSM */
-  if (peer_sort (p) != BGP_PEER_IBGP)
+  if (p->sort != BGP_PEER_IBGP)
     {
       if (p->gtsm_hops > 0)
 	vty_out (vty, "  External BGP neighbor may be up to %d hops away.%s",

+ 4 - 4
bgpd/bgp_zebra.c

@@ -664,13 +664,13 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, sa
   flags = 0;
   peer = info->peer;
 
-  if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
+  if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
     {
       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
     }
 
-  if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
+  if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
       || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
     SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
 
@@ -828,13 +828,13 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
   peer = info->peer;
   flags = 0;
 
-  if (peer_sort (peer) == BGP_PEER_IBGP)
+  if (peer->sort == BGP_PEER_IBGP)
     {
       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
     }
 
-  if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
+  if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
       || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
     SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
 

+ 32 - 24
bgpd/bgpd.c

@@ -201,7 +201,7 @@ bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
   /* 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 @@ bgp_cluster_id_unset (struct bgp *bgp)
   /* 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_global_config_reset (struct peer *peer)
   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 @@ peer_sort (struct peer *peer)
     }
 }
 
+/* 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_create (union sockunion *su, struct bgp *bgp, as_t local_as,
   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 @@ peer_create_accept (struct bgp *bgp)
 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 @@ peer_ebgp_multihop_set (struct peer *peer, int ttl)
   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 @@ peer_ebgp_multihop_set (struct peer *peer, int ttl)
 
           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 @@ peer_ebgp_multihop_set (struct peer *peer, int ttl)
 
   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 @@ peer_ebgp_multihop_set (struct peer *peer, int ttl)
       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 @@ peer_ebgp_multihop_unset (struct peer *peer)
   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 @@ peer_ebgp_multihop_unset (struct peer *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_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
     }
   else
@@ -2745,7 +2753,7 @@ peer_ebgp_multihop_unset (struct peer *peer)
       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 @@ peer_advertise_interval_unset (struct peer *peer)
   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 @@ peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
 
   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 @@ peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
 
         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 @@ peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
 
   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 @@ peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
       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 @@ peer_ttl_security_hops_unset (struct peer *peer)
 
   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 @@ peer_ttl_security_hops_unset (struct peer *peer)
   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 @@ peer_ttl_security_hops_unset (struct peer *peer)
       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 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
 	  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 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
 		   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);

+ 13 - 11
bgpd/bgpd.h

@@ -259,6 +259,16 @@ struct bgp_filter
   } usmap;
 };
 
+/* IBGP/EBGP identifier.  We also have a CONFED peer, which is to say,
+   a peer who's AS is part of our Confederation.  */
+typedef enum
+{
+  BGP_PEER_IBGP = 1,
+  BGP_PEER_EBGP,
+  BGP_PEER_INTERNAL,
+  BGP_PEER_CONFED,
+} bgp_peer_sort_t;
+
 /* BGP neighbor structure. */
 struct peer
 {
@@ -282,6 +292,8 @@ struct peer
   /* Peer's local AS number. */
   as_t local_as;
 
+  bgp_peer_sort_t sort;
+
   /* Peer's Change local AS number. */
   as_t change_local_as;
 
@@ -749,16 +761,6 @@ struct bgp_nlri
 /* Check AS path loop when we send NLRI.  */
 /* #define BGP_SEND_ASPATH_CHECK */
 
-/* IBGP/EBGP identifier.  We also have a CONFED peer, which is to say,
-   a peer who's AS is part of our Confederation.  */
-enum
-{
-  BGP_PEER_IBGP,
-  BGP_PEER_EBGP,
-  BGP_PEER_INTERNAL,
-  BGP_PEER_CONFED
-};
-
 /* Flag for peer_clear_soft().  */
 enum bgp_clear_type
 {
@@ -833,7 +835,7 @@ extern struct peer *peer_lookup_with_open (union sockunion *, as_t, struct in_ad
 				    int *);
 extern struct peer *peer_lock (struct peer *);
 extern struct peer *peer_unlock (struct peer *);
-extern int peer_sort (struct peer *peer);
+extern bgp_peer_sort_t peer_sort (struct peer *peer);
 extern int peer_active (struct peer *);
 extern int peer_active_nego (struct peer *);
 extern struct peer *peer_create_accept (struct bgp *);