diff options
Diffstat (limited to 'pathd/path_pcep_cli.c')
-rw-r--r-- | pathd/path_pcep_cli.c | 356 |
1 files changed, 313 insertions, 43 deletions
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(¤t_time, <); + gmtime_r(&session->time_connected, <); + 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); } |