diff options
author | Christian Franke <chris@opensourcerouting.org> | 2018-11-23 03:13:56 +0100 |
---|---|---|
committer | Rodny Molina <rmolina@linkedin.com> | 2018-12-07 20:45:14 +0100 |
commit | 1eb7c3a19568c8e460b8147c9dcd91cf0b9feb21 (patch) | |
tree | c9215e4fdfeb83ea1e2264245aef29eb466ea088 | |
parent | isisd: Make lspid_print non-static (diff) | |
download | frr-1eb7c3a19568c8e460b8147c9dcd91cf0b9feb21.tar.xz frr-1eb7c3a19568c8e460b8147c9dcd91cf0b9feb21.zip |
fabricd: Add `show openfabric flooding` command
Add a command to show to what neighbors an LSP has been flooded.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
-rw-r--r-- | isisd/fabricd.c | 60 | ||||
-rw-r--r-- | isisd/fabricd.h | 3 | ||||
-rw-r--r-- | isisd/isis_lsp.c | 4 | ||||
-rw-r--r-- | isisd/isis_lsp.h | 3 | ||||
-rw-r--r-- | isisd/isis_vty_fabricd.c | 85 |
5 files changed, 144 insertions, 11 deletions
diff --git a/isisd/fabricd.c b/isisd/fabricd.c index 5a9c424d6..3b6db67c2 100644 --- a/isisd/fabricd.c +++ b/isisd/fabricd.c @@ -35,6 +35,7 @@ DEFINE_MTYPE_STATIC(ISISD, FABRICD_STATE, "ISIS OpenFabric") DEFINE_MTYPE_STATIC(ISISD, FABRICD_NEIGHBOR, "ISIS OpenFabric Neighbor Entry") +DEFINE_MTYPE_STATIC(ISISD, FABRICD_FLOODING_INFO, "ISIS OpenFabric Flooding Log") /* Tracks initial synchronization as per section 2.4 * @@ -509,10 +510,13 @@ int fabricd_write_settings(struct isis_area *area, struct vty *vty) } static void move_to_queue(struct isis_lsp *lsp, struct neighbor_entry *n, - enum isis_tx_type type) + enum isis_tx_type type, struct isis_circuit *circuit) { n->present = false; + if (n->adj && n->adj->circuit == circuit) + return; + if (isis->debugs & DEBUG_FLOODING) { zlog_debug("OpenFabric: Adding %s to %s", print_sys_hostname(n->id), @@ -521,6 +525,11 @@ static void move_to_queue(struct isis_lsp *lsp, struct neighbor_entry *n, if (n->adj) isis_tx_queue_add(n->adj->circuit->tx_queue, lsp, type); + + uint8_t *neighbor_id = XMALLOC(MTYPE_FABRICD_FLOODING_INFO, sizeof(n->id)); + + memcpy(neighbor_id, n->id, sizeof(n->id)); + listnode_add(lsp->flooding_neighbors[type], neighbor_id); } static void mark_neighbor_as_present(struct hash_backet *backet, void *arg) @@ -571,11 +580,39 @@ static struct isis_lsp *lsp_for_neighbor(struct fabricd *f, return lsp_for_vertex(f->spftree, &vertex); } -void fabricd_lsp_flood(struct isis_lsp *lsp) +static void fabricd_free_lsp_flooding_info(void *val) +{ + XFREE(MTYPE_FABRICD_FLOODING_INFO, val); +} + +static void fabricd_lsp_reset_flooding_info(struct isis_lsp *lsp, + struct isis_circuit *circuit) +{ + XFREE(MTYPE_FABRICD_FLOODING_INFO, lsp->flooding_interface); + for (enum isis_tx_type type = TX_LSP_NORMAL; + type <= TX_LSP_CIRCUIT_SCOPED; type++) { + if (lsp->flooding_neighbors[type]) { + list_delete_all_node(lsp->flooding_neighbors[type]); + continue; + } + + lsp->flooding_neighbors[type] = list_new(); + lsp->flooding_neighbors[type]->del = fabricd_free_lsp_flooding_info; + } + + if (circuit) { + lsp->flooding_interface = XSTRDUP(MTYPE_FABRICD_FLOODING_INFO, + circuit->interface->name); + } +} + +void fabricd_lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit) { struct fabricd *f = lsp->area->fabricd; assert(f); + fabricd_lsp_reset_flooding_info(lsp, circuit); + void *cursor = NULL; struct neighbor_entry *n; @@ -597,7 +634,7 @@ void fabricd_lsp_flood(struct isis_lsp *lsp) rawlspid_print(node_lsp->hdr.lsp_id)); } - move_to_queue(lsp, n, TX_LSP_CIRCUIT_SCOPED); + move_to_queue(lsp, n, TX_LSP_CIRCUIT_SCOPED, circuit); } /* Mark all elements in NN as present */ @@ -625,7 +662,7 @@ void fabricd_lsp_flood(struct isis_lsp *lsp) print_sys_hostname(n->id)); } - move_to_queue(lsp, n, TX_LSP_CIRCUIT_SCOPED); + move_to_queue(lsp, n, TX_LSP_CIRCUIT_SCOPED, circuit); continue; } @@ -657,7 +694,8 @@ void fabricd_lsp_flood(struct isis_lsp *lsp) } move_to_queue(lsp, n, need_reflood ? - TX_LSP_NORMAL : TX_LSP_CIRCUIT_SCOPED); + TX_LSP_NORMAL : TX_LSP_CIRCUIT_SCOPED, + circuit); } if (isis->debugs & DEBUG_FLOODING) { @@ -709,3 +747,15 @@ struct list *fabricd_ip_addrs(struct isis_circuit *circuit) return NULL; } + +void fabricd_lsp_free(struct isis_lsp *lsp) +{ + XFREE(MTYPE_FABRICD_FLOODING_INFO, lsp->flooding_interface); + for (enum isis_tx_type type = TX_LSP_NORMAL; + type <= TX_LSP_CIRCUIT_SCOPED; type++) { + if (!lsp->flooding_neighbors[type]) + continue; + + list_delete(&lsp->flooding_neighbors[type]); + } +} diff --git a/isisd/fabricd.h b/isisd/fabricd.h index 76c182f2d..886fd3c62 100644 --- a/isisd/fabricd.h +++ b/isisd/fabricd.h @@ -42,8 +42,9 @@ struct isis_spftree *fabricd_spftree(struct isis_area *area); void fabricd_configure_tier(struct isis_area *area, uint8_t tier); uint8_t fabricd_tier(struct isis_area *area); int fabricd_write_settings(struct isis_area *area, struct vty *vty); -void fabricd_lsp_flood(struct isis_lsp *lsp); +void fabricd_lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit); void fabricd_trigger_csnp(struct isis_area *area); struct list *fabricd_ip_addrs(struct isis_circuit *circuit); +void fabricd_lsp_free(struct isis_lsp *lsp); #endif diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index b8640f34b..86d433cff 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -143,6 +143,8 @@ static void lsp_destroy(struct isis_lsp *lsp) if (lsp->pdu) stream_free(lsp->pdu); + + fabricd_lsp_free(lsp); XFREE(MTYPE_ISIS_LSP, lsp); } @@ -2011,7 +2013,7 @@ void _lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit, if (!fabricd) lsp_set_all_srmflags(lsp, true); else - fabricd_lsp_flood(lsp); + fabricd_lsp_flood(lsp, circuit); if (circuit) isis_tx_queue_del(circuit->tx_queue, lsp); diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h index 3013b8c21..7f088987b 100644 --- a/isisd/isis_lsp.h +++ b/isisd/isis_lsp.h @@ -47,6 +47,9 @@ struct isis_lsp { int age_out; struct isis_area *area; struct isis_tlvs *tlvs; + + struct list *flooding_neighbors[TX_LSP_CIRCUIT_SCOPED + 1]; + char *flooding_interface; }; dict_t *lsp_db_init(void); diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c index 5ef3af0f1..72ee2ac92 100644 --- a/isisd/isis_vty_fabricd.c +++ b/isisd/isis_vty_fabricd.c @@ -23,10 +23,12 @@ #include "command.h" -#include "isisd.h" -#include "isis_vty_common.h" -#include "fabricd.h" -#include "isis_tlvs.h" +#include "isisd/isisd.h" +#include "isisd/isis_vty_common.h" +#include "isisd/fabricd.h" +#include "isisd/isis_tlvs.h" +#include "isisd/isis_misc.h" +#include "isisd/isis_lsp.h" DEFUN (fabric_tier, fabric_tier_cmd, @@ -55,8 +57,83 @@ DEFUN (no_fabric_tier, return CMD_SUCCESS; } +static void lsp_print_flooding(struct vty *vty, struct isis_lsp *lsp) +{ + char lspid[255]; + + lspid_print(lsp->hdr.lsp_id, lspid, true, true); + vty_out(vty, "Flooding information for %s\n", lspid); + + if (!lsp->flooding_neighbors[TX_LSP_NORMAL]) { + vty_out(vty, " Never flooded.\n"); + return; + } + + vty_out(vty, " Last received on: %s\n", + lsp->flooding_interface ? + lsp->flooding_interface : "(null)"); + + for (enum isis_tx_type type = TX_LSP_NORMAL; + type <= TX_LSP_CIRCUIT_SCOPED; type++) { + struct listnode *node; + uint8_t *neighbor_id; + + vty_out(vty, " %s:\n", + (type == TX_LSP_NORMAL) ? "RF" : "DNR"); + for (ALL_LIST_ELEMENTS_RO(lsp->flooding_neighbors[type], + node, neighbor_id)) { + vty_out(vty, " %s\n", + print_sys_hostname(neighbor_id)); + } + } +} + +DEFUN (show_lsp_flooding, + show_lsp_flooding_cmd, + "show openfabric flooding [WORD]", + SHOW_STR + PROTO_HELP + "Flooding information\n" + "LSP ID\n") +{ + const char *lspid = NULL; + + if (argc == 4) { + lspid = argv[3]->arg; + } + + struct listnode *node; + struct isis_area *area; + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + dict_t *lspdb = area->lspdb[ISIS_LEVEL2 - 1]; + + vty_out(vty, "Area %s:\n", area->area_tag ? + area->area_tag : "null"); + + if (lspid) { + struct isis_lsp *lsp = lsp_for_arg(lspid, lspdb); + + if (lsp) + lsp_print_flooding(vty, lsp); + + continue; + } + + for (dnode_t *dnode = dict_first(lspdb); dnode; + dnode = dict_next(lspdb, dnode)) { + lsp_print_flooding(vty, dnode_get(dnode)); + vty_out(vty, "\n"); + } + } + + return CMD_SUCCESS; +} + void isis_vty_daemon_init(void) { install_element(ROUTER_NODE, &fabric_tier_cmd); install_element(ROUTER_NODE, &no_fabric_tier_cmd); + + install_element(ENABLE_NODE, &show_lsp_flooding_cmd); } |