1/*
2 * IS-IS Rout(e)ing protocol - isisd.c
3 *
4 * Copyright (C) 2001,2002   Sampo Saaristo
5 *                           Tampere University of Technology
6 *                           Institute of Communications Engineering
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public Licenseas published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16 * more details.
17
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "thread.h"
26#include "vty.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "time.h"
31#include "linklist.h"
32#include "if.h"
33#include "hash.h"
34#include "stream.h"
35#include "prefix.h"
36#include "table.h"
37
38#include "isisd/dict.h"
39#include "isisd/include-netbsd/iso.h"
40#include "isisd/isis_constants.h"
41#include "isisd/isis_common.h"
42#include "isisd/isis_flags.h"
43#include "isisd/isis_circuit.h"
44#include "isisd/isis_csm.h"
45#include "isisd/isisd.h"
46#include "isisd/isis_dynhn.h"
47#include "isisd/isis_adjacency.h"
48#include "isisd/isis_pdu.h"
49#include "isisd/isis_misc.h"
50#include "isisd/isis_constants.h"
51#include "isisd/isis_tlv.h"
52#include "isisd/isis_lsp.h"
53#include "isisd/isis_spf.h"
54#include "isisd/isis_route.h"
55#include "isisd/isis_zebra.h"
56#include "isisd/isis_events.h"
57
58#ifdef TOPOLOGY_GENERATE
59#include "spgrid.h"
60u_char DEFAULT_TOPOLOGY_BASEIS[6] = { 0xFE, 0xED, 0xFE, 0xED, 0x00, 0x00 };
61#endif /* TOPOLOGY_GENERATE */
62
63struct isis *isis = NULL;
64
65/*
66 * Prototypes.
67 */
68int isis_area_get(struct vty *, const char *);
69int isis_area_destroy(struct vty *, const char *);
70int area_net_title(struct vty *, const char *);
71int area_clear_net_title(struct vty *, const char *);
72int show_isis_interface_common(struct vty *, const char *ifname, char);
73int show_isis_neighbor_common(struct vty *, const char *id, char);
74int clear_isis_neighbor_common(struct vty *, const char *id);
75int isis_config_write(struct vty *);
76
77
78
79void
80isis_new (unsigned long process_id)
81{
82  isis = XCALLOC (MTYPE_ISIS, sizeof (struct isis));
83  /*
84   * Default values
85   */
86  isis->max_area_addrs = 3;
87  isis->process_id = process_id;
88  isis->router_id = 0;
89  isis->area_list = list_new ();
90  isis->init_circ_list = list_new ();
91  isis->uptime = time (NULL);
92  isis->nexthops = list_new ();
93#ifdef HAVE_IPV6
94  isis->nexthops6 = list_new ();
95#endif /* HAVE_IPV6 */
96  dyn_cache_init ();
97  /*
98   * uncomment the next line for full debugs
99   */
100  /* isis->debugs = 0xFFFF; */
101}
102
103struct isis_area *
104isis_area_create (const char *area_tag)
105{
106  struct isis_area *area;
107
108  area = XCALLOC (MTYPE_ISIS_AREA, sizeof (struct isis_area));
109
110  /*
111   * The first instance is level-1-2 rest are level-1, unless otherwise
112   * configured
113   */
114  if (listcount (isis->area_list) > 0)
115    area->is_type = IS_LEVEL_1;
116  else
117    area->is_type = IS_LEVEL_1_AND_2;
118
119  /*
120   * intialize the databases
121   */
122  if (area->is_type & IS_LEVEL_1)
123    {
124      area->lspdb[0] = lsp_db_init ();
125      area->route_table[0] = route_table_init ();
126#ifdef HAVE_IPV6
127      area->route_table6[0] = route_table_init ();
128#endif /* HAVE_IPV6 */
129    }
130  if (area->is_type & IS_LEVEL_2)
131    {
132      area->lspdb[1] = lsp_db_init ();
133      area->route_table[1] = route_table_init ();
134#ifdef HAVE_IPV6
135      area->route_table6[1] = route_table_init ();
136#endif /* HAVE_IPV6 */
137    }
138
139  spftree_area_init (area);
140
141  area->circuit_list = list_new ();
142  area->area_addrs = list_new ();
143  THREAD_TIMER_ON (master, area->t_tick, lsp_tick, area, 1);
144  flags_initialize (&area->flags);
145
146  /*
147   * Default values
148   */
149  area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME;	/* 1200 */
150  area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME;	/* 1200 */
151  area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL;	/* 900 */
152  area->lsp_refresh[1] = DEFAULT_MAX_LSP_GEN_INTERVAL;	/* 900 */
153  area->lsp_gen_interval[0] = DEFAULT_MIN_LSP_GEN_INTERVAL;
154  area->lsp_gen_interval[1] = DEFAULT_MIN_LSP_GEN_INTERVAL;
155  area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
156  area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
157  area->dynhostname = 1;
158  area->oldmetric = 0;
159  area->newmetric = 1;
160  area->lsp_frag_threshold = 90;
161#ifdef TOPOLOGY_GENERATE
162  memcpy (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS, ISIS_SYS_ID_LEN);
163#endif /* TOPOLOGY_GENERATE */
164
165  /* FIXME: Think of a better way... */
166  area->min_bcast_mtu = 1497;
167
168  area->area_tag = strdup (area_tag);
169  listnode_add (isis->area_list, area);
170  area->isis = isis;
171
172  return area;
173}
174
175struct isis_area *
176isis_area_lookup (const char *area_tag)
177{
178  struct isis_area *area;
179  struct listnode *node;
180
181  for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
182    if ((area->area_tag == NULL && area_tag == NULL) ||
183	(area->area_tag && area_tag
184	 && strcmp (area->area_tag, area_tag) == 0))
185    return area;
186
187  return NULL;
188}
189
190int
191isis_area_get (struct vty *vty, const char *area_tag)
192{
193  struct isis_area *area;
194
195  area = isis_area_lookup (area_tag);
196
197  if (area)
198    {
199      vty->node = ISIS_NODE;
200      vty->index = area;
201      return CMD_SUCCESS;
202    }
203
204  area = isis_area_create (area_tag);
205
206  if (isis->debugs & DEBUG_EVENTS)
207    zlog_debug ("New IS-IS area instance %s", area->area_tag);
208
209  vty->node = ISIS_NODE;
210  vty->index = area;
211
212  return CMD_SUCCESS;
213}
214
215int
216isis_area_destroy (struct vty *vty, const char *area_tag)
217{
218  struct isis_area *area;
219  struct listnode *node, *nnode;
220  struct isis_circuit *circuit;
221  struct area_addr *addr;
222
223  area = isis_area_lookup (area_tag);
224
225  if (area == NULL)
226    {
227      vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
228      return CMD_ERR_NO_MATCH;
229    }
230
231  if (area->circuit_list)
232    {
233      for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
234        {
235          circuit->ip_router = 0;
236#ifdef HAVE_IPV6
237          circuit->ipv6_router = 0;
238#endif
239          isis_csm_state_change (ISIS_DISABLE, circuit, area);
240        }
241      list_delete (area->circuit_list);
242      area->circuit_list = NULL;
243    }
244
245  if (area->lspdb[0] != NULL)
246    {
247      lsp_db_destroy (area->lspdb[0]);
248      area->lspdb[0] = NULL;
249    }
250  if (area->lspdb[1] != NULL)
251    {
252      lsp_db_destroy (area->lspdb[1]);
253      area->lspdb[1] = NULL;
254    }
255
256  spftree_area_del (area);
257
258  /* invalidate and validate would delete all routes from zebra */
259  isis_route_invalidate (area);
260  isis_route_validate (area);
261
262  if (area->route_table[0])
263    {
264      route_table_finish (area->route_table[0]);
265      area->route_table[0] = NULL;
266    }
267  if (area->route_table[1])
268    {
269      route_table_finish (area->route_table[1]);
270      area->route_table[1] = NULL;
271    }
272#ifdef HAVE_IPV6
273  if (area->route_table6[0])
274    {
275      route_table_finish (area->route_table6[0]);
276      area->route_table6[0] = NULL;
277    }
278  if (area->route_table6[1])
279    {
280      route_table_finish (area->route_table6[1]);
281      area->route_table6[1] = NULL;
282    }
283#endif /* HAVE_IPV6 */
284
285  for (ALL_LIST_ELEMENTS (area->area_addrs, node, nnode, addr))
286    {
287      list_delete_node (area->area_addrs, node);
288      XFREE (MTYPE_ISIS_AREA_ADDR, addr);
289    }
290  area->area_addrs = NULL;
291
292  THREAD_TIMER_OFF (area->t_tick);
293  THREAD_TIMER_OFF (area->t_lsp_refresh[0]);
294  THREAD_TIMER_OFF (area->t_lsp_refresh[1]);
295
296  thread_cancel_event (master, area);
297
298  listnode_delete (isis->area_list, area);
299
300  free (area->area_tag);
301
302  XFREE (MTYPE_ISIS_AREA, area);
303
304  if (listcount (isis->area_list) == 0)
305    {
306      memset (isis->sysid, 0, ISIS_SYS_ID_LEN);
307      isis->sysid_set = 0;
308    }
309
310  return CMD_SUCCESS;
311}
312
313int
314area_net_title (struct vty *vty, const char *net_title)
315{
316  struct isis_area *area;
317  struct area_addr *addr;
318  struct area_addr *addrp;
319  struct listnode *node;
320
321  u_char buff[255];
322  area = vty->index;
323
324  if (!area)
325    {
326      vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
327      return CMD_ERR_NO_MATCH;
328    }
329
330  /* We check that we are not over the maximal number of addresses */
331  if (listcount (area->area_addrs) >= isis->max_area_addrs)
332    {
333      vty_out (vty, "Maximum of area addresses (%d) already reached %s",
334	       isis->max_area_addrs, VTY_NEWLINE);
335      return CMD_ERR_NOTHING_TODO;
336    }
337
338  addr = XMALLOC (MTYPE_ISIS_AREA_ADDR, sizeof (struct area_addr));
339  addr->addr_len = dotformat2buff (buff, net_title);
340  memcpy (addr->area_addr, buff, addr->addr_len);
341#ifdef EXTREME_DEBUG
342  zlog_debug ("added area address %s for area %s (address length %d)",
343	     net_title, area->area_tag, addr->addr_len);
344#endif /* EXTREME_DEBUG */
345  if (addr->addr_len < 8 || addr->addr_len > 20)
346    {
347      vty_out (vty, "area address must be at least 8..20 octets long (%d)%s",
348               addr->addr_len, VTY_NEWLINE);
349      XFREE (MTYPE_ISIS_AREA_ADDR, addr);
350      return CMD_ERR_AMBIGUOUS;
351    }
352
353  if (addr->area_addr[addr->addr_len-1] != 0)
354    {
355      vty_out (vty, "nsel byte (last byte) in area address must be 0%s",
356               VTY_NEWLINE);
357      XFREE (MTYPE_ISIS_AREA_ADDR, addr);
358      return CMD_ERR_AMBIGUOUS;
359    }
360
361  if (isis->sysid_set == 0)
362    {
363      /*
364       * First area address - get the SystemID for this router
365       */
366      memcpy (isis->sysid, GETSYSID (addr), ISIS_SYS_ID_LEN);
367      isis->sysid_set = 1;
368      if (isis->debugs & DEBUG_EVENTS)
369	zlog_debug ("Router has SystemID %s", sysid_print (isis->sysid));
370    }
371  else
372    {
373      /*
374       * Check that the SystemID portions match
375       */
376      if (memcmp (isis->sysid, GETSYSID (addr), ISIS_SYS_ID_LEN))
377	{
378	  vty_out (vty,
379		   "System ID must not change when defining additional area"
380		   " addresses%s", VTY_NEWLINE);
381	  XFREE (MTYPE_ISIS_AREA_ADDR, addr);
382	  return CMD_ERR_AMBIGUOUS;
383	}
384
385      /* now we see that we don't already have this address */
386      for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp))
387	{
388	  if ((addrp->addr_len + ISIS_SYS_ID_LEN + ISIS_NSEL_LEN) != (addr->addr_len))
389	    continue;
390	  if (!memcmp (addrp->area_addr, addr->area_addr, addr->addr_len))
391	    {
392	      XFREE (MTYPE_ISIS_AREA_ADDR, addr);
393	      return CMD_SUCCESS;	/* silent fail */
394	    }
395	}
396    }
397
398  /*
399   * Forget the systemID part of the address
400   */
401  addr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
402  listnode_add (area->area_addrs, addr);
403
404  /* only now we can safely generate our LSPs for this area */
405  if (listcount (area->area_addrs) > 0)
406    {
407      if (area->is_type & IS_LEVEL_1)
408        lsp_generate (area, IS_LEVEL_1);
409      if (area->is_type & IS_LEVEL_2)
410        lsp_generate (area, IS_LEVEL_2);
411    }
412
413  return CMD_SUCCESS;
414}
415
416int
417area_clear_net_title (struct vty *vty, const char *net_title)
418{
419  struct isis_area *area;
420  struct area_addr addr, *addrp = NULL;
421  struct listnode *node;
422  u_char buff[255];
423
424  area = vty->index;
425  if (!area)
426    {
427      vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
428      return CMD_ERR_NO_MATCH;
429    }
430
431  addr.addr_len = dotformat2buff (buff, net_title);
432  if (addr.addr_len < 8 || addr.addr_len > 20)
433    {
434      vty_out (vty, "Unsupported area address length %d, should be 8...20 %s",
435	       addr.addr_len, VTY_NEWLINE);
436      return CMD_ERR_AMBIGUOUS;
437    }
438
439  memcpy (addr.area_addr, buff, (int) addr.addr_len);
440
441  for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp))
442    if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len &&
443	!memcmp (addrp->area_addr, addr.area_addr, addr.addr_len))
444    break;
445
446  if (!addrp)
447    {
448      vty_out (vty, "No area address %s for area %s %s", net_title,
449	       area->area_tag, VTY_NEWLINE);
450      return CMD_ERR_NO_MATCH;
451    }
452
453  listnode_delete (area->area_addrs, addrp);
454  XFREE (MTYPE_ISIS_AREA_ADDR, addrp);
455
456  /*
457   * Last area address - reset the SystemID for this router
458   */
459  if (listcount (area->area_addrs) == 0)
460    {
461      memset (isis->sysid, 0, ISIS_SYS_ID_LEN);
462      isis->sysid_set = 0;
463      if (isis->debugs & DEBUG_EVENTS)
464        zlog_debug ("Router has no SystemID");
465    }
466
467  return CMD_SUCCESS;
468}
469
470/*
471 * 'show isis interface' command
472 */
473
474int
475show_isis_interface_common (struct vty *vty, const char *ifname, char detail)
476{
477  struct listnode *anode, *cnode;
478  struct isis_area *area;
479  struct isis_circuit *circuit;
480
481  if (!isis)
482    {
483      vty_out (vty, "IS-IS Routing Process not enabled%s", VTY_NEWLINE);
484      return CMD_SUCCESS;
485    }
486
487  for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area))
488    {
489      vty_out (vty, "Area %s:%s", area->area_tag, VTY_NEWLINE);
490
491      if (detail == ISIS_UI_LEVEL_BRIEF)
492        vty_out (vty, "  Interface   CircId   State    Type     Level%s",
493                 VTY_NEWLINE);
494
495      for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit))
496        if (!ifname)
497          isis_circuit_print_vty (circuit, vty, detail);
498        else if (strcmp(circuit->interface->name, ifname) == 0)
499          isis_circuit_print_vty (circuit, vty, detail);
500    }
501
502  return CMD_SUCCESS;
503}
504
505DEFUN (show_isis_interface,
506       show_isis_interface_cmd,
507       "show isis interface",
508       SHOW_STR
509       "ISIS network information\n"
510       "ISIS interface\n")
511{
512  return show_isis_interface_common (vty, NULL, ISIS_UI_LEVEL_BRIEF);
513}
514
515DEFUN (show_isis_interface_detail,
516       show_isis_interface_detail_cmd,
517       "show isis interface detail",
518       SHOW_STR
519       "ISIS network information\n"
520       "ISIS interface\n"
521       "show detailed information\n")
522{
523  return show_isis_interface_common (vty, NULL, ISIS_UI_LEVEL_DETAIL);
524}
525
526DEFUN (show_isis_interface_arg,
527       show_isis_interface_arg_cmd,
528       "show isis interface WORD",
529       SHOW_STR
530       "ISIS network information\n"
531       "ISIS interface\n"
532       "ISIS interface name\n")
533{
534  return show_isis_interface_common (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
535}
536
537/*
538 * 'show isis neighbor' command
539 */
540
541int
542show_isis_neighbor_common (struct vty *vty, const char *id, char detail)
543{
544  struct listnode *anode, *cnode, *node;
545  struct isis_area *area;
546  struct isis_circuit *circuit;
547  struct list *adjdb;
548  struct isis_adjacency *adj;
549  struct isis_dynhn *dynhn;
550  u_char sysid[ISIS_SYS_ID_LEN];
551  int i;
552
553  if (!isis)
554    {
555      vty_out (vty, "IS-IS Routing Process not enabled%s", VTY_NEWLINE);
556      return CMD_SUCCESS;
557    }
558
559  memset (sysid, 0, ISIS_SYS_ID_LEN);
560  if (id)
561    {
562      if (sysid2buff (sysid, id) == 0)
563        {
564          dynhn = dynhn_find_by_name (id);
565          if (dynhn == NULL)
566            {
567              vty_out (vty, "Invalid system id %s%s", id, VTY_NEWLINE);
568              return CMD_SUCCESS;
569            }
570          memcpy (sysid, dynhn->id, ISIS_SYS_ID_LEN);
571        }
572    }
573
574  for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area))
575    {
576      vty_out (vty, "Area %s:%s", area->area_tag, VTY_NEWLINE);
577
578      if (detail == ISIS_UI_LEVEL_BRIEF)
579        vty_out (vty, "  System Id           Interface   L  State"
580                      "        Holdtime SNPA%s", VTY_NEWLINE);
581
582      for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit))
583        {
584          if (circuit->circ_type == CIRCUIT_T_BROADCAST)
585            {
586              for (i = 0; i < 2; i++)
587                {
588                  adjdb = circuit->u.bc.adjdb[i];
589                  if (adjdb && adjdb->count)
590                    {
591                      for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
592                        if (!id || !memcmp (adj->sysid, sysid,
593                                            ISIS_SYS_ID_LEN))
594                          isis_adj_print_vty (adj, vty, detail);
595                    }
596                }
597            }
598          else if (circuit->circ_type == CIRCUIT_T_P2P &&
599                   circuit->u.p2p.neighbor)
600            {
601              adj = circuit->u.p2p.neighbor;
602              if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN))
603                isis_adj_print_vty (adj, vty, detail);
604            }
605        }
606    }
607
608  return CMD_SUCCESS;
609}
610
611/*
612 * 'clear isis neighbor' command
613 */
614int
615clear_isis_neighbor_common (struct vty *vty, const char *id)
616{
617  struct listnode *anode, *cnode, *cnextnode, *node, *nnode;
618  struct isis_area *area;
619  struct isis_circuit *circuit;
620  struct list *adjdb;
621  struct isis_adjacency *adj;
622  struct isis_dynhn *dynhn;
623  u_char sysid[ISIS_SYS_ID_LEN];
624  int i;
625
626  if (!isis)
627    {
628      vty_out (vty, "IS-IS Routing Process not enabled%s", VTY_NEWLINE);
629      return CMD_SUCCESS;
630    }
631
632  memset (sysid, 0, ISIS_SYS_ID_LEN);
633  if (id)
634    {
635      if (sysid2buff (sysid, id) == 0)
636        {
637          dynhn = dynhn_find_by_name (id);
638          if (dynhn == NULL)
639            {
640              vty_out (vty, "Invalid system id %s%s", id, VTY_NEWLINE);
641              return CMD_SUCCESS;
642            }
643          memcpy (sysid, dynhn->id, ISIS_SYS_ID_LEN);
644        }
645    }
646
647  for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area))
648    {
649      for (ALL_LIST_ELEMENTS (area->circuit_list, cnode, cnextnode, circuit))
650        {
651          if (circuit->circ_type == CIRCUIT_T_BROADCAST)
652            {
653              for (i = 0; i < 2; i++)
654                {
655                  adjdb = circuit->u.bc.adjdb[i];
656                  if (adjdb && adjdb->count)
657                    {
658                      for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj))
659                        if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN))
660                          isis_adj_state_change (adj, ISIS_ADJ_DOWN,
661                                                 "clear user request");
662                    }
663                }
664            }
665          else if (circuit->circ_type == CIRCUIT_T_P2P &&
666                   circuit->u.p2p.neighbor)
667            {
668              adj = circuit->u.p2p.neighbor;
669              if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN))
670                isis_adj_state_change (adj, ISIS_ADJ_DOWN,
671                                       "clear user request");
672            }
673        }
674    }
675
676  return CMD_SUCCESS;
677}
678
679DEFUN (show_isis_neighbor,
680       show_isis_neighbor_cmd,
681       "show isis neighbor",
682       SHOW_STR
683       "ISIS network information\n"
684       "ISIS neighbor adjacencies\n")
685{
686  return show_isis_neighbor_common (vty, NULL, ISIS_UI_LEVEL_BRIEF);
687}
688
689DEFUN (show_isis_neighbor_detail,
690       show_isis_neighbor_detail_cmd,
691       "show isis neighbor detail",
692       SHOW_STR
693       "ISIS network information\n"
694       "ISIS neighbor adjacencies\n"
695       "show detailed information\n")
696{
697  return show_isis_neighbor_common (vty, NULL, ISIS_UI_LEVEL_DETAIL);
698}
699
700DEFUN (show_isis_neighbor_arg,
701       show_isis_neighbor_arg_cmd,
702       "show isis neighbor WORD",
703       SHOW_STR
704       "ISIS network information\n"
705       "ISIS neighbor adjacencies\n"
706       "System id\n")
707{
708  return show_isis_neighbor_common (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
709}
710
711DEFUN (clear_isis_neighbor,
712       clear_isis_neighbor_cmd,
713       "clear isis neighbor",
714       CLEAR_STR
715       "Reset ISIS network information\n"
716       "Reset ISIS neighbor adjacencies\n")
717{
718  return clear_isis_neighbor_common (vty, NULL);
719}
720
721DEFUN (clear_isis_neighbor_arg,
722       clear_isis_neighbor_arg_cmd,
723       "clear isis neighbor WORD",
724       CLEAR_STR
725       "ISIS network information\n"
726       "ISIS neighbor adjacencies\n"
727       "System id\n")
728{
729  return clear_isis_neighbor_common (vty, argv[0]);
730}
731
732/*
733 * 'isis debug', 'show debugging'
734 */
735void
736print_debug (struct vty *vty, int flags, int onoff)
737{
738  char onoffs[4];
739  if (onoff)
740    strcpy (onoffs, "on");
741  else
742    strcpy (onoffs, "off");
743
744  if (flags & DEBUG_ADJ_PACKETS)
745    vty_out (vty, "IS-IS Adjacency related packets debugging is %s%s", onoffs,
746	     VTY_NEWLINE);
747  if (flags & DEBUG_CHECKSUM_ERRORS)
748    vty_out (vty, "IS-IS checksum errors debugging is %s%s", onoffs,
749	     VTY_NEWLINE);
750  if (flags & DEBUG_LOCAL_UPDATES)
751    vty_out (vty, "IS-IS local updates debugging is %s%s", onoffs,
752	     VTY_NEWLINE);
753  if (flags & DEBUG_PROTOCOL_ERRORS)
754    vty_out (vty, "IS-IS protocol errors debugging is %s%s", onoffs,
755	     VTY_NEWLINE);
756  if (flags & DEBUG_SNP_PACKETS)
757    vty_out (vty, "IS-IS CSNP/PSNP packets debugging is %s%s", onoffs,
758	     VTY_NEWLINE);
759  if (flags & DEBUG_SPF_EVENTS)
760    vty_out (vty, "IS-IS SPF events debugging is %s%s", onoffs, VTY_NEWLINE);
761  if (flags & DEBUG_SPF_STATS)
762    vty_out (vty, "IS-IS SPF Timing and Statistics Data debugging is %s%s",
763	     onoffs, VTY_NEWLINE);
764  if (flags & DEBUG_SPF_TRIGGERS)
765    vty_out (vty, "IS-IS SPF triggering events debugging is %s%s", onoffs,
766	     VTY_NEWLINE);
767  if (flags & DEBUG_UPDATE_PACKETS)
768    vty_out (vty, "IS-IS Update related packet debugging is %s%s", onoffs,
769	     VTY_NEWLINE);
770  if (flags & DEBUG_RTE_EVENTS)
771    vty_out (vty, "IS-IS Route related debuggin is %s%s", onoffs,
772	     VTY_NEWLINE);
773  if (flags & DEBUG_EVENTS)
774    vty_out (vty, "IS-IS Event debugging is %s%s", onoffs, VTY_NEWLINE);
775  if (flags & DEBUG_PACKET_DUMP)
776    vty_out (vty, "IS-IS Packet dump debugging is %s%s", onoffs, VTY_NEWLINE);
777}
778
779DEFUN (show_debugging,
780       show_debugging_cmd,
781       "show debugging",
782       SHOW_STR
783       "State of each debugging option\n")
784{
785  vty_out (vty, "IS-IS:%s", VTY_NEWLINE);
786  print_debug (vty, isis->debugs, 1);
787  return CMD_SUCCESS;
788}
789
790/* Debug node. */
791static struct cmd_node debug_node = {
792  DEBUG_NODE,
793  "",
794  1
795};
796
797static int
798config_write_debug (struct vty *vty)
799{
800  int write = 0;
801  int flags = isis->debugs;
802
803  if (flags & DEBUG_ADJ_PACKETS)
804    {
805      vty_out (vty, "debug isis adj-packets%s", VTY_NEWLINE);
806      write++;
807    }
808  if (flags & DEBUG_CHECKSUM_ERRORS)
809    {
810      vty_out (vty, "debug isis checksum-errors%s", VTY_NEWLINE);
811      write++;
812    }
813  if (flags & DEBUG_LOCAL_UPDATES)
814    {
815      vty_out (vty, "debug isis local-updates%s", VTY_NEWLINE);
816      write++;
817    }
818  if (flags & DEBUG_PROTOCOL_ERRORS)
819    {
820      vty_out (vty, "debug isis protocol-errors%s", VTY_NEWLINE);
821      write++;
822    }
823  if (flags & DEBUG_SNP_PACKETS)
824    {
825      vty_out (vty, "debug isis snp-packets%s", VTY_NEWLINE);
826      write++;
827    }
828  if (flags & DEBUG_SPF_EVENTS)
829    {
830      vty_out (vty, "debug isis spf-events%s", VTY_NEWLINE);
831      write++;
832    }
833  if (flags & DEBUG_SPF_STATS)
834    {
835      vty_out (vty, "debug isis spf-statistics%s", VTY_NEWLINE);
836      write++;
837    }
838  if (flags & DEBUG_SPF_TRIGGERS)
839    {
840      vty_out (vty, "debug isis spf-triggers%s", VTY_NEWLINE);
841      write++;
842    }
843  if (flags & DEBUG_UPDATE_PACKETS)
844    {
845      vty_out (vty, "debug isis update-packets%s", VTY_NEWLINE);
846      write++;
847    }
848  if (flags & DEBUG_RTE_EVENTS)
849    {
850      vty_out (vty, "debug isis route-events%s", VTY_NEWLINE);
851      write++;
852    }
853  if (flags & DEBUG_EVENTS)
854    {
855      vty_out (vty, "debug isis events%s", VTY_NEWLINE);
856      write++;
857    }
858  if (flags & DEBUG_PACKET_DUMP)
859    {
860      vty_out (vty, "debug isis packet-dump%s", VTY_NEWLINE);
861      write++;
862    }
863
864  return write;
865}
866
867DEFUN (debug_isis_adj,
868       debug_isis_adj_cmd,
869       "debug isis adj-packets",
870       DEBUG_STR
871       "IS-IS information\n"
872       "IS-IS Adjacency related packets\n")
873{
874  isis->debugs |= DEBUG_ADJ_PACKETS;
875  print_debug (vty, DEBUG_ADJ_PACKETS, 1);
876
877  return CMD_SUCCESS;
878}
879
880DEFUN (no_debug_isis_adj,
881       no_debug_isis_adj_cmd,
882       "no debug isis adj-packets",
883       UNDEBUG_STR
884       "IS-IS information\n"
885       "IS-IS Adjacency related packets\n")
886{
887  isis->debugs &= ~DEBUG_ADJ_PACKETS;
888  print_debug (vty, DEBUG_ADJ_PACKETS, 0);
889
890  return CMD_SUCCESS;
891}
892
893DEFUN (debug_isis_csum,
894       debug_isis_csum_cmd,
895       "debug isis checksum-errors",
896       DEBUG_STR
897       "IS-IS information\n"
898       "IS-IS LSP checksum errors\n")
899{
900  isis->debugs |= DEBUG_CHECKSUM_ERRORS;
901  print_debug (vty, DEBUG_CHECKSUM_ERRORS, 1);
902
903  return CMD_SUCCESS;
904}
905
906DEFUN (no_debug_isis_csum,
907       no_debug_isis_csum_cmd,
908       "no debug isis checksum-errors",
909       UNDEBUG_STR
910       "IS-IS information\n"
911       "IS-IS LSP checksum errors\n")
912{
913  isis->debugs &= ~DEBUG_CHECKSUM_ERRORS;
914  print_debug (vty, DEBUG_CHECKSUM_ERRORS, 0);
915
916  return CMD_SUCCESS;
917}
918
919DEFUN (debug_isis_lupd,
920       debug_isis_lupd_cmd,
921       "debug isis local-updates",
922       DEBUG_STR
923       "IS-IS information\n"
924       "IS-IS local update packets\n")
925{
926  isis->debugs |= DEBUG_LOCAL_UPDATES;
927  print_debug (vty, DEBUG_LOCAL_UPDATES, 1);
928
929  return CMD_SUCCESS;
930}
931
932DEFUN (no_debug_isis_lupd,
933       no_debug_isis_lupd_cmd,
934       "no debug isis local-updates",
935       UNDEBUG_STR
936       "IS-IS information\n"
937       "IS-IS local update packets\n")
938{
939  isis->debugs &= ~DEBUG_LOCAL_UPDATES;
940  print_debug (vty, DEBUG_LOCAL_UPDATES, 0);
941
942  return CMD_SUCCESS;
943}
944
945DEFUN (debug_isis_err,
946       debug_isis_err_cmd,
947       "debug isis protocol-errors",
948       DEBUG_STR
949       "IS-IS information\n"
950       "IS-IS LSP protocol errors\n")
951{
952  isis->debugs |= DEBUG_PROTOCOL_ERRORS;
953  print_debug (vty, DEBUG_PROTOCOL_ERRORS, 1);
954
955  return CMD_SUCCESS;
956}
957
958DEFUN (no_debug_isis_err,
959       no_debug_isis_err_cmd,
960       "no debug isis protocol-errors",
961       UNDEBUG_STR
962       "IS-IS information\n"
963       "IS-IS LSP protocol errors\n")
964{
965  isis->debugs &= ~DEBUG_PROTOCOL_ERRORS;
966  print_debug (vty, DEBUG_PROTOCOL_ERRORS, 0);
967
968  return CMD_SUCCESS;
969}
970
971DEFUN (debug_isis_snp,
972       debug_isis_snp_cmd,
973       "debug isis snp-packets",
974       DEBUG_STR
975       "IS-IS information\n"
976       "IS-IS CSNP/PSNP packets\n")
977{
978  isis->debugs |= DEBUG_SNP_PACKETS;
979  print_debug (vty, DEBUG_SNP_PACKETS, 1);
980
981  return CMD_SUCCESS;
982}
983
984DEFUN (no_debug_isis_snp,
985       no_debug_isis_snp_cmd,
986       "no debug isis snp-packets",
987       UNDEBUG_STR
988       "IS-IS information\n"
989       "IS-IS CSNP/PSNP packets\n")
990{
991  isis->debugs &= ~DEBUG_SNP_PACKETS;
992  print_debug (vty, DEBUG_SNP_PACKETS, 0);
993
994  return CMD_SUCCESS;
995}
996
997DEFUN (debug_isis_upd,
998       debug_isis_upd_cmd,
999       "debug isis update-packets",
1000       DEBUG_STR
1001       "IS-IS information\n"
1002       "IS-IS Update related packets\n")
1003{
1004  isis->debugs |= DEBUG_UPDATE_PACKETS;
1005  print_debug (vty, DEBUG_UPDATE_PACKETS, 1);
1006
1007  return CMD_SUCCESS;
1008}
1009
1010DEFUN (no_debug_isis_upd,
1011       no_debug_isis_upd_cmd,
1012       "no debug isis update-packets",
1013       UNDEBUG_STR
1014       "IS-IS information\n"
1015       "IS-IS Update related packets\n")
1016{
1017  isis->debugs &= ~DEBUG_UPDATE_PACKETS;
1018  print_debug (vty, DEBUG_UPDATE_PACKETS, 0);
1019
1020  return CMD_SUCCESS;
1021}
1022
1023DEFUN (debug_isis_spfevents,
1024       debug_isis_spfevents_cmd,
1025       "debug isis spf-events",
1026       DEBUG_STR
1027       "IS-IS information\n"
1028       "IS-IS Shortest Path First Events\n")
1029{
1030  isis->debugs |= DEBUG_SPF_EVENTS;
1031  print_debug (vty, DEBUG_SPF_EVENTS, 1);
1032
1033  return CMD_SUCCESS;
1034}
1035
1036DEFUN (no_debug_isis_spfevents,
1037       no_debug_isis_spfevents_cmd,
1038       "no debug isis spf-events",
1039       UNDEBUG_STR
1040       "IS-IS information\n"
1041       "IS-IS Shortest Path First Events\n")
1042{
1043  isis->debugs &= ~DEBUG_SPF_EVENTS;
1044  print_debug (vty, DEBUG_SPF_EVENTS, 0);
1045
1046  return CMD_SUCCESS;
1047}
1048
1049DEFUN (debug_isis_spfstats,
1050       debug_isis_spfstats_cmd,
1051       "debug isis spf-statistics ",
1052       DEBUG_STR
1053       "IS-IS information\n"
1054       "IS-IS SPF Timing and Statistic Data\n")
1055{
1056  isis->debugs |= DEBUG_SPF_STATS;
1057  print_debug (vty, DEBUG_SPF_STATS, 1);
1058
1059  return CMD_SUCCESS;
1060}
1061
1062DEFUN (no_debug_isis_spfstats,
1063       no_debug_isis_spfstats_cmd,
1064       "no debug isis spf-statistics",
1065       UNDEBUG_STR
1066       "IS-IS information\n"
1067       "IS-IS SPF Timing and Statistic Data\n")
1068{
1069  isis->debugs &= ~DEBUG_SPF_STATS;
1070  print_debug (vty, DEBUG_SPF_STATS, 0);
1071
1072  return CMD_SUCCESS;
1073}
1074
1075DEFUN (debug_isis_spftrigg,
1076       debug_isis_spftrigg_cmd,
1077       "debug isis spf-triggers",
1078       DEBUG_STR
1079       "IS-IS information\n"
1080       "IS-IS SPF triggering events\n")
1081{
1082  isis->debugs |= DEBUG_SPF_TRIGGERS;
1083  print_debug (vty, DEBUG_SPF_TRIGGERS, 1);
1084
1085  return CMD_SUCCESS;
1086}
1087
1088DEFUN (no_debug_isis_spftrigg,
1089       no_debug_isis_spftrigg_cmd,
1090       "no debug isis spf-triggers",
1091       UNDEBUG_STR
1092       "IS-IS information\n"
1093       "IS-IS SPF triggering events\n")
1094{
1095  isis->debugs &= ~DEBUG_SPF_TRIGGERS;
1096  print_debug (vty, DEBUG_SPF_TRIGGERS, 0);
1097
1098  return CMD_SUCCESS;
1099}
1100
1101DEFUN (debug_isis_rtevents,
1102       debug_isis_rtevents_cmd,
1103       "debug isis route-events",
1104       DEBUG_STR
1105       "IS-IS information\n"
1106       "IS-IS Route related events\n")
1107{
1108  isis->debugs |= DEBUG_RTE_EVENTS;
1109  print_debug (vty, DEBUG_RTE_EVENTS, 1);
1110
1111  return CMD_SUCCESS;
1112}
1113
1114DEFUN (no_debug_isis_rtevents,
1115       no_debug_isis_rtevents_cmd,
1116       "no debug isis route-events",
1117       UNDEBUG_STR
1118       "IS-IS information\n"
1119       "IS-IS Route related events\n")
1120{
1121  isis->debugs &= ~DEBUG_RTE_EVENTS;
1122  print_debug (vty, DEBUG_RTE_EVENTS, 0);
1123
1124  return CMD_SUCCESS;
1125}
1126
1127DEFUN (debug_isis_events,
1128       debug_isis_events_cmd,
1129       "debug isis events",
1130       DEBUG_STR
1131       "IS-IS information\n"
1132       "IS-IS Events\n")
1133{
1134  isis->debugs |= DEBUG_EVENTS;
1135  print_debug (vty, DEBUG_EVENTS, 1);
1136
1137  return CMD_SUCCESS;
1138}
1139
1140DEFUN (no_debug_isis_events,
1141       no_debug_isis_events_cmd,
1142       "no debug isis events",
1143       UNDEBUG_STR
1144       "IS-IS information\n"
1145       "IS-IS Events\n")
1146{
1147  isis->debugs &= ~DEBUG_EVENTS;
1148  print_debug (vty, DEBUG_EVENTS, 0);
1149
1150  return CMD_SUCCESS;
1151}
1152
1153DEFUN (debug_isis_packet_dump,
1154       debug_isis_packet_dump_cmd,
1155       "debug isis packet-dump",
1156       DEBUG_STR
1157       "IS-IS information\n"
1158       "IS-IS packet dump\n")
1159{
1160  isis->debugs |= DEBUG_PACKET_DUMP;
1161  print_debug (vty, DEBUG_PACKET_DUMP, 1);
1162
1163  return CMD_SUCCESS;
1164}
1165
1166DEFUN (no_debug_isis_packet_dump,
1167       no_debug_isis_packet_dump_cmd,
1168       "no debug isis packet-dump",
1169       UNDEBUG_STR
1170       "IS-IS information\n"
1171       "IS-IS packet dump\n")
1172{
1173  isis->debugs &= ~DEBUG_PACKET_DUMP;
1174  print_debug (vty, DEBUG_PACKET_DUMP, 0);
1175
1176  return CMD_SUCCESS;
1177}
1178
1179DEFUN (show_hostname,
1180       show_hostname_cmd,
1181       "show isis hostname",
1182       SHOW_STR
1183       "IS-IS information\n"
1184       "IS-IS Dynamic hostname mapping\n")
1185{
1186  dynhn_print_all (vty);
1187
1188  return CMD_SUCCESS;
1189}
1190
1191static void
1192vty_out_timestr(struct vty *vty, time_t uptime)
1193{
1194  struct tm *tm;
1195  time_t difftime = time (NULL);
1196  difftime -= uptime;
1197  tm = gmtime (&difftime);
1198
1199#define ONE_DAY_SECOND 60*60*24
1200#define ONE_WEEK_SECOND 60*60*24*7
1201  if (difftime < ONE_DAY_SECOND)
1202    vty_out (vty,  "%02d:%02d:%02d",
1203        tm->tm_hour, tm->tm_min, tm->tm_sec);
1204  else if (difftime < ONE_WEEK_SECOND)
1205    vty_out (vty, "%dd%02dh%02dm",
1206        tm->tm_yday, tm->tm_hour, tm->tm_min);
1207  else
1208    vty_out (vty, "%02dw%dd%02dh",
1209        tm->tm_yday/7,
1210        tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1211  vty_out (vty, " ago");
1212}
1213
1214DEFUN (show_isis_summary,
1215       show_isis_summary_cmd,
1216       "show isis summary",
1217       SHOW_STR "IS-IS information\n" "IS-IS summary\n")
1218{
1219  struct listnode *node, *node2;
1220  struct isis_area *area;
1221  struct isis_spftree *spftree;
1222  int level;
1223
1224  if (isis == NULL)
1225  {
1226    vty_out (vty, "ISIS is not running%s", VTY_NEWLINE);
1227    return CMD_SUCCESS;
1228  }
1229
1230  vty_out (vty, "Process Id      : %ld%s", isis->process_id,
1231      VTY_NEWLINE);
1232  if (isis->sysid_set)
1233    vty_out (vty, "System Id       : %s%s", sysid_print (isis->sysid),
1234        VTY_NEWLINE);
1235
1236  vty_out (vty, "Up time         : ");
1237  vty_out_timestr(vty, isis->uptime);
1238  vty_out (vty, "%s", VTY_NEWLINE);
1239
1240  if (isis->area_list)
1241    vty_out (vty, "Number of areas : %d%s", isis->area_list->count,
1242        VTY_NEWLINE);
1243
1244  for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
1245  {
1246    vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null",
1247        VTY_NEWLINE);
1248
1249    if (listcount (area->area_addrs) > 0)
1250    {
1251      struct area_addr *area_addr;
1252      for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node2, area_addr))
1253      {
1254        vty_out (vty, "  Net: %s%s",
1255            isonet_print (area_addr->area_addr,
1256              area_addr->addr_len + ISIS_SYS_ID_LEN +
1257              1), VTY_NEWLINE);
1258      }
1259    }
1260
1261    for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++)
1262    {
1263      if ((area->is_type & level) == 0)
1264        continue;
1265
1266      vty_out (vty, "  Level-%d:%s", level, VTY_NEWLINE);
1267      spftree = area->spftree[level - 1];
1268      if (spftree->pending)
1269        vty_out (vty, "    IPv4 SPF: (pending)%s", VTY_NEWLINE);
1270      else
1271        vty_out (vty, "    IPv4 SPF:%s", VTY_NEWLINE);
1272
1273      vty_out (vty, "      minimum interval  : %d%s",
1274          area->min_spf_interval[level - 1], VTY_NEWLINE);
1275
1276      vty_out (vty, "      last run elapsed  : ");
1277      vty_out_timestr(vty, spftree->last_run_timestamp);
1278      vty_out (vty, "%s", VTY_NEWLINE);
1279
1280      vty_out (vty, "      last run duration : %u usec%s",
1281               (u_int32_t)spftree->last_run_duration, VTY_NEWLINE);
1282
1283      vty_out (vty, "      run count         : %d%s",
1284          spftree->runcount, VTY_NEWLINE);
1285
1286#ifdef HAVE_IPV6
1287      spftree = area->spftree6[level - 1];
1288      if (spftree->pending)
1289        vty_out (vty, "    IPv6 SPF: (pending)%s", VTY_NEWLINE);
1290      else
1291        vty_out (vty, "    IPv6 SPF:%s", VTY_NEWLINE);
1292
1293      vty_out (vty, "      minimum interval  : %d%s",
1294          area->min_spf_interval[level - 1], VTY_NEWLINE);
1295
1296      vty_out (vty, "      last run elapsed  : ");
1297      vty_out_timestr(vty, spftree->last_run_timestamp);
1298      vty_out (vty, "%s", VTY_NEWLINE);
1299
1300      vty_out (vty, "      last run duration : %u msec%s",
1301               spftree->last_run_duration, VTY_NEWLINE);
1302
1303      vty_out (vty, "      run count         : %d%s",
1304          spftree->runcount, VTY_NEWLINE);
1305#endif
1306    }
1307  }
1308  vty_out (vty, "%s", VTY_NEWLINE);
1309
1310  return CMD_SUCCESS;
1311}
1312
1313/*
1314 * This function supports following display options:
1315 * [ show isis database [detail] ]
1316 * [ show isis database <sysid> [detail] ]
1317 * [ show isis database <hostname> [detail] ]
1318 * [ show isis database <sysid>.<pseudo-id> [detail] ]
1319 * [ show isis database <hostname>.<pseudo-id> [detail] ]
1320 * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
1321 * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
1322 * [ show isis database detail <sysid> ]
1323 * [ show isis database detail <hostname> ]
1324 * [ show isis database detail <sysid>.<pseudo-id> ]
1325 * [ show isis database detail <hostname>.<pseudo-id> ]
1326 * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
1327 * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
1328 */
1329static int
1330show_isis_database (struct vty *vty, const char *argv, int ui_level)
1331{
1332  struct listnode *node;
1333  struct isis_area *area;
1334  struct isis_lsp *lsp;
1335  struct isis_dynhn *dynhn;
1336  const char *pos = argv;
1337  u_char lspid[ISIS_SYS_ID_LEN+2];
1338  char sysid[255];
1339  u_char number[3];
1340  int level, lsp_count;
1341
1342  if (isis->area_list->count == 0)
1343    return CMD_SUCCESS;
1344
1345  memset (&lspid, 0, ISIS_SYS_ID_LEN);
1346  memset (&sysid, 0, 255);
1347
1348  /*
1349   * extract fragment and pseudo id from the string argv
1350   * in the forms:
1351   * (a) <systemid/hostname>.<pseudo-id>-<framenent> or
1352   * (b) <systemid/hostname>.<pseudo-id> or
1353   * (c) <systemid/hostname> or
1354   * Where systemid is in the form:
1355   * xxxx.xxxx.xxxx
1356   */
1357  if (argv)
1358     strncpy (sysid, argv, 254);
1359  if (argv && strlen (argv) > 3)
1360    {
1361      pos = argv + strlen (argv) - 3;
1362      if (strncmp (pos, "-", 1) == 0)
1363      {
1364        memcpy (number, ++pos, 2);
1365        lspid[ISIS_SYS_ID_LEN+1] = (u_char) strtol ((char *)number, NULL, 16);
1366        pos -= 4;
1367        if (strncmp (pos, ".", 1) != 0)
1368          return CMD_ERR_AMBIGUOUS;
1369      }
1370      if (strncmp (pos, ".", 1) == 0)
1371      {
1372        memcpy (number, ++pos, 2);
1373        lspid[ISIS_SYS_ID_LEN] = (u_char) strtol ((char *)number, NULL, 16);
1374        sysid[pos - argv - 1] = '\0';
1375      }
1376    }
1377
1378  for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
1379    {
1380      vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null",
1381               VTY_NEWLINE);
1382
1383      for (level = 0; level < ISIS_LEVELS; level++)
1384        {
1385          if (area->lspdb[level] && dict_count (area->lspdb[level]) > 0)
1386            {
1387              lsp = NULL;
1388              if (argv != NULL)
1389                {
1390                  /*
1391                   * Try to find the lsp-id if the argv string is in
1392                   * the form hostname.<pseudo-id>-<fragment>
1393                   */
1394                  if (sysid2buff (lspid, sysid))
1395                    {
1396                      lsp = lsp_search (lspid, area->lspdb[level]);
1397                    }
1398                  else if ((dynhn = dynhn_find_by_name (sysid)))
1399                    {
1400                      memcpy (lspid, dynhn->id, ISIS_SYS_ID_LEN);
1401                      lsp = lsp_search (lspid, area->lspdb[level]);
1402                    }
1403                  else if (strncmp(unix_hostname (), sysid, 15) == 0)
1404                    {
1405                      memcpy (lspid, isis->sysid, ISIS_SYS_ID_LEN);
1406                      lsp = lsp_search (lspid, area->lspdb[level]);
1407                    }
1408                }
1409
1410              if (lsp != NULL || argv == NULL)
1411                {
1412                  vty_out (vty, "IS-IS Level-%d link-state database:%s",
1413                           level + 1, VTY_NEWLINE);
1414
1415                  /* print the title in all cases */
1416                  vty_out (vty, "LSP ID                  PduLen  "
1417                           "SeqNumber   Chksum  Holdtime  ATT/P/OL%s",
1418                           VTY_NEWLINE);
1419                }
1420
1421              if (lsp)
1422                {
1423                  if (ui_level == ISIS_UI_LEVEL_DETAIL)
1424                    lsp_print_detail (lsp, vty, area->dynhostname);
1425                  else
1426                    lsp_print (lsp, vty, area->dynhostname);
1427                }
1428              else if (argv == NULL)
1429                {
1430                  lsp_count = lsp_print_all (vty, area->lspdb[level],
1431                                             ui_level,
1432                                             area->dynhostname);
1433
1434                  vty_out (vty, "    %u LSPs%s%s",
1435                           lsp_count, VTY_NEWLINE, VTY_NEWLINE);
1436                }
1437            }
1438        }
1439    }
1440
1441  return CMD_SUCCESS;
1442}
1443
1444DEFUN (show_database_brief,
1445       show_database_cmd,
1446       "show isis database",
1447       SHOW_STR
1448       "IS-IS information\n"
1449       "IS-IS link state database\n")
1450{
1451  return show_isis_database (vty, NULL, ISIS_UI_LEVEL_BRIEF);
1452}
1453
1454DEFUN (show_database_lsp_brief,
1455       show_database_arg_cmd,
1456       "show isis database WORD",
1457       SHOW_STR
1458       "IS-IS information\n"
1459       "IS-IS link state database\n"
1460       "LSP ID\n")
1461{
1462  return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_BRIEF);
1463}
1464
1465DEFUN (show_database_lsp_detail,
1466       show_database_arg_detail_cmd,
1467       "show isis database WORD detail",
1468       SHOW_STR
1469       "IS-IS information\n"
1470       "IS-IS link state database\n"
1471       "LSP ID\n"
1472       "Detailed information\n")
1473{
1474  return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
1475}
1476
1477DEFUN (show_database_detail,
1478       show_database_detail_cmd,
1479       "show isis database detail",
1480       SHOW_STR
1481       "IS-IS information\n"
1482       "IS-IS link state database\n")
1483{
1484  return show_isis_database (vty, NULL, ISIS_UI_LEVEL_DETAIL);
1485}
1486
1487DEFUN (show_database_detail_lsp,
1488       show_database_detail_arg_cmd,
1489       "show isis database detail WORD",
1490       SHOW_STR
1491       "IS-IS information\n"
1492       "IS-IS link state database\n"
1493       "Detailed information\n"
1494       "LSP ID\n")
1495{
1496  return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
1497}
1498
1499/*
1500 * 'router isis' command
1501 */
1502DEFUN (router_isis,
1503       router_isis_cmd,
1504       "router isis WORD",
1505       ROUTER_STR
1506       "ISO IS-IS\n"
1507       "ISO Routing area tag")
1508{
1509  return isis_area_get (vty, argv[0]);
1510}
1511
1512/*
1513 *'no router isis' command
1514 */
1515DEFUN (no_router_isis,
1516       no_router_isis_cmd,
1517       "no router isis WORD",
1518       "no\n" ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag")
1519{
1520  return isis_area_destroy (vty, argv[0]);
1521}
1522
1523/*
1524 * 'net' command
1525 */
1526DEFUN (net,
1527       net_cmd,
1528       "net WORD",
1529       "A Network Entity Title for this process (OSI only)\n"
1530       "XX.XXXX. ... .XXX.XX  Network entity title (NET)\n")
1531{
1532  return area_net_title (vty, argv[0]);
1533}
1534
1535/*
1536 * 'no net' command
1537 */
1538DEFUN (no_net,
1539       no_net_cmd,
1540       "no net WORD",
1541       NO_STR
1542       "A Network Entity Title for this process (OSI only)\n"
1543       "XX.XXXX. ... .XXX.XX  Network entity title (NET)\n")
1544{
1545  return area_clear_net_title (vty, argv[0]);
1546}
1547
1548DEFUN (area_passwd_md5,
1549       area_passwd_md5_cmd,
1550       "area-password md5 WORD",
1551       "Configure the authentication password for an area\n"
1552       "Authentication type\n"
1553       "Area password\n")
1554{
1555  struct isis_area *area;
1556  int len;
1557
1558  area = vty->index;
1559
1560  if (!area)
1561    {
1562      vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE);
1563      return CMD_ERR_NO_MATCH;
1564    }
1565
1566  len = strlen (argv[0]);
1567  if (len > 254)
1568    {
1569      vty_out (vty, "Too long area password (>254)%s", VTY_NEWLINE);
1570      return CMD_ERR_AMBIGUOUS;
1571    }
1572
1573  area->area_passwd.len = (u_char) len;
1574  area->area_passwd.type = ISIS_PASSWD_TYPE_HMAC_MD5;
1575  strncpy ((char *)area->area_passwd.passwd, argv[0], 255);
1576
1577  if (argc > 1)
1578    {
1579      SET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND);
1580      if (strncmp(argv[1], "v", 1) == 0)
1581	SET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV);
1582      else
1583	UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV);
1584    }
1585  else
1586    {
1587      UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND);
1588      UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV);
1589    }
1590  lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1591
1592  return CMD_SUCCESS;
1593}
1594
1595ALIAS (area_passwd_md5,
1596       area_passwd_md5_snpauth_cmd,
1597       "area-password md5 WORD authenticate snp (send-only|validate)",
1598       "Configure the authentication password for an area\n"
1599       "Authentication type\n"
1600       "Area password\n"
1601       "Authentication\n"
1602       "SNP PDUs\n"
1603       "Send but do not check PDUs on receiving\n"
1604       "Send and check PDUs on receiving\n");
1605
1606DEFUN (area_passwd_clear,
1607       area_passwd_clear_cmd,
1608       "area-password clear WORD",
1609       "Configure the authentication password for an area\n"
1610       "Authentication type\n"
1611       "Area password\n")
1612{
1613  struct isis_area *area;
1614  int len;
1615
1616  area = vty->index;
1617
1618  if (!area)
1619    {
1620      vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE);
1621      return CMD_ERR_NO_MATCH;
1622    }
1623
1624  len = strlen (argv[0]);
1625  if (len > 254)
1626    {
1627      vty_out (vty, "Too long area password (>254)%s", VTY_NEWLINE);
1628      return CMD_ERR_AMBIGUOUS;
1629    }
1630
1631  area->area_passwd.len = (u_char) len;
1632  area->area_passwd.type = ISIS_PASSWD_TYPE_CLEARTXT;
1633  strncpy ((char *)area->area_passwd.passwd, argv[0], 255);
1634
1635  if (argc > 1)
1636    {
1637      SET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND);
1638      if (strncmp(argv[1], "v", 1) == 0)
1639	SET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV);
1640      else
1641	UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV);
1642    }
1643  else
1644    {
1645      UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND);
1646      UNSET_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV);
1647    }
1648  lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1649
1650  return CMD_SUCCESS;
1651}
1652
1653ALIAS (area_passwd_clear,
1654       area_passwd_clear_snpauth_cmd,
1655       "area-password clear WORD authenticate snp (send-only|validate)",
1656       "Configure the authentication password for an area\n"
1657       "Authentication type\n"
1658       "Area password\n"
1659       "Authentication\n"
1660       "SNP PDUs\n"
1661       "Send but do not check PDUs on receiving\n"
1662       "Send and check PDUs on receiving\n");
1663
1664DEFUN (no_area_passwd,
1665       no_area_passwd_cmd,
1666       "no area-password",
1667       NO_STR
1668       "Configure the authentication password for an area\n")
1669{
1670  struct isis_area *area;
1671
1672  area = vty->index;
1673
1674  if (!area)
1675    {
1676      vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE);
1677      return CMD_ERR_NO_MATCH;
1678    }
1679
1680  memset (&area->area_passwd, 0, sizeof (struct isis_passwd));
1681  lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1682
1683  return CMD_SUCCESS;
1684}
1685
1686DEFUN (domain_passwd_md5,
1687       domain_passwd_md5_cmd,
1688       "domain-password md5 WORD",
1689       "Set the authentication password for a routing domain\n"
1690       "Authentication type\n"
1691       "Routing domain password\n")
1692{
1693  struct isis_area *area;
1694  int len;
1695
1696  area = vty->index;
1697
1698  if (!area)
1699    {
1700      vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE);
1701      return CMD_ERR_NO_MATCH;
1702    }
1703
1704  len = strlen (argv[0]);
1705  if (len > 254)
1706    {
1707      vty_out (vty, "Too long area password (>254)%s", VTY_NEWLINE);
1708      return CMD_ERR_AMBIGUOUS;
1709    }
1710
1711  area->domain_passwd.len = (u_char) len;
1712  area->domain_passwd.type = ISIS_PASSWD_TYPE_HMAC_MD5;
1713  strncpy ((char *)area->domain_passwd.passwd, argv[0], 255);
1714
1715  if (argc > 1)
1716    {
1717      SET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND);
1718      if (strncmp(argv[1], "v", 1) == 0)
1719	SET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV);
1720      else
1721	UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV);
1722    }
1723  else
1724    {
1725      UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND);
1726      UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV);
1727    }
1728  lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1729
1730  return CMD_SUCCESS;
1731}
1732
1733ALIAS (domain_passwd_md5,
1734       domain_passwd_md5_snpauth_cmd,
1735       "domain-password md5 WORD authenticate snp (send-only|validate)",
1736       "Set the authentication password for a routing domain\n"
1737       "Authentication type\n"
1738       "Routing domain password\n"
1739       "Authentication\n"
1740       "SNP PDUs\n"
1741       "Send but do not check PDUs on receiving\n"
1742       "Send and check PDUs on receiving\n");
1743
1744DEFUN (domain_passwd_clear,
1745       domain_passwd_clear_cmd,
1746       "domain-password clear WORD",
1747       "Set the authentication password for a routing domain\n"
1748       "Authentication type\n"
1749       "Routing domain password\n")
1750{
1751  struct isis_area *area;
1752  int len;
1753
1754  area = vty->index;
1755
1756  if (!area)
1757    {
1758      vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE);
1759      return CMD_ERR_NO_MATCH;
1760    }
1761
1762  len = strlen (argv[0]);
1763  if (len > 254)
1764    {
1765      vty_out (vty, "Too long area password (>254)%s", VTY_NEWLINE);
1766      return CMD_ERR_AMBIGUOUS;
1767    }
1768
1769  area->domain_passwd.len = (u_char) len;
1770  area->domain_passwd.type = ISIS_PASSWD_TYPE_CLEARTXT;
1771  strncpy ((char *)area->domain_passwd.passwd, argv[0], 255);
1772
1773  if (argc > 1)
1774    {
1775      SET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND);
1776      if (strncmp(argv[1], "v", 1) == 0)
1777	SET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV);
1778      else
1779	UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV);
1780    }
1781  else
1782    {
1783      UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND);
1784      UNSET_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV);
1785    }
1786  lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1787
1788  return CMD_SUCCESS;
1789}
1790
1791ALIAS (domain_passwd_clear,
1792       domain_passwd_clear_snpauth_cmd,
1793       "domain-password clear WORD authenticate snp (send-only|validate)",
1794       "Set the authentication password for a routing domain\n"
1795       "Authentication type\n"
1796       "Routing domain password\n"
1797       "Authentication\n"
1798       "SNP PDUs\n"
1799       "Send but do not check PDUs on receiving\n"
1800       "Send and check PDUs on receiving\n");
1801
1802DEFUN (no_domain_passwd,
1803       no_domain_passwd_cmd,
1804       "no domain-password",
1805       NO_STR
1806       "Set the authentication password for a routing domain\n")
1807{
1808  struct isis_area *area;
1809
1810  area = vty->index;
1811
1812  if (!area)
1813    {
1814      vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE);
1815      return CMD_ERR_NO_MATCH;
1816    }
1817
1818  memset (&area->domain_passwd, 0, sizeof (struct isis_passwd));
1819  lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1820
1821  return CMD_SUCCESS;
1822}
1823
1824DEFUN (is_type,
1825       is_type_cmd,
1826       "is-type (level-1|level-1-2|level-2-only)",
1827       "IS Level for this routing process (OSI only)\n"
1828       "Act as a station router only\n"
1829       "Act as both a station router and an area router\n"
1830       "Act as an area router only\n")
1831{
1832  struct isis_area *area;
1833  int type;
1834
1835  area = vty->index;
1836
1837  if (!area)
1838    {
1839      vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE);
1840      return CMD_ERR_NO_MATCH;
1841    }
1842
1843  type = string2circuit_t (argv[0]);
1844  if (!type)
1845    {
1846      vty_out (vty, "Unknown IS level %s", VTY_NEWLINE);
1847      return CMD_SUCCESS;
1848    }
1849
1850  isis_event_system_type_change (area, type);
1851
1852  return CMD_SUCCESS;
1853}
1854
1855DEFUN (no_is_type,
1856       no_is_type_cmd,
1857       "no is-type (level-1|level-1-2|level-2-only)",
1858       NO_STR
1859       "IS Level for this routing process (OSI only)\n"
1860       "Act as a station router only\n"
1861       "Act as both a station router and an area router\n"
1862       "Act as an area router only\n")
1863{
1864  struct isis_area *area;
1865  int type;
1866
1867  area = vty->index;
1868  assert (area);
1869
1870  /*
1871   * Put the is-type back to defaults:
1872   * - level-1-2 on first area
1873   * - level-1 for the rest
1874   */
1875  if (listgetdata (listhead (isis->area_list)) == area)
1876    type = IS_LEVEL_1_AND_2;
1877  else
1878    type = IS_LEVEL_1;
1879
1880  isis_event_system_type_change (area, type);
1881
1882  return CMD_SUCCESS;
1883}
1884
1885static int
1886set_lsp_gen_interval (struct vty *vty, struct isis_area *area,
1887                      uint16_t interval, int level)
1888{
1889  int lvl;
1890
1891  for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl)
1892    {
1893      if (!(lvl & level))
1894        continue;
1895
1896      if (interval >= area->lsp_refresh[lvl-1])
1897        {
1898          vty_out (vty, "LSP gen interval %us must be less than "
1899                   "the LSP refresh interval %us%s",
1900                   interval, area->lsp_refresh[lvl-1], VTY_NEWLINE);
1901          return CMD_ERR_AMBIGUOUS;
1902        }
1903    }
1904
1905  for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl)
1906    {
1907      if (!(lvl & level))
1908        continue;
1909      area->lsp_gen_interval[lvl-1] = interval;
1910    }
1911
1912  return CMD_SUCCESS;
1913}
1914
1915DEFUN (lsp_gen_interval,
1916       lsp_gen_interval_cmd,
1917       "lsp-gen-interval <1-120>",
1918       "Minimum interval between regenerating same LSP\n"
1919       "Minimum interval in seconds\n")
1920{
1921  struct isis_area *area;
1922  uint16_t interval;
1923  int level;
1924
1925  area = vty->index;
1926  interval = atoi (argv[0]);
1927  level = IS_LEVEL_1 | IS_LEVEL_2;
1928  return set_lsp_gen_interval (vty, area, interval, level);
1929}
1930
1931DEFUN (no_lsp_gen_interval,
1932       no_lsp_gen_interval_cmd,
1933       "no lsp-gen-interval",
1934       NO_STR
1935       "Minimum interval between regenerating same LSP\n")
1936{
1937  struct isis_area *area;
1938  uint16_t interval;
1939  int level;
1940
1941  area = vty->index;
1942  interval = DEFAULT_MIN_LSP_GEN_INTERVAL;
1943  level = IS_LEVEL_1 | IS_LEVEL_2;
1944  return set_lsp_gen_interval (vty, area, interval, level);
1945}
1946
1947ALIAS (no_lsp_gen_interval,
1948       no_lsp_gen_interval_arg_cmd,
1949       "no lsp-gen-interval <1-120>",
1950       NO_STR
1951       "Minimum interval between regenerating same LSP\n"
1952       "Minimum interval in seconds\n")
1953
1954DEFUN (lsp_gen_interval_l1,
1955       lsp_gen_interval_l1_cmd,
1956       "lsp-gen-interval level-1 <1-120>",
1957       "Minimum interval between regenerating same LSP\n"
1958       "Set interval for level 1 only\n"
1959       "Minimum interval in seconds\n")
1960{
1961  struct isis_area *area;
1962  uint16_t interval;
1963  int level;
1964
1965  area = vty->index;
1966  interval = atoi (argv[0]);
1967  level = IS_LEVEL_1;
1968  return set_lsp_gen_interval (vty, area, interval, level);
1969}
1970
1971DEFUN (no_lsp_gen_interval_l1,
1972       no_lsp_gen_interval_l1_cmd,
1973       "no lsp-gen-interval level-1",
1974       NO_STR
1975       "Minimum interval between regenerating same LSP\n"
1976       "Set interval for level 1 only\n")
1977{
1978  struct isis_area *area;
1979  uint16_t interval;
1980  int level;
1981
1982  area = vty->index;
1983  interval = DEFAULT_MIN_LSP_GEN_INTERVAL;
1984  level = IS_LEVEL_1;
1985  return set_lsp_gen_interval (vty, area, interval, level);
1986}
1987
1988ALIAS (no_lsp_gen_interval_l1,
1989       no_lsp_gen_interval_l1_arg_cmd,
1990       "no lsp-gen-interval level-1 <1-120>",
1991       NO_STR
1992       "Minimum interval between regenerating same LSP\n"
1993       "Set interval for level 1 only\n"
1994       "Minimum interval in seconds\n")
1995
1996DEFUN (lsp_gen_interval_l2,
1997       lsp_gen_interval_l2_cmd,
1998       "lsp-gen-interval level-2 <1-120>",
1999       "Minimum interval between regenerating same LSP\n"
2000       "Set interval for level 2 only\n"
2001       "Minimum interval in seconds\n")
2002{
2003  struct isis_area *area;
2004  uint16_t interval;
2005  int level;
2006
2007  area = vty->index;
2008  interval = atoi (argv[0]);
2009  level = IS_LEVEL_2;
2010  return set_lsp_gen_interval (vty, area, interval, level);
2011}
2012
2013DEFUN (no_lsp_gen_interval_l2,
2014       no_lsp_gen_interval_l2_cmd,
2015       "no lsp-gen-interval level-2",
2016       NO_STR
2017       "Minimum interval between regenerating same LSP\n"
2018       "Set interval for level 2 only\n")
2019{
2020  struct isis_area *area;
2021  uint16_t interval;
2022  int level;
2023
2024  area = vty->index;
2025  interval = DEFAULT_MIN_LSP_GEN_INTERVAL;
2026  level = IS_LEVEL_2;
2027  return set_lsp_gen_interval (vty, area, interval, level);
2028}
2029
2030ALIAS (no_lsp_gen_interval_l2,
2031       no_lsp_gen_interval_l2_arg_cmd,
2032       "no lsp-gen-interval level-2 <1-120>",
2033       NO_STR
2034       "Minimum interval between regenerating same LSP\n"
2035       "Set interval for level 2 only\n"
2036       "Minimum interval in seconds\n")
2037
2038static int
2039validate_metric_style_narrow (struct vty *vty, struct isis_area *area)
2040{
2041  struct isis_circuit *circuit;
2042  struct listnode *node;
2043
2044  if (! vty)
2045    return CMD_ERR_AMBIGUOUS;
2046
2047  if (! area)
2048    {
2049      vty_out (vty, "ISIS area is invalid%s", VTY_NEWLINE);
2050      return CMD_ERR_AMBIGUOUS;
2051    }
2052
2053  for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
2054    {
2055      if ((area->is_type & IS_LEVEL_1) &&
2056          (circuit->is_type & IS_LEVEL_1) &&
2057          (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC))
2058        {
2059          vty_out (vty, "ISIS circuit %s metric is invalid%s",
2060                   circuit->interface->name, VTY_NEWLINE);
2061          return CMD_ERR_AMBIGUOUS;
2062        }
2063      if ((area->is_type & IS_LEVEL_2) &&
2064          (circuit->is_type & IS_LEVEL_2) &&
2065          (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC))
2066        {
2067          vty_out (vty, "ISIS circuit %s metric is invalid%s",
2068                   circuit->interface->name, VTY_NEWLINE);
2069          return CMD_ERR_AMBIGUOUS;
2070        }
2071    }
2072
2073  return CMD_SUCCESS;
2074}
2075
2076DEFUN (metric_style,
2077       metric_style_cmd,
2078       "metric-style (narrow|transition|wide)",
2079       "Use old-style (ISO 10589) or new-style packet formats\n"
2080       "Use old style of TLVs with narrow metric\n"
2081       "Send and accept both styles of TLVs during transition\n"
2082       "Use new style of TLVs to carry wider metric\n")
2083{
2084  struct isis_area *area;
2085  int ret;
2086
2087  area = vty->index;
2088  assert (area);
2089
2090  if (strncmp (argv[0], "w", 1) == 0)
2091    {
2092      area->newmetric = 1;
2093      area->oldmetric = 0;
2094    }
2095  else
2096    {
2097      ret = validate_metric_style_narrow (vty, area);
2098      if (ret != CMD_SUCCESS)
2099        return ret;
2100
2101      if (strncmp (argv[0], "t", 1) == 0)
2102	{
2103	  area->newmetric = 1;
2104	  area->oldmetric = 1;
2105	}
2106      else if (strncmp (argv[0], "n", 1) == 0)
2107	{
2108	  area->newmetric = 0;
2109	  area->oldmetric = 1;
2110	}
2111    }
2112
2113  return CMD_SUCCESS;
2114}
2115
2116DEFUN (no_metric_style,
2117       no_metric_style_cmd,
2118       "no metric-style",
2119       NO_STR
2120       "Use old-style (ISO 10589) or new-style packet formats\n")
2121{
2122  struct isis_area *area;
2123  int ret;
2124
2125  area = vty->index;
2126  assert (area);
2127
2128  ret = validate_metric_style_narrow (vty, area);
2129  if (ret != CMD_SUCCESS)
2130    return ret;
2131
2132  /* Default is narrow metric. */
2133  area->newmetric = 0;
2134  area->oldmetric = 1;
2135
2136  return CMD_SUCCESS;
2137}
2138
2139DEFUN (set_overload_bit,
2140       set_overload_bit_cmd,
2141       "set-overload-bit",
2142       "Set overload bit to avoid any transit traffic\n"
2143       "Set overload bit\n")
2144{
2145  struct isis_area *area;
2146
2147  area = vty->index;
2148  assert (area);
2149
2150  area->overload_bit = LSPBIT_OL;
2151  lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
2152
2153  return CMD_SUCCESS;
2154}
2155
2156DEFUN (no_set_overload_bit,
2157       no_set_overload_bit_cmd,
2158       "no set-overload-bit",
2159       "Reset overload bit to accept transit traffic\n"
2160       "Reset overload bit\n")
2161{
2162  struct isis_area *area;
2163
2164  area = vty->index;
2165  assert (area);
2166
2167  area->overload_bit = 0;
2168  lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
2169
2170  return CMD_SUCCESS;
2171}
2172
2173DEFUN (dynamic_hostname,
2174       dynamic_hostname_cmd,
2175       "hostname dynamic",
2176       "Dynamic hostname for IS-IS\n"
2177       "Dynamic hostname\n")
2178{
2179  struct isis_area *area;
2180
2181  area = vty->index;
2182  assert (area);
2183
2184  if (!area->dynhostname)
2185   {
2186     area->dynhostname = 1;
2187     lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0);
2188   }
2189
2190  return CMD_SUCCESS;
2191}
2192
2193DEFUN (no_dynamic_hostname,
2194       no_dynamic_hostname_cmd,
2195       "no hostname dynamic",
2196       NO_STR
2197       "Dynamic hostname for IS-IS\n"
2198       "Dynamic hostname\n")
2199{
2200  struct isis_area *area;
2201
2202  area = vty->index;
2203  assert (area);
2204
2205  if (area->dynhostname)
2206    {
2207      area->dynhostname = 0;
2208      lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0);
2209    }
2210
2211  return CMD_SUCCESS;
2212}
2213
2214DEFUN (spf_interval,
2215       spf_interval_cmd,
2216       "spf-interval <1-120>",
2217       "Minimum interval between SPF calculations\n"
2218       "Minimum interval between consecutive SPFs in seconds\n")
2219{
2220  struct isis_area *area;
2221  u_int16_t interval;
2222
2223  area = vty->index;
2224  interval = atoi (argv[0]);
2225  area->min_spf_interval[0] = interval;
2226  area->min_spf_interval[1] = interval;
2227
2228  return CMD_SUCCESS;
2229}
2230
2231DEFUN (no_spf_interval,
2232       no_spf_interval_cmd,
2233       "no spf-interval",
2234       NO_STR
2235       "Minimum interval between SPF calculations\n")
2236{
2237  struct isis_area *area;
2238
2239  area = vty->index;
2240
2241  area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
2242  area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
2243
2244  return CMD_SUCCESS;
2245}
2246
2247ALIAS (no_spf_interval,
2248       no_spf_interval_arg_cmd,
2249       "no spf-interval <1-120>",
2250       NO_STR
2251       "Minimum interval between SPF calculations\n"
2252       "Minimum interval between consecutive SPFs in seconds\n")
2253
2254DEFUN (spf_interval_l1,
2255       spf_interval_l1_cmd,
2256       "spf-interval level-1 <1-120>",
2257       "Minimum interval between SPF calculations\n"
2258       "Set interval for level 1 only\n"
2259       "Minimum interval between consecutive SPFs in seconds\n")
2260{
2261  struct isis_area *area;
2262  u_int16_t interval;
2263
2264  area = vty->index;
2265  interval = atoi (argv[0]);
2266  area->min_spf_interval[0] = interval;
2267
2268  return CMD_SUCCESS;
2269}
2270
2271DEFUN (no_spf_interval_l1,
2272       no_spf_interval_l1_cmd,
2273       "no spf-interval level-1",
2274       NO_STR
2275       "Minimum interval between SPF calculations\n"
2276       "Set interval for level 1 only\n")
2277{
2278  struct isis_area *area;
2279
2280  area = vty->index;
2281
2282  area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
2283
2284  return CMD_SUCCESS;
2285}
2286
2287ALIAS (no_spf_interval,
2288       no_spf_interval_l1_arg_cmd,
2289       "no spf-interval level-1 <1-120>",
2290       NO_STR
2291       "Minimum interval between SPF calculations\n"
2292       "Set interval for level 1 only\n"
2293       "Minimum interval between consecutive SPFs in seconds\n")
2294
2295DEFUN (spf_interval_l2,
2296       spf_interval_l2_cmd,
2297       "spf-interval level-2 <1-120>",
2298       "Minimum interval between SPF calculations\n"
2299       "Set interval for level 2 only\n"
2300       "Minimum interval between consecutive SPFs in seconds\n")
2301{
2302  struct isis_area *area;
2303  u_int16_t interval;
2304
2305  area = vty->index;
2306  interval = atoi (argv[0]);
2307  area->min_spf_interval[1] = interval;
2308
2309  return CMD_SUCCESS;
2310}
2311
2312DEFUN (no_spf_interval_l2,
2313       no_spf_interval_l2_cmd,
2314       "no spf-interval level-2",
2315       NO_STR
2316       "Minimum interval between SPF calculations\n"
2317       "Set interval for level 2 only\n")
2318{
2319  struct isis_area *area;
2320
2321  area = vty->index;
2322
2323  area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
2324
2325  return CMD_SUCCESS;
2326}
2327
2328ALIAS (no_spf_interval,
2329       no_spf_interval_l2_arg_cmd,
2330       "no spf-interval level-2 <1-120>",
2331       NO_STR
2332       "Minimum interval between SPF calculations\n"
2333       "Set interval for level 2 only\n"
2334       "Minimum interval between consecutive SPFs in seconds\n")
2335
2336static int
2337set_lsp_max_lifetime (struct vty *vty, struct isis_area *area,
2338                      uint16_t interval, int level)
2339{
2340  int lvl;
2341  int set_refresh_interval[ISIS_LEVELS] = {0, 0};
2342  uint16_t refresh_interval;
2343
2344  refresh_interval = interval - 300;
2345
2346  for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++)
2347    {
2348      if (!(lvl & level))
2349        continue;
2350      if (refresh_interval < area->lsp_refresh[lvl-1])
2351        {
2352          vty_out (vty, "Level %d Max LSP lifetime %us must be 300s greater than "
2353                   "the configured LSP refresh interval %us%s",
2354                   lvl, interval, area->lsp_refresh[lvl-1], VTY_NEWLINE);
2355          vty_out (vty, "Automatically reducing level %d LSP refresh interval "
2356                   "to %us%s", lvl, refresh_interval, VTY_NEWLINE);
2357          set_refresh_interval[lvl-1] = 1;
2358
2359          if (refresh_interval <= area->lsp_gen_interval[lvl-1])
2360            {
2361              vty_out (vty, "LSP refresh interval %us must be greater than "
2362                       "the configured LSP gen interval %us%s",
2363                       refresh_interval, area->lsp_gen_interval[lvl-1],
2364                       VTY_NEWLINE);
2365              return CMD_ERR_AMBIGUOUS;
2366            }
2367        }
2368    }
2369
2370  for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++)
2371    {
2372      if (!(lvl & level))
2373        continue;
2374      area->max_lsp_lifetime[lvl-1] = interval;
2375      /* Automatically reducing lsp_refresh_interval to interval - 300 */
2376      if (set_refresh_interval[lvl-1])
2377        area->lsp_refresh[lvl-1] = refresh_interval;
2378    }
2379
2380  lsp_regenerate_schedule (area, level, 1);
2381
2382  return CMD_SUCCESS;
2383}
2384
2385DEFUN (max_lsp_lifetime,
2386       max_lsp_lifetime_cmd,
2387       "max-lsp-lifetime <350-65535>",
2388       "Maximum LSP lifetime\n"
2389       "LSP lifetime in seconds\n")
2390{
2391  struct isis_area *area;
2392  uint16_t interval;
2393  int level;
2394
2395  area = vty->index;
2396  interval = atoi (argv[0]);
2397  level = IS_LEVEL_1 | IS_LEVEL_2;
2398  return set_lsp_max_lifetime (vty, area, interval, level);
2399}
2400
2401DEFUN (no_max_lsp_lifetime,
2402       no_max_lsp_lifetime_cmd,
2403       "no max-lsp-lifetime",
2404       NO_STR
2405       "LSP lifetime in seconds\n")
2406{
2407  struct isis_area *area;
2408  uint16_t interval;
2409  int level;
2410
2411  area = vty->index;
2412  interval = DEFAULT_LSP_LIFETIME;
2413  level = IS_LEVEL_1 | IS_LEVEL_2;
2414  return set_lsp_max_lifetime (vty, area, interval, level);
2415}
2416
2417ALIAS (no_max_lsp_lifetime,
2418       no_max_lsp_lifetime_arg_cmd,
2419       "no max-lsp-lifetime <350-65535>",
2420       NO_STR
2421       "Maximum LSP lifetime\n"
2422       "LSP lifetime in seconds\n")
2423
2424DEFUN (max_lsp_lifetime_l1,
2425       max_lsp_lifetime_l1_cmd,
2426       "max-lsp-lifetime level-1 <350-65535>",
2427       "Maximum LSP lifetime for Level 1 only\n"
2428       "LSP lifetime for Level 1 only in seconds\n")
2429{
2430  struct isis_area *area;
2431  uint16_t interval;
2432  int level;
2433
2434  area = vty->index;
2435  interval = atoi (argv[0]);
2436  level = IS_LEVEL_1;
2437  return set_lsp_max_lifetime (vty, area, interval, level);
2438}
2439
2440DEFUN (no_max_lsp_lifetime_l1,
2441       no_max_lsp_lifetime_l1_cmd,
2442       "no max-lsp-lifetime level-1",
2443       NO_STR
2444       "LSP lifetime for Level 1 only in seconds\n")
2445{
2446  struct isis_area *area;
2447  uint16_t interval;
2448  int level;
2449
2450  area = vty->index;
2451  interval = DEFAULT_LSP_LIFETIME;
2452  level = IS_LEVEL_1;
2453  return set_lsp_max_lifetime (vty, area, interval, level);
2454}
2455
2456ALIAS (no_max_lsp_lifetime_l1,
2457       no_max_lsp_lifetime_l1_arg_cmd,
2458       "no max-lsp-lifetime level-1 <350-65535>",
2459       NO_STR
2460       "Maximum LSP lifetime for Level 1 only\n"
2461       "LSP lifetime for Level 1 only in seconds\n")
2462
2463DEFUN (max_lsp_lifetime_l2,
2464       max_lsp_lifetime_l2_cmd,
2465       "max-lsp-lifetime level-2 <350-65535>",
2466       "Maximum LSP lifetime for Level 2 only\n"
2467       "LSP lifetime for Level 2 only in seconds\n")
2468{
2469  struct isis_area *area;
2470  uint16_t interval;
2471  int level;
2472
2473  area = vty->index;
2474  interval = atoi (argv[0]);
2475  level = IS_LEVEL_2;
2476  return set_lsp_max_lifetime (vty, area, interval, level);
2477}
2478
2479DEFUN (no_max_lsp_lifetime_l2,
2480       no_max_lsp_lifetime_l2_cmd,
2481       "no max-lsp-lifetime level-2",
2482       NO_STR
2483       "LSP lifetime for Level 2 only in seconds\n")
2484{
2485  struct isis_area *area;
2486  uint16_t interval;
2487  int level;
2488
2489  area = vty->index;
2490  interval = DEFAULT_LSP_LIFETIME;
2491  level = IS_LEVEL_2;
2492  return set_lsp_max_lifetime (vty, area, interval, level);
2493}
2494
2495ALIAS (no_max_lsp_lifetime_l2,
2496       no_max_lsp_lifetime_l2_arg_cmd,
2497       "no max-lsp-lifetime level-2 <350-65535>",
2498       NO_STR
2499       "Maximum LSP lifetime for Level 2 only\n"
2500       "LSP lifetime for Level 2 only in seconds\n")
2501
2502static int
2503set_lsp_refresh_interval (struct vty *vty, struct isis_area *area,
2504                          uint16_t interval, int level)
2505{
2506  int lvl;
2507
2508  for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl)
2509    {
2510      if (!(lvl & level))
2511        continue;
2512      if (interval <= area->lsp_gen_interval[lvl-1])
2513        {
2514          vty_out (vty, "LSP refresh interval %us must be greater than "
2515                   "the configured LSP gen interval %us%s",
2516                   interval, area->lsp_gen_interval[lvl-1],
2517                   VTY_NEWLINE);
2518          return CMD_ERR_AMBIGUOUS;
2519        }
2520      if (interval > (area->max_lsp_lifetime[lvl-1] - 300))
2521        {
2522          vty_out (vty, "LSP refresh interval %us must be less than "
2523                   "the configured LSP lifetime %us less 300%s",
2524                   interval, area->max_lsp_lifetime[lvl-1],
2525                   VTY_NEWLINE);
2526          return CMD_ERR_AMBIGUOUS;
2527        }
2528    }
2529
2530  for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl)
2531    {
2532      if (!(lvl & level))
2533        continue;
2534      area->lsp_refresh[lvl-1] = interval;
2535    }
2536  lsp_regenerate_schedule (area, level, 1);
2537
2538  return CMD_SUCCESS;
2539}
2540
2541DEFUN (lsp_refresh_interval,
2542       lsp_refresh_interval_cmd,
2543       "lsp-refresh-interval <1-65235>",
2544       "LSP refresh interval\n"
2545       "LSP refresh interval in seconds\n")
2546{
2547  struct isis_area *area;
2548  uint16_t interval;
2549  int level;
2550
2551  area = vty->index;
2552  interval = atoi (argv[0]);
2553  level = IS_LEVEL_1 | IS_LEVEL_2;
2554  return set_lsp_refresh_interval (vty, area, interval, level);
2555}
2556
2557DEFUN (no_lsp_refresh_interval,
2558       no_lsp_refresh_interval_cmd,
2559       "no lsp-refresh-interval",
2560       NO_STR
2561       "LSP refresh interval in seconds\n")
2562{
2563  struct isis_area *area;
2564  uint16_t interval;
2565  int level;
2566
2567  area = vty->index;
2568  interval = DEFAULT_MAX_LSP_GEN_INTERVAL;
2569  level = IS_LEVEL_1 | IS_LEVEL_2;
2570  return set_lsp_refresh_interval (vty, area, interval, level);
2571}
2572
2573ALIAS (no_lsp_refresh_interval,
2574       no_lsp_refresh_interval_arg_cmd,
2575       "no lsp-refresh-interval <1-65235>",
2576       NO_STR
2577       "LSP refresh interval\n"
2578       "LSP refresh interval in seconds\n")
2579
2580DEFUN (lsp_refresh_interval_l1,
2581       lsp_refresh_interval_l1_cmd,
2582       "lsp-refresh-interval level-1 <1-65235>",
2583       "LSP refresh interval for Level 1 only\n"
2584       "LSP refresh interval for Level 1 only in seconds\n")
2585{
2586  struct isis_area *area;
2587  uint16_t interval;
2588  int level;
2589
2590  area = vty->index;
2591  interval = atoi (argv[0]);
2592  level = IS_LEVEL_1;
2593  return set_lsp_refresh_interval (vty, area, interval, level);
2594}
2595
2596DEFUN (no_lsp_refresh_interval_l1,
2597       no_lsp_refresh_interval_l1_cmd,
2598       "no lsp-refresh-interval level-1",
2599       NO_STR
2600       "LSP refresh interval for Level 1 only in seconds\n")
2601{
2602  struct isis_area *area;
2603  uint16_t interval;
2604  int level;
2605
2606  area = vty->index;
2607  interval = DEFAULT_MAX_LSP_GEN_INTERVAL;
2608  level = IS_LEVEL_1;
2609  return set_lsp_refresh_interval (vty, area, interval, level);
2610}
2611
2612ALIAS (no_lsp_refresh_interval_l1,
2613       no_lsp_refresh_interval_l1_arg_cmd,
2614       "no lsp-refresh-interval level-1 <1-65235>",
2615       NO_STR
2616       "LSP refresh interval for Level 1 only\n"
2617       "LSP refresh interval for Level 1 only in seconds\n")
2618
2619DEFUN (lsp_refresh_interval_l2,
2620       lsp_refresh_interval_l2_cmd,
2621       "lsp-refresh-interval level-2 <1-65235>",
2622       "LSP refresh interval for Level 2 only\n"
2623       "LSP refresh interval for Level 2 only in seconds\n")
2624{
2625  struct isis_area *area;
2626  uint16_t interval;
2627  int level;
2628
2629  area = vty->index;
2630  interval = atoi (argv[0]);
2631  level = IS_LEVEL_2;
2632  return set_lsp_refresh_interval (vty, area, interval, level);
2633}
2634
2635DEFUN (no_lsp_refresh_interval_l2,
2636       no_lsp_refresh_interval_l2_cmd,
2637       "no lsp-refresh-interval level-2",
2638       NO_STR
2639       "LSP refresh interval for Level 2 only in seconds\n")
2640{
2641  struct isis_area *area;
2642  uint16_t interval;
2643  int level;
2644
2645  area = vty->index;
2646  interval = DEFAULT_MAX_LSP_GEN_INTERVAL;
2647  level = IS_LEVEL_2;
2648  return set_lsp_refresh_interval (vty, area, interval, level);
2649}
2650
2651ALIAS (no_lsp_refresh_interval_l2,
2652       no_lsp_refresh_interval_l2_arg_cmd,
2653       "no lsp-refresh-interval level-2 <1-65235>",
2654       NO_STR
2655       "LSP refresh interval for Level 2 only\n"
2656       "LSP refresh interval for Level 2 only in seconds\n")
2657
2658DEFUN (log_adj_changes,
2659       log_adj_changes_cmd,
2660       "log-adjacency-changes",
2661       "Log changes in adjacency state\n")
2662{
2663  struct isis_area *area;
2664
2665  area = vty->index;
2666  assert (area);
2667
2668  area->log_adj_changes = 1;
2669
2670  return CMD_SUCCESS;
2671}
2672
2673DEFUN (no_log_adj_changes,
2674       no_log_adj_changes_cmd,
2675       "no log-adjacency-changes",
2676       "Stop logging changes in adjacency state\n")
2677{
2678  struct isis_area *area;
2679
2680  area = vty->index;
2681  assert (area);
2682
2683  area->log_adj_changes = 0;
2684
2685  return CMD_SUCCESS;
2686}
2687
2688#ifdef TOPOLOGY_GENERATE
2689
2690DEFUN (topology_generate_grid,
2691       topology_generate_grid_cmd,
2692       "topology generate grid <1-100> <1-100> <1-65000> [param] [param] "
2693       "[param]",
2694       "Topology generation for IS-IS\n"
2695       "Topology generation\n"
2696       "Grid topology\n"
2697       "X parameter of the grid\n"
2698       "Y parameter of the grid\n"
2699       "Random seed\n"
2700       "Optional param 1\n"
2701       "Optional param 2\n"
2702       "Optional param 3\n"
2703       "Topology\n")
2704{
2705  struct isis_area *area;
2706
2707  area = vty->index;
2708  assert (area);
2709
2710  if (!spgrid_check_params (vty, argc, argv))
2711    {
2712      if (area->topology)
2713	list_delete (area->topology);
2714      area->topology = list_new ();
2715      memcpy (area->top_params, vty->buf, 200);
2716      gen_spgrid_topology (vty, area->topology);
2717      remove_topology_lsps (area);
2718      generate_topology_lsps (area);
2719      /* Regenerate L1 LSP to get two way connection to the generated
2720       * topology. */
2721      lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
2722    }
2723
2724  return CMD_SUCCESS;
2725}
2726
2727DEFUN (show_isis_generated_topology,
2728       show_isis_generated_topology_cmd,
2729       "show isis generated-topologies",
2730       SHOW_STR
2731       "ISIS network information\n"
2732       "Show generated topologies\n")
2733{
2734  struct isis_area *area;
2735  struct listnode *node;
2736  struct listnode *node2;
2737  struct arc *arc;
2738
2739  for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
2740    {
2741      if (!area->topology)
2742	continue;
2743
2744      vty_out (vty, "Topology for isis area: %s%s", area->area_tag,
2745	       VTY_NEWLINE);
2746      vty_out (vty, "From node     To node     Distance%s", VTY_NEWLINE);
2747
2748      for (ALL_LIST_ELEMENTS_RO (area->topology, node2, arc))
2749	vty_out (vty, "%9ld %11ld %12ld%s", arc->from_node, arc->to_node,
2750		 arc->distance, VTY_NEWLINE);
2751    }
2752  return CMD_SUCCESS;
2753}
2754
2755/* Base IS for topology generation. */
2756DEFUN (topology_baseis,
2757       topology_baseis_cmd,
2758       "topology base-is WORD",
2759       "Topology generation for IS-IS\n"
2760       "A Network IS Base for this topology\n"
2761       "XXXX.XXXX.XXXX Network entity title (NET)\n")
2762{
2763  struct isis_area *area;
2764  u_char buff[ISIS_SYS_ID_LEN];
2765
2766  area = vty->index;
2767  assert (area);
2768
2769  if (sysid2buff (buff, argv[0]))
2770    sysid2buff (area->topology_baseis, argv[0]);
2771
2772  return CMD_SUCCESS;
2773}
2774
2775DEFUN (no_topology_baseis,
2776       no_topology_baseis_cmd,
2777       "no topology base-is WORD",
2778       NO_STR
2779       "Topology generation for IS-IS\n"
2780       "A Network IS Base for this topology\n"
2781       "XXXX.XXXX.XXXX Network entity title (NET)\n")
2782{
2783  struct isis_area *area;
2784
2785  area = vty->index;
2786  assert (area);
2787
2788  memcpy (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS, ISIS_SYS_ID_LEN);
2789  return CMD_SUCCESS;
2790}
2791
2792ALIAS (no_topology_baseis,
2793       no_topology_baseis_noid_cmd,
2794       "no topology base-is",
2795       NO_STR
2796       "Topology generation for IS-IS\n"
2797       "A Network IS Base for this topology\n")
2798
2799DEFUN (topology_basedynh,
2800       topology_basedynh_cmd,
2801       "topology base-dynh WORD",
2802       "Topology generation for IS-IS\n"
2803       "Dynamic hostname base for this topology\n"
2804       "Dynamic hostname base\n")
2805{
2806  struct isis_area *area;
2807
2808  area = vty->index;
2809  assert (area);
2810
2811  /* I hope that it's enough. */
2812  area->topology_basedynh = strndup (argv[0], 16);
2813  return CMD_SUCCESS;
2814}
2815
2816#endif /* TOPOLOGY_GENERATE */
2817
2818/* IS-IS configuration write function */
2819int
2820isis_config_write (struct vty *vty)
2821{
2822  int write = 0;
2823
2824  if (isis != NULL)
2825    {
2826      struct isis_area *area;
2827      struct listnode *node, *node2;
2828
2829      for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
2830      {
2831	/* ISIS - Area name */
2832	vty_out (vty, "router isis %s%s", area->area_tag, VTY_NEWLINE);
2833	write++;
2834	/* ISIS - Net */
2835	if (listcount (area->area_addrs) > 0)
2836	  {
2837	    struct area_addr *area_addr;
2838	    for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node2, area_addr))
2839	      {
2840		vty_out (vty, " net %s%s",
2841			 isonet_print (area_addr->area_addr,
2842				       area_addr->addr_len + ISIS_SYS_ID_LEN +
2843				       1), VTY_NEWLINE);
2844		write++;
2845	      }
2846	  }
2847	/* ISIS - Dynamic hostname - Defaults to true so only display if
2848	 * false. */
2849	if (!area->dynhostname)
2850	  {
2851	    vty_out (vty, " no hostname dynamic%s", VTY_NEWLINE);
2852	    write++;
2853	  }
2854	/* ISIS - Metric-Style - when true displays wide */
2855	if (area->newmetric)
2856	  {
2857	    if (!area->oldmetric)
2858	      vty_out (vty, " metric-style wide%s", VTY_NEWLINE);
2859	    else
2860	      vty_out (vty, " metric-style transition%s", VTY_NEWLINE);
2861	    write++;
2862	  }
2863	else
2864	  {
2865	    vty_out (vty, " metric-style narrow%s", VTY_NEWLINE);
2866	    write++;
2867	  }
2868	/* ISIS - overload-bit */
2869	if (area->overload_bit)
2870	  {
2871	    vty_out (vty, " set-overload-bit%s", VTY_NEWLINE);
2872	    write++;
2873	  }
2874	/* ISIS - Area is-type (level-1-2 is default) */
2875	if (area->is_type == IS_LEVEL_1)
2876	  {
2877	    vty_out (vty, " is-type level-1%s", VTY_NEWLINE);
2878	    write++;
2879	  }
2880	else if (area->is_type == IS_LEVEL_2)
2881	  {
2882	    vty_out (vty, " is-type level-2-only%s", VTY_NEWLINE);
2883	    write++;
2884	  }
2885	/* ISIS - Lsp generation interval */
2886	if (area->lsp_gen_interval[0] == area->lsp_gen_interval[1])
2887	  {
2888	    if (area->lsp_gen_interval[0] != DEFAULT_MIN_LSP_GEN_INTERVAL)
2889	      {
2890		vty_out (vty, " lsp-gen-interval %d%s",
2891			 area->lsp_gen_interval[0], VTY_NEWLINE);
2892		write++;
2893	      }
2894	  }
2895	else
2896	  {
2897	    if (area->lsp_gen_interval[0] != DEFAULT_MIN_LSP_GEN_INTERVAL)
2898	      {
2899		vty_out (vty, " lsp-gen-interval level-1 %d%s",
2900			 area->lsp_gen_interval[0], VTY_NEWLINE);
2901		write++;
2902	      }
2903	    if (area->lsp_gen_interval[1] != DEFAULT_MIN_LSP_GEN_INTERVAL)
2904	      {
2905		vty_out (vty, " lsp-gen-interval level-2 %d%s",
2906			 area->lsp_gen_interval[1], VTY_NEWLINE);
2907		write++;
2908	      }
2909	  }
2910	/* ISIS - LSP lifetime */
2911	if (area->max_lsp_lifetime[0] == area->max_lsp_lifetime[1])
2912	  {
2913	    if (area->max_lsp_lifetime[0] != DEFAULT_LSP_LIFETIME)
2914	      {
2915		vty_out (vty, " max-lsp-lifetime %u%s", area->max_lsp_lifetime[0],
2916			 VTY_NEWLINE);
2917		write++;
2918	      }
2919	  }
2920	else
2921	  {
2922	    if (area->max_lsp_lifetime[0] != DEFAULT_LSP_LIFETIME)
2923	      {
2924		vty_out (vty, " max-lsp-lifetime level-1 %u%s",
2925			 area->max_lsp_lifetime[0], VTY_NEWLINE);
2926		write++;
2927	      }
2928	    if (area->max_lsp_lifetime[1] != DEFAULT_LSP_LIFETIME)
2929	      {
2930		vty_out (vty, " max-lsp-lifetime level-2 %u%s",
2931			 area->max_lsp_lifetime[1], VTY_NEWLINE);
2932		write++;
2933	      }
2934	  }
2935	/* ISIS - LSP refresh interval */
2936	if (area->lsp_refresh[0] == area->lsp_refresh[1])
2937	  {
2938	    if (area->lsp_refresh[0] != DEFAULT_MAX_LSP_GEN_INTERVAL)
2939	      {
2940		vty_out (vty, " lsp-refresh-interval %u%s", area->lsp_refresh[0],
2941			 VTY_NEWLINE);
2942		write++;
2943	      }
2944	  }
2945	else
2946	  {
2947	    if (area->lsp_refresh[0] != DEFAULT_MAX_LSP_GEN_INTERVAL)
2948	      {
2949		vty_out (vty, " lsp-refresh-interval level-1 %u%s",
2950			 area->lsp_refresh[0], VTY_NEWLINE);
2951		write++;
2952	      }
2953	    if (area->lsp_refresh[1] != DEFAULT_MAX_LSP_GEN_INTERVAL)
2954	      {
2955		vty_out (vty, " lsp-refresh-interval level-2 %u%s",
2956			 area->lsp_refresh[1], VTY_NEWLINE);
2957		write++;
2958	      }
2959	  }
2960	/* Minimum SPF interval. */
2961	if (area->min_spf_interval[0] == area->min_spf_interval[1])
2962	  {
2963	    if (area->min_spf_interval[0] != MINIMUM_SPF_INTERVAL)
2964	      {
2965		vty_out (vty, " spf-interval %d%s",
2966			 area->min_spf_interval[0], VTY_NEWLINE);
2967		write++;
2968	      }
2969	  }
2970	else
2971	  {
2972	    if (area->min_spf_interval[0] != MINIMUM_SPF_INTERVAL)
2973	      {
2974		vty_out (vty, " spf-interval level-1 %d%s",
2975			 area->min_spf_interval[0], VTY_NEWLINE);
2976		write++;
2977	      }
2978	    if (area->min_spf_interval[1] != MINIMUM_SPF_INTERVAL)
2979	      {
2980		vty_out (vty, " spf-interval level-2 %d%s",
2981			 area->min_spf_interval[1], VTY_NEWLINE);
2982		write++;
2983	      }
2984	  }
2985	/* Authentication passwords. */
2986	if (area->area_passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5)
2987	  {
2988	    vty_out(vty, " area-password md5 %s", area->area_passwd.passwd);
2989	    if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND))
2990	      {
2991		vty_out(vty, " authenticate snp ");
2992		if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV))
2993		  vty_out(vty, "validate");
2994		else
2995		  vty_out(vty, "send-only");
2996	      }
2997	    vty_out(vty, "%s", VTY_NEWLINE);
2998	    write++;
2999	  }
3000        else if (area->area_passwd.type == ISIS_PASSWD_TYPE_CLEARTXT)
3001          {
3002	    vty_out(vty, " area-password clear %s", area->area_passwd.passwd);
3003	    if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND))
3004	      {
3005		vty_out(vty, " authenticate snp ");
3006		if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV))
3007		  vty_out(vty, "validate");
3008		else
3009		  vty_out(vty, "send-only");
3010	      }
3011	    vty_out(vty, "%s", VTY_NEWLINE);
3012	    write++;
3013          }
3014	if (area->domain_passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5)
3015	  {
3016            vty_out(vty, " domain-password md5 %s",
3017                    area->domain_passwd.passwd);
3018	    if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND))
3019	      {
3020		vty_out(vty, " authenticate snp ");
3021		if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV))
3022		  vty_out(vty, "validate");
3023		else
3024		  vty_out(vty, "send-only");
3025	      }
3026	    vty_out(vty, "%s", VTY_NEWLINE);
3027	    write++;
3028	  }
3029        else if (area->domain_passwd.type == ISIS_PASSWD_TYPE_CLEARTXT)
3030	  {
3031	    vty_out(vty, " domain-password clear %s",
3032                    area->domain_passwd.passwd);
3033	    if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND))
3034	      {
3035		vty_out(vty, " authenticate snp ");
3036		if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV))
3037		  vty_out(vty, "validate");
3038		else
3039		  vty_out(vty, "send-only");
3040	      }
3041	    vty_out(vty, "%s", VTY_NEWLINE);
3042	    write++;
3043	  }
3044
3045	if (area->log_adj_changes)
3046	  {
3047	    vty_out (vty, " log-adjacency-changes%s", VTY_NEWLINE);
3048	    write++;
3049	  }
3050
3051#ifdef TOPOLOGY_GENERATE
3052	if (memcmp (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS,
3053		    ISIS_SYS_ID_LEN))
3054	  {
3055	    vty_out (vty, " topology base-is %s%s",
3056		     sysid_print ((u_char *)area->topology_baseis), VTY_NEWLINE);
3057	    write++;
3058	  }
3059	if (area->topology_basedynh)
3060	  {
3061	    vty_out (vty, " topology base-dynh %s%s",
3062		     area->topology_basedynh, VTY_NEWLINE);
3063	    write++;
3064	  }
3065	/* We save the whole command line here. */
3066	if (strlen(area->top_params))
3067	  {
3068	    vty_out (vty, " %s%s", area->top_params, VTY_NEWLINE);
3069	    write++;
3070	  }
3071#endif /* TOPOLOGY_GENERATE */
3072
3073      }
3074    }
3075
3076  return write;
3077}
3078
3079struct cmd_node isis_node = {
3080  ISIS_NODE,
3081  "%s(config-router)# ",
3082  1
3083};
3084
3085void
3086isis_init ()
3087{
3088  /* Install IS-IS top node */
3089  install_node (&isis_node, isis_config_write);
3090
3091  install_element (VIEW_NODE, &show_isis_summary_cmd);
3092
3093  install_element (VIEW_NODE, &show_isis_interface_cmd);
3094  install_element (VIEW_NODE, &show_isis_interface_detail_cmd);
3095  install_element (VIEW_NODE, &show_isis_interface_arg_cmd);
3096
3097  install_element (VIEW_NODE, &show_isis_neighbor_cmd);
3098  install_element (VIEW_NODE, &show_isis_neighbor_detail_cmd);
3099  install_element (VIEW_NODE, &show_isis_neighbor_arg_cmd);
3100  install_element (VIEW_NODE, &clear_isis_neighbor_cmd);
3101  install_element (VIEW_NODE, &clear_isis_neighbor_arg_cmd);
3102
3103  install_element (VIEW_NODE, &show_hostname_cmd);
3104  install_element (VIEW_NODE, &show_database_cmd);
3105  install_element (VIEW_NODE, &show_database_arg_cmd);
3106  install_element (VIEW_NODE, &show_database_arg_detail_cmd);
3107  install_element (VIEW_NODE, &show_database_detail_cmd);
3108  install_element (VIEW_NODE, &show_database_detail_arg_cmd);
3109
3110  install_element (ENABLE_NODE, &show_isis_summary_cmd);
3111
3112  install_element (ENABLE_NODE, &show_isis_interface_cmd);
3113  install_element (ENABLE_NODE, &show_isis_interface_detail_cmd);
3114  install_element (ENABLE_NODE, &show_isis_interface_arg_cmd);
3115
3116  install_element (ENABLE_NODE, &show_isis_neighbor_cmd);
3117  install_element (ENABLE_NODE, &show_isis_neighbor_detail_cmd);
3118  install_element (ENABLE_NODE, &show_isis_neighbor_arg_cmd);
3119  install_element (ENABLE_NODE, &clear_isis_neighbor_cmd);
3120  install_element (ENABLE_NODE, &clear_isis_neighbor_arg_cmd);
3121
3122  install_element (ENABLE_NODE, &show_hostname_cmd);
3123  install_element (ENABLE_NODE, &show_database_cmd);
3124  install_element (ENABLE_NODE, &show_database_arg_cmd);
3125  install_element (ENABLE_NODE, &show_database_arg_detail_cmd);
3126  install_element (ENABLE_NODE, &show_database_detail_cmd);
3127  install_element (ENABLE_NODE, &show_database_detail_arg_cmd);
3128  install_element (ENABLE_NODE, &show_debugging_cmd);
3129
3130  install_node (&debug_node, config_write_debug);
3131
3132  install_element (ENABLE_NODE, &debug_isis_adj_cmd);
3133  install_element (ENABLE_NODE, &no_debug_isis_adj_cmd);
3134  install_element (ENABLE_NODE, &debug_isis_csum_cmd);
3135  install_element (ENABLE_NODE, &no_debug_isis_csum_cmd);
3136  install_element (ENABLE_NODE, &debug_isis_lupd_cmd);
3137  install_element (ENABLE_NODE, &no_debug_isis_lupd_cmd);
3138  install_element (ENABLE_NODE, &debug_isis_err_cmd);
3139  install_element (ENABLE_NODE, &no_debug_isis_err_cmd);
3140  install_element (ENABLE_NODE, &debug_isis_snp_cmd);
3141  install_element (ENABLE_NODE, &no_debug_isis_snp_cmd);
3142  install_element (ENABLE_NODE, &debug_isis_upd_cmd);
3143  install_element (ENABLE_NODE, &no_debug_isis_upd_cmd);
3144  install_element (ENABLE_NODE, &debug_isis_spfevents_cmd);
3145  install_element (ENABLE_NODE, &no_debug_isis_spfevents_cmd);
3146  install_element (ENABLE_NODE, &debug_isis_spfstats_cmd);
3147  install_element (ENABLE_NODE, &no_debug_isis_spfstats_cmd);
3148  install_element (ENABLE_NODE, &debug_isis_spftrigg_cmd);
3149  install_element (ENABLE_NODE, &no_debug_isis_spftrigg_cmd);
3150  install_element (ENABLE_NODE, &debug_isis_rtevents_cmd);
3151  install_element (ENABLE_NODE, &no_debug_isis_rtevents_cmd);
3152  install_element (ENABLE_NODE, &debug_isis_events_cmd);
3153  install_element (ENABLE_NODE, &no_debug_isis_events_cmd);
3154  install_element (ENABLE_NODE, &debug_isis_packet_dump_cmd);
3155  install_element (ENABLE_NODE, &no_debug_isis_packet_dump_cmd);
3156
3157  install_element (CONFIG_NODE, &debug_isis_adj_cmd);
3158  install_element (CONFIG_NODE, &no_debug_isis_adj_cmd);
3159  install_element (CONFIG_NODE, &debug_isis_csum_cmd);
3160  install_element (CONFIG_NODE, &no_debug_isis_csum_cmd);
3161  install_element (CONFIG_NODE, &debug_isis_lupd_cmd);
3162  install_element (CONFIG_NODE, &no_debug_isis_lupd_cmd);
3163  install_element (CONFIG_NODE, &debug_isis_err_cmd);
3164  install_element (CONFIG_NODE, &no_debug_isis_err_cmd);
3165  install_element (CONFIG_NODE, &debug_isis_snp_cmd);
3166  install_element (CONFIG_NODE, &no_debug_isis_snp_cmd);
3167  install_element (CONFIG_NODE, &debug_isis_upd_cmd);
3168  install_element (CONFIG_NODE, &no_debug_isis_upd_cmd);
3169  install_element (CONFIG_NODE, &debug_isis_spfevents_cmd);
3170  install_element (CONFIG_NODE, &no_debug_isis_spfevents_cmd);
3171  install_element (CONFIG_NODE, &debug_isis_spfstats_cmd);
3172  install_element (CONFIG_NODE, &no_debug_isis_spfstats_cmd);
3173  install_element (CONFIG_NODE, &debug_isis_spftrigg_cmd);
3174  install_element (CONFIG_NODE, &no_debug_isis_spftrigg_cmd);
3175  install_element (CONFIG_NODE, &debug_isis_rtevents_cmd);
3176  install_element (CONFIG_NODE, &no_debug_isis_rtevents_cmd);
3177  install_element (CONFIG_NODE, &debug_isis_events_cmd);
3178  install_element (CONFIG_NODE, &no_debug_isis_events_cmd);
3179  install_element (CONFIG_NODE, &debug_isis_packet_dump_cmd);
3180  install_element (CONFIG_NODE, &no_debug_isis_packet_dump_cmd);
3181
3182  install_element (CONFIG_NODE, &router_isis_cmd);
3183  install_element (CONFIG_NODE, &no_router_isis_cmd);
3184
3185  install_default (ISIS_NODE);
3186
3187  install_element (ISIS_NODE, &net_cmd);
3188  install_element (ISIS_NODE, &no_net_cmd);
3189
3190  install_element (ISIS_NODE, &is_type_cmd);
3191  install_element (ISIS_NODE, &no_is_type_cmd);
3192
3193  install_element (ISIS_NODE, &area_passwd_md5_cmd);
3194  install_element (ISIS_NODE, &area_passwd_md5_snpauth_cmd);
3195  install_element (ISIS_NODE, &area_passwd_clear_cmd);
3196  install_element (ISIS_NODE, &area_passwd_clear_snpauth_cmd);
3197  install_element (ISIS_NODE, &no_area_passwd_cmd);
3198
3199  install_element (ISIS_NODE, &domain_passwd_md5_cmd);
3200  install_element (ISIS_NODE, &domain_passwd_md5_snpauth_cmd);
3201  install_element (ISIS_NODE, &domain_passwd_clear_cmd);
3202  install_element (ISIS_NODE, &domain_passwd_clear_snpauth_cmd);
3203  install_element (ISIS_NODE, &no_domain_passwd_cmd);
3204
3205  install_element (ISIS_NODE, &lsp_gen_interval_cmd);
3206  install_element (ISIS_NODE, &no_lsp_gen_interval_cmd);
3207  install_element (ISIS_NODE, &no_lsp_gen_interval_arg_cmd);
3208  install_element (ISIS_NODE, &lsp_gen_interval_l1_cmd);
3209  install_element (ISIS_NODE, &no_lsp_gen_interval_l1_cmd);
3210  install_element (ISIS_NODE, &no_lsp_gen_interval_l1_arg_cmd);
3211  install_element (ISIS_NODE, &lsp_gen_interval_l2_cmd);
3212  install_element (ISIS_NODE, &no_lsp_gen_interval_l2_cmd);
3213  install_element (ISIS_NODE, &no_lsp_gen_interval_l2_arg_cmd);
3214
3215  install_element (ISIS_NODE, &spf_interval_cmd);
3216  install_element (ISIS_NODE, &no_spf_interval_cmd);
3217  install_element (ISIS_NODE, &no_spf_interval_arg_cmd);
3218  install_element (ISIS_NODE, &spf_interval_l1_cmd);
3219  install_element (ISIS_NODE, &no_spf_interval_l1_cmd);
3220  install_element (ISIS_NODE, &no_spf_interval_l1_arg_cmd);
3221  install_element (ISIS_NODE, &spf_interval_l2_cmd);
3222  install_element (ISIS_NODE, &no_spf_interval_l2_cmd);
3223  install_element (ISIS_NODE, &no_spf_interval_l2_arg_cmd);
3224
3225  install_element (ISIS_NODE, &max_lsp_lifetime_cmd);
3226  install_element (ISIS_NODE, &no_max_lsp_lifetime_cmd);
3227  install_element (ISIS_NODE, &no_max_lsp_lifetime_arg_cmd);
3228  install_element (ISIS_NODE, &max_lsp_lifetime_l1_cmd);
3229  install_element (ISIS_NODE, &no_max_lsp_lifetime_l1_cmd);
3230  install_element (ISIS_NODE, &no_max_lsp_lifetime_l1_arg_cmd);
3231  install_element (ISIS_NODE, &max_lsp_lifetime_l2_cmd);
3232  install_element (ISIS_NODE, &no_max_lsp_lifetime_l2_cmd);
3233  install_element (ISIS_NODE, &no_max_lsp_lifetime_l2_arg_cmd);
3234
3235  install_element (ISIS_NODE, &lsp_refresh_interval_cmd);
3236  install_element (ISIS_NODE, &no_lsp_refresh_interval_cmd);
3237  install_element (ISIS_NODE, &no_lsp_refresh_interval_arg_cmd);
3238  install_element (ISIS_NODE, &lsp_refresh_interval_l1_cmd);
3239  install_element (ISIS_NODE, &no_lsp_refresh_interval_l1_cmd);
3240  install_element (ISIS_NODE, &no_lsp_refresh_interval_l1_arg_cmd);
3241  install_element (ISIS_NODE, &lsp_refresh_interval_l2_cmd);
3242  install_element (ISIS_NODE, &no_lsp_refresh_interval_l2_cmd);
3243  install_element (ISIS_NODE, &no_lsp_refresh_interval_l2_arg_cmd);
3244
3245  install_element (ISIS_NODE, &set_overload_bit_cmd);
3246  install_element (ISIS_NODE, &no_set_overload_bit_cmd);
3247
3248  install_element (ISIS_NODE, &dynamic_hostname_cmd);
3249  install_element (ISIS_NODE, &no_dynamic_hostname_cmd);
3250
3251  install_element (ISIS_NODE, &metric_style_cmd);
3252  install_element (ISIS_NODE, &no_metric_style_cmd);
3253
3254  install_element (ISIS_NODE, &log_adj_changes_cmd);
3255  install_element (ISIS_NODE, &no_log_adj_changes_cmd);
3256
3257#ifdef TOPOLOGY_GENERATE
3258  install_element (ISIS_NODE, &topology_generate_grid_cmd);
3259  install_element (ISIS_NODE, &topology_baseis_cmd);
3260  install_element (ISIS_NODE, &topology_basedynh_cmd);
3261  install_element (ISIS_NODE, &no_topology_baseis_cmd);
3262  install_element (ISIS_NODE, &no_topology_baseis_noid_cmd);
3263  install_element (VIEW_NODE, &show_isis_generated_topology_cmd);
3264  install_element (ENABLE_NODE, &show_isis_generated_topology_cmd);
3265#endif /* TOPOLOGY_GENERATE */
3266}
3267