From: Donald Sharp Date: Wed, 27 Sep 2017 00:06:13 +0000 (-0400) Subject: bgpd: Reduce multiaccess_check_v4 overhead for subgroups X-Git-Tag: frr-4.0-dev~272^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=65d4e0c69b5cb6e7811784ef563e1b23ba162cff;p=mirror%2Ffrr.git bgpd: Reduce multiaccess_check_v4 overhead for subgroups Perf results at scale( >1k peers) showed a non-trivial amount of time spent in bgp_multiaccess_check_v4. Upon function examination we are looking up the nexthops connected node in each call as well as having to unlock it after each iteration. Rewrite to lookup the nexthop node once. This should reduce the node lookup by aproximately 1/2 which should yield some performance results. There are probably better things to do here but would require deeper thought. Signed-off-by: Donald Sharp --- diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 2d05a9e194..870da22d20 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -430,6 +430,48 @@ int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer) return (ret); } +int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, + struct update_subgroup *subgrp) +{ + struct bgp_node *rn1, *rn2; + struct peer_af *paf; + struct prefix p, np; + struct bgp *bgp = NULL; + + np.family = AF_INET; + np.prefixlen = IPV4_MAX_BITLEN; + np.u.prefix4 = nexthop; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + + rn1 = rn2 = NULL; + + bgp = SUBGRP_INST(subgrp); + rn1 = bgp_node_match(bgp->connected_table[AFI_IP], + &np); + if (!rn1) + return 0; + + SUBGRP_FOREACH_PEER(subgrp, paf) { + p.u.prefix4 = paf->peer->su.sin.sin_addr; + + rn2 = bgp_node_match(bgp->connected_table[AFI_IP], + &p); + if (rn1 == rn2) { + bgp_unlock_node(rn1); + bgp_unlock_node(rn2); + return 1; + } + + if (rn2) + bgp_unlock_node(rn2); + } + + bgp_unlock_node(rn1); + return 0; +} + static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp, struct bgp_nexthop_cache *bnc) diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h index b482778fdf..2c5b2ab118 100644 --- a/bgpd/bgp_nexthop.h +++ b/bgpd/bgp_nexthop.h @@ -82,6 +82,8 @@ extern int bgp_nexthop_lookup(afi_t, struct peer *peer, struct bgp_info *, int *, int *); extern void bgp_connected_add(struct bgp *bgp, struct connected *c); extern void bgp_connected_delete(struct bgp *bgp, struct connected *c); +extern int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, + struct update_subgroup *subgrp); extern int bgp_multiaccess_check_v4(struct in_addr, struct peer *); extern int bgp_config_write_scan_time(struct vty *); extern int bgp_nexthop_self(struct bgp *, struct in_addr); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 5e51418165..44b3c5c348 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1319,7 +1319,6 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri, struct peer *onlypeer; struct bgp *bgp; struct attr *riattr; - struct peer_af *paf; char buf[PREFIX_STRLEN]; int ret; int transparent; @@ -1710,16 +1709,12 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri, * Note: 3rd party nexthop currently implemented for * IPv4 only. */ - SUBGRP_FOREACH_PEER (subgrp, paf) { - if (bgp_multiaccess_check_v4(riattr->nexthop, - paf->peer)) - break; - } - if (!paf) + if (!bgp_subgrp_multiaccess_check_v4(riattr->nexthop, + subgrp)) subgroup_announce_reset_nhop( (peer_cap_enhe(peer, afi, safi) - ? AF_INET6 - : p->family), + ? AF_INET6 + : p->family), attr); } /* If IPv6/MP and nexthop does not have any override and happens