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"
28 #include "lib/version.h"
29 #include "northbound.h"
30 #include "frr_pthread.h"
32 #include "termtable.h"
34 #include "pathd/pathd.h"
35 #include "pathd/path_errors.h"
36 #include "pathd/path_pcep.h"
37 #include "pathd/path_pcep_cli.h"
38 #include "pathd/path_pcep_controller.h"
39 #include "pathd/path_pcep_debug.h"
40 #include "pathd/path_pcep_lib.h"
41 #include "pathd/path_pcep_pcc.h"
43 #ifndef VTYSH_EXTRACT_PL
44 #include "pathd/path_pcep_cli_clippy.c"
47 #define DEFAULT_PCE_PRECEDENCE 255
48 #define DEFAULT_PCC_MSD 4
49 #define DEFAULT_SR_DRAFT07 false
50 #define DEFAULT_PCE_INITIATED false
51 #define DEFAULT_TIMER_KEEP_ALIVE 30
52 #define DEFAULT_TIMER_KEEP_ALIVE_MIN 1
53 #define DEFAULT_TIMER_KEEP_ALIVE_MAX 255
54 #define DEFAULT_TIMER_DEADTIMER 120
55 #define DEFAULT_TIMER_DEADTIMER_MIN 4
56 #define DEFAULT_TIMER_DEADTIMER_MAX 255
57 #define DEFAULT_TIMER_PCEP_REQUEST 30
58 #define DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL 30
59 #define DEFAULT_DELEGATION_TIMEOUT_INTERVAL 10
61 /* CLI Function declarations */
62 static int pcep_cli_debug_config_write(struct vty
*vty
);
63 static int pcep_cli_debug_set_all(uint32_t flags
, bool set
);
64 static int pcep_cli_pcep_config_write(struct vty
*vty
);
65 static int pcep_cli_pcc_config_write(struct vty
*vty
);
66 static int pcep_cli_pce_config_write(struct vty
*vty
);
67 static int pcep_cli_pcep_pce_config_write(struct vty
*vty
);
69 /* Internal Util Function declarations */
70 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
);
71 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
);
72 static struct pce_opts_cli
*pcep_cli_create_pce_opts();
73 static void pcep_cli_delete_pce(const char *pce_name
);
75 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
);
76 static struct pcep_config_group_opts
*
77 pcep_cli_find_pcep_pce_config(const char *group_name
);
79 pcep_cli_add_pcep_pce_config(struct pcep_config_group_opts
*config_group_opts
);
80 static struct pcep_config_group_opts
*
81 pcep_cli_create_pcep_pce_config(const char *group_name
);
82 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
);
83 static void pcep_cli_delete_pcep_pce_config(const char *group_name
);
84 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
85 char *buf
, size_t buf_len
);
86 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
87 pcep_configuration
*config
);
88 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
89 struct pcep_pcc_info
*pcc_info
);
90 static bool pcep_cli_pcc_has_pce(const char *pce_name
);
91 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
);
92 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
);
93 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
94 const char *peer_name
,
95 const char *precedence_str
,
102 static const char PCEP_VTYSH_ARG_ADDRESS
[] = "address";
103 static const char PCEP_VTYSH_ARG_SOURCE_ADDRESS
[] = "source-address";
104 static const char PCEP_VTYSH_ARG_IP
[] = "ip";
105 static const char PCEP_VTYSH_ARG_IPV6
[] = "ipv6";
106 static const char PCEP_VTYSH_ARG_PORT
[] = "port";
107 static const char PCEP_VTYSH_ARG_PRECEDENCE
[] = "precedence";
108 static const char PCEP_VTYSH_ARG_MSD
[] = "msd";
109 static const char PCEP_VTYSH_ARG_KEEP_ALIVE
[] = "keep-alive";
110 static const char PCEP_VTYSH_ARG_TIMER
[] = "timer";
111 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
[] = "min-peer-keep-alive";
112 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
[] = "max-peer-keep-alive";
113 static const char PCEP_VTYSH_ARG_DEAD_TIMER
[] = "dead-timer";
114 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MIN
[] = "min-peer-dead-timer";
115 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MAX
[] = "max-peer-dead-timer";
116 static const char PCEP_VTYSH_ARG_PCEP_REQUEST
[] = "pcep-request";
117 static const char PCEP_VTYSH_ARG_SESSION_TIMEOUT
[] = "session-timeout-interval";
118 static const char PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
[] = "delegation-timeout";
119 static const char PCEP_VTYSH_ARG_SR_DRAFT07
[] = "sr-draft07";
120 static const char PCEP_VTYSH_ARG_PCE_INIT
[] = "pce-initiated";
121 static const char PCEP_VTYSH_ARG_TCP_MD5
[] = "tcp-md5-auth";
122 static const char PCEP_VTYSH_ARG_BASIC
[] = "basic";
123 static const char PCEP_VTYSH_ARG_PATH
[] = "path";
124 static const char PCEP_VTYSH_ARG_MESSAGE
[] = "message";
125 static const char PCEP_VTYSH_ARG_PCEPLIB
[] = "pceplib";
126 static const char PCEP_CLI_CAP_STATEFUL
[] = " [Stateful PCE]";
127 static const char PCEP_CLI_CAP_INCL_DB_VER
[] = " [Include DB version]";
128 static const char PCEP_CLI_CAP_LSP_TRIGGERED
[] = " [LSP Triggered Resync]";
129 static const char PCEP_CLI_CAP_LSP_DELTA
[] = " [LSP Delta Sync]";
130 static const char PCEP_CLI_CAP_PCE_TRIGGERED
[] =
131 " [PCE triggered Initial Sync]";
132 static const char PCEP_CLI_CAP_SR_TE_PST
[] = " [SR TE PST]";
133 static const char PCEP_CLI_CAP_PCC_RESOLVE_NAI
[] =
134 " [PCC can resolve NAI to SID]";
135 static const char PCEP_CLI_CAP_PCC_INITIATED
[] = " [PCC Initiated LSPs]";
136 static const char PCEP_CLI_CAP_PCC_PCE_INITIATED
[] =
137 " [PCC and PCE Initiated LSPs]";
139 struct pce_connections
{
141 struct pce_opts
*connections
[MAX_PCC
];
144 struct pce_connections pce_connections_g
= {.num_connections
= 0};
146 /* Default PCE group that all PCE-Groups and PCEs will inherit from */
147 struct pcep_config_group_opts default_pcep_config_group_opts_g
= {
149 .tcp_md5_auth
= "\0",
150 .draft07
= DEFAULT_SR_DRAFT07
,
151 .pce_initiated
= DEFAULT_PCE_INITIATED
,
152 .keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE
,
153 .min_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MIN
,
154 .max_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MAX
,
155 .dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER
,
156 .min_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MIN
,
157 .max_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MAX
,
158 .pcep_request_time_seconds
= DEFAULT_TIMER_PCEP_REQUEST
,
159 .session_timeout_inteval_seconds
=
160 DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL
,
161 .delegation_timeout_seconds
= DEFAULT_DELEGATION_TIMEOUT_INTERVAL
,
162 .source_port
= DEFAULT_PCEP_TCP_PORT
,
163 .source_ip
.ipa_type
= IPADDR_NONE
,
166 /* Used by PCEP_PCE_CONFIG_NODE sub-commands to operate on the current pce group
168 struct pcep_config_group_opts
*current_pcep_config_group_opts_g
= NULL
;
169 /* Used by PCEP_PCE_NODE sub-commands to operate on the current pce opts */
170 struct pce_opts_cli
*current_pce_opts_g
= NULL
;
171 short pcc_msd_g
= DEFAULT_PCC_MSD
;
172 bool pcc_msd_configured_g
= false;
174 static struct cmd_node pcep_node
= {
177 .parent_node
= SR_TRAFFIC_ENG_NODE
,
178 .prompt
= "%s(config-sr-te-pcep)# "
181 static struct cmd_node pcep_pcc_node
= {
182 .name
= "srte pcep pcc",
183 .node
= PCEP_PCC_NODE
,
184 .parent_node
= PCEP_NODE
,
185 .prompt
= "%s(config-sr-te-pcep-pcc)# "
188 static struct cmd_node pcep_pce_node
= {
189 .name
= "srte pcep pce",
190 .node
= PCEP_PCE_NODE
,
191 .parent_node
= PCEP_NODE
,
192 .prompt
= "%s(config-sr-te-pcep-pce)# "
195 static struct cmd_node pcep_pce_config_node
= {
196 .name
= "srte pcep pce-config",
197 .node
= PCEP_PCE_CONFIG_NODE
,
198 .parent_node
= PCEP_NODE
,
199 .prompt
= "%s(pce-sr-te-pcep-pce-config)# "
202 /* Common code used in VTYSH processing for int values */
203 #define PCEP_VTYSH_INT_ARG_CHECK(arg_str, arg_val, arg_store, min_value, \
205 if (arg_str != NULL) { \
206 if (arg_val <= min_value || arg_val >= max_value) { \
208 "%% Invalid value %ld in range [%d - %d]", \
209 arg_val, min_value, max_value); \
210 return CMD_WARNING; \
212 arg_store = arg_val; \
215 #define MERGE_COMPARE_CONFIG_GROUP_VALUE(config_param, not_set_value) \
216 pce_opts_cli->pce_opts.config_opts.config_param = \
217 pce_opts_cli->pce_config_group_opts.config_param; \
218 if (pce_opts_cli->pce_config_group_opts.config_param \
219 == not_set_value) { \
220 pce_opts_cli->pce_opts.config_opts.config_param = \
221 ((pce_config != NULL \
222 && pce_config->config_param != not_set_value) \
223 ? pce_config->config_param \
224 : default_pcep_config_group_opts_g \
229 * Internal Util functions
232 /* Check if a pce_opts_cli already exists based on its name and return it,
233 * return NULL otherwise */
234 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
)
236 for (int i
= 0; i
< MAX_PCE
; i
++) {
237 struct pce_opts_cli
*pce_rhs_cli
= pcep_g
->pce_opts_cli
[i
];
238 if (pce_rhs_cli
!= NULL
) {
239 if (strcmp(pce_name
, pce_rhs_cli
->pce_opts
.pce_name
)
249 /* Add a new pce_opts_cli to pcep_g, return false if MAX_PCES, true otherwise */
250 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
)
252 for (int i
= 0; i
< MAX_PCE
; i
++) {
253 if (pcep_g
->pce_opts_cli
[i
] == NULL
) {
254 pcep_g
->pce_opts_cli
[i
] = pce_opts_cli
;
255 pcep_g
->num_pce_opts_cli
++;
263 /* Create a new pce opts_cli */
264 static struct pce_opts_cli
*pcep_cli_create_pce_opts(const char *name
)
266 struct pce_opts_cli
*pce_opts_cli
=
267 XCALLOC(MTYPE_PCEP
, sizeof(struct pce_opts_cli
));
268 strlcpy(pce_opts_cli
->pce_opts
.pce_name
, name
,
269 sizeof(pce_opts_cli
->pce_opts
.pce_name
));
270 pce_opts_cli
->pce_opts
.port
= PCEP_DEFAULT_PORT
;
275 static void pcep_cli_delete_pce(const char *pce_name
)
277 for (int i
= 0; i
< MAX_PCE
; i
++) {
278 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
279 if (strcmp(pcep_g
->pce_opts_cli
[i
]->pce_opts
.pce_name
,
282 XFREE(MTYPE_PCEP
, pcep_g
->pce_opts_cli
[i
]);
283 pcep_g
->pce_opts_cli
[i
] = NULL
;
284 pcep_g
->num_pce_opts_cli
--;
292 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
)
294 if (pce_opts_cli
->merged
== true) {
298 struct pcep_config_group_opts
*pce_config
=
299 pcep_cli_find_pcep_pce_config(pce_opts_cli
->config_group_name
);
301 /* Configuration priorities:
302 * 1) pce_opts->config_opts, if present, overwrite pce_config
303 * config_opts 2) pce_config config_opts, if present, overwrite
304 * default config_opts 3) If neither pce_opts->config_opts nor
305 * pce_config config_opts are set, then the default config_opts value
309 const char *tcp_md5_auth_str
=
310 pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
;
311 if (pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
[0] == '\0') {
312 if (pce_config
!= NULL
&& pce_config
->tcp_md5_auth
[0] != '\0') {
313 tcp_md5_auth_str
= pce_config
->tcp_md5_auth
;
316 default_pcep_config_group_opts_g
.tcp_md5_auth
;
319 strlcpy(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
,
321 sizeof(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
));
323 struct ipaddr
*source_ip
=
324 &pce_opts_cli
->pce_config_group_opts
.source_ip
;
325 if (pce_opts_cli
->pce_config_group_opts
.source_ip
.ipa_type
327 if (pce_config
!= NULL
328 && pce_config
->source_ip
.ipa_type
!= IPADDR_NONE
) {
329 source_ip
= &pce_config
->source_ip
;
331 source_ip
= &default_pcep_config_group_opts_g
.source_ip
;
334 memcpy(&pce_opts_cli
->pce_opts
.config_opts
.source_ip
, source_ip
,
335 sizeof(struct ipaddr
));
337 MERGE_COMPARE_CONFIG_GROUP_VALUE(draft07
, false);
338 MERGE_COMPARE_CONFIG_GROUP_VALUE(pce_initiated
, false);
339 MERGE_COMPARE_CONFIG_GROUP_VALUE(keep_alive_seconds
, 0);
340 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_keep_alive_seconds
, 0);
341 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_keep_alive_seconds
, 0);
342 MERGE_COMPARE_CONFIG_GROUP_VALUE(dead_timer_seconds
, 0);
343 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_dead_timer_seconds
, 0);
344 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_dead_timer_seconds
, 0);
345 MERGE_COMPARE_CONFIG_GROUP_VALUE(pcep_request_time_seconds
, 0);
346 MERGE_COMPARE_CONFIG_GROUP_VALUE(session_timeout_inteval_seconds
, 0);
347 MERGE_COMPARE_CONFIG_GROUP_VALUE(delegation_timeout_seconds
, 0);
348 MERGE_COMPARE_CONFIG_GROUP_VALUE(source_port
, 0);
350 pce_opts_cli
->merged
= true;
353 /* Check if a pcep_config_group_opts already exists based on its name and return
354 * it, return NULL otherwise */
355 static struct pcep_config_group_opts
*
356 pcep_cli_find_pcep_pce_config(const char *group_name
)
358 for (int i
= 0; i
< MAX_PCE
; i
++) {
359 struct pcep_config_group_opts
*pcep_pce_config_rhs
=
360 pcep_g
->config_group_opts
[i
];
361 if (pcep_pce_config_rhs
!= NULL
) {
362 if (strcmp(group_name
, pcep_pce_config_rhs
->name
)
364 return pcep_pce_config_rhs
;
372 /* Add a new pcep_config_group_opts to pcep_g, return false if MAX_PCE,
374 static bool pcep_cli_add_pcep_pce_config(
375 struct pcep_config_group_opts
*pcep_config_group_opts
)
377 for (int i
= 0; i
< MAX_PCE
; i
++) {
378 if (pcep_g
->config_group_opts
[i
] == NULL
) {
379 pcep_g
->config_group_opts
[i
] = pcep_config_group_opts
;
380 pcep_g
->num_config_group_opts
++;
388 /* Create a new pce group, inheriting its values from the default pce group */
389 static struct pcep_config_group_opts
*
390 pcep_cli_create_pcep_pce_config(const char *group_name
)
392 struct pcep_config_group_opts
*pcep_config_group_opts
=
393 XCALLOC(MTYPE_PCEP
, sizeof(struct pcep_config_group_opts
));
394 strlcpy(pcep_config_group_opts
->name
, group_name
,
395 sizeof(pcep_config_group_opts
->name
));
397 return pcep_config_group_opts
;
400 /* Iterate the pce_opts and return true if the pce-group-name is referenced,
401 * false otherwise. */
402 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
)
404 for (int i
= 0; i
< MAX_PCE
; i
++) {
405 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
406 if (strcmp(pcep_g
->pce_opts_cli
[i
]->config_group_name
,
417 static void pcep_cli_delete_pcep_pce_config(const char *group_name
)
419 for (int i
= 0; i
< MAX_PCE
; i
++) {
420 if (pcep_g
->config_group_opts
[i
] != NULL
) {
421 if (strcmp(pcep_g
->config_group_opts
[i
]->name
,
424 XFREE(MTYPE_PCEP
, pcep_g
->config_group_opts
[i
]);
425 pcep_g
->config_group_opts
[i
] = NULL
;
426 pcep_g
->num_config_group_opts
--;
433 static bool pcep_cli_pcc_has_pce(const char *pce_name
)
435 for (int i
= 0; i
< MAX_PCC
; i
++) {
436 struct pce_opts
*pce_opts
= pce_connections_g
.connections
[i
];
437 if (pce_opts
== NULL
) {
441 if (strcmp(pce_opts
->pce_name
, pce_name
) == 0) {
449 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
)
451 for (int i
= 0; i
< MAX_PCC
; i
++) {
452 if (pce_connections_g
.connections
[i
] == NULL
) {
453 pce_connections_g
.num_connections
++;
454 pce_connections_g
.connections
[i
] = pce_opts
;
460 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
)
462 for (int i
= 0; i
< MAX_PCC
; i
++) {
463 if (pce_connections_g
.connections
[i
] == pce_opts
) {
464 pce_connections_g
.num_connections
--;
465 pce_connections_g
.connections
[i
] = NULL
;
472 * VTY command implementations
475 static int path_pcep_cli_debug(struct vty
*vty
, const char *no_str
,
476 const char *basic_str
, const char *path_str
,
477 const char *message_str
, const char *pceplib_str
)
479 uint32_t mode
= DEBUG_NODE2MODE(vty
->node
);
480 bool no
= (no_str
!= NULL
);
482 DEBUG_MODE_SET(&pcep_g
->dbg
, mode
, !no
);
484 if (basic_str
!= NULL
) {
485 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
, !no
);
487 if (path_str
!= NULL
) {
488 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
, !no
);
490 if (message_str
!= NULL
) {
491 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
, !no
);
493 if (pceplib_str
!= NULL
) {
494 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
, !no
);
500 static int path_pcep_cli_show_srte_pcep_counters(struct vty
*vty
)
506 struct counters_group
*group
;
507 struct counters_subgroup
*subgroup
;
508 struct counter
*counter
;
509 const char *group_name
, *empty_string
= "";
513 group
= pcep_ctrl_get_counters(pcep_g
->fpt
, 1);
516 vty_out(vty
, "No counters to display.\n\n");
520 diff_time
= time(NULL
) - group
->start_time
;
521 localtime_r(&group
->start_time
, &tm_info
);
522 strftime(tm_buffer
, sizeof(tm_buffer
), "%Y-%m-%d %H:%M:%S", &tm_info
);
524 vty_out(vty
, "PCEP counters since %s (%uh %um %us):\n", tm_buffer
,
525 (uint32_t)(diff_time
/ 3600), (uint32_t)((diff_time
/ 60) % 60),
526 (uint32_t)(diff_time
% 60));
529 tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
530 ttable_add_row(tt
, "Group|Name|Value");
531 tt
->style
.cell
.rpad
= 2;
532 tt
->style
.corner
= '+';
534 ttable_rowseps(tt
, 0, BOTTOM
, true, '-');
536 for (row
= 0, i
= 0; i
<= group
->num_subgroups
; i
++) {
537 subgroup
= group
->subgroups
[i
];
538 if (subgroup
!= NULL
) {
539 group_name
= subgroup
->counters_subgroup_name
;
540 for (j
= 0; j
<= subgroup
->num_counters
; j
++) {
541 counter
= subgroup
->counters
[j
];
542 if (counter
!= NULL
) {
543 ttable_add_row(tt
, "%s|%s|%u",
545 counter
->counter_name
,
546 counter
->counter_value
);
548 group_name
= empty_string
;
551 ttable_rowseps(tt
, row
, BOTTOM
, true, '-');
555 /* Dump the generated table. */
556 table
= ttable_dump(tt
, "\n");
557 vty_out(vty
, "%s\n", table
);
558 XFREE(MTYPE_TMP
, table
);
562 pcep_lib_free_counters(group
);
567 static int path_pcep_cli_pcep_pce_config(struct vty
*vty
,
568 const char *pcep_pce_config
)
570 struct pcep_config_group_opts
*pce_config
=
571 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
572 if (pce_config
== NULL
) {
573 pce_config
= pcep_cli_create_pcep_pce_config(pcep_pce_config
);
574 if (pcep_cli_add_pcep_pce_config(pce_config
) == false) {
576 "%% Cannot create pce-config, as the Maximum limit of %d pce-config has been reached.\n",
578 XFREE(MTYPE_PCEP
, pce_config
);
583 "Notice: changes to this pce-config will not affect PCEs already configured with this group\n");
586 current_pcep_config_group_opts_g
= pce_config
;
587 vty
->node
= PCEP_PCE_CONFIG_NODE
;
592 static int path_pcep_cli_pcep_pce_config_delete(struct vty
*vty
,
593 const char *pcep_pce_config
)
595 struct pcep_config_group_opts
*pce_config
=
596 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
597 if (pce_config
== NULL
) {
599 "%% Cannot delete pce-config, since it does not exist.\n");
603 if (pcep_cli_is_pcep_pce_config_used(pce_config
->name
)) {
605 "%% Cannot delete pce-config, since it is in use by a peer.\n");
609 pcep_cli_delete_pcep_pce_config(pce_config
->name
);
614 static int path_pcep_cli_show_srte_pcep_pce_config(struct vty
*vty
,
615 const char *pcep_pce_config
)
619 /* Only show 1 Peer config group */
620 struct pcep_config_group_opts
*group_opts
;
621 if (pcep_pce_config
!= NULL
) {
622 if (strcmp(pcep_pce_config
, "default") == 0) {
623 group_opts
= &default_pcep_config_group_opts_g
;
626 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
628 if (group_opts
== NULL
) {
629 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
634 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
635 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
636 vty_out(vty
, "%s", buf
);
640 /* Show all Peer config groups */
641 for (int i
= 0; i
< MAX_PCE
; i
++) {
642 group_opts
= pcep_g
->config_group_opts
[i
];
643 if (group_opts
== NULL
) {
647 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
648 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
649 vty_out(vty
, "%s", buf
);
656 static int path_pcep_cli_pce(struct vty
*vty
, const char *pce_peer_name
)
658 /* If it already exists, it will be updated in the sub-commands */
659 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
660 if (pce_opts_cli
== NULL
) {
661 pce_opts_cli
= pcep_cli_create_pce_opts(pce_peer_name
);
663 if (!pcep_cli_add_pce(pce_opts_cli
)) {
665 "%% Cannot create PCE, as the Maximum limit of %d PCEs has been reached.\n",
667 XFREE(MTYPE_PCEP
, pce_opts_cli
);
672 current_pce_opts_g
= pce_opts_cli
;
673 vty
->node
= PCEP_PCE_NODE
;
678 static int path_pcep_cli_pce_delete(struct vty
*vty
, const char *pce_peer_name
)
680 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
681 if (pce_opts_cli
== NULL
) {
682 vty_out(vty
, "%% PCC peer does not exist.\n");
686 /* To better work with frr-reload, go ahead and delete it if its in use
688 if (pcep_cli_pcc_has_pce(pce_peer_name
)) {
690 "%% Notice: the pce is in use by a PCC, also disconnecting.\n");
691 path_pcep_cli_pcc_pcc_peer_delete(vty
, pce_peer_name
, NULL
, 0);
694 pcep_cli_delete_pce(pce_peer_name
);
699 /* Internal Util func to show an individual PCE,
700 * only used by path_pcep_cli_show_srte_pcep_pce() */
701 static void show_pce_peer(struct vty
*vty
, struct pce_opts_cli
*pce_opts_cli
)
703 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
704 vty_out(vty
, "PCE: %s\n", pce_opts
->pce_name
);
706 /* Remote PCE IP address */
707 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
708 vty_out(vty
, " %s %s %pI6 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
709 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
,
710 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
712 vty_out(vty
, " %s %s %pI4 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
713 PCEP_VTYSH_ARG_IP
, &pce_opts
->addr
.ipaddr_v4
,
714 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
717 if (pce_opts_cli
->config_group_name
[0] != '\0') {
718 vty_out(vty
, " pce-config: %s\n",
719 pce_opts_cli
->config_group_name
);
723 pcep_cli_print_pce_config(&pce_opts
->config_opts
, buf
, sizeof(buf
));
724 vty_out(vty
, "%s", buf
);
727 static int path_pcep_cli_show_srte_pcep_pce(struct vty
*vty
,
728 const char *pce_peer
)
730 /* Only show 1 PCE */
731 struct pce_opts_cli
*pce_opts_cli
;
732 if (pce_peer
!= NULL
) {
733 pce_opts_cli
= pcep_cli_find_pce(pce_peer
);
734 if (pce_opts_cli
== NULL
) {
735 vty_out(vty
, "%% PCE [%s] does not exist.\n", pce_peer
);
739 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
740 show_pce_peer(vty
, pce_opts_cli
);
746 for (int i
= 0; i
< MAX_PCE
; i
++) {
747 pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
748 if (pce_opts_cli
== NULL
) {
752 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
753 show_pce_peer(vty
, pce_opts_cli
);
759 static int path_pcep_cli_peer_sr_draft07(struct vty
*vty
)
761 struct pcep_config_group_opts
*pce_config
= NULL
;
763 if (vty
->node
== PCEP_PCE_NODE
) {
764 /* TODO need to see if the pce is in use, and reset the
766 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
767 current_pce_opts_g
->merged
= false;
768 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
769 pce_config
= current_pcep_config_group_opts_g
;
771 return CMD_ERR_NO_MATCH
;
774 pce_config
->draft07
= true;
779 static int path_pcep_cli_peer_pce_initiated(struct vty
*vty
)
781 struct pcep_config_group_opts
*pce_config
= NULL
;
783 if (vty
->node
== PCEP_PCE_NODE
) {
784 /* TODO need to see if the pce is in use, and reset the
786 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
787 current_pce_opts_g
->merged
= false;
788 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
789 pce_config
= current_pcep_config_group_opts_g
;
791 return CMD_ERR_NO_MATCH
;
794 pce_config
->pce_initiated
= true;
799 static int path_pcep_cli_peer_tcp_md5_auth(struct vty
*vty
,
800 const char *tcp_md5_auth
)
802 struct pcep_config_group_opts
*pce_config
= NULL
;
804 if (vty
->node
== PCEP_PCE_NODE
) {
805 /* TODO need to see if the pce is in use, and reset the
807 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
808 current_pce_opts_g
->merged
= false;
809 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
810 pce_config
= current_pcep_config_group_opts_g
;
812 return CMD_ERR_NO_MATCH
;
815 strlcpy(pce_config
->tcp_md5_auth
, tcp_md5_auth
,
816 sizeof(pce_config
->tcp_md5_auth
));
821 static int path_pcep_cli_peer_address(struct vty
*vty
, const char *ip_str
,
822 struct in_addr
*ip
, const char *ipv6_str
,
823 struct in6_addr
*ipv6
,
824 const char *port_str
, long port
)
826 struct pce_opts
*pce_opts
= NULL
;
827 if (vty
->node
== PCEP_PCE_NODE
) {
828 /* TODO need to see if the pce is in use, and reset the
830 pce_opts
= ¤t_pce_opts_g
->pce_opts
;
831 current_pce_opts_g
->merged
= false;
833 return CMD_ERR_NO_MATCH
;
836 if (ipv6_str
!= NULL
) {
837 pce_opts
->addr
.ipa_type
= IPADDR_V6
;
838 memcpy(&pce_opts
->addr
.ipaddr_v6
, ipv6
,
839 sizeof(struct in6_addr
));
840 } else if (ip_str
!= NULL
) {
841 pce_opts
->addr
.ipa_type
= IPADDR_V4
;
842 memcpy(&pce_opts
->addr
.ipaddr_v4
, ip
, sizeof(struct in_addr
));
844 return CMD_ERR_NO_MATCH
;
847 /* Handle the optional port */
848 pce_opts
->port
= PCEP_DEFAULT_PORT
;
849 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_opts
->port
, 0, 65535);
854 static int path_pcep_cli_peer_source_address(struct vty
*vty
,
857 const char *ipv6_str
,
858 struct in6_addr
*ipv6
,
859 const char *port_str
, long port
)
861 struct pcep_config_group_opts
*pce_config
= NULL
;
862 if (vty
->node
== PCEP_PCE_NODE
) {
863 /* TODO need to see if the pce is in use, and reset the
865 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
866 current_pce_opts_g
->merged
= false;
867 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
868 pce_config
= current_pcep_config_group_opts_g
;
870 return CMD_ERR_NO_MATCH
;
873 /* Handle the optional source IP */
874 if (ipv6_str
!= NULL
) {
875 pce_config
->source_ip
.ipa_type
= IPADDR_V6
;
876 memcpy(&pce_config
->source_ip
.ipaddr_v6
, ipv6
,
877 sizeof(struct in6_addr
));
878 } else if (ip_str
!= NULL
) {
879 pce_config
->source_ip
.ipa_type
= IPADDR_V4
;
880 memcpy(&pce_config
->source_ip
.ipaddr_v4
, ip
,
881 sizeof(struct in_addr
));
884 /* Handle the optional port */
885 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_config
->source_port
, 0,
891 static int path_pcep_cli_peer_pcep_pce_config_ref(struct vty
*vty
,
892 const char *config_group_name
)
894 if (vty
->node
== PCEP_PCE_NODE
) {
895 /* TODO need to see if the pce is in use, and reset the
897 current_pce_opts_g
->merged
= false;
899 return CMD_ERR_NO_MATCH
;
902 struct pcep_config_group_opts
*pce_config
=
903 pcep_cli_find_pcep_pce_config(config_group_name
);
904 if (pce_config
== NULL
) {
905 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
910 strlcpy(current_pce_opts_g
->config_group_name
, config_group_name
,
911 sizeof(current_pce_opts_g
->config_group_name
));
916 static int path_pcep_cli_peer_timers(
917 struct vty
*vty
, const char *keep_alive_str
, long keep_alive
,
918 const char *min_peer_keep_alive_str
, long min_peer_keep_alive
,
919 const char *max_peer_keep_alive_str
, long max_peer_keep_alive
,
920 const char *dead_timer_str
, long dead_timer
,
921 const char *min_peer_dead_timer_str
, long min_peer_dead_timer
,
922 const char *max_peer_dead_timer_str
, long max_peer_dead_timer
,
923 const char *pcep_request_str
, long pcep_request
,
924 const char *session_timeout_interval_str
, long session_timeout_interval
,
925 const char *delegation_timeout_str
, long delegation_timeout
)
927 struct pcep_config_group_opts
*pce_config
= NULL
;
928 if (vty
->node
== PCEP_PCE_NODE
) {
929 /* TODO need to see if the pce is in use, and reset the
931 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
932 current_pce_opts_g
->merged
= false;
933 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
934 pce_config
= current_pcep_config_group_opts_g
;
936 return CMD_ERR_NO_MATCH
;
939 if (min_peer_keep_alive
&& max_peer_keep_alive
)
940 if (min_peer_keep_alive
>= max_peer_keep_alive
) {
941 return CMD_ERR_NO_MATCH
;
944 if (min_peer_dead_timer
&& max_peer_dead_timer
)
945 if (min_peer_dead_timer
>= max_peer_dead_timer
) {
946 return CMD_ERR_NO_MATCH
;
949 /* Handle the arguments */
950 PCEP_VTYSH_INT_ARG_CHECK(keep_alive_str
, keep_alive
,
951 pce_config
->keep_alive_seconds
, 0, 64);
952 PCEP_VTYSH_INT_ARG_CHECK(min_peer_keep_alive_str
, min_peer_keep_alive
,
953 pce_config
->min_keep_alive_seconds
, 0, 256);
954 PCEP_VTYSH_INT_ARG_CHECK(max_peer_keep_alive_str
, max_peer_keep_alive
,
955 pce_config
->max_keep_alive_seconds
, 0, 256);
956 PCEP_VTYSH_INT_ARG_CHECK(dead_timer_str
, dead_timer
,
957 pce_config
->dead_timer_seconds
, 3, 256);
958 PCEP_VTYSH_INT_ARG_CHECK(min_peer_dead_timer_str
, min_peer_dead_timer
,
959 pce_config
->min_dead_timer_seconds
, 3, 256);
960 PCEP_VTYSH_INT_ARG_CHECK(max_peer_dead_timer_str
, max_peer_dead_timer
,
961 pce_config
->max_dead_timer_seconds
, 3, 256);
962 PCEP_VTYSH_INT_ARG_CHECK(pcep_request_str
, pcep_request
,
963 pce_config
->pcep_request_time_seconds
, 0, 121);
964 PCEP_VTYSH_INT_ARG_CHECK(
965 session_timeout_interval_str
, session_timeout_interval
,
966 pce_config
->session_timeout_inteval_seconds
, 0, 121);
967 PCEP_VTYSH_INT_ARG_CHECK(delegation_timeout_str
, delegation_timeout
,
968 pce_config
->delegation_timeout_seconds
, 0, 61);
973 static int path_pcep_cli_pcc(struct vty
*vty
)
975 VTY_PUSH_CONTEXT_NULL(PCEP_PCC_NODE
);
980 static int path_pcep_cli_pcc_delete(struct vty
*vty
)
982 /* Clear the pce_connections */
983 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
984 pcc_msd_configured_g
= false;
986 pcep_ctrl_remove_pcc(pcep_g
->fpt
, NULL
);
991 static int path_pcep_cli_pcc_pcc_msd(struct vty
*vty
, const char *msd_str
,
994 pcc_msd_configured_g
= true;
995 PCEP_VTYSH_INT_ARG_CHECK(msd_str
, msd
, pcc_msd_g
, 0, 33);
1000 static int path_pcep_cli_pcc_pcc_peer(struct vty
*vty
, const char *peer_name
,
1001 const char *precedence_str
,
1004 /* Check if the pcc-peer exists */
1005 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1006 if (pce_opts_cli
== NULL
) {
1007 vty_out(vty
, "%% PCE [%s] does not exist.\n", peer_name
);
1010 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1012 /* Check if the pcc-peer is duplicated */
1013 if (pcep_cli_pcc_has_pce(peer_name
)) {
1014 vty_out(vty
, "%% The peer [%s] has already been configured.\n",
1019 /* Get the optional precedence argument */
1020 pce_opts
->precedence
= DEFAULT_PCE_PRECEDENCE
;
1021 PCEP_VTYSH_INT_ARG_CHECK(precedence_str
, precedence
,
1022 pce_opts
->precedence
, 0, 256);
1024 /* Finalize the pce_opts config values */
1025 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
1026 pcep_cli_add_pce_connection(&pce_opts_cli
->pce_opts
);
1028 /* Verify the PCE has the IP set */
1029 struct in6_addr zero_v6_addr
;
1030 memset(&zero_v6_addr
, 0, sizeof(struct in6_addr
));
1031 if (memcmp(&pce_opts
->addr
.ip
, &zero_v6_addr
, IPADDRSZ(&pce_opts
->addr
))
1034 "%% The peer [%s] does not have an IP set and cannot be used until it does.\n",
1039 /* Update the pcc_opts with the source ip, port, and msd */
1040 struct pcc_opts
*pcc_opts_copy
=
1041 XMALLOC(MTYPE_PCEP
, sizeof(struct pcc_opts
));
1042 memcpy(&pcc_opts_copy
->addr
,
1043 &pce_opts_cli
->pce_opts
.config_opts
.source_ip
,
1044 sizeof(pcc_opts_copy
->addr
));
1045 pcc_opts_copy
->msd
= pcc_msd_g
;
1046 pcc_opts_copy
->port
= pce_opts_cli
->pce_opts
.config_opts
.source_port
;
1047 if (pcep_ctrl_update_pcc_options(pcep_g
->fpt
, pcc_opts_copy
)) {
1051 /* Send a copy of the pce_opts, this one is only used for the CLI */
1052 struct pce_opts
*pce_opts_copy
=
1053 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1054 memcpy(pce_opts_copy
, pce_opts
, sizeof(struct pce_opts
));
1055 if (pcep_ctrl_update_pce_options(pcep_g
->fpt
, pce_opts_copy
)) {
1062 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
1063 const char *peer_name
,
1064 const char *precedence_str
,
1067 /* Check if the pcc-peer is connected to the PCC */
1068 if (!pcep_cli_pcc_has_pce(peer_name
)) {
1070 "%% WARN: The peer [%s] is not connected to the PCC.\n",
1075 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1076 pcep_cli_remove_pce_connection(&pce_opts_cli
->pce_opts
);
1078 /* Send a copy of the pce_opts, this one is used for CLI only */
1079 struct pce_opts
*pce_opts_copy
=
1080 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1081 memcpy(pce_opts_copy
, &pce_opts_cli
->pce_opts
, sizeof(struct pce_opts
));
1082 pcep_ctrl_remove_pcc(pcep_g
->fpt
, pce_opts_copy
);
1087 static int path_pcep_cli_show_srte_pcep_pcc(struct vty
*vty
)
1089 vty_out(vty
, "pcc msd %d\n", pcc_msd_g
);
1094 /* Internal util function to print pcep capabilities to a buffer */
1095 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
1096 pcep_configuration
*config
)
1098 if (config
->support_stateful_pce_lsp_update
) {
1099 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_STATEFUL
);
1101 if (config
->support_include_db_version
) {
1102 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_INCL_DB_VER
);
1104 if (config
->support_lsp_triggered_resync
) {
1105 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_TRIGGERED
);
1107 if (config
->support_lsp_delta_sync
) {
1108 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_DELTA
);
1110 if (config
->support_pce_triggered_initial_sync
) {
1111 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCE_TRIGGERED
);
1113 if (config
->support_sr_te_pst
) {
1114 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_SR_TE_PST
);
1116 if (config
->pcc_can_resolve_nai_to_sid
) {
1117 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCC_RESOLVE_NAI
);
1121 /* Internal util function to print a pcep session */
1122 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
1123 struct pcep_pcc_info
*pcc_info
)
1128 vty_out(vty
, "\nPCE %s\n", pce_opts
->pce_name
);
1131 if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1132 vty_out(vty
, " PCE IP %pI4 port %d\n",
1133 &pce_opts
->addr
.ipaddr_v4
, pce_opts
->port
);
1134 } else if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1135 vty_out(vty
, " PCE IPv6 %pI6 port %d\n",
1136 &pce_opts
->addr
.ipaddr_v6
, pce_opts
->port
);
1140 if (IS_IPADDR_V4(&pcc_info
->pcc_addr
)) {
1141 vty_out(vty
, " PCC IP %pI4 port %d\n",
1142 &pcc_info
->pcc_addr
.ipaddr_v4
, pcc_info
->pcc_port
);
1143 } else if (IS_IPADDR_V6(&pcc_info
->pcc_addr
)) {
1144 vty_out(vty
, " PCC IPv6 %pI6 port %d\n",
1145 &pcc_info
->pcc_addr
.ipaddr_v6
, pcc_info
->pcc_port
);
1147 vty_out(vty
, " PCC MSD %d\n", pcc_info
->msd
);
1149 if (pcc_info
->status
== PCEP_PCC_OPERATING
) {
1150 vty_out(vty
, " Session Status UP\n");
1152 vty_out(vty
, " Session Status %s\n",
1153 pcc_status_name(pcc_info
->status
));
1156 if (pcc_info
->is_best_multi_pce
) {
1157 vty_out(vty
, " Precedence %d, best candidate\n",
1158 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1159 : DEFAULT_PCE_PRECEDENCE
));
1161 vty_out(vty
, " Precedence %d\n",
1162 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1163 : DEFAULT_PCE_PRECEDENCE
));
1165 vty_out(vty
, " Confidence %s\n",
1166 ((pcc_info
->previous_best
) ? "low"
1169 /* PCEPlib pcep session values, get a thread safe copy of the counters
1171 pcep_session
*session
=
1172 pcep_ctrl_get_pcep_session(pcep_g
->fpt
, pcc_info
->pcc_id
);
1174 /* Config Options values */
1175 struct pcep_config_group_opts
*config_opts
= &pce_opts
->config_opts
;
1176 if (session
!= NULL
) {
1177 vty_out(vty
, " Timer: KeepAlive config %d, pce-negotiated %d\n",
1178 config_opts
->keep_alive_seconds
,
1180 .keep_alive_pce_negotiated_timer_seconds
);
1181 vty_out(vty
, " Timer: DeadTimer config %d, pce-negotiated %d\n",
1182 config_opts
->dead_timer_seconds
,
1183 session
->pcc_config
.dead_timer_pce_negotiated_seconds
);
1185 vty_out(vty
, " Timer: KeepAlive %d\n",
1186 config_opts
->keep_alive_seconds
);
1187 vty_out(vty
, " Timer: DeadTimer %d\n",
1188 config_opts
->dead_timer_seconds
);
1190 vty_out(vty
, " Timer: PcRequest %d\n",
1191 config_opts
->pcep_request_time_seconds
);
1192 vty_out(vty
, " Timer: SessionTimeout Interval %d\n",
1193 config_opts
->session_timeout_inteval_seconds
);
1194 vty_out(vty
, " Timer: Delegation Timeout %d\n",
1195 config_opts
->delegation_timeout_seconds
);
1196 if (strlen(config_opts
->tcp_md5_auth
) > 0) {
1197 vty_out(vty
, " TCP MD5 Auth Str: %s\n",
1198 config_opts
->tcp_md5_auth
);
1200 vty_out(vty
, " No TCP MD5 Auth\n");
1203 if (config_opts
->draft07
) {
1204 vty_out(vty
, " PCE SR Version draft07\n");
1206 vty_out(vty
, " PCE SR Version draft16 and RFC8408\n");
1209 vty_out(vty
, " Next PcReq ID %d\n", pcc_info
->next_reqid
);
1210 vty_out(vty
, " Next PLSP ID %d\n", pcc_info
->next_plspid
);
1212 if (session
!= NULL
) {
1213 if (pcc_info
->status
== PCEP_PCC_SYNCHRONIZING
1214 || pcc_info
->status
== PCEP_PCC_OPERATING
) {
1215 time_t current_time
= time(NULL
);
1217 /* Just for the timezone */
1218 localtime_r(¤t_time
, <
);
1219 gmtime_r(&session
->time_connected
, <
);
1221 " Connected for %u seconds, since %d-%02d-%02d %02d:%02d:%02d UTC\n",
1222 (uint32_t)(current_time
1223 - session
->time_connected
),
1224 lt
.tm_year
+ 1900, lt
.tm_mon
+ 1, lt
.tm_mday
,
1225 lt
.tm_hour
, lt
.tm_min
, lt
.tm_sec
);
1228 /* PCC capabilities */
1231 if (config_opts
->pce_initiated
) {
1232 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1233 PCEP_CLI_CAP_PCC_PCE_INITIATED
);
1235 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1236 PCEP_CLI_CAP_PCC_INITIATED
);
1238 print_pcep_capabilities(buf
, sizeof(buf
) - index
,
1239 &session
->pcc_config
);
1240 vty_out(vty
, " PCC Capabilities:%s\n", buf
);
1242 /* PCE capabilities */
1244 print_pcep_capabilities(buf
, sizeof(buf
), &session
->pce_config
);
1245 if (buf
[0] != '\0') {
1246 vty_out(vty
, " PCE Capabilities:%s\n", buf
);
1248 XFREE(MTYPE_PCEP
, session
);
1250 vty_out(vty
, " Detailed session information not available\n");
1253 /* Message Counters, get a thread safe copy of the counters */
1254 struct counters_group
*group
=
1255 pcep_ctrl_get_counters(pcep_g
->fpt
, pcc_info
->pcc_id
);
1257 if (group
!= NULL
) {
1258 struct counters_subgroup
*rx_msgs
=
1259 find_subgroup(group
, COUNTER_SUBGROUP_ID_RX_MSG
);
1260 struct counters_subgroup
*tx_msgs
=
1261 find_subgroup(group
, COUNTER_SUBGROUP_ID_TX_MSG
);
1263 if (rx_msgs
!= NULL
&& tx_msgs
!= NULL
) {
1264 vty_out(vty
, " PCEP Message Statistics\n");
1265 vty_out(vty
, " %27s %6s\n", "Sent", "Rcvd");
1266 for (int i
= 0; i
< rx_msgs
->max_counters
; i
++) {
1267 struct counter
*rx_counter
=
1268 rx_msgs
->counters
[i
];
1269 struct counter
*tx_counter
=
1270 tx_msgs
->counters
[i
];
1271 if (rx_counter
!= NULL
&& tx_counter
!= NULL
) {
1272 vty_out(vty
, " %20s: %5d %5d\n",
1273 tx_counter
->counter_name
,
1274 tx_counter
->counter_value
,
1275 rx_counter
->counter_value
);
1278 vty_out(vty
, " %20s: %5d %5d\n", "Total",
1279 subgroup_counters_total(tx_msgs
),
1280 subgroup_counters_total(rx_msgs
));
1282 pcep_lib_free_counters(group
);
1284 vty_out(vty
, " Counters not available\n");
1287 XFREE(MTYPE_PCEP
, pcc_info
);
1290 static int path_pcep_cli_show_srte_pcep_session(struct vty
*vty
,
1291 const char *pcc_peer
)
1293 struct pce_opts_cli
*pce_opts_cli
;
1294 struct pcep_pcc_info
*pcc_info
;
1296 /* Only show 1 PCEP session */
1297 if (pcc_peer
!= NULL
) {
1298 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1299 if (pce_opts_cli
== NULL
) {
1300 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1304 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1305 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1310 pcc_info
= pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pcc_peer
);
1311 if (pcc_info
== NULL
) {
1313 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1318 print_pcep_session(vty
, &pce_opts_cli
->pce_opts
, pcc_info
);
1323 /* Show all PCEP sessions */
1324 struct pce_opts
*pce_opts
;
1325 int num_pcep_sessions_conf
= 0;
1326 int num_pcep_sessions_conn
= 0;
1327 for (int i
= 0; i
< MAX_PCC
; i
++) {
1328 pce_opts
= pce_connections_g
.connections
[i
];
1329 if (pce_opts
== NULL
) {
1334 pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pce_opts
->pce_name
);
1335 if (pcc_info
== NULL
) {
1337 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1338 pce_opts
->pce_name
);
1342 num_pcep_sessions_conn
+=
1343 pcc_info
->status
== PCEP_PCC_OPERATING
? 1 : 0;
1344 num_pcep_sessions_conf
++;
1345 print_pcep_session(vty
, pce_opts
, pcc_info
);
1348 vty_out(vty
, "PCEP Sessions => Configured %d ; Connected %d\n",
1349 num_pcep_sessions_conf
, num_pcep_sessions_conn
);
1354 static int path_pcep_cli_clear_srte_pcep_session(struct vty
*vty
,
1355 const char *pcc_peer
)
1357 struct pce_opts_cli
*pce_opts_cli
;
1359 /* Only clear 1 PCEP session */
1360 if (pcc_peer
!= NULL
) {
1361 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1362 if (pce_opts_cli
== NULL
) {
1363 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1367 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1368 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1373 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
,
1374 pce_opts_cli
->pce_opts
.pce_name
);
1375 vty_out(vty
, "PCEP session cleared for peer %s\n", pcc_peer
);
1380 /* Clear all PCEP sessions */
1381 struct pce_opts
*pce_opts
;
1382 int num_pcep_sessions
= 0;
1383 for (int i
= 0; i
< MAX_PCC
; i
++) {
1384 pce_opts
= pce_connections_g
.connections
[i
];
1385 if (pce_opts
== NULL
) {
1389 num_pcep_sessions
++;
1390 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
, pce_opts
->pce_name
);
1391 vty_out(vty
, "PCEP session cleared for peer %s\n",
1392 pce_opts
->pce_name
);
1395 vty_out(vty
, "Cleared [%d] PCEP sessions\n", num_pcep_sessions
);
1401 * Config Write functions
1404 int pcep_cli_debug_config_write(struct vty
*vty
)
1406 char buff
[128] = "";
1408 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1409 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1410 csnprintfrr(buff
, sizeof(buff
), " %s",
1411 PCEP_VTYSH_ARG_BASIC
);
1412 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1413 csnprintfrr(buff
, sizeof(buff
), " %s",
1414 PCEP_VTYSH_ARG_PATH
);
1415 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1416 csnprintfrr(buff
, sizeof(buff
), " %s",
1417 PCEP_VTYSH_ARG_MESSAGE
);
1418 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1419 csnprintfrr(buff
, sizeof(buff
), " %s",
1420 PCEP_VTYSH_ARG_PCEPLIB
);
1421 vty_out(vty
, "debug pathd pcep%s\n", buff
);
1429 int pcep_cli_debug_set_all(uint32_t flags
, bool set
)
1431 DEBUG_FLAGS_SET(&pcep_g
->dbg
, flags
, set
);
1433 /* If all modes have been turned off, don't preserve options. */
1434 if (!DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_ALL
))
1435 DEBUG_CLEAR(&pcep_g
->dbg
);
1440 int pcep_cli_pcep_config_write(struct vty
*vty
)
1442 vty_out(vty
, " pcep\n");
1443 pcep_cli_pcep_pce_config_write(vty
);
1444 pcep_cli_pce_config_write(vty
);
1445 pcep_cli_pcc_config_write(vty
);
1446 vty_out(vty
, " exit\n");
1450 int pcep_cli_pcc_config_write(struct vty
*vty
)
1452 struct pce_opts
*pce_opts
;
1456 /* The MSD, nor any PCE peers have been configured on the PCC */
1457 if (!pcc_msd_configured_g
&& pce_connections_g
.num_connections
== 0) {
1461 vty_out(vty
, " pcc\n");
1464 /* Prepare the MSD, if present */
1465 if (pcc_msd_configured_g
) {
1466 vty_out(vty
, " %s %d\n", PCEP_VTYSH_ARG_MSD
, pcc_msd_g
);
1470 if (pce_connections_g
.num_connections
== 0) {
1475 for (int i
= 0; i
< MAX_PCC
; i
++) {
1476 pce_opts
= pce_connections_g
.connections
[i
];
1477 if (pce_opts
== NULL
) {
1481 /* Only show the PCEs configured in the pcc sub-command */
1482 if (!pcep_cli_pcc_has_pce(pce_opts
->pce_name
)) {
1486 csnprintfrr(buf
, sizeof(buf
), " peer %s",
1487 pce_opts
->pce_name
);
1488 if (pce_opts
->precedence
> 0
1489 && pce_opts
->precedence
!= DEFAULT_PCE_PRECEDENCE
) {
1490 csnprintfrr(buf
, sizeof(buf
), " %s %d",
1491 PCEP_VTYSH_ARG_PRECEDENCE
,
1492 pce_opts
->precedence
);
1494 vty_out(vty
, "%s\n", buf
);
1499 vty_out(vty
, " exit\n");
1504 /* Internal function used by pcep_cli_pce_config_write()
1505 * and pcep_cli_pcep_pce_config_write() */
1506 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
1507 char *buf
, size_t buf_len
)
1511 if (group_opts
->source_ip
.ipa_type
!= IPADDR_NONE
1512 || group_opts
->source_port
!= 0) {
1513 csnprintfrr(buf
, buf_len
, " ");
1514 if (IS_IPADDR_V4(&group_opts
->source_ip
)) {
1515 csnprintfrr(buf
, buf_len
, " %s %s %pI4",
1516 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1518 &group_opts
->source_ip
.ipaddr_v4
);
1519 } else if (IS_IPADDR_V6(&group_opts
->source_ip
)) {
1520 csnprintfrr(buf
, buf_len
, " %s %s %pI6",
1521 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1522 PCEP_VTYSH_ARG_IPV6
,
1523 &group_opts
->source_ip
.ipaddr_v6
);
1525 if (group_opts
->source_port
> 0) {
1526 csnprintfrr(buf
, buf_len
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1527 group_opts
->source_port
);
1529 csnprintfrr(buf
, buf_len
, "\n");
1532 /* Group the keep-alive together for devman */
1533 if ((group_opts
->keep_alive_seconds
> 0)
1534 || (group_opts
->min_keep_alive_seconds
> 0)
1535 || (group_opts
->max_keep_alive_seconds
> 0)) {
1536 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1538 if (group_opts
->keep_alive_seconds
> 0) {
1539 csnprintfrr(buf
, buf_len
, " %s %d",
1540 PCEP_VTYSH_ARG_KEEP_ALIVE
,
1541 group_opts
->keep_alive_seconds
);
1543 if (group_opts
->min_keep_alive_seconds
> 0) {
1544 csnprintfrr(buf
, buf_len
, " %s %d",
1545 PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
,
1546 group_opts
->min_keep_alive_seconds
);
1548 if (group_opts
->max_keep_alive_seconds
> 0) {
1549 csnprintfrr(buf
, buf_len
, " %s %d",
1550 PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
,
1551 group_opts
->max_keep_alive_seconds
);
1553 csnprintfrr(buf
, buf_len
, "\n");
1557 /* Group the dead-timer together for devman */
1558 if ((group_opts
->dead_timer_seconds
> 0)
1559 || (group_opts
->min_dead_timer_seconds
> 0)
1560 || (group_opts
->max_dead_timer_seconds
> 0)) {
1561 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1563 if (group_opts
->dead_timer_seconds
> 0) {
1564 csnprintfrr(buf
, buf_len
, " %s %d",
1565 PCEP_VTYSH_ARG_DEAD_TIMER
,
1566 group_opts
->dead_timer_seconds
);
1568 if (group_opts
->min_dead_timer_seconds
> 0) {
1569 csnprintfrr(buf
, buf_len
, " %s %d",
1570 PCEP_VTYSH_ARG_DEAD_TIMER_MIN
,
1571 group_opts
->min_dead_timer_seconds
);
1573 if (group_opts
->max_dead_timer_seconds
> 0) {
1574 csnprintfrr(buf
, buf_len
, " %s %d",
1575 PCEP_VTYSH_ARG_DEAD_TIMER_MAX
,
1576 group_opts
->max_dead_timer_seconds
);
1578 csnprintfrr(buf
, buf_len
, "\n");
1582 if (group_opts
->pcep_request_time_seconds
> 0) {
1583 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1584 PCEP_VTYSH_ARG_TIMER
, PCEP_VTYSH_ARG_PCEP_REQUEST
,
1585 group_opts
->pcep_request_time_seconds
);
1588 if (group_opts
->delegation_timeout_seconds
> 0) {
1589 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1590 PCEP_VTYSH_ARG_TIMER
,
1591 PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
,
1592 group_opts
->delegation_timeout_seconds
);
1595 if (group_opts
->session_timeout_inteval_seconds
> 0) {
1596 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1597 PCEP_VTYSH_ARG_TIMER
,
1598 PCEP_VTYSH_ARG_SESSION_TIMEOUT
,
1599 group_opts
->session_timeout_inteval_seconds
);
1602 if (group_opts
->tcp_md5_auth
[0] != '\0') {
1603 csnprintfrr(buf
, buf_len
, " %s %s\n", PCEP_VTYSH_ARG_TCP_MD5
,
1604 group_opts
->tcp_md5_auth
);
1607 if (group_opts
->draft07
) {
1608 csnprintfrr(buf
, buf_len
, " %s\n",
1609 PCEP_VTYSH_ARG_SR_DRAFT07
);
1612 if (group_opts
->pce_initiated
) {
1613 csnprintfrr(buf
, buf_len
, " %s\n", PCEP_VTYSH_ARG_PCE_INIT
);
1620 int pcep_cli_pce_config_write(struct vty
*vty
)
1623 char buf
[1024] = "";
1625 for (int i
= 0; i
< MAX_PCE
; i
++) {
1626 struct pce_opts_cli
*pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
1627 if (pce_opts_cli
== NULL
) {
1630 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1632 vty_out(vty
, " pce %s\n", pce_opts
->pce_name
);
1633 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1634 vty_out(vty
, " %s %s %pI6", PCEP_VTYSH_ARG_ADDRESS
,
1635 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
);
1636 } else if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1637 vty_out(vty
, " address %s %pI4", PCEP_VTYSH_ARG_IP
,
1638 &pce_opts
->addr
.ipaddr_v4
);
1640 if (pce_opts
->port
!= PCEP_DEFAULT_PORT
) {
1641 vty_out(vty
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1644 vty_out(vty
, "%s\n", buf
);
1647 if (pce_opts_cli
->config_group_name
[0] != '\0') {
1648 vty_out(vty
, " config %s\n",
1649 pce_opts_cli
->config_group_name
);
1653 /* Only display the values configured on the PCE, not the values
1654 * from its optional pce-config-group, nor the default values */
1655 lines
+= pcep_cli_print_pce_config(
1656 &pce_opts_cli
->pce_config_group_opts
, buf
, sizeof(buf
));
1658 vty_out(vty
, "%s", buf
);
1661 vty_out(vty
, " exit\n");
1667 int pcep_cli_pcep_pce_config_write(struct vty
*vty
)
1670 char buf
[1024] = "";
1672 for (int i
= 0; i
< MAX_PCE
; i
++) {
1673 struct pcep_config_group_opts
*group_opts
=
1674 pcep_g
->config_group_opts
[i
];
1675 if (group_opts
== NULL
) {
1679 vty_out(vty
, " pce-config %s\n", group_opts
->name
);
1683 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
1684 vty_out(vty
, "%s", buf
);
1687 vty_out(vty
, " exit\n");
1694 * VTYSH command syntax definitions
1695 * The param names are taken from the path_pcep_cli_clippy.c generated file.
1698 DEFPY(show_debugging_pathd_pcep
,
1699 show_debugging_pathd_pcep_cmd
,
1700 "show debugging pathd-pcep",
1702 "State of each debugging option\n"
1703 "pathd pcep module debugging\n")
1705 vty_out(vty
, "Pathd pcep debugging status:\n");
1707 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1708 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1709 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1710 PCEP_VTYSH_ARG_BASIC
);
1711 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1712 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1713 PCEP_VTYSH_ARG_PATH
);
1714 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1715 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1716 PCEP_VTYSH_ARG_MESSAGE
);
1717 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1718 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1719 PCEP_VTYSH_ARG_PCEPLIB
);
1725 DEFPY(pcep_cli_debug
,
1727 "[no] debug pathd pcep [basic]$basic_str [path]$path_str [message]$message_str [pceplib]$pceplib_str",
1730 "pcep module debugging\n"
1731 "module basic debugging\n"
1732 "path structures debugging\n"
1733 "pcep message debugging\n"
1734 "pceplib debugging\n")
1736 return path_pcep_cli_debug(vty
, no
, basic_str
, path_str
, message_str
,
1740 DEFPY(pcep_cli_show_srte_pcep_counters
,
1741 pcep_cli_show_srte_pcep_counters_cmd
,
1742 "show sr-te pcep counters",
1748 return path_pcep_cli_show_srte_pcep_counters(vty
);
1755 "PCEP configuration\n")
1757 vty
->node
= PCEP_NODE
;
1762 pcep_cli_pcep_pce_config
,
1763 pcep_cli_pcep_pce_config_cmd
,
1764 "pce-config WORD$name",
1765 "Shared configuration\n"
1766 "Shared configuration name\n")
1768 return path_pcep_cli_pcep_pce_config(vty
, name
);
1771 DEFPY(pcep_cli_pcep_no_pce_config
,
1772 pcep_cli_pcep_no_pce_config_cmd
,
1773 "no pce-config WORD$name",
1775 "Shared configuration\n"
1776 "Shared configuration name\n")
1778 return path_pcep_cli_pcep_pce_config_delete(vty
, name
);
1781 DEFPY(pcep_cli_show_srte_pcep_pce_config
,
1782 pcep_cli_show_srte_pcep_pce_config_cmd
,
1783 "show sr-te pcep pce-config [<default|WORD>$name]",
1787 "Show shared PCE configuration\n"
1788 "Show default hard-coded values\n"
1789 "Shared configuration name\n")
1791 return path_pcep_cli_show_srte_pcep_pce_config(vty
, name
);
1798 "PCE configuration, address sub-config is mandatory\n"
1801 return path_pcep_cli_pce(vty
, name
);
1804 DEFPY(pcep_cli_no_pce
,
1805 pcep_cli_no_pce_cmd
,
1808 "PCE configuration, address sub-config is mandatory\n"
1811 return path_pcep_cli_pce_delete(vty
, name
);
1814 DEFPY(pcep_cli_show_srte_pcep_pce
,
1815 pcep_cli_show_srte_pcep_pce_cmd
,
1816 "show sr-te pcep pce [WORD$name]",
1820 "Show detailed pce values\n"
1823 return path_pcep_cli_show_srte_pcep_pce(vty
, name
);
1826 DEFPY(pcep_cli_peer_sr_draft07
,
1827 pcep_cli_peer_sr_draft07_cmd
,
1829 "Configure PCC to send PCEP Open with SR draft07\n")
1831 return path_pcep_cli_peer_sr_draft07(vty
);
1834 DEFPY(pcep_cli_peer_pce_initiated
,
1835 pcep_cli_peer_pce_initiated_cmd
,
1837 "Configure PCC to accept PCE initiated LSPs\n")
1839 return path_pcep_cli_peer_pce_initiated(vty
);
1842 DEFPY(pcep_cli_peer_tcp_md5_auth
,
1843 pcep_cli_peer_tcp_md5_auth_cmd
,
1844 "tcp-md5-auth WORD",
1845 "Configure PCC TCP-MD5 RFC2385 Authentication\n"
1846 "TCP-MD5 Authentication string\n")
1848 return path_pcep_cli_peer_tcp_md5_auth(vty
, tcp_md5_auth
);
1851 DEFPY(pcep_cli_peer_address
,
1852 pcep_cli_peer_address_cmd
,
1853 "address <ip A.B.C.D | ipv6 X:X::X:X> [port (1024-65535)]",
1854 "PCE IP Address configuration, mandatory configuration\n"
1855 "PCE IPv4 address\n"
1856 "Remote PCE server IPv4 address\n"
1857 "PCE IPv6 address\n"
1858 "Remote PCE server IPv6 address\n"
1859 "Remote PCE server port\n"
1860 "Remote PCE server port value\n")
1862 return path_pcep_cli_peer_address(vty
, ip_str
, &ip
, ipv6_str
, &ipv6
,
1866 DEFPY(pcep_cli_peer_source_address
,
1867 pcep_cli_peer_source_address_cmd
,
1868 "source-address [ip A.B.C.D | ipv6 X:X::X:X] [port (1024-65535)]",
1869 "PCE source IP Address configuration\n"
1870 "PCE source IPv4 address\n"
1871 "PCE source IPv4 address value\n"
1872 "PCE source IPv6 address\n"
1873 "PCE source IPv6 address value\n"
1874 "Source PCE server port\n"
1875 "Source PCE server port value\n")
1877 return path_pcep_cli_peer_source_address(vty
, ip_str
, &ip
, ipv6_str
,
1878 &ipv6
, port_str
, port
);
1881 DEFPY(pcep_cli_peer_pcep_pce_config_ref
,
1882 pcep_cli_peer_pcep_pce_config_ref_cmd
,
1884 "PCE shared configuration to use\n"
1885 "Shared configuration name\n")
1887 return path_pcep_cli_peer_pcep_pce_config_ref(vty
, name
);
1890 DEFPY(pcep_cli_peer_timers
,
1891 pcep_cli_peer_timers_cmd
,
1892 "timer [keep-alive (1-63)] [min-peer-keep-alive (1-255)] [max-peer-keep-alive (1-255)] "
1893 "[dead-timer (4-255)] [min-peer-dead-timer (4-255)] [max-peer-dead-timer (4-255)] "
1894 "[pcep-request (1-120)] [session-timeout-interval (1-120)] [delegation-timeout (1-60)]",
1895 "PCE PCEP Session Timers configuration\n"
1896 "PCC Keep Alive Timer\n"
1897 "PCC Keep Alive Timer value in seconds\n"
1898 "Min Acceptable PCE Keep Alive Timer\n"
1899 "Min Acceptable PCE Keep Alive Timer value in seconds\n"
1900 "Max Acceptable PCE Keep Alive Timer\n"
1901 "Max Acceptable PCE Keep Alive Timer value in seconds\n"
1903 "PCC Dead Timer value in seconds\n"
1904 "Min Acceptable PCE Dead Timer\n"
1905 "Min Acceptable PCE Dead Timer value in seconds\n"
1906 "Max Acceptable PCE Dead Timer\n"
1907 "Max Acceptable PCE Dead Timer value in seconds\n"
1908 "PCC PCEP Request Timer\n"
1909 "PCC PCEP Request Timer value in seconds\n"
1910 "PCC Session Timeout Interval\n"
1911 "PCC Session Timeout Interval value in seconds\n"
1912 "Multi-PCE delegation timeout\n"
1913 "Multi-PCE delegation timeout value in seconds\n")
1915 return path_pcep_cli_peer_timers(
1916 vty
, keep_alive_str
, keep_alive
, min_peer_keep_alive_str
,
1917 min_peer_keep_alive
, max_peer_keep_alive_str
,
1918 max_peer_keep_alive
, dead_timer_str
, dead_timer
,
1919 min_peer_dead_timer_str
, min_peer_dead_timer
,
1920 max_peer_dead_timer_str
, max_peer_dead_timer
, pcep_request_str
,
1921 pcep_request
, session_timeout_interval_str
,
1922 session_timeout_interval
, delegation_timeout_str
,
1923 delegation_timeout
);
1930 "PCC configuration\n")
1932 return path_pcep_cli_pcc(vty
);
1935 DEFPY(pcep_cli_no_pcc
,
1936 pcep_cli_no_pcc_cmd
,
1939 "PCC configuration\n")
1941 return path_pcep_cli_pcc_delete(vty
);
1944 DEFPY(pcep_cli_pcc_pcc_msd
,
1945 pcep_cli_pcc_pcc_msd_cmd
,
1947 "PCC maximum SID depth \n"
1948 "PCC maximum SID depth value\n")
1950 return path_pcep_cli_pcc_pcc_msd(vty
, msd_str
, msd
);
1953 DEFPY(pcep_cli_pcc_pcc_peer
,
1954 pcep_cli_pcc_pcc_peer_cmd
,
1955 "[no] peer WORD [precedence (1-255)]",
1959 "PCC Multi-PCE precedence\n"
1963 return path_pcep_cli_pcc_pcc_peer_delete(
1964 vty
, peer
, precedence_str
, precedence
);
1966 return path_pcep_cli_pcc_pcc_peer(vty
, peer
, precedence_str
,
1971 DEFPY(pcep_cli_show_srte_pcc
,
1972 pcep_cli_show_srte_pcc_cmd
,
1973 "show sr-te pcep pcc",
1977 "Show current PCC configuration\n")
1979 return path_pcep_cli_show_srte_pcep_pcc(vty
);
1982 DEFPY(pcep_cli_show_srte_pcep_session
,
1983 pcep_cli_show_srte_pcep_session_cmd
,
1984 "show sr-te pcep session [WORD]$pce",
1988 "Show PCEP Session information\n"
1991 return path_pcep_cli_show_srte_pcep_session(vty
, pce
);
1994 DEFPY(pcep_cli_clear_srte_pcep_session
,
1995 pcep_cli_clear_srte_pcep_session_cmd
,
1996 "clear sr-te pcep session [WORD]$pce",
2000 "Reset PCEP connection\n"
2003 return path_pcep_cli_clear_srte_pcep_session(vty
, pce
);
2006 void pcep_cli_init(void)
2008 hook_register(pathd_srte_config_write
, pcep_cli_pcep_config_write
);
2009 hook_register(nb_client_debug_config_write
,
2010 pcep_cli_debug_config_write
);
2011 hook_register(nb_client_debug_set_all
, pcep_cli_debug_set_all
);
2013 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
2015 install_node(&pcep_node
);
2016 install_node(&pcep_pcc_node
);
2017 install_node(&pcep_pce_node
);
2018 install_node(&pcep_pce_config_node
);
2020 install_default(PCEP_PCE_CONFIG_NODE
);
2021 install_default(PCEP_PCE_NODE
);
2022 install_default(PCEP_PCC_NODE
);
2023 install_default(PCEP_NODE
);
2025 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cli_pcep_cmd
);
2027 /* PCEP configuration group related configuration commands */
2028 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
2029 install_element(PCEP_NODE
, &pcep_cli_pcep_no_pce_config_cmd
);
2030 install_element(PCEP_PCE_CONFIG_NODE
,
2031 &pcep_cli_peer_source_address_cmd
);
2032 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_timers_cmd
);
2033 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2034 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2035 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2037 /* PCE peer related configuration commands */
2038 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
2039 install_element(PCEP_NODE
, &pcep_cli_no_pce_cmd
);
2040 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_address_cmd
);
2041 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_source_address_cmd
);
2042 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pcep_pce_config_ref_cmd
);
2043 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_timers_cmd
);
2044 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2045 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2046 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2048 /* PCC related configuration commands */
2049 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcc_cmd
);
2050 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
2051 install_element(PCEP_NODE
, &pcep_cli_no_pcc_cmd
);
2052 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_peer_cmd
);
2053 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_msd_cmd
);
2056 install_element(CONFIG_NODE
, &pcep_cli_debug_cmd
);
2057 install_element(ENABLE_NODE
, &pcep_cli_debug_cmd
);
2058 install_element(ENABLE_NODE
, &show_debugging_pathd_pcep_cmd
);
2059 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_counters_cmd
);
2060 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_config_cmd
);
2061 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_cmd
);
2062 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_session_cmd
);
2063 install_element(ENABLE_NODE
, &pcep_cli_clear_srte_pcep_session_cmd
);