LCOV - code coverage report
Current view: top level - zebra - interface.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 234 610 38.4 %
Date: 2015-11-19 Functions: 18 39 46.2 %

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

Generated by: LCOV version 1.10