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

网络

开发平台:

Unix_Linux

  1. /*
  2.  * Interface related function for RIPng.
  3.  * Copyright (C) 1998 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 "linklist.h"
  24. #include "if.h"
  25. #include "prefix.h"
  26. #include "memory.h"
  27. #include "network.h"
  28. #include "filter.h"
  29. #include "log.h"
  30. #include "stream.h"
  31. #include "zclient.h"
  32. #include "command.h"
  33. #include "table.h"
  34. #include "thread.h"
  35. #include "ripngd/ripngd.h"
  36. #include "ripngd/ripng_debug.h"
  37. /* If RFC2133 definition is used. */
  38. #ifndef IPV6_JOIN_GROUP
  39. #define IPV6_JOIN_GROUP  IPV6_ADD_MEMBERSHIP 
  40. #endif
  41. #ifndef IPV6_LEAVE_GROUP
  42. #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP 
  43. #endif
  44. /* Static utility function. */
  45. static void ripng_enable_apply (struct interface *);
  46. static void ripng_passive_interface_apply (struct interface *);
  47. /* Join to the all rip routers multicast group. */
  48. int
  49. ripng_multicast_join (struct interface *ifp)
  50. {
  51.   int ret;
  52.   struct ipv6_mreq mreq;
  53.   memset (&mreq, 0, sizeof (mreq));
  54.   inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr);
  55.   mreq.ipv6mr_interface = ifp->ifindex;
  56.   ret = setsockopt (ripng->sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
  57.     (char *) &mreq, sizeof (mreq));
  58.   if (ret < 0)
  59.     zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", strerror (errno));
  60.   if (IS_RIPNG_DEBUG_EVENT)
  61.     zlog_info ("RIPng %s join to all-rip-routers multicast group", ifp->name);
  62.   return ret;
  63. }
  64. /* Leave from the all rip routers multicast group. */
  65. int
  66. ripng_multicast_leave (struct interface *ifp)
  67. {
  68.   int ret;
  69.   struct ipv6_mreq mreq;
  70.   memset (&mreq, 0, sizeof (mreq));
  71.   inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr);
  72.   mreq.ipv6mr_interface = ifp->ifindex;
  73.   ret = setsockopt (ripng->sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
  74.     (char *) &mreq, sizeof (mreq));
  75.   if (ret < 0)
  76.     zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %sn", strerror (errno));
  77.   if (IS_RIPNG_DEBUG_EVENT)
  78.     zlog_info ("RIPng %s leave from all-rip-routers multicast group",
  79.        ifp->name);
  80.   return ret;
  81. }
  82. /* Check max mtu size. */
  83. int
  84. ripng_check_max_mtu ()
  85. {
  86.   listnode node;
  87.   struct interface *ifp;
  88.   int mtu;
  89.   mtu = 0;
  90.   for (node = listhead (iflist); node; nextnode (node))
  91.     {
  92.       ifp = getdata (node);
  93.       if (mtu < ifp->mtu)
  94. mtu = ifp->mtu;
  95.     }
  96.   return mtu;
  97. }
  98. int
  99. ripng_if_down (struct interface *ifp)
  100. {
  101.   struct route_node *rp;
  102.   struct ripng_info *rinfo;
  103.   struct ripng_interface *ri;
  104.   if (ripng)
  105.     {
  106.       for (rp = route_top (ripng->table); rp; rp = route_next (rp))
  107. if ((rinfo = rp->info) != NULL)
  108.   {
  109.     /* Routes got through this interface. */
  110.     if (rinfo->ifindex == ifp->ifindex
  111. && rinfo->type == ZEBRA_ROUTE_RIPNG
  112. && rinfo->sub_type == RIPNG_ROUTE_RTE)
  113.       {
  114. ripng_zebra_ipv6_delete ((struct prefix_ipv6 *) &rp->p,
  115.  &rinfo->nexthop,
  116.  rinfo->ifindex);
  117. RIPNG_TIMER_OFF (rinfo->t_timeout);
  118. RIPNG_TIMER_OFF (rinfo->t_garbage_collect);
  119.       
  120. rp->info = NULL;
  121. route_unlock_node (rp);
  122.       
  123. ripng_info_free (rinfo);
  124.       }
  125.     else
  126.       {
  127. /* All redistributed routes got through this interface. */
  128. if (rinfo->ifindex == ifp->ifindex)
  129.   ripng_redistribute_delete (rinfo->type, rinfo->sub_type,
  130.      (struct prefix_ipv6 *) &rp->p,
  131.      rinfo->ifindex);
  132.       }
  133.   }
  134.     }
  135.   ri = ifp->info;
  136.   
  137.   if (ripng && ri->running)
  138.    {
  139.      if (IS_RIPNG_DEBUG_EVENT)
  140.        zlog_info ("turn off %s", ifp->name);
  141.      /* Leave from multicast group. */
  142.      ripng_multicast_leave (ifp);
  143.      ri->running = 0;
  144.    }
  145.   return 0;
  146. }
  147. /* Inteface link up message processing. */
  148. int
  149. ripng_interface_up (int command, struct zclient *zclient, zebra_size_t length)
  150. {
  151.   struct stream *s;
  152.   struct interface *ifp;
  153.   /* zebra_interface_state_read() updates interface structure in iflist. */
  154.   s = zclient->ibuf;
  155.   ifp = zebra_interface_state_read (s);
  156.   if (ifp == NULL)
  157.     return 0;
  158.   if (IS_RIPNG_DEBUG_ZEBRA)
  159.     zlog_info ("interface up %s index %d flags %ld metric %d mtu %d",
  160.        ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
  161.   /* Check if this interface is RIPng enabled or not. */
  162.   ripng_enable_apply (ifp);
  163.   /* Check for a passive interface. */
  164.   ripng_passive_interface_apply (ifp);
  165.   /* Apply distribute list to the all interface. */
  166.   ripng_distribute_update_interface (ifp);
  167.   return 0;
  168. }
  169. /* Inteface link down message processing. */
  170. int
  171. ripng_interface_down (int command, struct zclient *zclient,
  172.       zebra_size_t length)
  173. {
  174.   struct stream *s;
  175.   struct interface *ifp;
  176.   /* zebra_interface_state_read() updates interface structure in iflist. */
  177.   s = zclient->ibuf;
  178.   ifp = zebra_interface_state_read (s);
  179.   if (ifp == NULL)
  180.     return 0;
  181.   ripng_if_down (ifp);
  182.   if (IS_RIPNG_DEBUG_ZEBRA)
  183.     zlog_info ("interface down %s index %d flags %ld metric %d mtu %d",
  184.        ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
  185.   return 0;
  186. }
  187. /* Inteface addition message from zebra. */
  188. int
  189. ripng_interface_add (int command, struct zclient *zclient, zebra_size_t length)
  190. {
  191.   struct interface *ifp;
  192.   ifp = zebra_interface_add_read (zclient->ibuf);
  193.   if (IS_RIPNG_DEBUG_ZEBRA)
  194.     zlog_info ("RIPng interface add %s index %d flags %ld metric %d mtu %d",
  195.        ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
  196.   /* Check is this interface is RIP enabled or not.*/
  197.   ripng_enable_apply (ifp);
  198.   /* Apply distribute list to the interface. */
  199.   ripng_distribute_update_interface (ifp);
  200.   /* Check interface routemap. */
  201.   ripng_if_rmap_update_interface (ifp);
  202.   return 0;
  203. }
  204. int
  205. ripng_interface_delete (int command, struct zclient *zclient,
  206. zebra_size_t length)
  207. {
  208.   return 0;
  209. }
  210. int
  211. ripng_interface_address_add (int command, struct zclient *zclient,
  212.      zebra_size_t length)
  213. {
  214.   struct connected *c;
  215.   struct prefix *p;
  216.   char buf[INET6_ADDRSTRLEN];
  217.   c = zebra_interface_address_add_read (zclient->ibuf);
  218.   if (c == NULL)
  219.     return 0;
  220.   p = c->address;
  221.   if (p->family == AF_INET6)
  222.     {
  223.       if (IS_RIPNG_DEBUG_ZEBRA)
  224. zlog_info ("RIPng connected address %s/%d add",
  225.    inet_ntop (AF_INET6, &p->u.prefix6, buf, INET6_ADDRSTRLEN),
  226.    p->prefixlen);
  227.       
  228.       /* Check is this interface is RIP enabled or not.*/
  229.       ripng_enable_apply (c->ifp);
  230.     }
  231.   return 0;
  232. }
  233. int
  234. ripng_interface_address_delete (int command, struct zclient *zclient,
  235. zebra_size_t length)
  236. {
  237.   struct connected *ifc;
  238.   struct prefix *p;
  239.   char buf[INET6_ADDRSTRLEN];
  240.   ifc = zebra_interface_address_delete_read (zclient->ibuf);
  241.   
  242.   if (ifc)
  243.     {
  244.       p = ifc->address;
  245.       if (p->family == AF_INET6)
  246. {
  247.   if (IS_RIPNG_DEBUG_ZEBRA)
  248.     zlog_info ("RIPng connected address %s/%d delete",
  249.        inet_ntop (AF_INET6, &p->u.prefix6, buf,
  250.   INET6_ADDRSTRLEN),
  251.        p->prefixlen);
  252.   /* Check is this interface is RIP enabled or not.*/
  253.   ripng_enable_apply (ifc->ifp);
  254. }
  255.       connected_free (ifc);
  256.     }
  257.   return 0;
  258. }
  259. /* RIPng enable interface vector. */
  260. vector ripng_enable_if;
  261. /* RIPng enable network table. */
  262. struct route_table *ripng_enable_network;
  263. /* Lookup RIPng enable network. */
  264. int
  265. ripng_enable_network_lookup (struct interface *ifp)
  266. {
  267.   listnode listnode;
  268.   struct connected *connected;
  269.   for (listnode = listhead (ifp->connected); listnode; nextnode (listnode))
  270.     if ((connected = getdata (listnode)) != NULL)
  271.       {
  272. struct prefix *p; 
  273. struct route_node *node;
  274. p = connected->address;
  275. if (p->family == AF_INET6)
  276.   {
  277.     node = route_node_match (ripng_enable_network, p);
  278.     if (node)
  279.       {
  280. route_unlock_node (node);
  281. return 1;
  282.       }
  283.   }
  284.       }
  285.   return -1;
  286. }
  287. /* Add RIPng enable network. */
  288. int
  289. ripng_enable_network_add (struct prefix *p)
  290. {
  291.   struct route_node *node;
  292.   node = route_node_get (ripng_enable_network, p);
  293.   if (node->info)
  294.     {
  295.       route_unlock_node (node);
  296.       return -1;
  297.     }
  298.   else
  299.     node->info = "enabled";
  300.   return 1;
  301. }
  302. /* Delete RIPng enable network. */
  303. int
  304. ripng_enable_network_delete (struct prefix *p)
  305. {
  306.   struct route_node *node;
  307.   node = route_node_lookup (ripng_enable_network, p);
  308.   if (node)
  309.     {
  310.       node->info = NULL;
  311.       /* Unlock info lock. */
  312.       route_unlock_node (node);
  313.       /* Unlock lookup lock. */
  314.       route_unlock_node (node);
  315.       return 1;
  316.     }
  317.   return -1;
  318. }
  319. /* Lookup function. */
  320. int
  321. ripng_enable_if_lookup (char *ifname)
  322. {
  323.   int i;
  324.   char *str;
  325.   for (i = 0; i < vector_max (ripng_enable_if); i++)
  326.     if ((str = vector_slot (ripng_enable_if, i)) != NULL)
  327.       if (strcmp (str, ifname) == 0)
  328. return i;
  329.   return -1;
  330. }
  331. /* Add interface to ripng_enable_if. */
  332. int
  333. ripng_enable_if_add (char *ifname)
  334. {
  335.   int ret;
  336.   ret = ripng_enable_if_lookup (ifname);
  337.   if (ret >= 0)
  338.     return -1;
  339.   vector_set (ripng_enable_if, strdup (ifname));
  340.   return 1;
  341. }
  342. /* Delete interface from ripng_enable_if. */
  343. int
  344. ripng_enable_if_delete (char *ifname)
  345. {
  346.   int index;
  347.   char *str;
  348.   index = ripng_enable_if_lookup (ifname);
  349.   if (index < 0)
  350.     return -1;
  351.   str = vector_slot (ripng_enable_if, index);
  352.   free (str);
  353.   vector_unset (ripng_enable_if, index);
  354.   return 1;
  355. }
  356. /* Wake up interface. */
  357. int
  358. ripng_interface_wakeup (struct thread *t)
  359. {
  360.   struct interface *ifp;
  361.   struct ripng_interface *ri;
  362.   /* Get interface. */
  363.   ifp = THREAD_ARG (t);
  364.   ri = ifp->info;
  365.   ri->t_wakeup = NULL;
  366.   /* Join to multicast group. */
  367.   ripng_multicast_join (ifp);
  368.   /* Send RIP request to the interface. */
  369.   ripng_request (ifp);
  370.   return 0;
  371. }
  372. /* Check RIPng is enabed on this interface. */
  373. void
  374. ripng_enable_apply (struct interface *ifp)
  375. {
  376.   int ret;
  377.   struct ripng_interface *ri = NULL;
  378.   /* Check interface. */
  379.   if (if_is_loopback (ifp))
  380.     return;
  381.   if (! if_is_up (ifp))
  382.     return;
  383.   
  384.   ri = ifp->info;
  385.   /* Check network configuration. */
  386.   ret = ripng_enable_network_lookup (ifp);
  387.   /* If the interface is matched. */
  388.   if (ret > 0)
  389.     ri->enable_network = 1;
  390.   else
  391.     ri->enable_network = 0;
  392.   /* Check interface name configuration. */
  393.   ret = ripng_enable_if_lookup (ifp->name);
  394.   if (ret >= 0)
  395.     ri->enable_interface = 1;
  396.   else
  397.     ri->enable_interface = 0;
  398.   /* Update running status of the interface. */
  399.   if (ri->enable_network || ri->enable_interface)
  400.     {
  401.       if (! ri->running)
  402. {
  403.   if (IS_RIPNG_DEBUG_EVENT)
  404.     zlog_info ("RIPng turn on %s", ifp->name);
  405.   /* Add interface wake up thread. */
  406.   if (! ri->t_wakeup)
  407.     ri->t_wakeup = thread_add_timer (master, ripng_interface_wakeup,
  408.      ifp, 1);
  409.   ri->running = 1;
  410. }
  411.     }
  412.   else
  413.     {
  414.       if (ri->running)
  415. {
  416.   if (IS_RIPNG_DEBUG_EVENT)
  417.     zlog_info ("RIPng turn off %s", ifp->name);
  418.   /* Leave from multicast group. */
  419.   ripng_multicast_leave (ifp);
  420.   ri->running = 0;
  421. }
  422.     }
  423. }
  424. /* Set distribute list to all interfaces. */
  425. static void
  426. ripng_enable_apply_all ()
  427. {
  428.   struct interface *ifp;
  429.   listnode node;
  430.   for (node = listhead (iflist); node; nextnode (node))
  431.     {
  432.       ifp = getdata (node);
  433.       ripng_enable_apply (ifp);
  434.     }
  435. }
  436. /* Vector to store passive-interface name. */
  437. vector Vripng_passive_interface;
  438. /* Utility function for looking up passive interface settings. */
  439. int
  440. ripng_passive_interface_lookup (char *ifname)
  441. {
  442.   int i;
  443.   char *str;
  444.   for (i = 0; i < vector_max (Vripng_passive_interface); i++)
  445.     if ((str = vector_slot (Vripng_passive_interface, i)) != NULL)
  446.       if (strcmp (str, ifname) == 0)
  447. return i;
  448.   return -1;
  449. }
  450. void
  451. ripng_passive_interface_apply (struct interface *ifp)
  452. {
  453.   int ret;
  454.   struct ripng_interface *ri;
  455.   ri = ifp->info;
  456.   ret = ripng_passive_interface_lookup (ifp->name);
  457.   if (ret < 0)
  458.     ri->passive = 0;
  459.   else
  460.     ri->passive = 1;
  461. }
  462. void
  463. ripng_passive_interface_apply_all (void)
  464. {
  465.   struct interface *ifp;
  466.   listnode node;
  467.   for (node = listhead (iflist); node; nextnode (node))
  468.     {
  469.       ifp = getdata (node);
  470.       ripng_passive_interface_apply (ifp);
  471.     }
  472. }
  473. /* Passive interface. */
  474. int
  475. ripng_passive_interface_set (struct vty *vty, char *ifname)
  476. {
  477.   if (ripng_passive_interface_lookup (ifname) >= 0)
  478.     return CMD_WARNING;
  479.   vector_set (Vripng_passive_interface, strdup (ifname));
  480.   ripng_passive_interface_apply_all ();
  481.   return CMD_SUCCESS;
  482. }
  483. int
  484. ripng_passive_interface_unset (struct vty *vty, char *ifname)
  485. {
  486.   int i;
  487.   char *str;
  488.   i = ripng_passive_interface_lookup (ifname);
  489.   if (i < 0)
  490.     return CMD_WARNING;
  491.   str = vector_slot (Vripng_passive_interface, i);
  492.   free (str);
  493.   vector_unset (Vripng_passive_interface, i);
  494.   ripng_passive_interface_apply_all ();
  495.   return CMD_SUCCESS;
  496. }
  497. /* Free all configured RIP passive-interface settings. */
  498. void
  499. ripng_passive_interface_clean (void)
  500. {
  501.   int i;
  502.   char *str;
  503.   for (i = 0; i < vector_max (Vripng_passive_interface); i++)
  504.     if ((str = vector_slot (Vripng_passive_interface, i)) != NULL)
  505.       {
  506. free (str);
  507. vector_slot (Vripng_passive_interface, i) = NULL;
  508.       }
  509.   ripng_passive_interface_apply_all ();
  510. }
  511. /* Write RIPng enable network and interface to the vty. */
  512. int
  513. ripng_network_write (struct vty *vty)
  514. {
  515.   int i;
  516.   char *str;
  517.   char *ifname;
  518.   struct route_node *node;
  519.   char buf[BUFSIZ];
  520.   /* Write enable network. */
  521.   for (node = route_top (ripng_enable_network); node; node = route_next (node))
  522.     if (node->info)
  523.       {
  524. struct prefix *p = &node->p;
  525. vty_out (vty, " network %s/%d%s", 
  526.  inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  527.  p->prefixlen,
  528.  VTY_NEWLINE);
  529.       }
  530.   
  531.   /* Write enable interface. */
  532.   for (i = 0; i < vector_max (ripng_enable_if); i++)
  533.     if ((str = vector_slot (ripng_enable_if, i)) != NULL)
  534.       vty_out (vty, " network %s%s", str,
  535.        VTY_NEWLINE);
  536.   /* Write passive interface. */
  537.   for (i = 0; i < vector_max (Vripng_passive_interface); i++)
  538.     if ((ifname = vector_slot (Vripng_passive_interface, i)) != NULL)
  539.       vty_out (vty, " passive-interface %s%s", ifname, VTY_NEWLINE);
  540.   return 0;
  541. }
  542. /* RIPng enable on specified interface or matched network. */
  543. DEFUN (ripng_network,
  544.        ripng_network_cmd,
  545.        "network IF_OR_ADDR",
  546.        "RIPng enable on specified interface or network.n"
  547.        "Interface or address")
  548. {
  549.   int ret;
  550.   struct prefix p;
  551.   ret = str2prefix (argv[0], &p);
  552.   /* Given string is IPv6 network or interface name. */
  553.   if (ret)
  554.     ret = ripng_enable_network_add (&p);
  555.   else
  556.     ret = ripng_enable_if_add (argv[0]);
  557.   if (ret < 0)
  558.     {
  559.       vty_out (vty, "There is same network configuration %s%s", argv[0],
  560.        VTY_NEWLINE);
  561.       return CMD_WARNING;
  562.     }
  563.   ripng_enable_apply_all ();
  564.   return CMD_SUCCESS;
  565. }
  566. /* RIPng enable on specified interface or matched network. */
  567. DEFUN (no_ripng_network,
  568.        no_ripng_network_cmd,
  569.        "no network IF_OR_ADDR",
  570.        NO_STR
  571.        "RIPng enable on specified interface or network.n"
  572.        "Interface or address")
  573. {
  574.   int ret;
  575.   struct prefix p;
  576.   ret = str2prefix (argv[0], &p);
  577.   /* Given string is interface name. */
  578.   if (ret)
  579.     ret = ripng_enable_network_delete (&p);
  580.   else
  581.     ret = ripng_enable_if_delete (argv[0]);
  582.   if (ret < 0)
  583.     {
  584.       vty_out (vty, "can't find network %s%s", argv[0],
  585.        VTY_NEWLINE);
  586.       return CMD_WARNING;
  587.     }
  588.   
  589.   ripng_enable_apply_all ();
  590.   return CMD_SUCCESS;
  591. }
  592. DEFUN (ripng_passive_interface,
  593.        ripng_passive_interface_cmd,
  594.        "passive-interface IFNAME",
  595.        "Suppress routing updates on an interfacen"
  596.        "Interface namen")
  597. {
  598.   return ripng_passive_interface_set (vty, argv[0]);
  599. }
  600. DEFUN (no_ripng_passive_interface,
  601.        no_ripng_passive_interface_cmd,
  602.        "no passive-interface IFNAME",
  603.        NO_STR
  604.        "Suppress routing updates on an interfacen"
  605.        "Interface namen")
  606. {
  607.   return ripng_passive_interface_unset (vty, argv[0]);
  608. }
  609. struct ripng_interface *
  610. ri_new ()
  611. {
  612.   struct ripng_interface *ri;
  613.   ri = XCALLOC (MTYPE_IF, sizeof (struct ripng_interface));
  614.   return ri;
  615. }
  616. int
  617. ripng_if_new_hook (struct interface *ifp)
  618. {
  619.   ifp->info = ri_new ();
  620.   return 0;
  621. }
  622. /* Configuration write function for ripngd. */
  623. int
  624. interface_config_write (struct vty *vty)
  625. {
  626.   listnode node;
  627.   struct interface *ifp;
  628.   struct ripng_interface *ri;
  629.   int write = 0;
  630.   for (node = listhead (iflist); node; nextnode (node))
  631.     {
  632.       ifp = getdata (node);
  633.       ri = ifp->info;
  634.       vty_out (vty, "interface %s%s", ifp->name,
  635.        VTY_NEWLINE);
  636.       if (ifp->desc)
  637. vty_out (vty, " description %s%s", ifp->desc,
  638.  VTY_NEWLINE);
  639.       vty_out (vty, "!%s", VTY_NEWLINE);
  640.       write++;
  641.     }
  642.   return write;
  643. }
  644. /* ripngd's interface node. */
  645. struct cmd_node interface_node =
  646. {
  647.   INTERFACE_NODE,
  648.   "%s(config-if)# ",
  649. };
  650. /* Initialization of interface. */
  651. void
  652. ripng_if_init ()
  653. {
  654.   /* Interface initialize. */
  655.   iflist = list_new ();
  656.   if_add_hook (IF_NEW_HOOK, ripng_if_new_hook);
  657.   /* RIPng enable network init. */
  658.   ripng_enable_network = route_table_init ();
  659.   /* RIPng enable interface init. */
  660.   ripng_enable_if = vector_init (1);
  661.   /* RIPng passive interface. */
  662.   Vripng_passive_interface = vector_init (1);
  663.   /* Install interface node. */
  664.   install_node (&interface_node, interface_config_write);
  665.   install_element (CONFIG_NODE, &interface_cmd);
  666.   install_element (INTERFACE_NODE, &config_end_cmd);
  667.   install_element (INTERFACE_NODE, &config_exit_cmd);
  668.   install_element (INTERFACE_NODE, &config_help_cmd);
  669.   install_element (INTERFACE_NODE, &interface_desc_cmd);
  670.   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
  671.   install_element (RIPNG_NODE, &ripng_network_cmd);
  672.   install_element (RIPNG_NODE, &no_ripng_network_cmd);
  673.   install_element (RIPNG_NODE, &ripng_passive_interface_cmd);
  674.   install_element (RIPNG_NODE, &no_ripng_passive_interface_cmd);
  675. }