]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Add support for SRv6 SID formats
authorCarmine Scarpitta <cscarpit@cisco.com>
Thu, 6 Jun 2024 15:23:11 +0000 (17:23 +0200)
committerCarmine Scarpitta <cscarpit@cisco.com>
Thu, 13 Jun 2024 12:54:16 +0000 (14:54 +0200)
Add functionalities to manage SRv6 SID formats (register / unregister /
lookup) and create two SID formats upon SRv6 Manager initialization:
`uncompressed-f4024` and `usid-f3216`.

In future commits, we will add the CLI to allow the user to choose
between the two formats.

Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
zebra/zebra_srv6.c
zebra/zebra_srv6.h
zebra/zebra_srv6_vty.c

index bb872ef91c62d9ce7f6cf21bd0709096ad36bd3c..dffc6ca091bbb0fd494c6524c011ce6a13e1c71c 100644 (file)
@@ -90,6 +90,98 @@ static int zebra_srv6_cleanup(struct zserv *client)
        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();
@@ -222,10 +314,24 @@ struct zebra_srv6 srv6;
 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;
 }
@@ -430,18 +536,30 @@ void zebra_srv6_encap_src_addr_unset(void)
 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)
index 21936c332354447e89b11f9e0a04b5d27ba43681..a645c5cc0d4986da5543ff499455668754485233 100644 (file)
 #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
@@ -74,4 +99,8 @@ extern int release_daemon_srv6_locator_chunks(struct zserv *client);
 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 */
index d5cd30e64bfc5c54e0ae0874bdcb6130c33d9674..ddb092247510fdd6bcf3f4b53251d5de3245007f 100644 (file)
@@ -198,15 +198,32 @@ DEFUN (show_srv6_locator_detail,
                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,