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;
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`.
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);
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);
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 ||
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__,
"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]",
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();
}