File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / interface.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /*
    2:  * Interface function.
    3:  * Copyright (C) 1997, 1999 Kunihiro Ishiguro
    4:  *
    5:  * This file is part of GNU Zebra.
    6:  *
    7:  * GNU Zebra is free software; you can redistribute it and/or modify it
    8:  * under the terms of the GNU General Public License as published by the
    9:  * Free Software Foundation; either version 2, or (at your option) any
   10:  * later version.
   11:  *
   12:  * GNU Zebra is distributed in the hope that it will be useful, but
   13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15:  * General Public License for more details.
   16:  *
   17:  * You should have received a copy of the GNU General Public License
   18:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
   19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   20:  * 02111-1307, USA.  
   21:  */
   22: 
   23: #include <zebra.h>
   24: 
   25: #include "if.h"
   26: #include "vty.h"
   27: #include "sockunion.h"
   28: #include "prefix.h"
   29: #include "command.h"
   30: #include "memory.h"
   31: #include "ioctl.h"
   32: #include "connected.h"
   33: #include "log.h"
   34: #include "zclient.h"
   35: #include "vrf.h"
   36: 
   37: #include "zebra/interface.h"
   38: #include "zebra/rtadv.h"
   39: #include "zebra/rib.h"
   40: #include "zebra/zserv.h"
   41: #include "zebra/redistribute.h"
   42: #include "zebra/debug.h"
   43: #include "zebra/irdp.h"
   44: 
   45: #if defined (HAVE_RTADV)
   46: /* Order is intentional.  Matches RFC4191.  This array is also used for
   47:    command matching, so only modify with care. */
   48: const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
   49: #endif /* HAVE_RTADV */
   50: 
   51: /* Called when new interface is added. */
   52: static int
   53: if_zebra_new_hook (struct interface *ifp)
   54: {
   55:   struct zebra_if *zebra_if;
   56: 
   57:   zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
   58: 
   59:   zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
   60:   zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
   61: 
   62: #if defined (HAVE_RTADV)
   63:   {
   64:     /* Set default router advertise values. */
   65:     struct rtadvconf *rtadv;
   66: 
   67:     rtadv = &zebra_if->rtadv;
   68: 
   69:     rtadv->AdvSendAdvertisements = 0;
   70:     rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
   71:     rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
   72:     rtadv->AdvIntervalTimer = 0;
   73:     rtadv->AdvManagedFlag = 0;
   74:     rtadv->AdvOtherConfigFlag = 0;
   75:     rtadv->AdvHomeAgentFlag = 0;
   76:     rtadv->AdvLinkMTU = 0;
   77:     rtadv->AdvReachableTime = 0;
   78:     rtadv->AdvRetransTimer = 0;
   79:     rtadv->AdvCurHopLimit = 0;
   80:     rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
   81:     rtadv->HomeAgentPreference = 0;
   82:     rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
   83:     rtadv->AdvIntervalOption = 0;
   84:     rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
   85: 
   86:     rtadv->AdvPrefixList = list_new ();
   87:   }    
   88: #endif /* HAVE_RTADV */
   89: 
   90:   /* Initialize installed address chains tree. */
   91:   zebra_if->ipv4_subnets = route_table_init ();
   92: 
   93:   ifp->info = zebra_if;
   94:   return 0;
   95: }
   96: 
   97: /* Called when interface is deleted. */
   98: static int
   99: if_zebra_delete_hook (struct interface *ifp)
  100: {
  101:   struct zebra_if *zebra_if;
  102:   
  103:   if (ifp->info)
  104:     {
  105:       zebra_if = ifp->info;
  106: 
  107:       /* Free installed address chains tree. */
  108:       if (zebra_if->ipv4_subnets)
  109: 	route_table_finish (zebra_if->ipv4_subnets);
  110: 
  111:       XFREE (MTYPE_TMP, zebra_if);
  112:     }
  113: 
  114:   return 0;
  115: }
  116: 
  117: /* Tie an interface address to its derived subnet list of addresses. */
  118: int
  119: if_subnet_add (struct interface *ifp, struct connected *ifc)
  120: {
  121:   struct route_node *rn;
  122:   struct zebra_if *zebra_if;
  123:   struct prefix cp;
  124:   struct list *addr_list;
  125: 
  126:   assert (ifp && ifp->info && ifc);
  127:   zebra_if = ifp->info;
  128: 
  129:   /* Get address derived subnet node and associated address list, while marking
  130:      address secondary attribute appropriately. */
  131:   cp = *ifc->address;
  132:   apply_mask (&cp);
  133:   rn = route_node_get (zebra_if->ipv4_subnets, &cp);
  134: 
  135:   if ((addr_list = rn->info))
  136:     SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
  137:   else
  138:     {
  139:       UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
  140:       rn->info = addr_list = list_new ();
  141:       route_lock_node (rn);
  142:     }
  143: 
  144:   /* Tie address at the tail of address list. */
  145:   listnode_add (addr_list, ifc);
  146:   
  147:   /* Return list element count. */
  148:   return (addr_list->count);
  149: }
  150: 
  151: /* Untie an interface address from its derived subnet list of addresses. */
  152: int
  153: if_subnet_delete (struct interface *ifp, struct connected *ifc)
  154: {
  155:   struct route_node *rn;
  156:   struct zebra_if *zebra_if;
  157:   struct list *addr_list;
  158: 
  159:   assert (ifp && ifp->info && ifc);
  160:   zebra_if = ifp->info;
  161: 
  162:   /* Get address derived subnet node. */
  163:   rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
  164:   if (! (rn && rn->info))
  165:     {
  166:       zlog_warn("Trying to remove an address from an unknown subnet."
  167:                 " (please report this bug)");
  168:       return -1;
  169:     }
  170:   route_unlock_node (rn);
  171:   
  172:   /* Untie address from subnet's address list. */
  173:   addr_list = rn->info;
  174: 
  175:   /* Deleting an address that is not registered is a bug.
  176:    * In any case, we shouldn't decrement the lock counter if the address
  177:    * is unknown. */
  178:   if (!listnode_lookup(addr_list, ifc))
  179:     {
  180:       zlog_warn("Trying to remove an address from a subnet where it is not"
  181:                 " currently registered. (please report this bug)");
  182:       return -1;
  183:     }
  184: 
  185:   listnode_delete (addr_list, ifc);
  186:   route_unlock_node (rn);
  187: 
  188:   /* Return list element count, if not empty. */
  189:   if (addr_list->count)
  190:     {
  191:       /* If deleted address is primary, mark subsequent one as such and distribute. */
  192:       if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
  193: 	{
  194: 	  ifc = listgetdata (listhead (addr_list));
  195: 	  zebra_interface_address_delete_update (ifp, ifc);
  196: 	  UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
  197: 	  /* XXX: Linux kernel removes all the secondary addresses when the primary
  198: 	   * address is removed. We could try to work around that, though this is
  199: 	   * non-trivial. */
  200: 	  zebra_interface_address_add_update (ifp, ifc);
  201: 	}
  202:       
  203:       return addr_list->count;
  204:     }
  205:   
  206:   /* Otherwise, free list and route node. */
  207:   list_free (addr_list);
  208:   rn->info = NULL;
  209:   route_unlock_node (rn);
  210: 
  211:   return 0;
  212: }
  213: 
  214: /* if_flags_mangle: A place for hacks that require mangling
  215:  * or tweaking the interface flags.
  216:  *
  217:  * ******************** Solaris flags hacks **************************
  218:  *
  219:  * Solaris IFF_UP flag reflects only the primary interface as the
  220:  * routing socket only sends IFINFO for the primary interface.  Hence  
  221:  * ~IFF_UP does not per se imply all the logical interfaces are also   
  222:  * down - which we only know of as addresses. Instead we must determine
  223:  * whether the interface really is up or not according to how many   
  224:  * addresses are still attached. (Solaris always sends RTM_DELADDR if
  225:  * an interface, logical or not, goes ~IFF_UP).
  226:  *
  227:  * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
  228:  * are addresses left in struct connected, not just the actual underlying
  229:  * IFF_UP flag.
  230:  *
  231:  * We must hence remember the real state of IFF_UP, which we do in
  232:  * struct zebra_if.primary_state.
  233:  *
  234:  * Setting IFF_UP within zebra to administratively shutdown the
  235:  * interface will affect only the primary interface/address on Solaris.
  236:  ************************End Solaris flags hacks ***********************
  237:  */
  238: static void
  239: if_flags_mangle (struct interface *ifp, uint64_t *newflags)
  240: {
  241: #ifdef SUNOS_5
  242:   struct zebra_if *zif = ifp->info;
  243:   
  244:   zif->primary_state = *newflags & (IFF_UP & 0xff);
  245:   
  246:   if (CHECK_FLAG (zif->primary_state, IFF_UP)
  247:       || listcount(ifp->connected) > 0)
  248:     SET_FLAG (*newflags, IFF_UP);
  249:   else
  250:     UNSET_FLAG (*newflags, IFF_UP);
  251: #endif /* SUNOS_5 */
  252: }
  253: 
  254: /* Update the flags field of the ifp with the new flag set provided.
  255:  * Take whatever actions are required for any changes in flags we care
  256:  * about.
  257:  *
  258:  * newflags should be the raw value, as obtained from the OS.
  259:  */
  260: void
  261: if_flags_update (struct interface *ifp, uint64_t newflags)
  262: {
  263:   if_flags_mangle (ifp, &newflags);
  264:     
  265:   if (if_is_operative (ifp))
  266:     {
  267:       /* operative -> inoperative? */
  268:       ifp->flags = newflags;
  269:       if (!if_is_operative (ifp))
  270:         if_down (ifp);
  271:     }
  272:   else
  273:     {
  274:       /* inoperative -> operative? */
  275:       ifp->flags = newflags;
  276:       if (if_is_operative (ifp))
  277:         if_up (ifp);
  278:     }
  279: }
  280: 
  281: /* Wake up configured address if it is not in current kernel
  282:    address. */
  283: static void
  284: if_addr_wakeup (struct interface *ifp)
  285: {
  286:   struct listnode *node, *nnode;
  287:   struct connected *ifc;
  288:   struct prefix *p;
  289:   int ret;
  290: 
  291:   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
  292:     {
  293:       p = ifc->address;
  294: 	
  295:       if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
  296: 	  && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
  297: 	{
  298: 	  /* Address check. */
  299: 	  if (p->family == AF_INET)
  300: 	    {
  301: 	      if (! if_is_up (ifp))
  302: 		{
  303: 		  /* Assume zebra is configured like following:
  304: 		   *
  305: 		   *   interface gre0
  306: 		   *    ip addr 192.0.2.1/24
  307: 		   *   !
  308: 		   *
  309: 		   * As soon as zebra becomes first aware that gre0 exists in the
  310: 		   * kernel, it will set gre0 up and configure its addresses.
  311: 		   *
  312: 		   * (This may happen at startup when the interface already exists
  313: 		   * or during runtime when the interface is added to the kernel)
  314: 		   *
  315: 		   * XXX: IRDP code is calling here via if_add_update - this seems
  316: 		   * somewhat weird.
  317: 		   * XXX: RUNNING is not a settable flag on any system
  318: 		   * I (paulj) am aware of.
  319: 		  */
  320: 		  if_set_flags (ifp, IFF_UP | IFF_RUNNING);
  321: 		  if_refresh (ifp);
  322: 		}
  323: 
  324: 	      ret = if_set_prefix (ifp, ifc);
  325: 	      if (ret < 0)
  326: 		{
  327: 		  zlog_warn ("Can't set interface's address: %s", 
  328: 			     safe_strerror(errno));
  329: 		  continue;
  330: 		}
  331: 
  332: 	      SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
  333: 	      /* The address will be advertised to zebra clients when the notification
  334: 	       * from the kernel has been received.
  335: 	       * It will also be added to the interface's subnet list then. */
  336: 	    }
  337: #ifdef HAVE_IPV6
  338: 	  if (p->family == AF_INET6)
  339: 	    {
  340: 	      if (! if_is_up (ifp))
  341: 		{
  342: 		  /* See long comment above */
  343: 		  if_set_flags (ifp, IFF_UP | IFF_RUNNING);
  344: 		  if_refresh (ifp);
  345: 		}
  346: 
  347: 	      ret = if_prefix_add_ipv6 (ifp, ifc);
  348: 	      if (ret < 0)
  349: 		{
  350: 		  zlog_warn ("Can't set interface's address: %s", 
  351: 			     safe_strerror(errno));
  352: 		  continue;
  353: 		}
  354: 
  355: 	      SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
  356: 	      /* The address will be advertised to zebra clients when the notification
  357: 	       * from the kernel has been received. */
  358: 	    }
  359: #endif /* HAVE_IPV6 */
  360: 	}
  361:     }
  362: }
  363: 
  364: /* Handle interface addition */
  365: void
  366: if_add_update (struct interface *ifp)
  367: {
  368:   struct zebra_if *if_data;
  369: 
  370:   if_data = ifp->info;
  371:   assert(if_data);
  372: 
  373:   if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
  374:     if_set_flags (ifp, IFF_MULTICAST);
  375:   else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
  376:     if_unset_flags (ifp, IFF_MULTICAST);
  377: 
  378:   zebra_interface_add_update (ifp);
  379: 
  380:   if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  381:     {
  382:       SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
  383: 
  384:       if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
  385: 	{
  386: 	  if (IS_ZEBRA_DEBUG_KERNEL)
  387: 	    zlog_debug ("interface %s vrf %u index %d is shutdown. "
  388: 			"Won't wake it up.",
  389: 			ifp->name, ifp->vrf_id, ifp->ifindex);
  390: 	  return;
  391: 	}
  392: 
  393:       if_addr_wakeup (ifp);
  394: 
  395:       if (IS_ZEBRA_DEBUG_KERNEL)
  396: 	zlog_debug ("interface %s vrf %u index %d becomes active.",
  397: 		    ifp->name, ifp->vrf_id, ifp->ifindex);
  398:     }
  399:   else
  400:     {
  401:       if (IS_ZEBRA_DEBUG_KERNEL)
  402: 	zlog_debug ("interface %s vrf %u index %d is added.",
  403: 		    ifp->name, ifp->vrf_id, ifp->ifindex);
  404:     }
  405: }
  406: 
  407: /* Handle an interface delete event */
  408: void 
  409: if_delete_update (struct interface *ifp)
  410: {
  411:   struct connected *ifc;
  412:   struct prefix *p;
  413:   struct route_node *rn;
  414:   struct zebra_if *zebra_if;
  415: 
  416:   zebra_if = ifp->info;
  417: 
  418:   if (if_is_up(ifp))
  419:     {
  420:       zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
  421:                 ifp->name, ifp->vrf_id, ifp->ifindex);
  422:       return;
  423:     }
  424: 
  425:   /* Mark interface as inactive */
  426:   UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
  427:   
  428:   if (IS_ZEBRA_DEBUG_KERNEL)
  429:     zlog_debug ("interface %s vrf %u index %d is now inactive.",
  430:                 ifp->name, ifp->vrf_id, ifp->ifindex);
  431: 
  432:   /* Delete connected routes from the kernel. */
  433:   if (ifp->connected)
  434:     {
  435:       struct listnode *node;
  436:       struct listnode *last = NULL;
  437: 
  438:       while ((node = (last ? last->next : listhead (ifp->connected))))
  439: 	{
  440: 	  ifc = listgetdata (node);
  441: 	  p = ifc->address;
  442: 	  
  443: 	  if (p->family == AF_INET
  444: 	      && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
  445: 	    {
  446: 	      struct listnode *anode;
  447: 	      struct listnode *next;
  448: 	      struct listnode *first;
  449: 	      struct list *addr_list;
  450: 	      
  451: 	      route_unlock_node (rn);
  452: 	      addr_list = (struct list *) rn->info;
  453: 	      
  454: 	      /* Remove addresses, secondaries first. */
  455: 	      first = listhead (addr_list);
  456: 	      for (anode = first->next; anode || first; anode = next)
  457: 		{
  458: 		  if (!anode)
  459: 		    {
  460: 		      anode = first;
  461: 		      first = NULL;
  462: 		    }
  463: 		  next = anode->next;
  464: 
  465: 		  ifc = listgetdata (anode);
  466: 		  p = ifc->address;
  467: 		  connected_down_ipv4 (ifp, ifc);
  468: 
  469: 		  /* XXX: We have to send notifications here explicitly, because we destroy
  470: 		   * the ifc before receiving the notification about the address being deleted.
  471: 		   */
  472: 		  zebra_interface_address_delete_update (ifp, ifc);
  473: 
  474: 		  UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  475: 		  UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
  476: 
  477: 		  /* Remove from subnet chain. */
  478: 		  list_delete_node (addr_list, anode);
  479: 		  route_unlock_node (rn);
  480: 		  
  481: 		  /* Remove from interface address list (unconditionally). */
  482: 		  if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  483: 		    {
  484: 		      listnode_delete (ifp->connected, ifc);
  485: 		      connected_free (ifc);
  486:                     }
  487:                   else
  488:                     last = node;
  489: 		}
  490: 
  491: 	      /* Free chain list and respective route node. */
  492: 	      list_delete (addr_list);
  493: 	      rn->info = NULL;
  494: 	      route_unlock_node (rn);
  495: 	    }
  496: #ifdef HAVE_IPV6
  497: 	  else if (p->family == AF_INET6)
  498: 	    {
  499: 	      connected_down_ipv6 (ifp, ifc);
  500: 
  501: 	      zebra_interface_address_delete_update (ifp, ifc);
  502: 
  503: 	      UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  504: 	      UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
  505: 
  506: 	      if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  507: 		last = node;
  508: 	      else
  509: 		{
  510: 		  listnode_delete (ifp->connected, ifc);
  511: 		  connected_free (ifc);
  512: 		}
  513: 	    }
  514: #endif /* HAVE_IPV6 */
  515: 	  else
  516: 	    {
  517: 	      last = node;
  518: 	    }
  519: 	}
  520:     }
  521:   zebra_interface_delete_update (ifp);
  522: 
  523:   /* Update ifindex after distributing the delete message.  This is in
  524:      case any client needs to have the old value of ifindex available
  525:      while processing the deletion.  Each client daemon is responsible
  526:      for setting ifindex to IFINDEX_INTERNAL after processing the
  527:      interface deletion message. */
  528:   ifp->ifindex = IFINDEX_INTERNAL;
  529: }
  530: 
  531: /* Interface is up. */
  532: void
  533: if_up (struct interface *ifp)
  534: {
  535:   struct listnode *node;
  536:   struct listnode *next;
  537:   struct connected *ifc;
  538:   struct prefix *p;
  539: 
  540:   /* Notify the protocol daemons. */
  541:   zebra_interface_up_update (ifp);
  542: 
  543:   /* Install connected routes to the kernel. */
  544:   if (ifp->connected)
  545:     {
  546:       for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
  547: 	{
  548: 	  p = ifc->address;
  549: 
  550: 	  if (p->family == AF_INET)
  551: 	    connected_up_ipv4 (ifp, ifc);
  552: #ifdef HAVE_IPV6
  553: 	  else if (p->family == AF_INET6)
  554: 	    connected_up_ipv6 (ifp, ifc);
  555: #endif /* HAVE_IPV6 */
  556: 	}
  557:     }
  558: 
  559:   /* Examine all static routes. */
  560:   rib_update (ifp->vrf_id);
  561: }
  562: 
  563: /* Interface goes down.  We have to manage different behavior of based
  564:    OS. */
  565: void
  566: if_down (struct interface *ifp)
  567: {
  568:   struct listnode *node;
  569:   struct listnode *next;
  570:   struct connected *ifc;
  571:   struct prefix *p;
  572: 
  573:   /* Notify to the protocol daemons. */
  574:   zebra_interface_down_update (ifp);
  575: 
  576:   /* Delete connected routes from the kernel. */
  577:   if (ifp->connected)
  578:     {
  579:       for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
  580: 	{
  581: 	  p = ifc->address;
  582: 
  583: 	  if (p->family == AF_INET)
  584: 	    connected_down_ipv4 (ifp, ifc);
  585: #ifdef HAVE_IPV6
  586: 	  else if (p->family == AF_INET6)
  587: 	    connected_down_ipv6 (ifp, ifc);
  588: #endif /* HAVE_IPV6 */
  589: 	}
  590:     }
  591: 
  592:   /* Examine all static routes which direct to the interface. */
  593:   rib_update (ifp->vrf_id);
  594: }
  595: 
  596: void
  597: if_refresh (struct interface *ifp)
  598: {
  599:   if_get_flags (ifp);
  600: }
  601: 
  602: /* Output prefix string to vty. */
  603: static int
  604: prefix_vty_out (struct vty *vty, struct prefix *p)
  605: {
  606:   char str[INET6_ADDRSTRLEN];
  607: 
  608:   inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
  609:   vty_out (vty, "%s", str);
  610:   return strlen (str);
  611: }
  612: 
  613: /* Dump if address information to vty. */
  614: static void
  615: connected_dump_vty (struct vty *vty, struct connected *connected)
  616: {
  617:   struct prefix *p;
  618: 
  619:   /* Print interface address. */
  620:   p = connected->address;
  621:   vty_out (vty, "  %s ", prefix_family_str (p));
  622:   prefix_vty_out (vty, p);
  623:   vty_out (vty, "/%d", p->prefixlen);
  624: 
  625:   /* If there is destination address, print it. */
  626:   if (connected->destination)
  627:     {
  628:       vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
  629:       prefix_vty_out (vty, connected->destination);
  630:     }
  631: 
  632:   if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
  633:     vty_out (vty, " secondary");
  634: 
  635:   if (connected->label)
  636:     vty_out (vty, " %s", connected->label);
  637: 
  638:   vty_out (vty, "%s", VTY_NEWLINE);
  639: }
  640: 
  641: #if defined (HAVE_RTADV)
  642: /* Dump interface ND information to vty. */
  643: static void
  644: nd_dump_vty (struct vty *vty, struct interface *ifp)
  645: {
  646:   struct zebra_if *zif;
  647:   struct rtadvconf *rtadv;
  648:   int interval;
  649: 
  650:   zif = (struct zebra_if *) ifp->info;
  651:   rtadv = &zif->rtadv;
  652: 
  653:   if (rtadv->AdvSendAdvertisements)
  654:     {
  655:       vty_out (vty, "  ND advertised reachable time is %d milliseconds%s",
  656: 	       rtadv->AdvReachableTime, VTY_NEWLINE);
  657:       vty_out (vty, "  ND advertised retransmit interval is %d milliseconds%s",
  658: 	       rtadv->AdvRetransTimer, VTY_NEWLINE);
  659:       interval = rtadv->MaxRtrAdvInterval;
  660:       if (interval % 1000)
  661:         vty_out (vty, "  ND router advertisements are sent every "
  662: 			"%d milliseconds%s", interval,
  663: 		 VTY_NEWLINE);
  664:       else
  665:         vty_out (vty, "  ND router advertisements are sent every "
  666: 			"%d seconds%s", interval / 1000,
  667: 		 VTY_NEWLINE);
  668:       if (rtadv->AdvDefaultLifetime != -1)
  669: 	vty_out (vty, "  ND router advertisements live for %d seconds%s",
  670: 		 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
  671:       else
  672: 	vty_out (vty, "  ND router advertisements lifetime tracks ra-interval%s",
  673: 		 VTY_NEWLINE);
  674:       vty_out (vty, "  ND router advertisement default router preference is "
  675: 			"%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
  676: 		 VTY_NEWLINE);
  677:       if (rtadv->AdvManagedFlag)
  678: 	vty_out (vty, "  Hosts use DHCP to obtain routable addresses.%s",
  679: 		 VTY_NEWLINE);
  680:       else
  681: 	vty_out (vty, "  Hosts use stateless autoconfig for addresses.%s",
  682: 		 VTY_NEWLINE);
  683:       if (rtadv->AdvHomeAgentFlag)
  684:       {
  685:       	vty_out (vty, "  ND router advertisements with "
  686: 				"Home Agent flag bit set.%s",
  687: 		 VTY_NEWLINE);
  688: 	if (rtadv->HomeAgentLifetime != -1)
  689: 	  vty_out (vty, "  Home Agent lifetime is %u seconds%s",
  690: 	           rtadv->HomeAgentLifetime, VTY_NEWLINE);
  691: 	else
  692: 	  vty_out (vty, "  Home Agent lifetime tracks ra-lifetime%s",
  693: 	           VTY_NEWLINE);
  694: 	vty_out (vty, "  Home Agent preference is %u%s",
  695: 	         rtadv->HomeAgentPreference, VTY_NEWLINE);
  696:       }
  697:       if (rtadv->AdvIntervalOption)
  698:       	vty_out (vty, "  ND router advertisements with Adv. Interval option.%s",
  699: 		 VTY_NEWLINE);
  700:     }
  701: }
  702: #endif /* HAVE_RTADV */
  703: 
  704: /* Interface's information print out to vty interface. */
  705: static void
  706: if_dump_vty (struct vty *vty, struct interface *ifp)
  707: {
  708:   struct connected *connected;
  709:   struct listnode *node;
  710:   struct route_node *rn;
  711:   struct zebra_if *zebra_if;
  712: 
  713:   zebra_if = ifp->info;
  714: 
  715:   vty_out (vty, "Interface %s is ", ifp->name);
  716:   if (if_is_up(ifp)) {
  717:     vty_out (vty, "up, line protocol ");
  718:     
  719:     if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
  720:       if (if_is_running(ifp))
  721:        vty_out (vty, "is up%s", VTY_NEWLINE);
  722:       else
  723: 	vty_out (vty, "is down%s", VTY_NEWLINE);
  724:     } else {
  725:       vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
  726:     }
  727:   } else {
  728:     vty_out (vty, "down%s", VTY_NEWLINE);
  729:   }
  730: 
  731:   vty_out (vty, "  vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
  732: 
  733:   if (ifp->desc)
  734:     vty_out (vty, "  Description: %s%s", ifp->desc,
  735: 	     VTY_NEWLINE);
  736:   if (ifp->ifindex == IFINDEX_INTERNAL)
  737:     {
  738:       vty_out(vty, "  pseudo interface%s", VTY_NEWLINE);
  739:       return;
  740:     }
  741:   else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  742:     {
  743:       vty_out(vty, "  index %d inactive interface%s", 
  744: 	      ifp->ifindex, 
  745: 	      VTY_NEWLINE);
  746:       return;
  747:     }
  748: 
  749:   vty_out (vty, "  index %d metric %d mtu %d ",
  750: 	   ifp->ifindex, ifp->metric, ifp->mtu);
  751: #ifdef HAVE_IPV6
  752:   if (ifp->mtu6 != ifp->mtu)
  753:     vty_out (vty, "mtu6 %d ", ifp->mtu6);
  754: #endif 
  755:   vty_out (vty, "%s  flags: %s%s", VTY_NEWLINE,
  756:            if_flag_dump (ifp->flags), VTY_NEWLINE);
  757:   
  758:   /* Hardware address. */
  759:   vty_out (vty, "  Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
  760:   if (ifp->hw_addr_len != 0)
  761:     {
  762:       int i;
  763: 
  764:       vty_out (vty, "  HWaddr: ");
  765:       for (i = 0; i < ifp->hw_addr_len; i++)
  766: 	vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
  767:       vty_out (vty, "%s", VTY_NEWLINE);
  768:     }
  769:   
  770:   /* Bandwidth in kbps */
  771:   if (ifp->bandwidth != 0)
  772:     {
  773:       vty_out(vty, "  bandwidth %u kbps", ifp->bandwidth);
  774:       vty_out(vty, "%s", VTY_NEWLINE);
  775:     }
  776: 
  777:   for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
  778:     {
  779:       if (! rn->info)
  780: 	continue;
  781:       
  782:       for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
  783:         connected_dump_vty (vty, connected);
  784:     }
  785: 
  786:   for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
  787:     {
  788:       if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
  789: 	  (connected->address->family == AF_INET6))
  790: 	connected_dump_vty (vty, connected);
  791:     }
  792: 
  793: #if defined (HAVE_RTADV)
  794:   nd_dump_vty (vty, ifp);
  795: #endif /* HAVE_RTADV */
  796: 
  797: #ifdef HAVE_PROC_NET_DEV
  798:   /* Statistics print out using proc file system. */
  799:   vty_out (vty, "    %lu input packets (%lu multicast), %lu bytes, "
  800: 	   "%lu dropped%s",
  801: 	   ifp->stats.rx_packets, ifp->stats.rx_multicast,
  802: 	   ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
  803: 
  804:   vty_out (vty, "    %lu input errors, %lu length, %lu overrun,"
  805: 	   " %lu CRC, %lu frame%s",
  806: 	   ifp->stats.rx_errors, ifp->stats.rx_length_errors,
  807: 	   ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
  808: 	   ifp->stats.rx_frame_errors, VTY_NEWLINE);
  809: 
  810:   vty_out (vty, "    %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
  811: 	   ifp->stats.rx_missed_errors, VTY_NEWLINE);
  812: 
  813:   vty_out (vty, "    %lu output packets, %lu bytes, %lu dropped%s",
  814: 	   ifp->stats.tx_packets, ifp->stats.tx_bytes,
  815: 	   ifp->stats.tx_dropped, VTY_NEWLINE);
  816: 
  817:   vty_out (vty, "    %lu output errors, %lu aborted, %lu carrier,"
  818: 	   " %lu fifo, %lu heartbeat%s",
  819: 	   ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
  820: 	   ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
  821: 	   ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
  822: 
  823:   vty_out (vty, "    %lu window, %lu collisions%s",
  824: 	   ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
  825: #endif /* HAVE_PROC_NET_DEV */
  826: 
  827: #ifdef HAVE_NET_RT_IFLIST
  828: #if defined (__bsdi__) || defined (__NetBSD__)
  829:   /* Statistics print out using sysctl (). */
  830:   vty_out (vty, "    input packets %llu, bytes %llu, dropped %llu,"
  831:            " multicast packets %llu%s",
  832:            (unsigned long long)ifp->stats.ifi_ipackets,
  833:            (unsigned long long)ifp->stats.ifi_ibytes,
  834:            (unsigned long long)ifp->stats.ifi_iqdrops,
  835:            (unsigned long long)ifp->stats.ifi_imcasts,
  836:            VTY_NEWLINE);
  837: 
  838:   vty_out (vty, "    input errors %llu%s",
  839:            (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
  840: 
  841:   vty_out (vty, "    output packets %llu, bytes %llu,"
  842:            " multicast packets %llu%s",
  843:            (unsigned long long)ifp->stats.ifi_opackets,
  844:            (unsigned long long)ifp->stats.ifi_obytes,
  845:            (unsigned long long)ifp->stats.ifi_omcasts,
  846:            VTY_NEWLINE);
  847: 
  848:   vty_out (vty, "    output errors %llu%s",
  849:            (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
  850: 
  851:   vty_out (vty, "    collisions %llu%s",
  852:            (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
  853: #else
  854:   /* Statistics print out using sysctl (). */
  855:   vty_out (vty, "    input packets %lu, bytes %lu, dropped %lu,"
  856: 	   " multicast packets %lu%s",
  857: 	   ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
  858: 	   ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
  859: 	   VTY_NEWLINE);
  860: 
  861:   vty_out (vty, "    input errors %lu%s",
  862: 	   ifp->stats.ifi_ierrors, VTY_NEWLINE);
  863: 
  864:   vty_out (vty, "    output packets %lu, bytes %lu, multicast packets %lu%s",
  865: 	   ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
  866: 	   ifp->stats.ifi_omcasts, VTY_NEWLINE);
  867: 
  868:   vty_out (vty, "    output errors %lu%s",
  869: 	   ifp->stats.ifi_oerrors, VTY_NEWLINE);
  870: 
  871:   vty_out (vty, "    collisions %lu%s",
  872: 	   ifp->stats.ifi_collisions, VTY_NEWLINE);
  873: #endif /* __bsdi__ || __NetBSD__ */
  874: #endif /* HAVE_NET_RT_IFLIST */
  875: }
  876: 
  877: /* Wrapper hook point for zebra daemon so that ifindex can be set 
  878:  * DEFUN macro not used as extract.pl HAS to ignore this
  879:  * See also interface_cmd in lib/if.c
  880:  */ 
  881: DEFUN_NOSH (zebra_interface,
  882: 	    zebra_interface_cmd,
  883: 	    "interface IFNAME",
  884: 	    "Select an interface to configure\n"
  885: 	    "Interface's name\n")
  886: {
  887:   int ret;
  888:   struct interface * ifp;
  889:   
  890:   /* Call lib interface() */
  891:   if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
  892:     return ret;
  893: 
  894:   ifp = vty->index;  
  895: 
  896:   if (ifp->ifindex == IFINDEX_INTERNAL)
  897:     /* Is this really necessary?  Shouldn't status be initialized to 0
  898:        in that case? */
  899:     UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
  900: 
  901:   return ret;
  902: }
  903: 
  904: ALIAS (zebra_interface,
  905:        zebra_interface_vrf_cmd,
  906:        "interface IFNAME " VRF_CMD_STR,
  907:        "Select an interface to configure\n"
  908:        "Interface's name\n"
  909:        VRF_CMD_HELP_STR)
  910: 
  911: struct cmd_node interface_node =
  912: {
  913:   INTERFACE_NODE,
  914:   "%s(config-if)# ",
  915:   1
  916: };
  917: 
  918: /* Show all interfaces to vty. */
  919: DEFUN (show_interface, show_interface_cmd,
  920:        "show interface",
  921:        SHOW_STR
  922:        "Interface status and configuration\n")
  923: {
  924:   struct listnode *node;
  925:   struct interface *ifp;
  926:   vrf_id_t vrf_id = VRF_DEFAULT;
  927: 
  928: #ifdef HAVE_PROC_NET_DEV
  929:   /* If system has interface statistics via proc file system, update
  930:      statistics. */
  931:   ifstat_update_proc ();
  932: #endif /* HAVE_PROC_NET_DEV */
  933: #ifdef HAVE_NET_RT_IFLIST
  934:   ifstat_update_sysctl ();
  935: #endif /* HAVE_NET_RT_IFLIST */
  936: 
  937:   if (argc > 0)
  938:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
  939: 
  940:   /* All interface print. */
  941:   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
  942:     if_dump_vty (vty, ifp);
  943: 
  944:   return CMD_SUCCESS;
  945: }
  946: 
  947: ALIAS (show_interface,
  948:        show_interface_vrf_cmd,
  949:        "show interface " VRF_CMD_STR,
  950:        SHOW_STR
  951:        "Interface status and configuration\n"
  952:        VRF_CMD_HELP_STR)
  953: 
  954: /* Show all interfaces to vty. */
  955: DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
  956:        "show interface " VRF_ALL_CMD_STR,
  957:        SHOW_STR
  958:        "Interface status and configuration\n"
  959:        VRF_ALL_CMD_HELP_STR)
  960: {
  961:   struct listnode *node;
  962:   struct interface *ifp;
  963:   vrf_iter_t iter;
  964: 
  965: #ifdef HAVE_PROC_NET_DEV
  966:   /* If system has interface statistics via proc file system, update
  967:      statistics. */
  968:   ifstat_update_proc ();
  969: #endif /* HAVE_PROC_NET_DEV */
  970: #ifdef HAVE_NET_RT_IFLIST
  971:   ifstat_update_sysctl ();
  972: #endif /* HAVE_NET_RT_IFLIST */
  973: 
  974:   /* All interface print. */
  975:   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
  976:     for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
  977:       if_dump_vty (vty, ifp);
  978: 
  979:   return CMD_SUCCESS;
  980: }
  981: 
  982: /* Show specified interface to vty. */
  983: DEFUN (show_interface_name, show_interface_name_cmd,
  984:        "show interface IFNAME",
  985:        SHOW_STR
  986:        "Interface status and configuration\n"
  987:        "Inteface name\n")
  988: {
  989:   struct interface *ifp;
  990:   vrf_id_t vrf_id = VRF_DEFAULT;
  991: 
  992: #ifdef HAVE_PROC_NET_DEV
  993:   /* If system has interface statistics via proc file system, update
  994:      statistics. */
  995:   ifstat_update_proc ();
  996: #endif /* HAVE_PROC_NET_DEV */
  997: #ifdef HAVE_NET_RT_IFLIST
  998:   ifstat_update_sysctl ();
  999: #endif /* HAVE_NET_RT_IFLIST */
 1000: 
 1001:   if (argc > 1)
 1002:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
 1003: 
 1004:   /* Specified interface print. */
 1005:   ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
 1006:   if (ifp == NULL)
 1007:     {
 1008:       vty_out (vty, "%% Can't find interface %s%s", argv[0],
 1009:                VTY_NEWLINE);
 1010:       return CMD_WARNING;
 1011:     }
 1012:   if_dump_vty (vty, ifp);
 1013: 
 1014:   return CMD_SUCCESS;
 1015: }
 1016: 
 1017: ALIAS (show_interface_name,
 1018:        show_interface_name_vrf_cmd,
 1019:        "show interface IFNAME " VRF_CMD_STR,
 1020:        SHOW_STR
 1021:        "Interface status and configuration\n"
 1022:        "Inteface name\n"
 1023:        VRF_CMD_HELP_STR)
 1024: 
 1025: /* Show specified interface to vty. */
 1026: DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
 1027:        "show interface IFNAME " VRF_ALL_CMD_STR,
 1028:        SHOW_STR
 1029:        "Interface status and configuration\n"
 1030:        "Inteface name\n"
 1031:        VRF_ALL_CMD_HELP_STR)
 1032: {
 1033:   struct interface *ifp;
 1034:   vrf_iter_t iter;
 1035:   int found = 0;
 1036: 
 1037: #ifdef HAVE_PROC_NET_DEV
 1038:   /* If system has interface statistics via proc file system, update
 1039:      statistics. */
 1040:   ifstat_update_proc ();
 1041: #endif /* HAVE_PROC_NET_DEV */
 1042: #ifdef HAVE_NET_RT_IFLIST
 1043:   ifstat_update_sysctl ();
 1044: #endif /* HAVE_NET_RT_IFLIST */
 1045: 
 1046:   /* All interface print. */
 1047:   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
 1048:     {
 1049:       /* Specified interface print. */
 1050:       ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
 1051:       if (ifp)
 1052:         {
 1053:           if_dump_vty (vty, ifp);
 1054:           found++;
 1055:         }
 1056:     }
 1057: 
 1058:   if (!found)
 1059:     {
 1060:       vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
 1061:       return CMD_WARNING;
 1062:     }
 1063: 
 1064:   return CMD_SUCCESS;
 1065: }
 1066: 
 1067: static void
 1068: if_show_description (struct vty *vty, vrf_id_t vrf_id)
 1069: {
 1070:   struct listnode *node;
 1071:   struct interface *ifp;
 1072: 
 1073:   vty_out (vty, "Interface       Status  Protocol  Description%s", VTY_NEWLINE);
 1074:   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
 1075:     {
 1076:       int len;
 1077: 
 1078:       len = vty_out (vty, "%s", ifp->name);
 1079:       vty_out (vty, "%*s", (16 - len), " ");
 1080:       
 1081:       if (if_is_up(ifp))
 1082: 	{
 1083: 	  vty_out (vty, "up      ");
 1084: 	  if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
 1085: 	    {
 1086: 	      if (if_is_running(ifp))
 1087: 		vty_out (vty, "up        ");
 1088: 	      else
 1089: 		vty_out (vty, "down      ");
 1090: 	    }
 1091: 	  else
 1092: 	    {
 1093: 	      vty_out (vty, "unknown   ");
 1094: 	    }
 1095: 	}
 1096:       else
 1097: 	{
 1098: 	  vty_out (vty, "down    down      ");
 1099: 	}
 1100: 
 1101:       if (ifp->desc)
 1102: 	vty_out (vty, "%s", ifp->desc);
 1103:       vty_out (vty, "%s", VTY_NEWLINE);
 1104:     }
 1105: }
 1106: 
 1107: DEFUN (show_interface_desc,
 1108:        show_interface_desc_cmd,
 1109:        "show interface description",
 1110:        SHOW_STR
 1111:        "Interface status and configuration\n"
 1112:        "Interface description\n")
 1113: {
 1114:   vrf_id_t vrf_id = VRF_DEFAULT;
 1115: 
 1116:   if (argc > 0)
 1117:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
 1118: 
 1119:   if_show_description (vty, vrf_id);
 1120: 
 1121:   return CMD_SUCCESS;
 1122: }
 1123: 
 1124: ALIAS (show_interface_desc,
 1125:        show_interface_desc_vrf_cmd,
 1126:        "show interface description " VRF_CMD_STR,
 1127:        SHOW_STR
 1128:        "Interface status and configuration\n"
 1129:        "Interface description\n"
 1130:        VRF_CMD_HELP_STR)
 1131: 
 1132: DEFUN (show_interface_desc_vrf_all,
 1133:        show_interface_desc_vrf_all_cmd,
 1134:        "show interface description " VRF_ALL_CMD_STR,
 1135:        SHOW_STR
 1136:        "Interface status and configuration\n"
 1137:        "Interface description\n"
 1138:        VRF_ALL_CMD_HELP_STR)
 1139: {
 1140:   vrf_iter_t iter;
 1141: 
 1142:   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
 1143:     if (!list_isempty (vrf_iter2iflist (iter)))
 1144:       {
 1145:         vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
 1146:                  vrf_iter2id (iter),
 1147:                  VTY_NEWLINE, VTY_NEWLINE);
 1148:         if_show_description (vty, vrf_iter2id (iter));
 1149:       }
 1150: 
 1151:   return CMD_SUCCESS;
 1152: }
 1153: 
 1154: DEFUN (multicast,
 1155:        multicast_cmd,
 1156:        "multicast",
 1157:        "Set multicast flag to interface\n")
 1158: {
 1159:   int ret;
 1160:   struct interface *ifp;
 1161:   struct zebra_if *if_data;
 1162: 
 1163:   ifp = (struct interface *) vty->index;
 1164:   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1165:     {
 1166:       ret = if_set_flags (ifp, IFF_MULTICAST);
 1167:       if (ret < 0)
 1168: 	{
 1169: 	  vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
 1170: 	  return CMD_WARNING;
 1171: 	}
 1172:       if_refresh (ifp);
 1173:     }
 1174:   if_data = ifp->info;
 1175:   if_data->multicast = IF_ZEBRA_MULTICAST_ON;
 1176: 
 1177:   return CMD_SUCCESS;
 1178: }
 1179: 
 1180: DEFUN (no_multicast,
 1181:        no_multicast_cmd,
 1182:        "no multicast",
 1183:        NO_STR
 1184:        "Unset multicast flag to interface\n")
 1185: {
 1186:   int ret;
 1187:   struct interface *ifp;
 1188:   struct zebra_if *if_data;
 1189: 
 1190:   ifp = (struct interface *) vty->index;
 1191:   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1192:     {
 1193:       ret = if_unset_flags (ifp, IFF_MULTICAST);
 1194:       if (ret < 0)
 1195: 	{
 1196: 	  vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
 1197: 	  return CMD_WARNING;
 1198: 	}
 1199:       if_refresh (ifp);
 1200:     }
 1201:   if_data = ifp->info;
 1202:   if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
 1203: 
 1204:   return CMD_SUCCESS;
 1205: }
 1206: 
 1207: DEFUN (linkdetect,
 1208:        linkdetect_cmd,
 1209:        "link-detect",
 1210:        "Enable link detection on interface\n")
 1211: {
 1212:   struct interface *ifp;
 1213:   int if_was_operative;
 1214:   
 1215:   ifp = (struct interface *) vty->index;
 1216:   if_was_operative = if_is_operative(ifp);
 1217:   SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
 1218: 
 1219:   /* When linkdetection is enabled, if might come down */
 1220:   if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
 1221: 
 1222:   /* FIXME: Will defer status change forwarding if interface
 1223:      does not come down! */
 1224: 
 1225:   return CMD_SUCCESS;
 1226: }
 1227: 
 1228: 
 1229: DEFUN (no_linkdetect,
 1230:        no_linkdetect_cmd,
 1231:        "no link-detect",
 1232:        NO_STR
 1233:        "Disable link detection on interface\n")
 1234: {
 1235:   struct interface *ifp;
 1236:   int if_was_operative;
 1237: 
 1238:   ifp = (struct interface *) vty->index;
 1239:   if_was_operative = if_is_operative(ifp);
 1240:   UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
 1241:   
 1242:   /* Interface may come up after disabling link detection */
 1243:   if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
 1244: 
 1245:   /* FIXME: see linkdetect_cmd */
 1246: 
 1247:   return CMD_SUCCESS;
 1248: }
 1249: 
 1250: DEFUN (shutdown_if,
 1251:        shutdown_if_cmd,
 1252:        "shutdown",
 1253:        "Shutdown the selected interface\n")
 1254: {
 1255:   int ret;
 1256:   struct interface *ifp;
 1257:   struct zebra_if *if_data;
 1258: 
 1259:   ifp = (struct interface *) vty->index;
 1260:   if (ifp->ifindex != IFINDEX_INTERNAL)
 1261:     {
 1262:         ret = if_unset_flags (ifp, IFF_UP);
 1263:         if (ret < 0)
 1264:           {
 1265:             vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
 1266:             return CMD_WARNING;
 1267:           }
 1268:         if_refresh (ifp);
 1269:     }
 1270:   if_data = ifp->info;
 1271:   if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
 1272: 
 1273:   return CMD_SUCCESS;
 1274: }
 1275: 
 1276: DEFUN (no_shutdown_if,
 1277:        no_shutdown_if_cmd,
 1278:        "no shutdown",
 1279:        NO_STR
 1280:        "Shutdown the selected interface\n")
 1281: {
 1282:   int ret;
 1283:   struct interface *ifp;
 1284:   struct zebra_if *if_data;
 1285: 
 1286:   ifp = (struct interface *) vty->index;
 1287: 
 1288:   if (ifp->ifindex != IFINDEX_INTERNAL)
 1289:     {
 1290:       ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
 1291:       if (ret < 0)
 1292: 	{
 1293: 	  vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
 1294: 	  return CMD_WARNING;
 1295: 	}
 1296:       if_refresh (ifp);
 1297: 
 1298:       /* Some addresses (in particular, IPv6 addresses on Linux) get
 1299:        * removed when the interface goes down. They need to be readded.
 1300:        */
 1301:       if_addr_wakeup(ifp);
 1302:     }
 1303: 
 1304:   if_data = ifp->info;
 1305:   if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
 1306: 
 1307:   return CMD_SUCCESS;
 1308: }
 1309: 
 1310: DEFUN (bandwidth_if,
 1311:        bandwidth_if_cmd,
 1312:        "bandwidth <1-10000000>",
 1313:        "Set bandwidth informational parameter\n"
 1314:        "Bandwidth in kilobits\n")
 1315: {
 1316:   struct interface *ifp;   
 1317:   unsigned int bandwidth;
 1318:   
 1319:   ifp = (struct interface *) vty->index;
 1320:   bandwidth = strtol(argv[0], NULL, 10);
 1321: 
 1322:   /* bandwidth range is <1-10000000> */
 1323:   if (bandwidth < 1 || bandwidth > 10000000)
 1324:     {
 1325:       vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
 1326:       return CMD_WARNING;
 1327:     }
 1328:   
 1329:   ifp->bandwidth = bandwidth;
 1330: 
 1331:   /* force protocols to recalculate routes due to cost change */
 1332:   if (if_is_operative (ifp))
 1333:     zebra_interface_up_update (ifp);
 1334:   
 1335:   return CMD_SUCCESS;
 1336: }
 1337: 
 1338: DEFUN (no_bandwidth_if,
 1339:        no_bandwidth_if_cmd,
 1340:        "no bandwidth",
 1341:        NO_STR
 1342:        "Set bandwidth informational parameter\n")
 1343: {
 1344:   struct interface *ifp;   
 1345:   
 1346:   ifp = (struct interface *) vty->index;
 1347: 
 1348:   ifp->bandwidth = 0;
 1349:   
 1350:   /* force protocols to recalculate routes due to cost change */
 1351:   if (if_is_operative (ifp))
 1352:     zebra_interface_up_update (ifp);
 1353: 
 1354:   return CMD_SUCCESS;
 1355: }
 1356: 
 1357: ALIAS (no_bandwidth_if,
 1358:        no_bandwidth_if_val_cmd,
 1359:        "no bandwidth <1-10000000>",
 1360:        NO_STR
 1361:        "Set bandwidth informational parameter\n"
 1362:        "Bandwidth in kilobits\n")
 1363: 
 1364: static int
 1365: ip_address_install (struct vty *vty, struct interface *ifp,
 1366: 		    const char *addr_str, const char *peer_str,
 1367: 		    const char *label)
 1368: {
 1369:   struct zebra_if *if_data;
 1370:   struct prefix_ipv4 cp;
 1371:   struct connected *ifc;
 1372:   struct prefix_ipv4 *p;
 1373:   int ret;
 1374: 
 1375:   if_data = ifp->info;
 1376: 
 1377:   ret = str2prefix_ipv4 (addr_str, &cp);
 1378:   if (ret <= 0)
 1379:     {
 1380:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
 1381:       return CMD_WARNING;
 1382:     }
 1383: 
 1384:   ifc = connected_check (ifp, (struct prefix *) &cp);
 1385:   if (! ifc)
 1386:     {
 1387:       ifc = connected_new ();
 1388:       ifc->ifp = ifp;
 1389: 
 1390:       /* Address. */
 1391:       p = prefix_ipv4_new ();
 1392:       *p = cp;
 1393:       ifc->address = (struct prefix *) p;
 1394: 
 1395:       /* Broadcast. */
 1396:       if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
 1397: 	{
 1398: 	  p = prefix_ipv4_new ();
 1399: 	  *p = cp;
 1400: 	  p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
 1401: 	  ifc->destination = (struct prefix *) p;
 1402: 	}
 1403: 
 1404:       /* Label. */
 1405:       if (label)
 1406: 	ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
 1407: 
 1408:       /* Add to linked list. */
 1409:       listnode_add (ifp->connected, ifc);
 1410:     }
 1411: 
 1412:   /* This address is configured from zebra. */
 1413:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1414:     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
 1415: 
 1416:   /* In case of this route need to install kernel. */
 1417:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
 1418:       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
 1419:       && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
 1420:     {
 1421:       /* Some system need to up the interface to set IP address. */
 1422:       if (! if_is_up (ifp))
 1423: 	{
 1424: 	  if_set_flags (ifp, IFF_UP | IFF_RUNNING);
 1425: 	  if_refresh (ifp);
 1426: 	}
 1427: 
 1428:       ret = if_set_prefix (ifp, ifc);
 1429:       if (ret < 0)
 1430: 	{
 1431: 	  vty_out (vty, "%% Can't set interface IP address: %s.%s", 
 1432: 		   safe_strerror(errno), VTY_NEWLINE);
 1433: 	  return CMD_WARNING;
 1434: 	}
 1435: 
 1436:       SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
 1437:       /* The address will be advertised to zebra clients when the notification
 1438:        * from the kernel has been received.
 1439:        * It will also be added to the subnet chain list, then. */
 1440:     }
 1441: 
 1442:   return CMD_SUCCESS;
 1443: }
 1444: 
 1445: static int
 1446: ip_address_uninstall (struct vty *vty, struct interface *ifp,
 1447: 		      const char *addr_str, const char *peer_str,
 1448: 		      const char *label)
 1449: {
 1450:   struct prefix_ipv4 cp;
 1451:   struct connected *ifc;
 1452:   int ret;
 1453: 
 1454:   /* Convert to prefix structure. */
 1455:   ret = str2prefix_ipv4 (addr_str, &cp);
 1456:   if (ret <= 0)
 1457:     {
 1458:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
 1459:       return CMD_WARNING;
 1460:     }
 1461: 
 1462:   /* Check current interface address. */
 1463:   ifc = connected_check (ifp, (struct prefix *) &cp);
 1464:   if (! ifc)
 1465:     {
 1466:       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
 1467:       return CMD_WARNING;
 1468:     }
 1469: 
 1470:   /* This is not configured address. */
 1471:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1472:     return CMD_WARNING;
 1473: 
 1474:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
 1475:   
 1476:   /* This is not real address or interface is not active. */
 1477:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
 1478:       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1479:     {
 1480:       listnode_delete (ifp->connected, ifc);
 1481:       connected_free (ifc);
 1482:       return CMD_WARNING;
 1483:     }
 1484: 
 1485:   /* This is real route. */
 1486:   ret = if_unset_prefix (ifp, ifc);
 1487:   if (ret < 0)
 1488:     {
 1489:       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
 1490: 	       safe_strerror(errno), VTY_NEWLINE);
 1491:       return CMD_WARNING;
 1492:     }
 1493:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
 1494:   /* we will receive a kernel notification about this route being removed.
 1495:    * this will trigger its removal from the connected list. */
 1496:   return CMD_SUCCESS;
 1497: }
 1498: 
 1499: DEFUN (ip_address,
 1500:        ip_address_cmd,
 1501:        "ip address A.B.C.D/M",
 1502:        "Interface Internet Protocol config commands\n"
 1503:        "Set the IP address of an interface\n"
 1504:        "IP address (e.g. 10.0.0.1/8)\n")
 1505: {
 1506:   return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
 1507: }
 1508: 
 1509: DEFUN (no_ip_address,
 1510:        no_ip_address_cmd,
 1511:        "no ip address A.B.C.D/M",
 1512:        NO_STR
 1513:        "Interface Internet Protocol config commands\n"
 1514:        "Set the IP address of an interface\n"
 1515:        "IP Address (e.g. 10.0.0.1/8)")
 1516: {
 1517:   return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
 1518: }
 1519: 
 1520: #ifdef HAVE_NETLINK
 1521: DEFUN (ip_address_label,
 1522:        ip_address_label_cmd,
 1523:        "ip address A.B.C.D/M label LINE",
 1524:        "Interface Internet Protocol config commands\n"
 1525:        "Set the IP address of an interface\n"
 1526:        "IP address (e.g. 10.0.0.1/8)\n"
 1527:        "Label of this address\n"
 1528:        "Label\n")
 1529: {
 1530:   return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
 1531: }
 1532: 
 1533: DEFUN (no_ip_address_label,
 1534:        no_ip_address_label_cmd,
 1535:        "no ip address A.B.C.D/M label LINE",
 1536:        NO_STR
 1537:        "Interface Internet Protocol config commands\n"
 1538:        "Set the IP address of an interface\n"
 1539:        "IP address (e.g. 10.0.0.1/8)\n"
 1540:        "Label of this address\n"
 1541:        "Label\n")
 1542: {
 1543:   return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
 1544: }
 1545: #endif /* HAVE_NETLINK */
 1546: 
 1547: #ifdef HAVE_IPV6
 1548: static int
 1549: ipv6_address_install (struct vty *vty, struct interface *ifp,
 1550: 		      const char *addr_str, const char *peer_str,
 1551: 		      const char *label, int secondary)
 1552: {
 1553:   struct zebra_if *if_data;
 1554:   struct prefix_ipv6 cp;
 1555:   struct connected *ifc;
 1556:   struct prefix_ipv6 *p;
 1557:   int ret;
 1558: 
 1559:   if_data = ifp->info;
 1560: 
 1561:   ret = str2prefix_ipv6 (addr_str, &cp);
 1562:   if (ret <= 0)
 1563:     {
 1564:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
 1565:       return CMD_WARNING;
 1566:     }
 1567: 
 1568:   ifc = connected_check (ifp, (struct prefix *) &cp);
 1569:   if (! ifc)
 1570:     {
 1571:       ifc = connected_new ();
 1572:       ifc->ifp = ifp;
 1573: 
 1574:       /* Address. */
 1575:       p = prefix_ipv6_new ();
 1576:       *p = cp;
 1577:       ifc->address = (struct prefix *) p;
 1578: 
 1579:       /* Secondary. */
 1580:       if (secondary)
 1581: 	SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
 1582: 
 1583:       /* Label. */
 1584:       if (label)
 1585: 	ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
 1586: 
 1587:       /* Add to linked list. */
 1588:       listnode_add (ifp->connected, ifc);
 1589:     }
 1590: 
 1591:   /* This address is configured from zebra. */
 1592:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1593:     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
 1594: 
 1595:   /* In case of this route need to install kernel. */
 1596:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
 1597:       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
 1598:       && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
 1599:     {
 1600:       /* Some system need to up the interface to set IP address. */
 1601:       if (! if_is_up (ifp))
 1602: 	{
 1603: 	  if_set_flags (ifp, IFF_UP | IFF_RUNNING);
 1604: 	  if_refresh (ifp);
 1605: 	}
 1606: 
 1607:       ret = if_prefix_add_ipv6 (ifp, ifc);
 1608: 
 1609:       if (ret < 0)
 1610: 	{
 1611: 	  vty_out (vty, "%% Can't set interface IP address: %s.%s", 
 1612: 		   safe_strerror(errno), VTY_NEWLINE);
 1613: 	  return CMD_WARNING;
 1614: 	}
 1615: 
 1616:       SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
 1617:       /* The address will be advertised to zebra clients when the notification
 1618:        * from the kernel has been received. */
 1619:     }
 1620: 
 1621:   return CMD_SUCCESS;
 1622: }
 1623: 
 1624: static int
 1625: ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
 1626: 			const char *addr_str, const char *peer_str,
 1627: 			const char *label, int secondry)
 1628: {
 1629:   struct prefix_ipv6 cp;
 1630:   struct connected *ifc;
 1631:   int ret;
 1632: 
 1633:   /* Convert to prefix structure. */
 1634:   ret = str2prefix_ipv6 (addr_str, &cp);
 1635:   if (ret <= 0)
 1636:     {
 1637:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
 1638:       return CMD_WARNING;
 1639:     }
 1640: 
 1641:   /* Check current interface address. */
 1642:   ifc = connected_check (ifp, (struct prefix *) &cp);
 1643:   if (! ifc)
 1644:     {
 1645:       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
 1646:       return CMD_WARNING;
 1647:     }
 1648: 
 1649:   /* This is not configured address. */
 1650:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1651:     return CMD_WARNING;
 1652: 
 1653:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
 1654: 
 1655:   /* This is not real address or interface is not active. */
 1656:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
 1657:       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1658:     {
 1659:       listnode_delete (ifp->connected, ifc);
 1660:       connected_free (ifc);
 1661:       return CMD_WARNING;
 1662:     }
 1663: 
 1664:   /* This is real route. */
 1665:   ret = if_prefix_delete_ipv6 (ifp, ifc);
 1666:   if (ret < 0)
 1667:     {
 1668:       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
 1669: 	       safe_strerror(errno), VTY_NEWLINE);
 1670:       return CMD_WARNING;
 1671:     }
 1672: 
 1673:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
 1674:   /* This information will be propagated to the zclients when the
 1675:    * kernel notification is received. */
 1676:   return CMD_SUCCESS;
 1677: }
 1678: 
 1679: DEFUN (ipv6_address,
 1680:        ipv6_address_cmd,
 1681:        "ipv6 address X:X::X:X/M",
 1682:        "Interface IPv6 config commands\n"
 1683:        "Set the IP address of an interface\n"
 1684:        "IPv6 address (e.g. 3ffe:506::1/48)\n")
 1685: {
 1686:   return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
 1687: }
 1688: 
 1689: DEFUN (no_ipv6_address,
 1690:        no_ipv6_address_cmd,
 1691:        "no ipv6 address X:X::X:X/M",
 1692:        NO_STR
 1693:        "Interface IPv6 config commands\n"
 1694:        "Set the IP address of an interface\n"
 1695:        "IPv6 address (e.g. 3ffe:506::1/48)\n")
 1696: {
 1697:   return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
 1698: }
 1699: #endif /* HAVE_IPV6 */
 1700: 
 1701: static int
 1702: if_config_write (struct vty *vty)
 1703: {
 1704:   struct listnode *node;
 1705:   struct interface *ifp;
 1706:   vrf_iter_t iter;
 1707: 
 1708:   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
 1709:   for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
 1710:     {
 1711:       struct zebra_if *if_data;
 1712:       struct listnode *addrnode;
 1713:       struct connected *ifc;
 1714:       struct prefix *p;
 1715: 
 1716:       if_data = ifp->info;
 1717: 
 1718:       if (ifp->vrf_id == VRF_DEFAULT)
 1719:         vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
 1720:       else
 1721:         vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
 1722:                  VTY_NEWLINE);
 1723: 
 1724:       if (if_data)
 1725: 	{
 1726: 	  if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
 1727: 	    vty_out (vty, " shutdown%s", VTY_NEWLINE);
 1728: 	}
 1729: 
 1730:       if (ifp->desc)
 1731: 	vty_out (vty, " description %s%s", ifp->desc,
 1732: 		 VTY_NEWLINE);
 1733: 
 1734:       /* Assign bandwidth here to avoid unnecessary interface flap
 1735: 	 while processing config script */
 1736:       if (ifp->bandwidth != 0)
 1737: 	vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE); 
 1738: 
 1739:       if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
 1740: 	vty_out(vty, " link-detect%s", VTY_NEWLINE);
 1741:       else
 1742: 	vty_out(vty, " no link-detect%s", VTY_NEWLINE);
 1743: 
 1744:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
 1745: 	  {
 1746: 	    if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1747: 	      {
 1748: 		char buf[INET6_ADDRSTRLEN];
 1749: 		p = ifc->address;
 1750: 		vty_out (vty, " ip%s address %s",
 1751: 			 p->family == AF_INET ? "" : "v6",
 1752: 			 prefix2str (p, buf, sizeof(buf)));
 1753: 
 1754: 		if (ifc->label)
 1755: 		  vty_out (vty, " label %s", ifc->label);
 1756: 
 1757: 		vty_out (vty, "%s", VTY_NEWLINE);
 1758: 	      }
 1759: 	  }
 1760: 
 1761:       if (if_data)
 1762: 	{
 1763: 	  if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
 1764: 	    vty_out (vty, " %smulticast%s",
 1765: 		     if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
 1766: 		     VTY_NEWLINE);
 1767: 	}
 1768: 
 1769: #if defined (HAVE_RTADV)
 1770:       rtadv_config_write (vty, ifp);
 1771: #endif /* HAVE_RTADV */
 1772: 
 1773: #ifdef HAVE_IRDP
 1774:       irdp_config_write (vty, ifp);
 1775: #endif /* IRDP */
 1776: 
 1777:       vty_out (vty, "!%s", VTY_NEWLINE);
 1778:     }
 1779:   return 0;
 1780: }
 1781: 
 1782: /* Allocate and initialize interface vector. */
 1783: void
 1784: zebra_if_init (void)
 1785: {
 1786:   /* Initialize interface and new hook. */
 1787:   if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
 1788:   if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
 1789:   
 1790:   /* Install configuration write function. */
 1791:   install_node (&interface_node, if_config_write);
 1792: 
 1793:   install_element (VIEW_NODE, &show_interface_cmd);
 1794:   install_element (VIEW_NODE, &show_interface_vrf_cmd);
 1795:   install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
 1796:   install_element (VIEW_NODE, &show_interface_name_cmd);
 1797:   install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
 1798:   install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
 1799:   install_element (ENABLE_NODE, &show_interface_cmd);
 1800:   install_element (ENABLE_NODE, &show_interface_vrf_cmd);
 1801:   install_element (ENABLE_NODE, &show_interface_vrf_all_cmd);
 1802:   install_element (ENABLE_NODE, &show_interface_name_cmd);
 1803:   install_element (ENABLE_NODE, &show_interface_name_vrf_cmd);
 1804:   install_element (ENABLE_NODE, &show_interface_name_vrf_all_cmd);
 1805:   install_element (ENABLE_NODE, &show_interface_desc_cmd);
 1806:   install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd);
 1807:   install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
 1808:   install_element (CONFIG_NODE, &zebra_interface_cmd);
 1809:   install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
 1810:   install_element (CONFIG_NODE, &no_interface_cmd);
 1811:   install_element (CONFIG_NODE, &no_interface_vrf_cmd);
 1812:   install_default (INTERFACE_NODE);
 1813:   install_element (INTERFACE_NODE, &interface_desc_cmd);
 1814:   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
 1815:   install_element (INTERFACE_NODE, &multicast_cmd);
 1816:   install_element (INTERFACE_NODE, &no_multicast_cmd);
 1817:   install_element (INTERFACE_NODE, &linkdetect_cmd);
 1818:   install_element (INTERFACE_NODE, &no_linkdetect_cmd);
 1819:   install_element (INTERFACE_NODE, &shutdown_if_cmd);
 1820:   install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
 1821:   install_element (INTERFACE_NODE, &bandwidth_if_cmd);
 1822:   install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
 1823:   install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
 1824:   install_element (INTERFACE_NODE, &ip_address_cmd);
 1825:   install_element (INTERFACE_NODE, &no_ip_address_cmd);
 1826: #ifdef HAVE_IPV6
 1827:   install_element (INTERFACE_NODE, &ipv6_address_cmd);
 1828:   install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
 1829: #endif /* HAVE_IPV6 */
 1830: #ifdef HAVE_NETLINK
 1831:   install_element (INTERFACE_NODE, &ip_address_label_cmd);
 1832:   install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
 1833: #endif /* HAVE_NETLINK */
 1834: }

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