]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Add `no sid vpn per-vrf export` command
authorCarmine Scarpitta <carmine.scarpitta@uniroma2.it>
Tue, 23 Aug 2022 14:04:06 +0000 (16:04 +0200)
committerCarmine Scarpitta <carmine.scarpitta@uniroma2.it>
Tue, 18 Oct 2022 14:08:24 +0000 (16:08 +0200)
The command `sid vpn per-vrf export (1-255)|auto` can be used to export
IPv4 and IPv6 routes from a VRF to the VPN RIB using a single SRv6 SID
(End.DT46 behavior).

This commit implements the no form of the above command, which can be
used to disable the export of the IPv4/IPv6 routes:
`no sid vpn per-vrf export`.

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
bgpd/bgp_mplsvpn.c
bgpd/bgp_mplsvpn.h
bgpd/bgp_vty.c

index 33cc836dacaebfa6d67ada1da24585014f64af84..a68167977de870f99dd2ceb21505649a39068e34 100644 (file)
@@ -611,6 +611,18 @@ static void sid_register(struct bgp *bgp, const struct in6_addr *sid,
        listnode_add(bgp->srv6_functions, func);
 }
 
+static void sid_unregister(struct bgp *bgp, const struct in6_addr *sid)
+{
+       struct listnode *node, *nnode;
+       struct bgp_srv6_function *func;
+
+       for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func))
+               if (sid_same(&func->sid, sid)) {
+                       listnode_delete(bgp->srv6_functions, func);
+                       XFREE(MTYPE_BGP_SRV6_FUNCTION, func);
+               }
+}
+
 static bool sid_exist(struct bgp *bgp, const struct in6_addr *sid)
 {
        struct listnode *node;
@@ -860,6 +872,69 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
                return ensure_vrf_tovpn_sid_per_vrf(bgp_vpn, bgp_vrf);
 }
 
+void delete_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
+                                afi_t afi)
+{
+       int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
+       uint32_t tovpn_sid_index = 0;
+       bool tovpn_sid_auto = false;
+
+       if (debug)
+               zlog_debug("%s: try to remove SID for vrf %s: afi %s", __func__,
+                          bgp_vrf->name_pretty, afi2str(afi));
+
+       tovpn_sid_index = bgp_vrf->vpn_policy[afi].tovpn_sid_index;
+       tovpn_sid_auto = CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
+                                   BGP_VPN_POLICY_TOVPN_SID_AUTO);
+
+       /* skip when VPN is configured on vrf-instance */
+       if (tovpn_sid_index != 0 || tovpn_sid_auto)
+               return;
+
+       srv6_locator_chunk_free(bgp_vrf->vpn_policy[afi].tovpn_sid_locator);
+       bgp_vrf->vpn_policy[afi].tovpn_sid_locator = NULL;
+
+       if (bgp_vrf->vpn_policy[afi].tovpn_sid) {
+               sid_unregister(bgp_vrf, bgp_vrf->vpn_policy[afi].tovpn_sid);
+               XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->vpn_policy[afi].tovpn_sid);
+       }
+       bgp_vrf->vpn_policy[afi].tovpn_sid_transpose_label = 0;
+}
+
+void delete_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
+{
+       int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
+       uint32_t tovpn_sid_index = 0;
+       bool tovpn_sid_auto = false;
+
+       if (debug)
+               zlog_debug("%s: try to remove SID for vrf %s", __func__,
+                          bgp_vrf->name_pretty);
+
+       tovpn_sid_index = bgp_vrf->tovpn_sid_index;
+       tovpn_sid_auto =
+               CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VPN_POLICY_TOVPN_SID_AUTO);
+
+       /* skip when VPN is configured on vrf-instance */
+       if (tovpn_sid_index != 0 || tovpn_sid_auto)
+               return;
+
+       srv6_locator_chunk_free(bgp_vrf->tovpn_sid_locator);
+       bgp_vrf->tovpn_sid_locator = NULL;
+
+       if (bgp_vrf->tovpn_sid) {
+               sid_unregister(bgp_vrf, bgp_vrf->tovpn_sid);
+               XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->tovpn_sid);
+       }
+       bgp_vrf->tovpn_sid_transpose_label = 0;
+}
+
+void delete_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
+{
+       delete_vrf_tovpn_sid_per_af(bgp_vpn, bgp_vrf, afi);
+       delete_vrf_tovpn_sid_per_vrf(bgp_vpn, bgp_vrf);
+}
+
 /*
  * This function embeds upper `len` bits of `label` in `sid`,
  * starting at offset `offset` as seen from the MSB of `sid`.
index 03d7a0dd2ce16b9ea1035ff20e92fa21934a1713..7b57e4c75d1064cedeb2bb5a2ffa32d69d2bed10 100644 (file)
@@ -88,6 +88,10 @@ extern void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi);
 extern void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp);
 extern int vpn_leak_label_callback(mpls_label_t label, void *lblid, bool alloc);
 extern void ensure_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
+extern void delete_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
+extern void delete_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
+                                       afi_t afi);
+extern void delete_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
 extern void ensure_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
                                        afi_t afi);
 extern void ensure_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
@@ -258,6 +262,13 @@ static inline void vpn_leak_postchange(enum vpn_policy_direction direction,
                        vpn_leak_zebra_vrf_label_update(bgp_vrf, afi);
                }
 
+               if (bgp_vrf->vpn_policy[afi].tovpn_sid_index == 0 &&
+                   !CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
+                               BGP_VPN_POLICY_TOVPN_SID_AUTO) &&
+                   bgp_vrf->tovpn_sid_index == 0 &&
+                   !CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_AUTO))
+                       delete_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
+
                if (!bgp_vrf->vpn_policy[afi].tovpn_sid && !bgp_vrf->tovpn_sid)
                        ensure_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
 
index 427ad1b3321a3cc65b8c32fae79e2c404dcdb1d5..f380460a95731d64ce4a58e11ff6fcc5ddea265e 100644 (file)
@@ -9068,9 +9068,15 @@ DEFPY (bgp_sid_vpn_export,
                 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
 
        if (no) {
-               /* implement me */
-               vty_out(vty, "It's not implemented\n");
-               return CMD_WARNING_CONFIG_FAILED;
+               /* when per-VRF SID is not set, do nothing */
+               if (bgp->tovpn_sid_index == 0 &&
+                   !CHECK_FLAG(bgp->vrf_flags, BGP_VRF_TOVPN_SID_AUTO))
+                       return CMD_SUCCESS;
+
+               sid_idx = 0;
+               sid_auto = false;
+               bgp->tovpn_sid_index = 0;
+               UNSET_FLAG(bgp->vrf_flags, BGP_VRF_TOVPN_SID_AUTO);
        }
 
        if (bgp->vpn_policy[AFI_IP].tovpn_sid_index != 0 ||
@@ -9113,7 +9119,7 @@ DEFPY (bgp_sid_vpn_export,
                if (debug)
                        zlog_debug("%s: auto per-vrf sid alloc.", __func__);
                SET_FLAG(bgp->vrf_flags, BGP_VRF_TOVPN_SID_AUTO);
-       } else {
+       } else if (sid_idx != 0) {
                /* SID allocation index-mode */
                if (debug)
                        zlog_debug("%s: idx %ld per-vrf sid alloc.", __func__,
@@ -9138,6 +9144,15 @@ ALIAS (af_label_vpn_export,
        "Between current address-family and vpn\n"
        "For routes leaked from current address-family to vpn\n")
 
+ALIAS (bgp_sid_vpn_export,
+       no_bgp_sid_vpn_export_cmd,
+       "no$no sid vpn per-vrf export",
+       NO_STR
+       "sid value for VRF\n"
+       "Between current vrf and vpn\n"
+       "sid per-VRF (both IPv4 and IPv6 address families)\n"
+       "For routes leaked from current vrf to vpn\n")
+
 DEFPY (af_nexthop_vpn_export,
        af_nexthop_vpn_export_cmd,
        "[no] nexthop vpn export [<A.B.C.D|X:X::X:X>$nexthop_su]",
@@ -19913,6 +19928,7 @@ void bgp_vty_init(void)
        install_element(BGP_IPV4_NODE, &af_sid_vpn_export_cmd);
        install_element(BGP_IPV6_NODE, &af_sid_vpn_export_cmd);
        install_element(BGP_NODE, &bgp_sid_vpn_export_cmd);
+       install_element(BGP_NODE, &no_bgp_sid_vpn_export_cmd);
 
        bgp_vty_if_init();
 }