summaryrefslogtreecommitdiff
path: root/isisd/isisd.c
diff options
context:
space:
mode:
Diffstat (limited to 'isisd/isisd.c')
-rw-r--r--isisd/isisd.c913
1 files changed, 668 insertions, 245 deletions
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 53e48bd1cf..0d39aba20b 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -35,6 +35,7 @@
#include "prefix.h"
#include "table.h"
#include "qobj.h"
+#include "vrf.h"
#include "spf_backoff.h"
#include "lib/northbound_cli.h"
@@ -75,44 +76,142 @@ unsigned long debug_bfd;
unsigned long debug_tx_queue;
unsigned long debug_sr;
-struct isis *isis = NULL;
-
-DEFINE_QOBJ_TYPE(isis)
DEFINE_QOBJ_TYPE(isis_area)
+/* ISIS process wide configuration. */
+static struct isis_master isis_master;
+
+/* ISIS process wide configuration pointer to export. */
+struct isis_master *im;
+
/*
* Prototypes.
*/
int isis_area_get(struct vty *, const char *);
int area_net_title(struct vty *, const char *);
int area_clear_net_title(struct vty *, const char *);
-int show_isis_interface_common(struct vty *, const char *ifname, char);
-int show_isis_neighbor_common(struct vty *, const char *id, char);
-int clear_isis_neighbor_common(struct vty *, const char *id);
+int show_isis_interface_common(struct vty *, const char *ifname, char,
+ const char *vrf_name, bool all_vrf);
+int show_isis_neighbor_common(struct vty *, const char *id, char,
+ const char *vrf_name, bool all_vrf);
+int clear_isis_neighbor_common(struct vty *, const char *id, const char *vrf_name,
+ bool all_vrf);
+
+static void isis_add(struct isis *isis)
+{
+ listnode_add(im->isis, isis);
+}
+
+static void isis_delete(struct isis *isis)
+{
+ listnode_delete(im->isis, isis);
+}
+
+/* Link ISIS instance to VRF. */
+void isis_vrf_link(struct isis *isis, struct vrf *vrf)
+{
+ isis->vrf_id = vrf->vrf_id;
+ if (vrf->info != (void *)isis)
+ vrf->info = (void *)isis;
+}
+
+/* Unlink ISIS instance to VRF. */
+void isis_vrf_unlink(struct isis *isis, struct vrf *vrf)
+{
+ if (vrf->info == (void *)isis)
+ vrf->info = NULL;
+ isis->vrf_id = VRF_UNKNOWN;
+}
+
+struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id)
+{
+ struct isis *isis = NULL;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
+ if (isis->vrf_id == vrf_id)
+ return isis;
+ return NULL;
+}
+
+struct isis *isis_lookup_by_vrfname(const char *vrfname)
+{
+ struct isis *isis = NULL;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
+ if (isis->name && vrfname && strcmp(isis->name, vrfname) == 0)
+ return isis;
+ return NULL;
+}
+
+struct isis *isis_lookup_by_sysid(uint8_t *sysid)
+{
+ struct isis *isis = NULL;
+ struct listnode *node, *nnode;
+ for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
+ if (!memcmp(isis->sysid, sysid, ISIS_SYS_ID_LEN))
+ return isis;
+ return NULL;
+}
+
+void isis_master_init(struct thread_master *master)
+{
+ memset(&isis_master, 0, sizeof(struct isis_master));
+ im = &isis_master;
+ im->isis = list_new();
+ im->master = master;
+}
+
+void isis_global_instance_create()
+{
+ struct isis *isis = NULL;
+ isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+ if (isis == NULL) {
+ isis = isis_new(VRF_DEFAULT);
+ isis_add(isis);
+ }
+}
-void isis_new(unsigned long process_id, vrf_id_t vrf_id)
+struct isis *isis_new(vrf_id_t vrf_id)
{
+ struct vrf *vrf = NULL;
+ struct isis *isis = NULL;
+
isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
+ isis->vrf_id = vrf_id;
+ vrf = vrf_lookup_by_id(vrf_id);
+
+ if (vrf) {
+ isis_vrf_link(isis, vrf);
+ isis->name = XSTRDUP(MTYPE_ISIS, vrf->name);
+ }
+
+ if (IS_DEBUG_EVENTS)
+ zlog_debug(
+ "%s: Create new isis instance with vrf_name %s vrf_id %u",
+ __func__, isis->name, isis->vrf_id);
+
/*
* Default values
*/
- isis->vrf_id = vrf_id;
isis->max_area_addrs = 3;
- isis->process_id = process_id;
+ isis->process_id = getpid();
isis->router_id = 0;
isis->area_list = list_new();
isis->init_circ_list = list_new();
isis->uptime = time(NULL);
- dyn_cache_init();
+ dyn_cache_init(isis);
- QOBJ_REG(isis, isis);
+ return isis;
}
-struct isis_area *isis_area_create(const char *area_tag)
+struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
{
struct isis_area *area;
-
+ struct isis *isis = NULL;
+ struct vrf *vrf = NULL;
area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
/*
@@ -136,6 +235,7 @@ struct isis_area *isis_area_create(const char *area_tag)
spftree_area_init(area);
area->circuit_list = list_new();
+ area->adjacency_list = list_new();
area->area_addrs = list_new();
thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
flags_initialize(&area->flags);
@@ -192,6 +292,25 @@ struct isis_area *isis_area_create(const char *area_tag)
area_mt_init(area);
area->area_tag = strdup(area_tag);
+
+ if (vrf_name) {
+ vrf = vrf_lookup_by_name(vrf_name);
+ if (vrf) {
+ isis = isis_lookup_by_vrfid(vrf->vrf_id);
+ if (isis == NULL) {
+ isis = isis_new(vrf->vrf_id);
+ isis_add(isis);
+ }
+ } else
+ return NULL;
+ } else {
+ isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+ if (isis == NULL) {
+ isis = isis_new(VRF_DEFAULT);
+ isis_add(isis);
+ }
+ }
+
listnode_add(isis->area_list, area);
area->isis = isis;
@@ -212,10 +331,15 @@ struct isis_area *isis_area_create(const char *area_tag)
return area;
}
-struct isis_area *isis_area_lookup(const char *area_tag)
+struct isis_area *isis_area_lookup(const char *area_tag, vrf_id_t vrf_id)
{
struct isis_area *area;
struct listnode *node;
+ struct isis *isis = NULL;
+
+ isis = isis_lookup_by_vrfid(vrf_id);
+ if (isis == NULL)
+ return NULL;
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
if ((area->area_tag == NULL && area_tag == NULL)
@@ -230,14 +354,14 @@ int isis_area_get(struct vty *vty, const char *area_tag)
{
struct isis_area *area;
- area = isis_area_lookup(area_tag);
+ area = isis_area_lookup(area_tag, VRF_DEFAULT);
if (area) {
VTY_PUSH_CONTEXT(ROUTER_NODE, area);
return CMD_SUCCESS;
}
- area = isis_area_create(area_tag);
+ area = isis_area_create(area_tag, VRF_DEFAULT_NAME);
if (IS_DEBUG_EVENTS)
zlog_debug("New IS-IS area instance %s", area->area_tag);
@@ -247,21 +371,12 @@ int isis_area_get(struct vty *vty, const char *area_tag)
return CMD_SUCCESS;
}
-int isis_area_destroy(const char *area_tag)
+void isis_area_destroy(struct isis_area *area)
{
- struct isis_area *area;
struct listnode *node, *nnode;
struct isis_circuit *circuit;
struct area_addr *addr;
- area = isis_area_lookup(area_tag);
-
- if (area == NULL) {
- zlog_warn("%s: could not find area with area-tag %s",
- __func__, area_tag);
- return CMD_ERR_NO_MATCH;
- }
-
QOBJ_UNREG(area);
if (fabricd)
@@ -280,6 +395,7 @@ int isis_area_destroy(const char *area_tag)
}
list_delete(&area->circuit_list);
}
+ list_delete(&area->adjacency_list);
lsp_db_fini(&area->lspdb[0]);
lsp_db_fini(&area->lspdb[1]);
@@ -312,20 +428,50 @@ int isis_area_destroy(const char *area_tag)
thread_cancel_event(master, area);
- listnode_delete(isis->area_list, area);
+ listnode_delete(area->isis->area_list, area);
free(area->area_tag);
area_mt_finish(area);
+ if (listcount(area->isis->area_list) == 0) {
+ memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN);
+ area->isis->sysid_set = 0;
+ }
+
XFREE(MTYPE_ISIS_AREA, area);
- if (listcount(isis->area_list) == 0) {
- memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
- isis->sysid_set = 0;
+}
+
+void isis_finish(struct isis *isis)
+{
+ struct vrf *vrf = NULL;
+
+ isis_delete(isis);
+ if (isis->name) {
+ vrf = vrf_lookup_by_name(isis->name);
+ if (vrf)
+ isis_vrf_unlink(isis, vrf);
+ XFREE(MTYPE_ISIS, isis->name);
+ } else {
+ vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ if (vrf)
+ isis_vrf_unlink(isis, vrf);
}
- return CMD_SUCCESS;
+ XFREE(MTYPE_ISIS, isis);
+}
+
+void isis_terminate()
+{
+ struct isis *isis = NULL;
+ struct listnode *node, *nnode;
+
+ if (listcount(im->isis) == 0)
+ return;
+
+ for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
+ isis_finish(isis);
}
#ifdef FABRICD
@@ -366,10 +512,10 @@ int area_net_title(struct vty *vty, const char *net_title)
uint8_t buff[255];
/* We check that we are not over the maximal number of addresses */
- if (listcount(area->area_addrs) >= isis->max_area_addrs) {
+ if (listcount(area->area_addrs) >= area->isis->max_area_addrs) {
vty_out(vty,
"Maximum of area addresses (%d) already reached \n",
- isis->max_area_addrs);
+ area->isis->max_area_addrs);
return CMD_ERR_NOTHING_TODO;
}
@@ -395,20 +541,21 @@ int area_net_title(struct vty *vty, const char *net_title)
return CMD_WARNING_CONFIG_FAILED;
}
- if (isis->sysid_set == 0) {
+ if (area->isis->sysid_set == 0) {
/*
* First area address - get the SystemID for this router
*/
- memcpy(isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN);
- isis->sysid_set = 1;
+ memcpy(area->isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN);
+ area->isis->sysid_set = 1;
if (IS_DEBUG_EVENTS)
zlog_debug("Router has SystemID %s",
- sysid_print(isis->sysid));
+ sysid_print(area->isis->sysid));
} else {
/*
* Check that the SystemID portions match
*/
- if (memcmp(isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN)) {
+ if (memcmp(area->isis->sysid, GETSYSID(addr),
+ ISIS_SYS_ID_LEN)) {
vty_out(vty,
"System ID must not change when defining additional area addresses\n");
XFREE(MTYPE_ISIS_AREA_ADDR, addr);
@@ -480,8 +627,8 @@ int area_clear_net_title(struct vty *vty, const char *net_title)
* Last area address - reset the SystemID for this router
*/
if (listcount(area->area_addrs) == 0) {
- memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
- isis->sysid_set = 0;
+ memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN);
+ area->isis->sysid_set = 0;
if (IS_DEBUG_EVENTS)
zlog_debug("Router has no SystemID");
}
@@ -493,100 +640,144 @@ int area_clear_net_title(struct vty *vty, const char *net_title)
* 'show isis interface' command
*/
-int show_isis_interface_common(struct vty *vty, const char *ifname, char detail)
+int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
+ const char *vrf_name, bool all_vrf)
{
- struct listnode *anode, *cnode;
+ struct listnode *anode, *cnode, *mnode, *inode;
struct isis_area *area;
struct isis_circuit *circuit;
+ struct isis *isis = NULL;
- if (!isis) {
+ if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
return CMD_SUCCESS;
}
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, mnode, inode, isis)) {
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list,
+ anode, area)) {
+ vty_out(vty, "Area %s:\n",
+ area->area_tag);
+
+ if (detail == ISIS_UI_LEVEL_BRIEF)
+ vty_out(vty,
+ " Interface CircId State Type Level\n");
+
+ for (ALL_LIST_ELEMENTS_RO(
+ area->circuit_list, cnode,
+ circuit))
+ if (!ifname)
+ isis_circuit_print_vty(
+ circuit, vty,
+ detail);
+ else if (strcmp(circuit->interface->name, ifname) == 0)
+ isis_circuit_print_vty(
+ circuit, vty,
+ detail);
+ }
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL) {
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
+ area)) {
+ vty_out(vty, "Area %s:\n", area->area_tag);
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
- vty_out(vty, "Area %s:\n", area->area_tag);
-
- if (detail == ISIS_UI_LEVEL_BRIEF)
- vty_out(vty,
- " Interface CircId State Type Level\n");
-
- for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit))
- if (!ifname)
- isis_circuit_print_vty(circuit, vty, detail);
- else if (strcmp(circuit->interface->name, ifname) == 0)
- isis_circuit_print_vty(circuit, vty, detail);
+ if (detail == ISIS_UI_LEVEL_BRIEF)
+ vty_out(vty,
+ " Interface CircId State Type Level\n");
+
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
+ cnode, circuit))
+ if (!ifname)
+ isis_circuit_print_vty(
+ circuit, vty, detail);
+ else if (
+ strcmp(circuit->interface->name,
+ ifname)
+ == 0)
+ isis_circuit_print_vty(
+ circuit, vty, detail);
+ }
+ }
}
return CMD_SUCCESS;
}
-DEFUN (show_isis_interface,
- show_isis_interface_cmd,
- "show " PROTO_NAME " interface",
- SHOW_STR
- PROTO_HELP
- "ISIS interface\n")
+DEFUN(show_isis_interface,
+ show_isis_interface_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] interface",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "IS-IS interface\n")
{
- return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF);
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF,
+ vrf_name, all_vrf);
}
-DEFUN (show_isis_interface_detail,
- show_isis_interface_detail_cmd,
- "show " PROTO_NAME " interface detail",
- SHOW_STR
- PROTO_HELP
- "ISIS interface\n"
- "show detailed information\n")
+DEFUN(show_isis_interface_detail,
+ show_isis_interface_detail_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] interface detail",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "IS-IS interface\n"
+ "show detailed information\n")
{
- return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_DETAIL);
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_DETAIL,
+ vrf_name, all_vrf);
}
-DEFUN (show_isis_interface_arg,
- show_isis_interface_arg_cmd,
- "show " PROTO_NAME " interface WORD",
- SHOW_STR
- PROTO_HELP
- "ISIS interface\n"
- "ISIS interface name\n")
+DEFUN(show_isis_interface_arg,
+ show_isis_interface_arg_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] interface WORD",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "IS-IS interface\n"
+ "IS-IS interface name\n")
{
- int idx_word = 3;
- return show_isis_interface_common(vty, argv[idx_word]->arg,
- ISIS_UI_LEVEL_DETAIL);
-}
+ int idx_word = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
-/*
- * 'show isis neighbor' command
- */
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
-int show_isis_neighbor_common(struct vty *vty, const char *id, char detail)
+ char *ifname = argv_find(argv, argc, "WORD", &idx_word)
+ ? argv[idx_word]->arg
+ : NULL;
+ return show_isis_interface_common(vty, ifname, ISIS_UI_LEVEL_DETAIL,
+ vrf_name, all_vrf);
+}
+
+static void isis_neighbor_common(struct vty *vty, const char *id, char detail,
+ struct isis *isis, uint8_t *sysid)
{
struct listnode *anode, *cnode, *node;
struct isis_area *area;
struct isis_circuit *circuit;
struct list *adjdb;
struct isis_adjacency *adj;
- struct isis_dynhn *dynhn;
- uint8_t sysid[ISIS_SYS_ID_LEN];
int i;
- if (!isis) {
- vty_out(vty, "IS-IS Routing Process not enabled\n");
- return CMD_SUCCESS;
- }
-
- memset(sysid, 0, ISIS_SYS_ID_LEN);
- if (id) {
- if (sysid2buff(sysid, id) == 0) {
- dynhn = dynhn_find_by_name(id);
- if (dynhn == NULL) {
- vty_out(vty, "Invalid system id %s\n", id);
- return CMD_SUCCESS;
- }
- memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN);
- }
- }
-
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
vty_out(vty, "Area %s:\n", area->area_tag);
@@ -602,9 +793,10 @@ int show_isis_neighbor_common(struct vty *vty, const char *id, char detail)
for (ALL_LIST_ELEMENTS_RO(
adjdb, node, adj))
if (!id
- || !memcmp(adj->sysid,
- sysid,
- ISIS_SYS_ID_LEN))
+ || !memcmp(
+ adj->sysid,
+ sysid,
+ ISIS_SYS_ID_LEN))
isis_adj_print_vty(
adj,
vty,
@@ -622,24 +814,20 @@ int show_isis_neighbor_common(struct vty *vty, const char *id, char detail)
}
}
- return CMD_SUCCESS;
}
-
/*
- * 'clear isis neighbor' command
+ * 'show isis neighbor' command
*/
-int clear_isis_neighbor_common(struct vty *vty, const char *id)
+
+int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
+ const char *vrf_name, bool all_vrf)
{
- struct listnode *anode, *cnode, *cnextnode, *node, *nnode;
- struct isis_area *area;
- struct isis_circuit *circuit;
- struct list *adjdb;
- struct isis_adjacency *adj;
+ struct listnode *nnode, *inode;
struct isis_dynhn *dynhn;
uint8_t sysid[ISIS_SYS_ID_LEN];
- int i;
+ struct isis *isis = NULL;
- if (!isis) {
+ if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
return CMD_SUCCESS;
}
@@ -656,6 +844,32 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id)
}
}
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ isis_neighbor_common(vty, id, detail, isis,
+ sysid);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ isis_neighbor_common(vty, id, detail, isis, sysid);
+ }
+
+ return CMD_SUCCESS;
+}
+
+static void isis_neighbor_common_clear(struct vty *vty, const char *id,
+ uint8_t *sysid, struct isis *isis)
+{
+ struct listnode *anode, *cnode, *cnextnode, *node, *nnode;
+ struct isis_area *area;
+ struct isis_circuit *circuit;
+ struct list *adjdb;
+ struct isis_adjacency *adj;
+ int i;
+
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
for (ALL_LIST_ELEMENTS(area->circuit_list, cnode, cnextnode,
circuit)) {
@@ -667,9 +881,10 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id)
adjdb, node, nnode,
adj))
if (!id
- || !memcmp(adj->sysid,
- sysid,
- ISIS_SYS_ID_LEN))
+ || !memcmp(
+ adj->sysid,
+ sysid,
+ ISIS_SYS_ID_LEN))
isis_adj_state_change(
&adj,
ISIS_ADJ_DOWN,
@@ -688,64 +903,149 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id)
}
}
}
-
- return CMD_SUCCESS;
}
-
-DEFUN (show_isis_neighbor,
- show_isis_neighbor_cmd,
- "show " PROTO_NAME " neighbor",
- SHOW_STR
- PROTO_HELP
- "ISIS neighbor adjacencies\n")
+/*
+ * 'clear isis neighbor' command
+ */
+int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_name,
+ bool all_vrf)
{
- return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF);
-}
+ struct listnode *nnode, *inode;
+ struct isis_dynhn *dynhn;
+ uint8_t sysid[ISIS_SYS_ID_LEN];
+ struct isis *isis = NULL;
-DEFUN (show_isis_neighbor_detail,
- show_isis_neighbor_detail_cmd,
- "show " PROTO_NAME " neighbor detail",
- SHOW_STR
- PROTO_HELP
- "ISIS neighbor adjacencies\n"
- "show detailed information\n")
-{
- return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_DETAIL);
-}
+ if (!im) {
+ vty_out(vty, "IS-IS Routing Process not enabled\n");
+ return CMD_SUCCESS;
+ }
-DEFUN (show_isis_neighbor_arg,
- show_isis_neighbor_arg_cmd,
- "show " PROTO_NAME " neighbor WORD",
- SHOW_STR
- PROTO_HELP
- "ISIS neighbor adjacencies\n"
- "System id\n")
-{
- int idx_word = 3;
- return show_isis_neighbor_common(vty, argv[idx_word]->arg,
- ISIS_UI_LEVEL_DETAIL);
-}
+ memset(sysid, 0, ISIS_SYS_ID_LEN);
+ if (id) {
+ if (sysid2buff(sysid, id) == 0) {
+ dynhn = dynhn_find_by_name(id);
+ if (dynhn == NULL) {
+ vty_out(vty, "Invalid system id %s\n", id);
+ return CMD_SUCCESS;
+ }
+ memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN);
+ }
+ }
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ isis_neighbor_common_clear(vty, id, sysid,
+ isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ isis_neighbor_common_clear(vty, id, sysid, isis);
+ }
-DEFUN (clear_isis_neighbor,
- clear_isis_neighbor_cmd,
- "clear " PROTO_NAME " neighbor",
- CLEAR_STR
- PROTO_HELP
- "ISIS neighbor adjacencies\n")
-{
- return clear_isis_neighbor_common(vty, NULL);
+ return CMD_SUCCESS;
}
-DEFUN (clear_isis_neighbor_arg,
- clear_isis_neighbor_arg_cmd,
- "clear " PROTO_NAME " neighbor WORD",
- CLEAR_STR
- PROTO_HELP
- "ISIS neighbor adjacencies\n"
- "System id\n")
-{
- int idx_word = 3;
- return clear_isis_neighbor_common(vty, argv[idx_word]->arg);
+DEFUN(show_isis_neighbor,
+ show_isis_neighbor_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] neighbor",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All vrfs\n"
+ "IS-IS neighbor adjacencies\n")
+{
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF,
+ vrf_name, all_vrf);
+}
+
+DEFUN(show_isis_neighbor_detail,
+ show_isis_neighbor_detail_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] neighbor detail",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "all vrfs\n"
+ "IS-IS neighbor adjacencies\n"
+ "show detailed information\n")
+{
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+
+ return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_DETAIL,
+ vrf_name, all_vrf);
+}
+
+DEFUN(show_isis_neighbor_arg,
+ show_isis_neighbor_arg_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] neighbor WORD",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All vrfs\n"
+ "IS-IS neighbor adjacencies\n"
+ "System id\n")
+{
+ int idx_word = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ char *id = argv_find(argv, argc, "WORD", &idx_word)
+ ? argv[idx_word]->arg
+ : NULL;
+
+ return show_isis_neighbor_common(vty, id, ISIS_UI_LEVEL_DETAIL,
+ vrf_name, all_vrf);
+}
+
+DEFUN(clear_isis_neighbor,
+ clear_isis_neighbor_cmd,
+ "clear " PROTO_NAME " [vrf <NAME|all>] neighbor",
+ CLEAR_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All vrfs\n"
+ "IS-IS neighbor adjacencies\n")
+{
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return clear_isis_neighbor_common(vty, NULL, vrf_name, all_vrf);
+}
+
+DEFUN(clear_isis_neighbor_arg,
+ clear_isis_neighbor_arg_cmd,
+ "clear " PROTO_NAME " [vrf <NAME|all>] neighbor WORD",
+ CLEAR_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All vrfs\n"
+ "IS-IS neighbor adjacencies\n"
+ "System id\n")
+{
+ int idx_word = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ char *id = argv_find(argv, argc, "WORD", &idx_word)
+ ? argv[idx_word]->arg
+ : NULL;
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return clear_isis_neighbor_common(vty, id, vrf_name, all_vrf);
}
/*
@@ -1248,34 +1548,41 @@ DEFUN (no_debug_isis_bfd,
return CMD_SUCCESS;
}
-DEFUN (show_hostname,
- show_hostname_cmd,
- "show " PROTO_NAME " hostname",
- SHOW_STR
- PROTO_HELP
- "IS-IS Dynamic hostname mapping\n")
+DEFUN(show_hostname, show_hostname_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] hostname",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "IS-IS Dynamic hostname mapping\n")
{
- dynhn_print_all(vty);
+ struct listnode *nnode, *inode;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+ struct isis *isis = NULL;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ dynhn_print_all(vty, isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ dynhn_print_all(vty, isis);
+ }
return CMD_SUCCESS;
}
-DEFUN (show_isis_spf_ietf,
- show_isis_spf_ietf_cmd,
- "show " PROTO_NAME " spf-delay-ietf",
- SHOW_STR
- PROTO_HELP
- "SPF delay IETF information\n")
+static void isis_spf_ietf_common(struct vty *vty, struct isis *isis)
{
- if (!isis) {
- vty_out(vty, "ISIS is not running\n");
- return CMD_SUCCESS;
- }
-
struct listnode *node;
struct isis_area *area;
-
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
+
+ vty_out(vty, "vrf : %s\n", isis->name);
vty_out(vty, "Area %s:\n",
area->area_tag ? area->area_tag : "null");
@@ -1306,23 +1613,49 @@ DEFUN (show_isis_spf_ietf,
}
}
}
+}
+
+DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] spf-delay-ietf",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "SPF delay IETF information\n")
+{
+ struct listnode *nnode, *inode;
+ struct isis *isis = NULL;
+ int idx_vrf = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)
+
+ if (!im) {
+ vty_out(vty, "ISIS is not running\n");
+ return CMD_SUCCESS;
+ }
+
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ isis_spf_ietf_common(vty, isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ isis_spf_ietf_common(vty, isis);
+ }
+
return CMD_SUCCESS;
}
-DEFUN (show_isis_summary,
- show_isis_summary_cmd,
- "show " PROTO_NAME " summary",
- SHOW_STR PROTO_HELP "summary\n")
+static void common_isis_summary(struct vty *vty, struct isis *isis)
{
struct listnode *node, *node2;
struct isis_area *area;
int level;
- if (isis == NULL) {
- vty_out(vty, PROTO_NAME " is not running\n");
- return CMD_SUCCESS;
- }
-
+ vty_out(vty, "vrf : %s\n", isis->name);
vty_out(vty, "Process Id : %ld\n", isis->process_id);
if (isis->sysid_set)
vty_out(vty, "System Id : %s\n",
@@ -1344,7 +1677,7 @@ DEFUN (show_isis_summary,
if (tier == ISIS_TIER_UNDEFINED)
vty_out(vty, " Tier: undefined\n");
else
- vty_out(vty, " Tier: %" PRIu8 "\n", tier);
+ vty_out(vty, " Tier: %hhu\n", tier);
}
if (listcount(area->area_addrs) > 0) {
@@ -1390,25 +1723,68 @@ DEFUN (show_isis_summary,
" (not used, IETF SPF delay activated)");
vty_out(vty, "\n");
- vty_out(vty, " IPv4 route computation:\n");
- isis_spf_print(area->spftree[SPFTREE_IPV4][level - 1],
- vty);
+ if (area->ip_circuits) {
+ vty_out(vty, " IPv4 route computation:\n");
+ isis_spf_print(
+ area->spftree[SPFTREE_IPV4][level - 1],
+ vty);
+ }
+
+ if (area->ipv6_circuits) {
+ vty_out(vty, " IPv6 route computation:\n");
+ isis_spf_print(
+ area->spftree[SPFTREE_IPV6][level - 1],
+ vty);
+ }
+
+ if (area->ipv6_circuits
+ && isis_area_ipv6_dstsrc_enabled(area)) {
+ vty_out(vty,
+ " IPv6 dst-src route computation:\n");
+ isis_spf_print(area->spftree[SPFTREE_DSTSRC]
+ [level - 1],
+ vty);
+ }
+ }
+ }
+}
- vty_out(vty, " IPv6 route computation:\n");
- isis_spf_print(area->spftree[SPFTREE_IPV6][level - 1],
- vty);
+DEFUN(show_isis_summary, show_isis_summary_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] summary",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "summary\n")
+{
+ struct listnode *inode, *nnode;
+ int idx_vrf = 0;
+ struct isis *isis = NULL;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
- vty_out(vty, " IPv6 dst-src route computation:\n");
- isis_spf_print(area->spftree[SPFTREE_DSTSRC][level-1],
- vty);
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)
+ if (!im) {
+ vty_out(vty, PROTO_NAME " is not running\n");
+ return CMD_SUCCESS;
+ }
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ common_isis_summary(vty, isis);
+ }
+ return 0;
}
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ common_isis_summary(vty, isis);
}
+
vty_out(vty, "\n");
return CMD_SUCCESS;
}
-struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv)
+struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv,
+ struct isis *isis)
{
char sysid[255] = {0};
uint8_t number[3];
@@ -1468,23 +1844,8 @@ struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv)
return lsp;
}
-/*
- * This function supports following display options:
- * [ show isis database [detail] ]
- * [ show isis database <sysid> [detail] ]
- * [ show isis database <hostname> [detail] ]
- * [ show isis database <sysid>.<pseudo-id> [detail] ]
- * [ show isis database <hostname>.<pseudo-id> [detail] ]
- * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
- * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
- * [ show isis database detail <sysid> ]
- * [ show isis database detail <hostname> ]
- * [ show isis database detail <sysid>.<pseudo-id> ]
- * [ show isis database detail <hostname>.<pseudo-id> ]
- * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
- * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
- */
-static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
+static int show_isis_database_common(struct vty *vty, const char *argv,
+ int ui_level, struct isis *isis)
{
struct listnode *node;
struct isis_area *area;
@@ -1500,7 +1861,9 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
for (level = 0; level < ISIS_LEVELS; level++) {
if (lspdb_count(&area->lspdb[level]) > 0) {
- lsp = lsp_for_arg(&area->lspdb[level], argv);
+ lsp = NULL;
+ lsp = lsp_for_arg(&area->lspdb[level], argv,
+ isis);
if (lsp != NULL || argv == NULL) {
vty_out(vty,
@@ -1516,14 +1879,17 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
if (ui_level == ISIS_UI_LEVEL_DETAIL)
lsp_print_detail(
lsp, vty,
- area->dynhostname);
+ area->dynhostname,
+ isis);
else
lsp_print(lsp, vty,
- area->dynhostname);
+ area->dynhostname,
+ isis);
} else if (argv == NULL) {
lsp_count = lsp_print_all(
vty, &area->lspdb[level],
- ui_level, area->dynhostname);
+ ui_level, area->dynhostname,
+ isis);
vty_out(vty, " %u LSPs\n\n",
lsp_count);
@@ -1531,25 +1897,64 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
}
}
}
+ return CMD_SUCCESS;
+}
+/*
+ * This function supports following display options:
+ * [ show isis database [detail] ]
+ * [ show isis database <sysid> [detail] ]
+ * [ show isis database <hostname> [detail] ]
+ * [ show isis database <sysid>.<pseudo-id> [detail] ]
+ * [ show isis database <hostname>.<pseudo-id> [detail] ]
+ * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
+ * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
+ * [ show isis database detail <sysid> ]
+ * [ show isis database detail <hostname> ]
+ * [ show isis database detail <sysid>.<pseudo-id> ]
+ * [ show isis database detail <hostname>.<pseudo-id> ]
+ * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
+ * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
+ */
+static int show_isis_database(struct vty *vty, const char *argv, int ui_level,
+ const char *vrf_name, bool all_vrf)
+{
+ struct listnode *inode, *nnode;
+ struct isis *isis = NULL;
+
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ show_isis_database_common(vty, argv, ui_level,
+ isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ show_isis_database_common(vty, argv, ui_level, isis);
+ }
return CMD_SUCCESS;
}
-DEFUN (show_database,
- show_database_cmd,
- "show " PROTO_NAME " database [detail] [WORD]",
- SHOW_STR
- PROTO_HELP
- "Link state database\n"
- "Detailed information\n"
- "LSP ID\n")
+DEFUN(show_database, show_database_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] database [detail] [WORD]",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "Link state database\n"
+ "Detailed information\n"
+ "LSP ID\n")
{
int idx = 0;
+ int idx_vrf = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
int uilevel = argv_find(argv, argc, "detail", &idx)
? ISIS_UI_LEVEL_DETAIL
: ISIS_UI_LEVEL_BRIEF;
char *id = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
- return show_isis_database(vty, id, uilevel);
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return show_isis_database(vty, id, uilevel, vrf_name, all_vrf);
}
#ifdef FABRICD
@@ -1578,8 +1983,20 @@ DEFUN (no_router_openfabric,
PROTO_HELP
"ISO Routing area tag\n")
{
+ struct isis_area *area;
+ const char *area_tag;
int idx_word = 3;
- return isis_area_destroy(argv[idx_word]->arg);
+
+ area_tag = argv[idx_word]->arg;
+ area = isis_area_lookup(area_tag, VRF_DEFAULT);
+ if (area == NULL) {
+ zlog_warn("%s: could not find area with area-tag %s",
+ __func__, area_tag);
+ return CMD_ERR_NO_MATCH;
+ }
+
+ isis_area_destroy(area);
+ return CMD_SUCCESS;
}
#endif /* ifdef FABRICD */
#ifdef FABRICD
@@ -1934,10 +2351,16 @@ DEFUN (no_log_adj_changes,
static int isis_config_write(struct vty *vty)
{
int write = 0;
+ struct isis_area *area;
+ struct listnode *node, *node2, *inode, *nnode;
+ struct isis *isis = NULL;
+
+ if (!im) {
+ vty_out(vty, "IS-IS Routing Process not enabled\n");
+ return CMD_SUCCESS;
+ }
- if (isis != NULL) {
- struct isis_area *area;
- struct listnode *node, *node2;
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
/* ISIS - Area name */