1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2020 Volta Networks, Inc
8 #include "pceplib/pcep_utils_counters.h"
9 #include "pceplib/pcep_session_logic.h"
15 #include "lib/version.h"
16 #include "northbound.h"
17 #include "frr_pthread.h"
19 #include "termtable.h"
21 #include "pathd/pathd.h"
22 #include "pathd/path_errors.h"
23 #include "pathd/path_pcep.h"
24 #include "pathd/path_pcep_cli.h"
25 #include "pathd/path_pcep_controller.h"
26 #include "pathd/path_pcep_debug.h"
27 #include "pathd/path_pcep_lib.h"
28 #include "pathd/path_pcep_pcc.h"
30 #include "pathd/path_pcep_cli_clippy.c"
32 #define DEFAULT_PCE_PRECEDENCE 255
33 #define DEFAULT_PCC_MSD 4
34 #define DEFAULT_SR_DRAFT07 false
35 #define DEFAULT_PCE_INITIATED false
36 #define DEFAULT_TIMER_KEEP_ALIVE 30
37 #define DEFAULT_TIMER_KEEP_ALIVE_MIN 1
38 #define DEFAULT_TIMER_KEEP_ALIVE_MAX 255
39 #define DEFAULT_TIMER_DEADTIMER 120
40 #define DEFAULT_TIMER_DEADTIMER_MIN 4
41 #define DEFAULT_TIMER_DEADTIMER_MAX 255
42 #define DEFAULT_TIMER_PCEP_REQUEST 30
43 #define DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL 30
44 #define DEFAULT_DELEGATION_TIMEOUT_INTERVAL 10
46 /* CLI Function declarations */
47 static int pcep_cli_debug_config_write(struct vty
*vty
);
48 static int pcep_cli_debug_set_all(uint32_t flags
, bool set
);
49 static int pcep_cli_pcep_config_write(struct vty
*vty
);
50 static int pcep_cli_pcc_config_write(struct vty
*vty
);
51 static int pcep_cli_pce_config_write(struct vty
*vty
);
52 static int pcep_cli_pcep_pce_config_write(struct vty
*vty
);
54 /* Internal Util Function declarations */
55 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
);
56 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
);
57 static struct pce_opts_cli
*pcep_cli_create_pce_opts(const char *name
);
58 static void pcep_cli_delete_pce(const char *pce_name
);
60 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
);
61 static struct pcep_config_group_opts
*
62 pcep_cli_find_pcep_pce_config(const char *group_name
);
64 pcep_cli_add_pcep_pce_config(struct pcep_config_group_opts
*config_group_opts
);
65 static struct pcep_config_group_opts
*
66 pcep_cli_create_pcep_pce_config(const char *group_name
);
67 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
);
68 static void pcep_cli_delete_pcep_pce_config(const char *group_name
);
69 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
70 char *buf
, size_t buf_len
);
71 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
72 pcep_configuration
*config
);
73 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
74 struct pcep_pcc_info
*pcc_info
);
75 static bool pcep_cli_pcc_has_pce(const char *pce_name
);
76 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
);
77 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
);
78 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
79 const char *peer_name
,
80 const char *precedence_str
,
87 static const char PCEP_VTYSH_ARG_ADDRESS
[] = "address";
88 static const char PCEP_VTYSH_ARG_SOURCE_ADDRESS
[] = "source-address";
89 static const char PCEP_VTYSH_ARG_IP
[] = "ip";
90 static const char PCEP_VTYSH_ARG_IPV6
[] = "ipv6";
91 static const char PCEP_VTYSH_ARG_PORT
[] = "port";
92 static const char PCEP_VTYSH_ARG_PRECEDENCE
[] = "precedence";
93 static const char PCEP_VTYSH_ARG_MSD
[] = "msd";
94 static const char PCEP_VTYSH_ARG_KEEP_ALIVE
[] = "keep-alive";
95 static const char PCEP_VTYSH_ARG_TIMER
[] = "timer";
96 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
[] = "min-peer-keep-alive";
97 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
[] = "max-peer-keep-alive";
98 static const char PCEP_VTYSH_ARG_DEAD_TIMER
[] = "dead-timer";
99 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MIN
[] = "min-peer-dead-timer";
100 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MAX
[] = "max-peer-dead-timer";
101 static const char PCEP_VTYSH_ARG_PCEP_REQUEST
[] = "pcep-request";
102 static const char PCEP_VTYSH_ARG_SESSION_TIMEOUT
[] = "session-timeout-interval";
103 static const char PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
[] = "delegation-timeout";
104 static const char PCEP_VTYSH_ARG_SR_DRAFT07
[] = "sr-draft07";
105 static const char PCEP_VTYSH_ARG_PCE_INIT
[] = "pce-initiated";
106 static const char PCEP_VTYSH_ARG_TCP_MD5
[] = "tcp-md5-auth";
107 static const char PCEP_VTYSH_ARG_BASIC
[] = "basic";
108 static const char PCEP_VTYSH_ARG_PATH
[] = "path";
109 static const char PCEP_VTYSH_ARG_MESSAGE
[] = "message";
110 static const char PCEP_VTYSH_ARG_PCEPLIB
[] = "pceplib";
111 static const char PCEP_CLI_CAP_STATEFUL
[] = " [Stateful PCE]";
112 static const char PCEP_CLI_CAP_INCL_DB_VER
[] = " [Include DB version]";
113 static const char PCEP_CLI_CAP_LSP_TRIGGERED
[] = " [LSP Triggered Resync]";
114 static const char PCEP_CLI_CAP_LSP_DELTA
[] = " [LSP Delta Sync]";
115 static const char PCEP_CLI_CAP_PCE_TRIGGERED
[] =
116 " [PCE triggered Initial Sync]";
117 static const char PCEP_CLI_CAP_SR_TE_PST
[] = " [SR TE PST]";
118 static const char PCEP_CLI_CAP_PCC_RESOLVE_NAI
[] =
119 " [PCC can resolve NAI to SID]";
120 static const char PCEP_CLI_CAP_PCC_INITIATED
[] = " [PCC Initiated LSPs]";
121 static const char PCEP_CLI_CAP_PCC_PCE_INITIATED
[] =
122 " [PCC and PCE Initiated LSPs]";
124 struct pce_connections
{
126 struct pce_opts
*connections
[MAX_PCC
];
129 struct pce_connections pce_connections_g
= {.num_connections
= 0};
131 /* Default PCE group that all PCE-Groups and PCEs will inherit from */
132 struct pcep_config_group_opts default_pcep_config_group_opts_g
= {
134 .tcp_md5_auth
= "\0",
135 .draft07
= DEFAULT_SR_DRAFT07
,
136 .pce_initiated
= DEFAULT_PCE_INITIATED
,
137 .keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE
,
138 .min_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MIN
,
139 .max_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MAX
,
140 .dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER
,
141 .min_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MIN
,
142 .max_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MAX
,
143 .pcep_request_time_seconds
= DEFAULT_TIMER_PCEP_REQUEST
,
144 .session_timeout_inteval_seconds
=
145 DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL
,
146 .delegation_timeout_seconds
= DEFAULT_DELEGATION_TIMEOUT_INTERVAL
,
147 .source_port
= DEFAULT_PCEP_TCP_PORT
,
148 .source_ip
.ipa_type
= IPADDR_NONE
,
151 /* Used by PCEP_PCE_CONFIG_NODE sub-commands to operate on the current pce group
153 struct pcep_config_group_opts
*current_pcep_config_group_opts_g
= NULL
;
154 /* Used by PCEP_PCE_NODE sub-commands to operate on the current pce opts */
155 struct pce_opts_cli
*current_pce_opts_g
= NULL
;
156 short pcc_msd_g
= DEFAULT_PCC_MSD
;
157 bool pcc_msd_configured_g
= false;
159 static struct cmd_node pcep_node
= {
162 .parent_node
= SR_TRAFFIC_ENG_NODE
,
163 .prompt
= "%s(config-sr-te-pcep)# "
166 static struct cmd_node pcep_pcc_node
= {
167 .name
= "srte pcep pcc",
168 .node
= PCEP_PCC_NODE
,
169 .parent_node
= PCEP_NODE
,
170 .prompt
= "%s(config-sr-te-pcep-pcc)# "
173 static struct cmd_node pcep_pce_node
= {
174 .name
= "srte pcep pce",
175 .node
= PCEP_PCE_NODE
,
176 .parent_node
= PCEP_NODE
,
177 .prompt
= "%s(config-sr-te-pcep-pce)# "
180 static struct cmd_node pcep_pce_config_node
= {
181 .name
= "srte pcep pce-config",
182 .node
= PCEP_PCE_CONFIG_NODE
,
183 .parent_node
= PCEP_NODE
,
184 .prompt
= "%s(pce-sr-te-pcep-pce-config)# "
187 /* Common code used in VTYSH processing for int values */
188 #define PCEP_VTYSH_INT_ARG_CHECK(arg_str, arg_val, arg_store, min_value, \
190 if (arg_str != NULL) { \
191 if (arg_val <= min_value || arg_val >= max_value) { \
193 "%% Invalid value %ld in range [%d - %d]", \
194 arg_val, min_value, max_value); \
195 return CMD_WARNING; \
197 arg_store = arg_val; \
200 #define MERGE_COMPARE_CONFIG_GROUP_VALUE(config_param, not_set_value) \
201 pce_opts_cli->pce_opts.config_opts.config_param = \
202 pce_opts_cli->pce_config_group_opts.config_param; \
203 if (pce_opts_cli->pce_config_group_opts.config_param \
204 == not_set_value) { \
205 pce_opts_cli->pce_opts.config_opts.config_param = \
206 ((pce_config != NULL \
207 && pce_config->config_param != not_set_value) \
208 ? pce_config->config_param \
209 : default_pcep_config_group_opts_g \
214 * Internal Util functions
217 /* Check if a pce_opts_cli already exists based on its name and return it,
218 * return NULL otherwise */
219 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
)
221 for (int i
= 0; i
< MAX_PCE
; i
++) {
222 struct pce_opts_cli
*pce_rhs_cli
= pcep_g
->pce_opts_cli
[i
];
223 if (pce_rhs_cli
!= NULL
) {
224 if (strcmp(pce_name
, pce_rhs_cli
->pce_opts
.pce_name
)
234 /* Add a new pce_opts_cli to pcep_g, return false if MAX_PCES, true otherwise */
235 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
)
237 for (int i
= 0; i
< MAX_PCE
; i
++) {
238 if (pcep_g
->pce_opts_cli
[i
] == NULL
) {
239 pcep_g
->pce_opts_cli
[i
] = pce_opts_cli
;
240 pcep_g
->num_pce_opts_cli
++;
248 /* Create a new pce opts_cli */
249 static struct pce_opts_cli
*pcep_cli_create_pce_opts(const char *name
)
251 struct pce_opts_cli
*pce_opts_cli
=
252 XCALLOC(MTYPE_PCEP
, sizeof(struct pce_opts_cli
));
253 strlcpy(pce_opts_cli
->pce_opts
.pce_name
, name
,
254 sizeof(pce_opts_cli
->pce_opts
.pce_name
));
255 pce_opts_cli
->pce_opts
.port
= PCEP_DEFAULT_PORT
;
260 static void pcep_cli_delete_pce(const char *pce_name
)
262 for (int i
= 0; i
< MAX_PCE
; i
++) {
263 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
264 if (strcmp(pcep_g
->pce_opts_cli
[i
]->pce_opts
.pce_name
,
267 XFREE(MTYPE_PCEP
, pcep_g
->pce_opts_cli
[i
]);
268 pcep_g
->pce_opts_cli
[i
] = NULL
;
269 pcep_g
->num_pce_opts_cli
--;
277 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
)
279 if (pce_opts_cli
->merged
== true) {
283 struct pcep_config_group_opts
*pce_config
=
284 pcep_cli_find_pcep_pce_config(pce_opts_cli
->config_group_name
);
286 /* Configuration priorities:
287 * 1) pce_opts->config_opts, if present, overwrite pce_config
288 * config_opts 2) pce_config config_opts, if present, overwrite
289 * default config_opts 3) If neither pce_opts->config_opts nor
290 * pce_config config_opts are set, then the default config_opts value
294 const char *tcp_md5_auth_str
=
295 pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
;
296 if (pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
[0] == '\0') {
297 if (pce_config
!= NULL
&& pce_config
->tcp_md5_auth
[0] != '\0') {
298 tcp_md5_auth_str
= pce_config
->tcp_md5_auth
;
301 default_pcep_config_group_opts_g
.tcp_md5_auth
;
304 strlcpy(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
,
306 sizeof(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
));
308 struct ipaddr
*source_ip
=
309 &pce_opts_cli
->pce_config_group_opts
.source_ip
;
310 if (pce_opts_cli
->pce_config_group_opts
.source_ip
.ipa_type
312 if (pce_config
!= NULL
313 && pce_config
->source_ip
.ipa_type
!= IPADDR_NONE
) {
314 source_ip
= &pce_config
->source_ip
;
316 source_ip
= &default_pcep_config_group_opts_g
.source_ip
;
319 memcpy(&pce_opts_cli
->pce_opts
.config_opts
.source_ip
, source_ip
,
320 sizeof(struct ipaddr
));
322 MERGE_COMPARE_CONFIG_GROUP_VALUE(draft07
, false);
323 MERGE_COMPARE_CONFIG_GROUP_VALUE(pce_initiated
, false);
324 MERGE_COMPARE_CONFIG_GROUP_VALUE(keep_alive_seconds
, 0);
325 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_keep_alive_seconds
, 0);
326 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_keep_alive_seconds
, 0);
327 MERGE_COMPARE_CONFIG_GROUP_VALUE(dead_timer_seconds
, 0);
328 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_dead_timer_seconds
, 0);
329 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_dead_timer_seconds
, 0);
330 MERGE_COMPARE_CONFIG_GROUP_VALUE(pcep_request_time_seconds
, 0);
331 MERGE_COMPARE_CONFIG_GROUP_VALUE(session_timeout_inteval_seconds
, 0);
332 MERGE_COMPARE_CONFIG_GROUP_VALUE(delegation_timeout_seconds
, 0);
333 MERGE_COMPARE_CONFIG_GROUP_VALUE(source_port
, 0);
335 pce_opts_cli
->merged
= true;
338 /* Check if a pcep_config_group_opts already exists based on its name and return
339 * it, return NULL otherwise */
340 static struct pcep_config_group_opts
*
341 pcep_cli_find_pcep_pce_config(const char *group_name
)
343 for (int i
= 0; i
< MAX_PCE
; i
++) {
344 struct pcep_config_group_opts
*pcep_pce_config_rhs
=
345 pcep_g
->config_group_opts
[i
];
346 if (pcep_pce_config_rhs
!= NULL
) {
347 if (strcmp(group_name
, pcep_pce_config_rhs
->name
)
349 return pcep_pce_config_rhs
;
357 /* Add a new pcep_config_group_opts to pcep_g, return false if MAX_PCE,
359 static bool pcep_cli_add_pcep_pce_config(
360 struct pcep_config_group_opts
*pcep_config_group_opts
)
362 for (int i
= 0; i
< MAX_PCE
; i
++) {
363 if (pcep_g
->config_group_opts
[i
] == NULL
) {
364 pcep_g
->config_group_opts
[i
] = pcep_config_group_opts
;
365 pcep_g
->num_config_group_opts
++;
373 /* Create a new pce group, inheriting its values from the default pce group */
374 static struct pcep_config_group_opts
*
375 pcep_cli_create_pcep_pce_config(const char *group_name
)
377 struct pcep_config_group_opts
*pcep_config_group_opts
=
378 XCALLOC(MTYPE_PCEP
, sizeof(struct pcep_config_group_opts
));
379 strlcpy(pcep_config_group_opts
->name
, group_name
,
380 sizeof(pcep_config_group_opts
->name
));
382 return pcep_config_group_opts
;
385 /* Iterate the pce_opts and return true if the pce-group-name is referenced,
386 * false otherwise. */
387 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
)
389 for (int i
= 0; i
< MAX_PCE
; i
++) {
390 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
391 if (strcmp(pcep_g
->pce_opts_cli
[i
]->config_group_name
,
402 static void pcep_cli_delete_pcep_pce_config(const char *group_name
)
404 for (int i
= 0; i
< MAX_PCE
; i
++) {
405 if (pcep_g
->config_group_opts
[i
] != NULL
) {
406 if (strcmp(pcep_g
->config_group_opts
[i
]->name
,
409 XFREE(MTYPE_PCEP
, pcep_g
->config_group_opts
[i
]);
410 pcep_g
->config_group_opts
[i
] = NULL
;
411 pcep_g
->num_config_group_opts
--;
418 static bool pcep_cli_pcc_has_pce(const char *pce_name
)
420 for (int i
= 0; i
< MAX_PCC
; i
++) {
421 struct pce_opts
*pce_opts
= pce_connections_g
.connections
[i
];
422 if (pce_opts
== NULL
) {
426 if (strcmp(pce_opts
->pce_name
, pce_name
) == 0) {
434 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
)
436 for (int i
= 0; i
< MAX_PCC
; i
++) {
437 if (pce_connections_g
.connections
[i
] == NULL
) {
438 pce_connections_g
.num_connections
++;
439 pce_connections_g
.connections
[i
] = pce_opts
;
445 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
)
447 for (int i
= 0; i
< MAX_PCC
; i
++) {
448 if (pce_connections_g
.connections
[i
] == pce_opts
) {
449 pce_connections_g
.num_connections
--;
450 pce_connections_g
.connections
[i
] = NULL
;
457 * VTY command implementations
460 static int path_pcep_cli_debug(struct vty
*vty
, const char *no_str
,
461 const char *basic_str
, const char *path_str
,
462 const char *message_str
, const char *pceplib_str
)
464 uint32_t mode
= DEBUG_NODE2MODE(vty
->node
);
465 bool no
= (no_str
!= NULL
);
467 DEBUG_MODE_SET(&pcep_g
->dbg
, mode
, !no
);
469 if (basic_str
!= NULL
) {
470 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
, !no
);
472 if (path_str
!= NULL
) {
473 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
, !no
);
475 if (message_str
!= NULL
) {
476 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
, !no
);
478 if (pceplib_str
!= NULL
) {
479 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
, !no
);
485 static int path_pcep_cli_show_srte_pcep_counters(struct vty
*vty
)
491 struct counters_group
*group
;
492 struct counters_subgroup
*subgroup
;
493 struct counter
*counter
;
494 const char *group_name
, *empty_string
= "";
498 group
= pcep_ctrl_get_counters(pcep_g
->fpt
, 1);
501 vty_out(vty
, "No counters to display.\n\n");
505 diff_time
= time(NULL
) - group
->start_time
;
506 localtime_r(&group
->start_time
, &tm_info
);
507 strftime(tm_buffer
, sizeof(tm_buffer
), "%Y-%m-%d %H:%M:%S", &tm_info
);
509 vty_out(vty
, "PCEP counters since %s (%uh %um %us):\n", tm_buffer
,
510 (uint32_t)(diff_time
/ 3600), (uint32_t)((diff_time
/ 60) % 60),
511 (uint32_t)(diff_time
% 60));
514 tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
515 ttable_add_row(tt
, "Group|Name|Value");
516 tt
->style
.cell
.rpad
= 2;
517 tt
->style
.corner
= '+';
519 ttable_rowseps(tt
, 0, BOTTOM
, true, '-');
521 for (row
= 0, i
= 0; i
<= group
->num_subgroups
; i
++) {
522 subgroup
= group
->subgroups
[i
];
523 if (subgroup
!= NULL
) {
524 group_name
= subgroup
->counters_subgroup_name
;
525 for (j
= 0; j
<= subgroup
->num_counters
; j
++) {
526 counter
= subgroup
->counters
[j
];
527 if (counter
!= NULL
) {
528 ttable_add_row(tt
, "%s|%s|%u",
530 counter
->counter_name
,
531 counter
->counter_value
);
533 group_name
= empty_string
;
536 ttable_rowseps(tt
, row
, BOTTOM
, true, '-');
540 /* Dump the generated table. */
541 table
= ttable_dump(tt
, "\n");
542 vty_out(vty
, "%s\n", table
);
543 XFREE(MTYPE_TMP
, table
);
547 pcep_lib_free_counters(group
);
552 static int path_pcep_cli_pcep_pce_config(struct vty
*vty
,
553 const char *pcep_pce_config
)
555 struct pcep_config_group_opts
*pce_config
=
556 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
557 if (pce_config
== NULL
) {
558 pce_config
= pcep_cli_create_pcep_pce_config(pcep_pce_config
);
559 if (pcep_cli_add_pcep_pce_config(pce_config
) == false) {
561 "%% Cannot create pce-config, as the Maximum limit of %d pce-config has been reached.\n",
563 XFREE(MTYPE_PCEP
, pce_config
);
568 "Notice: changes to this pce-config will not affect PCEs already configured with this group\n");
571 current_pcep_config_group_opts_g
= pce_config
;
572 vty
->node
= PCEP_PCE_CONFIG_NODE
;
577 static int path_pcep_cli_pcep_pce_config_delete(struct vty
*vty
,
578 const char *pcep_pce_config
)
580 struct pcep_config_group_opts
*pce_config
=
581 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
582 if (pce_config
== NULL
) {
584 "%% Cannot delete pce-config, since it does not exist.\n");
588 if (pcep_cli_is_pcep_pce_config_used(pce_config
->name
)) {
590 "%% Cannot delete pce-config, since it is in use by a peer.\n");
594 pcep_cli_delete_pcep_pce_config(pce_config
->name
);
599 static int path_pcep_cli_show_srte_pcep_pce_config(struct vty
*vty
,
600 const char *pcep_pce_config
)
604 /* Only show 1 Peer config group */
605 struct pcep_config_group_opts
*group_opts
;
606 if (pcep_pce_config
!= NULL
) {
607 if (strcmp(pcep_pce_config
, "default") == 0) {
608 group_opts
= &default_pcep_config_group_opts_g
;
611 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
613 if (group_opts
== NULL
) {
614 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
619 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
620 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
621 vty_out(vty
, "%s", buf
);
625 /* Show all Peer config groups */
626 for (int i
= 0; i
< MAX_PCE
; i
++) {
627 group_opts
= pcep_g
->config_group_opts
[i
];
628 if (group_opts
== NULL
) {
632 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
633 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
634 vty_out(vty
, "%s", buf
);
641 static int path_pcep_cli_pce(struct vty
*vty
, const char *pce_peer_name
)
643 /* If it already exists, it will be updated in the sub-commands */
644 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
645 if (pce_opts_cli
== NULL
) {
646 pce_opts_cli
= pcep_cli_create_pce_opts(pce_peer_name
);
648 if (!pcep_cli_add_pce(pce_opts_cli
)) {
650 "%% Cannot create PCE, as the Maximum limit of %d PCEs has been reached.\n",
652 XFREE(MTYPE_PCEP
, pce_opts_cli
);
657 current_pce_opts_g
= pce_opts_cli
;
658 vty
->node
= PCEP_PCE_NODE
;
663 static int path_pcep_cli_pce_delete(struct vty
*vty
, const char *pce_peer_name
)
665 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
666 if (pce_opts_cli
== NULL
) {
667 vty_out(vty
, "%% PCC peer does not exist.\n");
671 /* To better work with frr-reload, go ahead and delete it if its in use
673 if (pcep_cli_pcc_has_pce(pce_peer_name
)) {
675 "%% Notice: the pce is in use by a PCC, also disconnecting.\n");
676 path_pcep_cli_pcc_pcc_peer_delete(vty
, pce_peer_name
, NULL
, 0);
679 pcep_cli_delete_pce(pce_peer_name
);
684 /* Internal Util func to show an individual PCE,
685 * only used by path_pcep_cli_show_srte_pcep_pce() */
686 static void show_pce_peer(struct vty
*vty
, struct pce_opts_cli
*pce_opts_cli
)
688 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
689 vty_out(vty
, "PCE: %s\n", pce_opts
->pce_name
);
691 /* Remote PCE IP address */
692 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
693 vty_out(vty
, " %s %s %pI6 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
694 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
,
695 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
697 vty_out(vty
, " %s %s %pI4 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
698 PCEP_VTYSH_ARG_IP
, &pce_opts
->addr
.ipaddr_v4
,
699 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
702 if (pce_opts_cli
->config_group_name
[0] != '\0') {
703 vty_out(vty
, " pce-config: %s\n",
704 pce_opts_cli
->config_group_name
);
708 pcep_cli_print_pce_config(&pce_opts
->config_opts
, buf
, sizeof(buf
));
709 vty_out(vty
, "%s", buf
);
712 static int path_pcep_cli_show_srte_pcep_pce(struct vty
*vty
,
713 const char *pce_peer
)
715 /* Only show 1 PCE */
716 struct pce_opts_cli
*pce_opts_cli
;
717 if (pce_peer
!= NULL
) {
718 pce_opts_cli
= pcep_cli_find_pce(pce_peer
);
719 if (pce_opts_cli
== NULL
) {
720 vty_out(vty
, "%% PCE [%s] does not exist.\n", pce_peer
);
724 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
725 show_pce_peer(vty
, pce_opts_cli
);
731 for (int i
= 0; i
< MAX_PCE
; i
++) {
732 pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
733 if (pce_opts_cli
== NULL
) {
737 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
738 show_pce_peer(vty
, pce_opts_cli
);
744 static int path_pcep_cli_peer_sr_draft07(struct vty
*vty
)
746 struct pcep_config_group_opts
*pce_config
= NULL
;
748 if (vty
->node
== PCEP_PCE_NODE
) {
749 /* TODO need to see if the pce is in use, and reset the
751 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
752 current_pce_opts_g
->merged
= false;
753 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
754 pce_config
= current_pcep_config_group_opts_g
;
756 return CMD_ERR_NO_MATCH
;
759 pce_config
->draft07
= true;
764 static int path_pcep_cli_peer_pce_initiated(struct vty
*vty
)
766 struct pcep_config_group_opts
*pce_config
= NULL
;
768 if (vty
->node
== PCEP_PCE_NODE
) {
769 /* TODO need to see if the pce is in use, and reset the
771 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
772 current_pce_opts_g
->merged
= false;
773 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
774 pce_config
= current_pcep_config_group_opts_g
;
776 return CMD_ERR_NO_MATCH
;
779 pce_config
->pce_initiated
= true;
784 static int path_pcep_cli_peer_tcp_md5_auth(struct vty
*vty
,
785 const char *tcp_md5_auth
)
787 struct pcep_config_group_opts
*pce_config
= NULL
;
789 if (vty
->node
== PCEP_PCE_NODE
) {
790 /* TODO need to see if the pce is in use, and reset the
792 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
793 current_pce_opts_g
->merged
= false;
794 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
795 pce_config
= current_pcep_config_group_opts_g
;
797 return CMD_ERR_NO_MATCH
;
800 strlcpy(pce_config
->tcp_md5_auth
, tcp_md5_auth
,
801 sizeof(pce_config
->tcp_md5_auth
));
806 static int path_pcep_cli_peer_address(struct vty
*vty
, const char *ip_str
,
807 struct in_addr
*ip
, const char *ipv6_str
,
808 struct in6_addr
*ipv6
,
809 const char *port_str
, long port
)
811 struct pce_opts
*pce_opts
= NULL
;
812 if (vty
->node
== PCEP_PCE_NODE
) {
813 /* TODO need to see if the pce is in use, and reset the
815 pce_opts
= ¤t_pce_opts_g
->pce_opts
;
816 current_pce_opts_g
->merged
= false;
818 return CMD_ERR_NO_MATCH
;
821 if (ipv6_str
!= NULL
) {
822 pce_opts
->addr
.ipa_type
= IPADDR_V6
;
823 memcpy(&pce_opts
->addr
.ipaddr_v6
, ipv6
,
824 sizeof(struct in6_addr
));
825 } else if (ip_str
!= NULL
) {
826 pce_opts
->addr
.ipa_type
= IPADDR_V4
;
827 memcpy(&pce_opts
->addr
.ipaddr_v4
, ip
, sizeof(struct in_addr
));
829 return CMD_ERR_NO_MATCH
;
832 /* Handle the optional port */
833 pce_opts
->port
= PCEP_DEFAULT_PORT
;
834 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_opts
->port
, 0, 65535);
839 static int path_pcep_cli_peer_source_address(struct vty
*vty
,
842 const char *ipv6_str
,
843 struct in6_addr
*ipv6
,
844 const char *port_str
, long port
)
846 struct pcep_config_group_opts
*pce_config
= NULL
;
847 if (vty
->node
== PCEP_PCE_NODE
) {
848 /* TODO need to see if the pce is in use, and reset the
850 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
851 current_pce_opts_g
->merged
= false;
852 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
853 pce_config
= current_pcep_config_group_opts_g
;
855 return CMD_ERR_NO_MATCH
;
858 /* Handle the optional source IP */
859 if (ipv6_str
!= NULL
) {
860 pce_config
->source_ip
.ipa_type
= IPADDR_V6
;
861 memcpy(&pce_config
->source_ip
.ipaddr_v6
, ipv6
,
862 sizeof(struct in6_addr
));
863 } else if (ip_str
!= NULL
) {
864 pce_config
->source_ip
.ipa_type
= IPADDR_V4
;
865 memcpy(&pce_config
->source_ip
.ipaddr_v4
, ip
,
866 sizeof(struct in_addr
));
869 /* Handle the optional port */
870 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_config
->source_port
, 0,
876 static int path_pcep_cli_peer_pcep_pce_config_ref(struct vty
*vty
,
877 const char *config_group_name
)
879 if (vty
->node
== PCEP_PCE_NODE
) {
880 /* TODO need to see if the pce is in use, and reset the
882 current_pce_opts_g
->merged
= false;
884 return CMD_ERR_NO_MATCH
;
887 struct pcep_config_group_opts
*pce_config
=
888 pcep_cli_find_pcep_pce_config(config_group_name
);
889 if (pce_config
== NULL
) {
890 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
895 strlcpy(current_pce_opts_g
->config_group_name
, config_group_name
,
896 sizeof(current_pce_opts_g
->config_group_name
));
901 static int path_pcep_cli_peer_timers(
902 struct vty
*vty
, const char *keep_alive_str
, long keep_alive
,
903 const char *min_peer_keep_alive_str
, long min_peer_keep_alive
,
904 const char *max_peer_keep_alive_str
, long max_peer_keep_alive
,
905 const char *dead_timer_str
, long dead_timer
,
906 const char *min_peer_dead_timer_str
, long min_peer_dead_timer
,
907 const char *max_peer_dead_timer_str
, long max_peer_dead_timer
,
908 const char *pcep_request_str
, long pcep_request
,
909 const char *session_timeout_interval_str
, long session_timeout_interval
,
910 const char *delegation_timeout_str
, long delegation_timeout
)
912 struct pcep_config_group_opts
*pce_config
= NULL
;
913 if (vty
->node
== PCEP_PCE_NODE
) {
914 /* TODO need to see if the pce is in use, and reset the
916 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
917 current_pce_opts_g
->merged
= false;
918 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
919 pce_config
= current_pcep_config_group_opts_g
;
921 return CMD_ERR_NO_MATCH
;
924 if (min_peer_keep_alive
&& max_peer_keep_alive
)
925 if (min_peer_keep_alive
>= max_peer_keep_alive
) {
926 return CMD_ERR_NO_MATCH
;
929 if (min_peer_dead_timer
&& max_peer_dead_timer
)
930 if (min_peer_dead_timer
>= max_peer_dead_timer
) {
931 return CMD_ERR_NO_MATCH
;
934 /* Handle the arguments */
935 PCEP_VTYSH_INT_ARG_CHECK(keep_alive_str
, keep_alive
,
936 pce_config
->keep_alive_seconds
, 0, 64);
937 PCEP_VTYSH_INT_ARG_CHECK(min_peer_keep_alive_str
, min_peer_keep_alive
,
938 pce_config
->min_keep_alive_seconds
, 0, 256);
939 PCEP_VTYSH_INT_ARG_CHECK(max_peer_keep_alive_str
, max_peer_keep_alive
,
940 pce_config
->max_keep_alive_seconds
, 0, 256);
941 PCEP_VTYSH_INT_ARG_CHECK(dead_timer_str
, dead_timer
,
942 pce_config
->dead_timer_seconds
, 3, 256);
943 PCEP_VTYSH_INT_ARG_CHECK(min_peer_dead_timer_str
, min_peer_dead_timer
,
944 pce_config
->min_dead_timer_seconds
, 3, 256);
945 PCEP_VTYSH_INT_ARG_CHECK(max_peer_dead_timer_str
, max_peer_dead_timer
,
946 pce_config
->max_dead_timer_seconds
, 3, 256);
947 PCEP_VTYSH_INT_ARG_CHECK(pcep_request_str
, pcep_request
,
948 pce_config
->pcep_request_time_seconds
, 0, 121);
949 PCEP_VTYSH_INT_ARG_CHECK(
950 session_timeout_interval_str
, session_timeout_interval
,
951 pce_config
->session_timeout_inteval_seconds
, 0, 121);
952 PCEP_VTYSH_INT_ARG_CHECK(delegation_timeout_str
, delegation_timeout
,
953 pce_config
->delegation_timeout_seconds
, 0, 61);
958 static int path_pcep_cli_pcc(struct vty
*vty
)
960 VTY_PUSH_CONTEXT_NULL(PCEP_PCC_NODE
);
965 static int path_pcep_cli_pcc_delete(struct vty
*vty
)
967 /* Clear the pce_connections */
968 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
969 pcc_msd_configured_g
= false;
971 pcep_ctrl_remove_pcc(pcep_g
->fpt
, NULL
);
976 static int path_pcep_cli_pcc_pcc_msd(struct vty
*vty
, const char *msd_str
,
979 pcc_msd_configured_g
= true;
980 PCEP_VTYSH_INT_ARG_CHECK(msd_str
, msd
, pcc_msd_g
, 0, 33);
985 static int path_pcep_cli_pcc_pcc_peer(struct vty
*vty
, const char *peer_name
,
986 const char *precedence_str
,
989 /* Check if the pcc-peer exists */
990 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
991 if (pce_opts_cli
== NULL
) {
992 vty_out(vty
, "%% PCE [%s] does not exist.\n", peer_name
);
995 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
997 /* Check if the pcc-peer is duplicated */
998 if (pcep_cli_pcc_has_pce(peer_name
)) {
999 vty_out(vty
, "%% The peer [%s] has already been configured.\n",
1004 /* Get the optional precedence argument */
1005 pce_opts
->precedence
= DEFAULT_PCE_PRECEDENCE
;
1006 PCEP_VTYSH_INT_ARG_CHECK(precedence_str
, precedence
,
1007 pce_opts
->precedence
, 0, 256);
1009 /* Finalize the pce_opts config values */
1010 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
1011 pcep_cli_add_pce_connection(&pce_opts_cli
->pce_opts
);
1013 /* Verify the PCE has the IP set */
1014 struct in6_addr zero_v6_addr
;
1015 memset(&zero_v6_addr
, 0, sizeof(zero_v6_addr
));
1016 if (memcmp(&pce_opts
->addr
.ip
, &zero_v6_addr
, IPADDRSZ(&pce_opts
->addr
))
1019 "%% The peer [%s] does not have an IP set and cannot be used until it does.\n",
1024 /* Update the pcc_opts with the source ip, port, and msd */
1025 struct pcc_opts
*pcc_opts_copy
=
1026 XMALLOC(MTYPE_PCEP
, sizeof(struct pcc_opts
));
1027 memcpy(&pcc_opts_copy
->addr
,
1028 &pce_opts_cli
->pce_opts
.config_opts
.source_ip
,
1029 sizeof(pcc_opts_copy
->addr
));
1030 pcc_opts_copy
->msd
= pcc_msd_g
;
1031 pcc_opts_copy
->port
= pce_opts_cli
->pce_opts
.config_opts
.source_port
;
1032 if (pcep_ctrl_update_pcc_options(pcep_g
->fpt
, pcc_opts_copy
)) {
1036 /* Send a copy of the pce_opts, this one is only used for the CLI */
1037 struct pce_opts
*pce_opts_copy
=
1038 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1039 memcpy(pce_opts_copy
, pce_opts
, sizeof(struct pce_opts
));
1040 if (pcep_ctrl_update_pce_options(pcep_g
->fpt
, pce_opts_copy
)) {
1047 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
1048 const char *peer_name
,
1049 const char *precedence_str
,
1052 /* Check if the pcc-peer is connected to the PCC */
1053 if (!pcep_cli_pcc_has_pce(peer_name
)) {
1055 "%% WARN: The peer [%s] is not connected to the PCC.\n",
1060 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1061 pcep_cli_remove_pce_connection(&pce_opts_cli
->pce_opts
);
1063 /* Send a copy of the pce_opts, this one is used for CLI only */
1064 struct pce_opts
*pce_opts_copy
=
1065 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1066 memcpy(pce_opts_copy
, &pce_opts_cli
->pce_opts
, sizeof(struct pce_opts
));
1067 pcep_ctrl_remove_pcc(pcep_g
->fpt
, pce_opts_copy
);
1072 static int path_pcep_cli_show_srte_pcep_pcc(struct vty
*vty
)
1074 vty_out(vty
, "pcc msd %d\n", pcc_msd_g
);
1079 /* Internal util function to print pcep capabilities to a buffer */
1080 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
1081 pcep_configuration
*config
)
1083 if (config
->support_stateful_pce_lsp_update
) {
1084 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_STATEFUL
);
1086 if (config
->support_include_db_version
) {
1087 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_INCL_DB_VER
);
1089 if (config
->support_lsp_triggered_resync
) {
1090 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_TRIGGERED
);
1092 if (config
->support_lsp_delta_sync
) {
1093 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_DELTA
);
1095 if (config
->support_pce_triggered_initial_sync
) {
1096 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCE_TRIGGERED
);
1098 if (config
->support_sr_te_pst
) {
1099 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_SR_TE_PST
);
1101 if (config
->pcc_can_resolve_nai_to_sid
) {
1102 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCC_RESOLVE_NAI
);
1106 /* Internal util function to print a pcep session */
1107 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
1108 struct pcep_pcc_info
*pcc_info
)
1113 vty_out(vty
, "\nPCE %s\n", pce_opts
->pce_name
);
1116 if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1117 vty_out(vty
, " PCE IP %pI4 port %d\n",
1118 &pce_opts
->addr
.ipaddr_v4
, pce_opts
->port
);
1119 } else if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1120 vty_out(vty
, " PCE IPv6 %pI6 port %d\n",
1121 &pce_opts
->addr
.ipaddr_v6
, pce_opts
->port
);
1125 if (IS_IPADDR_V4(&pcc_info
->pcc_addr
)) {
1126 vty_out(vty
, " PCC IP %pI4 port %d\n",
1127 &pcc_info
->pcc_addr
.ipaddr_v4
, pcc_info
->pcc_port
);
1128 } else if (IS_IPADDR_V6(&pcc_info
->pcc_addr
)) {
1129 vty_out(vty
, " PCC IPv6 %pI6 port %d\n",
1130 &pcc_info
->pcc_addr
.ipaddr_v6
, pcc_info
->pcc_port
);
1132 vty_out(vty
, " PCC MSD %d\n", pcc_info
->msd
);
1134 if (pcc_info
->status
== PCEP_PCC_OPERATING
) {
1135 vty_out(vty
, " Session Status UP\n");
1137 vty_out(vty
, " Session Status %s\n",
1138 pcc_status_name(pcc_info
->status
));
1141 if (pcc_info
->is_best_multi_pce
) {
1142 vty_out(vty
, " Precedence %d, best candidate\n",
1143 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1144 : DEFAULT_PCE_PRECEDENCE
));
1146 vty_out(vty
, " Precedence %d\n",
1147 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1148 : DEFAULT_PCE_PRECEDENCE
));
1150 vty_out(vty
, " Confidence %s\n",
1151 ((pcc_info
->previous_best
) ? "low"
1154 /* PCEPlib pcep session values, get a thread safe copy of the counters
1156 pcep_session
*session
=
1157 pcep_ctrl_get_pcep_session(pcep_g
->fpt
, pcc_info
->pcc_id
);
1159 /* Config Options values */
1160 struct pcep_config_group_opts
*config_opts
= &pce_opts
->config_opts
;
1161 if (session
!= NULL
) {
1162 vty_out(vty
, " Timer: KeepAlive config %d, pce-negotiated %d\n",
1163 config_opts
->keep_alive_seconds
,
1165 .keep_alive_pce_negotiated_timer_seconds
);
1166 vty_out(vty
, " Timer: DeadTimer config %d, pce-negotiated %d\n",
1167 config_opts
->dead_timer_seconds
,
1168 session
->pcc_config
.dead_timer_pce_negotiated_seconds
);
1170 vty_out(vty
, " Timer: KeepAlive %d\n",
1171 config_opts
->keep_alive_seconds
);
1172 vty_out(vty
, " Timer: DeadTimer %d\n",
1173 config_opts
->dead_timer_seconds
);
1175 vty_out(vty
, " Timer: PcRequest %d\n",
1176 config_opts
->pcep_request_time_seconds
);
1177 vty_out(vty
, " Timer: SessionTimeout Interval %d\n",
1178 config_opts
->session_timeout_inteval_seconds
);
1179 vty_out(vty
, " Timer: Delegation Timeout %d\n",
1180 config_opts
->delegation_timeout_seconds
);
1181 if (strlen(config_opts
->tcp_md5_auth
) > 0) {
1182 vty_out(vty
, " TCP MD5 Auth Str: %s\n",
1183 config_opts
->tcp_md5_auth
);
1185 vty_out(vty
, " No TCP MD5 Auth\n");
1188 if (config_opts
->draft07
) {
1189 vty_out(vty
, " PCE SR Version draft07\n");
1191 vty_out(vty
, " PCE SR Version draft16 and RFC8408\n");
1194 vty_out(vty
, " Next PcReq ID %d\n", pcc_info
->next_reqid
);
1195 vty_out(vty
, " Next PLSP ID %d\n", pcc_info
->next_plspid
);
1197 if (session
!= NULL
) {
1198 if (pcc_info
->status
== PCEP_PCC_SYNCHRONIZING
1199 || pcc_info
->status
== PCEP_PCC_OPERATING
) {
1200 time_t current_time
= time(NULL
);
1202 /* Just for the timezone */
1203 localtime_r(¤t_time
, <
);
1204 gmtime_r(&session
->time_connected
, <
);
1206 " Connected for %u seconds, since %d-%02d-%02d %02d:%02d:%02d UTC\n",
1207 (uint32_t)(current_time
1208 - session
->time_connected
),
1209 lt
.tm_year
+ 1900, lt
.tm_mon
+ 1, lt
.tm_mday
,
1210 lt
.tm_hour
, lt
.tm_min
, lt
.tm_sec
);
1213 /* PCC capabilities */
1216 if (config_opts
->pce_initiated
) {
1217 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1218 PCEP_CLI_CAP_PCC_PCE_INITIATED
);
1220 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1221 PCEP_CLI_CAP_PCC_INITIATED
);
1223 print_pcep_capabilities(buf
, sizeof(buf
) - index
,
1224 &session
->pcc_config
);
1225 vty_out(vty
, " PCC Capabilities:%s\n", buf
);
1227 /* PCE capabilities */
1229 print_pcep_capabilities(buf
, sizeof(buf
), &session
->pce_config
);
1230 if (buf
[0] != '\0') {
1231 vty_out(vty
, " PCE Capabilities:%s\n", buf
);
1233 XFREE(MTYPE_PCEP
, session
);
1235 vty_out(vty
, " Detailed session information not available\n");
1238 /* Message Counters, get a thread safe copy of the counters */
1239 struct counters_group
*group
=
1240 pcep_ctrl_get_counters(pcep_g
->fpt
, pcc_info
->pcc_id
);
1242 if (group
!= NULL
) {
1243 struct counters_subgroup
*rx_msgs
=
1244 find_subgroup(group
, COUNTER_SUBGROUP_ID_RX_MSG
);
1245 struct counters_subgroup
*tx_msgs
=
1246 find_subgroup(group
, COUNTER_SUBGROUP_ID_TX_MSG
);
1248 if (rx_msgs
!= NULL
&& tx_msgs
!= NULL
) {
1249 vty_out(vty
, " PCEP Message Statistics\n");
1250 vty_out(vty
, " %27s %6s\n", "Sent", "Rcvd");
1251 for (int i
= 0; i
< rx_msgs
->max_counters
; i
++) {
1252 struct counter
*rx_counter
=
1253 rx_msgs
->counters
[i
];
1254 struct counter
*tx_counter
=
1255 tx_msgs
->counters
[i
];
1256 if (rx_counter
!= NULL
&& tx_counter
!= NULL
) {
1257 vty_out(vty
, " %20s: %5d %5d\n",
1258 tx_counter
->counter_name
,
1259 tx_counter
->counter_value
,
1260 rx_counter
->counter_value
);
1263 vty_out(vty
, " %20s: %5d %5d\n", "Total",
1264 subgroup_counters_total(tx_msgs
),
1265 subgroup_counters_total(rx_msgs
));
1267 pcep_lib_free_counters(group
);
1269 vty_out(vty
, " Counters not available\n");
1272 XFREE(MTYPE_PCEP
, pcc_info
);
1275 static int path_pcep_cli_show_srte_pcep_session(struct vty
*vty
,
1276 const char *pcc_peer
)
1278 struct pce_opts_cli
*pce_opts_cli
;
1279 struct pcep_pcc_info
*pcc_info
;
1281 /* Only show 1 PCEP session */
1282 if (pcc_peer
!= NULL
) {
1283 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1284 if (pce_opts_cli
== NULL
) {
1285 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1289 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1290 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1295 pcc_info
= pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pcc_peer
);
1296 if (pcc_info
== NULL
) {
1298 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1303 print_pcep_session(vty
, &pce_opts_cli
->pce_opts
, pcc_info
);
1308 /* Show all PCEP sessions */
1309 struct pce_opts
*pce_opts
;
1310 int num_pcep_sessions_conf
= 0;
1311 int num_pcep_sessions_conn
= 0;
1312 for (int i
= 0; i
< MAX_PCC
; i
++) {
1313 pce_opts
= pce_connections_g
.connections
[i
];
1314 if (pce_opts
== NULL
) {
1319 pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pce_opts
->pce_name
);
1320 if (pcc_info
== NULL
) {
1322 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1323 pce_opts
->pce_name
);
1327 num_pcep_sessions_conn
+=
1328 pcc_info
->status
== PCEP_PCC_OPERATING
? 1 : 0;
1329 num_pcep_sessions_conf
++;
1330 print_pcep_session(vty
, pce_opts
, pcc_info
);
1333 vty_out(vty
, "PCEP Sessions => Configured %d ; Connected %d\n",
1334 num_pcep_sessions_conf
, num_pcep_sessions_conn
);
1339 static int path_pcep_cli_clear_srte_pcep_session(struct vty
*vty
,
1340 const char *pcc_peer
)
1342 struct pce_opts_cli
*pce_opts_cli
;
1344 /* Only clear 1 PCEP session */
1345 if (pcc_peer
!= NULL
) {
1346 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1347 if (pce_opts_cli
== NULL
) {
1348 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1352 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1353 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1358 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
,
1359 pce_opts_cli
->pce_opts
.pce_name
);
1360 vty_out(vty
, "PCEP session cleared for peer %s\n", pcc_peer
);
1365 /* Clear all PCEP sessions */
1366 struct pce_opts
*pce_opts
;
1367 int num_pcep_sessions
= 0;
1368 for (int i
= 0; i
< MAX_PCC
; i
++) {
1369 pce_opts
= pce_connections_g
.connections
[i
];
1370 if (pce_opts
== NULL
) {
1374 num_pcep_sessions
++;
1375 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
, pce_opts
->pce_name
);
1376 vty_out(vty
, "PCEP session cleared for peer %s\n",
1377 pce_opts
->pce_name
);
1380 vty_out(vty
, "Cleared [%d] PCEP sessions\n", num_pcep_sessions
);
1386 * Config Write functions
1389 int pcep_cli_debug_config_write(struct vty
*vty
)
1391 char buff
[128] = "";
1393 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1394 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1395 csnprintfrr(buff
, sizeof(buff
), " %s",
1396 PCEP_VTYSH_ARG_BASIC
);
1397 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1398 csnprintfrr(buff
, sizeof(buff
), " %s",
1399 PCEP_VTYSH_ARG_PATH
);
1400 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1401 csnprintfrr(buff
, sizeof(buff
), " %s",
1402 PCEP_VTYSH_ARG_MESSAGE
);
1403 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1404 csnprintfrr(buff
, sizeof(buff
), " %s",
1405 PCEP_VTYSH_ARG_PCEPLIB
);
1406 vty_out(vty
, "debug pathd pcep%s\n", buff
);
1414 int pcep_cli_debug_set_all(uint32_t flags
, bool set
)
1416 DEBUG_FLAGS_SET(&pcep_g
->dbg
, flags
, set
);
1418 /* If all modes have been turned off, don't preserve options. */
1419 if (!DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_ALL
))
1420 DEBUG_CLEAR(&pcep_g
->dbg
);
1425 int pcep_cli_pcep_config_write(struct vty
*vty
)
1427 vty_out(vty
, " pcep\n");
1428 pcep_cli_pcep_pce_config_write(vty
);
1429 pcep_cli_pce_config_write(vty
);
1430 pcep_cli_pcc_config_write(vty
);
1431 vty_out(vty
, " exit\n");
1435 int pcep_cli_pcc_config_write(struct vty
*vty
)
1437 struct pce_opts
*pce_opts
;
1441 /* The MSD, nor any PCE peers have been configured on the PCC */
1442 if (!pcc_msd_configured_g
&& pce_connections_g
.num_connections
== 0) {
1446 vty_out(vty
, " pcc\n");
1449 /* Prepare the MSD, if present */
1450 if (pcc_msd_configured_g
) {
1451 vty_out(vty
, " %s %d\n", PCEP_VTYSH_ARG_MSD
, pcc_msd_g
);
1455 if (pce_connections_g
.num_connections
== 0) {
1460 for (int i
= 0; i
< MAX_PCC
; i
++) {
1461 pce_opts
= pce_connections_g
.connections
[i
];
1462 if (pce_opts
== NULL
) {
1466 /* Only show the PCEs configured in the pcc sub-command */
1467 if (!pcep_cli_pcc_has_pce(pce_opts
->pce_name
)) {
1471 csnprintfrr(buf
, sizeof(buf
), " peer %s",
1472 pce_opts
->pce_name
);
1473 if (pce_opts
->precedence
> 0
1474 && pce_opts
->precedence
!= DEFAULT_PCE_PRECEDENCE
) {
1475 csnprintfrr(buf
, sizeof(buf
), " %s %d",
1476 PCEP_VTYSH_ARG_PRECEDENCE
,
1477 pce_opts
->precedence
);
1479 vty_out(vty
, "%s\n", buf
);
1484 vty_out(vty
, " exit\n");
1489 /* Internal function used by pcep_cli_pce_config_write()
1490 * and pcep_cli_pcep_pce_config_write() */
1491 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
1492 char *buf
, size_t buf_len
)
1496 if (group_opts
->source_ip
.ipa_type
!= IPADDR_NONE
1497 || group_opts
->source_port
!= 0) {
1498 csnprintfrr(buf
, buf_len
, " ");
1499 if (IS_IPADDR_V4(&group_opts
->source_ip
)) {
1500 csnprintfrr(buf
, buf_len
, " %s %s %pI4",
1501 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1503 &group_opts
->source_ip
.ipaddr_v4
);
1504 } else if (IS_IPADDR_V6(&group_opts
->source_ip
)) {
1505 csnprintfrr(buf
, buf_len
, " %s %s %pI6",
1506 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1507 PCEP_VTYSH_ARG_IPV6
,
1508 &group_opts
->source_ip
.ipaddr_v6
);
1510 if (group_opts
->source_port
> 0) {
1511 csnprintfrr(buf
, buf_len
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1512 group_opts
->source_port
);
1514 csnprintfrr(buf
, buf_len
, "\n");
1517 /* Group the keep-alive together for devman */
1518 if ((group_opts
->keep_alive_seconds
> 0)
1519 || (group_opts
->min_keep_alive_seconds
> 0)
1520 || (group_opts
->max_keep_alive_seconds
> 0)) {
1521 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1523 if (group_opts
->keep_alive_seconds
> 0) {
1524 csnprintfrr(buf
, buf_len
, " %s %d",
1525 PCEP_VTYSH_ARG_KEEP_ALIVE
,
1526 group_opts
->keep_alive_seconds
);
1528 if (group_opts
->min_keep_alive_seconds
> 0) {
1529 csnprintfrr(buf
, buf_len
, " %s %d",
1530 PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
,
1531 group_opts
->min_keep_alive_seconds
);
1533 if (group_opts
->max_keep_alive_seconds
> 0) {
1534 csnprintfrr(buf
, buf_len
, " %s %d",
1535 PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
,
1536 group_opts
->max_keep_alive_seconds
);
1538 csnprintfrr(buf
, buf_len
, "\n");
1542 /* Group the dead-timer together for devman */
1543 if ((group_opts
->dead_timer_seconds
> 0)
1544 || (group_opts
->min_dead_timer_seconds
> 0)
1545 || (group_opts
->max_dead_timer_seconds
> 0)) {
1546 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1548 if (group_opts
->dead_timer_seconds
> 0) {
1549 csnprintfrr(buf
, buf_len
, " %s %d",
1550 PCEP_VTYSH_ARG_DEAD_TIMER
,
1551 group_opts
->dead_timer_seconds
);
1553 if (group_opts
->min_dead_timer_seconds
> 0) {
1554 csnprintfrr(buf
, buf_len
, " %s %d",
1555 PCEP_VTYSH_ARG_DEAD_TIMER_MIN
,
1556 group_opts
->min_dead_timer_seconds
);
1558 if (group_opts
->max_dead_timer_seconds
> 0) {
1559 csnprintfrr(buf
, buf_len
, " %s %d",
1560 PCEP_VTYSH_ARG_DEAD_TIMER_MAX
,
1561 group_opts
->max_dead_timer_seconds
);
1563 csnprintfrr(buf
, buf_len
, "\n");
1567 if (group_opts
->pcep_request_time_seconds
> 0) {
1568 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1569 PCEP_VTYSH_ARG_TIMER
, PCEP_VTYSH_ARG_PCEP_REQUEST
,
1570 group_opts
->pcep_request_time_seconds
);
1573 if (group_opts
->delegation_timeout_seconds
> 0) {
1574 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1575 PCEP_VTYSH_ARG_TIMER
,
1576 PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
,
1577 group_opts
->delegation_timeout_seconds
);
1580 if (group_opts
->session_timeout_inteval_seconds
> 0) {
1581 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1582 PCEP_VTYSH_ARG_TIMER
,
1583 PCEP_VTYSH_ARG_SESSION_TIMEOUT
,
1584 group_opts
->session_timeout_inteval_seconds
);
1587 if (group_opts
->tcp_md5_auth
[0] != '\0') {
1588 csnprintfrr(buf
, buf_len
, " %s %s\n", PCEP_VTYSH_ARG_TCP_MD5
,
1589 group_opts
->tcp_md5_auth
);
1592 if (group_opts
->draft07
) {
1593 csnprintfrr(buf
, buf_len
, " %s\n",
1594 PCEP_VTYSH_ARG_SR_DRAFT07
);
1597 if (group_opts
->pce_initiated
) {
1598 csnprintfrr(buf
, buf_len
, " %s\n", PCEP_VTYSH_ARG_PCE_INIT
);
1605 int pcep_cli_pce_config_write(struct vty
*vty
)
1608 char buf
[1024] = "";
1610 for (int i
= 0; i
< MAX_PCE
; i
++) {
1611 struct pce_opts_cli
*pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
1612 if (pce_opts_cli
== NULL
) {
1615 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1617 vty_out(vty
, " pce %s\n", pce_opts
->pce_name
);
1618 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1619 vty_out(vty
, " %s %s %pI6", PCEP_VTYSH_ARG_ADDRESS
,
1620 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
);
1621 } else if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1622 vty_out(vty
, " address %s %pI4", PCEP_VTYSH_ARG_IP
,
1623 &pce_opts
->addr
.ipaddr_v4
);
1625 if (pce_opts
->port
!= PCEP_DEFAULT_PORT
) {
1626 vty_out(vty
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1629 vty_out(vty
, "%s\n", buf
);
1632 if (pce_opts_cli
->config_group_name
[0] != '\0') {
1633 vty_out(vty
, " config %s\n",
1634 pce_opts_cli
->config_group_name
);
1638 /* Only display the values configured on the PCE, not the values
1639 * from its optional pce-config-group, nor the default values */
1640 lines
+= pcep_cli_print_pce_config(
1641 &pce_opts_cli
->pce_config_group_opts
, buf
, sizeof(buf
));
1643 vty_out(vty
, "%s", buf
);
1646 vty_out(vty
, " exit\n");
1652 int pcep_cli_pcep_pce_config_write(struct vty
*vty
)
1655 char buf
[1024] = "";
1657 for (int i
= 0; i
< MAX_PCE
; i
++) {
1658 struct pcep_config_group_opts
*group_opts
=
1659 pcep_g
->config_group_opts
[i
];
1660 if (group_opts
== NULL
) {
1664 vty_out(vty
, " pce-config %s\n", group_opts
->name
);
1668 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
1669 vty_out(vty
, "%s", buf
);
1672 vty_out(vty
, " exit\n");
1679 * VTYSH command syntax definitions
1680 * The param names are taken from the path_pcep_cli_clippy.c generated file.
1683 DEFPY(show_debugging_pathd_pcep
,
1684 show_debugging_pathd_pcep_cmd
,
1685 "show debugging pathd-pcep",
1687 "State of each debugging option\n"
1688 "pathd pcep module debugging\n")
1690 vty_out(vty
, "Pathd pcep debugging status:\n");
1692 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1693 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1694 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1695 PCEP_VTYSH_ARG_BASIC
);
1696 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1697 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1698 PCEP_VTYSH_ARG_PATH
);
1699 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1700 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1701 PCEP_VTYSH_ARG_MESSAGE
);
1702 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1703 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1704 PCEP_VTYSH_ARG_PCEPLIB
);
1710 DEFPY(pcep_cli_debug
,
1712 "[no] debug pathd pcep [basic]$basic_str [path]$path_str [message]$message_str [pceplib]$pceplib_str",
1715 "pcep module debugging\n"
1716 "module basic debugging\n"
1717 "path structures debugging\n"
1718 "pcep message debugging\n"
1719 "pceplib debugging\n")
1721 return path_pcep_cli_debug(vty
, no
, basic_str
, path_str
, message_str
,
1725 DEFPY(pcep_cli_show_srte_pcep_counters
,
1726 pcep_cli_show_srte_pcep_counters_cmd
,
1727 "show sr-te pcep counters",
1733 return path_pcep_cli_show_srte_pcep_counters(vty
);
1740 "PCEP configuration\n")
1742 vty
->node
= PCEP_NODE
;
1747 pcep_cli_pcep_pce_config
,
1748 pcep_cli_pcep_pce_config_cmd
,
1749 "pce-config WORD$name",
1750 "Shared configuration\n"
1751 "Shared configuration name\n")
1753 return path_pcep_cli_pcep_pce_config(vty
, name
);
1756 DEFPY(pcep_cli_pcep_no_pce_config
,
1757 pcep_cli_pcep_no_pce_config_cmd
,
1758 "no pce-config WORD$name",
1760 "Shared configuration\n"
1761 "Shared configuration name\n")
1763 return path_pcep_cli_pcep_pce_config_delete(vty
, name
);
1766 DEFPY(pcep_cli_show_srte_pcep_pce_config
,
1767 pcep_cli_show_srte_pcep_pce_config_cmd
,
1768 "show sr-te pcep pce-config [<default|WORD>$name]",
1772 "Show shared PCE configuration\n"
1773 "Show default hard-coded values\n"
1774 "Shared configuration name\n")
1776 return path_pcep_cli_show_srte_pcep_pce_config(vty
, name
);
1783 "PCE configuration, address sub-config is mandatory\n"
1786 return path_pcep_cli_pce(vty
, name
);
1789 DEFPY(pcep_cli_no_pce
,
1790 pcep_cli_no_pce_cmd
,
1793 "PCE configuration, address sub-config is mandatory\n"
1796 return path_pcep_cli_pce_delete(vty
, name
);
1799 DEFPY(pcep_cli_show_srte_pcep_pce
,
1800 pcep_cli_show_srte_pcep_pce_cmd
,
1801 "show sr-te pcep pce [WORD$name]",
1805 "Show detailed pce values\n"
1808 return path_pcep_cli_show_srte_pcep_pce(vty
, name
);
1811 DEFPY(pcep_cli_peer_sr_draft07
,
1812 pcep_cli_peer_sr_draft07_cmd
,
1814 "Configure PCC to send PCEP Open with SR draft07\n")
1816 return path_pcep_cli_peer_sr_draft07(vty
);
1819 DEFPY(pcep_cli_peer_pce_initiated
,
1820 pcep_cli_peer_pce_initiated_cmd
,
1822 "Configure PCC to accept PCE initiated LSPs\n")
1824 return path_pcep_cli_peer_pce_initiated(vty
);
1827 DEFPY(pcep_cli_peer_tcp_md5_auth
,
1828 pcep_cli_peer_tcp_md5_auth_cmd
,
1829 "tcp-md5-auth WORD",
1830 "Configure PCC TCP-MD5 RFC2385 Authentication\n"
1831 "TCP-MD5 Authentication string\n")
1833 return path_pcep_cli_peer_tcp_md5_auth(vty
, tcp_md5_auth
);
1836 DEFPY(pcep_cli_peer_address
,
1837 pcep_cli_peer_address_cmd
,
1838 "address <ip A.B.C.D | ipv6 X:X::X:X> [port (1024-65535)]",
1839 "PCE IP Address configuration, mandatory configuration\n"
1840 "PCE IPv4 address\n"
1841 "Remote PCE server IPv4 address\n"
1842 "PCE IPv6 address\n"
1843 "Remote PCE server IPv6 address\n"
1844 "Remote PCE server port\n"
1845 "Remote PCE server port value\n")
1847 return path_pcep_cli_peer_address(vty
, ip_str
, &ip
, ipv6_str
, &ipv6
,
1851 DEFPY(pcep_cli_peer_source_address
,
1852 pcep_cli_peer_source_address_cmd
,
1853 "source-address [ip A.B.C.D | ipv6 X:X::X:X] [port (1024-65535)]",
1854 "PCE source IP Address configuration\n"
1855 "PCE source IPv4 address\n"
1856 "PCE source IPv4 address value\n"
1857 "PCE source IPv6 address\n"
1858 "PCE source IPv6 address value\n"
1859 "Source PCE server port\n"
1860 "Source PCE server port value\n")
1862 return path_pcep_cli_peer_source_address(vty
, ip_str
, &ip
, ipv6_str
,
1863 &ipv6
, port_str
, port
);
1866 DEFPY(pcep_cli_peer_pcep_pce_config_ref
,
1867 pcep_cli_peer_pcep_pce_config_ref_cmd
,
1869 "PCE shared configuration to use\n"
1870 "Shared configuration name\n")
1872 return path_pcep_cli_peer_pcep_pce_config_ref(vty
, name
);
1875 DEFPY(pcep_cli_peer_timers
,
1876 pcep_cli_peer_timers_cmd
,
1877 "timer [keep-alive (1-63)] [min-peer-keep-alive (1-255)] [max-peer-keep-alive (1-255)] "
1878 "[dead-timer (4-255)] [min-peer-dead-timer (4-255)] [max-peer-dead-timer (4-255)] "
1879 "[pcep-request (1-120)] [session-timeout-interval (1-120)] [delegation-timeout (1-60)]",
1880 "PCE PCEP Session Timers configuration\n"
1881 "PCC Keep Alive Timer\n"
1882 "PCC Keep Alive Timer value in seconds\n"
1883 "Min Acceptable PCE Keep Alive Timer\n"
1884 "Min Acceptable PCE Keep Alive Timer value in seconds\n"
1885 "Max Acceptable PCE Keep Alive Timer\n"
1886 "Max Acceptable PCE Keep Alive Timer value in seconds\n"
1888 "PCC Dead Timer value in seconds\n"
1889 "Min Acceptable PCE Dead Timer\n"
1890 "Min Acceptable PCE Dead Timer value in seconds\n"
1891 "Max Acceptable PCE Dead Timer\n"
1892 "Max Acceptable PCE Dead Timer value in seconds\n"
1893 "PCC PCEP Request Timer\n"
1894 "PCC PCEP Request Timer value in seconds\n"
1895 "PCC Session Timeout Interval\n"
1896 "PCC Session Timeout Interval value in seconds\n"
1897 "Multi-PCE delegation timeout\n"
1898 "Multi-PCE delegation timeout value in seconds\n")
1900 return path_pcep_cli_peer_timers(
1901 vty
, keep_alive_str
, keep_alive
, min_peer_keep_alive_str
,
1902 min_peer_keep_alive
, max_peer_keep_alive_str
,
1903 max_peer_keep_alive
, dead_timer_str
, dead_timer
,
1904 min_peer_dead_timer_str
, min_peer_dead_timer
,
1905 max_peer_dead_timer_str
, max_peer_dead_timer
, pcep_request_str
,
1906 pcep_request
, session_timeout_interval_str
,
1907 session_timeout_interval
, delegation_timeout_str
,
1908 delegation_timeout
);
1915 "PCC configuration\n")
1917 return path_pcep_cli_pcc(vty
);
1920 DEFPY(pcep_cli_no_pcc
,
1921 pcep_cli_no_pcc_cmd
,
1924 "PCC configuration\n")
1926 return path_pcep_cli_pcc_delete(vty
);
1929 DEFPY(pcep_cli_pcc_pcc_msd
,
1930 pcep_cli_pcc_pcc_msd_cmd
,
1932 "PCC maximum SID depth \n"
1933 "PCC maximum SID depth value\n")
1935 return path_pcep_cli_pcc_pcc_msd(vty
, msd_str
, msd
);
1938 DEFPY(pcep_cli_pcc_pcc_peer
,
1939 pcep_cli_pcc_pcc_peer_cmd
,
1940 "[no] peer WORD [precedence (1-255)]",
1944 "PCC Multi-PCE precedence\n"
1948 return path_pcep_cli_pcc_pcc_peer_delete(
1949 vty
, peer
, precedence_str
, precedence
);
1951 return path_pcep_cli_pcc_pcc_peer(vty
, peer
, precedence_str
,
1956 DEFPY(pcep_cli_show_srte_pcc
,
1957 pcep_cli_show_srte_pcc_cmd
,
1958 "show sr-te pcep pcc",
1962 "Show current PCC configuration\n")
1964 return path_pcep_cli_show_srte_pcep_pcc(vty
);
1967 DEFPY(pcep_cli_show_srte_pcep_session
,
1968 pcep_cli_show_srte_pcep_session_cmd
,
1969 "show sr-te pcep session [WORD]$pce",
1973 "Show PCEP Session information\n"
1976 return path_pcep_cli_show_srte_pcep_session(vty
, pce
);
1979 DEFPY(pcep_cli_clear_srte_pcep_session
,
1980 pcep_cli_clear_srte_pcep_session_cmd
,
1981 "clear sr-te pcep session [WORD]$pce",
1985 "Reset PCEP connection\n"
1988 return path_pcep_cli_clear_srte_pcep_session(vty
, pce
);
1991 void pcep_cli_init(void)
1993 hook_register(pathd_srte_config_write
, pcep_cli_pcep_config_write
);
1994 hook_register(nb_client_debug_config_write
,
1995 pcep_cli_debug_config_write
);
1996 hook_register(nb_client_debug_set_all
, pcep_cli_debug_set_all
);
1998 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
2000 install_node(&pcep_node
);
2001 install_node(&pcep_pcc_node
);
2002 install_node(&pcep_pce_node
);
2003 install_node(&pcep_pce_config_node
);
2005 install_default(PCEP_PCE_CONFIG_NODE
);
2006 install_default(PCEP_PCE_NODE
);
2007 install_default(PCEP_PCC_NODE
);
2008 install_default(PCEP_NODE
);
2010 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cli_pcep_cmd
);
2012 /* PCEP configuration group related configuration commands */
2013 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
2014 install_element(PCEP_NODE
, &pcep_cli_pcep_no_pce_config_cmd
);
2015 install_element(PCEP_PCE_CONFIG_NODE
,
2016 &pcep_cli_peer_source_address_cmd
);
2017 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_timers_cmd
);
2018 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2019 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2020 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2022 /* PCE peer related configuration commands */
2023 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
2024 install_element(PCEP_NODE
, &pcep_cli_no_pce_cmd
);
2025 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_address_cmd
);
2026 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_source_address_cmd
);
2027 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pcep_pce_config_ref_cmd
);
2028 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_timers_cmd
);
2029 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2030 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2031 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2033 /* PCC related configuration commands */
2034 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcc_cmd
);
2035 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
2036 install_element(PCEP_NODE
, &pcep_cli_no_pcc_cmd
);
2037 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_peer_cmd
);
2038 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_msd_cmd
);
2041 install_element(CONFIG_NODE
, &pcep_cli_debug_cmd
);
2042 install_element(ENABLE_NODE
, &pcep_cli_debug_cmd
);
2043 install_element(ENABLE_NODE
, &show_debugging_pathd_pcep_cmd
);
2044 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_counters_cmd
);
2045 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_config_cmd
);
2046 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_cmd
);
2047 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_session_cmd
);
2048 install_element(ENABLE_NODE
, &pcep_cli_clear_srte_pcep_session_cmd
);