summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2023-02-21 14:01:03 +0100
committerGitHub <noreply@github.com>2023-02-21 14:01:03 +0100
commitba755d35e508c2452e5459bdd7c0dd67a70a88a4 (patch)
treeadc08f46788b8012240faec23ae7e7271bb0d40d /bgpd
parentMerge pull request #12849 from opensourcerouting/fix/tests_enum (diff)
parentbgpd: handle case where passed RD is null (diff)
downloadfrr-ba755d35e508c2452e5459bdd7c0dd67a70a88a4.tar.xz
frr-ba755d35e508c2452e5459bdd7c0dd67a70a88a4.zip
Merge pull request #12248 from pguibert6WIND/bgpasdot
lib, bgp: add initial support for asdot format
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_aspath.c81
-rw-r--r--bgpd/bgp_aspath.h12
-rw-r--r--bgpd/bgp_attr.c24
-rw-r--r--bgpd/bgp_btoa.c3
-rw-r--r--bgpd/bgp_debug.c11
-rw-r--r--bgpd/bgp_evpn.c16
-rw-r--r--bgpd/bgp_evpn_mh.c28
-rw-r--r--bgpd/bgp_evpn_private.h1
-rw-r--r--bgpd/bgp_evpn_vty.c78
-rw-r--r--bgpd/bgp_mplsvpn.c21
-rw-r--r--bgpd/bgp_mplsvpn_snmp.c6
-rw-r--r--bgpd/bgp_network.c2
-rw-r--r--bgpd/bgp_nexthop.c17
-rw-r--r--bgpd/bgp_nht.c16
-rw-r--r--bgpd/bgp_rd.c100
-rw-r--r--bgpd/bgp_rd.h17
-rw-r--r--bgpd/bgp_route.c84
-rw-r--r--bgpd/bgp_route.h1
-rw-r--r--bgpd/bgp_routemap.c58
-rw-r--r--bgpd/bgp_rpki.c53
-rw-r--r--bgpd/bgp_script.c3
-rw-r--r--bgpd/bgp_vty.c395
-rw-r--r--bgpd/bgp_vty.h3
-rw-r--r--bgpd/bgpd.c127
-rw-r--r--bgpd/bgpd.h48
-rw-r--r--bgpd/rfapi/bgp_rfapi_cfg.c9
-rw-r--r--bgpd/rfapi/rfapi.c6
-rw-r--r--bgpd/rfapi/rfapi_import.c12
-rw-r--r--bgpd/rfapi/rfapi_rib.c6
-rw-r--r--bgpd/rfapi/rfapi_vty.c3
30 files changed, 833 insertions, 408 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 584f524f0..2cc7e4657 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))
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
index dd65b423a..18af375c1 100644
--- a/bgpd/bgp_aspath.h
+++ b/bgpd/bgp_aspath.h
@@ -57,6 +57,9 @@ struct aspath {
and AS path regular expression match. */
char *str;
unsigned short str_len;
+
+ /* AS notation used by string expression of AS path */
+ enum asnotation_mode asnotation;
};
#define ASPATH_STR_DEFAULT_LEN 32
@@ -65,7 +68,9 @@ struct aspath {
extern void aspath_init(void);
extern void aspath_finish(void);
extern struct aspath *aspath_parse(struct stream *s, size_t length,
- int use32bit);
+ int use32bit,
+ enum asnotation_mode asnotation);
+
extern struct aspath *aspath_dup(struct aspath *aspath);
extern struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2);
extern struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2);
@@ -81,9 +86,10 @@ extern bool aspath_cmp_left(const struct aspath *aspath1,
extern bool aspath_cmp_left_confed(const struct aspath *as1,
const struct aspath *as2);
extern struct aspath *aspath_delete_confed_seq(struct aspath *aspath);
-extern struct aspath *aspath_empty(void);
+extern struct aspath *aspath_empty(enum asnotation_mode asnotation);
extern struct aspath *aspath_empty_get(void);
-extern struct aspath *aspath_str2aspath(const char *str);
+extern struct aspath *aspath_str2aspath(const char *str,
+ enum asnotation_mode asnotation);
extern void aspath_str_update(struct aspath *as, bool make_json);
extern void aspath_free(struct aspath *aspath);
extern struct aspath *aspath_intern(struct aspath *aspath);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index fe918a3e0..19c65ce4d 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1054,7 +1054,7 @@ struct attr *bgp_attr_default_set(struct attr *attr, struct bgp *bgp,
attr->origin = origin;
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
- attr->aspath = aspath_empty();
+ attr->aspath = aspath_empty(bgp->asnotation);
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
attr->weight = BGP_ATTR_DEFAULT_WEIGHT;
attr->tag = 0;
@@ -1092,7 +1092,7 @@ struct attr *bgp_attr_aggregate_intern(
if (aspath)
attr.aspath = aspath_intern(aspath);
else
- attr.aspath = aspath_empty();
+ attr.aspath = aspath_empty(bgp->asnotation);
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
/* Next hop attribute. */
@@ -1590,15 +1590,19 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
struct attr *const attr = args->attr;
struct peer *const peer = args->peer;
const bgp_size_t length = args->length;
+ enum asnotation_mode asnotation;
+ asnotation = bgp_get_asnotation(
+ args->peer && args->peer->bgp ? args->peer->bgp : NULL);
/*
* peer with AS4 => will get 4Byte ASnums
* otherwise, will get 16 Bit
*/
- attr->aspath = aspath_parse(
- peer->curr, length,
- CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
- && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV));
+ attr->aspath =
+ aspath_parse(peer->curr, length,
+ CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) &&
+ CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV),
+ asnotation);
/* In case of IBGP, length will be zero. */
if (!attr->aspath) {
@@ -1614,7 +1618,8 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
* such messages, conformant BGP speakers SHOULD use the "Treat-as-
* withdraw" error handling behavior as per [RFC7606].
*/
- if (peer->bgp->reject_as_sets && aspath_check_as_sets(attr->aspath)) {
+ if (peer->bgp && peer->bgp->reject_as_sets &&
+ aspath_check_as_sets(attr->aspath)) {
flog_err(EC_BGP_ATTR_MAL_AS_PATH,
"AS_SET and AS_CONFED_SET are deprecated from %pBP",
peer);
@@ -1690,8 +1695,11 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args,
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
const bgp_size_t length = args->length;
+ enum asnotation_mode asnotation;
+
+ asnotation = bgp_get_asnotation(peer->bgp);
- *as4_path = aspath_parse(peer->curr, length, 1);
+ *as4_path = aspath_parse(peer->curr, length, 1, asnotation);
/* In case of IBGP, length will be zero. */
if (!*as4_path) {
diff --git a/bgpd/bgp_btoa.c b/bgpd/bgp_btoa.c
index b410a4b89..fc3363b09 100644
--- a/bgpd/bgp_btoa.c
+++ b/bgpd/bgp_btoa.c
@@ -86,7 +86,8 @@ static void attr_parse(struct stream *s, uint16_t len)
case BGP_ATTR_AS_PATH: {
struct aspath *aspath;
- aspath = aspath_parse(s, length, 1);
+ aspath = aspath_parse(s, length, 1,
+ bgp_get_asnotation(NULL));
printf("ASPATH: %s\n", aspath->str);
aspath_free(aspath);
} break;
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 2dec1ca46..782245e51 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -2635,6 +2635,7 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
char tag_buf[30];
char overlay_index_buf[INET6_ADDRSTRLEN + 14];
const struct prefix_evpn *evp;
+ int len = 0;
/* ' with addpath ID ' 17
* max strlen of uint32 + 10
@@ -2688,11 +2689,15 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
}
}
- if (prd)
- snprintfrr(str, size, "RD %pRD %pFX%s%s%s %s %s", prd, pu.p,
+ if (prd) {
+ len += snprintfrr(str + len, size - len, "RD ");
+ len += snprintfrr(str + len, size - len,
+ BGP_RD_AS_FORMAT(bgp_get_asnotation(NULL)),
+ prd);
+ snprintfrr(str + len, size - len, " %pFX%s%s%s %s %s", pu.p,
overlay_index_buf, tag_buf, pathid_buf, afi2str(afi),
safi2str(safi));
- else if (safi == SAFI_FLOWSPEC) {
+ } else if (safi == SAFI_FLOWSPEC) {
char return_string[BGP_FLOWSPEC_NLRI_STRING_MAX];
const struct prefix_fs *fs = pu.fs;
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 4758cd98e..51b44a9e7 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -5923,6 +5923,8 @@ void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn)
vpn->prd.prefixlen = 64;
snprintfrr(buf, sizeof(buf), "%pI4:%hu", &bgp->router_id, vpn->rd_id);
(void)str2prefix_rd(buf, &vpn->prd);
+ if (vpn->prd_pretty)
+ XFREE(MTYPE_BGP, vpn->prd_pretty);
UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
}
@@ -6027,6 +6029,8 @@ void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
bf_release_index(bm->rd_idspace, vpn->rd_id);
hash_release(bgp->vni_svi_hash, vpn);
hash_release(bgp->vnihash, vpn);
+ if (vpn->prd_pretty)
+ XFREE(MTYPE_BGP, vpn->prd_pretty);
QOBJ_UNREG(vpn);
XFREE(MTYPE_BGP_EVPN, vpn);
}
@@ -6238,13 +6242,14 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id,
ret = bgp_get_vty(&bgp_vrf, &as, vrf_id_to_name(vrf_id),
vrf_id == VRF_DEFAULT
- ? BGP_INSTANCE_TYPE_DEFAULT
- : BGP_INSTANCE_TYPE_VRF);
+ ? BGP_INSTANCE_TYPE_DEFAULT
+ : BGP_INSTANCE_TYPE_VRF,
+ NULL, ASNOTATION_UNDEFINED);
switch (ret) {
case BGP_ERR_AS_MISMATCH:
flog_err(EC_BGP_EVPN_AS_MISMATCH,
- "BGP instance is already running; AS is %u",
- as);
+ "BGP instance is already running; AS is %s",
+ bgp_vrf->as_pretty);
return -1;
case BGP_ERR_INSTANCE_MISMATCH:
flog_err(EC_BGP_EVPN_INSTANCE_MISMATCH,
@@ -6660,6 +6665,9 @@ void bgp_evpn_cleanup(struct bgp *bgp)
list_delete(&bgp->vrf_import_rtl);
list_delete(&bgp->vrf_export_rtl);
list_delete(&bgp->l2vnis);
+
+ if (bgp->vrf_prd_pretty)
+ XFREE(MTYPE_BGP, bgp->vrf_prd_pretty);
}
/*
diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c
index fa913016f..391ca4cd1 100644
--- a/bgpd/bgp_evpn_mh.c
+++ b/bgpd/bgp_evpn_mh.c
@@ -2395,7 +2395,8 @@ static void bgp_evpn_es_json_frag_fill(json_object *json_frags,
for (ALL_LIST_ELEMENTS_RO(es->es_frag_list, node, es_frag)) {
json_frag = json_object_new_object();
- json_object_string_addf(json_frag, "rd", "%pRD", &es_frag->prd);
+ json_object_string_addf(json_frag, "rd", "%pRDP",
+ &es_frag->prd);
json_object_int_add(json_frag, "eviCount",
listcount(es_frag->es_evi_frag_list));
@@ -2410,7 +2411,7 @@ static void bgp_evpn_es_frag_show_detail(struct vty *vty,
struct bgp_evpn_es_frag *es_frag;
for (ALL_LIST_ELEMENTS_RO(es->es_frag_list, node, es_frag)) {
- vty_out(vty, " %pRD EVIs: %d\n", &es_frag->prd,
+ vty_out(vty, " %pRDP EVIs: %d\n", &es_frag->prd,
listcount(es_frag->es_evi_frag_list));
}
}
@@ -2524,7 +2525,7 @@ static void bgp_evpn_es_show_entry(struct vty *vty,
json_object_string_add(json, "esi", es->esi_str);
if (es->es_base_frag)
- json_object_string_addf(json, "rd", "%pRD",
+ json_object_string_addf(json, "rd", "%pRDP",
&es->es_base_frag->prd);
if (es->flags & (BGP_EVPNES_LOCAL | BGP_EVPNES_REMOTE)) {
@@ -2562,7 +2563,7 @@ static void bgp_evpn_es_show_entry(struct vty *vty,
bgp_evpn_es_vteps_str(vtep_str, es, sizeof(vtep_str));
- vty_out(vty, "%-30s %-5s %-21pRD %-8d %s\n", es->esi_str,
+ vty_out(vty, "%-30s %-5s %-21pRDP %-8d %s\n", es->esi_str,
type_str, &es->es_base_frag->prd,
listcount(es->es_evi_list), vtep_str);
}
@@ -2639,7 +2640,7 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty,
vty_out(vty, "ESI: %s\n", es->esi_str);
vty_out(vty, " Type: %s\n", type_str);
- vty_out(vty, " RD: %pRD\n", &es->es_base_frag->prd);
+ vty_out(vty, " RD: %pRDP\n", &es->es_base_frag->prd);
vty_out(vty, " Originator-IP: %pI4\n", &es->originator_ip);
if (es->flags & BGP_EVPNES_LOCAL)
vty_out(vty, " Local ES DF preference: %u\n",
@@ -3958,7 +3959,8 @@ static void bgp_evpn_es_evi_show_entry(struct vty *vty,
json_object *json_types;
json_object_string_add(json, "esi", es_evi->es->esi_str);
- json_object_int_add(json, "vni", es_evi->vpn->vni);
+ if (es_evi->vpn)
+ json_object_int_add(json, "vni", es_evi->vpn->vni);
if (es_evi->flags & (BGP_EVPNES_EVI_LOCAL |
BGP_EVPNES_EVI_REMOTE)) {
@@ -4002,13 +4004,18 @@ static void bgp_evpn_es_evi_show_entry(struct vty *vty,
static void bgp_evpn_es_evi_show_entry_detail(struct vty *vty,
struct bgp_evpn_es_evi *es_evi, json_object *json)
{
+ enum asnotation_mode mode;
+
+ mode = bgp_get_asnotation(es_evi->vpn->bgp_vrf);
+
if (json) {
json_object *json_flags;
/* Add the "brief" info first */
bgp_evpn_es_evi_show_entry(vty, es_evi, json);
if (es_evi->es_frag)
- json_object_string_addf(json, "esFragmentRd", "%pRD",
+ json_object_string_addf(json, "esFragmentRd",
+ BGP_RD_AS_FORMAT(mode),
&es_evi->es_frag->prd);
if (es_evi->flags & BGP_EVPNES_EVI_INCONS_VTEP_LIST) {
json_flags = json_object_new_array();
@@ -4032,9 +4039,12 @@ static void bgp_evpn_es_evi_show_entry_detail(struct vty *vty,
vty_out(vty, "VNI: %d ESI: %s\n",
es_evi->vpn->vni, es_evi->es->esi_str);
vty_out(vty, " Type: %s\n", type_str);
- if (es_evi->es_frag)
- vty_out(vty, " ES fragment RD: %pRD\n",
+ if (es_evi->es_frag) {
+ vty_out(vty, " ES fragment RD: ");
+ vty_out(vty, BGP_RD_AS_FORMAT(mode),
&es_evi->es_frag->prd);
+ vty_out(vty, "\n");
+ }
vty_out(vty, " Inconsistencies: %s\n",
(es_evi->flags & BGP_EVPNES_EVI_INCONS_VTEP_LIST) ?
"es-vtep-mismatch":"-");
diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h
index d63e7a1a1..fbf3b19c3 100644
--- a/bgpd/bgp_evpn_private.h
+++ b/bgpd/bgp_evpn_private.h
@@ -76,6 +76,7 @@ struct bgpevpn {
/* RD for this VNI. */
struct prefix_rd prd;
+ char *prd_pretty;
/* Route type 3 field */
struct in_addr originator_ip;
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 33c202c3d..59986102a 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -374,7 +374,9 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
json_object_int_add(json, "vni", bgp_vrf->l3vni);
json_object_string_add(json, "type", "L3");
json_object_string_add(json, "inKernel", "True");
- json_object_string_addf(json, "rd", "%pRD", &bgp_vrf->vrf_prd);
+ json_object_string_addf(json, "rd",
+ BGP_RD_AS_FORMAT(bgp_vrf->asnotation),
+ &bgp_vrf->vrf_prd);
json_object_string_addf(json, "originatorIp", "%pI4",
&bgp_vrf->originator_ip);
json_object_string_add(json, "advertiseGatewayMacip", "n/a");
@@ -398,7 +400,10 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
vty_out(vty, " Type: %s\n", "L3");
vty_out(vty, " Tenant VRF: %s\n",
vrf_id_to_name(bgp_vrf->vrf_id));
- vty_out(vty, " RD: %pRD\n", &bgp_vrf->vrf_prd);
+ vty_out(vty, " RD: ");
+ vty_out(vty, BGP_RD_AS_FORMAT(bgp_vrf->asnotation),
+ &bgp_vrf->vrf_prd);
+ vty_out(vty, "\n");
vty_out(vty, " Originator IP: %pI4\n",
&bgp_vrf->originator_ip);
vty_out(vty, " Advertise-gw-macip : %s\n", "n/a");
@@ -461,8 +466,10 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
json_object *json_import_rtl = NULL;
json_object *json_export_rtl = NULL;
struct bgp *bgp_evpn;
+ enum asnotation_mode asnotation;
bgp_evpn = bgp_get_evpn();
+ asnotation = bgp_get_asnotation(bgp_evpn);
if (json) {
json_import_rtl = json_object_new_array();
@@ -471,7 +478,8 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
json_object_string_add(json, "type", "L2");
json_object_string_add(json, "inKernel",
is_vni_live(vpn) ? "True" : "False");
- json_object_string_addf(json, "rd", "%pRD", &vpn->prd);
+ json_object_string_addf(
+ json, "rd", BGP_RD_AS_FORMAT(asnotation), &vpn->prd);
json_object_string_addf(json, "originatorIp", "%pI4",
&vpn->originator_ip);
json_object_string_addf(json, "mcastGroup", "%pI4",
@@ -512,7 +520,9 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
vty_out(vty, " Type: %s\n", "L2");
vty_out(vty, " Tenant-Vrf: %s\n",
vrf_id_to_name(vpn->tenant_vrf_id));
- vty_out(vty, " RD: %pRD\n", &vpn->prd);
+ vty_out(vty, " RD: ");
+ vty_out(vty, BGP_RD_AS_FORMAT(asnotation), &vpn->prd);
+ vty_out(vty, "\n");
vty_out(vty, " Originator IP: %pI4\n", &vpn->originator_ip);
vty_out(vty, " Mcast group: %pI4\n", &vpn->mcast_grp);
if (!vpn->advertise_gw_macip &&
@@ -991,7 +1001,9 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
json_object_string_add(json_vni, "inKernel", "True");
json_object_string_addf(json_vni, "originatorIp", "%pI4",
&bgp->originator_ip);
- json_object_string_addf(json_vni, "rd", "%pRD", &bgp->vrf_prd);
+ json_object_string_addf(json_vni, "rd",
+ BGP_RD_AS_FORMAT(bgp->asnotation),
+ &bgp->vrf_prd);
json_object_string_add(json_vni, "advertiseGatewayMacip",
"n/a");
json_object_string_add(json_vni, "advertiseSviMacIp", "n/a");
@@ -1007,7 +1019,8 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
json_vni, "rmac",
prefix_mac2str(&bgp->rmac, buf2, sizeof(buf2)));
} else {
- vty_out(vty, "%-1s %-10u %-4s %-21pRD", buf1, bgp->l3vni, "L3",
+ vty_out(vty, "%-1s %-10u %-4s ", buf1, bgp->l3vni, "L3");
+ vty_out(vty, BGP_RD_AS_FORMAT_SPACE(bgp->asnotation),
&bgp->vrf_prd);
}
@@ -1091,11 +1104,13 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[])
struct listnode *node, *nnode;
struct ecommunity *ecom;
struct bgp *bgp_evpn;
+ enum asnotation_mode asnotation;
vty = args[0];
json = args[1];
bgp_evpn = bgp_get_evpn();
+ asnotation = bgp_get_asnotation(bgp_evpn);
if (json) {
json_vni = json_object_new_object();
@@ -1112,7 +1127,9 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[])
json_object_string_add(json_vni, "type", "L2");
json_object_string_add(json_vni, "inKernel",
is_vni_live(vpn) ? "True" : "False");
- json_object_string_addf(json_vni, "rd", "%pRD", &vpn->prd);
+ json_object_string_addf(json_vni, "rd",
+ BGP_RD_AS_FORMAT(asnotation),
+ &vpn->prd);
json_object_string_addf(json_vni, "originatorIp", "%pI4",
&vpn->originator_ip);
json_object_string_addf(json_vni, "mcastGroup", "%pI4",
@@ -1142,8 +1159,8 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[])
json_object_string_add(json_vni, "advertiseSviMacIp",
"Disabled");
} else {
- vty_out(vty, "%-1s %-10u %-4s %-21pRD", buf1, vpn->vni, "L2",
- &vpn->prd);
+ vty_out(vty, "%-1s %-10u %-4s ", buf1, vpn->vni, "L2");
+ vty_out(vty, BGP_RD_AS_FORMAT_SPACE(asnotation), &vpn->prd);
}
for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
@@ -1332,9 +1349,9 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
json,
"defaultLocPrf",
bgp->default_local_pref);
- json_object_int_add(
- json, "localAS",
- bgp->as);
+ asn_asn2json(json, "localAS",
+ bgp->as,
+ bgp->asnotation);
} else {
if (option == SHOW_DISPLAY_TAGS)
vty_out(vty,
@@ -2203,7 +2220,8 @@ static void evpn_unconfigure_export_rt(struct bgp *bgp, struct bgpevpn *vpn,
/*
* Configure RD for VRF
*/
-static void evpn_configure_vrf_rd(struct bgp *bgp_vrf, struct prefix_rd *rd)
+static void evpn_configure_vrf_rd(struct bgp *bgp_vrf, struct prefix_rd *rd,
+ const char *rd_pretty)
{
/* If we have already advertise type-5 routes with a diffrent RD, we
* have to delete and withdraw them firs
@@ -2212,6 +2230,7 @@ static void evpn_configure_vrf_rd(struct bgp *bgp_vrf, struct prefix_rd *rd)
/* update RD */
memcpy(&bgp_vrf->vrf_prd, rd, sizeof(struct prefix_rd));
+ bgp_vrf->vrf_prd_pretty = XSTRDUP(MTYPE_BGP, rd_pretty);
SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD);
/* We have a new RD for VRF.
@@ -2233,7 +2252,8 @@ static void evpn_unconfigure_vrf_rd(struct bgp *bgp_vrf)
/* fall back to default RD */
bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf);
UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD);
-
+ if (bgp_vrf->vrf_prd_pretty)
+ XFREE(MTYPE_BGP, bgp_vrf->vrf_prd_pretty);
/* We have a new RD for VRF.
* Advertise all type-5 routes again with the new RD
*/
@@ -2244,7 +2264,7 @@ static void evpn_unconfigure_vrf_rd(struct bgp *bgp_vrf)
* Configure RD for a VNI (vty handler)
*/
static void evpn_configure_rd(struct bgp *bgp, struct bgpevpn *vpn,
- struct prefix_rd *rd)
+ struct prefix_rd *rd, const char *rd_pretty)
{
/* If the VNI is "live", we need to delete and withdraw this VNI's
* local routes with the prior RD first. Then, after updating RD,
@@ -2255,6 +2275,7 @@ static void evpn_configure_rd(struct bgp *bgp, struct bgpevpn *vpn,
/* update RD */
memcpy(&vpn->prd, rd, sizeof(struct prefix_rd));
+ vpn->prd_pretty = XSTRDUP(MTYPE_BGP, rd_pretty);
SET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
if (is_vni_live(vpn))
@@ -2778,7 +2799,8 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
if (json) {
json_rd = json_object_new_object();
- json_object_string_addf(json_rd, "rd", "%pRD", prd);
+ json_object_string_addf(json_rd, "rd",
+ BGP_RD_AS_FORMAT(bgp->asnotation), prd);
}
bgp_dest_unlock_node(rd_dest);
@@ -2861,7 +2883,9 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
if (json) {
if (add_rd_to_json)
- json_object_object_addf(json, json_rd, "%pRD", prd);
+ json_object_object_addf(
+ json, json_rd,
+ BGP_RD_AS_FORMAT(bgp->asnotation), prd);
else {
json_object_free(json_rd);
json_rd = NULL;
@@ -2916,7 +2940,7 @@ static void evpn_show_route_rd_all_macip(struct vty *vty, struct bgp *bgp,
continue;
prefix_rd2str((struct prefix_rd *)rd_destp, rd_str,
- sizeof(rd_str));
+ sizeof(rd_str), bgp->asnotation);
/* Construct an RT-2 from the user-supplied mac(ip),
* then search the l2vpn evpn table for it.
@@ -3043,7 +3067,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
tbl_ver = table->version;
prefix_rd2str((struct prefix_rd *)rd_destp, rd_str,
- sizeof(rd_str));
+ sizeof(rd_str), bgp->asnotation);
if (json)
json_rd = json_object_new_object();
@@ -3460,7 +3484,7 @@ static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
if (is_vni_configured(vpn)) {
vty_out(vty, " vni %u\n", vpn->vni);
if (is_rd_configured(vpn))
- vty_out(vty, " rd %pRD\n", &vpn->prd);
+ vty_out(vty, " rd %s\n", vpn->prd_pretty);
if (is_import_rt_configured(vpn)) {
for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode,
@@ -6111,7 +6135,7 @@ DEFUN (bgp_evpn_vrf_rd,
return CMD_SUCCESS;
/* Configure or update the RD. */
- evpn_configure_vrf_rd(bgp_vrf, &prd);
+ evpn_configure_vrf_rd(bgp_vrf, &prd, argv[1]->arg);
return CMD_SUCCESS;
}
@@ -6203,7 +6227,7 @@ DEFUN (bgp_evpn_vni_rd,
return CMD_SUCCESS;
/* Configure or update the RD. */
- evpn_configure_rd(bgp, vpn, &prd);
+ evpn_configure_rd(bgp, vpn, &prd, argv[1]->arg);
return CMD_SUCCESS;
}
@@ -6388,7 +6412,9 @@ DEFUN (show_bgp_vrf_l3vni_info,
for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, l3rt))
vty_out(vty, "%s ", ecommunity_str(l3rt->ecom));
vty_out(vty, "\n");
- vty_out(vty, " RD: %pRD\n", &bgp->vrf_prd);
+ vty_out(vty, " RD: ");
+ vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation), &bgp->vrf_prd);
+ vty_out(vty, "\n");
} else {
json_object_string_add(json, "vrf", name);
json_object_string_addf(json, "local-ip", "%pI4",
@@ -6424,7 +6450,9 @@ DEFUN (show_bgp_vrf_l3vni_info,
json_object_new_string(
ecommunity_str(l3rt->ecom)));
json_object_object_add(json, "import-rts", json_import_rts);
- json_object_string_addf(json, "rd", "%pRD", &bgp->vrf_prd);
+ json_object_string_addf(json, "rd",
+ BGP_RD_AS_FORMAT(bgp->asnotation),
+ &bgp->vrf_prd);
}
if (uj)
@@ -7251,7 +7279,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
}
}
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))
- vty_out(vty, " rd %pRD\n", &bgp->vrf_prd);
+ vty_out(vty, " rd %s\n", bgp->vrf_prd_pretty);
/* import route-target */
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) {
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index bd8ce5477..ab0217018 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1853,7 +1853,7 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
int origin_local = 0;
struct bgp *src_vrf;
struct interface *ifp;
-
+ char rd_buf[RD_ADDRSTRLEN];
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
if (!vpn_leak_from_vpn_active(to_bgp, afi, &debugmsg)) {
@@ -1892,6 +1892,10 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
return false;
}
+ rd_buf[0] = '\0';
+ if (debug && prd)
+ prefix_rd2str(prd, rd_buf, sizeof(rd_buf), to_bgp->asnotation);
+
/* A route MUST NOT ever be accepted back into its source VRF, even if
* it carries one or more RTs that match that VRF.
*/
@@ -1900,15 +1904,14 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
ECOMMUNITY_SIZE) == 0) {
if (debug)
zlog_debug(
- "%s: skipping import, match RD (%pRD) of src VRF (%s) and the prefix (%pFX)",
- __func__, prd, to_bgp->name_pretty, p);
-
+ "%s: skipping import, match RD (%s) of src VRF (%s) and the prefix (%pFX)",
+ __func__, rd_buf, to_bgp->name_pretty, p);
return false;
}
if (debug)
- zlog_debug("%s: updating RD %pRD, %pFX to %s", __func__, prd, p,
- to_bgp->name_pretty);
+ zlog_debug("%s: updating RD %s, %pFX to %s", __func__, rd_buf,
+ p, to_bgp->name_pretty);
/* shallow copy */
static_attr = *path_vpn->attr;
@@ -2403,7 +2406,7 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
&bgp->vrf_prd_auto);
bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
- sizeof(buf));
+ sizeof(buf), bgp->asnotation);
/* free up pre-existing memory if any and allocate
* the ecommunity attribute with new RD/RT
@@ -2538,8 +2541,8 @@ void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
SET_FLAG(from_bgp->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_RD_SET);
- prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd,
- buf, sizeof(buf));
+ prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd, buf,
+ sizeof(buf), from_bgp->asnotation);
from_bgp->vpn_policy[afi].rtlist[edir] =
ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
SET_FLAG(from_bgp->af_flags[afi][safi],
diff --git a/bgpd/bgp_mplsvpn_snmp.c b/bgpd/bgp_mplsvpn_snmp.c
index 95a7bb811..9b2ab6680 100644
--- a/bgpd/bgp_mplsvpn_snmp.c
+++ b/bgpd/bgp_mplsvpn_snmp.c
@@ -942,11 +942,13 @@ static uint8_t *mplsL3vpnVrfTable(struct variable *v, oid name[],
if (CHECK_FLAG(l3vpn_bgp->vpn_policy[AFI_IP].flags,
BGP_VPN_POLICY_TOVPN_RD_SET))
prefix_rd2str(&l3vpn_bgp->vpn_policy[AFI_IP].tovpn_rd,
- rd_buf, sizeof(rd_buf));
+ rd_buf, sizeof(rd_buf),
+ bgp_get_asnotation(l3vpn_bgp));
else if (CHECK_FLAG(l3vpn_bgp->vpn_policy[AFI_IP6].flags,
BGP_VPN_POLICY_TOVPN_RD_SET))
prefix_rd2str(&l3vpn_bgp->vpn_policy[AFI_IP6].tovpn_rd,
- rd_buf, sizeof(rd_buf));
+ rd_buf, sizeof(rd_buf),
+ bgp_get_asnotation(l3vpn_bgp));
*var_len = strnlen(rd_buf, RD_ADDRSTRLEN);
return (uint8_t *)rd_buf;
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index da89c594c..df67e2a72 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -538,7 +538,7 @@ static void bgp_accept(struct thread *thread)
peer1->host);
peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
- peer1->as, peer1->as_type, NULL, false);
+ peer1->as, peer1->as_type, NULL, false, NULL);
peer_xfer_config(peer, peer1);
bgp_peer_gr_flags_update(peer);
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index a3014c0c6..00a0bc840 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -802,6 +802,7 @@ static void bgp_show_nexthop_paths(struct vty *vty, struct bgp *bgp,
safi = table->safi;
bgp_path = table->bgp;
+
if (json) {
json_path = json_object_new_object();
json_object_string_add(json_path, "afi", afi2str(afi));
@@ -811,7 +812,8 @@ static void bgp_show_nexthop_paths(struct vty *vty, struct bgp *bgp,
dest);
if (dest->pdest)
json_object_string_addf(
- json_path, "rd", "%pRD",
+ json_path, "rd",
+ BGP_RD_AS_FORMAT(bgp->asnotation),
(struct prefix_rd *)bgp_dest_get_prefix(
dest->pdest));
json_object_string_add(
@@ -821,13 +823,14 @@ static void bgp_show_nexthop_paths(struct vty *vty, struct bgp *bgp,
json_object_array_add(paths, json_path);
continue;
}
- if (dest->pdest)
- vty_out(vty, " %d/%d %pBD RD %pRD %s flags 0x%x\n",
- afi, safi, dest,
+ if (dest->pdest) {
+ vty_out(vty, " %d/%d %pBD RD ", afi, safi, dest);
+ vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
(struct prefix_rd *)bgp_dest_get_prefix(
- dest->pdest),
- bgp_path->name_pretty, path->flags);
- else
+ dest->pdest));
+ vty_out(vty, " %s flags 0x%x\n", bgp_path->name_pretty,
+ path->flags);
+ } else
vty_out(vty, " %d/%d %pBD %s flags 0x%x\n",
afi, safi, dest, bgp_path->name_pretty, path->flags);
}
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 4f42766b9..25b458a8e 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -1190,14 +1190,20 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
}
if (BGP_DEBUG(nht, NHT)) {
- if (dest->pdest)
- zlog_debug(
- "... eval path %d/%d %pBD RD %pRD %s flags 0x%x",
- afi, safi, dest,
+
+ if (dest->pdest) {
+ char rd_buf[RD_ADDRSTRLEN];
+
+ prefix_rd2str(
(struct prefix_rd *)bgp_dest_get_prefix(
dest->pdest),
+ rd_buf, sizeof(rd_buf),
+ bgp_get_asnotation(bnc->bgp));
+ zlog_debug(
+ "... eval path %d/%d %pBD RD %s %s flags 0x%x",
+ afi, safi, dest, rd_buf,
bgp_path->name_pretty, path->flags);
- else
+ } else
zlog_debug(
"... eval path %d/%d %pBD %s flags 0x%x",
afi, safi, dest, bgp_path->name_pretty,
diff --git a/bgpd/bgp_rd.c b/bgpd/bgp_rd.c
index 6e73ab8d1..bb9f76b8a 100644
--- a/bgpd/bgp_rd.c
+++ b/bgpd/bgp_rd.c
@@ -83,12 +83,12 @@ void decode_rd_vnc_eth(const uint8_t *pnt, struct rd_vnc_eth *rd_vnc_eth)
int str2prefix_rd(const char *str, struct prefix_rd *prd)
{
- int ret = 0;
- char *p;
- char *p2;
+ int ret = 0, type = RD_TYPE_UNDEFINED;
+ char *p, *p2;
struct stream *s = NULL;
char *half = NULL;
struct in_addr addr;
+ as_t as_val;
prd->family = AF_UNSPEC;
prd->prefixlen = 64;
@@ -97,41 +97,55 @@ int str2prefix_rd(const char *str, struct prefix_rd *prd)
if (!p)
goto out;
+ /* a second ':' is accepted */
+ p2 = strchr(p + 1, ':');
+ if (p2) {
+ /* type is in first part */
+ half = XMALLOC(MTYPE_TMP, (p - str) + 1);
+ memcpy(half, str, (p - str));
+ half[p - str] = '\0';
+ type = atoi(half);
+ if (type != RD_TYPE_AS && type != RD_TYPE_IP &&
+ type != RD_TYPE_AS4)
+ goto out;
+ XFREE(MTYPE_TMP, half);
+ half = XMALLOC(MTYPE_TMP, (p2 - p));
+ memcpy(half, p + 1, (p2 - p - 1));
+ half[p2 - p - 1] = '\0';
+ p = p2 + 1;
+ } else {
+ half = XMALLOC(MTYPE_TMP, (p - str) + 1);
+ memcpy(half, str, (p - str));
+ half[p - str] = '\0';
+ }
if (!all_digit(p + 1))
goto out;
s = stream_new(RD_BYTES);
- half = XMALLOC(MTYPE_TMP, (p - str) + 1);
- memcpy(half, str, (p - str));
- half[p - str] = '\0';
-
- p2 = strchr(str, '.');
-
- if (!p2) {
- unsigned long as_val;
-
- if (!all_digit(half))
- goto out;
-
- as_val = atol(half);
- if (as_val > 0xffff) {
+ /* if it is an AS format or an IP */
+ if (asn_str2asn(half, &as_val)) {
+ if (as_val > UINT16_MAX) {
stream_putw(s, RD_TYPE_AS4);
stream_putl(s, as_val);
stream_putw(s, atol(p + 1));
+ if (type != RD_TYPE_UNDEFINED && type != RD_TYPE_AS4)
+ goto out;
} else {
stream_putw(s, RD_TYPE_AS);
stream_putw(s, as_val);
stream_putl(s, atol(p + 1));
+ if (type != RD_TYPE_UNDEFINED && type != RD_TYPE_AS)
+ goto out;
}
- } else {
- if (!inet_aton(half, &addr))
- goto out;
-
+ } else if (inet_aton(half, &addr)) {
stream_putw(s, RD_TYPE_IP);
stream_put_in_addr(s, &addr);
stream_putw(s, atol(p + 1));
- }
+ if (type != RD_TYPE_UNDEFINED && type != RD_TYPE_IP)
+ goto out;
+ } else
+ goto out;
memcpy(prd->val, s->data, 8);
ret = 1;
@@ -142,12 +156,14 @@ out:
return ret;
}
-char *prefix_rd2str(const struct prefix_rd *prd, char *buf, size_t size)
+char *prefix_rd2str(const struct prefix_rd *prd, char *buf, size_t size,
+ enum asnotation_mode asnotation)
{
const uint8_t *pnt;
uint16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip;
+ int len = 0;
assert(size >= RD_ADDRSTRLEN);
@@ -157,11 +173,15 @@ char *prefix_rd2str(const struct prefix_rd *prd, char *buf, size_t size)
if (type == RD_TYPE_AS) {
decode_rd_as(pnt + 2, &rd_as);
- snprintf(buf, size, "%u:%u", rd_as.as, rd_as.val);
+ len += snprintfrr(buf + len, size - len, ASN_FORMAT(asnotation),
+ &rd_as.as);
+ snprintfrr(buf + len, size - len, ":%u", rd_as.val);
return buf;
} else if (type == RD_TYPE_AS4) {
decode_rd_as4(pnt + 2, &rd_as);
- snprintf(buf, size, "%u:%u", rd_as.as, rd_as.val);
+ len += snprintfrr(buf + len, size - len, ASN_FORMAT(asnotation),
+ &rd_as.as);
+ snprintfrr(buf + len, size - len, ":%u", rd_as.val);
return buf;
} else if (type == RD_TYPE_IP) {
decode_rd_ip(pnt + 2, &rd_ip);
@@ -196,16 +216,38 @@ void form_auto_rd(struct in_addr router_id,
(void)str2prefix_rd(buf, prd);
}
-printfrr_ext_autoreg_p("RD", printfrr_prd);
-static ssize_t printfrr_prd(struct fbuf *buf, struct printfrr_eargs *ea,
- const void *ptr)
+static ssize_t printfrr_prd_asnotation(struct fbuf *buf,
+ struct printfrr_eargs *ea,
+ const void *ptr,
+ enum asnotation_mode asnotation)
{
char rd_buf[RD_ADDRSTRLEN];
if (!ptr)
return bputs(buf, "(null)");
- prefix_rd2str(ptr, rd_buf, sizeof(rd_buf));
+ prefix_rd2str(ptr, rd_buf, sizeof(rd_buf), asnotation);
return bputs(buf, rd_buf);
}
+
+printfrr_ext_autoreg_p("RDP", printfrr_prd);
+static ssize_t printfrr_prd(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *ptr)
+{
+ return printfrr_prd_asnotation(buf, ea, ptr, ASNOTATION_PLAIN);
+}
+
+printfrr_ext_autoreg_p("RDD", printfrr_prd_dot);
+static ssize_t printfrr_prd_dot(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *ptr)
+{
+ return printfrr_prd_asnotation(buf, ea, ptr, ASNOTATION_DOT);
+}
+
+printfrr_ext_autoreg_p("RDE", printfrr_prd_dotplus);
+static ssize_t printfrr_prd_dotplus(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *ptr)
+{
+ return printfrr_prd_asnotation(buf, ea, ptr, ASNOTATION_DOTPLUS);
+}
diff --git a/bgpd/bgp_rd.h b/bgpd/bgp_rd.h
index 44173b7a2..e38c2fad3 100644
--- a/bgpd/bgp_rd.h
+++ b/bgpd/bgp_rd.h
@@ -7,7 +7,11 @@
#ifndef _QUAGGA_BGP_RD_H
#define _QUAGGA_BGP_RD_H
+#include "asn.h"
+#include "prefix.h"
+
/* RD types */
+#define RD_TYPE_UNDEFINED (-1)
#define RD_TYPE_AS 0
#define RD_TYPE_IP 1
#define RD_TYPE_AS4 2
@@ -19,6 +23,16 @@
#define RD_ADDRSTRLEN 28
#define RD_BYTES 8
+#define BGP_RD_AS_FORMAT(mode) \
+ ((mode == ASNOTATION_DOT) \
+ ? "%pRDD" \
+ : ((mode == ASNOTATION_DOTPLUS) ? "%pRDE" : "%pRDP"))
+
+#define BGP_RD_AS_FORMAT_SPACE(mode) \
+ ((mode == ASNOTATION_DOT) \
+ ? "%-21pRDD" \
+ : ((mode == ASNOTATION_DOTPLUS) ? "%-21pRDE" : "%-21pRDP"))
+
struct rd_as {
uint16_t type;
as_t as;
@@ -51,7 +65,8 @@ extern void decode_rd_vnc_eth(const uint8_t *pnt,
#endif
extern int str2prefix_rd(const char *, struct prefix_rd *);
-extern char *prefix_rd2str(const struct prefix_rd *, char *, size_t);
+extern char *prefix_rd2str(const struct prefix_rd *prd, char *buf, size_t size,
+ enum asnotation_mode asnotation);
extern void form_auto_rd(struct in_addr router_id, uint16_t rd_id,
struct prefix_rd *prd);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 0d93abc12..977dca13d 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -6078,6 +6078,8 @@ static void bgp_static_free(struct bgp_static *bgp_static)
XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
route_map_counter_decrement(bgp_static->rmap.map);
+ if (bgp_static->prd_pretty)
+ XFREE(MTYPE_BGP, bgp_static->prd_pretty);
XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
XFREE(MTYPE_BGP_STATIC, bgp_static);
}
@@ -6981,6 +6983,8 @@ int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
bgp_static->label = label;
bgp_static->prd = prd;
+ if (rd_str)
+ bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
if (rmap_str) {
XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
route_map_counter_decrement(bgp_static->rmap.map);
@@ -7243,7 +7247,7 @@ static bool aggr_suppress_map_test(struct bgp *bgp,
return false;
/* Call route map matching and return result. */
- attr.aspath = aspath_empty();
+ attr.aspath = aspath_empty(bgp->asnotation);
rmap_path.peer = bgp->peer_self;
rmap_path.attr = &attr;
@@ -7337,9 +7341,12 @@ static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
struct lcommunity *lcomm)
{
static struct aspath *ae = NULL;
+ enum asnotation_mode asnotation;
+
+ asnotation = bgp_get_asnotation(NULL);
if (!ae)
- ae = aspath_empty();
+ ae = aspath_empty(asnotation);
if (!pi)
return false;
@@ -10254,10 +10261,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
if (dest && dest->pdest) {
pdest = dest->pdest;
if (is_pi_family_evpn(parent_ri)) {
- vty_out(vty,
- " Imported from %pRD:%pFX, VNI %s",
+ vty_out(vty, " Imported from ");
+ vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
(struct prefix_rd *)bgp_dest_get_prefix(
- pdest),
+ pdest));
+ vty_out(vty, ":%pFX, VNI %s",
(struct prefix_evpn *)
bgp_dest_get_prefix(dest),
tag_buf);
@@ -10270,12 +10278,15 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
: "inactive");
vty_out(vty, "\n");
- } else
- vty_out(vty, " Imported from %pRD:%pFX\n",
+ } else {
+ vty_out(vty, " Imported from ");
+ vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
(struct prefix_rd *)bgp_dest_get_prefix(
- pdest),
+ pdest));
+ vty_out(vty, ":%pFX\n",
(struct prefix_evpn *)
bgp_dest_get_prefix(dest));
+ }
}
}
@@ -11184,17 +11195,26 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
vty_out(vty, "{\n");
*json_header_depth = 2;
}
-
vty_out(vty,
" \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
- " \"localAS\": %u,\n \"routes\": { ",
+ " \"localAS\": ",
bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
? VRF_DEFAULT_NAME
: bgp->name,
table->version, &bgp->router_id,
- bgp->default_local_pref, bgp->as);
+ bgp->default_local_pref);
+ if ((bgp->asnotation == ASNOTATION_PLAIN) ||
+ ((bgp->asnotation == ASNOTATION_DOT) &&
+ (bgp->as < UINT16_MAX)))
+ vty_out(vty, "%u", bgp->as);
+ else {
+ vty_out(vty, "\"");
+ vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
+ vty_out(vty, "\"");
+ }
+ vty_out(vty, ",\n \"routes\": { ");
if (rd) {
vty_out(vty, " \"routeDistinguishers\" : {");
++*json_header_depth;
@@ -11468,7 +11488,10 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
vty_out(vty, "\n");
vty_out(vty, "Default local pref %u, ",
bgp->default_local_pref);
- vty_out(vty, "local AS %u\n", bgp->as);
+ vty_out(vty, "local AS ");
+ vty_out(vty, ASN_FORMAT(bgp->asnotation),
+ &bgp->as);
+ vty_out(vty, "\n");
if (!detail_routes) {
vty_out(vty, BGP_SHOW_SCODE_HEADER);
vty_out(vty, BGP_SHOW_NCODE_HEADER);
@@ -11665,7 +11688,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
char rd[RD_ADDRSTRLEN];
memcpy(&prd, dest_p, sizeof(struct prefix_rd));
- prefix_rd2str(&prd, rd, sizeof(rd));
+ prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
bgp_show_table(vty, bgp, safi, itable, type, output_arg,
rd, next == NULL, &output_cum,
&total_cum, &json_header_depth,
@@ -11816,13 +11839,16 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
if (safi == SAFI_EVPN) {
if (!json) {
vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
- prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
+ prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
+ bgp->asnotation)
: "",
prd ? ":" : "", (struct prefix_evpn *)p);
} else {
- json_object_string_add(json, "rd",
- prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
- "");
+ json_object_string_add(
+ json, "rd",
+ prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
+ bgp->asnotation)
+ : "");
bgp_evpn_route2json((struct prefix_evpn *)p, json);
}
} else {
@@ -11832,7 +11858,8 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
"\n",
((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
? prefix_rd2str(prd, buf1,
- sizeof(buf1))
+ sizeof(buf1),
+ bgp->asnotation)
: ""),
safi == SAFI_MPLS_VPN ? ":" : "", p,
dest->version);
@@ -12055,8 +12082,9 @@ static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
json_object_object_add(json_header, "paths", json_paths);
if (pfx_rd)
- json_object_object_addf(json, json_header, "%pRD",
- pfx_rd);
+ json_object_object_addf(
+ json, json_header,
+ BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
}
}
@@ -14465,7 +14493,8 @@ CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
prd = (const struct prefix_rd *)bgp_dest_get_prefix(
dest);
- prefix_rd2str(prd, rd_str, sizeof(rd_str));
+ prefix_rd2str(prd, rd_str, sizeof(rd_str),
+ bgp->asnotation);
show_adj_route(
vty, peer, table, afi, safi, type, rmap_name,
@@ -15594,7 +15623,6 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
struct bgp_dest *dest;
struct bgp_table *table;
const struct prefix *p;
- const struct prefix_rd *prd;
struct bgp_static *bgp_static;
mpls_label_t label;
@@ -15612,13 +15640,12 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
continue;
p = bgp_dest_get_prefix(dest);
- prd = (const struct prefix_rd *)bgp_dest_get_prefix(
- pdest);
/* "network" configuration display. */
label = decode_label(&bgp_static->label);
- vty_out(vty, " network %pFX rd %pRD", p, prd);
+ vty_out(vty, " network %pFX rd %s", p,
+ bgp_static->prd_pretty);
if (safi == SAFI_MPLS_VPN)
vty_out(vty, " label %u", label);
@@ -15641,7 +15668,6 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
struct bgp_dest *dest;
struct bgp_table *table;
const struct prefix *p;
- const struct prefix_rd *prd;
struct bgp_static *bgp_static;
char buf[PREFIX_STRLEN * 2];
char buf2[SU_ADDRSTRLEN];
@@ -15669,7 +15695,6 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
esi_to_str(bgp_static->eth_s_id,
esi_buf, sizeof(esi_buf));
p = bgp_dest_get_prefix(dest);
- prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
/* "network" configuration display. */
if (p->u.prefix_evpn.route_type == 5) {
@@ -15696,8 +15721,9 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
&bgp_static->gatewayIp.u.prefix, buf2,
sizeof(buf2));
vty_out(vty,
- " network %s rd %pRD ethtag %u label %u esi %s gwip %s routermac %s\n",
- buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
+ " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
+ buf, bgp_static->prd_pretty,
+ p->u.prefix_evpn.prefix_addr.eth_tag,
decode_label(&bgp_static->label), esi_buf, buf2,
macrouter);
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index d449152c2..bd4191bfd 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -355,6 +355,7 @@ struct bgp_static {
/* Route Distinguisher */
struct prefix_rd prd;
+ char *prd_pretty;
/* MPLS label. */
mpls_label_t label;
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index dbffecee3..4b6f290c7 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -213,7 +213,7 @@ static void *route_aspath_compile(const char *arg)
{
struct aspath *aspath;
- aspath = aspath_str2aspath(arg);
+ aspath = aspath_str2aspath(arg, bgp_get_asnotation(NULL));
if (!aspath)
return NULL;
return aspath;
@@ -5663,15 +5663,16 @@ DEFUN_YANG (no_set_label_index,
DEFUN_YANG (set_aspath_prepend_asn,
set_aspath_prepend_asn_cmd,
- "set as-path prepend (1-4294967295)...",
+ "set as-path prepend ASNUM...",
SET_STR
"Transform BGP AS_PATH attribute\n"
"Prepend to the as-path\n"
- "AS number\n")
+ AS_STR)
{
int idx_asn = 3;
int ret;
char *str;
+ struct aspath *aspath;
str = argv_concat(argv, argc, idx_asn);
@@ -5679,6 +5680,12 @@ DEFUN_YANG (set_aspath_prepend_asn,
"./set-action[action='frr-bgp-route-map:as-path-prepend']";
char xpath_value[XPATH_MAXLEN];
+ aspath = route_aspath_compile(str);
+ if (!aspath) {
+ vty_out(vty, "%% Invalid AS path value %s\n", str);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ route_aspath_free(aspath);
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
snprintf(xpath_value, sizeof(xpath_value),
"%s/rmap-set-action/frr-bgp-route-map:prepend-as-path", xpath);
@@ -5713,16 +5720,22 @@ DEFUN_YANG (set_aspath_prepend_lastas,
DEFPY_YANG (set_aspath_replace_asn,
set_aspath_replace_asn_cmd,
- "set as-path replace <any|(1-4294967295)>$replace",
+ "set as-path replace <any|ASNUM>$replace",
SET_STR
"Transform BGP AS_PATH attribute\n"
"Replace AS number to local AS number\n"
"Replace any AS number to local AS number\n"
- "Replace a specific AS number to local AS number\n")
+ "Replace a specific AS number in plain or dotted format to local AS number\n")
{
const char *xpath =
"./set-action[action='frr-bgp-route-map:as-path-replace']";
char xpath_value[XPATH_MAXLEN];
+ as_t as_value;
+
+ if (!strmatch(replace, "any") && !asn_str2asn(replace, &as_value)) {
+ vty_out(vty, "%% Invalid AS value %s\n", replace);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
snprintf(xpath_value, sizeof(xpath_value),
@@ -5733,13 +5746,13 @@ DEFPY_YANG (set_aspath_replace_asn,
DEFPY_YANG (no_set_aspath_replace_asn,
no_set_aspath_replace_asn_cmd,
- "no set as-path replace [<any|(1-4294967295)>]",
+ "no set as-path replace [<any|ASNUM>]",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
"Replace AS number to local AS number\n"
"Replace any AS number to local AS number\n"
- "Replace a specific AS number to local AS number\n")
+ "Replace a specific AS number in plain or dotted format to local AS number\n")
{
const char *xpath =
"./set-action[action='frr-bgp-route-map:as-path-replace']";
@@ -5750,12 +5763,12 @@ DEFPY_YANG (no_set_aspath_replace_asn,
DEFUN_YANG (no_set_aspath_prepend,
no_set_aspath_prepend_cmd,
- "no set as-path prepend [(1-4294967295)]",
+ "no set as-path prepend [ASNUM]",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
"Prepend to the as-path\n"
- "AS number\n")
+ AS_STR)
{
const char *xpath =
"./set-action[action='frr-bgp-route-map:as-path-prepend']";
@@ -5783,15 +5796,16 @@ DEFUN_YANG (no_set_aspath_prepend_lastas,
DEFUN_YANG (set_aspath_exclude,
set_aspath_exclude_cmd,
- "set as-path exclude (1-4294967295)...",
+ "set as-path exclude ASNUM...",
SET_STR
"Transform BGP AS-path attribute\n"
"Exclude from the as-path\n"
- "AS number\n")
+ AS_STR)
{
int idx_asn = 3;
int ret;
char *str;
+ struct aspath *aspath;
str = argv_concat(argv, argc, idx_asn);
@@ -5799,6 +5813,12 @@ DEFUN_YANG (set_aspath_exclude,
"./set-action[action='frr-bgp-route-map:as-path-exclude']";
char xpath_value[XPATH_MAXLEN];
+ aspath = route_aspath_compile(str);
+ if (!aspath) {
+ vty_out(vty, "%% Invalid AS path value %s\n", str);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ route_aspath_free(aspath);
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
snprintf(xpath_value, sizeof(xpath_value),
"%s/rmap-set-action/frr-bgp-route-map:exclude-as-path", xpath);
@@ -5810,7 +5830,7 @@ DEFUN_YANG (set_aspath_exclude,
DEFUN_YANG (no_set_aspath_exclude,
no_set_aspath_exclude_cmd,
- "no set as-path exclude (1-4294967295)...",
+ "no set as-path exclude ASNUM...",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
@@ -6496,11 +6516,11 @@ DEFPY_YANG (no_set_aigp_metric,
DEFUN_YANG (set_aggregator_as,
set_aggregator_as_cmd,
- "set aggregator as (1-4294967295) A.B.C.D",
+ "set aggregator as ASNUM A.B.C.D",
SET_STR
"BGP aggregator attribute\n"
"AS number of aggregator\n"
- "AS number\n"
+ AS_STR
"IP address of aggregator\n")
{
int idx_number = 3;
@@ -6509,6 +6529,12 @@ DEFUN_YANG (set_aggregator_as,
char xpath_addr[XPATH_MAXLEN];
const char *xpath =
"./set-action[action='frr-bgp-route-map:aggregator']";
+ as_t as_value;
+
+ if (!asn_str2asn(argv[idx_number]->arg, &as_value)) {
+ vty_out(vty, "%% Invalid AS value %s\n", argv[idx_number]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
@@ -6531,12 +6557,12 @@ DEFUN_YANG (set_aggregator_as,
DEFUN_YANG (no_set_aggregator_as,
no_set_aggregator_as_cmd,
- "no set aggregator as [(1-4294967295) A.B.C.D]",
+ "no set aggregator as [ASNUM A.B.C.D]",
NO_STR
SET_STR
"BGP aggregator attribute\n"
"AS number of aggregator\n"
- "AS number\n"
+ AS_STR
"IP address of aggregator\n")
{
const char *xpath =
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c
index 61b8b4edc..d7e1a6341 100644
--- a/bgpd/bgp_rpki.c
+++ b/bgpd/bgp_rpki.c
@@ -81,6 +81,7 @@ struct rpki_for_each_record_arg {
unsigned int *prefix_amount;
as_t as;
json_object *json;
+ enum asnotation_mode asnotation;
};
static int start(void);
@@ -105,7 +106,7 @@ static void rpki_delete_all_cache_nodes(void);
static int add_tcp_cache(const char *host, const char *port,
const uint8_t preference, const char *bindaddr);
static void print_record(const struct pfx_record *record, struct vty *vty,
- json_object *json);
+ json_object *json, enum asnotation_mode asnotation);
static bool is_synchronized(void);
static bool is_running(void);
static bool is_stopping(void);
@@ -270,7 +271,7 @@ static void rpki_delete_all_cache_nodes(void)
}
static void print_record(const struct pfx_record *record, struct vty *vty,
- json_object *json)
+ json_object *json, enum asnotation_mode asnotation)
{
char ip[INET6_ADDRSTRLEN];
json_object *json_record = NULL;
@@ -278,8 +279,10 @@ static void print_record(const struct pfx_record *record, struct vty *vty,
lrtr_ip_addr_to_str(&record->prefix, ip, sizeof(ip));
if (!json) {
- vty_out(vty, "%-40s %3u - %3u %10u\n", ip, record->min_len,
- record->max_len, record->asn);
+ vty_out(vty, "%-40s %3u - %3u ", ip, record->min_len,
+ record->max_len);
+ vty_out(vty, ASN_FORMAT(asnotation), &record->asn);
+ vty_out(vty, "\n");
} else {
json_record = json_object_new_object();
json_object_string_add(json_record, "prefix", ip);
@@ -287,7 +290,7 @@ static void print_record(const struct pfx_record *record, struct vty *vty,
record->min_len);
json_object_int_add(json_record, "prefixLenMax",
record->max_len);
- json_object_int_add(json_record, "asn", record->asn);
+ asn_asn2json(json_record, "asn", record->asn, asnotation);
json_object_array_add(json, json_record);
}
}
@@ -299,7 +302,7 @@ static void print_record_by_asn(const struct pfx_record *record, void *data)
if (record->asn == arg->as) {
(*arg->prefix_amount)++;
- print_record(record, vty, arg->json);
+ print_record(record, vty, arg->json, arg->asnotation);
}
}
@@ -310,7 +313,7 @@ static void print_record_cb(const struct pfx_record *record, void *data)
(*arg->prefix_amount)++;
- print_record(record, vty, arg->json);
+ print_record(record, vty, arg->json, arg->asnotation);
}
static struct rtr_mgr_group *get_groups(void)
@@ -728,6 +731,7 @@ static void print_prefix_table_by_asn(struct vty *vty, as_t as,
arg.vty = vty;
arg.as = as;
arg.json = NULL;
+ arg.asnotation = bgp_get_asnotation(bgp_lookup_by_vrf_id(VRF_DEFAULT));
if (!group) {
if (!json)
@@ -780,6 +784,7 @@ static void print_prefix_table(struct vty *vty, json_object *json)
arg.vty = vty;
arg.json = NULL;
+ arg.asnotation = bgp_get_asnotation(bgp_lookup_by_vrf_id(VRF_DEFAULT));
if (!group) {
if (!json)
@@ -1337,7 +1342,7 @@ DEFPY (show_rpki_prefix_table,
DEFPY (show_rpki_as_number,
show_rpki_as_number_cmd,
- "show rpki as-number (1-4294967295)$by_asn [json$uj]",
+ "show rpki as-number ASNUM$by_asn [json$uj]",
SHOW_STR
RPKI_OUTPUT_STRING
"Lookup by ASN in prefix table\n"
@@ -1345,23 +1350,28 @@ DEFPY (show_rpki_as_number,
JSON_STR)
{
struct json_object *json = NULL;
+ as_t as;
if (!is_synchronized()) {
if (!uj)
vty_out(vty, "No Connection to RPKI cache server.\n");
return CMD_WARNING;
}
-
+ if (!asn_str2asn(by_asn, &as)) {
+ if (!uj)
+ vty_out(vty, "Invalid AS value: %s.\n", by_asn);
+ return CMD_WARNING;
+ }
if (uj)
json = json_object_new_object();
- print_prefix_table_by_asn(vty, by_asn, json);
+ print_prefix_table_by_asn(vty, as, json);
return CMD_SUCCESS;
}
DEFPY (show_rpki_prefix,
show_rpki_prefix_cmd,
- "show rpki prefix <A.B.C.D/M|X:X::X:X/M> [(1-4294967295)$asn] [json$uj]",
+ "show rpki prefix <A.B.C.D/M|X:X::X:X/M> [ASNUM$asn] [json$uj]",
SHOW_STR
RPKI_OUTPUT_STRING
"Lookup IP prefix and optionally ASN in prefix table\n"
@@ -1372,6 +1382,8 @@ DEFPY (show_rpki_prefix,
{
json_object *json = NULL;
json_object *json_records = NULL;
+ as_t as;
+ enum asnotation_mode asnotation;
if (!is_synchronized()) {
if (!uj)
@@ -1392,13 +1404,19 @@ DEFPY (show_rpki_prefix,
return CMD_WARNING;
}
+ if (asn && !asn_str2asn(asn, &as)) {
+ if (!uj)
+ vty_out(vty, "Invalid AS value: %s.\n", asn);
+ return CMD_WARNING;
+ }
+
struct pfx_record *matches = NULL;
unsigned int match_count = 0;
enum pfxv_state result;
if (pfx_table_validate_r(rtr_config->pfx_table, &matches, &match_count,
- asn, &addr, prefix->prefixlen, &result)
- != PFX_SUCCESS) {
+ as, &addr, prefix->prefixlen,
+ &result) != PFX_SUCCESS) {
if (!json)
vty_out(vty, "Prefix lookup failed\n");
return CMD_WARNING;
@@ -1415,13 +1433,14 @@ DEFPY (show_rpki_prefix,
json_object_object_add(json, "prefixes", json_records);
}
+ asnotation = bgp_get_asnotation(bgp_lookup_by_vrf_id(VRF_DEFAULT));
for (size_t i = 0; i < match_count; ++i) {
const struct pfx_record *record = &matches[i];
- if (record->max_len >= prefix->prefixlen
- && ((asn != 0 && (uint32_t)asn == record->asn)
- || asn == 0)) {
- print_record(&matches[i], vty, json_records);
+ if (record->max_len >= prefix->prefixlen &&
+ ((as != 0 && (uint32_t)as == record->asn) || as == 0)) {
+ print_record(&matches[i], vty, json_records,
+ asnotation);
}
}
diff --git a/bgpd/bgp_script.c b/bgpd/bgp_script.c
index 6cc75494e..f4ab23352 100644
--- a/bgpd/bgp_script.c
+++ b/bgpd/bgp_script.c
@@ -149,7 +149,8 @@ void lua_decode_attr(lua_State *L, int idx, struct attr *attr)
attr->nh_ifindex = lua_tointeger(L, -1);
lua_pop(L, 1);
lua_getfield(L, idx, "aspath");
- attr->aspath = aspath_str2aspath(lua_tostring(L, -1));
+ attr->aspath = aspath_str2aspath(lua_tostring(L, -1),
+ bgp_get_asnotation(NULL));
lua_pop(L, 1);
lua_getfield(L, idx, "localpref");
attr->local_pref = lua_tointeger(L, -1);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index b858d9c4b..8ef18a34d 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -24,6 +24,7 @@
#include "queue.h"
#include "filter.h"
#include "frrstr.h"
+#include "asn.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr_evpn.h"
@@ -579,9 +580,10 @@ static const char *get_bgp_default_af_flag(afi_t afi, safi_t safi)
}
int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
- enum bgp_instance_type inst_type)
+ enum bgp_instance_type inst_type, const char *as_pretty,
+ enum asnotation_mode asnotation)
{
- int ret = bgp_get(bgp, as, name, inst_type);
+ int ret = bgp_get(bgp, as, name, inst_type, as_pretty, asnotation);
if (ret == BGP_CREATED) {
bgp_timers_set(*bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME,
@@ -1222,7 +1224,12 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
/* Clear all neighbors belonging to a specific AS. */
if (sort == clear_as) {
- as_t as = strtoul(arg, NULL, 10);
+ as_t as;
+
+ if (!asn_str2asn(arg, &as)) {
+ vty_out(vty, "%% BGP: No such AS %s\n", arg);
+ return CMD_WARNING;
+ }
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (peer->as != as)
@@ -1460,16 +1467,23 @@ DEFUN (no_auto_summary,
/* "router bgp" commands. */
DEFUN_NOSH (router_bgp,
router_bgp_cmd,
- "router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]",
+ "router bgp [ASNUM$instasn [<view|vrf> VIEWVRFNAME] [as-notation <dot|dot+|plain>]]",
ROUTER_STR
BGP_STR
AS_STR
- BGP_INSTANCE_HELP_STR)
+ BGP_INSTANCE_HELP_STR
+ "Force the AS notation output\n"
+ "use 'AA.BB' format for AS 4 byte values\n"
+ "use 'AA.BB' format for all AS values\n"
+ "use plain format for all AS values\n")
{
int idx_asn = 2;
int idx_view_vrf = 3;
int idx_vrf = 4;
int is_new_bgp = 0;
+ int idx_asnotation = 3;
+ int idx_asnotation_kind = 4;
+ enum asnotation_mode asnotation = ASNOTATION_UNDEFINED;
int ret;
as_t as;
struct bgp *bgp;
@@ -1494,39 +1508,62 @@ DEFUN_NOSH (router_bgp,
// "router bgp X"
else {
- as = strtoul(argv[idx_asn]->arg, NULL, 10);
+ if (!asn_str2asn(argv[idx_asn]->arg, &as)) {
+ vty_out(vty, "%% BGP: No such AS %s\n",
+ argv[idx_asn]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
if (as == BGP_PRIVATE_AS_MAX || as == BGP_AS4_MAX)
vty_out(vty, "Reserved AS used (%u|%u); AS is %u\n",
BGP_PRIVATE_AS_MAX, BGP_AS4_MAX, as);
inst_type = BGP_INSTANCE_TYPE_DEFAULT;
- if (argc > 3) {
- name = argv[idx_vrf]->arg;
- if (!strcmp(argv[idx_view_vrf]->text, "vrf")) {
- if (strmatch(name, VRF_DEFAULT_NAME))
- name = NULL;
- else
- inst_type = BGP_INSTANCE_TYPE_VRF;
- } else if (!strcmp(argv[idx_view_vrf]->text, "view"))
- inst_type = BGP_INSTANCE_TYPE_VIEW;
+ if (argv_find(argv, argc, "VIEWVRFNAME", &idx_vrf)) {
+ idx_view_vrf = idx_vrf - 1;
+ if (argv[idx_view_vrf]->text) {
+ name = argv[idx_vrf]->arg;
+
+ if (!strcmp(argv[idx_view_vrf]->text, "vrf")) {
+ if (strmatch(name, VRF_DEFAULT_NAME))
+ name = NULL;
+ else
+ inst_type =
+ BGP_INSTANCE_TYPE_VRF;
+ } else if (!strcmp(argv[idx_view_vrf]->text,
+ "view"))
+ inst_type = BGP_INSTANCE_TYPE_VIEW;
+ }
+ }
+ if (argv_find(argv, argc, "as-notation", &idx_asnotation)) {
+ idx_asnotation_kind = idx_asnotation + 1;
+ if (strmatch(argv[idx_asnotation_kind]->text, "dot+"))
+ asnotation = ASNOTATION_DOTPLUS;
+ else if (strmatch(argv[idx_asnotation_kind]->text,
+ "dot"))
+ asnotation = ASNOTATION_DOT;
+ else if (strmatch(argv[idx_asnotation_kind]->text,
+ "plain"))
+ asnotation = ASNOTATION_PLAIN;
}
if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
is_new_bgp = (bgp_lookup(as, name) == NULL);
- ret = bgp_get_vty(&bgp, &as, name, inst_type);
+ ret = bgp_get_vty(&bgp, &as, name, inst_type,
+ argv[idx_asn]->arg, asnotation);
switch (ret) {
case BGP_ERR_AS_MISMATCH:
- vty_out(vty, "BGP is already running; AS is %u\n", as);
+ vty_out(vty, "BGP is already running; AS is %s\n",
+ bgp->as_pretty);
return CMD_WARNING_CONFIG_FAILED;
case BGP_ERR_INSTANCE_MISMATCH:
vty_out(vty,
"BGP instance name and AS number mismatch\n");
vty_out(vty,
- "BGP instance is already running; AS is %u\n",
- as);
+ "BGP instance is already running; AS is %s\n",
+ bgp->as_pretty);
return CMD_WARNING_CONFIG_FAILED;
}
@@ -1542,6 +1579,19 @@ DEFUN_NOSH (router_bgp,
bgp_vpn_leak_export(bgp);
/* Pending: handle when user tries to change a view to vrf n vv.
*/
+ /* for pre-existing bgp instance,
+ * - update as_pretty
+ * - update asnotation if explicitly mentioned
+ */
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) {
+ XFREE(MTYPE_BGP, bgp->as_pretty);
+ bgp->as_pretty = XSTRDUP(MTYPE_BGP, argv[idx_asn]->arg);
+ if (!CHECK_FLAG(bgp->config, BGP_CONFIG_ASNOTATION) &&
+ asnotation != ASNOTATION_UNDEFINED) {
+ SET_FLAG(bgp->config, BGP_CONFIG_ASNOTATION);
+ bgp->asnotation = asnotation;
+ }
+ }
}
/* unset the auto created flag as the user config is now present */
@@ -1554,12 +1604,16 @@ DEFUN_NOSH (router_bgp,
/* "no router bgp" commands. */
DEFUN (no_router_bgp,
no_router_bgp_cmd,
- "no router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]",
+ "no router bgp [ASNUM$instasn [<view|vrf> VIEWVRFNAME] [as-notation <dot|dot+|plain>]]",
NO_STR
ROUTER_STR
BGP_STR
AS_STR
- BGP_INSTANCE_HELP_STR)
+ BGP_INSTANCE_HELP_STR
+ "Force the AS notation output\n"
+ "use 'AA.BB' format for AS 4 byte values\n"
+ "use 'AA.BB' format for all AS values\n"
+ "use plain format for all AS values\n")
{
int idx_asn = 3;
int idx_vrf = 5;
@@ -1588,8 +1642,11 @@ DEFUN (no_router_bgp,
return CMD_WARNING_CONFIG_FAILED;
}
} else {
- as = strtoul(argv[idx_asn]->arg, NULL, 10);
-
+ if (!asn_str2asn(argv[idx_asn]->arg, &as)) {
+ vty_out(vty, "%% BGP: No such AS %s\n",
+ argv[idx_asn]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
if (argc > 4) {
name = argv[idx_vrf]->arg;
if (strmatch(argv[idx_vrf - 1]->text, "vrf")
@@ -1821,7 +1878,6 @@ DEFPY (bgp_suppress_fib_pending,
return CMD_SUCCESS;
}
-
/* BGP Cluster ID. */
DEFUN (bgp_cluster_id,
bgp_cluster_id_cmd,
@@ -1917,30 +1973,33 @@ DEFPY (no_bgp_send_extra_data,
DEFUN (bgp_confederation_identifier,
bgp_confederation_identifier_cmd,
- "bgp confederation identifier (1-4294967295)",
+ "bgp confederation identifier ASNUM",
BGP_STR
"AS confederation parameters\n"
- "AS number\n"
+ AS_STR
"Set routing domain confederation AS\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_number = 3;
as_t as;
- as = strtoul(argv[idx_number]->arg, NULL, 10);
+ if (!asn_str2asn(argv[idx_number]->arg, &as)) {
+ vty_out(vty, "%% BGP: No such AS %s\n", argv[idx_number]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- bgp_confederation_id_set(bgp, as);
+ bgp_confederation_id_set(bgp, as, argv[idx_number]->arg);
return CMD_SUCCESS;
}
DEFUN (no_bgp_confederation_identifier,
no_bgp_confederation_identifier_cmd,
- "no bgp confederation identifier [(1-4294967295)]",
+ "no bgp confederation identifier [ASNUM]",
NO_STR
BGP_STR
"AS confederation parameters\n"
- "AS number\n"
+ AS_STR
"Set routing domain confederation AS\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
@@ -1951,7 +2010,7 @@ DEFUN (no_bgp_confederation_identifier,
DEFUN (bgp_confederation_peers,
bgp_confederation_peers_cmd,
- "bgp confederation peers (1-4294967295)...",
+ "bgp confederation peers ASNUM...",
BGP_STR
"AS confederation parameters\n"
"Peer ASs in BGP confederation\n"
@@ -1963,15 +2022,20 @@ DEFUN (bgp_confederation_peers,
int i;
for (i = idx_asn; i < argc; i++) {
- as = strtoul(argv[i]->arg, NULL, 10);
- bgp_confederation_peers_add(bgp, as);
+ if (!asn_str2asn(argv[i]->arg, &as)) {
+ vty_out(vty, "%% Invalid confed peer AS value: %s\n",
+ argv[i]->arg);
+ continue;
+ }
+
+ bgp_confederation_peers_add(bgp, as, argv[i]->arg);
}
return CMD_SUCCESS;
}
DEFUN (no_bgp_confederation_peers,
no_bgp_confederation_peers_cmd,
- "no bgp confederation peers (1-4294967295)...",
+ "no bgp confederation peers ASNUM...",
NO_STR
BGP_STR
"AS confederation parameters\n"
@@ -1984,8 +2048,11 @@ DEFUN (no_bgp_confederation_peers,
int i;
for (i = idx_asn; i < argc; i++) {
- as = strtoul(argv[i]->arg, NULL, 10);
-
+ if (!asn_str2asn(argv[i]->arg, &as)) {
+ vty_out(vty, "%% Invalid confed peer AS value: %s\n",
+ argv[i]->arg);
+ continue;
+ }
bgp_confederation_peers_remove(bgp, as);
}
return CMD_SUCCESS;
@@ -4489,11 +4556,13 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
} else if (as_str[0] == 'e') {
as = 0;
as_type = AS_EXTERNAL;
- } else {
- /* Get AS number. */
- as = strtoul(as_str, NULL, 10);
- }
+ } else if (!asn_str2asn(as_str, &as))
+ as_type = AS_UNSPECIFIED;
+ if (as_type == AS_UNSPECIFIED) {
+ vty_out(vty, "%% Invalid peer AS: %s\n", as_str);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
/* If peer is peer group or interface peer, call proper function. */
ret = str2sockunion(peer_str, &su);
if (ret < 0) {
@@ -4502,11 +4571,12 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
/* Check if existing interface peer */
peer = peer_lookup_by_conf_if(bgp, peer_str);
- ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type);
+ ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, as_str);
/* if not interface peer, check peer-group settings */
if (ret < 0 && !peer) {
- ret = peer_group_remote_as(bgp, peer_str, &as, as_type);
+ ret = peer_group_remote_as(bgp, peer_str, &as, as_type,
+ as_str);
if (ret < 0) {
vty_out(vty,
"%% Create the peer-group or interface first\n");
@@ -4520,7 +4590,7 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
"%% Can not configure the local system as neighbor\n");
return CMD_WARNING_CONFIG_FAILED;
}
- ret = peer_remote_as(bgp, &su, NULL, &as, as_type);
+ ret = peer_remote_as(bgp, &su, NULL, &as, as_type, as_str);
}
return bgp_vty_return(vty, ret);
@@ -4591,7 +4661,7 @@ ALIAS(no_bgp_shutdown, no_bgp_shutdown_msg_cmd,
DEFUN (neighbor_remote_as,
neighbor_remote_as_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> remote-as <(1-4294967295)|internal|external>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> remote-as <ASNUM|internal|external>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a BGP neighbor\n"
@@ -4671,18 +4741,19 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
as_type = AS_EXTERNAL;
} else {
/* Get AS number. */
- as = strtoul(as_str, NULL, 10);
- as_type = AS_SPECIFIED;
+ if (asn_str2asn(as_str, &as))
+ as_type = AS_SPECIFIED;
}
}
peer = peer_lookup_by_conf_if(bgp, conf_if);
if (peer) {
if (as_str)
- ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type);
+ ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type,
+ as_str);
} else {
peer = peer_create(NULL, conf_if, bgp, bgp->as, as, as_type,
- NULL, true);
+ NULL, true, as_str);
if (!peer) {
vty_out(vty, "%% BGP failed to create peer\n");
@@ -4784,7 +4855,7 @@ DEFUN (neighbor_interface_config_v6only,
DEFUN (neighbor_interface_config_remote_as,
neighbor_interface_config_remote_as_cmd,
- "neighbor WORD interface remote-as <(1-4294967295)|internal|external>",
+ "neighbor WORD interface remote-as <ASNUM|internal|external>",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Enable BGP on interface\n"
@@ -4801,7 +4872,7 @@ DEFUN (neighbor_interface_config_remote_as,
DEFUN (neighbor_interface_v6only_config_remote_as,
neighbor_interface_v6only_config_remote_as_cmd,
- "neighbor WORD interface v6only remote-as <(1-4294967295)|internal|external>",
+ "neighbor WORD interface v6only remote-as <ASNUM|internal|external>",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Enable BGP with v6 link-local only\n"
@@ -4970,7 +5041,7 @@ DEFUN (no_neighbor_peer_group,
DEFUN (no_neighbor_interface_peer_group_remote_as,
no_neighbor_interface_peer_group_remote_as_cmd,
- "no neighbor WORD remote-as <(1-4294967295)|internal|external>",
+ "no neighbor WORD remote-as <ASNUM|internal|external>",
NO_STR
NEIGHBOR_STR
"Interface name or neighbor tag\n"
@@ -4987,7 +5058,7 @@ DEFUN (no_neighbor_interface_peer_group_remote_as,
/* look up for neighbor by interface name config. */
peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
if (peer) {
- peer_as_change(peer, 0, AS_UNSPECIFIED);
+ peer_as_change(peer, 0, AS_UNSPECIFIED, NULL);
return CMD_SUCCESS;
}
@@ -5003,11 +5074,11 @@ DEFUN (no_neighbor_interface_peer_group_remote_as,
DEFUN (neighbor_local_as,
neighbor_local_as_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295)",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> local-as ASNUM",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a local-as number\n"
- "AS number used as local AS\n")
+ "AS number expressed in dotted or plain format used as local AS\n")
{
int idx_peer = 1;
int idx_number = 3;
@@ -5019,18 +5090,23 @@ DEFUN (neighbor_local_as,
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
- as = strtoul(argv[idx_number]->arg, NULL, 10);
- ret = peer_local_as_set(peer, as, 0, 0);
+ if (!asn_str2asn(argv[idx_number]->arg, &as)) {
+ vty_out(vty, "%% Invalid neighbor local-as value: %s\n",
+ argv[idx_number]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = peer_local_as_set(peer, as, 0, 0, argv[idx_number]->arg);
return bgp_vty_return(vty, ret);
}
DEFUN (neighbor_local_as_no_prepend,
neighbor_local_as_no_prepend_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> local-as ASNUM no-prepend",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a local-as number\n"
- "AS number used as local AS\n"
+ "AS number expressed in dotted or plain format used as local AS\n"
"Do not prepend local-as to updates from ebgp peers\n")
{
int idx_peer = 1;
@@ -5043,18 +5119,23 @@ DEFUN (neighbor_local_as_no_prepend,
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
- as = strtoul(argv[idx_number]->arg, NULL, 10);
- ret = peer_local_as_set(peer, as, 1, 0);
+ if (!asn_str2asn(argv[idx_number]->arg, &as)) {
+ vty_out(vty, "%% Invalid neighbor local-as value: %s\n",
+ argv[idx_number]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = peer_local_as_set(peer, as, 1, 0, argv[idx_number]->arg);
return bgp_vty_return(vty, ret);
}
DEFUN (neighbor_local_as_no_prepend_replace_as,
neighbor_local_as_no_prepend_replace_as_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend replace-as",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> local-as ASNUM no-prepend replace-as",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a local-as number\n"
- "AS number used as local AS\n"
+ "AS number expressed in dotted or plain format used as local AS\n"
"Do not prepend local-as to updates from ebgp peers\n"
"Do not prepend local-as to updates from ibgp peers\n")
{
@@ -5068,19 +5149,24 @@ DEFUN (neighbor_local_as_no_prepend_replace_as,
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
- as = strtoul(argv[idx_number]->arg, NULL, 10);
- ret = peer_local_as_set(peer, as, 1, 1);
+ if (!asn_str2asn(argv[idx_number]->arg, &as)) {
+ vty_out(vty, "%% Invalid neighbor local-as value: %s\n",
+ argv[idx_number]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = peer_local_as_set(peer, as, 1, 1, argv[idx_number]->arg);
return bgp_vty_return(vty, ret);
}
DEFUN (no_neighbor_local_as,
no_neighbor_local_as_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> local-as [(1-4294967295) [no-prepend [replace-as]]]",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> local-as [ASNUM [no-prepend [replace-as]]]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a local-as number\n"
- "AS number used as local AS\n"
+ "AS number expressed in dotted or plain format used as local AS\n"
"Do not prepend local-as to updates from ebgp peers\n"
"Do not prepend local-as to updates from ibgp peers\n")
{
@@ -9020,10 +9106,13 @@ DEFPY (af_rd_vpn_export,
bgp_get_default(), bgp);
if (yes) {
+ bgp->vpn_policy[afi].tovpn_rd_pretty =
+ XSTRDUP(MTYPE_BGP, rd_str);
bgp->vpn_policy[afi].tovpn_rd = prd;
SET_FLAG(bgp->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_RD_SET);
} else {
+ XFREE(MTYPE_BGP, bgp->vpn_policy[afi].tovpn_rd_pretty);
UNSET_FLAG(bgp->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_RD_SET);
}
@@ -9548,7 +9637,8 @@ DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd,
/* Auto-create assuming the same AS */
ret = bgp_get_vty(&bgp_default, &as, NULL,
- BGP_INSTANCE_TYPE_DEFAULT);
+ BGP_INSTANCE_TYPE_DEFAULT, NULL,
+ ASNOTATION_UNDEFINED);
if (ret) {
vty_out(vty,
@@ -9660,7 +9750,8 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
if (!bgp_default) {
/* Auto-create assuming the same AS */
ret = bgp_get_vty(&bgp_default, &as, NULL,
- BGP_INSTANCE_TYPE_DEFAULT);
+ BGP_INSTANCE_TYPE_DEFAULT, NULL,
+ ASNOTATION_UNDEFINED);
if (ret) {
vty_out(vty,
@@ -9675,8 +9766,8 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
vrf_bgp = bgp_default;
else
/* Auto-create assuming the same AS */
- ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type);
-
+ ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type,
+ NULL, ASNOTATION_UNDEFINED);
if (ret) {
vty_out(vty,
"VRF %s is not configured as a bgp instance\n",
@@ -10144,7 +10235,7 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name,
/* one clear bgp command to rule them all */
DEFUN (clear_ip_bgp_all,
clear_ip_bgp_all_cmd,
- "clear [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|l2vpn> [<unicast|multicast|vpn|labeled-unicast|flowspec|evpn>]] <*|A.B.C.D$neighbor|X:X::X:X$neighbor|WORD$neighbor|(1-4294967295)|external|peer-group PGNAME> [<soft [<in|out>]|in [prefix-filter]|out|message-stats>]",
+ "clear [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|l2vpn> [<unicast|multicast|vpn|labeled-unicast|flowspec|evpn>]] <*|A.B.C.D$neighbor|X:X::X:X$neighbor|WORD$neighbor|ASNUM|external|peer-group PGNAME> [<soft [<in|out>]|in [prefix-filter]|out|message-stats>]",
CLEAR_STR
IP_STR
BGP_STR
@@ -10157,7 +10248,7 @@ DEFUN (clear_ip_bgp_all,
"BGP IPv4 neighbor to clear\n"
"BGP IPv6 neighbor to clear\n"
"BGP neighbor on interface to clear\n"
- "Clear peers with the AS number\n"
+ "Clear peers with the AS number in plain or dotted format\n"
"Clear all external peers\n"
"Clear all members of peer-group\n"
"BGP peer-group name\n"
@@ -10198,7 +10289,7 @@ DEFUN (clear_ip_bgp_all,
if (argv_find_and_parse_afi(argv, argc, &idx, &afi))
argv_find_and_parse_safi(argv, argc, &idx, &safi);
- /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group PGNAME> */
+ /* <*|A.B.C.D|X:X::X:X|WORD|ASNUM|external|peer-group PGNAME> */
if (argv_find(argv, argc, "*", &idx)) {
clr_sort = clear_all;
} else if (argv_find(argv, argc, "A.B.C.D", &idx)) {
@@ -10217,7 +10308,7 @@ DEFUN (clear_ip_bgp_all,
} else if (argv_find(argv, argc, "WORD", &idx)) {
clr_sort = clear_peer;
clr_arg = argv[idx]->arg;
- } else if (argv_find(argv, argc, "(1-4294967295)", &idx)) {
+ } else if (argv_find(argv, argc, "ASNUM", &idx)) {
clr_sort = clear_as;
clr_arg = argv[idx]->arg;
} else if (argv_find(argv, argc, "external", &idx)) {
@@ -10355,8 +10446,8 @@ DEFUN (show_bgp_views,
/* Skip VRFs. */
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
continue;
- vty_out(vty, "\t%s (AS%u)\n", bgp->name ? bgp->name : "(null)",
- bgp->as);
+ vty_out(vty, "\t%s (AS%s)\n", bgp->name ? bgp->name : "(null)",
+ bgp->as_pretty);
}
return CMD_SUCCESS;
@@ -11142,7 +11233,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
json_object_string_addf(json, "routerId",
"%pI4",
&bgp->router_id);
- json_object_int_add(json, "as", bgp->as);
+ asn_asn2json(json, "as", bgp->as,
+ bgp->asnotation);
json_object_int_add(json, "vrfId", vrf_id_ui);
json_object_string_add(
json, "vrfName",
@@ -11152,8 +11244,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
: bgp->name);
} else {
vty_out(vty,
- "BGP router identifier %pI4, local AS number %u vrf-id %d",
- &bgp->router_id, bgp->as,
+ "BGP router identifier %pI4, local AS number %s vrf-id %d",
+ &bgp->router_id, bgp->as_pretty,
bgp->vrf_id == VRF_UNKNOWN
? -1
: (int)bgp->vrf_id);
@@ -11387,12 +11479,13 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
json_object_string_add(json_peer, "domainname",
peer->domainname);
- json_object_int_add(json_peer, "remoteAs", peer->as);
- json_object_int_add(
- json_peer, "localAs",
- peer->change_local_as
- ? peer->change_local_as
- : peer->local_as);
+ asn_asn2json(json_peer, "remoteAs", peer->as,
+ bgp->asnotation);
+ asn_asn2json(json_peer, "localAs",
+ peer->change_local_as
+ ? peer->change_local_as
+ : peer->local_as,
+ bgp->asnotation);
json_object_int_add(json_peer, "version", 4);
json_object_int_add(json_peer, "msgRcvd",
PEER_TOTAL_RX(peer));
@@ -11572,14 +11665,19 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
&peer->ibuf->count,
memory_order_relaxed);
- if (show_wide)
+ vty_out(vty, "4 ");
+ vty_out(vty, ASN_FORMAT_SPACE(bgp->asnotation),
+ &peer->as);
+ if (show_wide) {
vty_out(vty,
- "4 %10u %10u %9u %9u %8" PRIu64
- " %4zu %4zu %8s",
- peer->as,
+ ASN_FORMAT_SPACE(
+ bgp->asnotation),
peer->change_local_as
- ? peer->change_local_as
- : peer->local_as,
+ ? &peer->change_local_as
+ : &peer->local_as);
+ vty_out(vty,
+ " %9u %9u %8" PRIu64
+ " %4zu %4zu %8s",
PEER_TOTAL_RX(peer),
PEER_TOTAL_TX(peer),
peer->version[afi][safi],
@@ -11588,10 +11686,11 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
timebuf,
BGP_UPTIME_LEN, 0,
NULL));
- else
- vty_out(vty, "4 %10u %9u %9u %8" PRIu64
- " %4zu %4zu %8s",
- peer->as, PEER_TOTAL_RX(peer),
+ } else {
+ vty_out(vty,
+ " %9u %9u %8" PRIu64
+ " %4zu %4zu %8s",
+ PEER_TOTAL_RX(peer),
PEER_TOTAL_TX(peer),
peer->version[afi][safi],
inq_count, outq_count,
@@ -11599,7 +11698,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
timebuf,
BGP_UPTIME_LEN, 0,
NULL));
-
+ }
if (peer_established(peer)) {
if (peer->afc_recv[afi][safi]) {
if (CHECK_FLAG(
@@ -11892,7 +11991,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
DEFPY(show_ip_bgp_summary, show_ip_bgp_summary_cmd,
"show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
" [" BGP_SAFI_WITH_LABEL_CMD_STR
- "]] [all$all] summary [established|failed] [<neighbor <A.B.C.D|X:X::X:X|WORD>|remote-as <(1-4294967295)|internal|external>>] [terse] [wide] [json$uj]",
+ "]] [all$all] summary [established|failed] [<neighbor <A.B.C.D|X:X::X:X|WORD>|remote-as <ASNUM|internal|external>>] [terse] [wide] [json$uj]",
SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
BGP_SAFI_WITH_LABEL_HELP_STR
"Display the entries for all address families\n"
@@ -11903,8 +12002,7 @@ DEFPY(show_ip_bgp_summary, show_ip_bgp_summary_cmd,
"Neighbor to display information about\n"
"Neighbor to display information about\n"
"Neighbor on BGP configured interface\n"
- "Show only the specified remote AS sessions\n"
- "AS number\n"
+ "Show only the specified remote AS sessions\n" AS_STR
"Internal (iBGP) AS sessions\n"
"External (eBGP) AS sessions\n"
"Shorten the information on BGP instances\n"
@@ -11946,8 +12044,12 @@ DEFPY(show_ip_bgp_summary, show_ip_bgp_summary_cmd,
as_type = AS_INTERNAL;
else if (argv[idx + 1]->arg[0] == 'e')
as_type = AS_EXTERNAL;
- else
- as = (as_t)atoi(argv[idx + 1]->arg);
+ else if (!asn_str2asn(argv[idx + 1]->arg, &as)) {
+ vty_out(vty,
+ "%% Invalid neighbor remote-as value: %s\n",
+ argv[idx + 1]->arg);
+ return CMD_SUCCESS;
+ }
}
if (argv_find(argv, argc, "terse", &idx))
@@ -13082,13 +13184,14 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
json_object_string_addf(json_neigh, "bgpNeighborAddr",
"%pSU", &p->su);
- json_object_int_add(json_neigh, "remoteAs", p->as);
+ asn_asn2json(json_neigh, "remoteAs", p->as, bgp->asnotation);
if (p->change_local_as)
- json_object_int_add(json_neigh, "localAs",
- p->change_local_as);
+ asn_asn2json(json_neigh, "localAs", p->change_local_as,
+ bgp->asnotation);
else
- json_object_int_add(json_neigh, "localAs", p->local_as);
+ asn_asn2json(json_neigh, "localAs", p->local_as,
+ bgp->asnotation);
if (CHECK_FLAG(p->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
json_object_boolean_true_add(json_neigh,
@@ -13098,13 +13201,19 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
json_object_boolean_true_add(json_neigh,
"localAsReplaceAs");
} else {
- if ((p->as_type == AS_SPECIFIED) || (p->as_type == AS_EXTERNAL)
- || (p->as_type == AS_INTERNAL))
- vty_out(vty, "remote AS %u, ", p->as);
- else
+ if ((p->as_type == AS_SPECIFIED) ||
+ (p->as_type == AS_EXTERNAL) ||
+ (p->as_type == AS_INTERNAL)) {
+ vty_out(vty, "remote AS ");
+ vty_out(vty, ASN_FORMAT(bgp->asnotation), &p->as);
+ vty_out(vty, ", ");
+ } else
vty_out(vty, "remote AS Unspecified, ");
- vty_out(vty, "local AS %u%s%s, ",
- p->change_local_as ? p->change_local_as : p->local_as,
+ vty_out(vty, "local AS ");
+ vty_out(vty, ASN_FORMAT(bgp->asnotation),
+ p->change_local_as ? &p->change_local_as
+ : &p->local_as);
+ vty_out(vty, "%s%s, ",
CHECK_FLAG(p->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)
? " no-prepend"
: "",
@@ -15577,10 +15686,9 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
json_object_new_string(vname));
json_object_object_add(json, "exportToVrfs",
json_export_vrfs);
- json_object_string_addf(json, "routeDistinguisher",
- "%pRD",
- &bgp->vpn_policy[afi].tovpn_rd);
-
+ json_object_string_addf(
+ json, "routeDistinguisher", "%s",
+ bgp->vpn_policy[afi].tovpn_rd_pretty);
dir = BGP_VPN_POLICY_DIR_TOVPN;
if (bgp->vpn_policy[afi].rtlist[dir]) {
ecom_str = ecommunity_ecom2str(
@@ -15648,8 +15756,10 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
node, vname))
vty_out(vty, " %s\n", vname);
- vty_out(vty, "RD: %pRD\n",
+ vty_out(vty, "RD: ");
+ vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
&bgp->vpn_policy[afi].tovpn_rd);
+ vty_out(vty, "\n");
dir = BGP_VPN_POLICY_DIR_TOVPN;
if (bgp->vpn_policy[afi].rtlist[dir]) {
@@ -16014,18 +16124,22 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group,
if (conf->as_type == AS_SPECIFIED || conf->as_type == AS_EXTERNAL) {
if (json)
- json_object_int_add(json_peer_group, "remoteAs",
- conf->as);
- else
- vty_out(vty, "\nBGP peer-group %s, remote AS %u\n",
- group->name, conf->as);
+ asn_asn2json(json_peer_group, "remoteAs", conf->as,
+ bgp_get_asnotation(conf->bgp));
+ else {
+ vty_out(vty, "\nBGP peer-group %s, remote AS ",
+ group->name);
+ vty_out(vty, ASN_FORMAT(bgp_get_asnotation(conf->bgp)),
+ &conf->as);
+ vty_out(vty, "\n");
+ }
} else if (conf->as_type == AS_INTERNAL) {
if (json)
- json_object_int_add(json_peer_group, "remoteAs",
- group->bgp->as);
+ asn_asn2json(json, "remoteAs", group->bgp->as,
+ group->bgp->asnotation);
else
- vty_out(vty, "\nBGP peer-group %s, remote AS %u\n",
- group->name, group->bgp->as);
+ vty_out(vty, "\nBGP peer-group %s, remote AS %s\n",
+ group->name, group->bgp->as_pretty);
} else {
if (!json)
vty_out(vty, "\nBGP peer-group %s\n", group->name);
@@ -17148,8 +17262,8 @@ static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
}
if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET))
- vty_out(vty, "%*srd vpn export %pRD\n", indent, "",
- &bgp->vpn_policy[afi].tovpn_rd);
+ vty_out(vty, "%*srd vpn export %s\n", indent, "",
+ bgp->vpn_policy[afi].tovpn_rd_pretty);
if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
@@ -17319,7 +17433,7 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
vty_out(vty, " peer-group %s", peer->group->name);
if_pg_printed = true;
} else if (peer->as_type == AS_SPECIFIED) {
- vty_out(vty, " remote-as %u", peer->as);
+ vty_out(vty, " remote-as %s", peer->as_pretty);
if_ras_printed = true;
} else if (peer->as_type == AS_INTERNAL) {
vty_out(vty, " remote-as internal");
@@ -17339,8 +17453,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
if (g_peer->as_type == AS_UNSPECIFIED && !if_ras_printed) {
if (peer->as_type == AS_SPECIFIED) {
- vty_out(vty, " neighbor %s remote-as %u\n",
- addr, peer->as);
+ vty_out(vty, " neighbor %s remote-as %s\n",
+ addr, peer->as_pretty);
} else if (peer->as_type == AS_INTERNAL) {
vty_out(vty,
" neighbor %s remote-as internal\n",
@@ -17368,8 +17482,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
if (!if_ras_printed) {
if (peer->as_type == AS_SPECIFIED) {
- vty_out(vty, " neighbor %s remote-as %u\n",
- addr, peer->as);
+ vty_out(vty, " neighbor %s remote-as %s\n",
+ addr, peer->as_pretty);
} else if (peer->as_type == AS_INTERNAL) {
vty_out(vty,
" neighbor %s remote-as internal\n",
@@ -17384,8 +17498,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
/* local-as */
if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS)) {
- vty_out(vty, " neighbor %s local-as %u", addr,
- peer->change_local_as);
+ vty_out(vty, " neighbor %s local-as %s", addr,
+ peer->change_local_as_pretty);
if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND))
vty_out(vty, " no-prepend");
if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS))
@@ -18066,12 +18180,16 @@ int bgp_config_write(struct vty *vty)
continue;
/* Router bgp ASN */
- vty_out(vty, "router bgp %u", bgp->as);
+ vty_out(vty, "router bgp %s", bgp->as_pretty);
if (bgp->name)
vty_out(vty, " %s %s",
(bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
? "view" : "vrf", bgp->name);
+ if (CHECK_FLAG(bgp->config, BGP_CONFIG_ASNOTATION))
+ vty_out(vty, " as-notation %s",
+ asn_mode2str(bgp->asnotation));
+
vty_out(vty, "\n");
/* BGP fast-external-failover. */
@@ -18189,8 +18307,8 @@ int bgp_config_write(struct vty *vty)
/* Confederation identifier*/
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
- vty_out(vty, " bgp confederation identifier %u\n",
- bgp->confed_id);
+ vty_out(vty, " bgp confederation identifier %s\n",
+ bgp->confed_id_pretty);
/* Confederation peer */
if (bgp->confed_peers_cnt > 0) {
@@ -18199,7 +18317,8 @@ int bgp_config_write(struct vty *vty)
vty_out(vty, " bgp confederation peers");
for (i = 0; i < bgp->confed_peers_cnt; i++)
- vty_out(vty, " %u", bgp->confed_peers[i]);
+ vty_out(vty, " %s",
+ bgp->confed_peers[i].as_pretty);
vty_out(vty, "\n");
}
diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h
index 56485035e..1c5adff68 100644
--- a/bgpd/bgp_vty.h
+++ b/bgpd/bgp_vty.h
@@ -135,7 +135,8 @@ extern void bgp_vty_init(void);
extern void community_alias_vty(void);
extern const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json);
extern int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
- enum bgp_instance_type inst_type);
+ enum bgp_instance_type inst_type, const char *as_pretty,
+ enum asnotation_mode asnotation);
extern void bgp_config_write_update_delay(struct vty *vty, struct bgp *bgp);
extern void bgp_config_write_wpkt_quanta(struct vty *vty, struct bgp *bgp);
extern void bgp_config_write_rpkt_quanta(struct vty *vty, struct bgp *bgp);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 9ea5a92ad..09d7944ae 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -553,7 +553,7 @@ void bgp_tcp_keepalive_unset(struct bgp *bgp)
}
/* BGP confederation configuration. */
-void bgp_confederation_id_set(struct bgp *bgp, as_t as)
+void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str)
{
struct peer *peer;
struct listnode *node, *nnode;
@@ -565,6 +565,9 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as)
/* Remember - were we doing confederation before? */
already_confed = bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION);
bgp->confed_id = as;
+ if (bgp->confed_id_pretty)
+ XFREE(MTYPE_BGP, bgp->confed_id_pretty);
+ bgp->confed_id_pretty = XSTRDUP(MTYPE_BGP, as_str);
bgp_config_set(bgp, BGP_CONFIG_CONFEDERATION);
/* If we were doing confederation already, this is just an external
@@ -617,6 +620,7 @@ void bgp_confederation_id_unset(struct bgp *bgp)
struct listnode *node, *nnode;
bgp->confed_id = 0;
+ XFREE(MTYPE_BGP, bgp->confed_id_pretty);
bgp_config_unset(bgp, BGP_CONFIG_CONFEDERATION);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
@@ -644,14 +648,14 @@ bool bgp_confederation_peers_check(struct bgp *bgp, as_t as)
return false;
for (i = 0; i < bgp->confed_peers_cnt; i++)
- if (bgp->confed_peers[i] == as)
+ if (bgp->confed_peers[i].as == as)
return true;
return false;
}
/* Add an AS to the confederation set. */
-void bgp_confederation_peers_add(struct bgp *bgp, as_t as)
+void bgp_confederation_peers_add(struct bgp *bgp, as_t as, const char *as_str)
{
struct peer *peer;
struct listnode *node, *nnode;
@@ -662,11 +666,13 @@ void bgp_confederation_peers_add(struct bgp *bgp, as_t as)
if (bgp_confederation_peers_check(bgp, as))
return;
- bgp->confed_peers =
- XREALLOC(MTYPE_BGP_CONFED_LIST, bgp->confed_peers,
- (bgp->confed_peers_cnt + 1) * sizeof(as_t));
+ bgp->confed_peers = XREALLOC(MTYPE_BGP_CONFED_LIST, bgp->confed_peers,
+ (bgp->confed_peers_cnt + 1) *
+ sizeof(struct as_confed));
- bgp->confed_peers[bgp->confed_peers_cnt] = as;
+ bgp->confed_peers[bgp->confed_peers_cnt].as = as;
+ bgp->confed_peers[bgp->confed_peers_cnt].as_pretty =
+ XSTRDUP(MTYPE_BGP, as_str);
bgp->confed_peers_cnt++;
if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)) {
@@ -703,9 +709,15 @@ void bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
return;
for (i = 0; i < bgp->confed_peers_cnt; i++)
- if (bgp->confed_peers[i] == as)
- for (j = i + 1; j < bgp->confed_peers_cnt; j++)
- bgp->confed_peers[j - 1] = bgp->confed_peers[j];
+ if (bgp->confed_peers[i].as == as) {
+ XFREE(MTYPE_BGP, bgp->confed_peers[i].as_pretty);
+ for (j = i + 1; j < bgp->confed_peers_cnt; j++) {
+ bgp->confed_peers[j - 1].as =
+ bgp->confed_peers[j].as;
+ bgp->confed_peers[j - 1].as_pretty =
+ bgp->confed_peers[j].as_pretty;
+ }
+ }
bgp->confed_peers_cnt--;
@@ -714,9 +726,9 @@ void bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
XFREE(MTYPE_BGP_CONFED_LIST, bgp->confed_peers);
bgp->confed_peers = NULL;
} else
- bgp->confed_peers =
- XREALLOC(MTYPE_BGP_CONFED_LIST, bgp->confed_peers,
- bgp->confed_peers_cnt * sizeof(as_t));
+ bgp->confed_peers = XREALLOC(
+ MTYPE_BGP_CONFED_LIST, bgp->confed_peers,
+ bgp->confed_peers_cnt * sizeof(struct as_confed));
/* Now reset any peer who's remote AS has just been removed from the
CONFED */
@@ -1172,6 +1184,11 @@ static void peer_free(struct peer *peer)
FOREACH_AFI_SAFI (afi, safi)
bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_NONE);
+ if (peer->change_local_as_pretty)
+ XFREE(MTYPE_BGP, peer->change_local_as_pretty);
+ if (peer->as_pretty)
+ XFREE(MTYPE_BGP, peer->as_pretty);
+
bgp_unlock(peer->bgp);
memset(peer, 0, sizeof(struct peer));
@@ -1753,7 +1770,7 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp)
struct peer *peer_create(union sockunion *su, const char *conf_if,
struct bgp *bgp, as_t local_as, as_t remote_as,
int as_type, struct peer_group *group,
- bool config_node)
+ bool config_node, const char *as_str)
{
int active;
struct peer *peer;
@@ -1778,6 +1795,9 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
}
peer->local_as = local_as;
peer->as = remote_as;
+ /* internal and external values do not use as_pretty */
+ if (as_str && asn_str2asn(as_str, NULL))
+ peer->as_pretty = XSTRDUP(MTYPE_BGP, as_str);
peer->as_type = as_type;
peer->local_id = bgp->router_id;
peer->v_holdtime = bgp->default_holdtime;
@@ -1881,7 +1901,8 @@ bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi)
}
/* Change peer's AS number. */
-void peer_as_change(struct peer *peer, as_t as, int as_specified)
+void peer_as_change(struct peer *peer, as_t as, int as_specified,
+ const char *as_str)
{
enum bgp_peer_sort origtype, newtype;
@@ -1896,6 +1917,12 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified)
}
origtype = peer_sort_lookup(peer);
peer->as = as;
+ if (as_specified == AS_SPECIFIED && as_str) {
+ if (peer->as_pretty)
+ XFREE(MTYPE_BGP, peer->as_pretty);
+ peer->as_pretty = XSTRDUP(MTYPE_BGP, as_str);
+ } else if (peer->as_type == AS_UNSPECIFIED && peer->as_pretty)
+ XFREE(MTYPE_BGP, peer->as_pretty);
peer->as_type = as_specified;
if (bgp_config_check(peer->bgp, BGP_CONFIG_CONFEDERATION)
@@ -1953,7 +1980,7 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified)
/* If peer does not exist, create new one. If peer already exists,
set AS number to the peer. */
int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
- as_t *as, int as_type)
+ as_t *as, int as_type, const char *as_str)
{
struct peer *peer;
as_t local_as;
@@ -2007,7 +2034,7 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
/* Existing peer's AS number change. */
if (((peer->as_type == AS_SPECIFIED) && peer->as != *as)
|| (peer->as_type != as_type))
- peer_as_change(peer, *as, as_type);
+ peer_as_change(peer, *as, as_type, as_str);
} else {
if (conf_if)
return BGP_ERR_NO_INTERFACE_CONFIG;
@@ -2022,7 +2049,7 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
local_as = bgp->as;
peer_create(su, conf_if, bgp, local_as, *as, as_type, NULL,
- true);
+ true, as_str);
}
return 0;
@@ -2047,6 +2074,13 @@ const char *bgp_get_name_by_role(uint8_t role)
return "unknown";
}
+enum asnotation_mode bgp_get_asnotation(struct bgp *bgp)
+{
+ if (!bgp)
+ return ASNOTATION_PLAIN;
+ return bgp->asnotation;
+}
+
static void peer_group2peer_config_copy_af(struct peer_group *group,
struct peer *peer, afi_t afi,
safi_t safi)
@@ -2804,7 +2838,7 @@ static void peer_group2peer_config_copy(struct peer_group *group,
/* Peer group's remote AS configuration. */
int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
- int as_type)
+ int as_type, const char *as_str)
{
struct peer_group *group;
struct peer *peer;
@@ -2820,12 +2854,12 @@ int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
/* When we setup peer-group AS number all peer group member's AS
number must be updated to same number. */
- peer_as_change(group->conf, *as, as_type);
+ peer_as_change(group->conf, *as, as_type, as_str);
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
if (((peer->as_type == AS_SPECIFIED) && peer->as != *as)
|| (peer->as_type != as_type))
- peer_as_change(peer, *as, as_type);
+ peer_as_change(peer, *as, as_type, as_str);
}
return 0;
@@ -3132,7 +3166,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
}
peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
- group->conf->as_type, group, true);
+ group->conf->as_type, group, true, NULL);
peer = peer_lock(peer); /* group->peer list reference */
listnode_add(group->peer, peer);
@@ -3184,23 +3218,37 @@ static void bgp_vrf_string_name_delete(void *data)
/* BGP instance creation by `router bgp' commands. */
static struct bgp *bgp_create(as_t *as, const char *name,
- enum bgp_instance_type inst_type)
+ enum bgp_instance_type inst_type,
+ const char *as_pretty,
+ enum asnotation_mode asnotation)
{
struct bgp *bgp;
afi_t afi;
safi_t safi;
bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp));
+ bgp->as = *as;
+ if (as_pretty)
+ bgp->as_pretty = XSTRDUP(MTYPE_BGP, as_pretty);
+ else
+ bgp->as_pretty = XSTRDUP(MTYPE_BGP, asn_asn2asplain(*as));
+
+ if (asnotation != ASNOTATION_UNDEFINED) {
+ bgp->asnotation = asnotation;
+ SET_FLAG(bgp->config, BGP_CONFIG_ASNOTATION);
+ } else
+ asn_str2asn_notation(bgp->as_pretty, NULL, &bgp->asnotation);
if (BGP_DEBUG(zebra, ZEBRA)) {
if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- zlog_debug("Creating Default VRF, AS %u", *as);
+ zlog_debug("Creating Default VRF, AS %s",
+ bgp->as_pretty);
else
- zlog_debug("Creating %s %s, AS %u",
+ zlog_debug("Creating %s %s, AS %s",
(inst_type == BGP_INSTANCE_TYPE_VRF)
? "VRF"
: "VIEW",
- name, *as);
+ name, bgp->as_pretty);
}
/* Default the EVPN VRF to the default one */
@@ -3277,7 +3325,6 @@ static struct bgp *bgp_create(as_t *as, const char *name,
bgp->condition_check_period = DEFAULT_CONDITIONAL_ROUTES_POLL_TIME;
bgp_addpath_init_bgp_data(&bgp->tx_addpath);
bgp->fast_convergence = false;
- bgp->as = *as;
bgp->llgr_stale_time = BGP_DEFAULT_LLGR_STALE_TIME;
#ifdef ENABLE_BGP_VNC
@@ -3514,7 +3561,8 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *name,
/* Called from VTY commands. */
int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
- enum bgp_instance_type inst_type)
+ enum bgp_instance_type inst_type, const char *as_pretty,
+ enum asnotation_mode asnotation)
{
struct bgp *bgp;
struct vrf *vrf = NULL;
@@ -3524,7 +3572,7 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
if (ret || *bgp_val)
return ret;
- bgp = bgp_create(as, name, inst_type);
+ bgp = bgp_create(as, name, inst_type, as_pretty, asnotation);
/*
* view instances will never work inside of a vrf
@@ -3918,8 +3966,13 @@ void bgp_free(struct bgp *bgp)
dir = BGP_VPN_POLICY_DIR_TOVPN;
if (bgp->vpn_policy[afi].rtlist[dir])
ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
+ if (bgp->vpn_policy[afi].tovpn_rd_pretty)
+ XFREE(MTYPE_BGP, bgp->vpn_policy[afi].tovpn_rd_pretty);
}
+ bgp_confederation_id_unset(bgp);
+
+ XFREE(MTYPE_BGP, bgp->as_pretty);
XFREE(MTYPE_BGP, bgp->name);
XFREE(MTYPE_BGP, bgp->name_pretty);
XFREE(MTYPE_BGP, bgp->snmp_stats);
@@ -4024,7 +4077,7 @@ struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp,
/* Create peer first; we've already checked group config is valid. */
peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
- group->conf->as_type, group, true);
+ group->conf->as_type, group, true, NULL);
if (!peer)
return NULL;
@@ -6228,7 +6281,7 @@ int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi)
}
int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
- bool replace_as)
+ bool replace_as, const char *as_str)
{
bool old_no_prepend, old_replace_as;
struct bgp *bgp = peer->bgp;
@@ -6253,6 +6306,9 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
&& old_replace_as == replace_as)
return 0;
peer->change_local_as = as;
+ if (as_str)
+ peer->change_local_as_pretty = XSTRDUP(MTYPE_BGP, as_str);
+
(void)peer_sort(peer);
/* Check if handling a regular peer. */
@@ -6286,6 +6342,9 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS,
replace_as);
member->change_local_as = as;
+ if (as_str)
+ member->change_local_as_pretty =
+ XSTRDUP(MTYPE_BGP, as_str);
}
return 0;
@@ -6311,6 +6370,7 @@ int peer_local_as_unset(struct peer *peer)
peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
peer->change_local_as = 0;
+ XFREE(MTYPE_BGP, peer->change_local_as_pretty);
}
/* Check if handling a regular peer. */
@@ -6341,6 +6401,7 @@ int peer_local_as_unset(struct peer *peer)
UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
member->change_local_as = 0;
+ XFREE(MTYPE_BGP, member->change_local_as_pretty);
/* Send notification or stop peer depending on state. */
if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
@@ -8024,7 +8085,7 @@ static void bgp_instasn_autocomplete(vector comps, struct cmd_token *token)
{
struct listnode *next, *next2;
struct bgp *bgp, *bgp2;
- char buf[11];
+ char buf[ASN_STRING_MAX_SIZE];
for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
/* deduplicate */
@@ -8037,7 +8098,7 @@ static void bgp_instasn_autocomplete(vector comps, struct cmd_token *token)
if (bgp2 != bgp)
continue;
- snprintf(buf, sizeof(buf), "%u", bgp->as);
+ snprintf(buf, sizeof(buf), "%s", bgp->as_pretty);
vector_set(comps, XSTRDUP(MTYPE_COMPLETION, buf));
}
}
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 91f0de0ce..2a7c7a314 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -16,6 +16,7 @@
#include "vty.h"
#include "srv6.h"
#include "iana_afi.h"
+#include "asn.h"
/* For union sockunion. */
#include "queue.h"
@@ -62,7 +63,6 @@ enum zebra_gr_mode {
};
/* Typedef BGP specific types. */
-typedef uint32_t as_t;
typedef uint16_t as16_t; /* we may still encounter 16 Bit asnums */
typedef uint16_t bgp_size_t;
@@ -203,6 +203,7 @@ struct vpn_policy {
/* should be mpls_label_t? */
uint32_t tovpn_label; /* may be MPLS_LABEL_NONE */
uint32_t tovpn_zebra_vrf_label_last_sent;
+ char *tovpn_rd_pretty;
struct prefix_rd tovpn_rd;
struct prefix tovpn_nexthop; /* unset => set to 0 */
uint32_t flags;
@@ -324,10 +325,16 @@ struct bgp_srv6_function {
char locator_name[SRV6_LOCNAME_SIZE];
};
+struct as_confed {
+ as_t as;
+ char *as_pretty;
+};
+
/* BGP instance structure. */
struct bgp {
/* AS number of this BGP instance. */
as_t as;
+ char *as_pretty;
/* Name of this BGP instance. */
char *name;
@@ -383,6 +390,7 @@ struct bgp {
uint16_t config;
#define BGP_CONFIG_CLUSTER_ID (1 << 0)
#define BGP_CONFIG_CONFEDERATION (1 << 1)
+#define BGP_CONFIG_ASNOTATION (1 << 2)
/* BGP router identifier. */
struct in_addr router_id;
@@ -394,7 +402,8 @@ struct bgp {
/* BGP confederation information. */
as_t confed_id;
- as_t *confed_peers;
+ char *confed_id_pretty;
+ struct as_confed *confed_peers;
int confed_peers_cnt;
struct thread
@@ -728,6 +737,7 @@ struct bgp {
/* RD for this VRF */
struct prefix_rd vrf_prd;
+ char *vrf_prd_pretty;
/* import rt list for the vrf instance */
struct list *vrf_import_rtl;
@@ -782,6 +792,8 @@ struct bgp {
bool allow_martian;
+ enum asnotation_mode asnotation;
+
QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(bgp);
@@ -1105,6 +1117,8 @@ struct peer {
/* Peer's remote AS number. */
int as_type;
as_t as;
+ /* for vty as format */
+ char *as_pretty;
/* Peer's local AS number. */
as_t local_as;
@@ -1113,6 +1127,8 @@ struct peer {
/* Peer's Change local AS number. */
as_t change_local_as;
+ /* for vty as format */
+ char *change_local_as_pretty;
/* Remote router ID. */
struct in_addr remote_id;
@@ -2131,7 +2147,7 @@ extern void bgp_recalculate_all_bestpaths(struct bgp *bgp);
extern struct peer *peer_create(union sockunion *su, const char *conf_if,
struct bgp *bgp, as_t local_as, as_t remote_as,
int as_type, struct peer_group *group,
- bool config_node);
+ bool config_node, const char *as_str);
extern struct peer *peer_create_accept(struct bgp *);
extern void peer_xfer_config(struct peer *dst, struct peer *src);
extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
@@ -2158,7 +2174,9 @@ extern void bgp_option_norib_set_runtime(void);
/* unset the bgp no-rib option during runtime and reset all peers */
extern void bgp_option_norib_unset_runtime(void);
-extern int bgp_get(struct bgp **, as_t *, const char *, enum bgp_instance_type);
+extern int bgp_get(struct bgp **bgp, as_t *as, const char *name,
+ enum bgp_instance_type kind, const char *as_pretty,
+ enum asnotation_mode asnotation);
extern void bgp_instance_up(struct bgp *);
extern void bgp_instance_down(struct bgp *);
extern int bgp_delete(struct bgp *);
@@ -2174,11 +2192,13 @@ extern void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set);
extern void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id);
extern void bgp_cluster_id_unset(struct bgp *bgp);
-extern void bgp_confederation_id_set(struct bgp *bgp, as_t as);
+extern void bgp_confederation_id_set(struct bgp *bgp, as_t as,
+ const char *as_str);
extern void bgp_confederation_id_unset(struct bgp *bgp);
extern bool bgp_confederation_peers_check(struct bgp *, as_t);
-extern void bgp_confederation_peers_add(struct bgp *bgp, as_t as);
+extern void bgp_confederation_peers_add(struct bgp *bgp, as_t as,
+ const char *as_str);
extern void bgp_confederation_peers_remove(struct bgp *bgp, as_t as);
extern void bgp_timers_set(struct bgp *, uint32_t keepalive, uint32_t holdtime,
@@ -2199,10 +2219,13 @@ extern void bgp_listen_limit_unset(struct bgp *bgp);
extern bool bgp_update_delay_active(struct bgp *);
extern bool bgp_update_delay_configured(struct bgp *);
extern bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi);
-extern void peer_as_change(struct peer *, as_t, int);
-extern int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *,
- int);
-extern int peer_group_remote_as(struct bgp *, const char *, as_t *, int);
+extern void peer_as_change(struct peer *peer, as_t as, int as_type,
+ const char *as_str);
+extern int peer_remote_as(struct bgp *bgp, union sockunion *su,
+ const char *conf_if, as_t *as, int as_type,
+ const char *as_str);
+extern int peer_group_remote_as(struct bgp *bgp, const char *peer_str, as_t *as,
+ int as_type, const char *as_str);
extern int peer_delete(struct peer *peer);
extern void peer_notify_unconfig(struct peer *peer);
extern int peer_group_delete(struct peer_group *);
@@ -2281,8 +2304,8 @@ extern int peer_distribute_unset(struct peer *, afi_t, safi_t, int);
extern int peer_allowas_in_set(struct peer *, afi_t, safi_t, int, int);
extern int peer_allowas_in_unset(struct peer *, afi_t, safi_t);
-extern int peer_local_as_set(struct peer *, as_t, bool no_prepend,
- bool replace_as);
+extern int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
+ bool replace_as, const char *as_str);
extern int peer_local_as_unset(struct peer *);
extern int peer_prefix_list_set(struct peer *, afi_t, safi_t, int,
@@ -2341,6 +2364,7 @@ extern void peer_tx_shutdown_message_unset(struct peer *);
extern void bgp_route_map_update_timer(struct thread *thread);
extern const char *bgp_get_name_by_role(uint8_t role);
+extern enum asnotation_mode bgp_get_asnotation(struct bgp *bgp);
extern void bgp_route_map_terminate(void);
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c
index 40cb8f8d5..5b6961d18 100644
--- a/bgpd/rfapi/bgp_rfapi_cfg.c
+++ b/bgpd/rfapi/bgp_rfapi_cfg.c
@@ -410,6 +410,7 @@ DEFUN (vnc_defaults_rd,
} else {
+ /* TODO: save RD format */
ret = str2prefix_rd(argv[1]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed rd\n");
@@ -2874,6 +2875,7 @@ DEFUN (vnc_nve_group_rd,
} else {
+ /* TODO: save RD format */
ret = str2prefix_rd(argv[1]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed rd\n");
@@ -3346,6 +3348,7 @@ DEFUN (vnc_vrf_policy_rd,
} else {
+ /* TODO: save RD format */
ret = str2prefix_rd(argv[1]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed rd\n");
@@ -3924,7 +3927,7 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
value);
} else
- vty_out(vty, " rd %pRD\n", &rfg->rd);
+ vty_out(vty, " rd %pRDP\n", &rfg->rd);
}
if (rfg->rt_import_list && rfg->rt_export_list
@@ -4144,7 +4147,7 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
value);
} else
- vty_out(vty, " rd %pRD\n",
+ vty_out(vty, " rd %pRDP\n",
&hc->default_rd);
}
if (hc->default_response_lifetime
@@ -4224,7 +4227,7 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
value);
} else
- vty_out(vty, " rd %pRD\n",
+ vty_out(vty, " rd %pRDP\n",
&rfg->rd);
}
if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) {
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index 0c8fdc72e..8d6db9d77 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -363,7 +363,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
vnc_zlog_debug_verbose(
- "%s: peer=%p, prefix=%pFX, prd=%pRD afi=%d, safi=%d bn=%p, bn->info=%p",
+ "%s: peer=%p, prefix=%pFX, prd=%pRDP afi=%d, safi=%d bn=%p, bn->info=%p",
__func__, peer, p, prd, afi, safi, bn,
(bn ? bgp_dest_get_bgp_path_info(bn) : NULL));
@@ -1053,7 +1053,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
bgp_process(bgp, bn, afi, safi);
vnc_zlog_debug_any(
- "%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%pRD)",
+ "%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%pRDP)",
__func__, safi2str(safi), buf, bn, prd);
done:
@@ -3712,7 +3712,7 @@ int rfapi_set_autord_from_vn(struct prefix_rd *rd, struct rfapi_ip_addr *vn)
memcpy(rd->val + 2, &vn->addr.v6.s6_addr32[3],
4); /* low order 4 bytes */
}
- vnc_zlog_debug_verbose("%s: auto-RD is set to %pRD", __func__, rd);
+ vnc_zlog_debug_verbose("%s: auto-RD is set to %pRDP", __func__, rd);
return 0;
}
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index 6d4fc53f8..a50440536 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -2082,7 +2082,7 @@ static void rfapiItBiIndexAdd(struct agg_node *rn, /* Import table VPN node */
assert(bpi);
assert(bpi->extra);
- vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRD", __func__, bpi,
+ vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRDP", __func__, bpi,
bpi->peer, &bpi->extra->vnc.import.rd);
sl = RFAPI_RDINDEX_W_ALLOC(rn);
@@ -2120,7 +2120,9 @@ static void rfapiItBiIndexDump(struct agg_node *rn)
char buf[RD_ADDRSTRLEN];
char buf_aux_pfx[PREFIX_STRLEN];
- prefix_rd2str(&k->extra->vnc.import.rd, buf, sizeof(buf));
+ prefix_rd2str(
+ &k->extra->vnc.import.rd, buf, sizeof(buf),
+ bgp_get_asnotation(k->peer ? k->peer->bgp : NULL));
if (k->extra->vnc.import.aux_prefix.family) {
prefix2str(&k->extra->vnc.import.aux_prefix,
buf_aux_pfx, sizeof(buf_aux_pfx));
@@ -2158,7 +2160,7 @@ static struct bgp_path_info *rfapiItBiIndexSearch(
strlcpy(buf_aux_pfx, "(nil)", sizeof(buf_aux_pfx));
vnc_zlog_debug_verbose(
- "%s want prd=%pRD, peer=%p, aux_prefix=%s", __func__,
+ "%s want prd=%pRDP, peer=%p, aux_prefix=%s", __func__,
prd, peer, buf_aux_pfx);
rfapiItBiIndexDump(rn);
}
@@ -2174,7 +2176,7 @@ static struct bgp_path_info *rfapiItBiIndexSearch(
bpi_result = bpi_result->next) {
#ifdef DEBUG_BI_SEARCH
vnc_zlog_debug_verbose(
- "%s: bpi has prd=%pRD, peer=%p", __func__,
+ "%s: bpi has prd=%pRDP, peer=%p", __func__,
&bpi_result->extra->vnc.import.rd,
bpi_result->peer);
#endif
@@ -2238,7 +2240,7 @@ static void rfapiItBiIndexDel(struct agg_node *rn, /* Import table VPN node */
struct skiplist *sl;
int rc;
- vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRD", __func__, bpi,
+ vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRDP", __func__, bpi,
bpi->peer, &bpi->extra->vnc.import.rd);
sl = RFAPI_RDINDEX(rn);
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c
index b15620741..f727f24f1 100644
--- a/bgpd/rfapi/rfapi_rib.c
+++ b/bgpd/rfapi/rfapi_rib.c
@@ -1114,7 +1114,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
skiplist_insert(slRibPt, &ori->rk, ori);
vnc_zlog_debug_verbose(
- "%s: nomatch lPendCost item %p in slRibPt, added (rd=%pRD)",
+ "%s: nomatch lPendCost item %p in slRibPt, added (rd=%pRDP)",
__func__, ri, &ori->rk.rd);
}
@@ -1356,7 +1356,7 @@ callback:
ri->last_sent_time = monotime(NULL);
#if DEBUG_RIB_SL_RD
vnc_zlog_debug_verbose(
- "%s: move route to recently deleted list, rd=%pRD",
+ "%s: move route to recently deleted list, rd=%pRDP",
__func__, &ri->rk.rd);
#endif
@@ -2252,7 +2252,7 @@ static int print_rib_sl(int (*fp)(void *, const char *, ...), struct vty *vty,
}
#endif
- fp(out, " %c %-20s %-15s %-15s %-4u %-8s %-8s %pRD\n",
+ fp(out, " %c %-20s %-15s %-15s %-4u %-8s %-8s %pRDP\n",
deleted ? 'r' : ' ', *printedprefix ? "" : str_pfx, str_vn,
str_un, ri->cost, str_lifetime, str_age, &ri->rk.rd);
diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c
index 0144c28d5..2b768b8f8 100644
--- a/bgpd/rfapi/rfapi_vty.c
+++ b/bgpd/rfapi/rfapi_vty.c
@@ -1589,7 +1589,7 @@ void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd)
vty_out(vty, " ");
rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr);
vty_out(vty, " %p %p ", rfd->response_cb, rfd->cookie);
- vty_out(vty, "%pRD", &rfd->rd);
+ vty_out(vty, "%pRDP", &rfd->rd);
vty_out(vty, " %d", rfd->response_lifetime);
vty_out(vty, " %s", (rfd->rfg ? rfd->rfg->name : "<orphaned>"));
vty_out(vty, "%s", HVTYNL);
@@ -4709,6 +4709,7 @@ static int vnc_add_vrf_prefix(struct vty *vty, const char *arg_vrf,
if (arg_rd) {
opt = &optary[cur_opt++];
opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
+ /* TODO: save RD format */
if (!str2prefix_rd(arg_rd, &opt->v.internal_rd)) {
vty_out(vty, "Malformed RD \"%s\"\n", arg_rd);
return CMD_WARNING_CONFIG_FAILED;