summaryrefslogtreecommitdiff
path: root/bgpd/bgp_aspath.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2022-11-14 15:56:40 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2023-02-10 10:27:23 +0100
commit17571c4ae7fa294e031b3e614a4fa62f834d0b3d (patch)
treef29dc25306cd48687622614c9a994bb27ed4f191 /bgpd/bgp_aspath.c
parente55b08839914a3b94f361ee909ee63d265d07845 (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.c54
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))