diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index 90c13d4f93..88fa78ddfa 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -68,6 +68,10 @@ writing, *isisd* does not support multiple ISIS processes. Log changes in adjacency state. +.. clicmd:: log-pdu-drops + + Log any dropped PDUs. + .. clicmd:: metric-style [narrow | transition | wide] Set old-style (ISO 10589) or new-style packet formats: diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index 7e1bb9255c..ee51e46858 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -3025,6 +3025,26 @@ void cli_show_isis_log_adjacency(struct vty *vty, const struct lyd_node *dnode, vty_out(vty, " log-adjacency-changes\n"); } +/* + * XPath: /frr-isisd:isis/instance/log-pdu-drops + */ +DEFPY_YANG(log_pdu_drops, log_pdu_drops_cmd, "[no] log-pdu-drops", + NO_STR "Log any dropped PDUs\n") +{ + nb_cli_enqueue_change(vty, "./log-pdu-drops", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_log_pdu_drops(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " log-pdu-drops\n"); +} + /* * XPath: /frr-isisd:isis/instance/mpls/ldp-sync */ @@ -3290,6 +3310,7 @@ void isis_cli_init(void) install_element(INTERFACE_NODE, &isis_ti_lfa_cmd); install_element(ISIS_NODE, &log_adj_changes_cmd); + install_element(ISIS_NODE, &log_pdu_drops_cmd); install_element(ISIS_NODE, &isis_mpls_ldp_sync_cmd); install_element(ISIS_NODE, &no_isis_mpls_ldp_sync_cmd); diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c index 7dc3a0eb3d..9141bfc46c 100644 --- a/isisd/isis_nb.c +++ b/isisd/isis_nb.c @@ -558,6 +558,13 @@ const struct frr_yang_module_info frr_isisd_info = { .modify = isis_instance_log_adjacency_changes_modify, }, }, + { + .xpath = "/frr-isisd:isis/instance/log-pdu-drops", + .cbs = { + .cli_show = cli_show_isis_log_pdu_drops, + .modify = isis_instance_log_pdu_drops_modify, + }, + }, { .xpath = "/frr-isisd:isis/instance/mpls-te", .cbs = { diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index 480b2ce041..9a1f1f786f 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -196,6 +196,7 @@ int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_modify( int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_destroy( struct nb_cb_destroy_args *args); int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args); +int isis_instance_log_pdu_drops_modify(struct nb_cb_modify_args *args); int isis_instance_mpls_te_create(struct nb_cb_create_args *args); int isis_instance_mpls_te_destroy(struct nb_cb_destroy_args *args); int isis_instance_mpls_te_router_address_modify(struct nb_cb_modify_args *args); @@ -609,6 +610,8 @@ void cli_show_ip_isis_priority(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); void cli_show_isis_log_adjacency(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); +void cli_show_isis_log_pdu_drops(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults); void cli_show_isis_mpls_ldp_sync(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); void cli_show_isis_mpls_ldp_sync_holddown(struct vty *vty, diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 51e074e803..022bfbed6e 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -1830,6 +1830,23 @@ int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args) return NB_OK; } +/* + * XPath: /frr-isisd:isis/instance/log-pdu-drops + */ +int isis_instance_log_pdu_drops_modify(struct nb_cb_modify_args *args) +{ + struct isis_area *area; + bool log = yang_dnode_get_bool(args->dnode, NULL); + + if (args->event != NB_EV_APPLY) + return NB_OK; + + area = nb_running_get_entry(args->dnode, NULL, true); + area->log_pdu_drops = log ? 1 : 0; + + return NB_OK; +} + /* * XPath: /frr-isisd:isis/instance/mpls-te */ diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 0b84289f2d..0cd43a7abc 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -1651,14 +1651,14 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) if (idrp == ISO9542_ESIS) { flog_err(EC_LIB_DEVELOPMENT, "No support for ES-IS packet IDRP=%hhx", idrp); - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_ERROR; } if (idrp != ISO10589_ISIS) { flog_err(EC_ISIS_PACKET, "Not an IS-IS packet IDRP=%hhx", idrp); - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_ERROR; } @@ -1669,7 +1669,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) isis_notif_version_skew(circuit, version1, raw_pdu, sizeof(raw_pdu)); #endif /* ifndef FABRICD */ - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_WARNING; } @@ -1693,14 +1693,14 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) isis_notif_id_len_mismatch(circuit, id_len, raw_pdu, sizeof(raw_pdu)); #endif /* ifndef FABRICD */ - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_ERROR; } uint8_t expected_length; if (pdu_size(pdu_type, &expected_length)) { zlog_warn("Unsupported ISIS PDU %hhu", pdu_type); - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_WARNING; } @@ -1708,7 +1708,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) flog_err(EC_ISIS_PACKET, "Expected fixed header length = %hhu but got %hhu", expected_length, length); - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_ERROR; } @@ -1716,7 +1716,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) flog_err( EC_ISIS_PACKET, "PDU is too short to contain fixed header of given PDU type."); - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_ERROR; } @@ -1727,14 +1727,14 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) isis_notif_version_skew(circuit, version2, raw_pdu, sizeof(raw_pdu)); #endif /* ifndef FABRICD */ - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_WARNING; } if (circuit->is_passive) { zlog_warn("Received ISIS PDU on passive circuit %s", circuit->interface->name); - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_WARNING; } @@ -1753,7 +1753,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) isis_notif_max_area_addr_mismatch(circuit, max_area_addrs, raw_pdu, sizeof(raw_pdu)); #endif /* ifndef FABRICD */ - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_ERROR; } @@ -1762,8 +1762,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) case L2_LAN_HELLO: case P2P_HELLO: if (fabricd && pdu_type != P2P_HELLO) { - pdu_counter_count(circuit->area->pdu_drop_counters, - pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_ERROR; } @@ -1774,8 +1773,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) case FS_LINK_STATE: if (fabricd && pdu_type != L2_LINK_STATE && pdu_type != FS_LINK_STATE) { - pdu_counter_count(circuit->area->pdu_drop_counters, - pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_ERROR; } @@ -1788,12 +1786,12 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) retval = process_snp(pdu_type, circuit, ssnpa); break; default: - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return ISIS_ERROR; } if (retval != ISIS_OK) - pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type); + pdu_counter_count_drop(circuit->area, pdu_type); return retval; } @@ -2551,3 +2549,37 @@ out: isis_tx_queue_del(circuit->tx_queue, lsp); } } + +void isis_log_pdu_drops(struct isis_area *area, const char *pdu_type) +{ + uint64_t total_drops = 0; + + for (int i = 0; i < PDU_COUNTER_SIZE; i++) { + if (!area->pdu_drop_counters[i]) + continue; + total_drops += area->pdu_drop_counters[i]; + } + + zlog_info("PDU drop detected of type: %s. %" PRIu64 + " Total Drops; %" PRIu64 " L1 IIH drops; %" PRIu64 + " L2 IIH drops; %" PRIu64 " P2P IIH drops; %" PRIu64 + " L1 LSP drops; %" PRIu64 " L2 LSP drops; %" PRIu64 + " FS LSP drops; %" PRIu64 " L1 CSNP drops; %" PRIu64 + " L2 CSNP drops; %" PRIu64 " L1 PSNP drops; %" PRIu64 + " L2 PSNP drops.", + pdu_type, total_drops, + pdu_counter_get_count(area->pdu_drop_counters, L1_LAN_HELLO), + pdu_counter_get_count(area->pdu_drop_counters, L2_LAN_HELLO), + pdu_counter_get_count(area->pdu_drop_counters, P2P_HELLO), + pdu_counter_get_count(area->pdu_drop_counters, L1_LINK_STATE), + pdu_counter_get_count(area->pdu_drop_counters, L2_LINK_STATE), + pdu_counter_get_count(area->pdu_drop_counters, FS_LINK_STATE), + pdu_counter_get_count(area->pdu_drop_counters, + L1_COMPLETE_SEQ_NUM), + pdu_counter_get_count(area->pdu_drop_counters, + L2_COMPLETE_SEQ_NUM), + pdu_counter_get_count(area->pdu_drop_counters, + L1_PARTIAL_SEQ_NUM), + pdu_counter_get_count(area->pdu_drop_counters, + L2_PARTIAL_SEQ_NUM)); +} diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h index ccd89a70f1..5303c61d38 100644 --- a/isisd/isis_pdu.h +++ b/isisd/isis_pdu.h @@ -206,4 +206,6 @@ void send_lsp(struct isis_circuit *circuit, void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream); int send_hello(struct isis_circuit *circuit, int level); int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa); +void isis_log_pdu_drops(struct isis_area *area, const char *pdu_type); + #endif /* _ZEBRA_ISIS_PDU_H */ diff --git a/isisd/isis_pdu_counter.c b/isisd/isis_pdu_counter.c index 9d07b5e598..a3605a32a1 100644 --- a/isisd/isis_pdu_counter.c +++ b/isisd/isis_pdu_counter.c @@ -8,10 +8,10 @@ #include "vty.h" -#include "isisd/isis_pdu_counter.h" #include "isisd/isisd.h" #include "isisd/isis_circuit.h" #include "isisd/isis_pdu.h" +#include "isisd/isis_pdu_counter.h" static int pdu_type_to_counter_index(uint8_t pdu_type) { @@ -91,3 +91,23 @@ void pdu_counter_print(struct vty *vty, const char *prefix, pdu_counter_index_to_name(i), counter[i]); } } + +void pdu_counter_count_drop(struct isis_area *area, uint8_t pdu_type) +{ + pdu_counter_count(area->pdu_drop_counters, pdu_type); + + if (area->log_pdu_drops) { + isis_log_pdu_drops( + area, pdu_counter_index_to_name( + pdu_type_to_counter_index(pdu_type))); + } +} + +uint64_t pdu_counter_get_count(pdu_counter_t counter, uint8_t pdu_type) +{ + int index = pdu_type_to_counter_index(pdu_type); + + if (index < 0) + return -1; + return counter[index]; +} diff --git a/isisd/isis_pdu_counter.h b/isisd/isis_pdu_counter.h index c53c47368f..5c35b4fb51 100644 --- a/isisd/isis_pdu_counter.h +++ b/isisd/isis_pdu_counter.h @@ -24,5 +24,7 @@ typedef uint64_t pdu_counter_t[PDU_COUNTER_SIZE]; void pdu_counter_print(struct vty *vty, const char *prefix, pdu_counter_t counter); void pdu_counter_count(pdu_counter_t counter, uint8_t pdu_type); +void pdu_counter_count_drop(struct isis_area *area, uint8_t pdu_type); +uint64_t pdu_counter_get_count(pdu_counter_t counter, uint8_t pdu_type); #endif diff --git a/isisd/isisd.h b/isisd/isisd.h index 454876b7b0..12d9cd36c4 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -196,6 +196,8 @@ struct isis_area { int ip_circuits; /* logging adjacency changes? */ uint8_t log_adj_changes; + /* logging pdu drops? */ + uint8_t log_pdu_drops; /* multi topology settings */ struct list *mt_settings; /* MPLS-TE settings */ diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang index 66ec6a410d..de925b4823 100644 --- a/yang/frr-isisd.yang +++ b/yang/frr-isisd.yang @@ -1594,6 +1594,13 @@ module frr-isisd { "Log changes to the IS-IS adjacencies in this area."; } + leaf log-pdu-drops { + type boolean; + default "false"; + description + "Log any dropped PDUs in this area."; + } + container mpls-te { presence "Present if MPLS-TE is enabled."; description