diff options
Diffstat (limited to 'lib/zclient.c')
| -rw-r--r-- | lib/zclient.c | 196 |
1 files changed, 195 insertions, 1 deletions
diff --git a/lib/zclient.c b/lib/zclient.c index c5b1e72380..0e832f0d8f 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1125,6 +1125,10 @@ int zapi_srv6_locator_encode(struct stream *s, const struct srv6_locator *l) stream_put(s, l->name, strlen(l->name)); stream_putw(s, l->prefix.prefixlen); stream_put(s, &l->prefix.prefix, sizeof(l->prefix.prefix)); + stream_putc(s, l->block_bits_length); + stream_putc(s, l->node_bits_length); + stream_putc(s, l->function_bits_length); + stream_putc(s, l->argument_bits_length); stream_putc(s, l->flags); return 0; } @@ -1141,6 +1145,10 @@ int zapi_srv6_locator_decode(struct stream *s, struct srv6_locator *l) STREAM_GETW(s, l->prefix.prefixlen); STREAM_GET(&l->prefix.prefix, s, sizeof(l->prefix.prefix)); l->prefix.family = AF_INET6; + STREAM_GETC(s, l->block_bits_length); + STREAM_GETC(s, l->node_bits_length); + STREAM_GETC(s, l->function_bits_length); + STREAM_GETC(s, l->argument_bits_length); STREAM_GETC(s, l->flags); return 0; @@ -2125,6 +2133,46 @@ stream_failure: return false; } +bool zapi_srv6_sid_notify_decode(struct stream *s, struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, uint32_t *func, + uint32_t *wide_func, + enum zapi_srv6_sid_notify *note, + char **p_locator_name) +{ + uint32_t f, wf; + uint16_t len; + static char locator_name[SRV6_LOCNAME_SIZE] = {}; + + STREAM_GET(note, s, sizeof(*note)); + STREAM_GET(ctx, s, sizeof(struct srv6_sid_ctx)); + STREAM_GET(sid_value, s, sizeof(struct in6_addr)); + STREAM_GETL(s, f); + STREAM_GETL(s, wf); + + if (func) + *func = f; + if (wide_func) + *wide_func = wf; + + STREAM_GETW(s, len); + if (len > SRV6_LOCNAME_SIZE) { + *p_locator_name = NULL; + return false; + } + if (p_locator_name) { + if (len == 0) + *p_locator_name = NULL; + else { + STREAM_GET(locator_name, s, len); + *p_locator_name = locator_name; + } + } + return true; + +stream_failure: + return false; +} + struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh) { struct nexthop *n = nexthop_new(); @@ -2134,6 +2182,7 @@ struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh) n->ifindex = znh->ifindex; n->gate = znh->gate; n->srte_color = znh->srte_color; + n->weight = znh->weight; /* * This function currently handles labels @@ -2174,6 +2223,7 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh, znh->weight = nh->weight; znh->ifindex = nh->ifindex; znh->gate = nh->gate; + znh->srte_color = nh->srte_color; if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK)) SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_ONLINK); @@ -3267,10 +3317,154 @@ int srv6_manager_release_locator_chunk(struct zclient *zclient, return zclient_send_message(zclient); } +/** + * Function to request a SRv6 locator in an asynchronous way + * + * @param zclient The zclient used to connect to SRv6 Manager (zebra) + * @param locator_name Name of SRv6 locator + * @return 0 on success, -1 otherwise + */ +int srv6_manager_get_locator(struct zclient *zclient, const char *locator_name) +{ + struct stream *s; + size_t len; + + if (!locator_name) + return -1; + + if (zclient->sock < 0) { + flog_err(EC_LIB_ZAPI_SOCKET, "%s: invalid zclient socket", + __func__); + return -1; + } + + if (zclient_debug) + zlog_debug("Getting SRv6 Locator %s", locator_name); + + len = strlen(locator_name); + + /* Send request */ + s = zclient->obuf; + stream_reset(s); + zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR, VRF_DEFAULT); + + /* Locator name */ + stream_putw(s, len); + stream_put(s, locator_name, len); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + return zclient_send_message(zclient); +} + +/** + * Function to request an SRv6 SID in an asynchronous way + * + * @param zclient The zclient used to connect to SRv6 manager (zebra) + * @param ctx Context associated with the SRv6 SID + * @param sid_value SRv6 SID value for explicit SID allocation + * @param locator_name Name of the parent locator for dynamic SID allocation + * @param sid_func SID function assigned by the SRv6 Manager + * @result 0 on success, -1 otherwise + */ +int srv6_manager_get_sid(struct zclient *zclient, const struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, const char *locator_name, + uint32_t *sid_func) +{ + struct stream *s; + uint8_t flags = 0; + size_t len; + char buf[256]; + + if (zclient->sock < 0) { + flog_err(EC_LIB_ZAPI_SOCKET, "%s: invalid zclient socket", + __func__); + return ZCLIENT_SEND_FAILURE; + } + + if (zclient_debug) + zlog_debug("Getting SRv6 SID: %s", + srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + + /* send request */ + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_SRV6_SID, VRF_DEFAULT); + + /* Context associated with the SRv6 SID */ + stream_put(s, ctx, sizeof(struct srv6_sid_ctx)); + + /* Flags */ + if (!sid_zero_ipv6(sid_value)) + SET_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_SID_VALUE); + if (locator_name) + SET_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_LOCATOR); + stream_putc(s, flags); + + /* SRv6 SID value */ + if (CHECK_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_SID_VALUE)) + stream_put(s, sid_value, sizeof(struct in6_addr)); + + /* SRv6 locator */ + if (CHECK_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_LOCATOR)) { + len = strlen(locator_name); + stream_putw(s, len); + stream_put(s, locator_name, len); + } + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + /* Send the request to SRv6 Manager */ + return zclient_send_message(zclient); +} + +/** + * Function to release an SRv6 SID + * + * @param zclient Zclient used to connect to SRv6 manager (zebra) + * @param ctx Context associated with the SRv6 SID to be removed + * @result 0 on success, -1 otherwise + */ +int srv6_manager_release_sid(struct zclient *zclient, + const struct srv6_sid_ctx *ctx) +{ + struct stream *s; + char buf[256]; + + if (zclient->sock < 0) { + flog_err(EC_LIB_ZAPI_SOCKET, "%s: invalid zclient socket", + __func__); + return -1; + } + + if (zclient_debug) + zlog_debug("Releasing SRv6 SID: %s", + srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + + /* send request */ + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID, + VRF_DEFAULT); + + /* Context associated with the SRv6 SID */ + stream_put(s, ctx, sizeof(struct srv6_sid_ctx)); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + /* Send the SID release message */ + return zclient_send_message(zclient); +} + /* * Asynchronous label chunk request * - * @param zclient Zclient used to connect to label manager (zebra) + * @param zclient The zclient used to connect to label manager (zebra) * @param keep Avoid garbage collection * @param chunk_size Amount of labels requested * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care |
