diff options
| -rw-r--r-- | staticd/static_srv6.c | 134 | ||||
| -rw-r--r-- | staticd/static_srv6.h | 99 | ||||
| -rw-r--r-- | staticd/subdir.am | 2 | 
3 files changed, 235 insertions, 0 deletions
diff --git a/staticd/static_srv6.c b/staticd/static_srv6.c new file mode 100644 index 0000000000..d8e55894fe --- /dev/null +++ b/staticd/static_srv6.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * STATICd - Segment Routing over IPv6 (SRv6) code + * Copyright (C) 2025 Alibaba Inc. + *               Yuqing Zhao + *               Lingyu Zhang + */ +#include <zebra.h> + +#include "vrf.h" +#include "nexthop.h" + +#include "static_routes.h" +#include "static_srv6.h" +#include "static_vrf.h" +#include "static_zebra.h" + +/* + * List of SRv6 SIDs. + */ +struct list *srv6_locators; +struct list *srv6_sids; + +DEFINE_MTYPE_STATIC(STATIC, STATIC_SRV6_LOCATOR, "Static SRv6 locator"); +DEFINE_MTYPE_STATIC(STATIC, STATIC_SRV6_SID, "Static SRv6 SID"); + +/* + * Allocate an SRv6 SID object and initialize the fields common to all the + * behaviors (i.e., SID address and behavor). + */ +struct static_srv6_sid *static_srv6_sid_alloc(struct prefix_ipv6 *addr) +{ +	struct static_srv6_sid *sid = NULL; + +	sid = XCALLOC(MTYPE_STATIC_SRV6_SID, sizeof(struct static_srv6_sid)); +	sid->addr = *addr; + +	return sid; +} + +void static_srv6_sid_free(struct static_srv6_sid *sid) +{ +	XFREE(MTYPE_STATIC_SRV6_SID, sid); +} + +struct static_srv6_locator *static_srv6_locator_lookup(const char *name) +{ +	struct static_srv6_locator *locator; +	struct listnode *node; + +	for (ALL_LIST_ELEMENTS_RO(srv6_locators, node, locator)) +		if (!strncmp(name, locator->name, SRV6_LOCNAME_SIZE)) +			return locator; +	return NULL; +} + +/* + * Look-up an SRv6 SID in the list of SRv6 SIDs. + */ +struct static_srv6_sid *static_srv6_sid_lookup(struct prefix_ipv6 *sid_addr) +{ +	struct static_srv6_sid *sid; +	struct listnode *node; + +	for (ALL_LIST_ELEMENTS_RO(srv6_sids, node, sid)) +		if (memcmp(&sid->addr, sid_addr, sizeof(struct prefix_ipv6)) == 0) +			return sid; + +	return NULL; +} + +struct static_srv6_locator *static_srv6_locator_alloc(const char *name) +{ +	struct static_srv6_locator *locator = NULL; + +	locator = XCALLOC(MTYPE_STATIC_SRV6_LOCATOR, sizeof(struct static_srv6_locator)); +	strlcpy(locator->name, name, sizeof(locator->name)); + +	return locator; +} + +void static_srv6_locator_free(struct static_srv6_locator *locator) +{ +	XFREE(MTYPE_STATIC_SRV6_LOCATOR, locator); +} + +void delete_static_srv6_locator(void *val) +{ +	static_srv6_locator_free((struct static_srv6_locator *)val); +} + +/* + * Remove an SRv6 SID from the zebra RIB (if it was previously installed) and + * release the memory previously allocated for the SID. + */ +void static_srv6_sid_del(struct static_srv6_sid *sid) +{ +	if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID)) { +		static_zebra_release_srv6_sid(sid); +		UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID); +	} + +	if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA)) { +		static_zebra_srv6_sid_uninstall(sid); +		UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA); +	} + +	XFREE(MTYPE_STATIC_SRV6_SID, sid); +} + +void delete_static_srv6_sid(void *val) +{ +	static_srv6_sid_free((struct static_srv6_sid *)val); +} + +/* + * Initialize SRv6 data structures. + */ +void static_srv6_init(void) +{ +	srv6_locators = list_new(); +	srv6_locators->del = delete_static_srv6_locator; +	srv6_sids = list_new(); +	srv6_sids->del = delete_static_srv6_sid; +} + +/* + * Clean up all the SRv6 data structures. + */ +void static_srv6_cleanup(void) +{ +	list_delete(&srv6_locators); +	list_delete(&srv6_sids); +} diff --git a/staticd/static_srv6.h b/staticd/static_srv6.h new file mode 100644 index 0000000000..bed0ab7fa5 --- /dev/null +++ b/staticd/static_srv6.h @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * STATICd - Segment Routing over IPv6 (SRv6) header + * Copyright (C) 2025 Alibaba Inc. + *               Yuqing Zhao + *               Lingyu Zhang + */ +#ifndef __STATIC_SRV6_H__ +#define __STATIC_SRV6_H__ + +#include "vrf.h" +#include "srv6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Attributes for an SRv6 SID */ +struct static_srv6_sid_attributes { +	/* VRF name */ +	char vrf_name[VRF_NAMSIZ]; +	char ifname[IFNAMSIZ]; +	struct in6_addr nh6; +}; + +/* Static SRv6 SID */ +struct static_srv6_sid { +	/* SRv6 SID address */ +	struct prefix_ipv6 addr; +	/* behavior bound to the SRv6 SID */ +	enum srv6_endpoint_behavior_codepoint behavior; +	/* SID attributes */ +	struct static_srv6_sid_attributes attributes; + +	/* SRv6 SID flags */ +	uint8_t flags; +/* + * this SRv6 SID has been allocated by SID Manager + * and can be installed in the zebra RIB + */ +#define STATIC_FLAG_SRV6_SID_VALID (1 << 0) +/* this SRv6 SID has been installed in the zebra RIB */ +#define STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA (1 << 1) + +	char locator_name[SRV6_LOCNAME_SIZE]; +	struct static_srv6_locator *locator; +}; + +struct static_srv6_locator { +	char name[SRV6_LOCNAME_SIZE]; +	struct prefix_ipv6 prefix; + +	/* +	 * Bit length of SRv6 locator described in +	 * draft-ietf-bess-srv6-services-05#section-3.2.1 +	 */ +	uint8_t block_bits_length; +	uint8_t node_bits_length; +	uint8_t function_bits_length; +	uint8_t argument_bits_length; + +	uint8_t flags; +}; + +/* List of SRv6 SIDs. */ +extern struct list *srv6_locators; +extern struct list *srv6_sids; + +/* + * Allocate an SRv6 SID object and initialize its fields, SID address and + * behavor. + */ +extern struct static_srv6_sid *static_srv6_sid_alloc(struct prefix_ipv6 *addr); +extern void static_srv6_sid_free(struct static_srv6_sid *sid); +/* Look-up an SRv6 SID in the list of SRv6 SIDs. */ +extern struct static_srv6_sid *static_srv6_sid_lookup(struct prefix_ipv6 *sid_addr); +/* + * Remove an SRv6 SID from the zebra RIB (if it was previously installed) and + * release the memory previously allocated for the SID. + */ +extern void static_srv6_sid_del(struct static_srv6_sid *sid); + +/* Initialize SRv6 data structures. */ +extern void static_srv6_init(void); +/* Clean up all the SRv6 data structures. */ +extern void static_srv6_cleanup(void); + +struct static_srv6_locator *static_srv6_locator_alloc(const char *name); +void static_srv6_locator_free(struct static_srv6_locator *locator); +struct static_srv6_locator *static_srv6_locator_lookup(const char *name); + +void delete_static_srv6_sid(void *val); +void delete_static_srv6_locator(void *val); + +#ifdef __cplusplus +} +#endif + +#endif /* __STATIC_SRV6_H__ */ diff --git a/staticd/subdir.am b/staticd/subdir.am index 07ebe3c02c..bdbacbdd68 100644 --- a/staticd/subdir.am +++ b/staticd/subdir.am @@ -19,6 +19,7 @@ staticd_libstatic_a_SOURCES = \  	staticd/static_vty.c \  	staticd/static_nb.c \  	staticd/static_nb_config.c \ +	staticd/static_srv6.c \  	# end  noinst_HEADERS += \ @@ -29,6 +30,7 @@ noinst_HEADERS += \  	staticd/static_vty.h \  	staticd/static_vrf.h \  	staticd/static_nb.h \ +	staticd/static_srv6.h \  	# end  clippy_scan += \  | 
