From fa566a94af4c5b70fa917c5ca0c1db6808f676cc Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 22 Nov 2022 11:20:51 +0100 Subject: [PATCH] bgpd: store the route-distinguisher from config as a string The route-distinguisher string can be expressed in different ways when the AS number is part of the RD. And the configured string value has to be kept intact. The following vty commands store the string value internally: - router bgp / address-family ipv4 unicast / rd vpn export <> - router bgp / address-family l2vpn evpn / rd <> - router bgp / address-family l2vpn evpn / vni <> / rd <> The vty commands where RD is configured in the below places is not considered: - router bgp / rfapi related commands - router bgp / address-family xxx xxx / network .. rd <> Signed-off-by: Philippe Guibert --- bgpd/bgp_evpn.c | 7 +++++++ bgpd/bgp_evpn_private.h | 1 + bgpd/bgp_evpn_vty.c | 18 +++++++++++------- bgpd/bgp_route.c | 2 ++ bgpd/bgp_vty.c | 14 ++++++++------ bgpd/bgpd.c | 2 ++ bgpd/bgpd.h | 2 ++ bgpd/rfapi/bgp_rfapi_cfg.c | 3 +++ bgpd/rfapi/rfapi_vty.c | 1 + 9 files changed, 37 insertions(+), 13 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 323256816b..5bbc32d304 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -5937,6 +5937,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); } @@ -6041,6 +6043,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); } @@ -6675,6 +6679,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_private.h b/bgpd/bgp_evpn_private.h index 3f18e4e9f1..30a3ca670b 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -92,6 +92,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 e8a52cb430..e1f735f2b6 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -2233,7 +2233,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 @@ -2242,6 +2243,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. @@ -2263,7 +2265,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 */ @@ -2274,7 +2277,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, @@ -2285,6 +2288,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)) @@ -3493,7 +3497,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, @@ -6144,7 +6148,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; } @@ -6236,7 +6240,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; } @@ -7288,7 +7292,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_route.c b/bgpd/bgp_route.c index c46b8b4c2b..8f16f6cae8 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -15630,6 +15630,7 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp, /* "network" configuration display. */ label = decode_label(&bgp_static->label); + /* TODO: save RD format */ vty_out(vty, " network %pFX rd %pRDP", p, prd); if (safi == SAFI_MPLS_VPN) vty_out(vty, " label %u", label); @@ -15707,6 +15708,7 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp, inet_ntop(bgp_static->gatewayIp.family, &bgp_static->gatewayIp.u.prefix, buf2, sizeof(buf2)); + /* TODO: save RD format */ vty_out(vty, " 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, diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 0ea636764a..0f140baad5 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -9044,10 +9044,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); } @@ -15576,10 +15579,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( @@ -17153,8 +17155,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)) { diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 69557507d0..3d61f508d7 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3971,6 +3971,8 @@ 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); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 57685390c8..910cb42746 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -218,6 +218,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; @@ -751,6 +752,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; diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index 547893bfec..c1f64393c4 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -423,6 +423,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"); @@ -2887,6 +2888,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"); @@ -3359,6 +3361,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"); diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index dbbef2a077..c0a0ec2366 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -4722,6 +4722,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;