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

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