diff options
| -rw-r--r-- | bgpd/bgpd.c | 15 | ||||
| -rw-r--r-- | nhrpd/nhrp_peer.c | 5 | ||||
| -rw-r--r-- | staticd/static_zebra.c | 45 | ||||
| -rwxr-xr-x | tests/topotests/static_srv6_sids/test_static_srv6_sids.py | 30 |
4 files changed, 69 insertions, 26 deletions
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 342c3c6be6..c5d902521e 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3538,7 +3538,8 @@ peer_init: bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = MPLS_LABEL_NONE; - bgp->vpn_policy[afi].import_vrf = list_new(); + if (!bgp->vpn_policy[afi].import_vrf) + bgp->vpn_policy[afi].import_vrf = list_new(); bgp->vpn_policy[afi].import_vrf->del = bgp_vrf_string_name_delete; if (!hidden) { @@ -3556,7 +3557,7 @@ peer_init: bgp_mplsvpn_nh_label_bind_cache_init(&bgp->mplsvpn_nh_label_bind); - if (name) + if (name && !bgp->name) bgp->name = XSTRDUP(MTYPE_BGP_NAME, name); event_add_timer(bm->master, bgp_startup_timer_expire, bgp, @@ -4177,7 +4178,7 @@ int bgp_delete(struct bgp *bgp) peer_delete(peer); } - if (bgp->peer_self && !IS_BGP_INSTANCE_HIDDEN(bgp)) { + if (bgp->peer_self && (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating)) { peer_delete(bgp->peer_self); bgp->peer_self = NULL; } @@ -4187,7 +4188,7 @@ int bgp_delete(struct bgp *bgp) /* TODO - Other memory may need to be freed - e.g., NHT */ #ifdef ENABLE_BGP_VNC - if (!IS_BGP_INSTANCE_HIDDEN(bgp)) + if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating) rfapi_delete(bgp); #endif @@ -4238,7 +4239,7 @@ int bgp_delete(struct bgp *bgp) bgp_zebra_instance_deregister(bgp); } - if (!IS_BGP_INSTANCE_HIDDEN(bgp)) { + if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating) { /* Remove visibility via the master list - * there may however still be routes to be processed * still referencing the struct bgp. @@ -4250,7 +4251,7 @@ int bgp_delete(struct bgp *bgp) vrf = bgp_vrf_lookup_by_instance_type(bgp); bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false); - if (vrf && !IS_BGP_INSTANCE_HIDDEN(bgp)) + if (vrf && (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating)) bgp_vrf_unlink(bgp, vrf); /* Update EVPN VRF pointer */ @@ -4261,7 +4262,7 @@ int bgp_delete(struct bgp *bgp) bgp_set_evpn(bgp_get_default()); } - if (!IS_BGP_INSTANCE_HIDDEN(bgp)) { + if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating) { if (bgp->process_queue) work_queue_free_and_null(&bgp->process_queue); bgp_unlock(bgp); /* initial reference */ diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index fa11980c18..97932795a3 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -1355,6 +1355,11 @@ void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb) } break; case NHRP_ROUTE_NBMA_NEXTHOP: + if (hdr->hop_count == 0) { + nhrp_packet_send_error(&pp, NHRP_ERROR_HOP_COUNT_EXCEEDED, 0); + info = "hop count exceeded"; + goto drop; + } nhrp_peer_forward(peer, &pp); break; case NHRP_ROUTE_BLACKHOLE: diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 9a794d4d02..21a5eda6b4 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -615,8 +615,6 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid) struct seg6local_context ctx = {}; struct interface *ifp = NULL; struct vrf *vrf; - struct prefix_ipv6 sid_block = {}; - struct prefix_ipv6 locator_block = {}; struct prefix_ipv6 sid_locator = {}; if (!sid) @@ -699,22 +697,7 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid) break; } - sid_block = sid->addr; - sid_block.prefixlen = sid->locator->block_bits_length; - apply_mask(&sid_block); - - locator_block = sid->locator->prefix; - locator_block.prefixlen = sid->locator->block_bits_length; - apply_mask(&locator_block); - - if (prefix_same(&sid_block, &locator_block)) - ctx.block_len = sid->locator->block_bits_length; - else { - zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block, - &locator_block); - return; - } - + ctx.block_len = sid->locator->block_bits_length; sid_locator = sid->addr; sid_locator.prefixlen = sid->locator->block_bits_length + sid->locator->node_bits_length; apply_mask(&sid_locator); @@ -860,13 +843,37 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid) UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA); } +/* Validate if the sid block and locator block are the same */ +static bool static_zebra_sid_locator_block_check(struct static_srv6_sid *sid) +{ + struct prefix_ipv6 sid_block = {}; + struct prefix_ipv6 locator_block = {}; + + sid_block = sid->addr; + sid_block.prefixlen = sid->locator->block_bits_length; + apply_mask(&sid_block); + + locator_block = sid->locator->prefix; + locator_block.prefixlen = sid->locator->block_bits_length; + apply_mask(&locator_block); + + if (!prefix_same(&sid_block, &locator_block)) { + zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block, + &locator_block); + + return false; + } + + return true; +} + extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid) { struct srv6_sid_ctx ctx = {}; int ret = 0; struct vrf *vrf; - if (!sid) + if (!sid || !static_zebra_sid_locator_block_check(sid)) return; /* convert `srv6_endpoint_behavior_codepoint` to `seg6local_action_t` */ diff --git a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py index 565b38f625..ea148d18ea 100755 --- a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py +++ b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py @@ -172,6 +172,36 @@ def test_srv6_static_sids_sid_readd(): check_srv6_static_sids(router, "expected_srv6_sids.json") +def test_srv6_static_sids_wrong_sid_block(): + """ + The purpose of this test is to verify how FRR behaves when the user + provides an invalid configuration. + Add a new static Sid with a mismatch in locator and sid block + to make sure no Sid is allocated by zebra (TBD: Strict verify once show cmd + commit is merged (#16836)) + """ + router = get_topogen().gears["r1"] + router.vtysh_cmd( + """ + configure terminal + segment-routing + srv6 + locators + locator MAIN1 + prefix fcbb:1234:1::/48 block-len 32 node-len 16 func-bits 16 + srv6 + static-sids + sid fcbb:bbbb:1:fe50::/64 locator MAIN1 behavior uA interface sr0 nexthop 2001::3 + """ + ) + + output = json.loads(router.vtysh_cmd("show ipv6 route static json")) + if "fcbb:bbbb:1:fe50::/64" in output: + assert ( + False + ), "Failed. Expected no entry for fcbb:bbbb:1:fe50::/64 since loc and node block dont match" + + def test_srv6_static_sids_sid_delete_all(): """ Remove all static SIDs and verify they get removed |
