diff options
| author | Carmine Scarpitta <cscarpit@cisco.com> | 2024-03-22 15:13:00 +0100 | 
|---|---|---|
| committer | Carmine Scarpitta <cscarpit@cisco.com> | 2024-06-13 14:54:16 +0200 | 
| commit | 021386a34eb49893ce6b7df16c2fe1096a8fedf6 (patch) | |
| tree | 2c36ea18925fb719e9b0ebf58a3e6ef95d3546f2 | |
| parent | 2e02bd2366ebf877963802d79e66b805ccffbf4c (diff) | |
lib: Add support for SRv6 SID formats
Add functionalities to manage SRv6 SID formats (allocate / free).
Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
| -rw-r--r-- | lib/srv6.c | 148 | ||||
| -rw-r--r-- | lib/srv6.h | 61 | 
2 files changed, 175 insertions, 34 deletions
diff --git a/lib/srv6.c b/lib/srv6.c index a82103e423..abaff7eab8 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -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); - -	/* 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"); +	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->sid_format->node_len); + +		/* 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->sid_format->argument_len); + +		/* 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); - -	/* 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"); +	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->sid_format->node_len); + +		/* 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->sid_format->argument_len); + +		/* 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); diff --git a/lib/srv6.h b/lib/srv6.h index 433c5c14fd..04f560b267 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -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  | 
