summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_main.c2
-rw-r--r--bgpd/bgp_route.c6
-rw-r--r--bgpd/bgp_vty.c15
-rw-r--r--bgpd/bgpd.c22
-rw-r--r--isisd/isis_tlvs.c72
-rw-r--r--staticd/static_zebra.c13
-rwxr-xr-xtests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py30
-rw-r--r--tests/topotests/static_srv6_sids/expected_srv6_sids.json35
-rw-r--r--tests/topotests/static_srv6_sids/r1/frr.conf1
-rw-r--r--zebra/zebra_srv6.c23
10 files changed, 165 insertions, 54 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 9ca20c949a..9dbef791b0 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -327,7 +327,7 @@ static int bgp_vrf_disable(struct vrf *vrf)
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
- bgp = bgp_lookup_by_name(vrf->name);
+ bgp = bgp_lookup_by_name_filter(vrf->name, false);
if (bgp) {
vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index f2e61e1e7f..e932738cd4 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3885,6 +3885,12 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
BGP_PATH_ATTR_CHANGED);
UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
+ } else {
+ /*
+ * Ensure that on uninstall that the INSTALL_PENDING
+ * is no longer set
+ */
+ UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
}
/* call bmp hook for loc-rib route update / withdraw after flags were
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 046b18f224..e18f6443b5 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -122,6 +122,9 @@ FRR_CFG_DEFAULT_BOOL(BGP_ENFORCE_FIRST_AS,
{ .val_bool = false, .match_version = "< 9.1", },
{ .val_bool = true },
);
+FRR_CFG_DEFAULT_BOOL(BGP_RR_ALLOW_OUTBOUND_POLICY,
+ { .val_bool = false },
+);
DEFINE_HOOK(bgp_inst_config_write,
(struct bgp *bgp, struct vty *vty),
@@ -622,6 +625,8 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
BGP_FLAG_DYNAMIC_CAPABILITY);
if (DFLT_BGP_ENFORCE_FIRST_AS)
SET_FLAG((*bgp)->flags, BGP_FLAG_ENFORCE_FIRST_AS);
+ if (DFLT_BGP_RR_ALLOW_OUTBOUND_POLICY)
+ SET_FLAG((*bgp)->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
ret = BGP_SUCCESS;
}
@@ -19780,10 +19785,12 @@ int bgp_config_write(struct vty *vty)
}
}
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
- vty_out(vty,
- " bgp route-reflector allow-outbound-policy\n");
- }
+ if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY) !=
+ SAVE_BGP_RR_ALLOW_OUTBOUND_POLICY)
+ vty_out(vty, " %sbgp route-reflector allow-outbound-policy\n",
+ CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY) ? ""
+ : "no ");
+
if (CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID))
vty_out(vty, " bgp bestpath compare-routerid\n");
if (CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP))
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index edf90d3dd8..efb2c00fa5 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -3988,6 +3988,7 @@ int bgp_delete(struct bgp *bgp)
uint32_t a_ann_cnt = 0, a_l2_cnt = 0, a_l3_cnt = 0;
struct bgp *bgp_to_proc = NULL;
struct bgp *bgp_to_proc_next = NULL;
+ struct bgp *bgp_default = bgp_get_default();
assert(bgp);
@@ -4041,13 +4042,26 @@ int bgp_delete(struct bgp *bgp)
bgp_soft_reconfig_table_task_cancel(bgp, NULL, NULL);
/* make sure we withdraw any exported routes */
- vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP, bgp_get_default(),
- bgp);
- vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6, bgp_get_default(),
- bgp);
+ vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP, bgp_default, bgp);
+ vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6, bgp_default, bgp);
bgp_vpn_leak_unimport(bgp);
+ /*
+ * Release SRv6 SIDs, like it's done in `vpn_leak_postchange()`
+ * and bgp_sid_vpn_export_cmd/af_sid_vpn_export_cmd commands.
+ */
+ bgp->tovpn_sid_index = 0;
+ UNSET_FLAG(bgp->vrf_flags, BGP_VRF_TOVPN_SID_AUTO);
+ delete_vrf_tovpn_sid_per_vrf(bgp_default, bgp);
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+ bgp->vpn_policy[afi].tovpn_sid_index = 0;
+ UNSET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_AUTO);
+ delete_vrf_tovpn_sid_per_af(bgp_default, bgp, afi);
+
+ vpn_leak_zebra_vrf_sid_withdraw(bgp, afi);
+ }
+
bgp_vpn_release_label(bgp, AFI_IP, true);
bgp_vpn_release_label(bgp, AFI_IP6, true);
diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c
index 18b13547a5..8c97dcda2f 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -1053,9 +1053,8 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
adj->algorithm));
json_object_int_add(srv6_endx_sid_json,
"weight", adj->weight);
- json_object_string_add(srv6_endx_sid_json,
- "behavior",
- seg6local_action2str(
+ json_object_string_add(srv6_endx_sid_json, "behavior",
+ srv6_endpoint_behavior_codepoint2str(
adj->behavior));
json_object_boolean_add(
srv6_endx_sid_json, "flagB",
@@ -1081,22 +1080,17 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
for (adj = (struct isis_srv6_endx_sid_subtlv *)
exts->srv6_endx_sid.head;
adj; adj = adj->next) {
- sbuf_push(
- buf, indent,
- "SRv6 End.X SID: %pI6, Algorithm: %s, Weight: %hhu, Endpoint Behavior: %s, Flags: B:%c, S:%c, P:%c\n",
- &adj->sid,
- sr_algorithm_string(adj->algorithm),
- adj->weight,
- seg6local_action2str(adj->behavior),
- adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG
- ? '1'
- : '0',
- adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG
- ? '1'
- : '0',
- adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG
- ? '1'
- : '0');
+ sbuf_push(buf, indent,
+ "SRv6 End.X SID: %pI6, Algorithm: %s, Weight: %hhu, Endpoint Behavior: %s, Flags: B:%c, S:%c, P:%c\n",
+ &adj->sid, sr_algorithm_string(adj->algorithm),
+ adj->weight,
+ srv6_endpoint_behavior_codepoint2str(adj->behavior),
+ adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG ? '1'
+ : '0',
+ adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG ? '1'
+ : '0',
+ adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG ? '1'
+ : '0');
if (adj->subsubtlvs)
isis_format_subsubtlvs(adj->subsubtlvs,
buf, NULL,
@@ -1131,9 +1125,8 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
lan->algorithm));
json_object_int_add(srv6_lan_endx_sid_json,
"weight", lan->weight);
- json_object_string_add(srv6_lan_endx_sid_json,
- "behavior",
- seg6local_action2str(
+ json_object_string_add(srv6_lan_endx_sid_json, "behavior",
+ srv6_endpoint_behavior_codepoint2str(
lan->behavior));
json_object_boolean_add(
srv6_lan_endx_sid_json, "flagB",
@@ -1162,24 +1155,19 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
for (lan = (struct isis_srv6_lan_endx_sid_subtlv *)
exts->srv6_lan_endx_sid.head;
lan; lan = lan->next) {
- sbuf_push(
- buf, indent,
- "SRv6 Lan End.X SID: %pI6, Algorithm: %s, Weight: %hhu, Endpoint Behavior: %s, Flags: B:%c, S:%c, P:%c "
- "Neighbor-ID: %pSY\n",
- &lan->sid,
- sr_algorithm_string(lan->algorithm),
- lan->weight,
- seg6local_action2str(lan->behavior),
- lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG
- ? '1'
- : '0',
- lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG
- ? '1'
- : '0',
- lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG
- ? '1'
- : '0',
- lan->neighbor_id);
+ sbuf_push(buf, indent,
+ "SRv6 Lan End.X SID: %pI6, Algorithm: %s, Weight: %hhu, Endpoint Behavior: %s, Flags: B:%c, S:%c, P:%c "
+ "Neighbor-ID: %pSY\n",
+ &lan->sid, sr_algorithm_string(lan->algorithm),
+ lan->weight,
+ srv6_endpoint_behavior_codepoint2str(lan->behavior),
+ lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG ? '1'
+ : '0',
+ lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG ? '1'
+ : '0',
+ lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG ? '1'
+ : '0',
+ lan->neighbor_id);
if (lan->subsubtlvs)
isis_format_subsubtlvs(lan->subsubtlvs,
buf, NULL,
@@ -2823,7 +2811,7 @@ static void format_item_srv6_end_sid(uint16_t mtid, struct isis_item *i,
sid_json = json_object_new_object();
json_object_object_add(json, "srv6EndSid", sid_json);
json_object_string_add(sid_json, "endpointBehavior",
- seg6local_action2str(sid->behavior));
+ srv6_endpoint_behavior_codepoint2str(sid->behavior));
json_object_string_addf(sid_json, "sidValue", "%pI6", &sid->sid);
if (sid->subsubtlvs) {
struct json_object *subtlvs_json;
@@ -2836,7 +2824,7 @@ static void format_item_srv6_end_sid(uint16_t mtid, struct isis_item *i,
} else {
sbuf_push(buf, indent, "SRv6 End SID ");
sbuf_push(buf, 0, "Endpoint Behavior: %s, ",
- seg6local_action2str(sid->behavior));
+ srv6_endpoint_behavior_codepoint2str(sid->behavior));
sbuf_push(buf, 0, "SID value: %pI6\n", &sid->sid);
if (sid->subsubtlvs) {
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 057193aa08..6da2dfec90 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -1169,6 +1169,19 @@ static int static_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS)
DEBUGD(&static_dbg_srv6, "%s: SRv6 SID %pI6 %s: RELEASED", __func__, &sid_addr,
srv6_sid_ctx2str(buf, sizeof(buf), &ctx));
+ for (ALL_LIST_ELEMENTS_RO(srv6_sids, node, sid)) {
+ if (IPV6_ADDR_SAME(&sid->addr.prefix, &sid_addr)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found || !sid) {
+ zlog_err("SRv6 SID %pI6 %s: not found", &sid_addr,
+ srv6_sid_ctx2str(buf, sizeof(buf), &ctx));
+ return 0;
+ }
+
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID);
break;
diff --git a/tests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py b/tests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py
index cf590ad01d..5c0b909517 100755
--- a/tests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py
+++ b/tests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py
@@ -159,6 +159,36 @@ def test_sid_reachable_again_bgp_update():
check_ping("c11", "192.168.2.1", True, 10, 1)
+def test_sid_unreachable_no_router():
+ get_topogen().gears["r2"].vtysh_cmd(
+ """
+ configure terminal
+ no router bgp 65002 vrf vrf10
+ """
+ )
+ check_ping("c11", "192.168.2.1", False, 10, 1)
+
+
+def test_sid_reachable_again_no_router():
+ get_topogen().gears["r2"].vtysh_cmd(
+ """
+ configure terminal
+ router bgp 65002 vrf vrf10
+ bgp router-id 192.0.2.2
+ !
+ address-family ipv4 unicast
+ redistribute connected
+ sid vpn export 1
+ rd vpn export 65002:10
+ rt vpn both 0:10
+ import vpn
+ export vpn
+ exit-address-family
+ """
+ )
+ check_ping("c11", "192.168.2.1", True, 10, 1)
+
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
diff --git a/tests/topotests/static_srv6_sids/expected_srv6_sids.json b/tests/topotests/static_srv6_sids/expected_srv6_sids.json
index e1a2a16afe..5799d97988 100644
--- a/tests/topotests/static_srv6_sids/expected_srv6_sids.json
+++ b/tests/topotests/static_srv6_sids/expected_srv6_sids.json
@@ -1,4 +1,39 @@
{
+ "fcbb:bbbb:1::/48": [
+ {
+ "prefix": "fcbb:bbbb:1::/48",
+ "prefixLen": 48,
+ "protocol": "static",
+ "vrfId": 0,
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 1,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 9,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "directlyConnected": true,
+ "interfaceName": "sr0",
+ "active": true,
+ "weight": 1,
+ "seg6local": {
+ "action": "End"
+ },
+ "seg6localContext": {
+
+ }
+ }
+ ]
+ }
+ ],
"fcbb:bbbb:1:fe10::/64": [
{
"prefix": "fcbb:bbbb:1:fe10::/64",
diff --git a/tests/topotests/static_srv6_sids/r1/frr.conf b/tests/topotests/static_srv6_sids/r1/frr.conf
index 999e35c35b..b4904d9ac2 100644
--- a/tests/topotests/static_srv6_sids/r1/frr.conf
+++ b/tests/topotests/static_srv6_sids/r1/frr.conf
@@ -8,6 +8,7 @@ segment-routing
!
!
static-sids
+ sid fcbb:bbbb:1::/48 locator MAIN behavior uN
sid fcbb:bbbb:1:fe10::/64 locator MAIN behavior uDT4 vrf Vrf10
sid fcbb:bbbb:1:fe20::/64 locator MAIN behavior uDT6 vrf Vrf20
sid fcbb:bbbb:1:fe30::/64 locator MAIN behavior uDT46 vrf Vrf30
diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c
index 624f60e815..6d228c5e24 100644
--- a/zebra/zebra_srv6.c
+++ b/zebra/zebra_srv6.c
@@ -1547,9 +1547,26 @@ static int get_srv6_sid_explicit(struct zebra_srv6_sid **sid,
}
if (ctx->behavior == ZEBRA_SEG6_LOCAL_ACTION_END) {
- zlog_err("%s: invalid SM request arguments: explicit SID allocation not allowed for End/uN behavior",
- __func__);
- return -1;
+ zctx = zebra_srv6_sid_ctx_alloc();
+ zctx->ctx = *ctx;
+
+ *sid = zebra_srv6_sid_alloc(zctx, sid_value, locator, block, sid_func,
+ SRV6_SID_ALLOC_MODE_EXPLICIT);
+ if (!(*sid)) {
+ flog_err(EC_ZEBRA_SM_CANNOT_ASSIGN_SID,
+ "%s: failed to create SRv6 SID %s (%pI6)", __func__,
+ srv6_sid_ctx2str(buf, sizeof(buf), ctx), sid_value);
+ return -1;
+ }
+ (*sid)->ctx = zctx;
+ zctx->sid = *sid;
+ listnode_add(srv6->sids, zctx);
+
+ if (IS_ZEBRA_DEBUG_SRV6)
+ zlog_debug("%s: allocated explicit SRv6 SID %pI6 for context %s", __func__,
+ &(*sid)->value, srv6_sid_ctx2str(buf, sizeof(buf), ctx));
+
+ return 1;
}
/* Allocate an explicit SID function for the SID */