2 * Copyright (C) 2020 NetDEF, Inc.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option)
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along
15 * with this program; see the file COPYING; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "northbound_cli.h"
30 #include "termtable.h"
32 #include "pathd/pathd.h"
33 #include "pathd/path_nb.h"
34 #include "pathd/path_cli_clippy.c"
35 #include "pathd/path_ted.h"
37 #define XPATH_MAXATTRSIZE 64
38 #define XPATH_MAXKEYSIZE 42
39 #define XPATH_POLICY_BASELEN 100
40 #define XPATH_POLICY_MAXLEN (XPATH_POLICY_BASELEN + XPATH_MAXATTRSIZE)
41 #define XPATH_CANDIDATE_BASELEN (XPATH_POLICY_BASELEN + XPATH_MAXKEYSIZE)
42 #define XPATH_CANDIDATE_MAXLEN (XPATH_CANDIDATE_BASELEN + XPATH_MAXATTRSIZE)
45 static int config_write_segment_routing(struct vty
*vty
);
46 static int segment_list_has_src_dst(
47 struct vty
*vty
, char *xpath
, long index
, const char *index_str
,
48 struct in_addr adj_src_ipv4
, struct in_addr adj_dst_ipv4
,
49 struct in6_addr adj_src_ipv6
, struct in6_addr adj_dst_ipv6
,
50 const char *adj_src_ipv4_str
, const char *adj_dst_ipv4_str
,
51 const char *adj_src_ipv6_str
, const char *adj_dst_ipv6_str
);
52 static int segment_list_has_prefix(
53 struct vty
*vty
, char *xpath
, long index
, const char *index_str
,
54 const struct prefix_ipv4
*prefix_ipv4
, const char *prefix_ipv4_str
,
55 const struct prefix_ipv6
*prefix_ipv6
, const char *prefix_ipv6_str
,
56 const char *has_algo
, long algo
, const char *algo_str
,
57 const char *has_iface_id
, long iface_id
, const char *iface_id_str
);
59 DEFINE_MTYPE_STATIC(PATHD
, PATH_CLI
, "Client");
61 DEFINE_HOOK(pathd_srte_config_write
, (struct vty
*vty
), (vty
));
63 /* Vty node structures. */
64 static struct cmd_node segment_routing_node
= {
65 .name
= "segment-routing",
66 .node
= SEGMENT_ROUTING_NODE
,
67 .parent_node
= CONFIG_NODE
,
68 .prompt
= "%s(config-sr)# ",
69 .config_write
= config_write_segment_routing
,
72 static struct cmd_node sr_traffic_eng_node
= {
73 .name
= "sr traffic-eng",
74 .node
= SR_TRAFFIC_ENG_NODE
,
75 .parent_node
= SEGMENT_ROUTING_NODE
,
76 .prompt
= "%s(config-sr-te)# ",
79 static struct cmd_node srte_segment_list_node
= {
80 .name
= "srte segment-list",
81 .node
= SR_SEGMENT_LIST_NODE
,
82 .parent_node
= SR_TRAFFIC_ENG_NODE
,
83 .prompt
= "%s(config-sr-te-segment-list)# ",
86 static struct cmd_node srte_policy_node
= {
87 .name
= "srte policy",
88 .node
= SR_POLICY_NODE
,
89 .parent_node
= SR_TRAFFIC_ENG_NODE
,
90 .prompt
= "%s(config-sr-te-policy)# ",
93 static struct cmd_node srte_candidate_dyn_node
= {
94 .name
= "srte candidate-dyn",
95 .node
= SR_CANDIDATE_DYN_NODE
,
96 .parent_node
= SR_POLICY_NODE
,
97 .prompt
= "%s(config-sr-te-candidate)# ",
104 DEFPY(show_srte_policy
,
105 show_srte_policy_cmd
,
112 struct srte_policy
*policy
;
115 if (RB_EMPTY(srte_policy_head
, &srte_policies
)) {
116 vty_out(vty
, "No SR Policies to display.\n\n");
121 tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
122 ttable_add_row(tt
, "Endpoint|Color|Name|BSID|Status");
123 tt
->style
.cell
.rpad
= 2;
124 tt
->style
.corner
= '+';
126 ttable_rowseps(tt
, 0, BOTTOM
, true, '-');
128 RB_FOREACH (policy
, srte_policy_head
, &srte_policies
) {
129 char endpoint
[ENDPOINT_STR_LENGTH
];
130 char binding_sid
[16] = "-";
132 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
133 if (policy
->binding_sid
!= MPLS_LABEL_NONE
)
134 snprintf(binding_sid
, sizeof(binding_sid
), "%u",
135 policy
->binding_sid
);
137 ttable_add_row(tt
, "%s|%u|%s|%s|%s", endpoint
, policy
->color
,
138 policy
->name
, binding_sid
,
139 policy
->status
== SRTE_POLICY_STATUS_UP
144 /* Dump the generated table. */
145 table
= ttable_dump(tt
, "\n");
146 vty_out(vty
, "%s\n", table
);
147 XFREE(MTYPE_TMP
, table
);
156 * Show detailed SR-TE info
158 DEFPY(show_srte_policy_detail
,
159 show_srte_policy_detail_cmd
,
160 "show sr-te policy detail",
164 "Show a detailed summary\n")
166 struct srte_policy
*policy
;
168 if (RB_EMPTY(srte_policy_head
, &srte_policies
)) {
169 vty_out(vty
, "No SR Policies to display.\n\n");
174 RB_FOREACH (policy
, srte_policy_head
, &srte_policies
) {
175 struct srte_candidate
*candidate
;
176 char endpoint
[ENDPOINT_STR_LENGTH
];
177 char binding_sid
[16] = "-";
178 char *segment_list_info
;
179 static char undefined_info
[] = "(undefined)";
180 static char created_by_pce_info
[] = "(created by PCE)";
183 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
184 if (policy
->binding_sid
!= MPLS_LABEL_NONE
)
185 snprintf(binding_sid
, sizeof(binding_sid
), "%u",
186 policy
->binding_sid
);
188 "Endpoint: %s Color: %u Name: %s BSID: %s Status: %s\n",
189 endpoint
, policy
->color
, policy
->name
, binding_sid
,
190 policy
->status
== SRTE_POLICY_STATUS_UP
? "Active"
193 RB_FOREACH (candidate
, srte_candidate_head
,
194 &policy
->candidate_paths
) {
195 struct srte_segment_list
*segment_list
;
197 segment_list
= candidate
->lsp
->segment_list
;
198 if (segment_list
== NULL
)
199 segment_list_info
= undefined_info
;
200 else if (segment_list
->protocol_origin
202 segment_list_info
= created_by_pce_info
;
205 candidate
->lsp
->segment_list
->name
;
208 " %s Preference: %d Name: %s Type: %s Segment-List: %s Protocol-Origin: %s\n",
209 CHECK_FLAG(candidate
->flags
, F_CANDIDATE_BEST
)
212 candidate
->preference
, candidate
->name
,
213 candidate
->type
== SRTE_CANDIDATE_TYPE_EXPLICIT
218 candidate
->lsp
->protocol_origin
));
228 segment_routing_list
,
231 "Configure segment routing\n")
233 VTY_PUSH_CONTEXT_NULL(SEGMENT_ROUTING_NODE
);
241 "Configure SR traffic engineering\n")
243 VTY_PUSH_CONTEXT_NULL(SR_TRAFFIC_ENG_NODE
);
248 * XPath: /frr-pathd:pathd/srte/segment-list
252 srte_segment_list_cmd
,
253 "segment-list WORD$name",
255 "Segment List Name\n")
257 char xpath
[XPATH_MAXLEN
];
260 snprintf(xpath
, sizeof(xpath
),
261 "/frr-pathd:pathd/srte/segment-list[name='%s']", name
);
262 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
264 snprintf(xpath
, sizeof(xpath
),
265 "/frr-pathd:pathd/srte/segment-list[name='%s']/protocol-origin",
267 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, "local");
269 snprintf(xpath
, sizeof(xpath
),
270 "/frr-pathd:pathd/srte/segment-list[name='%s']/originator", name
);
271 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, "config");
273 ret
= nb_cli_apply_changes(vty
, NULL
);
274 if (ret
== CMD_SUCCESS
) {
275 snprintf(xpath
, sizeof(xpath
),
276 "/frr-pathd:pathd/srte/segment-list[name='%s']", name
);
277 VTY_PUSH_XPATH(SR_SEGMENT_LIST_NODE
, xpath
);
283 DEFPY(srte_no_segment_list
,
284 srte_no_segment_list_cmd
,
285 "no segment-list WORD$name",
288 "Segment List Name\n")
290 char xpath
[XPATH_MAXLEN
];
292 snprintf(xpath
, sizeof(xpath
),
293 "/frr-pathd:pathd/srte/segment-list[name='%s']", name
);
294 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
296 return nb_cli_apply_changes(vty
, NULL
);
299 void cli_show_srte_segment_list(struct vty
*vty
, const struct lyd_node
*dnode
,
302 vty_out(vty
, " segment-list %s\n",
303 yang_dnode_get_string(dnode
, "./name"));
306 void cli_show_srte_segment_list_end(struct vty
*vty
,
307 const struct lyd_node
*dnode
)
309 vty_out(vty
, " exit\n");
312 static int segment_list_has_src_dst(
313 struct vty
*vty
, char *xpath
, long index
, const char *index_str
,
314 struct in_addr adj_src_ipv4
, struct in_addr adj_dst_ipv4
,
315 struct in6_addr adj_src_ipv6
, struct in6_addr adj_dst_ipv6
,
316 const char *adj_src_ipv4_str
, const char *adj_dst_ipv4_str
,
317 const char *adj_src_ipv6_str
, const char *adj_dst_ipv6_str
)
319 const char *node_src_id
;
320 uint32_t ted_sid
= MPLS_LABEL_NONE
;
322 struct ipaddr ip_src
= {};
323 struct ipaddr ip_dst
= {};
324 if (adj_src_ipv4_str
!= NULL
) {
325 ip_src
.ipa_type
= IPADDR_V4
;
326 ip_src
.ip
._v4_addr
= adj_src_ipv4
;
327 ip_dst
.ipa_type
= IPADDR_V4
;
328 ip_dst
.ip
._v4_addr
= adj_dst_ipv4
;
329 } else if (adj_src_ipv6_str
!= NULL
) {
330 ip_src
.ipa_type
= IPADDR_V6
;
331 ip_src
.ip
._v6_addr
= adj_src_ipv6
;
332 ip_dst
.ipa_type
= IPADDR_V6
;
333 ip_dst
.ip
._v6_addr
= adj_dst_ipv6
;
335 return CMD_ERR_NO_MATCH
;
337 ted_sid
= path_ted_query_type_f(&ip_src
, &ip_dst
);
338 if (ted_sid
== MPLS_LABEL_NONE
) {
340 "%s: [rcv ted] CLI NOT FOUND Continue query_type_f SRC (%pIA) DST (%pIA)!",
341 __func__
, &ip_src
, &ip_dst
);
344 snprintf(xpath
, XPATH_MAXLEN
, "./segment[index='%s']/nai/type",
346 if (adj_src_ipv4_str
!= NULL
) {
347 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
349 node_src_id
= adj_src_ipv4_str
;
350 } else if (adj_src_ipv6_str
!= NULL
) {
351 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
353 node_src_id
= adj_src_ipv6_str
;
356 * This is just to make the compiler happy about
357 * node_src_id not being initialized. This
358 * should never happen unless we change the cli
361 assert(!"We must have a adj_src_ipv4_str or a adj_src_ipv6_str");
365 snprintf(xpath
, XPATH_MAXLEN
, "./segment[index='%s']/nai/local-address",
367 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, node_src_id
);
368 snprintf(xpath
, XPATH_MAXLEN
,
369 "./segment[index='%s']/nai/remote-address", index_str
);
370 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
371 adj_dst_ipv4_str
? adj_dst_ipv4_str
375 int segment_list_has_prefix(
376 struct vty
*vty
, char *xpath
, long index
, const char *index_str
,
377 const struct prefix_ipv4
*prefix_ipv4
, const char *prefix_ipv4_str
,
378 const struct prefix_ipv6
*prefix_ipv6
, const char *prefix_ipv6_str
,
379 const char *has_algo
, long algo
, const char *algo_str
,
380 const char *has_iface_id
, long iface_id
, const char *iface_id_str
)
382 char buf_prefix
[INET6_ADDRSTRLEN
];
384 uint32_t ted_sid
= MPLS_LABEL_NONE
;
385 struct prefix prefix_cli
= {};
386 struct ipaddr pre_ipaddr
= {};
387 /* prefix with algorithm or local interface id */
389 snprintf(xpath
, XPATH_MAXLEN
, "./segment[index='%s']/nai/type",
391 if (has_iface_id
!= NULL
) {
392 if (prefix_ipv4_str
!= NULL
) {
393 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
395 } else if (prefix_ipv6_str
!= NULL
) {
396 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
399 return CMD_ERR_NO_MATCH
;
402 if (prefix_ipv4_str
!= NULL
) {
403 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
405 } else if (prefix_ipv6_str
!= NULL
) {
406 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
409 return CMD_ERR_NO_MATCH
;
413 if (prefix_ipv4_str
!= NULL
) {
414 if (!str2prefix(prefix_ipv4_str
, &prefix_cli
)) {
415 vty_out(vty
, "%% Malformed prefix\n");
416 return CMD_WARNING_CONFIG_FAILED
;
418 inet_ntop(AF_INET
, &prefix_cli
.u
.prefix4
, buf_prefix
,
420 pre_ipaddr
.ipa_type
= IPADDR_V4
;
421 pre_ipaddr
.ip
._v4_addr
= prefix_cli
.u
.prefix4
;
422 } else if (prefix_ipv6_str
!= NULL
) {
423 if (!str2prefix(prefix_ipv6_str
, &prefix_cli
)) {
424 vty_out(vty
, "%% Malformed prefix\n");
425 return CMD_WARNING_CONFIG_FAILED
;
427 inet_ntop(AF_INET6
, &prefix_cli
.u
.prefix6
, buf_prefix
,
429 pre_ipaddr
.ipa_type
= IPADDR_V6
;
430 pre_ipaddr
.ip
._v6_addr
= prefix_cli
.u
.prefix6
;
432 snprintf(xpath
, XPATH_MAXLEN
, "./segment[index='%s']/nai/local-address",
434 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, buf_prefix
);
435 snprintf(xpath
, XPATH_MAXLEN
,
436 "./segment[index='%s']/nai/local-prefix-len", index_str
);
437 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
439 ? strchr(prefix_ipv4_str
, '/') + 1
440 : strchr(prefix_ipv6_str
, '/') + 1);
442 if (has_algo
!= NULL
) {
443 snprintf(xpath
, XPATH_MAXLEN
,
444 "./segment[index='%s']/nai/algorithm", index_str
);
445 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, algo_str
);
447 if (has_iface_id
!= NULL
) {
448 snprintf(xpath
, XPATH_MAXLEN
,
449 "./segment[index='%s']/nai/local-interface",
451 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
455 if (has_algo
!= NULL
) {
456 ted_sid
= path_ted_query_type_c(&prefix_cli
, algo
);
457 if (ted_sid
== MPLS_LABEL_NONE
) {
459 "%s: [rcv ted] CLI NOT FOUND Continue query_type_c PREFIX (%pIA/%d) ALGO (%ld) sid:(%d)!",
460 __func__
, &pre_ipaddr
, prefix_cli
.prefixlen
,
464 if (has_iface_id
!= NULL
) {
465 ted_sid
= path_ted_query_type_e(&prefix_cli
, iface_id
);
466 if (ted_sid
== MPLS_LABEL_NONE
) {
468 "%s: [rcv ted] CLI NOT FOUND Continue query_type_e PREFIX (%pIA/%d) IFACE (%ld) sid:(%d)!",
469 __func__
, &pre_ipaddr
, prefix_cli
.prefixlen
,
476 * XPath: /frr-pathd:pathd/srte/segment-list/segment
478 /* clang-format off */
479 DEFPY(srte_segment_list_segment
, srte_segment_list_segment_cmd
,
480 "index (0-4294967295)$index <[mpls$has_mpls_label label (16-1048575)$label] "
483 "prefix <A.B.C.D/M$prefix_ipv4|X:X::X:X/M$prefix_ipv6>"
484 "<algorithm$has_algo (0-1)$algo| iface$has_iface_id (0-4294967295)$iface_id>"
485 "| adjacency$has_adj "
486 "<A.B.C.D$adj_src_ipv4 A.B.C.D$adj_dst_ipv4|X:X::X:X$adj_src_ipv6 X:X::X:X$adj_dst_ipv6>"
495 "NAI prefix identifier\n"
496 "NAI IPv4 prefix identifier\n"
497 "NAI IPv6 prefix identifier\n"
499 "Algorithm Value SPF or Strict-SPF\n"
503 "ADJ IPv4 src identifier\n"
504 "ADJ IPv4 dst identifier\n"
505 "ADJ IPv6 src identifier\n"
506 "ADJ IPv6 dst identifier\n")
507 /* clang-format on */
509 char xpath
[XPATH_MAXLEN
];
510 int status
= CMD_SUCCESS
;
513 snprintf(xpath
, sizeof(xpath
), "./segment[index='%s']", index_str
);
514 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
516 if (has_mpls_label
!= NULL
) {
517 snprintf(xpath
, sizeof(xpath
),
518 "./segment[index='%s']/sid-value", index_str
);
519 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, label_str
);
520 return nb_cli_apply_changes(vty
, NULL
);
523 if (has_adj
!= NULL
) {
524 status
= segment_list_has_src_dst(vty
, xpath
, index
, index_str
,
525 adj_src_ipv4
, adj_dst_ipv4
,
526 adj_src_ipv6
, adj_dst_ipv6
,
527 adj_src_ipv4_str
, adj_dst_ipv4_str
,
528 adj_src_ipv6_str
, adj_dst_ipv6_str
);
529 if (status
!= CMD_SUCCESS
)
532 status
= segment_list_has_prefix(
533 vty
, xpath
, index
, index_str
, prefix_ipv4
,
534 prefix_ipv4_str
, prefix_ipv6
, prefix_ipv6_str
, has_algo
,
535 algo
, algo_str
, has_iface_id
, iface_id
, iface_id_str
);
536 if (status
!= CMD_SUCCESS
)
540 return nb_cli_apply_changes(vty
, NULL
);
543 DEFPY(srte_segment_list_no_segment
,
544 srte_segment_list_no_segment_cmd
,
545 "no index (0-4294967295)$index",
550 char xpath
[XPATH_MAXLEN
];
552 snprintf(xpath
, sizeof(xpath
), "./segment[index='%s']", index_str
);
553 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
555 return nb_cli_apply_changes(vty
, NULL
);
558 void cli_show_srte_segment_list_segment(struct vty
*vty
,
559 const struct lyd_node
*dnode
,
562 vty_out(vty
, " index %s", yang_dnode_get_string(dnode
, "./index"));
563 if (yang_dnode_exists(dnode
, "./sid-value")) {
564 vty_out(vty
, " mpls label %s",
565 yang_dnode_get_string(dnode
, "./sid-value"));
567 if (yang_dnode_exists(dnode
, "./nai")) {
569 struct ipaddr addr_rmt
;
571 switch (yang_dnode_get_enum(dnode
, "./nai/type")) {
572 case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE
:
573 case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE
:
574 case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM
:
575 yang_dnode_get_ip(&addr
, dnode
, "./nai/local-address");
576 vty_out(vty
, " nai prefix %pI4", &addr
.ipaddr_v4
);
578 case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE
:
579 case SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE
:
580 case SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM
:
581 yang_dnode_get_ip(&addr
, dnode
, "./nai/local-address");
582 vty_out(vty
, " nai prefix %pI6", &addr
.ipaddr_v6
);
584 case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY
:
585 yang_dnode_get_ip(&addr
, dnode
, "./nai/local-address");
586 yang_dnode_get_ip(&addr_rmt
, dnode
,
587 "./nai/remote-address");
588 vty_out(vty
, " nai adjacency %pI4", &addr
.ipaddr_v4
);
589 vty_out(vty
, " %pI4", &addr_rmt
.ipaddr_v4
);
591 case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY
:
592 yang_dnode_get_ip(&addr
, dnode
, "./nai/local-address");
593 yang_dnode_get_ip(&addr_rmt
, dnode
,
594 "./nai/remote-address");
595 vty_out(vty
, " nai adjacency %pI6", &addr
.ipaddr_v6
);
596 vty_out(vty
, " %pI6", &addr_rmt
.ipaddr_v6
);
601 if (yang_dnode_exists(dnode
, "./nai/local-prefix-len")) {
603 yang_dnode_get_string(
604 dnode
, "./nai/local-prefix-len"));
606 if (yang_dnode_exists(dnode
, "./nai/local-interface")) {
607 vty_out(vty
, " iface %s",
608 yang_dnode_get_string(dnode
,
609 "./nai/local-interface"));
611 if (yang_dnode_exists(dnode
, "./nai/algorithm")) {
612 vty_out(vty
, " algorithm %s",
613 yang_dnode_get_string(dnode
,
621 * XPath: /frr-pathd:pathd/policy
626 "policy color (0-4294967295)$num endpoint <A.B.C.D|X:X::X:X>$endpoint",
627 "Segment Routing Policy\n"
629 "SR Policy color value\n"
630 "SR Policy endpoint\n"
631 "SR Policy endpoint IPv4 address\n"
632 "SR Policy endpoint IPv6 address\n")
634 char xpath
[XPATH_POLICY_BASELEN
];
637 snprintf(xpath
, sizeof(xpath
),
638 "/frr-pathd:pathd/srte/policy[color='%s'][endpoint='%s']",
639 num_str
, endpoint_str
);
640 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
642 ret
= nb_cli_apply_changes(vty
, NULL
);
643 if (ret
== CMD_SUCCESS
)
644 VTY_PUSH_XPATH(SR_POLICY_NODE
, xpath
);
649 DEFPY(srte_no_policy
,
651 "no policy color (0-4294967295)$num endpoint <A.B.C.D|X:X::X:X>$endpoint",
653 "Segment Routing Policy\n"
655 "SR Policy color value\n"
656 "SR Policy endpoint\n"
657 "SR Policy endpoint IPv4 address\n"
658 "SR Policy endpoint IPv6 address\n")
660 char xpath
[XPATH_POLICY_BASELEN
];
662 snprintf(xpath
, sizeof(xpath
),
663 "/frr-pathd:pathd/srte/policy[color='%s'][endpoint='%s']",
664 num_str
, endpoint_str
);
665 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
667 return nb_cli_apply_changes(vty
, NULL
);
670 void cli_show_srte_policy(struct vty
*vty
, const struct lyd_node
*dnode
,
673 vty_out(vty
, " policy color %s endpoint %s\n",
674 yang_dnode_get_string(dnode
, "./color"),
675 yang_dnode_get_string(dnode
, "./endpoint"));
678 void cli_show_srte_policy_end(struct vty
*vty
, const struct lyd_node
*dnode
)
680 vty_out(vty
, " exit\n");
684 * XPath: /frr-pathd:pathd/srte/policy/name
686 DEFPY(srte_policy_name
,
687 srte_policy_name_cmd
,
689 "Segment Routing Policy name\n"
690 "SR Policy name value\n")
692 nb_cli_enqueue_change(vty
, "./name", NB_OP_CREATE
, name
);
694 return nb_cli_apply_changes(vty
, NULL
);
697 DEFPY(srte_policy_no_name
,
698 srte_policy_no_name_cmd
,
701 "Segment Routing Policy name\n"
702 "SR Policy name value\n")
704 nb_cli_enqueue_change(vty
, "./name", NB_OP_DESTROY
, NULL
);
706 return nb_cli_apply_changes(vty
, NULL
);
710 void cli_show_srte_policy_name(struct vty
*vty
, const struct lyd_node
*dnode
,
713 vty_out(vty
, " name %s\n", yang_dnode_get_string(dnode
, NULL
));
717 * XPath: /frr-pathd:pathd/srte/policy/binding-sid
719 DEFPY(srte_policy_binding_sid
,
720 srte_policy_binding_sid_cmd
,
721 "binding-sid (16-1048575)$label",
722 "Segment Routing Policy Binding-SID\n"
723 "SR Policy Binding-SID label\n")
725 nb_cli_enqueue_change(vty
, "./binding-sid", NB_OP_CREATE
, label_str
);
727 return nb_cli_apply_changes(vty
, NULL
);
730 DEFPY(srte_policy_no_binding_sid
,
731 srte_policy_no_binding_sid_cmd
,
732 "no binding-sid [(16-1048575)]",
734 "Segment Routing Policy Binding-SID\n"
735 "SR Policy Binding-SID label\n")
737 nb_cli_enqueue_change(vty
, "./binding-sid", NB_OP_DESTROY
, NULL
);
739 return nb_cli_apply_changes(vty
, NULL
);
742 void cli_show_srte_policy_binding_sid(struct vty
*vty
,
743 const struct lyd_node
*dnode
,
746 vty_out(vty
, " binding-sid %s\n", yang_dnode_get_string(dnode
, NULL
));
750 * XPath: /frr-pathd:pathd/srte/policy/candidate-path
752 DEFPY(srte_policy_candidate_exp
,
753 srte_policy_candidate_exp_cmd
,
754 "candidate-path preference (0-4294967295)$preference name WORD$name \
755 explicit segment-list WORD$list_name",
756 "Segment Routing Policy Candidate Path\n"
757 "Segment Routing Policy Candidate Path Preference\n"
758 "Administrative Preference\n"
759 "Segment Routing Policy Candidate Path Name\n"
763 "Name of the Segment List\n")
765 nb_cli_enqueue_change(vty
, ".", NB_OP_CREATE
, preference_str
);
766 nb_cli_enqueue_change(vty
, "./name", NB_OP_MODIFY
, name
);
767 nb_cli_enqueue_change(vty
, "./protocol-origin", NB_OP_MODIFY
, "local");
768 nb_cli_enqueue_change(vty
, "./originator", NB_OP_MODIFY
, "config");
769 nb_cli_enqueue_change(vty
, "./type", NB_OP_MODIFY
, "explicit");
770 nb_cli_enqueue_change(vty
, "./segment-list-name", NB_OP_MODIFY
,
772 return nb_cli_apply_changes(vty
, "./candidate-path[preference='%s']",
777 srte_policy_candidate_dyn
,
778 srte_policy_candidate_dyn_cmd
,
779 "candidate-path preference (0-4294967295)$preference name WORD$name dynamic",
780 "Segment Routing Policy Candidate Path\n"
781 "Segment Routing Policy Candidate Path Preference\n"
782 "Administrative Preference\n"
783 "Segment Routing Policy Candidate Path Name\n"
787 char xpath
[XPATH_MAXLEN
+ XPATH_CANDIDATE_BASELEN
];
790 snprintf(xpath
, sizeof(xpath
), "%s/candidate-path[preference='%s']",
791 VTY_CURR_XPATH
, preference_str
);
793 nb_cli_enqueue_change(vty
, ".", NB_OP_CREATE
, preference_str
);
794 nb_cli_enqueue_change(vty
, "./name", NB_OP_MODIFY
, name
);
795 nb_cli_enqueue_change(vty
, "./protocol-origin", NB_OP_MODIFY
, "local");
796 nb_cli_enqueue_change(vty
, "./originator", NB_OP_MODIFY
, "config");
797 nb_cli_enqueue_change(vty
, "./type", NB_OP_MODIFY
, "dynamic");
798 ret
= nb_cli_apply_changes(vty
, "./candidate-path[preference='%s']",
801 if (ret
== CMD_SUCCESS
)
802 VTY_PUSH_XPATH(SR_CANDIDATE_DYN_NODE
, xpath
);
807 DEFPY(srte_candidate_bandwidth
,
808 srte_candidate_bandwidth_cmd
,
809 "bandwidth BANDWIDTH$value [required$required]",
810 "Define a bandwidth constraint\n"
812 "Required constraint\n")
814 nb_cli_enqueue_change(vty
, "./constraints/bandwidth/required",
815 NB_OP_MODIFY
, required
? "true" : "false");
816 nb_cli_enqueue_change(vty
, "./constraints/bandwidth/value",
817 NB_OP_MODIFY
, value
);
818 return nb_cli_apply_changes(vty
, NULL
);
821 DEFPY(srte_candidate_no_bandwidth
,
822 srte_candidate_no_bandwidth_cmd
,
823 "no bandwidth [BANDWIDTH$value] [required$required]",
825 "Remove a bandwidth constraint\n"
827 "Required constraint\n")
829 nb_cli_enqueue_change(vty
, "./constraints/bandwidth", NB_OP_DESTROY
,
831 return nb_cli_apply_changes(vty
, NULL
);
834 DEFPY(srte_candidate_affinity_filter
, srte_candidate_affinity_filter_cmd
,
835 "affinity <exclude-any|include-any|include-all>$type BITPATTERN$value",
836 "Affinity constraint\n"
837 "Exclude any matching link\n"
838 "Include any matching link\n"
839 "Include all matching links\n"
840 "Attribute filter bit pattern as an hexadecimal value from 0x00000000 to 0xFFFFFFFF\n")
843 char xpath
[XPATH_CANDIDATE_MAXLEN
];
844 char decimal_value
[11];
846 if (sscanf(value
, "0x%x", &filter
) != 1) {
847 vty_out(vty
, "affinity type: fscanf: %s\n",
848 safe_strerror(errno
));
849 return CMD_WARNING_CONFIG_FAILED
;
851 snprintf(decimal_value
, sizeof(decimal_value
), "%u", filter
);
852 snprintf(xpath
, sizeof(xpath
), "./constraints/affinity/%s", type
);
853 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, decimal_value
);
855 return nb_cli_apply_changes(vty
, NULL
);
858 DEFPY(srte_candidate_no_affinity_filter
, srte_candidate_no_affinity_filter_cmd
,
859 "no affinity <exclude-any|include-any|include-all>$type [BITPATTERN$value]",
861 "Affinity constraint\n"
862 "Exclude any matching link\n"
863 "Include any matching link\n"
864 "Include all matching links\n"
865 "Attribute filter bit pattern as an hexadecimal value from 0x00000000 to 0xFFFFFFFF\n")
867 char xpath
[XPATH_CANDIDATE_MAXLEN
];
869 snprintf(xpath
, sizeof(xpath
), "./constraints/affinity/%s", type
);
870 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
871 return nb_cli_apply_changes(vty
, NULL
);
874 DEFPY(srte_candidate_metric
,
875 srte_candidate_metric_cmd
,
876 "metric [bound$bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type METRIC$value [required$required]",
877 "Define a metric constraint\n"
878 "If the metric is bounded\n"
882 "Aggregate bandwidth consumption\n"
883 "Load of the most loaded link\n"
884 "Cumulative IGP cost\n"
885 "Cumulative TE cost\n"
888 "P2MP hop count metric\n"
889 "Segment-ID (SID) Depth.\n"
890 "Path Delay metric\n"
891 "Path Delay Variation metric\n"
893 "P2MP Path Delay metric\n"
894 "P2MP Path Delay variation metric\n"
895 "P2MP Path Loss metric\n"
896 "Number of adaptations on a path\n"
897 "Number of layers on a path\n"
898 "Domain Count metric\n"
899 "Border Node Count metric\n"
901 "Required constraint\n")
903 char xpath
[XPATH_CANDIDATE_MAXLEN
];
904 snprintf(xpath
, sizeof(xpath
), "./constraints/metrics[type='%s']/value",
906 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, value
);
907 snprintf(xpath
, sizeof(xpath
),
908 "./constraints/metrics[type='%s']/is-bound", type
);
909 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
910 (bound
!= NULL
) ? "true" : "false");
911 snprintf(xpath
, sizeof(xpath
),
912 "./constraints/metrics[type='%s']/required", type
);
913 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
914 required
? "true" : "false");
915 return nb_cli_apply_changes(vty
, NULL
);
918 DEFPY(srte_candidate_no_metric
,
919 srte_candidate_no_metric_cmd
,
920 "no metric [bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type [METRIC$value] [required$required]",
922 "Remove a metric constraint\n"
923 "If the metric is bounded\n"
927 "Aggregate bandwidth consumption\n"
928 "Load of the most loaded link\n"
929 "Cumulative IGP cost\n"
930 "Cumulative TE cost\n"
933 "P2MP hop count metric\n"
934 "Segment-ID (SID) Depth.\n"
935 "Path Delay metric\n"
936 "Path Delay Variation metric\n"
938 "P2MP Path Delay metric\n"
939 "P2MP Path Delay variation metric\n"
940 "P2MP Path Loss metric\n"
941 "Number of adaptations on a path\n"
942 "Number of layers on a path\n"
943 "Domain Count metric\n"
944 "Border Node Count metric\n"
946 "Required constraint\n")
948 char xpath
[XPATH_CANDIDATE_MAXLEN
];
949 snprintf(xpath
, sizeof(xpath
), "./constraints/metrics[type='%s']",
951 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
952 return nb_cli_apply_changes(vty
, NULL
);
955 DEFPY(srte_policy_no_candidate
,
956 srte_policy_no_candidate_cmd
,
958 preference (0-4294967295)$preference\
961 explicit segment-list WORD\
965 "Segment Routing Policy Candidate Path\n"
966 "Segment Routing Policy Candidate Path Preference\n"
967 "Administrative Preference\n"
968 "Segment Routing Policy Candidate Path Name\n"
972 "Name of the Segment List\n"
975 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
977 return nb_cli_apply_changes(vty
, "./candidate-path[preference='%s']",
981 DEFPY(srte_candidate_objfun
,
982 srte_candidate_objfun_cmd
,
983 "objective-function <mcp|mlp|mbp|mbc|mll|mcc|spt|mct|mplp|mup|mrup|mtd|mbn|mctd|msl|mss|msn>$type [required$required]",
984 "Define an objective function constraint\n"
985 "Minimum Cost Path\n"
986 "Minimum Load Path\n"
987 "Maximum residual Bandwidth Path\n"
988 "Minimize aggregate Bandwidth Consumption\n"
989 "Minimize the Load of the most loaded Link\n"
990 "Minimize the Cumulative Cost of a set of paths\n"
991 "Shortest Path Tree\n"
992 "Minimum Cost Tree\n"
993 "Minimum Packet Loss Path\n"
994 "Maximum Under-Utilized Path\n"
995 "Maximum Reserved Under-Utilized Path\n"
996 "Minimize the number of Transit Domains\n"
997 "Minimize the number of Border Nodes\n"
998 "Minimize the number of Common Transit Domains\n"
999 "Minimize the number of Shared Links\n"
1000 "Minimize the number of Shared SRLGs\n"
1001 "Minimize the number of Shared Nodes\n"
1002 "Required constraint\n")
1004 char xpath
[XPATH_CANDIDATE_MAXLEN
];
1005 nb_cli_enqueue_change(vty
, "./constraints/objective-function",
1006 NB_OP_DESTROY
, NULL
);
1007 snprintf(xpath
, sizeof(xpath
),
1008 "./constraints/objective-function/required");
1009 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
,
1010 required
? "true" : "false");
1011 nb_cli_enqueue_change(vty
, "./constraints/objective-function/type",
1012 NB_OP_MODIFY
, type
);
1013 return nb_cli_apply_changes(vty
, NULL
);
1016 DEFPY(srte_candidate_no_objfun
,
1017 srte_candidate_no_objfun_cmd
,
1018 "no objective-function [<mcp|mlp|mbp|mbc|mll|mcc|spt|mct|mplp|mup|mrup|mtd|mbn|mctd|msl|mss|msn>] [required$required]",
1020 "Remove an objective function constraint\n"
1021 "Minimum Cost Path\n"
1022 "Minimum Load Path\n"
1023 "Maximum residual Bandwidth Path\n"
1024 "Minimize aggregate Bandwidth Consumption\n"
1025 "Minimize the Load of the most loaded Link\n"
1026 "Minimize the Cumulative Cost of a set of paths\n"
1027 "Shortest Path Tree\n"
1028 "Minimum Cost Tree\n"
1029 "Minimum Packet Loss Path\n"
1030 "Maximum Under-Utilized Path\n"
1031 "Maximum Reserved Under-Utilized Path\n"
1032 "Minimize the number of Transit Domains\n"
1033 "Minimize the number of Border Nodes\n"
1034 "Minimize the number of Common Transit Domains\n"
1035 "Minimize the number of Shared Links\n"
1036 "Minimize the number of Shared SRLGs\n"
1037 "Minimize the number of Shared Nodes\n"
1038 "Required constraint\n")
1040 nb_cli_enqueue_change(vty
, "./constraints/objective-function",
1041 NB_OP_DESTROY
, NULL
);
1042 return nb_cli_apply_changes(vty
, NULL
);
1045 static const char *objfun_type_name(enum objfun_type type
)
1082 case OBJFUN_UNDEFINED
:
1086 assert(!"Reached end of function we should never hit");
1089 DEFPY_NOSH(show_debugging_pathd
, show_debugging_pathd_cmd
,
1090 "show debugging [pathd]",
1092 "State of each debugging option\n"
1093 "pathd module debugging\n")
1096 vty_out(vty
, "Path debugging status:\n");
1098 cmd_show_lib_debugs(vty
);
1099 /* nothing to do here */
1100 path_ted_show_debugging(vty
);
1101 path_policy_show_debugging(vty
);
1105 DEFPY(debug_path_policy
, debug_path_policy_cmd
, "[no] debug pathd policy",
1108 "policy debugging\n")
1110 uint32_t mode
= DEBUG_NODE2MODE(vty
->node
);
1113 DEBUG_MODE_SET(&path_policy_debug
, mode
, !no
);
1114 DEBUG_FLAGS_SET(&path_policy_debug
, PATH_POLICY_DEBUG_BASIC
, !no_debug
);
1118 static const char *metric_type_name(enum srte_candidate_metric_type type
)
1121 case SRTE_CANDIDATE_METRIC_TYPE_IGP
:
1123 case SRTE_CANDIDATE_METRIC_TYPE_TE
:
1125 case SRTE_CANDIDATE_METRIC_TYPE_HC
:
1127 case SRTE_CANDIDATE_METRIC_TYPE_ABC
:
1129 case SRTE_CANDIDATE_METRIC_TYPE_LMLL
:
1131 case SRTE_CANDIDATE_METRIC_TYPE_CIGP
:
1133 case SRTE_CANDIDATE_METRIC_TYPE_CTE
:
1135 case SRTE_CANDIDATE_METRIC_TYPE_PIGP
:
1137 case SRTE_CANDIDATE_METRIC_TYPE_PTE
:
1139 case SRTE_CANDIDATE_METRIC_TYPE_PHC
:
1141 case SRTE_CANDIDATE_METRIC_TYPE_MSD
:
1143 case SRTE_CANDIDATE_METRIC_TYPE_PD
:
1145 case SRTE_CANDIDATE_METRIC_TYPE_PDV
:
1147 case SRTE_CANDIDATE_METRIC_TYPE_PL
:
1149 case SRTE_CANDIDATE_METRIC_TYPE_PPD
:
1151 case SRTE_CANDIDATE_METRIC_TYPE_PPDV
:
1153 case SRTE_CANDIDATE_METRIC_TYPE_PPL
:
1155 case SRTE_CANDIDATE_METRIC_TYPE_NAP
:
1157 case SRTE_CANDIDATE_METRIC_TYPE_NLP
:
1159 case SRTE_CANDIDATE_METRIC_TYPE_DC
:
1161 case SRTE_CANDIDATE_METRIC_TYPE_BNC
:
1168 static void config_write_float(struct vty
*vty
, float value
)
1170 if (fabs(truncf(value
) - value
) < FLT_EPSILON
) {
1171 vty_out(vty
, " %d", (int)value
);
1174 vty_out(vty
, " %f", value
);
1178 static void config_write_metric(struct vty
*vty
,
1179 enum srte_candidate_metric_type type
,
1180 float value
, bool required
, bool is_bound
)
1182 const char *name
= metric_type_name(type
);
1185 vty_out(vty
, " metric %s%s", is_bound
? "bound " : "",
1186 metric_type_name(type
));
1187 config_write_float(vty
, value
);
1188 vty_out(vty
, required
? " required" : "");
1192 static int config_write_metric_cb(const struct lyd_node
*dnode
, void *arg
)
1194 struct vty
*vty
= arg
;
1195 enum srte_candidate_metric_type type
;
1196 bool required
, is_bound
= false;
1199 type
= yang_dnode_get_enum(dnode
, "./type");
1200 value
= (float)yang_dnode_get_dec64(dnode
, "./value");
1201 required
= yang_dnode_get_bool(dnode
, "./required");
1202 if (yang_dnode_exists(dnode
, "./is-bound"))
1203 is_bound
= yang_dnode_get_bool(dnode
, "./is-bound");
1205 config_write_metric(vty
, type
, value
, required
, is_bound
);
1206 return YANG_ITER_CONTINUE
;
1209 void cli_show_srte_policy_candidate_path(struct vty
*vty
,
1210 const struct lyd_node
*dnode
,
1216 enum objfun_type objfun_type
;
1217 const char *type
= yang_dnode_get_string(dnode
, "./type");
1219 vty_out(vty
, " candidate-path preference %s name %s %s",
1220 yang_dnode_get_string(dnode
, "./preference"),
1221 yang_dnode_get_string(dnode
, "./name"), type
);
1222 if (strmatch(type
, "explicit"))
1223 vty_out(vty
, " segment-list %s",
1224 yang_dnode_get_string(dnode
, "./segment-list-name"));
1227 if (strmatch(type
, "dynamic")) {
1228 if (yang_dnode_exists(dnode
, "./constraints/bandwidth")) {
1229 bandwidth
= (float)yang_dnode_get_dec64(
1230 dnode
, "./constraints/bandwidth/value");
1231 required
= yang_dnode_get_bool(
1232 dnode
, "./constraints/bandwidth/required");
1233 vty_out(vty
, " bandwidth");
1234 config_write_float(vty
, bandwidth
);
1236 vty_out(vty
, " required");
1239 if (yang_dnode_exists(dnode
,
1240 "./constraints/affinity/exclude-any")) {
1241 affinity
= yang_dnode_get_uint32(
1242 dnode
, "./constraints/affinity/exclude-any");
1243 vty_out(vty
, " affinity exclude-any 0x%08x\n",
1246 if (yang_dnode_exists(dnode
,
1247 "./constraints/affinity/include-any")) {
1248 affinity
= yang_dnode_get_uint32(
1249 dnode
, "./constraints/affinity/include-any");
1250 vty_out(vty
, " affinity include-any 0x%08x\n",
1253 if (yang_dnode_exists(dnode
,
1254 "./constraints/affinity/include-all")) {
1255 affinity
= yang_dnode_get_uint32(
1256 dnode
, "./constraints/affinity/include-all");
1257 vty_out(vty
, " affinity include-all 0x%08x\n",
1260 yang_dnode_iterate(config_write_metric_cb
, vty
, dnode
,
1261 "./constraints/metrics");
1262 if (yang_dnode_exists(dnode
,
1263 "./constraints/objective-function")) {
1264 objfun_type
= yang_dnode_get_enum(dnode
,
1265 "./constraints/objective-function/type");
1266 required
= yang_dnode_get_bool(dnode
,
1267 "./constraints/objective-function/required");
1268 vty_out(vty
, " objective-function %s%s\n",
1269 objfun_type_name(objfun_type
),
1270 required
? " required" : "");
1275 void cli_show_srte_policy_candidate_path_end(struct vty
*vty
,
1276 const struct lyd_node
*dnode
)
1278 const char *type
= yang_dnode_get_string(dnode
, "./type");
1280 if (strmatch(type
, "dynamic"))
1281 vty_out(vty
, " exit\n");
1284 static int config_write_dnode(const struct lyd_node
*dnode
, void *arg
)
1286 struct vty
*vty
= arg
;
1288 nb_cli_show_dnode_cmds(vty
, dnode
, false);
1290 return YANG_ITER_CONTINUE
;
1293 int config_write_segment_routing(struct vty
*vty
)
1295 vty_out(vty
, "segment-routing\n");
1296 vty_out(vty
, " traffic-eng\n");
1298 path_ted_config_write(vty
);
1300 yang_dnode_iterate(config_write_dnode
, vty
, running_config
->dnode
,
1301 "/frr-pathd:pathd/srte/segment-list");
1302 yang_dnode_iterate(config_write_dnode
, vty
, running_config
->dnode
,
1303 "/frr-pathd:pathd/srte/policy");
1305 hook_call(pathd_srte_config_write
, vty
);
1307 vty_out(vty
, " exit\n");
1308 vty_out(vty
, "exit\n");
1313 static int path_policy_cli_debug_config_write(struct vty
*vty
)
1315 if (DEBUG_MODE_CHECK(&path_policy_debug
, DEBUG_MODE_CONF
)) {
1316 if (DEBUG_FLAGS_CHECK(&path_policy_debug
,
1317 PATH_POLICY_DEBUG_BASIC
))
1318 vty_out(vty
, "debug pathd policy\n");
1324 static int path_policy_cli_debug_set_all(uint32_t flags
, bool set
)
1326 DEBUG_FLAGS_SET(&path_policy_debug
, flags
, set
);
1328 /* If all modes have been turned off, don't preserve options. */
1329 if (!DEBUG_MODE_CHECK(&path_policy_debug
, DEBUG_MODE_ALL
))
1330 DEBUG_CLEAR(&path_policy_debug
);
1335 void path_cli_init(void)
1337 hook_register(nb_client_debug_config_write
,
1338 path_policy_cli_debug_config_write
);
1339 hook_register(nb_client_debug_set_all
, path_policy_cli_debug_set_all
);
1341 install_node(&segment_routing_node
);
1342 install_node(&sr_traffic_eng_node
);
1343 install_node(&srte_segment_list_node
);
1344 install_node(&srte_policy_node
);
1345 install_node(&srte_candidate_dyn_node
);
1346 install_default(SEGMENT_ROUTING_NODE
);
1347 install_default(SR_TRAFFIC_ENG_NODE
);
1348 install_default(SR_SEGMENT_LIST_NODE
);
1349 install_default(SR_POLICY_NODE
);
1350 install_default(SR_CANDIDATE_DYN_NODE
);
1352 install_element(ENABLE_NODE
, &show_debugging_pathd_cmd
);
1353 install_element(ENABLE_NODE
, &show_srte_policy_cmd
);
1354 install_element(ENABLE_NODE
, &show_srte_policy_detail_cmd
);
1356 install_element(ENABLE_NODE
, &debug_path_policy_cmd
);
1357 install_element(CONFIG_NODE
, &debug_path_policy_cmd
);
1359 install_element(CONFIG_NODE
, &segment_routing_cmd
);
1360 install_element(SEGMENT_ROUTING_NODE
, &sr_traffic_eng_cmd
);
1361 install_element(SR_TRAFFIC_ENG_NODE
, &srte_segment_list_cmd
);
1362 install_element(SR_TRAFFIC_ENG_NODE
, &srte_no_segment_list_cmd
);
1363 install_element(SR_SEGMENT_LIST_NODE
,
1364 &srte_segment_list_segment_cmd
);
1365 install_element(SR_SEGMENT_LIST_NODE
,
1366 &srte_segment_list_no_segment_cmd
);
1367 install_element(SR_TRAFFIC_ENG_NODE
, &srte_policy_cmd
);
1368 install_element(SR_TRAFFIC_ENG_NODE
, &srte_no_policy_cmd
);
1369 install_element(SR_POLICY_NODE
, &srte_policy_name_cmd
);
1370 install_element(SR_POLICY_NODE
, &srte_policy_no_name_cmd
);
1371 install_element(SR_POLICY_NODE
, &srte_policy_binding_sid_cmd
);
1372 install_element(SR_POLICY_NODE
, &srte_policy_no_binding_sid_cmd
);
1373 install_element(SR_POLICY_NODE
, &srte_policy_candidate_exp_cmd
);
1374 install_element(SR_POLICY_NODE
, &srte_policy_candidate_dyn_cmd
);
1375 install_element(SR_POLICY_NODE
, &srte_policy_no_candidate_cmd
);
1376 install_element(SR_CANDIDATE_DYN_NODE
,
1377 &srte_candidate_bandwidth_cmd
);
1378 install_element(SR_CANDIDATE_DYN_NODE
,
1379 &srte_candidate_no_bandwidth_cmd
);
1380 install_element(SR_CANDIDATE_DYN_NODE
,
1381 &srte_candidate_affinity_filter_cmd
);
1382 install_element(SR_CANDIDATE_DYN_NODE
,
1383 &srte_candidate_no_affinity_filter_cmd
);
1384 install_element(SR_CANDIDATE_DYN_NODE
,
1385 &srte_candidate_metric_cmd
);
1386 install_element(SR_CANDIDATE_DYN_NODE
,
1387 &srte_candidate_no_metric_cmd
);
1388 install_element(SR_CANDIDATE_DYN_NODE
,
1389 &srte_candidate_objfun_cmd
);
1390 install_element(SR_CANDIDATE_DYN_NODE
,
1391 &srte_candidate_no_objfun_cmd
);