bgpd: Code to handle BGP aggregate's as-path.

With this commit:
1) 'struct bgp_aggregate' is moved to bgp_route.h from bgp_route.c
2) Hashes to accommodate the as-path, communities, extended-communities and
   large-communities attributes of all the routes aggregated by an
   aggregate route is introduced in 'struct bgp_aggregate'.
3) Place-holders for the aggregate route's as-path, communities,
   extended-communities and large-communities attributes are introduced in
   'struct bgp_aggregate'.
4) The code to manage the as-path of the routes that are aggregatable under
   a configured aggregate-address is introduced.
5) The code to compute the aggregate-route's as-path is introduced.

Signed-off-by: NaveenThanikachalam <nthanikachal@vmware.com>
This commit is contained in:
Naveen Thanikachalam 2019-02-06 05:44:20 -08:00
parent 83c2a84d7c
commit e00d800877
4 changed files with 186 additions and 29 deletions

View File

@ -212,6 +212,9 @@ static struct assegment *assegment_append_asns(struct assegment *seg,
{
as_t *newas;
if (!seg)
return seg;
newas = XREALLOC(MTYPE_AS_SEG_DATA, seg->as,
ASSEGMENT_DATA_SIZE(seg->length + num, 1));
@ -1372,7 +1375,8 @@ static struct aspath *aspath_merge(struct aspath *as1, struct aspath *as2)
while (last && last->next)
last = last->next;
last->next = as2->segments;
if (last)
last->next = as2->segments;
as2->segments = new;
aspath_str_update(as2, false);
return as2;
@ -1447,7 +1451,8 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2)
* bypass the merged seg2, and attach any chain after it
* to chain descending from as2's head
*/
as2segtail->next = as2seghead->next;
if (as2segtail)
as2segtail->next = as2seghead->next;
/* as2->segments is now referenceless and useless */
assegment_free(as2seghead);
@ -2096,3 +2101,110 @@ void aspath_print_all_vty(struct vty *vty)
void *))aspath_show_all_iterator,
vty);
}
static struct aspath *bgp_aggr_aspath_lookup(struct bgp_aggregate *aggregate,
struct aspath *aspath)
{
return hash_lookup(aggregate->aspath_hash, aspath);
}
static void *bgp_aggr_aspath_hash_alloc(void *p)
{
struct aspath *ref = (struct aspath *)p;
struct aspath *aspath = NULL;
aspath = aspath_dup(ref);
return aspath;
}
static void bgp_aggr_aspath_prepare(struct hash_backet *hb, void *arg)
{
struct aspath *asmerge = NULL;
struct aspath *hb_aspath = hb->data;
struct aspath **aggr_aspath = arg;
if (*aggr_aspath) {
asmerge = aspath_aggregate(*aggr_aspath, hb_aspath);
aspath_free(*aggr_aspath);
*aggr_aspath = asmerge;
} else
*aggr_aspath = aspath_dup(hb_aspath);
}
void bgp_aggr_aspath_remove(void *arg)
{
struct aspath *aspath = arg;
aspath_free(aspath);
}
void bgp_compute_aggregate_aspath(struct bgp_aggregate *aggregate,
struct aspath *aspath)
{
struct aspath *aggr_aspath = NULL;
if ((aggregate == NULL) || (aspath == NULL))
return;
/* Create hash if not already created.
*/
if (aggregate->aspath_hash == NULL)
aggregate->aspath_hash = hash_create(
aspath_key_make, aspath_cmp,
"BGP Aggregator as-path hash");
aggr_aspath = bgp_aggr_aspath_lookup(aggregate, aspath);
if (aggr_aspath == NULL) {
/* Insert as-path into hash.
*/
aggr_aspath = hash_get(aggregate->aspath_hash, aspath,
bgp_aggr_aspath_hash_alloc);
/* Compute aggregate's as-path.
*/
hash_iterate(aggregate->aspath_hash,
bgp_aggr_aspath_prepare,
&aggregate->aspath);
}
/* Increment refernce counter.
*/
aggr_aspath->refcnt++;
}
void bgp_remove_aspath_from_aggregate(struct bgp_aggregate *aggregate,
struct aspath *aspath)
{
struct aspath *aggr_aspath = NULL;
struct aspath *ret_aspath = NULL;
if ((aggregate == NULL) || (aspath == NULL))
return;
if (aggregate->aspath_hash == NULL)
return;
/* Look-up the aspath in the hash.
*/
aggr_aspath = bgp_aggr_aspath_lookup(aggregate, aspath);
if (aggr_aspath) {
aggr_aspath->refcnt--;
if (aggr_aspath->refcnt == 0) {
ret_aspath = hash_release(aggregate->aspath_hash,
aggr_aspath);
aspath_free(ret_aspath);
/* Remove aggregate's old as-path.
*/
aspath_free(aggregate->aspath);
aggregate->aspath = NULL;
/* Compute aggregate's as-path.
*/
hash_iterate(aggregate->aspath_hash,
bgp_aggr_aspath_prepare,
&aggregate->aspath);
}
}
}

View File

@ -22,6 +22,7 @@
#define _QUAGGA_BGP_ASPATH_H
#include "lib/json.h"
#include "bgpd/bgp_route.h"
/* AS path segment type. */
#define AS_SET 1
@ -130,4 +131,10 @@ extern unsigned int aspath_has_as4(struct aspath *);
/* For SNMP BGP4PATHATTRASPATHSEGMENT, might be useful for debug */
extern uint8_t *aspath_snmp_pathseg(struct aspath *, size_t *);
extern void bgp_compute_aggregate_aspath(struct bgp_aggregate *aggregate,
struct aspath *aspath);
extern void bgp_remove_aspath_from_aggregate(struct bgp_aggregate *aggregate,
struct aspath *aspath);
extern void bgp_aggr_aspath_remove(void *arg);
#endif /* _QUAGGA_BGP_ASPATH_H */

View File

@ -5513,33 +5513,6 @@ DEFPY(ipv6_bgp_network,
label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
}
/* Aggreagete address:
advertise-map Set condition to advertise attribute
as-set Generate AS set path information
attribute-map Set attributes of aggregate
route-map Set parameters of aggregate
summary-only Filter more specific routes from updates
suppress-map Conditionally filter more specific routes from updates
<cr>
*/
struct bgp_aggregate {
/* Summary-only flag. */
uint8_t summary_only;
/* AS set generation. */
uint8_t as_set;
/* Route-map for aggregated route. */
struct route_map *map;
/* Suppress-count. */
unsigned long count;
/* SAFI configuration. */
safi_t safi;
};
static struct bgp_aggregate *bgp_aggregate_new(void)
{
return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));

View File

@ -272,6 +272,71 @@ struct bgp_static {
struct prefix gatewayIp;
};
/* Aggreagete address:
*
* advertise-map Set condition to advertise attribute
* as-set Generate AS set path information
* attribute-map Set attributes of aggregate
* route-map Set parameters of aggregate
* summary-only Filter more specific routes from updates
* suppress-map Conditionally filter more specific routes from updates
* <cr>
*/
struct bgp_aggregate {
/* Summary-only flag. */
uint8_t summary_only;
/* AS set generation. */
uint8_t as_set;
/* Route-map for aggregated route. */
struct route_map *map;
/* Suppress-count. */
unsigned long count;
/* Count of routes of origin type incomplete under this aggregate. */
unsigned long incomplete_origin_count;
/* Count of routes of origin type egp under this aggregate. */
unsigned long egp_origin_count;
/* Hash containing the communities of all the
* routes under this aggregate.
*/
struct hash *community_hash;
/* Hash containing the extended communities of all the
* routes under this aggregate.
*/
struct hash *ecommunity_hash;
/* Hash containing the large communities of all the
* routes under this aggregate.
*/
struct hash *lcommunity_hash;
/* Hash containing the AS-Path of all the
* routes under this aggregate.
*/
struct hash *aspath_hash;
/* Aggregate route's community. */
struct community *community;
/* Aggregate route's extended community. */
struct ecommunity *ecommunity;
/* Aggregate route's large community. */
struct lcommunity *lcommunity;
/* Aggregate route's as-path. */
struct aspath *aspath;
/* SAFI configuration. */
safi_t safi;
};
#define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen) \
((nhlen) < IPV4_MAX_BYTELEN \
? 0 \