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_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 strlcpy(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
,
326 sizeof(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
));
328 struct ipaddr
*source_ip
=
329 &pce_opts_cli
->pce_config_group_opts
.source_ip
;
330 if (pce_opts_cli
->pce_config_group_opts
.source_ip
.ipa_type
332 if (pce_config
!= NULL
333 && pce_config
->source_ip
.ipa_type
!= IPADDR_NONE
) {
334 source_ip
= &pce_config
->source_ip
;
336 source_ip
= &default_pcep_config_group_opts_g
.source_ip
;
339 memcpy(&pce_opts_cli
->pce_opts
.config_opts
.source_ip
, source_ip
,
340 sizeof(struct ipaddr
));
342 MERGE_COMPARE_CONFIG_GROUP_VALUE(draft07
, false);
343 MERGE_COMPARE_CONFIG_GROUP_VALUE(pce_initiated
, false);
344 MERGE_COMPARE_CONFIG_GROUP_VALUE(keep_alive_seconds
, 0);
345 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_keep_alive_seconds
, 0);
346 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_keep_alive_seconds
, 0);
347 MERGE_COMPARE_CONFIG_GROUP_VALUE(dead_timer_seconds
, 0);
348 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_dead_timer_seconds
, 0);
349 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_dead_timer_seconds
, 0);
350 MERGE_COMPARE_CONFIG_GROUP_VALUE(pcep_request_time_seconds
, 0);
351 MERGE_COMPARE_CONFIG_GROUP_VALUE(session_timeout_inteval_seconds
, 0);
352 MERGE_COMPARE_CONFIG_GROUP_VALUE(delegation_timeout_seconds
, 0);
353 MERGE_COMPARE_CONFIG_GROUP_VALUE(source_port
, 0);
355 pce_opts_cli
->merged
= true;
358 /* Check if a pcep_config_group_opts already exists based on its name and return
359 * it, return NULL otherwise */
360 static struct pcep_config_group_opts
*
361 pcep_cli_find_pcep_pce_config(const char *group_name
)
363 for (int i
= 0; i
< MAX_PCE
; i
++) {
364 struct pcep_config_group_opts
*pcep_pce_config_rhs
=
365 pcep_g
->config_group_opts
[i
];
366 if (pcep_pce_config_rhs
!= NULL
) {
367 if (strcmp(group_name
, pcep_pce_config_rhs
->name
)
369 return pcep_pce_config_rhs
;
377 /* Add a new pcep_config_group_opts to pcep_g, return false if MAX_PCE,
379 static bool pcep_cli_add_pcep_pce_config(
380 struct pcep_config_group_opts
*pcep_config_group_opts
)
382 for (int i
= 0; i
< MAX_PCE
; i
++) {
383 if (pcep_g
->config_group_opts
[i
] == NULL
) {
384 pcep_g
->config_group_opts
[i
] = pcep_config_group_opts
;
385 pcep_g
->num_config_group_opts
++;
393 /* Create a new pce group, inheriting its values from the default pce group */
394 static struct pcep_config_group_opts
*
395 pcep_cli_create_pcep_pce_config(const char *group_name
)
397 struct pcep_config_group_opts
*pcep_config_group_opts
=
398 XCALLOC(MTYPE_PCEP
, sizeof(struct pcep_config_group_opts
));
399 strlcpy(pcep_config_group_opts
->name
, group_name
,
400 sizeof(pcep_config_group_opts
->name
));
402 return pcep_config_group_opts
;
405 /* Iterate the pce_opts and return true if the pce-group-name is referenced,
406 * false otherwise. */
407 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
)
409 for (int i
= 0; i
< MAX_PCE
; i
++) {
410 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
411 if (strcmp(pcep_g
->pce_opts_cli
[i
]->config_group_name
,
422 static void pcep_cli_delete_pcep_pce_config(const char *group_name
)
424 for (int i
= 0; i
< MAX_PCE
; i
++) {
425 if (pcep_g
->config_group_opts
[i
] != NULL
) {
426 if (strcmp(pcep_g
->config_group_opts
[i
]->name
,
429 XFREE(MTYPE_PCEP
, pcep_g
->config_group_opts
[i
]);
430 pcep_g
->config_group_opts
[i
] = NULL
;
431 pcep_g
->num_config_group_opts
--;
438 static bool pcep_cli_pcc_has_pce(const char *pce_name
)
440 for (int i
= 0; i
< MAX_PCC
; i
++) {
441 struct pce_opts
*pce_opts
= pce_connections_g
.connections
[i
];
442 if (pce_opts
== NULL
) {
446 if (strcmp(pce_opts
->pce_name
, pce_name
) == 0) {
454 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
)
456 for (int i
= 0; i
< MAX_PCC
; i
++) {
457 if (pce_connections_g
.connections
[i
] == NULL
) {
458 pce_connections_g
.num_connections
++;
459 pce_connections_g
.connections
[i
] = pce_opts
;
465 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
)
467 for (int i
= 0; i
< MAX_PCC
; i
++) {
468 if (pce_connections_g
.connections
[i
] == pce_opts
) {
469 pce_connections_g
.num_connections
--;
470 pce_connections_g
.connections
[i
] = NULL
;
477 * VTY command implementations
480 static int path_pcep_cli_debug(struct vty
*vty
, const char *no_str
,
481 const char *basic_str
, const char *path_str
,
482 const char *message_str
, const char *pceplib_str
)
484 uint32_t mode
= DEBUG_NODE2MODE(vty
->node
);
485 bool no
= (no_str
!= NULL
);
487 DEBUG_MODE_SET(&pcep_g
->dbg
, mode
, !no
);
489 if (basic_str
!= NULL
) {
490 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
, !no
);
492 if (path_str
!= NULL
) {
493 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
, !no
);
495 if (message_str
!= NULL
) {
496 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
, !no
);
498 if (pceplib_str
!= NULL
) {
499 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
, !no
);
505 static int path_pcep_cli_show_srte_pcep_counters(struct vty
*vty
)
511 struct counters_group
*group
;
512 struct counters_subgroup
*subgroup
;
513 struct counter
*counter
;
514 const char *group_name
, *empty_string
= "";
518 group
= pcep_ctrl_get_counters(pcep_g
->fpt
, 1);
521 vty_out(vty
, "No counters to display.\n\n");
525 diff_time
= time(NULL
) - group
->start_time
;
526 tm_info
= localtime(&group
->start_time
);
527 strftime(tm_buffer
, sizeof(tm_buffer
), "%Y-%m-%d %H:%M:%S", tm_info
);
529 vty_out(vty
, "PCEP counters since %s (%uh %um %us):\n", tm_buffer
,
530 (uint32_t)(diff_time
/ 3600), (uint32_t)((diff_time
/ 60) % 60),
531 (uint32_t)(diff_time
% 60));
534 tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
535 ttable_add_row(tt
, "Group|Name|Value");
536 tt
->style
.cell
.rpad
= 2;
537 tt
->style
.corner
= '+';
539 ttable_rowseps(tt
, 0, BOTTOM
, true, '-');
541 for (row
= 0, i
= 0; i
<= group
->num_subgroups
; i
++) {
542 subgroup
= group
->subgroups
[i
];
543 if (subgroup
!= NULL
) {
544 group_name
= subgroup
->counters_subgroup_name
;
545 for (j
= 0; j
<= subgroup
->num_counters
; j
++) {
546 counter
= subgroup
->counters
[j
];
547 if (counter
!= NULL
) {
548 ttable_add_row(tt
, "%s|%s|%u",
550 counter
->counter_name
,
551 counter
->counter_value
);
553 group_name
= empty_string
;
556 ttable_rowseps(tt
, row
, BOTTOM
, true, '-');
560 /* Dump the generated table. */
561 table
= ttable_dump(tt
, "\n");
562 vty_out(vty
, "%s\n", table
);
563 XFREE(MTYPE_TMP
, table
);
567 pcep_lib_free_counters(group
);
572 static int path_pcep_cli_pcep_pce_config(struct vty
*vty
,
573 const char *pcep_pce_config
)
575 struct pcep_config_group_opts
*pce_config
=
576 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
577 if (pce_config
== NULL
) {
578 pce_config
= pcep_cli_create_pcep_pce_config(pcep_pce_config
);
579 if (pcep_cli_add_pcep_pce_config(pce_config
) == false) {
581 "%% Cannot create pce-config, as the Maximum limit of %d pce-config has been reached.\n",
583 XFREE(MTYPE_PCEP
, pce_config
);
588 "Notice: changes to this pce-config will not affect PCEs already configured with this group\n");
591 current_pcep_config_group_opts_g
= pce_config
;
592 vty
->node
= PCEP_PCE_CONFIG_NODE
;
597 static int path_pcep_cli_pcep_pce_config_delete(struct vty
*vty
,
598 const char *pcep_pce_config
)
600 struct pcep_config_group_opts
*pce_config
=
601 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
602 if (pce_config
== NULL
) {
604 "%% Cannot delete pce-config, since it does not exist.\n");
608 if (pcep_cli_is_pcep_pce_config_used(pce_config
->name
)) {
610 "%% Cannot delete pce-config, since it is in use by a peer.\n");
614 pcep_cli_delete_pcep_pce_config(pce_config
->name
);
619 static int path_pcep_cli_show_srte_pcep_pce_config(struct vty
*vty
,
620 const char *pcep_pce_config
)
624 /* Only show 1 Peer config group */
625 struct pcep_config_group_opts
*group_opts
;
626 if (pcep_pce_config
!= NULL
) {
627 if (strcmp(pcep_pce_config
, "default") == 0) {
628 group_opts
= &default_pcep_config_group_opts_g
;
631 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
633 if (group_opts
== NULL
) {
634 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
639 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
640 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
641 vty_out(vty
, "%s", buf
);
645 /* Show all Peer config groups */
646 for (int i
= 0; i
< MAX_PCE
; i
++) {
647 group_opts
= pcep_g
->config_group_opts
[i
];
648 if (group_opts
== NULL
) {
652 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
653 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
654 vty_out(vty
, "%s", buf
);
661 static int path_pcep_cli_pce(struct vty
*vty
, const char *pce_peer_name
)
663 /* If it already exists, it will be updated in the sub-commands */
664 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
665 if (pce_opts_cli
== NULL
) {
666 pce_opts_cli
= pcep_cli_create_pce_opts(pce_peer_name
);
668 if (!pcep_cli_add_pce(pce_opts_cli
)) {
670 "%% Cannot create PCE, as the Maximum limit of %d PCEs has been reached.\n",
672 XFREE(MTYPE_PCEP
, pce_opts_cli
);
677 current_pce_opts_g
= pce_opts_cli
;
678 vty
->node
= PCEP_PCE_NODE
;
683 static int path_pcep_cli_pce_delete(struct vty
*vty
, const char *pce_peer_name
)
685 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
686 if (pce_opts_cli
== NULL
) {
687 vty_out(vty
, "%% PCC peer does not exist.\n");
691 /* To better work with frr-reload, go ahead and delete it if its in use
693 if (pcep_cli_pcc_has_pce(pce_peer_name
)) {
695 "%% Notice: the pce is in use by a PCC, also disconnecting.\n");
696 path_pcep_cli_pcc_pcc_peer_delete(vty
, pce_peer_name
, NULL
, 0);
699 pcep_cli_delete_pce(pce_peer_name
);
704 /* Internal Util func to show an individual PCE,
705 * only used by path_pcep_cli_show_srte_pcep_pce() */
706 static void show_pce_peer(struct vty
*vty
, struct pce_opts_cli
*pce_opts_cli
)
708 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
709 vty_out(vty
, "PCE: %s\n", pce_opts
->pce_name
);
711 /* Remote PCE IP address */
712 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
713 vty_out(vty
, " %s %s %pI6 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
714 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
,
715 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
717 vty_out(vty
, " %s %s %pI4 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
718 PCEP_VTYSH_ARG_IP
, &pce_opts
->addr
.ipaddr_v4
,
719 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
722 if (pce_opts_cli
->config_group_name
[0] != '\0') {
723 vty_out(vty
, " pce-config: %s\n",
724 pce_opts_cli
->config_group_name
);
728 pcep_cli_print_pce_config(&pce_opts
->config_opts
, buf
, sizeof(buf
));
729 vty_out(vty
, "%s", buf
);
732 static int path_pcep_cli_show_srte_pcep_pce(struct vty
*vty
,
733 const char *pce_peer
)
735 /* Only show 1 PCE */
736 struct pce_opts_cli
*pce_opts_cli
;
737 if (pce_peer
!= NULL
) {
738 pce_opts_cli
= pcep_cli_find_pce(pce_peer
);
739 if (pce_opts_cli
== NULL
) {
740 vty_out(vty
, "%% PCE [%s] does not exist.\n", pce_peer
);
744 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
745 show_pce_peer(vty
, pce_opts_cli
);
751 for (int i
= 0; i
< MAX_PCE
; i
++) {
752 pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
753 if (pce_opts_cli
== NULL
) {
757 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
758 show_pce_peer(vty
, pce_opts_cli
);
764 static int path_pcep_cli_peer_sr_draft07(struct vty
*vty
)
766 struct pcep_config_group_opts
*pce_config
= NULL
;
768 if (vty
->node
== PCEP_PCE_NODE
) {
769 /* TODO need to see if the pce is in use, and reset the
771 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
772 current_pce_opts_g
->merged
= false;
773 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
774 pce_config
= current_pcep_config_group_opts_g
;
776 return CMD_ERR_NO_MATCH
;
779 pce_config
->draft07
= true;
784 static int path_pcep_cli_peer_pce_initiated(struct vty
*vty
)
786 struct pcep_config_group_opts
*pce_config
= NULL
;
788 if (vty
->node
== PCEP_PCE_NODE
) {
789 /* TODO need to see if the pce is in use, and reset the
791 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
792 current_pce_opts_g
->merged
= false;
793 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
794 pce_config
= current_pcep_config_group_opts_g
;
796 return CMD_ERR_NO_MATCH
;
799 pce_config
->pce_initiated
= true;
804 static int path_pcep_cli_peer_tcp_md5_auth(struct vty
*vty
,
805 const char *tcp_md5_auth
)
807 struct pcep_config_group_opts
*pce_config
= NULL
;
809 if (vty
->node
== PCEP_PCE_NODE
) {
810 /* TODO need to see if the pce is in use, and reset the
812 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
813 current_pce_opts_g
->merged
= false;
814 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
815 pce_config
= current_pcep_config_group_opts_g
;
817 return CMD_ERR_NO_MATCH
;
820 strlcpy(pce_config
->tcp_md5_auth
, tcp_md5_auth
,
821 sizeof(pce_config
->tcp_md5_auth
));
826 static int path_pcep_cli_peer_address(struct vty
*vty
, const char *ip_str
,
827 struct in_addr
*ip
, const char *ipv6_str
,
828 struct in6_addr
*ipv6
,
829 const char *port_str
, long port
)
831 struct pce_opts
*pce_opts
= NULL
;
832 if (vty
->node
== PCEP_PCE_NODE
) {
833 /* TODO need to see if the pce is in use, and reset the
835 pce_opts
= ¤t_pce_opts_g
->pce_opts
;
836 current_pce_opts_g
->merged
= false;
838 return CMD_ERR_NO_MATCH
;
841 if (ipv6_str
!= NULL
) {
842 pce_opts
->addr
.ipa_type
= IPADDR_V6
;
843 memcpy(&pce_opts
->addr
.ipaddr_v6
, ipv6
,
844 sizeof(struct in6_addr
));
845 } else if (ip_str
!= NULL
) {
846 pce_opts
->addr
.ipa_type
= IPADDR_V4
;
847 memcpy(&pce_opts
->addr
.ipaddr_v4
, ip
, sizeof(struct in_addr
));
849 return CMD_ERR_NO_MATCH
;
852 /* Handle the optional port */
853 pce_opts
->port
= PCEP_DEFAULT_PORT
;
854 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_opts
->port
, 0, 65535);
859 static int path_pcep_cli_peer_source_address(struct vty
*vty
,
862 const char *ipv6_str
,
863 struct in6_addr
*ipv6
,
864 const char *port_str
, long port
)
866 struct pcep_config_group_opts
*pce_config
= NULL
;
867 if (vty
->node
== PCEP_PCE_NODE
) {
868 /* TODO need to see if the pce is in use, and reset the
870 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
871 current_pce_opts_g
->merged
= false;
872 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
873 pce_config
= current_pcep_config_group_opts_g
;
875 return CMD_ERR_NO_MATCH
;
878 /* Handle the optional source IP */
879 if (ipv6_str
!= NULL
) {
880 pce_config
->source_ip
.ipa_type
= IPADDR_V6
;
881 memcpy(&pce_config
->source_ip
.ipaddr_v6
, ipv6
,
882 sizeof(struct in6_addr
));
883 } else if (ip_str
!= NULL
) {
884 pce_config
->source_ip
.ipa_type
= IPADDR_V4
;
885 memcpy(&pce_config
->source_ip
.ipaddr_v4
, ip
,
886 sizeof(struct in_addr
));
889 /* Handle the optional port */
890 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_config
->source_port
, 0,
896 static int path_pcep_cli_peer_pcep_pce_config_ref(struct vty
*vty
,
897 const char *config_group_name
)
899 if (vty
->node
== PCEP_PCE_NODE
) {
900 /* TODO need to see if the pce is in use, and reset the
902 current_pce_opts_g
->merged
= false;
904 return CMD_ERR_NO_MATCH
;
907 struct pcep_config_group_opts
*pce_config
=
908 pcep_cli_find_pcep_pce_config(config_group_name
);
909 if (pce_config
== NULL
) {
910 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
915 strlcpy(current_pce_opts_g
->config_group_name
, config_group_name
,
916 sizeof(current_pce_opts_g
->config_group_name
));
921 static int path_pcep_cli_peer_timers(
922 struct vty
*vty
, const char *keep_alive_str
, long keep_alive
,
923 const char *min_peer_keep_alive_str
, long min_peer_keep_alive
,
924 const char *max_peer_keep_alive_str
, long max_peer_keep_alive
,
925 const char *dead_timer_str
, long dead_timer
,
926 const char *min_peer_dead_timer_str
, long min_peer_dead_timer
,
927 const char *max_peer_dead_timer_str
, long max_peer_dead_timer
,
928 const char *pcep_request_str
, long pcep_request
,
929 const char *session_timeout_interval_str
, long session_timeout_interval
,
930 const char *delegation_timeout_str
, long delegation_timeout
)
932 struct pcep_config_group_opts
*pce_config
= NULL
;
933 if (vty
->node
== PCEP_PCE_NODE
) {
934 /* TODO need to see if the pce is in use, and reset the
936 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
937 current_pce_opts_g
->merged
= false;
938 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
939 pce_config
= current_pcep_config_group_opts_g
;
941 return CMD_ERR_NO_MATCH
;
944 if (min_peer_keep_alive
&& max_peer_keep_alive
)
945 if (min_peer_keep_alive
>= max_peer_keep_alive
) {
946 return CMD_ERR_NO_MATCH
;
949 if (min_peer_dead_timer
&& max_peer_dead_timer
)
950 if (min_peer_dead_timer
>= max_peer_dead_timer
) {
951 return CMD_ERR_NO_MATCH
;
954 /* Handle the arguments */
955 PCEP_VTYSH_INT_ARG_CHECK(keep_alive_str
, keep_alive
,
956 pce_config
->keep_alive_seconds
, 0, 64);
957 PCEP_VTYSH_INT_ARG_CHECK(min_peer_keep_alive_str
, min_peer_keep_alive
,
958 pce_config
->min_keep_alive_seconds
, 0, 256);
959 PCEP_VTYSH_INT_ARG_CHECK(max_peer_keep_alive_str
, max_peer_keep_alive
,
960 pce_config
->max_keep_alive_seconds
, 0, 256);
961 PCEP_VTYSH_INT_ARG_CHECK(dead_timer_str
, dead_timer
,
962 pce_config
->dead_timer_seconds
, 3, 256);
963 PCEP_VTYSH_INT_ARG_CHECK(min_peer_dead_timer_str
, min_peer_dead_timer
,
964 pce_config
->min_dead_timer_seconds
, 3, 256);
965 PCEP_VTYSH_INT_ARG_CHECK(max_peer_dead_timer_str
, max_peer_dead_timer
,
966 pce_config
->max_dead_timer_seconds
, 3, 256);
967 PCEP_VTYSH_INT_ARG_CHECK(pcep_request_str
, pcep_request
,
968 pce_config
->pcep_request_time_seconds
, 0, 121);
969 PCEP_VTYSH_INT_ARG_CHECK(
970 session_timeout_interval_str
, session_timeout_interval
,
971 pce_config
->session_timeout_inteval_seconds
, 0, 121);
972 PCEP_VTYSH_INT_ARG_CHECK(delegation_timeout_str
, delegation_timeout
,
973 pce_config
->delegation_timeout_seconds
, 0, 61);
978 static int path_pcep_cli_pcc(struct vty
*vty
)
980 VTY_PUSH_CONTEXT_NULL(PCEP_PCC_NODE
);
985 static int path_pcep_cli_pcc_delete(struct vty
*vty
)
987 /* Clear the pce_connections */
988 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
989 pcc_msd_configured_g
= false;
991 pcep_ctrl_remove_pcc(pcep_g
->fpt
, NULL
);
996 static int path_pcep_cli_pcc_pcc_msd(struct vty
*vty
, const char *msd_str
,
999 pcc_msd_configured_g
= true;
1000 PCEP_VTYSH_INT_ARG_CHECK(msd_str
, msd
, pcc_msd_g
, 0, 33);
1005 static int path_pcep_cli_pcc_pcc_peer(struct vty
*vty
, const char *peer_name
,
1006 const char *precedence_str
,
1009 /* Check if the pcc-peer exists */
1010 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1011 if (pce_opts_cli
== NULL
) {
1012 vty_out(vty
, "%% PCE [%s] does not exist.\n", peer_name
);
1015 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1017 /* Check if the pcc-peer is duplicated */
1018 if (pcep_cli_pcc_has_pce(peer_name
)) {
1019 vty_out(vty
, "%% The peer [%s] has already been configured.\n",
1024 /* Get the optional precedence argument */
1025 pce_opts
->precedence
= DEFAULT_PCE_PRECEDENCE
;
1026 PCEP_VTYSH_INT_ARG_CHECK(precedence_str
, precedence
,
1027 pce_opts
->precedence
, 0, 256);
1029 /* Finalize the pce_opts config values */
1030 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
1031 pcep_cli_add_pce_connection(&pce_opts_cli
->pce_opts
);
1033 /* Verify the PCE has the IP set */
1034 struct in6_addr zero_v6_addr
;
1035 memset(&zero_v6_addr
, 0, sizeof(struct in6_addr
));
1036 if (memcmp(&pce_opts
->addr
.ip
, &zero_v6_addr
, IPADDRSZ(&pce_opts
->addr
))
1039 "%% The peer [%s] does not have an IP set and cannot be used until it does.\n",
1044 /* Update the pcc_opts with the source ip, port, and msd */
1045 struct pcc_opts
*pcc_opts_copy
=
1046 XMALLOC(MTYPE_PCEP
, sizeof(struct pcc_opts
));
1047 memcpy(&pcc_opts_copy
->addr
,
1048 &pce_opts_cli
->pce_opts
.config_opts
.source_ip
,
1049 sizeof(pcc_opts_copy
->addr
));
1050 pcc_opts_copy
->msd
= pcc_msd_g
;
1051 pcc_opts_copy
->port
= pce_opts_cli
->pce_opts
.config_opts
.source_port
;
1052 if (pcep_ctrl_update_pcc_options(pcep_g
->fpt
, pcc_opts_copy
)) {
1056 /* Send a copy of the pce_opts, this one is only used for the CLI */
1057 struct pce_opts
*pce_opts_copy
=
1058 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1059 memcpy(pce_opts_copy
, pce_opts
, sizeof(struct pce_opts
));
1060 if (pcep_ctrl_update_pce_options(pcep_g
->fpt
, pce_opts_copy
)) {
1067 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
1068 const char *peer_name
,
1069 const char *precedence_str
,
1072 /* Check if the pcc-peer is connected to the PCC */
1073 if (!pcep_cli_pcc_has_pce(peer_name
)) {
1075 "%% WARN: The peer [%s] is not connected to the PCC.\n",
1080 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1081 pcep_cli_remove_pce_connection(&pce_opts_cli
->pce_opts
);
1083 /* Send a copy of the pce_opts, this one is used for CLI only */
1084 struct pce_opts
*pce_opts_copy
=
1085 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1086 memcpy(pce_opts_copy
, &pce_opts_cli
->pce_opts
, sizeof(struct pce_opts
));
1087 pcep_ctrl_remove_pcc(pcep_g
->fpt
, pce_opts_copy
);
1092 static int path_pcep_cli_show_srte_pcep_pcc(struct vty
*vty
)
1094 vty_out(vty
, "pcc msd %d\n", pcc_msd_g
);
1099 /* Internal util function to print pcep capabilities to a buffer */
1100 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
1101 pcep_configuration
*config
)
1103 if (config
->support_stateful_pce_lsp_update
) {
1104 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_STATEFUL
);
1106 if (config
->support_include_db_version
) {
1107 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_INCL_DB_VER
);
1109 if (config
->support_lsp_triggered_resync
) {
1110 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_TRIGGERED
);
1112 if (config
->support_lsp_delta_sync
) {
1113 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_DELTA
);
1115 if (config
->support_pce_triggered_initial_sync
) {
1116 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCE_TRIGGERED
);
1118 if (config
->support_sr_te_pst
) {
1119 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_SR_TE_PST
);
1121 if (config
->pcc_can_resolve_nai_to_sid
) {
1122 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCC_RESOLVE_NAI
);
1126 /* Internal util function to print a pcep session */
1127 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
1128 struct pcep_pcc_info
*pcc_info
)
1133 vty_out(vty
, "\nPCE %s\n", pce_opts
->pce_name
);
1136 if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1137 vty_out(vty
, " PCE IP %pI4 port %d\n",
1138 &pce_opts
->addr
.ipaddr_v4
, pce_opts
->port
);
1139 } else if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1140 vty_out(vty
, " PCE IPv6 %pI6 port %d\n",
1141 &pce_opts
->addr
.ipaddr_v6
, pce_opts
->port
);
1145 if (IS_IPADDR_V4(&pcc_info
->pcc_addr
)) {
1146 vty_out(vty
, " PCC IP %pI4 port %d\n",
1147 &pcc_info
->pcc_addr
.ipaddr_v4
, pcc_info
->pcc_port
);
1148 } else if (IS_IPADDR_V6(&pcc_info
->pcc_addr
)) {
1149 vty_out(vty
, " PCC IPv6 %pI6 port %d\n",
1150 &pcc_info
->pcc_addr
.ipaddr_v6
, pcc_info
->pcc_port
);
1152 vty_out(vty
, " PCC MSD %d\n", pcc_info
->msd
);
1154 if (pcc_info
->status
== PCEP_PCC_OPERATING
) {
1155 vty_out(vty
, " Session Status UP\n");
1157 vty_out(vty
, " Session Status %s\n",
1158 pcc_status_name(pcc_info
->status
));
1161 if (pcc_info
->is_best_multi_pce
) {
1162 vty_out(vty
, " Precedence %d, best candidate\n",
1163 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1164 : DEFAULT_PCE_PRECEDENCE
));
1166 vty_out(vty
, " Precedence %d\n",
1167 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1168 : DEFAULT_PCE_PRECEDENCE
));
1170 vty_out(vty
, " Confidence %s\n",
1171 ((pcc_info
->previous_best
) ? "low"
1174 /* PCEPlib pcep session values, get a thread safe copy of the counters
1176 pcep_session
*session
=
1177 pcep_ctrl_get_pcep_session(pcep_g
->fpt
, pcc_info
->pcc_id
);
1179 /* Config Options values */
1180 struct pcep_config_group_opts
*config_opts
= &pce_opts
->config_opts
;
1181 if (session
!= NULL
) {
1182 vty_out(vty
, " Timer: KeepAlive config %d, pce-negotiated %d\n",
1183 config_opts
->keep_alive_seconds
,
1185 .keep_alive_pce_negotiated_timer_seconds
);
1186 vty_out(vty
, " Timer: DeadTimer config %d, pce-negotiated %d\n",
1187 config_opts
->dead_timer_seconds
,
1188 session
->pcc_config
.dead_timer_pce_negotiated_seconds
);
1190 vty_out(vty
, " Timer: KeepAlive %d\n",
1191 config_opts
->keep_alive_seconds
);
1192 vty_out(vty
, " Timer: DeadTimer %d\n",
1193 config_opts
->dead_timer_seconds
);
1195 vty_out(vty
, " Timer: PcRequest %d\n",
1196 config_opts
->pcep_request_time_seconds
);
1197 vty_out(vty
, " Timer: SessionTimeout Interval %d\n",
1198 config_opts
->session_timeout_inteval_seconds
);
1199 vty_out(vty
, " Timer: Delegation Timeout %d\n",
1200 config_opts
->delegation_timeout_seconds
);
1201 if (strlen(config_opts
->tcp_md5_auth
) > 0) {
1202 vty_out(vty
, " TCP MD5 Auth Str: %s\n",
1203 config_opts
->tcp_md5_auth
);
1205 vty_out(vty
, " No TCP MD5 Auth\n");
1208 if (config_opts
->draft07
) {
1209 vty_out(vty
, " PCE SR Version draft07\n");
1211 vty_out(vty
, " PCE SR Version draft16 and RFC8408\n");
1214 vty_out(vty
, " Next PcReq ID %d\n", pcc_info
->next_reqid
);
1215 vty_out(vty
, " Next PLSP ID %d\n", pcc_info
->next_plspid
);
1217 if (session
!= NULL
) {
1218 if (pcc_info
->status
== PCEP_PCC_SYNCHRONIZING
1219 || pcc_info
->status
== PCEP_PCC_OPERATING
) {
1220 time_t current_time
= time(NULL
);
1222 /* Just for the timezone */
1223 localtime_r(¤t_time
, <
);
1224 gmtime_r(&session
->time_connected
, <
);
1226 " Connected for %u seconds, since %d-%02d-%02d %02d:%02d:%02d UTC\n",
1227 (uint32_t)(current_time
1228 - session
->time_connected
),
1229 lt
.tm_year
+ 1900, lt
.tm_mon
+ 1, lt
.tm_mday
,
1230 lt
.tm_hour
, lt
.tm_min
, lt
.tm_sec
);
1233 /* PCC capabilities */
1236 if (config_opts
->pce_initiated
) {
1237 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1238 PCEP_CLI_CAP_PCC_PCE_INITIATED
);
1240 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1241 PCEP_CLI_CAP_PCC_INITIATED
);
1243 print_pcep_capabilities(buf
, sizeof(buf
) - index
,
1244 &session
->pcc_config
);
1245 vty_out(vty
, " PCC Capabilities:%s\n", buf
);
1247 /* PCE capabilities */
1249 print_pcep_capabilities(buf
, sizeof(buf
), &session
->pce_config
);
1250 if (buf
[0] != '\0') {
1251 vty_out(vty
, " PCE Capabilities:%s\n", buf
);
1253 XFREE(MTYPE_PCEP
, session
);
1255 vty_out(vty
, " Detailed session information not available\n");
1258 /* Message Counters, get a thread safe copy of the counters */
1259 struct counters_group
*group
=
1260 pcep_ctrl_get_counters(pcep_g
->fpt
, pcc_info
->pcc_id
);
1262 if (group
!= NULL
) {
1263 struct counters_subgroup
*rx_msgs
=
1264 find_subgroup(group
, COUNTER_SUBGROUP_ID_RX_MSG
);
1265 struct counters_subgroup
*tx_msgs
=
1266 find_subgroup(group
, COUNTER_SUBGROUP_ID_TX_MSG
);
1268 if (rx_msgs
!= NULL
&& tx_msgs
!= NULL
) {
1269 vty_out(vty
, " PCEP Message Statistics\n");
1270 vty_out(vty
, " %27s %6s\n", "Sent", "Rcvd");
1271 for (int i
= 0; i
< rx_msgs
->max_counters
; i
++) {
1272 struct counter
*rx_counter
=
1273 rx_msgs
->counters
[i
];
1274 struct counter
*tx_counter
=
1275 tx_msgs
->counters
[i
];
1276 if (rx_counter
!= NULL
&& tx_counter
!= NULL
) {
1277 vty_out(vty
, " %20s: %5d %5d\n",
1278 tx_counter
->counter_name
,
1279 tx_counter
->counter_value
,
1280 rx_counter
->counter_value
);
1283 vty_out(vty
, " %20s: %5d %5d\n", "Total",
1284 subgroup_counters_total(tx_msgs
),
1285 subgroup_counters_total(rx_msgs
));
1287 pcep_lib_free_counters(group
);
1289 vty_out(vty
, " Counters not available\n");
1292 XFREE(MTYPE_PCEP
, pcc_info
);
1295 static int path_pcep_cli_show_srte_pcep_session(struct vty
*vty
,
1296 const char *pcc_peer
)
1298 struct pce_opts_cli
*pce_opts_cli
;
1299 struct pcep_pcc_info
*pcc_info
;
1301 /* Only show 1 PCEP session */
1302 if (pcc_peer
!= NULL
) {
1303 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1304 if (pce_opts_cli
== NULL
) {
1305 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1309 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1310 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1315 pcc_info
= pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pcc_peer
);
1316 if (pcc_info
== NULL
) {
1318 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1323 print_pcep_session(vty
, &pce_opts_cli
->pce_opts
, pcc_info
);
1328 /* Show all PCEP sessions */
1329 struct pce_opts
*pce_opts
;
1330 int num_pcep_sessions_conf
= 0;
1331 int num_pcep_sessions_conn
= 0;
1332 for (int i
= 0; i
< MAX_PCC
; i
++) {
1333 pce_opts
= pce_connections_g
.connections
[i
];
1334 if (pce_opts
== NULL
) {
1339 pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pce_opts
->pce_name
);
1340 if (pcc_info
== NULL
) {
1342 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1343 pce_opts
->pce_name
);
1347 num_pcep_sessions_conn
+=
1348 pcc_info
->status
== PCEP_PCC_OPERATING
? 1 : 0;
1349 num_pcep_sessions_conf
++;
1350 print_pcep_session(vty
, pce_opts
, pcc_info
);
1353 vty_out(vty
, "PCEP Sessions => Configured %d ; Connected %d\n",
1354 num_pcep_sessions_conf
, num_pcep_sessions_conn
);
1359 static int path_pcep_cli_clear_srte_pcep_session(struct vty
*vty
,
1360 const char *pcc_peer
)
1362 struct pce_opts_cli
*pce_opts_cli
;
1364 /* Only clear 1 PCEP session */
1365 if (pcc_peer
!= NULL
) {
1366 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1367 if (pce_opts_cli
== NULL
) {
1368 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1372 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1373 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1378 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
,
1379 pce_opts_cli
->pce_opts
.pce_name
);
1380 vty_out(vty
, "PCEP session cleared for peer %s\n", pcc_peer
);
1385 /* Clear all PCEP sessions */
1386 struct pce_opts
*pce_opts
;
1387 int num_pcep_sessions
= 0;
1388 for (int i
= 0; i
< MAX_PCC
; i
++) {
1389 pce_opts
= pce_connections_g
.connections
[i
];
1390 if (pce_opts
== NULL
) {
1394 num_pcep_sessions
++;
1395 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
, pce_opts
->pce_name
);
1396 vty_out(vty
, "PCEP session cleared for peer %s\n",
1397 pce_opts
->pce_name
);
1400 vty_out(vty
, "Cleared [%d] PCEP sessions\n", num_pcep_sessions
);
1406 * Config Write functions
1409 int pcep_cli_debug_config_write(struct vty
*vty
)
1411 char buff
[128] = "";
1413 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1414 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1415 csnprintfrr(buff
, sizeof(buff
), " %s",
1416 PCEP_VTYSH_ARG_BASIC
);
1417 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1418 csnprintfrr(buff
, sizeof(buff
), " %s",
1419 PCEP_VTYSH_ARG_PATH
);
1420 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1421 csnprintfrr(buff
, sizeof(buff
), " %s",
1422 PCEP_VTYSH_ARG_MESSAGE
);
1423 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1424 csnprintfrr(buff
, sizeof(buff
), " %s",
1425 PCEP_VTYSH_ARG_PCEPLIB
);
1426 vty_out(vty
, "debug pathd pcep%s\n", buff
);
1434 int pcep_cli_debug_set_all(uint32_t flags
, bool set
)
1436 DEBUG_FLAGS_SET(&pcep_g
->dbg
, flags
, set
);
1438 /* If all modes have been turned off, don't preserve options. */
1439 if (!DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_ALL
))
1440 DEBUG_CLEAR(&pcep_g
->dbg
);
1445 int pcep_cli_pcep_config_write(struct vty
*vty
)
1447 vty_out(vty
, " pcep\n");
1451 int pcep_cli_pcc_config_write(struct vty
*vty
)
1453 struct pce_opts
*pce_opts
;
1457 /* The MSD, nor any PCE peers have been configured on the PCC */
1458 if (!pcc_msd_configured_g
&& pce_connections_g
.num_connections
== 0) {
1462 vty_out(vty
, " pcc\n");
1465 /* Prepare the MSD, if present */
1466 if (pcc_msd_configured_g
) {
1467 vty_out(vty
, " %s %d\n", PCEP_VTYSH_ARG_MSD
, pcc_msd_g
);
1471 if (pce_connections_g
.num_connections
== 0) {
1476 for (int i
= 0; i
< MAX_PCC
; i
++) {
1477 pce_opts
= pce_connections_g
.connections
[i
];
1478 if (pce_opts
== NULL
) {
1482 /* Only show the PCEs configured in the pcc sub-command */
1483 if (!pcep_cli_pcc_has_pce(pce_opts
->pce_name
)) {
1487 csnprintfrr(buf
, sizeof(buf
), " peer %s",
1488 pce_opts
->pce_name
);
1489 if (pce_opts
->precedence
> 0
1490 && pce_opts
->precedence
!= DEFAULT_PCE_PRECEDENCE
) {
1491 csnprintfrr(buf
, sizeof(buf
), " %s %d",
1492 PCEP_VTYSH_ARG_PRECEDENCE
,
1493 pce_opts
->precedence
);
1495 vty_out(vty
, "%s\n", buf
);
1503 /* Internal function used by pcep_cli_pce_config_write()
1504 * and pcep_cli_pcep_pce_config_write() */
1505 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
1506 char *buf
, size_t buf_len
)
1510 if (group_opts
->source_ip
.ipa_type
!= IPADDR_NONE
1511 || group_opts
->source_port
!= 0) {
1512 csnprintfrr(buf
, buf_len
, " ");
1513 if (IS_IPADDR_V4(&group_opts
->source_ip
)) {
1514 csnprintfrr(buf
, buf_len
, " %s %s %pI4",
1515 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1517 &group_opts
->source_ip
.ipaddr_v4
);
1518 } else if (IS_IPADDR_V6(&group_opts
->source_ip
)) {
1519 csnprintfrr(buf
, buf_len
, " %s %s %pI6",
1520 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1521 PCEP_VTYSH_ARG_IPV6
,
1522 &group_opts
->source_ip
.ipaddr_v6
);
1524 if (group_opts
->source_port
> 0) {
1525 csnprintfrr(buf
, buf_len
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1526 group_opts
->source_port
);
1528 csnprintfrr(buf
, buf_len
, "\n");
1531 /* Group the keep-alive together for devman */
1532 if ((group_opts
->keep_alive_seconds
> 0)
1533 || (group_opts
->min_keep_alive_seconds
> 0)
1534 || (group_opts
->max_keep_alive_seconds
> 0)) {
1535 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1537 if (group_opts
->keep_alive_seconds
> 0) {
1538 csnprintfrr(buf
, buf_len
, " %s %d",
1539 PCEP_VTYSH_ARG_KEEP_ALIVE
,
1540 group_opts
->keep_alive_seconds
);
1542 if (group_opts
->min_keep_alive_seconds
> 0) {
1543 csnprintfrr(buf
, buf_len
, " %s %d",
1544 PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
,
1545 group_opts
->min_keep_alive_seconds
);
1547 if (group_opts
->max_keep_alive_seconds
> 0) {
1548 csnprintfrr(buf
, buf_len
, " %s %d",
1549 PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
,
1550 group_opts
->max_keep_alive_seconds
);
1552 csnprintfrr(buf
, buf_len
, "\n");
1556 /* Group the dead-timer together for devman */
1557 if ((group_opts
->dead_timer_seconds
> 0)
1558 || (group_opts
->min_dead_timer_seconds
> 0)
1559 || (group_opts
->max_dead_timer_seconds
> 0)) {
1560 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1562 if (group_opts
->dead_timer_seconds
> 0) {
1563 csnprintfrr(buf
, buf_len
, " %s %d",
1564 PCEP_VTYSH_ARG_DEAD_TIMER
,
1565 group_opts
->dead_timer_seconds
);
1567 if (group_opts
->min_dead_timer_seconds
> 0) {
1568 csnprintfrr(buf
, buf_len
, " %s %d",
1569 PCEP_VTYSH_ARG_DEAD_TIMER_MIN
,
1570 group_opts
->min_dead_timer_seconds
);
1572 if (group_opts
->max_dead_timer_seconds
> 0) {
1573 csnprintfrr(buf
, buf_len
, " %s %d",
1574 PCEP_VTYSH_ARG_DEAD_TIMER_MAX
,
1575 group_opts
->max_dead_timer_seconds
);
1577 csnprintfrr(buf
, buf_len
, "\n");
1581 if (group_opts
->pcep_request_time_seconds
> 0) {
1582 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1583 PCEP_VTYSH_ARG_TIMER
, PCEP_VTYSH_ARG_PCEP_REQUEST
,
1584 group_opts
->pcep_request_time_seconds
);
1587 if (group_opts
->delegation_timeout_seconds
> 0) {
1588 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1589 PCEP_VTYSH_ARG_TIMER
,
1590 PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
,
1591 group_opts
->delegation_timeout_seconds
);
1594 if (group_opts
->session_timeout_inteval_seconds
> 0) {
1595 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1596 PCEP_VTYSH_ARG_TIMER
,
1597 PCEP_VTYSH_ARG_SESSION_TIMEOUT
,
1598 group_opts
->session_timeout_inteval_seconds
);
1601 if (group_opts
->tcp_md5_auth
[0] != '\0') {
1602 csnprintfrr(buf
, buf_len
, " %s %s\n", PCEP_VTYSH_ARG_TCP_MD5
,
1603 group_opts
->tcp_md5_auth
);
1606 if (group_opts
->draft07
) {
1607 csnprintfrr(buf
, buf_len
, " %s\n",
1608 PCEP_VTYSH_ARG_SR_DRAFT07
);
1611 if (group_opts
->pce_initiated
) {
1612 csnprintfrr(buf
, buf_len
, " %s\n", PCEP_VTYSH_ARG_PCE_INIT
);
1619 int pcep_cli_pce_config_write(struct vty
*vty
)
1622 char buf
[1024] = "";
1624 for (int i
= 0; i
< MAX_PCE
; i
++) {
1625 struct pce_opts_cli
*pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
1626 if (pce_opts_cli
== NULL
) {
1629 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1631 vty_out(vty
, " pce %s\n", pce_opts
->pce_name
);
1632 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1633 vty_out(vty
, " %s %s %pI6", PCEP_VTYSH_ARG_ADDRESS
,
1634 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
);
1635 } else if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1636 vty_out(vty
, " address %s %pI4", PCEP_VTYSH_ARG_IP
,
1637 &pce_opts
->addr
.ipaddr_v4
);
1639 if (pce_opts
->port
!= PCEP_DEFAULT_PORT
) {
1640 vty_out(vty
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1643 vty_out(vty
, "%s\n", buf
);
1646 if (pce_opts_cli
->config_group_name
[0] != '\0') {
1647 vty_out(vty
, " config %s\n",
1648 pce_opts_cli
->config_group_name
);
1652 /* Only display the values configured on the PCE, not the values
1653 * from its optional pce-config-group, nor the default values */
1654 lines
+= pcep_cli_print_pce_config(
1655 &pce_opts_cli
->pce_config_group_opts
, buf
, sizeof(buf
));
1657 vty_out(vty
, "%s", buf
);
1664 int pcep_cli_pcep_pce_config_write(struct vty
*vty
)
1667 char buf
[1024] = "";
1669 for (int i
= 0; i
< MAX_PCE
; i
++) {
1670 struct pcep_config_group_opts
*group_opts
=
1671 pcep_g
->config_group_opts
[i
];
1672 if (group_opts
== NULL
) {
1676 vty_out(vty
, " pce-config %s\n", group_opts
->name
);
1680 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
1681 vty_out(vty
, "%s", buf
);
1689 * VTYSH command syntax definitions
1690 * The param names are taken from the path_pcep_cli_clippy.c generated file.
1693 DEFPY(show_debugging_pathd_pcep
,
1694 show_debugging_pathd_pcep_cmd
,
1695 "show debugging pathd-pcep",
1697 "State of each debugging option\n"
1698 "pathd pcep module debugging\n")
1700 vty_out(vty
, "Pathd pcep debugging status:\n");
1702 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1703 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1704 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1705 PCEP_VTYSH_ARG_BASIC
);
1706 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1707 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1708 PCEP_VTYSH_ARG_PATH
);
1709 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1710 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1711 PCEP_VTYSH_ARG_MESSAGE
);
1712 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1713 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1714 PCEP_VTYSH_ARG_PCEPLIB
);
1720 DEFPY(pcep_cli_debug
,
1722 "[no] debug pathd pcep [basic]$basic_str [path]$path_str [message]$message_str [pceplib]$pceplib_str",
1725 "pcep module debugging\n"
1726 "module basic debugging\n"
1727 "path structures debugging\n"
1728 "pcep message debugging\n"
1729 "pceplib debugging\n")
1731 return path_pcep_cli_debug(vty
, no
, basic_str
, path_str
, message_str
,
1735 DEFPY(pcep_cli_show_srte_pcep_counters
,
1736 pcep_cli_show_srte_pcep_counters_cmd
,
1737 "show sr-te pcep counters",
1743 return path_pcep_cli_show_srte_pcep_counters(vty
);
1750 "PCEP configuration\n")
1752 vty
->node
= PCEP_NODE
;
1757 pcep_cli_pcep_pce_config
,
1758 pcep_cli_pcep_pce_config_cmd
,
1759 "[no] pce-config WORD$name",
1761 "Shared configuration\n"
1762 "Shared configuration name\n")
1765 return path_pcep_cli_pcep_pce_config(vty
, name
);
1766 return path_pcep_cli_pcep_pce_config_delete(vty
, name
);
1769 DEFPY(pcep_cli_show_srte_pcep_pce_config
,
1770 pcep_cli_show_srte_pcep_pce_config_cmd
,
1771 "show sr-te pcep pce-config [<default|WORD>$name]",
1775 "Show shared PCE configuration\n"
1776 "Show default hard-coded values\n"
1777 "Shared configuration name\n")
1779 return path_pcep_cli_show_srte_pcep_pce_config(vty
, name
);
1785 "[no] pce WORD$name",
1787 "PCE configuration, address sub-config is mandatory\n"
1791 return path_pcep_cli_pce(vty
, name
);
1792 return path_pcep_cli_pce_delete(vty
, name
);
1795 DEFPY(pcep_cli_show_srte_pcep_pce
,
1796 pcep_cli_show_srte_pcep_pce_cmd
,
1797 "show sr-te pcep pce [WORD$name]",
1801 "Show detailed pce values\n"
1804 return path_pcep_cli_show_srte_pcep_pce(vty
, name
);
1807 DEFPY(pcep_cli_peer_sr_draft07
,
1808 pcep_cli_peer_sr_draft07_cmd
,
1810 "Configure PCC to send PCEP Open with SR draft07\n")
1812 return path_pcep_cli_peer_sr_draft07(vty
);
1815 DEFPY(pcep_cli_peer_pce_initiated
,
1816 pcep_cli_peer_pce_initiated_cmd
,
1818 "Configure PCC to accept PCE initiated LSPs\n")
1820 return path_pcep_cli_peer_pce_initiated(vty
);
1823 DEFPY(pcep_cli_peer_tcp_md5_auth
,
1824 pcep_cli_peer_tcp_md5_auth_cmd
,
1825 "tcp-md5-auth WORD",
1826 "Configure PCC TCP-MD5 RFC2385 Authentication\n"
1827 "TCP-MD5 Authentication string\n")
1829 return path_pcep_cli_peer_tcp_md5_auth(vty
, tcp_md5_auth
);
1832 DEFPY(pcep_cli_peer_address
,
1833 pcep_cli_peer_address_cmd
,
1834 "address <ip A.B.C.D | ipv6 X:X::X:X> [port (1024-65535)]",
1835 "PCE IP Address configuration, mandatory configuration\n"
1836 "PCE IPv4 address\n"
1837 "Remote PCE server IPv4 address\n"
1838 "PCE IPv6 address\n"
1839 "Remote PCE server IPv6 address\n"
1840 "Remote PCE server port\n"
1841 "Remote PCE server port value\n")
1843 return path_pcep_cli_peer_address(vty
, ip_str
, &ip
, ipv6_str
, &ipv6
,
1847 DEFPY(pcep_cli_peer_source_address
,
1848 pcep_cli_peer_source_address_cmd
,
1849 "source-address [ip A.B.C.D | ipv6 X:X::X:X] [port (1024-65535)]",
1850 "PCE source IP Address configuration\n"
1851 "PCE source IPv4 address\n"
1852 "PCE source IPv4 address value\n"
1853 "PCE source IPv6 address\n"
1854 "PCE source IPv6 address value\n"
1855 "Source PCE server port\n"
1856 "Source PCE server port value\n")
1858 return path_pcep_cli_peer_source_address(vty
, ip_str
, &ip
, ipv6_str
,
1859 &ipv6
, port_str
, port
);
1862 DEFPY(pcep_cli_peer_pcep_pce_config_ref
,
1863 pcep_cli_peer_pcep_pce_config_ref_cmd
,
1865 "PCE shared configuration to use\n"
1866 "Shared configuration name\n")
1868 return path_pcep_cli_peer_pcep_pce_config_ref(vty
, name
);
1871 DEFPY(pcep_cli_peer_timers
,
1872 pcep_cli_peer_timers_cmd
,
1873 "timer [keep-alive (1-63)] [min-peer-keep-alive (1-255)] [max-peer-keep-alive (1-255)] "
1874 "[dead-timer (4-255)] [min-peer-dead-timer (4-255)] [max-peer-dead-timer (4-255)] "
1875 "[pcep-request (1-120)] [session-timeout-interval (1-120)] [delegation-timeout (1-60)]",
1876 "PCE PCEP Session Timers configuration\n"
1877 "PCC Keep Alive Timer\n"
1878 "PCC Keep Alive Timer value in seconds\n"
1879 "Min Acceptable PCE Keep Alive Timer\n"
1880 "Min Acceptable PCE Keep Alive Timer value in seconds\n"
1881 "Max Acceptable PCE Keep Alive Timer\n"
1882 "Max Acceptable PCE Keep Alive Timer value in seconds\n"
1884 "PCC Dead Timer value in seconds\n"
1885 "Min Acceptable PCE Dead Timer\n"
1886 "Min Acceptable PCE Dead Timer value in seconds\n"
1887 "Max Acceptable PCE Dead Timer\n"
1888 "Max Acceptable PCE Dead Timer value in seconds\n"
1889 "PCC PCEP Request Timer\n"
1890 "PCC PCEP Request Timer value in seconds\n"
1891 "PCC Session Timeout Interval\n"
1892 "PCC Session Timeout Interval value in seconds\n"
1893 "Multi-PCE delegation timeout\n"
1894 "Multi-PCE delegation timeout value in seconds\n")
1896 return path_pcep_cli_peer_timers(
1897 vty
, keep_alive_str
, keep_alive
, min_peer_keep_alive_str
,
1898 min_peer_keep_alive
, max_peer_keep_alive_str
,
1899 max_peer_keep_alive
, dead_timer_str
, dead_timer
,
1900 min_peer_dead_timer_str
, min_peer_dead_timer
,
1901 max_peer_dead_timer_str
, max_peer_dead_timer
, pcep_request_str
,
1902 pcep_request
, session_timeout_interval_str
,
1903 session_timeout_interval
, delegation_timeout_str
,
1904 delegation_timeout
);
1912 "PCC configuration\n")
1915 return path_pcep_cli_pcc_delete(vty
);
1917 return path_pcep_cli_pcc(vty
);
1921 DEFPY(pcep_cli_pcc_pcc_msd
,
1922 pcep_cli_pcc_pcc_msd_cmd
,
1924 "PCC maximum SID depth \n"
1925 "PCC maximum SID depth value\n")
1927 return path_pcep_cli_pcc_pcc_msd(vty
, msd_str
, msd
);
1930 DEFPY(pcep_cli_pcc_pcc_peer
,
1931 pcep_cli_pcc_pcc_peer_cmd
,
1932 "[no] peer WORD [precedence (1-255)]",
1936 "PCC Multi-PCE precedence\n"
1940 return path_pcep_cli_pcc_pcc_peer_delete(
1941 vty
, peer
, precedence_str
, precedence
);
1943 return path_pcep_cli_pcc_pcc_peer(vty
, peer
, precedence_str
,
1948 DEFPY(pcep_cli_show_srte_pcc
,
1949 pcep_cli_show_srte_pcc_cmd
,
1950 "show sr-te pcep pcc",
1954 "Show current PCC configuration\n")
1956 return path_pcep_cli_show_srte_pcep_pcc(vty
);
1959 DEFPY(pcep_cli_show_srte_pcep_session
,
1960 pcep_cli_show_srte_pcep_session_cmd
,
1961 "show sr-te pcep session [WORD]$pce",
1965 "Show PCEP Session information\n"
1968 return path_pcep_cli_show_srte_pcep_session(vty
, pce
);
1971 DEFPY(pcep_cli_clear_srte_pcep_session
,
1972 pcep_cli_clear_srte_pcep_session_cmd
,
1973 "clear sr-te pcep session [WORD]$pce",
1977 "Reset PCEP connection\n"
1980 return path_pcep_cli_clear_srte_pcep_session(vty
, pce
);
1983 void pcep_cli_init(void)
1985 hook_register(nb_client_debug_config_write
,
1986 pcep_cli_debug_config_write
);
1987 hook_register(nb_client_debug_set_all
, pcep_cli_debug_set_all
);
1989 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
1991 install_node(&pcep_node
);
1992 install_node(&pcep_pcc_node
);
1993 install_node(&pcep_pce_node
);
1994 install_node(&pcep_pce_config_node
);
1996 install_default(PCEP_PCE_CONFIG_NODE
);
1997 install_default(PCEP_PCE_NODE
);
1998 install_default(PCEP_PCC_NODE
);
1999 install_default(PCEP_NODE
);
2001 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cli_pcep_cmd
);
2003 /* PCEP configuration group related configuration commands */
2004 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
2005 install_element(PCEP_PCE_CONFIG_NODE
,
2006 &pcep_cli_peer_source_address_cmd
);
2007 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_timers_cmd
);
2008 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2009 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2010 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2012 /* PCE peer related configuration commands */
2013 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
2014 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_address_cmd
);
2015 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_source_address_cmd
);
2016 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pcep_pce_config_ref_cmd
);
2017 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_timers_cmd
);
2018 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2019 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2020 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2022 /* PCC related configuration commands */
2023 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcc_cmd
);
2024 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
2025 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_peer_cmd
);
2026 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_msd_cmd
);
2029 install_element(CONFIG_NODE
, &pcep_cli_debug_cmd
);
2030 install_element(ENABLE_NODE
, &pcep_cli_debug_cmd
);
2031 install_element(ENABLE_NODE
, &show_debugging_pathd_pcep_cmd
);
2032 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_counters_cmd
);
2033 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_config_cmd
);
2034 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_cmd
);
2035 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_session_cmd
);
2036 install_element(ENABLE_NODE
, &pcep_cli_clear_srte_pcep_session_cmd
);