diff options
| author | Russ White <russ@riw.us> | 2023-02-21 08:01:03 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-21 08:01:03 -0500 | 
| commit | ba755d35e508c2452e5459bdd7c0dd67a70a88a4 (patch) | |
| tree | adc08f46788b8012240faec23ae7e7271bb0d40d /bgpd/bgp_aspath.c | |
| parent | 39c664c4ea530a9460efa1a78fe669ae56c85f83 (diff) | |
| parent | 616e9f0d9f0458788adf4b30707016c8db383b02 (diff) | |
Merge pull request #12248 from pguibert6WIND/bgpasdot
lib, bgp: add initial support for asdot format
Diffstat (limited to 'bgpd/bgp_aspath.c')
| -rw-r--r-- | bgpd/bgp_aspath.c | 81 | 
1 files changed, 42 insertions, 39 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 584f524f05..2cc7e46573 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -287,9 +287,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. */ @@ -537,8 +541,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); @@ -569,7 +575,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.   * @@ -595,12 +601,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, @@ -691,6 +696,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) @@ -718,6 +724,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;  } @@ -825,7 +832,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; @@ -840,6 +848,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; @@ -1057,7 +1066,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; @@ -1077,7 +1086,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; @@ -1521,7 +1530,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) { @@ -1751,7 +1760,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; @@ -1880,16 +1889,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;  } @@ -1925,6 +1934,8 @@ static const char *aspath_gettoken(const char *buf, enum as_token *token,  				   unsigned long *asno)  {  	const char *p = buf; +	as_t asval; +	bool found = false;  	/* Skip separators (space for sequences, ',' for sets). */  	while (isspace((unsigned char)*p) || *p == ',') @@ -1961,30 +1972,18 @@ static const char *aspath_gettoken(const char *buf, enum as_token *token,  		return p;  	} -	/* Check actual AS value. */ -	if (isdigit((unsigned char)*p)) { -		as_t asval; - -		*token = as_token_asval; -		asval = (*p - '0'); -		p++; - -		while (isdigit((unsigned char)*p)) { -			asval *= 10; -			asval += (*p - '0'); -			p++; -		} +	asval = 0; +	p = asn_str2asn_parse(p, &asval, &found); +	if (found) {  		*asno = asval; -		return p; -	} - -	/* There is no match then return unknown token. */ -	*token = as_token_unknown; -	p++; +		*token = as_token_asval; +	} else +		*token = as_token_unknown;  	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; @@ -1992,7 +1991,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; @@ -2066,6 +2065,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))  | 
