return 0;
}
+/* --- Zebra SRv6 SID format management functions --------------------------- */
+
+void zebra_srv6_sid_format_register(struct zebra_srv6_sid_format *format)
+{
+ struct zebra_srv6 *srv6 = zebra_srv6_get_default();
+
+ /* Ensure that the format is registered only once */
+ assert(!zebra_srv6_sid_format_lookup(format->name));
+
+ listnode_add(srv6->sid_formats, format);
+}
+
+void zebra_srv6_sid_format_unregister(struct zebra_srv6_sid_format *format)
+{
+ struct zebra_srv6 *srv6 = zebra_srv6_get_default();
+
+ listnode_delete(srv6->sid_formats, format);
+}
+
+struct zebra_srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name)
+{
+ struct zebra_srv6 *srv6 = zebra_srv6_get_default();
+ struct zebra_srv6_sid_format *format;
+ struct listnode *node;
+
+ for (ALL_LIST_ELEMENTS_RO(srv6->sid_formats, node, format))
+ if (!strncmp(name, format->name, sizeof(format->name)))
+ return format;
+
+ return NULL;
+}
+
+/*
+ * Helper function to create the SRv6 compressed format `usid-f3216`.
+ */
+static struct zebra_srv6_sid_format *create_srv6_sid_format_usid_f3216(void)
+{
+ struct zebra_srv6_sid_format *format = NULL;
+
+ format = zebra_srv6_sid_format_alloc(
+ ZEBRA_SRV6_SID_FORMAT_USID_F3216_NAME);
+
+ format->type = SRV6_SID_FORMAT_TYPE_USID;
+
+ /* Define block/node/function length */
+ format->block_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN;
+ format->node_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_NODE_LEN;
+ format->function_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_FUNCTION_LEN;
+ format->argument_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_ARGUMENT_LEN;
+
+ /* Define the ranges from which the SID function can be allocated */
+ format->config.usid.lib_start =
+ ZEBRA_SRV6_SID_FORMAT_USID_F3216_LIB_START;
+ format->config.usid.elib_start =
+ ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_START;
+ format->config.usid.elib_end = ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_END;
+ format->config.usid.wlib_start =
+ ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_START;
+ format->config.usid.wlib_end = ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_END;
+ format->config.usid.ewlib_start =
+ ZEBRA_SRV6_SID_FORMAT_USID_F3216_EWLIB_START;
+
+ return format;
+}
+
+/*
+ * Helper function to create the SRv6 uncompressed format.
+ */
+static struct zebra_srv6_sid_format *create_srv6_sid_format_uncompressed(void)
+{
+ struct zebra_srv6_sid_format *format = NULL;
+
+ format = zebra_srv6_sid_format_alloc(
+ ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME);
+
+ format->type = ZEBRA_SRV6_SID_FORMAT_TYPE_UNCOMPRESSED;
+
+ /* Define block/node/function length */
+ format->block_len = ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN;
+ format->node_len = ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN;
+ format->function_len =
+ ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNCTION_LEN;
+ format->argument_len =
+ ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_ARGUMENT_LEN;
+
+ /* Define the ranges from which the SID function can be allocated */
+ format->config.uncompressed.explicit_start =
+ ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START;
+
+ return format;
+}
+
void zebra_srv6_locator_add(struct srv6_locator *locator)
{
struct zebra_srv6 *srv6 = zebra_srv6_get_default();
struct zebra_srv6 *zebra_srv6_get_default(void)
{
static bool first_execution = true;
+ struct zebra_srv6_sid_format *format_usidf3216;
+ struct zebra_srv6_sid_format *format_uncompressed;
if (first_execution) {
first_execution = false;
srv6.locators = list_new();
+
+ /* Initialize list of SID formats */
+ srv6.sid_formats = list_new();
+ srv6.sid_formats->del = delete_zebra_srv6_sid_format;
+
+ /* Create SID format `usid-f3216` */
+ format_usidf3216 = create_srv6_sid_format_usid_f3216();
+ zebra_srv6_sid_format_register(format_usidf3216);
+
+ /* Create SID format `uncompressed` */
+ format_uncompressed = create_srv6_sid_format_uncompressed();
+ zebra_srv6_sid_format_register(format_uncompressed);
}
return &srv6;
}
void zebra_srv6_terminate(void)
{
struct srv6_locator *locator;
+ struct zebra_srv6_sid_format *format;
- if (!srv6.locators)
- return;
+ if (srv6.locators) {
+ while (listcount(srv6.locators)) {
+ locator = listnode_head(srv6.locators);
- while (listcount(srv6.locators)) {
- locator = listnode_head(srv6.locators);
+ listnode_delete(srv6.locators, locator);
+ srv6_locator_free(locator);
+ }
- listnode_delete(srv6.locators, locator);
- srv6_locator_free(locator);
+ list_delete(&srv6.locators);
}
- list_delete(&srv6.locators);
+ /* Free SRv6 SID formats */
+ if (srv6.sid_formats) {
+ while (listcount(srv6.sid_formats)) {
+ format = listnode_head(srv6.sid_formats);
+
+ zebra_srv6_sid_format_unregister(format);
+ zebra_srv6_sid_format_free(format);
+ }
+
+ list_delete(&srv6.sid_formats);
+ }
}
void zebra_srv6_init(void)
#include <pthread.h>
#include <plist.h>
+/* Default config for SRv6 SID `usid-f3216` format */
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_NAME "usid-f3216"
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN 32
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_NODE_LEN 16
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_FUNCTION_LEN 16
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_ARGUMENT_LEN 0
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_LIB_START 0xE000
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_START 0xFE00
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_END 0xFEFF
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_START 0xFFF0
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_END 0xFFF7
+#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_EWLIB_START 0xFFF7
+
+/* Default config for SRv6 SID `uncompressed` format */
+#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME "uncompressed-f4024"
+#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN 40
+#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN 24
+#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNCTION_LEN 16
+#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_ARGUMENT_LEN 0
+#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START 0xFF00
+#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNC_UNRESERVED_MIN 0x40
+
/* SRv6 instance structure. */
struct zebra_srv6 {
struct list *locators;
/* Source address for SRv6 encapsulation */
struct in6_addr encap_src_addr;
+
+ /* SRv6 SID formats */
+ struct list *sid_formats;
};
/* declare hooks for the basic API, so that it can be specialized or served
extern void zebra_srv6_encap_src_addr_set(struct in6_addr *src_addr);
extern void zebra_srv6_encap_src_addr_unset(void);
+void zebra_srv6_sid_format_register(struct zebra_srv6_sid_format *format);
+void zebra_srv6_sid_format_unregister(struct zebra_srv6_sid_format *format);
+struct zebra_srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name);
+
#endif /* _ZEBRA_SRV6_H */
prefix2str(&locator->prefix, str, sizeof(str));
vty_out(vty, "Name: %s\n", locator->name);
vty_out(vty, "Prefix: %s\n", str);
- vty_out(vty, "Block-Bit-Len: %u\n", locator->block_bits_length);
- vty_out(vty, "Node-Bit-Len: %u\n", locator->node_bits_length);
- vty_out(vty, "Function-Bit-Len: %u\n",
- locator->function_bits_length);
- vty_out(vty, "Argument-Bit-Len: %u\n",
- locator->argument_bits_length);
-
- if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID))
- vty_out(vty, "Behavior: uSID\n");
+ if (locator->sid_format) {
+ vty_out(vty, "Block-Bit-Len: %u\n",
+ locator->sid_format->block_len);
+ vty_out(vty, "Node-Bit-Len: %u\n",
+ locator->sid_format->node_len);
+ vty_out(vty, "Function-Bit-Len: %u\n",
+ locator->sid_format->function_len);
+ vty_out(vty, "Argument-Bit-Len: %u\n",
+ locator->sid_format->argument_len);
+
+ if (locator->sid_format->type ==
+ SRV6_SID_FORMAT_TYPE_USID)
+ vty_out(vty, "Behavior: uSID\n");
+ } else {
+ vty_out(vty, "Block-Bit-Len: %u\n",
+ locator->block_bits_length);
+ vty_out(vty, "Node-Bit-Len: %u\n",
+ locator->node_bits_length);
+ vty_out(vty, "Function-Bit-Len: %u\n",
+ locator->function_bits_length);
+ vty_out(vty, "Argument-Bit-Len: %u\n",
+ locator->argument_bits_length);
+
+ if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID))
+ vty_out(vty, "Behavior: uSID\n");
+ }
vty_out(vty, "Chunks:\n");
for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node,