1/*
2 * IS-IS Rout(e)ing protocol - isis_circuit.h
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#include <zebra.h>
23#ifdef GNU_LINUX
24#include <net/ethernet.h>
25#else
26#include <netinet/if_ether.h>
27#endif
28
29#ifndef ETHER_ADDR_LEN
30#define	ETHER_ADDR_LEN	ETHERADDRL
31#endif
32
33#include "log.h"
34#include "memory.h"
35#include "if.h"
36#include "linklist.h"
37#include "command.h"
38#include "thread.h"
39#include "hash.h"
40#include "prefix.h"
41#include "stream.h"
42
43#include "isisd/dict.h"
44#include "isisd/include-netbsd/iso.h"
45#include "isisd/isis_constants.h"
46#include "isisd/isis_common.h"
47#include "isisd/isis_flags.h"
48#include "isisd/isis_circuit.h"
49#include "isisd/isis_tlv.h"
50#include "isisd/isis_lsp.h"
51#include "isisd/isis_pdu.h"
52#include "isisd/isis_network.h"
53#include "isisd/isis_misc.h"
54#include "isisd/isis_constants.h"
55#include "isisd/isis_adjacency.h"
56#include "isisd/isis_dr.h"
57#include "isisd/isisd.h"
58#include "isisd/isis_csm.h"
59#include "isisd/isis_events.h"
60
61/*
62 * Prototypes.
63 */
64int isis_interface_config_write(struct vty *);
65int isis_if_new_hook(struct interface *);
66int isis_if_delete_hook(struct interface *);
67
68struct isis_circuit *
69isis_circuit_new ()
70{
71  struct isis_circuit *circuit;
72  int i;
73
74  circuit = XCALLOC (MTYPE_ISIS_CIRCUIT, sizeof (struct isis_circuit));
75  if (circuit == NULL)
76    {
77      zlog_err ("Can't malloc isis circuit");
78      return NULL;
79    }
80
81  /*
82   * Default values
83   */
84  circuit->is_type = IS_LEVEL_1_AND_2;
85  circuit->flags = 0;
86  circuit->pad_hellos = 1;
87  for (i = 0; i < 2; i++)
88    {
89      circuit->hello_interval[i] = DEFAULT_HELLO_INTERVAL;
90      circuit->hello_multiplier[i] = DEFAULT_HELLO_MULTIPLIER;
91      circuit->csnp_interval[i] = DEFAULT_CSNP_INTERVAL;
92      circuit->psnp_interval[i] = DEFAULT_PSNP_INTERVAL;
93      circuit->priority[i] = DEFAULT_PRIORITY;
94      circuit->metrics[i].metric_default = DEFAULT_CIRCUIT_METRIC;
95      circuit->metrics[i].metric_expense = METRICS_UNSUPPORTED;
96      circuit->metrics[i].metric_error = METRICS_UNSUPPORTED;
97      circuit->metrics[i].metric_delay = METRICS_UNSUPPORTED;
98      circuit->te_metric[i] = DEFAULT_CIRCUIT_METRIC;
99    }
100
101  return circuit;
102}
103
104void
105isis_circuit_del (struct isis_circuit *circuit)
106{
107  if (!circuit)
108    return;
109
110  isis_circuit_if_unbind (circuit, circuit->interface);
111
112  /* and lastly the circuit itself */
113  XFREE (MTYPE_ISIS_CIRCUIT, circuit);
114
115  return;
116}
117
118void
119isis_circuit_configure (struct isis_circuit *circuit, struct isis_area *area)
120{
121  assert (area);
122  circuit->area = area;
123
124  /*
125   * The level for the circuit is same as for the area, unless configured
126   * otherwise.
127   */
128  if (area->is_type != IS_LEVEL_1_AND_2 && area->is_type != circuit->is_type)
129    zlog_warn ("circut %s is_type %d mismatch with area %s is_type %d",
130               circuit->interface->name, circuit->is_type,
131               circuit->area->area_tag, area->is_type);
132
133  /*
134   * Add the circuit into area
135   */
136  listnode_add (area->circuit_list, circuit);
137
138  circuit->idx = flags_get_index (&area->flags);
139
140  return;
141}
142
143void
144isis_circuit_deconfigure (struct isis_circuit *circuit, struct isis_area *area)
145{
146  /* Free the index of SRM and SSN flags */
147  flags_free_index (&area->flags, circuit->idx);
148  circuit->idx = 0;
149  /* Remove circuit from area */
150  assert (circuit->area == area);
151  listnode_delete (area->circuit_list, circuit);
152  circuit->area = NULL;
153
154  return;
155}
156
157struct isis_circuit *
158circuit_lookup_by_ifp (struct interface *ifp, struct list *list)
159{
160  struct isis_circuit *circuit = NULL;
161  struct listnode *node;
162
163  if (!list)
164    return NULL;
165
166  for (ALL_LIST_ELEMENTS_RO (list, node, circuit))
167    if (circuit->interface == ifp)
168      {
169        assert (ifp->info == circuit);
170        return circuit;
171      }
172
173  return NULL;
174}
175
176struct isis_circuit *
177circuit_scan_by_ifp (struct interface *ifp)
178{
179  struct isis_area *area;
180  struct listnode *node;
181  struct isis_circuit *circuit;
182
183  if (ifp->info)
184    return (struct isis_circuit *)ifp->info;
185
186  if (isis->area_list)
187    {
188      for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
189        {
190          circuit = circuit_lookup_by_ifp (ifp, area->circuit_list);
191          if (circuit)
192            return circuit;
193        }
194    }
195  return circuit_lookup_by_ifp (ifp, isis->init_circ_list);
196}
197
198static struct isis_circuit *
199isis_circuit_lookup (struct vty *vty)
200{
201  struct interface *ifp;
202  struct isis_circuit *circuit;
203
204  ifp = (struct interface *) vty->index;
205  if (!ifp)
206    {
207      vty_out (vty, "Invalid interface %s", VTY_NEWLINE);
208      return NULL;
209    }
210
211  circuit = circuit_scan_by_ifp (ifp);
212  if (!circuit)
213    {
214      vty_out (vty, "ISIS is not enabled on circuit %s%s",
215               ifp->name, VTY_NEWLINE);
216      return NULL;
217    }
218
219  return circuit;
220}
221
222void
223isis_circuit_add_addr (struct isis_circuit *circuit,
224		       struct connected *connected)
225{
226  struct listnode *node;
227  struct prefix_ipv4 *ipv4;
228  u_char buf[BUFSIZ];
229#ifdef HAVE_IPV6
230  struct prefix_ipv6 *ipv6;
231#endif /* HAVE_IPV6 */
232
233  memset (&buf, 0, BUFSIZ);
234  if (connected->address->family == AF_INET)
235    {
236      u_int32_t addr = connected->address->u.prefix4.s_addr;
237      addr = ntohl (addr);
238      if (IPV4_NET0(addr) ||
239          IPV4_NET127(addr) ||
240          IN_CLASSD(addr) ||
241          IPV4_LINKLOCAL(addr))
242        return;
243
244      for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ipv4))
245        if (prefix_same ((struct prefix *) ipv4, connected->address))
246          return;
247
248      ipv4 = prefix_ipv4_new ();
249      ipv4->prefixlen = connected->address->prefixlen;
250      ipv4->prefix = connected->address->u.prefix4;
251      listnode_add (circuit->ip_addrs, ipv4);
252      if (circuit->area)
253        lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
254
255#ifdef EXTREME_DEBUG
256      prefix2str (connected->address, buf, BUFSIZ);
257      zlog_debug ("Added IP address %s to circuit %d", buf,
258		 circuit->circuit_id);
259#endif /* EXTREME_DEBUG */
260    }
261#ifdef HAVE_IPV6
262  if (connected->address->family == AF_INET6)
263    {
264      if (IN6_IS_ADDR_LOOPBACK(&connected->address->u.prefix6))
265        return;
266
267      for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_link, node, ipv6))
268        if (prefix_same ((struct prefix *) ipv6, connected->address))
269          return;
270      for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, node, ipv6))
271        if (prefix_same ((struct prefix *) ipv6, connected->address))
272          return;
273
274      ipv6 = prefix_ipv6_new ();
275      ipv6->prefixlen = connected->address->prefixlen;
276      ipv6->prefix = connected->address->u.prefix6;
277
278      if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
279	listnode_add (circuit->ipv6_link, ipv6);
280      else
281	listnode_add (circuit->ipv6_non_link, ipv6);
282      if (circuit->area)
283        lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
284
285#ifdef EXTREME_DEBUG
286      prefix2str (connected->address, buf, BUFSIZ);
287      zlog_debug ("Added IPv6 address %s to circuit %d", buf,
288		 circuit->circuit_id);
289#endif /* EXTREME_DEBUG */
290    }
291#endif /* HAVE_IPV6 */
292  return;
293}
294
295void
296isis_circuit_del_addr (struct isis_circuit *circuit,
297		       struct connected *connected)
298{
299  struct prefix_ipv4 *ipv4, *ip = NULL;
300  struct listnode *node;
301  u_char buf[BUFSIZ];
302#ifdef HAVE_IPV6
303  struct prefix_ipv6 *ipv6, *ip6 = NULL;
304  int found = 0;
305#endif /* HAVE_IPV6 */
306
307  memset (&buf, 0, BUFSIZ);
308  if (connected->address->family == AF_INET)
309    {
310      ipv4 = prefix_ipv4_new ();
311      ipv4->prefixlen = connected->address->prefixlen;
312      ipv4->prefix = connected->address->u.prefix4;
313
314      for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ip))
315        if (prefix_same ((struct prefix *) ip, (struct prefix *) ipv4))
316          break;
317
318      if (ip)
319	{
320	  listnode_delete (circuit->ip_addrs, ip);
321          if (circuit->area)
322            lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
323	}
324      else
325	{
326	  prefix2str (connected->address, (char *)buf, BUFSIZ);
327	  zlog_warn ("Nonexitant ip address %s removal attempt from \
328                      circuit %d", buf, circuit->circuit_id);
329	}
330
331      prefix_ipv4_free (ipv4);
332    }
333#ifdef HAVE_IPV6
334  if (connected->address->family == AF_INET6)
335    {
336      ipv6 = prefix_ipv6_new ();
337      ipv6->prefixlen = connected->address->prefixlen;
338      ipv6->prefix = connected->address->u.prefix6;
339
340      if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
341	{
342	  for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_link, node, ip6))
343	    {
344	      if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
345		break;
346	    }
347	  if (ip6)
348	    {
349	      listnode_delete (circuit->ipv6_link, ip6);
350	      found = 1;
351	    }
352	}
353      else
354	{
355	  for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, node, ip6))
356	    {
357	      if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
358		break;
359	    }
360	  if (ip6)
361	    {
362	      listnode_delete (circuit->ipv6_non_link, ip6);
363	      found = 1;
364	    }
365	}
366
367      if (!found)
368	{
369	  prefix2str (connected->address, (char *)buf, BUFSIZ);
370	  zlog_warn ("Nonexitant ip address %s removal attempt from \
371		      circuit %d", buf, circuit->circuit_id);
372	}
373      else if (circuit->area)
374	  lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
375
376      prefix_ipv6_free (ipv6);
377    }
378#endif /* HAVE_IPV6 */
379  return;
380}
381
382static u_char
383isis_circuit_id_gen (struct interface *ifp)
384{
385  u_char id = 0;
386  char ifname[16];
387  unsigned int i;
388  int start = -1, end = -1;
389
390  /*
391   * Get a stable circuit id from ifname. This makes
392   * the ifindex from flapping when netdevs are created
393   * and deleted on the fly. Note that this circuit id
394   * is used in pseudo lsps so it is better to be stable.
395   * The following code works on any reasonanle ifname
396   * like: eth1 or trk-1.1 etc.
397   */
398  for (i = 0; i < strlen (ifp->name); i++)
399    {
400      if (isdigit(ifp->name[i]))
401        {
402          if (start < 0)
403            {
404              start = i;
405              end = i + 1;
406            }
407          else
408            {
409              end = i + 1;
410            }
411        }
412      else if (start >= 0)
413        break;
414    }
415
416  if ((start >= 0) && (end >= start) && (end - start) < 16)
417    {
418      memset (ifname, 0, 16);
419      strncpy (ifname, &ifp->name[start], end - start);
420      id = (u_char)atoi(ifname);
421    }
422
423  /* Try to be unique. */
424  if (!id)
425    id = (u_char)((ifp->ifindex & 0xff) | 0x80);
426
427  return id;
428}
429
430void
431isis_circuit_if_add (struct isis_circuit *circuit, struct interface *ifp)
432{
433  struct listnode *node, *nnode;
434  struct connected *conn;
435
436  circuit->circuit_id = isis_circuit_id_gen (ifp);
437
438  isis_circuit_if_bind (circuit, ifp);
439  /*  isis_circuit_update_addrs (circuit, ifp); */
440
441  if (if_is_broadcast (ifp))
442    {
443      if (circuit->circ_type_config == CIRCUIT_T_P2P)
444        circuit->circ_type = CIRCUIT_T_P2P;
445      else
446        circuit->circ_type = CIRCUIT_T_BROADCAST;
447    }
448  else if (if_is_pointopoint (ifp))
449    {
450      circuit->circ_type = CIRCUIT_T_P2P;
451    }
452  else if (if_is_loopback (ifp))
453    {
454      circuit->circ_type = CIRCUIT_T_LOOPBACK;
455      circuit->is_passive = 1;
456    }
457  else
458    {
459      /* It's normal in case of loopback etc. */
460      if (isis->debugs & DEBUG_EVENTS)
461        zlog_debug ("isis_circuit_if_add: unsupported media");
462      circuit->circ_type = CIRCUIT_T_UNKNOWN;
463    }
464
465  circuit->ip_addrs = list_new ();
466#ifdef HAVE_IPV6
467  circuit->ipv6_link = list_new ();
468  circuit->ipv6_non_link = list_new ();
469#endif /* HAVE_IPV6 */
470
471  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, conn))
472    isis_circuit_add_addr (circuit, conn);
473
474  return;
475}
476
477void
478isis_circuit_if_del (struct isis_circuit *circuit, struct interface *ifp)
479{
480  struct listnode *node, *nnode;
481  struct connected *conn;
482
483  assert (circuit->interface == ifp);
484
485  /* destroy addresses */
486  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, conn))
487    isis_circuit_del_addr (circuit, conn);
488
489  if (circuit->ip_addrs)
490    {
491      assert (listcount(circuit->ip_addrs) == 0);
492      list_delete (circuit->ip_addrs);
493      circuit->ip_addrs = NULL;
494    }
495
496#ifdef HAVE_IPV6
497  if (circuit->ipv6_link)
498    {
499      assert (listcount(circuit->ipv6_link) == 0);
500      list_delete (circuit->ipv6_link);
501      circuit->ipv6_link = NULL;
502    }
503
504  if (circuit->ipv6_non_link)
505    {
506      assert (listcount(circuit->ipv6_non_link) == 0);
507      list_delete (circuit->ipv6_non_link);
508      circuit->ipv6_non_link = NULL;
509    }
510#endif /* HAVE_IPV6 */
511
512  circuit->circ_type = CIRCUIT_T_UNKNOWN;
513  circuit->circuit_id = 0;
514
515  return;
516}
517
518void
519isis_circuit_if_bind (struct isis_circuit *circuit, struct interface *ifp)
520{
521  assert (circuit != NULL);
522  assert (ifp != NULL);
523  if (circuit->interface)
524    assert (circuit->interface == ifp);
525  else
526    circuit->interface = ifp;
527  if (ifp->info)
528    assert (ifp->info == circuit);
529  else
530    ifp->info = circuit;
531}
532
533void
534isis_circuit_if_unbind (struct isis_circuit *circuit, struct interface *ifp)
535{
536  assert (circuit != NULL);
537  assert (ifp != NULL);
538  assert (circuit->interface == ifp);
539  assert (ifp->info == circuit);
540  circuit->interface = NULL;
541  ifp->info = NULL;
542}
543
544static void
545isis_circuit_update_all_srmflags (struct isis_circuit *circuit, int is_set)
546{
547  struct isis_area *area;
548  struct isis_lsp *lsp;
549  dnode_t *dnode, *dnode_next;
550  int level;
551
552  assert (circuit);
553  area = circuit->area;
554  assert (area);
555  for (level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++)
556    {
557      if (level & circuit->is_type)
558        {
559          if (area->lspdb[level - 1] &&
560              dict_count (area->lspdb[level - 1]) > 0)
561            {
562              for (dnode = dict_first (area->lspdb[level - 1]);
563                   dnode != NULL; dnode = dnode_next)
564                {
565                  dnode_next = dict_next (area->lspdb[level - 1], dnode);
566                  lsp = dnode_get (dnode);
567                  if (is_set)
568                    {
569                      ISIS_SET_FLAG (lsp->SRMflags, circuit);
570                    }
571                  else
572                    {
573                      ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
574                    }
575                }
576            }
577        }
578    }
579}
580
581int
582isis_circuit_up (struct isis_circuit *circuit)
583{
584  int retv;
585
586  /* Set the flags for all the lsps of the circuit. */
587  isis_circuit_update_all_srmflags (circuit, 1);
588
589  if (circuit->state == C_STATE_UP)
590    return ISIS_OK;
591
592  if (circuit->is_passive)
593    return ISIS_OK;
594
595  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
596    {
597      /*
598       * Get the Hardware Address
599       */
600#ifdef HAVE_STRUCT_SOCKADDR_DL
601#ifndef SUNOS_5
602      if (circuit->interface->sdl.sdl_alen != ETHER_ADDR_LEN)
603        zlog_warn ("unsupported link layer");
604      else
605        memcpy (circuit->u.bc.snpa, LLADDR (&circuit->interface->sdl),
606                ETH_ALEN);
607#endif
608#else
609      if (circuit->interface->hw_addr_len != ETH_ALEN)
610        {
611          zlog_warn ("unsupported link layer");
612        }
613      else
614        {
615          memcpy (circuit->u.bc.snpa, circuit->interface->hw_addr, ETH_ALEN);
616        }
617#ifdef EXTREME_DEGUG
618      zlog_debug ("isis_circuit_if_add: if_id %d, isomtu %d snpa %s",
619                  circuit->interface->ifindex, ISO_MTU (circuit),
620                  snpa_print (circuit->u.bc.snpa));
621#endif /* EXTREME_DEBUG */
622#endif /* HAVE_STRUCT_SOCKADDR_DL */
623
624      circuit->u.bc.adjdb[0] = list_new ();
625      circuit->u.bc.adjdb[1] = list_new ();
626
627      if (circuit->area->min_bcast_mtu == 0 ||
628          ISO_MTU (circuit) < circuit->area->min_bcast_mtu)
629        circuit->area->min_bcast_mtu = ISO_MTU (circuit);
630      /*
631       * ISO 10589 - 8.4.1 Enabling of broadcast circuits
632       */
633
634      /* initilizing the hello sending threads
635       * for a broadcast IF
636       */
637
638      /* 8.4.1 a) commence sending of IIH PDUs */
639
640      if (circuit->is_type & IS_LEVEL_1)
641        {
642          thread_add_event (master, send_lan_l1_hello, circuit, 0);
643          circuit->u.bc.lan_neighs[0] = list_new ();
644        }
645
646      if (circuit->is_type & IS_LEVEL_2)
647        {
648          thread_add_event (master, send_lan_l2_hello, circuit, 0);
649          circuit->u.bc.lan_neighs[1] = list_new ();
650        }
651
652      /* 8.4.1 b) FIXME: solicit ES - 8.4.6 */
653      /* 8.4.1 c) FIXME: listen for ESH PDUs */
654
655      /* 8.4.1 d) */
656      /* dr election will commence in... */
657      if (circuit->is_type & IS_LEVEL_1)
658        THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
659            circuit, 2 * circuit->hello_interval[0]);
660      if (circuit->is_type & IS_LEVEL_2)
661        THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
662            circuit, 2 * circuit->hello_interval[1]);
663    }
664  else
665    {
666      /* initializing the hello send threads
667       * for a ptp IF
668       */
669      circuit->u.p2p.neighbor = NULL;
670      thread_add_event (master, send_p2p_hello, circuit, 0);
671    }
672
673  /* initializing PSNP timers */
674  if (circuit->is_type & IS_LEVEL_1)
675    THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
676                     isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
677
678  if (circuit->is_type & IS_LEVEL_2)
679    THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
680                     isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
681
682  /* unified init for circuits; ignore warnings below this level */
683  retv = isis_sock_init (circuit);
684  if (retv != ISIS_OK)
685    {
686      isis_circuit_down (circuit);
687      return retv;
688    }
689
690  /* initialize the circuit streams after opening connection */
691  if (circuit->rcv_stream == NULL)
692    circuit->rcv_stream = stream_new (ISO_MTU (circuit));
693
694  if (circuit->snd_stream == NULL)
695    circuit->snd_stream = stream_new (ISO_MTU (circuit));
696
697#ifdef GNU_LINUX
698  THREAD_READ_ON (master, circuit->t_read, isis_receive, circuit,
699                  circuit->fd);
700#else
701  THREAD_TIMER_ON (master, circuit->t_read, isis_receive, circuit,
702                   circuit->fd);
703#endif
704
705  circuit->lsp_queue = list_new ();
706  circuit->lsp_queue_last_cleared = time (NULL);
707
708  return ISIS_OK;
709}
710
711void
712isis_circuit_down (struct isis_circuit *circuit)
713{
714  if (circuit->state != C_STATE_UP)
715    return;
716
717  /* Clear the flags for all the lsps of the circuit. */
718  isis_circuit_update_all_srmflags (circuit, 0);
719
720  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
721    {
722      /* destroy neighbour lists */
723      if (circuit->u.bc.lan_neighs[0])
724        {
725          list_delete (circuit->u.bc.lan_neighs[0]);
726          circuit->u.bc.lan_neighs[0] = NULL;
727        }
728      if (circuit->u.bc.lan_neighs[1])
729        {
730          list_delete (circuit->u.bc.lan_neighs[1]);
731          circuit->u.bc.lan_neighs[1] = NULL;
732        }
733      /* destroy adjacency databases */
734      if (circuit->u.bc.adjdb[0])
735        {
736          circuit->u.bc.adjdb[0]->del = isis_delete_adj;
737          list_delete (circuit->u.bc.adjdb[0]);
738          circuit->u.bc.adjdb[0] = NULL;
739        }
740      if (circuit->u.bc.adjdb[1])
741        {
742          circuit->u.bc.adjdb[1]->del = isis_delete_adj;
743          list_delete (circuit->u.bc.adjdb[1]);
744          circuit->u.bc.adjdb[1] = NULL;
745        }
746      if (circuit->u.bc.is_dr[0])
747        {
748          isis_dr_resign (circuit, 1);
749          circuit->u.bc.is_dr[0] = 0;
750        }
751      memset (circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1);
752      if (circuit->u.bc.is_dr[1])
753        {
754          isis_dr_resign (circuit, 2);
755          circuit->u.bc.is_dr[1] = 0;
756        }
757      memset (circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
758      memset (circuit->u.bc.snpa, 0, ETH_ALEN);
759
760      THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[0]);
761      THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[1]);
762      THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[0]);
763      THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[1]);
764      THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[0]);
765      THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[1]);
766    }
767  else if (circuit->circ_type == CIRCUIT_T_P2P)
768    {
769      isis_delete_adj (circuit->u.p2p.neighbor);
770      circuit->u.p2p.neighbor = NULL;
771      THREAD_TIMER_OFF (circuit->u.p2p.t_send_p2p_hello);
772    }
773
774  /* Cancel all active threads */
775  THREAD_TIMER_OFF (circuit->t_send_csnp[0]);
776  THREAD_TIMER_OFF (circuit->t_send_csnp[1]);
777  THREAD_TIMER_OFF (circuit->t_send_psnp[0]);
778  THREAD_TIMER_OFF (circuit->t_send_psnp[1]);
779  THREAD_OFF (circuit->t_read);
780
781  if (circuit->lsp_queue)
782    {
783      circuit->lsp_queue->del = NULL;
784      list_delete (circuit->lsp_queue);
785      circuit->lsp_queue = NULL;
786    }
787
788  /* send one gratuitous hello to spead up convergence */
789  if (circuit->is_type & IS_LEVEL_1)
790    send_hello (circuit, IS_LEVEL_1);
791  if (circuit->is_type & IS_LEVEL_2)
792    send_hello (circuit, IS_LEVEL_2);
793
794  circuit->upadjcount[0] = 0;
795  circuit->upadjcount[1] = 0;
796
797  /* close the socket */
798  if (circuit->fd)
799    {
800      close (circuit->fd);
801      circuit->fd = 0;
802    }
803
804  if (circuit->rcv_stream != NULL)
805    {
806      stream_free (circuit->rcv_stream);
807      circuit->rcv_stream = NULL;
808    }
809
810  if (circuit->snd_stream != NULL)
811    {
812      stream_free (circuit->snd_stream);
813      circuit->snd_stream = NULL;
814    }
815
816  thread_cancel_event (master, circuit);
817
818  return;
819}
820
821void
822circuit_update_nlpids (struct isis_circuit *circuit)
823{
824  circuit->nlpids.count = 0;
825
826  if (circuit->ip_router)
827    {
828      circuit->nlpids.nlpids[0] = NLPID_IP;
829      circuit->nlpids.count++;
830    }
831#ifdef HAVE_IPV6
832  if (circuit->ipv6_router)
833    {
834      circuit->nlpids.nlpids[circuit->nlpids.count] = NLPID_IPV6;
835      circuit->nlpids.count++;
836    }
837#endif /* HAVE_IPV6 */
838  return;
839}
840
841void
842isis_circuit_print_vty (struct isis_circuit *circuit, struct vty *vty,
843                        char detail)
844{
845  if (detail == ISIS_UI_LEVEL_BRIEF)
846    {
847      vty_out (vty, "  %-12s", circuit->interface->name);
848      vty_out (vty, "0x%-7x", circuit->circuit_id);
849      vty_out (vty, "%-9s", circuit_state2string (circuit->state));
850      vty_out (vty, "%-9s", circuit_type2string (circuit->circ_type));
851      vty_out (vty, "%-9s", circuit_t2string (circuit->is_type));
852      vty_out (vty, "%s", VTY_NEWLINE);
853    }
854
855  if (detail == ISIS_UI_LEVEL_DETAIL)
856    {
857      vty_out (vty, "  Interface: %s", circuit->interface->name);
858      vty_out (vty, ", State: %s", circuit_state2string (circuit->state));
859      if (circuit->is_passive)
860        vty_out (vty, ", Passive");
861      else
862        vty_out (vty, ", Active");
863      vty_out (vty, ", Circuit Id: 0x%x", circuit->circuit_id);
864      vty_out (vty, "%s", VTY_NEWLINE);
865      vty_out (vty, "    Type: %s", circuit_type2string (circuit->circ_type));
866      vty_out (vty, ", Level: %s", circuit_t2string (circuit->is_type));
867      if (circuit->circ_type == CIRCUIT_T_BROADCAST)
868        vty_out (vty, ", SNPA: %-10s", snpa_print (circuit->u.bc.snpa));
869      vty_out (vty, "%s", VTY_NEWLINE);
870      if (circuit->is_type & IS_LEVEL_1)
871        {
872          vty_out (vty, "    Level-1 Information:%s", VTY_NEWLINE);
873          if (circuit->area->newmetric)
874            vty_out (vty, "      Metric: %d", circuit->te_metric[0]);
875          else
876            vty_out (vty, "      Metric: %d",
877                     circuit->metrics[0].metric_default);
878          if (!circuit->is_passive)
879            {
880              vty_out (vty, ", Active neighbors: %u%s",
881                       circuit->upadjcount[0], VTY_NEWLINE);
882              vty_out (vty, "      Hello interval: %u, "
883                            "Holddown count: %u %s%s",
884                       circuit->hello_interval[0],
885                       circuit->hello_multiplier[0],
886                       (circuit->pad_hellos ? "(pad)" : "(no-pad)"),
887                       VTY_NEWLINE);
888              vty_out (vty, "      CNSP interval: %u, "
889                            "PSNP interval: %u%s",
890                       circuit->csnp_interval[0],
891                       circuit->psnp_interval[0], VTY_NEWLINE);
892              if (circuit->circ_type == CIRCUIT_T_BROADCAST)
893                vty_out (vty, "      LAN Priority: %u, %s%s",
894                         circuit->priority[0],
895                         (circuit->u.bc.is_dr[0] ? \
896                          "is DIS" : "is not DIS"), VTY_NEWLINE);
897            }
898          else
899            {
900              vty_out (vty, "%s", VTY_NEWLINE);
901            }
902        }
903      if (circuit->is_type & IS_LEVEL_2)
904        {
905          vty_out (vty, "    Level-2 Information:%s", VTY_NEWLINE);
906          if (circuit->area->newmetric)
907            vty_out (vty, "      Metric: %d", circuit->te_metric[1]);
908          else
909            vty_out (vty, "      Metric: %d",
910                     circuit->metrics[1].metric_default);
911          if (!circuit->is_passive)
912            {
913              vty_out (vty, ", Active neighbors: %u%s",
914                       circuit->upadjcount[1], VTY_NEWLINE);
915              vty_out (vty, "      Hello interval: %u, "
916                            "Holddown count: %u %s%s",
917                       circuit->hello_interval[1],
918                       circuit->hello_multiplier[1],
919                       (circuit->pad_hellos ? "(pad)" : "(no-pad)"),
920                       VTY_NEWLINE);
921              vty_out (vty, "      CNSP interval: %u, "
922                            "PSNP interval: %u%s",
923                       circuit->csnp_interval[1],
924                       circuit->psnp_interval[1], VTY_NEWLINE);
925              if (circuit->circ_type == CIRCUIT_T_BROADCAST)
926                vty_out (vty, "      LAN Priority: %u, %s%s",
927                         circuit->priority[1],
928                         (circuit->u.bc.is_dr[1] ? \
929                          "is DIS" : "is not DIS"), VTY_NEWLINE);
930            }
931          else
932            {
933              vty_out (vty, "%s", VTY_NEWLINE);
934            }
935        }
936      if (circuit->ip_addrs && listcount (circuit->ip_addrs) > 0)
937        {
938          struct listnode *node;
939          struct prefix *ip_addr;
940          u_char buf[BUFSIZ];
941          vty_out (vty, "    IP Prefix(es):%s", VTY_NEWLINE);
942          for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ip_addr))
943            {
944              prefix2str (ip_addr, (char*)buf, BUFSIZ),
945              vty_out (vty, "      %s%s", buf, VTY_NEWLINE);
946            }
947        }
948      vty_out (vty, "%s", VTY_NEWLINE);
949    }
950  return;
951}
952
953int
954isis_interface_config_write (struct vty *vty)
955{
956  int write = 0;
957  struct listnode *node, *node2;
958  struct interface *ifp;
959  struct isis_area *area;
960  struct isis_circuit *circuit;
961  int i;
962
963  for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
964    {
965      /* IF name */
966      vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
967      write++;
968      /* IF desc */
969      if (ifp->desc)
970        {
971          vty_out (vty, " description %s%s", ifp->desc, VTY_NEWLINE);
972          write++;
973        }
974      /* ISIS Circuit */
975      for (ALL_LIST_ELEMENTS_RO (isis->area_list, node2, area))
976        {
977          circuit = circuit_lookup_by_ifp (ifp, area->circuit_list);
978          if (circuit == NULL)
979            continue;
980          if (circuit->ip_router)
981            {
982              vty_out (vty, " ip router isis %s%s", area->area_tag,
983                       VTY_NEWLINE);
984              write++;
985            }
986          if (circuit->is_passive)
987            {
988              vty_out (vty, " isis passive%s", VTY_NEWLINE);
989              write++;
990            }
991          if (circuit->circ_type_config == CIRCUIT_T_P2P)
992            {
993              vty_out (vty, " isis network point-to-point%s", VTY_NEWLINE);
994              write++;
995            }
996#ifdef HAVE_IPV6
997          if (circuit->ipv6_router)
998            {
999              vty_out (vty, " ipv6 router isis %s%s", area->area_tag,
1000                  VTY_NEWLINE);
1001              write++;
1002            }
1003#endif /* HAVE_IPV6 */
1004
1005          /* ISIS - circuit type */
1006          if (circuit->is_type == IS_LEVEL_1)
1007            {
1008              vty_out (vty, " isis circuit-type level-1%s", VTY_NEWLINE);
1009              write++;
1010            }
1011          else
1012            {
1013              if (circuit->is_type == IS_LEVEL_2)
1014                {
1015                  vty_out (vty, " isis circuit-type level-2-only%s",
1016                           VTY_NEWLINE);
1017                  write++;
1018                }
1019            }
1020
1021          /* ISIS - CSNP interval */
1022          if (circuit->csnp_interval[0] == circuit->csnp_interval[1])
1023            {
1024              if (circuit->csnp_interval[0] != DEFAULT_CSNP_INTERVAL)
1025                {
1026                  vty_out (vty, " isis csnp-interval %d%s",
1027                           circuit->csnp_interval[0], VTY_NEWLINE);
1028                  write++;
1029                }
1030            }
1031          else
1032          {
1033            for (i = 0; i < 2; i++)
1034              {
1035                if (circuit->csnp_interval[i] != DEFAULT_CSNP_INTERVAL)
1036                  {
1037                    vty_out (vty, " isis csnp-interval %d level-%d%s",
1038                             circuit->csnp_interval[i], i + 1, VTY_NEWLINE);
1039                    write++;
1040                  }
1041              }
1042          }
1043
1044          /* ISIS - PSNP interval */
1045          if (circuit->psnp_interval[0] == circuit->psnp_interval[1])
1046            {
1047              if (circuit->psnp_interval[0] != DEFAULT_PSNP_INTERVAL)
1048                {
1049                  vty_out (vty, " isis psnp-interval %d%s",
1050                           circuit->psnp_interval[0], VTY_NEWLINE);
1051                  write++;
1052                }
1053            }
1054          else
1055            {
1056              for (i = 0; i < 2; i++)
1057                {
1058                  if (circuit->psnp_interval[i] != DEFAULT_PSNP_INTERVAL)
1059                  {
1060                    vty_out (vty, " isis psnp-interval %d level-%d%s",
1061                             circuit->psnp_interval[i], i + 1, VTY_NEWLINE);
1062                    write++;
1063                  }
1064                }
1065            }
1066
1067          /* ISIS - Hello padding - Defaults to true so only display if false */
1068          if (circuit->pad_hellos == 0)
1069            {
1070              vty_out (vty, " no isis hello padding%s", VTY_NEWLINE);
1071              write++;
1072            }
1073
1074          /* ISIS - Hello interval */
1075          if (circuit->hello_interval[0] == circuit->hello_interval[1])
1076            {
1077              if (circuit->hello_interval[0] != DEFAULT_HELLO_INTERVAL)
1078                {
1079                  vty_out (vty, " isis hello-interval %d%s",
1080                           circuit->hello_interval[0], VTY_NEWLINE);
1081                  write++;
1082                }
1083            }
1084          else
1085            {
1086              for (i = 0; i < 2; i++)
1087                {
1088                  if (circuit->hello_interval[i] != DEFAULT_HELLO_INTERVAL)
1089                    {
1090                      vty_out (vty, " isis hello-interval %d level-%d%s",
1091                               circuit->hello_interval[i], i + 1, VTY_NEWLINE);
1092                      write++;
1093                    }
1094                }
1095            }
1096
1097          /* ISIS - Hello Multiplier */
1098          if (circuit->hello_multiplier[0] == circuit->hello_multiplier[1])
1099            {
1100              if (circuit->hello_multiplier[0] != DEFAULT_HELLO_MULTIPLIER)
1101                {
1102                  vty_out (vty, " isis hello-multiplier %d%s",
1103                           circuit->hello_multiplier[0], VTY_NEWLINE);
1104                  write++;
1105                }
1106            }
1107          else
1108            {
1109              for (i = 0; i < 2; i++)
1110                {
1111                  if (circuit->hello_multiplier[i] != DEFAULT_HELLO_MULTIPLIER)
1112                    {
1113                      vty_out (vty, " isis hello-multiplier %d level-%d%s",
1114                               circuit->hello_multiplier[i], i + 1,
1115                               VTY_NEWLINE);
1116                      write++;
1117                    }
1118                }
1119            }
1120
1121          /* ISIS - Priority */
1122          if (circuit->priority[0] == circuit->priority[1])
1123            {
1124              if (circuit->priority[0] != DEFAULT_PRIORITY)
1125                {
1126                  vty_out (vty, " isis priority %d%s",
1127                           circuit->priority[0], VTY_NEWLINE);
1128                  write++;
1129                }
1130            }
1131          else
1132            {
1133              for (i = 0; i < 2; i++)
1134                {
1135                  if (circuit->priority[i] != DEFAULT_PRIORITY)
1136                    {
1137                      vty_out (vty, " isis priority %d level-%d%s",
1138                               circuit->priority[i], i + 1, VTY_NEWLINE);
1139                      write++;
1140                    }
1141                }
1142            }
1143
1144          /* ISIS - Metric */
1145          if (circuit->te_metric[0] == circuit->te_metric[1])
1146            {
1147              if (circuit->te_metric[0] != DEFAULT_CIRCUIT_METRIC)
1148                {
1149                  vty_out (vty, " isis metric %d%s", circuit->te_metric[0],
1150                           VTY_NEWLINE);
1151                  write++;
1152                }
1153            }
1154          else
1155            {
1156              for (i = 0; i < 2; i++)
1157                {
1158                  if (circuit->te_metric[i] != DEFAULT_CIRCUIT_METRIC)
1159                    {
1160                      vty_out (vty, " isis metric %d level-%d%s",
1161                               circuit->te_metric[i], i + 1, VTY_NEWLINE);
1162                      write++;
1163                    }
1164                }
1165            }
1166          if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5)
1167            {
1168              vty_out (vty, " isis password md5 %s%s", circuit->passwd.passwd,
1169                       VTY_NEWLINE);
1170              write++;
1171            }
1172          else if (circuit->passwd.type == ISIS_PASSWD_TYPE_CLEARTXT)
1173            {
1174              vty_out (vty, " isis password clear %s%s", circuit->passwd.passwd,
1175                       VTY_NEWLINE);
1176              write++;
1177            }
1178        }
1179      vty_out (vty, "!%s", VTY_NEWLINE);
1180    }
1181
1182  return write;
1183}
1184
1185DEFUN (ip_router_isis,
1186       ip_router_isis_cmd,
1187       "ip router isis WORD",
1188       "Interface Internet Protocol config commands\n"
1189       "IP router interface commands\n"
1190       "IS-IS Routing for IP\n"
1191       "Routing process tag\n")
1192{
1193  struct isis_circuit *circuit;
1194  struct interface *ifp;
1195  struct isis_area *area;
1196
1197  ifp = (struct interface *) vty->index;
1198  assert (ifp);
1199
1200  /* Prevent more than one area per circuit */
1201  circuit = circuit_scan_by_ifp (ifp);
1202  if (circuit)
1203    {
1204      if (circuit->ip_router == 1)
1205        {
1206          if (strcmp (circuit->area->area_tag, argv[0]))
1207            {
1208              vty_out (vty, "ISIS circuit is already defined on %s%s",
1209                       circuit->area->area_tag, VTY_NEWLINE);
1210              return CMD_ERR_NOTHING_TODO;
1211            }
1212          return CMD_SUCCESS;
1213        }
1214    }
1215
1216  if (isis_area_get (vty, argv[0]) != CMD_SUCCESS)
1217    {
1218      vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
1219      return CMD_ERR_NO_MATCH;
1220    }
1221  area = vty->index;
1222
1223  circuit = isis_csm_state_change (ISIS_ENABLE, circuit, area);
1224  isis_circuit_if_bind (circuit, ifp);
1225
1226  circuit->ip_router = 1;
1227  area->ip_circuits++;
1228  circuit_update_nlpids (circuit);
1229
1230  vty->node = INTERFACE_NODE;
1231  vty->index = ifp;
1232
1233  return CMD_SUCCESS;
1234}
1235
1236DEFUN (no_ip_router_isis,
1237       no_ip_router_isis_cmd,
1238       "no ip router isis WORD",
1239       NO_STR
1240       "Interface Internet Protocol config commands\n"
1241       "IP router interface commands\n"
1242       "IS-IS Routing for IP\n"
1243       "Routing process tag\n")
1244{
1245  struct interface *ifp;
1246  struct isis_area *area;
1247  struct isis_circuit *circuit;
1248
1249  ifp = (struct interface *) vty->index;
1250  if (!ifp)
1251    {
1252      vty_out (vty, "Invalid interface %s", VTY_NEWLINE);
1253      return CMD_ERR_NO_MATCH;
1254    }
1255
1256  area = isis_area_lookup (argv[0]);
1257  if (!area)
1258    {
1259      vty_out (vty, "Can't find ISIS instance %s%s",
1260               argv[0], VTY_NEWLINE);
1261      return CMD_ERR_NO_MATCH;
1262    }
1263
1264  circuit = circuit_lookup_by_ifp (ifp, area->circuit_list);
1265  if (!circuit)
1266    {
1267      vty_out (vty, "ISIS is not enabled on circuit %s%s",
1268               ifp->name, VTY_NEWLINE);
1269      return CMD_ERR_NO_MATCH;
1270    }
1271
1272  circuit->ip_router = 0;
1273  area->ip_circuits--;
1274#ifdef HAVE_IPV6
1275  if (circuit->ipv6_router == 0)
1276#endif
1277    isis_csm_state_change (ISIS_DISABLE, circuit, area);
1278
1279  return CMD_SUCCESS;
1280}
1281
1282#ifdef HAVE_IPV6
1283DEFUN (ipv6_router_isis,
1284       ipv6_router_isis_cmd,
1285       "ipv6 router isis WORD",
1286       "IPv6 interface subcommands\n"
1287       "IPv6 Router interface commands\n"
1288       "IS-IS Routing for IPv6\n"
1289       "Routing process tag\n")
1290{
1291  struct isis_circuit *circuit;
1292  struct interface *ifp;
1293  struct isis_area *area;
1294
1295  ifp = (struct interface *) vty->index;
1296  assert (ifp);
1297
1298  /* Prevent more than one area per circuit */
1299  circuit = circuit_scan_by_ifp (ifp);
1300  if (circuit)
1301    {
1302      if (circuit->ipv6_router == 1)
1303      {
1304        if (strcmp (circuit->area->area_tag, argv[0]))
1305          {
1306            vty_out (vty, "ISIS circuit is already defined for IPv6 on %s%s",
1307                     circuit->area->area_tag, VTY_NEWLINE);
1308            return CMD_ERR_NOTHING_TODO;
1309          }
1310        return CMD_SUCCESS;
1311      }
1312    }
1313
1314  if (isis_area_get (vty, argv[0]) != CMD_SUCCESS)
1315    {
1316      vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
1317      return CMD_ERR_NO_MATCH;
1318    }
1319  area = vty->index;
1320
1321  circuit = isis_csm_state_change (ISIS_ENABLE, circuit, area);
1322  isis_circuit_if_bind (circuit, ifp);
1323
1324  circuit->ipv6_router = 1;
1325  area->ipv6_circuits++;
1326  circuit_update_nlpids (circuit);
1327
1328  vty->node = INTERFACE_NODE;
1329  vty->index = ifp;
1330
1331  return CMD_SUCCESS;
1332}
1333
1334DEFUN (no_ipv6_router_isis,
1335       no_ipv6_router_isis_cmd,
1336       "no ipv6 router isis WORD",
1337       NO_STR
1338       "IPv6 interface subcommands\n"
1339       "IPv6 Router interface commands\n"
1340       "IS-IS Routing for IPv6\n"
1341       "Routing process tag\n")
1342{
1343  struct interface *ifp;
1344  struct isis_area *area;
1345  struct listnode *node;
1346  struct isis_circuit *circuit;
1347
1348  ifp = (struct interface *) vty->index;
1349  if (!ifp)
1350    {
1351      vty_out (vty, "Invalid interface %s", VTY_NEWLINE);
1352      return CMD_ERR_NO_MATCH;
1353    }
1354
1355  area = isis_area_lookup (argv[0]);
1356  if (!area)
1357    {
1358      vty_out (vty, "Can't find ISIS instance %s%s",
1359               argv[0], VTY_NEWLINE);
1360      return CMD_ERR_NO_MATCH;
1361    }
1362
1363  circuit = circuit_lookup_by_ifp (ifp, area->circuit_list);
1364  if (!circuit)
1365    {
1366      vty_out (vty, "ISIS is not enabled on circuit %s%s",
1367               ifp->name, VTY_NEWLINE);
1368      return CMD_ERR_NO_MATCH;
1369    }
1370
1371  circuit->ipv6_router = 0;
1372  area->ipv6_circuits--;
1373  if (circuit->ip_router == 0)
1374    isis_csm_state_change (ISIS_DISABLE, circuit, area);
1375
1376  return CMD_SUCCESS;
1377}
1378#endif /* HAVE_IPV6 */
1379
1380DEFUN (isis_passive,
1381       isis_passive_cmd,
1382       "isis passive",
1383       "IS-IS commands\n"
1384       "Configure the passive mode for interface\n")
1385{
1386  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1387  if (!circuit)
1388    return CMD_ERR_NO_MATCH;
1389
1390  if (circuit->is_passive == 1)
1391    return CMD_SUCCESS;
1392
1393  if (circuit->state != C_STATE_UP)
1394    {
1395      circuit->is_passive = 1;
1396    }
1397  else
1398    {
1399      struct isis_area *area = circuit->area;
1400      isis_csm_state_change (ISIS_DISABLE, circuit, area);
1401      circuit->is_passive = 1;
1402      isis_csm_state_change (ISIS_ENABLE, circuit, area);
1403    }
1404
1405  return CMD_SUCCESS;
1406}
1407
1408DEFUN (no_isis_passive,
1409       no_isis_passive_cmd,
1410       "no isis passive",
1411       NO_STR
1412       "IS-IS commands\n"
1413       "Configure the passive mode for interface\n")
1414{
1415  struct interface *ifp;
1416  struct isis_circuit *circuit;
1417
1418  ifp = (struct interface *) vty->index;
1419  if (!ifp)
1420    {
1421      vty_out (vty, "Invalid interface %s", VTY_NEWLINE);
1422      return CMD_ERR_NO_MATCH;
1423    }
1424
1425  /* FIXME: what is wrong with circuit = ifp->info ? */
1426  circuit = circuit_scan_by_ifp (ifp);
1427  if (!circuit)
1428    {
1429      vty_out (vty, "ISIS is not enabled on circuit %s%s",
1430               ifp->name, VTY_NEWLINE);
1431      return CMD_ERR_NO_MATCH;
1432    }
1433
1434  if (if_is_loopback(ifp))
1435    {
1436      vty_out (vty, "Can't set no passive for loopback interface%s",
1437               VTY_NEWLINE);
1438      return CMD_ERR_AMBIGUOUS;
1439    }
1440
1441  if (circuit->is_passive == 0)
1442    return CMD_SUCCESS;
1443
1444  if (circuit->state != C_STATE_UP)
1445    {
1446      circuit->is_passive = 0;
1447    }
1448  else
1449    {
1450      struct isis_area *area = circuit->area;
1451      isis_csm_state_change (ISIS_DISABLE, circuit, area);
1452      circuit->is_passive = 0;
1453      isis_csm_state_change (ISIS_ENABLE, circuit, area);
1454    }
1455
1456  return CMD_SUCCESS;
1457}
1458
1459DEFUN (isis_circuit_type,
1460       isis_circuit_type_cmd,
1461       "isis circuit-type (level-1|level-1-2|level-2-only)",
1462       "IS-IS commands\n"
1463       "Configure circuit type for interface\n"
1464       "Level-1 only adjacencies are formed\n"
1465       "Level-1-2 adjacencies are formed\n"
1466       "Level-2 only adjacencies are formed\n")
1467{
1468  int circuit_type;
1469  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1470  if (!circuit)
1471    return CMD_ERR_NO_MATCH;
1472
1473  circuit_type = string2circuit_t (argv[0]);
1474  if (!circuit_type)
1475    {
1476      vty_out (vty, "Unknown circuit-type %s", VTY_NEWLINE);
1477      return CMD_ERR_AMBIGUOUS;
1478    }
1479
1480  if (circuit->state == C_STATE_UP &&
1481      circuit->area->is_type != IS_LEVEL_1_AND_2 &&
1482      circuit->area->is_type != circuit_type)
1483    {
1484      vty_out (vty, "Invalid circuit level for area %s.%s",
1485               circuit->area->area_tag, VTY_NEWLINE);
1486      return CMD_ERR_AMBIGUOUS;
1487    }
1488  isis_event_circuit_type_change (circuit, circuit_type);
1489
1490  return CMD_SUCCESS;
1491}
1492
1493DEFUN (no_isis_circuit_type,
1494       no_isis_circuit_type_cmd,
1495       "no isis circuit-type (level-1|level-1-2|level-2-only)",
1496       NO_STR
1497       "IS-IS commands\n"
1498       "Configure circuit type for interface\n"
1499       "Level-1 only adjacencies are formed\n"
1500       "Level-1-2 adjacencies are formed\n"
1501       "Level-2 only adjacencies are formed\n")
1502{
1503  int circuit_type;
1504  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1505  if (!circuit)
1506    return CMD_ERR_NO_MATCH;
1507
1508  /*
1509   * Set the circuits level to its default value
1510   */
1511  if (circuit->state == C_STATE_UP)
1512    circuit_type = circuit->area->is_type;
1513  else
1514    circuit_type = IS_LEVEL_1_AND_2;
1515  isis_event_circuit_type_change (circuit, circuit_type);
1516
1517  return CMD_SUCCESS;
1518}
1519
1520DEFUN (isis_passwd_md5,
1521       isis_passwd_md5_cmd,
1522       "isis password md5 WORD",
1523       "IS-IS commands\n"
1524       "Configure the authentication password for a circuit\n"
1525       "Authentication type\n"
1526       "Circuit password\n")
1527{
1528  int len;
1529  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1530  if (!circuit)
1531    return CMD_ERR_NO_MATCH;
1532
1533  len = strlen (argv[0]);
1534  if (len > 254)
1535    {
1536      vty_out (vty, "Too long circuit password (>254)%s", VTY_NEWLINE);
1537      return CMD_ERR_AMBIGUOUS;
1538    }
1539  circuit->passwd.len = len;
1540  circuit->passwd.type = ISIS_PASSWD_TYPE_HMAC_MD5;
1541  strncpy ((char *)circuit->passwd.passwd, argv[0], 255);
1542
1543  return CMD_SUCCESS;
1544}
1545
1546DEFUN (isis_passwd_clear,
1547       isis_passwd_clear_cmd,
1548       "isis password clear WORD",
1549       "IS-IS commands\n"
1550       "Configure the authentication password for a circuit\n"
1551       "Authentication type\n"
1552       "Circuit password\n")
1553{
1554  int len;
1555  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1556  if (!circuit)
1557    return CMD_ERR_NO_MATCH;
1558
1559  len = strlen (argv[0]);
1560  if (len > 254)
1561    {
1562      vty_out (vty, "Too long circuit password (>254)%s", VTY_NEWLINE);
1563      return CMD_ERR_AMBIGUOUS;
1564    }
1565  circuit->passwd.len = len;
1566  circuit->passwd.type = ISIS_PASSWD_TYPE_CLEARTXT;
1567  strncpy ((char *)circuit->passwd.passwd, argv[0], 255);
1568
1569  return CMD_SUCCESS;
1570}
1571
1572DEFUN (no_isis_passwd,
1573       no_isis_passwd_cmd,
1574       "no isis password",
1575       NO_STR
1576       "IS-IS commands\n"
1577       "Configure the authentication password for a circuit\n")
1578{
1579  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1580  if (!circuit)
1581    return CMD_ERR_NO_MATCH;
1582
1583  memset (&circuit->passwd, 0, sizeof (struct isis_passwd));
1584
1585  return CMD_SUCCESS;
1586}
1587
1588DEFUN (isis_priority,
1589       isis_priority_cmd,
1590       "isis priority <0-127>",
1591       "IS-IS commands\n"
1592       "Set priority for Designated Router election\n"
1593       "Priority value\n")
1594{
1595  int prio;
1596  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1597  if (!circuit)
1598    return CMD_ERR_NO_MATCH;
1599
1600  prio = atoi (argv[0]);
1601  if (prio < MIN_PRIORITY || prio > MAX_PRIORITY)
1602    {
1603      vty_out (vty, "Invalid priority %d - should be <0-127>%s",
1604               prio, VTY_NEWLINE);
1605      return CMD_ERR_AMBIGUOUS;
1606    }
1607
1608  circuit->priority[0] = prio;
1609  circuit->priority[1] = prio;
1610
1611  return CMD_SUCCESS;
1612}
1613
1614DEFUN (no_isis_priority,
1615       no_isis_priority_cmd,
1616       "no isis priority",
1617       NO_STR
1618       "IS-IS commands\n"
1619       "Set priority for Designated Router election\n")
1620{
1621  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1622  if (!circuit)
1623    return CMD_ERR_NO_MATCH;
1624
1625  circuit->priority[0] = DEFAULT_PRIORITY;
1626  circuit->priority[1] = DEFAULT_PRIORITY;
1627
1628  return CMD_SUCCESS;
1629}
1630
1631ALIAS (no_isis_priority,
1632       no_isis_priority_arg_cmd,
1633       "no isis priority <0-127>",
1634       NO_STR
1635       "IS-IS commands\n"
1636       "Set priority for Designated Router election\n"
1637       "Priority value\n")
1638
1639DEFUN (isis_priority_l1,
1640       isis_priority_l1_cmd,
1641       "isis priority <0-127> level-1",
1642       "IS-IS commands\n"
1643       "Set priority for Designated Router election\n"
1644       "Priority value\n"
1645       "Specify priority for level-1 routing\n")
1646{
1647  int prio;
1648  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1649  if (!circuit)
1650    return CMD_ERR_NO_MATCH;
1651
1652  prio = atoi (argv[0]);
1653  if (prio < MIN_PRIORITY || prio > MAX_PRIORITY)
1654    {
1655      vty_out (vty, "Invalid priority %d - should be <0-127>%s",
1656               prio, VTY_NEWLINE);
1657      return CMD_ERR_AMBIGUOUS;
1658    }
1659
1660  circuit->priority[0] = prio;
1661
1662  return CMD_SUCCESS;
1663}
1664
1665DEFUN (no_isis_priority_l1,
1666       no_isis_priority_l1_cmd,
1667       "no isis priority level-1",
1668       NO_STR
1669       "IS-IS commands\n"
1670       "Set priority for Designated Router election\n"
1671       "Specify priority for level-1 routing\n")
1672{
1673  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1674  if (!circuit)
1675    return CMD_ERR_NO_MATCH;
1676
1677  circuit->priority[0] = DEFAULT_PRIORITY;
1678
1679  return CMD_SUCCESS;
1680}
1681
1682ALIAS (no_isis_priority_l1,
1683       no_isis_priority_l1_arg_cmd,
1684       "no isis priority <0-127> level-1",
1685       NO_STR
1686       "IS-IS commands\n"
1687       "Set priority for Designated Router election\n"
1688       "Priority value\n"
1689       "Specify priority for level-1 routing\n")
1690
1691DEFUN (isis_priority_l2,
1692       isis_priority_l2_cmd,
1693       "isis priority <0-127> level-2",
1694       "IS-IS commands\n"
1695       "Set priority for Designated Router election\n"
1696       "Priority value\n"
1697       "Specify priority for level-2 routing\n")
1698{
1699  int prio;
1700  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1701  if (!circuit)
1702    return CMD_ERR_NO_MATCH;
1703
1704  prio = atoi (argv[0]);
1705  if (prio < MIN_PRIORITY || prio > MAX_PRIORITY)
1706    {
1707      vty_out (vty, "Invalid priority %d - should be <0-127>%s",
1708               prio, VTY_NEWLINE);
1709      return CMD_ERR_AMBIGUOUS;
1710    }
1711
1712  circuit->priority[1] = prio;
1713
1714  return CMD_SUCCESS;
1715}
1716
1717DEFUN (no_isis_priority_l2,
1718       no_isis_priority_l2_cmd,
1719       "no isis priority level-2",
1720       NO_STR
1721       "IS-IS commands\n"
1722       "Set priority for Designated Router election\n"
1723       "Specify priority for level-2 routing\n")
1724{
1725  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1726  if (!circuit)
1727    return CMD_ERR_NO_MATCH;
1728
1729  circuit->priority[1] = DEFAULT_PRIORITY;
1730
1731  return CMD_SUCCESS;
1732}
1733
1734ALIAS (no_isis_priority_l2,
1735       no_isis_priority_l2_arg_cmd,
1736       "no isis priority <0-127> level-2",
1737       NO_STR
1738       "IS-IS commands\n"
1739       "Set priority for Designated Router election\n"
1740       "Priority value\n"
1741       "Specify priority for level-2 routing\n")
1742
1743/* Metric command */
1744DEFUN (isis_metric,
1745       isis_metric_cmd,
1746       "isis metric <0-16777215>",
1747       "IS-IS commands\n"
1748       "Set default metric for circuit\n"
1749       "Default metric value\n")
1750{
1751  int met;
1752  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1753  if (!circuit)
1754    return CMD_ERR_NO_MATCH;
1755
1756  met = atoi (argv[0]);
1757
1758  /* RFC3787 section 5.1 */
1759  if (circuit->area && circuit->area->oldmetric == 1 &&
1760      met > MAX_NARROW_LINK_METRIC)
1761    {
1762      vty_out (vty, "Invalid metric %d - should be <0-63> "
1763               "when narrow metric type enabled%s",
1764               met, VTY_NEWLINE);
1765      return CMD_ERR_AMBIGUOUS;
1766    }
1767
1768  /* RFC4444 */
1769  if (circuit->area && circuit->area->newmetric == 1 &&
1770      met > MAX_WIDE_LINK_METRIC)
1771    {
1772      vty_out (vty, "Invalid metric %d - should be <0-16777215> "
1773               "when wide metric type enabled%s",
1774               met, VTY_NEWLINE);
1775      return CMD_ERR_AMBIGUOUS;
1776    }
1777
1778  circuit->te_metric[0] = met;
1779  circuit->te_metric[1] = met;
1780
1781  circuit->metrics[0].metric_default = met;
1782  circuit->metrics[1].metric_default = met;
1783
1784  if (circuit->area)
1785    lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
1786
1787  return CMD_SUCCESS;
1788}
1789
1790DEFUN (no_isis_metric,
1791       no_isis_metric_cmd,
1792       "no isis metric",
1793       NO_STR
1794       "IS-IS commands\n"
1795       "Set default metric for circuit\n")
1796{
1797  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1798  if (!circuit)
1799    return CMD_ERR_NO_MATCH;
1800
1801  circuit->te_metric[0] = DEFAULT_CIRCUIT_METRIC;
1802  circuit->te_metric[1] = DEFAULT_CIRCUIT_METRIC;
1803  circuit->metrics[0].metric_default = DEFAULT_CIRCUIT_METRIC;
1804  circuit->metrics[1].metric_default = DEFAULT_CIRCUIT_METRIC;
1805
1806  if (circuit->area)
1807    lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
1808
1809  return CMD_SUCCESS;
1810}
1811
1812ALIAS (no_isis_metric,
1813       no_isis_metric_arg_cmd,
1814       "no isis metric <0-16777215>",
1815       NO_STR
1816       "IS-IS commands\n"
1817       "Set default metric for circuit\n"
1818       "Default metric value\n")
1819
1820DEFUN (isis_metric_l1,
1821       isis_metric_l1_cmd,
1822       "isis metric <0-16777215> level-1",
1823       "IS-IS commands\n"
1824       "Set default metric for circuit\n"
1825       "Default metric value\n"
1826       "Specify metric for level-1 routing\n")
1827{
1828  int met;
1829  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1830  if (!circuit)
1831    return CMD_ERR_NO_MATCH;
1832
1833  met = atoi (argv[0]);
1834
1835  /* RFC3787 section 5.1 */
1836  if (circuit->area && circuit->area->oldmetric == 1 &&
1837      met > MAX_NARROW_LINK_METRIC)
1838    {
1839      vty_out (vty, "Invalid metric %d - should be <0-63> "
1840               "when narrow metric type enabled%s",
1841               met, VTY_NEWLINE);
1842      return CMD_ERR_AMBIGUOUS;
1843    }
1844
1845  /* RFC4444 */
1846  if (circuit->area && circuit->area->newmetric == 1 &&
1847      met > MAX_WIDE_LINK_METRIC)
1848    {
1849      vty_out (vty, "Invalid metric %d - should be <0-16777215> "
1850               "when wide metric type enabled%s",
1851               met, VTY_NEWLINE);
1852      return CMD_ERR_AMBIGUOUS;
1853    }
1854
1855  circuit->te_metric[0] = met;
1856  circuit->metrics[0].metric_default = met;
1857
1858  if (circuit->area)
1859    lsp_regenerate_schedule (circuit->area, IS_LEVEL_1, 0);
1860
1861  return CMD_SUCCESS;
1862}
1863
1864DEFUN (no_isis_metric_l1,
1865       no_isis_metric_l1_cmd,
1866       "no isis metric level-1",
1867       NO_STR
1868       "IS-IS commands\n"
1869       "Set default metric for circuit\n"
1870       "Specify metric for level-1 routing\n")
1871{
1872  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1873  if (!circuit)
1874    return CMD_ERR_NO_MATCH;
1875
1876  circuit->te_metric[0] = DEFAULT_CIRCUIT_METRIC;
1877  circuit->metrics[0].metric_default = DEFAULT_CIRCUIT_METRIC;
1878
1879  if (circuit->area)
1880    lsp_regenerate_schedule (circuit->area, IS_LEVEL_1, 0);
1881
1882  return CMD_SUCCESS;
1883}
1884
1885ALIAS (no_isis_metric_l1,
1886       no_isis_metric_l1_arg_cmd,
1887       "no isis metric <0-16777215> level-1",
1888       NO_STR
1889       "IS-IS commands\n"
1890       "Set default metric for circuit\n"
1891       "Default metric value\n"
1892       "Specify metric for level-1 routing\n")
1893
1894DEFUN (isis_metric_l2,
1895       isis_metric_l2_cmd,
1896       "isis metric <0-16777215> level-2",
1897       "IS-IS commands\n"
1898       "Set default metric for circuit\n"
1899       "Default metric value\n"
1900       "Specify metric for level-2 routing\n")
1901{
1902  int met;
1903  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1904  if (!circuit)
1905    return CMD_ERR_NO_MATCH;
1906
1907  met = atoi (argv[0]);
1908
1909  /* RFC3787 section 5.1 */
1910  if (circuit->area && circuit->area->oldmetric == 1 &&
1911      met > MAX_NARROW_LINK_METRIC)
1912    {
1913      vty_out (vty, "Invalid metric %d - should be <0-63> "
1914               "when narrow metric type enabled%s",
1915               met, VTY_NEWLINE);
1916      return CMD_ERR_AMBIGUOUS;
1917    }
1918
1919  /* RFC4444 */
1920  if (circuit->area && circuit->area->newmetric == 1 &&
1921      met > MAX_WIDE_LINK_METRIC)
1922    {
1923      vty_out (vty, "Invalid metric %d - should be <0-16777215> "
1924               "when wide metric type enabled%s",
1925               met, VTY_NEWLINE);
1926      return CMD_ERR_AMBIGUOUS;
1927    }
1928
1929  circuit->te_metric[1] = met;
1930  circuit->metrics[1].metric_default = met;
1931
1932  if (circuit->area)
1933    lsp_regenerate_schedule (circuit->area, IS_LEVEL_2, 0);
1934
1935  return CMD_SUCCESS;
1936}
1937
1938DEFUN (no_isis_metric_l2,
1939       no_isis_metric_l2_cmd,
1940       "no isis metric level-2",
1941       NO_STR
1942       "IS-IS commands\n"
1943       "Set default metric for circuit\n"
1944       "Specify metric for level-2 routing\n")
1945{
1946  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1947  if (!circuit)
1948    return CMD_ERR_NO_MATCH;
1949
1950  circuit->te_metric[1] = DEFAULT_CIRCUIT_METRIC;
1951  circuit->metrics[1].metric_default = DEFAULT_CIRCUIT_METRIC;
1952
1953  if (circuit->area)
1954    lsp_regenerate_schedule (circuit->area, IS_LEVEL_2, 0);
1955
1956  return CMD_SUCCESS;
1957}
1958
1959ALIAS (no_isis_metric_l2,
1960       no_isis_metric_l2_arg_cmd,
1961       "no isis metric <0-16777215> level-2",
1962       NO_STR
1963       "IS-IS commands\n"
1964       "Set default metric for circuit\n"
1965       "Default metric value\n"
1966       "Specify metric for level-2 routing\n")
1967/* end of metrics */
1968
1969DEFUN (isis_hello_interval,
1970       isis_hello_interval_cmd,
1971       "isis hello-interval <1-600>",
1972       "IS-IS commands\n"
1973       "Set Hello interval\n"
1974       "Hello interval value\n"
1975       "Holdtime 1 seconds, interval depends on multiplier\n")
1976{
1977  int interval;
1978  struct isis_circuit *circuit = isis_circuit_lookup (vty);
1979  if (!circuit)
1980    return CMD_ERR_NO_MATCH;
1981
1982  interval = atoi (argv[0]);
1983  if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL)
1984    {
1985      vty_out (vty, "Invalid hello-interval %d - should be <1-600>%s",
1986               interval, VTY_NEWLINE);
1987      return CMD_ERR_AMBIGUOUS;
1988    }
1989
1990  circuit->hello_interval[0] = (u_int16_t) interval;
1991  circuit->hello_interval[1] = (u_int16_t) interval;
1992
1993  return CMD_SUCCESS;
1994}
1995
1996DEFUN (no_isis_hello_interval,
1997       no_isis_hello_interval_cmd,
1998       "no isis hello-interval",
1999       NO_STR
2000       "IS-IS commands\n"
2001       "Set Hello interval\n")
2002{
2003  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2004  if (!circuit)
2005    return CMD_ERR_NO_MATCH;
2006
2007  circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL;
2008  circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL;
2009
2010  return CMD_SUCCESS;
2011}
2012
2013ALIAS (no_isis_hello_interval,
2014       no_isis_hello_interval_arg_cmd,
2015       "no isis hello-interval <1-600>",
2016       NO_STR
2017       "IS-IS commands\n"
2018       "Set Hello interval\n"
2019       "Hello interval value\n"
2020       "Holdtime 1 second, interval depends on multiplier\n")
2021
2022DEFUN (isis_hello_interval_l1,
2023       isis_hello_interval_l1_cmd,
2024       "isis hello-interval <1-600> level-1",
2025       "IS-IS commands\n"
2026       "Set Hello interval\n"
2027       "Hello interval value\n"
2028       "Holdtime 1 second, interval depends on multiplier\n"
2029       "Specify hello-interval for level-1 IIHs\n")
2030{
2031  long interval;
2032  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2033  if (!circuit)
2034    return CMD_ERR_NO_MATCH;
2035
2036  interval = atoi (argv[0]);
2037  if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL)
2038    {
2039      vty_out (vty, "Invalid hello-interval %ld - should be <1-600>%s",
2040               interval, VTY_NEWLINE);
2041      return CMD_ERR_AMBIGUOUS;
2042    }
2043
2044  circuit->hello_interval[0] = (u_int16_t) interval;
2045
2046  return CMD_SUCCESS;
2047}
2048
2049DEFUN (no_isis_hello_interval_l1,
2050       no_isis_hello_interval_l1_cmd,
2051       "no isis hello-interval level-1",
2052       NO_STR
2053       "IS-IS commands\n"
2054       "Set Hello interval\n"
2055       "Specify hello-interval for level-1 IIHs\n")
2056{
2057  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2058  if (!circuit)
2059    return CMD_ERR_NO_MATCH;
2060
2061  circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL;
2062
2063  return CMD_SUCCESS;
2064}
2065
2066ALIAS (no_isis_hello_interval_l1,
2067       no_isis_hello_interval_l1_arg_cmd,
2068       "no isis hello-interval <1-600> level-1",
2069       NO_STR
2070       "IS-IS commands\n"
2071       "Set Hello interval\n"
2072       "Hello interval value\n"
2073       "Holdtime 1 second, interval depends on multiplier\n"
2074       "Specify hello-interval for level-1 IIHs\n")
2075
2076DEFUN (isis_hello_interval_l2,
2077       isis_hello_interval_l2_cmd,
2078       "isis hello-interval <1-600> level-2",
2079       "IS-IS commands\n"
2080       "Set Hello interval\n"
2081       "Hello interval value\n"
2082       "Holdtime 1 second, interval depends on multiplier\n"
2083       "Specify hello-interval for level-2 IIHs\n")
2084{
2085  long interval;
2086  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2087  if (!circuit)
2088    return CMD_ERR_NO_MATCH;
2089
2090  interval = atoi (argv[0]);
2091  if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL)
2092    {
2093      vty_out (vty, "Invalid hello-interval %ld - should be <1-600>%s",
2094               interval, VTY_NEWLINE);
2095      return CMD_ERR_AMBIGUOUS;
2096    }
2097
2098  circuit->hello_interval[1] = (u_int16_t) interval;
2099
2100  return CMD_SUCCESS;
2101}
2102
2103DEFUN (no_isis_hello_interval_l2,
2104       no_isis_hello_interval_l2_cmd,
2105       "no isis hello-interval level-2",
2106       NO_STR
2107       "IS-IS commands\n"
2108       "Set Hello interval\n"
2109       "Specify hello-interval for level-2 IIHs\n")
2110{
2111  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2112  if (!circuit)
2113    return CMD_ERR_NO_MATCH;
2114
2115  circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL;
2116
2117  return CMD_SUCCESS;
2118}
2119
2120ALIAS (no_isis_hello_interval_l2,
2121       no_isis_hello_interval_l2_arg_cmd,
2122       "no isis hello-interval <1-600> level-2",
2123       NO_STR
2124       "IS-IS commands\n"
2125       "Set Hello interval\n"
2126       "Hello interval value\n"
2127       "Holdtime 1 second, interval depends on multiplier\n"
2128       "Specify hello-interval for level-2 IIHs\n")
2129
2130DEFUN (isis_hello_multiplier,
2131       isis_hello_multiplier_cmd,
2132       "isis hello-multiplier <2-100>",
2133       "IS-IS commands\n"
2134       "Set multiplier for Hello holding time\n"
2135       "Hello multiplier value\n")
2136{
2137  int mult;
2138  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2139  if (!circuit)
2140    return CMD_ERR_NO_MATCH;
2141
2142  mult = atoi (argv[0]);
2143  if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER)
2144    {
2145      vty_out (vty, "Invalid hello-multiplier %d - should be <2-100>%s",
2146               mult, VTY_NEWLINE);
2147      return CMD_ERR_AMBIGUOUS;
2148    }
2149
2150  circuit->hello_multiplier[0] = (u_int16_t) mult;
2151  circuit->hello_multiplier[1] = (u_int16_t) mult;
2152
2153  return CMD_SUCCESS;
2154}
2155
2156DEFUN (no_isis_hello_multiplier,
2157       no_isis_hello_multiplier_cmd,
2158       "no isis hello-multiplier",
2159       NO_STR
2160       "IS-IS commands\n"
2161       "Set multiplier for Hello holding time\n")
2162{
2163  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2164  if (!circuit)
2165    return CMD_ERR_NO_MATCH;
2166
2167  circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER;
2168  circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER;
2169
2170  return CMD_SUCCESS;
2171}
2172
2173ALIAS (no_isis_hello_multiplier,
2174       no_isis_hello_multiplier_arg_cmd,
2175       "no isis hello-multiplier <2-100>",
2176       NO_STR
2177       "IS-IS commands\n"
2178       "Set multiplier for Hello holding time\n"
2179       "Hello multiplier value\n")
2180
2181DEFUN (isis_hello_multiplier_l1,
2182       isis_hello_multiplier_l1_cmd,
2183       "isis hello-multiplier <2-100> level-1",
2184       "IS-IS commands\n"
2185       "Set multiplier for Hello holding time\n"
2186       "Hello multiplier value\n"
2187       "Specify hello multiplier for level-1 IIHs\n")
2188{
2189  int mult;
2190  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2191  if (!circuit)
2192    return CMD_ERR_NO_MATCH;
2193
2194  mult = atoi (argv[0]);
2195  if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER)
2196    {
2197      vty_out (vty, "Invalid hello-multiplier %d - should be <2-100>%s",
2198               mult, VTY_NEWLINE);
2199      return CMD_ERR_AMBIGUOUS;
2200    }
2201
2202  circuit->hello_multiplier[0] = (u_int16_t) mult;
2203
2204  return CMD_SUCCESS;
2205}
2206
2207DEFUN (no_isis_hello_multiplier_l1,
2208       no_isis_hello_multiplier_l1_cmd,
2209       "no isis hello-multiplier level-1",
2210       NO_STR
2211       "IS-IS commands\n"
2212       "Set multiplier for Hello holding time\n"
2213       "Specify hello multiplier for level-1 IIHs\n")
2214{
2215  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2216  if (!circuit)
2217    return CMD_ERR_NO_MATCH;
2218
2219  circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER;
2220
2221  return CMD_SUCCESS;
2222}
2223
2224ALIAS (no_isis_hello_multiplier_l1,
2225       no_isis_hello_multiplier_l1_arg_cmd,
2226       "no isis hello-multiplier <2-100> level-1",
2227       NO_STR
2228       "IS-IS commands\n"
2229       "Set multiplier for Hello holding time\n"
2230       "Hello multiplier value\n"
2231       "Specify hello multiplier for level-1 IIHs\n")
2232
2233DEFUN (isis_hello_multiplier_l2,
2234       isis_hello_multiplier_l2_cmd,
2235       "isis hello-multiplier <2-100> level-2",
2236       "IS-IS commands\n"
2237       "Set multiplier for Hello holding time\n"
2238       "Hello multiplier value\n"
2239       "Specify hello multiplier for level-2 IIHs\n")
2240{
2241  int mult;
2242  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2243  if (!circuit)
2244    return CMD_ERR_NO_MATCH;
2245
2246  mult = atoi (argv[0]);
2247  if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER)
2248    {
2249      vty_out (vty, "Invalid hello-multiplier %d - should be <2-100>%s",
2250               mult, VTY_NEWLINE);
2251      return CMD_ERR_AMBIGUOUS;
2252    }
2253
2254  circuit->hello_multiplier[1] = (u_int16_t) mult;
2255
2256  return CMD_SUCCESS;
2257}
2258
2259DEFUN (no_isis_hello_multiplier_l2,
2260       no_isis_hello_multiplier_l2_cmd,
2261       "no isis hello-multiplier level-2",
2262       NO_STR
2263       "IS-IS commands\n"
2264       "Set multiplier for Hello holding time\n"
2265       "Specify hello multiplier for level-2 IIHs\n")
2266{
2267  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2268  if (!circuit)
2269    return CMD_ERR_NO_MATCH;
2270
2271  circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER;
2272
2273  return CMD_SUCCESS;
2274}
2275
2276ALIAS (no_isis_hello_multiplier_l2,
2277       no_isis_hello_multiplier_l2_arg_cmd,
2278       "no isis hello-multiplier <2-100> level-2",
2279       NO_STR
2280       "IS-IS commands\n"
2281       "Set multiplier for Hello holding time\n"
2282       "Hello multiplier value\n"
2283       "Specify hello multiplier for level-2 IIHs\n")
2284
2285DEFUN (isis_hello_padding,
2286       isis_hello_padding_cmd,
2287       "isis hello padding",
2288       "IS-IS commands\n"
2289       "Add padding to IS-IS hello packets\n"
2290       "Pad hello packets\n"
2291       "<cr>\n")
2292{
2293  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2294  if (!circuit)
2295    return CMD_ERR_NO_MATCH;
2296
2297  circuit->pad_hellos = 1;
2298
2299  return CMD_SUCCESS;
2300}
2301
2302DEFUN (no_isis_hello_padding,
2303       no_isis_hello_padding_cmd,
2304       "no isis hello padding",
2305       NO_STR
2306       "IS-IS commands\n"
2307       "Add padding to IS-IS hello packets\n"
2308       "Pad hello packets\n"
2309       "<cr>\n")
2310{
2311  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2312  if (!circuit)
2313    return CMD_ERR_NO_MATCH;
2314
2315  circuit->pad_hellos = 0;
2316
2317  return CMD_SUCCESS;
2318}
2319
2320DEFUN (csnp_interval,
2321       csnp_interval_cmd,
2322       "isis csnp-interval <1-600>",
2323       "IS-IS commands\n"
2324       "Set CSNP interval in seconds\n"
2325       "CSNP interval value\n")
2326{
2327  unsigned long interval;
2328  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2329  if (!circuit)
2330    return CMD_ERR_NO_MATCH;
2331
2332  interval = atol (argv[0]);
2333  if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL)
2334    {
2335      vty_out (vty, "Invalid csnp-interval %lu - should be <1-600>%s",
2336               interval, VTY_NEWLINE);
2337      return CMD_ERR_AMBIGUOUS;
2338    }
2339
2340  circuit->csnp_interval[0] = (u_int16_t) interval;
2341  circuit->csnp_interval[1] = (u_int16_t) interval;
2342
2343  return CMD_SUCCESS;
2344}
2345
2346DEFUN (no_csnp_interval,
2347       no_csnp_interval_cmd,
2348       "no isis csnp-interval",
2349       NO_STR
2350       "IS-IS commands\n"
2351       "Set CSNP interval in seconds\n")
2352{
2353  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2354  if (!circuit)
2355    return CMD_ERR_NO_MATCH;
2356
2357  circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL;
2358  circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL;
2359
2360  return CMD_SUCCESS;
2361}
2362
2363ALIAS (no_csnp_interval,
2364       no_csnp_interval_arg_cmd,
2365       "no isis csnp-interval <1-600>",
2366       NO_STR
2367       "IS-IS commands\n"
2368       "Set CSNP interval in seconds\n"
2369       "CSNP interval value\n")
2370
2371DEFUN (csnp_interval_l1,
2372       csnp_interval_l1_cmd,
2373       "isis csnp-interval <1-600> level-1",
2374       "IS-IS commands\n"
2375       "Set CSNP interval in seconds\n"
2376       "CSNP interval value\n"
2377       "Specify interval for level-1 CSNPs\n")
2378{
2379  unsigned long interval;
2380  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2381  if (!circuit)
2382    return CMD_ERR_NO_MATCH;
2383
2384  interval = atol (argv[0]);
2385  if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL)
2386    {
2387      vty_out (vty, "Invalid csnp-interval %lu - should be <1-600>%s",
2388               interval, VTY_NEWLINE);
2389      return CMD_ERR_AMBIGUOUS;
2390    }
2391
2392  circuit->csnp_interval[0] = (u_int16_t) interval;
2393
2394  return CMD_SUCCESS;
2395}
2396
2397DEFUN (no_csnp_interval_l1,
2398       no_csnp_interval_l1_cmd,
2399       "no isis csnp-interval level-1",
2400       NO_STR
2401       "IS-IS commands\n"
2402       "Set CSNP interval in seconds\n"
2403       "Specify interval for level-1 CSNPs\n")
2404{
2405  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2406  if (!circuit)
2407    return CMD_ERR_NO_MATCH;
2408
2409  circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL;
2410
2411  return CMD_SUCCESS;
2412}
2413
2414ALIAS (no_csnp_interval_l1,
2415       no_csnp_interval_l1_arg_cmd,
2416       "no isis csnp-interval <1-600> level-1",
2417       NO_STR
2418       "IS-IS commands\n"
2419       "Set CSNP interval in seconds\n"
2420       "CSNP interval value\n"
2421       "Specify interval for level-1 CSNPs\n")
2422
2423DEFUN (csnp_interval_l2,
2424       csnp_interval_l2_cmd,
2425       "isis csnp-interval <1-600> level-2",
2426       "IS-IS commands\n"
2427       "Set CSNP interval in seconds\n"
2428       "CSNP interval value\n"
2429       "Specify interval for level-2 CSNPs\n")
2430{
2431  unsigned long interval;
2432  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2433  if (!circuit)
2434    return CMD_ERR_NO_MATCH;
2435
2436  interval = atol (argv[0]);
2437  if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL)
2438    {
2439      vty_out (vty, "Invalid csnp-interval %lu - should be <1-600>%s",
2440               interval, VTY_NEWLINE);
2441      return CMD_ERR_AMBIGUOUS;
2442    }
2443
2444  circuit->csnp_interval[1] = (u_int16_t) interval;
2445
2446  return CMD_SUCCESS;
2447}
2448
2449DEFUN (no_csnp_interval_l2,
2450       no_csnp_interval_l2_cmd,
2451       "no isis csnp-interval level-2",
2452       NO_STR
2453       "IS-IS commands\n"
2454       "Set CSNP interval in seconds\n"
2455       "Specify interval for level-2 CSNPs\n")
2456{
2457  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2458  if (!circuit)
2459    return CMD_ERR_NO_MATCH;
2460
2461  circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL;
2462
2463  return CMD_SUCCESS;
2464}
2465
2466ALIAS (no_csnp_interval_l2,
2467       no_csnp_interval_l2_arg_cmd,
2468       "no isis csnp-interval <1-600> level-2",
2469       NO_STR
2470       "IS-IS commands\n"
2471       "Set CSNP interval in seconds\n"
2472       "CSNP interval value\n"
2473       "Specify interval for level-2 CSNPs\n")
2474
2475DEFUN (psnp_interval,
2476       psnp_interval_cmd,
2477       "isis psnp-interval <1-120>",
2478       "IS-IS commands\n"
2479       "Set PSNP interval in seconds\n"
2480       "PSNP interval value\n")
2481{
2482  unsigned long interval;
2483  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2484  if (!circuit)
2485    return CMD_ERR_NO_MATCH;
2486
2487  interval = atol (argv[0]);
2488  if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL)
2489    {
2490      vty_out (vty, "Invalid psnp-interval %lu - should be <1-120>%s",
2491               interval, VTY_NEWLINE);
2492      return CMD_ERR_AMBIGUOUS;
2493    }
2494
2495  circuit->psnp_interval[0] = (u_int16_t) interval;
2496  circuit->psnp_interval[1] = (u_int16_t) interval;
2497
2498  return CMD_SUCCESS;
2499}
2500
2501DEFUN (no_psnp_interval,
2502       no_psnp_interval_cmd,
2503       "no isis psnp-interval",
2504       NO_STR
2505       "IS-IS commands\n"
2506       "Set PSNP interval in seconds\n")
2507{
2508  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2509  if (!circuit)
2510    return CMD_ERR_NO_MATCH;
2511
2512  circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL;
2513  circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL;
2514
2515  return CMD_SUCCESS;
2516}
2517
2518ALIAS (no_psnp_interval,
2519       no_psnp_interval_arg_cmd,
2520       "no isis psnp-interval <1-120>",
2521       NO_STR
2522       "IS-IS commands\n"
2523       "Set PSNP interval in seconds\n"
2524       "PSNP interval value\n")
2525
2526DEFUN (psnp_interval_l1,
2527       psnp_interval_l1_cmd,
2528       "isis psnp-interval <1-120> level-1",
2529       "IS-IS commands\n"
2530       "Set PSNP interval in seconds\n"
2531       "PSNP interval value\n"
2532       "Specify interval for level-1 PSNPs\n")
2533{
2534  unsigned long interval;
2535  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2536  if (!circuit)
2537    return CMD_ERR_NO_MATCH;
2538
2539  interval = atol (argv[0]);
2540  if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL)
2541    {
2542      vty_out (vty, "Invalid psnp-interval %lu - should be <1-120>%s",
2543               interval, VTY_NEWLINE);
2544      return CMD_ERR_AMBIGUOUS;
2545    }
2546
2547  circuit->psnp_interval[0] = (u_int16_t) interval;
2548
2549  return CMD_SUCCESS;
2550}
2551
2552DEFUN (no_psnp_interval_l1,
2553       no_psnp_interval_l1_cmd,
2554       "no isis psnp-interval level-1",
2555       NO_STR
2556       "IS-IS commands\n"
2557       "Set PSNP interval in seconds\n"
2558       "Specify interval for level-1 PSNPs\n")
2559{
2560  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2561  if (!circuit)
2562    return CMD_ERR_NO_MATCH;
2563
2564  circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL;
2565
2566  return CMD_SUCCESS;
2567}
2568
2569ALIAS (no_psnp_interval_l1,
2570       no_psnp_interval_l1_arg_cmd,
2571       "no isis psnp-interval <1-120> level-1",
2572       NO_STR
2573       "IS-IS commands\n"
2574       "Set PSNP interval in seconds\n"
2575       "PSNP interval value\n"
2576       "Specify interval for level-1 PSNPs\n")
2577
2578DEFUN (psnp_interval_l2,
2579       psnp_interval_l2_cmd,
2580       "isis psnp-interval <1-120> level-2",
2581       "IS-IS commands\n"
2582       "Set PSNP interval in seconds\n"
2583       "PSNP interval value\n"
2584       "Specify interval for level-2 PSNPs\n")
2585{
2586  unsigned long interval;
2587  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2588  if (!circuit)
2589    return CMD_ERR_NO_MATCH;
2590
2591  interval = atol (argv[0]);
2592  if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL)
2593    {
2594      vty_out (vty, "Invalid psnp-interval %lu - should be <1-120>%s",
2595               interval, VTY_NEWLINE);
2596      return CMD_ERR_AMBIGUOUS;
2597    }
2598
2599  circuit->psnp_interval[1] = (u_int16_t) interval;
2600
2601  return CMD_SUCCESS;
2602}
2603
2604DEFUN (no_psnp_interval_l2,
2605       no_psnp_interval_l2_cmd,
2606       "no isis psnp-interval level-2",
2607       NO_STR
2608       "IS-IS commands\n"
2609       "Set PSNP interval in seconds\n"
2610       "Specify interval for level-2 PSNPs\n")
2611{
2612  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2613  if (!circuit)
2614    return CMD_ERR_NO_MATCH;
2615
2616  circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL;
2617
2618  return CMD_SUCCESS;
2619}
2620
2621ALIAS (no_psnp_interval_l2,
2622       no_psnp_interval_l2_arg_cmd,
2623       "no isis psnp-interval <1-120> level-2",
2624       NO_STR
2625       "IS-IS commands\n"
2626       "Set PSNP interval in seconds\n"
2627       "PSNP interval value\n"
2628       "Specify interval for level-2 PSNPs\n")
2629
2630struct cmd_node interface_node = {
2631  INTERFACE_NODE,
2632  "%s(config-if)# ",
2633  1,
2634};
2635
2636DEFUN (isis_network,
2637       isis_network_cmd,
2638       "isis network point-to-point",
2639       "IS-IS commands\n"
2640       "Set network type\n"
2641       "point-to-point network type\n")
2642{
2643  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2644  if (!circuit)
2645    return CMD_ERR_NO_MATCH;
2646
2647  /* RFC5309 section 4 */
2648  if (circuit->circ_type == CIRCUIT_T_P2P)
2649    return CMD_SUCCESS;
2650
2651  if (circuit->state != C_STATE_UP)
2652    {
2653      circuit->circ_type = CIRCUIT_T_P2P;
2654      circuit->circ_type_config = CIRCUIT_T_P2P;
2655    }
2656  else
2657    {
2658      struct isis_area *area = circuit->area;
2659      if (!if_is_broadcast (circuit->interface))
2660        {
2661          vty_out (vty, "isis network point-to-point "
2662                   "is valid only on broadcast interfaces%s",
2663                   VTY_NEWLINE);
2664          return CMD_ERR_AMBIGUOUS;
2665        }
2666
2667      isis_csm_state_change (ISIS_DISABLE, circuit, area);
2668      circuit->circ_type = CIRCUIT_T_P2P;
2669      circuit->circ_type_config = CIRCUIT_T_P2P;
2670      isis_csm_state_change (ISIS_ENABLE, circuit, area);
2671    }
2672
2673  return CMD_SUCCESS;
2674}
2675
2676DEFUN (no_isis_network,
2677       no_isis_network_cmd,
2678       "no isis network point-to-point",
2679       NO_STR
2680       "IS-IS commands\n"
2681       "Set network type for circuit\n"
2682       "point-to-point network type\n")
2683{
2684  struct isis_circuit *circuit = isis_circuit_lookup (vty);
2685  if (!circuit)
2686    return CMD_ERR_NO_MATCH;
2687
2688  /* RFC5309 section 4 */
2689  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
2690    return CMD_SUCCESS;
2691
2692  if (circuit->state != C_STATE_UP)
2693    {
2694      circuit->circ_type = CIRCUIT_T_BROADCAST;
2695      circuit->circ_type_config = CIRCUIT_T_BROADCAST;
2696    }
2697  else
2698    {
2699      struct isis_area *area = circuit->area;
2700      if (circuit->interface &&
2701          !if_is_broadcast (circuit->interface))
2702      {
2703        vty_out (vty, "no isis network point-to-point "
2704                 "is valid only on broadcast interfaces%s",
2705                 VTY_NEWLINE);
2706        return CMD_ERR_AMBIGUOUS;
2707      }
2708
2709      isis_csm_state_change (ISIS_DISABLE, circuit, area);
2710      circuit->circ_type = CIRCUIT_T_BROADCAST;
2711      circuit->circ_type_config = CIRCUIT_T_BROADCAST;
2712      isis_csm_state_change (ISIS_ENABLE, circuit, area);
2713    }
2714
2715  return CMD_SUCCESS;
2716}
2717
2718int
2719isis_if_new_hook (struct interface *ifp)
2720{
2721  return 0;
2722}
2723
2724int
2725isis_if_delete_hook (struct interface *ifp)
2726{
2727  struct isis_circuit *circuit;
2728  /* Clean up the circuit data */
2729  if (ifp && ifp->info)
2730    {
2731      circuit = ifp->info;
2732      isis_csm_state_change (IF_DOWN_FROM_Z, circuit, circuit->area);
2733      isis_csm_state_change (ISIS_DISABLE, circuit, circuit->area);
2734    }
2735
2736  return 0;
2737}
2738
2739void
2740isis_circuit_init ()
2741{
2742  /* Initialize Zebra interface data structure */
2743  if_init ();
2744  if_add_hook (IF_NEW_HOOK, isis_if_new_hook);
2745  if_add_hook (IF_DELETE_HOOK, isis_if_delete_hook);
2746
2747  /* Install interface node */
2748  install_node (&interface_node, isis_interface_config_write);
2749  install_element (CONFIG_NODE, &interface_cmd);
2750  install_element (CONFIG_NODE, &no_interface_cmd);
2751
2752  install_default (INTERFACE_NODE);
2753  install_element (INTERFACE_NODE, &interface_desc_cmd);
2754  install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2755
2756  install_element (INTERFACE_NODE, &ip_router_isis_cmd);
2757  install_element (INTERFACE_NODE, &no_ip_router_isis_cmd);
2758
2759  install_element (INTERFACE_NODE, &isis_passive_cmd);
2760  install_element (INTERFACE_NODE, &no_isis_passive_cmd);
2761
2762  install_element (INTERFACE_NODE, &isis_circuit_type_cmd);
2763  install_element (INTERFACE_NODE, &no_isis_circuit_type_cmd);
2764
2765  install_element (INTERFACE_NODE, &isis_passwd_clear_cmd);
2766  install_element (INTERFACE_NODE, &isis_passwd_md5_cmd);
2767  install_element (INTERFACE_NODE, &no_isis_passwd_cmd);
2768
2769  install_element (INTERFACE_NODE, &isis_priority_cmd);
2770  install_element (INTERFACE_NODE, &no_isis_priority_cmd);
2771  install_element (INTERFACE_NODE, &no_isis_priority_arg_cmd);
2772  install_element (INTERFACE_NODE, &isis_priority_l1_cmd);
2773  install_element (INTERFACE_NODE, &no_isis_priority_l1_cmd);
2774  install_element (INTERFACE_NODE, &no_isis_priority_l1_arg_cmd);
2775  install_element (INTERFACE_NODE, &isis_priority_l2_cmd);
2776  install_element (INTERFACE_NODE, &no_isis_priority_l2_cmd);
2777  install_element (INTERFACE_NODE, &no_isis_priority_l2_arg_cmd);
2778
2779  install_element (INTERFACE_NODE, &isis_metric_cmd);
2780  install_element (INTERFACE_NODE, &no_isis_metric_cmd);
2781  install_element (INTERFACE_NODE, &no_isis_metric_arg_cmd);
2782  install_element (INTERFACE_NODE, &isis_metric_l1_cmd);
2783  install_element (INTERFACE_NODE, &no_isis_metric_l1_cmd);
2784  install_element (INTERFACE_NODE, &no_isis_metric_l1_arg_cmd);
2785  install_element (INTERFACE_NODE, &isis_metric_l2_cmd);
2786  install_element (INTERFACE_NODE, &no_isis_metric_l2_cmd);
2787  install_element (INTERFACE_NODE, &no_isis_metric_l2_arg_cmd);
2788
2789  install_element (INTERFACE_NODE, &isis_hello_interval_cmd);
2790  install_element (INTERFACE_NODE, &no_isis_hello_interval_cmd);
2791  install_element (INTERFACE_NODE, &no_isis_hello_interval_arg_cmd);
2792  install_element (INTERFACE_NODE, &isis_hello_interval_l1_cmd);
2793  install_element (INTERFACE_NODE, &no_isis_hello_interval_l1_cmd);
2794  install_element (INTERFACE_NODE, &no_isis_hello_interval_l1_arg_cmd);
2795  install_element (INTERFACE_NODE, &isis_hello_interval_l2_cmd);
2796  install_element (INTERFACE_NODE, &no_isis_hello_interval_l2_cmd);
2797  install_element (INTERFACE_NODE, &no_isis_hello_interval_l2_arg_cmd);
2798
2799  install_element (INTERFACE_NODE, &isis_hello_multiplier_cmd);
2800  install_element (INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
2801  install_element (INTERFACE_NODE, &no_isis_hello_multiplier_arg_cmd);
2802  install_element (INTERFACE_NODE, &isis_hello_multiplier_l1_cmd);
2803  install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l1_cmd);
2804  install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l1_arg_cmd);
2805  install_element (INTERFACE_NODE, &isis_hello_multiplier_l2_cmd);
2806  install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l2_cmd);
2807  install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l2_arg_cmd);
2808
2809  install_element (INTERFACE_NODE, &isis_hello_padding_cmd);
2810  install_element (INTERFACE_NODE, &no_isis_hello_padding_cmd);
2811
2812  install_element (INTERFACE_NODE, &csnp_interval_cmd);
2813  install_element (INTERFACE_NODE, &no_csnp_interval_cmd);
2814  install_element (INTERFACE_NODE, &no_csnp_interval_arg_cmd);
2815  install_element (INTERFACE_NODE, &csnp_interval_l1_cmd);
2816  install_element (INTERFACE_NODE, &no_csnp_interval_l1_cmd);
2817  install_element (INTERFACE_NODE, &no_csnp_interval_l1_arg_cmd);
2818  install_element (INTERFACE_NODE, &csnp_interval_l2_cmd);
2819  install_element (INTERFACE_NODE, &no_csnp_interval_l2_cmd);
2820  install_element (INTERFACE_NODE, &no_csnp_interval_l2_arg_cmd);
2821
2822  install_element (INTERFACE_NODE, &psnp_interval_cmd);
2823  install_element (INTERFACE_NODE, &no_psnp_interval_cmd);
2824  install_element (INTERFACE_NODE, &no_psnp_interval_arg_cmd);
2825  install_element (INTERFACE_NODE, &psnp_interval_l1_cmd);
2826  install_element (INTERFACE_NODE, &no_psnp_interval_l1_cmd);
2827  install_element (INTERFACE_NODE, &no_psnp_interval_l1_arg_cmd);
2828  install_element (INTERFACE_NODE, &psnp_interval_l2_cmd);
2829  install_element (INTERFACE_NODE, &no_psnp_interval_l2_cmd);
2830  install_element (INTERFACE_NODE, &no_psnp_interval_l2_arg_cmd);
2831
2832  install_element (INTERFACE_NODE, &isis_network_cmd);
2833  install_element (INTERFACE_NODE, &no_isis_network_cmd);
2834
2835#ifdef HAVE_IPV6
2836  install_element (INTERFACE_NODE, &ipv6_router_isis_cmd);
2837  install_element (INTERFACE_NODE, &no_ipv6_router_isis_cmd);
2838#endif
2839}
2840