diff options
| author | Philippe Guibert <philippe.guibert@6wind.com> | 2022-11-14 15:56:40 +0100 | 
|---|---|---|
| committer | Philippe Guibert <philippe.guibert@6wind.com> | 2023-02-10 10:27:23 +0100 | 
| commit | 17571c4ae7fa294e031b3e614a4fa62f834d0b3d (patch) | |
| tree | f29dc25306cd48687622614c9a994bb27ed4f191 /bgpd/bgp_aspath.c | |
| parent | e55b08839914a3b94f361ee909ee63d265d07845 (diff) | |
bgpd: aspath list format binds on as-notation format
Each BGP prefix may have an as-path list attached. A forged
string is stored in the BGP attribute and shows the as-path
list output.
Before this commit, the as-path list output was expressed as
a list of AS values in plain format. Now, if a given BGP instance
uses a specific asnotation, then the output is changed:
new output:
router bgp 1.1 asnotation dot
!
 address-family ipv4 unicast
  network 10.200.0.0/24 route-map rmap
  network 10.201.0.0/24 route-map rmap
  redistribute connected route-map rmap
 exit-address-family
exit
!
route-map rmap permit 1
 set as-path prepend 1.1 5433.55 264564564
exit
ubuntu2004# do show bgp ipv4
BGP table version is 2, local router ID is 10.0.2.15, vrf id 0
Default local pref 100, local AS 1.1
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
    Network          Next Hop            Metric LocPrf Weight Path
 *> 4.4.4.4/32       0.0.0.0                  0         32768 1.1 5433.55 4036.61268 ?
 *> 10.0.2.0/24      0.0.0.0                  0         32768 1.1 5433.55 4036.61268 ?
    10.200.0.0/24    0.0.0.0                  0         32768 1.1 5433.55 4036.61268 i
    10.201.0.0/24    0.0.0.0                  0         32768 1.1 5433.55 4036.61268 i
The changes include:
- the aspath structure has a new field: asnotation type
The ashash list will differentiate 2 aspaths using a different
asnotation.
- 3 new printf extensions display the as number in the wished
format: pASP, pASD, pASE for plain, dot, or dot+ format (extended).
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'bgpd/bgp_aspath.c')
| -rw-r--r-- | bgpd/bgp_aspath.c | 54 | 
1 files changed, 34 insertions, 20 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 9f74aa76d4..fdfe494e99 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -302,9 +302,13 @@ static struct assegment *assegment_normalise(struct assegment *head)  	return head;  } -static struct aspath *aspath_new(void) +static struct aspath *aspath_new(enum asnotation_mode asnotation)  { -	return XCALLOC(MTYPE_AS_PATH, sizeof(struct aspath)); +	struct aspath *as; + +	as = XCALLOC(MTYPE_AS_PATH, sizeof(struct aspath)); +	as->asnotation = asnotation; +	return as;  }  /* Free AS path structure. */ @@ -552,8 +556,10 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)   *   * This was changed to 10 after the well-known BGP assertion, which   * had hit some parts of the Internet in May of 2009. + * plain format : '4294967295 ' : 10 + 1 + * astod format : '65535.65535 ': 11 + 1   */ -#define ASN_STR_LEN (10 + 1) +#define ASN_STR_LEN (11 + 1)  	str_size = MAX(assegment_count_asns(seg, 0) * ASN_STR_LEN + 2 + 1,  		       ASPATH_STR_DEFAULT_LEN);  	str_buf = XMALLOC(MTYPE_AS_STR, str_size); @@ -584,7 +590,7 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)  /* We might need to increase str_buf, particularly if path has   * differing segments types, our initial guesstimate above will - * have been wrong. Need 10 chars for ASN, a separator each and + * have been wrong. Need 11 chars for ASN, a separator each and   * potentially two segment delimiters, plus a space between each   * segment and trailing zero.   * @@ -610,12 +616,11 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)  		/* write out the ASNs, with their separators, bar the last one*/  		for (i = 0; i < seg->length; i++) {  			if (make_json) -				json_object_array_add( -					jseg_list, -					json_object_new_int64(seg->as[i])); - -			len += snprintf(str_buf + len, str_size - len, "%u", -					seg->as[i]); +				asn_asn2json_array(jseg_list, seg->as[i], +						   as->asnotation); +			len += snprintfrr(str_buf + len, str_size - len, +					  ASN_FORMAT(as->asnotation), +					  &seg->as[i]);  			if (i < (seg->length - 1))  				len += snprintf(str_buf + len, str_size - len, @@ -706,6 +711,7 @@ struct aspath *aspath_dup(struct aspath *aspath)  	new->str = XMALLOC(MTYPE_AS_STR, buflen);  	new->str_len = aspath->str_len; +	new->asnotation = aspath->asnotation;  	/* copy the string data */  	if (aspath->str_len > 0) @@ -733,6 +739,7 @@ static void *aspath_hash_alloc(void *arg)  	new->str = aspath->str;  	new->str_len = aspath->str_len;  	new->json = aspath->json; +	new->asnotation = aspath->asnotation;  	return new;  } @@ -840,7 +847,8 @@ static int assegments_parse(struct stream *s, size_t length,     On error NULL is returned.   */ -struct aspath *aspath_parse(struct stream *s, size_t length, int use32bit) +struct aspath *aspath_parse(struct stream *s, size_t length, int use32bit, +			    enum asnotation_mode asnotation)  {  	struct aspath as;  	struct aspath *find; @@ -855,6 +863,7 @@ struct aspath *aspath_parse(struct stream *s, size_t length, int use32bit)  		return NULL;  	memset(&as, 0, sizeof(as)); +	as.asnotation = asnotation;  	if (assegments_parse(s, length, &as.segments, use32bit) < 0)  		return NULL; @@ -1072,7 +1081,7 @@ struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2)  			seg = assegment_append_asns(seg, seg1->as, match);  			if (!aspath) { -				aspath = aspath_new(); +				aspath = aspath_new(as1->asnotation);  				aspath->segments = seg;  			} else  				prevseg->next = seg; @@ -1092,7 +1101,7 @@ struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2)  	}  	if (!aspath) -		aspath = aspath_new(); +		aspath = aspath_new(as1->asnotation);  	/* Make as-set using rest of all information. */  	from = match; @@ -1536,7 +1545,7 @@ struct aspath *aspath_filter_exclude(struct aspath *source,  	struct assegment *srcseg, *exclseg, *lastseg;  	struct aspath *newpath; -	newpath = aspath_new(); +	newpath = aspath_new(source->asnotation);  	lastseg = NULL;  	for (srcseg = source->segments; srcseg; srcseg = srcseg->next) { @@ -1766,7 +1775,7 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath,  		newseg = assegment_append_asns(newseg, seg->as, cpasns);  		if (!newpath) { -			newpath = aspath_new(); +			newpath = aspath_new(aspath->asnotation);  			newpath->segments = newseg;  		} else  			prevseg->next = newseg; @@ -1895,16 +1904,16 @@ static void aspath_segment_add(struct aspath *as, int type)  		as->segments = new;  } -struct aspath *aspath_empty(void) +struct aspath *aspath_empty(enum asnotation_mode asnotation)  { -	return aspath_parse(NULL, 0, 1); /* 32Bit ;-) */ +	return aspath_parse(NULL, 0, 1, asnotation); /* 32Bit ;-) */  }  struct aspath *aspath_empty_get(void)  {  	struct aspath *aspath; -	aspath = aspath_new(); +	aspath = aspath_new(bgp_get_asnotation(NULL));  	aspath_make_str_count(aspath, false);  	return aspath;  } @@ -1988,7 +1997,8 @@ static const char *aspath_gettoken(const char *buf, enum as_token *token,  	return p;  } -struct aspath *aspath_str2aspath(const char *str) +struct aspath *aspath_str2aspath(const char *str, +				 enum asnotation_mode asnotation)  {  	enum as_token token = as_token_unknown;  	unsigned short as_type; @@ -1996,7 +2006,7 @@ struct aspath *aspath_str2aspath(const char *str)  	struct aspath *aspath;  	int needtype; -	aspath = aspath_new(); +	aspath = aspath_new(asnotation);  	/* We start default type as AS_SEQUENCE. */  	as_type = AS_SEQUENCE; @@ -2070,6 +2080,10 @@ bool aspath_cmp(const void *arg1, const void *arg2)  	const struct assegment *seg1 = ((const struct aspath *)arg1)->segments;  	const struct assegment *seg2 = ((const struct aspath *)arg2)->segments; +	if (((const struct aspath *)arg1)->asnotation != +	    ((const struct aspath *)arg2)->asnotation) +		return false; +  	while (seg1 || seg2) {  		int i;  		if ((!seg1 && seg2) || (seg1 && !seg2))  | 
