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

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

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