struct srv6_locator {
char name[SRV6_LOCNAME_SIZE];
struct prefix_ipv6 prefix;
+
+ /*
+ * Bit length of SRv6 locator described in
+ * draft-ietf-bess-srv6-services-05#section-3.2.1
+ */
+ uint8_t block_bits_length;
+ uint8_t node_bits_length;
uint8_t function_bits_length;
+ uint8_t argument_bits_length;
+
int algonum;
uint64_t current;
bool status_up;
DECLARE_QOBJ_TYPE(srv6_locator);
struct srv6_locator_chunk {
+ char locator_name[SRV6_LOCNAME_SIZE];
+ struct prefix_ipv6 prefix;
+
+ /*
+ * Bit length of SRv6 locator described in
+ * draft-ietf-bess-srv6-services-05#section-3.2.1
+ */
+ uint8_t block_bits_length;
+ uint8_t node_bits_length;
+ uint8_t function_bits_length;
+ uint8_t argument_bits_length;
+
+ /*
+ * For Zclient communication values
+ */
uint8_t keep;
uint8_t proto;
uint16_t instance;
uint32_t session_id;
- struct prefix_ipv6 prefix;
};
static inline const char *seg6_mode2str(enum seg6_mode_t mode)
return ret;
}
+int zapi_srv6_locator_chunk_encode(struct stream *s,
+ const struct srv6_locator_chunk *c)
+{
+ stream_putc(s, c->proto);
+ stream_putw(s, c->instance);
+ stream_putw(s, strlen(c->locator_name));
+ stream_put(s, c->locator_name, strlen(c->locator_name));
+ stream_putw(s, c->prefix.prefixlen);
+ stream_put(s, &c->prefix.prefix, sizeof(c->prefix.prefix));
+ stream_putc(s, c->block_bits_length);
+ stream_putc(s, c->node_bits_length);
+ stream_putc(s, c->function_bits_length);
+ stream_putc(s, c->argument_bits_length);
+ return 0;
+}
+
+int zapi_srv6_locator_chunk_decode(struct stream *s,
+ struct srv6_locator_chunk *c)
+{
+ uint16_t len = 0;
+
+ STREAM_GETC(s, c->proto);
+ STREAM_GETW(s, c->instance);
+ STREAM_GETW(s, len);
+ if (len > SRV6_LOCNAME_SIZE)
+ goto stream_failure;
+
+ STREAM_GET(c->locator_name, s, len);
+ STREAM_GETW(s, c->prefix.prefixlen);
+ STREAM_GET(&c->prefix.prefix, s, sizeof(c->prefix.prefix));
+ STREAM_GETC(s, c->block_bits_length);
+ STREAM_GETC(s, c->node_bits_length);
+ STREAM_GETC(s, c->function_bits_length);
+ STREAM_GETC(s, c->argument_bits_length);
+ return 0;
+
+stream_failure:
+ return -1;
+}
+
static int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
{
int i;
struct zapi_labels *zl);
extern int zapi_labels_decode(struct stream *s, struct zapi_labels *zl);
+extern int zapi_srv6_locator_chunk_encode(struct stream *s,
+ const struct srv6_locator_chunk *c);
+extern int zapi_srv6_locator_chunk_decode(struct stream *s,
+ struct srv6_locator_chunk *c);
+
extern enum zclient_send_status zebra_send_pw(struct zclient *zclient,
int command, struct zapi_pw *pw);
extern int zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS,
vrf_id_t vrf_id,
struct srv6_locator *loc)
{
+ struct srv6_locator_chunk chunk;
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK, vrf_id);
-
- /* proto */
- stream_putc(s, client->proto);
-
- /* instance */
- stream_putw(s, client->instance);
-
- if (loc) {
- stream_putw(s, strlen(loc->name));
- stream_put(s, loc->name, strlen(loc->name));
- stream_putw(s, loc->prefix.prefixlen);
- stream_put(s, &loc->prefix.prefix, 16);
- }
+ memset(&chunk, 0, sizeof(chunk));
+ strlcpy(chunk.locator_name, loc->name, sizeof(chunk.locator_name));
+ chunk.prefix = loc->prefix;
+ chunk.block_bits_length = loc->block_bits_length;
+ chunk.node_bits_length = loc->node_bits_length;
+ chunk.function_bits_length = loc->function_bits_length;
+ chunk.argument_bits_length = loc->argument_bits_length;
+ chunk.keep = 0;
+ chunk.proto = client->proto;
+ chunk.instance = client->instance;
- /* Write packet size. */
+ zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK, vrf_id);
+ zapi_srv6_locator_chunk_encode(s, &chunk);
stream_putw_at(s, 0, stream_get_endp(s));
-
return zserv_send_message(client, s);
}
struct listnode *node = NULL;
locator->prefix = *prefix;
+
+ /*
+ * TODO(slankdev): please support variable node-bit-length.
+ * In draft-ietf-bess-srv6-services-05#section-3.2.1.
+ * Locator block length and Locator node length are defined.
+ * Which are defined as "locator-len == block-len + node-len".
+ * In current implementation, node bits length is hardcoded as 24.
+ * It should be supported various val.
+ *
+ * Cisco IOS-XR support only following pattern.
+ * (1) Teh locator length should be 64-bits long.
+ * (2) The SID block portion (MSBs) cannot exceed 40 bits.
+ * If this value is less than 40 bits,
+ * user should use a pattern of zeros as a filler.
+ * (3) The Node Id portion (LSBs) cannot exceed 24 bits.
+ */
+ locator->block_bits_length = prefix->prefixlen - 24;
+ locator->node_bits_length = 24;
locator->function_bits_length = func_bit_len;
+ locator->argument_bits_length = 0;
if (list_isempty(locator->chunks)) {
chunk = srv6_locator_chunk_alloc();