diff options
| -rw-r--r-- | bgpd/bgp_debug.c | 11 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_mh.c | 25 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_vty.c | 54 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 20 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn_snmp.c | 6 | ||||
| -rw-r--r-- | bgpd/bgp_nexthop.c | 17 | ||||
| -rw-r--r-- | bgpd/bgp_nht.c | 16 | ||||
| -rw-r--r-- | bgpd/bgp_rd.c | 67 | ||||
| -rw-r--r-- | bgpd/bgp_rd.h | 16 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 44 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 4 | ||||
| -rw-r--r-- | bgpd/rfapi/bgp_rfapi_cfg.c | 6 | ||||
| -rw-r--r-- | bgpd/rfapi/rfapi.c | 6 | ||||
| -rw-r--r-- | bgpd/rfapi/rfapi_import.c | 12 | ||||
| -rw-r--r-- | bgpd/rfapi/rfapi_rib.c | 6 | ||||
| -rw-r--r-- | bgpd/rfapi/rfapi_vty.c | 2 | ||||
| -rw-r--r-- | lib/asn.c | 17 | ||||
| -rw-r--r-- | lib/asn.h | 2 | ||||
| -rw-r--r-- | lib/prefix.h | 5 | 
19 files changed, 223 insertions, 113 deletions
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index f01c3e4f35..91156b9ed0 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -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; diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index 7ad0816631..dd40a072f9 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -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":"-"); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 067ad525c2..e8a52cb430 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -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) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 33e7d971ad..a892fe261c 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -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], diff --git a/bgpd/bgp_mplsvpn_snmp.c b/bgpd/bgp_mplsvpn_snmp.c index ea147e55b9..7407d44a25 100644 --- a/bgpd/bgp_mplsvpn_snmp.c +++ b/bgpd/bgp_mplsvpn_snmp.c @@ -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; diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 77e26037c0..f666c3a5e2 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -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);  	} diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index cf8ff524e9..595aa46355 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -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, diff --git a/bgpd/bgp_rd.c b/bgpd/bgp_rd.c index b4bcbdb804..f2ecd3de5f 100644 --- a/bgpd/bgp_rd.c +++ b/bgpd/bgp_rd.c @@ -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); +} diff --git a/bgpd/bgp_rd.h b/bgpd/bgp_rd.h index 2aee44c721..aa9bc0b872 100644 --- a/bgpd/bgp_rd.h +++ b/bgpd/bgp_rd.h @@ -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); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 9d9422b362..c46b8b4c2b 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 36b1707a1e..0ea636764a 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -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]) { diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index b65d90e1b3..547893bfec 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -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) { diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 80d0b3e269..9209b34653 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -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;  } diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 5db40be362..7024797cf9 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -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); diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 50a10c3b1d..b4600d5203 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -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); diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index e04938fde3..dbbef2a077 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -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); @@ -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);  } @@ -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 *) diff --git a/lib/prefix.h b/lib/prefix.h index 7de8d7903e..be049ad8a7 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -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  | 
