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 #include "pathd/path_pcep_cli_clippy.c"
45 #define DEFAULT_PCE_PRECEDENCE 255
46 #define DEFAULT_PCC_MSD 4
47 #define DEFAULT_SR_DRAFT07 false
48 #define DEFAULT_PCE_INITIATED false
49 #define DEFAULT_TIMER_KEEP_ALIVE 30
50 #define DEFAULT_TIMER_KEEP_ALIVE_MIN 1
51 #define DEFAULT_TIMER_KEEP_ALIVE_MAX 255
52 #define DEFAULT_TIMER_DEADTIMER 120
53 #define DEFAULT_TIMER_DEADTIMER_MIN 4
54 #define DEFAULT_TIMER_DEADTIMER_MAX 255
55 #define DEFAULT_TIMER_PCEP_REQUEST 30
56 #define DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL 30
57 #define DEFAULT_DELEGATION_TIMEOUT_INTERVAL 10
59 /* CLI Function declarations */
60 static int pcep_cli_debug_config_write(struct vty
*vty
);
61 static int pcep_cli_debug_set_all(uint32_t flags
, bool set
);
62 static int pcep_cli_pcep_config_write(struct vty
*vty
);
63 static int pcep_cli_pcc_config_write(struct vty
*vty
);
64 static int pcep_cli_pce_config_write(struct vty
*vty
);
65 static int pcep_cli_pcep_pce_config_write(struct vty
*vty
);
67 /* Internal Util Function declarations */
68 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
);
69 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
);
70 static struct pce_opts_cli
*pcep_cli_create_pce_opts(const char *name
);
71 static void pcep_cli_delete_pce(const char *pce_name
);
73 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
);
74 static struct pcep_config_group_opts
*
75 pcep_cli_find_pcep_pce_config(const char *group_name
);
77 pcep_cli_add_pcep_pce_config(struct pcep_config_group_opts
*config_group_opts
);
78 static struct pcep_config_group_opts
*
79 pcep_cli_create_pcep_pce_config(const char *group_name
);
80 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
);
81 static void pcep_cli_delete_pcep_pce_config(const char *group_name
);
82 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
83 char *buf
, size_t buf_len
);
84 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
85 pcep_configuration
*config
);
86 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
87 struct pcep_pcc_info
*pcc_info
);
88 static bool pcep_cli_pcc_has_pce(const char *pce_name
);
89 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
);
90 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
);
91 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
92 const char *peer_name
,
93 const char *precedence_str
,
100 static const char PCEP_VTYSH_ARG_ADDRESS
[] = "address";
101 static const char PCEP_VTYSH_ARG_SOURCE_ADDRESS
[] = "source-address";
102 static const char PCEP_VTYSH_ARG_IP
[] = "ip";
103 static const char PCEP_VTYSH_ARG_IPV6
[] = "ipv6";
104 static const char PCEP_VTYSH_ARG_PORT
[] = "port";
105 static const char PCEP_VTYSH_ARG_PRECEDENCE
[] = "precedence";
106 static const char PCEP_VTYSH_ARG_MSD
[] = "msd";
107 static const char PCEP_VTYSH_ARG_KEEP_ALIVE
[] = "keep-alive";
108 static const char PCEP_VTYSH_ARG_TIMER
[] = "timer";
109 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
[] = "min-peer-keep-alive";
110 static const char PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
[] = "max-peer-keep-alive";
111 static const char PCEP_VTYSH_ARG_DEAD_TIMER
[] = "dead-timer";
112 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MIN
[] = "min-peer-dead-timer";
113 static const char PCEP_VTYSH_ARG_DEAD_TIMER_MAX
[] = "max-peer-dead-timer";
114 static const char PCEP_VTYSH_ARG_PCEP_REQUEST
[] = "pcep-request";
115 static const char PCEP_VTYSH_ARG_SESSION_TIMEOUT
[] = "session-timeout-interval";
116 static const char PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
[] = "delegation-timeout";
117 static const char PCEP_VTYSH_ARG_SR_DRAFT07
[] = "sr-draft07";
118 static const char PCEP_VTYSH_ARG_PCE_INIT
[] = "pce-initiated";
119 static const char PCEP_VTYSH_ARG_TCP_MD5
[] = "tcp-md5-auth";
120 static const char PCEP_VTYSH_ARG_BASIC
[] = "basic";
121 static const char PCEP_VTYSH_ARG_PATH
[] = "path";
122 static const char PCEP_VTYSH_ARG_MESSAGE
[] = "message";
123 static const char PCEP_VTYSH_ARG_PCEPLIB
[] = "pceplib";
124 static const char PCEP_CLI_CAP_STATEFUL
[] = " [Stateful PCE]";
125 static const char PCEP_CLI_CAP_INCL_DB_VER
[] = " [Include DB version]";
126 static const char PCEP_CLI_CAP_LSP_TRIGGERED
[] = " [LSP Triggered Resync]";
127 static const char PCEP_CLI_CAP_LSP_DELTA
[] = " [LSP Delta Sync]";
128 static const char PCEP_CLI_CAP_PCE_TRIGGERED
[] =
129 " [PCE triggered Initial Sync]";
130 static const char PCEP_CLI_CAP_SR_TE_PST
[] = " [SR TE PST]";
131 static const char PCEP_CLI_CAP_PCC_RESOLVE_NAI
[] =
132 " [PCC can resolve NAI to SID]";
133 static const char PCEP_CLI_CAP_PCC_INITIATED
[] = " [PCC Initiated LSPs]";
134 static const char PCEP_CLI_CAP_PCC_PCE_INITIATED
[] =
135 " [PCC and PCE Initiated LSPs]";
137 struct pce_connections
{
139 struct pce_opts
*connections
[MAX_PCC
];
142 struct pce_connections pce_connections_g
= {.num_connections
= 0};
144 /* Default PCE group that all PCE-Groups and PCEs will inherit from */
145 struct pcep_config_group_opts default_pcep_config_group_opts_g
= {
147 .tcp_md5_auth
= "\0",
148 .draft07
= DEFAULT_SR_DRAFT07
,
149 .pce_initiated
= DEFAULT_PCE_INITIATED
,
150 .keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE
,
151 .min_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MIN
,
152 .max_keep_alive_seconds
= DEFAULT_TIMER_KEEP_ALIVE_MAX
,
153 .dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER
,
154 .min_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MIN
,
155 .max_dead_timer_seconds
= DEFAULT_TIMER_DEADTIMER_MAX
,
156 .pcep_request_time_seconds
= DEFAULT_TIMER_PCEP_REQUEST
,
157 .session_timeout_inteval_seconds
=
158 DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL
,
159 .delegation_timeout_seconds
= DEFAULT_DELEGATION_TIMEOUT_INTERVAL
,
160 .source_port
= DEFAULT_PCEP_TCP_PORT
,
161 .source_ip
.ipa_type
= IPADDR_NONE
,
164 /* Used by PCEP_PCE_CONFIG_NODE sub-commands to operate on the current pce group
166 struct pcep_config_group_opts
*current_pcep_config_group_opts_g
= NULL
;
167 /* Used by PCEP_PCE_NODE sub-commands to operate on the current pce opts */
168 struct pce_opts_cli
*current_pce_opts_g
= NULL
;
169 short pcc_msd_g
= DEFAULT_PCC_MSD
;
170 bool pcc_msd_configured_g
= false;
172 static struct cmd_node pcep_node
= {
175 .parent_node
= SR_TRAFFIC_ENG_NODE
,
176 .prompt
= "%s(config-sr-te-pcep)# "
179 static struct cmd_node pcep_pcc_node
= {
180 .name
= "srte pcep pcc",
181 .node
= PCEP_PCC_NODE
,
182 .parent_node
= PCEP_NODE
,
183 .prompt
= "%s(config-sr-te-pcep-pcc)# "
186 static struct cmd_node pcep_pce_node
= {
187 .name
= "srte pcep pce",
188 .node
= PCEP_PCE_NODE
,
189 .parent_node
= PCEP_NODE
,
190 .prompt
= "%s(config-sr-te-pcep-pce)# "
193 static struct cmd_node pcep_pce_config_node
= {
194 .name
= "srte pcep pce-config",
195 .node
= PCEP_PCE_CONFIG_NODE
,
196 .parent_node
= PCEP_NODE
,
197 .prompt
= "%s(pce-sr-te-pcep-pce-config)# "
200 /* Common code used in VTYSH processing for int values */
201 #define PCEP_VTYSH_INT_ARG_CHECK(arg_str, arg_val, arg_store, min_value, \
203 if (arg_str != NULL) { \
204 if (arg_val <= min_value || arg_val >= max_value) { \
206 "%% Invalid value %ld in range [%d - %d]", \
207 arg_val, min_value, max_value); \
208 return CMD_WARNING; \
210 arg_store = arg_val; \
213 #define MERGE_COMPARE_CONFIG_GROUP_VALUE(config_param, not_set_value) \
214 pce_opts_cli->pce_opts.config_opts.config_param = \
215 pce_opts_cli->pce_config_group_opts.config_param; \
216 if (pce_opts_cli->pce_config_group_opts.config_param \
217 == not_set_value) { \
218 pce_opts_cli->pce_opts.config_opts.config_param = \
219 ((pce_config != NULL \
220 && pce_config->config_param != not_set_value) \
221 ? pce_config->config_param \
222 : default_pcep_config_group_opts_g \
227 * Internal Util functions
230 /* Check if a pce_opts_cli already exists based on its name and return it,
231 * return NULL otherwise */
232 static struct pce_opts_cli
*pcep_cli_find_pce(const char *pce_name
)
234 for (int i
= 0; i
< MAX_PCE
; i
++) {
235 struct pce_opts_cli
*pce_rhs_cli
= pcep_g
->pce_opts_cli
[i
];
236 if (pce_rhs_cli
!= NULL
) {
237 if (strcmp(pce_name
, pce_rhs_cli
->pce_opts
.pce_name
)
247 /* Add a new pce_opts_cli to pcep_g, return false if MAX_PCES, true otherwise */
248 static bool pcep_cli_add_pce(struct pce_opts_cli
*pce_opts_cli
)
250 for (int i
= 0; i
< MAX_PCE
; i
++) {
251 if (pcep_g
->pce_opts_cli
[i
] == NULL
) {
252 pcep_g
->pce_opts_cli
[i
] = pce_opts_cli
;
253 pcep_g
->num_pce_opts_cli
++;
261 /* Create a new pce opts_cli */
262 static struct pce_opts_cli
*pcep_cli_create_pce_opts(const char *name
)
264 struct pce_opts_cli
*pce_opts_cli
=
265 XCALLOC(MTYPE_PCEP
, sizeof(struct pce_opts_cli
));
266 strlcpy(pce_opts_cli
->pce_opts
.pce_name
, name
,
267 sizeof(pce_opts_cli
->pce_opts
.pce_name
));
268 pce_opts_cli
->pce_opts
.port
= PCEP_DEFAULT_PORT
;
273 static void pcep_cli_delete_pce(const char *pce_name
)
275 for (int i
= 0; i
< MAX_PCE
; i
++) {
276 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
277 if (strcmp(pcep_g
->pce_opts_cli
[i
]->pce_opts
.pce_name
,
280 XFREE(MTYPE_PCEP
, pcep_g
->pce_opts_cli
[i
]);
281 pcep_g
->pce_opts_cli
[i
] = NULL
;
282 pcep_g
->num_pce_opts_cli
--;
290 pcep_cli_merge_pcep_pce_config_options(struct pce_opts_cli
*pce_opts_cli
)
292 if (pce_opts_cli
->merged
== true) {
296 struct pcep_config_group_opts
*pce_config
=
297 pcep_cli_find_pcep_pce_config(pce_opts_cli
->config_group_name
);
299 /* Configuration priorities:
300 * 1) pce_opts->config_opts, if present, overwrite pce_config
301 * config_opts 2) pce_config config_opts, if present, overwrite
302 * default config_opts 3) If neither pce_opts->config_opts nor
303 * pce_config config_opts are set, then the default config_opts value
307 const char *tcp_md5_auth_str
=
308 pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
;
309 if (pce_opts_cli
->pce_config_group_opts
.tcp_md5_auth
[0] == '\0') {
310 if (pce_config
!= NULL
&& pce_config
->tcp_md5_auth
[0] != '\0') {
311 tcp_md5_auth_str
= pce_config
->tcp_md5_auth
;
314 default_pcep_config_group_opts_g
.tcp_md5_auth
;
317 strlcpy(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
,
319 sizeof(pce_opts_cli
->pce_opts
.config_opts
.tcp_md5_auth
));
321 struct ipaddr
*source_ip
=
322 &pce_opts_cli
->pce_config_group_opts
.source_ip
;
323 if (pce_opts_cli
->pce_config_group_opts
.source_ip
.ipa_type
325 if (pce_config
!= NULL
326 && pce_config
->source_ip
.ipa_type
!= IPADDR_NONE
) {
327 source_ip
= &pce_config
->source_ip
;
329 source_ip
= &default_pcep_config_group_opts_g
.source_ip
;
332 memcpy(&pce_opts_cli
->pce_opts
.config_opts
.source_ip
, source_ip
,
333 sizeof(struct ipaddr
));
335 MERGE_COMPARE_CONFIG_GROUP_VALUE(draft07
, false);
336 MERGE_COMPARE_CONFIG_GROUP_VALUE(pce_initiated
, false);
337 MERGE_COMPARE_CONFIG_GROUP_VALUE(keep_alive_seconds
, 0);
338 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_keep_alive_seconds
, 0);
339 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_keep_alive_seconds
, 0);
340 MERGE_COMPARE_CONFIG_GROUP_VALUE(dead_timer_seconds
, 0);
341 MERGE_COMPARE_CONFIG_GROUP_VALUE(min_dead_timer_seconds
, 0);
342 MERGE_COMPARE_CONFIG_GROUP_VALUE(max_dead_timer_seconds
, 0);
343 MERGE_COMPARE_CONFIG_GROUP_VALUE(pcep_request_time_seconds
, 0);
344 MERGE_COMPARE_CONFIG_GROUP_VALUE(session_timeout_inteval_seconds
, 0);
345 MERGE_COMPARE_CONFIG_GROUP_VALUE(delegation_timeout_seconds
, 0);
346 MERGE_COMPARE_CONFIG_GROUP_VALUE(source_port
, 0);
348 pce_opts_cli
->merged
= true;
351 /* Check if a pcep_config_group_opts already exists based on its name and return
352 * it, return NULL otherwise */
353 static struct pcep_config_group_opts
*
354 pcep_cli_find_pcep_pce_config(const char *group_name
)
356 for (int i
= 0; i
< MAX_PCE
; i
++) {
357 struct pcep_config_group_opts
*pcep_pce_config_rhs
=
358 pcep_g
->config_group_opts
[i
];
359 if (pcep_pce_config_rhs
!= NULL
) {
360 if (strcmp(group_name
, pcep_pce_config_rhs
->name
)
362 return pcep_pce_config_rhs
;
370 /* Add a new pcep_config_group_opts to pcep_g, return false if MAX_PCE,
372 static bool pcep_cli_add_pcep_pce_config(
373 struct pcep_config_group_opts
*pcep_config_group_opts
)
375 for (int i
= 0; i
< MAX_PCE
; i
++) {
376 if (pcep_g
->config_group_opts
[i
] == NULL
) {
377 pcep_g
->config_group_opts
[i
] = pcep_config_group_opts
;
378 pcep_g
->num_config_group_opts
++;
386 /* Create a new pce group, inheriting its values from the default pce group */
387 static struct pcep_config_group_opts
*
388 pcep_cli_create_pcep_pce_config(const char *group_name
)
390 struct pcep_config_group_opts
*pcep_config_group_opts
=
391 XCALLOC(MTYPE_PCEP
, sizeof(struct pcep_config_group_opts
));
392 strlcpy(pcep_config_group_opts
->name
, group_name
,
393 sizeof(pcep_config_group_opts
->name
));
395 return pcep_config_group_opts
;
398 /* Iterate the pce_opts and return true if the pce-group-name is referenced,
399 * false otherwise. */
400 static bool pcep_cli_is_pcep_pce_config_used(const char *group_name
)
402 for (int i
= 0; i
< MAX_PCE
; i
++) {
403 if (pcep_g
->pce_opts_cli
[i
] != NULL
) {
404 if (strcmp(pcep_g
->pce_opts_cli
[i
]->config_group_name
,
415 static void pcep_cli_delete_pcep_pce_config(const char *group_name
)
417 for (int i
= 0; i
< MAX_PCE
; i
++) {
418 if (pcep_g
->config_group_opts
[i
] != NULL
) {
419 if (strcmp(pcep_g
->config_group_opts
[i
]->name
,
422 XFREE(MTYPE_PCEP
, pcep_g
->config_group_opts
[i
]);
423 pcep_g
->config_group_opts
[i
] = NULL
;
424 pcep_g
->num_config_group_opts
--;
431 static bool pcep_cli_pcc_has_pce(const char *pce_name
)
433 for (int i
= 0; i
< MAX_PCC
; i
++) {
434 struct pce_opts
*pce_opts
= pce_connections_g
.connections
[i
];
435 if (pce_opts
== NULL
) {
439 if (strcmp(pce_opts
->pce_name
, pce_name
) == 0) {
447 static void pcep_cli_add_pce_connection(struct pce_opts
*pce_opts
)
449 for (int i
= 0; i
< MAX_PCC
; i
++) {
450 if (pce_connections_g
.connections
[i
] == NULL
) {
451 pce_connections_g
.num_connections
++;
452 pce_connections_g
.connections
[i
] = pce_opts
;
458 static void pcep_cli_remove_pce_connection(struct pce_opts
*pce_opts
)
460 for (int i
= 0; i
< MAX_PCC
; i
++) {
461 if (pce_connections_g
.connections
[i
] == pce_opts
) {
462 pce_connections_g
.num_connections
--;
463 pce_connections_g
.connections
[i
] = NULL
;
470 * VTY command implementations
473 static int path_pcep_cli_debug(struct vty
*vty
, const char *no_str
,
474 const char *basic_str
, const char *path_str
,
475 const char *message_str
, const char *pceplib_str
)
477 uint32_t mode
= DEBUG_NODE2MODE(vty
->node
);
478 bool no
= (no_str
!= NULL
);
480 DEBUG_MODE_SET(&pcep_g
->dbg
, mode
, !no
);
482 if (basic_str
!= NULL
) {
483 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
, !no
);
485 if (path_str
!= NULL
) {
486 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
, !no
);
488 if (message_str
!= NULL
) {
489 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
, !no
);
491 if (pceplib_str
!= NULL
) {
492 DEBUG_FLAGS_SET(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
, !no
);
498 static int path_pcep_cli_show_srte_pcep_counters(struct vty
*vty
)
504 struct counters_group
*group
;
505 struct counters_subgroup
*subgroup
;
506 struct counter
*counter
;
507 const char *group_name
, *empty_string
= "";
511 group
= pcep_ctrl_get_counters(pcep_g
->fpt
, 1);
514 vty_out(vty
, "No counters to display.\n\n");
518 diff_time
= time(NULL
) - group
->start_time
;
519 localtime_r(&group
->start_time
, &tm_info
);
520 strftime(tm_buffer
, sizeof(tm_buffer
), "%Y-%m-%d %H:%M:%S", &tm_info
);
522 vty_out(vty
, "PCEP counters since %s (%uh %um %us):\n", tm_buffer
,
523 (uint32_t)(diff_time
/ 3600), (uint32_t)((diff_time
/ 60) % 60),
524 (uint32_t)(diff_time
% 60));
527 tt
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
528 ttable_add_row(tt
, "Group|Name|Value");
529 tt
->style
.cell
.rpad
= 2;
530 tt
->style
.corner
= '+';
532 ttable_rowseps(tt
, 0, BOTTOM
, true, '-');
534 for (row
= 0, i
= 0; i
<= group
->num_subgroups
; i
++) {
535 subgroup
= group
->subgroups
[i
];
536 if (subgroup
!= NULL
) {
537 group_name
= subgroup
->counters_subgroup_name
;
538 for (j
= 0; j
<= subgroup
->num_counters
; j
++) {
539 counter
= subgroup
->counters
[j
];
540 if (counter
!= NULL
) {
541 ttable_add_row(tt
, "%s|%s|%u",
543 counter
->counter_name
,
544 counter
->counter_value
);
546 group_name
= empty_string
;
549 ttable_rowseps(tt
, row
, BOTTOM
, true, '-');
553 /* Dump the generated table. */
554 table
= ttable_dump(tt
, "\n");
555 vty_out(vty
, "%s\n", table
);
556 XFREE(MTYPE_TMP
, table
);
560 pcep_lib_free_counters(group
);
565 static int path_pcep_cli_pcep_pce_config(struct vty
*vty
,
566 const char *pcep_pce_config
)
568 struct pcep_config_group_opts
*pce_config
=
569 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
570 if (pce_config
== NULL
) {
571 pce_config
= pcep_cli_create_pcep_pce_config(pcep_pce_config
);
572 if (pcep_cli_add_pcep_pce_config(pce_config
) == false) {
574 "%% Cannot create pce-config, as the Maximum limit of %d pce-config has been reached.\n",
576 XFREE(MTYPE_PCEP
, pce_config
);
581 "Notice: changes to this pce-config will not affect PCEs already configured with this group\n");
584 current_pcep_config_group_opts_g
= pce_config
;
585 vty
->node
= PCEP_PCE_CONFIG_NODE
;
590 static int path_pcep_cli_pcep_pce_config_delete(struct vty
*vty
,
591 const char *pcep_pce_config
)
593 struct pcep_config_group_opts
*pce_config
=
594 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
595 if (pce_config
== NULL
) {
597 "%% Cannot delete pce-config, since it does not exist.\n");
601 if (pcep_cli_is_pcep_pce_config_used(pce_config
->name
)) {
603 "%% Cannot delete pce-config, since it is in use by a peer.\n");
607 pcep_cli_delete_pcep_pce_config(pce_config
->name
);
612 static int path_pcep_cli_show_srte_pcep_pce_config(struct vty
*vty
,
613 const char *pcep_pce_config
)
617 /* Only show 1 Peer config group */
618 struct pcep_config_group_opts
*group_opts
;
619 if (pcep_pce_config
!= NULL
) {
620 if (strcmp(pcep_pce_config
, "default") == 0) {
621 group_opts
= &default_pcep_config_group_opts_g
;
624 pcep_cli_find_pcep_pce_config(pcep_pce_config
);
626 if (group_opts
== NULL
) {
627 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
632 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
633 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
634 vty_out(vty
, "%s", buf
);
638 /* Show all Peer config groups */
639 for (int i
= 0; i
< MAX_PCE
; i
++) {
640 group_opts
= pcep_g
->config_group_opts
[i
];
641 if (group_opts
== NULL
) {
645 vty_out(vty
, "pce-config: %s\n", group_opts
->name
);
646 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
647 vty_out(vty
, "%s", buf
);
654 static int path_pcep_cli_pce(struct vty
*vty
, const char *pce_peer_name
)
656 /* If it already exists, it will be updated in the sub-commands */
657 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
658 if (pce_opts_cli
== NULL
) {
659 pce_opts_cli
= pcep_cli_create_pce_opts(pce_peer_name
);
661 if (!pcep_cli_add_pce(pce_opts_cli
)) {
663 "%% Cannot create PCE, as the Maximum limit of %d PCEs has been reached.\n",
665 XFREE(MTYPE_PCEP
, pce_opts_cli
);
670 current_pce_opts_g
= pce_opts_cli
;
671 vty
->node
= PCEP_PCE_NODE
;
676 static int path_pcep_cli_pce_delete(struct vty
*vty
, const char *pce_peer_name
)
678 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(pce_peer_name
);
679 if (pce_opts_cli
== NULL
) {
680 vty_out(vty
, "%% PCC peer does not exist.\n");
684 /* To better work with frr-reload, go ahead and delete it if its in use
686 if (pcep_cli_pcc_has_pce(pce_peer_name
)) {
688 "%% Notice: the pce is in use by a PCC, also disconnecting.\n");
689 path_pcep_cli_pcc_pcc_peer_delete(vty
, pce_peer_name
, NULL
, 0);
692 pcep_cli_delete_pce(pce_peer_name
);
697 /* Internal Util func to show an individual PCE,
698 * only used by path_pcep_cli_show_srte_pcep_pce() */
699 static void show_pce_peer(struct vty
*vty
, struct pce_opts_cli
*pce_opts_cli
)
701 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
702 vty_out(vty
, "PCE: %s\n", pce_opts
->pce_name
);
704 /* Remote PCE IP address */
705 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
706 vty_out(vty
, " %s %s %pI6 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
707 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
,
708 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
710 vty_out(vty
, " %s %s %pI4 %s %d\n", PCEP_VTYSH_ARG_ADDRESS
,
711 PCEP_VTYSH_ARG_IP
, &pce_opts
->addr
.ipaddr_v4
,
712 PCEP_VTYSH_ARG_PORT
, pce_opts
->port
);
715 if (pce_opts_cli
->config_group_name
[0] != '\0') {
716 vty_out(vty
, " pce-config: %s\n",
717 pce_opts_cli
->config_group_name
);
721 pcep_cli_print_pce_config(&pce_opts
->config_opts
, buf
, sizeof(buf
));
722 vty_out(vty
, "%s", buf
);
725 static int path_pcep_cli_show_srte_pcep_pce(struct vty
*vty
,
726 const char *pce_peer
)
728 /* Only show 1 PCE */
729 struct pce_opts_cli
*pce_opts_cli
;
730 if (pce_peer
!= NULL
) {
731 pce_opts_cli
= pcep_cli_find_pce(pce_peer
);
732 if (pce_opts_cli
== NULL
) {
733 vty_out(vty
, "%% PCE [%s] does not exist.\n", pce_peer
);
737 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
738 show_pce_peer(vty
, pce_opts_cli
);
744 for (int i
= 0; i
< MAX_PCE
; i
++) {
745 pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
746 if (pce_opts_cli
== NULL
) {
750 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
751 show_pce_peer(vty
, pce_opts_cli
);
757 static int path_pcep_cli_peer_sr_draft07(struct vty
*vty
)
759 struct pcep_config_group_opts
*pce_config
= NULL
;
761 if (vty
->node
== PCEP_PCE_NODE
) {
762 /* TODO need to see if the pce is in use, and reset the
764 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
765 current_pce_opts_g
->merged
= false;
766 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
767 pce_config
= current_pcep_config_group_opts_g
;
769 return CMD_ERR_NO_MATCH
;
772 pce_config
->draft07
= true;
777 static int path_pcep_cli_peer_pce_initiated(struct vty
*vty
)
779 struct pcep_config_group_opts
*pce_config
= NULL
;
781 if (vty
->node
== PCEP_PCE_NODE
) {
782 /* TODO need to see if the pce is in use, and reset the
784 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
785 current_pce_opts_g
->merged
= false;
786 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
787 pce_config
= current_pcep_config_group_opts_g
;
789 return CMD_ERR_NO_MATCH
;
792 pce_config
->pce_initiated
= true;
797 static int path_pcep_cli_peer_tcp_md5_auth(struct vty
*vty
,
798 const char *tcp_md5_auth
)
800 struct pcep_config_group_opts
*pce_config
= NULL
;
802 if (vty
->node
== PCEP_PCE_NODE
) {
803 /* TODO need to see if the pce is in use, and reset the
805 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
806 current_pce_opts_g
->merged
= false;
807 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
808 pce_config
= current_pcep_config_group_opts_g
;
810 return CMD_ERR_NO_MATCH
;
813 strlcpy(pce_config
->tcp_md5_auth
, tcp_md5_auth
,
814 sizeof(pce_config
->tcp_md5_auth
));
819 static int path_pcep_cli_peer_address(struct vty
*vty
, const char *ip_str
,
820 struct in_addr
*ip
, const char *ipv6_str
,
821 struct in6_addr
*ipv6
,
822 const char *port_str
, long port
)
824 struct pce_opts
*pce_opts
= NULL
;
825 if (vty
->node
== PCEP_PCE_NODE
) {
826 /* TODO need to see if the pce is in use, and reset the
828 pce_opts
= ¤t_pce_opts_g
->pce_opts
;
829 current_pce_opts_g
->merged
= false;
831 return CMD_ERR_NO_MATCH
;
834 if (ipv6_str
!= NULL
) {
835 pce_opts
->addr
.ipa_type
= IPADDR_V6
;
836 memcpy(&pce_opts
->addr
.ipaddr_v6
, ipv6
,
837 sizeof(struct in6_addr
));
838 } else if (ip_str
!= NULL
) {
839 pce_opts
->addr
.ipa_type
= IPADDR_V4
;
840 memcpy(&pce_opts
->addr
.ipaddr_v4
, ip
, sizeof(struct in_addr
));
842 return CMD_ERR_NO_MATCH
;
845 /* Handle the optional port */
846 pce_opts
->port
= PCEP_DEFAULT_PORT
;
847 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_opts
->port
, 0, 65535);
852 static int path_pcep_cli_peer_source_address(struct vty
*vty
,
855 const char *ipv6_str
,
856 struct in6_addr
*ipv6
,
857 const char *port_str
, long port
)
859 struct pcep_config_group_opts
*pce_config
= NULL
;
860 if (vty
->node
== PCEP_PCE_NODE
) {
861 /* TODO need to see if the pce is in use, and reset the
863 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
864 current_pce_opts_g
->merged
= false;
865 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
866 pce_config
= current_pcep_config_group_opts_g
;
868 return CMD_ERR_NO_MATCH
;
871 /* Handle the optional source IP */
872 if (ipv6_str
!= NULL
) {
873 pce_config
->source_ip
.ipa_type
= IPADDR_V6
;
874 memcpy(&pce_config
->source_ip
.ipaddr_v6
, ipv6
,
875 sizeof(struct in6_addr
));
876 } else if (ip_str
!= NULL
) {
877 pce_config
->source_ip
.ipa_type
= IPADDR_V4
;
878 memcpy(&pce_config
->source_ip
.ipaddr_v4
, ip
,
879 sizeof(struct in_addr
));
882 /* Handle the optional port */
883 PCEP_VTYSH_INT_ARG_CHECK(port_str
, port
, pce_config
->source_port
, 0,
889 static int path_pcep_cli_peer_pcep_pce_config_ref(struct vty
*vty
,
890 const char *config_group_name
)
892 if (vty
->node
== PCEP_PCE_NODE
) {
893 /* TODO need to see if the pce is in use, and reset the
895 current_pce_opts_g
->merged
= false;
897 return CMD_ERR_NO_MATCH
;
900 struct pcep_config_group_opts
*pce_config
=
901 pcep_cli_find_pcep_pce_config(config_group_name
);
902 if (pce_config
== NULL
) {
903 vty_out(vty
, "%% pce-config [%s] does not exist.\n",
908 strlcpy(current_pce_opts_g
->config_group_name
, config_group_name
,
909 sizeof(current_pce_opts_g
->config_group_name
));
914 static int path_pcep_cli_peer_timers(
915 struct vty
*vty
, const char *keep_alive_str
, long keep_alive
,
916 const char *min_peer_keep_alive_str
, long min_peer_keep_alive
,
917 const char *max_peer_keep_alive_str
, long max_peer_keep_alive
,
918 const char *dead_timer_str
, long dead_timer
,
919 const char *min_peer_dead_timer_str
, long min_peer_dead_timer
,
920 const char *max_peer_dead_timer_str
, long max_peer_dead_timer
,
921 const char *pcep_request_str
, long pcep_request
,
922 const char *session_timeout_interval_str
, long session_timeout_interval
,
923 const char *delegation_timeout_str
, long delegation_timeout
)
925 struct pcep_config_group_opts
*pce_config
= NULL
;
926 if (vty
->node
== PCEP_PCE_NODE
) {
927 /* TODO need to see if the pce is in use, and reset the
929 pce_config
= ¤t_pce_opts_g
->pce_config_group_opts
;
930 current_pce_opts_g
->merged
= false;
931 } else if (vty
->node
== PCEP_PCE_CONFIG_NODE
) {
932 pce_config
= current_pcep_config_group_opts_g
;
934 return CMD_ERR_NO_MATCH
;
937 if (min_peer_keep_alive
&& max_peer_keep_alive
)
938 if (min_peer_keep_alive
>= max_peer_keep_alive
) {
939 return CMD_ERR_NO_MATCH
;
942 if (min_peer_dead_timer
&& max_peer_dead_timer
)
943 if (min_peer_dead_timer
>= max_peer_dead_timer
) {
944 return CMD_ERR_NO_MATCH
;
947 /* Handle the arguments */
948 PCEP_VTYSH_INT_ARG_CHECK(keep_alive_str
, keep_alive
,
949 pce_config
->keep_alive_seconds
, 0, 64);
950 PCEP_VTYSH_INT_ARG_CHECK(min_peer_keep_alive_str
, min_peer_keep_alive
,
951 pce_config
->min_keep_alive_seconds
, 0, 256);
952 PCEP_VTYSH_INT_ARG_CHECK(max_peer_keep_alive_str
, max_peer_keep_alive
,
953 pce_config
->max_keep_alive_seconds
, 0, 256);
954 PCEP_VTYSH_INT_ARG_CHECK(dead_timer_str
, dead_timer
,
955 pce_config
->dead_timer_seconds
, 3, 256);
956 PCEP_VTYSH_INT_ARG_CHECK(min_peer_dead_timer_str
, min_peer_dead_timer
,
957 pce_config
->min_dead_timer_seconds
, 3, 256);
958 PCEP_VTYSH_INT_ARG_CHECK(max_peer_dead_timer_str
, max_peer_dead_timer
,
959 pce_config
->max_dead_timer_seconds
, 3, 256);
960 PCEP_VTYSH_INT_ARG_CHECK(pcep_request_str
, pcep_request
,
961 pce_config
->pcep_request_time_seconds
, 0, 121);
962 PCEP_VTYSH_INT_ARG_CHECK(
963 session_timeout_interval_str
, session_timeout_interval
,
964 pce_config
->session_timeout_inteval_seconds
, 0, 121);
965 PCEP_VTYSH_INT_ARG_CHECK(delegation_timeout_str
, delegation_timeout
,
966 pce_config
->delegation_timeout_seconds
, 0, 61);
971 static int path_pcep_cli_pcc(struct vty
*vty
)
973 VTY_PUSH_CONTEXT_NULL(PCEP_PCC_NODE
);
978 static int path_pcep_cli_pcc_delete(struct vty
*vty
)
980 /* Clear the pce_connections */
981 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
982 pcc_msd_configured_g
= false;
984 pcep_ctrl_remove_pcc(pcep_g
->fpt
, NULL
);
989 static int path_pcep_cli_pcc_pcc_msd(struct vty
*vty
, const char *msd_str
,
992 pcc_msd_configured_g
= true;
993 PCEP_VTYSH_INT_ARG_CHECK(msd_str
, msd
, pcc_msd_g
, 0, 33);
998 static int path_pcep_cli_pcc_pcc_peer(struct vty
*vty
, const char *peer_name
,
999 const char *precedence_str
,
1002 /* Check if the pcc-peer exists */
1003 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1004 if (pce_opts_cli
== NULL
) {
1005 vty_out(vty
, "%% PCE [%s] does not exist.\n", peer_name
);
1008 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1010 /* Check if the pcc-peer is duplicated */
1011 if (pcep_cli_pcc_has_pce(peer_name
)) {
1012 vty_out(vty
, "%% The peer [%s] has already been configured.\n",
1017 /* Get the optional precedence argument */
1018 pce_opts
->precedence
= DEFAULT_PCE_PRECEDENCE
;
1019 PCEP_VTYSH_INT_ARG_CHECK(precedence_str
, precedence
,
1020 pce_opts
->precedence
, 0, 256);
1022 /* Finalize the pce_opts config values */
1023 pcep_cli_merge_pcep_pce_config_options(pce_opts_cli
);
1024 pcep_cli_add_pce_connection(&pce_opts_cli
->pce_opts
);
1026 /* Verify the PCE has the IP set */
1027 struct in6_addr zero_v6_addr
;
1028 memset(&zero_v6_addr
, 0, sizeof(zero_v6_addr
));
1029 if (memcmp(&pce_opts
->addr
.ip
, &zero_v6_addr
, IPADDRSZ(&pce_opts
->addr
))
1032 "%% The peer [%s] does not have an IP set and cannot be used until it does.\n",
1037 /* Update the pcc_opts with the source ip, port, and msd */
1038 struct pcc_opts
*pcc_opts_copy
=
1039 XMALLOC(MTYPE_PCEP
, sizeof(struct pcc_opts
));
1040 memcpy(&pcc_opts_copy
->addr
,
1041 &pce_opts_cli
->pce_opts
.config_opts
.source_ip
,
1042 sizeof(pcc_opts_copy
->addr
));
1043 pcc_opts_copy
->msd
= pcc_msd_g
;
1044 pcc_opts_copy
->port
= pce_opts_cli
->pce_opts
.config_opts
.source_port
;
1045 if (pcep_ctrl_update_pcc_options(pcep_g
->fpt
, pcc_opts_copy
)) {
1049 /* Send a copy of the pce_opts, this one is only used for the CLI */
1050 struct pce_opts
*pce_opts_copy
=
1051 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1052 memcpy(pce_opts_copy
, pce_opts
, sizeof(struct pce_opts
));
1053 if (pcep_ctrl_update_pce_options(pcep_g
->fpt
, pce_opts_copy
)) {
1060 static int path_pcep_cli_pcc_pcc_peer_delete(struct vty
*vty
,
1061 const char *peer_name
,
1062 const char *precedence_str
,
1065 /* Check if the pcc-peer is connected to the PCC */
1066 if (!pcep_cli_pcc_has_pce(peer_name
)) {
1068 "%% WARN: The peer [%s] is not connected to the PCC.\n",
1073 struct pce_opts_cli
*pce_opts_cli
= pcep_cli_find_pce(peer_name
);
1074 pcep_cli_remove_pce_connection(&pce_opts_cli
->pce_opts
);
1076 /* Send a copy of the pce_opts, this one is used for CLI only */
1077 struct pce_opts
*pce_opts_copy
=
1078 XMALLOC(MTYPE_PCEP
, sizeof(struct pce_opts
));
1079 memcpy(pce_opts_copy
, &pce_opts_cli
->pce_opts
, sizeof(struct pce_opts
));
1080 pcep_ctrl_remove_pcc(pcep_g
->fpt
, pce_opts_copy
);
1085 static int path_pcep_cli_show_srte_pcep_pcc(struct vty
*vty
)
1087 vty_out(vty
, "pcc msd %d\n", pcc_msd_g
);
1092 /* Internal util function to print pcep capabilities to a buffer */
1093 static void print_pcep_capabilities(char *buf
, size_t buf_len
,
1094 pcep_configuration
*config
)
1096 if (config
->support_stateful_pce_lsp_update
) {
1097 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_STATEFUL
);
1099 if (config
->support_include_db_version
) {
1100 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_INCL_DB_VER
);
1102 if (config
->support_lsp_triggered_resync
) {
1103 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_TRIGGERED
);
1105 if (config
->support_lsp_delta_sync
) {
1106 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_LSP_DELTA
);
1108 if (config
->support_pce_triggered_initial_sync
) {
1109 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCE_TRIGGERED
);
1111 if (config
->support_sr_te_pst
) {
1112 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_SR_TE_PST
);
1114 if (config
->pcc_can_resolve_nai_to_sid
) {
1115 csnprintfrr(buf
, buf_len
, "%s", PCEP_CLI_CAP_PCC_RESOLVE_NAI
);
1119 /* Internal util function to print a pcep session */
1120 static void print_pcep_session(struct vty
*vty
, struct pce_opts
*pce_opts
,
1121 struct pcep_pcc_info
*pcc_info
)
1126 vty_out(vty
, "\nPCE %s\n", pce_opts
->pce_name
);
1129 if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1130 vty_out(vty
, " PCE IP %pI4 port %d\n",
1131 &pce_opts
->addr
.ipaddr_v4
, pce_opts
->port
);
1132 } else if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1133 vty_out(vty
, " PCE IPv6 %pI6 port %d\n",
1134 &pce_opts
->addr
.ipaddr_v6
, pce_opts
->port
);
1138 if (IS_IPADDR_V4(&pcc_info
->pcc_addr
)) {
1139 vty_out(vty
, " PCC IP %pI4 port %d\n",
1140 &pcc_info
->pcc_addr
.ipaddr_v4
, pcc_info
->pcc_port
);
1141 } else if (IS_IPADDR_V6(&pcc_info
->pcc_addr
)) {
1142 vty_out(vty
, " PCC IPv6 %pI6 port %d\n",
1143 &pcc_info
->pcc_addr
.ipaddr_v6
, pcc_info
->pcc_port
);
1145 vty_out(vty
, " PCC MSD %d\n", pcc_info
->msd
);
1147 if (pcc_info
->status
== PCEP_PCC_OPERATING
) {
1148 vty_out(vty
, " Session Status UP\n");
1150 vty_out(vty
, " Session Status %s\n",
1151 pcc_status_name(pcc_info
->status
));
1154 if (pcc_info
->is_best_multi_pce
) {
1155 vty_out(vty
, " Precedence %d, best candidate\n",
1156 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1157 : DEFAULT_PCE_PRECEDENCE
));
1159 vty_out(vty
, " Precedence %d\n",
1160 ((pcc_info
->precedence
> 0) ? pcc_info
->precedence
1161 : DEFAULT_PCE_PRECEDENCE
));
1163 vty_out(vty
, " Confidence %s\n",
1164 ((pcc_info
->previous_best
) ? "low"
1167 /* PCEPlib pcep session values, get a thread safe copy of the counters
1169 pcep_session
*session
=
1170 pcep_ctrl_get_pcep_session(pcep_g
->fpt
, pcc_info
->pcc_id
);
1172 /* Config Options values */
1173 struct pcep_config_group_opts
*config_opts
= &pce_opts
->config_opts
;
1174 if (session
!= NULL
) {
1175 vty_out(vty
, " Timer: KeepAlive config %d, pce-negotiated %d\n",
1176 config_opts
->keep_alive_seconds
,
1178 .keep_alive_pce_negotiated_timer_seconds
);
1179 vty_out(vty
, " Timer: DeadTimer config %d, pce-negotiated %d\n",
1180 config_opts
->dead_timer_seconds
,
1181 session
->pcc_config
.dead_timer_pce_negotiated_seconds
);
1183 vty_out(vty
, " Timer: KeepAlive %d\n",
1184 config_opts
->keep_alive_seconds
);
1185 vty_out(vty
, " Timer: DeadTimer %d\n",
1186 config_opts
->dead_timer_seconds
);
1188 vty_out(vty
, " Timer: PcRequest %d\n",
1189 config_opts
->pcep_request_time_seconds
);
1190 vty_out(vty
, " Timer: SessionTimeout Interval %d\n",
1191 config_opts
->session_timeout_inteval_seconds
);
1192 vty_out(vty
, " Timer: Delegation Timeout %d\n",
1193 config_opts
->delegation_timeout_seconds
);
1194 if (strlen(config_opts
->tcp_md5_auth
) > 0) {
1195 vty_out(vty
, " TCP MD5 Auth Str: %s\n",
1196 config_opts
->tcp_md5_auth
);
1198 vty_out(vty
, " No TCP MD5 Auth\n");
1201 if (config_opts
->draft07
) {
1202 vty_out(vty
, " PCE SR Version draft07\n");
1204 vty_out(vty
, " PCE SR Version draft16 and RFC8408\n");
1207 vty_out(vty
, " Next PcReq ID %d\n", pcc_info
->next_reqid
);
1208 vty_out(vty
, " Next PLSP ID %d\n", pcc_info
->next_plspid
);
1210 if (session
!= NULL
) {
1211 if (pcc_info
->status
== PCEP_PCC_SYNCHRONIZING
1212 || pcc_info
->status
== PCEP_PCC_OPERATING
) {
1213 time_t current_time
= time(NULL
);
1215 /* Just for the timezone */
1216 localtime_r(¤t_time
, <
);
1217 gmtime_r(&session
->time_connected
, <
);
1219 " Connected for %u seconds, since %d-%02d-%02d %02d:%02d:%02d UTC\n",
1220 (uint32_t)(current_time
1221 - session
->time_connected
),
1222 lt
.tm_year
+ 1900, lt
.tm_mon
+ 1, lt
.tm_mday
,
1223 lt
.tm_hour
, lt
.tm_min
, lt
.tm_sec
);
1226 /* PCC capabilities */
1229 if (config_opts
->pce_initiated
) {
1230 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1231 PCEP_CLI_CAP_PCC_PCE_INITIATED
);
1233 index
+= csnprintfrr(buf
, sizeof(buf
), "%s",
1234 PCEP_CLI_CAP_PCC_INITIATED
);
1236 print_pcep_capabilities(buf
, sizeof(buf
) - index
,
1237 &session
->pcc_config
);
1238 vty_out(vty
, " PCC Capabilities:%s\n", buf
);
1240 /* PCE capabilities */
1242 print_pcep_capabilities(buf
, sizeof(buf
), &session
->pce_config
);
1243 if (buf
[0] != '\0') {
1244 vty_out(vty
, " PCE Capabilities:%s\n", buf
);
1246 XFREE(MTYPE_PCEP
, session
);
1248 vty_out(vty
, " Detailed session information not available\n");
1251 /* Message Counters, get a thread safe copy of the counters */
1252 struct counters_group
*group
=
1253 pcep_ctrl_get_counters(pcep_g
->fpt
, pcc_info
->pcc_id
);
1255 if (group
!= NULL
) {
1256 struct counters_subgroup
*rx_msgs
=
1257 find_subgroup(group
, COUNTER_SUBGROUP_ID_RX_MSG
);
1258 struct counters_subgroup
*tx_msgs
=
1259 find_subgroup(group
, COUNTER_SUBGROUP_ID_TX_MSG
);
1261 if (rx_msgs
!= NULL
&& tx_msgs
!= NULL
) {
1262 vty_out(vty
, " PCEP Message Statistics\n");
1263 vty_out(vty
, " %27s %6s\n", "Sent", "Rcvd");
1264 for (int i
= 0; i
< rx_msgs
->max_counters
; i
++) {
1265 struct counter
*rx_counter
=
1266 rx_msgs
->counters
[i
];
1267 struct counter
*tx_counter
=
1268 tx_msgs
->counters
[i
];
1269 if (rx_counter
!= NULL
&& tx_counter
!= NULL
) {
1270 vty_out(vty
, " %20s: %5d %5d\n",
1271 tx_counter
->counter_name
,
1272 tx_counter
->counter_value
,
1273 rx_counter
->counter_value
);
1276 vty_out(vty
, " %20s: %5d %5d\n", "Total",
1277 subgroup_counters_total(tx_msgs
),
1278 subgroup_counters_total(rx_msgs
));
1280 pcep_lib_free_counters(group
);
1282 vty_out(vty
, " Counters not available\n");
1285 XFREE(MTYPE_PCEP
, pcc_info
);
1288 static int path_pcep_cli_show_srte_pcep_session(struct vty
*vty
,
1289 const char *pcc_peer
)
1291 struct pce_opts_cli
*pce_opts_cli
;
1292 struct pcep_pcc_info
*pcc_info
;
1294 /* Only show 1 PCEP session */
1295 if (pcc_peer
!= NULL
) {
1296 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1297 if (pce_opts_cli
== NULL
) {
1298 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1302 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1303 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1308 pcc_info
= pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pcc_peer
);
1309 if (pcc_info
== NULL
) {
1311 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1316 print_pcep_session(vty
, &pce_opts_cli
->pce_opts
, pcc_info
);
1321 /* Show all PCEP sessions */
1322 struct pce_opts
*pce_opts
;
1323 int num_pcep_sessions_conf
= 0;
1324 int num_pcep_sessions_conn
= 0;
1325 for (int i
= 0; i
< MAX_PCC
; i
++) {
1326 pce_opts
= pce_connections_g
.connections
[i
];
1327 if (pce_opts
== NULL
) {
1332 pcep_ctrl_get_pcc_info(pcep_g
->fpt
, pce_opts
->pce_name
);
1333 if (pcc_info
== NULL
) {
1335 "%% Cannot retrieve PCEP session info for PCE [%s]\n",
1336 pce_opts
->pce_name
);
1340 num_pcep_sessions_conn
+=
1341 pcc_info
->status
== PCEP_PCC_OPERATING
? 1 : 0;
1342 num_pcep_sessions_conf
++;
1343 print_pcep_session(vty
, pce_opts
, pcc_info
);
1346 vty_out(vty
, "PCEP Sessions => Configured %d ; Connected %d\n",
1347 num_pcep_sessions_conf
, num_pcep_sessions_conn
);
1352 static int path_pcep_cli_clear_srte_pcep_session(struct vty
*vty
,
1353 const char *pcc_peer
)
1355 struct pce_opts_cli
*pce_opts_cli
;
1357 /* Only clear 1 PCEP session */
1358 if (pcc_peer
!= NULL
) {
1359 pce_opts_cli
= pcep_cli_find_pce(pcc_peer
);
1360 if (pce_opts_cli
== NULL
) {
1361 vty_out(vty
, "%% PCE [%s] does not exist.\n", pcc_peer
);
1365 if (!pcep_cli_pcc_has_pce(pcc_peer
)) {
1366 vty_out(vty
, "%% PCC is not connected to PCE [%s].\n",
1371 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
,
1372 pce_opts_cli
->pce_opts
.pce_name
);
1373 vty_out(vty
, "PCEP session cleared for peer %s\n", pcc_peer
);
1378 /* Clear all PCEP sessions */
1379 struct pce_opts
*pce_opts
;
1380 int num_pcep_sessions
= 0;
1381 for (int i
= 0; i
< MAX_PCC
; i
++) {
1382 pce_opts
= pce_connections_g
.connections
[i
];
1383 if (pce_opts
== NULL
) {
1387 num_pcep_sessions
++;
1388 pcep_ctrl_reset_pcc_session(pcep_g
->fpt
, pce_opts
->pce_name
);
1389 vty_out(vty
, "PCEP session cleared for peer %s\n",
1390 pce_opts
->pce_name
);
1393 vty_out(vty
, "Cleared [%d] PCEP sessions\n", num_pcep_sessions
);
1399 * Config Write functions
1402 int pcep_cli_debug_config_write(struct vty
*vty
)
1404 char buff
[128] = "";
1406 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1407 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1408 csnprintfrr(buff
, sizeof(buff
), " %s",
1409 PCEP_VTYSH_ARG_BASIC
);
1410 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1411 csnprintfrr(buff
, sizeof(buff
), " %s",
1412 PCEP_VTYSH_ARG_PATH
);
1413 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1414 csnprintfrr(buff
, sizeof(buff
), " %s",
1415 PCEP_VTYSH_ARG_MESSAGE
);
1416 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1417 csnprintfrr(buff
, sizeof(buff
), " %s",
1418 PCEP_VTYSH_ARG_PCEPLIB
);
1419 vty_out(vty
, "debug pathd pcep%s\n", buff
);
1427 int pcep_cli_debug_set_all(uint32_t flags
, bool set
)
1429 DEBUG_FLAGS_SET(&pcep_g
->dbg
, flags
, set
);
1431 /* If all modes have been turned off, don't preserve options. */
1432 if (!DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_ALL
))
1433 DEBUG_CLEAR(&pcep_g
->dbg
);
1438 int pcep_cli_pcep_config_write(struct vty
*vty
)
1440 vty_out(vty
, " pcep\n");
1441 pcep_cli_pcep_pce_config_write(vty
);
1442 pcep_cli_pce_config_write(vty
);
1443 pcep_cli_pcc_config_write(vty
);
1444 vty_out(vty
, " exit\n");
1448 int pcep_cli_pcc_config_write(struct vty
*vty
)
1450 struct pce_opts
*pce_opts
;
1454 /* The MSD, nor any PCE peers have been configured on the PCC */
1455 if (!pcc_msd_configured_g
&& pce_connections_g
.num_connections
== 0) {
1459 vty_out(vty
, " pcc\n");
1462 /* Prepare the MSD, if present */
1463 if (pcc_msd_configured_g
) {
1464 vty_out(vty
, " %s %d\n", PCEP_VTYSH_ARG_MSD
, pcc_msd_g
);
1468 if (pce_connections_g
.num_connections
== 0) {
1473 for (int i
= 0; i
< MAX_PCC
; i
++) {
1474 pce_opts
= pce_connections_g
.connections
[i
];
1475 if (pce_opts
== NULL
) {
1479 /* Only show the PCEs configured in the pcc sub-command */
1480 if (!pcep_cli_pcc_has_pce(pce_opts
->pce_name
)) {
1484 csnprintfrr(buf
, sizeof(buf
), " peer %s",
1485 pce_opts
->pce_name
);
1486 if (pce_opts
->precedence
> 0
1487 && pce_opts
->precedence
!= DEFAULT_PCE_PRECEDENCE
) {
1488 csnprintfrr(buf
, sizeof(buf
), " %s %d",
1489 PCEP_VTYSH_ARG_PRECEDENCE
,
1490 pce_opts
->precedence
);
1492 vty_out(vty
, "%s\n", buf
);
1497 vty_out(vty
, " exit\n");
1502 /* Internal function used by pcep_cli_pce_config_write()
1503 * and pcep_cli_pcep_pce_config_write() */
1504 static int pcep_cli_print_pce_config(struct pcep_config_group_opts
*group_opts
,
1505 char *buf
, size_t buf_len
)
1509 if (group_opts
->source_ip
.ipa_type
!= IPADDR_NONE
1510 || group_opts
->source_port
!= 0) {
1511 csnprintfrr(buf
, buf_len
, " ");
1512 if (IS_IPADDR_V4(&group_opts
->source_ip
)) {
1513 csnprintfrr(buf
, buf_len
, " %s %s %pI4",
1514 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1516 &group_opts
->source_ip
.ipaddr_v4
);
1517 } else if (IS_IPADDR_V6(&group_opts
->source_ip
)) {
1518 csnprintfrr(buf
, buf_len
, " %s %s %pI6",
1519 PCEP_VTYSH_ARG_SOURCE_ADDRESS
,
1520 PCEP_VTYSH_ARG_IPV6
,
1521 &group_opts
->source_ip
.ipaddr_v6
);
1523 if (group_opts
->source_port
> 0) {
1524 csnprintfrr(buf
, buf_len
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1525 group_opts
->source_port
);
1527 csnprintfrr(buf
, buf_len
, "\n");
1530 /* Group the keep-alive together for devman */
1531 if ((group_opts
->keep_alive_seconds
> 0)
1532 || (group_opts
->min_keep_alive_seconds
> 0)
1533 || (group_opts
->max_keep_alive_seconds
> 0)) {
1534 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1536 if (group_opts
->keep_alive_seconds
> 0) {
1537 csnprintfrr(buf
, buf_len
, " %s %d",
1538 PCEP_VTYSH_ARG_KEEP_ALIVE
,
1539 group_opts
->keep_alive_seconds
);
1541 if (group_opts
->min_keep_alive_seconds
> 0) {
1542 csnprintfrr(buf
, buf_len
, " %s %d",
1543 PCEP_VTYSH_ARG_KEEP_ALIVE_MIN
,
1544 group_opts
->min_keep_alive_seconds
);
1546 if (group_opts
->max_keep_alive_seconds
> 0) {
1547 csnprintfrr(buf
, buf_len
, " %s %d",
1548 PCEP_VTYSH_ARG_KEEP_ALIVE_MAX
,
1549 group_opts
->max_keep_alive_seconds
);
1551 csnprintfrr(buf
, buf_len
, "\n");
1555 /* Group the dead-timer together for devman */
1556 if ((group_opts
->dead_timer_seconds
> 0)
1557 || (group_opts
->min_dead_timer_seconds
> 0)
1558 || (group_opts
->max_dead_timer_seconds
> 0)) {
1559 csnprintfrr(buf
, buf_len
, " %s", PCEP_VTYSH_ARG_TIMER
);
1561 if (group_opts
->dead_timer_seconds
> 0) {
1562 csnprintfrr(buf
, buf_len
, " %s %d",
1563 PCEP_VTYSH_ARG_DEAD_TIMER
,
1564 group_opts
->dead_timer_seconds
);
1566 if (group_opts
->min_dead_timer_seconds
> 0) {
1567 csnprintfrr(buf
, buf_len
, " %s %d",
1568 PCEP_VTYSH_ARG_DEAD_TIMER_MIN
,
1569 group_opts
->min_dead_timer_seconds
);
1571 if (group_opts
->max_dead_timer_seconds
> 0) {
1572 csnprintfrr(buf
, buf_len
, " %s %d",
1573 PCEP_VTYSH_ARG_DEAD_TIMER_MAX
,
1574 group_opts
->max_dead_timer_seconds
);
1576 csnprintfrr(buf
, buf_len
, "\n");
1580 if (group_opts
->pcep_request_time_seconds
> 0) {
1581 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1582 PCEP_VTYSH_ARG_TIMER
, PCEP_VTYSH_ARG_PCEP_REQUEST
,
1583 group_opts
->pcep_request_time_seconds
);
1586 if (group_opts
->delegation_timeout_seconds
> 0) {
1587 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1588 PCEP_VTYSH_ARG_TIMER
,
1589 PCEP_VTYSH_ARG_DELEGATION_TIMEOUT
,
1590 group_opts
->delegation_timeout_seconds
);
1593 if (group_opts
->session_timeout_inteval_seconds
> 0) {
1594 csnprintfrr(buf
, buf_len
, " %s %s %d\n",
1595 PCEP_VTYSH_ARG_TIMER
,
1596 PCEP_VTYSH_ARG_SESSION_TIMEOUT
,
1597 group_opts
->session_timeout_inteval_seconds
);
1600 if (group_opts
->tcp_md5_auth
[0] != '\0') {
1601 csnprintfrr(buf
, buf_len
, " %s %s\n", PCEP_VTYSH_ARG_TCP_MD5
,
1602 group_opts
->tcp_md5_auth
);
1605 if (group_opts
->draft07
) {
1606 csnprintfrr(buf
, buf_len
, " %s\n",
1607 PCEP_VTYSH_ARG_SR_DRAFT07
);
1610 if (group_opts
->pce_initiated
) {
1611 csnprintfrr(buf
, buf_len
, " %s\n", PCEP_VTYSH_ARG_PCE_INIT
);
1618 int pcep_cli_pce_config_write(struct vty
*vty
)
1621 char buf
[1024] = "";
1623 for (int i
= 0; i
< MAX_PCE
; i
++) {
1624 struct pce_opts_cli
*pce_opts_cli
= pcep_g
->pce_opts_cli
[i
];
1625 if (pce_opts_cli
== NULL
) {
1628 struct pce_opts
*pce_opts
= &pce_opts_cli
->pce_opts
;
1630 vty_out(vty
, " pce %s\n", pce_opts
->pce_name
);
1631 if (IS_IPADDR_V6(&pce_opts
->addr
)) {
1632 vty_out(vty
, " %s %s %pI6", PCEP_VTYSH_ARG_ADDRESS
,
1633 PCEP_VTYSH_ARG_IPV6
, &pce_opts
->addr
.ipaddr_v6
);
1634 } else if (IS_IPADDR_V4(&pce_opts
->addr
)) {
1635 vty_out(vty
, " address %s %pI4", PCEP_VTYSH_ARG_IP
,
1636 &pce_opts
->addr
.ipaddr_v4
);
1638 if (pce_opts
->port
!= PCEP_DEFAULT_PORT
) {
1639 vty_out(vty
, " %s %d", PCEP_VTYSH_ARG_PORT
,
1642 vty_out(vty
, "%s\n", buf
);
1645 if (pce_opts_cli
->config_group_name
[0] != '\0') {
1646 vty_out(vty
, " config %s\n",
1647 pce_opts_cli
->config_group_name
);
1651 /* Only display the values configured on the PCE, not the values
1652 * from its optional pce-config-group, nor the default values */
1653 lines
+= pcep_cli_print_pce_config(
1654 &pce_opts_cli
->pce_config_group_opts
, buf
, sizeof(buf
));
1656 vty_out(vty
, "%s", buf
);
1659 vty_out(vty
, " exit\n");
1665 int pcep_cli_pcep_pce_config_write(struct vty
*vty
)
1668 char buf
[1024] = "";
1670 for (int i
= 0; i
< MAX_PCE
; i
++) {
1671 struct pcep_config_group_opts
*group_opts
=
1672 pcep_g
->config_group_opts
[i
];
1673 if (group_opts
== NULL
) {
1677 vty_out(vty
, " pce-config %s\n", group_opts
->name
);
1681 pcep_cli_print_pce_config(group_opts
, buf
, sizeof(buf
));
1682 vty_out(vty
, "%s", buf
);
1685 vty_out(vty
, " exit\n");
1692 * VTYSH command syntax definitions
1693 * The param names are taken from the path_pcep_cli_clippy.c generated file.
1696 DEFPY(show_debugging_pathd_pcep
,
1697 show_debugging_pathd_pcep_cmd
,
1698 "show debugging pathd-pcep",
1700 "State of each debugging option\n"
1701 "pathd pcep module debugging\n")
1703 vty_out(vty
, "Pathd pcep debugging status:\n");
1705 if (DEBUG_MODE_CHECK(&pcep_g
->dbg
, DEBUG_MODE_CONF
)) {
1706 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_BASIC
))
1707 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1708 PCEP_VTYSH_ARG_BASIC
);
1709 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PATH
))
1710 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1711 PCEP_VTYSH_ARG_PATH
);
1712 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEP
))
1713 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1714 PCEP_VTYSH_ARG_MESSAGE
);
1715 if (DEBUG_FLAGS_CHECK(&pcep_g
->dbg
, PCEP_DEBUG_MODE_PCEPLIB
))
1716 vty_out(vty
, " Pathd pcep %s debugging is on\n",
1717 PCEP_VTYSH_ARG_PCEPLIB
);
1723 DEFPY(pcep_cli_debug
,
1725 "[no] debug pathd pcep [basic]$basic_str [path]$path_str [message]$message_str [pceplib]$pceplib_str",
1728 "pcep module debugging\n"
1729 "module basic debugging\n"
1730 "path structures debugging\n"
1731 "pcep message debugging\n"
1732 "pceplib debugging\n")
1734 return path_pcep_cli_debug(vty
, no
, basic_str
, path_str
, message_str
,
1738 DEFPY(pcep_cli_show_srte_pcep_counters
,
1739 pcep_cli_show_srte_pcep_counters_cmd
,
1740 "show sr-te pcep counters",
1746 return path_pcep_cli_show_srte_pcep_counters(vty
);
1753 "PCEP configuration\n")
1755 vty
->node
= PCEP_NODE
;
1760 pcep_cli_pcep_pce_config
,
1761 pcep_cli_pcep_pce_config_cmd
,
1762 "pce-config WORD$name",
1763 "Shared configuration\n"
1764 "Shared configuration name\n")
1766 return path_pcep_cli_pcep_pce_config(vty
, name
);
1769 DEFPY(pcep_cli_pcep_no_pce_config
,
1770 pcep_cli_pcep_no_pce_config_cmd
,
1771 "no pce-config WORD$name",
1773 "Shared configuration\n"
1774 "Shared configuration name\n")
1776 return path_pcep_cli_pcep_pce_config_delete(vty
, name
);
1779 DEFPY(pcep_cli_show_srte_pcep_pce_config
,
1780 pcep_cli_show_srte_pcep_pce_config_cmd
,
1781 "show sr-te pcep pce-config [<default|WORD>$name]",
1785 "Show shared PCE configuration\n"
1786 "Show default hard-coded values\n"
1787 "Shared configuration name\n")
1789 return path_pcep_cli_show_srte_pcep_pce_config(vty
, name
);
1796 "PCE configuration, address sub-config is mandatory\n"
1799 return path_pcep_cli_pce(vty
, name
);
1802 DEFPY(pcep_cli_no_pce
,
1803 pcep_cli_no_pce_cmd
,
1806 "PCE configuration, address sub-config is mandatory\n"
1809 return path_pcep_cli_pce_delete(vty
, name
);
1812 DEFPY(pcep_cli_show_srte_pcep_pce
,
1813 pcep_cli_show_srte_pcep_pce_cmd
,
1814 "show sr-te pcep pce [WORD$name]",
1818 "Show detailed pce values\n"
1821 return path_pcep_cli_show_srte_pcep_pce(vty
, name
);
1824 DEFPY(pcep_cli_peer_sr_draft07
,
1825 pcep_cli_peer_sr_draft07_cmd
,
1827 "Configure PCC to send PCEP Open with SR draft07\n")
1829 return path_pcep_cli_peer_sr_draft07(vty
);
1832 DEFPY(pcep_cli_peer_pce_initiated
,
1833 pcep_cli_peer_pce_initiated_cmd
,
1835 "Configure PCC to accept PCE initiated LSPs\n")
1837 return path_pcep_cli_peer_pce_initiated(vty
);
1840 DEFPY(pcep_cli_peer_tcp_md5_auth
,
1841 pcep_cli_peer_tcp_md5_auth_cmd
,
1842 "tcp-md5-auth WORD",
1843 "Configure PCC TCP-MD5 RFC2385 Authentication\n"
1844 "TCP-MD5 Authentication string\n")
1846 return path_pcep_cli_peer_tcp_md5_auth(vty
, tcp_md5_auth
);
1849 DEFPY(pcep_cli_peer_address
,
1850 pcep_cli_peer_address_cmd
,
1851 "address <ip A.B.C.D | ipv6 X:X::X:X> [port (1024-65535)]",
1852 "PCE IP Address configuration, mandatory configuration\n"
1853 "PCE IPv4 address\n"
1854 "Remote PCE server IPv4 address\n"
1855 "PCE IPv6 address\n"
1856 "Remote PCE server IPv6 address\n"
1857 "Remote PCE server port\n"
1858 "Remote PCE server port value\n")
1860 return path_pcep_cli_peer_address(vty
, ip_str
, &ip
, ipv6_str
, &ipv6
,
1864 DEFPY(pcep_cli_peer_source_address
,
1865 pcep_cli_peer_source_address_cmd
,
1866 "source-address [ip A.B.C.D | ipv6 X:X::X:X] [port (1024-65535)]",
1867 "PCE source IP Address configuration\n"
1868 "PCE source IPv4 address\n"
1869 "PCE source IPv4 address value\n"
1870 "PCE source IPv6 address\n"
1871 "PCE source IPv6 address value\n"
1872 "Source PCE server port\n"
1873 "Source PCE server port value\n")
1875 return path_pcep_cli_peer_source_address(vty
, ip_str
, &ip
, ipv6_str
,
1876 &ipv6
, port_str
, port
);
1879 DEFPY(pcep_cli_peer_pcep_pce_config_ref
,
1880 pcep_cli_peer_pcep_pce_config_ref_cmd
,
1882 "PCE shared configuration to use\n"
1883 "Shared configuration name\n")
1885 return path_pcep_cli_peer_pcep_pce_config_ref(vty
, name
);
1888 DEFPY(pcep_cli_peer_timers
,
1889 pcep_cli_peer_timers_cmd
,
1890 "timer [keep-alive (1-63)] [min-peer-keep-alive (1-255)] [max-peer-keep-alive (1-255)] "
1891 "[dead-timer (4-255)] [min-peer-dead-timer (4-255)] [max-peer-dead-timer (4-255)] "
1892 "[pcep-request (1-120)] [session-timeout-interval (1-120)] [delegation-timeout (1-60)]",
1893 "PCE PCEP Session Timers configuration\n"
1894 "PCC Keep Alive Timer\n"
1895 "PCC Keep Alive Timer value in seconds\n"
1896 "Min Acceptable PCE Keep Alive Timer\n"
1897 "Min Acceptable PCE Keep Alive Timer value in seconds\n"
1898 "Max Acceptable PCE Keep Alive Timer\n"
1899 "Max Acceptable PCE Keep Alive Timer value in seconds\n"
1901 "PCC Dead Timer value in seconds\n"
1902 "Min Acceptable PCE Dead Timer\n"
1903 "Min Acceptable PCE Dead Timer value in seconds\n"
1904 "Max Acceptable PCE Dead Timer\n"
1905 "Max Acceptable PCE Dead Timer value in seconds\n"
1906 "PCC PCEP Request Timer\n"
1907 "PCC PCEP Request Timer value in seconds\n"
1908 "PCC Session Timeout Interval\n"
1909 "PCC Session Timeout Interval value in seconds\n"
1910 "Multi-PCE delegation timeout\n"
1911 "Multi-PCE delegation timeout value in seconds\n")
1913 return path_pcep_cli_peer_timers(
1914 vty
, keep_alive_str
, keep_alive
, min_peer_keep_alive_str
,
1915 min_peer_keep_alive
, max_peer_keep_alive_str
,
1916 max_peer_keep_alive
, dead_timer_str
, dead_timer
,
1917 min_peer_dead_timer_str
, min_peer_dead_timer
,
1918 max_peer_dead_timer_str
, max_peer_dead_timer
, pcep_request_str
,
1919 pcep_request
, session_timeout_interval_str
,
1920 session_timeout_interval
, delegation_timeout_str
,
1921 delegation_timeout
);
1928 "PCC configuration\n")
1930 return path_pcep_cli_pcc(vty
);
1933 DEFPY(pcep_cli_no_pcc
,
1934 pcep_cli_no_pcc_cmd
,
1937 "PCC configuration\n")
1939 return path_pcep_cli_pcc_delete(vty
);
1942 DEFPY(pcep_cli_pcc_pcc_msd
,
1943 pcep_cli_pcc_pcc_msd_cmd
,
1945 "PCC maximum SID depth \n"
1946 "PCC maximum SID depth value\n")
1948 return path_pcep_cli_pcc_pcc_msd(vty
, msd_str
, msd
);
1951 DEFPY(pcep_cli_pcc_pcc_peer
,
1952 pcep_cli_pcc_pcc_peer_cmd
,
1953 "[no] peer WORD [precedence (1-255)]",
1957 "PCC Multi-PCE precedence\n"
1961 return path_pcep_cli_pcc_pcc_peer_delete(
1962 vty
, peer
, precedence_str
, precedence
);
1964 return path_pcep_cli_pcc_pcc_peer(vty
, peer
, precedence_str
,
1969 DEFPY(pcep_cli_show_srte_pcc
,
1970 pcep_cli_show_srte_pcc_cmd
,
1971 "show sr-te pcep pcc",
1975 "Show current PCC configuration\n")
1977 return path_pcep_cli_show_srte_pcep_pcc(vty
);
1980 DEFPY(pcep_cli_show_srte_pcep_session
,
1981 pcep_cli_show_srte_pcep_session_cmd
,
1982 "show sr-te pcep session [WORD]$pce",
1986 "Show PCEP Session information\n"
1989 return path_pcep_cli_show_srte_pcep_session(vty
, pce
);
1992 DEFPY(pcep_cli_clear_srte_pcep_session
,
1993 pcep_cli_clear_srte_pcep_session_cmd
,
1994 "clear sr-te pcep session [WORD]$pce",
1998 "Reset PCEP connection\n"
2001 return path_pcep_cli_clear_srte_pcep_session(vty
, pce
);
2004 void pcep_cli_init(void)
2006 hook_register(pathd_srte_config_write
, pcep_cli_pcep_config_write
);
2007 hook_register(nb_client_debug_config_write
,
2008 pcep_cli_debug_config_write
);
2009 hook_register(nb_client_debug_set_all
, pcep_cli_debug_set_all
);
2011 memset(&pce_connections_g
, 0, sizeof(pce_connections_g
));
2013 install_node(&pcep_node
);
2014 install_node(&pcep_pcc_node
);
2015 install_node(&pcep_pce_node
);
2016 install_node(&pcep_pce_config_node
);
2018 install_default(PCEP_PCE_CONFIG_NODE
);
2019 install_default(PCEP_PCE_NODE
);
2020 install_default(PCEP_PCC_NODE
);
2021 install_default(PCEP_NODE
);
2023 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cli_pcep_cmd
);
2025 /* PCEP configuration group related configuration commands */
2026 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
2027 install_element(PCEP_NODE
, &pcep_cli_pcep_no_pce_config_cmd
);
2028 install_element(PCEP_PCE_CONFIG_NODE
,
2029 &pcep_cli_peer_source_address_cmd
);
2030 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_timers_cmd
);
2031 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2032 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2033 install_element(PCEP_PCE_CONFIG_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2035 /* PCE peer related configuration commands */
2036 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
2037 install_element(PCEP_NODE
, &pcep_cli_no_pce_cmd
);
2038 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_address_cmd
);
2039 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_source_address_cmd
);
2040 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pcep_pce_config_ref_cmd
);
2041 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_timers_cmd
);
2042 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_sr_draft07_cmd
);
2043 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_pce_initiated_cmd
);
2044 install_element(PCEP_PCE_NODE
, &pcep_cli_peer_tcp_md5_auth_cmd
);
2046 /* PCC related configuration commands */
2047 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcc_cmd
);
2048 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
2049 install_element(PCEP_NODE
, &pcep_cli_no_pcc_cmd
);
2050 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_peer_cmd
);
2051 install_element(PCEP_PCC_NODE
, &pcep_cli_pcc_pcc_msd_cmd
);
2054 install_element(CONFIG_NODE
, &pcep_cli_debug_cmd
);
2055 install_element(ENABLE_NODE
, &pcep_cli_debug_cmd
);
2056 install_element(ENABLE_NODE
, &show_debugging_pathd_pcep_cmd
);
2057 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_counters_cmd
);
2058 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_config_cmd
);
2059 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_pce_cmd
);
2060 install_element(ENABLE_NODE
, &pcep_cli_show_srte_pcep_session_cmd
);
2061 install_element(ENABLE_NODE
, &pcep_cli_clear_srte_pcep_session_cmd
);