mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 12:41:21 +00:00
zebra: Add support for SRv6 SID formats
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>
This commit is contained in:
parent
021386a34e
commit
1298867671
@ -90,6 +90,98 @@ static int zebra_srv6_cleanup(struct zserv *client)
|
|||||||
return 0;
|
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)
|
void zebra_srv6_locator_add(struct srv6_locator *locator)
|
||||||
{
|
{
|
||||||
struct zebra_srv6 *srv6 = zebra_srv6_get_default();
|
struct zebra_srv6 *srv6 = zebra_srv6_get_default();
|
||||||
@ -222,10 +314,24 @@ struct zebra_srv6 srv6;
|
|||||||
struct zebra_srv6 *zebra_srv6_get_default(void)
|
struct zebra_srv6 *zebra_srv6_get_default(void)
|
||||||
{
|
{
|
||||||
static bool first_execution = true;
|
static bool first_execution = true;
|
||||||
|
struct zebra_srv6_sid_format *format_usidf3216;
|
||||||
|
struct zebra_srv6_sid_format *format_uncompressed;
|
||||||
|
|
||||||
if (first_execution) {
|
if (first_execution) {
|
||||||
first_execution = false;
|
first_execution = false;
|
||||||
srv6.locators = list_new();
|
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;
|
return &srv6;
|
||||||
}
|
}
|
||||||
@ -430,18 +536,30 @@ void zebra_srv6_encap_src_addr_unset(void)
|
|||||||
void zebra_srv6_terminate(void)
|
void zebra_srv6_terminate(void)
|
||||||
{
|
{
|
||||||
struct srv6_locator *locator;
|
struct srv6_locator *locator;
|
||||||
|
struct zebra_srv6_sid_format *format;
|
||||||
|
|
||||||
if (!srv6.locators)
|
if (srv6.locators) {
|
||||||
return;
|
while (listcount(srv6.locators)) {
|
||||||
|
locator = listnode_head(srv6.locators);
|
||||||
|
|
||||||
while (listcount(srv6.locators)) {
|
listnode_delete(srv6.locators, locator);
|
||||||
locator = listnode_head(srv6.locators);
|
srv6_locator_free(locator);
|
||||||
|
}
|
||||||
|
|
||||||
listnode_delete(srv6.locators, locator);
|
list_delete(&srv6.locators);
|
||||||
srv6_locator_free(locator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
void zebra_srv6_init(void)
|
||||||
|
@ -16,12 +16,37 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <plist.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. */
|
/* SRv6 instance structure. */
|
||||||
struct zebra_srv6 {
|
struct zebra_srv6 {
|
||||||
struct list *locators;
|
struct list *locators;
|
||||||
|
|
||||||
/* Source address for SRv6 encapsulation */
|
/* Source address for SRv6 encapsulation */
|
||||||
struct in6_addr encap_src_addr;
|
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
|
/* 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_set(struct in6_addr *src_addr);
|
||||||
extern void zebra_srv6_encap_src_addr_unset(void);
|
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 */
|
#endif /* _ZEBRA_SRV6_H */
|
||||||
|
@ -198,15 +198,32 @@ DEFUN (show_srv6_locator_detail,
|
|||||||
prefix2str(&locator->prefix, str, sizeof(str));
|
prefix2str(&locator->prefix, str, sizeof(str));
|
||||||
vty_out(vty, "Name: %s\n", locator->name);
|
vty_out(vty, "Name: %s\n", locator->name);
|
||||||
vty_out(vty, "Prefix: %s\n", str);
|
vty_out(vty, "Prefix: %s\n", str);
|
||||||
vty_out(vty, "Block-Bit-Len: %u\n", locator->block_bits_length);
|
if (locator->sid_format) {
|
||||||
vty_out(vty, "Node-Bit-Len: %u\n", locator->node_bits_length);
|
vty_out(vty, "Block-Bit-Len: %u\n",
|
||||||
vty_out(vty, "Function-Bit-Len: %u\n",
|
locator->sid_format->block_len);
|
||||||
locator->function_bits_length);
|
vty_out(vty, "Node-Bit-Len: %u\n",
|
||||||
vty_out(vty, "Argument-Bit-Len: %u\n",
|
locator->sid_format->node_len);
|
||||||
locator->argument_bits_length);
|
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 (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID))
|
if (locator->sid_format->type ==
|
||||||
vty_out(vty, "Behavior: uSID\n");
|
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");
|
vty_out(vty, "Chunks:\n");
|
||||||
for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node,
|
for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node,
|
||||||
|
Loading…
Reference in New Issue
Block a user