File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / isisd / isis_circuit.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:38 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

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

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