From 621fb5f341aac84275ef5cd24d115ddb6c867064 Mon Sep 17 00:00:00 2001 From: Olivier Dugeon Date: Fri, 21 Jan 2022 19:02:35 +0100 Subject: [PATCH] sharpd: Add call to CSPF New Constaint Shortest Path First algorithm has been introduce in FRR library. Add a new 'show sharp cspf' command as example of how to use these CSPF algorithm. Signed-off-by: Olivier Dugeon --- doc/user/sharp.rst | 11 ++++- sharpd/sharp_vty.c | 103 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) diff --git a/doc/user/sharp.rst b/doc/user/sharp.rst index e088c2f75b..e9d4e2763f 100644 --- a/doc/user/sharp.rst +++ b/doc/user/sharp.rst @@ -139,7 +139,7 @@ keyword. At present, no sharp commands will be preserved in the config. .. clicmd:: sharp import-te - Import Traffic Engineering Database produce by OSPF or IS-IS. + Import Traffic Engineering Database produced by OSPF or IS-IS. .. clicmd:: show sharp ted [verbose|json] @@ -147,6 +147,15 @@ keyword. At present, no sharp commands will be preserved in the config. Show imported Traffic Engineering Data Base +.. clicmd:: show sharp cspf source destination (0-16777215) [rsv-bw (0-7) BANDWIDTH] + + Show the result of a call to the Constraint Shortest Path First (CSPF) + algorithm that allows to compute a path between a source and a + destination under various constraints. Standard Metric, TE Metric, Delay + and Bandwidth are supported constraints. Prior to use this function, it is + necessary to import a Traffic Engineering Database with `sharp import-te` + command (see above). + .. clicmd:: sharp install seg6-routes [vrf NAME] nexthop-seg6 X:X::X:X encap X:X::X:X (1-1000000) This command installs a route for SRv6 Transit behavior (on Linux it is diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 0a323f744e..e1ad5dcecc 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -29,7 +29,9 @@ #include "vrf.h" #include "zclient.h" #include "nexthop_group.h" +#include "linklist.h" #include "link_state.h" +#include "cspf.h" #include "sharpd/sharp_globals.h" #include "sharpd/sharp_zebra.h" @@ -1150,6 +1152,106 @@ DEFPY (show_sharp_segment_routing_srv6, return CMD_SUCCESS; } +DEFPY (show_sharp_cspf, + show_sharp_cspf_cmd, + "show sharp cspf source \ + destination \ + (0-16777215)$cost \ + [rsv-bw (0-7)$cos BANDWIDTH$bw]", + SHOW_STR + SHARP_STR + "Constraint Shortest Path First path computation\n" + "Source of the path\n" + "IPv4 Source address in dot decimal A.B.C.D\n" + "IPv6 Source address as X:X:X:X\n" + "Destination of the path\n" + "IPv4 Destination address in dot decimal A.B.C.D\n" + "IPv6 Destination address as X:X:X:X\n" + "Maximum Metric\n" + "Maximum TE Metric\n" + "Maxim Delay\n" + "Value of Maximum cost\n" + "Reserved Bandwidth of this path\n" + "Class of Service or Priority level\n" + "Bytes/second (IEEE floating point format)\n") +{ + + struct cspf *algo; + struct constraints csts; + struct c_path *path; + struct listnode *node; + struct ls_edge *edge; + int idx; + + if (sg.ted == NULL) { + vty_out(vty, "MPLS-TE import is not enabled\n"); + return CMD_WARNING; + } + + if ((src4.s_addr != INADDR_ANY && dst4.s_addr == INADDR_ANY) || + (src4.s_addr == INADDR_ANY && dst4.s_addr != INADDR_ANY)) { + vty_out(vty, "Don't mix IPv4 and IPv6 addresses\n"); + return CMD_WARNING; + } + + idx = 6; + memset(&csts, 0, sizeof(struct constraints)); + if (argv_find(argv, argc, "metric", &idx)) { + csts.ctype = CSPF_METRIC; + csts.cost = cost; + } + idx = 6; + if (argv_find(argv, argc, "te-metric", &idx)) { + csts.ctype = CSPF_TE_METRIC; + csts.cost = cost; + } + idx = 6; + if (argv_find(argv, argc, "delay", &idx)) { + csts.ctype = CSPF_DELAY; + csts.cost = cost; + } + if (argc > 9) { + if (sscanf(bw, "%g", &csts.bw) != 1) { + vty_out(vty, "Bandwidth constraints: fscanf: %s\n", + safe_strerror(errno)); + return CMD_WARNING_CONFIG_FAILED; + } + csts.cos = cos; + } + + /* Initialize and call point-to-point Path computation */ + if (src4.s_addr != INADDR_ANY) + algo = cspf_init_v4(NULL, sg.ted, src4, dst4, &csts); + else + algo = cspf_init_v6(NULL, sg.ted, src6, dst6, &csts); + path = compute_p2p_path(algo, sg.ted); + cspf_del(algo); + + if (!path) { + vty_out(vty, "Path computation failed without error\n"); + return CMD_SUCCESS; + } + if (path->status != SUCCESS) { + vty_out(vty, "Path computation failed: %d\n", path->status); + return CMD_SUCCESS; + } + + vty_out(vty, "Path computation success\n"); + vty_out(vty, "\tCost: %d\n", path->weight); + vty_out(vty, "\tEdges:"); + for (ALL_LIST_ELEMENTS_RO(path->edges, node, edge)) { + if (src4.s_addr != INADDR_ANY) + vty_out(vty, " %pI4", + &edge->attributes->standard.remote); + else + vty_out(vty, " %pI6", + &edge->attributes->standard.remote6); + } + vty_out(vty, "\n"); + + return CMD_SUCCESS; +} + void sharp_vty_init(void) { install_element(ENABLE_NODE, &install_routes_data_dump_cmd); @@ -1175,6 +1277,7 @@ 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, &show_sharp_cspf_cmd); install_element(ENABLE_NODE, &sharp_srv6_manager_get_locator_chunk_cmd); install_element(ENABLE_NODE, -- 2.39.5