summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2018-11-23 03:13:56 +0100
committerRodny Molina <rmolina@linkedin.com>2018-12-07 20:45:14 +0100
commit1eb7c3a19568c8e460b8147c9dcd91cf0b9feb21 (patch)
treec9215e4fdfeb83ea1e2264245aef29eb466ea088
parentisisd: Make lspid_print non-static (diff)
downloadfrr-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.c60
-rw-r--r--isisd/fabricd.h3
-rw-r--r--isisd/isis_lsp.c4
-rw-r--r--isisd/isis_lsp.h3
-rw-r--r--isisd/isis_vty_fabricd.c85
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);
}