bgpd: support for as notation format for route distinguisher

RD may be built based on an AS number. Like for the AS, the RD
may use the AS notation. The two below examples can illustrate:

RD 1.1:20 stands for an AS4B:NN RD with AS4B=65536 in dot format.
RD 0.1:20 stands for an AS2B:NNNN RD with AS2B=0.1 in dot+ format.

This commit adds the asnotation mode to prefix_rd2str() API so as
to pick up the relevant display.

Two new printfrr extensions are available to display the RD with
the two above display methods.
- The pRDD extension stands for dot asnotation format
- The pRDE extension stands for dot+ asnotation format.
- The pRD extension has been renamed to pRDP extension

The code is changed each time '%pRD' printf extension is called.
Possibly, the asnotation may change the output, then a macro defines
the asnotation mode to use. A side effect of forging the mode to
use is that the string could not be concatenated with other strings
in vty_out and snprintfrr. Those functions have been called multiple
times. When zlog_debug needs to display the RD with some other string,
the prefix_rd2str() old API is used instead of the printf extension.

Some code has been kept untouched:
- code related to running-config. Actually, wherever an RD is displayed,
its configured name should be dumped.
- bgp rfapi code
- bgp evpn multihoming code (partially done), since the logic is
missing to get the asnotation of 'struct bgp_evpn_es'.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2022-11-22 09:57:10 +01:00
parent 44a4d55ed8
commit 4a8cd6ad7f
19 changed files with 223 additions and 113 deletions

View File

@ -2651,6 +2651,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
@ -2704,11 +2705,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;

View File

@ -2406,7 +2406,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));
@ -2421,7 +2422,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));
}
}
@ -2535,7 +2536,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)) {
@ -2573,7 +2574,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);
}
@ -2650,7 +2651,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",
@ -4009,13 +4010,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();
@ -4039,9 +4045,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":"-");

View File

@ -387,7 +387,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");
@ -411,7 +413,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");
@ -474,8 +479,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();
@ -484,7 +491,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",
@ -525,7 +533,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 &&
@ -1004,7 +1014,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");
@ -1020,7 +1032,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);
}
@ -1104,11 +1117,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();
@ -1125,7 +1140,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",
@ -1155,8 +1172,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)) {
@ -2791,7 +2808,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);
@ -2874,7 +2892,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;
@ -2929,7 +2949,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.
@ -3056,7 +3076,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();
@ -6401,7 +6421,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",
@ -6437,7 +6459,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)

View File

@ -1868,7 +1868,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)) {
@ -1907,6 +1907,9 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
return false;
}
if (debug)
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.
*/
@ -1915,15 +1918,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;
@ -2418,7 +2420,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
@ -2553,8 +2555,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],

View File

@ -957,11 +957,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;

View File

@ -817,6 +817,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));
@ -826,7 +827,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(
@ -836,13 +838,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);
}

View File

@ -1205,14 +1205,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,

View File

@ -101,10 +101,10 @@ int str2prefix_rd(const char *str, struct prefix_rd *prd)
{
int ret = 0;
char *p;
char *p2;
struct stream *s = NULL;
char *half = NULL;
struct in_addr addr;
as_t as_val;
prd->family = AF_UNSPEC;
prd->prefixlen = 64;
@ -116,22 +116,15 @@ int str2prefix_rd(const char *str, struct prefix_rd *prd)
if (!all_digit(p + 1))
goto out;
/* case AS dot format is used */
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));
@ -140,14 +133,12 @@ int str2prefix_rd(const char *str, struct prefix_rd *prd)
stream_putw(s, as_val);
stream_putl(s, atol(p + 1));
}
} 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));
}
} else
goto out;
memcpy(prd->val, s->data, 8);
ret = 1;
@ -158,12 +149,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);
@ -173,11 +166,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);
@ -212,16 +209,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);
}

View File

@ -23,6 +23,9 @@
#ifndef _QUAGGA_BGP_RD_H
#define _QUAGGA_BGP_RD_H
#include "asn.h"
#include "prefix.h"
/* RD types */
#define RD_TYPE_AS 0
#define RD_TYPE_IP 1
@ -35,6 +38,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;
@ -67,7 +80,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);

View File

@ -10260,10 +10260,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);
@ -10276,12 +10277,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));
}
}
}
@ -11682,7 +11686,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,
@ -11832,13 +11836,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 {
@ -11848,7 +11855,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);
@ -12057,8 +12065,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);
}
}
@ -14467,7 +14476,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,
@ -15620,7 +15630,7 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
/* "network" configuration display. */
label = decode_label(&bgp_static->label);
vty_out(vty, " network %pFX rd %pRD", p, prd);
vty_out(vty, " network %pFX rd %pRDP", p, prd);
if (safi == SAFI_MPLS_VPN)
vty_out(vty, " label %u", label);
@ -15698,7 +15708,7 @@ 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",
" network %s rd %pRDP ethtag %u label %u esi %s gwip %s routermac %s\n",
buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
decode_label(&bgp_static->label), esi_buf, buf2,
macrouter);

View File

@ -15647,8 +15647,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]) {

View File

@ -3937,7 +3937,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
@ -4157,7 +4157,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
@ -4237,7 +4237,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) {

View File

@ -376,7 +376,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));
@ -1066,7 +1066,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:
@ -3725,7 +3725,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;
}

View File

@ -2097,7 +2097,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);
@ -2135,7 +2135,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));
@ -2173,7 +2175,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);
}
@ -2189,7 +2191,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
@ -2253,7 +2255,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);

View File

@ -1127,7 +1127,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);
}
@ -1369,7 +1369,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
@ -2265,7 +2265,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);

View File

@ -1602,7 +1602,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);

View File

@ -212,6 +212,17 @@ void asn_asn2json_array(json_object *jseg_list, as_t asn,
}
}
char *asn_asn2string(const as_t *asn, char *buf, size_t len,
enum asnotation_mode asnotation)
{
if ((asnotation == ASNOTATION_PLAIN) ||
((asnotation == ASNOTATION_DOT) && *asn < UINT16_MAX))
snprintf(buf, len, "%u", *asn);
else
asn_asn2asdot(*asn, buf, len);
return buf;
}
static ssize_t printfrr_asnotation(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr,
enum asnotation_mode asnotation)
@ -223,11 +234,7 @@ static ssize_t printfrr_asnotation(struct fbuf *buf, struct printfrr_eargs *ea,
if (!ptr)
return bputs(buf, "(null)");
asn = ptr;
if ((asnotation == ASNOTATION_PLAIN) ||
((asnotation == ASNOTATION_DOT) && *asn < UINT16_MAX))
snprintf(as_str, sizeof(as_str), "%u", *asn);
else
asn_asn2asdot(*asn, as_str, sizeof(as_str));
asn_asn2string(asn, as_str, sizeof(as_str), asnotation);
return bputs(buf, as_str);
}

View File

@ -53,6 +53,8 @@ void asn_asn2json_array(json_object *jseg_list, as_t asn,
enum asnotation_mode asnotation);
void asn_asn2json(json_object *jseg_list, const char *attr,
as_t asn, enum asnotation_mode asnotation);
extern char *asn_asn2string(const as_t *as, char *buf, size_t len,
enum asnotation_mode asnotation);
/* display AS in appropriate format */
#ifdef _FRR_ATTRIBUTE_PRINTFRR
#pragma FRR printfrr_ext "%pASP" (as_t *)

View File

@ -659,7 +659,10 @@ static inline bool ipv4_mcast_ssm(const struct in_addr *addr)
#pragma FRR printfrr_ext "%pFX" (struct prefix_eth *)
#pragma FRR printfrr_ext "%pFX" (struct prefix_evpn *)
#pragma FRR printfrr_ext "%pFX" (struct prefix_fs *)
#pragma FRR printfrr_ext "%pRD" (struct prefix_rd *)
#pragma FRR printfrr_ext "%pRDP" (struct prefix_rd *)
/* RD with AS4B with dot and dot+ format */
#pragma FRR printfrr_ext "%pRDD" (struct prefix_rd *)
#pragma FRR printfrr_ext "%pRDE" (struct prefix_rd *)
#pragma FRR printfrr_ext "%pPSG4" (struct prefix_sg *)
#endif