2 * Copyright (C) 2020 Volta Networks, Inc
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "pceplib/pcep_utils_counters.h"
22 #include "pceplib/pcep_session_logic.h"
29 #include "northbound.h"
30 #include "frr_pthread.h"
32 #include "termtable.h"
34 #include "pathd/pathd.h"
35 #include "pathd/path_errors.h"
36 #include "pathd/path_pcep.h"
37 #include "pathd/path_pcep_cli.h"
38 #include "pathd/path_pcep_controller.h"
39 #include "pathd/path_pcep_debug.h"
40 #include "pathd/path_pcep_lib.h"
41 #include "pathd/path_pcep_pcc.h"
43 #ifndef VTYSH_EXTRACT_PL
44 #include "pathd/path_pcep_cli_clippy.c"
47 #define DEFAULT_PCE_PRECEDENCE 255
48 #define DEFAULT_PCC_MSD 4
49 #define DEFAULT_SR_DRAFT07 false
50 #define DEFAULT_PCE_INITIATED false
51 #define DEFAULT_TIMER_KEEP_ALIVE 30
52 #define DEFAULT_TIMER_KEEP_ALIVE_MIN 1
53 #define DEFAULT_TIMER_KEEP_ALIVE_MAX 255
54 #define DEFAULT_TIMER_DEADTIMER 120
55 #define DEFAULT_TIMER_DEADTIMER_MIN 4
56 #define DEFAULT_TIMER_DEADTIMER_MAX 255
57 #define DEFAULT_TIMER_PCEP_REQUEST 30
58 #define DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL 30
59 #define DEFAULT_DELEGATION_TIMEOUT_INTERVAL 10
61 /* CLI Function declarations */
62 static int pcep_cli_debug_config_write(struct vty
*vty
);
63 static int pcep_cli_debug_set_all(uint32_t flags
, bool set
);
64 static int pcep_cli_pcep_config_write(struct vty
*vty
);
65 static int pcep_cli_pcc_config_write(struct vty
*vty
);
66 static int pcep_cli_pce_config_write(struct vty
*vty
);
67 static int pcep_cli_pcep_pce_config_write(struct vty
*vty
);
69 /* Internal Util Function declarations */
70 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
);
71 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
);
72 static struct pce_opts_cli
*pcep_cli_create_pce_opts();
73 static void pcep_cli_delete_pce(const char *pce_name
);
75 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
);
76 static struct pcep_config_group_opts
*
77 pcep_cli_find_pcep_pce_config(const char *group_name
);
79 pcep_cli_add_pcep_pce_config(struct pcep_config_group_opts
*config_group_opts
);
80 static struct pcep_config_group_opts
*
81 pcep_cli_create_pcep_pce_config(const char *group_name
);
82 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
);
83 static void pcep_cli_delete_pcep_pce_config(const char *group_name
);
84 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
85 char *buf
, size_t buf_len
);
86 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
87 pcep_configuration
*config
);
88 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
89 struct pcep_pcc_info
*pcc_info
);
90 static bool pcep_cli_pcc_has_pce(const char *pce_name
);
91 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
);
92 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
);
93 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
94 const char *peer_name
,
95 const char *precedence_str
,
102 static const char PCEP_VTYSH_ARG_ADDRESS
[] = "address";
103 static const char PCEP_VTYSH_ARG_SOURCE_ADDRESS
[] = "source-address";
104 static const char PCEP_VTYSH_ARG_IP
[] = "ip";
105 static const char PCEP_VTYSH_ARG_IPV6
[] = "ipv6";
106 static const char PCEP_VTYSH_ARG_PORT
[] = "port";
107 static const char PCEP_VTYSH_ARG_PRECEDENCE
[] = "precedence";
108 static const char PCEP_VTYSH_ARG_MSD
[] = "msd";
109 static const char PCEP_VTYSH_ARG_KEEP_ALIVE
[] = "keep-alive";
110 static const char PCEP_VTYSH_ARG_TIMER
[] = "timer";
111 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
[] = "min-peer-keep-alive";
112 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
[] = "max-peer-keep-alive";
113 static const char PCEP_VTYSH_ARG_DEAD_TIMER
[] = "dead-timer";
114 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MIN
[] = "min-peer-dead-timer";
115 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MAX
[] = "max-peer-dead-timer";
116 static const char PCEP_VTYSH_ARG_PCEP_REQUEST
[] = "pcep-request";
117 static const char PCEP_VTYSH_ARG_SESSION_TIMEOUT
[] = "session-timeout-interval";
118 static const char PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
[] = "delegation-timeout";
119 static const char PCEP_VTYSH_ARG_SR_DRAFT07
[] = "sr-draft07";
120 static const char PCEP_VTYSH_ARG_PCE_INIT
[] = "pce-initiated";
121 static const char PCEP_VTYSH_ARG_TCP_MD5
[] = "tcp-md5-auth";
122 static const char PCEP_VTYSH_ARG_BASIC
[] = "basic";
123 static const char PCEP_VTYSH_ARG_PATH
[] = "path";
124 static const char PCEP_VTYSH_ARG_MESSAGE
[] = "message";
125 static const char PCEP_VTYSH_ARG_PCEPLIB
[] = "pceplib";
126 static const char PCEP_CLI_CAP_STATEFUL
[] = " [Stateful PCE]";
127 static const char PCEP_CLI_CAP_INCL_DB_VER
[] = " [Include DB version]";
128 static const char PCEP_CLI_CAP_LSP_TRIGGERED
[] = " [LSP Triggered Resync]";
129 static const char PCEP_CLI_CAP_LSP_DELTA
[] = " [LSP Delta Sync]";
130 static const char PCEP_CLI_CAP_PCE_TRIGGERED
[] =
131 " [PCE triggered Initial Sync]";
132 static const char PCEP_CLI_CAP_SR_TE_PST
[] = " [SR TE PST]";
133 static const char PCEP_CLI_CAP_PCC_RESOLVE_NAI
[] =
134 " [PCC can resolve NAI to SID]";
135 static const char PCEP_CLI_CAP_PCC_INITIATED
[] = " [PCC Initiated LSPs]";
136 static const char PCEP_CLI_CAP_PCC_PCE_INITIATED
[] =
137 " [PCC and PCE Initiated LSPs]";
139 struct pce_connections
{
141 struct pce_opts
*connections
[MAX_PCC
];
144 struct pce_connections pce_connections_g
= {.num_connections
= 0};
146 /* Default PCE group that all PCE-Groups and PCEs will inherit from */
147 struct pcep_config_group_opts default_pcep_config_group_opts_g
= {
149 .tcp_md5_auth
= "\0",
150 .draft07
= DEFAULT_SR_DRAFT07
,
151 .pce_initiated
= DEFAULT_PCE_INITIATED
,
152 .keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE
,
153 .min_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MIN
,
154 .max_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MAX
,
155 .dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER
,
156 .min_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MIN
,
157 .max_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MAX
,
158 .pcep_request_time_seconds
= DEFAULT_TIMER_PCEP_REQUEST
,
159 .session_timeout_inteval_seconds
=
160 DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL
,
161 .delegation_timeout_seconds
= DEFAULT_DELEGATION_TIMEOUT_INTERVAL
,
162 .source_port
= DEFAULT_PCEP_TCP_PORT
,
163 .source_ip
.ipa_type
= IPADDR_NONE
,
166 /* Used by PCEP_PCE_CONFIG_NODE sub-commands to operate on the current pce group
168 struct pcep_config_group_opts
*current_pcep_config_group_opts_g
= NULL
;
169 /* Used by PCEP_PCE_NODE sub-commands to operate on the current pce opts */
170 struct pce_opts_cli
*current_pce_opts_g
= NULL
;
171 short pcc_msd_g
= DEFAULT_PCC_MSD
;
172 bool pcc_msd_configured_g
= false;
174 static struct cmd_node pcep_node
= {
177 .parent_node
= SR_TRAFFIC_ENG_NODE
,
178 .config_write
= pcep_cli_pcep_config_write
,
179 .prompt
= "%s(config-sr-te-pcep)# "
182 static struct cmd_node pcep_pcc_node
= {
183 .name
= "srte pcep pcc",
184 .node
= PCEP_PCC_NODE
,
185 .parent_node
= PCEP_NODE
,
186 .config_write
= pcep_cli_pcc_config_write
,
187 .prompt
= "%s(config-sr-te-pcep-pcc)# "
190 static struct cmd_node pcep_pce_node
= {
191 .name
= "srte pcep pce",
192 .node
= PCEP_PCE_NODE
,
193 .parent_node
= PCEP_NODE
,
194 .config_write
= pcep_cli_pce_config_write
,
195 .prompt
= "%s(config-sr-te-pcep-pce)# "
198 static struct cmd_node pcep_pce_config_node
= {
199 .name
= "srte pcep pce-config",
200 .node
= PCEP_PCE_CONFIG_NODE
,
201 .parent_node
= PCEP_NODE
,
202 .config_write
= pcep_cli_pcep_pce_config_write
,
203 .prompt
= "%s(pce-sr-te-pcep-pce-config)# "
206 /* Common code used in VTYSH processing for int values */
207 #define PCEP_VTYSH_INT_ARG_CHECK(arg_str, arg_val, arg_store, min_value, \
209 if (arg_str != NULL) { \
210 if (arg_val <= min_value || arg_val >= max_value) { \
212 "%% Invalid value %ld in range [%d - %d]", \
213 arg_val, min_value, max_value); \
214 return CMD_WARNING; \
216 arg_store = arg_val; \
219 #define MERGE_COMPARE_CONFIG_GROUP_VALUE(config_param, not_set_value) \
220 pce_opts_cli->pce_opts.config_opts.config_param = \
221 pce_opts_cli->pce_config_group_opts.config_param; \
222 if (pce_opts_cli->pce_config_group_opts.config_param \
223 == not_set_value) { \
224 pce_opts_cli->pce_opts.config_opts.config_param = \
225 ((pce_config != NULL \
226 && pce_config->config_param != not_set_value) \
227 ? pce_config->config_param \
228 : default_pcep_config_group_opts_g \
233 * Internal Util functions
236 /* Check if a pce_opts_cli already exists based on its name and return it,
237 * return NULL otherwise */
238 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
)
240 for (int i
= 0; i
< MAX_PCE
; i
++) {
241 struct pce_opts_cli
*pce_rhs_cli
= pcep_g
->pce_opts_cli
[i
];
242 if (pce_rhs_cli
!= NULL
) {
243 if (strcmp(pce_name
, pce_rhs_cli
->pce_opts
.pce_name
)
253 /* Add a new pce_opts_cli to pcep_g, return false if MAX_PCES, true otherwise */
254 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
)
256 for (int i
= 0; i
< MAX_PCE
; i
++) {
257 if (pcep_g
->pce_opts_cli
[i
] == NULL
) {
258 pcep_g
->pce_opts_cli
[i
] = pce_opts_cli
;
259 pcep_g
->num_pce_opts_cli
++;
267 /* Create a new pce opts_cli */
268 static struct pce_opts_cli
*pcep_cli_create_pce_opts(const char *name
)
270 struct pce_opts_cli
*pce_opts_cli
=
271 XCALLOC(MTYPE_PCEP
, sizeof(struct pce_opts_cli
));
272 strlcpy(pce_opts_cli
->pce_opts
.pce_name
, name
,
273 sizeof(pce_opts_cli
->pce_opts
.pce_name
));
274 pce_opts_cli
->pce_opts
.port
= PCEP_DEFAULT_PORT
;
279 static void pcep_cli_delete_pce(const char *pce_name
)
281 for (int i
= 0; i
< MAX_PCE
; i
++) {
282 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
283 if (strcmp(pcep_g
->pce_opts_cli
[i
]->pce_opts
.pce_name
,
286 XFREE(MTYPE_PCEP
, pcep_g
->pce_opts_cli
[i
]);
287 pcep_g
->pce_opts_cli
[i
] = NULL
;
288 pcep_g
->num_pce_opts_cli
--;
296 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
)
298 if (pce_opts_cli
->merged
== true) {
302 struct pcep_config_group_opts
*pce_config
=
303 pcep_cli_find_pcep_pce_config(pce_opts_cli
->config_group_name
);
305 /* Configuration priorities:
306 * 1) pce_opts->config_opts, if present, overwrite pce_config
307 * config_opts 2) pce_config config_opts, if present, overwrite
308 * default config_opts 3) If neither pce_opts->config_opts nor
309 * pce_config config_opts are set, then the default config_opts value
313 const char *tcp_md5_auth_str
=
314 pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
;
315 if (pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
[0] == '\0') {
316 if (pce_config
!= NULL
&& pce_config
->tcp_md5_auth
[0] != '\0') {
317 tcp_md5_auth_str
= pce_config
->tcp_md5_auth
;
320 default_pcep_config_group_opts_g
.tcp_md5_auth
;
323 strlcpy(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
,
325 sizeof(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
));
327 struct ipaddr
*source_ip
=
328 &pce_opts_cli
->pce_config_group_opts
.source_ip
;
329 if (pce_opts_cli
->pce_config_group_opts
.source_ip
.ipa_type
331 if (pce_config
!= NULL
332 && pce_config
->source_ip
.ipa_type
!= IPADDR_NONE
) {
333 source_ip
= &pce_config
->source_ip
;
335 source_ip
= &default_pcep_config_group_opts_g
.source_ip
;
338 memcpy(&pce_opts_cli
->pce_opts
.config_opts
.source_ip
, source_ip
,
339 sizeof(struct ipaddr
));
341 MERGE_COMPARE_CONFIG_GROUP_VALUE(draft07
, false);
342 MERGE_COMPARE_CONFIG_GROUP_VALUE(pce_initiated
, false);
343 MERGE_COMPARE_CONFIG_GROUP_VALUE(keep_alive_seconds
, 0);
344 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_keep_alive_seconds
, 0);
345 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_keep_alive_seconds
, 0);
346 MERGE_COMPARE_CONFIG_GROUP_VALUE(dead_timer_seconds
, 0);
347 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_dead_timer_seconds
, 0);
348 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_dead_timer_seconds
, 0);
349 MERGE_COMPARE_CONFIG_GROUP_VALUE(pcep_request_time_seconds
, 0);
350 MERGE_COMPARE_CONFIG_GROUP_VALUE(session_timeout_inteval_seconds
, 0);
351 MERGE_COMPARE_CONFIG_GROUP_VALUE(delegation_timeout_seconds
, 0);
352 MERGE_COMPARE_CONFIG_GROUP_VALUE(source_port
, 0);
354 pce_opts_cli
->merged
= true;
357 /* Check if a pcep_config_group_opts already exists based on its name and return
358 * it, return NULL otherwise */
359 static struct pcep_config_group_opts
*
360 pcep_cli_find_pcep_pce_config(const char *group_name
)
362 for (int i
= 0; i
< MAX_PCE
; i
++) {
363 struct pcep_config_group_opts
*pcep_pce_config_rhs
=
364 pcep_g
->config_group_opts
[i
];
365 if (pcep_pce_config_rhs
!= NULL
) {
366 if (strcmp(group_name
, pcep_pce_config_rhs
->name
)
368 return pcep_pce_config_rhs
;
376 /* Add a new pcep_config_group_opts to pcep_g, return false if MAX_PCE,
378 static bool pcep_cli_add_pcep_pce_config(
379 struct pcep_config_group_opts
*pcep_config_group_opts
)
381 for (int i
= 0; i
< MAX_PCE
; i
++) {
382 if (pcep_g
->config_group_opts
[i
] == NULL
) {
383 pcep_g
->config_group_opts
[i
] = pcep_config_group_opts
;
384 pcep_g
->num_config_group_opts
++;
392 /* Create a new pce group, inheriting its values from the default pce group */
393 static struct pcep_config_group_opts
*
394 pcep_cli_create_pcep_pce_config(const char *group_name
)
396 struct pcep_config_group_opts
*pcep_config_group_opts
=
397 XCALLOC(MTYPE_PCEP
, sizeof(struct pcep_config_group_opts
));
398 strlcpy(pcep_config_group_opts
->name
, group_name
,
399 sizeof(pcep_config_group_opts
->name
));
401 return pcep_config_group_opts
;
404 /* Iterate the pce_opts and return true if the pce-group-name is referenced,
405 * false otherwise. */
406 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
)
408 for (int i
= 0; i
< MAX_PCE
; i
++) {
409 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
410 if (strcmp(pcep_g
->pce_opts_cli
[i
]->config_group_name
,
421 static void pcep_cli_delete_pcep_pce_config(const char *group_name
)
423 for (int i
= 0; i
< MAX_PCE
; i
++) {
424 if (pcep_g
->config_group_opts
[i
] != NULL
) {
425 if (strcmp(pcep_g
->config_group_opts
[i
]->name
,
428 XFREE(MTYPE_PCEP
, pcep_g
->config_group_opts
[i
]);
429 pcep_g
->config_group_opts
[i
] = NULL
;
430 pcep_g
->num_config_group_opts
--;
437 static bool pcep_cli_pcc_has_pce(const char *pce_name
)
439 for (int i
= 0; i
< MAX_PCC
; i
++) {
440 struct pce_opts
*pce_opts
= pce_connections_g
.connections
[i
];
441 if (pce_opts
== NULL
) {
445 if (strcmp(pce_opts
->pce_name
, pce_name
) == 0) {
453 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
)
455 for (int i
= 0; i
< MAX_PCC
; i
++) {
456 if (pce_connections_g
.connections
[i
] == NULL
) {
457 pce_connections_g
.num_connections
++;
458 pce_connections_g
.connections
[i
] = pce_opts
;
464 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
)
466 for (int i
= 0; i
< MAX_PCC
; i
++) {
467 if (pce_connections_g
.connections
[i
] == pce_opts
) {
468 pce_connections_g
.num_connections
--;
469 pce_connections_g
.connections
[i
] = NULL
;
476 * VTY command implementations
479 static int path_pcep_cli_debug(struct vty
*vty
, const char *no_str
,
480 const char *basic_str
, const char *path_str
,
481 const char *message_str
, const char *pceplib_str
)
483 uint32_t mode
= DEBUG_NODE2MODE(vty
->node
);
484 bool no
= (no_str
!= NULL
);
486 DEBUG_MODE_SET(&pcep_g
->dbg
, mode
, !no
);
488 if (basic_str
!= NULL
) {
489 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
, !no
);
491 if (path_str
!= NULL
) {
492 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
, !no
);
494 if (message_str
!= NULL
) {
495 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
, !no
);
497 if (pceplib_str
!= NULL
) {
498 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
, !no
);
504 static int path_pcep_cli_show_srte_pcep_counters(struct vty
*vty
)
510 struct counters_group
*group
;
511 struct counters_subgroup
*subgroup
;
512 struct counter
*counter
;
513 const char *group_name
, *empty_string
= "";
517 group
= pcep_ctrl_get_counters(pcep_g
->fpt
, 1);
520 vty_out(vty
, "No counters to display.\n\n");
524 diff_time
= time(NULL
) - group
->start_time
;
525 tm_info
= localtime(&group
->start_time
);
526 strftime(tm_buffer
, sizeof(tm_buffer
), "%Y-%m-%d %H:%M:%S", tm_info
);
528 vty_out(vty
, "PCEP counters since %s (%uh %um %us):\n", tm_buffer
,
529 (uint32_t)(diff_time
/ 3600), (uint32_t)((diff_time
/ 60) % 60),
530 (uint32_t)(diff_time
% 60));
533 tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
534 ttable_add_row(tt
, "Group|Name|Value");
535 tt
->style
.cell
.rpad
= 2;
536 tt
->style
.corner
= '+';
538 ttable_rowseps(tt
, 0, BOTTOM
, true, '-');
540 for (row
= 0, i
= 0; i
<= group
->num_subgroups
; i
++) {
541 subgroup
= group
->subgroups
[i
];
542 if (subgroup
!= NULL
) {
543 group_name
= subgroup
->counters_subgroup_name
;
544 for (j
= 0; j
<= subgroup
->num_counters
; j
++) {
545 counter
= subgroup
->counters
[j
];
546 if (counter
!= NULL
) {
547 ttable_add_row(tt
, "%s|%s|%u",
549 counter
->counter_name
,
550 counter
->counter_value
);
552 group_name
= empty_string
;
555 ttable_rowseps(tt
, row
, BOTTOM
, true, '-');
559 /* Dump the generated table. */
560 table
= ttable_dump(tt
, "\n");
561 vty_out(vty
, "%s\n", table
);
562 XFREE(MTYPE_TMP
, table
);
566 pcep_lib_free_counters(group
);
571 static int path_pcep_cli_pcep_pce_config(struct vty
*vty
,
572 const char *pcep_pce_config
)
574 struct pcep_config_group_opts
*pce_config
=
575 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
576 if (pce_config
== NULL
) {
577 pce_config
= pcep_cli_create_pcep_pce_config(pcep_pce_config
);
578 if (pcep_cli_add_pcep_pce_config(pce_config
) == false) {
580 "%% Cannot create pce-config, as the Maximum limit of %d pce-config has been reached.\n",
582 XFREE(MTYPE_PCEP
, pce_config
);
587 "Notice: changes to this pce-config will not affect PCEs already configured with this group\n");
590 current_pcep_config_group_opts_g
= pce_config
;
591 vty
->node
= PCEP_PCE_CONFIG_NODE
;
596 static int path_pcep_cli_pcep_pce_config_delete(struct vty
*vty
,
597 const char *pcep_pce_config
)
599 struct pcep_config_group_opts
*pce_config
=
600 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
601 if (pce_config
== NULL
) {
603 "%% Cannot delete pce-config, since it does not exist.\n");
607 if (pcep_cli_is_pcep_pce_config_used(pce_config
->name
)) {
609 "%% Cannot delete pce-config, since it is in use by a peer.\n");
613 pcep_cli_delete_pcep_pce_config(pce_config
->name
);
618 static int path_pcep_cli_show_srte_pcep_pce_config(struct vty
*vty
,
619 const char *pcep_pce_config
)
623 /* Only show 1 Peer config group */
624 struct pcep_config_group_opts
*group_opts
;
625 if (pcep_pce_config
!= NULL
) {
626 if (strcmp(pcep_pce_config
, "default") == 0) {
627 group_opts
= &default_pcep_config_group_opts_g
;
630 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
632 if (group_opts
== NULL
) {
633 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
638 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
639 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
640 vty_out(vty
, "%s", buf
);
644 /* Show all Peer config groups */
645 for (int i
= 0; i
< MAX_PCE
; i
++) {
646 group_opts
= pcep_g
->config_group_opts
[i
];
647 if (group_opts
== NULL
) {
651 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
652 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
653 vty_out(vty
, "%s", buf
);
660 static int path_pcep_cli_pce(struct vty
*vty
, const char *pce_peer_name
)
662 /* If it already exists, it will be updated in the sub-commands */
663 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
664 if (pce_opts_cli
== NULL
) {
665 pce_opts_cli
= pcep_cli_create_pce_opts(pce_peer_name
);
667 if (!pcep_cli_add_pce(pce_opts_cli
)) {
669 "%% Cannot create PCE, as the Maximum limit of %d PCEs has been reached.\n",
671 XFREE(MTYPE_PCEP
, pce_opts_cli
);
676 current_pce_opts_g
= pce_opts_cli
;
677 vty
->node
= PCEP_PCE_NODE
;
682 static int path_pcep_cli_pce_delete(struct vty
*vty
, const char *pce_peer_name
)
684 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
685 if (pce_opts_cli
== NULL
) {
686 vty_out(vty
, "%% PCC peer does not exist.\n");
690 /* To better work with frr-reload, go ahead and delete it if its in use
692 if (pcep_cli_pcc_has_pce(pce_peer_name
)) {
694 "%% Notice: the pce is in use by a PCC, also disconnecting.\n");
695 path_pcep_cli_pcc_pcc_peer_delete(vty
, pce_peer_name
, NULL
, 0);
698 pcep_cli_delete_pce(pce_peer_name
);
703 /* Internal Util func to show an individual PCE,
704 * only used by path_pcep_cli_show_srte_pcep_pce() */
705 static void show_pce_peer(struct vty
*vty
, struct pce_opts_cli
*pce_opts_cli
)
707 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
708 vty_out(vty
, "PCE: %s\n", pce_opts
->pce_name
);
710 /* Remote PCE IP address */
711 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
712 vty_out(vty
, " %s %s %pI6 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
713 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
,
714 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
716 vty_out(vty
, " %s %s %pI4 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
717 PCEP_VTYSH_ARG_IP
, &pce_opts
->addr
.ipaddr_v4
,
718 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
721 if (pce_opts_cli
->config_group_name
[0] != '\0') {
722 vty_out(vty
, " pce-config: %s\n",
723 pce_opts_cli
->config_group_name
);
727 pcep_cli_print_pce_config(&pce_opts
->config_opts
, buf
, sizeof(buf
));
728 vty_out(vty
, "%s", buf
);
731 static int path_pcep_cli_show_srte_pcep_pce(struct vty
*vty
,
732 const char *pce_peer
)
734 /* Only show 1 PCE */
735 struct pce_opts_cli
*pce_opts_cli
;
736 if (pce_peer
!= NULL
) {
737 pce_opts_cli
= pcep_cli_find_pce(pce_peer
);
738 if (pce_opts_cli
== NULL
) {
739 vty_out(vty
, "%% PCE [%s] does not exist.\n", pce_peer
);
743 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
744 show_pce_peer(vty
, pce_opts_cli
);
750 for (int i
= 0; i
< MAX_PCE
; i
++) {
751 pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
752 if (pce_opts_cli
== NULL
) {
756 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
757 show_pce_peer(vty
, pce_opts_cli
);
763 static int path_pcep_cli_peer_sr_draft07(struct vty
*vty
)
765 struct pcep_config_group_opts
*pce_config
= NULL
;
767 if (vty
->node
== PCEP_PCE_NODE
) {
768 /* TODO need to see if the pce is in use, and reset the
770 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
771 current_pce_opts_g
->merged
= false;
772 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
773 pce_config
= current_pcep_config_group_opts_g
;
775 return CMD_ERR_NO_MATCH
;
778 pce_config
->draft07
= true;
783 static int path_pcep_cli_peer_pce_initiated(struct vty
*vty
)
785 struct pcep_config_group_opts
*pce_config
= NULL
;
787 if (vty
->node
== PCEP_PCE_NODE
) {
788 /* TODO need to see if the pce is in use, and reset the
790 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
791 current_pce_opts_g
->merged
= false;
792 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
793 pce_config
= current_pcep_config_group_opts_g
;
795 return CMD_ERR_NO_MATCH
;
798 pce_config
->pce_initiated
= true;
803 static int path_pcep_cli_peer_tcp_md5_auth(struct vty
*vty
,
804 const char *tcp_md5_auth
)
806 struct pcep_config_group_opts
*pce_config
= NULL
;
808 if (vty
->node
== PCEP_PCE_NODE
) {
809 /* TODO need to see if the pce is in use, and reset the
811 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
812 current_pce_opts_g
->merged
= false;
813 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
814 pce_config
= current_pcep_config_group_opts_g
;
816 return CMD_ERR_NO_MATCH
;
819 strlcpy(pce_config
->tcp_md5_auth
, tcp_md5_auth
,
820 sizeof(pce_config
->tcp_md5_auth
));
825 static int path_pcep_cli_peer_address(struct vty
*vty
, const char *ip_str
,
826 struct in_addr
*ip
, const char *ipv6_str
,
827 struct in6_addr
*ipv6
,
828 const char *port_str
, long port
)
830 struct pce_opts
*pce_opts
= NULL
;
831 if (vty
->node
== PCEP_PCE_NODE
) {
832 /* TODO need to see if the pce is in use, and reset the
834 pce_opts
= ¤t_pce_opts_g
->pce_opts
;
835 current_pce_opts_g
->merged
= false;
837 return CMD_ERR_NO_MATCH
;
840 if (ipv6_str
!= NULL
) {
841 pce_opts
->addr
.ipa_type
= IPADDR_V6
;
842 memcpy(&pce_opts
->addr
.ipaddr_v6
, ipv6
,
843 sizeof(struct in6_addr
));
844 } else if (ip_str
!= NULL
) {
845 pce_opts
->addr
.ipa_type
= IPADDR_V4
;
846 memcpy(&pce_opts
->addr
.ipaddr_v4
, ip
, sizeof(struct in_addr
));
848 return CMD_ERR_NO_MATCH
;
851 /* Handle the optional port */
852 pce_opts
->port
= PCEP_DEFAULT_PORT
;
853 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_opts
->port
, 0, 65535);
858 static int path_pcep_cli_peer_source_address(struct vty
*vty
,
861 const char *ipv6_str
,
862 struct in6_addr
*ipv6
,
863 const char *port_str
, long port
)
865 struct pcep_config_group_opts
*pce_config
= NULL
;
866 if (vty
->node
== PCEP_PCE_NODE
) {
867 /* TODO need to see if the pce is in use, and reset the
869 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
870 current_pce_opts_g
->merged
= false;
871 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
872 pce_config
= current_pcep_config_group_opts_g
;
874 return CMD_ERR_NO_MATCH
;
877 /* Handle the optional source IP */
878 if (ipv6_str
!= NULL
) {
879 pce_config
->source_ip
.ipa_type
= IPADDR_V6
;
880 memcpy(&pce_config
->source_ip
.ipaddr_v6
, ipv6
,
881 sizeof(struct in6_addr
));
882 } else if (ip_str
!= NULL
) {
883 pce_config
->source_ip
.ipa_type
= IPADDR_V4
;
884 memcpy(&pce_config
->source_ip
.ipaddr_v4
, ip
,
885 sizeof(struct in_addr
));
888 /* Handle the optional port */
889 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_config
->source_port
, 0,
895 static int path_pcep_cli_peer_pcep_pce_config_ref(struct vty
*vty
,
896 const char *config_group_name
)
898 if (vty
->node
== PCEP_PCE_NODE
) {
899 /* TODO need to see if the pce is in use, and reset the
901 current_pce_opts_g
->merged
= false;
903 return CMD_ERR_NO_MATCH
;
906 struct pcep_config_group_opts
*pce_config
=
907 pcep_cli_find_pcep_pce_config(config_group_name
);
908 if (pce_config
== NULL
) {
909 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
914 strlcpy(current_pce_opts_g
->config_group_name
, config_group_name
,
915 sizeof(current_pce_opts_g
->config_group_name
));
920 static int path_pcep_cli_peer_timers(
921 struct vty
*vty
, const char *keep_alive_str
, long keep_alive
,
922 const char *min_peer_keep_alive_str
, long min_peer_keep_alive
,
923 const char *max_peer_keep_alive_str
, long max_peer_keep_alive
,
924 const char *dead_timer_str
, long dead_timer
,
925 const char *min_peer_dead_timer_str
, long min_peer_dead_timer
,
926 const char *max_peer_dead_timer_str
, long max_peer_dead_timer
,
927 const char *pcep_request_str
, long pcep_request
,
928 const char *session_timeout_interval_str
, long session_timeout_interval
,
929 const char *delegation_timeout_str
, long delegation_timeout
)
931 struct pcep_config_group_opts
*pce_config
= NULL
;
932 if (vty
->node
== PCEP_PCE_NODE
) {
933 /* TODO need to see if the pce is in use, and reset the
935 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
936 current_pce_opts_g
->merged
= false;
937 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
938 pce_config
= current_pcep_config_group_opts_g
;
940 return CMD_ERR_NO_MATCH
;
943 if (min_peer_keep_alive
&& max_peer_keep_alive
)
944 if (min_peer_keep_alive
>= max_peer_keep_alive
) {
945 return CMD_ERR_NO_MATCH
;
948 if (min_peer_dead_timer
&& max_peer_dead_timer
)
949 if (min_peer_dead_timer
>= max_peer_dead_timer
) {
950 return CMD_ERR_NO_MATCH
;
953 /* Handle the arguments */
954 PCEP_VTYSH_INT_ARG_CHECK(keep_alive_str
, keep_alive
,
955 pce_config
->keep_alive_seconds
, 0, 64);
956 PCEP_VTYSH_INT_ARG_CHECK(min_peer_keep_alive_str
, min_peer_keep_alive
,
957 pce_config
->min_keep_alive_seconds
, 0, 256);
958 PCEP_VTYSH_INT_ARG_CHECK(max_peer_keep_alive_str
, max_peer_keep_alive
,
959 pce_config
->max_keep_alive_seconds
, 0, 256);
960 PCEP_VTYSH_INT_ARG_CHECK(dead_timer_str
, dead_timer
,
961 pce_config
->dead_timer_seconds
, 3, 256);
962 PCEP_VTYSH_INT_ARG_CHECK(min_peer_dead_timer_str
, min_peer_dead_timer
,
963 pce_config
->min_dead_timer_seconds
, 3, 256);
964 PCEP_VTYSH_INT_ARG_CHECK(max_peer_dead_timer_str
, max_peer_dead_timer
,
965 pce_config
->max_dead_timer_seconds
, 3, 256);
966 PCEP_VTYSH_INT_ARG_CHECK(pcep_request_str
, pcep_request
,
967 pce_config
->pcep_request_time_seconds
, 0, 121);
968 PCEP_VTYSH_INT_ARG_CHECK(
969 session_timeout_interval_str
, session_timeout_interval
,
970 pce_config
->session_timeout_inteval_seconds
, 0, 121);
971 PCEP_VTYSH_INT_ARG_CHECK(delegation_timeout_str
, delegation_timeout
,
972 pce_config
->delegation_timeout_seconds
, 0, 61);
977 static int path_pcep_cli_pcc(struct vty
*vty
)
979 VTY_PUSH_CONTEXT_NULL(PCEP_PCC_NODE
);
984 static int path_pcep_cli_pcc_delete(struct vty
*vty
)
986 /* Clear the pce_connections */
987 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
988 pcc_msd_configured_g
= false;
990 pcep_ctrl_remove_pcc(pcep_g
->fpt
, NULL
);
995 static int path_pcep_cli_pcc_pcc_msd(struct vty
*vty
, const char *msd_str
,
998 pcc_msd_configured_g
= true;
999 PCEP_VTYSH_INT_ARG_CHECK(msd_str
, msd
, pcc_msd_g
, 0, 33);
1004 static int path_pcep_cli_pcc_pcc_peer(struct vty
*vty
, const char *peer_name
,
1005 const char *precedence_str
,
1008 /* Check if the pcc-peer exists */
1009 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1010 if (pce_opts_cli
== NULL
) {
1011 vty_out(vty
, "%% PCE [%s] does not exist.\n", peer_name
);
1014 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1016 /* Check if the pcc-peer is duplicated */
1017 if (pcep_cli_pcc_has_pce(peer_name
)) {
1018 vty_out(vty
, "%% The peer [%s] has already been configured.\n",
1023 /* Get the optional precedence argument */
1024 pce_opts
->precedence
= DEFAULT_PCE_PRECEDENCE
;
1025 PCEP_VTYSH_INT_ARG_CHECK(precedence_str
, precedence
,
1026 pce_opts
->precedence
, 0, 256);
1028 /* Finalize the pce_opts config values */
1029 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
1030 pcep_cli_add_pce_connection(&pce_opts_cli
->pce_opts
);
1032 /* Verify the PCE has the IP set */
1033 struct in6_addr zero_v6_addr
;
1034 memset(&zero_v6_addr
, 0, sizeof(struct in6_addr
));
1035 if (memcmp(&pce_opts
->addr
.ip
, &zero_v6_addr
, IPADDRSZ(&pce_opts
->addr
))
1038 "%% The peer [%s] does not have an IP set and cannot be used until it does.\n",
1043 /* Update the pcc_opts with the source ip, port, and msd */
1044 struct pcc_opts
*pcc_opts_copy
=
1045 XMALLOC(MTYPE_PCEP
, sizeof(struct pcc_opts
));
1046 memcpy(&pcc_opts_copy
->addr
,
1047 &pce_opts_cli
->pce_opts
.config_opts
.source_ip
,
1048 sizeof(pcc_opts_copy
->addr
));
1049 pcc_opts_copy
->msd
= pcc_msd_g
;
1050 pcc_opts_copy
->port
= pce_opts_cli
->pce_opts
.config_opts
.source_port
;
1051 if (pcep_ctrl_update_pcc_options(pcep_g
->fpt
, pcc_opts_copy
)) {
1055 /* Send a copy of the pce_opts, this one is only used for the CLI */
1056 struct pce_opts
*pce_opts_copy
=
1057 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1058 memcpy(pce_opts_copy
, pce_opts
, sizeof(struct pce_opts
));
1059 if (pcep_ctrl_update_pce_options(pcep_g
->fpt
, pce_opts_copy
)) {
1066 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
1067 const char *peer_name
,
1068 const char *precedence_str
,
1071 /* Check if the pcc-peer is connected to the PCC */
1072 if (!pcep_cli_pcc_has_pce(peer_name
)) {
1074 "%% WARN: The peer [%s] is not connected to the PCC.\n",
1079 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1080 pcep_cli_remove_pce_connection(&pce_opts_cli
->pce_opts
);
1082 /* Send a copy of the pce_opts, this one is used for CLI only */
1083 struct pce_opts
*pce_opts_copy
=
1084 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1085 memcpy(pce_opts_copy
, &pce_opts_cli
->pce_opts
, sizeof(struct pce_opts
));
1086 pcep_ctrl_remove_pcc(pcep_g
->fpt
, pce_opts_copy
);
1091 static int path_pcep_cli_show_srte_pcep_pcc(struct vty
*vty
)
1093 vty_out(vty
, "pcc msd %d\n", pcc_msd_g
);
1098 /* Internal util function to print pcep capabilities to a buffer */
1099 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
1100 pcep_configuration
*config
)
1102 if (config
->support_stateful_pce_lsp_update
) {
1103 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_STATEFUL
);
1105 if (config
->support_include_db_version
) {
1106 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_INCL_DB_VER
);
1108 if (config
->support_lsp_triggered_resync
) {
1109 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_TRIGGERED
);
1111 if (config
->support_lsp_delta_sync
) {
1112 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_DELTA
);
1114 if (config
->support_pce_triggered_initial_sync
) {
1115 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCE_TRIGGERED
);
1117 if (config
->support_sr_te_pst
) {
1118 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_SR_TE_PST
);
1120 if (config
->pcc_can_resolve_nai_to_sid
) {
1121 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCC_RESOLVE_NAI
);
1125 /* Internal util function to print a pcep session */
1126 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
1127 struct pcep_pcc_info
*pcc_info
)
1132 vty_out(vty
, "\nPCE %s\n", pce_opts
->pce_name
);
1135 if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1136 vty_out(vty
, " PCE IP %pI4 port %d\n",
1137 &pce_opts
->addr
.ipaddr_v4
, pce_opts
->port
);
1138 } else if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1139 vty_out(vty
, " PCE IPv6 %pI6 port %d\n",
1140 &pce_opts
->addr
.ipaddr_v6
, pce_opts
->port
);
1144 if (IS_IPADDR_V4(&pcc_info
->pcc_addr
)) {
1145 vty_out(vty
, " PCC IP %pI4 port %d\n",
1146 &pcc_info
->pcc_addr
.ipaddr_v4
, pcc_info
->pcc_port
);
1147 } else if (IS_IPADDR_V6(&pcc_info
->pcc_addr
)) {
1148 vty_out(vty
, " PCC IPv6 %pI6 port %d\n",
1149 &pcc_info
->pcc_addr
.ipaddr_v6
, pcc_info
->pcc_port
);
1151 vty_out(vty
, " PCC MSD %d\n", pcc_info
->msd
);
1153 if (pcc_info
->status
== PCEP_PCC_OPERATING
) {
1154 vty_out(vty
, " Session Status UP\n");
1156 vty_out(vty
, " Session Status %s\n",
1157 pcc_status_name(pcc_info
->status
));
1160 if (pcc_info
->is_best_multi_pce
) {
1161 vty_out(vty
, " Precedence %d, best candidate\n",
1162 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1163 : DEFAULT_PCE_PRECEDENCE
));
1165 vty_out(vty
, " Precedence %d\n",
1166 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1167 : DEFAULT_PCE_PRECEDENCE
));
1169 vty_out(vty
, " Confidence %s\n",
1170 ((pcc_info
->previous_best
) ? "low"
1173 /* PCEPlib pcep session values, get a thread safe copy of the counters
1175 pcep_session
*session
=
1176 pcep_ctrl_get_pcep_session(pcep_g
->fpt
, pcc_info
->pcc_id
);
1178 /* Config Options values */
1179 struct pcep_config_group_opts
*config_opts
= &pce_opts
->config_opts
;
1180 if (session
!= NULL
) {
1181 vty_out(vty
, " Timer: KeepAlive config %d, pce-negotiated %d\n",
1182 config_opts
->keep_alive_seconds
,
1184 .keep_alive_pce_negotiated_timer_seconds
);
1185 vty_out(vty
, " Timer: DeadTimer config %d, pce-negotiated %d\n",
1186 config_opts
->dead_timer_seconds
,
1187 session
->pcc_config
.dead_timer_pce_negotiated_seconds
);
1189 vty_out(vty
, " Timer: KeepAlive %d\n",
1190 config_opts
->keep_alive_seconds
);
1191 vty_out(vty
, " Timer: DeadTimer %d\n",
1192 config_opts
->dead_timer_seconds
);
1194 vty_out(vty
, " Timer: PcRequest %d\n",
1195 config_opts
->pcep_request_time_seconds
);
1196 vty_out(vty
, " Timer: SessionTimeout Interval %d\n",
1197 config_opts
->session_timeout_inteval_seconds
);
1198 vty_out(vty
, " Timer: Delegation Timeout %d\n",
1199 config_opts
->delegation_timeout_seconds
);
1200 if (strlen(config_opts
->tcp_md5_auth
) > 0) {
1201 vty_out(vty
, " TCP MD5 Auth Str: %s\n",
1202 config_opts
->tcp_md5_auth
);
1204 vty_out(vty
, " No TCP MD5 Auth\n");
1207 if (config_opts
->draft07
) {
1208 vty_out(vty
, " PCE SR Version draft07\n");
1210 vty_out(vty
, " PCE SR Version draft16 and RFC8408\n");
1213 vty_out(vty
, " Next PcReq ID %d\n", pcc_info
->next_reqid
);
1214 vty_out(vty
, " Next PLSP ID %d\n", pcc_info
->next_plspid
);
1216 if (session
!= NULL
) {
1217 if (pcc_info
->status
== PCEP_PCC_SYNCHRONIZING
1218 || pcc_info
->status
== PCEP_PCC_OPERATING
) {
1219 time_t current_time
= time(NULL
);
1221 /* Just for the timezone */
1222 localtime_r(¤t_time
, <
);
1223 gmtime_r(&session
->time_connected
, <
);
1225 " Connected for %u seconds, since %d-%02d-%02d %02d:%02d:%02d UTC\n",
1226 (uint32_t)(current_time
1227 - session
->time_connected
),
1228 lt
.tm_year
+ 1900, lt
.tm_mon
+ 1, lt
.tm_mday
,
1229 lt
.tm_hour
, lt
.tm_min
, lt
.tm_sec
);
1232 /* PCC capabilities */
1235 if (config_opts
->pce_initiated
) {
1236 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1237 PCEP_CLI_CAP_PCC_PCE_INITIATED
);
1239 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1240 PCEP_CLI_CAP_PCC_INITIATED
);
1242 print_pcep_capabilities(buf
, sizeof(buf
) - index
,
1243 &session
->pcc_config
);
1244 vty_out(vty
, " PCC Capabilities:%s\n", buf
);
1246 /* PCE capabilities */
1248 print_pcep_capabilities(buf
, sizeof(buf
), &session
->pce_config
);
1249 if (buf
[0] != '\0') {
1250 vty_out(vty
, " PCE Capabilities:%s\n", buf
);
1252 XFREE(MTYPE_PCEP
, session
);
1254 vty_out(vty
, " Detailed session information not available\n");
1257 /* Message Counters, get a thread safe copy of the counters */
1258 struct counters_group
*group
=
1259 pcep_ctrl_get_counters(pcep_g
->fpt
, pcc_info
->pcc_id
);
1261 if (group
!= NULL
) {
1262 struct counters_subgroup
*rx_msgs
=
1263 find_subgroup(group
, COUNTER_SUBGROUP_ID_RX_MSG
);
1264 struct counters_subgroup
*tx_msgs
=
1265 find_subgroup(group
, COUNTER_SUBGROUP_ID_TX_MSG
);
1267 if (rx_msgs
!= NULL
&& tx_msgs
!= NULL
) {
1268 vty_out(vty
, " PCEP Message Statistics\n");
1269 vty_out(vty
, " %27s %6s\n", "Sent", "Rcvd");
1270 for (int i
= 0; i
< rx_msgs
->max_counters
; i
++) {
1271 struct counter
*rx_counter
=
1272 rx_msgs
->counters
[i
];
1273 struct counter
*tx_counter
=
1274 tx_msgs
->counters
[i
];
1275 if (rx_counter
!= NULL
&& tx_counter
!= NULL
) {
1276 vty_out(vty
, " %20s: %5d %5d\n",
1277 tx_counter
->counter_name
,
1278 tx_counter
->counter_value
,
1279 rx_counter
->counter_value
);
1282 vty_out(vty
, " %20s: %5d %5d\n", "Total",
1283 subgroup_counters_total(tx_msgs
),
1284 subgroup_counters_total(rx_msgs
));
1286 pcep_lib_free_counters(group
);
1288 vty_out(vty
, " Counters not available\n");
1291 XFREE(MTYPE_PCEP
, pcc_info
);
1294 static int path_pcep_cli_show_srte_pcep_session(struct vty
*vty
,
1295 const char *pcc_peer
)
1297 struct pce_opts_cli
*pce_opts_cli
;
1298 struct pcep_pcc_info
*pcc_info
;
1300 /* Only show 1 PCEP session */
1301 if (pcc_peer
!= NULL
) {
1302 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1303 if (pce_opts_cli
== NULL
) {
1304 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1308 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1309 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1314 pcc_info
= pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pcc_peer
);
1315 if (pcc_info
== NULL
) {
1317 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1322 print_pcep_session(vty
, &pce_opts_cli
->pce_opts
, pcc_info
);
1327 /* Show all PCEP sessions */
1328 struct pce_opts
*pce_opts
;
1329 int num_pcep_sessions_conf
= 0;
1330 int num_pcep_sessions_conn
= 0;
1331 for (int i
= 0; i
< MAX_PCC
; i
++) {
1332 pce_opts
= pce_connections_g
.connections
[i
];
1333 if (pce_opts
== NULL
) {
1338 pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pce_opts
->pce_name
);
1339 if (pcc_info
== NULL
) {
1341 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1342 pce_opts
->pce_name
);
1346 num_pcep_sessions_conn
+=
1347 pcc_info
->status
== PCEP_PCC_OPERATING
? 1 : 0;
1348 num_pcep_sessions_conf
++;
1349 print_pcep_session(vty
, pce_opts
, pcc_info
);
1352 vty_out(vty
, "PCEP Sessions => Configured %d ; Connected %d\n",
1353 num_pcep_sessions_conf
, num_pcep_sessions_conn
);
1358 static int path_pcep_cli_clear_srte_pcep_session(struct vty
*vty
,
1359 const char *pcc_peer
)
1361 struct pce_opts_cli
*pce_opts_cli
;
1363 /* Only clear 1 PCEP session */
1364 if (pcc_peer
!= NULL
) {
1365 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1366 if (pce_opts_cli
== NULL
) {
1367 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1371 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1372 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1377 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
,
1378 pce_opts_cli
->pce_opts
.pce_name
);
1379 vty_out(vty
, "PCEP session cleared for peer %s\n", pcc_peer
);
1384 /* Clear all PCEP sessions */
1385 struct pce_opts
*pce_opts
;
1386 int num_pcep_sessions
= 0;
1387 for (int i
= 0; i
< MAX_PCC
; i
++) {
1388 pce_opts
= pce_connections_g
.connections
[i
];
1389 if (pce_opts
== NULL
) {
1393 num_pcep_sessions
++;
1394 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
, pce_opts
->pce_name
);
1395 vty_out(vty
, "PCEP session cleared for peer %s\n",
1396 pce_opts
->pce_name
);
1399 vty_out(vty
, "Cleared [%d] PCEP sessions\n", num_pcep_sessions
);
1405 * Config Write functions
1408 int pcep_cli_debug_config_write(struct vty
*vty
)
1410 char buff
[128] = "";
1412 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1413 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1414 csnprintfrr(buff
, sizeof(buff
), " %s",
1415 PCEP_VTYSH_ARG_BASIC
);
1416 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1417 csnprintfrr(buff
, sizeof(buff
), " %s",
1418 PCEP_VTYSH_ARG_PATH
);
1419 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1420 csnprintfrr(buff
, sizeof(buff
), " %s",
1421 PCEP_VTYSH_ARG_MESSAGE
);
1422 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1423 csnprintfrr(buff
, sizeof(buff
), " %s",
1424 PCEP_VTYSH_ARG_PCEPLIB
);
1425 vty_out(vty
, "debug pathd pcep%s\n", buff
);
1433 int pcep_cli_debug_set_all(uint32_t flags
, bool set
)
1435 DEBUG_FLAGS_SET(&pcep_g
->dbg
, flags
, set
);
1437 /* If all modes have been turned off, don't preserve options. */
1438 if (!DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_ALL
))
1439 DEBUG_CLEAR(&pcep_g
->dbg
);
1444 int pcep_cli_pcep_config_write(struct vty
*vty
)
1446 vty_out(vty
, " pcep\n");
1450 int pcep_cli_pcc_config_write(struct vty
*vty
)
1452 struct pce_opts
*pce_opts
;
1456 /* The MSD, nor any PCE peers have been configured on the PCC */
1457 if (!pcc_msd_configured_g
&& pce_connections_g
.num_connections
== 0) {
1461 vty_out(vty
, " pcc\n");
1464 /* Prepare the MSD, if present */
1465 if (pcc_msd_configured_g
) {
1466 vty_out(vty
, " %s %d\n", PCEP_VTYSH_ARG_MSD
, pcc_msd_g
);
1470 if (pce_connections_g
.num_connections
== 0) {
1475 for (int i
= 0; i
< MAX_PCC
; i
++) {
1476 pce_opts
= pce_connections_g
.connections
[i
];
1477 if (pce_opts
== NULL
) {
1481 /* Only show the PCEs configured in the pcc sub-command */
1482 if (!pcep_cli_pcc_has_pce(pce_opts
->pce_name
)) {
1486 csnprintfrr(buf
, sizeof(buf
), " peer %s",
1487 pce_opts
->pce_name
);
1488 if (pce_opts
->precedence
> 0
1489 && pce_opts
->precedence
!= DEFAULT_PCE_PRECEDENCE
) {
1490 csnprintfrr(buf
, sizeof(buf
), " %s %d",
1491 PCEP_VTYSH_ARG_PRECEDENCE
,
1492 pce_opts
->precedence
);
1494 vty_out(vty
, "%s\n", buf
);
1502 /* Internal function used by pcep_cli_pce_config_write()
1503 * and pcep_cli_pcep_pce_config_write() */
1504 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
1505 char *buf
, size_t buf_len
)
1509 if (group_opts
->source_ip
.ipa_type
!= IPADDR_NONE
1510 || group_opts
->source_port
!= 0) {
1511 csnprintfrr(buf
, buf_len
, " ");
1512 if (IS_IPADDR_V4(&group_opts
->source_ip
)) {
1513 csnprintfrr(buf
, buf_len
, " %s %s %pI4",
1514 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1516 &group_opts
->source_ip
.ipaddr_v4
);
1517 } else if (IS_IPADDR_V6(&group_opts
->source_ip
)) {
1518 csnprintfrr(buf
, buf_len
, " %s %s %pI6",
1519 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1520 PCEP_VTYSH_ARG_IPV6
,
1521 &group_opts
->source_ip
.ipaddr_v6
);
1523 if (group_opts
->source_port
> 0) {
1524 csnprintfrr(buf
, buf_len
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1525 group_opts
->source_port
);
1527 csnprintfrr(buf
, buf_len
, "\n");
1530 /* Group the keep-alive together for devman */
1531 if ((group_opts
->keep_alive_seconds
> 0)
1532 || (group_opts
->min_keep_alive_seconds
> 0)
1533 || (group_opts
->max_keep_alive_seconds
> 0)) {
1534 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1536 if (group_opts
->keep_alive_seconds
> 0) {
1537 csnprintfrr(buf
, buf_len
, " %s %d",
1538 PCEP_VTYSH_ARG_KEEP_ALIVE
,
1539 group_opts
->keep_alive_seconds
);
1541 if (group_opts
->min_keep_alive_seconds
> 0) {
1542 csnprintfrr(buf
, buf_len
, " %s %d",
1543 PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
,
1544 group_opts
->min_keep_alive_seconds
);
1546 if (group_opts
->max_keep_alive_seconds
> 0) {
1547 csnprintfrr(buf
, buf_len
, " %s %d",
1548 PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
,
1549 group_opts
->max_keep_alive_seconds
);
1551 csnprintfrr(buf
, buf_len
, "\n");
1555 /* Group the dead-timer together for devman */
1556 if ((group_opts
->dead_timer_seconds
> 0)
1557 || (group_opts
->min_dead_timer_seconds
> 0)
1558 || (group_opts
->max_dead_timer_seconds
> 0)) {
1559 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1561 if (group_opts
->dead_timer_seconds
> 0) {
1562 csnprintfrr(buf
, buf_len
, " %s %d",
1563 PCEP_VTYSH_ARG_DEAD_TIMER
,
1564 group_opts
->dead_timer_seconds
);
1566 if (group_opts
->min_dead_timer_seconds
> 0) {
1567 csnprintfrr(buf
, buf_len
, " %s %d",
1568 PCEP_VTYSH_ARG_DEAD_TIMER_MIN
,
1569 group_opts
->min_dead_timer_seconds
);
1571 if (group_opts
->max_dead_timer_seconds
> 0) {
1572 csnprintfrr(buf
, buf_len
, " %s %d",
1573 PCEP_VTYSH_ARG_DEAD_TIMER_MAX
,
1574 group_opts
->max_dead_timer_seconds
);
1576 csnprintfrr(buf
, buf_len
, "\n");
1580 if (group_opts
->pcep_request_time_seconds
> 0) {
1581 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1582 PCEP_VTYSH_ARG_TIMER
, PCEP_VTYSH_ARG_PCEP_REQUEST
,
1583 group_opts
->pcep_request_time_seconds
);
1586 if (group_opts
->delegation_timeout_seconds
> 0) {
1587 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1588 PCEP_VTYSH_ARG_TIMER
,
1589 PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
,
1590 group_opts
->delegation_timeout_seconds
);
1593 if (group_opts
->session_timeout_inteval_seconds
> 0) {
1594 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1595 PCEP_VTYSH_ARG_TIMER
,
1596 PCEP_VTYSH_ARG_SESSION_TIMEOUT
,
1597 group_opts
->session_timeout_inteval_seconds
);
1600 if (group_opts
->tcp_md5_auth
[0] != '\0') {
1601 csnprintfrr(buf
, buf_len
, " %s %s\n", PCEP_VTYSH_ARG_TCP_MD5
,
1602 group_opts
->tcp_md5_auth
);
1605 if (group_opts
->draft07
) {
1606 csnprintfrr(buf
, buf_len
, " %s\n",
1607 PCEP_VTYSH_ARG_SR_DRAFT07
);
1610 if (group_opts
->pce_initiated
) {
1611 csnprintfrr(buf
, buf_len
, " %s\n", PCEP_VTYSH_ARG_PCE_INIT
);
1618 int pcep_cli_pce_config_write(struct vty
*vty
)
1621 char buf
[1024] = "";
1623 for (int i
= 0; i
< MAX_PCE
; i
++) {
1624 struct pce_opts_cli
*pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
1625 if (pce_opts_cli
== NULL
) {
1628 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1630 vty_out(vty
, " pce %s\n", pce_opts
->pce_name
);
1631 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1632 vty_out(vty
, " %s %s %pI6", PCEP_VTYSH_ARG_ADDRESS
,
1633 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
);
1634 } else if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1635 vty_out(vty
, " address %s %pI4", PCEP_VTYSH_ARG_IP
,
1636 &pce_opts
->addr
.ipaddr_v4
);
1638 if (pce_opts
->port
!= PCEP_DEFAULT_PORT
) {
1639 vty_out(vty
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1642 vty_out(vty
, "%s\n", buf
);
1645 if (pce_opts_cli
->config_group_name
[0] != '\0') {
1646 vty_out(vty
, " config %s\n",
1647 pce_opts_cli
->config_group_name
);
1651 /* Only display the values configured on the PCE, not the values
1652 * from its optional pce-config-group, nor the default values */
1653 lines
+= pcep_cli_print_pce_config(
1654 &pce_opts_cli
->pce_config_group_opts
, buf
, sizeof(buf
));
1656 vty_out(vty
, "%s", buf
);
1663 int pcep_cli_pcep_pce_config_write(struct vty
*vty
)
1666 char buf
[1024] = "";
1668 for (int i
= 0; i
< MAX_PCE
; i
++) {
1669 struct pcep_config_group_opts
*group_opts
=
1670 pcep_g
->config_group_opts
[i
];
1671 if (group_opts
== NULL
) {
1675 vty_out(vty
, " pce-config %s\n", group_opts
->name
);
1679 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
1680 vty_out(vty
, "%s", buf
);
1688 * VTYSH command syntax definitions
1689 * The param names are taken from the path_pcep_cli_clippy.c generated file.
1692 DEFPY(show_debugging_pathd_pcep
,
1693 show_debugging_pathd_pcep_cmd
,
1694 "show debugging pathd-pcep",
1696 "State of each debugging option\n"
1697 "pathd pcep module debugging\n")
1699 vty_out(vty
, "Pathd pcep debugging status:\n");
1701 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1702 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1703 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1704 PCEP_VTYSH_ARG_BASIC
);
1705 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1706 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1707 PCEP_VTYSH_ARG_PATH
);
1708 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1709 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1710 PCEP_VTYSH_ARG_MESSAGE
);
1711 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1712 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1713 PCEP_VTYSH_ARG_PCEPLIB
);
1719 DEFPY(pcep_cli_debug
,
1721 "[no] debug pathd pcep [basic]$basic_str [path]$path_str [message]$message_str [pceplib]$pceplib_str",
1724 "pcep module debugging\n"
1725 "module basic debugging\n"
1726 "path structures debugging\n"
1727 "pcep message debugging\n"
1728 "pceplib debugging\n")
1730 return path_pcep_cli_debug(vty
, no
, basic_str
, path_str
, message_str
,
1734 DEFPY(pcep_cli_show_srte_pcep_counters
,
1735 pcep_cli_show_srte_pcep_counters_cmd
,
1736 "show sr-te pcep counters",
1742 return path_pcep_cli_show_srte_pcep_counters(vty
);
1749 "PCEP configuration\n")
1751 vty
->node
= PCEP_NODE
;
1756 pcep_cli_pcep_pce_config
,
1757 pcep_cli_pcep_pce_config_cmd
,
1758 "[no] pce-config WORD$name",
1760 "Shared configuration\n"
1761 "Shared configuration name\n")
1764 return path_pcep_cli_pcep_pce_config(vty
, name
);
1765 return path_pcep_cli_pcep_pce_config_delete(vty
, name
);
1768 DEFPY(pcep_cli_show_srte_pcep_pce_config
,
1769 pcep_cli_show_srte_pcep_pce_config_cmd
,
1770 "show sr-te pcep pce-config [<default|WORD>$name]",
1774 "Show shared PCE configuration\n"
1775 "Show default hard-coded values\n"
1776 "Shared configuration name\n")
1778 return path_pcep_cli_show_srte_pcep_pce_config(vty
, name
);
1784 "[no] pce WORD$name",
1786 "PCE configuration, address sub-config is mandatory\n"
1790 return path_pcep_cli_pce(vty
, name
);
1791 return path_pcep_cli_pce_delete(vty
, name
);
1794 DEFPY(pcep_cli_show_srte_pcep_pce
,
1795 pcep_cli_show_srte_pcep_pce_cmd
,
1796 "show sr-te pcep pce [WORD$name]",
1800 "Show detailed pce values\n"
1803 return path_pcep_cli_show_srte_pcep_pce(vty
, name
);
1806 DEFPY(pcep_cli_peer_sr_draft07
,
1807 pcep_cli_peer_sr_draft07_cmd
,
1809 "Configure PCC to send PCEP Open with SR draft07\n")
1811 return path_pcep_cli_peer_sr_draft07(vty
);
1814 DEFPY(pcep_cli_peer_pce_initiated
,
1815 pcep_cli_peer_pce_initiated_cmd
,
1817 "Configure PCC to accept PCE initiated LSPs\n")
1819 return path_pcep_cli_peer_pce_initiated(vty
);
1822 DEFPY(pcep_cli_peer_tcp_md5_auth
,
1823 pcep_cli_peer_tcp_md5_auth_cmd
,
1824 "tcp-md5-auth WORD",
1825 "Configure PCC TCP-MD5 RFC2385 Authentication\n"
1826 "TCP-MD5 Authentication string\n")
1828 return path_pcep_cli_peer_tcp_md5_auth(vty
, tcp_md5_auth
);
1831 DEFPY(pcep_cli_peer_address
,
1832 pcep_cli_peer_address_cmd
,
1833 "address <ip A.B.C.D | ipv6 X:X::X:X> [port (1024-65535)]",
1834 "PCE IP Address configuration, mandatory configuration\n"
1835 "PCE IPv4 address\n"
1836 "Remote PCE server IPv4 address\n"
1837 "PCE IPv6 address\n"
1838 "Remote PCE server IPv6 address\n"
1839 "Remote PCE server port\n"
1840 "Remote PCE server port value\n")
1842 return path_pcep_cli_peer_address(vty
, ip_str
, &ip
, ipv6_str
, &ipv6
,
1846 DEFPY(pcep_cli_peer_source_address
,
1847 pcep_cli_peer_source_address_cmd
,
1848 "source-address [ip A.B.C.D | ipv6 X:X::X:X] [port (1024-65535)]",
1849 "PCE source IP Address configuration\n"
1850 "PCE source IPv4 address\n"
1851 "PCE source IPv4 address value\n"
1852 "PCE source IPv6 address\n"
1853 "PCE source IPv6 address value\n"
1854 "Source PCE server port\n"
1855 "Source PCE server port value\n")
1857 return path_pcep_cli_peer_source_address(vty
, ip_str
, &ip
, ipv6_str
,
1858 &ipv6
, port_str
, port
);
1861 DEFPY(pcep_cli_peer_pcep_pce_config_ref
,
1862 pcep_cli_peer_pcep_pce_config_ref_cmd
,
1864 "PCE shared configuration to use\n"
1865 "Shared configuration name\n")
1867 return path_pcep_cli_peer_pcep_pce_config_ref(vty
, name
);
1870 DEFPY(pcep_cli_peer_timers
,
1871 pcep_cli_peer_timers_cmd
,
1872 "timer [keep-alive (1-63)] [min-peer-keep-alive (1-255)] [max-peer-keep-alive (1-255)] "
1873 "[dead-timer (4-255)] [min-peer-dead-timer (4-255)] [max-peer-dead-timer (4-255)] "
1874 "[pcep-request (1-120)] [session-timeout-interval (1-120)] [delegation-timeout (1-60)]",
1875 "PCE PCEP Session Timers configuration\n"
1876 "PCC Keep Alive Timer\n"
1877 "PCC Keep Alive Timer value in seconds\n"
1878 "Min Acceptable PCE Keep Alive Timer\n"
1879 "Min Acceptable PCE Keep Alive Timer value in seconds\n"
1880 "Max Acceptable PCE Keep Alive Timer\n"
1881 "Max Acceptable PCE Keep Alive Timer value in seconds\n"
1883 "PCC Dead Timer value in seconds\n"
1884 "Min Acceptable PCE Dead Timer\n"
1885 "Min Acceptable PCE Dead Timer value in seconds\n"
1886 "Max Acceptable PCE Dead Timer\n"
1887 "Max Acceptable PCE Dead Timer value in seconds\n"
1888 "PCC PCEP Request Timer\n"
1889 "PCC PCEP Request Timer value in seconds\n"
1890 "PCC Session Timeout Interval\n"
1891 "PCC Session Timeout Interval value in seconds\n"
1892 "Multi-PCE delegation timeout\n"
1893 "Multi-PCE delegation timeout value in seconds\n")
1895 return path_pcep_cli_peer_timers(
1896 vty
, keep_alive_str
, keep_alive
, min_peer_keep_alive_str
,
1897 min_peer_keep_alive
, max_peer_keep_alive_str
,
1898 max_peer_keep_alive
, dead_timer_str
, dead_timer
,
1899 min_peer_dead_timer_str
, min_peer_dead_timer
,
1900 max_peer_dead_timer_str
, max_peer_dead_timer
, pcep_request_str
,
1901 pcep_request
, session_timeout_interval_str
,
1902 session_timeout_interval
, delegation_timeout_str
,
1903 delegation_timeout
);
1911 "PCC configuration\n")
1914 return path_pcep_cli_pcc_delete(vty
);
1916 return path_pcep_cli_pcc(vty
);
1920 DEFPY(pcep_cli_pcc_pcc_msd
,
1921 pcep_cli_pcc_pcc_msd_cmd
,
1923 "PCC maximum SID depth \n"
1924 "PCC maximum SID depth value\n")
1926 return path_pcep_cli_pcc_pcc_msd(vty
, msd_str
, msd
);
1929 DEFPY(pcep_cli_pcc_pcc_peer
,
1930 pcep_cli_pcc_pcc_peer_cmd
,
1931 "[no] peer WORD [precedence (1-255)]",
1935 "PCC Multi-PCE precedence\n"
1939 return path_pcep_cli_pcc_pcc_peer_delete(
1940 vty
, peer
, precedence_str
, precedence
);
1942 return path_pcep_cli_pcc_pcc_peer(vty
, peer
, precedence_str
,
1947 DEFPY(pcep_cli_show_srte_pcc
,
1948 pcep_cli_show_srte_pcc_cmd
,
1949 "show sr-te pcep pcc",
1953 "Show current PCC configuration\n")
1955 return path_pcep_cli_show_srte_pcep_pcc(vty
);
1958 DEFPY(pcep_cli_show_srte_pcep_session
,
1959 pcep_cli_show_srte_pcep_session_cmd
,
1960 "show sr-te pcep session [WORD]$pce",
1964 "Show PCEP Session information\n"
1967 return path_pcep_cli_show_srte_pcep_session(vty
, pce
);
1970 DEFPY(pcep_cli_clear_srte_pcep_session
,
1971 pcep_cli_clear_srte_pcep_session_cmd
,
1972 "clear sr-te pcep session [WORD]$pce",
1976 "Reset PCEP connection\n"
1979 return path_pcep_cli_clear_srte_pcep_session(vty
, pce
);
1982 void pcep_cli_init(void)
1984 hook_register(nb_client_debug_config_write
,
1985 pcep_cli_debug_config_write
);
1986 hook_register(nb_client_debug_set_all
, pcep_cli_debug_set_all
);
1988 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
1990 install_node(&pcep_node
);
1991 install_node(&pcep_pcc_node
);
1992 install_node(&pcep_pce_node
);
1993 install_node(&pcep_pce_config_node
);
1995 install_default(PCEP_PCE_CONFIG_NODE
);
1996 install_default(PCEP_PCE_NODE
);
1997 install_default(PCEP_PCC_NODE
);
1998 install_default(PCEP_NODE
);
2000 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cli_pcep_cmd
);
2002 /* PCEP configuration group related configuration commands */
2003 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
2004 install_element(PCEP_PCE_CONFIG_NODE
,
2005 &pcep_cli_peer_source_address_cmd
);
2006 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_timers_cmd
);
2007 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2008 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2009 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2011 /* PCE peer related configuration commands */
2012 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
2013 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_address_cmd
);
2014 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_source_address_cmd
);
2015 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pcep_pce_config_ref_cmd
);
2016 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_timers_cmd
);
2017 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2018 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2019 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2021 /* PCC related configuration commands */
2022 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcc_cmd
);
2023 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
2024 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_peer_cmd
);
2025 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_msd_cmd
);
2028 install_element(CONFIG_NODE
, &pcep_cli_debug_cmd
);
2029 install_element(ENABLE_NODE
, &pcep_cli_debug_cmd
);
2030 install_element(ENABLE_NODE
, &show_debugging_pathd_pcep_cmd
);
2031 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_counters_cmd
);
2032 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_config_cmd
);
2033 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_cmd
);
2034 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_session_cmd
);
2035 install_element(ENABLE_NODE
, &pcep_cli_clear_srte_pcep_session_cmd
);