]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: add zapi_srv6_locator_chunk_{en,de}code
authorHiroki Shirokura <slank.dev@gmail.com>
Thu, 31 Dec 2020 11:56:32 +0000 (11:56 +0000)
committerMark Stapp <mjs@voltanet.io>
Wed, 2 Jun 2021 14:24:48 +0000 (10:24 -0400)
Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
lib/srv6.h
lib/zclient.c
lib/zclient.h
zebra/zapi_msg.c
zebra/zebra_srv6_vty.c

index 46ff830e7fc4cbb2792cd56f8a1fe10d0912310f..9ac89125cebe7dc93ee0cc3b5f9410821fff7cad 100644 (file)
@@ -76,7 +76,16 @@ struct seg6local_context {
 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;
@@ -87,11 +96,25 @@ struct srv6_locator {
 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)
index 1acf7f20d5165d63fc9ab227304d7263ed5a6ed0..f6b97a768fcf56682e80c3d72a36c64070e11d13 100644 (file)
@@ -1074,6 +1074,46 @@ done:
        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;
index e06079673a04bc4760aea0760fe4b2a127fb5c8d..d9ca6a859d3d53d8ed7e6393a51ba984dbf1d296 100644 (file)
@@ -1092,6 +1092,11 @@ extern int zapi_labels_encode(struct stream *s, int cmd,
                              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,
index 25c51e2227e262644524cc25cc2371d69ddfc392..46bd9d995955d13659ca1c0eca5ae2ec15b92750 100644 (file)
@@ -2701,26 +2701,23 @@ int zsend_srv6_manager_get_locator_chunk_response(struct zserv *client,
                                                  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);
 }
 
index 0bc48f6339a55a687a6927f818c2de779e5ec64e..803e9f119666cd8aabda7045dd3d1c67915cf55e 100644 (file)
@@ -246,7 +246,26 @@ DEFPY (locator_prefix,
        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();