diff options
| author | Carmine Scarpitta <cscarpit@cisco.com> | 2025-02-07 17:47:45 +0100 | 
|---|---|---|
| committer | Mergify <37929162+mergify[bot]@users.noreply.github.com> | 2025-02-13 18:38:16 +0000 | 
| commit | fce911649bb656a174cc2d47c708a548d5b6676f (patch) | |
| tree | 2a91998adfa4e07a24a06f5beac581f778593dd8 | |
| parent | dcebe85aa699cf52aed4b5e7cd4c0e466c734ada (diff) | |
staticd: Fix SRv6 SID installation and deletion
The SRv6 support in staticd (PR #16894) does not set the correct SID
parameters (block length, node length, function length).
This commit fixes the issue and computes the correct parameters.
Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
(cherry picked from commit e1654ba5548625981d2b9ff580b2fb6e2ae9d5dc)
| -rw-r--r-- | staticd/static_zebra.c | 62 | 
1 files changed, 54 insertions, 8 deletions
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 6da2dfec90..9a794d4d02 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -615,6 +615,9 @@ 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)  		return; @@ -696,10 +699,30 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid)  		break;  	} -	ctx.block_len = sid->locator->block_bits_length; -	ctx.node_len = sid->locator->node_bits_length; -	ctx.function_len = sid->locator->function_bits_length; -	ctx.argument_len = sid->locator->argument_bits_length; +	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; +	} + +	sid_locator = sid->addr; +	sid_locator.prefixlen = sid->locator->block_bits_length + sid->locator->node_bits_length; +	apply_mask(&sid_locator); + +	if (prefix_same(&sid_locator, &sid->locator->prefix)) +		ctx.node_len = sid->locator->node_bits_length; + +	ctx.function_len = sid->addr.prefixlen - (ctx.block_len + ctx.node_len);  	/* Attach the SID to the SRv6 interface */  	if (!ifp) { @@ -724,6 +747,9 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid)  	struct interface *ifp = NULL;  	struct seg6local_context ctx = {};  	struct vrf *vrf; +	struct prefix_ipv6 sid_block = {}; +	struct prefix_ipv6 locator_block = {}; +	struct prefix_ipv6 sid_locator = {};  	if (!sid)  		return; @@ -803,10 +829,30 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid)  		}  	} -	ctx.block_len = sid->locator->block_bits_length; -	ctx.node_len = sid->locator->node_bits_length; -	ctx.function_len = sid->locator->function_bits_length; -	ctx.argument_len = sid->locator->argument_bits_length; +	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; +	} + +	sid_locator = sid->addr; +	sid_locator.prefixlen = sid->locator->block_bits_length + sid->locator->node_bits_length; +	apply_mask(&sid_locator); + +	if (prefix_same(&sid_locator, &sid->locator->prefix)) +		ctx.node_len = sid->locator->node_bits_length; + +	ctx.function_len = sid->addr.prefixlen - (ctx.block_len + ctx.node_len);  	static_zebra_send_localsid(ZEBRA_ROUTE_DELETE, &sid->addr.prefix, sid->addr.prefixlen,  				   ifp->ifindex, action, &ctx);  | 
