summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgpd.c15
-rw-r--r--nhrpd/nhrp_peer.c5
-rw-r--r--staticd/static_zebra.c45
-rwxr-xr-xtests/topotests/static_srv6_sids/test_static_srv6_sids.py30
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