]> git.puffer.fish Git - matthieu/frr.git/commitdiff
sharpd: support create/delete srv6-locator (step2)
authorHiroki Shirokura <slank.dev@gmail.com>
Sun, 11 Oct 2020 08:27:40 +0000 (17:27 +0900)
committerMark Stapp <mjs@voltanet.io>
Wed, 2 Jun 2021 14:24:47 +0000 (10:24 -0400)
Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
sharpd/sharp_globals.h
sharpd/sharp_main.c
sharpd/sharp_vty.c
sharpd/sharp_zebra.c
sharpd/sharp_zebra.h

index b050ba85ca9229eb12e07b755bfa405451aa0d52..46096f4aa7fd8cce2c18f322de9ccf86d0875970 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef __SHARP_GLOBAL_H__
 #define __SHARP_GLOBAL_H__
 
+#include "lib/srv6.h"
+
 DECLARE_MGROUP(SHARPD);
 
 struct sharp_routes {
@@ -52,6 +54,14 @@ struct sharp_routes {
        char opaque[ZAPI_MESSAGE_OPAQUE_LENGTH];
 };
 
+struct sharp_srv6_locator {
+       /* name of locator */
+       char name[SRV6_LOCNAME_SIZE];
+
+       /* list of struct prefix_ipv6 */
+       struct list *chunks;
+};
+
 struct sharp_global {
        /* Global data about route install/deletions */
        struct sharp_routes r;
@@ -61,6 +71,9 @@ struct sharp_global {
 
        /* Traffic Engineering Database */
        struct ls_ted *ted;
+
+       /* list of sharp_srv6_locator */
+       struct list *srv6_locators;
 };
 
 extern struct sharp_global sg;
index e93db34ffa4bdf01249e85d52e2071ea7e7cfdc2..75cf1453858d8ffe9f603c1c460fe57986ccf47e 100644 (file)
@@ -140,6 +140,7 @@ static void sharp_global_init(void)
        memset(&sg, 0, sizeof(sg));
        sg.nhs = list_new();
        sg.ted = NULL;
+       sg.srv6_locators = list_new();
 }
 
 static void sharp_start_configuration(void)
index 253d1943b338a4ef79d7e5826e2e876b2f1aabcf..c580338f33aa01a8a0d78457d228353c7b07b806 100644 (file)
@@ -39,6 +39,8 @@
 #include "sharpd/sharp_vty_clippy.c"
 #endif
 
+DEFINE_MTYPE_STATIC(SHARPD, SRV6_LOCATOR, "SRv6 Locator");
+
 DEFPY(watch_redistribute, watch_redistribute_cmd,
       "sharp watch [vrf NAME$vrf_name] redistribute " FRR_REDIST_STR_SHARPD,
       "Sharp routing Protocol\n"
@@ -784,6 +786,40 @@ DEFPY (import_te,
        return CMD_SUCCESS;
 }
 
+DEFPY (sharp_srv6_manager_get_locator_chunk,
+       sharp_srv6_manager_get_locator_chunk_cmd,
+       "sharp srv6-manager get-locator-chunk NAME$locator_name",
+       SHARP_STR
+       "Segment-Routing IPv6\n"
+       "Get SRv6 locator-chunk\n"
+       "SRv6 Locator name\n")
+{
+       int ret;
+       struct listnode *node;
+       struct sharp_srv6_locator *loc;
+       struct sharp_srv6_locator *loc_found = NULL;
+
+       for (ALL_LIST_ELEMENTS_RO(sg.srv6_locators, node, loc)) {
+               if (strcmp(loc->name, locator_name))
+                       continue;
+               loc_found = loc;
+               break;
+       }
+       if (!loc_found) {
+               loc = XCALLOC(MTYPE_SRV6_LOCATOR,
+                             sizeof(struct sharp_srv6_locator));
+               loc->chunks = list_new();
+               snprintf(loc->name, SRV6_LOCNAME_SIZE, "%s", locator_name);
+               listnode_add(sg.srv6_locators, loc);
+       }
+
+       ret = sharp_zebra_srv6_manager_get_locator_chunk(locator_name);
+       if (ret < 0)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       return CMD_SUCCESS;
+}
+
 DEFUN (show_sharp_ted,
        show_sharp_ted_cmd,
        "show sharp ted [<vertex [A.B.C.D]|edge [A.B.C.D]|subnet [A.B.C.D/M]>] [verbose|json]",
@@ -905,6 +941,71 @@ DEFUN (show_sharp_ted,
                                json, JSON_C_TO_STRING_PRETTY));
                json_object_free(json);
        }
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (sharp_srv6_manager_release_locator_chunk,
+       sharp_srv6_manager_release_locator_chunk_cmd,
+       "sharp srv6-manager release-locator-chunk NAME$locator_name",
+       SHARP_STR
+       "Segment-Routing IPv6\n"
+       "Release SRv6 locator-chunk\n"
+       "SRv6 Locator name\n")
+{
+       int ret;
+       struct listnode *loc_node;
+       struct sharp_srv6_locator *loc;
+
+       for (ALL_LIST_ELEMENTS_RO(sg.srv6_locators, loc_node, loc)) {
+               if (!strcmp(loc->name, locator_name)) {
+                       list_delete_all_node(loc->chunks);
+                       list_delete(&loc->chunks);
+                       listnode_delete(sg.srv6_locators, loc);
+                       break;
+               }
+       }
+
+       ret = sharp_zebra_srv6_manager_release_locator_chunk(locator_name);
+       if (ret < 0)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (show_sharp_segment_routing_srv6,
+       show_sharp_segment_routing_srv6_cmd,
+       "show sharp segment-routing srv6",
+       SHOW_STR
+       SHARP_STR
+       "Segment-Routing\n"
+       "Segment-Routing IPv6\n")
+{
+       char str[256];
+       struct listnode *loc_node;
+       struct listnode *chunk_node;
+       struct sharp_srv6_locator *loc;
+       struct prefix_ipv6 *chunk;
+       json_object *jo_locs = NULL;
+       json_object *jo_loc = NULL;
+       json_object *jo_chunks = NULL;
+
+       jo_locs = json_object_new_array();
+       for (ALL_LIST_ELEMENTS_RO(sg.srv6_locators, loc_node, loc)) {
+               jo_loc = json_object_new_object();
+               json_object_array_add(jo_locs, jo_loc);
+               json_object_string_add(jo_loc, "name", loc->name);
+               jo_chunks = json_object_new_array();
+               json_object_object_add(jo_loc, "chunks", jo_chunks);
+               for (ALL_LIST_ELEMENTS_RO(loc->chunks, chunk_node, chunk)) {
+                       prefix2str(chunk, str, sizeof(str));
+                       json_array_string_add(jo_chunks, str);
+               }
+       }
+
+       vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                       jo_locs, JSON_C_TO_STRING_PRETTY));
+       json_object_free(jo_locs);
        return CMD_SUCCESS;
 }
 
@@ -932,5 +1033,9 @@ void sharp_vty_init(void)
        install_element(ENABLE_NODE, &show_debugging_sharpd_cmd);
        install_element(ENABLE_NODE, &show_sharp_ted_cmd);
 
+       install_element(ENABLE_NODE, &sharp_srv6_manager_get_locator_chunk_cmd);
+       install_element(ENABLE_NODE, &sharp_srv6_manager_release_locator_chunk_cmd);
+       install_element(ENABLE_NODE, &show_sharp_segment_routing_srv6_cmd);
+
        return;
 }
index da056160bfc6043d024f337ac308c372c689f591..7c24ae380f91b0bba49259bac093659aeed4517c 100644 (file)
@@ -924,6 +924,68 @@ static int nhg_notify_owner(ZAPI_CALLBACK_ARGS)
        return 0;
 }
 
+int sharp_zebra_srv6_manager_get_locator_chunk(const char* locator_name)
+{
+       return srv6_manager_get_locator_chunk(zclient, locator_name);
+}
+
+int sharp_zebra_srv6_manager_release_locator_chunk(const char *locator_name)
+{
+       return srv6_manager_release_locator_chunk(zclient, locator_name);
+}
+
+static void sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
+{
+       struct stream *s = NULL;
+       uint8_t proto;
+       uint16_t instance;
+       uint16_t len;
+       char name[256] = {0};
+       struct prefix_ipv6 *chunk = NULL;
+       chunk = prefix_ipv6_new();
+
+       s = zclient->ibuf;
+       STREAM_GETC(s, proto);
+       STREAM_GETW(s, instance);
+
+       STREAM_GETW(s, len);
+       STREAM_GET(name, s, len);
+
+       STREAM_GETW(s, chunk->prefixlen);
+       STREAM_GET(&chunk->prefix, s, 16);
+
+       if (zclient->redist_default != proto) {
+               zlog_err("Got SRv6 Manager msg with wrong proto %u", proto);
+               return;
+       }
+       if (zclient->instance != instance) {
+               zlog_err("Got SRv6 Manager msg with wrong instance %u", proto);
+               return;
+       }
+
+       struct listnode *loc_node;
+       struct sharp_srv6_locator *loc;
+       for (ALL_LIST_ELEMENTS_RO(sg.srv6_locators, loc_node, loc)) {
+               if (strcmp(loc->name, name))
+                       continue;
+
+               struct listnode *chunk_node;
+               struct prefix_ipv6 *c;
+               for (ALL_LIST_ELEMENTS_RO(loc->chunks, chunk_node, c)) {
+                       if (!prefix_cmp(c, chunk))
+                               return;
+               }
+               listnode_add(loc->chunks, chunk);
+       }
+       return;
+
+stream_failure:
+       free(chunk);
+
+       zlog_err("%s: can't get locator_chunk!!", __func__);
+       return;
+}
+
 void sharp_zebra_init(void)
 {
        struct zclient_options opt = {.receive_notify = true};
@@ -945,4 +1007,5 @@ void sharp_zebra_init(void)
        zclient->redistribute_route_add = sharp_redistribute_route;
        zclient->redistribute_route_del = sharp_redistribute_route;
        zclient->opaque_msg_handler = sharp_opaque_handler;
+       zclient->process_srv6_locator_chunk = sharp_zebra_process_srv6_locator_chunk;
 }
index 495ce6ec58192e428dc6d849becfe2cc9687dfff..043a7405c27020417ab4d96e65add041c2aca75f 100644 (file)
@@ -65,4 +65,11 @@ extern void sharp_zebra_register_te(void);
 
 extern void sharp_redistribute_vrf(struct vrf *vrf, int source);
 
+extern int sharp_zebra_srv6_manager_get_locator_chunk(const char* locator_name);
+extern int sharp_zebra_srv6_manager_release_locator_chunk(const char *locator_name);
+extern void sharp_install_seg6local_route_helper(struct prefix *p,
+                                                uint8_t instance,
+                                                enum seg6local_action_t act,
+                                                struct seg6local_context *ctx);
+
 #endif