diff options
Diffstat (limited to 'isisd/isisd.c')
| -rw-r--r-- | isisd/isisd.c | 913 |
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 */ |
