lib: Add support for SRv6 SID formats

Add functionalities to manage SRv6 SID formats (allocate / free).

Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
This commit is contained in:
Carmine Scarpitta 2024-03-22 15:13:00 +01:00
parent 2e02bd2366
commit 021386a34e
2 changed files with 167 additions and 26 deletions

View File

@ -10,8 +10,10 @@
#include "log.h"
DEFINE_QOBJ_TYPE(srv6_locator);
DEFINE_QOBJ_TYPE(srv6_sid_format);
DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR, "SRV6 locator");
DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR_CHUNK, "SRV6 locator chunk");
DEFINE_MTYPE_STATIC(LIB, SRV6_SID_FORMAT, "SRv6 SID format");
const char *seg6local_action2str(uint32_t action)
{
@ -154,6 +156,36 @@ void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk)
XFREE(MTYPE_SRV6_LOCATOR_CHUNK, *chunk);
}
struct srv6_sid_format *srv6_sid_format_alloc(const char *name)
{
struct srv6_sid_format *format = NULL;
format = XCALLOC(MTYPE_SRV6_SID_FORMAT, sizeof(struct srv6_sid_format));
strlcpy(format->name, name, sizeof(format->name));
QOBJ_REG(format, srv6_sid_format);
return format;
}
void srv6_sid_format_free(struct srv6_sid_format *format)
{
if (!format)
return;
QOBJ_UNREG(format);
XFREE(MTYPE_SRV6_SID_FORMAT, format);
}
/**
* Free an SRv6 SID format.
*
* @param val SRv6 SID format to be freed
*/
void delete_srv6_sid_format(void *val)
{
srv6_sid_format_free((struct srv6_sid_format *)val);
}
json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk)
{
json_object *jo_root = NULL;
@ -223,23 +255,47 @@ json_object *srv6_locator_json(const struct srv6_locator *loc)
/* set prefix */
json_object_string_addf(jo_root, "prefix", "%pFX", &loc->prefix);
/* set block_bits_length */
json_object_int_add(jo_root, "blockBitsLength", loc->block_bits_length);
if (loc->sid_format) {
/* set block_bits_length */
json_object_int_add(jo_root, "blockBitsLength",
loc->sid_format->block_len);
/* set node_bits_length */
json_object_int_add(jo_root, "nodeBitsLength", loc->node_bits_length);
/* set node_bits_length */
json_object_int_add(jo_root, "nodeBitsLength",
loc->sid_format->node_len);
/* set function_bits_length */
json_object_int_add(jo_root, "functionBitsLength",
loc->function_bits_length);
/* set function_bits_length */
json_object_int_add(jo_root, "functionBitsLength",
loc->sid_format->function_len);
/* set argument_bits_length */
json_object_int_add(jo_root, "argumentBitsLength",
loc->argument_bits_length);
/* set argument_bits_length */
json_object_int_add(jo_root, "argumentBitsLength",
loc->sid_format->argument_len);
/* set true if the locator is a Micro-segment (uSID) locator */
if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
json_object_string_add(jo_root, "behavior", "usid");
/* set true if the locator is a Micro-segment (uSID) locator */
if (loc->sid_format->type == SRV6_SID_FORMAT_TYPE_USID)
json_object_string_add(jo_root, "behavior", "usid");
} else {
/* set block_bits_length */
json_object_int_add(jo_root, "blockBitsLength",
loc->block_bits_length);
/* set node_bits_length */
json_object_int_add(jo_root, "nodeBitsLength",
loc->node_bits_length);
/* set function_bits_length */
json_object_int_add(jo_root, "functionBitsLength",
loc->function_bits_length);
/* set argument_bits_length */
json_object_int_add(jo_root, "argumentBitsLength",
loc->argument_bits_length);
/* set true if the locator is a Micro-segment (uSID) locator */
if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
json_object_string_add(jo_root, "behavior", "usid");
}
/* set status_up */
json_object_boolean_add(jo_root, "statusUp",
@ -272,23 +328,47 @@ json_object *srv6_locator_detailed_json(const struct srv6_locator *loc)
/* set prefix */
json_object_string_addf(jo_root, "prefix", "%pFX", &loc->prefix);
/* set block_bits_length */
json_object_int_add(jo_root, "blockBitsLength", loc->block_bits_length);
if (loc->sid_format) {
/* set block_bits_length */
json_object_int_add(jo_root, "blockBitsLength",
loc->sid_format->block_len);
/* set node_bits_length */
json_object_int_add(jo_root, "nodeBitsLength", loc->node_bits_length);
/* set node_bits_length */
json_object_int_add(jo_root, "nodeBitsLength",
loc->sid_format->node_len);
/* set function_bits_length */
json_object_int_add(jo_root, "functionBitsLength",
loc->function_bits_length);
/* set function_bits_length */
json_object_int_add(jo_root, "functionBitsLength",
loc->sid_format->function_len);
/* set argument_bits_length */
json_object_int_add(jo_root, "argumentBitsLength",
loc->argument_bits_length);
/* set argument_bits_length */
json_object_int_add(jo_root, "argumentBitsLength",
loc->sid_format->argument_len);
/* set true if the locator is a Micro-segment (uSID) locator */
if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
json_object_string_add(jo_root, "behavior", "usid");
/* set true if the locator is a Micro-segment (uSID) locator */
if (loc->sid_format->type == SRV6_SID_FORMAT_TYPE_USID)
json_object_string_add(jo_root, "behavior", "usid");
} else {
/* set block_bits_length */
json_object_int_add(jo_root, "blockBitsLength",
loc->block_bits_length);
/* set node_bits_length */
json_object_int_add(jo_root, "nodeBitsLength",
loc->node_bits_length);
/* set function_bits_length */
json_object_int_add(jo_root, "functionBitsLength",
loc->function_bits_length);
/* set argument_bits_length */
json_object_int_add(jo_root, "argumentBitsLength",
loc->argument_bits_length);
/* set true if the locator is a Micro-segment (uSID) locator */
if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
json_object_string_add(jo_root, "behavior", "usid");
}
/* set algonum */
json_object_int_add(jo_root, "algoNum", loc->algonum);

View File

@ -20,6 +20,8 @@
#define SRH_BASE_HEADER_LENGTH 8
#define SRH_SEGMENT_LENGTH 16
#define SRV6_SID_FORMAT_NAME_SIZE 512
#ifdef __cplusplus
extern "C" {
#endif
@ -183,6 +185,61 @@ struct nexthop_srv6 {
struct seg6_seg_stack *seg6_segs;
};
/* SID format type */
enum srv6_sid_format_type {
SRV6_SID_FORMAT_TYPE_UNSPEC = 0,
/* SRv6 SID uncompressed format */
SRV6_SID_FORMAT_TYPE_UNCOMPRESSED = 1,
/* SRv6 SID compressed uSID format */
SRV6_SID_FORMAT_TYPE_USID = 2,
};
/* SRv6 SID format */
struct srv6_sid_format {
/* Name of the format */
char name[SRV6_SID_FORMAT_NAME_SIZE];
/* Format type: uncompressed vs compressed */
enum srv6_sid_format_type type;
/*
* Lengths of block/node/function/argument parts of the SIDs allocated
* using this format
*/
uint8_t block_len;
uint8_t node_len;
uint8_t function_len;
uint8_t argument_len;
union {
/* Configuration settings for compressed uSID format type */
struct {
/* Start of the Local ID Block (LIB) range */
uint32_t lib_start;
/* Start/End of the Explicit LIB range */
uint32_t elib_start;
uint32_t elib_end;
/* Start/End of the Wide LIB range */
uint32_t wlib_start;
uint32_t wlib_end;
/* Start/End of the Explicit Wide LIB range */
uint32_t ewlib_start;
} usid;
/* Configuration settings for uncompressed format type */
struct {
/* Start of the Explicit range */
uint32_t explicit_start;
} uncompressed;
} config;
QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(srv6_sid_format);
static inline const char *seg6_mode2str(enum seg6_mode_t mode)
{
switch (mode) {
@ -260,6 +317,10 @@ json_object *srv6_locator_detailed_json(const struct srv6_locator *loc);
json_object *
srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk);
extern struct srv6_sid_format *srv6_sid_format_alloc(const char *name);
extern void srv6_sid_format_free(struct srv6_sid_format *format);
extern void delete_srv6_sid_format(void *format);
#ifdef __cplusplus
}
#endif