From 3f045a08812525505e165deea99a79447b44506b Mon Sep 17 00:00:00 2001 From: Josh Bailey Date: Sat, 24 Mar 2012 08:35:20 -0700 Subject: isisd: add Google's changes to IS-IS --- isisd/isisd.c | 1991 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 1497 insertions(+), 494 deletions(-) (limited to 'isisd/isisd.c') diff --git a/isisd/isisd.c b/isisd/isisd.c index 1e84a1ce..6cbb85b1 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -27,6 +27,7 @@ #include "command.h" #include "log.h" #include "memory.h" +#include "time.h" #include "linklist.h" #include "if.h" #include "hash.h" @@ -38,8 +39,9 @@ #include "isisd/include-netbsd/iso.h" #include "isisd/isis_constants.h" #include "isisd/isis_common.h" -#include "isisd/isis_circuit.h" #include "isisd/isis_flags.h" +#include "isisd/isis_circuit.h" +#include "isisd/isis_csm.h" #include "isisd/isisd.h" #include "isisd/isis_dynhn.h" #include "isisd/isis_adjacency.h" @@ -59,19 +61,17 @@ u_char DEFAULT_TOPOLOGY_BASEIS[6] = { 0xFE, 0xED, 0xFE, 0xED, 0x00, 0x00 }; #endif /* TOPOLOGY_GENERATE */ struct isis *isis = NULL; -extern struct thread_master *master; /* * Prototypes. */ -void isis_new(unsigned long); -struct isis_area *isis_area_create(void); int isis_area_get(struct vty *, const char *); int isis_area_destroy(struct vty *, const char *); -int area_net_title(struct vty *, const u_char *); -int area_clear_net_title(struct vty *, const u_char *); -int show_clns_neigh(struct vty *, char); -void print_debug(struct vty *, int, int); +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 isis_config_write(struct vty *); @@ -84,8 +84,8 @@ isis_new (unsigned long process_id) * Default values */ isis->max_area_addrs = 3; - isis->process_id = process_id; + isis->router_id = 0; isis->area_list = list_new (); isis->init_circ_list = list_new (); isis->uptime = time (NULL); @@ -93,6 +93,7 @@ isis_new (unsigned long process_id) #ifdef HAVE_IPV6 isis->nexthops6 = list_new (); #endif /* HAVE_IPV6 */ + dyn_cache_init (); /* * uncomment the next line for full debugs */ @@ -100,7 +101,7 @@ isis_new (unsigned long process_id) } struct isis_area * -isis_area_create () +isis_area_create (const char *area_tag) { struct isis_area *area; @@ -114,36 +115,48 @@ isis_area_create () area->is_type = IS_LEVEL_1; else area->is_type = IS_LEVEL_1_AND_2; + /* * intialize the databases */ - area->lspdb[0] = lsp_db_init (); - area->lspdb[1] = lsp_db_init (); - - spftree_area_init (area); - area->route_table[0] = route_table_init (); - area->route_table[1] = route_table_init (); + if (area->is_type & IS_LEVEL_1) + { + area->lspdb[0] = lsp_db_init (); + area->route_table[0] = route_table_init (); +#ifdef HAVE_IPV6 + area->route_table6[0] = route_table_init (); +#endif /* HAVE_IPV6 */ + } + if (area->is_type & IS_LEVEL_2) + { + area->lspdb[1] = lsp_db_init (); + area->route_table[1] = route_table_init (); #ifdef HAVE_IPV6 - area->route_table6[0] = route_table_init (); - area->route_table6[1] = route_table_init (); + area->route_table6[1] = route_table_init (); #endif /* HAVE_IPV6 */ + } + + spftree_area_init (area); + area->circuit_list = list_new (); area->area_addrs = list_new (); THREAD_TIMER_ON (master, area->t_tick, lsp_tick, area, 1); flags_initialize (&area->flags); + /* * Default values */ - area->max_lsp_lifetime[0] = MAX_AGE; /* 1200 */ - area->max_lsp_lifetime[1] = MAX_AGE; /* 1200 */ - area->lsp_gen_interval[0] = LSP_GEN_INTERVAL_DEFAULT; - area->lsp_gen_interval[1] = LSP_GEN_INTERVAL_DEFAULT; - area->lsp_refresh[0] = MAX_LSP_GEN_INTERVAL; /* 900 */ - area->lsp_refresh[1] = MAX_LSP_GEN_INTERVAL; /* 900 */ + area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME; /* 1200 */ + area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME; /* 1200 */ + area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */ + area->lsp_refresh[1] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */ + area->lsp_gen_interval[0] = DEFAULT_MIN_LSP_GEN_INTERVAL; + area->lsp_gen_interval[1] = DEFAULT_MIN_LSP_GEN_INTERVAL; area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; area->dynhostname = 1; - area->oldmetric = 1; + area->oldmetric = 0; + area->newmetric = 1; area->lsp_frag_threshold = 90; #ifdef TOPOLOGY_GENERATE memcpy (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS, ISIS_SYS_ID_LEN); @@ -152,6 +165,10 @@ isis_area_create () /* FIXME: Think of a better way... */ area->min_bcast_mtu = 1497; + area->area_tag = strdup (area_tag); + listnode_add (isis->area_list, area); + area->isis = isis; + return area; } @@ -184,9 +201,7 @@ isis_area_get (struct vty *vty, const char *area_tag) return CMD_SUCCESS; } - area = isis_area_create (); - area->area_tag = strdup (area_tag); - listnode_add (isis->area_list, area); + area = isis_area_create (area_tag); if (isis->debugs & DEBUG_EVENTS) zlog_debug ("New IS-IS area instance %s", area->area_tag); @@ -203,40 +218,100 @@ isis_area_destroy (struct vty *vty, const char *area_tag) 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) { vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE); - return CMD_WARNING; + return CMD_ERR_NO_MATCH; } if (area->circuit_list) { for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit)) - { - /* The fact that it's in circuit_list means that it was configured */ - isis_circuit_deconfigure (circuit, area); - isis_circuit_del (circuit); - } - + { + circuit->ip_router = 0; +#ifdef HAVE_IPV6 + circuit->ipv6_router = 0; +#endif + isis_csm_state_change (ISIS_DISABLE, circuit, area); + } list_delete (area->circuit_list); + area->circuit_list = NULL; } - listnode_delete (isis->area_list, area); + + if (area->lspdb[0] != NULL) + { + lsp_db_destroy (area->lspdb[0]); + area->lspdb[0] = NULL; + } + if (area->lspdb[1] != NULL) + { + lsp_db_destroy (area->lspdb[1]); + area->lspdb[1] = NULL; + } + + spftree_area_del (area); + + /* invalidate and validate would delete all routes from zebra */ + isis_route_invalidate (area); + isis_route_validate (area); + + if (area->route_table[0]) + { + route_table_finish (area->route_table[0]); + area->route_table[0] = NULL; + } + if (area->route_table[1]) + { + route_table_finish (area->route_table[1]); + area->route_table[1] = NULL; + } +#ifdef HAVE_IPV6 + if (area->route_table6[0]) + { + route_table_finish (area->route_table6[0]); + area->route_table6[0] = NULL; + } + if (area->route_table6[1]) + { + route_table_finish (area->route_table6[1]); + area->route_table6[1] = NULL; + } +#endif /* HAVE_IPV6 */ + + for (ALL_LIST_ELEMENTS (area->area_addrs, node, nnode, addr)) + { + list_delete_node (area->area_addrs, node); + XFREE (MTYPE_ISIS_AREA_ADDR, addr); + } + area->area_addrs = NULL; + THREAD_TIMER_OFF (area->t_tick); - if (area->t_remove_aged) - thread_cancel (area->t_remove_aged); THREAD_TIMER_OFF (area->t_lsp_refresh[0]); THREAD_TIMER_OFF (area->t_lsp_refresh[1]); + thread_cancel_event (master, area); + + listnode_delete (isis->area_list, area); + + free (area->area_tag); + XFREE (MTYPE_ISIS_AREA, area); + if (listcount (isis->area_list) == 0) + { + memset (isis->sysid, 0, ISIS_SYS_ID_LEN); + isis->sysid_set = 0; + } + return CMD_SUCCESS; } int -area_net_title (struct vty *vty, const u_char *net_title) +area_net_title (struct vty *vty, const char *net_title) { struct isis_area *area; struct area_addr *addr; @@ -249,7 +324,7 @@ area_net_title (struct vty *vty, const u_char *net_title) if (!area) { vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE); - return CMD_WARNING; + return CMD_ERR_NO_MATCH; } /* We check that we are not over the maximal number of addresses */ @@ -257,7 +332,7 @@ area_net_title (struct vty *vty, const u_char *net_title) { vty_out (vty, "Maximum of area addresses (%d) already reached %s", isis->max_area_addrs, VTY_NEWLINE); - return CMD_WARNING; + return CMD_ERR_NOTHING_TODO; } addr = XMALLOC (MTYPE_ISIS_AREA_ADDR, sizeof (struct area_addr)); @@ -269,10 +344,18 @@ area_net_title (struct vty *vty, const u_char *net_title) #endif /* EXTREME_DEBUG */ if (addr->addr_len < 8 || addr->addr_len > 20) { - zlog_warn ("area address must be at least 8..20 octets long (%d)", - addr->addr_len); + vty_out (vty, "area address must be at least 8..20 octets long (%d)%s", + addr->addr_len, VTY_NEWLINE); + XFREE (MTYPE_ISIS_AREA_ADDR, addr); + return CMD_ERR_AMBIGUOUS; + } + + if (addr->area_addr[addr->addr_len-1] != 0) + { + vty_out (vty, "nsel byte (last byte) in area address must be 0%s", + VTY_NEWLINE); XFREE (MTYPE_ISIS_AREA_ADDR, addr); - return CMD_WARNING; + return CMD_ERR_AMBIGUOUS; } if (isis->sysid_set == 0) @@ -280,7 +363,7 @@ area_net_title (struct vty *vty, const u_char *net_title) /* * First area address - get the SystemID for this router */ - memcpy (isis->sysid, GETSYSID (addr, ISIS_SYS_ID_LEN), ISIS_SYS_ID_LEN); + memcpy (isis->sysid, GETSYSID (addr), ISIS_SYS_ID_LEN); isis->sysid_set = 1; if (isis->debugs & DEBUG_EVENTS) zlog_debug ("Router has SystemID %s", sysid_print (isis->sysid)); @@ -290,20 +373,19 @@ area_net_title (struct vty *vty, const u_char *net_title) /* * Check that the SystemID portions match */ - if (memcmp (isis->sysid, GETSYSID (addr, ISIS_SYS_ID_LEN), - ISIS_SYS_ID_LEN)) + if (memcmp (isis->sysid, GETSYSID (addr), ISIS_SYS_ID_LEN)) { vty_out (vty, "System ID must not change when defining additional area" " addresses%s", VTY_NEWLINE); XFREE (MTYPE_ISIS_AREA_ADDR, addr); - return CMD_WARNING; + return CMD_ERR_AMBIGUOUS; } /* now we see that we don't already have this address */ for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp)) { - if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) != (addr->addr_len)) + if ((addrp->addr_len + ISIS_SYS_ID_LEN + ISIS_NSEL_LEN) != (addr->addr_len)) continue; if (!memcmp (addrp->area_addr, addr->area_addr, addr->addr_len)) { @@ -311,26 +393,28 @@ area_net_title (struct vty *vty, const u_char *net_title) return CMD_SUCCESS; /* silent fail */ } } - } + /* * Forget the systemID part of the address */ - addr->addr_len -= (ISIS_SYS_ID_LEN + 1); + addr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN); listnode_add (area->area_addrs, addr); /* only now we can safely generate our LSPs for this area */ if (listcount (area->area_addrs) > 0) { - lsp_l1_generate (area); - lsp_l2_generate (area); + if (area->is_type & IS_LEVEL_1) + lsp_generate (area, IS_LEVEL_1); + if (area->is_type & IS_LEVEL_2) + lsp_generate (area, IS_LEVEL_2); } return CMD_SUCCESS; } int -area_clear_net_title (struct vty *vty, const u_char *net_title) +area_clear_net_title (struct vty *vty, const char *net_title) { struct isis_area *area; struct area_addr addr, *addrp = NULL; @@ -341,7 +425,7 @@ area_clear_net_title (struct vty *vty, const u_char *net_title) if (!area) { vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE); - return CMD_WARNING; + return CMD_ERR_NO_MATCH; } addr.addr_len = dotformat2buff (buff, net_title); @@ -349,13 +433,13 @@ area_clear_net_title (struct vty *vty, const u_char *net_title) { vty_out (vty, "Unsupported area address length %d, should be 8...20 %s", addr.addr_len, VTY_NEWLINE); - return CMD_WARNING; + return CMD_ERR_AMBIGUOUS; } memcpy (addr.area_addr, buff, (int) addr.addr_len); for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp)) - if (addrp->addr_len == addr.addr_len && + if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len && !memcmp (addrp->area_addr, addr.area_addr, addr.addr_len)) break; @@ -363,26 +447,36 @@ area_clear_net_title (struct vty *vty, const u_char *net_title) { vty_out (vty, "No area address %s for area %s %s", net_title, area->area_tag, VTY_NEWLINE); - return CMD_WARNING; + return CMD_ERR_NO_MATCH; } listnode_delete (area->area_addrs, addrp); + XFREE (MTYPE_ISIS_AREA_ADDR, addrp); + + /* + * 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; + if (isis->debugs & DEBUG_EVENTS) + zlog_debug ("Router has no SystemID"); + } return CMD_SUCCESS; } /* - * 'show clns neighbors' command + * 'show isis interface' command */ int -show_clns_neigh (struct vty *vty, char detail) +show_isis_interface_common (struct vty *vty, const char *ifname, char detail) { struct listnode *anode, *cnode; struct isis_area *area; struct isis_circuit *circuit; - struct list *db; - int i; if (!isis) { @@ -395,92 +489,246 @@ show_clns_neigh (struct vty *vty, char detail) vty_out (vty, "Area %s:%s", area->area_tag, VTY_NEWLINE); if (detail == ISIS_UI_LEVEL_BRIEF) - vty_out (vty, " System Id Interface L State " - "Holdtime SNPA%s", VTY_NEWLINE); + vty_out (vty, " Interface CircId State Type Level%s", + VTY_NEWLINE); for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit)) - { - if (circuit->circ_type == CIRCUIT_T_BROADCAST) - { - for (i = 0; i < 2; i++) - { - db = circuit->u.bc.adjdb[i]; - if (db && db->count) - { - if (detail == ISIS_UI_LEVEL_BRIEF) - isis_adjdb_iterate (db, - (void (*) - (struct isis_adjacency *, - void *)) isis_adj_print_vty, - vty); - if (detail == ISIS_UI_LEVEL_DETAIL) - isis_adjdb_iterate (db, - (void (*) - (struct isis_adjacency *, - void *)) - isis_adj_print_vty_detail, vty); - if (detail == ISIS_UI_LEVEL_EXTENSIVE) - isis_adjdb_iterate (db, - (void (*) - (struct isis_adjacency *, - void *)) - isis_adj_print_vty_extensive, - vty); - } - } - } - else if (circuit->circ_type == CIRCUIT_T_P2P && - circuit->u.p2p.neighbor) - { - if (detail == ISIS_UI_LEVEL_BRIEF) - isis_adj_p2p_print_vty (circuit->u.p2p.neighbor, vty); - if (detail == ISIS_UI_LEVEL_DETAIL) - isis_adj_p2p_print_vty_detail (circuit->u.p2p.neighbor, vty); - if (detail == ISIS_UI_LEVEL_EXTENSIVE) - isis_adj_p2p_print_vty_extensive (circuit->u.p2p.neighbor, - vty); - } - } + 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_clns_neighbors, - show_clns_neighbors_cmd, - "show clns neighbors", +DEFUN (show_isis_interface, + show_isis_interface_cmd, + "show isis interface", SHOW_STR - "clns network information\n" - "CLNS neighbor adjacencies\n") + "ISIS network information\n" + "ISIS interface\n") { - return show_clns_neigh (vty, ISIS_UI_LEVEL_BRIEF); + return show_isis_interface_common (vty, NULL, ISIS_UI_LEVEL_BRIEF); } -ALIAS (show_clns_neighbors, - show_isis_neighbors_cmd, - "show isis neighbors", +DEFUN (show_isis_interface_detail, + show_isis_interface_detail_cmd, + "show isis interface detail", SHOW_STR - "IS-IS network information\n" - "IS-IS neighbor adjacencies\n") + "ISIS network information\n" + "ISIS interface\n" + "show detailed information\n") +{ + return show_isis_interface_common (vty, NULL, ISIS_UI_LEVEL_DETAIL); +} -DEFUN (show_clns_neighbors_detail, - show_clns_neighbors_detail_cmd, - "show clns neighbors detail", +DEFUN (show_isis_interface_arg, + show_isis_interface_arg_cmd, + "show isis interface WORD", SHOW_STR - "clns network information\n" - "CLNS neighbor adjacencies\n" - "show detailed information\n") + "ISIS network information\n" + "ISIS interface\n" + "ISIS interface name\n") +{ + return show_isis_interface_common (vty, argv[0], ISIS_UI_LEVEL_DETAIL); +} + +/* + * 'show isis neighbor' command + */ + +int +show_isis_neighbor_common (struct vty *vty, const char *id, char detail) +{ + struct listnode *anode, *cnode, *node; + struct isis_area *area; + struct isis_circuit *circuit; + struct list *adjdb; + struct isis_adjacency *adj; + struct isis_dynhn *dynhn; + u_char sysid[ISIS_SYS_ID_LEN]; + int i; + + if (!isis) + { + vty_out (vty, "IS-IS Routing Process not enabled%s", VTY_NEWLINE); + 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%s", id, VTY_NEWLINE); + 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:%s", area->area_tag, VTY_NEWLINE); + + if (detail == ISIS_UI_LEVEL_BRIEF) + vty_out (vty, " System Id Interface L State" + " Holdtime SNPA%s", VTY_NEWLINE); + + for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit)) + { + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + { + for (i = 0; i < 2; i++) + { + adjdb = circuit->u.bc.adjdb[i]; + if (adjdb && adjdb->count) + { + for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj)) + if (!id || !memcmp (adj->sysid, sysid, + ISIS_SYS_ID_LEN)) + isis_adj_print_vty (adj, vty, detail); + } + } + } + else if (circuit->circ_type == CIRCUIT_T_P2P && + circuit->u.p2p.neighbor) + { + adj = circuit->u.p2p.neighbor; + if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN)) + isis_adj_print_vty (adj, vty, detail); + } + } + } + + return CMD_SUCCESS; +} + +/* + * 'clear isis neighbor' command + */ +int +clear_isis_neighbor_common (struct vty *vty, const char *id) +{ + struct listnode *anode, *cnode, *cnextnode, *node, *nnode; + struct isis_area *area; + struct isis_circuit *circuit; + struct list *adjdb; + struct isis_adjacency *adj; + struct isis_dynhn *dynhn; + u_char sysid[ISIS_SYS_ID_LEN]; + int i; + + if (!isis) + { + vty_out (vty, "IS-IS Routing Process not enabled%s", VTY_NEWLINE); + 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%s", id, VTY_NEWLINE); + return CMD_SUCCESS; + } + memcpy (sysid, dynhn->id, ISIS_SYS_ID_LEN); + } + } + + for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area)) + { + for (ALL_LIST_ELEMENTS (area->circuit_list, cnode, cnextnode, circuit)) + { + if (circuit->circ_type == CIRCUIT_T_BROADCAST) + { + for (i = 0; i < 2; i++) + { + adjdb = circuit->u.bc.adjdb[i]; + if (adjdb && adjdb->count) + { + for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj)) + if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN)) + isis_adj_state_change (adj, ISIS_ADJ_DOWN, + "clear user request"); + } + } + } + else if (circuit->circ_type == CIRCUIT_T_P2P && + circuit->u.p2p.neighbor) + { + adj = circuit->u.p2p.neighbor; + if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN)) + isis_adj_state_change (adj, ISIS_ADJ_DOWN, + "clear user request"); + } + } + } + + return CMD_SUCCESS; +} + +DEFUN (show_isis_neighbor, + show_isis_neighbor_cmd, + "show isis neighbor", + SHOW_STR + "ISIS network information\n" + "ISIS neighbor adjacencies\n") { - return show_clns_neigh (vty, ISIS_UI_LEVEL_DETAIL); + return show_isis_neighbor_common (vty, NULL, ISIS_UI_LEVEL_BRIEF); } -ALIAS (show_clns_neighbors_detail, - show_isis_neighbors_detail_cmd, - "show isis neighbors detail", +DEFUN (show_isis_neighbor_detail, + show_isis_neighbor_detail_cmd, + "show isis neighbor detail", SHOW_STR - "IS-IS network information\n" - "IS-IS neighbor adjacencies\n" + "ISIS network information\n" + "ISIS neighbor adjacencies\n" "show detailed information\n") +{ + return show_isis_neighbor_common (vty, NULL, ISIS_UI_LEVEL_DETAIL); +} + +DEFUN (show_isis_neighbor_arg, + show_isis_neighbor_arg_cmd, + "show isis neighbor WORD", + SHOW_STR + "ISIS network information\n" + "ISIS neighbor adjacencies\n" + "System id\n") +{ + return show_isis_neighbor_common (vty, argv[0], ISIS_UI_LEVEL_DETAIL); +} + +DEFUN (clear_isis_neighbor, + clear_isis_neighbor_cmd, + "clear isis neighbor", + CLEAR_STR + "Reset ISIS network information\n" + "Reset ISIS neighbor adjacencies\n") +{ + return clear_isis_neighbor_common (vty, NULL); +} + +DEFUN (clear_isis_neighbor_arg, + clear_isis_neighbor_arg_cmd, + "claer isis neighbor WORD", + CLEAR_STR + "ISIS network information\n" + "ISIS neighbor adjacencies\n" + "System id\n") +{ + return clear_isis_neighbor_common (vty, argv[0]); +} + /* * 'isis debug', 'show debugging' */ @@ -524,7 +772,8 @@ print_debug (struct vty *vty, int flags, int onoff) VTY_NEWLINE); if (flags & DEBUG_EVENTS) vty_out (vty, "IS-IS Event debugging is %s%s", onoffs, VTY_NEWLINE); - + if (flags & DEBUG_PACKET_DUMP) + vty_out (vty, "IS-IS Packet dump debugging is %s%s", onoffs, VTY_NEWLINE); } DEFUN (show_debugging, @@ -606,6 +855,11 @@ config_write_debug (struct vty *vty) vty_out (vty, "debug isis events%s", VTY_NEWLINE); write++; } + if (flags & DEBUG_PACKET_DUMP) + { + vty_out (vty, "debug isis packet-dump%s", VTY_NEWLINE); + write++; + } return write; } @@ -792,7 +1046,6 @@ DEFUN (no_debug_isis_spfevents, return CMD_SUCCESS; } - DEFUN (debug_isis_spfstats, debug_isis_spfstats_cmd, "debug isis spf-statistics ", @@ -897,6 +1150,32 @@ DEFUN (no_debug_isis_events, return CMD_SUCCESS; } +DEFUN (debug_isis_packet_dump, + debug_isis_packet_dump_cmd, + "debug isis packet-dump", + DEBUG_STR + "IS-IS information\n" + "IS-IS packet dump\n") +{ + isis->debugs |= DEBUG_PACKET_DUMP; + print_debug (vty, DEBUG_PACKET_DUMP, 1); + + return CMD_SUCCESS; +} + +DEFUN (no_debug_isis_packet_dump, + no_debug_isis_packet_dump_cmd, + "no debug isis packet-dump", + UNDEBUG_STR + "IS-IS information\n" + "IS-IS packet dump\n") +{ + isis->debugs &= ~DEBUG_PACKET_DUMP; + print_debug (vty, DEBUG_PACKET_DUMP, 0); + + return CMD_SUCCESS; +} + DEFUN (show_hostname, show_hostname_cmd, "show isis hostname", @@ -909,99 +1188,331 @@ DEFUN (show_hostname, return CMD_SUCCESS; } -DEFUN (show_database, - show_database_cmd, - "show isis database", - SHOW_STR "IS-IS information\n" "IS-IS link state database\n") +static void +vty_out_timestr(struct vty *vty, time_t uptime) { - struct listnode *node; + struct tm *tm; + time_t difftime = time (NULL); + difftime -= uptime; + tm = gmtime (&difftime); + +#define ONE_DAY_SECOND 60*60*24 +#define ONE_WEEK_SECOND 60*60*24*7 + if (difftime < ONE_DAY_SECOND) + vty_out (vty, "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (difftime < ONE_WEEK_SECOND) + vty_out (vty, "%dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); + else + vty_out (vty, "%02dw%dd%02dh", + tm->tm_yday/7, + tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + vty_out (vty, " ago"); +} + +DEFUN (show_isis_summary, + show_isis_summary_cmd, + "show isis summary", + SHOW_STR "IS-IS information\n" "IS-IS summary\n") +{ + struct listnode *node, *node2; struct isis_area *area; - int level, lsp_count; + struct isis_spftree *spftree; + int level; - if (isis->area_list->count == 0) + if (isis == NULL) + { + vty_out (vty, "ISIS is not running%s", VTY_NEWLINE); return CMD_SUCCESS; + } + + vty_out (vty, "Process Id : %ld%s", isis->process_id, + VTY_NEWLINE); + if (isis->sysid_set) + vty_out (vty, "System Id : %s%s", sysid_print (isis->sysid), + VTY_NEWLINE); + + vty_out (vty, "Up time : "); + vty_out_timestr(vty, isis->uptime); + vty_out (vty, "%s", VTY_NEWLINE); + + if (isis->area_list) + vty_out (vty, "Number of areas : %d%s", isis->area_list->count, + VTY_NEWLINE); for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) + { + vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null", + VTY_NEWLINE); + + if (listcount (area->area_addrs) > 0) { - vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null", - VTY_NEWLINE); - for (level = 0; level < ISIS_LEVELS; level++) - { - if (area->lspdb[level] && dict_count (area->lspdb[level]) > 0) - { - vty_out (vty, "IS-IS Level-%d link-state database:%s", - level + 1, VTY_NEWLINE); + struct area_addr *area_addr; + for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node2, area_addr)) + { + vty_out (vty, " Net: %s%s", + isonet_print (area_addr->area_addr, + area_addr->addr_len + ISIS_SYS_ID_LEN + + 1), VTY_NEWLINE); + } + } - lsp_count = lsp_print_all (vty, area->lspdb[level], - ISIS_UI_LEVEL_BRIEF, - area->dynhostname); + for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) + { + if ((area->is_type & level) == 0) + continue; - vty_out (vty, "%s %u LSPs%s%s", - VTY_NEWLINE, lsp_count, VTY_NEWLINE, VTY_NEWLINE); - } - } + vty_out (vty, " Level-%d:%s", level, VTY_NEWLINE); + spftree = area->spftree[level - 1]; + if (spftree->pending) + vty_out (vty, " IPv4 SPF: (pending)%s", VTY_NEWLINE); + else + vty_out (vty, " IPv4 SPF:%s", VTY_NEWLINE); + + vty_out (vty, " minimum interval : %d%s", + area->min_spf_interval[level - 1], VTY_NEWLINE); + + vty_out (vty, " last run : "); + vty_out_timestr(vty, spftree->lastrun); + vty_out (vty, "%s", VTY_NEWLINE); + + vty_out (vty, " run count : %d%s", + spftree->runcount, VTY_NEWLINE); + +#ifdef HAVE_IPV6 + spftree = area->spftree6[level - 1]; + if (spftree->pending) + vty_out (vty, " IPv6 SPF: (pending)%s", VTY_NEWLINE); + else + vty_out (vty, " IPv6 SPF:%s", VTY_NEWLINE); + + vty_out (vty, " minimum interval : %d%s", + area->min_spf_interval[level - 1], VTY_NEWLINE); + + vty_out (vty, " last run : "); + vty_out_timestr(vty, spftree->lastrun); + vty_out (vty, "%s", VTY_NEWLINE); + + vty_out (vty, " run count : %d%s", + spftree->runcount, VTY_NEWLINE); +#endif } + } + vty_out (vty, "%s", VTY_NEWLINE); return CMD_SUCCESS; } -DEFUN (show_database_detail, - show_database_detail_cmd, - "show isis database detail", - SHOW_STR - "IS-IS information\n" - "IS-IS link state database\n") +/* + * This function supports following display options: + * [ show isis database [detail] ] + * [ show isis database [detail] ] + * [ show isis database [detail] ] + * [ show isis database . [detail] ] + * [ show isis database . [detail] ] + * [ show isis database .- [detail] ] + * [ show isis database .- [detail] ] + * [ show isis database detail ] + * [ show isis database detail ] + * [ show isis database detail . ] + * [ show isis database detail . ] + * [ show isis database detail .- ] + * [ show isis database detail .- ] + */ +static int +show_isis_database (struct vty *vty, const char *argv, int ui_level) { struct listnode *node; struct isis_area *area; + struct isis_lsp *lsp; + struct isis_dynhn *dynhn; + const char *pos = argv; + u_char lspid[ISIS_SYS_ID_LEN+2]; + char sysid[15]; /* len of xxxx.xxxx.xxxx + place for #0 termination */ + u_char number[3]; int level, lsp_count; if (isis->area_list->count == 0) return CMD_SUCCESS; + memset (&lspid, 0, ISIS_SYS_ID_LEN); + memset (&sysid, 0, 15); + + if (argv) + { + strncpy (sysid, argv, 15); + sysid[14] = '\0'; + } + + /* + * extract fragment and pseudo id from the string argv + * in the forms: + * (a) .- or + * (b) . or + * (c) or + * Where systemid is in the form: + * xxxx.xxxx.xxxx + */ + if (argv && strlen (argv) > 3) + { + pos = argv + strlen (argv) - 3; + if (strncmp (pos, "-", 1) == 0) + { + memcpy (number, ++pos, 2); + lspid[ISIS_SYS_ID_LEN+1] = (u_char) strtol ((char *)number, NULL, 16); + pos -= 4; + if (strncmp (pos, ".", 1) != 0) + return CMD_ERR_AMBIGUOUS; + } + if (strncmp (pos, ".", 1) == 0) + { + memcpy (number, ++pos, 2); + lspid[ISIS_SYS_ID_LEN] = (u_char) strtol ((char *)number, NULL, 16); + sysid[pos - argv - 1] = '\0'; + } + } + for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) { vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null", - VTY_NEWLINE); - for (level = 0; level < ISIS_LEVELS; level++) - { - if (area->lspdb[level] && dict_count (area->lspdb[level]) > 0) - { - vty_out (vty, "IS-IS Level-%d Link State Database:%s", - level + 1, VTY_NEWLINE); - - lsp_count = lsp_print_all (vty, area->lspdb[level], - ISIS_UI_LEVEL_DETAIL, - area->dynhostname); + VTY_NEWLINE); - vty_out (vty, "%s %u LSPs%s%s", - VTY_NEWLINE, lsp_count, VTY_NEWLINE, VTY_NEWLINE); - } - } + for (level = 0; level < ISIS_LEVELS; level++) + { + if (area->lspdb[level] && dict_count (area->lspdb[level]) > 0) + { + lsp = NULL; + if (argv != NULL) + { + /* + * Try to find the lsp-id if the argv string is in + * the form hostname.- + */ + if (sysid2buff (lspid, sysid)) + { + lsp = lsp_search (lspid, area->lspdb[level]); + } + else if ((dynhn = dynhn_find_by_name (sysid))) + { + memcpy (lspid, dynhn->id, ISIS_SYS_ID_LEN); + lsp = lsp_search (lspid, area->lspdb[level]); + } + else if (strncmp(unix_hostname (), sysid, 15) == 0) + { + memcpy (lspid, isis->sysid, ISIS_SYS_ID_LEN); + lsp = lsp_search (lspid, area->lspdb[level]); + } + } + + if (lsp != NULL || argv == NULL) + { + vty_out (vty, "IS-IS Level-%d link-state database:%s", + level + 1, VTY_NEWLINE); + + /* print the title in all cases */ + vty_out (vty, "LSP ID PduLen " + "SeqNumber Chksum Holdtime ATT/P/OL%s", + VTY_NEWLINE); + } + + if (lsp) + { + if (ui_level == ISIS_UI_LEVEL_DETAIL) + lsp_print_detail (lsp, vty, area->dynhostname); + else + lsp_print (lsp, vty, area->dynhostname); + } + else if (argv == NULL) + { + lsp_count = lsp_print_all (vty, area->lspdb[level], + ui_level, + area->dynhostname); + + vty_out (vty, " %u LSPs%s%s", + lsp_count, VTY_NEWLINE, VTY_NEWLINE); + } + } + } } return CMD_SUCCESS; } -/* - * 'router isis' command - */ -DEFUN (router_isis, - router_isis_cmd, - "router isis WORD", - ROUTER_STR - "ISO IS-IS\n" - "ISO Routing area tag") +DEFUN (show_database_brief, + show_database_cmd, + "show isis database", + SHOW_STR + "IS-IS information\n" + "IS-IS link state database\n") { - return isis_area_get (vty, argv[0]); + return show_isis_database (vty, NULL, ISIS_UI_LEVEL_BRIEF); } -/* - *'no router isis' command - */ -DEFUN (no_router_isis, - no_router_isis_cmd, - "no router isis WORD", +DEFUN (show_database_lsp_brief, + show_database_arg_cmd, + "show isis database WORD", + SHOW_STR + "IS-IS information\n" + "IS-IS link state database\n" + "LSP ID\n") +{ + return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_BRIEF); +} + +DEFUN (show_database_lsp_detail, + show_database_arg_detail_cmd, + "show isis database WORD detail", + SHOW_STR + "IS-IS information\n" + "IS-IS link state database\n" + "LSP ID\n" + "Detailed information\n") +{ + return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_DETAIL); +} + +DEFUN (show_database_detail, + show_database_detail_cmd, + "show isis database detail", + SHOW_STR + "IS-IS information\n" + "IS-IS link state database\n") +{ + return show_isis_database (vty, NULL, ISIS_UI_LEVEL_DETAIL); +} + +DEFUN (show_database_detail_lsp, + show_database_detail_arg_cmd, + "show isis database detail WORD", + SHOW_STR + "IS-IS information\n" + "IS-IS link state database\n" + "Detailed information\n" + "LSP ID\n") +{ + return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_DETAIL); +} + +/* + * 'router isis' command + */ +DEFUN (router_isis, + router_isis_cmd, + "router isis WORD", + ROUTER_STR + "ISO IS-IS\n" + "ISO Routing area tag") +{ + return isis_area_get (vty, argv[0]); +} + +/* + *'no router isis' command + */ +DEFUN (no_router_isis, + no_router_isis_cmd, + "no router isis WORD", "no\n" ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag") { return isis_area_destroy (vty, argv[0]); @@ -1032,10 +1543,69 @@ DEFUN (no_net, return area_clear_net_title (vty, argv[0]); } -DEFUN (area_passwd, - area_passwd_cmd, - "area-password WORD", +DEFUN (area_passwd_md5, + area_passwd_md5_cmd, + "area-password md5 WORD", + "Configure the authentication password for an area\n" + "Authentication type\n" + "Area password\n") +{ + struct isis_area *area; + int len; + + area = vty->index; + + if (!area) + { + vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE); + return CMD_ERR_NO_MATCH; + } + + len = strlen (argv[0]); + if (len > 254) + { + vty_out (vty, "Too long area password (>254)%s", VTY_NEWLINE); + return CMD_ERR_AMBIGUOUS; + } + + area->area_passwd.len = (u_char) len; + area->area_passwd.type = ISIS_PASSWD_TYPE_HMAC_MD5; + strncpy ((char *)area->area_passwd.passwd, argv[0], 255); + + if (argc > 1) + { + SET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND); + if (strncmp(argv[1], "v", 1) == 0) + SET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV); + else + UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV); + } + else + { + UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND); + UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV); + } + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); + + return CMD_SUCCESS; +} + +ALIAS (area_passwd_md5, + area_passwd_md5_snpauth_cmd, + "area-password md5 WORD authenticate snp (send-only|validate)", + "Configure the authentication password for an area\n" + "Authentication type\n" + "Area password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n"); + +DEFUN (area_passwd_clear, + area_passwd_clear_cmd, + "area-password clear WORD", "Configure the authentication password for an area\n" + "Authentication type\n" "Area password\n") { struct isis_area *area; @@ -1045,16 +1615,17 @@ DEFUN (area_passwd, if (!area) { - vty_out (vty, "Cant find IS-IS instance%s", VTY_NEWLINE); - return CMD_WARNING; + vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE); + return CMD_ERR_NO_MATCH; } len = strlen (argv[0]); if (len > 254) { vty_out (vty, "Too long area password (>254)%s", VTY_NEWLINE); - return CMD_WARNING; + return CMD_ERR_AMBIGUOUS; } + area->area_passwd.len = (u_char) len; area->area_passwd.type = ISIS_PASSWD_TYPE_CLEARTXT; strncpy ((char *)area->area_passwd.passwd, argv[0], 255); @@ -1072,14 +1643,16 @@ DEFUN (area_passwd, UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND); UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV); } + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); return CMD_SUCCESS; } -ALIAS (area_passwd, - area_passwd_snpauth_cmd, - "area-password WORD authenticate snp (send-only|validate)", +ALIAS (area_passwd_clear, + area_passwd_clear_snpauth_cmd, + "area-password clear WORD authenticate snp (send-only|validate)", "Configure the authentication password for an area\n" + "Authentication type\n" "Area password\n" "Authentication\n" "SNP PDUs\n" @@ -1098,19 +1671,79 @@ DEFUN (no_area_passwd, if (!area) { - vty_out (vty, "Cant find IS-IS instance%s", VTY_NEWLINE); - return CMD_WARNING; + vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE); + return CMD_ERR_NO_MATCH; } memset (&area->area_passwd, 0, sizeof (struct isis_passwd)); + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); + + return CMD_SUCCESS; +} + +DEFUN (domain_passwd_md5, + domain_passwd_md5_cmd, + "domain-password md5 WORD", + "Set the authentication password for a routing domain\n" + "Authentication type\n" + "Routing domain password\n") +{ + struct isis_area *area; + int len; + + area = vty->index; + + if (!area) + { + vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE); + return CMD_ERR_NO_MATCH; + } + + len = strlen (argv[0]); + if (len > 254) + { + vty_out (vty, "Too long area password (>254)%s", VTY_NEWLINE); + return CMD_ERR_AMBIGUOUS; + } + + area->domain_passwd.len = (u_char) len; + area->domain_passwd.type = ISIS_PASSWD_TYPE_HMAC_MD5; + strncpy ((char *)area->domain_passwd.passwd, argv[0], 255); + + if (argc > 1) + { + SET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND); + if (strncmp(argv[1], "v", 1) == 0) + SET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV); + else + UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV); + } + else + { + UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND); + UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV); + } + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); return CMD_SUCCESS; } -DEFUN (domain_passwd, - domain_passwd_cmd, - "domain-password WORD", +ALIAS (domain_passwd_md5, + domain_passwd_md5_snpauth_cmd, + "domain-password md5 WORD authenticate snp (send-only|validate)", + "Set the authentication password for a routing domain\n" + "Authentication type\n" + "Routing domain password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n"); + +DEFUN (domain_passwd_clear, + domain_passwd_clear_cmd, + "domain-password clear WORD", "Set the authentication password for a routing domain\n" + "Authentication type\n" "Routing domain password\n") { struct isis_area *area; @@ -1120,16 +1753,17 @@ DEFUN (domain_passwd, if (!area) { - vty_out (vty, "Cant find IS-IS instance%s", VTY_NEWLINE); - return CMD_WARNING; + vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE); + return CMD_ERR_NO_MATCH; } len = strlen (argv[0]); if (len > 254) { vty_out (vty, "Too long area password (>254)%s", VTY_NEWLINE); - return CMD_WARNING; + return CMD_ERR_AMBIGUOUS; } + area->domain_passwd.len = (u_char) len; area->domain_passwd.type = ISIS_PASSWD_TYPE_CLEARTXT; strncpy ((char *)area->domain_passwd.passwd, argv[0], 255); @@ -1147,14 +1781,16 @@ DEFUN (domain_passwd, UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND); UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV); } + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); return CMD_SUCCESS; } -ALIAS (domain_passwd, - domain_passwd_snpauth_cmd, - "domain-password WORD authenticate snp (send-only|validate)", +ALIAS (domain_passwd_clear, + domain_passwd_clear_snpauth_cmd, + "domain-password clear WORD authenticate snp (send-only|validate)", "Set the authentication password for a routing domain\n" + "Authentication type\n" "Routing domain password\n" "Authentication\n" "SNP PDUs\n" @@ -1163,7 +1799,7 @@ ALIAS (domain_passwd, DEFUN (no_domain_passwd, no_domain_passwd_cmd, - "no domain-password WORD", + "no domain-password", NO_STR "Set the authentication password for a routing domain\n") { @@ -1173,11 +1809,12 @@ DEFUN (no_domain_passwd, if (!area) { - vty_out (vty, "Cant find IS-IS instance%s", VTY_NEWLINE); - return CMD_WARNING; + vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE); + return CMD_ERR_NO_MATCH; } memset (&area->domain_passwd, 0, sizeof (struct isis_passwd)); + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); return CMD_SUCCESS; } @@ -1197,8 +1834,8 @@ DEFUN (is_type, if (!area) { - vty_out (vty, "Cant find IS-IS instance%s", VTY_NEWLINE); - return CMD_WARNING; + vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE); + return CMD_ERR_NO_MATCH; } type = string2circuit_t (argv[0]); @@ -1229,8 +1866,9 @@ DEFUN (no_is_type, assert (area); /* - * Put the is-type back to default. Which is level-1-2 on first - * circuit for the area level-1 for the rest + * Put the is-type back to defaults: + * - level-1-2 on first area + * - level-1 for the rest */ if (listgetdata (listhead (isis->area_list)) == area) type = IS_LEVEL_1_AND_2; @@ -1242,6 +1880,36 @@ DEFUN (no_is_type, return CMD_SUCCESS; } +static int +set_lsp_gen_interval (struct vty *vty, struct isis_area *area, + uint16_t interval, int level) +{ + int lvl; + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) + { + if (!(lvl & level)) + continue; + + if (interval >= area->lsp_refresh[lvl-1]) + { + vty_out (vty, "LSP gen interval %us must be less than " + "the LSP refresh interval %us%s", + interval, area->lsp_refresh[lvl-1], VTY_NEWLINE); + return CMD_ERR_AMBIGUOUS; + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) + { + if (!(lvl & level)) + continue; + area->lsp_gen_interval[lvl-1] = interval; + } + + return CMD_SUCCESS; +} + DEFUN (lsp_gen_interval, lsp_gen_interval_cmd, "lsp-gen-interval <1-120>", @@ -1250,15 +1918,12 @@ DEFUN (lsp_gen_interval, { struct isis_area *area; uint16_t interval; + int level; area = vty->index; - assert (area); - interval = atoi (argv[0]); - area->lsp_gen_interval[0] = interval; - area->lsp_gen_interval[1] = interval; - - return CMD_SUCCESS; + level = IS_LEVEL_1 | IS_LEVEL_2; + return set_lsp_gen_interval (vty, area, interval, level); } DEFUN (no_lsp_gen_interval, @@ -1268,14 +1933,13 @@ DEFUN (no_lsp_gen_interval, "Minimum interval between regenerating same LSP\n") { struct isis_area *area; + uint16_t interval; + int level; area = vty->index; - assert (area); - - area->lsp_gen_interval[0] = LSP_GEN_INTERVAL_DEFAULT; - area->lsp_gen_interval[1] = LSP_GEN_INTERVAL_DEFAULT; - - return CMD_SUCCESS; + interval = DEFAULT_MIN_LSP_GEN_INTERVAL; + level = IS_LEVEL_1 | IS_LEVEL_2; + return set_lsp_gen_interval (vty, area, interval, level); } ALIAS (no_lsp_gen_interval, @@ -1294,14 +1958,12 @@ DEFUN (lsp_gen_interval_l1, { struct isis_area *area; uint16_t interval; + int level; area = vty->index; - assert (area); - interval = atoi (argv[0]); - area->lsp_gen_interval[0] = interval; - - return CMD_SUCCESS; + level = IS_LEVEL_1; + return set_lsp_gen_interval (vty, area, interval, level); } DEFUN (no_lsp_gen_interval_l1, @@ -1312,13 +1974,13 @@ DEFUN (no_lsp_gen_interval_l1, "Set interval for level 1 only\n") { struct isis_area *area; + uint16_t interval; + int level; area = vty->index; - assert (area); - - area->lsp_gen_interval[0] = LSP_GEN_INTERVAL_DEFAULT; - - return CMD_SUCCESS; + interval = DEFAULT_MIN_LSP_GEN_INTERVAL; + level = IS_LEVEL_1; + return set_lsp_gen_interval (vty, area, interval, level); } ALIAS (no_lsp_gen_interval_l1, @@ -1337,15 +1999,13 @@ DEFUN (lsp_gen_interval_l2, "Minimum interval in seconds\n") { struct isis_area *area; - int interval; + uint16_t interval; + int level; area = vty->index; - assert (area); - interval = atoi (argv[0]); - area->lsp_gen_interval[1] = interval; - - return CMD_SUCCESS; + level = IS_LEVEL_2; + return set_lsp_gen_interval (vty, area, interval, level); } DEFUN (no_lsp_gen_interval_l2, @@ -1356,15 +2016,13 @@ DEFUN (no_lsp_gen_interval_l2, "Set interval for level 2 only\n") { struct isis_area *area; - int interval; + uint16_t interval; + int level; area = vty->index; - assert (area); - - interval = atoi (argv[0]); - area->lsp_gen_interval[1] = LSP_GEN_INTERVAL_DEFAULT; - - return CMD_SUCCESS; + interval = DEFAULT_MIN_LSP_GEN_INTERVAL; + level = IS_LEVEL_2; + return set_lsp_gen_interval (vty, area, interval, level); } ALIAS (no_lsp_gen_interval_l2, @@ -1384,6 +2042,8 @@ DEFUN (metric_style, "Use new style of TLVs to carry wider metric\n") { struct isis_area *area; + struct isis_circuit *circuit; + struct listnode *node; area = vty->index; assert (area); @@ -1400,6 +2060,25 @@ DEFUN (metric_style, } else if (strncmp (argv[0], "n", 1) == 0) { + for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit)) + { + if ((area->is_type & IS_LEVEL_1) && + (circuit->is_type & IS_LEVEL_1) && + (circuit->metrics[0].metric_default > MAX_NARROW_LINK_METRIC)) + { + vty_out (vty, "ISIS circuit %s metric is invalid%s", + circuit->interface->name, VTY_NEWLINE); + return CMD_ERR_AMBIGUOUS; + } + if ((area->is_type & IS_LEVEL_2) && + (circuit->is_type & IS_LEVEL_2) && + (circuit->metrics[1].metric_default > MAX_NARROW_LINK_METRIC)) + { + vty_out (vty, "ISIS circuit %s metric is invalid%s", + circuit->interface->name, VTY_NEWLINE); + return CMD_ERR_AMBIGUOUS; + } + } area->newmetric = 0; area->oldmetric = 1; } @@ -1425,6 +2104,40 @@ DEFUN (no_metric_style, return CMD_SUCCESS; } +DEFUN (set_overload_bit, + set_overload_bit_cmd, + "set-overload-bit", + "Set overload bit to avoid any transit traffic\n" + "Set overload bit\n") +{ + struct isis_area *area; + + area = vty->index; + assert (area); + + area->overload_bit = LSPBIT_OL; + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); + + return CMD_SUCCESS; +} + +DEFUN (no_set_overload_bit, + no_set_overload_bit_cmd, + "no set-overload-bit", + "Reset overload bit to accept transit traffic\n" + "Reset overload bit\n") +{ + struct isis_area *area; + + area = vty->index; + assert (area); + + area->overload_bit = 0; + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); + + return CMD_SUCCESS; +} + DEFUN (dynamic_hostname, dynamic_hostname_cmd, "hostname dynamic", @@ -1436,7 +2149,11 @@ DEFUN (dynamic_hostname, area = vty->index; assert (area); - area->dynhostname = 1; + if (!area->dynhostname) + { + area->dynhostname = 1; + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0); + } return CMD_SUCCESS; } @@ -1453,7 +2170,11 @@ DEFUN (no_dynamic_hostname, area = vty->index; assert (area); - area->dynhostname = 0; + if (area->dynhostname) + { + area->dynhostname = 0; + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0); + } return CMD_SUCCESS; } @@ -1580,308 +2301,487 @@ ALIAS (no_spf_interval, "Set interval for level 2 only\n" "Minimum interval between consecutive SPFs in seconds\n") -#ifdef TOPOLOGY_GENERATE -DEFUN (topology_generate_grid, - topology_generate_grid_cmd, - "topology generate grid <1-100> <1-100> <1-65000> [param] [param] " - "[param]", - "Topology generation for IS-IS\n" - "Topology generation\n" - "Grid topology\n" - "X parameter of the grid\n" - "Y parameter of the grid\n" - "Random seed\n" - "Optional param 1\n" - "Optional param 2\n" - "Optional param 3\n" - "Topology\n") +static int +set_lsp_max_lifetime (struct vty *vty, struct isis_area *area, + uint16_t interval, int level) { - struct isis_area *area; + int lvl; + int set_refresh_interval[ISIS_LEVELS] = {0, 0}; + uint16_t refresh_interval; - area = vty->index; - assert (area); + refresh_interval = interval - 300; - if (!spgrid_check_params (vty, argc, argv)) + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { - if (area->topology) - list_delete (area->topology); - area->topology = list_new (); - memcpy (area->top_params, vty->buf, 200); - gen_spgrid_topology (vty, area->topology); - remove_topology_lsps (area); - generate_topology_lsps (area); - /* Regenerate L1 LSP to get two way connection to the generated - * topology. */ - lsp_regenerate_schedule (area); + if (!(lvl & level)) + continue; + if (refresh_interval < area->lsp_refresh[lvl-1]) + { + vty_out (vty, "Level %d Max LSP lifetime %us must be 300s greater than " + "the configured LSP refresh interval %us%s", + lvl, interval, area->lsp_refresh[lvl-1], VTY_NEWLINE); + vty_out (vty, "Automatically reducing level %d LSP refresh interval " + "to %us%s", lvl, refresh_interval, VTY_NEWLINE); + set_refresh_interval[lvl-1] = 1; + + if (refresh_interval <= area->lsp_gen_interval[lvl-1]) + { + vty_out (vty, "LSP refresh interval %us must be greater than " + "the configured LSP gen interval %us%s", + refresh_interval, area->lsp_gen_interval[lvl-1], + VTY_NEWLINE); + return CMD_ERR_AMBIGUOUS; + } + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) + { + if (!(lvl & level)) + continue; + area->max_lsp_lifetime[lvl-1] = interval; + /* Automatically reducing lsp_refresh_interval to interval - 300 */ + if (set_refresh_interval[lvl-1]) + area->lsp_refresh[lvl-1] = refresh_interval; } + lsp_regenerate_schedule (area, level, 1); + return CMD_SUCCESS; } -DEFUN (show_isis_generated_topology, - show_isis_generated_topology_cmd, - "show isis generated-topologies", - SHOW_STR - "CLNS network information\n" - "Show generated topologies\n") +DEFUN (max_lsp_lifetime, + max_lsp_lifetime_cmd, + "max-lsp-lifetime <350-65535>", + "Maximum LSP lifetime\n" + "LSP lifetime in seconds\n") { struct isis_area *area; - struct listnode *node; - struct listnode *node2; - struct arc *arc; - - for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) - { - if (!area->topology) - continue; + uint16_t interval; + int level; - vty_out (vty, "Topology for isis area: %s%s", area->area_tag, - VTY_NEWLINE); - vty_out (vty, "From node To node Distance%s", VTY_NEWLINE); + area = vty->index; + interval = atoi (argv[0]); + level = IS_LEVEL_1 | IS_LEVEL_2; + return set_lsp_max_lifetime (vty, area, interval, level); +} - for (ALL_LIST_ELEMENTS_RO (area->topology, node2, arc)) - vty_out (vty, "%9ld %11ld %12ld%s", arc->from_node, arc->to_node, - arc->distance, VTY_NEWLINE); - } - return CMD_SUCCESS; -} - -/* Base IS for topology generation. */ -DEFUN (topology_baseis, - topology_baseis_cmd, - "topology base-is WORD", - "Topology generation for IS-IS\n" - "A Network IS Base for this topology\n" - "XXXX.XXXX.XXXX Network entity title (NET)\n") +DEFUN (no_max_lsp_lifetime, + no_max_lsp_lifetime_cmd, + "no max-lsp-lifetime", + NO_STR + "LSP lifetime in seconds\n") { struct isis_area *area; - u_char buff[ISIS_SYS_ID_LEN]; + uint16_t interval; + int level; area = vty->index; - assert (area); - - if (sysid2buff (buff, argv[0])) - sysid2buff (area->topology_baseis, argv[0]); - - return CMD_SUCCESS; + interval = DEFAULT_LSP_LIFETIME; + level = IS_LEVEL_1 | IS_LEVEL_2; + return set_lsp_max_lifetime (vty, area, interval, level); } -DEFUN (no_topology_baseis, - no_topology_baseis_cmd, - "no topology base-is WORD", +ALIAS (no_max_lsp_lifetime, + no_max_lsp_lifetime_arg_cmd, + "no max-lsp-lifetime <350-65535>", NO_STR - "Topology generation for IS-IS\n" - "A Network IS Base for this topology\n" - "XXXX.XXXX.XXXX Network entity title (NET)\n") + "Maximum LSP lifetime\n" + "LSP lifetime in seconds\n") + +DEFUN (max_lsp_lifetime_l1, + max_lsp_lifetime_l1_cmd, + "max-lsp-lifetime level-1 <350-65535>", + "Maximum LSP lifetime for Level 1 only\n" + "LSP lifetime for Level 1 only in seconds\n") { struct isis_area *area; + uint16_t interval; + int level; area = vty->index; - assert (area); - - memcpy (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS, ISIS_SYS_ID_LEN); - return CMD_SUCCESS; + interval = atoi (argv[0]); + level = IS_LEVEL_1; + return set_lsp_max_lifetime (vty, area, interval, level); } -ALIAS (no_topology_baseis, - no_topology_baseis_noid_cmd, - "no topology base-is", +DEFUN (no_max_lsp_lifetime_l1, + no_max_lsp_lifetime_l1_cmd, + "no max-lsp-lifetime level-1", NO_STR - "Topology generation for IS-IS\n" - "A Network IS Base for this topology\n") - -DEFUN (topology_basedynh, - topology_basedynh_cmd, - "topology base-dynh WORD", - "Topology generation for IS-IS\n" - "Dynamic hostname base for this topology\n" - "Dynamic hostname base\n") + "LSP lifetime for Level 1 only in seconds\n") { struct isis_area *area; + uint16_t interval; + int level; area = vty->index; - assert (area); - - /* I hope that it's enough. */ - area->topology_basedynh = strndup (argv[0], 16); - return CMD_SUCCESS; + interval = DEFAULT_LSP_LIFETIME; + level = IS_LEVEL_1; + return set_lsp_max_lifetime (vty, area, interval, level); } -#endif /* TOPOLOGY_GENERATE */ -DEFUN (lsp_lifetime, - lsp_lifetime_cmd, - "lsp-lifetime <380-65535>", - "Maximum LSP lifetime\n" - "LSP lifetime in seconds\n") +ALIAS (no_max_lsp_lifetime_l1, + no_max_lsp_lifetime_l1_arg_cmd, + "no max-lsp-lifetime level-1 <350-65535>", + NO_STR + "Maximum LSP lifetime for Level 1 only\n" + "LSP lifetime for Level 1 only in seconds\n") + +DEFUN (max_lsp_lifetime_l2, + max_lsp_lifetime_l2_cmd, + "max-lsp-lifetime level-2 <350-65535>", + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime for Level 2 only in seconds\n") { struct isis_area *area; uint16_t interval; + int level; area = vty->index; - assert (area); - interval = atoi (argv[0]); + level = IS_LEVEL_2; + return set_lsp_max_lifetime (vty, area, interval, level); +} - if (interval < ISIS_MIN_LSP_LIFETIME) - { - vty_out (vty, "LSP lifetime (%us) below %us%s", - interval, ISIS_MIN_LSP_LIFETIME, VTY_NEWLINE); +DEFUN (no_max_lsp_lifetime_l2, + no_max_lsp_lifetime_l2_cmd, + "no max-lsp-lifetime level-2", + NO_STR + "LSP lifetime for Level 2 only in seconds\n") +{ + struct isis_area *area; + uint16_t interval; + int level; - return CMD_WARNING; - } + area = vty->index; + interval = DEFAULT_LSP_LIFETIME; + level = IS_LEVEL_2; + return set_lsp_max_lifetime (vty, area, interval, level); +} +ALIAS (no_max_lsp_lifetime_l2, + no_max_lsp_lifetime_l2_arg_cmd, + "no max-lsp-lifetime level-2 <350-65535>", + NO_STR + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime for Level 2 only in seconds\n") - area->max_lsp_lifetime[0] = interval; - area->max_lsp_lifetime[1] = interval; - area->lsp_refresh[0] = interval - 300; - area->lsp_refresh[1] = interval - 300; +static int +set_lsp_refresh_interval (struct vty *vty, struct isis_area *area, + uint16_t interval, int level) +{ + int lvl; - if (area->t_lsp_refresh[0]) + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - thread_cancel (area->t_lsp_refresh[0]); - thread_execute (master, lsp_refresh_l1, area, 0); + if (!(lvl & level)) + continue; + if (interval <= area->lsp_gen_interval[lvl-1]) + { + vty_out (vty, "LSP refresh interval %us must be greater than " + "the configured LSP gen interval %us%s", + interval, area->lsp_gen_interval[lvl-1], + VTY_NEWLINE); + return CMD_ERR_AMBIGUOUS; + } + if (interval > (area->max_lsp_lifetime[lvl-1] - 300)) + { + vty_out (vty, "LSP refresh interval %us must be less than " + "the configured LSP lifetime %us less 300%s", + interval, area->max_lsp_lifetime[lvl-1], + VTY_NEWLINE); + return CMD_ERR_AMBIGUOUS; + } } - if (area->t_lsp_refresh[1]) + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - thread_cancel (area->t_lsp_refresh[1]); - thread_execute (master, lsp_refresh_l2, area, 0); + if (!(lvl & level)) + continue; + area->lsp_refresh[lvl-1] = interval; } - + lsp_regenerate_schedule (area, level, 1); return CMD_SUCCESS; } -DEFUN (no_lsp_lifetime, - no_lsp_lifetime_cmd, - "no lsp-lifetime", - NO_STR - "LSP lifetime in seconds\n") +DEFUN (lsp_refresh_interval, + lsp_refresh_interval_cmd, + "lsp-refresh-interval <1-65235>", + "LSP refresh interval\n" + "LSP refresh interval in seconds\n") { struct isis_area *area; + uint16_t interval; + int level; area = vty->index; - assert (area); + interval = atoi (argv[0]); + level = IS_LEVEL_1 | IS_LEVEL_2; + return set_lsp_refresh_interval (vty, area, interval, level); +} - area->max_lsp_lifetime[0] = MAX_AGE; /* 1200s */ - area->max_lsp_lifetime[1] = MAX_AGE; /* 1200s */ - area->lsp_refresh[0] = MAX_LSP_GEN_INTERVAL; /* 900s */ - area->lsp_refresh[1] = MAX_LSP_GEN_INTERVAL; /* 900s */ +DEFUN (no_lsp_refresh_interval, + no_lsp_refresh_interval_cmd, + "no lsp-refresh-interval", + NO_STR + "LSP refresh interval in seconds\n") +{ + struct isis_area *area; + uint16_t interval; + int level; - return CMD_SUCCESS; + area = vty->index; + interval = DEFAULT_MAX_LSP_GEN_INTERVAL; + level = IS_LEVEL_1 | IS_LEVEL_2; + return set_lsp_refresh_interval (vty, area, interval, level); } -ALIAS (no_lsp_lifetime, - no_lsp_lifetime_arg_cmd, - "no lsp-lifetime <380-65535>", +ALIAS (no_lsp_refresh_interval, + no_lsp_refresh_interval_arg_cmd, + "no lsp-refresh-interval <1-65235>", NO_STR - "Maximum LSP lifetime\n" - "LSP lifetime in seconds\n") + "LSP refresh interval\n" + "LSP refresh interval in seconds\n") -DEFUN (lsp_lifetime_l1, - lsp_lifetime_l1_cmd, - "lsp-lifetime level-1 <380-65535>", - "Maximum LSP lifetime for Level 1 only\n" - "LSP lifetime for Level 1 only in seconds\n") +DEFUN (lsp_refresh_interval_l1, + lsp_refresh_interval_l1_cmd, + "lsp-refresh-interval level-1 <1-65235>", + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 1 only in seconds\n") { struct isis_area *area; uint16_t interval; + int level; area = vty->index; - assert (area); + interval = atoi (argv[0]); + level = IS_LEVEL_1; + return set_lsp_refresh_interval (vty, area, interval, level); +} + +DEFUN (no_lsp_refresh_interval_l1, + no_lsp_refresh_interval_l1_cmd, + "no lsp-refresh-interval level-1", + NO_STR + "LSP refresh interval for Level 1 only in seconds\n") +{ + struct isis_area *area; + uint16_t interval; + int level; + + area = vty->index; + interval = DEFAULT_MAX_LSP_GEN_INTERVAL; + level = IS_LEVEL_1; + return set_lsp_refresh_interval (vty, area, interval, level); +} + +ALIAS (no_lsp_refresh_interval_l1, + no_lsp_refresh_interval_l1_arg_cmd, + "no lsp-refresh-interval level-1 <1-65235>", + NO_STR + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 1 only in seconds\n") +DEFUN (lsp_refresh_interval_l2, + lsp_refresh_interval_l2_cmd, + "lsp-refresh-interval level-2 <1-65235>", + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval for Level 2 only in seconds\n") +{ + struct isis_area *area; + uint16_t interval; + int level; + + area = vty->index; interval = atoi (argv[0]); + level = IS_LEVEL_2; + return set_lsp_refresh_interval (vty, area, interval, level); +} - if (interval < ISIS_MIN_LSP_LIFETIME) - { - vty_out (vty, "Level-1 LSP lifetime (%us) below %us%s", - interval, ISIS_MIN_LSP_LIFETIME, VTY_NEWLINE); +DEFUN (no_lsp_refresh_interval_l2, + no_lsp_refresh_interval_l2_cmd, + "no lsp-refresh-interval level-2", + NO_STR + "LSP refresh interval for Level 2 only in seconds\n") +{ + struct isis_area *area; + uint16_t interval; + int level; - return CMD_WARNING; - } + area = vty->index; + interval = DEFAULT_MAX_LSP_GEN_INTERVAL; + level = IS_LEVEL_2; + return set_lsp_refresh_interval (vty, area, interval, level); +} + +ALIAS (no_lsp_refresh_interval_l2, + no_lsp_refresh_interval_l2_arg_cmd, + "no lsp-refresh-interval level-2 <1-65235>", + NO_STR + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval for Level 2 only in seconds\n") + +DEFUN (log_adj_changes, + log_adj_changes_cmd, + "log-adjacency-changes", + "Log changes in adjacency state\n") +{ + struct isis_area *area; + area = vty->index; + assert (area); - area->max_lsp_lifetime[0] = interval; - area->lsp_refresh[0] = interval - 300; + area->log_adj_changes = 1; return CMD_SUCCESS; } -DEFUN (no_lsp_lifetime_l1, - no_lsp_lifetime_l1_cmd, - "no lsp-lifetime level-1", - NO_STR - "LSP lifetime for Level 1 only in seconds\n") +DEFUN (no_log_adj_changes, + no_log_adj_changes_cmd, + "no log-adjacency-changes", + "Stop logging changes in adjacency state\n") { struct isis_area *area; area = vty->index; assert (area); - area->max_lsp_lifetime[0] = MAX_AGE; /* 1200s */ - area->lsp_refresh[0] = MAX_LSP_GEN_INTERVAL; /* 900s */ + area->log_adj_changes = 0; return CMD_SUCCESS; } -ALIAS (no_lsp_lifetime_l1, - no_lsp_lifetime_l1_arg_cmd, - "no lsp-lifetime level-1 <380-65535>", - NO_STR - "Maximum LSP lifetime for Level 1 only\n" - "LSP lifetime for Level 1 only in seconds\n") +#ifdef TOPOLOGY_GENERATE -DEFUN (lsp_lifetime_l2, - lsp_lifetime_l2_cmd, - "lsp-lifetime level-2 <380-65535>", - "Maximum LSP lifetime for Level 2 only\n" - "LSP lifetime for Level 2 only in seconds\n") +DEFUN (topology_generate_grid, + topology_generate_grid_cmd, + "topology generate grid <1-100> <1-100> <1-65000> [param] [param] " + "[param]", + "Topology generation for IS-IS\n" + "Topology generation\n" + "Grid topology\n" + "X parameter of the grid\n" + "Y parameter of the grid\n" + "Random seed\n" + "Optional param 1\n" + "Optional param 2\n" + "Optional param 3\n" + "Topology\n") { struct isis_area *area; - uint16_t interval; area = vty->index; assert (area); - interval = atoi (argv[0]); + if (!spgrid_check_params (vty, argc, argv)) + { + if (area->topology) + list_delete (area->topology); + area->topology = list_new (); + memcpy (area->top_params, vty->buf, 200); + gen_spgrid_topology (vty, area->topology); + remove_topology_lsps (area); + generate_topology_lsps (area); + /* Regenerate L1 LSP to get two way connection to the generated + * topology. */ + lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1); + } - if (interval < ISIS_MIN_LSP_LIFETIME) + return CMD_SUCCESS; +} + +DEFUN (show_isis_generated_topology, + show_isis_generated_topology_cmd, + "show isis generated-topologies", + SHOW_STR + "ISIS network information\n" + "Show generated topologies\n") +{ + struct isis_area *area; + struct listnode *node; + struct listnode *node2; + struct arc *arc; + + for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) { - vty_out (vty, "Level-2 LSP lifetime (%us) below %us%s", - interval, ISIS_MIN_LSP_LIFETIME, VTY_NEWLINE); + if (!area->topology) + continue; - return CMD_WARNING; + vty_out (vty, "Topology for isis area: %s%s", area->area_tag, + VTY_NEWLINE); + vty_out (vty, "From node To node Distance%s", VTY_NEWLINE); + + for (ALL_LIST_ELEMENTS_RO (area->topology, node2, arc)) + vty_out (vty, "%9ld %11ld %12ld%s", arc->from_node, arc->to_node, + arc->distance, VTY_NEWLINE); } + return CMD_SUCCESS; +} + +/* Base IS for topology generation. */ +DEFUN (topology_baseis, + topology_baseis_cmd, + "topology base-is WORD", + "Topology generation for IS-IS\n" + "A Network IS Base for this topology\n" + "XXXX.XXXX.XXXX Network entity title (NET)\n") +{ + struct isis_area *area; + u_char buff[ISIS_SYS_ID_LEN]; + + area = vty->index; + assert (area); - area->max_lsp_lifetime[1] = interval; - area->lsp_refresh[1] = interval - 300; + if (sysid2buff (buff, argv[0])) + sysid2buff (area->topology_baseis, argv[0]); return CMD_SUCCESS; } -DEFUN (no_lsp_lifetime_l2, - no_lsp_lifetime_l2_cmd, - "no lsp-lifetime level-2", +DEFUN (no_topology_baseis, + no_topology_baseis_cmd, + "no topology base-is WORD", NO_STR - "LSP lifetime for Level 2 only in seconds\n") + "Topology generation for IS-IS\n" + "A Network IS Base for this topology\n" + "XXXX.XXXX.XXXX Network entity title (NET)\n") { struct isis_area *area; area = vty->index; assert (area); - area->max_lsp_lifetime[1] = MAX_AGE; /* 1200s */ - area->lsp_refresh[1] = MAX_LSP_GEN_INTERVAL; /* 900s */ - + memcpy (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS, ISIS_SYS_ID_LEN); return CMD_SUCCESS; } -ALIAS (no_lsp_lifetime_l2, - no_lsp_lifetime_l2_arg_cmd, - "no lsp-lifetime level-2 <380-65535>", +ALIAS (no_topology_baseis, + no_topology_baseis_noid_cmd, + "no topology base-is", NO_STR - "Maximum LSP lifetime for Level 2 only\n" - "LSP lifetime for Level 2 only in seconds\n") + "Topology generation for IS-IS\n" + "A Network IS Base for this topology\n") + +DEFUN (topology_basedynh, + topology_basedynh_cmd, + "topology base-dynh WORD", + "Topology generation for IS-IS\n" + "Dynamic hostname base for this topology\n" + "Dynamic hostname base\n") +{ + struct isis_area *area; + + area = vty->index; + assert (area); + + /* I hope that it's enough. */ + area->topology_basedynh = strndup (argv[0], 16); + return CMD_SUCCESS; +} + +#endif /* TOPOLOGY_GENERATE */ /* IS-IS configuration write function */ int @@ -1919,34 +2819,36 @@ isis_config_write (struct vty *vty) vty_out (vty, " no hostname dynamic%s", VTY_NEWLINE); write++; } - /* ISIS - Metric-Style - when true displays wide */ - if (area->newmetric) + /* ISIS - Metric-Style - when true displays narrow */ + if (area->oldmetric) { - if (!area->oldmetric) - vty_out (vty, " metric-style wide%s", VTY_NEWLINE); + if (!area->newmetric) + vty_out (vty, " metric-style narrow%s", VTY_NEWLINE); else vty_out (vty, " metric-style transition%s", VTY_NEWLINE); write++; } - + /* ISIS - overload-bit */ + if (area->overload_bit) + { + vty_out (vty, " set-overload-bit%s", VTY_NEWLINE); + write++; + } /* ISIS - Area is-type (level-1-2 is default) */ if (area->is_type == IS_LEVEL_1) { vty_out (vty, " is-type level-1%s", VTY_NEWLINE); write++; } - else + else if (area->is_type == IS_LEVEL_2) { - if (area->is_type == IS_LEVEL_2) - { - vty_out (vty, " is-type level-2-only%s", VTY_NEWLINE); - write++; - } + vty_out (vty, " is-type level-2-only%s", VTY_NEWLINE); + write++; } /* ISIS - Lsp generation interval */ if (area->lsp_gen_interval[0] == area->lsp_gen_interval[1]) { - if (area->lsp_gen_interval[0] != LSP_GEN_INTERVAL_DEFAULT) + if (area->lsp_gen_interval[0] != DEFAULT_MIN_LSP_GEN_INTERVAL) { vty_out (vty, " lsp-gen-interval %d%s", area->lsp_gen_interval[0], VTY_NEWLINE); @@ -1955,13 +2857,13 @@ isis_config_write (struct vty *vty) } else { - if (area->lsp_gen_interval[0] != LSP_GEN_INTERVAL_DEFAULT) + if (area->lsp_gen_interval[0] != DEFAULT_MIN_LSP_GEN_INTERVAL) { vty_out (vty, " lsp-gen-interval level-1 %d%s", area->lsp_gen_interval[0], VTY_NEWLINE); write++; } - if (area->lsp_gen_interval[1] != LSP_GEN_INTERVAL_DEFAULT) + if (area->lsp_gen_interval[1] != DEFAULT_MIN_LSP_GEN_INTERVAL) { vty_out (vty, " lsp-gen-interval level-2 %d%s", area->lsp_gen_interval[1], VTY_NEWLINE); @@ -1971,28 +2873,53 @@ isis_config_write (struct vty *vty) /* ISIS - LSP lifetime */ if (area->max_lsp_lifetime[0] == area->max_lsp_lifetime[1]) { - if (area->max_lsp_lifetime[0] != MAX_AGE) + if (area->max_lsp_lifetime[0] != DEFAULT_LSP_LIFETIME) { - vty_out (vty, " lsp-lifetime %u%s", area->max_lsp_lifetime[0], + vty_out (vty, " max-lsp-lifetime %u%s", area->max_lsp_lifetime[0], VTY_NEWLINE); write++; } } else { - if (area->max_lsp_lifetime[0] != MAX_AGE) + if (area->max_lsp_lifetime[0] != DEFAULT_LSP_LIFETIME) { - vty_out (vty, " lsp-lifetime level-1 %u%s", + vty_out (vty, " max-lsp-lifetime level-1 %u%s", area->max_lsp_lifetime[0], VTY_NEWLINE); write++; } - if (area->max_lsp_lifetime[1] != MAX_AGE) + if (area->max_lsp_lifetime[1] != DEFAULT_LSP_LIFETIME) { - vty_out (vty, " lsp-lifetime level-2 %u%s", + vty_out (vty, " max-lsp-lifetime level-2 %u%s", area->max_lsp_lifetime[1], VTY_NEWLINE); write++; } } + /* ISIS - LSP refresh interval */ + if (area->lsp_refresh[0] == area->lsp_refresh[1]) + { + if (area->lsp_refresh[0] != DEFAULT_MAX_LSP_GEN_INTERVAL) + { + vty_out (vty, " lsp-refresh-interval %u%s", area->lsp_refresh[0], + VTY_NEWLINE); + write++; + } + } + else + { + if (area->lsp_refresh[0] != DEFAULT_MAX_LSP_GEN_INTERVAL) + { + vty_out (vty, " lsp-refresh-interval level-1 %u%s", + area->lsp_refresh[0], VTY_NEWLINE); + write++; + } + if (area->lsp_refresh[1] != DEFAULT_MAX_LSP_GEN_INTERVAL) + { + vty_out (vty, " lsp-refresh-interval level-2 %u%s", + area->lsp_refresh[1], VTY_NEWLINE); + write++; + } + } /* Minimum SPF interval. */ if (area->min_spf_interval[0] == area->min_spf_interval[1]) { @@ -2019,9 +2946,9 @@ isis_config_write (struct vty *vty) } } /* Authentication passwords. */ - if (area->area_passwd.len > 0) + if (area->area_passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) { - vty_out(vty, " area-password %s", area->area_passwd.passwd); + vty_out(vty, " area-password md5 %s", area->area_passwd.passwd); if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND)) { vty_out(vty, " authenticate snp "); @@ -2032,10 +2959,40 @@ isis_config_write (struct vty *vty) } vty_out(vty, "%s", VTY_NEWLINE); write++; - } - if (area->domain_passwd.len > 0) + } + else if (area->area_passwd.type == ISIS_PASSWD_TYPE_CLEARTXT) + { + vty_out(vty, " area-password clear %s", area->area_passwd.passwd); + if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND)) + { + vty_out(vty, " authenticate snp "); + if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV)) + vty_out(vty, "validate"); + else + vty_out(vty, "send-only"); + } + vty_out(vty, "%s", VTY_NEWLINE); + write++; + } + if (area->domain_passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) + { + vty_out(vty, " domain-password md5 %s", + area->domain_passwd.passwd); + if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND)) + { + vty_out(vty, " authenticate snp "); + if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV)) + vty_out(vty, "validate"); + else + vty_out(vty, "send-only"); + } + vty_out(vty, "%s", VTY_NEWLINE); + write++; + } + else if (area->domain_passwd.type == ISIS_PASSWD_TYPE_CLEARTXT) { - vty_out(vty, " domain-password %s", area->domain_passwd.passwd); + vty_out(vty, " domain-password clear %s", + area->domain_passwd.passwd); if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND)) { vty_out(vty, " authenticate snp "); @@ -2048,12 +3005,18 @@ isis_config_write (struct vty *vty) write++; } + if (area->log_adj_changes) + { + vty_out (vty, " log-adjacency-changes%s", VTY_NEWLINE); + write++; + } + #ifdef TOPOLOGY_GENERATE if (memcmp (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS, ISIS_SYS_ID_LEN)) { vty_out (vty, " topology base-is %s%s", - sysid_print (area->topology_baseis), VTY_NEWLINE); + sysid_print ((u_char *)area->topology_baseis), VTY_NEWLINE); write++; } if (area->topology_basedynh) @@ -2076,7 +3039,7 @@ isis_config_write (struct vty *vty) return write; } -static struct cmd_node isis_node = { +struct cmd_node isis_node = { ISIS_NODE, "%s(config-router)# ", 1 @@ -2088,23 +3051,43 @@ isis_init () /* Install IS-IS top node */ install_node (&isis_node, isis_config_write); - install_element (VIEW_NODE, &show_clns_neighbors_cmd); - install_element (VIEW_NODE, &show_isis_neighbors_cmd); - install_element (VIEW_NODE, &show_clns_neighbors_detail_cmd); - install_element (VIEW_NODE, &show_isis_neighbors_detail_cmd); + install_element (VIEW_NODE, &show_isis_summary_cmd); + + install_element (VIEW_NODE, &show_isis_interface_cmd); + install_element (VIEW_NODE, &show_isis_interface_detail_cmd); + install_element (VIEW_NODE, &show_isis_interface_arg_cmd); + + install_element (VIEW_NODE, &show_isis_neighbor_cmd); + install_element (VIEW_NODE, &show_isis_neighbor_detail_cmd); + install_element (VIEW_NODE, &show_isis_neighbor_arg_cmd); + install_element (VIEW_NODE, &clear_isis_neighbor_cmd); + install_element (VIEW_NODE, &clear_isis_neighbor_arg_cmd); install_element (VIEW_NODE, &show_hostname_cmd); install_element (VIEW_NODE, &show_database_cmd); + install_element (VIEW_NODE, &show_database_arg_cmd); + install_element (VIEW_NODE, &show_database_arg_detail_cmd); install_element (VIEW_NODE, &show_database_detail_cmd); + install_element (VIEW_NODE, &show_database_detail_arg_cmd); + + install_element (ENABLE_NODE, &show_isis_summary_cmd); - install_element (ENABLE_NODE, &show_clns_neighbors_cmd); - install_element (ENABLE_NODE, &show_isis_neighbors_cmd); - install_element (ENABLE_NODE, &show_clns_neighbors_detail_cmd); - install_element (ENABLE_NODE, &show_isis_neighbors_detail_cmd); + install_element (ENABLE_NODE, &show_isis_interface_cmd); + install_element (ENABLE_NODE, &show_isis_interface_detail_cmd); + install_element (ENABLE_NODE, &show_isis_interface_arg_cmd); + + install_element (ENABLE_NODE, &show_isis_neighbor_cmd); + install_element (ENABLE_NODE, &show_isis_neighbor_detail_cmd); + install_element (ENABLE_NODE, &show_isis_neighbor_arg_cmd); + install_element (ENABLE_NODE, &clear_isis_neighbor_cmd); + install_element (ENABLE_NODE, &clear_isis_neighbor_arg_cmd); install_element (ENABLE_NODE, &show_hostname_cmd); install_element (ENABLE_NODE, &show_database_cmd); + install_element (ENABLE_NODE, &show_database_arg_cmd); + install_element (ENABLE_NODE, &show_database_arg_detail_cmd); install_element (ENABLE_NODE, &show_database_detail_cmd); + install_element (ENABLE_NODE, &show_database_detail_arg_cmd); install_element (ENABLE_NODE, &show_debugging_cmd); install_node (&debug_node, config_write_debug); @@ -2131,6 +3114,8 @@ isis_init () install_element (ENABLE_NODE, &no_debug_isis_rtevents_cmd); install_element (ENABLE_NODE, &debug_isis_events_cmd); install_element (ENABLE_NODE, &no_debug_isis_events_cmd); + install_element (ENABLE_NODE, &debug_isis_packet_dump_cmd); + install_element (ENABLE_NODE, &no_debug_isis_packet_dump_cmd); install_element (CONFIG_NODE, &debug_isis_adj_cmd); install_element (CONFIG_NODE, &no_debug_isis_adj_cmd); @@ -2154,6 +3139,8 @@ isis_init () install_element (CONFIG_NODE, &no_debug_isis_rtevents_cmd); install_element (CONFIG_NODE, &debug_isis_events_cmd); install_element (CONFIG_NODE, &no_debug_isis_events_cmd); + install_element (CONFIG_NODE, &debug_isis_packet_dump_cmd); + install_element (CONFIG_NODE, &no_debug_isis_packet_dump_cmd); install_element (CONFIG_NODE, &router_isis_cmd); install_element (CONFIG_NODE, &no_router_isis_cmd); @@ -2166,12 +3153,16 @@ isis_init () install_element (ISIS_NODE, &is_type_cmd); install_element (ISIS_NODE, &no_is_type_cmd); - install_element (ISIS_NODE, &area_passwd_cmd); - install_element (ISIS_NODE, &area_passwd_snpauth_cmd); + install_element (ISIS_NODE, &area_passwd_md5_cmd); + install_element (ISIS_NODE, &area_passwd_md5_snpauth_cmd); + install_element (ISIS_NODE, &area_passwd_clear_cmd); + install_element (ISIS_NODE, &area_passwd_clear_snpauth_cmd); install_element (ISIS_NODE, &no_area_passwd_cmd); - install_element (ISIS_NODE, &domain_passwd_cmd); - install_element (ISIS_NODE, &domain_passwd_snpauth_cmd); + install_element (ISIS_NODE, &domain_passwd_md5_cmd); + install_element (ISIS_NODE, &domain_passwd_md5_snpauth_cmd); + install_element (ISIS_NODE, &domain_passwd_clear_cmd); + install_element (ISIS_NODE, &domain_passwd_clear_snpauth_cmd); install_element (ISIS_NODE, &no_domain_passwd_cmd); install_element (ISIS_NODE, &lsp_gen_interval_cmd); @@ -2194,21 +3185,38 @@ isis_init () install_element (ISIS_NODE, &no_spf_interval_l2_cmd); install_element (ISIS_NODE, &no_spf_interval_l2_arg_cmd); - install_element (ISIS_NODE, &lsp_lifetime_cmd); - install_element (ISIS_NODE, &no_lsp_lifetime_cmd); - install_element (ISIS_NODE, &no_lsp_lifetime_arg_cmd); - install_element (ISIS_NODE, &lsp_lifetime_l1_cmd); - install_element (ISIS_NODE, &no_lsp_lifetime_l1_cmd); - install_element (ISIS_NODE, &no_lsp_lifetime_l1_arg_cmd); - install_element (ISIS_NODE, &lsp_lifetime_l2_cmd); - install_element (ISIS_NODE, &no_lsp_lifetime_l2_cmd); - install_element (ISIS_NODE, &no_lsp_lifetime_l2_arg_cmd); + install_element (ISIS_NODE, &max_lsp_lifetime_cmd); + install_element (ISIS_NODE, &no_max_lsp_lifetime_cmd); + install_element (ISIS_NODE, &no_max_lsp_lifetime_arg_cmd); + install_element (ISIS_NODE, &max_lsp_lifetime_l1_cmd); + install_element (ISIS_NODE, &no_max_lsp_lifetime_l1_cmd); + install_element (ISIS_NODE, &no_max_lsp_lifetime_l1_arg_cmd); + install_element (ISIS_NODE, &max_lsp_lifetime_l2_cmd); + install_element (ISIS_NODE, &no_max_lsp_lifetime_l2_cmd); + install_element (ISIS_NODE, &no_max_lsp_lifetime_l2_arg_cmd); + + install_element (ISIS_NODE, &lsp_refresh_interval_cmd); + install_element (ISIS_NODE, &no_lsp_refresh_interval_cmd); + install_element (ISIS_NODE, &no_lsp_refresh_interval_arg_cmd); + install_element (ISIS_NODE, &lsp_refresh_interval_l1_cmd); + install_element (ISIS_NODE, &no_lsp_refresh_interval_l1_cmd); + install_element (ISIS_NODE, &no_lsp_refresh_interval_l1_arg_cmd); + install_element (ISIS_NODE, &lsp_refresh_interval_l2_cmd); + install_element (ISIS_NODE, &no_lsp_refresh_interval_l2_cmd); + install_element (ISIS_NODE, &no_lsp_refresh_interval_l2_arg_cmd); + + install_element (ISIS_NODE, &set_overload_bit_cmd); + install_element (ISIS_NODE, &no_set_overload_bit_cmd); install_element (ISIS_NODE, &dynamic_hostname_cmd); install_element (ISIS_NODE, &no_dynamic_hostname_cmd); install_element (ISIS_NODE, &metric_style_cmd); install_element (ISIS_NODE, &no_metric_style_cmd); + + install_element (ISIS_NODE, &log_adj_changes_cmd); + install_element (ISIS_NODE, &no_log_adj_changes_cmd); + #ifdef TOPOLOGY_GENERATE install_element (ISIS_NODE, &topology_generate_grid_cmd); install_element (ISIS_NODE, &topology_baseis_cmd); @@ -2218,9 +3226,4 @@ isis_init () install_element (VIEW_NODE, &show_isis_generated_topology_cmd); install_element (ENABLE_NODE, &show_isis_generated_topology_cmd); #endif /* TOPOLOGY_GENERATE */ - - isis_new (0); - isis_circuit_init (); - isis_zebra_init (); - isis_spf_cmds_init (); } -- cgit v1.2.1