mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 10:19:52 +00:00
bgpd : route agg. with comm attr is consuming lot of cycles.
While configuring aggregate route prepare the hash table first, then prepare the aggregated standard comm value and then do the unique sort once for standard community. Signed-off-by: vishaldhingra<vdhingra@vmware.com>
This commit is contained in:
parent
f1eb1f0526
commit
21fec67453
@ -910,15 +910,13 @@ static void *bgp_aggr_communty_hash_alloc(void *p)
|
||||
|
||||
static void bgp_aggr_community_prepare(struct hash_backet *hb, void *arg)
|
||||
{
|
||||
struct community *commerge = NULL;
|
||||
struct community *hb_community = hb->data;
|
||||
struct community **aggr_community = arg;
|
||||
|
||||
if (*aggr_community) {
|
||||
commerge = community_merge(*aggr_community, hb_community);
|
||||
*aggr_community = community_uniq_sort(commerge);
|
||||
community_free(&commerge);
|
||||
} else
|
||||
if (*aggr_community)
|
||||
*aggr_community = community_merge(*aggr_community,
|
||||
hb_community);
|
||||
else
|
||||
*aggr_community = community_dup(hb_community);
|
||||
}
|
||||
|
||||
@ -931,6 +929,14 @@ void bgp_aggr_community_remove(void *arg)
|
||||
|
||||
void bgp_compute_aggregate_community(struct bgp_aggregate *aggregate,
|
||||
struct community *community)
|
||||
{
|
||||
bgp_compute_aggregate_community_hash(aggregate, community);
|
||||
bgp_compute_aggregate_community_val(aggregate);
|
||||
}
|
||||
|
||||
|
||||
void bgp_compute_aggregate_community_hash(struct bgp_aggregate *aggregate,
|
||||
struct community *community)
|
||||
{
|
||||
struct community *aggr_community = NULL;
|
||||
|
||||
@ -951,32 +957,47 @@ void bgp_compute_aggregate_community(struct bgp_aggregate *aggregate,
|
||||
*/
|
||||
aggr_community = hash_get(aggregate->community_hash, community,
|
||||
bgp_aggr_communty_hash_alloc);
|
||||
|
||||
/* Re-compute aggregate's community.
|
||||
*/
|
||||
if (aggregate->community)
|
||||
community_free(&aggregate->community);
|
||||
|
||||
hash_iterate(aggregate->community_hash,
|
||||
bgp_aggr_community_prepare,
|
||||
&aggregate->community);
|
||||
}
|
||||
|
||||
/* Increment refernce counter.
|
||||
/* Increment reference counter.
|
||||
*/
|
||||
aggr_community->refcnt++;
|
||||
}
|
||||
|
||||
void bgp_compute_aggregate_community_val(struct bgp_aggregate *aggregate)
|
||||
{
|
||||
struct community *commerge = NULL;
|
||||
|
||||
if (aggregate == NULL)
|
||||
return;
|
||||
|
||||
/* Re-compute aggregate's community.
|
||||
*/
|
||||
if (aggregate->community)
|
||||
community_free(&aggregate->community);
|
||||
if (aggregate->community_hash &&
|
||||
aggregate->community_hash->count) {
|
||||
hash_iterate(aggregate->community_hash,
|
||||
bgp_aggr_community_prepare,
|
||||
&aggregate->community);
|
||||
commerge = aggregate->community;
|
||||
aggregate->community = community_uniq_sort(commerge);
|
||||
if (commerge)
|
||||
community_free(&commerge);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void bgp_remove_community_from_aggregate(struct bgp_aggregate *aggregate,
|
||||
struct community *community)
|
||||
{
|
||||
struct community *aggr_community = NULL;
|
||||
struct community *ret_comm = NULL;
|
||||
|
||||
if ((aggregate == NULL) || (community == NULL))
|
||||
return;
|
||||
|
||||
if (aggregate->community_hash == NULL)
|
||||
if ((!aggregate)
|
||||
|| (!aggregate->community_hash)
|
||||
|| (!community))
|
||||
return;
|
||||
|
||||
/* Look-up the community in the hash.
|
||||
@ -990,13 +1011,33 @@ void bgp_remove_community_from_aggregate(struct bgp_aggregate *aggregate,
|
||||
aggr_community);
|
||||
community_free(&ret_comm);
|
||||
|
||||
community_free(&aggregate->community);
|
||||
|
||||
/* Compute aggregate's community.
|
||||
*/
|
||||
hash_iterate(aggregate->community_hash,
|
||||
bgp_aggr_community_prepare,
|
||||
&aggregate->community);
|
||||
bgp_compute_aggregate_community_val(aggregate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bgp_remove_comm_from_aggregate_hash(struct bgp_aggregate *aggregate,
|
||||
struct community *community)
|
||||
{
|
||||
|
||||
struct community *aggr_community = NULL;
|
||||
struct community *ret_comm = NULL;
|
||||
|
||||
if ((!aggregate)
|
||||
|| (!aggregate->community_hash)
|
||||
|| (!community))
|
||||
return;
|
||||
|
||||
/* Look-up the community in the hash.
|
||||
*/
|
||||
aggr_community = bgp_aggr_community_lookup(aggregate, community);
|
||||
if (aggr_community) {
|
||||
aggr_community->refcnt--;
|
||||
|
||||
if (aggr_community->refcnt == 0) {
|
||||
ret_comm = hash_release(aggregate->community_hash,
|
||||
aggr_community);
|
||||
community_free(&ret_comm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,8 +92,16 @@ extern struct hash *community_hash(void);
|
||||
extern uint32_t community_val_get(struct community *com, int i);
|
||||
extern void bgp_compute_aggregate_community(struct bgp_aggregate *aggregate,
|
||||
struct community *community);
|
||||
|
||||
extern void bgp_compute_aggregate_community_val(
|
||||
struct bgp_aggregate *aggregate);
|
||||
extern void bgp_compute_aggregate_community_hash(
|
||||
struct bgp_aggregate *aggregate,
|
||||
struct community *community);
|
||||
extern void bgp_remove_community_from_aggregate(struct bgp_aggregate *aggregate,
|
||||
struct community *community);
|
||||
extern void bgp_remove_comm_from_aggregate_hash(struct bgp_aggregate *aggregate,
|
||||
struct community *community);
|
||||
extern void bgp_aggr_community_remove(void *arg);
|
||||
|
||||
#endif /* _QUAGGA_BGP_COMMUNITY_H */
|
||||
|
@ -5933,7 +5933,7 @@ void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
|
||||
/* Compute aggregate route's community.
|
||||
*/
|
||||
if (pi->attr->community)
|
||||
bgp_compute_aggregate_community(
|
||||
bgp_compute_aggregate_community_hash(
|
||||
aggregate,
|
||||
pi->attr->community);
|
||||
|
||||
@ -5954,8 +5954,11 @@ void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
|
||||
if (match)
|
||||
bgp_process(bgp, rn, afi, safi);
|
||||
}
|
||||
if (aggregate->as_set)
|
||||
if (aggregate->as_set) {
|
||||
bgp_compute_aggregate_community_val(aggregate);
|
||||
bgp_compute_aggregate_lcommunity_val(aggregate);
|
||||
}
|
||||
|
||||
|
||||
bgp_unlock_node(top);
|
||||
|
||||
@ -6044,7 +6047,7 @@ void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
|
||||
if (pi->attr->community)
|
||||
/* Remove community from aggregate.
|
||||
*/
|
||||
bgp_remove_community_from_aggregate(
|
||||
bgp_remove_comm_from_aggregate_hash(
|
||||
aggregate,
|
||||
pi->attr->community);
|
||||
|
||||
@ -6070,6 +6073,8 @@ void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
|
||||
bgp_process(bgp, rn, afi, safi);
|
||||
}
|
||||
if (aggregate->as_set) {
|
||||
if (aggregate->community)
|
||||
community_free(&aggregate->community);
|
||||
if (aggregate->lcommunity)
|
||||
lcommunity_free(&aggregate->lcommunity);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user