summaryrefslogtreecommitdiffstats
path: root/pathd
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 04:24:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 04:24:31 +0000
commitacb594b1d825c6e12369cebb941968ec08c840ce (patch)
treed544788908e7353a4f117e2991f15f4236a0c963 /pathd
parentAdding upstream version 9.1. (diff)
downloadfrr-acb594b1d825c6e12369cebb941968ec08c840ce.tar.xz
frr-acb594b1d825c6e12369cebb941968ec08c840ce.zip
Adding upstream version 10.0.upstream/10.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'pathd')
-rw-r--r--pathd/path_cli.c76
-rw-r--r--pathd/path_main.c17
-rw-r--r--pathd/path_nb.c4
-rw-r--r--pathd/path_nb_config.c44
-rw-r--r--pathd/path_pcep.h1
-rw-r--r--pathd/path_pcep_cli.c356
-rw-r--r--pathd/path_zebra.c5
7 files changed, 392 insertions, 111 deletions
diff --git a/pathd/path_cli.c b/pathd/path_cli.c
index 45f4ac7..e22931c 100644
--- a/pathd/path_cli.c
+++ b/pathd/path_cli.c
@@ -287,7 +287,7 @@ void cli_show_srte_segment_list(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults)
{
vty_out(vty, " segment-list %s\n",
- yang_dnode_get_string(dnode, "./name"));
+ yang_dnode_get_string(dnode, "name"));
}
void cli_show_srte_segment_list_end(struct vty *vty,
@@ -546,37 +546,37 @@ void cli_show_srte_segment_list_segment(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
- vty_out(vty, " index %s", yang_dnode_get_string(dnode, "./index"));
- if (yang_dnode_exists(dnode, "./sid-value")) {
+ vty_out(vty, " index %s", yang_dnode_get_string(dnode, "index"));
+ if (yang_dnode_exists(dnode, "sid-value")) {
vty_out(vty, " mpls label %s",
- yang_dnode_get_string(dnode, "./sid-value"));
+ yang_dnode_get_string(dnode, "sid-value"));
}
- if (yang_dnode_exists(dnode, "./nai")) {
+ if (yang_dnode_exists(dnode, "nai")) {
struct ipaddr addr;
struct ipaddr addr_rmt;
- switch (yang_dnode_get_enum(dnode, "./nai/type")) {
+ switch (yang_dnode_get_enum(dnode, "nai/type")) {
case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE:
case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE:
case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM:
- yang_dnode_get_ip(&addr, dnode, "./nai/local-address");
+ yang_dnode_get_ip(&addr, dnode, "nai/local-address");
vty_out(vty, " nai prefix %pI4", &addr.ipaddr_v4);
break;
case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE:
case SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE:
case SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM:
- yang_dnode_get_ip(&addr, dnode, "./nai/local-address");
+ yang_dnode_get_ip(&addr, dnode, "nai/local-address");
vty_out(vty, " nai prefix %pI6", &addr.ipaddr_v6);
break;
case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY:
- yang_dnode_get_ip(&addr, dnode, "./nai/local-address");
+ yang_dnode_get_ip(&addr, dnode, "nai/local-address");
yang_dnode_get_ip(&addr_rmt, dnode,
"./nai/remote-address");
vty_out(vty, " nai adjacency %pI4", &addr.ipaddr_v4);
vty_out(vty, " %pI4", &addr_rmt.ipaddr_v4);
break;
case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY:
- yang_dnode_get_ip(&addr, dnode, "./nai/local-address");
+ yang_dnode_get_ip(&addr, dnode, "nai/local-address");
yang_dnode_get_ip(&addr_rmt, dnode,
"./nai/remote-address");
vty_out(vty, " nai adjacency %pI6", &addr.ipaddr_v6);
@@ -585,17 +585,17 @@ void cli_show_srte_segment_list_segment(struct vty *vty,
default:
break;
}
- if (yang_dnode_exists(dnode, "./nai/local-prefix-len")) {
+ if (yang_dnode_exists(dnode, "nai/local-prefix-len")) {
vty_out(vty, "/%s",
yang_dnode_get_string(
dnode, "./nai/local-prefix-len"));
}
- if (yang_dnode_exists(dnode, "./nai/local-interface")) {
+ if (yang_dnode_exists(dnode, "nai/local-interface")) {
vty_out(vty, " iface %s",
yang_dnode_get_string(dnode,
"./nai/local-interface"));
}
- if (yang_dnode_exists(dnode, "./nai/algorithm")) {
+ if (yang_dnode_exists(dnode, "nai/algorithm")) {
vty_out(vty, " algorithm %s",
yang_dnode_get_string(dnode,
"./nai/algorithm"));
@@ -658,8 +658,8 @@ void cli_show_srte_policy(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults)
{
vty_out(vty, " policy color %s endpoint %s\n",
- yang_dnode_get_string(dnode, "./color"),
- yang_dnode_get_string(dnode, "./endpoint"));
+ yang_dnode_get_string(dnode, "color"),
+ yang_dnode_get_string(dnode, "endpoint"));
}
void cli_show_srte_policy_end(struct vty *vty, const struct lyd_node *dnode)
@@ -860,7 +860,7 @@ DEFPY(srte_candidate_no_affinity_filter, srte_candidate_no_affinity_filter_cmd,
DEFPY(srte_candidate_metric,
srte_candidate_metric_cmd,
- "metric [bound$bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type METRIC$value [required$required]",
+ "metric [bound$bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type METRIC$value [required$required] [computed$computed]",
"Define a metric constraint\n"
"If the metric is bounded\n"
"IGP metric\n"
@@ -885,7 +885,8 @@ DEFPY(srte_candidate_metric,
"Domain Count metric\n"
"Border Node Count metric\n"
"Metric value\n"
- "Required constraint\n")
+ "Required constraint\n"
+ "Force the PCE to provide the computed path metric\n")
{
char xpath[XPATH_CANDIDATE_MAXLEN];
snprintf(xpath, sizeof(xpath), "./constraints/metrics[type='%s']/value",
@@ -899,12 +900,16 @@ DEFPY(srte_candidate_metric,
"./constraints/metrics[type='%s']/required", type);
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
required ? "true" : "false");
+ snprintf(xpath, sizeof(xpath),
+ "./constraints/metrics[type='%s']/is-computed", type);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+ computed ? "true" : "false");
return nb_cli_apply_changes(vty, NULL);
}
DEFPY(srte_candidate_no_metric,
srte_candidate_no_metric_cmd,
- "no metric [bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type [METRIC$value] [required$required]",
+ "no metric [bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type [METRIC$value] [required$required] [computed$computed]",
NO_STR
"Remove a metric constraint\n"
"If the metric is bounded\n"
@@ -930,7 +935,8 @@ DEFPY(srte_candidate_no_metric,
"Domain Count metric\n"
"Border Node Count metric\n"
"Metric value\n"
- "Required constraint\n")
+ "Required constraint\n"
+ "Force the PCE to provide the computed path metric\n")
{
char xpath[XPATH_CANDIDATE_MAXLEN];
snprintf(xpath, sizeof(xpath), "./constraints/metrics[type='%s']",
@@ -1164,7 +1170,8 @@ static void config_write_float(struct vty *vty, float value)
static void config_write_metric(struct vty *vty,
enum srte_candidate_metric_type type,
- float value, bool required, bool is_bound)
+ float value, bool required, bool is_bound,
+ bool is_computed)
{
const char *name = metric_type_name(type);
if (name == NULL)
@@ -1173,6 +1180,7 @@ static void config_write_metric(struct vty *vty,
metric_type_name(type));
config_write_float(vty, value);
vty_out(vty, required ? " required" : "");
+ vty_out(vty, is_computed ? " computed" : "");
vty_out(vty, "\n");
}
@@ -1180,16 +1188,18 @@ static int config_write_metric_cb(const struct lyd_node *dnode, void *arg)
{
struct vty *vty = arg;
enum srte_candidate_metric_type type;
- bool required, is_bound = false;
+ bool required, is_bound = false, is_computed = false;
float value;
- type = yang_dnode_get_enum(dnode, "./type");
- value = (float)yang_dnode_get_dec64(dnode, "./value");
- required = yang_dnode_get_bool(dnode, "./required");
- if (yang_dnode_exists(dnode, "./is-bound"))
- is_bound = yang_dnode_get_bool(dnode, "./is-bound");
+ type = yang_dnode_get_enum(dnode, "type");
+ value = (float)yang_dnode_get_dec64(dnode, "value");
+ required = yang_dnode_get_bool(dnode, "required");
+ if (yang_dnode_exists(dnode, "is-bound"))
+ is_bound = yang_dnode_get_bool(dnode, "is-bound");
+ if (yang_dnode_exists(dnode, "is-computed"))
+ is_computed = yang_dnode_get_bool(dnode, "is-computed");
- config_write_metric(vty, type, value, required, is_bound);
+ config_write_metric(vty, type, value, required, is_bound, is_computed);
return YANG_ITER_CONTINUE;
}
@@ -1201,18 +1211,18 @@ void cli_show_srte_policy_candidate_path(struct vty *vty,
uint32_t affinity;
bool required;
enum objfun_type objfun_type;
- const char *type = yang_dnode_get_string(dnode, "./type");
+ const char *type = yang_dnode_get_string(dnode, "type");
vty_out(vty, " candidate-path preference %s name %s %s",
- yang_dnode_get_string(dnode, "./preference"),
- yang_dnode_get_string(dnode, "./name"), type);
+ yang_dnode_get_string(dnode, "preference"),
+ yang_dnode_get_string(dnode, "name"), type);
if (strmatch(type, "explicit"))
vty_out(vty, " segment-list %s",
- yang_dnode_get_string(dnode, "./segment-list-name"));
+ yang_dnode_get_string(dnode, "segment-list-name"));
vty_out(vty, "\n");
if (strmatch(type, "dynamic")) {
- if (yang_dnode_exists(dnode, "./constraints/bandwidth")) {
+ if (yang_dnode_exists(dnode, "constraints/bandwidth")) {
bandwidth = (float)yang_dnode_get_dec64(
dnode, "./constraints/bandwidth/value");
required = yang_dnode_get_bool(
@@ -1262,7 +1272,7 @@ void cli_show_srte_policy_candidate_path(struct vty *vty,
void cli_show_srte_policy_candidate_path_end(struct vty *vty,
const struct lyd_node *dnode)
{
- const char *type = yang_dnode_get_string(dnode, "./type");
+ const char *type = yang_dnode_get_string(dnode, "type");
if (strmatch(type, "dynamic"))
vty_out(vty, " exit\n");
diff --git a/pathd/path_main.c b/pathd/path_main.c
index c333162..fe636c5 100644
--- a/pathd/path_main.c
+++ b/pathd/path_main.c
@@ -95,17 +95,20 @@ static const struct frr_yang_module_info *pathd_yang_modules[] = {
&frr_pathd_info,
};
-#define PATH_VTY_PORT 2621
+/* clang-format off */
+FRR_DAEMON_INFO(pathd, PATH,
+ .vty_port = PATH_VTY_PORT,
+ .proghelp = "Implementation of PATH.",
-FRR_DAEMON_INFO(pathd, PATH, .vty_port = PATH_VTY_PORT,
+ .signals = path_signals,
+ .n_signals = array_size(path_signals),
- .proghelp = "Implementation of PATH.",
+ .privs = &pathd_privs,
- .signals = path_signals, .n_signals = array_size(path_signals),
-
- .privs = &pathd_privs, .yang_modules = pathd_yang_modules,
- .n_yang_modules = array_size(pathd_yang_modules),
+ .yang_modules = pathd_yang_modules,
+ .n_yang_modules = array_size(pathd_yang_modules),
);
+/* clang-format on */
int main(int argc, char **argv, char **envp)
{
diff --git a/pathd/path_nb.c b/pathd/path_nb.c
index 9e91957..e1c0cc3 100644
--- a/pathd/path_nb.c
+++ b/pathd/path_nb.c
@@ -313,8 +313,8 @@ int iter_objfun_cb(const struct lyd_node *dnode, void *arg)
pref = &of_arg->prefs[of_arg->free_slot++];
- pref->index = yang_dnode_get_uint32(dnode, "./index");
- pref->type = yang_dnode_get_enum(dnode, "./type");
+ pref->index = yang_dnode_get_uint32(dnode, "index");
+ pref->type = yang_dnode_get_enum(dnode, "type");
/* Simplistic insertion sort */
p = &of_arg->first;
diff --git a/pathd/path_nb_config.c b/pathd/path_nb_config.c
index ad24f23..48531ba 100644
--- a/pathd/path_nb_config.c
+++ b/pathd/path_nb_config.c
@@ -31,7 +31,7 @@ int pathd_srte_segment_list_create(struct nb_cb_create_args *args)
if (args->event != NB_EV_APPLY)
return NB_OK;
- name = yang_dnode_get_string(args->dnode, "./name");
+ name = yang_dnode_get_string(args->dnode, "name");
segment_list = srte_segment_list_add(name);
nb_running_set_entry(args->dnode, segment_list);
SET_FLAG(segment_list->flags, F_SEGMENT_LIST_NEW);
@@ -104,7 +104,7 @@ int pathd_srte_segment_list_segment_create(struct nb_cb_create_args *args)
return NB_OK;
segment_list = nb_running_get_entry(args->dnode, NULL, true);
- index = yang_dnode_get_uint32(args->dnode, "./index");
+ index = yang_dnode_get_uint32(args->dnode, "index");
segment = srte_segment_entry_add(segment_list, index);
nb_running_set_entry(args->dnode, segment);
SET_FLAG(segment_list->flags, F_SEGMENT_LIST_MODIFIED);
@@ -191,9 +191,9 @@ void pathd_srte_segment_list_segment_nai_apply_finish(
const char *algo_buf, *local_prefix_len_buf;
segment = nb_running_get_entry(args->dnode, NULL, true);
- type = yang_dnode_get_enum(args->dnode, "./type");
+ type = yang_dnode_get_enum(args->dnode, "type");
- yang_dnode_get_ip(&local_addr, args->dnode, "./local-address");
+ yang_dnode_get_ip(&local_addr, args->dnode, "local-address");
switch (type) {
case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE:
@@ -208,12 +208,12 @@ void pathd_srte_segment_list_segment_nai_apply_finish(
yang_dnode_get_ip(&remote_addr, args->dnode,
"./remote-address");
local_iface =
- yang_dnode_get_uint32(args->dnode, "./local-interface");
+ yang_dnode_get_uint32(args->dnode, "local-interface");
remote_iface = yang_dnode_get_uint32(args->dnode,
"./remote-interface");
break;
case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM:
- algo_buf = yang_dnode_get_string(args->dnode, "./algorithm");
+ algo_buf = yang_dnode_get_string(args->dnode, "algorithm");
algo = atoi(algo_buf);
local_prefix_len_buf = yang_dnode_get_string(
args->dnode, "./local-prefix-len");
@@ -221,7 +221,7 @@ void pathd_srte_segment_list_segment_nai_apply_finish(
break;
case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE:
local_iface =
- yang_dnode_get_uint32(args->dnode, "./local-interface");
+ yang_dnode_get_uint32(args->dnode, "local-interface");
local_prefix_len_buf = yang_dnode_get_string(
args->dnode, "./local-prefix-len");
local_prefix_len = atoi(local_prefix_len_buf);
@@ -254,8 +254,8 @@ int pathd_srte_policy_create(struct nb_cb_create_args *args)
if (args->event != NB_EV_APPLY)
return NB_OK;
- color = yang_dnode_get_uint32(args->dnode, "./color");
- yang_dnode_get_ip(&endpoint, args->dnode, "./endpoint");
+ color = yang_dnode_get_uint32(args->dnode, "color");
+ yang_dnode_get_ip(&endpoint, args->dnode, "endpoint");
policy = srte_policy_add(color, &endpoint, SRTE_ORIGIN_LOCAL, NULL);
nb_running_set_entry(args->dnode, policy);
@@ -377,7 +377,7 @@ int pathd_srte_policy_candidate_path_create(struct nb_cb_create_args *args)
return NB_OK;
policy = nb_running_get_entry(args->dnode, NULL, true);
- preference = yang_dnode_get_uint32(args->dnode, "./preference");
+ preference = yang_dnode_get_uint32(args->dnode, "preference");
candidate =
srte_candidate_add(policy, preference, SRTE_ORIGIN_LOCAL, NULL);
nb_running_set_entry(args->dnode, candidate);
@@ -539,7 +539,7 @@ int pathd_srte_policy_candidate_path_metrics_destroy(
assert(args->context != NULL);
candidate = nb_running_get_entry(args->dnode, NULL, true);
- type = yang_dnode_get_enum(args->dnode, "./type");
+ type = yang_dnode_get_enum(args->dnode, "type");
srte_candidate_unset_metric(candidate, type);
return NB_OK;
@@ -557,13 +557,13 @@ void pathd_srte_policy_candidate_path_metrics_apply_finish(
candidate = nb_running_get_entry(args->dnode, NULL, true);
- type = yang_dnode_get_enum(args->dnode, "./type");
- value = (float)yang_dnode_get_dec64(args->dnode, "./value");
- required = yang_dnode_get_bool(args->dnode, "./required");
- if (yang_dnode_exists(args->dnode, "./is-bound"))
- is_bound = yang_dnode_get_bool(args->dnode, "./is-bound");
- if (yang_dnode_exists(args->dnode, "./is-computed"))
- is_computed = yang_dnode_get_bool(args->dnode, "./is-computed");
+ type = yang_dnode_get_enum(args->dnode, "type");
+ value = (float)yang_dnode_get_dec64(args->dnode, "value");
+ required = yang_dnode_get_bool(args->dnode, "required");
+ if (yang_dnode_exists(args->dnode, "is-bound"))
+ is_bound = yang_dnode_get_bool(args->dnode, "is-bound");
+ if (yang_dnode_exists(args->dnode, "is-computed"))
+ is_computed = yang_dnode_get_bool(args->dnode, "is-computed");
srte_candidate_set_metric(candidate, type, value, required, is_bound,
is_computed);
@@ -597,8 +597,8 @@ void pathd_srte_policy_candidate_path_objfun_apply_finish(
bool required;
candidate = nb_running_get_entry(args->dnode, NULL, true);
- required = yang_dnode_get_bool(args->dnode, "./required");
- type = yang_dnode_get_enum(args->dnode, "./type");
+ required = yang_dnode_get_bool(args->dnode, "required");
+ type = yang_dnode_get_enum(args->dnode, "type");
srte_candidate_set_objfun(candidate, required, type);
}
@@ -739,8 +739,8 @@ void pathd_srte_policy_candidate_path_bandwidth_apply_finish(
assert(args->context != NULL);
candidate = nb_running_get_entry(args->dnode, NULL, true);
- value = (float)yang_dnode_get_dec64(args->dnode, "./value");
- required = yang_dnode_get_bool(args->dnode, "./required");
+ value = (float)yang_dnode_get_dec64(args->dnode, "value");
+ required = yang_dnode_get_bool(args->dnode, "required");
srte_candidate_set_bandwidth(candidate, value, required);
}
diff --git a/pathd/path_pcep.h b/pathd/path_pcep.h
index 5c6a023..d6dbcb5 100644
--- a/pathd/path_pcep.h
+++ b/pathd/path_pcep.h
@@ -25,6 +25,7 @@ DECLARE_MTYPE(PCEP);
#define PCEP_DEBUG_MODE_PATH 0x02
#define PCEP_DEBUG_MODE_PCEP 0x04
#define PCEP_DEBUG_MODE_PCEPLIB 0x08
+#define PCEP_DEBUG_MODE_ALL 0x0F
#define PCEP_DEBUG(fmt, ...) \
do { \
if (DEBUG_FLAGS_CHECK(&pcep_g->dbg, PCEP_DEBUG_MODE_BASIC)) \
diff --git a/pathd/path_pcep_cli.c b/pathd/path_pcep_cli.c
index c46649b..47a811d 100644
--- a/pathd/path_pcep_cli.c
+++ b/pathd/path_pcep_cli.c
@@ -43,6 +43,8 @@
#define DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL 30
#define DEFAULT_DELEGATION_TIMEOUT_INTERVAL 10
+#define BUFFER_PCC_PCE_SIZE 1024
+
/* CLI Function declarations */
static int pcep_cli_debug_config_write(struct vty *vty);
static int pcep_cli_debug_set_all(uint32_t flags, bool set);
@@ -73,6 +75,9 @@ static void print_pcep_capabilities(char *buf, size_t buf_len,
pcep_configuration *config);
static void print_pcep_session(struct vty *vty, struct pce_opts *pce_opts,
struct pcep_pcc_info *pcc_info);
+static void print_pcep_session_json(struct vty *vty, struct pce_opts *pce_opts,
+ struct pcep_pcc_info *pcc_info,
+ json_object *json);
static bool pcep_cli_pcc_has_pce(const char *pce_name);
static void pcep_cli_add_pce_connection(struct pce_opts *pce_opts);
static void pcep_cli_remove_pce_connection(struct pce_opts *pce_opts);
@@ -458,28 +463,32 @@ static void pcep_cli_remove_pce_connection(struct pce_opts *pce_opts)
* VTY command implementations
*/
-static int path_pcep_cli_debug(struct vty *vty, const char *no_str,
- const char *basic_str, const char *path_str,
- const char *message_str, const char *pceplib_str)
+static int path_pcep_cli_debug(struct vty *vty, const char *debug_type, bool set)
{
uint32_t mode = DEBUG_NODE2MODE(vty->node);
- bool no = (no_str != NULL);
-
- DEBUG_MODE_SET(&pcep_g->dbg, mode, !no);
- if (basic_str != NULL) {
- DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_BASIC, !no);
- }
- if (path_str != NULL) {
- DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PATH, !no);
- }
- if (message_str != NULL) {
- DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PCEP, !no);
- }
- if (pceplib_str != NULL) {
- DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PCEPLIB, !no);
+ /* Global Set */
+ if (debug_type == NULL) {
+ DEBUG_MODE_SET(&pcep_g->dbg, mode, set);
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_ALL, set);
+ return CMD_SUCCESS;
}
+ DEBUG_MODE_SET(&pcep_g->dbg, mode, true);
+
+ if (strcmp(debug_type, "basic") == 0)
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_BASIC, set);
+ else if (strcmp(debug_type, "path") == 0)
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PATH, set);
+ else if (strcmp(debug_type, "message") == 0)
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PCEP, set);
+ else if (strcmp(debug_type, "pceplib") == 0)
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PCEPLIB, set);
+
+ /* Unset the pcep debug mode if there is no flag at least set*/
+ if (!DEBUG_FLAGS_CHECK(&pcep_g->dbg, PCEP_DEBUG_MODE_ALL))
+ DEBUG_MODE_SET(&pcep_g->dbg, mode, false);
+
return CMD_SUCCESS;
}
@@ -1022,7 +1031,7 @@ static int path_pcep_cli_pcc_pcc_msd(struct vty *vty, const char *msd_str,
{
if (reset)
pcc_msd_configured_g = false;
- else {
+ else if (msd_str) {
pcc_msd_configured_g = true;
PCEP_VTYSH_INT_ARG_CHECK(msd_str, msd, pcc_msd_g, 0, 33);
}
@@ -1183,10 +1192,188 @@ static void print_pcep_capabilities(char *buf, size_t buf_len,
}
/* Internal util function to print a pcep session */
+static void print_pcep_session_json(struct vty *vty, struct pce_opts *pce_opts,
+ struct pcep_pcc_info *pcc_info,
+ json_object *json)
+{
+ char buf[BUFFER_PCC_PCE_SIZE] = {};
+ int index = 0;
+ pcep_session *session;
+ struct pcep_config_group_opts *config_opts;
+ struct counters_group *group;
+
+ /* PCE IP */
+ if (IS_IPADDR_V4(&pce_opts->addr))
+ json_object_string_addf(json, "pceAddress", "%pI4",
+ &pce_opts->addr.ipaddr_v4);
+ else if (IS_IPADDR_V6(&pce_opts->addr))
+ json_object_string_addf(json, "pceAddress", "%pI6",
+ &pce_opts->addr.ipaddr_v6);
+ json_object_int_add(json, "pcePort", pce_opts->port);
+
+ /* PCC IP */
+ if (IS_IPADDR_V4(&pcc_info->pcc_addr))
+ json_object_string_addf(json, "pccAddress", "%pI4",
+ &pcc_info->pcc_addr.ipaddr_v4);
+ else if (IS_IPADDR_V6(&pcc_info->pcc_addr))
+ json_object_string_addf(json, "pccAddress", "%pI6",
+ &pcc_info->pcc_addr.ipaddr_v6);
+
+ json_object_int_add(json, "pccPort", pcc_info->pcc_port);
+ json_object_int_add(json, "pccMsd", pcc_info->msd);
+
+ if (pcc_info->status == PCEP_PCC_OPERATING)
+ json_object_string_add(json, "sessionStatus", "UP");
+ else
+ json_object_string_add(json, "sessionStatus",
+ pcc_status_name(pcc_info->status));
+
+ json_object_boolean_add(json, "bestMultiPce",
+ pcc_info->is_best_multi_pce);
+ json_object_int_add(json, "precedence",
+ pcc_info->precedence > 0 ? pcc_info->precedence
+ : DEFAULT_PCE_PRECEDENCE);
+ json_object_string_add(json, "confidence",
+ pcc_info->previous_best ? "low" : "normal");
+
+ /* PCEPlib pcep session values, get a thread safe copy of the counters
+ */
+ session = pcep_ctrl_get_pcep_session(pcep_g->fpt, pcc_info->pcc_id);
+
+ /* Config Options values */
+ config_opts = &pce_opts->config_opts;
+ json_object_int_add(json, "keepaliveConfig",
+ config_opts->keep_alive_seconds);
+ json_object_int_add(json, "deadTimerConfig",
+ config_opts->dead_timer_seconds);
+ json_object_int_add(json, "pccPcepRequestTimerConfig",
+ config_opts->pcep_request_time_seconds);
+ json_object_int_add(json, "sessionTimeoutIntervalSec",
+ config_opts->session_timeout_inteval_seconds);
+ json_object_int_add(json, "delegationTimeout",
+ config_opts->delegation_timeout_seconds);
+ json_object_boolean_add(json, "tcpMd5Authentication",
+ (strlen(config_opts->tcp_md5_auth) > 0));
+ if (strlen(config_opts->tcp_md5_auth) > 0)
+ json_object_string_add(json, "tcpMd5AuthenticationString",
+ config_opts->tcp_md5_auth);
+ json_object_boolean_add(json, "draft07", !!config_opts->draft07);
+ json_object_boolean_add(json, "draft16AndRfc8408",
+ !config_opts->draft07);
+
+ json_object_int_add(json, "nextPcRequestId", pcc_info->next_reqid);
+ /* original identifier used by the PCC for LSP instantiation */
+ json_object_int_add(json, "nextPLspId", pcc_info->next_plspid);
+
+ if (session != NULL) {
+ json_object_int_add(json, "sessionKeepalivePceNegotiatedSec",
+ session->pcc_config
+ .keep_alive_pce_negotiated_timer_seconds);
+ json_object_int_add(json, "sessionDeadTimerPceNegotiatedSec",
+ session->pcc_config
+ .dead_timer_pce_negotiated_seconds);
+ if (pcc_info->status == PCEP_PCC_SYNCHRONIZING ||
+ pcc_info->status == PCEP_PCC_OPERATING) {
+ time_t current_time = time(NULL);
+ struct tm lt = { 0 };
+ /* Just for the timezone */
+ localtime_r(&current_time, &lt);
+ gmtime_r(&session->time_connected, &lt);
+ json_object_int_add(json, "sessionConnectionDurationSec",
+ (uint32_t)(current_time -
+ session->time_connected));
+ json_object_string_addf(json,
+ "sessionConnectionStartTimeUTC",
+ "%d-%02d-%02d %02d:%02d:%02d",
+ lt.tm_year + 1900, lt.tm_mon + 1,
+ lt.tm_mday, lt.tm_hour,
+ lt.tm_min, lt.tm_sec);
+ }
+
+ /* PCC capabilities */
+ buf[0] = '\0';
+
+ if (config_opts->pce_initiated)
+ index += csnprintfrr(buf, sizeof(buf), "%s",
+ PCEP_CLI_CAP_PCC_PCE_INITIATED);
+ else
+ index += csnprintfrr(buf, sizeof(buf), "%s",
+ PCEP_CLI_CAP_PCC_INITIATED);
+ print_pcep_capabilities(buf, sizeof(buf) - index,
+ &session->pcc_config);
+ json_object_string_add(json, "pccCapabilities", buf);
+
+ /* PCE capabilities */
+ buf[0] = '\0';
+ print_pcep_capabilities(buf, sizeof(buf), &session->pce_config);
+ if (buf[0] != '\0')
+ json_object_string_add(json, "pceCapabilities", buf);
+ XFREE(MTYPE_PCEP, session);
+ } else {
+ json_object_string_add(json, "warningSession",
+ "Detailed session information not available.");
+ }
+
+ /* Message Counters, get a thread safe copy of the counters */
+ group = pcep_ctrl_get_counters(pcep_g->fpt, pcc_info->pcc_id);
+
+ if (group != NULL) {
+ struct counters_subgroup *rx_msgs =
+ find_subgroup(group, COUNTER_SUBGROUP_ID_RX_MSG);
+ struct counters_subgroup *tx_msgs =
+ find_subgroup(group, COUNTER_SUBGROUP_ID_TX_MSG);
+ json_object *json_counter;
+ struct counter *tx_counter, *rx_counter;
+
+ if (rx_msgs != NULL) {
+ json_counter = json_object_new_object();
+ for (int i = 0; i < rx_msgs->max_counters; i++) {
+ rx_counter = rx_msgs->counters[i];
+
+ if (rx_counter &&
+ rx_counter->counter_name_json[0] != '\0')
+ json_object_int_add(
+ json_counter,
+ rx_counter->counter_name_json,
+ rx_counter->counter_value);
+ }
+ json_object_int_add(json_counter, "total",
+ subgroup_counters_total(rx_msgs));
+ json_object_object_add(json, "messageStatisticsReceived",
+ json_counter);
+ }
+ if (tx_msgs != NULL) {
+ json_counter = json_object_new_object();
+ for (int i = 0; i < tx_msgs->max_counters; i++) {
+ tx_counter = tx_msgs->counters[i];
+
+ if (tx_counter &&
+ tx_counter->counter_name_json[0] != '\0')
+ json_object_int_add(
+ json_counter,
+ tx_counter->counter_name_json,
+ tx_counter->counter_value);
+ }
+ json_object_int_add(json_counter, "total",
+ subgroup_counters_total(tx_msgs));
+ json_object_object_add(json, "messageStatisticsSent",
+ json_counter);
+ }
+ pcep_lib_free_counters(group);
+ } else {
+ json_object_string_add(json, "messageStatisticsWarning",
+ "Counters not available.");
+ }
+
+ XFREE(MTYPE_PCEP, pcc_info);
+}
+
+/* Internal util function to print a pcep session */
static void print_pcep_session(struct vty *vty, struct pce_opts *pce_opts,
struct pcep_pcc_info *pcc_info)
{
char buf[1024];
+
buf[0] = '\0';
vty_out(vty, "\nPCE %s\n", pce_opts->pce_name);
@@ -1237,6 +1424,7 @@ static void print_pcep_session(struct vty *vty, struct pce_opts *pce_opts,
/* Config Options values */
struct pcep_config_group_opts *config_opts = &pce_opts->config_opts;
+
if (session != NULL) {
vty_out(vty, " Timer: KeepAlive config %d, pce-negotiated %d\n",
config_opts->keep_alive_seconds,
@@ -1352,34 +1540,66 @@ static void print_pcep_session(struct vty *vty, struct pce_opts *pce_opts,
}
static int path_pcep_cli_show_srte_pcep_session(struct vty *vty,
- const char *pcc_peer)
+ const char *pcc_peer, bool uj)
{
struct pce_opts_cli *pce_opts_cli;
struct pcep_pcc_info *pcc_info;
+ json_object *json = NULL;
+
+ if (uj)
+ json = json_object_new_object();
/* Only show 1 PCEP session */
if (pcc_peer != NULL) {
+ if (json)
+ json_object_string_add(json, "pceName", pcc_peer);
pce_opts_cli = pcep_cli_find_pce(pcc_peer);
if (pce_opts_cli == NULL) {
- vty_out(vty, "%% PCE [%s] does not exist.\n", pcc_peer);
+ if (json) {
+ json_object_string_addf(json, "warning",
+ "PCE [%s] does not exist.",
+ pcc_peer);
+ vty_json(vty, json);
+ } else
+ vty_out(vty, "%% PCE [%s] does not exist.\n",
+ pcc_peer);
return CMD_WARNING;
}
if (!pcep_cli_pcc_has_pce(pcc_peer)) {
- vty_out(vty, "%% PCC is not connected to PCE [%s].\n",
- pcc_peer);
+ if (json) {
+ json_object_string_addf(json, "warning",
+ "PCC is not connected to PCE [%s].",
+ pcc_peer);
+ vty_json(vty, json);
+ } else
+ vty_out(vty,
+ "%% PCC is not connected to PCE [%s].\n",
+ pcc_peer);
return CMD_WARNING;
}
pcc_info = pcep_ctrl_get_pcc_info(pcep_g->fpt, pcc_peer);
if (pcc_info == NULL) {
- vty_out(vty,
- "%% Cannot retrieve PCEP session info for PCE [%s]\n",
- pcc_peer);
+ if (json) {
+ json_object_string_addf(json, "warning",
+ "Cannot retrieve PCEP session info for PCE [%s].",
+ pcc_peer);
+ vty_json(vty, json);
+ } else
+ vty_out(vty,
+ "%% Cannot retrieve PCEP session info for PCE [%s]\n",
+ pcc_peer);
return CMD_WARNING;
}
- print_pcep_session(vty, &pce_opts_cli->pce_opts, pcc_info);
+ if (json) {
+ print_pcep_session_json(vty, &pce_opts_cli->pce_opts,
+ pcc_info, json);
+ vty_json(vty, json);
+ } else
+ print_pcep_session(vty, &pce_opts_cli->pce_opts,
+ pcc_info);
return CMD_SUCCESS;
}
@@ -1388,29 +1608,56 @@ static int path_pcep_cli_show_srte_pcep_session(struct vty *vty,
struct pce_opts *pce_opts;
int num_pcep_sessions_conf = 0;
int num_pcep_sessions_conn = 0;
+ json_object *json_array = NULL, *json_entry = NULL;
+
+ if (json)
+ json_array = json_object_new_array();
for (int i = 0; i < MAX_PCC; i++) {
pce_opts = pce_connections_g.connections[i];
if (pce_opts == NULL) {
continue;
}
+ if (json) {
+ json_entry = json_object_new_object();
+ json_object_string_add(json_entry, "pceName",
+ pce_opts->pce_name);
+ }
pcc_info =
pcep_ctrl_get_pcc_info(pcep_g->fpt, pce_opts->pce_name);
if (pcc_info == NULL) {
- vty_out(vty,
- "%% Cannot retrieve PCEP session info for PCE [%s]\n",
- pce_opts->pce_name);
+ if (json_entry) {
+ json_object_string_addf(json_entry, "warning",
+ "Cannot retrieve PCEP session info for PCE [%s].",
+ pce_opts->pce_name);
+ json_object_array_add(json_array, json_entry);
+ } else
+ vty_out(vty,
+ "%% Cannot retrieve PCEP session info for PCE [%s]\n",
+ pce_opts->pce_name);
continue;
}
num_pcep_sessions_conn +=
pcc_info->status == PCEP_PCC_OPERATING ? 1 : 0;
num_pcep_sessions_conf++;
- print_pcep_session(vty, pce_opts, pcc_info);
- }
-
- vty_out(vty, "PCEP Sessions => Configured %d ; Connected %d\n",
- num_pcep_sessions_conf, num_pcep_sessions_conn);
+ if (json_entry) {
+ print_pcep_session_json(vty, pce_opts, pcc_info,
+ json_entry);
+ json_object_array_add(json_array, json_entry);
+ } else
+ print_pcep_session(vty, pce_opts, pcc_info);
+ }
+ if (json) {
+ json_object_object_add(json, "pcepSessions", json_array);
+ json_object_int_add(json, "pcepSessionsConfigured",
+ num_pcep_sessions_conf);
+ json_object_int_add(json, "pcepSessionsConnected",
+ num_pcep_sessions_conn);
+ vty_json(vty, json);
+ } else
+ vty_out(vty, "PCEP Sessions => Configured %d ; Connected %d\n",
+ num_pcep_sessions_conf, num_pcep_sessions_conn);
return CMD_SUCCESS;
}
@@ -1702,7 +1949,7 @@ int pcep_cli_pce_config_write(struct vty *vty)
&pce_opts->addr.ipaddr_v4);
}
if (pce_opts->port != PCEP_DEFAULT_PORT) {
- vty_out(vty, " %s %d", PCEP_VTYSH_ARG_PORT,
+ vty_out(vty, " %s %d", PCEP_VTYSH_ARG_PORT,
pce_opts->port);
}
vty_out(vty, "%s\n", buf);
@@ -1788,7 +2035,7 @@ DEFPY(show_debugging_pathd_pcep,
DEFPY(pcep_cli_debug,
pcep_cli_debug_cmd,
- "[no] debug pathd pcep [basic]$basic_str [path]$path_str [message]$message_str [pceplib]$pceplib_str",
+ "[no] debug pathd pcep [<basic|path|message|pceplib>$debug_type]",
NO_STR DEBUG_STR
"pathd debugging\n"
"pcep module debugging\n"
@@ -1797,8 +2044,7 @@ DEFPY(pcep_cli_debug,
"pcep message debugging\n"
"pceplib debugging\n")
{
- return path_pcep_cli_debug(vty, no, basic_str, path_str, message_str,
- pceplib_str);
+ return path_pcep_cli_debug(vty, debug_type, !no);
}
DEFPY(pcep_cli_show_srte_pcep_counters,
@@ -2040,12 +2286,21 @@ DEFPY(pcep_cli_no_pcc,
DEFPY(pcep_cli_pcc_pcc_msd,
pcep_cli_pcc_pcc_msd_cmd,
- "[no] msd (1-32)",
+ "msd (1-32)",
+ "PCC maximum SID depth \n"
+ "PCC maximum SID depth value\n")
+{
+ return path_pcep_cli_pcc_pcc_msd(vty, msd_str, msd, false);
+}
+
+DEFPY(no_pcep_cli_pcc_pcc_msd,
+ no_pcep_cli_pcc_pcc_msd_cmd,
+ "no msd [(1-32)]",
NO_STR
"PCC maximum SID depth \n"
"PCC maximum SID depth value\n")
{
- return path_pcep_cli_pcc_pcc_msd(vty, msd_str, msd, no);
+ return path_pcep_cli_pcc_pcc_msd(vty, msd_str, msd, true);
}
DEFPY(pcep_cli_pcc_pcc_peer,
@@ -2079,14 +2334,27 @@ DEFPY(pcep_cli_show_srte_pcc,
DEFPY(pcep_cli_show_srte_pcep_session,
pcep_cli_show_srte_pcep_session_cmd,
- "show sr-te pcep session [WORD]$pce",
+ "show sr-te pcep session WORD$pce [json$uj]",
SHOW_STR
"SR-TE info\n"
"PCEP info\n"
"Show PCEP Session information\n"
- "PCE name\n")
+ "PCE name\n"
+ JSON_STR)
+{
+ return path_pcep_cli_show_srte_pcep_session(vty, pce, !!uj);
+}
+
+DEFPY(pcep_cli_show_srte_pcep_sessions,
+ pcep_cli_show_srte_pcep_sessions_cmd,
+ "show sr-te pcep session [json$uj]",
+ SHOW_STR
+ "SR-TE info\n"
+ "PCEP info\n"
+ "Show PCEP Session information\n"
+ JSON_STR)
{
- return path_pcep_cli_show_srte_pcep_session(vty, pce);
+ return path_pcep_cli_show_srte_pcep_session(vty, NULL, !!uj);
}
DEFPY(pcep_cli_clear_srte_pcep_session,
@@ -2150,6 +2418,7 @@ void pcep_cli_init(void)
install_element(PCEP_NODE, &pcep_cli_no_pcc_cmd);
install_element(PCEP_PCC_NODE, &pcep_cli_pcc_pcc_peer_cmd);
install_element(PCEP_PCC_NODE, &pcep_cli_pcc_pcc_msd_cmd);
+ install_element(PCEP_PCC_NODE, &no_pcep_cli_pcc_pcc_msd_cmd);
/* Top commands */
install_element(CONFIG_NODE, &pcep_cli_debug_cmd);
@@ -2159,5 +2428,6 @@ void pcep_cli_init(void)
install_element(ENABLE_NODE, &pcep_cli_show_srte_pcep_pce_config_cmd);
install_element(ENABLE_NODE, &pcep_cli_show_srte_pcep_pce_cmd);
install_element(ENABLE_NODE, &pcep_cli_show_srte_pcep_session_cmd);
+ install_element(ENABLE_NODE, &pcep_cli_show_srte_pcep_sessions_cmd);
install_element(ENABLE_NODE, &pcep_cli_clear_srte_pcep_session_cmd);
}
diff --git a/pathd/path_zebra.c b/pathd/path_zebra.c
index 826443f..645fa50 100644
--- a/pathd/path_zebra.c
+++ b/pathd/path_zebra.c
@@ -320,9 +320,6 @@ static zclient_handler *const path_handlers[] = {
*/
void path_zebra_init(struct event_loop *master)
{
- struct zclient_options options = zclient_options_default;
- options.synchronous = true;
-
/* Initialize asynchronous zclient. */
zclient = zclient_new(master, &zclient_options_default, path_handlers,
array_size(path_handlers));
@@ -330,7 +327,7 @@ void path_zebra_init(struct event_loop *master)
zclient->zebra_connected = path_zebra_connected;
/* Initialize special zclient for synchronous message exchanges. */
- zclient_sync = zclient_new(master, &options, NULL, 0);
+ zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_SRTE;
zclient_sync->instance = 1;