summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_srv6_vty.c
diff options
context:
space:
mode:
authorHiroki Shirokura <slank.dev@gmail.com>2020-02-23 12:38:26 +0100
committerMark Stapp <mjs@voltanet.io>2021-06-02 16:24:47 +0200
commit0097897734b08194d0c6acae1d759e2001cd9026 (patch)
tree46e90cefc8443e330a46d76ab2ceefa6e4a8d68b /zebra/zebra_srv6_vty.c
parentzebra: ZAPI add new api to manipulate srv6-locator (step2) (diff)
downloadfrr-0097897734b08194d0c6acae1d759e2001cd9026.tar.xz
frr-0097897734b08194d0c6acae1d759e2001cd9026.zip
zebra: add new CLI to manipulate srv6-locator (step2)
This commit is a part of #5853 works that add new clis to configure SRv6 locator and its show commands. Following clis are added on this commit. vtysh -c 'conf te' \ -c 'segment-routing' \ -c ' srv6' \ -c ' locators' \ -c ' locator LOC1' \ -c ' prefix A::/64' - "show segment-routing srv6 sid [json]" - "show segment-routing srv6 locator [json]" - "show segment-routing srv6 locator NAME detail [json]" - "show runnning-config" (make it to print srv6 configuration) Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
Diffstat (limited to 'zebra/zebra_srv6_vty.c')
-rw-r--r--zebra/zebra_srv6_vty.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c
index f8eff70c2..73038fad7 100644
--- a/zebra/zebra_srv6_vty.c
+++ b/zebra/zebra_srv6_vty.c
@@ -31,7 +31,9 @@
#include "lib/json.h"
#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/zebra_vrf.h"
+#include "zebra/zebra_srv6.h"
#include "zebra/zebra_srv6_vty.h"
#include "zebra/zebra_rnh.h"
#include "zebra/redistribute.h"
@@ -70,6 +72,108 @@ static struct cmd_node srv6_loc_node = {
.prompt = "%s(config-srv6-locator)# "
};
+DEFUN (show_srv6_locator,
+ show_srv6_locator_cmd,
+ "show segment-routing srv6 locator [json]",
+ SHOW_STR
+ "Segment Routing\n"
+ "Segment Routing SRv6\n"
+ "Locator Information\n"
+ JSON_STR)
+{
+ const bool uj = use_json(argc, argv);
+ struct zebra_srv6 *srv6 = zebra_srv6_get_default();
+ struct srv6_locator *locator;
+ struct listnode *node;
+ char str[256];
+ int id;
+ json_object *json = NULL;
+ json_object *json_locators = NULL;
+ json_object *json_locator = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
+ json_locators = json_object_new_array();
+ json_object_object_add(json, "locators", json_locators);
+
+ for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
+ json_locator = srv6_locator_json(locator);
+ if (!json_locator)
+ continue;
+ json_object_array_add(json_locators, json_locator);
+
+ }
+
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
+ JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ vty_out(vty, "Locator:\n");
+ vty_out(vty, "Name ID Prefix Status\n");
+ vty_out(vty, "-------------------- ------- ------------------------ -------\n");
+
+ id = 1;
+ for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
+ prefix2str(&locator->prefix, str, sizeof(str));
+ vty_out(vty, "%-20s %7d %-24s %s\n",
+ locator->name, id, str,
+ locator->status_up ? "Up" : "Down");
+ ++id;
+ }
+ vty_out(vty, "\n");
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_srv6_locator_detail,
+ show_srv6_locator_detail_cmd,
+ "show segment-routing srv6 locator NAME detail [json]",
+ SHOW_STR
+ "Segment Routing\n"
+ "Segment Routing SRv6\n"
+ "Locator Information\n"
+ "Locator Name\n"
+ "Detailed information\n"
+ JSON_STR)
+{
+ const bool uj = use_json(argc, argv);
+ struct zebra_srv6 *srv6 = zebra_srv6_get_default();
+ struct srv6_locator *locator;
+ struct listnode *node;
+ char str[256];
+ const char *locator_name = argv[4]->arg;
+
+ if (uj) {
+ vty_out(vty, "JSON format isn't supported\n");
+ return CMD_WARNING;
+ } else {
+ for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
+ if (strcmp(locator->name, locator_name) != 0) {
+ continue;
+ }
+
+ prefix2str(&locator->prefix, str, sizeof(str));
+ vty_out(vty, "Name: %s\n", locator->name);
+ vty_out(vty, "Prefix: %s\n", str);
+ vty_out(vty, "Function-Bit-Len: %u\n",
+ locator->function_bits_length);
+
+ vty_out(vty, "Chunks:\n");
+ struct listnode *node;
+ struct srv6_locator_chunk *chunk;
+ for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node, chunk)) {
+ prefix2str(&chunk->prefix, str, sizeof(str));
+ vty_out(vty, "- prefix: %s, owner: %s\n", str,
+ zebra_route_string(chunk->proto));
+ }
+ }
+
+ }
+
+ return CMD_SUCCESS;
+}
+
DEFUN_NOSH (segment_routing,
segment_routing_cmd,
"segment-routing",
@@ -103,12 +207,106 @@ DEFUN_NOSH (srv6_locator,
"Segment Routing SRv6 locator\n"
"Specify locator-name\n")
{
+ struct srv6_locator *locator = NULL;
+
+ locator = zebra_srv6_locator_lookup(argv[1]->arg);
+ if (locator) {
+ VTY_PUSH_CONTEXT(SRV6_LOC_NODE, locator);
+ locator->status_up = true;
+ return CMD_SUCCESS;
+ }
+
+ locator = srv6_locator_alloc(argv[1]->arg);
+ if (!locator) {
+ vty_out(vty, "%% Alloc failed\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ locator->status_up = true;
+
+ VTY_PUSH_CONTEXT(SRV6_LOC_NODE, locator);
vty->node = SRV6_LOC_NODE;
return CMD_SUCCESS;
}
+DEFUN (locator_prefix,
+ locator_prefix_cmd,
+ "prefix X:X::X:X/M [func-bits (8-64)]",
+ "Configure SRv6 locator prefix\n"
+ "Specify SRv6 locator prefix\n"
+ "Configure SRv6 locator function length in bits\n"
+ "Specify SRv6 locator function length in bits\n")
+{
+ VTY_DECLVAR_CONTEXT(srv6_locator, locator);
+ struct prefix_ipv6 prefix;
+ struct srv6_locator_chunk *chunk = NULL;
+ struct listnode *node = NULL;
+ uint8_t function_bits_length = 16;
+ int ret;
+
+ ret = str2prefix_ipv6(argv[1]->arg, &prefix);
+ if (ret <= 0) {
+ vty_out(vty, "%% Malformed address\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ apply_mask_ipv6(&prefix);
+
+ if (argc >= 3)
+ function_bits_length = strtoul(argv[3]->arg, NULL, 10);
+
+ locator->prefix = prefix;
+ locator->function_bits_length = function_bits_length;
+
+ if (list_isempty(locator->chunks)) {
+ chunk = srv6_locator_chunk_alloc();
+ chunk->prefix = prefix;
+ chunk->proto = 0;
+ listnode_add(locator->chunks, chunk);
+ } else {
+ for (ALL_LIST_ELEMENTS_RO(locator->chunks, node, chunk)) {
+ uint8_t zero[16] = {0};
+ if (memcmp(&chunk->prefix.prefix, zero, 16) == 0) {
+ struct zserv *client;
+ struct listnode *client_node;
+ chunk->prefix = prefix;
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, client_node, client)) {
+ if (client->proto != chunk->proto)
+ continue;
+ struct srv6_locator *tmp;
+ srv6_manager_get_locator_chunk_call(
+ &tmp, client, locator->name, VRF_DEFAULT);
+ }
+ }
+ }
+ }
+
+ zebra_srv6_locator_add(locator);
+ return CMD_SUCCESS;
+}
+
static int zebra_sr_config(struct vty *vty)
{
+ struct zebra_srv6 *srv6 = zebra_srv6_get_default();
+ struct listnode *node;
+ struct srv6_locator *locator;
+ char str[256];
+
+ vty_out(vty, "!\n");
+ if (zebra_srv6_is_enable()) {
+ vty_out(vty, "segment-routing\n");
+ vty_out(vty, " srv6\n");
+ vty_out(vty, " locators\n");
+ for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
+ inet_ntop(AF_INET6, &locator->prefix.prefix,
+ str, sizeof(str));
+ vty_out(vty, " locator %s\n", locator->name);
+ vty_out(vty, " prefix %s/%u\n", str,
+ locator->prefix.prefixlen);
+ vty_out(vty, " !\n");
+ }
+ vty_out(vty, " !\n");
+ vty_out(vty, " !\n");
+ vty_out(vty, "!\n");
+ }
return 0;
}
@@ -129,4 +327,11 @@ void zebra_srv6_vty_init(void)
install_element(SEGMENT_ROUTING_NODE, &srv6_cmd);
install_element(SRV6_NODE, &srv6_locators_cmd);
install_element(SRV6_LOCS_NODE, &srv6_locator_cmd);
+
+ /* Command for configuration */
+ install_element(SRV6_LOC_NODE, &locator_prefix_cmd);
+
+ /* Command for operation */
+ install_element(VIEW_NODE, &show_srv6_locator_cmd);
+ install_element(VIEW_NODE, &show_srv6_locator_detail_cmd);
}