mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 15:33:56 +00:00
bgpd: Code to handle BGP aggregate's communities.
With this commit: 1) The code to manage the communities attribute of the routes that are aggregatable under a configured aggregate-address is introduced. 2) The code to compute the aggregate-route's communities attribute is introduced. Signed-off-by: NaveenThanikachalam <nthanikachal@vmware.com>
This commit is contained in:
parent
e00d800877
commit
c0d7a6ccb9
@ -910,3 +910,112 @@ void community_finish(void)
|
|||||||
hash_free(comhash);
|
hash_free(comhash);
|
||||||
comhash = NULL;
|
comhash = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct community *bgp_aggr_community_lookup(
|
||||||
|
struct bgp_aggregate *aggregate,
|
||||||
|
struct community *community)
|
||||||
|
{
|
||||||
|
return hash_lookup(aggregate->community_hash, community);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *bgp_aggr_communty_hash_alloc(void *p)
|
||||||
|
{
|
||||||
|
struct community *ref = (struct community *)p;
|
||||||
|
struct community *community = NULL;
|
||||||
|
|
||||||
|
community = community_dup(ref);
|
||||||
|
return community;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
*aggr_community = community_dup(hb_community);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bgp_aggr_community_remove(void *arg)
|
||||||
|
{
|
||||||
|
struct community *community = arg;
|
||||||
|
|
||||||
|
community_free(&community);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bgp_compute_aggregate_community(struct bgp_aggregate *aggregate,
|
||||||
|
struct community *community)
|
||||||
|
{
|
||||||
|
struct community *aggr_community = NULL;
|
||||||
|
|
||||||
|
if ((aggregate == NULL) || (community == NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Create hash if not already created.
|
||||||
|
*/
|
||||||
|
if (aggregate->community_hash == NULL)
|
||||||
|
aggregate->community_hash = hash_create(
|
||||||
|
(unsigned int (*)(void *))community_hash_make,
|
||||||
|
(bool (*)(const void *, const void *))community_cmp,
|
||||||
|
"BGP Aggregator community hash");
|
||||||
|
|
||||||
|
aggr_community = bgp_aggr_community_lookup(aggregate, community);
|
||||||
|
if (aggr_community == NULL) {
|
||||||
|
/* Insert community into hash.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
aggr_community->refcnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
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);
|
||||||
|
|
||||||
|
community_free(&aggregate->community);
|
||||||
|
|
||||||
|
/* Compute aggregate's community.
|
||||||
|
*/
|
||||||
|
hash_iterate(aggregate->community_hash,
|
||||||
|
bgp_aggr_community_prepare,
|
||||||
|
&aggregate->community);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#define _QUAGGA_BGP_COMMUNITY_H
|
#define _QUAGGA_BGP_COMMUNITY_H
|
||||||
|
|
||||||
#include "lib/json.h"
|
#include "lib/json.h"
|
||||||
|
#include "bgpd/bgp_route.h"
|
||||||
|
|
||||||
/* Communities attribute. */
|
/* Communities attribute. */
|
||||||
struct community {
|
struct community {
|
||||||
@ -89,5 +90,10 @@ extern void community_del_val(struct community *, uint32_t *);
|
|||||||
extern unsigned long community_count(void);
|
extern unsigned long community_count(void);
|
||||||
extern struct hash *community_hash(void);
|
extern struct hash *community_hash(void);
|
||||||
extern uint32_t community_val_get(struct community *com, int i);
|
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_remove_community_from_aggregate(struct bgp_aggregate *aggregate,
|
||||||
|
struct community *community);
|
||||||
|
extern void bgp_aggr_community_remove(void *arg);
|
||||||
|
|
||||||
#endif /* _QUAGGA_BGP_COMMUNITY_H */
|
#endif /* _QUAGGA_BGP_COMMUNITY_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user