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

    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 = -1; /* derive from MaxRtrAdvInterval */
   80:     rtadv->HomeAgentPreference = 0;
   81:     rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
   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 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:       if (rtadv->AdvDefaultLifetime != -1)
  634: 	vty_out (vty, "  ND router advertisements live for %d seconds%s",
  635: 		 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
  636:       else
  637: 	vty_out (vty, "  ND router advertisements lifetime tracks ra-interval%s",
  638: 		 VTY_NEWLINE);
  639:       vty_out (vty, "  ND router advertisement default router preference is "
  640: 			"%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
  641: 		 VTY_NEWLINE);
  642:       if (rtadv->AdvManagedFlag)
  643: 	vty_out (vty, "  Hosts use DHCP to obtain routable addresses.%s",
  644: 		 VTY_NEWLINE);
  645:       else
  646: 	vty_out (vty, "  Hosts use stateless autoconfig for addresses.%s",
  647: 		 VTY_NEWLINE);
  648:       if (rtadv->AdvHomeAgentFlag)
  649:       {
  650:       	vty_out (vty, "  ND router advertisements with "
  651: 				"Home Agent flag bit set.%s",
  652: 		 VTY_NEWLINE);
  653: 	if (rtadv->HomeAgentLifetime != -1)
  654: 	  vty_out (vty, "  Home Agent lifetime is %u seconds%s",
  655: 	           rtadv->HomeAgentLifetime, VTY_NEWLINE);
  656: 	else
  657: 	  vty_out (vty, "  Home Agent lifetime tracks ra-lifetime%s",
  658: 	           VTY_NEWLINE);
  659: 	vty_out (vty, "  Home Agent preference is %u%s",
  660: 	         rtadv->HomeAgentPreference, VTY_NEWLINE);
  661:       }
  662:       if (rtadv->AdvIntervalOption)
  663:       	vty_out (vty, "  ND router advertisements with Adv. Interval option.%s",
  664: 		 VTY_NEWLINE);
  665:     }
  666: }
  667: #endif /* RTADV */
  668: 
  669: /* Interface's information print out to vty interface. */
  670: static void
  671: if_dump_vty (struct vty *vty, struct interface *ifp)
  672: {
  673: #ifdef HAVE_STRUCT_SOCKADDR_DL
  674:   struct sockaddr_dl *sdl;
  675: #endif /* HAVE_STRUCT_SOCKADDR_DL */
  676:   struct connected *connected;
  677:   struct listnode *node;
  678:   struct route_node *rn;
  679:   struct zebra_if *zebra_if;
  680: 
  681:   zebra_if = ifp->info;
  682: 
  683:   vty_out (vty, "Interface %s is ", ifp->name);
  684:   if (if_is_up(ifp)) {
  685:     vty_out (vty, "up, line protocol ");
  686:     
  687:     if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
  688:       if (if_is_running(ifp))
  689:        vty_out (vty, "is up%s", VTY_NEWLINE);
  690:       else
  691: 	vty_out (vty, "is down%s", VTY_NEWLINE);
  692:     } else {
  693:       vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
  694:     }
  695:   } else {
  696:     vty_out (vty, "down%s", VTY_NEWLINE);
  697:   }
  698: 
  699:   if (ifp->desc)
  700:     vty_out (vty, "  Description: %s%s", ifp->desc,
  701: 	     VTY_NEWLINE);
  702:   if (ifp->ifindex == IFINDEX_INTERNAL)
  703:     {
  704:       vty_out(vty, "  pseudo interface%s", VTY_NEWLINE);
  705:       return;
  706:     }
  707:   else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  708:     {
  709:       vty_out(vty, "  index %d inactive interface%s", 
  710: 	      ifp->ifindex, 
  711: 	      VTY_NEWLINE);
  712:       return;
  713:     }
  714: 
  715:   vty_out (vty, "  index %d metric %d mtu %d ",
  716: 	   ifp->ifindex, ifp->metric, ifp->mtu);
  717: #ifdef HAVE_IPV6
  718:   if (ifp->mtu6 != ifp->mtu)
  719:     vty_out (vty, "mtu6 %d ", ifp->mtu6);
  720: #endif 
  721:   vty_out (vty, "%s  flags: %s%s", VTY_NEWLINE,
  722:            if_flag_dump (ifp->flags), VTY_NEWLINE);
  723:   
  724:   /* Hardware address. */
  725: #ifdef HAVE_STRUCT_SOCKADDR_DL
  726:   sdl = &ifp->sdl;
  727:   if (sdl != NULL && sdl->sdl_alen != 0)
  728:     {
  729:       int i;
  730:       u_char *ptr;
  731: 
  732:       vty_out (vty, "  HWaddr: ");
  733:       for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
  734:         vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
  735:       vty_out (vty, "%s", VTY_NEWLINE);
  736:     }
  737: #else
  738:   if (ifp->hw_addr_len != 0)
  739:     {
  740:       int i;
  741: 
  742:       vty_out (vty, "  HWaddr: ");
  743:       for (i = 0; i < ifp->hw_addr_len; i++)
  744: 	vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
  745:       vty_out (vty, "%s", VTY_NEWLINE);
  746:     }
  747: #endif /* HAVE_STRUCT_SOCKADDR_DL */
  748:   
  749:   /* Bandwidth in kbps */
  750:   if (ifp->bandwidth != 0)
  751:     {
  752:       vty_out(vty, "  bandwidth %u kbps", ifp->bandwidth);
  753:       vty_out(vty, "%s", VTY_NEWLINE);
  754:     }
  755: 
  756:   for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
  757:     {
  758:       if (! rn->info)
  759: 	continue;
  760:       
  761:       for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
  762:         connected_dump_vty (vty, connected);
  763:     }
  764: 
  765:   for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
  766:     {
  767:       if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
  768: 	  (connected->address->family == AF_INET6))
  769: 	connected_dump_vty (vty, connected);
  770:     }
  771: 
  772: #ifdef RTADV
  773:   nd_dump_vty (vty, ifp);
  774: #endif /* RTADV */
  775: 
  776: #ifdef HAVE_PROC_NET_DEV
  777:   /* Statistics print out using proc file system. */
  778:   vty_out (vty, "    %lu input packets (%lu multicast), %lu bytes, "
  779: 	   "%lu dropped%s",
  780: 	   ifp->stats.rx_packets, ifp->stats.rx_multicast,
  781: 	   ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
  782: 
  783:   vty_out (vty, "    %lu input errors, %lu length, %lu overrun,"
  784: 	   " %lu CRC, %lu frame%s",
  785: 	   ifp->stats.rx_errors, ifp->stats.rx_length_errors,
  786: 	   ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
  787: 	   ifp->stats.rx_frame_errors, VTY_NEWLINE);
  788: 
  789:   vty_out (vty, "    %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
  790: 	   ifp->stats.rx_missed_errors, VTY_NEWLINE);
  791: 
  792:   vty_out (vty, "    %lu output packets, %lu bytes, %lu dropped%s",
  793: 	   ifp->stats.tx_packets, ifp->stats.tx_bytes,
  794: 	   ifp->stats.tx_dropped, VTY_NEWLINE);
  795: 
  796:   vty_out (vty, "    %lu output errors, %lu aborted, %lu carrier,"
  797: 	   " %lu fifo, %lu heartbeat%s",
  798: 	   ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
  799: 	   ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
  800: 	   ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
  801: 
  802:   vty_out (vty, "    %lu window, %lu collisions%s",
  803: 	   ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
  804: #endif /* HAVE_PROC_NET_DEV */
  805: 
  806: #ifdef HAVE_NET_RT_IFLIST
  807: #if defined (__bsdi__) || defined (__NetBSD__)
  808:   /* Statistics print out using sysctl (). */
  809:   vty_out (vty, "    input packets %qu, bytes %qu, dropped %qu,"
  810: 	   " multicast packets %qu%s",
  811: 	   ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
  812: 	   ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
  813: 	   VTY_NEWLINE);
  814: 
  815:   vty_out (vty, "    input errors %qu%s",
  816: 	   ifp->stats.ifi_ierrors, VTY_NEWLINE);
  817: 
  818:   vty_out (vty, "    output packets %qu, bytes %qu, multicast packets %qu%s",
  819: 	   ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
  820: 	   ifp->stats.ifi_omcasts, VTY_NEWLINE);
  821: 
  822:   vty_out (vty, "    output errors %qu%s",
  823: 	   ifp->stats.ifi_oerrors, VTY_NEWLINE);
  824: 
  825:   vty_out (vty, "    collisions %qu%s",
  826: 	   ifp->stats.ifi_collisions, VTY_NEWLINE);
  827: #else
  828:   /* Statistics print out using sysctl (). */
  829:   vty_out (vty, "    input packets %lu, bytes %lu, dropped %lu,"
  830: 	   " multicast packets %lu%s",
  831: 	   ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
  832: 	   ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
  833: 	   VTY_NEWLINE);
  834: 
  835:   vty_out (vty, "    input errors %lu%s",
  836: 	   ifp->stats.ifi_ierrors, VTY_NEWLINE);
  837: 
  838:   vty_out (vty, "    output packets %lu, bytes %lu, multicast packets %lu%s",
  839: 	   ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
  840: 	   ifp->stats.ifi_omcasts, VTY_NEWLINE);
  841: 
  842:   vty_out (vty, "    output errors %lu%s",
  843: 	   ifp->stats.ifi_oerrors, VTY_NEWLINE);
  844: 
  845:   vty_out (vty, "    collisions %lu%s",
  846: 	   ifp->stats.ifi_collisions, VTY_NEWLINE);
  847: #endif /* __bsdi__ || __NetBSD__ */
  848: #endif /* HAVE_NET_RT_IFLIST */
  849: }
  850: 
  851: /* Wrapper hook point for zebra daemon so that ifindex can be set 
  852:  * DEFUN macro not used as extract.pl HAS to ignore this
  853:  * See also interface_cmd in lib/if.c
  854:  */ 
  855: DEFUN_NOSH (zebra_interface,
  856: 	    zebra_interface_cmd,
  857: 	    "interface IFNAME",
  858: 	    "Select an interface to configure\n"
  859: 	    "Interface's name\n")
  860: {
  861:   int ret;
  862:   struct interface * ifp;
  863:   
  864:   /* Call lib interface() */
  865:   if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
  866:     return ret;
  867: 
  868:   ifp = vty->index;  
  869: 
  870:   if (ifp->ifindex == IFINDEX_INTERNAL)
  871:     /* Is this really necessary?  Shouldn't status be initialized to 0
  872:        in that case? */
  873:     UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
  874: 
  875:   return ret;
  876: }
  877: 
  878: struct cmd_node interface_node =
  879: {
  880:   INTERFACE_NODE,
  881:   "%s(config-if)# ",
  882:   1
  883: };
  884: 
  885: /* Show all or specified interface to vty. */
  886: DEFUN (show_interface, show_interface_cmd,
  887:        "show interface [IFNAME]",  
  888:        SHOW_STR
  889:        "Interface status and configuration\n"
  890:        "Inteface name\n")
  891: {
  892:   struct listnode *node;
  893:   struct interface *ifp;
  894:   
  895: #ifdef HAVE_PROC_NET_DEV
  896:   /* If system has interface statistics via proc file system, update
  897:      statistics. */
  898:   ifstat_update_proc ();
  899: #endif /* HAVE_PROC_NET_DEV */
  900: #ifdef HAVE_NET_RT_IFLIST
  901:   ifstat_update_sysctl ();
  902: #endif /* HAVE_NET_RT_IFLIST */
  903: 
  904:   /* Specified interface print. */
  905:   if (argc != 0)
  906:     {
  907:       ifp = if_lookup_by_name (argv[0]);
  908:       if (ifp == NULL) 
  909: 	{
  910: 	  vty_out (vty, "%% Can't find interface %s%s", argv[0],
  911: 		   VTY_NEWLINE);
  912: 	  return CMD_WARNING;
  913: 	}
  914:       if_dump_vty (vty, ifp);
  915:       return CMD_SUCCESS;
  916:     }
  917: 
  918:   /* All interface print. */
  919:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  920:     if_dump_vty (vty, ifp);
  921: 
  922:   return CMD_SUCCESS;
  923: }
  924: 
  925: DEFUN (show_interface_desc,
  926:        show_interface_desc_cmd,
  927:        "show interface description",
  928:        SHOW_STR
  929:        "Interface status and configuration\n"
  930:        "Interface description\n")
  931: {
  932:   struct listnode *node;
  933:   struct interface *ifp;
  934: 
  935:   vty_out (vty, "Interface       Status  Protocol  Description%s", VTY_NEWLINE);
  936:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  937:     {
  938:       int len;
  939: 
  940:       len = vty_out (vty, "%s", ifp->name);
  941:       vty_out (vty, "%*s", (16 - len), " ");
  942:       
  943:       if (if_is_up(ifp))
  944: 	{
  945: 	  vty_out (vty, "up      ");
  946: 	  if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
  947: 	    {
  948: 	      if (if_is_running(ifp))
  949: 		vty_out (vty, "up        ");
  950: 	      else
  951: 		vty_out (vty, "down      ");
  952: 	    }
  953: 	  else
  954: 	    {
  955: 	      vty_out (vty, "unknown   ");
  956: 	    }
  957: 	}
  958:       else
  959: 	{
  960: 	  vty_out (vty, "down    down      ");
  961: 	}
  962: 
  963:       if (ifp->desc)
  964: 	vty_out (vty, "%s", ifp->desc);
  965:       vty_out (vty, "%s", VTY_NEWLINE);
  966:     }
  967:   return CMD_SUCCESS;
  968: }
  969: 
  970: DEFUN (multicast,
  971:        multicast_cmd,
  972:        "multicast",
  973:        "Set multicast flag to interface\n")
  974: {
  975:   int ret;
  976:   struct interface *ifp;
  977:   struct zebra_if *if_data;
  978: 
  979:   ifp = (struct interface *) vty->index;
  980:   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  981:     {
  982:       ret = if_set_flags (ifp, IFF_MULTICAST);
  983:       if (ret < 0)
  984: 	{
  985: 	  vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
  986: 	  return CMD_WARNING;
  987: 	}
  988:       if_refresh (ifp);
  989:     }
  990:   if_data = ifp->info;
  991:   if_data->multicast = IF_ZEBRA_MULTICAST_ON;
  992: 
  993:   return CMD_SUCCESS;
  994: }
  995: 
  996: DEFUN (no_multicast,
  997:        no_multicast_cmd,
  998:        "no multicast",
  999:        NO_STR
 1000:        "Unset multicast flag to interface\n")
 1001: {
 1002:   int ret;
 1003:   struct interface *ifp;
 1004:   struct zebra_if *if_data;
 1005: 
 1006:   ifp = (struct interface *) vty->index;
 1007:   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1008:     {
 1009:       ret = if_unset_flags (ifp, IFF_MULTICAST);
 1010:       if (ret < 0)
 1011: 	{
 1012: 	  vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
 1013: 	  return CMD_WARNING;
 1014: 	}
 1015:       if_refresh (ifp);
 1016:     }
 1017:   if_data = ifp->info;
 1018:   if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
 1019: 
 1020:   return CMD_SUCCESS;
 1021: }
 1022: 
 1023: DEFUN (linkdetect,
 1024:        linkdetect_cmd,
 1025:        "link-detect",
 1026:        "Enable link detection on interface\n")
 1027: {
 1028:   struct interface *ifp;
 1029:   int if_was_operative;
 1030:   
 1031:   ifp = (struct interface *) vty->index;
 1032:   if_was_operative = if_is_operative(ifp);
 1033:   SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
 1034: 
 1035:   /* When linkdetection is enabled, if might come down */
 1036:   if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
 1037: 
 1038:   /* FIXME: Will defer status change forwarding if interface
 1039:      does not come down! */
 1040: 
 1041:   return CMD_SUCCESS;
 1042: }
 1043: 
 1044: 
 1045: DEFUN (no_linkdetect,
 1046:        no_linkdetect_cmd,
 1047:        "no link-detect",
 1048:        NO_STR
 1049:        "Disable link detection on interface\n")
 1050: {
 1051:   struct interface *ifp;
 1052:   int if_was_operative;
 1053: 
 1054:   ifp = (struct interface *) vty->index;
 1055:   if_was_operative = if_is_operative(ifp);
 1056:   UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
 1057:   
 1058:   /* Interface may come up after disabling link detection */
 1059:   if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
 1060: 
 1061:   /* FIXME: see linkdetect_cmd */
 1062: 
 1063:   return CMD_SUCCESS;
 1064: }
 1065: 
 1066: DEFUN (shutdown_if,
 1067:        shutdown_if_cmd,
 1068:        "shutdown",
 1069:        "Shutdown the selected interface\n")
 1070: {
 1071:   int ret;
 1072:   struct interface *ifp;
 1073:   struct zebra_if *if_data;
 1074: 
 1075:   ifp = (struct interface *) vty->index;
 1076:   ret = if_unset_flags (ifp, IFF_UP);
 1077:   if (ret < 0)
 1078:     {
 1079:       vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
 1080:       return CMD_WARNING;
 1081:     }
 1082:   if_refresh (ifp);
 1083:   if_data = ifp->info;
 1084:   if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
 1085: 
 1086:   return CMD_SUCCESS;
 1087: }
 1088: 
 1089: DEFUN (no_shutdown_if,
 1090:        no_shutdown_if_cmd,
 1091:        "no shutdown",
 1092:        NO_STR
 1093:        "Shutdown the selected interface\n")
 1094: {
 1095:   int ret;
 1096:   struct interface *ifp;
 1097:   struct zebra_if *if_data;
 1098: 
 1099:   ifp = (struct interface *) vty->index;
 1100:   ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
 1101:   if (ret < 0)
 1102:     {
 1103:       vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
 1104:       return CMD_WARNING;
 1105:     }
 1106:   if_refresh (ifp);
 1107:   if_data = ifp->info;
 1108:   if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
 1109: 
 1110:   return CMD_SUCCESS;
 1111: }
 1112: 
 1113: DEFUN (bandwidth_if,
 1114:        bandwidth_if_cmd,
 1115:        "bandwidth <1-10000000>",
 1116:        "Set bandwidth informational parameter\n"
 1117:        "Bandwidth in kilobits\n")
 1118: {
 1119:   struct interface *ifp;   
 1120:   unsigned int bandwidth;
 1121:   
 1122:   ifp = (struct interface *) vty->index;
 1123:   bandwidth = strtol(argv[0], NULL, 10);
 1124: 
 1125:   /* bandwidth range is <1-10000000> */
 1126:   if (bandwidth < 1 || bandwidth > 10000000)
 1127:     {
 1128:       vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
 1129:       return CMD_WARNING;
 1130:     }
 1131:   
 1132:   ifp->bandwidth = bandwidth;
 1133: 
 1134:   /* force protocols to recalculate routes due to cost change */
 1135:   if (if_is_operative (ifp))
 1136:     zebra_interface_up_update (ifp);
 1137:   
 1138:   return CMD_SUCCESS;
 1139: }
 1140: 
 1141: DEFUN (no_bandwidth_if,
 1142:        no_bandwidth_if_cmd,
 1143:        "no bandwidth",
 1144:        NO_STR
 1145:        "Set bandwidth informational parameter\n")
 1146: {
 1147:   struct interface *ifp;   
 1148:   
 1149:   ifp = (struct interface *) vty->index;
 1150: 
 1151:   ifp->bandwidth = 0;
 1152:   
 1153:   /* force protocols to recalculate routes due to cost change */
 1154:   if (if_is_operative (ifp))
 1155:     zebra_interface_up_update (ifp);
 1156: 
 1157:   return CMD_SUCCESS;
 1158: }
 1159: 
 1160: ALIAS (no_bandwidth_if,
 1161:        no_bandwidth_if_val_cmd,
 1162:        "no bandwidth <1-10000000>",
 1163:        NO_STR
 1164:        "Set bandwidth informational parameter\n"
 1165:        "Bandwidth in kilobits\n")
 1166: 
 1167: static int
 1168: ip_address_install (struct vty *vty, struct interface *ifp,
 1169: 		    const char *addr_str, const char *peer_str,
 1170: 		    const char *label)
 1171: {
 1172:   struct prefix_ipv4 cp;
 1173:   struct connected *ifc;
 1174:   struct prefix_ipv4 *p;
 1175:   int ret;
 1176: 
 1177:   ret = str2prefix_ipv4 (addr_str, &cp);
 1178:   if (ret <= 0)
 1179:     {
 1180:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
 1181:       return CMD_WARNING;
 1182:     }
 1183: 
 1184:   ifc = connected_check (ifp, (struct prefix *) &cp);
 1185:   if (! ifc)
 1186:     {
 1187:       ifc = connected_new ();
 1188:       ifc->ifp = ifp;
 1189: 
 1190:       /* Address. */
 1191:       p = prefix_ipv4_new ();
 1192:       *p = cp;
 1193:       ifc->address = (struct prefix *) p;
 1194: 
 1195:       /* Broadcast. */
 1196:       if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
 1197: 	{
 1198: 	  p = prefix_ipv4_new ();
 1199: 	  *p = cp;
 1200: 	  p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
 1201: 	  ifc->destination = (struct prefix *) p;
 1202: 	}
 1203: 
 1204:       /* Label. */
 1205:       if (label)
 1206: 	ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
 1207: 
 1208:       /* Add to linked list. */
 1209:       listnode_add (ifp->connected, ifc);
 1210:     }
 1211: 
 1212:   /* This address is configured from zebra. */
 1213:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1214:     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
 1215: 
 1216:   /* In case of this route need to install kernel. */
 1217:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
 1218:       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1219:     {
 1220:       /* Some system need to up the interface to set IP address. */
 1221:       if (! if_is_up (ifp))
 1222: 	{
 1223: 	  if_set_flags (ifp, IFF_UP | IFF_RUNNING);
 1224: 	  if_refresh (ifp);
 1225: 	}
 1226: 
 1227:       ret = if_set_prefix (ifp, ifc);
 1228:       if (ret < 0)
 1229: 	{
 1230: 	  vty_out (vty, "%% Can't set interface IP address: %s.%s", 
 1231: 		   safe_strerror(errno), VTY_NEWLINE);
 1232: 	  return CMD_WARNING;
 1233: 	}
 1234: 
 1235:       /* Add to subnet chain list (while marking secondary attribute). */
 1236:       if_subnet_add (ifp, ifc);
 1237: 
 1238:       /* IP address propery set. */
 1239:       SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
 1240: 
 1241:       /* Update interface address information to protocol daemon. */
 1242:       zebra_interface_address_add_update (ifp, ifc);
 1243: 
 1244:       /* If interface is up register connected route. */
 1245:       if (if_is_operative(ifp))
 1246: 	connected_up_ipv4 (ifp, ifc);
 1247:     }
 1248: 
 1249:   return CMD_SUCCESS;
 1250: }
 1251: 
 1252: static int
 1253: ip_address_uninstall (struct vty *vty, struct interface *ifp,
 1254: 		      const char *addr_str, const char *peer_str,
 1255: 		      const char *label)
 1256: {
 1257:   struct prefix_ipv4 cp;
 1258:   struct connected *ifc;
 1259:   int ret;
 1260: 
 1261:   /* Convert to prefix structure. */
 1262:   ret = str2prefix_ipv4 (addr_str, &cp);
 1263:   if (ret <= 0)
 1264:     {
 1265:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
 1266:       return CMD_WARNING;
 1267:     }
 1268: 
 1269:   /* Check current interface address. */
 1270:   ifc = connected_check (ifp, (struct prefix *) &cp);
 1271:   if (! ifc)
 1272:     {
 1273:       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
 1274:       return CMD_WARNING;
 1275:     }
 1276: 
 1277:   /* This is not configured address. */
 1278:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1279:     return CMD_WARNING;
 1280: 
 1281:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
 1282:   
 1283:   /* This is not real address or interface is not active. */
 1284:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
 1285:       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1286:     {
 1287:       listnode_delete (ifp->connected, ifc);
 1288:       connected_free (ifc);
 1289:       return CMD_WARNING;
 1290:     }
 1291: 
 1292:   /* This is real route. */
 1293:   ret = if_unset_prefix (ifp, ifc);
 1294:   if (ret < 0)
 1295:     {
 1296:       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
 1297: 	       safe_strerror(errno), VTY_NEWLINE);
 1298:       return CMD_WARNING;
 1299:     }
 1300:   /* success! call returned that the address deletion went through.
 1301:    * this is a synchronous operation, so we know it succeeded and can
 1302:    * now update all internal state. */
 1303: 
 1304:   /* the HAVE_NETLINK check is only here because, on BSD, although the
 1305:    * call above is still synchronous, we get a second confirmation later
 1306:    * through the route socket, and we don't want to touch that behaviour
 1307:    * for now.  It should work without the #ifdef, but why take the risk...
 1308:    * -- equinox 2012-07-13 */
 1309: #ifdef HAVE_NETLINK
 1310: 
 1311:   /* Remove connected route. */
 1312:   connected_down_ipv4 (ifp, ifc);
 1313: 
 1314:   /* Redistribute this information. */
 1315:   zebra_interface_address_delete_update (ifp, ifc);
 1316: 
 1317:   /* IP address propery set. */
 1318:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
 1319: 
 1320:   /* remove from interface, remark secondaries */
 1321:   if_subnet_delete (ifp, ifc);
 1322: 
 1323:   /* Free address information. */
 1324:   listnode_delete (ifp->connected, ifc);
 1325:   connected_free (ifc);
 1326: #endif
 1327: 
 1328:   return CMD_SUCCESS;
 1329: }
 1330: 
 1331: DEFUN (ip_address,
 1332:        ip_address_cmd,
 1333:        "ip address A.B.C.D/M",
 1334:        "Interface Internet Protocol config commands\n"
 1335:        "Set the IP address of an interface\n"
 1336:        "IP address (e.g. 10.0.0.1/8)\n")
 1337: {
 1338:   return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
 1339: }
 1340: 
 1341: DEFUN (no_ip_address,
 1342:        no_ip_address_cmd,
 1343:        "no ip address A.B.C.D/M",
 1344:        NO_STR
 1345:        "Interface Internet Protocol config commands\n"
 1346:        "Set the IP address of an interface\n"
 1347:        "IP Address (e.g. 10.0.0.1/8)")
 1348: {
 1349:   return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
 1350: }
 1351: 
 1352: #ifdef HAVE_NETLINK
 1353: DEFUN (ip_address_label,
 1354:        ip_address_label_cmd,
 1355:        "ip address A.B.C.D/M label LINE",
 1356:        "Interface Internet Protocol config commands\n"
 1357:        "Set the IP address of an interface\n"
 1358:        "IP address (e.g. 10.0.0.1/8)\n"
 1359:        "Label of this address\n"
 1360:        "Label\n")
 1361: {
 1362:   return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
 1363: }
 1364: 
 1365: DEFUN (no_ip_address_label,
 1366:        no_ip_address_label_cmd,
 1367:        "no ip address A.B.C.D/M label LINE",
 1368:        NO_STR
 1369:        "Interface Internet Protocol config commands\n"
 1370:        "Set the IP address of an interface\n"
 1371:        "IP address (e.g. 10.0.0.1/8)\n"
 1372:        "Label of this address\n"
 1373:        "Label\n")
 1374: {
 1375:   return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
 1376: }
 1377: #endif /* HAVE_NETLINK */
 1378: 
 1379: #ifdef HAVE_IPV6
 1380: static int
 1381: ipv6_address_install (struct vty *vty, struct interface *ifp,
 1382: 		      const char *addr_str, const char *peer_str,
 1383: 		      const char *label, int secondary)
 1384: {
 1385:   struct prefix_ipv6 cp;
 1386:   struct connected *ifc;
 1387:   struct prefix_ipv6 *p;
 1388:   int ret;
 1389: 
 1390:   ret = str2prefix_ipv6 (addr_str, &cp);
 1391:   if (ret <= 0)
 1392:     {
 1393:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
 1394:       return CMD_WARNING;
 1395:     }
 1396: 
 1397:   ifc = connected_check (ifp, (struct prefix *) &cp);
 1398:   if (! ifc)
 1399:     {
 1400:       ifc = connected_new ();
 1401:       ifc->ifp = ifp;
 1402: 
 1403:       /* Address. */
 1404:       p = prefix_ipv6_new ();
 1405:       *p = cp;
 1406:       ifc->address = (struct prefix *) p;
 1407: 
 1408:       /* Secondary. */
 1409:       if (secondary)
 1410: 	SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
 1411: 
 1412:       /* Label. */
 1413:       if (label)
 1414: 	ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
 1415: 
 1416:       /* Add to linked list. */
 1417:       listnode_add (ifp->connected, ifc);
 1418:     }
 1419: 
 1420:   /* This address is configured from zebra. */
 1421:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1422:     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
 1423: 
 1424:   /* In case of this route need to install kernel. */
 1425:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
 1426:       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1427:     {
 1428:       /* Some system need to up the interface to set IP address. */
 1429:       if (! if_is_up (ifp))
 1430: 	{
 1431: 	  if_set_flags (ifp, IFF_UP | IFF_RUNNING);
 1432: 	  if_refresh (ifp);
 1433: 	}
 1434: 
 1435:       ret = if_prefix_add_ipv6 (ifp, ifc);
 1436: 
 1437:       if (ret < 0)
 1438: 	{
 1439: 	  vty_out (vty, "%% Can't set interface IP address: %s.%s", 
 1440: 		   safe_strerror(errno), VTY_NEWLINE);
 1441: 	  return CMD_WARNING;
 1442: 	}
 1443: 
 1444:       /* IP address propery set. */
 1445:       SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
 1446: 
 1447:       /* Update interface address information to protocol daemon. */
 1448:       zebra_interface_address_add_update (ifp, ifc);
 1449: 
 1450:       /* If interface is up register connected route. */
 1451:       if (if_is_operative(ifp))
 1452: 	connected_up_ipv6 (ifp, ifc);
 1453:     }
 1454: 
 1455:   return CMD_SUCCESS;
 1456: }
 1457: 
 1458: static int
 1459: ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
 1460: 			const char *addr_str, const char *peer_str,
 1461: 			const char *label, int secondry)
 1462: {
 1463:   struct prefix_ipv6 cp;
 1464:   struct connected *ifc;
 1465:   int ret;
 1466: 
 1467:   /* Convert to prefix structure. */
 1468:   ret = str2prefix_ipv6 (addr_str, &cp);
 1469:   if (ret <= 0)
 1470:     {
 1471:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
 1472:       return CMD_WARNING;
 1473:     }
 1474: 
 1475:   /* Check current interface address. */
 1476:   ifc = connected_check (ifp, (struct prefix *) &cp);
 1477:   if (! ifc)
 1478:     {
 1479:       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
 1480:       return CMD_WARNING;
 1481:     }
 1482: 
 1483:   /* This is not configured address. */
 1484:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1485:     return CMD_WARNING;
 1486: 
 1487:   /* This is not real address or interface is not active. */
 1488:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
 1489:       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1490:     {
 1491:       listnode_delete (ifp->connected, ifc);
 1492:       connected_free (ifc);
 1493:       return CMD_WARNING;
 1494:     }
 1495: 
 1496:   /* This is real route. */
 1497:   ret = if_prefix_delete_ipv6 (ifp, ifc);
 1498:   if (ret < 0)
 1499:     {
 1500:       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
 1501: 	       safe_strerror(errno), VTY_NEWLINE);
 1502:       return CMD_WARNING;
 1503:     }
 1504: 
 1505:   /* Redistribute this information. */
 1506:   zebra_interface_address_delete_update (ifp, ifc);
 1507: 
 1508:   /* Remove connected route. */
 1509:   connected_down_ipv6 (ifp, ifc);
 1510: 
 1511:   /* Free address information. */
 1512:   listnode_delete (ifp->connected, ifc);
 1513:   connected_free (ifc);
 1514: 
 1515:   return CMD_SUCCESS;
 1516: }
 1517: 
 1518: DEFUN (ipv6_address,
 1519:        ipv6_address_cmd,
 1520:        "ipv6 address X:X::X:X/M",
 1521:        "Interface IPv6 config commands\n"
 1522:        "Set the IP address of an interface\n"
 1523:        "IPv6 address (e.g. 3ffe:506::1/48)\n")
 1524: {
 1525:   return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
 1526: }
 1527: 
 1528: DEFUN (no_ipv6_address,
 1529:        no_ipv6_address_cmd,
 1530:        "no ipv6 address X:X::X:X/M",
 1531:        NO_STR
 1532:        "Interface IPv6 config commands\n"
 1533:        "Set the IP address of an interface\n"
 1534:        "IPv6 address (e.g. 3ffe:506::1/48)\n")
 1535: {
 1536:   return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
 1537: }
 1538: #endif /* HAVE_IPV6 */
 1539: 
 1540: static int
 1541: if_config_write (struct vty *vty)
 1542: {
 1543:   struct listnode *node;
 1544:   struct interface *ifp;
 1545: 
 1546:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
 1547:     {
 1548:       struct zebra_if *if_data;
 1549:       struct listnode *addrnode;
 1550:       struct connected *ifc;
 1551:       struct prefix *p;
 1552: 
 1553:       if_data = ifp->info;
 1554:       
 1555:       vty_out (vty, "interface %s%s", ifp->name,
 1556: 	       VTY_NEWLINE);
 1557: 
 1558:       if (ifp->desc)
 1559: 	vty_out (vty, " description %s%s", ifp->desc,
 1560: 		 VTY_NEWLINE);
 1561: 
 1562:       /* Assign bandwidth here to avoid unnecessary interface flap
 1563: 	 while processing config script */
 1564:       if (ifp->bandwidth != 0)
 1565: 	vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE); 
 1566: 
 1567:       if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
 1568: 	vty_out(vty, " link-detect%s", VTY_NEWLINE);
 1569: 
 1570:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
 1571: 	  {
 1572: 	    if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
 1573: 	      {
 1574: 		char buf[INET6_ADDRSTRLEN];
 1575: 		p = ifc->address;
 1576: 		vty_out (vty, " ip%s address %s/%d",
 1577: 			 p->family == AF_INET ? "" : "v6",
 1578: 			 inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
 1579: 			 p->prefixlen);
 1580: 
 1581: 		if (ifc->label)
 1582: 		  vty_out (vty, " label %s", ifc->label);
 1583: 
 1584: 		vty_out (vty, "%s", VTY_NEWLINE);
 1585: 	      }
 1586: 	  }
 1587: 
 1588:       if (if_data)
 1589: 	{
 1590: 	  if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
 1591: 	    vty_out (vty, " shutdown%s", VTY_NEWLINE);
 1592: 
 1593: 	  if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
 1594: 	    vty_out (vty, " %smulticast%s",
 1595: 		     if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
 1596: 		     VTY_NEWLINE);
 1597: 	}
 1598: 
 1599: #ifdef RTADV
 1600:       rtadv_config_write (vty, ifp);
 1601: #endif /* RTADV */
 1602: 
 1603: #ifdef HAVE_IRDP
 1604:       irdp_config_write (vty, ifp);
 1605: #endif /* IRDP */
 1606: 
 1607:       vty_out (vty, "!%s", VTY_NEWLINE);
 1608:     }
 1609:   return 0;
 1610: }
 1611: 
 1612: /* Allocate and initialize interface vector. */
 1613: void
 1614: zebra_if_init (void)
 1615: {
 1616:   /* Initialize interface and new hook. */
 1617:   if_init ();
 1618:   if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
 1619:   if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
 1620:   
 1621:   /* Install configuration write function. */
 1622:   install_node (&interface_node, if_config_write);
 1623: 
 1624:   install_element (VIEW_NODE, &show_interface_cmd);
 1625:   install_element (ENABLE_NODE, &show_interface_cmd);
 1626:   install_element (ENABLE_NODE, &show_interface_desc_cmd);
 1627:   install_element (CONFIG_NODE, &zebra_interface_cmd);
 1628:   install_element (CONFIG_NODE, &no_interface_cmd);
 1629:   install_default (INTERFACE_NODE);
 1630:   install_element (INTERFACE_NODE, &interface_desc_cmd);
 1631:   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
 1632:   install_element (INTERFACE_NODE, &multicast_cmd);
 1633:   install_element (INTERFACE_NODE, &no_multicast_cmd);
 1634:   install_element (INTERFACE_NODE, &linkdetect_cmd);
 1635:   install_element (INTERFACE_NODE, &no_linkdetect_cmd);
 1636:   install_element (INTERFACE_NODE, &shutdown_if_cmd);
 1637:   install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
 1638:   install_element (INTERFACE_NODE, &bandwidth_if_cmd);
 1639:   install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
 1640:   install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
 1641:   install_element (INTERFACE_NODE, &ip_address_cmd);
 1642:   install_element (INTERFACE_NODE, &no_ip_address_cmd);
 1643: #ifdef HAVE_IPV6
 1644:   install_element (INTERFACE_NODE, &ipv6_address_cmd);
 1645:   install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
 1646: #endif /* HAVE_IPV6 */
 1647: #ifdef HAVE_NETLINK
 1648:   install_element (INTERFACE_NODE, &ip_address_label_cmd);
 1649:   install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
 1650: #endif /* HAVE_NETLINK */
 1651: }

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