interface.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:34k
源码类别:

网络

开发平台:

Unix_Linux

  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. #include <zebra.h>
  23. #include "if.h"
  24. #include "vty.h"
  25. #include "sockunion.h"
  26. #include "prefix.h"
  27. #include "command.h"
  28. #include "memory.h"
  29. #include "ioctl.h"
  30. #include "connected.h"
  31. #include "log.h"
  32. #include "zclient.h"
  33. #include "zebra/interface.h"
  34. #include "zebra/rtadv.h"
  35. #include "zebra/rib.h"
  36. #include "zebra/zserv.h"
  37. #include "zebra/redistribute.h"
  38. #include "zebra/debug.h"
  39. /* Allocate a new internal interface index 
  40.  * This works done from the top so that %d macros
  41.  * print a - sign! 
  42.  */
  43. static unsigned int
  44. if_new_intern_ifindex (void)
  45. {
  46.   /* Start here so that first one assigned is 0xFFFFFFFF */
  47.   static unsigned int ifindex = IFINDEX_INTERNBASE + 1;
  48.   for (;;) 
  49.     {
  50.       ifindex--;
  51.       if ( ifindex <= IFINDEX_INTERNBASE )
  52.        ifindex = 0xFFFFFFFF;
  53.       if (if_lookup_by_index(ifindex) == NULL)
  54.        return ifindex;
  55.     }
  56. }
  57. /* Called when new interface is added. */
  58. int
  59. if_zebra_new_hook (struct interface *ifp)
  60. {
  61.   struct zebra_if *zebra_if;
  62.   zebra_if = XMALLOC (MTYPE_TMP, sizeof (struct zebra_if));
  63.   memset (zebra_if, 0, sizeof (struct zebra_if));
  64.   zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
  65.   zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_UNSPEC;
  66. #ifdef RTADV
  67.   {
  68.     /* Set default router advertise values. */
  69.     struct rtadvconf *rtadv;
  70.     rtadv = &zebra_if->rtadv;
  71.     rtadv->AdvSendAdvertisements = 0;
  72.     rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
  73.     rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
  74.     rtadv->AdvIntervalTimer = 0;
  75.     rtadv->AdvManagedFlag = 0;
  76.     rtadv->AdvOtherConfigFlag = 0;
  77.     rtadv->AdvLinkMTU = 0;
  78.     rtadv->AdvReachableTime = 0;
  79.     rtadv->AdvRetransTimer = 0;
  80.     rtadv->AdvCurHopLimit = 0;
  81.     rtadv->AdvDefaultLifetime = RTADV_ADV_DEFAULT_LIFETIME;
  82.     rtadv->AdvPrefixList = list_new ();
  83.   }    
  84. #endif /* RTADV */
  85.   ifp->info = zebra_if;
  86.   return 0;
  87. }
  88. /* Called when interface is deleted. */
  89. int
  90. if_zebra_delete_hook (struct interface *ifp)
  91. {
  92.   if (ifp->info)
  93.     XFREE (MTYPE_TMP, ifp->info);
  94.   return 0;
  95. }
  96. /* Wake up configured address if it is not in current kernel
  97.    address. */
  98. void
  99. if_addr_wakeup (struct interface *ifp)
  100. {
  101.   struct listnode *node;
  102.   struct connected *ifc;
  103.   struct prefix *p;
  104.   int ret;
  105.   for (node = listhead (ifp->connected); node; nextnode (node))
  106.     {
  107.       ifc = getdata (node);
  108.       p = ifc->address;
  109.       if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
  110.   && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
  111. {
  112.   /* Address check. */
  113.   if (p->family == AF_INET)
  114.     {
  115.       if (! if_is_up (ifp))
  116. {
  117.   if_set_flags (ifp, IFF_UP | IFF_RUNNING);
  118.   if_refresh (ifp);
  119. }
  120.       ret = if_set_prefix (ifp, ifc);
  121.       if (ret < 0)
  122. {
  123.   zlog_warn ("Can't set interface's address: %s", 
  124.      strerror(errno));
  125.   continue;
  126. }
  127.       SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  128.       zebra_interface_address_add_update (ifp, ifc);
  129.       if (if_is_up(ifp))
  130. connected_up_ipv4 (ifp, ifc);
  131.     }
  132. #ifdef HAVE_IPV6
  133.   if (p->family == AF_INET6)
  134.     {
  135.       if (! if_is_up (ifp))
  136. {
  137.   if_set_flags (ifp, IFF_UP | IFF_RUNNING);
  138.   if_refresh (ifp);
  139. }
  140.       ret = if_prefix_add_ipv6 (ifp, ifc);
  141.       if (ret < 0)
  142. {
  143.   zlog_warn ("Can't set interface's address: %s", 
  144.      strerror(errno));
  145.   continue;
  146. }
  147.       SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  148.       zebra_interface_address_add_update (ifp, ifc);
  149.       if (if_is_up(ifp))
  150. connected_up_ipv6 (ifp, ifc);
  151.     }
  152. #endif /* HAVE_IPV6 */
  153. }
  154.     }
  155. }
  156. /* Handle interface addition */
  157. void
  158. if_add_update (struct interface *ifp)
  159. {
  160.   zebra_interface_add_update (ifp);
  161.   if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  162.     {
  163.       SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
  164.       if_addr_wakeup (ifp);
  165.       if (IS_ZEBRA_DEBUG_KERNEL)
  166. zlog_info ("interface %s index %d becomes active.", 
  167.    ifp->name, ifp->ifindex);
  168.     }
  169.   else
  170.     {
  171.       if (IS_ZEBRA_DEBUG_KERNEL)
  172. zlog_info ("interface %s index %d is added.", ifp->name, ifp->ifindex);
  173.     }
  174. }
  175. /* Handle an interface delete event */
  176. void 
  177. if_delete_update (struct interface *ifp)
  178. {
  179.   struct listnode *node;
  180.   struct listnode *next;
  181.   struct connected *ifc;
  182.   struct prefix *p;
  183.   if (if_is_up(ifp))
  184.     {
  185.       zlog_err ("interface %s index %d is still up while being deleted.",
  186.     ifp->name, ifp->ifindex);
  187.       return;
  188.     }
  189.   /* Mark interface as inactive */
  190.   UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
  191.   
  192.   if (IS_ZEBRA_DEBUG_KERNEL)
  193.     zlog_info ("interface %s index %d is now inactive.",
  194.        ifp->name, ifp->ifindex);
  195.   /* Delete connected routes from the kernel. */
  196.   if (ifp->connected)
  197.     {
  198.       for (node = listhead (ifp->connected); node; node = next)
  199. {
  200.   next = node->next;
  201.   ifc = getdata (node);
  202.   p = ifc->address;
  203.   if (p->family == AF_INET)
  204.     connected_down_ipv4 (ifp, ifc);
  205. #ifdef HAVE_IPV6
  206.   else if (p->family == AF_INET6)
  207.     connected_down_ipv6 (ifp, ifc);
  208. #endif /* HAVE_IPV6 */
  209.   zebra_interface_address_delete_update (ifp, ifc);
  210.   UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  211.   
  212.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  213.     {      
  214.       listnode_delete (ifp->connected, ifc);
  215.       connected_free (ifc);
  216.     }
  217. }
  218.     }
  219.   zebra_interface_delete_update (ifp);
  220. }
  221. /* Interface is up. */
  222. void
  223. if_up (struct interface *ifp)
  224. {
  225.   listnode node;
  226.   listnode next;
  227.   struct connected *ifc;
  228.   struct prefix *p;
  229.   /* Notify the protocol daemons. */
  230.   zebra_interface_up_update (ifp);
  231.   /* Install connected routes to the kernel. */
  232.   if (ifp->connected)
  233.     {
  234.       for (node = listhead (ifp->connected); node; node = next)
  235. {
  236.   next = node->next;
  237.   ifc = getdata (node);
  238.   p = ifc->address;
  239.   if (p->family == AF_INET)
  240.     connected_up_ipv4 (ifp, ifc);
  241. #ifdef HAVE_IPV6
  242.   else if (p->family == AF_INET6)
  243.     connected_up_ipv6 (ifp, ifc);
  244. #endif /* HAVE_IPV6 */
  245. }
  246.     }
  247.   /* Examine all static routes. */
  248.   rib_update ();
  249. }
  250. /* Interface goes down.  We have to manage different behavior of based
  251.    OS. */
  252. void
  253. if_down (struct interface *ifp)
  254. {
  255.   listnode node;
  256.   listnode next;
  257.   struct connected *ifc;
  258.   struct prefix *p;
  259.   /* Notify to the protocol daemons. */
  260.   zebra_interface_down_update (ifp);
  261.   /* Delete connected routes from the kernel. */
  262.   if (ifp->connected)
  263.     {
  264.       for (node = listhead (ifp->connected); node; node = next)
  265. {
  266.   next = node->next;
  267.   ifc = getdata (node);
  268.   p = ifc->address;
  269.   if (p->family == AF_INET)
  270.     connected_down_ipv4 (ifp, ifc);
  271. #ifdef HAVE_IPV6
  272.   else if (p->family == AF_INET6)
  273.     connected_down_ipv6 (ifp, ifc);
  274. #endif /* HAVE_IPV6 */
  275. }
  276.     }
  277.   /* Examine all static routes which direct to the interface. */
  278.   rib_update ();
  279. }
  280. void
  281. if_refresh (struct interface *ifp)
  282. {
  283.   if (if_is_up (ifp))
  284.     {
  285.       if_get_flags (ifp);
  286.       if (! if_is_up (ifp))
  287. if_down (ifp);
  288.     }
  289.   else
  290.     {
  291.       if_get_flags (ifp);
  292.       if (if_is_up (ifp))
  293. if_up (ifp);
  294.     }
  295. }
  296. /* Printout flag information into vty */
  297. void
  298. if_flag_dump_vty (struct vty *vty, unsigned long flag)
  299. {
  300.   int separator = 0;
  301. #define IFF_OUT_VTY(X, Y) 
  302.   if ((X) && (flag & (X))) 
  303.     { 
  304.       if (separator) 
  305. vty_out (vty, ","); 
  306.       else 
  307. separator = 1; 
  308.       vty_out (vty, Y); 
  309.     }
  310.   vty_out (vty, "<");
  311.   IFF_OUT_VTY (IFF_UP, "UP");
  312.   IFF_OUT_VTY (IFF_BROADCAST, "BROADCAST");
  313.   IFF_OUT_VTY (IFF_DEBUG, "DEBUG");
  314.   IFF_OUT_VTY (IFF_LOOPBACK, "LOOPBACK");
  315.   IFF_OUT_VTY (IFF_POINTOPOINT, "POINTOPOINT");
  316.   IFF_OUT_VTY (IFF_NOTRAILERS, "NOTRAILERS");
  317.   IFF_OUT_VTY (IFF_RUNNING, "RUNNING");
  318.   IFF_OUT_VTY (IFF_NOARP, "NOARP");
  319.   IFF_OUT_VTY (IFF_PROMISC, "PROMISC");
  320.   IFF_OUT_VTY (IFF_ALLMULTI, "ALLMULTI");
  321.   IFF_OUT_VTY (IFF_OACTIVE, "OACTIVE");
  322.   IFF_OUT_VTY (IFF_SIMPLEX, "SIMPLEX");
  323.   IFF_OUT_VTY (IFF_LINK0, "LINK0");
  324.   IFF_OUT_VTY (IFF_LINK1, "LINK1");
  325.   IFF_OUT_VTY (IFF_LINK2, "LINK2");
  326.   IFF_OUT_VTY (IFF_MULTICAST, "MULTICAST");
  327.   vty_out (vty, ">");
  328. }
  329. /* Output prefix string to vty. */
  330. int
  331. prefix_vty_out (struct vty *vty, struct prefix *p)
  332. {
  333.   char str[INET6_ADDRSTRLEN];
  334.   inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
  335.   vty_out (vty, "%s", str);
  336.   return strlen (str);
  337. }
  338. /* Dump if address information to vty. */
  339. void
  340. connected_dump_vty (struct vty *vty, struct connected *connected)
  341. {
  342.   struct prefix *p;
  343.   struct interface *ifp;
  344.   /* Set interface pointer. */
  345.   ifp = connected->ifp;
  346.   /* Print interface address. */
  347.   p = connected->address;
  348.   vty_out (vty, "  %s ", prefix_family_str (p));
  349.   prefix_vty_out (vty, p);
  350.   vty_out (vty, "/%d", p->prefixlen);
  351.   /* If there is destination address, print it. */
  352.   p = connected->destination;
  353.   if (p)
  354.     {
  355.       if (p->family == AF_INET)
  356. if (ifp->flags & IFF_BROADCAST)
  357.   {
  358.     vty_out (vty, " broadcast ");
  359.     prefix_vty_out (vty, p);
  360.   }
  361.       if (ifp->flags & IFF_POINTOPOINT)
  362. {
  363.   vty_out (vty, " pointopoint ");
  364.   prefix_vty_out (vty, p);
  365. }
  366.     }
  367.   if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
  368.     vty_out (vty, " secondary");
  369.   if (connected->label)
  370.     vty_out (vty, " %s", connected->label);
  371.   vty_out (vty, "%s", VTY_NEWLINE);
  372. }
  373. #ifdef RTADV
  374. /* Dump interface ND information to vty. */
  375. void
  376. nd_dump_vty (struct vty *vty, struct interface *ifp)
  377. {
  378.   struct zebra_if *zif;
  379.   struct rtadvconf *rtadv;
  380.   zif = (struct zebra_if *) ifp->info;
  381.   rtadv = &zif->rtadv;
  382.   if (rtadv->AdvSendAdvertisements)
  383.     {
  384.       vty_out (vty, "  ND advertised reachable time is %d milliseconds%s",
  385.        rtadv->AdvReachableTime, VTY_NEWLINE);
  386.       vty_out (vty, "  ND advertised retransmit interval is %d milliseconds%s",
  387.        rtadv->AdvRetransTimer, VTY_NEWLINE);
  388.       vty_out (vty, "  ND router advertisements are sent every %d seconds%s",
  389.        rtadv->MaxRtrAdvInterval, VTY_NEWLINE);
  390.       vty_out (vty, "  ND router advertisements live for %d seconds%s",
  391.        rtadv->AdvDefaultLifetime, VTY_NEWLINE);
  392.       if (rtadv->AdvManagedFlag)
  393. vty_out (vty, "  Hosts use DHCP to obtain routable addresses.%s",
  394.  VTY_NEWLINE);
  395.       else
  396. vty_out (vty, "  Hosts use stateless autoconfig for addresses.%s",
  397.  VTY_NEWLINE);
  398.     }
  399. }
  400. #endif /* RTADV */
  401. /* Interface's information print out to vty interface. */
  402. void
  403. if_dump_vty (struct vty *vty, struct interface *ifp)
  404. {
  405. #ifdef HAVE_SOCKADDR_DL
  406.   struct sockaddr_dl *sdl;
  407. #endif /* HAVE_SOCKADDR_DL */
  408.   struct connected *connected;
  409.   listnode node;
  410.   vty_out (vty, "Interface %s%s", ifp->name,
  411.    VTY_NEWLINE);
  412.   if (ifp->desc)
  413.     vty_out (vty, "  Description: %s%s", ifp->desc,
  414.      VTY_NEWLINE);
  415.   if (ifp->ifindex <= 0)
  416.     {
  417.       vty_out(vty, "  index %d pseudo interface%s", ifp->ifindex, VTY_NEWLINE);
  418.       return;
  419.     }
  420.   else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  421.     {
  422.       vty_out(vty, "  index %d inactive interface%s", 
  423.       ifp->ifindex, 
  424.       VTY_NEWLINE);
  425.       return;
  426.     }
  427.   vty_out (vty, "  index %d metric %d mtu %d ",
  428.    ifp->ifindex, ifp->metric, ifp->mtu);
  429.   if_flag_dump_vty (vty, ifp->flags);
  430.   vty_out (vty, "%s", VTY_NEWLINE);
  431.   /* Hardware address. */
  432. #ifdef HAVE_SOCKADDR_DL
  433.   sdl = &ifp->sdl;
  434.   if (sdl != NULL && sdl->sdl_alen != 0)
  435.     {
  436.       int i;
  437.       u_char *ptr;
  438.       vty_out (vty, "  HWaddr: ");
  439.       for (i = 0, ptr = LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
  440. vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
  441.       vty_out (vty, "%s", VTY_NEWLINE);
  442.     }
  443. #else
  444.   if (ifp->hw_addr_len != 0)
  445.     {
  446.       int i;
  447.       vty_out (vty, "  HWaddr: ");
  448.       for (i = 0; i < ifp->hw_addr_len; i++)
  449. vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
  450.       vty_out (vty, "%s", VTY_NEWLINE);
  451.     }
  452. #endif /* HAVE_SOCKADDR_DL */
  453.   
  454.   /* Bandwidth in kbps */
  455.   if (ifp->bandwidth != 0)
  456.     {
  457.       vty_out(vty, "  bandwidth %u kbps", ifp->bandwidth);
  458.       vty_out(vty, "%s", VTY_NEWLINE);
  459.     }
  460.   for (node = listhead (ifp->connected); node; nextnode (node))
  461.     {
  462.       connected = getdata (node);
  463.       if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL))
  464. connected_dump_vty (vty, connected);
  465.     }
  466. #ifdef RTADV
  467.   nd_dump_vty (vty, ifp);
  468. #endif /* RTADV */
  469. #ifdef HAVE_PROC_NET_DEV
  470.   /* Statistics print out using proc file system. */
  471.   vty_out (vty, "    input packets %lu, bytes %lu, dropped %lu,"
  472.    " multicast packets %lu%s",
  473.    ifp->stats.rx_packets, ifp->stats.rx_bytes, 
  474.    ifp->stats.rx_dropped, ifp->stats.rx_multicast, VTY_NEWLINE);
  475.   vty_out (vty, "    input errors %lu, length %lu, overrun %lu,"
  476.    " CRC %lu, frame %lu, fifo %lu, missed %lu%s",
  477.    ifp->stats.rx_errors, ifp->stats.rx_length_errors,
  478.    ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
  479.    ifp->stats.rx_frame_errors, ifp->stats.rx_fifo_errors,
  480.    ifp->stats.rx_missed_errors, VTY_NEWLINE);
  481.   vty_out (vty, "    output packets %lu, bytes %lu, dropped %lu%s",
  482.    ifp->stats.tx_packets, ifp->stats.tx_bytes,
  483.    ifp->stats.tx_dropped, VTY_NEWLINE);
  484.   vty_out (vty, "    output errors %lu, aborted %lu, carrier %lu,"
  485.    " fifo %lu, heartbeat %lu, window %lu%s",
  486.    ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
  487.    ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
  488.    ifp->stats.tx_heartbeat_errors, ifp->stats.tx_window_errors,
  489.    VTY_NEWLINE);
  490.   vty_out (vty, "    collisions %lu%s", ifp->stats.collisions, VTY_NEWLINE);
  491. #endif /* HAVE_PROC_NET_DEV */
  492. #ifdef HAVE_NET_RT_IFLIST
  493. #if defined (__bsdi__) || defined (__NetBSD__)
  494.   /* Statistics print out using sysctl (). */
  495.   vty_out (vty, "    input packets %qu, bytes %qu, dropped %qu,"
  496.    " multicast packets %qu%s",
  497.    ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
  498.    ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
  499.    VTY_NEWLINE);
  500.   vty_out (vty, "    input errors %qu%s",
  501.    ifp->stats.ifi_ierrors, VTY_NEWLINE);
  502.   vty_out (vty, "    output packets %qu, bytes %qu, multicast packets %qu%s",
  503.    ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
  504.    ifp->stats.ifi_omcasts, VTY_NEWLINE);
  505.   vty_out (vty, "    output errors %qu%s",
  506.    ifp->stats.ifi_oerrors, VTY_NEWLINE);
  507.   vty_out (vty, "    collisions %qu%s",
  508.    ifp->stats.ifi_collisions, VTY_NEWLINE);
  509. #else
  510.   /* Statistics print out using sysctl (). */
  511.   vty_out (vty, "    input packets %lu, bytes %lu, dropped %lu,"
  512.    " multicast packets %lu%s",
  513.    ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
  514.    ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
  515.    VTY_NEWLINE);
  516.   vty_out (vty, "    input errors %lu%s",
  517.    ifp->stats.ifi_ierrors, VTY_NEWLINE);
  518.   vty_out (vty, "    output packets %lu, bytes %lu, multicast packets %lu%s",
  519.    ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
  520.    ifp->stats.ifi_omcasts, VTY_NEWLINE);
  521.   vty_out (vty, "    output errors %lu%s",
  522.    ifp->stats.ifi_oerrors, VTY_NEWLINE);
  523.   vty_out (vty, "    collisions %lu%s",
  524.    ifp->stats.ifi_collisions, VTY_NEWLINE);
  525. #endif /* __bsdi__ || __NetBSD__ */
  526. #endif /* HAVE_NET_RT_IFLIST */
  527. }
  528. /* Check supported address family. */
  529. int
  530. if_supported_family (int family)
  531. {
  532.   if (family == AF_INET)
  533.     return 1;
  534. #ifdef HAVE_IPV6
  535.   if (family == AF_INET6)
  536.     return 1;
  537. #endif /* HAVE_IPV6 */
  538.   return 0;
  539. }
  540. /* Wrapper hook point for zebra daemon so that ifindex can be set 
  541.  * DEFUN macro not used as extract.pl HAS to ignore this
  542.  * See also interface_cmd in lib/if.c
  543.  */ 
  544. DEFUN_NOSH (zebra_interface,
  545.     zebra_interface_cmd,
  546.     "interface IFNAME",
  547.     "Select an interface to configuren"
  548.     "Interface's namen")
  549. {
  550.   int ret;
  551.   struct interface * ifp;
  552.   
  553.   /* Call lib interface() */
  554.   ret = interface_cmd.func (self, vty, argc, argv);
  555.   ifp = vty->index;  
  556.   /* Set ifindex 
  557.      this only happens if interface is NOT in kernel */
  558.   if (ifp->ifindex == 0)
  559.     {
  560.       ifp->ifindex = if_new_intern_ifindex ();
  561.       UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
  562.     }
  563.   return ret;
  564. }
  565. DEFUN (no_zebra_interface,
  566.        no_zebra_interface_cmd,
  567.        "no interface IFNAME",
  568.        "Delete a pseudo interface's configurationn"
  569.        "Interface's namen")
  570. {
  571.   struct interface *ifp;
  572.   
  573.   ifp = if_lookup_by_name(argv[0]);
  574.   
  575.   if (ifp == NULL) 
  576.     {
  577.       vty_out (vty, "Inteface %s does not exist%s", 
  578.               argv[0],
  579.               VTY_NEWLINE);
  580.       return CMD_WARNING;
  581.     }
  582.   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  583.     {
  584.       vty_out(vty, "Only inactive interfaces can be deleted%s", VTY_NEWLINE);
  585.       return CMD_WARNING;
  586.     }
  587.   /* Delete interface */
  588.   if_delete(ifp);
  589.   return CMD_SUCCESS;
  590. struct cmd_node interface_node =
  591. {
  592.   INTERFACE_NODE,
  593.   "%s(config-if)# ",
  594.   1
  595. };
  596. /* Show all or specified interface to vty. */
  597. DEFUN (show_interface, show_interface_cmd,
  598.        "show interface [IFNAME]",  
  599.        SHOW_STR
  600.        "Interface status and configurationn"
  601.        "Inteface namen")
  602. {
  603.   listnode node;
  604.   struct interface *ifp;
  605.   
  606. #ifdef HAVE_PROC_NET_DEV
  607.   /* If system has interface statistics via proc file system, update
  608.      statistics. */
  609.   ifstat_update_proc ();
  610. #endif /* HAVE_PROC_NET_DEV */
  611. #ifdef HAVE_NET_RT_IFLIST
  612.   ifstat_update_sysctl ();
  613. #endif /* HAVE_NET_RT_IFLIST */
  614.   /* Specified interface print. */
  615.   if (argc != 0)
  616.     {
  617.       ifp = if_lookup_by_name (argv[0]);
  618.       if (ifp == NULL) 
  619. {
  620.   vty_out (vty, "%% Can't find interface %s%s", argv[0],
  621.    VTY_NEWLINE);
  622.   return CMD_WARNING;
  623. }
  624.       if_dump_vty (vty, ifp);
  625.       return CMD_SUCCESS;
  626.     }
  627.   /* All interface print. */
  628.   for (node = listhead (iflist); node; nextnode (node))
  629.     if_dump_vty (vty, getdata (node));
  630.   return CMD_SUCCESS;
  631. }
  632. DEFUN (multicast,
  633.        multicast_cmd,
  634.        "multicast",
  635.        "Set multicast flag to interfacen")
  636. {
  637.   int ret;
  638.   struct interface *ifp;
  639.   struct zebra_if *if_data;
  640.   ifp = (struct interface *) vty->index;
  641.   ret = if_set_flags (ifp, IFF_MULTICAST);
  642.   if (ret < 0)
  643.     {
  644.       vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
  645.       return CMD_WARNING;
  646.     }
  647.   if_refresh (ifp);
  648.   if_data = ifp->info;
  649.   if_data->multicast = IF_ZEBRA_MULTICAST_ON;
  650.   
  651.   return CMD_SUCCESS;
  652. }
  653. DEFUN (no_multicast,
  654.        no_multicast_cmd,
  655.        "no multicast",
  656.        NO_STR
  657.        "Unset multicast flag to interfacen")
  658. {
  659.   int ret;
  660.   struct interface *ifp;
  661.   struct zebra_if *if_data;
  662.   ifp = (struct interface *) vty->index;
  663.   ret = if_unset_flags (ifp, IFF_MULTICAST);
  664.   if (ret < 0)
  665.     {
  666.       vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
  667.       return CMD_WARNING;
  668.     }
  669.   if_refresh (ifp);
  670.   if_data = ifp->info;
  671.   if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
  672.   return CMD_SUCCESS;
  673. }
  674. DEFUN (shutdown_if,
  675.        shutdown_if_cmd,
  676.        "shutdown",
  677.        "Shutdown the selected interfacen")
  678. {
  679.   int ret;
  680.   struct interface *ifp;
  681.   struct zebra_if *if_data;
  682.   ifp = (struct interface *) vty->index;
  683.   ret = if_unset_flags (ifp, IFF_UP);
  684.   if (ret < 0)
  685.     {
  686.       vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
  687.       return CMD_WARNING;
  688.     }
  689.   if_refresh (ifp);
  690.   if_data = ifp->info;
  691.   if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
  692.   return CMD_SUCCESS;
  693. }
  694. DEFUN (no_shutdown_if,
  695.        no_shutdown_if_cmd,
  696.        "no shutdown",
  697.        NO_STR
  698.        "Shutdown the selected interfacen")
  699. {
  700.   int ret;
  701.   struct interface *ifp;
  702.   struct zebra_if *if_data;
  703.   ifp = (struct interface *) vty->index;
  704.   ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
  705.   if (ret < 0)
  706.     {
  707.       vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
  708.       return CMD_WARNING;
  709.     }
  710.   if_refresh (ifp);
  711.   if_data = ifp->info;
  712.   if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
  713.   return CMD_SUCCESS;
  714. }
  715. DEFUN (bandwidth_if,
  716.        bandwidth_if_cmd,
  717.        "bandwidth <1-10000000>",
  718.        "Set bandwidth informational parametern"
  719.        "Bandwidth in kilobitsn")
  720. {
  721.   struct interface *ifp;   
  722.   unsigned int bandwidth;
  723.   
  724.   ifp = (struct interface *) vty->index;
  725.   bandwidth = strtol(argv[0], NULL, 10);
  726.   /* bandwidth range is <1-10000000> */
  727.   if (bandwidth < 1 || bandwidth > 10000000)
  728.     {
  729.       vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
  730.       return CMD_WARNING;
  731.     }
  732.   
  733.   ifp->bandwidth = bandwidth;
  734.   /* force protocols to recalculate routes due to cost change */
  735.   if (if_is_up (ifp))
  736.     zebra_interface_up_update (ifp);
  737.   
  738.   return CMD_SUCCESS;
  739. }
  740. DEFUN (no_bandwidth_if,
  741.        no_bandwidth_if_cmd,
  742.        "no bandwidth",
  743.        NO_STR
  744.        "Set bandwidth informational parametern")
  745. {
  746.   struct interface *ifp;   
  747.   
  748.   ifp = (struct interface *) vty->index;
  749.   ifp->bandwidth = 0;
  750.   
  751.   /* force protocols to recalculate routes due to cost change */
  752.   if (if_is_up (ifp))
  753.     zebra_interface_up_update (ifp);
  754.   return CMD_SUCCESS;
  755. }
  756. ALIAS (no_bandwidth_if,
  757.        no_bandwidth_if_val_cmd,
  758.        "no bandwidth <1-10000000>",
  759.        NO_STR
  760.        "Set bandwidth informational parametern"
  761.        "Bandwidth in kilobitsn");
  762. int
  763. ip_address_install (struct vty *vty, struct interface *ifp, char *addr_str,
  764.     char *peer_str, char *label, int secondary)
  765. {
  766.   struct prefix_ipv4 cp;
  767.   struct connected *ifc;
  768.   struct prefix_ipv4 *p;
  769.   struct in_addr mask;
  770.   int ret;
  771.   ret = str2prefix_ipv4 (addr_str, &cp);
  772.   if (ret <= 0)
  773.     {
  774.       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
  775.       return CMD_WARNING;
  776.     }
  777.   ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
  778.   if (! ifc)
  779.     {
  780.       ifc = connected_new ();
  781.       ifc->ifp = ifp;
  782.       /* Address. */
  783.       p = prefix_ipv4_new ();
  784.       *p = cp;
  785.       ifc->address = (struct prefix *) p;
  786.       /* Broadcast. */
  787.       if (p->prefixlen <= 30)
  788. {
  789.   p = prefix_ipv4_new ();
  790.   *p = cp;
  791.   masklen2ip (p->prefixlen, &mask);
  792.   p->prefix.s_addr |= ~mask.s_addr;
  793.   ifc->destination = (struct prefix *) p;
  794. }
  795.       /* Secondary. */
  796.       if (secondary)
  797. SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
  798.       /* Label. */
  799.       if (label)
  800. ifc->label = strdup (label);
  801.       /* Add to linked list. */
  802.       listnode_add (ifp->connected, ifc);
  803.     }
  804.   /* This address is configured from zebra. */
  805.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  806.     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
  807.   /* In case of this route need to install kernel. */
  808.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
  809.       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  810.     {
  811.       /* Some system need to up the interface to set IP address. */
  812.       if (! if_is_up (ifp))
  813. {
  814.   if_set_flags (ifp, IFF_UP | IFF_RUNNING);
  815.   if_refresh (ifp);
  816. }
  817.       ret = if_set_prefix (ifp, ifc);
  818.       if (ret < 0)
  819. {
  820.   vty_out (vty, "%% Can't set interface IP address: %s.%s", 
  821.    strerror(errno), VTY_NEWLINE);
  822.   return CMD_WARNING;
  823. }
  824.       /* IP address propery set. */
  825.       SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  826.       /* Update interface address information to protocol daemon. */
  827.       zebra_interface_address_add_update (ifp, ifc);
  828.       /* If interface is up register connected route. */
  829.       if (if_is_up(ifp))
  830. connected_up_ipv4 (ifp, ifc);
  831.     }
  832.   return CMD_SUCCESS;
  833. }
  834. int
  835. ip_address_uninstall (struct vty *vty, struct interface *ifp, char *addr_str,
  836.       char *peer_str, char *label, int secondry)
  837. {
  838.   struct prefix_ipv4 cp;
  839.   struct connected *ifc;
  840.   int ret;
  841.   /* Convert to prefix structure. */
  842.   ret = str2prefix_ipv4 (addr_str, &cp);
  843.   if (ret <= 0)
  844.     {
  845.       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
  846.       return CMD_WARNING;
  847.     }
  848.   /* Check current interface address. */
  849.   ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
  850.   if (! ifc)
  851.     {
  852.       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
  853.       return CMD_WARNING;
  854.     }
  855.   /* This is not configured address. */
  856.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  857.     return CMD_WARNING;
  858.   /* This is not real address or interface is not active. */
  859.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
  860.       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  861.     {
  862.       listnode_delete (ifp->connected, ifc);
  863.       connected_free (ifc);
  864.       return CMD_WARNING;
  865.     }
  866.   /* This is real route. */
  867.   ret = if_unset_prefix (ifp, ifc);
  868.   if (ret < 0)
  869.     {
  870.       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
  871.        strerror(errno), VTY_NEWLINE);
  872.       return CMD_WARNING;
  873.     }
  874.   /* Redistribute this information. */
  875.   zebra_interface_address_delete_update (ifp, ifc);
  876.   /* Remove connected route. */
  877.   connected_down_ipv4 (ifp, ifc);
  878.   /* Free address information. */
  879.   listnode_delete (ifp->connected, ifc);
  880.   connected_free (ifc);
  881.   return CMD_SUCCESS;
  882. }
  883. DEFUN (ip_address,
  884.        ip_address_cmd,
  885.        "ip address A.B.C.D/M",
  886.        "Interface Internet Protocol config commandsn"
  887.        "Set the IP address of an interfacen"
  888.        "IP address (e.g. 10.0.0.1/8)n")
  889. {
  890.   return ip_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
  891. }
  892. DEFUN (no_ip_address,
  893.        no_ip_address_cmd,
  894.        "no ip address A.B.C.D/M",
  895.        NO_STR
  896.        "Interface Internet Protocol config commandsn"
  897.        "Set the IP address of an interfacen"
  898.        "IP Address (e.g. 10.0.0.1/8)")
  899. {
  900.   return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
  901. }
  902. #ifdef HAVE_NETLINK
  903. DEFUN (ip_address_secondary,
  904.        ip_address_secondary_cmd,
  905.        "ip address A.B.C.D/M secondary",
  906.        "Interface Internet Protocol config commandsn"
  907.        "Set the IP address of an interfacen"
  908.        "IP address (e.g. 10.0.0.1/8)n"
  909.        "Secondary IP addressn")
  910. {
  911.   return ip_address_install (vty, vty->index, argv[0], NULL, NULL, 1);
  912. }
  913. DEFUN (ip_address_label,
  914.        ip_address_label_cmd,
  915.        "ip address A.B.C.D/M label LINE",
  916.        "Interface Internet Protocol config commandsn"
  917.        "Set the IP address of an interfacen"
  918.        "IP address (e.g. 10.0.0.1/8)n"
  919.        "Label of this addressn"
  920.        "Labeln")
  921. {
  922.   return ip_address_install (vty, vty->index, argv[0], NULL, argv[1], 1);
  923. }
  924. DEFUN (no_ip_address_secondary,
  925.        no_ip_address_secondary_cmd,
  926.        "no ip address A.B.C.D/M secondary",
  927.        NO_STR
  928.        "Interface Internet Protocol config commandsn"
  929.        "Set the IP address of an interfacen"
  930.        "IP address (e.g. 10.0.0.1/8)n"
  931.        "Secondary IP addressn")
  932. {
  933.   return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 1);
  934. }
  935. DEFUN (no_ip_address_label,
  936.        no_ip_address_label_cmd,
  937.        "no ip address A.B.C.D/M label LINE",
  938.        NO_STR
  939.        "Interface Internet Protocol config commandsn"
  940.        "Set the IP address of an interfacen"
  941.        "IP address (e.g. 10.0.0.1/8)n"
  942.        "Label of this addressn"
  943.        "Labeln")
  944. {
  945.   return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1], 1);
  946. }
  947. #endif /* HAVE_NETLINK */
  948. #ifdef HAVE_IPV6
  949. int
  950. ipv6_address_install (struct vty *vty, struct interface *ifp, char *addr_str,
  951.       char *peer_str, char *label, int secondary)
  952. {
  953.   struct prefix_ipv6 cp;
  954.   struct connected *ifc;
  955.   struct prefix_ipv6 *p;
  956.   int ret;
  957.   ret = str2prefix_ipv6 (addr_str, &cp);
  958.   if (ret <= 0)
  959.     {
  960.       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
  961.       return CMD_WARNING;
  962.     }
  963.   ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
  964.   if (! ifc)
  965.     {
  966.       ifc = connected_new ();
  967.       ifc->ifp = ifp;
  968.       /* Address. */
  969.       p = prefix_ipv6_new ();
  970.       *p = cp;
  971.       ifc->address = (struct prefix *) p;
  972.       /* Secondary. */
  973.       if (secondary)
  974. SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
  975.       /* Label. */
  976.       if (label)
  977. ifc->label = strdup (label);
  978.       /* Add to linked list. */
  979.       listnode_add (ifp->connected, ifc);
  980.     }
  981.   /* This address is configured from zebra. */
  982.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  983.     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
  984.   /* In case of this route need to install kernel. */
  985.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
  986.       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  987.     {
  988.       /* Some system need to up the interface to set IP address. */
  989.       if (! if_is_up (ifp))
  990. {
  991.   if_set_flags (ifp, IFF_UP | IFF_RUNNING);
  992.   if_refresh (ifp);
  993. }
  994.       ret = if_prefix_add_ipv6 (ifp, ifc);
  995.       if (ret < 0)
  996. {
  997.   vty_out (vty, "%% Can't set interface IP address: %s.%s", 
  998.    strerror(errno), VTY_NEWLINE);
  999.   return CMD_WARNING;
  1000. }
  1001.       /* IP address propery set. */
  1002.       SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
  1003.       /* Update interface address information to protocol daemon. */
  1004.       zebra_interface_address_add_update (ifp, ifc);
  1005.       /* If interface is up register connected route. */
  1006.       if (if_is_up(ifp))
  1007. connected_up_ipv6 (ifp, ifc);
  1008.     }
  1009.   return CMD_SUCCESS;
  1010. }
  1011. int
  1012. ipv6_address_uninstall (struct vty *vty, struct interface *ifp, char *addr_str,
  1013. char *peer_str, char *label, int secondry)
  1014. {
  1015.   struct prefix_ipv6 cp;
  1016.   struct connected *ifc;
  1017.   int ret;
  1018.   /* Convert to prefix structure. */
  1019.   ret = str2prefix_ipv6 (addr_str, &cp);
  1020.   if (ret <= 0)
  1021.     {
  1022.       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
  1023.       return CMD_WARNING;
  1024.     }
  1025.   /* Check current interface address. */
  1026.   ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
  1027.   if (! ifc)
  1028.     {
  1029.       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
  1030.       return CMD_WARNING;
  1031.     }
  1032.   /* This is not configured address. */
  1033.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  1034.     return CMD_WARNING;
  1035.   /* This is not real address or interface is not active. */
  1036.   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
  1037.       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  1038.     {
  1039.       listnode_delete (ifp->connected, ifc);
  1040.       connected_free (ifc);
  1041.       return CMD_WARNING;
  1042.     }
  1043.   /* This is real route. */
  1044.   ret = if_prefix_delete_ipv6 (ifp, ifc);
  1045.   if (ret < 0)
  1046.     {
  1047.       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
  1048.        strerror(errno), VTY_NEWLINE);
  1049.       return CMD_WARNING;
  1050.     }
  1051.   /* Redistribute this information. */
  1052.   zebra_interface_address_delete_update (ifp, ifc);
  1053.   /* Remove connected route. */
  1054.   connected_down_ipv6 (ifp, ifc);
  1055.   /* Free address information. */
  1056.   listnode_delete (ifp->connected, ifc);
  1057.   connected_free (ifc);
  1058.   return CMD_SUCCESS;
  1059. }
  1060. DEFUN (ipv6_address,
  1061.        ipv6_address_cmd,
  1062.        "ipv6 address X:X::X:X/M",
  1063.        "Interface Internet Protocol config commandsn"
  1064.        "Set the IP address of an interfacen"
  1065.        "IPv6 address (e.g. 3ffe:506::1/48)n")
  1066. {
  1067.   return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
  1068. }
  1069. DEFUN (no_ipv6_address,
  1070.        no_ipv6_address_cmd,
  1071.        "no ipv6 address X:X::X:X/M",
  1072.        NO_STR
  1073.        "Interface Internet Protocol config commandsn"
  1074.        "Set the IP address of an interfacen"
  1075.        "IPv6 address (e.g. 3ffe:506::1/48)n")
  1076. {
  1077.   return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
  1078. }
  1079. #endif /* HAVE_IPV6 */
  1080. #ifdef KAME
  1081. DEFUN (ip_tunnel,
  1082.        ip_tunnel_cmd,
  1083.        "ip tunnel IP_address IP_address",
  1084.        "KAME ip tunneling configuration commandsn"
  1085.        "Set FROM IP address and TO IP addressn")
  1086. {
  1087.   return CMD_SUCCESS;
  1088. }
  1089. DEFUN (no_ip_tunnel, no_ip_tunnel_cmd,
  1090.        "no ip tunnel",
  1091.        NO_STR
  1092.        "Set FROM IP address and TO IP addressn")
  1093. {
  1094.   return CMD_SUCCESS;
  1095. }
  1096. #endif /* KAME */
  1097. int
  1098. if_config_write (struct vty *vty)
  1099. {
  1100.   listnode node;
  1101.   struct interface *ifp;
  1102.   char buf[BUFSIZ];
  1103.   for (node = listhead (iflist); node; nextnode (node))
  1104.     {
  1105.       struct zebra_if *if_data;
  1106.       listnode addrnode;
  1107.       struct connected *ifc;
  1108.       struct prefix *p;
  1109.       ifp = getdata (node);
  1110.       if_data = ifp->info;
  1111.       
  1112.       vty_out (vty, "interface %s%s", ifp->name,
  1113.        VTY_NEWLINE);
  1114.       if (ifp->desc)
  1115. vty_out (vty, " description %s%s", ifp->desc,
  1116.  VTY_NEWLINE);
  1117.       /* Assign bandwidth here to avoid unnecessary interface flap
  1118.  while processing config script */
  1119.       if (ifp->bandwidth != 0)
  1120. vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE); 
  1121.       for (addrnode = listhead (ifp->connected); addrnode; nextnode (addrnode))
  1122.   {
  1123.     ifc = getdata (addrnode);
  1124.     if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
  1125.       {
  1126. p = ifc->address;
  1127. vty_out (vty, " ip%s address %s/%d",
  1128.  p->family == AF_INET ? "" : "v6",
  1129.  inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  1130.  p->prefixlen);
  1131. if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
  1132.   vty_out (vty, " secondary");
  1133.   
  1134. if (ifc->label)
  1135.   vty_out (vty, " label %s", ifc->label);
  1136. vty_out (vty, "%s", VTY_NEWLINE);
  1137.       }
  1138.   }
  1139.       if (if_data)
  1140. {
  1141.   if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
  1142.     vty_out (vty, " shutdown%s", VTY_NEWLINE);
  1143.   if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
  1144.     vty_out (vty, " %smulticast%s",
  1145.      if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
  1146.      VTY_NEWLINE);
  1147. }
  1148. #ifdef RTADV
  1149.       rtadv_config_write (vty, ifp);
  1150. #endif /* RTADV */
  1151. #ifdef HAVE_IRDP
  1152.       irdp_config_write (vty, ifp);
  1153. #endif /* IRDP */
  1154.       vty_out (vty, "!%s", VTY_NEWLINE);
  1155.     }
  1156.   return 0;
  1157. }
  1158. /* Allocate and initialize interface vector. */
  1159. void
  1160. zebra_if_init ()
  1161. {
  1162.   /* Initialize interface and new hook. */
  1163.   if_init ();
  1164.   if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
  1165.   if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
  1166.   
  1167.   /* Install configuration write function. */
  1168.   install_node (&interface_node, if_config_write);
  1169.   install_element (VIEW_NODE, &show_interface_cmd);
  1170.   install_element (ENABLE_NODE, &show_interface_cmd);
  1171.   install_element (CONFIG_NODE, &zebra_interface_cmd);
  1172.   install_element (CONFIG_NODE, &no_zebra_interface_cmd);
  1173.   install_default (INTERFACE_NODE);
  1174.   install_element (INTERFACE_NODE, &interface_desc_cmd);
  1175.   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
  1176.   install_element (INTERFACE_NODE, &multicast_cmd);
  1177.   install_element (INTERFACE_NODE, &no_multicast_cmd);
  1178.   install_element (INTERFACE_NODE, &shutdown_if_cmd);
  1179.   install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
  1180.   install_element (INTERFACE_NODE, &bandwidth_if_cmd);
  1181.   install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
  1182.   install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
  1183.   install_element (INTERFACE_NODE, &ip_address_cmd);
  1184.   install_element (INTERFACE_NODE, &no_ip_address_cmd);
  1185. #ifdef HAVE_IPV6
  1186.   install_element (INTERFACE_NODE, &ipv6_address_cmd);
  1187.   install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
  1188. #endif /* HAVE_IPV6 */
  1189. #ifdef KAME
  1190.   install_element (INTERFACE_NODE, &ip_tunnel_cmd);
  1191.   install_element (INTERFACE_NODE, &no_ip_tunnel_cmd);
  1192. #endif /* KAME */
  1193. #ifdef HAVE_NETLINK
  1194.   install_element (INTERFACE_NODE, &ip_address_secondary_cmd);
  1195.   install_element (INTERFACE_NODE, &ip_address_label_cmd);
  1196.   install_element (INTERFACE_NODE, &no_ip_address_secondary_cmd);
  1197.   install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
  1198. #endif /* HAVE_NETLINK */
  1199. }