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
);
1449 int pcep_cli_pcc_config_write(struct vty
*vty
)
1451 struct pce_opts
*pce_opts
;
1455 /* The MSD, nor any PCE peers have been configured on the PCC */
1456 if (!pcc_msd_configured_g
&& pce_connections_g
.num_connections
== 0) {
1460 vty_out(vty
, " pcc\n");
1463 /* Prepare the MSD, if present */
1464 if (pcc_msd_configured_g
) {
1465 vty_out(vty
, " %s %d\n", PCEP_VTYSH_ARG_MSD
, pcc_msd_g
);
1469 if (pce_connections_g
.num_connections
== 0) {
1474 for (int i
= 0; i
< MAX_PCC
; i
++) {
1475 pce_opts
= pce_connections_g
.connections
[i
];
1476 if (pce_opts
== NULL
) {
1480 /* Only show the PCEs configured in the pcc sub-command */
1481 if (!pcep_cli_pcc_has_pce(pce_opts
->pce_name
)) {
1485 csnprintfrr(buf
, sizeof(buf
), " peer %s",
1486 pce_opts
->pce_name
);
1487 if (pce_opts
->precedence
> 0
1488 && pce_opts
->precedence
!= DEFAULT_PCE_PRECEDENCE
) {
1489 csnprintfrr(buf
, sizeof(buf
), " %s %d",
1490 PCEP_VTYSH_ARG_PRECEDENCE
,
1491 pce_opts
->precedence
);
1493 vty_out(vty
, "%s\n", buf
);
1501 /* Internal function used by pcep_cli_pce_config_write()
1502 * and pcep_cli_pcep_pce_config_write() */
1503 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
1504 char *buf
, size_t buf_len
)
1508 if (group_opts
->source_ip
.ipa_type
!= IPADDR_NONE
1509 || group_opts
->source_port
!= 0) {
1510 csnprintfrr(buf
, buf_len
, " ");
1511 if (IS_IPADDR_V4(&group_opts
->source_ip
)) {
1512 csnprintfrr(buf
, buf_len
, " %s %s %pI4",
1513 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1515 &group_opts
->source_ip
.ipaddr_v4
);
1516 } else if (IS_IPADDR_V6(&group_opts
->source_ip
)) {
1517 csnprintfrr(buf
, buf_len
, " %s %s %pI6",
1518 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1519 PCEP_VTYSH_ARG_IPV6
,
1520 &group_opts
->source_ip
.ipaddr_v6
);
1522 if (group_opts
->source_port
> 0) {
1523 csnprintfrr(buf
, buf_len
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1524 group_opts
->source_port
);
1526 csnprintfrr(buf
, buf_len
, "\n");
1529 /* Group the keep-alive together for devman */
1530 if ((group_opts
->keep_alive_seconds
> 0)
1531 || (group_opts
->min_keep_alive_seconds
> 0)
1532 || (group_opts
->max_keep_alive_seconds
> 0)) {
1533 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1535 if (group_opts
->keep_alive_seconds
> 0) {
1536 csnprintfrr(buf
, buf_len
, " %s %d",
1537 PCEP_VTYSH_ARG_KEEP_ALIVE
,
1538 group_opts
->keep_alive_seconds
);
1540 if (group_opts
->min_keep_alive_seconds
> 0) {
1541 csnprintfrr(buf
, buf_len
, " %s %d",
1542 PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
,
1543 group_opts
->min_keep_alive_seconds
);
1545 if (group_opts
->max_keep_alive_seconds
> 0) {
1546 csnprintfrr(buf
, buf_len
, " %s %d",
1547 PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
,
1548 group_opts
->max_keep_alive_seconds
);
1550 csnprintfrr(buf
, buf_len
, "\n");
1554 /* Group the dead-timer together for devman */
1555 if ((group_opts
->dead_timer_seconds
> 0)
1556 || (group_opts
->min_dead_timer_seconds
> 0)
1557 || (group_opts
->max_dead_timer_seconds
> 0)) {
1558 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1560 if (group_opts
->dead_timer_seconds
> 0) {
1561 csnprintfrr(buf
, buf_len
, " %s %d",
1562 PCEP_VTYSH_ARG_DEAD_TIMER
,
1563 group_opts
->dead_timer_seconds
);
1565 if (group_opts
->min_dead_timer_seconds
> 0) {
1566 csnprintfrr(buf
, buf_len
, " %s %d",
1567 PCEP_VTYSH_ARG_DEAD_TIMER_MIN
,
1568 group_opts
->min_dead_timer_seconds
);
1570 if (group_opts
->max_dead_timer_seconds
> 0) {
1571 csnprintfrr(buf
, buf_len
, " %s %d",
1572 PCEP_VTYSH_ARG_DEAD_TIMER_MAX
,
1573 group_opts
->max_dead_timer_seconds
);
1575 csnprintfrr(buf
, buf_len
, "\n");
1579 if (group_opts
->pcep_request_time_seconds
> 0) {
1580 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1581 PCEP_VTYSH_ARG_TIMER
, PCEP_VTYSH_ARG_PCEP_REQUEST
,
1582 group_opts
->pcep_request_time_seconds
);
1585 if (group_opts
->delegation_timeout_seconds
> 0) {
1586 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1587 PCEP_VTYSH_ARG_TIMER
,
1588 PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
,
1589 group_opts
->delegation_timeout_seconds
);
1592 if (group_opts
->session_timeout_inteval_seconds
> 0) {
1593 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1594 PCEP_VTYSH_ARG_TIMER
,
1595 PCEP_VTYSH_ARG_SESSION_TIMEOUT
,
1596 group_opts
->session_timeout_inteval_seconds
);
1599 if (group_opts
->tcp_md5_auth
[0] != '\0') {
1600 csnprintfrr(buf
, buf_len
, " %s %s\n", PCEP_VTYSH_ARG_TCP_MD5
,
1601 group_opts
->tcp_md5_auth
);
1604 if (group_opts
->draft07
) {
1605 csnprintfrr(buf
, buf_len
, " %s\n",
1606 PCEP_VTYSH_ARG_SR_DRAFT07
);
1609 if (group_opts
->pce_initiated
) {
1610 csnprintfrr(buf
, buf_len
, " %s\n", PCEP_VTYSH_ARG_PCE_INIT
);
1617 int pcep_cli_pce_config_write(struct vty
*vty
)
1620 char buf
[1024] = "";
1622 for (int i
= 0; i
< MAX_PCE
; i
++) {
1623 struct pce_opts_cli
*pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
1624 if (pce_opts_cli
== NULL
) {
1627 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1629 vty_out(vty
, " pce %s\n", pce_opts
->pce_name
);
1630 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1631 vty_out(vty
, " %s %s %pI6", PCEP_VTYSH_ARG_ADDRESS
,
1632 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
);
1633 } else if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1634 vty_out(vty
, " address %s %pI4", PCEP_VTYSH_ARG_IP
,
1635 &pce_opts
->addr
.ipaddr_v4
);
1637 if (pce_opts
->port
!= PCEP_DEFAULT_PORT
) {
1638 vty_out(vty
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1641 vty_out(vty
, "%s\n", buf
);
1644 if (pce_opts_cli
->config_group_name
[0] != '\0') {
1645 vty_out(vty
, " config %s\n",
1646 pce_opts_cli
->config_group_name
);
1650 /* Only display the values configured on the PCE, not the values
1651 * from its optional pce-config-group, nor the default values */
1652 lines
+= pcep_cli_print_pce_config(
1653 &pce_opts_cli
->pce_config_group_opts
, buf
, sizeof(buf
));
1655 vty_out(vty
, "%s", buf
);
1662 int pcep_cli_pcep_pce_config_write(struct vty
*vty
)
1665 char buf
[1024] = "";
1667 for (int i
= 0; i
< MAX_PCE
; i
++) {
1668 struct pcep_config_group_opts
*group_opts
=
1669 pcep_g
->config_group_opts
[i
];
1670 if (group_opts
== NULL
) {
1674 vty_out(vty
, " pce-config %s\n", group_opts
->name
);
1678 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
1679 vty_out(vty
, "%s", buf
);
1687 * VTYSH command syntax definitions
1688 * The param names are taken from the path_pcep_cli_clippy.c generated file.
1691 DEFPY(show_debugging_pathd_pcep
,
1692 show_debugging_pathd_pcep_cmd
,
1693 "show debugging pathd-pcep",
1695 "State of each debugging option\n"
1696 "pathd pcep module debugging\n")
1698 vty_out(vty
, "Pathd pcep debugging status:\n");
1700 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1701 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1702 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1703 PCEP_VTYSH_ARG_BASIC
);
1704 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1705 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1706 PCEP_VTYSH_ARG_PATH
);
1707 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1708 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1709 PCEP_VTYSH_ARG_MESSAGE
);
1710 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1711 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1712 PCEP_VTYSH_ARG_PCEPLIB
);
1718 DEFPY(pcep_cli_debug
,
1720 "[no] debug pathd pcep [basic]$basic_str [path]$path_str [message]$message_str [pceplib]$pceplib_str",
1723 "pcep module debugging\n"
1724 "module basic debugging\n"
1725 "path structures debugging\n"
1726 "pcep message debugging\n"
1727 "pceplib debugging\n")
1729 return path_pcep_cli_debug(vty
, no
, basic_str
, path_str
, message_str
,
1733 DEFPY(pcep_cli_show_srte_pcep_counters
,
1734 pcep_cli_show_srte_pcep_counters_cmd
,
1735 "show sr-te pcep counters",
1741 return path_pcep_cli_show_srte_pcep_counters(vty
);
1748 "PCEP configuration\n")
1750 vty
->node
= PCEP_NODE
;
1755 pcep_cli_pcep_pce_config
,
1756 pcep_cli_pcep_pce_config_cmd
,
1757 "pce-config WORD$name",
1758 "Shared configuration\n"
1759 "Shared configuration name\n")
1761 return path_pcep_cli_pcep_pce_config(vty
, name
);
1764 DEFPY(pcep_cli_pcep_no_pce_config
,
1765 pcep_cli_pcep_no_pce_config_cmd
,
1766 "no pce-config WORD$name",
1768 "Shared configuration\n"
1769 "Shared configuration name\n")
1771 return path_pcep_cli_pcep_pce_config_delete(vty
, name
);
1774 DEFPY(pcep_cli_show_srte_pcep_pce_config
,
1775 pcep_cli_show_srte_pcep_pce_config_cmd
,
1776 "show sr-te pcep pce-config [<default|WORD>$name]",
1780 "Show shared PCE configuration\n"
1781 "Show default hard-coded values\n"
1782 "Shared configuration name\n")
1784 return path_pcep_cli_show_srte_pcep_pce_config(vty
, name
);
1791 "PCE configuration, address sub-config is mandatory\n"
1794 return path_pcep_cli_pce(vty
, name
);
1797 DEFPY(pcep_cli_no_pce
,
1798 pcep_cli_no_pce_cmd
,
1801 "PCE configuration, address sub-config is mandatory\n"
1804 return path_pcep_cli_pce_delete(vty
, name
);
1807 DEFPY(pcep_cli_show_srte_pcep_pce
,
1808 pcep_cli_show_srte_pcep_pce_cmd
,
1809 "show sr-te pcep pce [WORD$name]",
1813 "Show detailed pce values\n"
1816 return path_pcep_cli_show_srte_pcep_pce(vty
, name
);
1819 DEFPY(pcep_cli_peer_sr_draft07
,
1820 pcep_cli_peer_sr_draft07_cmd
,
1822 "Configure PCC to send PCEP Open with SR draft07\n")
1824 return path_pcep_cli_peer_sr_draft07(vty
);
1827 DEFPY(pcep_cli_peer_pce_initiated
,
1828 pcep_cli_peer_pce_initiated_cmd
,
1830 "Configure PCC to accept PCE initiated LSPs\n")
1832 return path_pcep_cli_peer_pce_initiated(vty
);
1835 DEFPY(pcep_cli_peer_tcp_md5_auth
,
1836 pcep_cli_peer_tcp_md5_auth_cmd
,
1837 "tcp-md5-auth WORD",
1838 "Configure PCC TCP-MD5 RFC2385 Authentication\n"
1839 "TCP-MD5 Authentication string\n")
1841 return path_pcep_cli_peer_tcp_md5_auth(vty
, tcp_md5_auth
);
1844 DEFPY(pcep_cli_peer_address
,
1845 pcep_cli_peer_address_cmd
,
1846 "address <ip A.B.C.D | ipv6 X:X::X:X> [port (1024-65535)]",
1847 "PCE IP Address configuration, mandatory configuration\n"
1848 "PCE IPv4 address\n"
1849 "Remote PCE server IPv4 address\n"
1850 "PCE IPv6 address\n"
1851 "Remote PCE server IPv6 address\n"
1852 "Remote PCE server port\n"
1853 "Remote PCE server port value\n")
1855 return path_pcep_cli_peer_address(vty
, ip_str
, &ip
, ipv6_str
, &ipv6
,
1859 DEFPY(pcep_cli_peer_source_address
,
1860 pcep_cli_peer_source_address_cmd
,
1861 "source-address [ip A.B.C.D | ipv6 X:X::X:X] [port (1024-65535)]",
1862 "PCE source IP Address configuration\n"
1863 "PCE source IPv4 address\n"
1864 "PCE source IPv4 address value\n"
1865 "PCE source IPv6 address\n"
1866 "PCE source IPv6 address value\n"
1867 "Source PCE server port\n"
1868 "Source PCE server port value\n")
1870 return path_pcep_cli_peer_source_address(vty
, ip_str
, &ip
, ipv6_str
,
1871 &ipv6
, port_str
, port
);
1874 DEFPY(pcep_cli_peer_pcep_pce_config_ref
,
1875 pcep_cli_peer_pcep_pce_config_ref_cmd
,
1877 "PCE shared configuration to use\n"
1878 "Shared configuration name\n")
1880 return path_pcep_cli_peer_pcep_pce_config_ref(vty
, name
);
1883 DEFPY(pcep_cli_peer_timers
,
1884 pcep_cli_peer_timers_cmd
,
1885 "timer [keep-alive (1-63)] [min-peer-keep-alive (1-255)] [max-peer-keep-alive (1-255)] "
1886 "[dead-timer (4-255)] [min-peer-dead-timer (4-255)] [max-peer-dead-timer (4-255)] "
1887 "[pcep-request (1-120)] [session-timeout-interval (1-120)] [delegation-timeout (1-60)]",
1888 "PCE PCEP Session Timers configuration\n"
1889 "PCC Keep Alive Timer\n"
1890 "PCC Keep Alive Timer value in seconds\n"
1891 "Min Acceptable PCE Keep Alive Timer\n"
1892 "Min Acceptable PCE Keep Alive Timer value in seconds\n"
1893 "Max Acceptable PCE Keep Alive Timer\n"
1894 "Max Acceptable PCE Keep Alive Timer value in seconds\n"
1896 "PCC Dead Timer value in seconds\n"
1897 "Min Acceptable PCE Dead Timer\n"
1898 "Min Acceptable PCE Dead Timer value in seconds\n"
1899 "Max Acceptable PCE Dead Timer\n"
1900 "Max Acceptable PCE Dead Timer value in seconds\n"
1901 "PCC PCEP Request Timer\n"
1902 "PCC PCEP Request Timer value in seconds\n"
1903 "PCC Session Timeout Interval\n"
1904 "PCC Session Timeout Interval value in seconds\n"
1905 "Multi-PCE delegation timeout\n"
1906 "Multi-PCE delegation timeout value in seconds\n")
1908 return path_pcep_cli_peer_timers(
1909 vty
, keep_alive_str
, keep_alive
, min_peer_keep_alive_str
,
1910 min_peer_keep_alive
, max_peer_keep_alive_str
,
1911 max_peer_keep_alive
, dead_timer_str
, dead_timer
,
1912 min_peer_dead_timer_str
, min_peer_dead_timer
,
1913 max_peer_dead_timer_str
, max_peer_dead_timer
, pcep_request_str
,
1914 pcep_request
, session_timeout_interval_str
,
1915 session_timeout_interval
, delegation_timeout_str
,
1916 delegation_timeout
);
1923 "PCC configuration\n")
1925 return path_pcep_cli_pcc(vty
);
1928 DEFPY(pcep_cli_no_pcc
,
1929 pcep_cli_no_pcc_cmd
,
1932 "PCC configuration\n")
1934 return path_pcep_cli_pcc_delete(vty
);
1937 DEFPY(pcep_cli_pcc_pcc_msd
,
1938 pcep_cli_pcc_pcc_msd_cmd
,
1940 "PCC maximum SID depth \n"
1941 "PCC maximum SID depth value\n")
1943 return path_pcep_cli_pcc_pcc_msd(vty
, msd_str
, msd
);
1946 DEFPY(pcep_cli_pcc_pcc_peer
,
1947 pcep_cli_pcc_pcc_peer_cmd
,
1948 "[no] peer WORD [precedence (1-255)]",
1952 "PCC Multi-PCE precedence\n"
1956 return path_pcep_cli_pcc_pcc_peer_delete(
1957 vty
, peer
, precedence_str
, precedence
);
1959 return path_pcep_cli_pcc_pcc_peer(vty
, peer
, precedence_str
,
1964 DEFPY(pcep_cli_show_srte_pcc
,
1965 pcep_cli_show_srte_pcc_cmd
,
1966 "show sr-te pcep pcc",
1970 "Show current PCC configuration\n")
1972 return path_pcep_cli_show_srte_pcep_pcc(vty
);
1975 DEFPY(pcep_cli_show_srte_pcep_session
,
1976 pcep_cli_show_srte_pcep_session_cmd
,
1977 "show sr-te pcep session [WORD]$pce",
1981 "Show PCEP Session information\n"
1984 return path_pcep_cli_show_srte_pcep_session(vty
, pce
);
1987 DEFPY(pcep_cli_clear_srte_pcep_session
,
1988 pcep_cli_clear_srte_pcep_session_cmd
,
1989 "clear sr-te pcep session [WORD]$pce",
1993 "Reset PCEP connection\n"
1996 return path_pcep_cli_clear_srte_pcep_session(vty
, pce
);
1999 void pcep_cli_init(void)
2001 hook_register(pathd_srte_config_write
, pcep_cli_pcep_config_write
);
2002 hook_register(nb_client_debug_config_write
,
2003 pcep_cli_debug_config_write
);
2004 hook_register(nb_client_debug_set_all
, pcep_cli_debug_set_all
);
2006 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
2008 install_node(&pcep_node
);
2009 install_node(&pcep_pcc_node
);
2010 install_node(&pcep_pce_node
);
2011 install_node(&pcep_pce_config_node
);
2013 install_default(PCEP_PCE_CONFIG_NODE
);
2014 install_default(PCEP_PCE_NODE
);
2015 install_default(PCEP_PCC_NODE
);
2016 install_default(PCEP_NODE
);
2018 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cli_pcep_cmd
);
2020 /* PCEP configuration group related configuration commands */
2021 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
2022 install_element(PCEP_NODE
, &pcep_cli_pcep_no_pce_config_cmd
);
2023 install_element(PCEP_PCE_CONFIG_NODE
,
2024 &pcep_cli_peer_source_address_cmd
);
2025 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_timers_cmd
);
2026 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2027 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2028 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2030 /* PCE peer related configuration commands */
2031 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
2032 install_element(PCEP_NODE
, &pcep_cli_no_pce_cmd
);
2033 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_address_cmd
);
2034 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_source_address_cmd
);
2035 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pcep_pce_config_ref_cmd
);
2036 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_timers_cmd
);
2037 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2038 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2039 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2041 /* PCC related configuration commands */
2042 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcc_cmd
);
2043 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
2044 install_element(PCEP_NODE
, &pcep_cli_no_pcc_cmd
);
2045 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_peer_cmd
);
2046 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_msd_cmd
);
2049 install_element(CONFIG_NODE
, &pcep_cli_debug_cmd
);
2050 install_element(ENABLE_NODE
, &pcep_cli_debug_cmd
);
2051 install_element(ENABLE_NODE
, &show_debugging_pathd_pcep_cmd
);
2052 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_counters_cmd
);
2053 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_config_cmd
);
2054 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_cmd
);
2055 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_session_cmd
);
2056 install_element(ENABLE_NODE
, &pcep_cli_clear_srte_pcep_session_cmd
);