diff options
author | Yuqing Zhao <galadriel.zyq@alibaba-inc.com> | 2025-01-13 11:02:23 +0100 |
---|---|---|
committer | Yuqing Zhao <galadriel.zyq@alibaba-inc.com> | 2025-01-18 11:28:49 +0100 |
commit | 807d90050d147a371c14687b85ccb67fbd4607c4 (patch) | |
tree | 93eec79642f23e53c50b65649c25f0c3000f37f3 /staticd | |
parent | lib: Add a function to print SRv6 Endpoint Behavior Codepoints (diff) | |
download | frr-807d90050d147a371c14687b85ccb67fbd4607c4.tar.xz frr-807d90050d147a371c14687b85ccb67fbd4607c4.zip |
staticd: Add infrastructure for SRv6
This commit adds datastructures and helper functions required to support SRv6 in staticd.
* List of locators
* List of SIDs
* Data structure to represent an SRv6 SID
* Functions to allocate/deallocate an SRv6 SID
* Functions to allocate, deallocate and lookup a locator
* Function to initialize/Cleanup SRv6
Signed-off-by: Yuqing Zhao <galadriel.zyq@alibaba-inc.com>
Diffstat (limited to 'staticd')
-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 000000000..d8e55894f --- /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 000000000..bed0ab7fa --- /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 07ebe3c02..bdbacbdd6 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 += \ |