File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / isisd / isis_circuit.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:11 2012 UTC (12 years, 5 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_20_1, v0_99_20, HEAD
quagga

    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_circuit.h"
   48: #include "isisd/isis_tlv.h"
   49: #include "isisd/isis_lsp.h"
   50: #include "isisd/isis_pdu.h"
   51: #include "isisd/isis_network.h"
   52: #include "isisd/isis_misc.h"
   53: #include "isisd/isis_constants.h"
   54: #include "isisd/isis_adjacency.h"
   55: #include "isisd/isis_dr.h"
   56: #include "isisd/isis_flags.h"
   57: #include "isisd/isisd.h"
   58: #include "isisd/isis_csm.h"
   59: #include "isisd/isis_events.h"
   60: 
   61: extern struct thread_master *master;
   62: extern struct isis *isis;
   63: 
   64: /*
   65:  * Prototypes.
   66:  */
   67: void isis_circuit_down(struct isis_circuit *);
   68: int isis_interface_config_write(struct vty *);
   69: int isis_if_new_hook(struct interface *);
   70: int isis_if_delete_hook(struct interface *);
   71: 
   72: struct isis_circuit *
   73: isis_circuit_new ()
   74: {
   75:   struct isis_circuit *circuit;
   76:   int i;
   77: 
   78:   circuit = XCALLOC (MTYPE_ISIS_CIRCUIT, sizeof (struct isis_circuit));
   79:   if (circuit)
   80:     {
   81:       /* set default metrics for circuit */
   82:       for (i = 0; i < 2; i++)
   83: 	{
   84: 	  circuit->metrics[i].metric_default = DEFAULT_CIRCUIT_METRICS;
   85: 	  circuit->metrics[i].metric_expense = METRICS_UNSUPPORTED;
   86: 	  circuit->metrics[i].metric_error = METRICS_UNSUPPORTED;
   87: 	  circuit->metrics[i].metric_delay = METRICS_UNSUPPORTED;
   88: 	  circuit->te_metric[i] = DEFAULT_CIRCUIT_METRICS;
   89: 	}
   90:     }
   91:   else
   92:     {
   93:       zlog_err ("Can't malloc isis circuit");
   94:       return NULL;
   95:     }
   96: 
   97:   return circuit;
   98: }
   99: 
  100: void
  101: isis_circuit_configure (struct isis_circuit *circuit, struct isis_area *area)
  102: {
  103:   int i;
  104:   circuit->area = area;
  105:   /*
  106:    * The level for the circuit is same as for the area, unless configured
  107:    * otherwise.
  108:    */
  109:   circuit->circuit_is_type = area->is_type;
  110:   /*
  111:    * Default values
  112:    */
  113:   for (i = 0; i < 2; i++)
  114:     {
  115:       circuit->hello_interval[i] = HELLO_INTERVAL;
  116:       circuit->hello_multiplier[i] = HELLO_MULTIPLIER;
  117:       circuit->csnp_interval[i] = CSNP_INTERVAL;
  118:       circuit->psnp_interval[i] = PSNP_INTERVAL;
  119:       circuit->u.bc.priority[i] = DEFAULT_PRIORITY;
  120:     }
  121:   if (circuit->circ_type == CIRCUIT_T_BROADCAST)
  122:     {
  123:       circuit->u.bc.adjdb[0] = list_new ();
  124:       circuit->u.bc.adjdb[1] = list_new ();
  125:       circuit->u.bc.pad_hellos = 1;
  126:     }
  127:   circuit->lsp_interval = LSP_INTERVAL;
  128: 
  129:   /*
  130:    * Add the circuit into area
  131:    */
  132:   listnode_add (area->circuit_list, circuit);
  133: 
  134:   circuit->idx = flags_get_index (&area->flags);
  135:   circuit->lsp_queue = list_new ();
  136: 
  137:   return;
  138: }
  139: 
  140: void
  141: isis_circuit_deconfigure (struct isis_circuit *circuit,
  142: 			  struct isis_area *area)
  143: {
  144: 
  145:   /* destroy adjacencies */
  146:   if (circuit->u.bc.adjdb[0])
  147:     isis_adjdb_iterate (circuit->u.bc.adjdb[0], (void(*) (struct isis_adjacency *, void *)) isis_delete_adj, circuit->u.bc.adjdb[0]);
  148:   if (circuit->u.bc.adjdb[1])
  149:     isis_adjdb_iterate (circuit->u.bc.adjdb[1], (void(*) (struct isis_adjacency *, void *)) isis_delete_adj, circuit->u.bc.adjdb[1]);
  150:   /* Remove circuit from area */
  151:   listnode_delete (area->circuit_list, circuit);
  152:   /* Free the index of SRM and SSN flags */
  153:   flags_free_index (&area->flags, circuit->idx);
  154: 
  155:   return;
  156: }
  157: 
  158: struct isis_circuit *
  159: circuit_lookup_by_ifp (struct interface *ifp, struct list *list)
  160: {
  161:   struct isis_circuit *circuit = NULL;
  162:   struct listnode *node;
  163: 
  164:   if (!list)
  165:     return NULL;
  166: 
  167:   for (ALL_LIST_ELEMENTS_RO (list, node, circuit))
  168:     if (circuit->interface == ifp)
  169:       return circuit;
  170:   
  171:   return NULL;
  172: }
  173: 
  174: struct isis_circuit *
  175: circuit_scan_by_ifp (struct interface *ifp)
  176: {
  177:   struct isis_area *area;
  178:   struct listnode *node;
  179:   struct isis_circuit *circuit;
  180: 
  181:   if (!isis->area_list)
  182:     return NULL;
  183: 
  184:   for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
  185:     {
  186:       circuit = circuit_lookup_by_ifp (ifp, area->circuit_list);
  187:       if (circuit)
  188: 	return circuit;
  189:     }
  190: 
  191:   return circuit_lookup_by_ifp (ifp, isis->init_circ_list);
  192: }
  193: 
  194: void
  195: isis_circuit_del (struct isis_circuit *circuit)
  196: {
  197: 
  198:   if (!circuit)
  199:     return;
  200: 
  201:   if (circuit->circ_type == CIRCUIT_T_BROADCAST)
  202:     {
  203:       /* destroy adjacency databases */
  204:       if (circuit->u.bc.adjdb[0])
  205: 	list_delete (circuit->u.bc.adjdb[0]);
  206:       if (circuit->u.bc.adjdb[1])
  207: 	list_delete (circuit->u.bc.adjdb[1]);
  208:       /* destroy neighbour lists */
  209:       if (circuit->u.bc.lan_neighs[0])
  210: 	list_delete (circuit->u.bc.lan_neighs[0]);
  211:       if (circuit->u.bc.lan_neighs[1])
  212: 	list_delete (circuit->u.bc.lan_neighs[1]);
  213:       /* destroy addresses */
  214:     }
  215:   if (circuit->ip_addrs)
  216:     list_delete (circuit->ip_addrs);
  217: #ifdef HAVE_IPV6
  218:   if (circuit->ipv6_link)
  219:     list_delete (circuit->ipv6_link);
  220:   if (circuit->ipv6_non_link)
  221:     list_delete (circuit->ipv6_non_link);
  222: #endif /* HAVE_IPV6 */
  223: 
  224:   /* and lastly the circuit itself */
  225:   XFREE (MTYPE_ISIS_CIRCUIT, circuit);
  226: 
  227:   return;
  228: }
  229: 
  230: void
  231: isis_circuit_add_addr (struct isis_circuit *circuit,
  232: 		       struct connected *connected)
  233: {
  234:   struct prefix_ipv4 *ipv4;
  235:   u_char buf[BUFSIZ];
  236: #ifdef HAVE_IPV6
  237:   struct prefix_ipv6 *ipv6;
  238: #endif /* HAVE_IPV6 */
  239: 
  240:   if (!circuit->ip_addrs)
  241:     circuit->ip_addrs = list_new ();
  242: #ifdef HAVE_IPV6
  243:   if (!circuit->ipv6_link)
  244:     circuit->ipv6_link = list_new ();
  245:   if (!circuit->ipv6_non_link)
  246:     circuit->ipv6_non_link = list_new ();
  247: #endif /* HAVE_IPV6 */
  248: 
  249:   memset (&buf, 0, BUFSIZ);
  250:   if (connected->address->family == AF_INET)
  251:     {
  252:       ipv4 = prefix_ipv4_new ();
  253:       ipv4->prefixlen = connected->address->prefixlen;
  254:       ipv4->prefix = connected->address->u.prefix4;
  255:       listnode_add (circuit->ip_addrs, ipv4);
  256:       if (circuit->area)
  257: 	lsp_regenerate_schedule (circuit->area);
  258: 
  259: #ifdef EXTREME_DEBUG
  260:       prefix2str (connected->address, buf, BUFSIZ);
  261:       zlog_debug ("Added IP address %s to circuit %d", buf,
  262: 		 circuit->circuit_id);
  263: #endif /* EXTREME_DEBUG */
  264:     }
  265: #ifdef HAVE_IPV6
  266:   if (connected->address->family == AF_INET6)
  267:     {
  268:       ipv6 = prefix_ipv6_new ();
  269:       ipv6->prefixlen = connected->address->prefixlen;
  270:       ipv6->prefix = connected->address->u.prefix6;
  271: 
  272:       if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
  273: 	listnode_add (circuit->ipv6_link, ipv6);
  274:       else
  275: 	listnode_add (circuit->ipv6_non_link, ipv6);
  276:       if (circuit->area)
  277: 	lsp_regenerate_schedule (circuit->area);
  278: 
  279: #ifdef EXTREME_DEBUG
  280:       prefix2str (connected->address, buf, BUFSIZ);
  281:       zlog_debug ("Added IPv6 address %s to circuit %d", buf,
  282: 		 circuit->circuit_id);
  283: #endif /* EXTREME_DEBUG */
  284:     }
  285: #endif /* HAVE_IPV6 */
  286:   return;
  287: }
  288: 
  289: void
  290: isis_circuit_del_addr (struct isis_circuit *circuit,
  291: 		       struct connected *connected)
  292: {
  293:   struct prefix_ipv4 *ipv4, *ip = NULL;
  294:   struct listnode *node;
  295:   u_char buf[BUFSIZ];
  296: #ifdef HAVE_IPV6
  297:   struct prefix_ipv6 *ipv6, *ip6 = NULL;
  298:   int found = 0;
  299: #endif /* HAVE_IPV6 */
  300: 
  301:   memset (&buf, 0, BUFSIZ);
  302:   if (connected->address->family == AF_INET)
  303:     {
  304:       ipv4 = prefix_ipv4_new ();
  305:       ipv4->prefixlen = connected->address->prefixlen;
  306:       ipv4->prefix = connected->address->u.prefix4;
  307: 
  308:       for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ip))
  309:         if (prefix_same ((struct prefix *) ip, (struct prefix *) &ipv4))
  310:           break;
  311: 
  312:       if (ip)
  313: 	{
  314: 	  listnode_delete (circuit->ip_addrs, ip);
  315: 	  if (circuit->area)
  316: 	    lsp_regenerate_schedule (circuit->area);
  317: 	}
  318:       else
  319: 	{
  320: 	  prefix2str (connected->address, (char *)buf, BUFSIZ);
  321: 	  zlog_warn("Nonexitant ip address %s removal attempt from circuit \
  322: 		     %d", buf, circuit->circuit_id);
  323: 	}
  324:     }
  325: #ifdef HAVE_IPV6
  326:   if (connected->address->family == AF_INET6)
  327:     {
  328:       ipv6 = prefix_ipv6_new ();
  329:       ipv6->prefixlen = connected->address->prefixlen;
  330:       ipv6->prefix = connected->address->u.prefix6;
  331: 
  332:       if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
  333: 	{
  334: 	  for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_link, node, ip6))
  335: 	    {
  336: 	      if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
  337: 		break;
  338: 	    }
  339: 	  if (ip6)
  340: 	    {
  341: 	      listnode_delete (circuit->ipv6_link, ip6);
  342: 	      found = 1;
  343: 	    }
  344: 	}
  345:       else
  346: 	{
  347: 	  for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, node, ip6))
  348: 	    {
  349: 	      if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
  350: 		break;
  351: 	    }
  352: 	  if (ip6)
  353: 	    {
  354: 	      listnode_delete (circuit->ipv6_non_link, ip6);
  355: 	      found = 1;
  356: 	    }
  357: 	}
  358: 
  359:       if (!found)
  360: 	{
  361: 	  prefix2str (connected->address, (char *)buf, BUFSIZ);
  362: 	  zlog_warn("Nonexitant ip address %s removal attempt from \
  363: 		     circuit %d", buf, circuit->circuit_id);
  364: 	}
  365:       else
  366: 	if (circuit->area)
  367: 	  lsp_regenerate_schedule (circuit->area);
  368:     }
  369: #endif /* HAVE_IPV6 */
  370:   return;
  371: }
  372: 
  373: void
  374: isis_circuit_if_add (struct isis_circuit *circuit, struct interface *ifp)
  375: {
  376:   struct listnode *node, *nnode;
  377:   struct connected *conn;
  378: 
  379:   circuit->interface = ifp;
  380:   ifp->info = circuit;
  381: 
  382:   circuit->circuit_id = ifp->ifindex % 255;	/* FIXME: Why not ? */
  383: 
  384:   /*  isis_circuit_update_addrs (circuit, ifp); */
  385: 
  386:   if (if_is_broadcast (ifp))
  387:     {
  388:       circuit->circ_type = CIRCUIT_T_BROADCAST;
  389:       /*
  390:        * Get the Hardware Address
  391:        */
  392: #ifdef HAVE_STRUCT_SOCKADDR_DL
  393: #ifndef SUNOS_5
  394:       if (circuit->interface->sdl.sdl_alen != ETHER_ADDR_LEN)
  395: 	zlog_warn ("unsupported link layer");
  396:       else
  397: 	memcpy (circuit->u.bc.snpa, LLADDR (&circuit->interface->sdl),
  398: 		ETH_ALEN);
  399: #endif
  400: #else
  401:       if (circuit->interface->hw_addr_len != ETH_ALEN)
  402: 	{
  403: 	  zlog_warn ("unsupported link layer");
  404: 	}
  405:       else
  406: 	{
  407: 	  memcpy (circuit->u.bc.snpa, circuit->interface->hw_addr, ETH_ALEN);
  408: 	}
  409: #ifdef EXTREME_DEGUG
  410:       zlog_debug ("isis_circuit_if_add: if_id %d, isomtu %d snpa %s",
  411: 		 circuit->interface->ifindex, ISO_MTU (circuit),
  412: 		 snpa_print (circuit->u.bc.snpa));
  413: 
  414: #endif /* EXTREME_DEBUG */
  415: #endif /* HAVE_STRUCT_SOCKADDR_DL */
  416:     }
  417:   else if (if_is_pointopoint (ifp))
  418:     {
  419:       circuit->circ_type = CIRCUIT_T_P2P;
  420:     }
  421:   else
  422:     {
  423:       /* It's normal in case of loopback etc. */
  424:       if (isis->debugs & DEBUG_EVENTS)
  425: 	zlog_debug ("isis_circuit_if_add: unsupported media");
  426:     }
  427: 
  428:   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, conn))
  429:     isis_circuit_add_addr (circuit, conn);
  430: 
  431:   return;
  432: }
  433: 
  434: void
  435: isis_circuit_update_params (struct isis_circuit *circuit,
  436: 			    struct interface *ifp)
  437: {
  438:   assert (circuit);
  439: 
  440:   if (circuit->circuit_id != ifp->ifindex)
  441:     {
  442:       zlog_warn ("changing circuit_id %d->%d", circuit->circuit_id,
  443: 		 ifp->ifindex);
  444:       circuit->circuit_id = ifp->ifindex % 255;
  445:     }
  446: 
  447:   /* FIXME: Why is this needed? shouldn't we compare to the area's mtu */
  448:   /* Ofer, this was here in case someone changes the mtu (e.g. with ifconfig) 
  449:      The areas MTU is the minimum of mtu's of circuits in the area
  450:      now we can't catch the change
  451:      if (circuit->mtu != ifp->mtu) {
  452:      zlog_warn ("changing circuit mtu %d->%d", circuit->mtu, 
  453:      ifp->mtu);    
  454:      circuit->mtu = ifp->mtu;
  455:      }
  456:    */
  457:   /*
  458:    * Get the Hardware Address
  459:    */
  460: #ifdef HAVE_STRUCT_SOCKADDR_DL
  461: #ifndef SUNOS_5
  462:   if (circuit->interface->sdl.sdl_alen != ETHER_ADDR_LEN)
  463:     zlog_warn ("unsupported link layer");
  464:   else
  465:     memcpy (circuit->u.bc.snpa, LLADDR (&circuit->interface->sdl), ETH_ALEN);
  466: #endif
  467: #else
  468:   if (circuit->interface->hw_addr_len != ETH_ALEN)
  469:     {
  470:       zlog_warn ("unsupported link layer");
  471:     }
  472:   else
  473:     {
  474:       if (memcmp (circuit->u.bc.snpa, circuit->interface->hw_addr, ETH_ALEN))
  475: 	{
  476: 	  zlog_warn ("changing circuit snpa %s->%s",
  477: 		     snpa_print (circuit->u.bc.snpa),
  478: 		     snpa_print (circuit->interface->hw_addr));
  479: 	}
  480:     }
  481: #endif
  482: 
  483:   if (if_is_broadcast (ifp))
  484:     {
  485:       circuit->circ_type = CIRCUIT_T_BROADCAST;
  486:     }
  487:   else if (if_is_pointopoint (ifp))
  488:     {
  489:       circuit->circ_type = CIRCUIT_T_P2P;
  490:     }
  491:   else
  492:     {
  493:       zlog_warn ("isis_circuit_update_params: unsupported media");
  494:     }
  495: 
  496:   return;
  497: }
  498: 
  499: void
  500: isis_circuit_if_del (struct isis_circuit *circuit)
  501: {
  502:   circuit->interface->info = NULL;
  503:   circuit->interface = NULL;
  504: 
  505:   return;
  506: }
  507: 
  508: void
  509: isis_circuit_up (struct isis_circuit *circuit)
  510: {
  511: 
  512:   if (circuit->circ_type == CIRCUIT_T_BROADCAST)
  513:     {
  514:       if (circuit->area->min_bcast_mtu == 0 ||
  515: 	  ISO_MTU (circuit) < circuit->area->min_bcast_mtu)
  516: 	circuit->area->min_bcast_mtu = ISO_MTU (circuit);
  517:       /*
  518:        * ISO 10589 - 8.4.1 Enabling of broadcast circuits
  519:        */
  520: 
  521:       /* initilizing the hello sending threads
  522:        * for a broadcast IF
  523:        */
  524: 
  525:       /* 8.4.1 a) commence sending of IIH PDUs */
  526: 
  527:       if (circuit->circuit_is_type & IS_LEVEL_1)
  528: 	{
  529: 	  thread_add_event (master, send_lan_l1_hello, circuit, 0);
  530: 	  circuit->u.bc.lan_neighs[0] = list_new ();
  531: 	}
  532: 
  533:       if (circuit->circuit_is_type & IS_LEVEL_2)
  534: 	{
  535: 	  thread_add_event (master, send_lan_l2_hello, circuit, 0);
  536: 	  circuit->u.bc.lan_neighs[1] = list_new ();
  537: 	}
  538: 
  539:       /* 8.4.1 b) FIXME: solicit ES - 8.4.6 */
  540:       /* 8.4.1 c) FIXME: listen for ESH PDUs */
  541: 
  542:       /* 8.4.1 d) */
  543:       /* dr election will commence in... */
  544:       if (circuit->circuit_is_type & IS_LEVEL_1)
  545: 	THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
  546: 			 circuit, 2 * circuit->hello_interval[0]);
  547:       if (circuit->circuit_is_type & IS_LEVEL_2)
  548: 	THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
  549: 			 circuit, 2 * circuit->hello_interval[1]);
  550:     }
  551:   else
  552:     {
  553:       /* initializing the hello send threads
  554:        * for a ptp IF
  555:        */
  556:       thread_add_event (master, send_p2p_hello, circuit, 0);
  557: 
  558:     }
  559: 
  560:   /* initializing PSNP timers */
  561:   if (circuit->circuit_is_type & IS_LEVEL_1)
  562:     {
  563:       THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
  564: 		       isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
  565:     }
  566: 
  567:   if (circuit->circuit_is_type & IS_LEVEL_2)
  568:     {
  569:       THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
  570: 		       isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
  571:     }
  572: 
  573:   /* initialize the circuit streams */
  574:   if (circuit->rcv_stream == NULL)
  575:     circuit->rcv_stream = stream_new (ISO_MTU (circuit));
  576: 
  577:   if (circuit->snd_stream == NULL)
  578:     circuit->snd_stream = stream_new (ISO_MTU (circuit));
  579: 
  580:   /* unified init for circuits */
  581:   isis_sock_init (circuit);
  582: 
  583: #ifdef GNU_LINUX
  584:   THREAD_READ_ON (master, circuit->t_read, isis_receive, circuit,
  585: 		  circuit->fd);
  586: #else
  587:   THREAD_TIMER_ON (master, circuit->t_read, isis_receive, circuit,
  588: 		   circuit->fd);
  589: #endif
  590:   return;
  591: }
  592: 
  593: void
  594: isis_circuit_down (struct isis_circuit *circuit)
  595: {
  596:   /* Cancel all active threads -- FIXME: wrong place */
  597:   /* HT: Read thread if GNU_LINUX, TIMER thread otherwise. */
  598:   THREAD_OFF (circuit->t_read);
  599:   if (circuit->circ_type == CIRCUIT_T_BROADCAST)
  600:     {
  601:       THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[0]);
  602:       THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[1]);
  603:       THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[0]);
  604:       THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[1]);
  605:     }
  606:   else if (circuit->circ_type == CIRCUIT_T_P2P)
  607:     {
  608:       THREAD_TIMER_OFF (circuit->u.p2p.t_send_p2p_hello);
  609:     }
  610: 
  611:   if (circuit->t_send_psnp[0]) {
  612:     THREAD_TIMER_OFF (circuit->t_send_psnp[0]);
  613:   }
  614:   if (circuit->t_send_psnp[1]) {
  615:     THREAD_TIMER_OFF (circuit->t_send_psnp[1]);
  616:   }
  617:   /* close the socket */
  618:   close (circuit->fd);
  619: 
  620:   return;
  621: }
  622: 
  623: void
  624: circuit_update_nlpids (struct isis_circuit *circuit)
  625: {
  626:   circuit->nlpids.count = 0;
  627: 
  628:   if (circuit->ip_router)
  629:     {
  630:       circuit->nlpids.nlpids[0] = NLPID_IP;
  631:       circuit->nlpids.count++;
  632:     }
  633: #ifdef HAVE_IPV6
  634:   if (circuit->ipv6_router)
  635:     {
  636:       circuit->nlpids.nlpids[circuit->nlpids.count] = NLPID_IPV6;
  637:       circuit->nlpids.count++;
  638:     }
  639: #endif /* HAVE_IPV6 */
  640:   return;
  641: }
  642: 
  643: int
  644: isis_interface_config_write (struct vty *vty)
  645: {
  646: 
  647:   int write = 0;
  648:   struct listnode *node, *node2;
  649:   struct interface *ifp;
  650:   struct isis_area *area;
  651:   struct isis_circuit *c;
  652:   int i;
  653: 
  654:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  655:   {
  656:     /* IF name */
  657:     vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
  658:     write++;
  659:     /* IF desc */
  660:     if (ifp->desc)
  661:       {
  662: 	vty_out (vty, " description %s%s", ifp->desc, VTY_NEWLINE);
  663: 	write++;
  664:       }
  665:     /* ISIS Circuit */
  666:     for (ALL_LIST_ELEMENTS_RO (isis->area_list, node2, area))
  667:     {
  668:       c = circuit_lookup_by_ifp (ifp, area->circuit_list);
  669:       if (c)
  670: 	{
  671: 	  if (c->ip_router)
  672: 	    {
  673: 	      vty_out (vty, " ip router isis %s%s", area->area_tag,
  674: 		       VTY_NEWLINE);
  675: 	      write++;
  676: 	    }
  677: #ifdef HAVE_IPV6
  678: 	  if (c->ipv6_router)
  679: 	    {
  680: 	      vty_out (vty, " ipv6 router isis %s%s", area->area_tag,
  681: 		       VTY_NEWLINE);
  682: 	      write++;
  683: 	    }
  684: #endif /* HAVE_IPV6 */
  685: 
  686: 	  /* ISIS - circuit type */
  687: 	  if (c->circuit_is_type == IS_LEVEL_1)
  688: 	    {
  689: 	      vty_out (vty, " isis circuit-type level-1%s", VTY_NEWLINE);
  690: 	      write++;
  691: 	    }
  692: 	  else
  693: 	    {
  694: 	      if (c->circuit_is_type == IS_LEVEL_2)
  695: 		{
  696: 		  vty_out (vty, " isis circuit-type level-2-only%s",
  697: 			   VTY_NEWLINE);
  698: 		  write++;
  699: 		}
  700: 	    }
  701: 
  702: 	  /* ISIS - CSNP interval - FIXME: compare to cisco */
  703: 	  if (c->csnp_interval[0] == c->csnp_interval[1])
  704: 	    {
  705: 	      if (c->csnp_interval[0] != CSNP_INTERVAL)
  706: 		{
  707: 		  vty_out (vty, " isis csnp-interval %d%s",
  708: 			   c->csnp_interval[0], VTY_NEWLINE);
  709: 		  write++;
  710: 		}
  711: 	    }
  712: 	  else
  713: 	    {
  714: 	      for (i = 0; i < 2; i++)
  715: 		{
  716: 		  if (c->csnp_interval[1] != CSNP_INTERVAL)
  717: 		    {
  718: 		      vty_out (vty, " isis csnp-interval %d level-%d%s",
  719: 			       c->csnp_interval[1], i + 1, VTY_NEWLINE);
  720: 		      write++;
  721: 		    }
  722: 		}
  723: 	    }
  724: 
  725: 	  /* ISIS - Hello padding - Defaults to true so only display if false */
  726: 	  if (c->circ_type == CIRCUIT_T_BROADCAST && !c->u.bc.pad_hellos)
  727: 	    {
  728: 	      vty_out (vty, " no isis hello padding%s", VTY_NEWLINE);
  729: 	      write++;
  730: 	    }
  731: 
  732: 	  /* ISIS - Hello interval - FIXME: compare to cisco */
  733: 	  if (c->hello_interval[0] == c->hello_interval[1])
  734: 	    {
  735: 	      if (c->hello_interval[0] != HELLO_INTERVAL)
  736: 		{
  737: 		  vty_out (vty, " isis hello-interval %d%s",
  738: 			   c->hello_interval[0], VTY_NEWLINE);
  739: 		  write++;
  740: 		}
  741: 	    }
  742: 	  else
  743: 	    {
  744: 	      for (i = 0; i < 2; i++)
  745: 		{
  746: 		  if (c->hello_interval[i] != HELLO_INTERVAL)
  747: 		    {
  748: 		      if (c->hello_interval[i] == HELLO_MINIMAL)
  749: 			{
  750: 			  vty_out (vty,
  751: 				   " isis hello-interval minimal level-%d%s",
  752: 				   i + 1, VTY_NEWLINE);
  753: 			}
  754: 		      else
  755: 			{
  756: 			  vty_out (vty, " isis hello-interval %d level-%d%s",
  757: 				   c->hello_interval[i], i + 1, VTY_NEWLINE);
  758: 			}
  759: 		      write++;
  760: 		    }
  761: 		}
  762: 	    }
  763: 
  764: 	  /* ISIS - Hello Multiplier */
  765: 	  if (c->hello_multiplier[0] == c->hello_multiplier[1])
  766: 	    {
  767: 	      if (c->hello_multiplier[0] != HELLO_MULTIPLIER)
  768: 		{
  769: 		  vty_out (vty, " isis hello-multiplier %d%s",
  770: 			   c->hello_multiplier[0], VTY_NEWLINE);
  771: 		  write++;
  772: 		}
  773: 	    }
  774: 	  else
  775: 	    {
  776: 	      for (i = 0; i < 2; i++)
  777: 		{
  778: 		  if (c->hello_multiplier[i] != HELLO_MULTIPLIER)
  779: 		    {
  780: 		      vty_out (vty, " isis hello-multiplier %d level-%d%s",
  781: 			       c->hello_multiplier[i], i + 1, VTY_NEWLINE);
  782: 		      write++;
  783: 		    }
  784: 		}
  785: 	    }
  786: 	  /* ISIS - Priority */
  787: 	  if (c->circ_type == CIRCUIT_T_BROADCAST)
  788: 	    {
  789: 	      if (c->u.bc.priority[0] == c->u.bc.priority[1])
  790: 		{
  791: 		  if (c->u.bc.priority[0] != DEFAULT_PRIORITY)
  792: 		    {
  793: 		      vty_out (vty, " isis priority %d%s",
  794: 			       c->u.bc.priority[0], VTY_NEWLINE);
  795: 		      write++;
  796: 		    }
  797: 		}
  798: 	      else
  799: 		{
  800: 		  for (i = 0; i < 2; i++)
  801: 		    {
  802: 		      if (c->u.bc.priority[i] != DEFAULT_PRIORITY)
  803: 			{
  804: 			  vty_out (vty, " isis priority %d level-%d%s",
  805: 				   c->u.bc.priority[i], i + 1, VTY_NEWLINE);
  806: 			  write++;
  807: 			}
  808: 		    }
  809: 		}
  810: 	    }
  811: 	  /* ISIS - Metric */
  812: 	  if (c->te_metric[0] == c->te_metric[1])
  813: 	    {
  814: 	      if (c->te_metric[0] != DEFAULT_CIRCUIT_METRICS)
  815: 		{
  816: 		  vty_out (vty, " isis metric %d%s", c->te_metric[0],
  817: 			   VTY_NEWLINE);
  818: 		  write++;
  819: 		}
  820: 	    }
  821: 	  else
  822: 	    {
  823: 	      for (i = 0; i < 2; i++)
  824: 		{
  825: 		  if (c->te_metric[i] != DEFAULT_CIRCUIT_METRICS)
  826: 		    {
  827: 		      vty_out (vty, " isis metric %d level-%d%s",
  828: 			       c->te_metric[i], i + 1, VTY_NEWLINE);
  829: 		      write++;
  830: 		    }
  831: 		}
  832: 	    }
  833: 
  834: 	}
  835:     }
  836:     vty_out (vty, "!%s", VTY_NEWLINE);
  837:   }
  838: 
  839:   return write;
  840: }
  841: 
  842: DEFUN (ip_router_isis,
  843:        ip_router_isis_cmd,
  844:        "ip router isis WORD",
  845:        "Interface Internet Protocol config commands\n"
  846:        "IP router interface commands\n"
  847:        "IS-IS Routing for IP\n"
  848:        "Routing process tag\n")
  849: {
  850:   struct isis_circuit *c;
  851:   struct interface *ifp;
  852:   struct isis_area *area;
  853: 
  854:   ifp = (struct interface *) vty->index;
  855:   assert (ifp);
  856: 
  857:   area = isis_area_lookup (argv[0]);
  858: 
  859:   /* Prevent more than one circuit per interface */
  860:   if (area)
  861:     c = circuit_lookup_by_ifp (ifp, area->circuit_list);
  862:   else
  863:     c = NULL;
  864:   if (c && (ifp->info != NULL))
  865:     {
  866: #ifdef HAVE_IPV6
  867:       if (c->ipv6_router == 0)
  868: 	{
  869: #endif /* HAVE_IPV6 */
  870: 	  /* FIXME: Find the way to warn only vty users. */
  871: 	  /* vty_out (vty, "ISIS circuit is already defined%s", VTY_NEWLINE); */
  872: 	  return CMD_WARNING;
  873: #ifdef HAVE_IPV6
  874: 	}
  875: #endif /* HAVE_IPV6 */
  876:     }
  877: 
  878:   /* this is here for ciscopability */
  879:   if (!area)
  880:     {
  881:       /* FIXME: Find the way to warn only vty users. */
  882:       /* vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE); */
  883:       return CMD_WARNING;
  884:     }
  885: 
  886:   if (!c)
  887:     {
  888:       c = circuit_lookup_by_ifp (ifp, isis->init_circ_list);
  889:       c = isis_csm_state_change (ISIS_ENABLE, c, area);
  890:       c->interface = ifp;	/* this is automatic */
  891:       ifp->info = c;		/* hardly related to the FSM */
  892:     }
  893: 
  894:   if (!c)
  895:     return CMD_WARNING;
  896: 
  897:   c->ip_router = 1;
  898:   area->ip_circuits++;
  899:   circuit_update_nlpids (c);
  900: 
  901:   vty->node = INTERFACE_NODE;
  902: 
  903:   return CMD_SUCCESS;
  904: }
  905: 
  906: DEFUN (no_ip_router_isis,
  907:        no_ip_router_isis_cmd,
  908:        "no ip router isis WORD",
  909:        NO_STR
  910:        "Interface Internet Protocol config commands\n"
  911:        "IP router interface commands\n"
  912:        "IS-IS Routing for IP\n"
  913:        "Routing process tag\n")
  914: {
  915:   struct isis_circuit *circuit = NULL;
  916:   struct interface *ifp;
  917:   struct isis_area *area;
  918:   struct listnode *node;
  919: 
  920:   ifp = (struct interface *) vty->index;
  921:   assert (ifp);
  922: 
  923:   area = isis_area_lookup (argv[0]);
  924:   if (!area)
  925:     {
  926:       vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
  927:       return CMD_WARNING;
  928:     }
  929:   for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
  930:     if (circuit->interface == ifp)
  931:       break;
  932:   if (!circuit)
  933:     {
  934:       vty_out (vty, "Can't find ISIS interface %s", VTY_NEWLINE);
  935:       return CMD_WARNING;
  936:     }
  937:   circuit->ip_router = 0;
  938:   area->ip_circuits--;
  939: #ifdef HAVE_IPV6
  940:   if (circuit->ipv6_router == 0)
  941: #endif
  942:     isis_csm_state_change (ISIS_DISABLE, circuit, area);
  943: 
  944:   return CMD_SUCCESS;
  945: }
  946: 
  947: DEFUN (isis_circuit_type,
  948:        isis_circuit_type_cmd,
  949:        "isis circuit-type (level-1|level-1-2|level-2-only)",
  950:        "IS-IS commands\n"
  951:        "Configure circuit type for interface\n"
  952:        "Level-1 only adjacencies are formed\n"
  953:        "Level-1-2 adjacencies are formed\n"
  954:        "Level-2 only adjacencies are formed\n")
  955: {
  956:   struct isis_circuit *circuit;
  957:   struct interface *ifp;
  958:   int circuit_t;
  959:   int is_type;
  960: 
  961:   ifp = vty->index;
  962:   circuit = ifp->info;
  963:   /* UGLY - will remove l8r */
  964:   if (circuit == NULL)
  965:     {
  966:       return CMD_WARNING;
  967:     }
  968: 
  969:   /* XXX what to do when ip_router_isis is not executed */
  970:   if (circuit->area == NULL)
  971:     return CMD_WARNING;
  972: 
  973:   assert (circuit);
  974: 
  975:   circuit_t = string2circuit_t (argv[0]);
  976: 
  977:   if (!circuit_t)
  978:     {
  979:       vty_out (vty, "Unknown circuit-type %s", VTY_NEWLINE);
  980:       return CMD_SUCCESS;
  981:     }
  982: 
  983:   is_type = circuit->area->is_type;
  984:   if (is_type == IS_LEVEL_1_AND_2 || is_type == circuit_t)
  985:     isis_event_circuit_type_change (circuit, circuit_t);
  986:   else
  987:     {
  988:       vty_out (vty, "invalid circuit level for area %s.%s",
  989: 	       circuit->area->area_tag, VTY_NEWLINE);
  990:     }
  991: 
  992:   return CMD_SUCCESS;
  993: }
  994: 
  995: DEFUN (no_isis_circuit_type,
  996:        no_isis_circuit_type_cmd,
  997:        "no isis circuit-type (level-1|level-1-2|level-2-only)",
  998:        NO_STR
  999:        "IS-IS commands\n"
 1000:        "Configure circuit type for interface\n"
 1001:        "Level-1 only adjacencies are formed\n"
 1002:        "Level-1-2 adjacencies are formed\n"
 1003:        "Level-2 only adjacencies are formed\n")
 1004: {
 1005:   struct isis_circuit *circuit;
 1006:   struct interface *ifp;
 1007: 
 1008:   ifp = vty->index;
 1009:   circuit = ifp->info;
 1010:   if (circuit == NULL)
 1011:     {
 1012:       return CMD_WARNING;
 1013:     }
 1014: 
 1015:   assert (circuit);
 1016: 
 1017:   /*
 1018:    * Set the circuits level to its default value which is that of the area
 1019:    */
 1020:   isis_event_circuit_type_change (circuit, circuit->area->is_type);
 1021: 
 1022:   return CMD_SUCCESS;
 1023: }
 1024: 
 1025: DEFUN (isis_passwd,
 1026:        isis_passwd_cmd,
 1027:        "isis password WORD",
 1028:        "IS-IS commands\n"
 1029:        "Configure the authentication password for interface\n"
 1030:        "Password\n")
 1031: {
 1032:   struct isis_circuit *circuit;
 1033:   struct interface *ifp;
 1034:   int len;
 1035: 
 1036:   ifp = vty->index;
 1037:   circuit = ifp->info;
 1038:   if (circuit == NULL)
 1039:     {
 1040:       return CMD_WARNING;
 1041:     }
 1042: 
 1043:   len = strlen (argv[0]);
 1044:   if (len > 254)
 1045:     {
 1046:       vty_out (vty, "Too long circuit password (>254)%s", VTY_NEWLINE);
 1047:       return CMD_WARNING;
 1048:     }
 1049:   circuit->passwd.len = len;
 1050:   circuit->passwd.type = ISIS_PASSWD_TYPE_CLEARTXT;
 1051:   strncpy ((char *)circuit->passwd.passwd, argv[0], 255);
 1052: 
 1053:   return CMD_SUCCESS;
 1054: }
 1055: 
 1056: DEFUN (no_isis_passwd,
 1057:        no_isis_passwd_cmd,
 1058:        "no isis password",
 1059:        NO_STR
 1060:        "IS-IS commands\n"
 1061:        "Configure the authentication password for interface\n")
 1062: {
 1063:   struct isis_circuit *circuit;
 1064:   struct interface *ifp;
 1065: 
 1066:   ifp = vty->index;
 1067:   circuit = ifp->info;
 1068:   if (circuit == NULL)
 1069:     {
 1070:       return CMD_WARNING;
 1071:     }
 1072: 
 1073:   memset (&circuit->passwd, 0, sizeof (struct isis_passwd));
 1074: 
 1075:   return CMD_SUCCESS;
 1076: }
 1077: 
 1078: 
 1079: DEFUN (isis_priority,
 1080:        isis_priority_cmd,
 1081:        "isis priority <0-127>",
 1082:        "IS-IS commands\n"
 1083:        "Set priority for Designated Router election\n"
 1084:        "Priority value\n")
 1085: {
 1086:   struct isis_circuit *circuit;
 1087:   struct interface *ifp;
 1088:   int prio;
 1089: 
 1090:   ifp = vty->index;
 1091:   circuit = ifp->info;
 1092:   if (circuit == NULL)
 1093:     {
 1094:       return CMD_WARNING;
 1095:     }
 1096:   assert (circuit);
 1097: 
 1098:   prio = atoi (argv[0]);
 1099: 
 1100:   circuit->u.bc.priority[0] = prio;
 1101:   circuit->u.bc.priority[1] = prio;
 1102: 
 1103:   return CMD_SUCCESS;
 1104: }
 1105: 
 1106: DEFUN (no_isis_priority,
 1107:        no_isis_priority_cmd,
 1108:        "no isis priority",
 1109:        NO_STR
 1110:        "IS-IS commands\n"
 1111:        "Set priority for Designated Router election\n")
 1112: {
 1113:   struct isis_circuit *circuit;
 1114:   struct interface *ifp;
 1115: 
 1116:   ifp = vty->index;
 1117:   circuit = ifp->info;
 1118:   if (circuit == NULL)
 1119:     {
 1120:       return CMD_WARNING;
 1121:     }
 1122:   assert (circuit);
 1123: 
 1124:   circuit->u.bc.priority[0] = DEFAULT_PRIORITY;
 1125:   circuit->u.bc.priority[1] = DEFAULT_PRIORITY;
 1126: 
 1127:   return CMD_SUCCESS;
 1128: }
 1129: 
 1130: ALIAS (no_isis_priority,
 1131:        no_isis_priority_arg_cmd,
 1132:        "no isis priority <0-127>",
 1133:        NO_STR
 1134:        "IS-IS commands\n"
 1135:        "Set priority for Designated Router election\n"
 1136:        "Priority value\n")
 1137: 
 1138: DEFUN (isis_priority_l1,
 1139:        isis_priority_l1_cmd,
 1140:        "isis priority <0-127> level-1",
 1141:        "IS-IS commands\n"
 1142:        "Set priority for Designated Router election\n"
 1143:        "Priority value\n"
 1144:        "Specify priority for level-1 routing\n")
 1145: {
 1146:   struct isis_circuit *circuit;
 1147:   struct interface *ifp;
 1148:   int prio;
 1149: 
 1150:   ifp = vty->index;
 1151:   circuit = ifp->info;
 1152:   if (circuit == NULL)
 1153:     {
 1154:       return CMD_WARNING;
 1155:     }
 1156:   assert (circuit);
 1157: 
 1158:   prio = atoi (argv[0]);
 1159: 
 1160:   circuit->u.bc.priority[0] = prio;
 1161: 
 1162:   return CMD_SUCCESS;
 1163: }
 1164: 
 1165: DEFUN (no_isis_priority_l1,
 1166:        no_isis_priority_l1_cmd,
 1167:        "no isis priority level-1",
 1168:        NO_STR
 1169:        "IS-IS commands\n"
 1170:        "Set priority for Designated Router election\n"
 1171:        "Specify priority for level-1 routing\n")
 1172: {
 1173:   struct isis_circuit *circuit;
 1174:   struct interface *ifp;
 1175: 
 1176:   ifp = vty->index;
 1177:   circuit = ifp->info;
 1178:   if (circuit == NULL)
 1179:     {
 1180:       return CMD_WARNING;
 1181:     }
 1182:   assert (circuit);
 1183: 
 1184:   circuit->u.bc.priority[0] = DEFAULT_PRIORITY;
 1185: 
 1186:   return CMD_SUCCESS;
 1187: }
 1188: 
 1189: ALIAS (no_isis_priority_l1,
 1190:        no_isis_priority_l1_arg_cmd,
 1191:        "no isis priority <0-127> level-1",
 1192:        NO_STR
 1193:        "IS-IS commands\n"
 1194:        "Set priority for Designated Router election\n"
 1195:        "Priority value\n"
 1196:        "Specify priority for level-1 routing\n")
 1197: 
 1198: DEFUN (isis_priority_l2,
 1199:        isis_priority_l2_cmd,
 1200:        "isis priority <0-127> level-2",
 1201:        "IS-IS commands\n"
 1202:        "Set priority for Designated Router election\n"
 1203:        "Priority value\n"
 1204:        "Specify priority for level-2 routing\n")
 1205: {
 1206:   struct isis_circuit *circuit;
 1207:   struct interface *ifp;
 1208:   int prio;
 1209: 
 1210:   ifp = vty->index;
 1211:   circuit = ifp->info;
 1212:   if (circuit == NULL)
 1213:     {
 1214:       return CMD_WARNING;
 1215:     }
 1216:   assert (circuit);
 1217: 
 1218:   prio = atoi (argv[0]);
 1219: 
 1220:   circuit->u.bc.priority[1] = prio;
 1221: 
 1222:   return CMD_SUCCESS;
 1223: }
 1224: 
 1225: DEFUN (no_isis_priority_l2,
 1226:        no_isis_priority_l2_cmd,
 1227:        "no isis priority level-2",
 1228:        NO_STR
 1229:        "IS-IS commands\n"
 1230:        "Set priority for Designated Router election\n"
 1231:        "Specify priority for level-2 routing\n")
 1232: {
 1233:   struct isis_circuit *circuit;
 1234:   struct interface *ifp;
 1235: 
 1236:   ifp = vty->index;
 1237:   circuit = ifp->info;
 1238:   if (circuit == NULL)
 1239:     {
 1240:       return CMD_WARNING;
 1241:     }
 1242:   assert (circuit);
 1243: 
 1244:   circuit->u.bc.priority[1] = DEFAULT_PRIORITY;
 1245: 
 1246:   return CMD_SUCCESS;
 1247: }
 1248: 
 1249: ALIAS (no_isis_priority_l2,
 1250:        no_isis_priority_l2_arg_cmd,
 1251:        "no isis priority <0-127> level-2",
 1252:        NO_STR
 1253:        "IS-IS commands\n"
 1254:        "Set priority for Designated Router election\n"
 1255:        "Priority value\n"
 1256:        "Specify priority for level-2 routing\n")
 1257: 
 1258: /* Metric command */
 1259:   DEFUN (isis_metric,
 1260:        isis_metric_cmd,
 1261:        "isis metric <0-16777215>",
 1262:        "IS-IS commands\n"
 1263:        "Set default metric for circuit\n"
 1264:        "Default metric value\n")
 1265: {
 1266:   struct isis_circuit *circuit;
 1267:   struct interface *ifp;
 1268:   int met;
 1269: 
 1270:   ifp = vty->index;
 1271:   circuit = ifp->info;
 1272:   if (circuit == NULL)
 1273:     {
 1274:       return CMD_WARNING;
 1275:     }
 1276:   assert (circuit);
 1277: 
 1278:   met = atoi (argv[0]);
 1279: 
 1280:   circuit->te_metric[0] = met;
 1281:   circuit->te_metric[1] = met;
 1282: 
 1283:   if (met > 63)
 1284:     met = 63;
 1285: 
 1286:   circuit->metrics[0].metric_default = met;
 1287:   circuit->metrics[1].metric_default = met;
 1288: 
 1289:   return CMD_SUCCESS;
 1290: }
 1291: 
 1292: DEFUN (no_isis_metric,
 1293:        no_isis_metric_cmd,
 1294:        "no isis metric",
 1295:        NO_STR
 1296:        "IS-IS commands\n"
 1297:        "Set default metric for circuit\n")
 1298: {
 1299:   struct isis_circuit *circuit;
 1300:   struct interface *ifp;
 1301: 
 1302:   ifp = vty->index;
 1303:   circuit = ifp->info;
 1304:   if (circuit == NULL)
 1305:     {
 1306:       return CMD_WARNING;
 1307:     }
 1308:   assert (circuit);
 1309: 
 1310:   circuit->te_metric[0] = DEFAULT_CIRCUIT_METRICS;
 1311:   circuit->te_metric[1] = DEFAULT_CIRCUIT_METRICS;
 1312:   circuit->metrics[0].metric_default = DEFAULT_CIRCUIT_METRICS;
 1313:   circuit->metrics[1].metric_default = DEFAULT_CIRCUIT_METRICS;
 1314: 
 1315:   return CMD_SUCCESS;
 1316: }
 1317: 
 1318: ALIAS (no_isis_metric,
 1319:        no_isis_metric_arg_cmd,
 1320:        "no isis metric <0-16777215>",
 1321:        NO_STR
 1322:        "IS-IS commands\n"
 1323:        "Set default metric for circuit\n"
 1324:        "Default metric value\n")
 1325: 
 1326: /* end of metrics */
 1327: DEFUN (isis_hello_interval,
 1328:        isis_hello_interval_cmd,
 1329:        "isis hello-interval (<1-65535>|minimal)",
 1330:        "IS-IS commands\n"
 1331:        "Set Hello interval\n"
 1332:        "Hello interval value\n"
 1333:        "Holdtime 1 seconds, interval depends on multiplier\n")
 1334: {
 1335:   struct isis_circuit *circuit;
 1336:   struct interface *ifp;
 1337:   int interval;
 1338:   char c;
 1339: 
 1340:   ifp = vty->index;
 1341:   circuit = ifp->info;
 1342:   if (circuit == NULL)
 1343:     {
 1344:       return CMD_WARNING;
 1345:     }
 1346:   assert (circuit);
 1347:   c = *argv[0];
 1348:   if (isdigit ((int) c))
 1349:     {
 1350:       interval = atoi (argv[0]);
 1351:     }
 1352:   else
 1353:     interval = HELLO_MINIMAL;	/* FIXME: should be calculated */
 1354: 
 1355:   circuit->hello_interval[0] = (u_int16_t) interval;
 1356:   circuit->hello_interval[1] = (u_int16_t) interval;
 1357: 
 1358:   return CMD_SUCCESS;
 1359: }
 1360: 
 1361: DEFUN (no_isis_hello_interval,
 1362:        no_isis_hello_interval_cmd,
 1363:        "no isis hello-interval",
 1364:        NO_STR
 1365:        "IS-IS commands\n"
 1366:        "Set Hello interval\n")
 1367: {
 1368:   struct isis_circuit *circuit;
 1369:   struct interface *ifp;
 1370: 
 1371:   ifp = vty->index;
 1372:   circuit = ifp->info;
 1373:   if (circuit == NULL)
 1374:     {
 1375:       return CMD_WARNING;
 1376:     }
 1377:   assert (circuit);
 1378: 
 1379: 
 1380:   circuit->hello_interval[0] = HELLO_INTERVAL;	/* Default is 1 sec. */
 1381:   circuit->hello_interval[1] = HELLO_INTERVAL;
 1382: 
 1383:   return CMD_SUCCESS;
 1384: }
 1385: 
 1386: ALIAS (no_isis_hello_interval,
 1387:        no_isis_hello_interval_arg_cmd,
 1388:        "no isis hello-interval (<1-65535>|minimal)",
 1389:        NO_STR
 1390:        "IS-IS commands\n"
 1391:        "Set Hello interval\n"
 1392:        "Hello interval value\n"
 1393:        "Holdtime 1 second, interval depends on multiplier\n")
 1394: 
 1395: DEFUN (isis_hello_interval_l1,
 1396:        isis_hello_interval_l1_cmd,
 1397:        "isis hello-interval (<1-65535>|minimal) level-1",
 1398:        "IS-IS commands\n"
 1399:        "Set Hello interval\n"
 1400:        "Hello interval value\n"
 1401:        "Holdtime 1 second, interval depends on multiplier\n"
 1402:        "Specify hello-interval for level-1 IIHs\n")
 1403: {
 1404:   struct isis_circuit *circuit;
 1405:   struct interface *ifp;
 1406:   long interval;
 1407:   char c;
 1408: 
 1409:   ifp = vty->index;
 1410:   circuit = ifp->info;
 1411:   if (circuit == NULL)
 1412:     {
 1413:       return CMD_WARNING;
 1414:     }
 1415:   assert (circuit);
 1416: 
 1417:   c = *argv[0];
 1418:   if (isdigit ((int) c))
 1419:     {
 1420:       interval = atoi (argv[0]);
 1421:     }
 1422:   else
 1423:     interval = HELLO_MINIMAL;
 1424: 
 1425:   circuit->hello_interval[0] = (u_int16_t) interval;
 1426: 
 1427:   return CMD_SUCCESS;
 1428: }
 1429: 
 1430: DEFUN (no_isis_hello_interval_l1,
 1431:        no_isis_hello_interval_l1_cmd,
 1432:        "no isis hello-interval level-1",
 1433:        NO_STR
 1434:        "IS-IS commands\n"
 1435:        "Set Hello interval\n"
 1436:        "Specify hello-interval for level-1 IIHs\n")
 1437: {
 1438:   struct isis_circuit *circuit;
 1439:   struct interface *ifp;
 1440: 
 1441:   ifp = vty->index;
 1442:   circuit = ifp->info;
 1443:   if (circuit == NULL)
 1444:     {
 1445:       return CMD_WARNING;
 1446:     }
 1447:   assert (circuit);
 1448: 
 1449: 
 1450:   circuit->hello_interval[0] = HELLO_INTERVAL;	/* Default is 1 sec. */
 1451: 
 1452:   return CMD_SUCCESS;
 1453: }
 1454: 
 1455: ALIAS (no_isis_hello_interval_l1,
 1456:        no_isis_hello_interval_l1_arg_cmd,
 1457:        "no isis hello-interval (<1-65535>|minimal) level-1",
 1458:        NO_STR
 1459:        "IS-IS commands\n"
 1460:        "Set Hello interval\n"
 1461:        "Hello interval value\n"
 1462:        "Holdtime 1 second, interval depends on multiplier\n"
 1463:        "Specify hello-interval for level-1 IIHs\n")
 1464: 
 1465: DEFUN (isis_hello_interval_l2,
 1466:        isis_hello_interval_l2_cmd,
 1467:        "isis hello-interval (<1-65535>|minimal) level-2",
 1468:        "IS-IS commands\n"
 1469:        "Set Hello interval\n"
 1470:        "Hello interval value\n"
 1471:        "Holdtime 1 second, interval depends on multiplier\n"
 1472:        "Specify hello-interval for level-2 IIHs\n")
 1473: {
 1474:   struct isis_circuit *circuit;
 1475:   struct interface *ifp;
 1476:   long interval;
 1477:   char c;
 1478: 
 1479:   ifp = vty->index;
 1480:   circuit = ifp->info;
 1481:   if (circuit == NULL)
 1482:     {
 1483:       return CMD_WARNING;
 1484:     }
 1485:   assert (circuit);
 1486: 
 1487:   c = *argv[0];
 1488:   if (isdigit ((int) c))
 1489:     {
 1490:       interval = atoi (argv[0]);
 1491:     }
 1492:   else
 1493:     interval = HELLO_MINIMAL;
 1494: 
 1495:   circuit->hello_interval[1] = (u_int16_t) interval;
 1496: 
 1497:   return CMD_SUCCESS;
 1498: }
 1499: 
 1500: DEFUN (no_isis_hello_interval_l2,
 1501:        no_isis_hello_interval_l2_cmd,
 1502:        "no isis hello-interval level-2",
 1503:        NO_STR
 1504:        "IS-IS commands\n"
 1505:        "Set Hello interval\n"
 1506:        "Specify hello-interval for level-2 IIHs\n")
 1507: {
 1508:   struct isis_circuit *circuit;
 1509:   struct interface *ifp;
 1510: 
 1511:   ifp = vty->index;
 1512:   circuit = ifp->info;
 1513:   if (circuit == NULL)
 1514:     {
 1515:       return CMD_WARNING;
 1516:     }
 1517:   assert (circuit);
 1518: 
 1519: 
 1520:   circuit->hello_interval[1] = HELLO_INTERVAL;	/* Default is 1 sec. */
 1521: 
 1522:   return CMD_SUCCESS;
 1523: }
 1524: 
 1525: ALIAS (no_isis_hello_interval_l2,
 1526:        no_isis_hello_interval_l2_arg_cmd,
 1527:        "no isis hello-interval (<1-65535>|minimal) level-2",
 1528:        NO_STR
 1529:        "IS-IS commands\n"
 1530:        "Set Hello interval\n"
 1531:        "Hello interval value\n"
 1532:        "Holdtime 1 second, interval depends on multiplier\n"
 1533:        "Specify hello-interval for level-2 IIHs\n")
 1534: 
 1535: DEFUN (isis_hello_multiplier,
 1536:        isis_hello_multiplier_cmd,
 1537:        "isis hello-multiplier <3-1000>",
 1538:        "IS-IS commands\n"
 1539:        "Set multiplier for Hello holding time\n"
 1540:        "Hello multiplier value\n")
 1541: {
 1542:   struct isis_circuit *circuit;
 1543:   struct interface *ifp;
 1544:   int mult;
 1545: 
 1546:   ifp = vty->index;
 1547:   circuit = ifp->info;
 1548:   if (circuit == NULL)
 1549:     {
 1550:       return CMD_WARNING;
 1551:     }
 1552:   assert (circuit);
 1553: 
 1554:   mult = atoi (argv[0]);
 1555: 
 1556:   circuit->hello_multiplier[0] = (u_int16_t) mult;
 1557:   circuit->hello_multiplier[1] = (u_int16_t) mult;
 1558: 
 1559:   return CMD_SUCCESS;
 1560: }
 1561: 
 1562: DEFUN (no_isis_hello_multiplier,
 1563:        no_isis_hello_multiplier_cmd,
 1564:        "no isis hello-multiplier",
 1565:        NO_STR
 1566:        "IS-IS commands\n"
 1567:        "Set multiplier for Hello holding time\n")
 1568: {
 1569:   struct isis_circuit *circuit;
 1570:   struct interface *ifp;
 1571: 
 1572:   ifp = vty->index;
 1573:   circuit = ifp->info;
 1574:   if (circuit == NULL)
 1575:     {
 1576:       return CMD_WARNING;
 1577:     }
 1578:   assert (circuit);
 1579: 
 1580:   circuit->hello_multiplier[0] = HELLO_MULTIPLIER;
 1581:   circuit->hello_multiplier[1] = HELLO_MULTIPLIER;
 1582: 
 1583:   return CMD_SUCCESS;
 1584: }
 1585: 
 1586: ALIAS (no_isis_hello_multiplier,
 1587:        no_isis_hello_multiplier_arg_cmd,
 1588:        "no isis hello-multiplier <3-1000>",
 1589:        NO_STR
 1590:        "IS-IS commands\n"
 1591:        "Set multiplier for Hello holding time\n"
 1592:        "Hello multiplier value\n")
 1593: 
 1594: DEFUN (isis_hello_multiplier_l1,
 1595:        isis_hello_multiplier_l1_cmd,
 1596:        "isis hello-multiplier <3-1000> level-1",
 1597:        "IS-IS commands\n"
 1598:        "Set multiplier for Hello holding time\n"
 1599:        "Hello multiplier value\n"
 1600:        "Specify hello multiplier for level-1 IIHs\n")
 1601: {
 1602:   struct isis_circuit *circuit;
 1603:   struct interface *ifp;
 1604:   int mult;
 1605: 
 1606:   ifp = vty->index;
 1607:   circuit = ifp->info;
 1608:   if (circuit == NULL)
 1609:     {
 1610:       return CMD_WARNING;
 1611:     }
 1612:   assert (circuit);
 1613: 
 1614:   mult = atoi (argv[0]);
 1615: 
 1616:   circuit->hello_multiplier[0] = (u_int16_t) mult;
 1617: 
 1618:   return CMD_SUCCESS;
 1619: }
 1620: 
 1621: DEFUN (no_isis_hello_multiplier_l1,
 1622:        no_isis_hello_multiplier_l1_cmd,
 1623:        "no isis hello-multiplier level-1",
 1624:        NO_STR
 1625:        "IS-IS commands\n"
 1626:        "Set multiplier for Hello holding time\n"
 1627:        "Specify hello multiplier for level-1 IIHs\n")
 1628: {
 1629:   struct isis_circuit *circuit;
 1630:   struct interface *ifp;
 1631: 
 1632:   ifp = vty->index;
 1633:   circuit = ifp->info;
 1634:   if (circuit == NULL)
 1635:     {
 1636:       return CMD_WARNING;
 1637:     }
 1638:   assert (circuit);
 1639: 
 1640:   circuit->hello_multiplier[0] = HELLO_MULTIPLIER;
 1641: 
 1642:   return CMD_SUCCESS;
 1643: }
 1644: 
 1645: ALIAS (no_isis_hello_multiplier_l1,
 1646:        no_isis_hello_multiplier_l1_arg_cmd,
 1647:        "no isis hello-multiplier <3-1000> level-1",
 1648:        NO_STR
 1649:        "IS-IS commands\n"
 1650:        "Set multiplier for Hello holding time\n"
 1651:        "Hello multiplier value\n"
 1652:        "Specify hello multiplier for level-1 IIHs\n")
 1653: 
 1654: DEFUN (isis_hello_multiplier_l2,
 1655:        isis_hello_multiplier_l2_cmd,
 1656:        "isis hello-multiplier <3-1000> level-2",
 1657:        "IS-IS commands\n"
 1658:        "Set multiplier for Hello holding time\n"
 1659:        "Hello multiplier value\n"
 1660:        "Specify hello multiplier for level-2 IIHs\n")
 1661: {
 1662:   struct isis_circuit *circuit;
 1663:   struct interface *ifp;
 1664:   int mult;
 1665: 
 1666:   ifp = vty->index;
 1667:   circuit = ifp->info;
 1668:   if (circuit == NULL)
 1669:     {
 1670:       return CMD_WARNING;
 1671:     }
 1672:   assert (circuit);
 1673: 
 1674:   mult = atoi (argv[0]);
 1675: 
 1676:   circuit->hello_multiplier[1] = (u_int16_t) mult;
 1677: 
 1678:   return CMD_SUCCESS;
 1679: }
 1680: 
 1681: DEFUN (no_isis_hello_multiplier_l2,
 1682:        no_isis_hello_multiplier_l2_cmd,
 1683:        "no isis hello-multiplier level-2",
 1684:        NO_STR
 1685:        "IS-IS commands\n"
 1686:        "Set multiplier for Hello holding time\n"
 1687:        "Specify hello multiplier for level-2 IIHs\n")
 1688: {
 1689:   struct isis_circuit *circuit;
 1690:   struct interface *ifp;
 1691: 
 1692:   ifp = vty->index;
 1693:   circuit = ifp->info;
 1694:   if (circuit == NULL)
 1695:     {
 1696:       return CMD_WARNING;
 1697:     }
 1698:   assert (circuit);
 1699: 
 1700:   circuit->hello_multiplier[1] = HELLO_MULTIPLIER;
 1701: 
 1702:   return CMD_SUCCESS;
 1703: }
 1704: 
 1705: ALIAS (no_isis_hello_multiplier_l2,
 1706:        no_isis_hello_multiplier_l2_arg_cmd,
 1707:        "no isis hello-multiplier <3-1000> level-2",
 1708:        NO_STR
 1709:        "IS-IS commands\n"
 1710:        "Set multiplier for Hello holding time\n"
 1711:        "Hello multiplier value\n"
 1712:        "Specify hello multiplier for level-2 IIHs\n")
 1713: 
 1714: DEFUN (isis_hello,
 1715:        isis_hello_cmd,
 1716:        "isis hello padding",
 1717:        "IS-IS commands\n"
 1718:        "Add padding to IS-IS hello packets\n"
 1719:        "Pad hello packets\n"
 1720:        "<cr>\n")
 1721: {
 1722:   struct interface *ifp;
 1723:   struct isis_circuit *circuit;
 1724: 
 1725:   ifp = vty->index;
 1726:   circuit = ifp->info;
 1727:   if (circuit == NULL)
 1728:     {
 1729:       return CMD_WARNING;
 1730:     }
 1731:   assert (circuit);
 1732: 
 1733:   circuit->u.bc.pad_hellos = 1;
 1734: 
 1735:   return CMD_SUCCESS;
 1736: }
 1737: 
 1738: DEFUN (no_isis_hello,
 1739:        no_isis_hello_cmd,
 1740:        "no isis hello padding",
 1741:        NO_STR
 1742:        "IS-IS commands\n"
 1743:        "Add padding to IS-IS hello packets\n"
 1744:        "Pad hello packets\n"
 1745:        "<cr>\n")
 1746: {
 1747:   struct isis_circuit *circuit;
 1748:   struct interface *ifp;
 1749: 
 1750:   ifp = vty->index;
 1751:   circuit = ifp->info;
 1752:   if (circuit == NULL)
 1753:     {
 1754:       return CMD_WARNING;
 1755:     }
 1756:   assert (circuit);
 1757: 
 1758:   circuit->u.bc.pad_hellos = 0;
 1759: 
 1760:   return CMD_SUCCESS;
 1761: }
 1762: 
 1763: DEFUN (csnp_interval,
 1764:        csnp_interval_cmd,
 1765:        "isis csnp-interval <0-65535>",
 1766:        "IS-IS commands\n"
 1767:        "Set CSNP interval in seconds\n"
 1768:        "CSNP interval value\n")
 1769: {
 1770:   struct isis_circuit *circuit;
 1771:   struct interface *ifp;
 1772:   unsigned long interval;
 1773: 
 1774:   ifp = vty->index;
 1775:   circuit = ifp->info;
 1776:   if (circuit == NULL)
 1777:     {
 1778:       return CMD_WARNING;
 1779:     }
 1780:   assert (circuit);
 1781: 
 1782:   interval = atol (argv[0]);
 1783: 
 1784:   circuit->csnp_interval[0] = (u_int16_t) interval;
 1785:   circuit->csnp_interval[1] = (u_int16_t) interval;
 1786: 
 1787:   return CMD_SUCCESS;
 1788: }
 1789: 
 1790: DEFUN (no_csnp_interval,
 1791:        no_csnp_interval_cmd,
 1792:        "no isis csnp-interval",
 1793:        NO_STR
 1794:        "IS-IS commands\n"
 1795:        "Set CSNP interval in seconds\n")
 1796: {
 1797:   struct isis_circuit *circuit;
 1798:   struct interface *ifp;
 1799: 
 1800:   ifp = vty->index;
 1801:   circuit = ifp->info;
 1802:   if (circuit == NULL)
 1803:     {
 1804:       return CMD_WARNING;
 1805:     }
 1806:   assert (circuit);
 1807: 
 1808:   circuit->csnp_interval[0] = CSNP_INTERVAL;
 1809:   circuit->csnp_interval[1] = CSNP_INTERVAL;
 1810: 
 1811:   return CMD_SUCCESS;
 1812: }
 1813: 
 1814: ALIAS (no_csnp_interval,
 1815:        no_csnp_interval_arg_cmd,
 1816:        "no isis csnp-interval <0-65535>",
 1817:        NO_STR
 1818:        "IS-IS commands\n"
 1819:        "Set CSNP interval in seconds\n"
 1820:        "CSNP interval value\n")
 1821: 
 1822: DEFUN (csnp_interval_l1,
 1823:        csnp_interval_l1_cmd,
 1824:        "isis csnp-interval <0-65535> level-1",
 1825:        "IS-IS commands\n"
 1826:        "Set CSNP interval in seconds\n"
 1827:        "CSNP interval value\n"
 1828:        "Specify interval for level-1 CSNPs\n")
 1829: {
 1830:   struct isis_circuit *circuit;
 1831:   struct interface *ifp;
 1832:   unsigned long interval;
 1833: 
 1834:   ifp = vty->index;
 1835:   circuit = ifp->info;
 1836:   if (circuit == NULL)
 1837:     {
 1838:       return CMD_WARNING;
 1839:     }
 1840:   assert (circuit);
 1841: 
 1842:   interval = atol (argv[0]);
 1843: 
 1844:   circuit->csnp_interval[0] = (u_int16_t) interval;
 1845: 
 1846:   return CMD_SUCCESS;
 1847: }
 1848: 
 1849: DEFUN (no_csnp_interval_l1,
 1850:        no_csnp_interval_l1_cmd,
 1851:        "no isis csnp-interval level-1",
 1852:        NO_STR
 1853:        "IS-IS commands\n"
 1854:        "Set CSNP interval in seconds\n"
 1855:        "Specify interval for level-1 CSNPs\n")
 1856: {
 1857:   struct isis_circuit *circuit;
 1858:   struct interface *ifp;
 1859: 
 1860:   ifp = vty->index;
 1861:   circuit = ifp->info;
 1862:   if (circuit == NULL)
 1863:     {
 1864:       return CMD_WARNING;
 1865:     }
 1866:   assert (circuit);
 1867: 
 1868:   circuit->csnp_interval[0] = CSNP_INTERVAL;
 1869: 
 1870:   return CMD_SUCCESS;
 1871: }
 1872: 
 1873: ALIAS (no_csnp_interval_l1,
 1874:        no_csnp_interval_l1_arg_cmd,
 1875:        "no isis csnp-interval <0-65535> level-1",
 1876:        NO_STR
 1877:        "IS-IS commands\n"
 1878:        "Set CSNP interval in seconds\n"
 1879:        "CSNP interval value\n"
 1880:        "Specify interval for level-1 CSNPs\n")
 1881: 
 1882: DEFUN (csnp_interval_l2,
 1883:        csnp_interval_l2_cmd,
 1884:        "isis csnp-interval <0-65535> level-2",
 1885:        "IS-IS commands\n"
 1886:        "Set CSNP interval in seconds\n"
 1887:        "CSNP interval value\n"
 1888:        "Specify interval for level-2 CSNPs\n")
 1889: {
 1890:   struct isis_circuit *circuit;
 1891:   struct interface *ifp;
 1892:   unsigned long interval;
 1893: 
 1894:   ifp = vty->index;
 1895:   circuit = ifp->info;
 1896:   if (circuit == NULL)
 1897:     {
 1898:       return CMD_WARNING;
 1899:     }
 1900:   assert (circuit);
 1901: 
 1902:   interval = atol (argv[0]);
 1903: 
 1904:   circuit->csnp_interval[1] = (u_int16_t) interval;
 1905: 
 1906:   return CMD_SUCCESS;
 1907: }
 1908: 
 1909: DEFUN (no_csnp_interval_l2,
 1910:        no_csnp_interval_l2_cmd,
 1911:        "no isis csnp-interval level-2",
 1912:        NO_STR
 1913:        "IS-IS commands\n"
 1914:        "Set CSNP interval in seconds\n"
 1915:        "Specify interval for level-2 CSNPs\n")
 1916: {
 1917:   struct isis_circuit *circuit;
 1918:   struct interface *ifp;
 1919: 
 1920:   ifp = vty->index;
 1921:   circuit = ifp->info;
 1922:   if (circuit == NULL)
 1923:     {
 1924:       return CMD_WARNING;
 1925:     }
 1926:   assert (circuit);
 1927: 
 1928:   circuit->csnp_interval[1] = CSNP_INTERVAL;
 1929: 
 1930:   return CMD_SUCCESS;
 1931: }
 1932: 
 1933: ALIAS (no_csnp_interval_l2,
 1934:        no_csnp_interval_l2_arg_cmd,
 1935:        "no isis csnp-interval <0-65535> level-2",
 1936:        NO_STR
 1937:        "IS-IS commands\n"
 1938:        "Set CSNP interval in seconds\n"
 1939:        "CSNP interval value\n"
 1940:        "Specify interval for level-2 CSNPs\n")
 1941: 
 1942: #ifdef HAVE_IPV6
 1943: DEFUN (ipv6_router_isis,
 1944:        ipv6_router_isis_cmd,
 1945:        "ipv6 router isis WORD",
 1946:        "IPv6 interface subcommands\n"
 1947:        "IPv6 Router interface commands\n"
 1948:        "IS-IS Routing for IPv6\n"
 1949:        "Routing process tag\n")
 1950: {
 1951:   struct isis_circuit *c;
 1952:   struct interface *ifp;
 1953:   struct isis_area *area;
 1954: 
 1955:   ifp = (struct interface *) vty->index;
 1956:   assert (ifp);
 1957: 
 1958:   area = isis_area_lookup (argv[0]);
 1959: 
 1960:   /* Prevent more than one circuit per interface */
 1961:   if (area)
 1962:     c = circuit_lookup_by_ifp (ifp, area->circuit_list);
 1963:   else
 1964:     c = NULL;
 1965: 
 1966:   if (c && (ifp->info != NULL))
 1967:     {
 1968:       if (c->ipv6_router == 1)
 1969: 	{
 1970: 	  vty_out (vty, "ISIS circuit is already defined for IPv6%s",
 1971: 		   VTY_NEWLINE);
 1972: 	  return CMD_WARNING;
 1973: 	}
 1974:     }
 1975: 
 1976:   /* this is here for ciscopability */
 1977:   if (!area)
 1978:     {
 1979:       vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
 1980:       return CMD_WARNING;
 1981:     }
 1982: 
 1983:   if (!c)
 1984:     {
 1985:       c = circuit_lookup_by_ifp (ifp, isis->init_circ_list);
 1986:       c = isis_csm_state_change (ISIS_ENABLE, c, area);
 1987:       c->interface = ifp;
 1988:       ifp->info = c;
 1989:     }
 1990: 
 1991:   if (!c)
 1992:     return CMD_WARNING;
 1993: 
 1994:   c->ipv6_router = 1;
 1995:   area->ipv6_circuits++;
 1996:   circuit_update_nlpids (c);
 1997: 
 1998:   vty->node = INTERFACE_NODE;
 1999: 
 2000:   return CMD_SUCCESS;
 2001: }
 2002: 
 2003: DEFUN (no_ipv6_router_isis,
 2004:        no_ipv6_router_isis_cmd,
 2005:        "no ipv6 router isis WORD",
 2006:        NO_STR
 2007:        "IPv6 interface subcommands\n"
 2008:        "IPv6 Router interface commands\n"
 2009:        "IS-IS Routing for IPv6\n"
 2010:        "Routing process tag\n")
 2011: {
 2012:   struct isis_circuit *c;
 2013:   struct interface *ifp;
 2014:   struct isis_area *area;
 2015: 
 2016:   ifp = (struct interface *) vty->index;
 2017:   /* UGLY - will remove l8r
 2018:      if (circuit == NULL) {
 2019:      return CMD_WARNING;
 2020:      } */
 2021:   assert (ifp);
 2022: 
 2023:   area = isis_area_lookup (argv[0]);
 2024:   if (!area)
 2025:     {
 2026:       vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
 2027:       return CMD_WARNING;
 2028:     }
 2029: 
 2030:   c = circuit_lookup_by_ifp (ifp, area->circuit_list);
 2031:   if (!c)
 2032:     return CMD_WARNING;
 2033: 
 2034:   c->ipv6_router = 0;
 2035:   area->ipv6_circuits--;
 2036:   if (c->ip_router == 0)
 2037:     isis_csm_state_change (ISIS_DISABLE, c, area);
 2038: 
 2039:   return CMD_SUCCESS;
 2040: }
 2041: #endif /* HAVE_IPV6 */
 2042: 
 2043: static struct cmd_node interface_node = {
 2044:   INTERFACE_NODE,
 2045:   "%s(config-if)# ",
 2046:   1,
 2047: };
 2048: 
 2049: int
 2050: isis_if_new_hook (struct interface *ifp)
 2051: {
 2052: /* FIXME: Discuss if the circuit should be created here
 2053:   ifp->info = XMALLOC (MTYPE_ISIS_IF_INFO, sizeof (struct isis_if_info)); */
 2054:   ifp->info = NULL;
 2055:   return 0;
 2056: }
 2057: 
 2058: int
 2059: isis_if_delete_hook (struct interface *ifp)
 2060: {
 2061: /* FIXME: Discuss if the circuit should be created here
 2062:   XFREE (MTYPE_ISIS_IF_INFO, ifp->info);*/
 2063:   ifp->info = NULL;
 2064:   return 0;
 2065: }
 2066: 
 2067: void
 2068: isis_circuit_init ()
 2069: {
 2070:   /* Initialize Zebra interface data structure */
 2071:   if_init ();
 2072:   if_add_hook (IF_NEW_HOOK, isis_if_new_hook);
 2073:   if_add_hook (IF_DELETE_HOOK, isis_if_delete_hook);
 2074: 
 2075:   /* Install interface node */
 2076:   install_node (&interface_node, isis_interface_config_write);
 2077:   install_element (CONFIG_NODE, &interface_cmd);
 2078: 
 2079:   install_default (INTERFACE_NODE);
 2080:   install_element (INTERFACE_NODE, &interface_desc_cmd);
 2081:   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
 2082: 
 2083:   install_element (INTERFACE_NODE, &ip_router_isis_cmd);
 2084:   install_element (INTERFACE_NODE, &no_ip_router_isis_cmd);
 2085: 
 2086:   install_element (INTERFACE_NODE, &isis_circuit_type_cmd);
 2087:   install_element (INTERFACE_NODE, &no_isis_circuit_type_cmd);
 2088: 
 2089:   install_element (INTERFACE_NODE, &isis_passwd_cmd);
 2090:   install_element (INTERFACE_NODE, &no_isis_passwd_cmd);
 2091: 
 2092:   install_element (INTERFACE_NODE, &isis_priority_cmd);
 2093:   install_element (INTERFACE_NODE, &no_isis_priority_cmd);
 2094:   install_element (INTERFACE_NODE, &no_isis_priority_arg_cmd);
 2095:   install_element (INTERFACE_NODE, &isis_priority_l1_cmd);
 2096:   install_element (INTERFACE_NODE, &no_isis_priority_l1_cmd);
 2097:   install_element (INTERFACE_NODE, &no_isis_priority_l1_arg_cmd);
 2098:   install_element (INTERFACE_NODE, &isis_priority_l2_cmd);
 2099:   install_element (INTERFACE_NODE, &no_isis_priority_l2_cmd);
 2100:   install_element (INTERFACE_NODE, &no_isis_priority_l2_arg_cmd);
 2101: 
 2102:   install_element (INTERFACE_NODE, &isis_metric_cmd);
 2103:   install_element (INTERFACE_NODE, &no_isis_metric_cmd);
 2104:   install_element (INTERFACE_NODE, &no_isis_metric_arg_cmd);
 2105: 
 2106:   install_element (INTERFACE_NODE, &isis_hello_interval_cmd);
 2107:   install_element (INTERFACE_NODE, &no_isis_hello_interval_cmd);
 2108:   install_element (INTERFACE_NODE, &no_isis_hello_interval_arg_cmd);
 2109:   install_element (INTERFACE_NODE, &isis_hello_interval_l1_cmd);
 2110:   install_element (INTERFACE_NODE, &no_isis_hello_interval_l1_cmd);
 2111:   install_element (INTERFACE_NODE, &no_isis_hello_interval_l1_arg_cmd);
 2112:   install_element (INTERFACE_NODE, &isis_hello_interval_l2_cmd);
 2113:   install_element (INTERFACE_NODE, &no_isis_hello_interval_l2_cmd);
 2114:   install_element (INTERFACE_NODE, &no_isis_hello_interval_l2_arg_cmd);
 2115: 
 2116:   install_element (INTERFACE_NODE, &isis_hello_multiplier_cmd);
 2117:   install_element (INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
 2118:   install_element (INTERFACE_NODE, &no_isis_hello_multiplier_arg_cmd);
 2119:   install_element (INTERFACE_NODE, &isis_hello_multiplier_l1_cmd);
 2120:   install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l1_cmd);
 2121:   install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l1_arg_cmd);
 2122:   install_element (INTERFACE_NODE, &isis_hello_multiplier_l2_cmd);
 2123:   install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l2_cmd);
 2124:   install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l2_arg_cmd);
 2125: 
 2126:   install_element (INTERFACE_NODE, &isis_hello_cmd);
 2127:   install_element (INTERFACE_NODE, &no_isis_hello_cmd);
 2128:   install_element (INTERFACE_NODE, &csnp_interval_cmd);
 2129:   install_element (INTERFACE_NODE, &no_csnp_interval_cmd);
 2130:   install_element (INTERFACE_NODE, &no_csnp_interval_arg_cmd);
 2131:   install_element (INTERFACE_NODE, &csnp_interval_l1_cmd);
 2132:   install_element (INTERFACE_NODE, &no_csnp_interval_l1_cmd);
 2133:   install_element (INTERFACE_NODE, &no_csnp_interval_l1_arg_cmd);
 2134:   install_element (INTERFACE_NODE, &csnp_interval_l2_cmd);
 2135:   install_element (INTERFACE_NODE, &no_csnp_interval_l2_cmd);
 2136:   install_element (INTERFACE_NODE, &no_csnp_interval_l2_arg_cmd);
 2137: 
 2138: #ifdef HAVE_IPV6
 2139:   install_element (INTERFACE_NODE, &ipv6_router_isis_cmd);
 2140:   install_element (INTERFACE_NODE, &no_ipv6_router_isis_cmd);
 2141: #endif
 2142: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>