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 <pcep_utils_counters.h>
22 #include <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_memory.h"
37 #include "pathd/path_pcep.h"
38 #include "pathd/path_pcep_cli.h"
39 #include "pathd/path_pcep_controller.h"
40 #include "pathd/path_pcep_debug.h"
41 #include "pathd/path_pcep_lib.h"
42 #include "pathd/path_pcep_pcc.h"
44 #ifndef VTYSH_EXTRACT_PL
45 #include "pathd/path_pcep_cli_clippy.c"
48 #define DEFAULT_PCE_PRECEDENCE 255
49 #define DEFAULT_PCC_MSD 4
50 #define DEFAULT_SR_DRAFT07 false
51 #define DEFAULT_PCE_INITIATED false
52 #define DEFAULT_TIMER_KEEP_ALIVE 30
53 #define DEFAULT_TIMER_KEEP_ALIVE_MIN 1
54 #define DEFAULT_TIMER_KEEP_ALIVE_MAX 255
55 #define DEFAULT_TIMER_DEADTIMER 120
56 #define DEFAULT_TIMER_DEADTIMER_MIN 4
57 #define DEFAULT_TIMER_DEADTIMER_MAX 255
58 #define DEFAULT_TIMER_PCEP_REQUEST 30
59 #define DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL 30
60 #define DEFAULT_DELEGATION_TIMEOUT_INTERVAL 10
62 /* CLI Function declarations */
63 static int pcep_cli_debug_config_write(struct vty
*vty
);
64 static int pcep_cli_debug_set_all(uint32_t flags
, bool set
);
65 static int pcep_cli_pcep_config_write(struct vty
*vty
);
66 static int pcep_cli_pcc_config_write(struct vty
*vty
);
67 static int pcep_cli_pce_config_write(struct vty
*vty
);
68 static int pcep_cli_pcep_pce_config_write(struct vty
*vty
);
70 /* Internal Util Function declarations */
71 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
);
72 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
);
73 static struct pce_opts_cli
*pcep_cli_create_pce_opts();
74 static void pcep_cli_delete_pce(const char *pce_name
);
76 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
);
77 static struct pcep_config_group_opts
*
78 pcep_cli_find_pcep_pce_config(const char *group_name
);
80 pcep_cli_add_pcep_pce_config(struct pcep_config_group_opts
*config_group_opts
);
81 static struct pcep_config_group_opts
*
82 pcep_cli_create_pcep_pce_config(const char *group_name
);
83 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
);
84 static void pcep_cli_delete_pcep_pce_config(const char *group_name
);
85 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
86 char *buf
, size_t buf_len
);
87 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
88 pcep_configuration
*config
);
89 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
90 struct pcep_pcc_info
*pcc_info
);
91 static bool pcep_cli_pcc_has_pce(const char *pce_name
);
92 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
);
93 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
);
94 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
95 const char *peer_name
,
96 const char *precedence_str
,
103 static const char PCEP_VTYSH_ARG_ADDRESS
[] = "address";
104 static const char PCEP_VTYSH_ARG_SOURCE_ADDRESS
[] = "source-address";
105 static const char PCEP_VTYSH_ARG_IP
[] = "ip";
106 static const char PCEP_VTYSH_ARG_IPV6
[] = "ipv6";
107 static const char PCEP_VTYSH_ARG_PORT
[] = "port";
108 static const char PCEP_VTYSH_ARG_PRECEDENCE
[] = "precedence";
109 static const char PCEP_VTYSH_ARG_MSD
[] = "msd";
110 static const char PCEP_VTYSH_ARG_KEEP_ALIVE
[] = "keep-alive";
111 static const char PCEP_VTYSH_ARG_TIMER
[] = "timer";
112 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
[] = "min-peer-keep-alive";
113 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
[] = "max-peer-keep-alive";
114 static const char PCEP_VTYSH_ARG_DEAD_TIMER
[] = "dead-timer";
115 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MIN
[] = "min-peer-dead-timer";
116 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MAX
[] = "max-peer-dead-timer";
117 static const char PCEP_VTYSH_ARG_PCEP_REQUEST
[] = "pcep-request";
118 static const char PCEP_VTYSH_ARG_SESSION_TIMEOUT
[] = "session-timeout-interval";
119 static const char PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
[] = "delegation-timeout";
120 static const char PCEP_VTYSH_ARG_SR_DRAFT07
[] = "sr-draft07";
121 static const char PCEP_VTYSH_ARG_PCE_INIT
[] = "pce-initiated";
122 static const char PCEP_VTYSH_ARG_TCP_MD5
[] = "tcp-md5-auth";
123 static const char PCEP_VTYSH_ARG_BASIC
[] = "basic";
124 static const char PCEP_VTYSH_ARG_PATH
[] = "path";
125 static const char PCEP_VTYSH_ARG_MESSAGE
[] = "message";
126 static const char PCEP_VTYSH_ARG_PCEPLIB
[] = "pceplib";
127 static const char PCEP_CLI_CAP_STATEFUL
[] = " [Stateful PCE]";
128 static const char PCEP_CLI_CAP_INCL_DB_VER
[] = " [Include DB version]";
129 static const char PCEP_CLI_CAP_LSP_TRIGGERED
[] = " [LSP Triggered Resync]";
130 static const char PCEP_CLI_CAP_LSP_DELTA
[] = " [LSP Delta Sync]";
131 static const char PCEP_CLI_CAP_PCE_TRIGGERED
[] =
132 " [PCE triggered Initial Sync]";
133 static const char PCEP_CLI_CAP_SR_TE_PST
[] = " [SR TE PST]";
134 static const char PCEP_CLI_CAP_PCC_RESOLVE_NAI
[] =
135 " [PCC can resolve NAI to SID]";
136 static const char PCEP_CLI_CAP_PCC_INITIATED
[] = " [PCC Initiated LSPs]";
137 static const char PCEP_CLI_CAP_PCC_PCE_INITIATED
[] =
138 " [PCC and PCE Initiated LSPs]";
140 struct pce_connections
{
142 struct pce_opts
*connections
[MAX_PCC
];
145 struct pce_connections pce_connections_g
= {.num_connections
= 0};
147 /* Default PCE group that all PCE-Groups and PCEs will inherit from */
148 struct pcep_config_group_opts default_pcep_config_group_opts_g
= {
150 .tcp_md5_auth
= "\0",
151 .draft07
= DEFAULT_SR_DRAFT07
,
152 .pce_initiated
= DEFAULT_PCE_INITIATED
,
153 .keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE
,
154 .min_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MIN
,
155 .max_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MAX
,
156 .dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER
,
157 .min_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MIN
,
158 .max_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MAX
,
159 .pcep_request_time_seconds
= DEFAULT_TIMER_PCEP_REQUEST
,
160 .session_timeout_inteval_seconds
=
161 DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL
,
162 .delegation_timeout_seconds
= DEFAULT_DELEGATION_TIMEOUT_INTERVAL
,
163 .source_port
= DEFAULT_PCEP_TCP_PORT
,
164 .source_ip
.ipa_type
= IPADDR_NONE
,
167 /* Used by PCEP_PCE_CONFIG_NODE sub-commands to operate on the current pce group
169 struct pcep_config_group_opts
*current_pcep_config_group_opts_g
= NULL
;
170 /* Used by PCEP_PCE_NODE sub-commands to operate on the current pce opts */
171 struct pce_opts_cli
*current_pce_opts_g
= NULL
;
172 short pcc_msd_g
= DEFAULT_PCC_MSD
;
173 bool pcc_msd_configured_g
= false;
175 static struct cmd_node pcep_node
= {
178 .parent_node
= SR_TRAFFIC_ENG_NODE
,
179 .config_write
= pcep_cli_pcep_config_write
,
180 .prompt
= "%s(config-sr-te-pcep)# "
183 static struct cmd_node pcep_pcc_node
= {
184 .name
= "srte pcep pcc",
185 .node
= PCEP_PCC_NODE
,
186 .parent_node
= PCEP_NODE
,
187 .config_write
= pcep_cli_pcc_config_write
,
188 .prompt
= "%s(config-sr-te-pcep-pcc)# "
191 static struct cmd_node pcep_pce_node
= {
192 .name
= "srte pcep pce",
193 .node
= PCEP_PCE_NODE
,
194 .parent_node
= PCEP_NODE
,
195 .config_write
= pcep_cli_pce_config_write
,
196 .prompt
= "%s(config-sr-te-pcep-pce)# "
199 static struct cmd_node pcep_pce_config_node
= {
200 .name
= "srte pcep pce-config",
201 .node
= PCEP_PCE_CONFIG_NODE
,
202 .parent_node
= PCEP_NODE
,
203 .config_write
= pcep_cli_pcep_pce_config_write
,
204 .prompt
= "%s(pce-sr-te-pcep-pce-config)# "
207 /* Common code used in VTYSH processing for int values */
208 #define PCEP_VTYSH_INT_ARG_CHECK(arg_str, arg_val, arg_store, min_value, \
210 if (arg_str != NULL) { \
211 if (arg_val <= min_value || arg_val >= max_value) { \
213 "%% Invalid value %ld in range [%d - %d]", \
214 arg_val, min_value, max_value); \
215 return CMD_WARNING; \
217 arg_store = arg_val; \
220 #define MERGE_COMPARE_CONFIG_GROUP_VALUE(config_param, not_set_value) \
221 pce_opts_cli->pce_opts.config_opts.config_param = \
222 pce_opts_cli->pce_config_group_opts.config_param; \
223 if (pce_opts_cli->pce_config_group_opts.config_param \
224 == not_set_value) { \
225 pce_opts_cli->pce_opts.config_opts.config_param = \
226 ((pce_config != NULL \
227 && pce_config->config_param != not_set_value) \
228 ? pce_config->config_param \
229 : default_pcep_config_group_opts_g \
234 * Internal Util functions
237 /* Check if a pce_opts_cli already exists based on its name and return it,
238 * return NULL otherwise */
239 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
)
241 for (int i
= 0; i
< MAX_PCE
; i
++) {
242 struct pce_opts_cli
*pce_rhs_cli
= pcep_g
->pce_opts_cli
[i
];
243 if (pce_rhs_cli
!= NULL
) {
244 if (strcmp(pce_name
, pce_rhs_cli
->pce_opts
.pce_name
)
254 /* Add a new pce_opts_cli to pcep_g, return false if MAX_PCES, true otherwise */
255 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
)
257 for (int i
= 0; i
< MAX_PCE
; i
++) {
258 if (pcep_g
->pce_opts_cli
[i
] == NULL
) {
259 pcep_g
->pce_opts_cli
[i
] = pce_opts_cli
;
260 pcep_g
->num_pce_opts_cli
++;
268 /* Create a new pce opts_cli */
269 static struct pce_opts_cli
*pcep_cli_create_pce_opts(const char *name
)
271 struct pce_opts_cli
*pce_opts_cli
=
272 XCALLOC(MTYPE_PCEP
, sizeof(struct pce_opts_cli
));
273 strlcpy(pce_opts_cli
->pce_opts
.pce_name
, name
,
274 sizeof(pce_opts_cli
->pce_opts
.pce_name
));
275 pce_opts_cli
->pce_opts
.port
= PCEP_DEFAULT_PORT
;
280 static void pcep_cli_delete_pce(const char *pce_name
)
282 for (int i
= 0; i
< MAX_PCE
; i
++) {
283 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
284 if (strcmp(pcep_g
->pce_opts_cli
[i
]->pce_opts
.pce_name
,
287 XFREE(MTYPE_PCEP
, pcep_g
->pce_opts_cli
[i
]);
288 pcep_g
->pce_opts_cli
[i
] = NULL
;
289 pcep_g
->num_pce_opts_cli
--;
297 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
)
299 if (pce_opts_cli
->merged
== true) {
303 struct pcep_config_group_opts
*pce_config
=
304 pcep_cli_find_pcep_pce_config(pce_opts_cli
->config_group_name
);
306 /* Configuration priorities:
307 * 1) pce_opts->config_opts, if present, overwrite pce_config
308 * config_opts 2) pce_config config_opts, if present, overwrite
309 * default config_opts 3) If neither pce_opts->config_opts nor
310 * pce_config config_opts are set, then the default config_opts value
314 const char *tcp_md5_auth_str
=
315 pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
;
316 if (pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
[0] == '\0') {
317 if (pce_config
!= NULL
&& pce_config
->tcp_md5_auth
[0] != '\0') {
318 tcp_md5_auth_str
= pce_config
->tcp_md5_auth
;
321 default_pcep_config_group_opts_g
.tcp_md5_auth
;
324 strncpy(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
,
325 tcp_md5_auth_str
, TCP_MD5SIG_MAXKEYLEN
);
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 (%luh %lum %lus):\n", tm_buffer
,
529 diff_time
/ 3600, (diff_time
/ 60) % 60, diff_time
% 60);
532 tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
533 ttable_add_row(tt
, "Group|Name|Value");
534 tt
->style
.cell
.rpad
= 2;
535 tt
->style
.corner
= '+';
537 ttable_rowseps(tt
, 0, BOTTOM
, true, '-');
539 for (row
= 0, i
= 0; i
<= group
->num_subgroups
; i
++) {
540 subgroup
= group
->subgroups
[i
];
541 if (subgroup
!= NULL
) {
542 group_name
= subgroup
->counters_subgroup_name
;
543 for (j
= 0; j
<= subgroup
->num_counters
; j
++) {
544 counter
= subgroup
->counters
[j
];
545 if (counter
!= NULL
) {
546 ttable_add_row(tt
, "%s|%s|%u",
548 counter
->counter_name
,
549 counter
->counter_value
);
551 group_name
= empty_string
;
554 ttable_rowseps(tt
, row
, BOTTOM
, true, '-');
558 /* Dump the generated table. */
559 table
= ttable_dump(tt
, "\n");
560 vty_out(vty
, "%s\n", table
);
561 XFREE(MTYPE_TMP
, table
);
565 pcep_lib_free_counters(group
);
570 static int path_pcep_cli_pcep_pce_config(struct vty
*vty
,
571 const char *pcep_pce_config
)
573 struct pcep_config_group_opts
*pce_config
=
574 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
575 if (pce_config
== NULL
) {
576 pce_config
= pcep_cli_create_pcep_pce_config(pcep_pce_config
);
577 if (pcep_cli_add_pcep_pce_config(pce_config
) == false) {
579 "%% Cannot create pce-config, as the Maximum limit of %d pce-config has been reached.\n",
581 XFREE(MTYPE_PCEP
, pce_config
);
586 "Notice: changes to this pce-config will not affect PCEs already configured with this group\n");
589 current_pcep_config_group_opts_g
= pce_config
;
590 vty
->node
= PCEP_PCE_CONFIG_NODE
;
595 static int path_pcep_cli_pcep_pce_config_delete(struct vty
*vty
,
596 const char *pcep_pce_config
)
598 struct pcep_config_group_opts
*pce_config
=
599 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
600 if (pce_config
== NULL
) {
602 "%% Cannot delete pce-config, since it does not exist.\n");
606 if (pcep_cli_is_pcep_pce_config_used(pce_config
->name
)) {
608 "%% Cannot delete pce-config, since it is in use by a peer.\n");
612 pcep_cli_delete_pcep_pce_config(pce_config
->name
);
617 static int path_pcep_cli_show_srte_pcep_pce_config(struct vty
*vty
,
618 const char *pcep_pce_config
)
622 /* Only show 1 Peer config group */
623 struct pcep_config_group_opts
*group_opts
;
624 if (pcep_pce_config
!= NULL
) {
625 if (strcmp(pcep_pce_config
, "default") == 0) {
626 group_opts
= &default_pcep_config_group_opts_g
;
629 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
631 if (group_opts
== NULL
) {
632 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
637 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
638 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
639 vty_out(vty
, "%s", buf
);
643 /* Show all Peer config groups */
644 for (int i
= 0; i
< MAX_PCE
; i
++) {
645 group_opts
= pcep_g
->config_group_opts
[i
];
646 if (group_opts
== NULL
) {
650 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
651 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
652 vty_out(vty
, "%s", buf
);
659 static int path_pcep_cli_pce(struct vty
*vty
, const char *pce_peer_name
)
661 /* If it already exists, it will be updated in the sub-commands */
662 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
663 if (pce_opts_cli
== NULL
) {
664 pce_opts_cli
= pcep_cli_create_pce_opts(pce_peer_name
);
666 if (!pcep_cli_add_pce(pce_opts_cli
)) {
668 "%% Cannot create PCE, as the Maximum limit of %d PCEs has been reached.\n",
670 XFREE(MTYPE_PCEP
, pce_opts_cli
);
675 current_pce_opts_g
= pce_opts_cli
;
676 vty
->node
= PCEP_PCE_NODE
;
681 static int path_pcep_cli_pce_delete(struct vty
*vty
, const char *pce_peer_name
)
683 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
684 if (pce_opts_cli
== NULL
) {
685 vty_out(vty
, "%% PCC peer does not exist.\n");
689 /* To better work with frr-reload, go ahead and delete it if its in use
691 if (pcep_cli_pcc_has_pce(pce_peer_name
)) {
693 "%% Notice: the pce is in use by a PCC, also disconnecting.\n");
694 path_pcep_cli_pcc_pcc_peer_delete(vty
, pce_peer_name
, NULL
, 0);
697 pcep_cli_delete_pce(pce_peer_name
);
702 /* Internal Util func to show an individual PCE,
703 * only used by path_pcep_cli_show_srte_pcep_pce() */
704 static void show_pce_peer(struct vty
*vty
, struct pce_opts_cli
*pce_opts_cli
)
706 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
707 vty_out(vty
, "PCE: %s\n", pce_opts
->pce_name
);
709 /* Remote PCE IP address */
710 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
711 vty_out(vty
, " %s %s %pI6 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
712 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
,
713 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
715 vty_out(vty
, " %s %s %pI4 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
716 PCEP_VTYSH_ARG_IP
, &pce_opts
->addr
.ipaddr_v4
,
717 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
720 if (pce_opts_cli
->config_group_name
[0] != '\0') {
721 vty_out(vty
, " pce-config: %s\n",
722 pce_opts_cli
->config_group_name
);
726 pcep_cli_print_pce_config(&pce_opts
->config_opts
, buf
, sizeof(buf
));
727 vty_out(vty
, "%s", buf
);
730 static int path_pcep_cli_show_srte_pcep_pce(struct vty
*vty
,
731 const char *pce_peer
)
733 /* Only show 1 PCE */
734 struct pce_opts_cli
*pce_opts_cli
;
735 if (pce_peer
!= NULL
) {
736 pce_opts_cli
= pcep_cli_find_pce(pce_peer
);
737 if (pce_opts_cli
== NULL
) {
738 vty_out(vty
, "%% PCE [%s] does not exist.\n", pce_peer
);
742 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
743 show_pce_peer(vty
, pce_opts_cli
);
749 for (int i
= 0; i
< MAX_PCE
; i
++) {
750 pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
751 if (pce_opts_cli
== NULL
) {
755 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
756 show_pce_peer(vty
, pce_opts_cli
);
762 static int path_pcep_cli_peer_sr_draft07(struct vty
*vty
)
764 struct pcep_config_group_opts
*pce_config
= NULL
;
766 if (vty
->node
== PCEP_PCE_NODE
) {
767 /* TODO need to see if the pce is in use, and reset the
769 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
770 current_pce_opts_g
->merged
= false;
771 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
772 pce_config
= current_pcep_config_group_opts_g
;
774 return CMD_ERR_NO_MATCH
;
777 pce_config
->draft07
= true;
782 static int path_pcep_cli_peer_pce_initiated(struct vty
*vty
)
784 struct pcep_config_group_opts
*pce_config
= NULL
;
786 if (vty
->node
== PCEP_PCE_NODE
) {
787 /* TODO need to see if the pce is in use, and reset the
789 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
790 current_pce_opts_g
->merged
= false;
791 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
792 pce_config
= current_pcep_config_group_opts_g
;
794 return CMD_ERR_NO_MATCH
;
797 pce_config
->pce_initiated
= true;
802 static int path_pcep_cli_peer_tcp_md5_auth(struct vty
*vty
,
803 const char *tcp_md5_auth
)
805 struct pcep_config_group_opts
*pce_config
= NULL
;
807 if (vty
->node
== PCEP_PCE_NODE
) {
808 /* TODO need to see if the pce is in use, and reset the
810 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
811 current_pce_opts_g
->merged
= false;
812 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
813 pce_config
= current_pcep_config_group_opts_g
;
815 return CMD_ERR_NO_MATCH
;
818 strncpy(pce_config
->tcp_md5_auth
, tcp_md5_auth
, TCP_MD5SIG_MAXKEYLEN
);
823 static int path_pcep_cli_peer_address(struct vty
*vty
, const char *ip_str
,
824 struct in_addr
*ip
, const char *ipv6_str
,
825 struct in6_addr
*ipv6
,
826 const char *port_str
, long port
)
828 struct pce_opts
*pce_opts
= NULL
;
829 if (vty
->node
== PCEP_PCE_NODE
) {
830 /* TODO need to see if the pce is in use, and reset the
832 pce_opts
= ¤t_pce_opts_g
->pce_opts
;
833 current_pce_opts_g
->merged
= false;
835 return CMD_ERR_NO_MATCH
;
838 if (ipv6_str
!= NULL
) {
839 pce_opts
->addr
.ipa_type
= IPADDR_V6
;
840 memcpy(&pce_opts
->addr
.ipaddr_v6
, ipv6
,
841 sizeof(struct in6_addr
));
842 } else if (ip_str
!= NULL
) {
843 pce_opts
->addr
.ipa_type
= IPADDR_V4
;
844 memcpy(&pce_opts
->addr
.ipaddr_v4
, ip
, sizeof(struct in_addr
));
846 return CMD_ERR_NO_MATCH
;
849 /* Handle the optional port */
850 pce_opts
->port
= PCEP_DEFAULT_PORT
;
851 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_opts
->port
, 0, 65535);
856 static int path_pcep_cli_peer_source_address(struct vty
*vty
,
859 const char *ipv6_str
,
860 struct in6_addr
*ipv6
,
861 const char *port_str
, long port
)
863 struct pcep_config_group_opts
*pce_config
= NULL
;
864 if (vty
->node
== PCEP_PCE_NODE
) {
865 /* TODO need to see if the pce is in use, and reset the
867 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
868 current_pce_opts_g
->merged
= false;
869 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
870 pce_config
= current_pcep_config_group_opts_g
;
872 return CMD_ERR_NO_MATCH
;
875 /* Handle the optional source IP */
876 if (ipv6_str
!= NULL
) {
877 pce_config
->source_ip
.ipa_type
= IPADDR_V6
;
878 memcpy(&pce_config
->source_ip
.ipaddr_v6
, ipv6
,
879 sizeof(struct in6_addr
));
880 } else if (ip_str
!= NULL
) {
881 pce_config
->source_ip
.ipa_type
= IPADDR_V4
;
882 memcpy(&pce_config
->source_ip
.ipaddr_v4
, ip
,
883 sizeof(struct in_addr
));
886 /* Handle the optional port */
887 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_config
->source_port
, 0,
893 static int path_pcep_cli_peer_pcep_pce_config_ref(struct vty
*vty
,
894 const char *config_group_name
)
896 if (vty
->node
== PCEP_PCE_NODE
) {
897 /* TODO need to see if the pce is in use, and reset the
899 current_pce_opts_g
->merged
= false;
901 return CMD_ERR_NO_MATCH
;
904 struct pcep_config_group_opts
*pce_config
=
905 pcep_cli_find_pcep_pce_config(config_group_name
);
906 if (pce_config
== NULL
) {
907 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
912 strlcpy(current_pce_opts_g
->config_group_name
, config_group_name
,
913 sizeof(current_pce_opts_g
->config_group_name
));
918 static int path_pcep_cli_peer_timers(
919 struct vty
*vty
, const char *keep_alive_str
, long keep_alive
,
920 const char *min_peer_keep_alive_str
, long min_peer_keep_alive
,
921 const char *max_peer_keep_alive_str
, long max_peer_keep_alive
,
922 const char *dead_timer_str
, long dead_timer
,
923 const char *min_peer_dead_timer_str
, long min_peer_dead_timer
,
924 const char *max_peer_dead_timer_str
, long max_peer_dead_timer
,
925 const char *pcep_request_str
, long pcep_request
,
926 const char *session_timeout_interval_str
, long session_timeout_interval
,
927 const char *delegation_timeout_str
, long delegation_timeout
)
929 struct pcep_config_group_opts
*pce_config
= NULL
;
930 if (vty
->node
== PCEP_PCE_NODE
) {
931 /* TODO need to see if the pce is in use, and reset the
933 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
934 current_pce_opts_g
->merged
= false;
935 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
936 pce_config
= current_pcep_config_group_opts_g
;
938 return CMD_ERR_NO_MATCH
;
941 if (min_peer_keep_alive
&& max_peer_keep_alive
)
942 if (min_peer_keep_alive
>= max_peer_keep_alive
) {
943 return CMD_ERR_NO_MATCH
;
946 if (min_peer_dead_timer
&& max_peer_dead_timer
)
947 if (min_peer_dead_timer
>= max_peer_dead_timer
) {
948 return CMD_ERR_NO_MATCH
;
951 /* Handle the arguments */
952 PCEP_VTYSH_INT_ARG_CHECK(keep_alive_str
, keep_alive
,
953 pce_config
->keep_alive_seconds
, 0, 64);
954 PCEP_VTYSH_INT_ARG_CHECK(min_peer_keep_alive_str
, min_peer_keep_alive
,
955 pce_config
->min_keep_alive_seconds
, 0, 256);
956 PCEP_VTYSH_INT_ARG_CHECK(max_peer_keep_alive_str
, max_peer_keep_alive
,
957 pce_config
->max_keep_alive_seconds
, 0, 256);
958 PCEP_VTYSH_INT_ARG_CHECK(dead_timer_str
, dead_timer
,
959 pce_config
->dead_timer_seconds
, 3, 256);
960 PCEP_VTYSH_INT_ARG_CHECK(min_peer_dead_timer_str
, min_peer_dead_timer
,
961 pce_config
->min_dead_timer_seconds
, 3, 256);
962 PCEP_VTYSH_INT_ARG_CHECK(max_peer_dead_timer_str
, max_peer_dead_timer
,
963 pce_config
->max_dead_timer_seconds
, 3, 256);
964 PCEP_VTYSH_INT_ARG_CHECK(pcep_request_str
, pcep_request
,
965 pce_config
->pcep_request_time_seconds
, 0, 121);
966 PCEP_VTYSH_INT_ARG_CHECK(
967 session_timeout_interval_str
, session_timeout_interval
,
968 pce_config
->session_timeout_inteval_seconds
, 0, 121);
969 PCEP_VTYSH_INT_ARG_CHECK(delegation_timeout_str
, delegation_timeout
,
970 pce_config
->delegation_timeout_seconds
, 0, 61);
975 static int path_pcep_cli_pcc(struct vty
*vty
)
977 VTY_PUSH_CONTEXT_NULL(PCEP_PCC_NODE
);
982 static int path_pcep_cli_pcc_delete(struct vty
*vty
)
984 /* Clear the pce_connections */
985 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
986 pcc_msd_configured_g
= false;
988 pcep_ctrl_remove_pcc(pcep_g
->fpt
, NULL
);
993 static int path_pcep_cli_pcc_pcc_msd(struct vty
*vty
, const char *msd_str
,
996 pcc_msd_configured_g
= true;
997 PCEP_VTYSH_INT_ARG_CHECK(msd_str
, msd
, pcc_msd_g
, 0, 33);
1002 static int path_pcep_cli_pcc_pcc_peer(struct vty
*vty
, const char *peer_name
,
1003 const char *precedence_str
,
1006 /* Check if the pcc-peer exists */
1007 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1008 if (pce_opts_cli
== NULL
) {
1009 vty_out(vty
, "%% PCE [%s] does not exist.\n", peer_name
);
1012 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1014 /* Check if the pcc-peer is duplicated */
1015 if (pcep_cli_pcc_has_pce(peer_name
)) {
1016 vty_out(vty
, "%% The peer [%s] has already been configured.\n",
1021 /* Get the optional precedence argument */
1022 pce_opts
->precedence
= DEFAULT_PCE_PRECEDENCE
;
1023 PCEP_VTYSH_INT_ARG_CHECK(precedence_str
, precedence
,
1024 pce_opts
->precedence
, 0, 256);
1026 /* Finalize the pce_opts config values */
1027 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
1028 pcep_cli_add_pce_connection(&pce_opts_cli
->pce_opts
);
1030 /* Verify the PCE has the IP set */
1031 struct in6_addr zero_v6_addr
;
1032 memset(&zero_v6_addr
, 0, sizeof(struct in6_addr
));
1033 if (memcmp(&pce_opts
->addr
.ip
, &zero_v6_addr
, IPADDRSZ(&pce_opts
->addr
))
1036 "%% The peer [%s] does not have an IP set and cannot be used until it does.\n",
1041 /* Update the pcc_opts with the source ip, port, and msd */
1042 struct pcc_opts
*pcc_opts_copy
=
1043 XMALLOC(MTYPE_PCEP
, sizeof(struct pcc_opts
));
1044 memcpy(&pcc_opts_copy
->addr
,
1045 &pce_opts_cli
->pce_opts
.config_opts
.source_ip
,
1046 sizeof(struct pcc_opts
));
1047 pcc_opts_copy
->msd
= pcc_msd_g
;
1048 pcc_opts_copy
->port
= pce_opts_cli
->pce_opts
.config_opts
.source_port
;
1049 if (pcep_ctrl_update_pcc_options(pcep_g
->fpt
, pcc_opts_copy
)) {
1053 /* Send a copy of the pce_opts, this one is only used for the CLI */
1054 struct pce_opts
*pce_opts_copy
=
1055 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1056 memcpy(pce_opts_copy
, pce_opts
, sizeof(struct pce_opts
));
1057 if (pcep_ctrl_update_pce_options(pcep_g
->fpt
, pce_opts_copy
)) {
1064 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
1065 const char *peer_name
,
1066 const char *precedence_str
,
1069 /* Check if the pcc-peer is connected to the PCC */
1070 if (!pcep_cli_pcc_has_pce(peer_name
)) {
1072 "%% WARN: The peer [%s] is not connected to the PCC.\n",
1077 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1078 pcep_cli_remove_pce_connection(&pce_opts_cli
->pce_opts
);
1080 /* Send a copy of the pce_opts, this one is used for CLI only */
1081 struct pce_opts
*pce_opts_copy
=
1082 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1083 memcpy(pce_opts_copy
, &pce_opts_cli
->pce_opts
, sizeof(struct pce_opts
));
1084 pcep_ctrl_remove_pcc(pcep_g
->fpt
, pce_opts_copy
);
1089 static int path_pcep_cli_show_srte_pcep_pcc(struct vty
*vty
)
1091 vty_out(vty
, "pcc msd %d\n", pcc_msd_g
);
1096 /* Internal util function to print pcep capabilities to a buffer */
1097 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
1098 pcep_configuration
*config
)
1100 if (config
->support_stateful_pce_lsp_update
) {
1101 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_STATEFUL
);
1103 if (config
->support_include_db_version
) {
1104 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_INCL_DB_VER
);
1106 if (config
->support_lsp_triggered_resync
) {
1107 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_TRIGGERED
);
1109 if (config
->support_lsp_delta_sync
) {
1110 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_DELTA
);
1112 if (config
->support_pce_triggered_initial_sync
) {
1113 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCE_TRIGGERED
);
1115 if (config
->support_sr_te_pst
) {
1116 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_SR_TE_PST
);
1118 if (config
->pcc_can_resolve_nai_to_sid
) {
1119 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCC_RESOLVE_NAI
);
1123 /* Internal util function to print a pcep session */
1124 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
1125 struct pcep_pcc_info
*pcc_info
)
1130 vty_out(vty
, "\nPCE %s\n", pce_opts
->pce_name
);
1133 if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1134 vty_out(vty
, " PCE IP %pI4 port %d\n",
1135 &pce_opts
->addr
.ipaddr_v4
, pce_opts
->port
);
1136 } else if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1137 vty_out(vty
, " PCE IPv6 %pI6 port %d\n",
1138 &pce_opts
->addr
.ipaddr_v6
, pce_opts
->port
);
1142 if (IS_IPADDR_V4(&pcc_info
->pcc_addr
)) {
1143 vty_out(vty
, " PCC IP %pI4 port %d\n",
1144 &pcc_info
->pcc_addr
.ipaddr_v4
, pcc_info
->pcc_port
);
1145 } else if (IS_IPADDR_V6(&pcc_info
->pcc_addr
)) {
1146 vty_out(vty
, " PCC IPv6 %pI6 port %d\n",
1147 &pcc_info
->pcc_addr
.ipaddr_v6
, pcc_info
->pcc_port
);
1149 vty_out(vty
, " PCC MSD %d\n", pcc_info
->msd
);
1151 if (pcc_info
->status
== PCEP_PCC_OPERATING
) {
1152 vty_out(vty
, " Session Status UP\n");
1154 vty_out(vty
, " Session Status %s\n",
1155 pcc_status_name(pcc_info
->status
));
1158 if (pcc_info
->is_best_multi_pce
) {
1159 vty_out(vty
, " Precedence %d, best candidate\n",
1160 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1161 : DEFAULT_PCE_PRECEDENCE
));
1163 vty_out(vty
, " Precedence %d\n",
1164 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1165 : DEFAULT_PCE_PRECEDENCE
));
1167 vty_out(vty
, " Confidence %s\n",
1168 ((pcc_info
->previous_best
) ? "low"
1171 /* PCEPlib pcep session values, get a thread safe copy of the counters
1173 pcep_session
*session
=
1174 pcep_ctrl_get_pcep_session(pcep_g
->fpt
, pcc_info
->pcc_id
);
1176 /* Config Options values */
1177 struct pcep_config_group_opts
*config_opts
= &pce_opts
->config_opts
;
1178 if (session
!= NULL
) {
1179 vty_out(vty
, " Timer: KeepAlive config %d, pce-negotiated %d\n",
1180 config_opts
->keep_alive_seconds
,
1182 .keep_alive_pce_negotiated_timer_seconds
);
1183 vty_out(vty
, " Timer: DeadTimer config %d, pce-negotiated %d\n",
1184 config_opts
->dead_timer_seconds
,
1185 session
->pcc_config
.dead_timer_pce_negotiated_seconds
);
1187 vty_out(vty
, " Timer: KeepAlive %d\n",
1188 config_opts
->keep_alive_seconds
);
1189 vty_out(vty
, " Timer: DeadTimer %d\n",
1190 config_opts
->dead_timer_seconds
);
1192 vty_out(vty
, " Timer: PcRequest %d\n",
1193 config_opts
->pcep_request_time_seconds
);
1194 vty_out(vty
, " Timer: SessionTimeout Interval %d\n",
1195 config_opts
->session_timeout_inteval_seconds
);
1196 vty_out(vty
, " Timer: Delegation Timeout %d\n",
1197 config_opts
->delegation_timeout_seconds
);
1198 if (strlen(config_opts
->tcp_md5_auth
) > 0) {
1199 vty_out(vty
, " TCP MD5 Auth Str: %s\n",
1200 config_opts
->tcp_md5_auth
);
1202 vty_out(vty
, " No TCP MD5 Auth\n");
1205 if (config_opts
->draft07
) {
1206 vty_out(vty
, " PCE SR Version draft07\n");
1208 vty_out(vty
, " PCE SR Version draft16 and RFC8408\n");
1211 vty_out(vty
, " Next PcReq ID %d\n", pcc_info
->next_reqid
);
1212 vty_out(vty
, " Next PLSP ID %d\n", pcc_info
->next_plspid
);
1214 if (session
!= NULL
) {
1215 if (pcc_info
->status
== PCEP_PCC_SYNCHRONIZING
1216 || pcc_info
->status
== PCEP_PCC_OPERATING
) {
1217 time_t current_time
= time(NULL
);
1219 /* Just for the timezone */
1220 localtime_r(¤t_time
, <
);
1221 gmtime_r(&session
->time_connected
, <
);
1223 " Connected for %ld seconds, since %d-%02d-%02d %02d:%02d:%02d UTC\n",
1224 (current_time
- session
->time_connected
),
1225 lt
.tm_year
+ 1900, lt
.tm_mon
+ 1, lt
.tm_mday
,
1226 lt
.tm_hour
, lt
.tm_min
, lt
.tm_sec
);
1229 /* PCC capabilities */
1232 if (config_opts
->pce_initiated
) {
1233 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1234 PCEP_CLI_CAP_PCC_PCE_INITIATED
);
1236 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1237 PCEP_CLI_CAP_PCC_INITIATED
);
1239 print_pcep_capabilities(buf
, sizeof(buf
) - index
,
1240 &session
->pcc_config
);
1241 vty_out(vty
, " PCC Capabilities:%s\n", buf
);
1243 /* PCE capabilities */
1245 print_pcep_capabilities(buf
, sizeof(buf
), &session
->pce_config
);
1246 if (buf
[0] != '\0') {
1247 vty_out(vty
, " PCE Capabilities:%s\n", buf
);
1249 XFREE(MTYPE_PCEP
, session
);
1251 vty_out(vty
, " Detailed session information not available\n");
1254 /* Message Counters, get a thread safe copy of the counters */
1255 struct counters_group
*group
=
1256 pcep_ctrl_get_counters(pcep_g
->fpt
, pcc_info
->pcc_id
);
1258 if (group
!= NULL
) {
1259 struct counters_subgroup
*rx_msgs
=
1260 find_subgroup(group
, COUNTER_SUBGROUP_ID_RX_MSG
);
1261 struct counters_subgroup
*tx_msgs
=
1262 find_subgroup(group
, COUNTER_SUBGROUP_ID_TX_MSG
);
1264 if (rx_msgs
!= NULL
&& tx_msgs
!= NULL
) {
1265 vty_out(vty
, " PCEP Message Statistics\n");
1266 vty_out(vty
, " %27s %6s\n", "Sent", "Rcvd");
1267 for (int i
= 0; i
< rx_msgs
->max_counters
; i
++) {
1268 struct counter
*rx_counter
=
1269 rx_msgs
->counters
[i
];
1270 struct counter
*tx_counter
=
1271 tx_msgs
->counters
[i
];
1272 if (rx_counter
!= NULL
&& tx_counter
!= NULL
) {
1273 vty_out(vty
, " %20s: %5d %5d\n",
1274 tx_counter
->counter_name
,
1275 tx_counter
->counter_value
,
1276 rx_counter
->counter_value
);
1279 vty_out(vty
, " %20s: %5d %5d\n", "Total",
1280 subgroup_counters_total(tx_msgs
),
1281 subgroup_counters_total(rx_msgs
));
1283 pcep_lib_free_counters(group
);
1285 vty_out(vty
, " Counters not available\n");
1288 XFREE(MTYPE_PCEP
, pcc_info
);
1291 static int path_pcep_cli_show_srte_pcep_session(struct vty
*vty
,
1292 const char *pcc_peer
)
1294 struct pce_opts_cli
*pce_opts_cli
;
1295 struct pcep_pcc_info
*pcc_info
;
1297 /* Only show 1 PCEP session */
1298 if (pcc_peer
!= NULL
) {
1299 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1300 if (pce_opts_cli
== NULL
) {
1301 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1305 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1306 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1311 pcc_info
= pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pcc_peer
);
1312 if (pcc_info
== NULL
) {
1314 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1319 print_pcep_session(vty
, &pce_opts_cli
->pce_opts
, pcc_info
);
1324 /* Show all PCEP sessions */
1325 struct pce_opts
*pce_opts
;
1326 int num_pcep_sessions_conf
= 0;
1327 int num_pcep_sessions_conn
= 0;
1328 for (int i
= 0; i
< MAX_PCC
; i
++) {
1329 pce_opts
= pce_connections_g
.connections
[i
];
1330 if (pce_opts
== NULL
) {
1335 pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pce_opts
->pce_name
);
1336 if (pcc_info
== NULL
) {
1338 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1339 pce_opts
->pce_name
);
1343 num_pcep_sessions_conn
+=
1344 pcc_info
->status
== PCEP_PCC_OPERATING
? 1 : 0;
1345 num_pcep_sessions_conf
++;
1346 print_pcep_session(vty
, pce_opts
, pcc_info
);
1349 vty_out(vty
, "PCEP Sessions => Configured %d ; Connected %d\n",
1350 num_pcep_sessions_conf
, num_pcep_sessions_conn
);
1355 static int path_pcep_cli_clear_srte_pcep_session(struct vty
*vty
,
1356 const char *pcc_peer
)
1358 struct pce_opts_cli
*pce_opts_cli
;
1360 /* Only clear 1 PCEP session */
1361 if (pcc_peer
!= NULL
) {
1362 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1363 if (pce_opts_cli
== NULL
) {
1364 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1368 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1369 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1374 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
,
1375 pce_opts_cli
->pce_opts
.pce_name
);
1376 vty_out(vty
, "PCEP session cleared for peer %s\n", pcc_peer
);
1381 /* Clear all PCEP sessions */
1382 struct pce_opts
*pce_opts
;
1383 int num_pcep_sessions
= 0;
1384 for (int i
= 0; i
< MAX_PCC
; i
++) {
1385 pce_opts
= pce_connections_g
.connections
[i
];
1386 if (pce_opts
== NULL
) {
1390 num_pcep_sessions
++;
1391 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
, pce_opts
->pce_name
);
1392 vty_out(vty
, "PCEP session cleared for peer %s\n",
1393 pce_opts
->pce_name
);
1396 vty_out(vty
, "Cleared [%d] PCEP sessions\n", num_pcep_sessions
);
1402 * Config Write functions
1405 int pcep_cli_debug_config_write(struct vty
*vty
)
1407 char buff
[128] = "";
1409 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1410 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1411 csnprintfrr(buff
, sizeof(buff
), " %s",
1412 PCEP_VTYSH_ARG_BASIC
);
1413 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1414 csnprintfrr(buff
, sizeof(buff
), " %s",
1415 PCEP_VTYSH_ARG_PATH
);
1416 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1417 csnprintfrr(buff
, sizeof(buff
), " %s",
1418 PCEP_VTYSH_ARG_MESSAGE
);
1419 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1420 csnprintfrr(buff
, sizeof(buff
), " %s",
1421 PCEP_VTYSH_ARG_PCEPLIB
);
1422 vty_out(vty
, "debug pathd pcep%s\n", buff
);
1430 int pcep_cli_debug_set_all(uint32_t flags
, bool set
)
1432 DEBUG_FLAGS_SET(&pcep_g
->dbg
, flags
, set
);
1434 /* If all modes have been turned off, don't preserve options. */
1435 if (!DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_ALL
))
1436 DEBUG_CLEAR(&pcep_g
->dbg
);
1441 int pcep_cli_pcep_config_write(struct vty
*vty
)
1443 vty_out(vty
, " pcep\n");
1447 int pcep_cli_pcc_config_write(struct vty
*vty
)
1449 struct pce_opts
*pce_opts
;
1453 /* The MSD, nor any PCE peers have been configured on the PCC */
1454 if (!pcc_msd_configured_g
&& pce_connections_g
.num_connections
== 0) {
1458 vty_out(vty
, " pcc\n");
1461 /* Prepare the MSD, if present */
1462 if (pcc_msd_configured_g
) {
1463 vty_out(vty
, " %s %d\n", PCEP_VTYSH_ARG_MSD
, pcc_msd_g
);
1467 if (pce_connections_g
.num_connections
== 0) {
1472 for (int i
= 0; i
< MAX_PCC
; i
++) {
1473 pce_opts
= pce_connections_g
.connections
[i
];
1474 if (pce_opts
== NULL
) {
1478 /* Only show the PCEs configured in the pcc sub-command */
1479 if (!pcep_cli_pcc_has_pce(pce_opts
->pce_name
)) {
1483 csnprintfrr(buf
, sizeof(buf
), " peer %s",
1484 pce_opts
->pce_name
);
1485 if (pce_opts
->precedence
> 0
1486 && pce_opts
->precedence
!= DEFAULT_PCE_PRECEDENCE
) {
1487 csnprintfrr(buf
, sizeof(buf
), " %s %d",
1488 PCEP_VTYSH_ARG_PRECEDENCE
,
1489 pce_opts
->precedence
);
1491 vty_out(vty
, "%s\n", buf
);
1499 /* Internal function used by pcep_cli_pce_config_write()
1500 * and pcep_cli_pcep_pce_config_write() */
1501 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
1502 char *buf
, size_t buf_len
)
1506 if (group_opts
->source_ip
.ipa_type
!= IPADDR_NONE
1507 || group_opts
->source_port
!= 0) {
1508 csnprintfrr(buf
, buf_len
, " ");
1509 if (IS_IPADDR_V4(&group_opts
->source_ip
)) {
1510 csnprintfrr(buf
, buf_len
, " %s %s %pI4",
1511 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1513 &group_opts
->source_ip
.ipaddr_v4
);
1514 } else if (IS_IPADDR_V6(&group_opts
->source_ip
)) {
1515 csnprintfrr(buf
, buf_len
, " %s %s %pI6",
1516 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1517 PCEP_VTYSH_ARG_IPV6
,
1518 &group_opts
->source_ip
.ipaddr_v6
);
1520 if (group_opts
->source_port
> 0) {
1521 csnprintfrr(buf
, buf_len
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1522 group_opts
->source_port
);
1524 csnprintfrr(buf
, buf_len
, "\n");
1527 /* Group the keep-alive together for devman */
1528 if ((group_opts
->keep_alive_seconds
> 0)
1529 || (group_opts
->min_keep_alive_seconds
> 0)
1530 || (group_opts
->max_keep_alive_seconds
> 0)) {
1531 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1533 if (group_opts
->keep_alive_seconds
> 0) {
1534 csnprintfrr(buf
, buf_len
, " %s %d",
1535 PCEP_VTYSH_ARG_KEEP_ALIVE
,
1536 group_opts
->keep_alive_seconds
);
1538 if (group_opts
->min_keep_alive_seconds
> 0) {
1539 csnprintfrr(buf
, buf_len
, " %s %d",
1540 PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
,
1541 group_opts
->min_keep_alive_seconds
);
1543 if (group_opts
->max_keep_alive_seconds
> 0) {
1544 csnprintfrr(buf
, buf_len
, " %s %d",
1545 PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
,
1546 group_opts
->max_keep_alive_seconds
);
1548 csnprintfrr(buf
, buf_len
, "\n");
1552 /* Group the dead-timer together for devman */
1553 if ((group_opts
->dead_timer_seconds
> 0)
1554 || (group_opts
->min_dead_timer_seconds
> 0)
1555 || (group_opts
->max_dead_timer_seconds
> 0)) {
1556 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1558 if (group_opts
->dead_timer_seconds
> 0) {
1559 csnprintfrr(buf
, buf_len
, " %s %d",
1560 PCEP_VTYSH_ARG_DEAD_TIMER
,
1561 group_opts
->dead_timer_seconds
);
1563 if (group_opts
->min_dead_timer_seconds
> 0) {
1564 csnprintfrr(buf
, buf_len
, " %s %d",
1565 PCEP_VTYSH_ARG_DEAD_TIMER_MIN
,
1566 group_opts
->min_dead_timer_seconds
);
1568 if (group_opts
->max_dead_timer_seconds
> 0) {
1569 csnprintfrr(buf
, buf_len
, " %s %d",
1570 PCEP_VTYSH_ARG_DEAD_TIMER_MAX
,
1571 group_opts
->max_dead_timer_seconds
);
1573 csnprintfrr(buf
, buf_len
, "\n");
1577 if (group_opts
->pcep_request_time_seconds
> 0) {
1578 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1579 PCEP_VTYSH_ARG_TIMER
, PCEP_VTYSH_ARG_PCEP_REQUEST
,
1580 group_opts
->pcep_request_time_seconds
);
1583 if (group_opts
->delegation_timeout_seconds
> 0) {
1584 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1585 PCEP_VTYSH_ARG_TIMER
,
1586 PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
,
1587 group_opts
->delegation_timeout_seconds
);
1590 if (group_opts
->session_timeout_inteval_seconds
> 0) {
1591 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1592 PCEP_VTYSH_ARG_TIMER
,
1593 PCEP_VTYSH_ARG_SESSION_TIMEOUT
,
1594 group_opts
->session_timeout_inteval_seconds
);
1597 if (group_opts
->tcp_md5_auth
[0] != '\0') {
1598 csnprintfrr(buf
, buf_len
, " %s %s\n", PCEP_VTYSH_ARG_TCP_MD5
,
1599 group_opts
->tcp_md5_auth
);
1602 if (group_opts
->draft07
) {
1603 csnprintfrr(buf
, buf_len
, " %s\n",
1604 PCEP_VTYSH_ARG_SR_DRAFT07
);
1607 if (group_opts
->pce_initiated
) {
1608 csnprintfrr(buf
, buf_len
, " %s\n", PCEP_VTYSH_ARG_PCE_INIT
);
1615 int pcep_cli_pce_config_write(struct vty
*vty
)
1618 char buf
[1024] = "";
1620 for (int i
= 0; i
< MAX_PCE
; i
++) {
1621 struct pce_opts_cli
*pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
1622 if (pce_opts_cli
== NULL
) {
1625 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1627 vty_out(vty
, " pce %s\n", pce_opts
->pce_name
);
1628 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1629 vty_out(vty
, " %s %s %pI6", PCEP_VTYSH_ARG_ADDRESS
,
1630 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
);
1631 } else if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1632 vty_out(vty
, " address %s %pI4", PCEP_VTYSH_ARG_IP
,
1633 &pce_opts
->addr
.ipaddr_v4
);
1635 if (pce_opts
->port
!= PCEP_DEFAULT_PORT
) {
1636 vty_out(vty
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1639 vty_out(vty
, "%s\n", buf
);
1642 if (pce_opts_cli
->config_group_name
[0] != '\0') {
1643 vty_out(vty
, " config %s\n",
1644 pce_opts_cli
->config_group_name
);
1648 /* Only display the values configured on the PCE, not the values
1649 * from its optional pce-config-group, nor the default values */
1650 lines
+= pcep_cli_print_pce_config(
1651 &pce_opts_cli
->pce_config_group_opts
, buf
, sizeof(buf
));
1653 vty_out(vty
, "%s", buf
);
1660 int pcep_cli_pcep_pce_config_write(struct vty
*vty
)
1663 char buf
[1024] = "";
1665 for (int i
= 0; i
< MAX_PCE
; i
++) {
1666 struct pcep_config_group_opts
*group_opts
=
1667 pcep_g
->config_group_opts
[i
];
1668 if (group_opts
== NULL
) {
1672 vty_out(vty
, " pce-config %s\n", group_opts
->name
);
1676 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
1677 vty_out(vty
, "%s", buf
);
1685 * VTYSH command syntax definitions
1686 * The param names are taken from the path_pcep_cli_clippy.c generated file.
1689 DEFPY(show_debugging_pathd_pcep
,
1690 show_debugging_pathd_pcep_cmd
,
1691 "show debugging pathd-pcep",
1693 "State of each debugging option\n"
1694 "pathd pcep module debugging\n")
1696 vty_out(vty
, "Pathd pcep debugging status:\n");
1698 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1699 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1700 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1701 PCEP_VTYSH_ARG_BASIC
);
1702 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1703 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1704 PCEP_VTYSH_ARG_PATH
);
1705 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1706 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1707 PCEP_VTYSH_ARG_MESSAGE
);
1708 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1709 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1710 PCEP_VTYSH_ARG_PCEPLIB
);
1716 DEFPY(pcep_cli_debug
,
1718 "[no] debug pathd pcep [basic]$basic_str [path]$path_str [message]$message_str [pceplib]$pceplib_str",
1721 "pcep module debugging\n"
1722 "module basic debugging\n"
1723 "path structures debugging\n"
1724 "pcep message debugging\n"
1725 "pceplib debugging\n")
1727 return path_pcep_cli_debug(vty
, no
, basic_str
, path_str
, message_str
,
1731 DEFPY(pcep_cli_show_srte_pcep_counters
,
1732 pcep_cli_show_srte_pcep_counters_cmd
,
1733 "show sr-te pcep counters",
1739 return path_pcep_cli_show_srte_pcep_counters(vty
);
1746 "PCEP configuration\n")
1748 vty
->node
= PCEP_NODE
;
1753 pcep_cli_pcep_pce_config
,
1754 pcep_cli_pcep_pce_config_cmd
,
1755 "[no] pce-config WORD$name",
1757 "Shared configuration\n"
1758 "Shared configuration name\n")
1761 return path_pcep_cli_pcep_pce_config(vty
, name
);
1762 return path_pcep_cli_pcep_pce_config_delete(vty
, name
);
1765 DEFPY(pcep_cli_show_srte_pcep_pce_config
,
1766 pcep_cli_show_srte_pcep_pce_config_cmd
,
1767 "show sr-te pcep pce-config [<default|WORD>$name]",
1771 "Show shared PCE configuration\n"
1772 "Show default hard-coded values\n"
1773 "Shared configuration name\n")
1775 return path_pcep_cli_show_srte_pcep_pce_config(vty
, name
);
1781 "[no] pce WORD$name",
1783 "PCE configuration, address sub-config is mandatory\n"
1787 return path_pcep_cli_pce(vty
, name
);
1788 return path_pcep_cli_pce_delete(vty
, name
);
1791 DEFPY(pcep_cli_show_srte_pcep_pce
,
1792 pcep_cli_show_srte_pcep_pce_cmd
,
1793 "show sr-te pcep pce [WORD$name]",
1797 "Show detailed pce values\n"
1800 return path_pcep_cli_show_srte_pcep_pce(vty
, name
);
1803 DEFPY(pcep_cli_peer_sr_draft07
,
1804 pcep_cli_peer_sr_draft07_cmd
,
1806 "Configure PCC to send PCEP Open with SR draft07\n")
1808 return path_pcep_cli_peer_sr_draft07(vty
);
1811 DEFPY(pcep_cli_peer_pce_initiated
,
1812 pcep_cli_peer_pce_initiated_cmd
,
1814 "Configure PCC to accept PCE initiated LSPs\n")
1816 return path_pcep_cli_peer_pce_initiated(vty
);
1819 DEFPY(pcep_cli_peer_tcp_md5_auth
,
1820 pcep_cli_peer_tcp_md5_auth_cmd
,
1821 "tcp-md5-auth WORD",
1822 "Configure PCC TCP-MD5 RFC2385 Authentication\n"
1823 "TCP-MD5 Authentication string\n")
1825 return path_pcep_cli_peer_tcp_md5_auth(vty
, tcp_md5_auth
);
1828 DEFPY(pcep_cli_peer_address
,
1829 pcep_cli_peer_address_cmd
,
1830 "address <ip A.B.C.D | ipv6 X:X::X:X> [port (1024-65535)]",
1831 "PCE IP Address configuration, mandatory configuration\n"
1832 "PCE IPv4 address\n"
1833 "Remote PCE server IPv4 address\n"
1834 "PCE IPv6 address\n"
1835 "Remote PCE server IPv6 address\n"
1836 "Remote PCE server port\n"
1837 "Remote PCE server port value\n")
1839 return path_pcep_cli_peer_address(vty
, ip_str
, &ip
, ipv6_str
, &ipv6
,
1843 DEFPY(pcep_cli_peer_source_address
,
1844 pcep_cli_peer_source_address_cmd
,
1845 "source-address [ip A.B.C.D | ipv6 X:X::X:X] [port (1024-65535)]",
1846 "PCE source IP Address configuration\n"
1847 "PCE source IPv4 address\n"
1848 "PCE source IPv4 address value\n"
1849 "PCE source IPv6 address\n"
1850 "PCE source IPv6 address value\n"
1851 "Source PCE server port\n"
1852 "Source PCE server port value\n")
1854 return path_pcep_cli_peer_source_address(vty
, ip_str
, &ip
, ipv6_str
,
1855 &ipv6
, port_str
, port
);
1858 DEFPY(pcep_cli_peer_pcep_pce_config_ref
,
1859 pcep_cli_peer_pcep_pce_config_ref_cmd
,
1861 "PCE shared configuration to use\n"
1862 "Shared configuration name\n")
1864 return path_pcep_cli_peer_pcep_pce_config_ref(vty
, name
);
1867 DEFPY(pcep_cli_peer_timers
,
1868 pcep_cli_peer_timers_cmd
,
1869 "timer [keep-alive (1-63)] [min-peer-keep-alive (1-255)] [max-peer-keep-alive (1-255)] "
1870 "[dead-timer (4-255)] [min-peer-dead-timer (4-255)] [max-peer-dead-timer (4-255)] "
1871 "[pcep-request (1-120)] [session-timeout-interval (1-120)] [delegation-timeout (1-60)]",
1872 "PCE PCEP Session Timers configuration\n"
1873 "PCC Keep Alive Timer\n"
1874 "PCC Keep Alive Timer value in seconds\n"
1875 "Min Acceptable PCE Keep Alive Timer\n"
1876 "Min Acceptable PCE Keep Alive Timer value in seconds\n"
1877 "Max Acceptable PCE Keep Alive Timer\n"
1878 "Max Acceptable PCE Keep Alive Timer value in seconds\n"
1880 "PCC Dead Timer value in seconds\n"
1881 "Min Acceptable PCE Dead Timer\n"
1882 "Min Acceptable PCE Dead Timer value in seconds\n"
1883 "Max Acceptable PCE Dead Timer\n"
1884 "Max Acceptable PCE Dead Timer value in seconds\n"
1885 "PCC PCEP Request Timer\n"
1886 "PCC PCEP Request Timer value in seconds\n"
1887 "PCC Session Timeout Interval\n"
1888 "PCC Session Timeout Interval value in seconds\n"
1889 "Multi-PCE delegation timeout\n"
1890 "Multi-PCE delegation timeout value in seconds\n")
1892 return path_pcep_cli_peer_timers(
1893 vty
, keep_alive_str
, keep_alive
, min_peer_keep_alive_str
,
1894 min_peer_keep_alive
, max_peer_keep_alive_str
,
1895 max_peer_keep_alive
, dead_timer_str
, dead_timer
,
1896 min_peer_dead_timer_str
, min_peer_dead_timer
,
1897 max_peer_dead_timer_str
, max_peer_dead_timer
, pcep_request_str
,
1898 pcep_request
, session_timeout_interval_str
,
1899 session_timeout_interval
, delegation_timeout_str
,
1900 delegation_timeout
);
1908 "PCC configuration\n")
1911 return path_pcep_cli_pcc_delete(vty
);
1913 return path_pcep_cli_pcc(vty
);
1917 DEFPY(pcep_cli_pcc_pcc_msd
,
1918 pcep_cli_pcc_pcc_msd_cmd
,
1920 "PCC maximum SID depth \n"
1921 "PCC maximum SID depth value\n")
1923 return path_pcep_cli_pcc_pcc_msd(vty
, msd_str
, msd
);
1926 DEFPY(pcep_cli_pcc_pcc_peer
,
1927 pcep_cli_pcc_pcc_peer_cmd
,
1928 "[no] peer WORD [precedence (1-255)]",
1932 "PCC Multi-PCE precedence\n"
1936 return path_pcep_cli_pcc_pcc_peer_delete(
1937 vty
, peer
, precedence_str
, precedence
);
1939 return path_pcep_cli_pcc_pcc_peer(vty
, peer
, precedence_str
,
1944 DEFPY(pcep_cli_show_srte_pcc
,
1945 pcep_cli_show_srte_pcc_cmd
,
1946 "show sr-te pcep pcc",
1950 "Show current PCC configuration\n")
1952 return path_pcep_cli_show_srte_pcep_pcc(vty
);
1955 DEFPY(pcep_cli_show_srte_pcep_session
,
1956 pcep_cli_show_srte_pcep_session_cmd
,
1957 "show sr-te pcep session [WORD]$pce",
1961 "Show PCEP Session information\n"
1964 return path_pcep_cli_show_srte_pcep_session(vty
, pce
);
1967 DEFPY(pcep_cli_clear_srte_pcep_session
,
1968 pcep_cli_clear_srte_pcep_session_cmd
,
1969 "clear sr-te pcep session [WORD]$pce",
1973 "Reset PCEP connection\n"
1976 return path_pcep_cli_clear_srte_pcep_session(vty
, pce
);
1979 void pcep_cli_init(void)
1981 hook_register(nb_client_debug_config_write
,
1982 pcep_cli_debug_config_write
);
1983 hook_register(nb_client_debug_set_all
, pcep_cli_debug_set_all
);
1985 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
1987 install_node(&pcep_node
);
1988 install_node(&pcep_pcc_node
);
1989 install_node(&pcep_pce_node
);
1990 install_node(&pcep_pce_config_node
);
1992 install_default(PCEP_PCE_CONFIG_NODE
);
1993 install_default(PCEP_PCE_NODE
);
1994 install_default(PCEP_PCC_NODE
);
1995 install_default(PCEP_NODE
);
1997 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cli_pcep_cmd
);
1999 /* PCEP configuration group related configuration commands */
2000 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
2001 install_element(PCEP_PCE_CONFIG_NODE
,
2002 &pcep_cli_peer_source_address_cmd
);
2003 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_timers_cmd
);
2004 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2005 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2006 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2008 /* PCE peer related configuration commands */
2009 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
2010 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_address_cmd
);
2011 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_source_address_cmd
);
2012 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pcep_pce_config_ref_cmd
);
2013 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_timers_cmd
);
2014 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2015 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2016 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2018 /* PCC related configuration commands */
2019 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcc_cmd
);
2020 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
2021 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_peer_cmd
);
2022 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_msd_cmd
);
2025 install_element(CONFIG_NODE
, &pcep_cli_debug_cmd
);
2026 install_element(ENABLE_NODE
, &pcep_cli_debug_cmd
);
2027 install_element(ENABLE_NODE
, &show_debugging_pathd_pcep_cmd
);
2028 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_counters_cmd
);
2029 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_config_cmd
);
2030 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_cmd
);
2031 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_session_cmd
);
2032 install_element(ENABLE_NODE
, &pcep_cli_clear_srte_pcep_session_cmd
);