]> git.puffer.fish Git - matthieu/frr.git/commitdiff
staticd: Add infrastructure for SRv6
authorYuqing Zhao <galadriel.zyq@alibaba-inc.com>
Mon, 13 Jan 2025 10:02:23 +0000 (11:02 +0100)
committerYuqing Zhao <galadriel.zyq@alibaba-inc.com>
Sat, 18 Jan 2025 10:28:49 +0000 (10:28 +0000)
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>
staticd/static_srv6.c [new file with mode: 0644]
staticd/static_srv6.h [new file with mode: 0644]
staticd/subdir.am

diff --git a/staticd/static_srv6.c b/staticd/static_srv6.c
new file mode 100644 (file)
index 0000000..d8e5589
--- /dev/null
@@ -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 (file)
index 0000000..bed0ab7
--- /dev/null
@@ -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__ */
index 07ebe3c02c27ecb9cf7f25840e61bd2e9db02c4d..bdbacbdd68c90cf7b9d1cc3922968c0bc34d557a 100644 (file)
@@ -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 += \