zebra: Allow multiple Explicit Sids support for same ctx

In the current code, we cannot allocate more than one sid for the same
ctx even if they are from different/same(with differente node len)
locator blocks.

For example, if we have the following config
    segment-routing
     srv6
      static-sids
       sid fcbb:bbbb:1::/48 locator MAIN behavior uN
       sid 1234:5678:1::/48 locator RAJA behavior uN
     srv6
      locators
       locator MAIN
        prefix fcbb:bbbb:1::/48 block-len 32 node-len 16 func-bits 16
       locator RAJA
        prefix 1234:5678:1::/48 block-len 32 node-len 16 func-bits 16

Although the locators blocks are different, and staticd request to
allocate multiple sid seems valid, zebra allocates only the first
static-sid and returns the below error for others.
ZEBRA: [NGMNY-JWMWQ] get_srv6_sid_explicit: cannot alloc SID 1234:5678:1:: for ctx End USP: ctx already associated with SID fcbb:bbbb:1::

But we should allow a node behave as a multiple Endpoints expecially if
we have a topology where the node resides at the intersection of
multiple zones/domain.

Fix is to simple remove the check. With fix for the above config,

ip -6 route show
1234:5678:1::/48 nhid 9  encap seg6local action End dev sr0 proto 196 metric 20 pref medium
fcbb:bbbb:1::/48 nhid 9  encap seg6local action End dev sr0 proto 196 metric 20 pref medium

Signed-off-by: Rajasekar Raja <rajasekarr@nvidia.com>
This commit is contained in:
Rajasekar Raja 2025-04-29 10:47:14 -07:00
parent 3dd4d417be
commit ebbae8cb92
2 changed files with 30 additions and 13 deletions

View file

@ -27,6 +27,7 @@ sys.path.append(os.path.join(CWD, "../"))
from lib import topotest
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
from time import sleep
pytestmark = [pytest.mark.staticd]
@ -319,6 +320,35 @@ def test_srv6_static_sids_sid_readd_all():
check_srv6_static_sids(router, "expected_srv6_sids.json")
def test_srv6_static_sids_sid_multiple_uN_behavior():
"""
Request for multiple uN with different locators
"""
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
router = tgen.gears["r1"]
router.vtysh_cmd(
"""
configure terminal
segment-routing
srv6
static-sids
sid fcbb:cccc:1::/48 locator MAIN1 behavior uN
srv6
locators
locator MAIN1
prefix fcbb:cccc:1::/48 block-len 32 node-len 16 func-bits 16
"""
)
sleep(1)
output = json.loads(router.vtysh_cmd("show ipv6 route static json"))
if "fcbb:bbbb:1::/48" not in output or "fcbb:cccc:1::/48" not in output:
assert False, "Failed. Expected entry for fcbb:cccc:1::/48 and fcbb:bbbb:1::/48"
def test_srv6_static_sids_srv6_disable():
"""
Disable SRv6

View file

@ -1521,19 +1521,6 @@ static int get_srv6_sid_explicit(struct zebra_srv6_sid **sid,
return 0;
}
/*
* It is not allowed to allocate an explicit SID for a given context if the context
* is already associated with an explicit SID
*/
if (s->sid->alloc_mode == SRV6_SID_ALLOC_MODE_EXPLICIT) {
zlog_err("%s: cannot alloc SID %pI6 for ctx %s: ctx already associated with SID %pI6",
__func__, sid_value,
srv6_sid_ctx2str(buf, sizeof(buf),
&s->ctx),
&s->sid->value);
return -1;
}
zctx = s;
break;
}