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 <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2017-09-26 20:06:13 -04:00
parent 6988ea42d2
commit 65d4e0c69b
3 changed files with 48 additions and 9 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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