Import Upstream version 1.2.2
[quagga-debian.git] / isisd / isisd.c
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 #include "isisd/isis_te.h"
58
59 #ifdef TOPOLOGY_GENERATE
60 #include "spgrid.h"
61 u_char DEFAULT_TOPOLOGY_BASEIS[6] = { 0xFE, 0xED, 0xFE, 0xED, 0x00, 0x00 };
62 #endif /* TOPOLOGY_GENERATE */
63
64 struct isis *isis = NULL;
65
66 /*
67  * Prototypes.
68  */
69 int isis_area_get(struct vty *, const char *);
70 int isis_area_destroy(struct vty *, const char *);
71 int area_net_title(struct vty *, const char *);
72 int area_clear_net_title(struct vty *, const char *);
73 int show_isis_interface_common(struct vty *, const char *ifname, char);
74 int show_isis_neighbor_common(struct vty *, const char *id, char);
75 int clear_isis_neighbor_common(struct vty *, const char *id);
76 int isis_config_write(struct vty *);
77
78
79
80 void
81 isis_new (unsigned long process_id)
82 {
83   isis = XCALLOC (MTYPE_ISIS, sizeof (struct isis));
84   /*
85    * Default values
86    */
87   isis->max_area_addrs = 3;
88   isis->process_id = process_id;
89   isis->router_id = 0;
90   isis->area_list = list_new ();
91   isis->init_circ_list = list_new ();
92   isis->uptime = time (NULL);
93   isis->nexthops = list_new ();
94 #ifdef HAVE_IPV6
95   isis->nexthops6 = list_new ();
96 #endif /* HAVE_IPV6 */
97   dyn_cache_init ();
98   /*
99    * uncomment the next line for full debugs
100    */
101   /* isis->debugs = 0xFFFF; */
102   isisMplsTE.status = disable;            /* Only support TE metric */
103 }
104
105 struct isis_area *
106 isis_area_create (const char *area_tag)
107 {
108   struct isis_area *area;
109
110   area = XCALLOC (MTYPE_ISIS_AREA, sizeof (struct isis_area));
111
112   /*
113    * The first instance is level-1-2 rest are level-1, unless otherwise
114    * configured
115    */
116   if (listcount (isis->area_list) > 0)
117     area->is_type = IS_LEVEL_1;
118   else
119     area->is_type = IS_LEVEL_1_AND_2;
120
121   /*
122    * intialize the databases
123    */
124   if (area->is_type & IS_LEVEL_1)
125     {
126       area->lspdb[0] = lsp_db_init ();
127       area->route_table[0] = route_table_init ();
128 #ifdef HAVE_IPV6
129       area->route_table6[0] = route_table_init ();
130 #endif /* HAVE_IPV6 */
131     }
132   if (area->is_type & IS_LEVEL_2)
133     {
134       area->lspdb[1] = lsp_db_init ();
135       area->route_table[1] = route_table_init ();
136 #ifdef HAVE_IPV6
137       area->route_table6[1] = route_table_init ();
138 #endif /* HAVE_IPV6 */
139     }
140
141   spftree_area_init (area);
142
143   area->circuit_list = list_new ();
144   area->area_addrs = list_new ();
145   THREAD_TIMER_ON (master, area->t_tick, lsp_tick, area, 1);
146   flags_initialize (&area->flags);
147
148   /*
149    * Default values
150    */
151   area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME;     /* 1200 */
152   area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME;     /* 1200 */
153   area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL;  /* 900 */
154   area->lsp_refresh[1] = DEFAULT_MAX_LSP_GEN_INTERVAL;  /* 900 */
155   area->lsp_gen_interval[0] = DEFAULT_MIN_LSP_GEN_INTERVAL;
156   area->lsp_gen_interval[1] = DEFAULT_MIN_LSP_GEN_INTERVAL;
157   area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
158   area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
159   area->dynhostname = 1;
160   area->oldmetric = 0;
161   area->newmetric = 1;
162   area->lsp_frag_threshold = 90;
163   area->lsp_mtu = DEFAULT_LSP_MTU;
164 #ifdef TOPOLOGY_GENERATE
165   memcpy (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS, ISIS_SYS_ID_LEN);
166 #endif /* TOPOLOGY_GENERATE */
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
175 struct isis_area *
176 isis_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
190 int
191 isis_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
215 int
216 isis_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   isis_redist_area_finish(area);
286
287   for (ALL_LIST_ELEMENTS (area->area_addrs, node, nnode, addr))
288     {
289       list_delete_node (area->area_addrs, node);
290       XFREE (MTYPE_ISIS_AREA_ADDR, addr);
291     }
292   area->area_addrs = NULL;
293
294   THREAD_TIMER_OFF (area->t_tick);
295   THREAD_TIMER_OFF (area->t_lsp_refresh[0]);
296   THREAD_TIMER_OFF (area->t_lsp_refresh[1]);
297
298   thread_cancel_event (master, area);
299
300   listnode_delete (isis->area_list, area);
301
302   free (area->area_tag);
303
304   XFREE (MTYPE_ISIS_AREA, area);
305
306   if (listcount (isis->area_list) == 0)
307     {
308       memset (isis->sysid, 0, ISIS_SYS_ID_LEN);
309       isis->sysid_set = 0;
310     }
311
312   return CMD_SUCCESS;
313 }
314
315 int
316 area_net_title (struct vty *vty, const char *net_title)
317 {
318   struct isis_area *area;
319   struct area_addr *addr;
320   struct area_addr *addrp;
321   struct listnode *node;
322
323   u_char buff[255];
324   area = vty->index;
325
326   if (!area)
327     {
328       vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
329       return CMD_ERR_NO_MATCH;
330     }
331
332   /* We check that we are not over the maximal number of addresses */
333   if (listcount (area->area_addrs) >= isis->max_area_addrs)
334     {
335       vty_out (vty, "Maximum of area addresses (%d) already reached %s",
336                isis->max_area_addrs, VTY_NEWLINE);
337       return CMD_ERR_NOTHING_TODO;
338     }
339
340   addr = XMALLOC (MTYPE_ISIS_AREA_ADDR, sizeof (struct area_addr));
341   addr->addr_len = dotformat2buff (buff, net_title);
342   memcpy (addr->area_addr, buff, addr->addr_len);
343 #ifdef EXTREME_DEBUG
344   zlog_debug ("added area address %s for area %s (address length %d)",
345              net_title, area->area_tag, addr->addr_len);
346 #endif /* EXTREME_DEBUG */
347   if (addr->addr_len < 8 || addr->addr_len > 20)
348     {
349       vty_out (vty, "area address must be at least 8..20 octets long (%d)%s",
350                addr->addr_len, VTY_NEWLINE);
351       XFREE (MTYPE_ISIS_AREA_ADDR, addr);
352       return CMD_ERR_AMBIGUOUS;
353     }
354
355   if (addr->area_addr[addr->addr_len-1] != 0)
356     {
357       vty_out (vty, "nsel byte (last byte) in area address must be 0%s",
358                VTY_NEWLINE);
359       XFREE (MTYPE_ISIS_AREA_ADDR, addr);
360       return CMD_ERR_AMBIGUOUS;
361     }
362
363   if (isis->sysid_set == 0)
364     {
365       /*
366        * First area address - get the SystemID for this router
367        */
368       memcpy (isis->sysid, GETSYSID (addr), ISIS_SYS_ID_LEN);
369       isis->sysid_set = 1;
370       if (isis->debugs & DEBUG_EVENTS)
371         zlog_debug ("Router has SystemID %s", sysid_print (isis->sysid));
372     }
373   else
374     {
375       /*
376        * Check that the SystemID portions match
377        */
378       if (memcmp (isis->sysid, GETSYSID (addr), ISIS_SYS_ID_LEN))
379         {
380           vty_out (vty,
381                    "System ID must not change when defining additional area"
382                    " addresses%s", VTY_NEWLINE);
383           XFREE (MTYPE_ISIS_AREA_ADDR, addr);
384           return CMD_ERR_AMBIGUOUS;
385         }
386
387       /* now we see that we don't already have this address */
388       for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp))
389         {
390           if ((addrp->addr_len + ISIS_SYS_ID_LEN + ISIS_NSEL_LEN) != (addr->addr_len))
391             continue;
392           if (!memcmp (addrp->area_addr, addr->area_addr, addr->addr_len))
393             {
394               XFREE (MTYPE_ISIS_AREA_ADDR, addr);
395               return CMD_SUCCESS;       /* silent fail */
396             }
397         }
398     }
399
400   /*
401    * Forget the systemID part of the address
402    */
403   addr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
404   listnode_add (area->area_addrs, addr);
405
406   /* only now we can safely generate our LSPs for this area */
407   if (listcount (area->area_addrs) > 0)
408     {
409       if (area->is_type & IS_LEVEL_1)
410         lsp_generate (area, IS_LEVEL_1);
411       if (area->is_type & IS_LEVEL_2)
412         lsp_generate (area, IS_LEVEL_2);
413     }
414
415   return CMD_SUCCESS;
416 }
417
418 int
419 area_clear_net_title (struct vty *vty, const char *net_title)
420 {
421   struct isis_area *area;
422   struct area_addr addr, *addrp = NULL;
423   struct listnode *node;
424   u_char buff[255];
425
426   area = vty->index;
427   if (!area)
428     {
429       vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
430       return CMD_ERR_NO_MATCH;
431     }
432
433   addr.addr_len = dotformat2buff (buff, net_title);
434   if (addr.addr_len < 8 || addr.addr_len > 20)
435     {
436       vty_out (vty, "Unsupported area address length %d, should be 8...20 %s",
437                addr.addr_len, VTY_NEWLINE);
438       return CMD_ERR_AMBIGUOUS;
439     }
440
441   memcpy (addr.area_addr, buff, (int) addr.addr_len);
442
443   for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp))
444     if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len &&
445         !memcmp (addrp->area_addr, addr.area_addr, addr.addr_len))
446     break;
447
448   if (!addrp)
449     {
450       vty_out (vty, "No area address %s for area %s %s", net_title,
451                area->area_tag, VTY_NEWLINE);
452       return CMD_ERR_NO_MATCH;
453     }
454
455   listnode_delete (area->area_addrs, addrp);
456   XFREE (MTYPE_ISIS_AREA_ADDR, addrp);
457
458   /*
459    * Last area address - reset the SystemID for this router
460    */
461   if (listcount (area->area_addrs) == 0)
462     {
463       memset (isis->sysid, 0, ISIS_SYS_ID_LEN);
464       isis->sysid_set = 0;
465       if (isis->debugs & DEBUG_EVENTS)
466         zlog_debug ("Router has no SystemID");
467     }
468
469   return CMD_SUCCESS;
470 }
471
472 /*
473  * 'show isis interface' command
474  */
475
476 int
477 show_isis_interface_common (struct vty *vty, const char *ifname, char detail)
478 {
479   struct listnode *anode, *cnode;
480   struct isis_area *area;
481   struct isis_circuit *circuit;
482
483   if (!isis)
484     {
485       vty_out (vty, "IS-IS Routing Process not enabled%s", VTY_NEWLINE);
486       return CMD_SUCCESS;
487     }
488
489   for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area))
490     {
491       vty_out (vty, "Area %s:%s", area->area_tag, VTY_NEWLINE);
492
493       if (detail == ISIS_UI_LEVEL_BRIEF)
494         vty_out (vty, "  Interface   CircId   State    Type     Level%s",
495                  VTY_NEWLINE);
496
497       for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit))
498         if (!ifname)
499           isis_circuit_print_vty (circuit, vty, detail);
500         else if (strcmp(circuit->interface->name, ifname) == 0)
501           isis_circuit_print_vty (circuit, vty, detail);
502     }
503
504   return CMD_SUCCESS;
505 }
506
507 DEFUN (show_isis_interface,
508        show_isis_interface_cmd,
509        "show isis interface",
510        SHOW_STR
511        "ISIS network information\n"
512        "ISIS interface\n")
513 {
514   return show_isis_interface_common (vty, NULL, ISIS_UI_LEVEL_BRIEF);
515 }
516
517 DEFUN (show_isis_interface_detail,
518        show_isis_interface_detail_cmd,
519        "show isis interface detail",
520        SHOW_STR
521        "ISIS network information\n"
522        "ISIS interface\n"
523        "show detailed information\n")
524 {
525   return show_isis_interface_common (vty, NULL, ISIS_UI_LEVEL_DETAIL);
526 }
527
528 DEFUN (show_isis_interface_arg,
529        show_isis_interface_arg_cmd,
530        "show isis interface WORD",
531        SHOW_STR
532        "ISIS network information\n"
533        "ISIS interface\n"
534        "ISIS interface name\n")
535 {
536   return show_isis_interface_common (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
537 }
538
539 /*
540  * 'show isis neighbor' command
541  */
542
543 int
544 show_isis_neighbor_common (struct vty *vty, const char *id, char detail)
545 {
546   struct listnode *anode, *cnode, *node;
547   struct isis_area *area;
548   struct isis_circuit *circuit;
549   struct list *adjdb;
550   struct isis_adjacency *adj;
551   struct isis_dynhn *dynhn;
552   u_char sysid[ISIS_SYS_ID_LEN];
553   int i;
554
555   if (!isis)
556     {
557       vty_out (vty, "IS-IS Routing Process not enabled%s", VTY_NEWLINE);
558       return CMD_SUCCESS;
559     }
560
561   memset (sysid, 0, ISIS_SYS_ID_LEN);
562   if (id)
563     {
564       if (sysid2buff (sysid, id) == 0)
565         {
566           dynhn = dynhn_find_by_name (id);
567           if (dynhn == NULL)
568             {
569               vty_out (vty, "Invalid system id %s%s", id, VTY_NEWLINE);
570               return CMD_SUCCESS;
571             }
572           memcpy (sysid, dynhn->id, ISIS_SYS_ID_LEN);
573         }
574     }
575
576   for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area))
577     {
578       vty_out (vty, "Area %s:%s", area->area_tag, VTY_NEWLINE);
579
580       if (detail == ISIS_UI_LEVEL_BRIEF)
581         vty_out (vty, "  System Id           Interface   L  State"
582                       "        Holdtime SNPA%s", VTY_NEWLINE);
583
584       for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit))
585         {
586           if (circuit->circ_type == CIRCUIT_T_BROADCAST)
587             {
588               for (i = 0; i < 2; i++)
589                 {
590                   adjdb = circuit->u.bc.adjdb[i];
591                   if (adjdb && adjdb->count)
592                     {
593                       for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
594                         if (!id || !memcmp (adj->sysid, sysid,
595                                             ISIS_SYS_ID_LEN))
596                           isis_adj_print_vty (adj, vty, detail);
597                     }
598                 }
599             }
600           else if (circuit->circ_type == CIRCUIT_T_P2P &&
601                    circuit->u.p2p.neighbor)
602             {
603               adj = circuit->u.p2p.neighbor;
604               if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN))
605                 isis_adj_print_vty (adj, vty, detail);
606             }
607         }
608     }
609
610   return CMD_SUCCESS;
611 }
612
613 /*
614  * 'clear isis neighbor' command
615  */
616 int
617 clear_isis_neighbor_common (struct vty *vty, const char *id)
618 {
619   struct listnode *anode, *cnode, *cnextnode, *node, *nnode;
620   struct isis_area *area;
621   struct isis_circuit *circuit;
622   struct list *adjdb;
623   struct isis_adjacency *adj;
624   struct isis_dynhn *dynhn;
625   u_char sysid[ISIS_SYS_ID_LEN];
626   int i;
627
628   if (!isis)
629     {
630       vty_out (vty, "IS-IS Routing Process not enabled%s", VTY_NEWLINE);
631       return CMD_SUCCESS;
632     }
633
634   memset (sysid, 0, ISIS_SYS_ID_LEN);
635   if (id)
636     {
637       if (sysid2buff (sysid, id) == 0)
638         {
639           dynhn = dynhn_find_by_name (id);
640           if (dynhn == NULL)
641             {
642               vty_out (vty, "Invalid system id %s%s", id, VTY_NEWLINE);
643               return CMD_SUCCESS;
644             }
645           memcpy (sysid, dynhn->id, ISIS_SYS_ID_LEN);
646         }
647     }
648
649   for (ALL_LIST_ELEMENTS_RO (isis->area_list, anode, area))
650     {
651       for (ALL_LIST_ELEMENTS (area->circuit_list, cnode, cnextnode, circuit))
652         {
653           if (circuit->circ_type == CIRCUIT_T_BROADCAST)
654             {
655               for (i = 0; i < 2; i++)
656                 {
657                   adjdb = circuit->u.bc.adjdb[i];
658                   if (adjdb && adjdb->count)
659                     {
660                       for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj))
661                         if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN))
662                           isis_adj_state_change (adj, ISIS_ADJ_DOWN,
663                                                  "clear user request");
664                     }
665                 }
666             }
667           else if (circuit->circ_type == CIRCUIT_T_P2P &&
668                    circuit->u.p2p.neighbor)
669             {
670               adj = circuit->u.p2p.neighbor;
671               if (!id || !memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN))
672                 isis_adj_state_change (adj, ISIS_ADJ_DOWN,
673                                        "clear user request");
674             }
675         }
676     }
677
678   return CMD_SUCCESS;
679 }
680
681 DEFUN (show_isis_neighbor,
682        show_isis_neighbor_cmd,
683        "show isis neighbor",
684        SHOW_STR
685        "ISIS network information\n"
686        "ISIS neighbor adjacencies\n")
687 {
688   return show_isis_neighbor_common (vty, NULL, ISIS_UI_LEVEL_BRIEF);
689 }
690
691 DEFUN (show_isis_neighbor_detail,
692        show_isis_neighbor_detail_cmd,
693        "show isis neighbor detail",
694        SHOW_STR
695        "ISIS network information\n"
696        "ISIS neighbor adjacencies\n"
697        "show detailed information\n")
698 {
699   return show_isis_neighbor_common (vty, NULL, ISIS_UI_LEVEL_DETAIL);
700 }
701
702 DEFUN (show_isis_neighbor_arg,
703        show_isis_neighbor_arg_cmd,
704        "show isis neighbor WORD",
705        SHOW_STR
706        "ISIS network information\n"
707        "ISIS neighbor adjacencies\n"
708        "System id\n")
709 {
710   return show_isis_neighbor_common (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
711 }
712
713 DEFUN (clear_isis_neighbor,
714        clear_isis_neighbor_cmd,
715        "clear isis neighbor",
716        CLEAR_STR
717        "Reset ISIS network information\n"
718        "Reset ISIS neighbor adjacencies\n")
719 {
720   return clear_isis_neighbor_common (vty, NULL);
721 }
722
723 DEFUN (clear_isis_neighbor_arg,
724        clear_isis_neighbor_arg_cmd,
725        "clear isis neighbor WORD",
726        CLEAR_STR
727        "ISIS network information\n"
728        "ISIS neighbor adjacencies\n"
729        "System id\n")
730 {
731   return clear_isis_neighbor_common (vty, argv[0]);
732 }
733
734 /*
735  * 'isis debug', 'show debugging'
736  */
737 void
738 print_debug (struct vty *vty, int flags, int onoff)
739 {
740   char onoffs[4];
741   if (onoff)
742     strcpy (onoffs, "on");
743   else
744     strcpy (onoffs, "off");
745
746   if (flags & DEBUG_ADJ_PACKETS)
747     vty_out (vty, "IS-IS Adjacency related packets debugging is %s%s", onoffs,
748              VTY_NEWLINE);
749   if (flags & DEBUG_CHECKSUM_ERRORS)
750     vty_out (vty, "IS-IS checksum errors debugging is %s%s", onoffs,
751              VTY_NEWLINE);
752   if (flags & DEBUG_LOCAL_UPDATES)
753     vty_out (vty, "IS-IS local updates debugging is %s%s", onoffs,
754              VTY_NEWLINE);
755   if (flags & DEBUG_PROTOCOL_ERRORS)
756     vty_out (vty, "IS-IS protocol errors debugging is %s%s", onoffs,
757              VTY_NEWLINE);
758   if (flags & DEBUG_SNP_PACKETS)
759     vty_out (vty, "IS-IS CSNP/PSNP packets debugging is %s%s", onoffs,
760              VTY_NEWLINE);
761   if (flags & DEBUG_SPF_EVENTS)
762     vty_out (vty, "IS-IS SPF events debugging is %s%s", onoffs, VTY_NEWLINE);
763   if (flags & DEBUG_SPF_STATS)
764     vty_out (vty, "IS-IS SPF Timing and Statistics Data debugging is %s%s",
765              onoffs, VTY_NEWLINE);
766   if (flags & DEBUG_SPF_TRIGGERS)
767     vty_out (vty, "IS-IS SPF triggering events debugging is %s%s", onoffs,
768              VTY_NEWLINE);
769   if (flags & DEBUG_UPDATE_PACKETS)
770     vty_out (vty, "IS-IS Update related packet debugging is %s%s", onoffs,
771              VTY_NEWLINE);
772   if (flags & DEBUG_RTE_EVENTS)
773     vty_out (vty, "IS-IS Route related debuggin is %s%s", onoffs,
774              VTY_NEWLINE);
775   if (flags & DEBUG_EVENTS)
776     vty_out (vty, "IS-IS Event debugging is %s%s", onoffs, VTY_NEWLINE);
777   if (flags & DEBUG_PACKET_DUMP)
778     vty_out (vty, "IS-IS Packet dump debugging is %s%s", onoffs, VTY_NEWLINE);
779   if (flags & DEBUG_LSP_GEN)
780     vty_out (vty, "IS-IS LSP generation debugging is %s%s", onoffs, VTY_NEWLINE);
781   if (flags & DEBUG_LSP_SCHED)
782     vty_out (vty, "IS-IS LSP scheduling debugging is %s%s", onoffs, VTY_NEWLINE);
783 }
784
785 DEFUN (show_debugging,
786        show_debugging_isis_cmd,
787        "show debugging isis",
788        SHOW_STR
789        "State of each debugging option\n")
790 {
791   if (isis->debugs) {
792       vty_out (vty, "IS-IS:%s", VTY_NEWLINE);
793       print_debug (vty, isis->debugs, 1);
794   }
795   return CMD_SUCCESS;
796 }
797
798 /* Debug node. */
799 static struct cmd_node debug_node = {
800   DEBUG_NODE,
801   "",
802   1
803 };
804
805 static int
806 config_write_debug (struct vty *vty)
807 {
808   int write = 0;
809   int flags = isis->debugs;
810
811   if (flags & DEBUG_ADJ_PACKETS)
812     {
813       vty_out (vty, "debug isis adj-packets%s", VTY_NEWLINE);
814       write++;
815     }
816   if (flags & DEBUG_CHECKSUM_ERRORS)
817     {
818       vty_out (vty, "debug isis checksum-errors%s", VTY_NEWLINE);
819       write++;
820     }
821   if (flags & DEBUG_LOCAL_UPDATES)
822     {
823       vty_out (vty, "debug isis local-updates%s", VTY_NEWLINE);
824       write++;
825     }
826   if (flags & DEBUG_PROTOCOL_ERRORS)
827     {
828       vty_out (vty, "debug isis protocol-errors%s", VTY_NEWLINE);
829       write++;
830     }
831   if (flags & DEBUG_SNP_PACKETS)
832     {
833       vty_out (vty, "debug isis snp-packets%s", VTY_NEWLINE);
834       write++;
835     }
836   if (flags & DEBUG_SPF_EVENTS)
837     {
838       vty_out (vty, "debug isis spf-events%s", VTY_NEWLINE);
839       write++;
840     }
841   if (flags & DEBUG_SPF_STATS)
842     {
843       vty_out (vty, "debug isis spf-statistics%s", VTY_NEWLINE);
844       write++;
845     }
846   if (flags & DEBUG_SPF_TRIGGERS)
847     {
848       vty_out (vty, "debug isis spf-triggers%s", VTY_NEWLINE);
849       write++;
850     }
851   if (flags & DEBUG_UPDATE_PACKETS)
852     {
853       vty_out (vty, "debug isis update-packets%s", VTY_NEWLINE);
854       write++;
855     }
856   if (flags & DEBUG_RTE_EVENTS)
857     {
858       vty_out (vty, "debug isis route-events%s", VTY_NEWLINE);
859       write++;
860     }
861   if (flags & DEBUG_EVENTS)
862     {
863       vty_out (vty, "debug isis events%s", VTY_NEWLINE);
864       write++;
865     }
866   if (flags & DEBUG_PACKET_DUMP)
867     {
868       vty_out (vty, "debug isis packet-dump%s", VTY_NEWLINE);
869       write++;
870     }
871   if (flags & DEBUG_LSP_GEN)
872     {
873       vty_out (vty, "debug isis lsp-gen%s", VTY_NEWLINE);
874       write++;
875     }
876   if (flags & DEBUG_LSP_SCHED)
877     {
878       vty_out (vty, "debug isis lsp-sched%s", VTY_NEWLINE);
879       write++;
880     }
881
882   return write;
883 }
884
885 DEFUN (debug_isis_adj,
886        debug_isis_adj_cmd,
887        "debug isis adj-packets",
888        DEBUG_STR
889        "IS-IS information\n"
890        "IS-IS Adjacency related packets\n")
891 {
892   isis->debugs |= DEBUG_ADJ_PACKETS;
893   print_debug (vty, DEBUG_ADJ_PACKETS, 1);
894
895   return CMD_SUCCESS;
896 }
897
898 DEFUN (no_debug_isis_adj,
899        no_debug_isis_adj_cmd,
900        "no debug isis adj-packets",
901        UNDEBUG_STR
902        "IS-IS information\n"
903        "IS-IS Adjacency related packets\n")
904 {
905   isis->debugs &= ~DEBUG_ADJ_PACKETS;
906   print_debug (vty, DEBUG_ADJ_PACKETS, 0);
907
908   return CMD_SUCCESS;
909 }
910
911 DEFUN (debug_isis_csum,
912        debug_isis_csum_cmd,
913        "debug isis checksum-errors",
914        DEBUG_STR
915        "IS-IS information\n"
916        "IS-IS LSP checksum errors\n")
917 {
918   isis->debugs |= DEBUG_CHECKSUM_ERRORS;
919   print_debug (vty, DEBUG_CHECKSUM_ERRORS, 1);
920
921   return CMD_SUCCESS;
922 }
923
924 DEFUN (no_debug_isis_csum,
925        no_debug_isis_csum_cmd,
926        "no debug isis checksum-errors",
927        UNDEBUG_STR
928        "IS-IS information\n"
929        "IS-IS LSP checksum errors\n")
930 {
931   isis->debugs &= ~DEBUG_CHECKSUM_ERRORS;
932   print_debug (vty, DEBUG_CHECKSUM_ERRORS, 0);
933
934   return CMD_SUCCESS;
935 }
936
937 DEFUN (debug_isis_lupd,
938        debug_isis_lupd_cmd,
939        "debug isis local-updates",
940        DEBUG_STR
941        "IS-IS information\n"
942        "IS-IS local update packets\n")
943 {
944   isis->debugs |= DEBUG_LOCAL_UPDATES;
945   print_debug (vty, DEBUG_LOCAL_UPDATES, 1);
946
947   return CMD_SUCCESS;
948 }
949
950 DEFUN (no_debug_isis_lupd,
951        no_debug_isis_lupd_cmd,
952        "no debug isis local-updates",
953        UNDEBUG_STR
954        "IS-IS information\n"
955        "IS-IS local update packets\n")
956 {
957   isis->debugs &= ~DEBUG_LOCAL_UPDATES;
958   print_debug (vty, DEBUG_LOCAL_UPDATES, 0);
959
960   return CMD_SUCCESS;
961 }
962
963 DEFUN (debug_isis_err,
964        debug_isis_err_cmd,
965        "debug isis protocol-errors",
966        DEBUG_STR
967        "IS-IS information\n"
968        "IS-IS LSP protocol errors\n")
969 {
970   isis->debugs |= DEBUG_PROTOCOL_ERRORS;
971   print_debug (vty, DEBUG_PROTOCOL_ERRORS, 1);
972
973   return CMD_SUCCESS;
974 }
975
976 DEFUN (no_debug_isis_err,
977        no_debug_isis_err_cmd,
978        "no debug isis protocol-errors",
979        UNDEBUG_STR
980        "IS-IS information\n"
981        "IS-IS LSP protocol errors\n")
982 {
983   isis->debugs &= ~DEBUG_PROTOCOL_ERRORS;
984   print_debug (vty, DEBUG_PROTOCOL_ERRORS, 0);
985
986   return CMD_SUCCESS;
987 }
988
989 DEFUN (debug_isis_snp,
990        debug_isis_snp_cmd,
991        "debug isis snp-packets",
992        DEBUG_STR
993        "IS-IS information\n"
994        "IS-IS CSNP/PSNP packets\n")
995 {
996   isis->debugs |= DEBUG_SNP_PACKETS;
997   print_debug (vty, DEBUG_SNP_PACKETS, 1);
998
999   return CMD_SUCCESS;
1000 }
1001
1002 DEFUN (no_debug_isis_snp,
1003        no_debug_isis_snp_cmd,
1004        "no debug isis snp-packets",
1005        UNDEBUG_STR
1006        "IS-IS information\n"
1007        "IS-IS CSNP/PSNP packets\n")
1008 {
1009   isis->debugs &= ~DEBUG_SNP_PACKETS;
1010   print_debug (vty, DEBUG_SNP_PACKETS, 0);
1011
1012   return CMD_SUCCESS;
1013 }
1014
1015 DEFUN (debug_isis_upd,
1016        debug_isis_upd_cmd,
1017        "debug isis update-packets",
1018        DEBUG_STR
1019        "IS-IS information\n"
1020        "IS-IS Update related packets\n")
1021 {
1022   isis->debugs |= DEBUG_UPDATE_PACKETS;
1023   print_debug (vty, DEBUG_UPDATE_PACKETS, 1);
1024
1025   return CMD_SUCCESS;
1026 }
1027
1028 DEFUN (no_debug_isis_upd,
1029        no_debug_isis_upd_cmd,
1030        "no debug isis update-packets",
1031        UNDEBUG_STR
1032        "IS-IS information\n"
1033        "IS-IS Update related packets\n")
1034 {
1035   isis->debugs &= ~DEBUG_UPDATE_PACKETS;
1036   print_debug (vty, DEBUG_UPDATE_PACKETS, 0);
1037
1038   return CMD_SUCCESS;
1039 }
1040
1041 DEFUN (debug_isis_spfevents,
1042        debug_isis_spfevents_cmd,
1043        "debug isis spf-events",
1044        DEBUG_STR
1045        "IS-IS information\n"
1046        "IS-IS Shortest Path First Events\n")
1047 {
1048   isis->debugs |= DEBUG_SPF_EVENTS;
1049   print_debug (vty, DEBUG_SPF_EVENTS, 1);
1050
1051   return CMD_SUCCESS;
1052 }
1053
1054 DEFUN (no_debug_isis_spfevents,
1055        no_debug_isis_spfevents_cmd,
1056        "no debug isis spf-events",
1057        UNDEBUG_STR
1058        "IS-IS information\n"
1059        "IS-IS Shortest Path First Events\n")
1060 {
1061   isis->debugs &= ~DEBUG_SPF_EVENTS;
1062   print_debug (vty, DEBUG_SPF_EVENTS, 0);
1063
1064   return CMD_SUCCESS;
1065 }
1066
1067 DEFUN (debug_isis_spfstats,
1068        debug_isis_spfstats_cmd,
1069        "debug isis spf-statistics ",
1070        DEBUG_STR
1071        "IS-IS information\n"
1072        "IS-IS SPF Timing and Statistic Data\n")
1073 {
1074   isis->debugs |= DEBUG_SPF_STATS;
1075   print_debug (vty, DEBUG_SPF_STATS, 1);
1076
1077   return CMD_SUCCESS;
1078 }
1079
1080 DEFUN (no_debug_isis_spfstats,
1081        no_debug_isis_spfstats_cmd,
1082        "no debug isis spf-statistics",
1083        UNDEBUG_STR
1084        "IS-IS information\n"
1085        "IS-IS SPF Timing and Statistic Data\n")
1086 {
1087   isis->debugs &= ~DEBUG_SPF_STATS;
1088   print_debug (vty, DEBUG_SPF_STATS, 0);
1089
1090   return CMD_SUCCESS;
1091 }
1092
1093 DEFUN (debug_isis_spftrigg,
1094        debug_isis_spftrigg_cmd,
1095        "debug isis spf-triggers",
1096        DEBUG_STR
1097        "IS-IS information\n"
1098        "IS-IS SPF triggering events\n")
1099 {
1100   isis->debugs |= DEBUG_SPF_TRIGGERS;
1101   print_debug (vty, DEBUG_SPF_TRIGGERS, 1);
1102
1103   return CMD_SUCCESS;
1104 }
1105
1106 DEFUN (no_debug_isis_spftrigg,
1107        no_debug_isis_spftrigg_cmd,
1108        "no debug isis spf-triggers",
1109        UNDEBUG_STR
1110        "IS-IS information\n"
1111        "IS-IS SPF triggering events\n")
1112 {
1113   isis->debugs &= ~DEBUG_SPF_TRIGGERS;
1114   print_debug (vty, DEBUG_SPF_TRIGGERS, 0);
1115
1116   return CMD_SUCCESS;
1117 }
1118
1119 DEFUN (debug_isis_rtevents,
1120        debug_isis_rtevents_cmd,
1121        "debug isis route-events",
1122        DEBUG_STR
1123        "IS-IS information\n"
1124        "IS-IS Route related events\n")
1125 {
1126   isis->debugs |= DEBUG_RTE_EVENTS;
1127   print_debug (vty, DEBUG_RTE_EVENTS, 1);
1128
1129   return CMD_SUCCESS;
1130 }
1131
1132 DEFUN (no_debug_isis_rtevents,
1133        no_debug_isis_rtevents_cmd,
1134        "no debug isis route-events",
1135        UNDEBUG_STR
1136        "IS-IS information\n"
1137        "IS-IS Route related events\n")
1138 {
1139   isis->debugs &= ~DEBUG_RTE_EVENTS;
1140   print_debug (vty, DEBUG_RTE_EVENTS, 0);
1141
1142   return CMD_SUCCESS;
1143 }
1144
1145 DEFUN (debug_isis_events,
1146        debug_isis_events_cmd,
1147        "debug isis events",
1148        DEBUG_STR
1149        "IS-IS information\n"
1150        "IS-IS Events\n")
1151 {
1152   isis->debugs |= DEBUG_EVENTS;
1153   print_debug (vty, DEBUG_EVENTS, 1);
1154
1155   return CMD_SUCCESS;
1156 }
1157
1158 DEFUN (no_debug_isis_events,
1159        no_debug_isis_events_cmd,
1160        "no debug isis events",
1161        UNDEBUG_STR
1162        "IS-IS information\n"
1163        "IS-IS Events\n")
1164 {
1165   isis->debugs &= ~DEBUG_EVENTS;
1166   print_debug (vty, DEBUG_EVENTS, 0);
1167
1168   return CMD_SUCCESS;
1169 }
1170
1171 DEFUN (debug_isis_packet_dump,
1172        debug_isis_packet_dump_cmd,
1173        "debug isis packet-dump",
1174        DEBUG_STR
1175        "IS-IS information\n"
1176        "IS-IS packet dump\n")
1177 {
1178   isis->debugs |= DEBUG_PACKET_DUMP;
1179   print_debug (vty, DEBUG_PACKET_DUMP, 1);
1180
1181   return CMD_SUCCESS;
1182 }
1183
1184 DEFUN (no_debug_isis_packet_dump,
1185        no_debug_isis_packet_dump_cmd,
1186        "no debug isis packet-dump",
1187        UNDEBUG_STR
1188        "IS-IS information\n"
1189        "IS-IS packet dump\n")
1190 {
1191   isis->debugs &= ~DEBUG_PACKET_DUMP;
1192   print_debug (vty, DEBUG_PACKET_DUMP, 0);
1193
1194   return CMD_SUCCESS;
1195 }
1196
1197 DEFUN (debug_isis_lsp_gen,
1198        debug_isis_lsp_gen_cmd,
1199        "debug isis lsp-gen",
1200        DEBUG_STR
1201        "IS-IS information\n"
1202        "IS-IS generation of own LSPs\n")
1203 {
1204   isis->debugs |= DEBUG_LSP_GEN;
1205   print_debug (vty, DEBUG_LSP_GEN, 1);
1206
1207   return CMD_SUCCESS;
1208 }
1209
1210 DEFUN (no_debug_isis_lsp_gen,
1211        no_debug_isis_lsp_gen_cmd,
1212        "no debug isis lsp-gen",
1213        UNDEBUG_STR
1214        "IS-IS information\n"
1215        "IS-IS generation of own LSPs\n")
1216 {
1217   isis->debugs &= ~DEBUG_LSP_GEN;
1218   print_debug (vty, DEBUG_LSP_GEN, 0);
1219
1220   return CMD_SUCCESS;
1221 }
1222
1223 DEFUN (debug_isis_lsp_sched,
1224        debug_isis_lsp_sched_cmd,
1225        "debug isis lsp-sched",
1226        DEBUG_STR
1227        "IS-IS information\n"
1228        "IS-IS scheduling of LSP generation\n")
1229 {
1230   isis->debugs |= DEBUG_LSP_SCHED;
1231   print_debug (vty, DEBUG_LSP_SCHED, 1);
1232
1233   return CMD_SUCCESS;
1234 }
1235
1236 DEFUN (no_debug_isis_lsp_sched,
1237        no_debug_isis_lsp_sched_cmd,
1238        "no debug isis lsp-gen",
1239        UNDEBUG_STR
1240        "IS-IS information\n"
1241        "IS-IS scheduling of LSP generation\n")
1242 {
1243   isis->debugs &= ~DEBUG_LSP_SCHED;
1244   print_debug (vty, DEBUG_LSP_SCHED, 0);
1245
1246   return CMD_SUCCESS;
1247 }
1248
1249 DEFUN (show_hostname,
1250        show_hostname_cmd,
1251        "show isis hostname",
1252        SHOW_STR
1253        "IS-IS information\n"
1254        "IS-IS Dynamic hostname mapping\n")
1255 {
1256   dynhn_print_all (vty);
1257
1258   return CMD_SUCCESS;
1259 }
1260
1261 static void
1262 vty_out_timestr(struct vty *vty, time_t uptime)
1263 {
1264   struct tm *tm;
1265   time_t difftime = time (NULL);
1266   difftime -= uptime;
1267   tm = gmtime (&difftime);
1268
1269 #define ONE_DAY_SECOND 60*60*24
1270 #define ONE_WEEK_SECOND 60*60*24*7
1271   if (difftime < ONE_DAY_SECOND)
1272     vty_out (vty,  "%02d:%02d:%02d", 
1273         tm->tm_hour, tm->tm_min, tm->tm_sec);
1274   else if (difftime < ONE_WEEK_SECOND)
1275     vty_out (vty, "%dd%02dh%02dm", 
1276         tm->tm_yday, tm->tm_hour, tm->tm_min);
1277   else
1278     vty_out (vty, "%02dw%dd%02dh", 
1279         tm->tm_yday/7,
1280         tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1281   vty_out (vty, " ago");
1282 }
1283
1284 DEFUN (show_isis_summary,
1285        show_isis_summary_cmd,
1286        "show isis summary",
1287        SHOW_STR "IS-IS information\n" "IS-IS summary\n")
1288 {
1289   struct listnode *node, *node2;
1290   struct isis_area *area;
1291   struct isis_spftree *spftree;
1292   int level;
1293
1294   if (isis == NULL)
1295   {
1296     vty_out (vty, "ISIS is not running%s", VTY_NEWLINE);
1297     return CMD_SUCCESS;
1298   }
1299
1300   vty_out (vty, "Process Id      : %ld%s", isis->process_id,
1301       VTY_NEWLINE);
1302   if (isis->sysid_set)
1303     vty_out (vty, "System Id       : %s%s", sysid_print (isis->sysid),
1304         VTY_NEWLINE);
1305
1306   vty_out (vty, "Up time         : ");
1307   vty_out_timestr(vty, isis->uptime);
1308   vty_out (vty, "%s", VTY_NEWLINE);
1309
1310   if (isis->area_list)
1311     vty_out (vty, "Number of areas : %d%s", isis->area_list->count,
1312         VTY_NEWLINE);
1313
1314   for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
1315   {
1316     vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null",
1317         VTY_NEWLINE);
1318
1319     if (listcount (area->area_addrs) > 0)
1320     {
1321       struct area_addr *area_addr;
1322       for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node2, area_addr))
1323       {
1324         vty_out (vty, "  Net: %s%s",
1325             isonet_print (area_addr->area_addr,
1326               area_addr->addr_len + ISIS_SYS_ID_LEN +
1327               1), VTY_NEWLINE);
1328       }
1329     }
1330
1331     for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++)
1332     {
1333       if ((area->is_type & level) == 0)
1334         continue;
1335
1336       vty_out (vty, "  Level-%d:%s", level, VTY_NEWLINE);
1337       spftree = area->spftree[level - 1];
1338       if (spftree->pending)
1339         vty_out (vty, "    IPv4 SPF: (pending)%s", VTY_NEWLINE);
1340       else
1341         vty_out (vty, "    IPv4 SPF:%s", VTY_NEWLINE);
1342
1343       vty_out (vty, "      minimum interval  : %d%s",
1344           area->min_spf_interval[level - 1], VTY_NEWLINE);
1345
1346       vty_out (vty, "      last run elapsed  : ");
1347       vty_out_timestr(vty, spftree->last_run_timestamp);
1348       vty_out (vty, "%s", VTY_NEWLINE);
1349
1350       vty_out (vty, "      last run duration : %u usec%s",
1351                (u_int32_t)spftree->last_run_duration, VTY_NEWLINE);
1352
1353       vty_out (vty, "      run count         : %d%s",
1354           spftree->runcount, VTY_NEWLINE);
1355
1356 #ifdef HAVE_IPV6
1357       spftree = area->spftree6[level - 1];
1358       if (spftree->pending)
1359         vty_out (vty, "    IPv6 SPF: (pending)%s", VTY_NEWLINE);
1360       else
1361         vty_out (vty, "    IPv6 SPF:%s", VTY_NEWLINE);
1362
1363       vty_out (vty, "      minimum interval  : %d%s",
1364           area->min_spf_interval[level - 1], VTY_NEWLINE);
1365
1366       vty_out (vty, "      last run elapsed  : ");
1367       vty_out_timestr(vty, spftree->last_run_timestamp);
1368       vty_out (vty, "%s", VTY_NEWLINE);
1369
1370       vty_out (vty, "      last run duration : %llu msec%s",
1371                (unsigned long long)spftree->last_run_duration, VTY_NEWLINE);
1372
1373       vty_out (vty, "      run count         : %d%s",
1374           spftree->runcount, VTY_NEWLINE);
1375 #endif
1376     }
1377   }
1378   vty_out (vty, "%s", VTY_NEWLINE);
1379
1380   return CMD_SUCCESS;
1381 }
1382
1383 /*
1384  * This function supports following display options:
1385  * [ show isis database [detail] ]
1386  * [ show isis database <sysid> [detail] ]
1387  * [ show isis database <hostname> [detail] ]
1388  * [ show isis database <sysid>.<pseudo-id> [detail] ]
1389  * [ show isis database <hostname>.<pseudo-id> [detail] ]
1390  * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
1391  * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
1392  * [ show isis database detail <sysid> ]
1393  * [ show isis database detail <hostname> ]
1394  * [ show isis database detail <sysid>.<pseudo-id> ]
1395  * [ show isis database detail <hostname>.<pseudo-id> ]
1396  * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
1397  * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
1398  */
1399 static int
1400 show_isis_database (struct vty *vty, const char *argv, int ui_level)
1401 {
1402   struct listnode *node;
1403   struct isis_area *area;
1404   struct isis_lsp *lsp;
1405   struct isis_dynhn *dynhn;
1406   const char *pos = argv;
1407   u_char lspid[ISIS_SYS_ID_LEN+2];
1408   char sysid[255];
1409   u_char number[3];
1410   int level, lsp_count;
1411
1412   if (isis->area_list->count == 0)
1413     return CMD_SUCCESS;
1414
1415   memset (&lspid, 0, ISIS_SYS_ID_LEN);
1416   memset (&sysid, 0, 255);
1417
1418   /*
1419    * extract fragment and pseudo id from the string argv
1420    * in the forms:
1421    * (a) <systemid/hostname>.<pseudo-id>-<framenent> or
1422    * (b) <systemid/hostname>.<pseudo-id> or
1423    * (c) <systemid/hostname> or
1424    * Where systemid is in the form:
1425    * xxxx.xxxx.xxxx
1426    */
1427   if (argv)
1428      strncpy (sysid, argv, 254);
1429   if (argv && strlen (argv) > 3)
1430     {
1431       pos = argv + strlen (argv) - 3;
1432       if (strncmp (pos, "-", 1) == 0)
1433       {
1434         memcpy (number, ++pos, 2);
1435         lspid[ISIS_SYS_ID_LEN+1] = (u_char) strtol ((char *)number, NULL, 16);
1436         pos -= 4;
1437         if (strncmp (pos, ".", 1) != 0)
1438           return CMD_ERR_AMBIGUOUS;
1439       }
1440       if (strncmp (pos, ".", 1) == 0)
1441       {
1442         memcpy (number, ++pos, 2);
1443         lspid[ISIS_SYS_ID_LEN] = (u_char) strtol ((char *)number, NULL, 16);
1444         sysid[pos - argv - 1] = '\0';
1445       }
1446     }
1447
1448   for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
1449     {
1450       vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null",
1451                VTY_NEWLINE);
1452
1453       for (level = 0; level < ISIS_LEVELS; level++)
1454         {
1455           if (area->lspdb[level] && dict_count (area->lspdb[level]) > 0)
1456             {
1457               lsp = NULL;
1458               if (argv != NULL)
1459                 {
1460                   /*
1461                    * Try to find the lsp-id if the argv string is in
1462                    * the form hostname.<pseudo-id>-<fragment>
1463                    */
1464                   if (sysid2buff (lspid, sysid))
1465                     {
1466                       lsp = lsp_search (lspid, area->lspdb[level]);
1467                     }
1468                   else if ((dynhn = dynhn_find_by_name (sysid)))
1469                     {
1470                       memcpy (lspid, dynhn->id, ISIS_SYS_ID_LEN);
1471                       lsp = lsp_search (lspid, area->lspdb[level]);
1472                     }
1473                   else if (strncmp(unix_hostname (), sysid, 15) == 0)
1474                     {
1475                       memcpy (lspid, isis->sysid, ISIS_SYS_ID_LEN);
1476                       lsp = lsp_search (lspid, area->lspdb[level]);
1477                     }
1478                 }
1479
1480               if (lsp != NULL || argv == NULL)
1481                 {
1482                   vty_out (vty, "IS-IS Level-%d link-state database:%s",
1483                            level + 1, VTY_NEWLINE);
1484
1485                   /* print the title in all cases */
1486                   vty_out (vty, "LSP ID                  PduLen  "
1487                            "SeqNumber   Chksum  Holdtime  ATT/P/OL%s",
1488                            VTY_NEWLINE);
1489                 }
1490
1491               if (lsp)
1492                 {
1493                   if (ui_level == ISIS_UI_LEVEL_DETAIL)
1494                     lsp_print_detail (lsp, vty, area->dynhostname);
1495                   else
1496                     lsp_print (lsp, vty, area->dynhostname);
1497                 }
1498               else if (argv == NULL)
1499                 {
1500                   lsp_count = lsp_print_all (vty, area->lspdb[level],
1501                                              ui_level,
1502                                              area->dynhostname);
1503
1504                   vty_out (vty, "    %u LSPs%s%s",
1505                            lsp_count, VTY_NEWLINE, VTY_NEWLINE);
1506                 }
1507             }
1508         }
1509     }
1510
1511   return CMD_SUCCESS;
1512 }
1513
1514 DEFUN (show_database_brief,
1515        show_database_cmd,
1516        "show isis database",
1517        SHOW_STR
1518        "IS-IS information\n"
1519        "IS-IS link state database\n")
1520 {
1521   return show_isis_database (vty, NULL, ISIS_UI_LEVEL_BRIEF);
1522 }
1523
1524 DEFUN (show_database_lsp_brief,
1525        show_database_arg_cmd,
1526        "show isis database WORD",
1527        SHOW_STR
1528        "IS-IS information\n"
1529        "IS-IS link state database\n"
1530        "LSP ID\n")
1531 {
1532   return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_BRIEF);
1533 }
1534
1535 DEFUN (show_database_lsp_detail,
1536        show_database_arg_detail_cmd,
1537        "show isis database WORD detail",
1538        SHOW_STR
1539        "IS-IS information\n"
1540        "IS-IS link state database\n"
1541        "LSP ID\n"
1542        "Detailed information\n")
1543 {
1544   return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
1545 }
1546
1547 DEFUN (show_database_detail,
1548        show_database_detail_cmd,
1549        "show isis database detail",
1550        SHOW_STR
1551        "IS-IS information\n"
1552        "IS-IS link state database\n")
1553 {
1554   return show_isis_database (vty, NULL, ISIS_UI_LEVEL_DETAIL);
1555 }
1556
1557 DEFUN (show_database_detail_lsp,
1558        show_database_detail_arg_cmd,
1559        "show isis database detail WORD",
1560        SHOW_STR
1561        "IS-IS information\n"
1562        "IS-IS link state database\n"
1563        "Detailed information\n"
1564        "LSP ID\n")
1565 {
1566   return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
1567 }
1568
1569 /* 
1570  * 'router isis' command 
1571  */
1572 DEFUN (router_isis,
1573        router_isis_cmd,
1574        "router isis WORD",
1575        ROUTER_STR
1576        "ISO IS-IS\n"
1577        "ISO Routing area tag")
1578 {
1579   return isis_area_get (vty, argv[0]);
1580 }
1581
1582 /* 
1583  *'no router isis' command 
1584  */
1585 DEFUN (no_router_isis,
1586        no_router_isis_cmd,
1587        "no router isis WORD",
1588        "no\n" ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag")
1589 {
1590   return isis_area_destroy (vty, argv[0]);
1591 }
1592
1593 /*
1594  * 'net' command
1595  */
1596 DEFUN (net,
1597        net_cmd,
1598        "net WORD",
1599        "A Network Entity Title for this process (OSI only)\n"
1600        "XX.XXXX. ... .XXX.XX  Network entity title (NET)\n")
1601 {
1602   return area_net_title (vty, argv[0]);
1603 }
1604
1605 /*
1606  * 'no net' command
1607  */
1608 DEFUN (no_net,
1609        no_net_cmd,
1610        "no net WORD",
1611        NO_STR
1612        "A Network Entity Title for this process (OSI only)\n"
1613        "XX.XXXX. ... .XXX.XX  Network entity title (NET)\n")
1614 {
1615   return area_clear_net_title (vty, argv[0]);
1616 }
1617
1618 void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu)
1619 {
1620   area->lsp_mtu = lsp_mtu;
1621   lsp_regenerate_schedule(area, IS_LEVEL_1_AND_2, 1);
1622 }
1623
1624 static int
1625 isis_area_passwd_set(struct isis_area *area, int level, u_char passwd_type,
1626                      const char *passwd, u_char snp_auth)
1627 {
1628   struct isis_passwd *dest;
1629   struct isis_passwd modified;
1630   int len;
1631
1632   assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
1633   dest = (level == IS_LEVEL_1) ? &area->area_passwd : &area->domain_passwd;
1634   memset(&modified, 0, sizeof(modified));
1635
1636   if (passwd_type != ISIS_PASSWD_TYPE_UNUSED)
1637     {
1638       if (!passwd)
1639         return -1;
1640
1641       len = strlen(passwd);
1642       if (len > 254)
1643         return -1;
1644
1645       modified.len = len;
1646       strncpy((char*)modified.passwd, passwd, 255);
1647       modified.type = passwd_type;
1648       modified.snp_auth = snp_auth;
1649     }
1650
1651   if (memcmp(&modified, dest, sizeof(modified)))
1652     {
1653       memcpy(dest, &modified, sizeof(modified));
1654       lsp_regenerate_schedule(area, IS_LEVEL_1|IS_LEVEL_2, 1);
1655     }
1656
1657   return 0;
1658 }
1659
1660 int
1661 isis_area_passwd_unset (struct isis_area *area, int level)
1662 {
1663   return isis_area_passwd_set (area, level, ISIS_PASSWD_TYPE_UNUSED, NULL, 0);
1664 }
1665
1666 int
1667 isis_area_passwd_cleartext_set (struct isis_area *area, int level,
1668                                 const char *passwd, u_char snp_auth)
1669 {
1670   return isis_area_passwd_set (area, level, ISIS_PASSWD_TYPE_CLEARTXT,
1671                                passwd, snp_auth);
1672 }
1673
1674 int
1675 isis_area_passwd_hmac_md5_set (struct isis_area *area, int level,
1676                                const char *passwd, u_char snp_auth)
1677 {
1678   return isis_area_passwd_set (area, level, ISIS_PASSWD_TYPE_HMAC_MD5,
1679                                passwd, snp_auth);
1680 }
1681
1682 static void
1683 area_resign_level (struct isis_area *area, int level)
1684 {
1685   if (area->lspdb[level - 1])
1686     {
1687       lsp_db_destroy (area->lspdb[level - 1]);
1688       area->lspdb[level - 1] = NULL;
1689     }
1690   if (area->spftree[level - 1])
1691     {
1692       isis_spftree_del (area->spftree[level - 1]);
1693       area->spftree[level - 1] = NULL;
1694     }
1695 #ifdef HAVE_IPV6
1696   if (area->spftree6[level - 1])
1697     {
1698       isis_spftree_del (area->spftree6[level - 1]);
1699       area->spftree6[level - 1] = NULL;
1700     }
1701 #endif
1702   if (area->route_table[level - 1])
1703     {
1704       route_table_finish (area->route_table[level - 1]);
1705       area->route_table[level - 1] = NULL;
1706     }
1707 #ifdef HAVE_IPV6
1708   if (area->route_table6[level - 1])
1709     {
1710       route_table_finish (area->route_table6[level - 1]);
1711       area->route_table6[level - 1] = NULL;
1712     }
1713 #endif /* HAVE_IPV6 */
1714
1715   sched_debug("ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.",
1716               area->area_tag, level);
1717   THREAD_TIMER_OFF (area->t_lsp_refresh[level - 1]);
1718   area->lsp_regenerate_pending[level - 1] = 0;
1719 }
1720
1721 void
1722 isis_area_is_type_set(struct isis_area *area, int is_type)
1723 {
1724   struct listnode *node;
1725   struct isis_circuit *circuit;
1726
1727   if (isis->debugs & DEBUG_EVENTS)
1728     zlog_debug ("ISIS-Evt (%s) system type change %s -> %s", area->area_tag,
1729                circuit_t2string (area->is_type), circuit_t2string (is_type));
1730
1731   if (area->is_type == is_type)
1732     return;                     /* No change */
1733
1734   switch (area->is_type)
1735   {
1736     case IS_LEVEL_1:
1737       if (is_type == IS_LEVEL_2)
1738         area_resign_level (area, IS_LEVEL_1);
1739
1740       if (area->lspdb[1] == NULL)
1741         area->lspdb[1] = lsp_db_init ();
1742       if (area->route_table[1] == NULL)
1743         area->route_table[1] = route_table_init ();
1744 #ifdef HAVE_IPV6
1745       if (area->route_table6[1] == NULL)
1746         area->route_table6[1] = route_table_init ();
1747 #endif /* HAVE_IPV6 */
1748       break;
1749
1750     case IS_LEVEL_1_AND_2:
1751       if (is_type == IS_LEVEL_1)
1752         area_resign_level (area, IS_LEVEL_2);
1753       else
1754         area_resign_level (area, IS_LEVEL_1);
1755       break;
1756
1757     case IS_LEVEL_2:
1758       if (is_type == IS_LEVEL_1)
1759         area_resign_level (area, IS_LEVEL_2);
1760
1761       if (area->lspdb[0] == NULL)
1762         area->lspdb[0] = lsp_db_init ();
1763       if (area->route_table[0] == NULL)
1764         area->route_table[0] = route_table_init ();
1765 #ifdef HAVE_IPV6
1766       if (area->route_table6[0] == NULL)
1767         area->route_table6[0] = route_table_init ();
1768 #endif /* HAVE_IPV6 */
1769       break;
1770
1771     default:
1772       break;
1773   }
1774
1775   area->is_type = is_type;
1776
1777   /* override circuit's is_type */
1778   if (area->is_type != IS_LEVEL_1_AND_2)
1779   {
1780     for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
1781       isis_circuit_is_type_set (circuit, is_type);
1782   }
1783
1784   spftree_area_init (area);
1785
1786   if (is_type & IS_LEVEL_1)
1787     lsp_generate (area, IS_LEVEL_1);
1788   if (is_type & IS_LEVEL_2)
1789     lsp_generate (area, IS_LEVEL_2);
1790   lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1791
1792   return;
1793 }
1794
1795 void isis_area_metricstyle_set(struct isis_area *area, bool old_metric,
1796                                bool new_metric)
1797 {
1798   if (area->oldmetric != old_metric
1799       || area->newmetric != new_metric)
1800     {
1801       area->oldmetric = old_metric;
1802       area->newmetric = new_metric;
1803       lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1804     }
1805 }
1806
1807 void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
1808 {
1809   char new_overload_bit = overload_bit ? LSPBIT_OL : 0;
1810
1811   if (new_overload_bit != area->overload_bit)
1812     {
1813       area->overload_bit = new_overload_bit;
1814       lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1815     }
1816 }
1817
1818 void isis_area_attached_bit_set(struct isis_area *area, bool attached_bit)
1819 {
1820   char new_attached_bit = attached_bit ? LSPBIT_ATT : 0;
1821
1822   if (new_attached_bit != area->attached_bit)
1823     {
1824       area->attached_bit = new_attached_bit;
1825       lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1826     }
1827 }
1828
1829 void isis_area_dynhostname_set(struct isis_area *area, bool dynhostname)
1830 {
1831   if (area->dynhostname != dynhostname)
1832     {
1833       area->dynhostname = dynhostname;
1834       lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1835     }
1836 }
1837
1838 void
1839 isis_area_max_lsp_lifetime_set(struct isis_area *area, int level,
1840                                uint16_t max_lsp_lifetime)
1841 {
1842   assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
1843
1844   if (area->max_lsp_lifetime[level-1] == max_lsp_lifetime)
1845     return;
1846
1847   area->max_lsp_lifetime[level-1] = max_lsp_lifetime;
1848   lsp_regenerate_schedule(area, level, 1);
1849 }
1850
1851 void
1852 isis_area_lsp_refresh_set(struct isis_area *area, int level,
1853                           uint16_t lsp_refresh)
1854 {
1855   assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
1856
1857   if (area->lsp_refresh[level-1] == lsp_refresh)
1858     return;
1859
1860   area->lsp_refresh[level-1] = lsp_refresh;
1861   lsp_regenerate_schedule(area, level, 1);
1862 }
1863
1864 DEFUN (log_adj_changes,
1865        log_adj_changes_cmd,
1866        "log-adjacency-changes",
1867        "Log changes in adjacency state\n")
1868 {
1869   struct isis_area *area;
1870
1871   area = vty->index;
1872   assert (area);
1873
1874   area->log_adj_changes = 1;
1875
1876   return CMD_SUCCESS;
1877 }
1878
1879 DEFUN (no_log_adj_changes,
1880        no_log_adj_changes_cmd,
1881        "no log-adjacency-changes",
1882        "Stop logging changes in adjacency state\n")
1883 {
1884   struct isis_area *area;
1885
1886   area = vty->index;
1887   assert (area);
1888
1889   area->log_adj_changes = 0;
1890
1891   return CMD_SUCCESS;
1892 }
1893
1894 #ifdef TOPOLOGY_GENERATE
1895
1896 DEFUN (topology_generate_grid,
1897        topology_generate_grid_cmd,
1898        "topology generate grid <1-100> <1-100> <1-65000> [param] [param] "
1899        "[param]",
1900        "Topology generation for IS-IS\n"
1901        "Topology generation\n"
1902        "Grid topology\n"
1903        "X parameter of the grid\n"
1904        "Y parameter of the grid\n"
1905        "Random seed\n"
1906        "Optional param 1\n"
1907        "Optional param 2\n"
1908        "Optional param 3\n"
1909        "Topology\n")
1910 {
1911   struct isis_area *area;
1912
1913   area = vty->index;
1914   assert (area);
1915
1916   if (!spgrid_check_params (vty, argc, argv))
1917     {
1918       if (area->topology)
1919         list_delete (area->topology);
1920       area->topology = list_new ();
1921       memcpy (area->top_params, vty->buf, 200);
1922       gen_spgrid_topology (vty, area->topology);
1923       remove_topology_lsps (area);
1924       generate_topology_lsps (area);
1925       /* Regenerate L1 LSP to get two way connection to the generated
1926        * topology. */
1927       lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1928     }
1929
1930   return CMD_SUCCESS;
1931 }
1932
1933 DEFUN (show_isis_generated_topology,
1934        show_isis_generated_topology_cmd,
1935        "show isis generated-topologies",
1936        SHOW_STR
1937        "ISIS network information\n"
1938        "Show generated topologies\n")
1939 {
1940   struct isis_area *area;
1941   struct listnode *node;
1942   struct listnode *node2;
1943   struct arc *arc;
1944
1945   for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
1946     {
1947       if (!area->topology)
1948         continue;
1949
1950       vty_out (vty, "Topology for isis area: %s%s", area->area_tag,
1951                VTY_NEWLINE);
1952       vty_out (vty, "From node     To node     Distance%s", VTY_NEWLINE);
1953
1954       for (ALL_LIST_ELEMENTS_RO (area->topology, node2, arc))
1955         vty_out (vty, "%9ld %11ld %12ld%s", arc->from_node, arc->to_node,
1956                  arc->distance, VTY_NEWLINE);
1957     }
1958   return CMD_SUCCESS;
1959 }
1960
1961 /* Base IS for topology generation. */
1962 DEFUN (topology_baseis,
1963        topology_baseis_cmd,
1964        "topology base-is WORD",
1965        "Topology generation for IS-IS\n"
1966        "A Network IS Base for this topology\n"
1967        "XXXX.XXXX.XXXX Network entity title (NET)\n")
1968 {
1969   struct isis_area *area;
1970   u_char buff[ISIS_SYS_ID_LEN];
1971
1972   area = vty->index;
1973   assert (area);
1974
1975   if (sysid2buff (buff, argv[0]))
1976     sysid2buff (area->topology_baseis, argv[0]);
1977
1978   return CMD_SUCCESS;
1979 }
1980
1981 DEFUN (no_topology_baseis,
1982        no_topology_baseis_cmd,
1983        "no topology base-is WORD",
1984        NO_STR
1985        "Topology generation for IS-IS\n"
1986        "A Network IS Base for this topology\n"
1987        "XXXX.XXXX.XXXX Network entity title (NET)\n")
1988 {
1989   struct isis_area *area;
1990
1991   area = vty->index;
1992   assert (area);
1993
1994   memcpy (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS, ISIS_SYS_ID_LEN);
1995   return CMD_SUCCESS;
1996 }
1997
1998 ALIAS (no_topology_baseis,
1999        no_topology_baseis_noid_cmd,
2000        "no topology base-is",
2001        NO_STR
2002        "Topology generation for IS-IS\n"
2003        "A Network IS Base for this topology\n")
2004
2005 DEFUN (topology_basedynh,
2006        topology_basedynh_cmd,
2007        "topology base-dynh WORD",
2008        "Topology generation for IS-IS\n"
2009        "Dynamic hostname base for this topology\n"
2010        "Dynamic hostname base\n")
2011 {
2012   struct isis_area *area;
2013
2014   area = vty->index;
2015   assert (area);
2016
2017   /* I hope that it's enough. */
2018   area->topology_basedynh = strndup (argv[0], 16); 
2019   return CMD_SUCCESS;
2020 }
2021
2022 #endif /* TOPOLOGY_GENERATE */
2023
2024 /* IS-IS configuration write function */
2025 int
2026 isis_config_write (struct vty *vty)
2027 {
2028   int write = 0;
2029
2030   if (isis != NULL)
2031     {
2032       struct isis_area *area;
2033       struct listnode *node, *node2;
2034
2035       for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
2036       {
2037         /* ISIS - Area name */
2038         vty_out (vty, "router isis %s%s", area->area_tag, VTY_NEWLINE);
2039         write++;
2040         /* ISIS - Net */
2041         if (listcount (area->area_addrs) > 0)
2042           {
2043             struct area_addr *area_addr;
2044             for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node2, area_addr))
2045               {
2046                 vty_out (vty, " net %s%s",
2047                          isonet_print (area_addr->area_addr,
2048                                        area_addr->addr_len + ISIS_SYS_ID_LEN +
2049                                        1), VTY_NEWLINE);
2050                 write++;
2051               }
2052           }
2053         /* ISIS - Dynamic hostname - Defaults to true so only display if
2054          * false. */
2055         if (!area->dynhostname)
2056           {
2057             vty_out (vty, " no hostname dynamic%s", VTY_NEWLINE);
2058             write++;
2059           }
2060         /* ISIS - Metric-Style - when true displays wide */
2061         if (area->newmetric)
2062           {
2063             if (!area->oldmetric)
2064               vty_out (vty, " metric-style wide%s", VTY_NEWLINE);
2065             else
2066               vty_out (vty, " metric-style transition%s", VTY_NEWLINE);
2067             write++;
2068           }
2069         else
2070           {
2071             vty_out (vty, " metric-style narrow%s", VTY_NEWLINE);
2072             write++;
2073           }
2074         /* ISIS - overload-bit */
2075         if (area->overload_bit)
2076           {
2077             vty_out (vty, " set-overload-bit%s", VTY_NEWLINE);
2078             write++;
2079           }
2080         /* ISIS - Area is-type (level-1-2 is default) */
2081         if (area->is_type == IS_LEVEL_1)
2082           {
2083             vty_out (vty, " is-type level-1%s", VTY_NEWLINE);
2084             write++;
2085           }
2086         else if (area->is_type == IS_LEVEL_2)
2087           {
2088             vty_out (vty, " is-type level-2-only%s", VTY_NEWLINE);
2089             write++;
2090           }
2091         write += isis_redist_config_write(vty, area, AF_INET);
2092         write += isis_redist_config_write(vty, area, AF_INET6);
2093         /* ISIS - Lsp generation interval */
2094         if (area->lsp_gen_interval[0] == area->lsp_gen_interval[1])
2095           {
2096             if (area->lsp_gen_interval[0] != DEFAULT_MIN_LSP_GEN_INTERVAL)
2097               {
2098                 vty_out (vty, " lsp-gen-interval %d%s",
2099                          area->lsp_gen_interval[0], VTY_NEWLINE);
2100                 write++;
2101               }
2102           }
2103         else
2104           {
2105             if (area->lsp_gen_interval[0] != DEFAULT_MIN_LSP_GEN_INTERVAL)
2106               {
2107                 vty_out (vty, " lsp-gen-interval level-1 %d%s",
2108                          area->lsp_gen_interval[0], VTY_NEWLINE);
2109                 write++;
2110               }
2111             if (area->lsp_gen_interval[1] != DEFAULT_MIN_LSP_GEN_INTERVAL)
2112               {
2113                 vty_out (vty, " lsp-gen-interval level-2 %d%s",
2114                          area->lsp_gen_interval[1], VTY_NEWLINE);
2115                 write++;
2116               }
2117           }
2118         /* ISIS - LSP lifetime */
2119         if (area->max_lsp_lifetime[0] == area->max_lsp_lifetime[1])
2120           {
2121             if (area->max_lsp_lifetime[0] != DEFAULT_LSP_LIFETIME)
2122               {
2123                 vty_out (vty, " max-lsp-lifetime %u%s", area->max_lsp_lifetime[0],
2124                          VTY_NEWLINE);
2125                 write++;
2126               }
2127           }
2128         else
2129           {
2130             if (area->max_lsp_lifetime[0] != DEFAULT_LSP_LIFETIME)
2131               {
2132                 vty_out (vty, " max-lsp-lifetime level-1 %u%s",
2133                          area->max_lsp_lifetime[0], VTY_NEWLINE);
2134                 write++;
2135               }
2136             if (area->max_lsp_lifetime[1] != DEFAULT_LSP_LIFETIME)
2137               {
2138                 vty_out (vty, " max-lsp-lifetime level-2 %u%s",
2139                          area->max_lsp_lifetime[1], VTY_NEWLINE);
2140                 write++;
2141               }
2142           }
2143         /* ISIS - LSP refresh interval */
2144         if (area->lsp_refresh[0] == area->lsp_refresh[1])
2145           {
2146             if (area->lsp_refresh[0] != DEFAULT_MAX_LSP_GEN_INTERVAL)
2147               {
2148                 vty_out (vty, " lsp-refresh-interval %u%s", area->lsp_refresh[0],
2149                          VTY_NEWLINE);
2150                 write++;
2151               }
2152           }
2153         else
2154           {
2155             if (area->lsp_refresh[0] != DEFAULT_MAX_LSP_GEN_INTERVAL)
2156               {
2157                 vty_out (vty, " lsp-refresh-interval level-1 %u%s",
2158                          area->lsp_refresh[0], VTY_NEWLINE);
2159                 write++;
2160               }
2161             if (area->lsp_refresh[1] != DEFAULT_MAX_LSP_GEN_INTERVAL)
2162               {
2163                 vty_out (vty, " lsp-refresh-interval level-2 %u%s",
2164                          area->lsp_refresh[1], VTY_NEWLINE);
2165                 write++;
2166               }
2167           }
2168         if (area->lsp_mtu != DEFAULT_LSP_MTU)
2169           {
2170             vty_out(vty, " lsp-mtu %u%s", area->lsp_mtu, VTY_NEWLINE);
2171             write++;
2172           }
2173
2174         /* Minimum SPF interval. */
2175         if (area->min_spf_interval[0] == area->min_spf_interval[1])
2176           {
2177             if (area->min_spf_interval[0] != MINIMUM_SPF_INTERVAL)
2178               {
2179                 vty_out (vty, " spf-interval %d%s",
2180                          area->min_spf_interval[0], VTY_NEWLINE);
2181                 write++;
2182               }
2183           }
2184         else
2185           {
2186             if (area->min_spf_interval[0] != MINIMUM_SPF_INTERVAL)
2187               {
2188                 vty_out (vty, " spf-interval level-1 %d%s",
2189                          area->min_spf_interval[0], VTY_NEWLINE);
2190                 write++;
2191               }
2192             if (area->min_spf_interval[1] != MINIMUM_SPF_INTERVAL)
2193               {
2194                 vty_out (vty, " spf-interval level-2 %d%s",
2195                          area->min_spf_interval[1], VTY_NEWLINE);
2196                 write++;
2197               }
2198           }
2199         /* Authentication passwords. */
2200         if (area->area_passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5)
2201           {
2202             vty_out(vty, " area-password md5 %s", area->area_passwd.passwd);
2203             if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND))
2204               {
2205                 vty_out(vty, " authenticate snp ");
2206                 if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV))
2207                   vty_out(vty, "validate");
2208                 else
2209                   vty_out(vty, "send-only");
2210               }
2211             vty_out(vty, "%s", VTY_NEWLINE);
2212             write++; 
2213           }
2214         else if (area->area_passwd.type == ISIS_PASSWD_TYPE_CLEARTXT)
2215           {
2216             vty_out(vty, " area-password clear %s", area->area_passwd.passwd);
2217             if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_SEND))
2218               {
2219                 vty_out(vty, " authenticate snp ");
2220                 if (CHECK_FLAG(area->area_passwd.snp_auth, SNP_AUTH_RECV))
2221                   vty_out(vty, "validate");
2222                 else
2223                   vty_out(vty, "send-only");
2224               }
2225             vty_out(vty, "%s", VTY_NEWLINE);
2226             write++; 
2227           }
2228         if (area->domain_passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5)
2229           {
2230             vty_out(vty, " domain-password md5 %s",
2231                     area->domain_passwd.passwd);
2232             if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND))
2233               {
2234                 vty_out(vty, " authenticate snp ");
2235                 if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV))
2236                   vty_out(vty, "validate");
2237                 else
2238                   vty_out(vty, "send-only");
2239               }
2240             vty_out(vty, "%s", VTY_NEWLINE);
2241             write++;
2242           }
2243         else if (area->domain_passwd.type == ISIS_PASSWD_TYPE_CLEARTXT)
2244           {
2245             vty_out(vty, " domain-password clear %s",
2246                     area->domain_passwd.passwd); 
2247             if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_SEND))
2248               {
2249                 vty_out(vty, " authenticate snp ");
2250                 if (CHECK_FLAG(area->domain_passwd.snp_auth, SNP_AUTH_RECV))
2251                   vty_out(vty, "validate");
2252                 else
2253                   vty_out(vty, "send-only");
2254               }
2255             vty_out(vty, "%s", VTY_NEWLINE);
2256             write++;
2257           }
2258
2259         if (area->log_adj_changes)
2260           {
2261             vty_out (vty, " log-adjacency-changes%s", VTY_NEWLINE);
2262             write++;
2263           }
2264
2265 #ifdef TOPOLOGY_GENERATE
2266         if (memcmp (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS,
2267                     ISIS_SYS_ID_LEN))
2268           {
2269             vty_out (vty, " topology base-is %s%s",
2270                      sysid_print ((u_char *)area->topology_baseis), VTY_NEWLINE);
2271             write++;
2272           }
2273         if (area->topology_basedynh)
2274           {
2275             vty_out (vty, " topology base-dynh %s%s",
2276                      area->topology_basedynh, VTY_NEWLINE);
2277             write++;
2278           }
2279         /* We save the whole command line here. */
2280         if (strlen(area->top_params))
2281           {
2282             vty_out (vty, " %s%s", area->top_params, VTY_NEWLINE);
2283             write++;
2284           }
2285 #endif /* TOPOLOGY_GENERATE */
2286
2287       }
2288     isis_mpls_te_config_write_router(vty);
2289     }
2290
2291   return write;
2292 }
2293
2294 struct cmd_node isis_node = {
2295   ISIS_NODE,
2296   "%s(config-router)# ",
2297   1
2298 };
2299
2300 void
2301 isis_init ()
2302 {
2303   /* Install IS-IS top node */
2304   install_node (&isis_node, isis_config_write);
2305
2306   install_element (VIEW_NODE, &show_isis_summary_cmd);
2307
2308   install_element (VIEW_NODE, &show_isis_interface_cmd);
2309   install_element (VIEW_NODE, &show_isis_interface_detail_cmd);
2310   install_element (VIEW_NODE, &show_isis_interface_arg_cmd);
2311
2312   install_element (VIEW_NODE, &show_isis_neighbor_cmd);
2313   install_element (VIEW_NODE, &show_isis_neighbor_detail_cmd);
2314   install_element (VIEW_NODE, &show_isis_neighbor_arg_cmd);
2315   install_element (VIEW_NODE, &clear_isis_neighbor_cmd);
2316   install_element (VIEW_NODE, &clear_isis_neighbor_arg_cmd);
2317
2318   install_element (VIEW_NODE, &show_hostname_cmd);
2319   install_element (VIEW_NODE, &show_database_cmd);
2320   install_element (VIEW_NODE, &show_database_arg_cmd);
2321   install_element (VIEW_NODE, &show_database_arg_detail_cmd);
2322   install_element (VIEW_NODE, &show_database_detail_cmd);
2323   install_element (VIEW_NODE, &show_database_detail_arg_cmd);
2324
2325   install_element (ENABLE_NODE, &show_debugging_isis_cmd);
2326
2327   install_node (&debug_node, config_write_debug);
2328
2329   install_element (ENABLE_NODE, &debug_isis_adj_cmd);
2330   install_element (ENABLE_NODE, &no_debug_isis_adj_cmd);
2331   install_element (ENABLE_NODE, &debug_isis_csum_cmd);
2332   install_element (ENABLE_NODE, &no_debug_isis_csum_cmd);
2333   install_element (ENABLE_NODE, &debug_isis_lupd_cmd);
2334   install_element (ENABLE_NODE, &no_debug_isis_lupd_cmd);
2335   install_element (ENABLE_NODE, &debug_isis_err_cmd);
2336   install_element (ENABLE_NODE, &no_debug_isis_err_cmd);
2337   install_element (ENABLE_NODE, &debug_isis_snp_cmd);
2338   install_element (ENABLE_NODE, &no_debug_isis_snp_cmd);
2339   install_element (ENABLE_NODE, &debug_isis_upd_cmd);
2340   install_element (ENABLE_NODE, &no_debug_isis_upd_cmd);
2341   install_element (ENABLE_NODE, &debug_isis_spfevents_cmd);
2342   install_element (ENABLE_NODE, &no_debug_isis_spfevents_cmd);
2343   install_element (ENABLE_NODE, &debug_isis_spfstats_cmd);
2344   install_element (ENABLE_NODE, &no_debug_isis_spfstats_cmd);
2345   install_element (ENABLE_NODE, &debug_isis_spftrigg_cmd);
2346   install_element (ENABLE_NODE, &no_debug_isis_spftrigg_cmd);
2347   install_element (ENABLE_NODE, &debug_isis_rtevents_cmd);
2348   install_element (ENABLE_NODE, &no_debug_isis_rtevents_cmd);
2349   install_element (ENABLE_NODE, &debug_isis_events_cmd);
2350   install_element (ENABLE_NODE, &no_debug_isis_events_cmd);
2351   install_element (ENABLE_NODE, &debug_isis_packet_dump_cmd);
2352   install_element (ENABLE_NODE, &no_debug_isis_packet_dump_cmd);
2353   install_element (ENABLE_NODE, &debug_isis_lsp_gen_cmd);
2354   install_element (ENABLE_NODE, &no_debug_isis_lsp_gen_cmd);
2355   install_element (ENABLE_NODE, &debug_isis_lsp_sched_cmd);
2356   install_element (ENABLE_NODE, &no_debug_isis_lsp_sched_cmd);
2357
2358   install_element (CONFIG_NODE, &debug_isis_adj_cmd);
2359   install_element (CONFIG_NODE, &no_debug_isis_adj_cmd);
2360   install_element (CONFIG_NODE, &debug_isis_csum_cmd);
2361   install_element (CONFIG_NODE, &no_debug_isis_csum_cmd);
2362   install_element (CONFIG_NODE, &debug_isis_lupd_cmd);
2363   install_element (CONFIG_NODE, &no_debug_isis_lupd_cmd);
2364   install_element (CONFIG_NODE, &debug_isis_err_cmd);
2365   install_element (CONFIG_NODE, &no_debug_isis_err_cmd);
2366   install_element (CONFIG_NODE, &debug_isis_snp_cmd);
2367   install_element (CONFIG_NODE, &no_debug_isis_snp_cmd);
2368   install_element (CONFIG_NODE, &debug_isis_upd_cmd);
2369   install_element (CONFIG_NODE, &no_debug_isis_upd_cmd);
2370   install_element (CONFIG_NODE, &debug_isis_spfevents_cmd);
2371   install_element (CONFIG_NODE, &no_debug_isis_spfevents_cmd);
2372   install_element (CONFIG_NODE, &debug_isis_spfstats_cmd);
2373   install_element (CONFIG_NODE, &no_debug_isis_spfstats_cmd);
2374   install_element (CONFIG_NODE, &debug_isis_spftrigg_cmd);
2375   install_element (CONFIG_NODE, &no_debug_isis_spftrigg_cmd);
2376   install_element (CONFIG_NODE, &debug_isis_rtevents_cmd);
2377   install_element (CONFIG_NODE, &no_debug_isis_rtevents_cmd);
2378   install_element (CONFIG_NODE, &debug_isis_events_cmd);
2379   install_element (CONFIG_NODE, &no_debug_isis_events_cmd);
2380   install_element (CONFIG_NODE, &debug_isis_packet_dump_cmd);
2381   install_element (CONFIG_NODE, &no_debug_isis_packet_dump_cmd);
2382   install_element (CONFIG_NODE, &debug_isis_lsp_gen_cmd);
2383   install_element (CONFIG_NODE, &no_debug_isis_lsp_gen_cmd);
2384   install_element (CONFIG_NODE, &debug_isis_lsp_sched_cmd);
2385   install_element (CONFIG_NODE, &no_debug_isis_lsp_sched_cmd);
2386
2387   install_element (CONFIG_NODE, &router_isis_cmd);
2388   install_element (CONFIG_NODE, &no_router_isis_cmd);
2389
2390   install_default (ISIS_NODE);
2391
2392   install_element (ISIS_NODE, &net_cmd);
2393   install_element (ISIS_NODE, &no_net_cmd);
2394
2395   install_element (ISIS_NODE, &log_adj_changes_cmd);
2396   install_element (ISIS_NODE, &no_log_adj_changes_cmd);
2397
2398 #ifdef TOPOLOGY_GENERATE
2399   install_element (ISIS_NODE, &topology_generate_grid_cmd);
2400   install_element (ISIS_NODE, &topology_baseis_cmd);
2401   install_element (ISIS_NODE, &topology_basedynh_cmd);
2402   install_element (ISIS_NODE, &no_topology_baseis_cmd);
2403   install_element (ISIS_NODE, &no_topology_baseis_noid_cmd);
2404   install_element (VIEW_NODE, &show_isis_generated_topology_cmd);
2405 #endif /* TOPOLOGY_GENERATE */
2406 }