summaryrefslogtreecommitdiffstats
path: root/vtysh
diff options
context:
space:
mode:
authorSebastien Merle <sebastien@netdef.org>2020-07-31 18:04:20 +0200
committerSebastien Merle <sebastien@netdef.org>2020-12-18 16:34:02 +0100
commit4d7b695d3abe80fbb1b666aed8faa1b9e9387fdb (patch)
tree9dc538cd213acebfe50152a048799f4f09bbcbc9 /vtysh
parentMerge pull request #7717 from ranjanyash54/2368 (diff)
downloadfrr-4d7b695d3abe80fbb1b666aed8faa1b9e9387fdb.tar.xz
frr-4d7b695d3abe80fbb1b666aed8faa1b9e9387fdb.zip
pathd: New SR-TE policy management daemon
This new daemon manages Segment-Routing Traffic-Engineering (SR-TE) Policies and installs them into zebra. It provides the usual yang support and vtysh commands to define or change SR-TE Policies. In a nutshell SR-TE Policies provide the possibility to steer traffic through a (possibly dynamic) list of Segment Routing segments to the endpoint of the policy. This list of segments is part of a Candidate Path which again belongs to the SR-TE Policy. SR-TE Policies are uniquely identified by their color and endpoint. The color can be used to e.g. match BGP communities on incoming traffic. There can be multiple Candidate Paths for a single policy, the active Candidate Path is chosen according to certain conditions of which the most important is its preference. Candidate Paths can be explicit (fixed list of segments) or dynamic (list of segment comes from e.g. PCEP, see below). Configuration example: segment-routing traffic-eng segment-list SL index 10 mpls label 1111 index 20 mpls label 2222 ! policy color 4 endpoint 10.10.10.4 name POL4 binding-sid 104 candidate-path preference 100 name exp explicit segment-list SL candidate-path preference 200 name dyn dynamic ! ! ! There is an important connection between dynamic Candidate Paths and the overall topic of Path Computation. Later on for pathd a dynamic module will be introduced that is capable of communicating via the PCEP protocol with a PCE (Path Computation Element) which again is capable of calculating paths according to its local TED (Traffic Engineering Database). This dynamic module will be able to inject the mentioned dynamic Candidate Paths into pathd based on calculated paths from a PCE. https://tools.ietf.org/html/draft-ietf-spring-segment-routing-policy-06 Co-authored-by: Sebastien Merle <sebastien@netdef.org> Co-authored-by: Renato Westphal <renato@opensourcerouting.org> Co-authored-by: GalaxyGorilla <sascha@netdef.org> Co-authored-by: Emanuele Di Pascale <emanuele@voltanet.io> Signed-off-by: Sebastien Merle <sebastien@netdef.org>
Diffstat (limited to 'vtysh')
-rw-r--r--vtysh/vtysh.c162
-rw-r--r--vtysh/vtysh.h3
2 files changed, 164 insertions, 1 deletions
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index c78132508..93a63cd96 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -139,6 +139,7 @@ struct vtysh_client vtysh_client[] = {
{.fd = -1, .name = "staticd", .flag = VTYSH_STATICD, .next = NULL},
{.fd = -1, .name = "bfdd", .flag = VTYSH_BFDD, .next = NULL},
{.fd = -1, .name = "vrrpd", .flag = VTYSH_VRRPD, .next = NULL},
+ {.fd = -1, .name = "pathd", .flag = VTYSH_PATHD, .next = NULL},
};
/* Searches for client by name, returns index */
@@ -538,6 +539,11 @@ static int vtysh_execute_func(const char *line, int pager)
|| saved_node == LDP_IPV6_IFACE_NODE)
&& (tried == 1)) {
vtysh_execute("exit");
+ } else if ((saved_node == SR_SEGMENT_LIST_NODE
+ || saved_node == SR_POLICY_NODE
+ || saved_node == SR_CANDIDATE_DYN_NODE)
+ && (tried > 0)) {
+ vtysh_execute("exit");
} else if (tried) {
vtysh_execute("end");
vtysh_execute("configure");
@@ -689,6 +695,7 @@ int vtysh_mark_file(const char *filename)
int ret;
vector vline;
int tried = 0;
+ bool ending;
const struct cmd_element *cmd;
int saved_ret, prev_node;
int lineno = 0;
@@ -740,6 +747,12 @@ int vtysh_mark_file(const char *filename)
vty->node = LDP_L2VPN_NODE;
}
break;
+ case SR_CANDIDATE_DYN_NODE:
+ if (strncmp(vty_buf_copy, " ", 2)) {
+ vty_out(vty, " exit\n");
+ vty->node = SR_POLICY_NODE;
+ }
+ break;
default:
break;
}
@@ -812,6 +825,23 @@ int vtysh_mark_file(const char *filename)
} else if ((prev_node == BFD_PEER_NODE)
&& (tried == 1)) {
vty_out(vty, "exit\n");
+ } else if (((prev_node == SEGMENT_ROUTING_NODE)
+ || (prev_node == SR_TRAFFIC_ENG_NODE)
+ || (prev_node == SR_SEGMENT_LIST_NODE)
+ || (prev_node == SR_POLICY_NODE)
+ || (prev_node == SR_CANDIDATE_DYN_NODE))
+ && (tried > 0)) {
+ ending = (vty->node != SEGMENT_ROUTING_NODE)
+ && (vty->node != SR_TRAFFIC_ENG_NODE)
+ && (vty->node != SR_SEGMENT_LIST_NODE)
+ && (vty->node != SR_POLICY_NODE)
+ && (vty->node != SR_CANDIDATE_DYN_NODE);
+ if (ending)
+ tried--;
+ while (tried-- > 0)
+ vty_out(vty, "exit\n");
+ if (ending)
+ vty_out(vty, "end\n");
} else if (tried) {
vty_out(vty, "end\n");
}
@@ -1219,6 +1249,41 @@ static struct cmd_node pw_node = {
.prompt = "%s(config-pw)# ",
};
+static struct cmd_node segment_routing_node = {
+ .name = "segment-routing",
+ .node = SEGMENT_ROUTING_NODE,
+ .parent_node = CONFIG_NODE,
+ .prompt = "%s(config-sr)# ",
+};
+
+static struct cmd_node sr_traffic_eng_node = {
+ .name = "sr traffic-eng",
+ .node = SR_TRAFFIC_ENG_NODE,
+ .parent_node = SEGMENT_ROUTING_NODE,
+ .prompt = "%s(config-sr-te)# ",
+};
+
+static struct cmd_node srte_segment_list_node = {
+ .name = "srte segment-list",
+ .node = SR_SEGMENT_LIST_NODE,
+ .parent_node = SR_TRAFFIC_ENG_NODE,
+ .prompt = "%s(config-sr-te-segment-list)# ",
+};
+
+static struct cmd_node srte_policy_node = {
+ .name = "srte policy",
+ .node = SR_POLICY_NODE,
+ .parent_node = SR_TRAFFIC_ENG_NODE,
+ .prompt = "%s(config-sr-te-policy)# ",
+};
+
+static struct cmd_node srte_candidate_dyn_node = {
+ .name = "srte candidate-dyn",
+ .node = SR_CANDIDATE_DYN_NODE,
+ .parent_node = SR_POLICY_NODE,
+ .prompt = "%s(config-sr-te-candidate)# ",
+};
+
static struct cmd_node vrf_node = {
.name = "vrf",
.node = VRF_NODE,
@@ -1974,6 +2039,60 @@ DEFUNSH(VTYSH_FABRICD, router_openfabric, router_openfabric_cmd, "router openfab
}
#endif /* HAVE_FABRICD */
+#if defined(HAVE_PATHD)
+DEFUNSH(VTYSH_PATHD, segment_routing, segment_routing_cmd,
+ "segment-routing",
+ "Configure segment routing\n")
+{
+ vty->node = SEGMENT_ROUTING_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUNSH(VTYSH_PATHD, sr_traffic_eng, sr_traffic_eng_cmd,
+ "traffic-eng",
+ "Configure SR traffic engineering\n")
+{
+ vty->node = SR_TRAFFIC_ENG_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUNSH(VTYSH_PATHD, srte_segment_list, srte_segment_list_cmd,
+ "segment-list WORD$name",
+ "Segment List\n"
+ "Segment List Name\n")
+{
+ vty->node = SR_SEGMENT_LIST_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUNSH(VTYSH_PATHD, srte_policy, srte_policy_cmd,
+ "policy color (0-4294967295) endpoint <A.B.C.D|X:X::X:X>",
+ "Segment Routing Policy\n"
+ "SR Policy color\n"
+ "SR Policy color value\n"
+ "SR Policy endpoint\n"
+ "SR Policy endpoint IPv4 address\n"
+ "SR Policy endpoint IPv6 address\n")
+{
+ vty->node = SR_POLICY_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUNSH(VTYSH_PATHD, srte_policy_candidate_dyn_path,
+ srte_policy_candidate_dyn_path_cmd,
+ "candidate-path preference (0-4294967295) name WORD dynamic",
+ "Segment Routing Policy Candidate Path\n"
+ "Segment Routing Policy Candidate Path Preference\n"
+ "Administrative Preference\n"
+ "Segment Routing Policy Candidate Path Name\n"
+ "Symbolic Name\n"
+ "Dynamic Path\n")
+{
+ vty->node = SR_CANDIDATE_DYN_NODE;
+ return CMD_SUCCESS;
+}
+#endif /* HAVE_PATHD */
+
DEFUNSH(VTYSH_RMAP, vtysh_route_map, vtysh_route_map_cmd,
"route-map WORD <deny|permit> (1-65535)",
"Create route-map or enter route-map command mode\n"
@@ -2347,6 +2466,18 @@ DEFUNSH(VTYSH_KEYS, vtysh_quit_keys, vtysh_quit_keys_cmd, "quit",
return vtysh_exit_keys(self, vty, argc, argv);
}
+DEFUNSH(VTYSH_PATHD, vtysh_exit_pathd, vtysh_exit_pathd_cmd, "exit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit(vty);
+}
+
+DEFUNSH(VTYSH_PATHD, vtysh_quit_pathd, vtysh_quit_pathd_cmd, "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_pathd(self, vty, argc, argv);
+}
+
DEFUNSH(VTYSH_ALL, vtysh_exit_line_vty, vtysh_exit_line_vty_cmd, "exit",
"Exit current mode and down to previous mode\n")
{
@@ -4144,6 +4275,37 @@ void vtysh_init_vty(void)
install_element(BFD_PROFILE_NODE, &vtysh_end_all_cmd);
#endif /* HAVE_BFDD */
+#if defined(HAVE_PATHD)
+ install_node(&segment_routing_node);
+ install_node(&sr_traffic_eng_node);
+ install_node(&srte_segment_list_node);
+ install_node(&srte_policy_node);
+ install_node(&srte_candidate_dyn_node);
+
+ install_element(SEGMENT_ROUTING_NODE, &vtysh_exit_pathd_cmd);
+ install_element(SEGMENT_ROUTING_NODE, &vtysh_quit_pathd_cmd);
+ install_element(SR_TRAFFIC_ENG_NODE, &vtysh_exit_pathd_cmd);
+ install_element(SR_TRAFFIC_ENG_NODE, &vtysh_quit_pathd_cmd);
+ install_element(SR_SEGMENT_LIST_NODE, &vtysh_exit_pathd_cmd);
+ install_element(SR_SEGMENT_LIST_NODE, &vtysh_quit_pathd_cmd);
+ install_element(SR_POLICY_NODE, &vtysh_exit_pathd_cmd);
+ install_element(SR_POLICY_NODE, &vtysh_quit_pathd_cmd);
+ install_element(SR_CANDIDATE_DYN_NODE, &vtysh_exit_pathd_cmd);
+ install_element(SR_CANDIDATE_DYN_NODE, &vtysh_quit_pathd_cmd);
+
+ install_element(SEGMENT_ROUTING_NODE, &vtysh_end_all_cmd);
+ install_element(SR_TRAFFIC_ENG_NODE, &vtysh_end_all_cmd);
+ install_element(SR_SEGMENT_LIST_NODE, &vtysh_end_all_cmd);
+ install_element(SR_POLICY_NODE, &vtysh_end_all_cmd);
+ install_element(SR_CANDIDATE_DYN_NODE, &vtysh_end_all_cmd);
+
+ install_element(CONFIG_NODE, &segment_routing_cmd);
+ install_element(SEGMENT_ROUTING_NODE, &sr_traffic_eng_cmd);
+ install_element(SR_TRAFFIC_ENG_NODE, &srte_segment_list_cmd);
+ install_element(SR_TRAFFIC_ENG_NODE, &srte_policy_cmd);
+ install_element(SR_POLICY_NODE, &srte_policy_candidate_dyn_path_cmd);
+#endif /* HAVE_PATHD */
+
/* keychain */
install_node(&keychain_node);
install_element(CONFIG_NODE, &key_chain_cmd);
diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
index d2675a81b..9683518b6 100644
--- a/vtysh/vtysh.h
+++ b/vtysh/vtysh.h
@@ -43,6 +43,7 @@ DECLARE_MGROUP(MVTYSH)
#define VTYSH_BFDD 0x10000
#define VTYSH_FABRICD 0x20000
#define VTYSH_VRRPD 0x40000
+#define VTYSH_PATHD 0x80000
#define VTYSH_WAS_ACTIVE (-2)
@@ -51,7 +52,7 @@ DECLARE_MGROUP(MVTYSH)
/* watchfrr is not in ALL since library CLI functions should not be
* run on it (logging & co. should stay in a fixed/frozen config, and
* things like prefix lists are not even initialised) */
-#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD|VTYSH_FABRICD|VTYSH_VRRPD
+#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD|VTYSH_FABRICD|VTYSH_VRRPD|VTYSH_PATHD
#define VTYSH_ACL VTYSH_BFDD|VTYSH_BABELD|VTYSH_BGPD|VTYSH_EIGRPD|VTYSH_ISISD|VTYSH_FABRICD|VTYSH_LDPD|VTYSH_NHRPD|VTYSH_OSPF6D|VTYSH_OSPFD|VTYSH_PBRD|VTYSH_PIMD|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_VRRPD|VTYSH_ZEBRA
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_FABRICD
#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD|VTYSH_FABRICD|VTYSH_VRRPD