From 021386a34eb49893ce6b7df16c2fe1096a8fedf6 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 22 Mar 2024 15:13:00 +0100 Subject: lib: Add support for SRv6 SID formats Add functionalities to manage SRv6 SID formats (allocate / free). Signed-off-by: Carmine Scarpitta --- lib/srv6.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 114 insertions(+), 34 deletions(-) (limited to 'lib/srv6.c') 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); -- cgit v1.2.3 From f00554ed563b8a4ce0cc7fff7ea107d3ae8aa6b1 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 8 May 2024 16:41:05 +0200 Subject: lib: Add function to copy an SRv6 locator Add a new function to copy an SRv6 locator. Signed-off-by: Carmine Scarpitta --- lib/srv6.c | 15 +++++++++++++++ lib/srv6.h | 2 ++ 2 files changed, 17 insertions(+) (limited to 'lib/srv6.c') diff --git a/lib/srv6.c b/lib/srv6.c index abaff7eab8..1f485fb8ac 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -141,6 +141,21 @@ struct srv6_locator_chunk *srv6_locator_chunk_alloc(void) return chunk; } +void srv6_locator_copy(struct srv6_locator *copy, + const struct srv6_locator *locator) +{ + strlcpy(copy->name, locator->name, sizeof(locator->name)); + copy->prefix = locator->prefix; + copy->block_bits_length = locator->block_bits_length; + copy->node_bits_length = locator->node_bits_length; + copy->function_bits_length = locator->function_bits_length; + copy->argument_bits_length = locator->argument_bits_length; + copy->algonum = locator->algonum; + copy->current = locator->current; + copy->status_up = locator->status_up; + copy->flags = locator->flags; +} + void srv6_locator_free(struct srv6_locator *locator) { if (locator) { diff --git a/lib/srv6.h b/lib/srv6.h index 04f560b267..66f1854dab 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -311,6 +311,8 @@ extern struct srv6_locator_chunk *srv6_locator_chunk_alloc(void); extern void srv6_locator_free(struct srv6_locator *locator); extern void srv6_locator_chunk_list_free(void *data); extern void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk); +extern void srv6_locator_copy(struct srv6_locator *copy, + const struct srv6_locator *locator); json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk); json_object *srv6_locator_json(const struct srv6_locator *loc); json_object *srv6_locator_detailed_json(const struct srv6_locator *loc); -- cgit v1.2.3 From 3cb88e69848d607a8d069b0858798e2de324fd43 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Mon, 6 May 2024 17:44:18 +0200 Subject: lib: Add support for SRv6 SIDs Add a data structure to represent an SRv6 SID context and the related management functions (allocate/free). Signed-off-by: Carmine Scarpitta --- lib/srv6.c | 24 +++++++++++++++++++++++ lib/srv6.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) (limited to 'lib/srv6.c') diff --git a/lib/srv6.c b/lib/srv6.c index 1f485fb8ac..883d429b62 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -14,6 +14,7 @@ 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"); +DEFINE_MTYPE_STATIC(LIB, SRV6_SID_CTX, "SRv6 SID context"); const char *seg6local_action2str(uint32_t action) { @@ -201,6 +202,29 @@ void delete_srv6_sid_format(void *val) srv6_sid_format_free((struct srv6_sid_format *)val); } +struct srv6_sid_ctx *srv6_sid_ctx_alloc(enum seg6local_action_t behavior, + struct in_addr *nh4, + struct in6_addr *nh6, vrf_id_t vrf_id) +{ + struct srv6_sid_ctx *ctx = NULL; + + ctx = XCALLOC(MTYPE_SRV6_SID_CTX, sizeof(struct srv6_sid_ctx)); + ctx->behavior = behavior; + if (nh4) + ctx->nh4 = *nh4; + if (nh6) + ctx->nh6 = *nh6; + if (vrf_id) + ctx->vrf_id = vrf_id; + + return ctx; +} + +void srv6_sid_ctx_free(struct srv6_sid_ctx *ctx) +{ + XFREE(MTYPE_SRV6_SID_CTX, ctx); +} + json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk) { json_object *jo_root = NULL; diff --git a/lib/srv6.h b/lib/srv6.h index 4a6ea5c72b..01b0820133 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -246,6 +246,17 @@ struct srv6_sid_format { }; DECLARE_QOBJ_TYPE(srv6_sid_format); +/* Context for an SRv6 SID */ +struct srv6_sid_ctx { + /* Behavior associated with the SID */ + enum seg6local_action_t behavior; + + /* Behavior-specific attributes */ + struct in_addr nh4; + struct in6_addr nh6; + vrf_id_t vrf_id; +}; + static inline const char *seg6_mode2str(enum seg6_mode_t mode) { switch (mode) { @@ -309,6 +320,54 @@ const char *seg6local_context2str(char *str, size_t size, const struct seg6local_context *ctx, uint32_t action); +static inline const char *srv6_sid_ctx2str(char *str, size_t size, + const struct srv6_sid_ctx *ctx) +{ + int len = 0; + + len += snprintf(str + len, size - len, "%s", + seg6local_action2str(ctx->behavior)); + + switch (ctx->behavior) { + case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC: + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END: + len += snprintf(str + len, size - len, " USP"); + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END_X: + case ZEBRA_SEG6_LOCAL_ACTION_END_DX6: + len += snprintfrr(str + len, size - len, " nh6 %pI6", &ctx->nh6); + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END_DX4: + len += snprintfrr(str + len, size - len, " nh4 %pI4", &ctx->nh4); + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END_T: + case ZEBRA_SEG6_LOCAL_ACTION_END_DT6: + case ZEBRA_SEG6_LOCAL_ACTION_END_DT4: + case ZEBRA_SEG6_LOCAL_ACTION_END_DT46: + len += snprintf(str + len, size - len, " vrf_id %u", + ctx->vrf_id); + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END_DX2: + case ZEBRA_SEG6_LOCAL_ACTION_END_B6: + case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP: + case ZEBRA_SEG6_LOCAL_ACTION_END_BM: + case ZEBRA_SEG6_LOCAL_ACTION_END_S: + case ZEBRA_SEG6_LOCAL_ACTION_END_AS: + case ZEBRA_SEG6_LOCAL_ACTION_END_AM: + case ZEBRA_SEG6_LOCAL_ACTION_END_BPF: + default: + len += snprintf(str + len, size - len, " unknown(%s)", __func__); + } + + return str; +} + int snprintf_seg6_segs(char *str, size_t size, const struct seg6_segs *segs); @@ -329,6 +388,12 @@ 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); +extern struct srv6_sid_ctx *srv6_sid_ctx_alloc(enum seg6local_action_t behavior, + struct in_addr *nh4, + struct in6_addr *nh6, + vrf_id_t vrf_id); +extern void srv6_sid_ctx_free(struct srv6_sid_ctx *ctx); + #ifdef __cplusplus } #endif -- cgit v1.2.3