diff options
| -rw-r--r-- | bgpd/bgp_main.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 6 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 15 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 22 | ||||
| -rw-r--r-- | isisd/isis_tlvs.c | 72 | ||||
| -rw-r--r-- | staticd/static_zebra.c | 13 | ||||
| -rwxr-xr-x | tests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py | 30 | ||||
| -rw-r--r-- | tests/topotests/static_srv6_sids/expected_srv6_sids.json | 35 | ||||
| -rw-r--r-- | tests/topotests/static_srv6_sids/r1/frr.conf | 1 | ||||
| -rw-r--r-- | zebra/zebra_srv6.c | 23 |
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 */ |
