#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"
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]",
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;
}
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;
}
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};
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;
}