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

网络

开发平台:

Unix_Linux

  1. /* Interface related function for RIP.
  2.  * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
  3.  *
  4.  * This file is part of GNU Zebra.
  5.  *
  6.  * GNU Zebra is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation; either version 2, or (at your option) any
  9.  * later version.
  10.  *
  11.  * GNU Zebra is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
  18.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19.  * 02111-1307, USA.  
  20.  */
  21. #include <zebra.h>
  22. #include "command.h"
  23. #include "if.h"
  24. #include "sockunion.h"
  25. #include "prefix.h"
  26. #include "memory.h"
  27. #include "network.h"
  28. #include "table.h"
  29. #include "log.h"
  30. #include "stream.h"
  31. #include "thread.h"
  32. #include "zclient.h"
  33. #include "filter.h"
  34. #include "sockopt.h"
  35. #include "zebra/connected.h"
  36. #include "ripd/ripd.h"
  37. #include "ripd/rip_debug.h"
  38. void rip_enable_apply (struct interface *);
  39. void rip_passive_interface_apply (struct interface *);
  40. int rip_if_down(struct interface *ifp);
  41. struct message ri_version_msg[] = 
  42. {
  43.   {RI_RIP_VERSION_1,       "1"},
  44.   {RI_RIP_VERSION_2,       "2"},
  45.   {RI_RIP_VERSION_1_AND_2, "1 2"},
  46.   {0,                      NULL}
  47. };
  48. /* RIP enabled network vector. */
  49. vector rip_enable_interface;
  50. /* RIP enabled interface table. */
  51. struct route_table *rip_enable_network;
  52. /* Vector to store passive-interface name. */
  53. vector Vrip_passive_interface;
  54. /* Join to the RIP version 2 multicast group. */
  55. int
  56. ipv4_multicast_join (int sock, 
  57.      struct in_addr group, 
  58.      struct in_addr ifa,
  59.      unsigned int ifindex)
  60. {
  61.   int ret;
  62.   ret = setsockopt_multicast_ipv4 (sock, 
  63.    IP_ADD_MEMBERSHIP, 
  64.    ifa, 
  65.    group.s_addr, 
  66.    ifindex); 
  67.   if (ret < 0) 
  68.     zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
  69.   strerror (errno));
  70.   return ret;
  71. }
  72. /* Leave from the RIP version 2 multicast group. */
  73. int
  74. ipv4_multicast_leave (int sock, 
  75.       struct in_addr group, 
  76.       struct in_addr ifa,
  77.       unsigned int ifindex)
  78. {
  79.   int ret;
  80.   ret = setsockopt_multicast_ipv4 (sock, 
  81.    IP_DROP_MEMBERSHIP, 
  82.    ifa, 
  83.    group.s_addr, 
  84.    ifindex);
  85.   if (ret < 0) 
  86.     zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
  87.   return ret;
  88. }
  89. /* Allocate new RIP's interface configuration. */
  90. struct rip_interface *
  91. rip_interface_new ()
  92. {
  93.   struct rip_interface *ri;
  94.   ri = XMALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
  95.   memset (ri, 0, sizeof (struct rip_interface));
  96.   /* Default authentication type is simple password for Cisco
  97.      compatibility. */
  98.   /* ri->auth_type = RIP_NO_AUTH; */
  99.   ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
  100.   /* Set default split-horizon behavior.  If the interface is Frame
  101.      Relay or SMDS is enabled, the default value for split-horizon is
  102.      off.  But currently Zebra does detect Frame Relay or SMDS
  103.      interface.  So all interface is set to split horizon.  */
  104.   ri->split_horizon_default = 1;
  105.   ri->split_horizon = ri->split_horizon_default;
  106.   return ri;
  107. }
  108. void
  109. rip_interface_multicast_set (int sock, struct interface *ifp)
  110. {
  111.   int ret;
  112.   listnode node;
  113.   struct servent *sp;
  114.   struct sockaddr_in from;
  115.   for (node = listhead (ifp->connected); node; nextnode (node))
  116.     {
  117.       struct prefix_ipv4 *p;
  118.       struct connected *connected;
  119.       struct in_addr addr;
  120.       connected = getdata (node);
  121.       p = (struct prefix_ipv4 *) connected->address;
  122.       if (p->family == AF_INET)
  123. {
  124.   addr = p->prefix;
  125.   if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF,
  126.  addr, 0, ifp->ifindex) < 0) 
  127.     {
  128.       zlog_warn ("Can't setsockopt IP_MULTICAST_IF to fd %d", sock);
  129.       return;
  130.     }
  131.   /* Bind myself. */
  132.   memset (&from, 0, sizeof (struct sockaddr_in));
  133.   /* Set RIP port. */
  134.   sp = getservbyname ("router", "udp");
  135.   if (sp) 
  136.     from.sin_port = sp->s_port;
  137.   else 
  138.     from.sin_port = htons (RIP_PORT_DEFAULT);
  139.   /* Address shoud be any address. */
  140.   from.sin_family = AF_INET;
  141.   from.sin_addr = addr;
  142. #ifdef HAVE_SIN_LEN
  143.   from.sin_len = sizeof (struct sockaddr_in);
  144. #endif /* HAVE_SIN_LEN */
  145.   ret = bind (sock, (struct sockaddr *) & from, 
  146.       sizeof (struct sockaddr_in));
  147.   if (ret < 0)
  148.     {
  149.       zlog_warn ("Can't bind socket: %s", strerror (errno));
  150.       return;
  151.     }
  152.   return;
  153. }
  154.     }
  155. }
  156. /* Send RIP request packet to specified interface. */
  157. void
  158. rip_request_interface_send (struct interface *ifp, u_char version)
  159. {
  160.   struct sockaddr_in to;
  161.   /* RIPv2 support multicast. */
  162.   if (version == RIPv2 && if_is_multicast (ifp))
  163.     {
  164.       
  165.       if (IS_RIP_DEBUG_EVENT)
  166. zlog_info ("multicast request on %s", ifp->name);
  167.       rip_request_send (NULL, ifp, version);
  168.       return;
  169.     }
  170.   /* RIPv1 and non multicast interface. */
  171.   if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
  172.     {
  173.       listnode cnode;
  174.       if (IS_RIP_DEBUG_EVENT)
  175. zlog_info ("broadcast request to %s", ifp->name);
  176.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  177. {
  178.   struct prefix_ipv4 *p;
  179.   struct connected *connected;
  180.   connected = getdata (cnode);
  181.   p = (struct prefix_ipv4 *) connected->destination;
  182.   if (p->family == AF_INET)
  183.     {
  184.       memset (&to, 0, sizeof (struct sockaddr_in));
  185.       to.sin_port = htons (RIP_PORT_DEFAULT);
  186.       to.sin_addr = p->prefix;
  187.       rip_request_send (&to, ifp, version);
  188.     }
  189. }
  190.     }
  191. }
  192. /* This will be executed when interface goes up. */
  193. void
  194. rip_request_interface (struct interface *ifp)
  195. {
  196.   struct rip_interface *ri;
  197.   /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
  198.   if (if_is_loopback (ifp))
  199.     return;
  200.   /* If interface is down, don't send RIP packet. */
  201.   if (! if_is_up (ifp))
  202.     return;
  203.   /* Fetch RIP interface information. */
  204.   ri = ifp->info;
  205.   /* If there is no version configuration in the interface,
  206.      use rip's version setting. */
  207.   if (ri->ri_send == RI_RIP_UNSPEC)
  208.     {
  209.       if (rip->version == RIPv1)
  210. rip_request_interface_send (ifp, RIPv1);
  211.       else
  212. rip_request_interface_send (ifp, RIPv2);
  213.     }
  214.   /* If interface has RIP version configuration use it. */
  215.   else
  216.     {
  217.       if (ri->ri_send & RIPv1)
  218. rip_request_interface_send (ifp, RIPv1);
  219.       if (ri->ri_send & RIPv2)
  220. rip_request_interface_send (ifp, RIPv2);
  221.     }
  222. }
  223. /* Send RIP request to the neighbor. */
  224. void
  225. rip_request_neighbor (struct in_addr addr)
  226. {
  227.   struct sockaddr_in to;
  228.   memset (&to, 0, sizeof (struct sockaddr_in));
  229.   to.sin_port = htons (RIP_PORT_DEFAULT);
  230.   to.sin_addr = addr;
  231.   rip_request_send (&to, NULL, rip->version);
  232. }
  233. /* Request routes at all interfaces. */
  234. void
  235. rip_request_neighbor_all ()
  236. {
  237.   struct route_node *rp;
  238.   if (! rip)
  239.     return;
  240.   if (IS_RIP_DEBUG_EVENT)
  241.     zlog_info ("request to the all neighbor");
  242.   /* Send request to all neighbor. */
  243.   for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
  244.     if (rp->info)
  245.       rip_request_neighbor (rp->p.u.prefix4);
  246. }
  247. /* Multicast packet receive socket. */
  248. int
  249. rip_multicast_join (struct interface *ifp, int sock)
  250. {
  251.   struct rip_interface *ri;
  252.   listnode cnode;
  253.   ri = ifp->info;
  254.   if (if_is_up (ifp) && if_is_multicast (ifp))
  255.     {
  256.       if (IS_RIP_DEBUG_EVENT)
  257. zlog_info ("multicast join at %s", ifp->name);
  258.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  259. {
  260.   struct prefix_ipv4 *p;
  261.   struct connected *connected;
  262.   struct in_addr group;
  263.       
  264.   connected = getdata (cnode);
  265.   p = (struct prefix_ipv4 *) connected->address;
  266.       
  267.   if (p->family != AF_INET)
  268.     continue;
  269.       
  270.   group.s_addr = htonl (INADDR_RIP_GROUP);
  271.   if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
  272.     return -1;
  273.   else
  274.     {
  275.       ri->joined_multicast = 1;
  276.       return 0;
  277.     }
  278. }
  279.     }
  280.   return 0;
  281. }
  282. /* Leave from multicast group. */
  283. void
  284. rip_multicast_leave (struct interface *ifp, int sock)
  285. {
  286.   struct rip_interface *ri;
  287.   listnode cnode;
  288.   ri = ifp->info;
  289.   if (ri->joined_multicast)
  290.     {
  291.       ri->joined_multicast = 0;
  292.       if (IS_RIP_DEBUG_EVENT)
  293. zlog_info ("multicast leave from %s", ifp->name);
  294.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  295. {
  296.   struct prefix_ipv4 *p;
  297.   struct connected *connected;
  298.   struct in_addr group;
  299.       
  300.   connected = getdata (cnode);
  301.   p = (struct prefix_ipv4 *) connected->address;
  302.       
  303.   if (p->family != AF_INET)
  304.     continue;
  305.       
  306.   group.s_addr = htonl (INADDR_RIP_GROUP);
  307.           if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
  308.     return;
  309.         }
  310.     }
  311. }
  312. /* Is there and address on interface that I could use ? */
  313. int
  314. rip_if_ipv4_address_check (struct interface *ifp)
  315. {
  316.   struct listnode *nn;
  317.   struct connected *connected;
  318.   int count = 0;
  319.   for (nn = listhead (ifp->connected); nn; nextnode (nn))
  320.     if ((connected = getdata (nn)) != NULL)
  321.       {
  322. struct prefix *p;
  323. p = connected->address;
  324. if (p->family == AF_INET)
  325.           {
  326.     count++;
  327.   }
  328.       }
  329.   return count;
  330. }
  331. /* Does this address belongs to me ? */
  332. int
  333. if_check_address (struct in_addr addr)
  334. {
  335.   listnode node;
  336.   for (node = listhead (iflist); node; nextnode (node))
  337.     {
  338.       listnode cnode;
  339.       struct interface *ifp;
  340.       ifp = getdata (node);
  341.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  342. {
  343.   struct connected *connected;
  344.   struct prefix_ipv4 *p;
  345.   connected = getdata (cnode);
  346.   p = (struct prefix_ipv4 *) connected->address;
  347.   if (p->family != AF_INET)
  348.     continue;
  349.   if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
  350.     return 1;
  351. }
  352.     }
  353.   return 0;
  354. }
  355. /* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */
  356. int
  357. if_valid_neighbor (struct in_addr addr)
  358. {
  359.   listnode node;
  360.   struct connected *connected = NULL;
  361.   struct prefix_ipv4 *p;
  362.   for (node = listhead (iflist); node; nextnode (node))
  363.     {
  364.       listnode cnode;
  365.       struct interface *ifp;
  366.       ifp = getdata (node);
  367.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  368. {
  369.   struct prefix *pxn = NULL; /* Prefix of the neighbor */
  370.   struct prefix *pxc = NULL; /* Prefix of the connected network */
  371.   connected = getdata (cnode);
  372.   if (if_is_pointopoint (ifp))
  373.     {
  374.       p = (struct prefix_ipv4 *) connected->address;
  375.       if (p && p->family == AF_INET)
  376. {
  377.   if (IPV4_ADDR_SAME (&p->prefix, &addr))
  378.     return 1;
  379.   p = (struct prefix_ipv4 *) connected->destination;
  380.   if (p && IPV4_ADDR_SAME (&p->prefix, &addr))
  381.     return 1;
  382. }
  383.     }
  384.   else
  385.     {
  386.       p = (struct prefix_ipv4 *) connected->address;
  387.       if (p->family != AF_INET)
  388. continue;
  389.       pxn = prefix_new();
  390.       pxn->family = AF_INET;
  391.       pxn->prefixlen = 32;
  392.       pxn->u.prefix4 = addr;
  393.       
  394.       pxc = prefix_new();
  395.       prefix_copy(pxc, (struct prefix *) p);
  396.       apply_mask(pxc);
  397.   
  398.       if (prefix_match (pxc, pxn)) 
  399. {
  400.   prefix_free (pxn);
  401.   prefix_free (pxc);
  402.   return 1;
  403. }
  404.       prefix_free(pxc);
  405.       prefix_free(pxn);
  406.     }
  407. }
  408.     }
  409.   return 0;
  410. }
  411. /* Inteface link down message processing. */
  412. int
  413. rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
  414. {
  415.   struct interface *ifp;
  416.   struct stream *s;
  417.   s = zclient->ibuf;  
  418.   /* zebra_interface_state_read() updates interface structure in
  419.      iflist. */
  420.   ifp = zebra_interface_state_read(s);
  421.   if (ifp == NULL)
  422.     return 0;
  423.   rip_if_down(ifp);
  424.  
  425.   if (IS_RIP_DEBUG_ZEBRA)
  426.     zlog_info ("interface %s index %d flags %ld metric %d mtu %d is down",
  427.        ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
  428.   return 0;
  429. }
  430. /* Inteface link up message processing */
  431. int
  432. rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
  433. {
  434.   struct interface *ifp;
  435.   /* zebra_interface_state_read () updates interface structure in
  436.      iflist. */
  437.   ifp = zebra_interface_state_read (zclient->ibuf);
  438.   if (ifp == NULL)
  439.     return 0;
  440.   if (IS_RIP_DEBUG_ZEBRA)
  441.     zlog_info ("interface %s index %d flags %ld metric %d mtu %d is up",
  442.        ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
  443.   /* Check if this interface is RIP enabled or not.*/
  444.   rip_enable_apply (ifp);
  445.  
  446.   /* Check for a passive interface */
  447.   rip_passive_interface_apply (ifp);
  448.   /* Apply distribute list to the all interface. */
  449.   rip_distribute_update_interface (ifp);
  450.   return 0;
  451. }
  452. /* Inteface addition message from zebra. */
  453. int
  454. rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
  455. {
  456.   struct interface *ifp;
  457.   ifp = zebra_interface_add_read (zclient->ibuf);
  458.   if (IS_RIP_DEBUG_ZEBRA)
  459.     zlog_info ("interface add %s index %d flags %ld metric %d mtu %d",
  460.        ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
  461.   /* Check if this interface is RIP enabled or not.*/
  462.   rip_enable_apply (ifp);
  463.   /* Apply distribute list to the all interface. */
  464.   rip_distribute_update_interface (ifp);
  465.   /* rip_request_neighbor_all (); */
  466.   return 0;
  467. }
  468. int
  469. rip_interface_delete (int command, struct zclient *zclient,
  470.       zebra_size_t length)
  471. {
  472.   struct interface *ifp;
  473.   struct stream *s;
  474.   s = zclient->ibuf;  
  475.   /* zebra_interface_state_read() updates interface structure in iflist */
  476.   ifp = zebra_interface_state_read(s);
  477.   if (ifp == NULL)
  478.     return 0;
  479.   if (if_is_up (ifp)) {
  480.     rip_if_down(ifp);
  481.   } 
  482.   
  483.   zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
  484.     ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);  
  485.   
  486.   /* To support pseudo interface do not free interface structure.  */
  487.   /* if_delete(ifp); */
  488.   return 0;
  489. }
  490. void
  491. rip_interface_clean ()
  492. {
  493.   listnode node;
  494.   struct interface *ifp;
  495.   struct rip_interface *ri;
  496.   for (node = listhead (iflist); node; nextnode (node))
  497.     {
  498.       ifp = getdata (node);
  499.       ri = ifp->info;
  500.       ri->enable_network = 0;
  501.       ri->enable_interface = 0;
  502.       ri->running = 0;
  503.       if (ri->t_wakeup)
  504. {
  505.   thread_cancel (ri->t_wakeup);
  506.   ri->t_wakeup = NULL;
  507. }
  508.     }
  509. }
  510. void
  511. rip_interface_reset ()
  512. {
  513.   listnode node;
  514.   struct interface *ifp;
  515.   struct rip_interface *ri;
  516.   for (node = listhead (iflist); node; nextnode (node))
  517.     {
  518.       ifp = getdata (node);
  519.       ri = ifp->info;
  520.       ri->enable_network = 0;
  521.       ri->enable_interface = 0;
  522.       ri->running = 0;
  523.       ri->ri_send = RI_RIP_UNSPEC;
  524.       ri->ri_receive = RI_RIP_UNSPEC;
  525.       /* ri->auth_type = RIP_NO_AUTH; */
  526.       ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
  527.       if (ri->auth_str)
  528. {
  529.   free (ri->auth_str);
  530.   ri->auth_str = NULL;
  531. }
  532.       if (ri->key_chain)
  533. {
  534.   free (ri->key_chain);
  535.   ri->key_chain = NULL;
  536. }
  537.       ri->split_horizon = 0;
  538.       ri->split_horizon_default = 0;
  539.       ri->list[RIP_FILTER_IN] = NULL;
  540.       ri->list[RIP_FILTER_OUT] = NULL;
  541.       ri->prefix[RIP_FILTER_IN] = NULL;
  542.       ri->prefix[RIP_FILTER_OUT] = NULL;
  543.       
  544.       if (ri->t_wakeup)
  545. {
  546.   thread_cancel (ri->t_wakeup);
  547.   ri->t_wakeup = NULL;
  548. }
  549.       ri->recv_badpackets = 0;
  550.       ri->recv_badroutes = 0;
  551.       ri->sent_updates = 0;
  552.       ri->passive = 0;
  553.     }
  554. }
  555. int
  556. rip_if_down(struct interface *ifp)
  557. {
  558.   struct route_node *rp;
  559.   struct rip_info *rinfo;
  560.   struct rip_interface *ri = NULL;
  561.   if (rip)
  562.     {
  563.       for (rp = route_top (rip->table); rp; rp = route_next (rp))
  564. if ((rinfo = rp->info) != NULL)
  565.   {
  566.     /* Routes got through this interface. */
  567.     if (rinfo->ifindex == ifp->ifindex &&
  568. rinfo->type == ZEBRA_ROUTE_RIP &&
  569. rinfo->sub_type == RIP_ROUTE_RTE)
  570.       {
  571. rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
  572.        &rinfo->nexthop,
  573.        rinfo->ifindex);
  574. rip_redistribute_delete (rinfo->type,rinfo->sub_type,
  575.  (struct prefix_ipv4 *)&rp->p,
  576.  rinfo->ifindex);
  577.       }
  578.     else
  579.       {
  580. /* All redistributed routes but static and system */
  581. if ((rinfo->ifindex == ifp->ifindex) &&
  582.     (rinfo->type != ZEBRA_ROUTE_STATIC) &&
  583.     (rinfo->type != ZEBRA_ROUTE_SYSTEM))
  584.   rip_redistribute_delete (rinfo->type,rinfo->sub_type,
  585.    (struct prefix_ipv4 *)&rp->p,
  586.    rinfo->ifindex);
  587.       }
  588.   }
  589.     }
  590.     
  591.   ri = ifp->info;
  592.   
  593.   if (ri->running)
  594.    {
  595.      if (IS_RIP_DEBUG_EVENT)
  596.        zlog_info ("turn off %s", ifp->name);
  597.      /* Leave from multicast group. */
  598.      rip_multicast_leave (ifp, rip->sock);
  599.      ri->running = 0;
  600.    }
  601.   return 0;
  602. }
  603. /* Needed for stop RIP process. */
  604. void
  605. rip_if_down_all ()
  606. {
  607.   struct interface *ifp;
  608.   listnode node;
  609.   for (node = listhead (iflist); node; nextnode (node))
  610.     {
  611.       ifp = getdata (node);
  612.       rip_if_down (ifp);
  613.     }
  614. }
  615. int
  616. rip_interface_address_add (int command, struct zclient *zclient,
  617.    zebra_size_t length)
  618. {
  619.   struct connected *ifc;
  620.   struct prefix *p;
  621.   ifc = zebra_interface_address_add_read (zclient->ibuf);
  622.   if (ifc == NULL)
  623.     return 0;
  624.   p = ifc->address;
  625.   if (p->family == AF_INET)
  626.     {
  627.       if (IS_RIP_DEBUG_ZEBRA)
  628. zlog_info ("connected address %s/%d is added", 
  629.    inet_ntoa (p->u.prefix4), p->prefixlen);
  630.       
  631.       /* Check is this interface is RIP enabled or not.*/
  632.       rip_enable_apply (ifc->ifp);
  633. #ifdef HAVE_SNMP
  634.       rip_ifaddr_add (ifc->ifp, ifc);
  635. #endif /* HAVE_SNMP */
  636.     }
  637.   return 0;
  638. }
  639. int
  640. rip_interface_address_delete (int command, struct zclient *zclient,
  641.       zebra_size_t length)
  642. {
  643.   struct connected *ifc;
  644.   struct prefix *p;
  645.   ifc = zebra_interface_address_delete_read (zclient->ibuf);
  646.   
  647.   if (ifc)
  648.     {
  649.       p = ifc->address;
  650.       if (p->family == AF_INET)
  651. {
  652.   if (IS_RIP_DEBUG_ZEBRA)
  653.     zlog_info ("connected address %s/%d is deleted",
  654.        inet_ntoa (p->u.prefix4), p->prefixlen);
  655. #ifdef HAVE_SNMP
  656.   rip_ifaddr_delete (ifc->ifp, ifc);
  657. #endif /* HAVE_SNMP */
  658.   /* Check if this interface is RIP enabled or not.*/
  659.   rip_enable_apply (ifc->ifp);
  660. }
  661.       connected_free (ifc);
  662.     }
  663.   return 0;
  664. }
  665. /* Check interface is enabled by network statement. */
  666. int
  667. rip_enable_network_lookup (struct interface *ifp)
  668. {
  669.   struct listnode *nn;
  670.   struct connected *connected;
  671.   struct prefix_ipv4 address;
  672.   for (nn = listhead (ifp->connected); nn; nextnode (nn))
  673.     if ((connected = getdata (nn)) != NULL)
  674.       {
  675. struct prefix *p; 
  676. struct route_node *node;
  677. p = connected->address;
  678. if (p->family == AF_INET)
  679.   {
  680.     address.family = AF_INET;
  681.     address.prefix = p->u.prefix4;
  682.     address.prefixlen = IPV4_MAX_BITLEN;
  683.     
  684.     node = route_node_match (rip_enable_network,
  685.      (struct prefix *)&address);
  686.     if (node)
  687.       {
  688. route_unlock_node (node);
  689. return 1;
  690.       }
  691.   }
  692.       }
  693.   return -1;
  694. }
  695. /* Add RIP enable network. */
  696. int
  697. rip_enable_network_add (struct prefix *p)
  698. {
  699.   struct route_node *node;
  700.   node = route_node_get (rip_enable_network, p);
  701.   if (node->info)
  702.     {
  703.       route_unlock_node (node);
  704.       return -1;
  705.     }
  706.   else
  707.     node->info = "enabled";
  708.   return 1;
  709. }
  710. /* Delete RIP enable network. */
  711. int
  712. rip_enable_network_delete (struct prefix *p)
  713. {
  714.   struct route_node *node;
  715.   node = route_node_lookup (rip_enable_network, p);
  716.   if (node)
  717.     {
  718.       node->info = NULL;
  719.       /* Unlock info lock. */
  720.       route_unlock_node (node);
  721.       /* Unlock lookup lock. */
  722.       route_unlock_node (node);
  723.       return 1;
  724.     }
  725.   return -1;
  726. }
  727. /* Check interface is enabled by ifname statement. */
  728. int
  729. rip_enable_if_lookup (char *ifname)
  730. {
  731.   int i;
  732.   char *str;
  733.   for (i = 0; i < vector_max (rip_enable_interface); i++)
  734.     if ((str = vector_slot (rip_enable_interface, i)) != NULL)
  735.       if (strcmp (str, ifname) == 0)
  736. return i;
  737.   return -1;
  738. }
  739. /* Add interface to rip_enable_if. */
  740. int
  741. rip_enable_if_add (char *ifname)
  742. {
  743.   int ret;
  744.   ret = rip_enable_if_lookup (ifname);
  745.   if (ret >= 0)
  746.     return -1;
  747.   vector_set (rip_enable_interface, strdup (ifname));
  748.   return 1;
  749. }
  750. /* Delete interface from rip_enable_if. */
  751. int
  752. rip_enable_if_delete (char *ifname)
  753. {
  754.   int index;
  755.   char *str;
  756.   index = rip_enable_if_lookup (ifname);
  757.   if (index < 0)
  758.     return -1;
  759.   str = vector_slot (rip_enable_interface, index);
  760.   free (str);
  761.   vector_unset (rip_enable_interface, index);
  762.   return 1;
  763. }
  764. /* Join to multicast group and send request to the interface. */
  765. int
  766. rip_interface_wakeup (struct thread *t)
  767. {
  768.   struct interface *ifp;
  769.   struct rip_interface *ri;
  770.   /* Get interface. */
  771.   ifp = THREAD_ARG (t);
  772.   ri = ifp->info;
  773.   ri->t_wakeup = NULL;
  774.   /* Join to multicast group. */
  775.   if (rip_multicast_join (ifp, rip->sock) < 0)
  776.     {
  777.       zlog_err ("multicast join failed, interface %s not running", ifp->name);
  778.       return 0;
  779.     }
  780.   /* Set running flag. */
  781.   ri->running = 1;
  782.   /* Send RIP request to the interface. */
  783.   rip_request_interface (ifp);
  784.   return 0;
  785. }
  786. int rip_redistribute_check (int);
  787. void
  788. rip_connect_set (struct interface *ifp, int set)
  789. {
  790.   struct listnode *nn;
  791.   struct connected *connected;
  792.   struct prefix_ipv4 address;
  793.   for (nn = listhead (ifp->connected); nn; nextnode (nn))
  794.     if ((connected = getdata (nn)) != NULL)
  795.       {
  796. struct prefix *p; 
  797. p = connected->address;
  798. if (p->family != AF_INET)
  799.   continue;
  800. address.family = AF_INET;
  801. address.prefix = p->u.prefix4;
  802. address.prefixlen = p->prefixlen;
  803. apply_mask_ipv4 (&address);
  804. if (set)
  805.   rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
  806. &address, connected->ifp->ifindex, NULL);
  807. else
  808.   {
  809.     rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
  810.      &address, connected->ifp->ifindex);
  811.     if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
  812.       rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
  813.     &address, connected->ifp->ifindex, NULL);
  814.   }
  815.       }
  816. }
  817. /* Update interface status. */
  818. void
  819. rip_enable_apply (struct interface *ifp)
  820. {
  821.   int ret;
  822.   struct rip_interface *ri = NULL;
  823.   /* Check interface. */
  824.   if (if_is_loopback (ifp))
  825.     return;
  826.   if (! if_is_up (ifp))
  827.     return;
  828.   ri = ifp->info;
  829.   /* Check network configuration. */
  830.   ret = rip_enable_network_lookup (ifp);
  831.   /* If the interface is matched. */
  832.   if (ret > 0)
  833.     ri->enable_network = 1;
  834.   else
  835.     ri->enable_network = 0;
  836.   /* Check interface name configuration. */
  837.   ret = rip_enable_if_lookup (ifp->name);
  838.   if (ret >= 0)
  839.     ri->enable_interface = 1;
  840.   else
  841.     ri->enable_interface = 0;
  842.   /* any interface MUST have an IPv4 address */
  843.   if ( ! rip_if_ipv4_address_check (ifp) )
  844.     {
  845.       ri->enable_network = 0;
  846.       ri->enable_interface = 0;
  847.     }
  848.   /* Update running status of the interface. */
  849.   if (ri->enable_network || ri->enable_interface)
  850.     {
  851.       if (! ri->running)
  852. {
  853.   if (IS_RIP_DEBUG_EVENT)
  854.     zlog_info ("turn on %s", ifp->name);
  855.   /* Add interface wake up thread. */
  856.   if (! ri->t_wakeup)
  857.     ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
  858.      ifp, 1);
  859.           rip_connect_set (ifp, 1);
  860. }
  861.     }
  862.   else
  863.     {
  864.       if (ri->running)
  865. {
  866.   if (IS_RIP_DEBUG_EVENT)
  867.     zlog_info ("turn off %s", ifp->name);
  868.   /* Might as well clean up the route table as well */ 
  869.   rip_if_down(ifp);
  870.   ri->running = 0;
  871.           rip_connect_set (ifp, 0);
  872. }
  873.     }
  874. }
  875. /* Apply network configuration to all interface. */
  876. void
  877. rip_enable_apply_all ()
  878. {
  879.   struct interface *ifp;
  880.   listnode node;
  881.   /* Check each interface. */
  882.   for (node = listhead (iflist); node; nextnode (node))
  883.     {
  884.       ifp = getdata (node);
  885.       rip_enable_apply (ifp);
  886.     }
  887. }
  888. int
  889. rip_neighbor_lookup (struct sockaddr_in *from)
  890. {
  891.   struct prefix_ipv4 p;
  892.   struct route_node *node;
  893.   memset (&p, 0, sizeof (struct prefix_ipv4));
  894.   p.family = AF_INET;
  895.   p.prefix = from->sin_addr;
  896.   p.prefixlen = IPV4_MAX_BITLEN;
  897.   node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
  898.   if (node)
  899.     {
  900.       route_unlock_node (node);
  901.       return 1;
  902.     }
  903.   return 0;
  904. }
  905. /* Add new RIP neighbor to the neighbor tree. */
  906. int
  907. rip_neighbor_add (struct prefix_ipv4 *p)
  908. {
  909.   struct route_node *node;
  910.   node = route_node_get (rip->neighbor, (struct prefix *) p);
  911.   if (node->info)
  912.     return -1;
  913.   node->info = rip->neighbor;
  914.   return 0;
  915. }
  916. /* Delete RIP neighbor from the neighbor tree. */
  917. int
  918. rip_neighbor_delete (struct prefix_ipv4 *p)
  919. {
  920.   struct route_node *node;
  921.   /* Lock for look up. */
  922.   node = route_node_lookup (rip->neighbor, (struct prefix *) p);
  923.   if (! node)
  924.     return -1;
  925.   
  926.   node->info = NULL;
  927.   /* Unlock lookup lock. */
  928.   route_unlock_node (node);
  929.   /* Unlock real neighbor information lock. */
  930.   route_unlock_node (node);
  931.   return 0;
  932. }
  933. /* Clear all network and neighbor configuration. */
  934. void
  935. rip_clean_network ()
  936. {
  937.   int i;
  938.   char *str;
  939.   struct route_node *rn;
  940.   /* rip_enable_network. */
  941.   for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
  942.     if (rn->info)
  943.       {
  944. rn->info = NULL;
  945. route_unlock_node (rn);
  946.       }
  947.   /* rip_enable_interface. */
  948.   for (i = 0; i < vector_max (rip_enable_interface); i++)
  949.     if ((str = vector_slot (rip_enable_interface, i)) != NULL)
  950.       {
  951. free (str);
  952. vector_slot (rip_enable_interface, i) = NULL;
  953.       }
  954. }
  955. /* Utility function for looking up passive interface settings. */
  956. int
  957. rip_passive_interface_lookup (char *ifname)
  958. {
  959.   int i;
  960.   char *str;
  961.   for (i = 0; i < vector_max (Vrip_passive_interface); i++)
  962.     if ((str = vector_slot (Vrip_passive_interface, i)) != NULL)
  963.       if (strcmp (str, ifname) == 0)
  964. return i;
  965.   return -1;
  966. }
  967. void
  968. rip_passive_interface_apply (struct interface *ifp)
  969. {
  970.   int ret;
  971.   struct rip_interface *ri;
  972.   ri = ifp->info;
  973.   ret = rip_passive_interface_lookup (ifp->name);
  974.   if (ret < 0)
  975.     ri->passive = 0;
  976.   else
  977.     ri->passive = 1;
  978. }
  979. void
  980. rip_passive_interface_apply_all ()
  981. {
  982.   struct interface *ifp;
  983.   listnode node;
  984.   for (node = listhead (iflist); node; nextnode (node))
  985.     {
  986.       ifp = getdata (node);
  987.       rip_passive_interface_apply (ifp);
  988.     }
  989. }
  990. /* Passive interface. */
  991. int
  992. rip_passive_interface_set (struct vty *vty, char *ifname)
  993. {
  994.   if (rip_passive_interface_lookup (ifname) >= 0)
  995.     return CMD_WARNING;
  996.   vector_set (Vrip_passive_interface, strdup (ifname));
  997.   rip_passive_interface_apply_all ();
  998.   return CMD_SUCCESS;
  999. }
  1000. int
  1001. rip_passive_interface_unset (struct vty *vty, char *ifname)
  1002. {
  1003.   int i;
  1004.   char *str;
  1005.   i = rip_passive_interface_lookup (ifname);
  1006.   if (i < 0)
  1007.     return CMD_WARNING;
  1008.   str = vector_slot (Vrip_passive_interface, i);
  1009.   free (str);
  1010.   vector_unset (Vrip_passive_interface, i);
  1011.   rip_passive_interface_apply_all ();
  1012.   return CMD_SUCCESS;
  1013. }
  1014. /* Free all configured RIP passive-interface settings. */
  1015. void
  1016. rip_passive_interface_clean ()
  1017. {
  1018.   int i;
  1019.   char *str;
  1020.   for (i = 0; i < vector_max (Vrip_passive_interface); i++)
  1021.     if ((str = vector_slot (Vrip_passive_interface, i)) != NULL)
  1022.       {
  1023. free (str);
  1024. vector_slot (Vrip_passive_interface, i) = NULL;
  1025.       }
  1026.   rip_passive_interface_apply_all ();
  1027. }
  1028. /* RIP enable network or interface configuration. */
  1029. DEFUN (rip_network,
  1030.        rip_network_cmd,
  1031.        "network (A.B.C.D/M|WORD)",
  1032.        "Enable routing on an IP networkn"
  1033.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1034.        "Interface namen")
  1035. {
  1036.   int ret;
  1037.   struct prefix_ipv4 p;
  1038.   ret = str2prefix_ipv4 (argv[0], &p);
  1039.   if (ret)
  1040.     ret = rip_enable_network_add ((struct prefix *) &p);
  1041.   else
  1042.     ret = rip_enable_if_add (argv[0]);
  1043.   if (ret < 0)
  1044.     {
  1045.       vty_out (vty, "There is a same network configuration %s%s", argv[0],
  1046.        VTY_NEWLINE);
  1047.       return CMD_WARNING;
  1048.     }
  1049.   rip_enable_apply_all ();
  1050.   return CMD_SUCCESS;
  1051. }
  1052. /* RIP enable network or interface configuration. */
  1053. DEFUN (no_rip_network,
  1054.        no_rip_network_cmd,
  1055.        "no network (A.B.C.D/M|WORD)",
  1056.        NO_STR
  1057.        "Enable routing on an IP networkn"
  1058.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1059.        "Interface namen")
  1060. {
  1061.   int ret;
  1062.   struct prefix_ipv4 p;
  1063.   ret = str2prefix_ipv4 (argv[0], &p);
  1064.   if (ret)
  1065.     ret = rip_enable_network_delete ((struct prefix *) &p);
  1066.   else
  1067.     ret = rip_enable_if_delete (argv[0]);
  1068.   if (ret < 0)
  1069.     {
  1070.       vty_out (vty, "Can't find network configuration %s%s", argv[0],
  1071.        VTY_NEWLINE);
  1072.       return CMD_WARNING;
  1073.     }
  1074.   rip_enable_apply_all ();
  1075.   return CMD_SUCCESS;
  1076. }
  1077. /* RIP neighbor configuration set. */
  1078. DEFUN (rip_neighbor,
  1079.        rip_neighbor_cmd,
  1080.        "neighbor A.B.C.D",
  1081.        "Specify a neighbor routern"
  1082.        "Neighbor addressn")
  1083. {
  1084.   int ret;
  1085.   struct prefix_ipv4 p;
  1086.   ret = str2prefix_ipv4 (argv[0], &p);
  1087.   if (ret <= 0)
  1088.     {
  1089.       vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
  1090.       return CMD_WARNING;
  1091.     }
  1092.   rip_neighbor_add (&p);
  1093.   
  1094.   return CMD_SUCCESS;
  1095. }
  1096. /* RIP neighbor configuration unset. */
  1097. DEFUN (no_rip_neighbor,
  1098.        no_rip_neighbor_cmd,
  1099.        "no neighbor A.B.C.D",
  1100.        NO_STR
  1101.        "Specify a neighbor routern"
  1102.        "Neighbor addressn")
  1103. {
  1104.   int ret;
  1105.   struct prefix_ipv4 p;
  1106.   ret = str2prefix_ipv4 (argv[0], &p);
  1107.   if (ret <= 0)
  1108.     {
  1109.       vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
  1110.       return CMD_WARNING;
  1111.     }
  1112.   rip_neighbor_delete (&p);
  1113.   
  1114.   return CMD_SUCCESS;
  1115. }
  1116. DEFUN (ip_rip_receive_version,
  1117.        ip_rip_receive_version_cmd,
  1118.        "ip rip receive version (1|2)",
  1119.        IP_STR
  1120.        "Routing Information Protocoln"
  1121.        "Advertisement receptionn"
  1122.        "Version controln"
  1123.        "RIP version 1n"
  1124.        "RIP version 2n")
  1125. {
  1126.   struct interface *ifp;
  1127.   struct rip_interface *ri;
  1128.   ifp = (struct interface *)vty->index;
  1129.   ri = ifp->info;
  1130.   /* Version 1. */
  1131.   if (atoi (argv[0]) == 1)
  1132.     {
  1133.       ri->ri_receive = RI_RIP_VERSION_1;
  1134.       return CMD_SUCCESS;
  1135.     }
  1136.   if (atoi (argv[0]) == 2)
  1137.     {
  1138.       ri->ri_receive = RI_RIP_VERSION_2;
  1139.       return CMD_SUCCESS;
  1140.     }
  1141.   return CMD_WARNING;
  1142. }
  1143. DEFUN (ip_rip_receive_version_1,
  1144.        ip_rip_receive_version_1_cmd,
  1145.        "ip rip receive version 1 2",
  1146.        IP_STR
  1147.        "Routing Information Protocoln"
  1148.        "Advertisement receptionn"
  1149.        "Version controln"
  1150.        "RIP version 1n"
  1151.        "RIP version 2n")
  1152. {
  1153.   struct interface *ifp;
  1154.   struct rip_interface *ri;
  1155.   ifp = (struct interface *)vty->index;
  1156.   ri = ifp->info;
  1157.   /* Version 1 and 2. */
  1158.   ri->ri_receive = RI_RIP_VERSION_1_AND_2;
  1159.   return CMD_SUCCESS;
  1160. }
  1161. DEFUN (ip_rip_receive_version_2,
  1162.        ip_rip_receive_version_2_cmd,
  1163.        "ip rip receive version 2 1",
  1164.        IP_STR
  1165.        "Routing Information Protocoln"
  1166.        "Advertisement receptionn"
  1167.        "Version controln"
  1168.        "RIP version 2n"
  1169.        "RIP version 1n")
  1170. {
  1171.   struct interface *ifp;
  1172.   struct rip_interface *ri;
  1173.   ifp = (struct interface *)vty->index;
  1174.   ri = ifp->info;
  1175.   /* Version 1 and 2. */
  1176.   ri->ri_receive = RI_RIP_VERSION_1_AND_2;
  1177.   return CMD_SUCCESS;
  1178. }
  1179. DEFUN (no_ip_rip_receive_version,
  1180.        no_ip_rip_receive_version_cmd,
  1181.        "no ip rip receive version",
  1182.        NO_STR
  1183.        IP_STR
  1184.        "Routing Information Protocoln"
  1185.        "Advertisement receptionn"
  1186.        "Version controln")
  1187. {
  1188.   struct interface *ifp;
  1189.   struct rip_interface *ri;
  1190.   ifp = (struct interface *)vty->index;
  1191.   ri = ifp->info;
  1192.   ri->ri_receive = RI_RIP_UNSPEC;
  1193.   return CMD_SUCCESS;
  1194. }
  1195. ALIAS (no_ip_rip_receive_version,
  1196.        no_ip_rip_receive_version_num_cmd,
  1197.        "no ip rip receive version (1|2)",
  1198.        NO_STR
  1199.        IP_STR
  1200.        "Routing Information Protocoln"
  1201.        "Advertisement receptionn"
  1202.        "Version controln"
  1203.        "Version 1n"
  1204.        "Version 2n");
  1205. DEFUN (ip_rip_send_version,
  1206.        ip_rip_send_version_cmd,
  1207.        "ip rip send version (1|2)",
  1208.        IP_STR
  1209.        "Routing Information Protocoln"
  1210.        "Advertisement transmissionn"
  1211.        "Version controln"
  1212.        "RIP version 1n"
  1213.        "RIP version 2n")
  1214. {
  1215.   struct interface *ifp;
  1216.   struct rip_interface *ri;
  1217.   ifp = (struct interface *)vty->index;
  1218.   ri = ifp->info;
  1219.   /* Version 1. */
  1220.   if (atoi (argv[0]) == 1)
  1221.     {
  1222.       ri->ri_send = RI_RIP_VERSION_1;
  1223.       return CMD_SUCCESS;
  1224.     }
  1225.   if (atoi (argv[0]) == 2)
  1226.     {
  1227.       ri->ri_send = RI_RIP_VERSION_2;
  1228.       return CMD_SUCCESS;
  1229.     }
  1230.   return CMD_WARNING;
  1231. }
  1232. DEFUN (ip_rip_send_version_1,
  1233.        ip_rip_send_version_1_cmd,
  1234.        "ip rip send version 1 2",
  1235.        IP_STR
  1236.        "Routing Information Protocoln"
  1237.        "Advertisement transmissionn"
  1238.        "Version controln"
  1239.        "RIP version 1n"
  1240.        "RIP version 2n")
  1241. {
  1242.   struct interface *ifp;
  1243.   struct rip_interface *ri;
  1244.   ifp = (struct interface *)vty->index;
  1245.   ri = ifp->info;
  1246.   /* Version 1 and 2. */
  1247.   ri->ri_send = RI_RIP_VERSION_1_AND_2;
  1248.   return CMD_SUCCESS;
  1249. }
  1250. DEFUN (ip_rip_send_version_2,
  1251.        ip_rip_send_version_2_cmd,
  1252.        "ip rip send version 2 1",
  1253.        IP_STR
  1254.        "Routing Information Protocoln"
  1255.        "Advertisement transmissionn"
  1256.        "Version controln"
  1257.        "RIP version 2n"
  1258.        "RIP version 1n")
  1259. {
  1260.   struct interface *ifp;
  1261.   struct rip_interface *ri;
  1262.   ifp = (struct interface *)vty->index;
  1263.   ri = ifp->info;
  1264.   /* Version 1 and 2. */
  1265.   ri->ri_send = RI_RIP_VERSION_1_AND_2;
  1266.   return CMD_SUCCESS;
  1267. }
  1268. DEFUN (no_ip_rip_send_version,
  1269.        no_ip_rip_send_version_cmd,
  1270.        "no ip rip send version",
  1271.        NO_STR
  1272.        IP_STR
  1273.        "Routing Information Protocoln"
  1274.        "Advertisement transmissionn"
  1275.        "Version controln")
  1276. {
  1277.   struct interface *ifp;
  1278.   struct rip_interface *ri;
  1279.   ifp = (struct interface *)vty->index;
  1280.   ri = ifp->info;
  1281.   ri->ri_send = RI_RIP_UNSPEC;
  1282.   return CMD_SUCCESS;
  1283. }
  1284. ALIAS (no_ip_rip_send_version,
  1285.        no_ip_rip_send_version_num_cmd,
  1286.        "no ip rip send version (1|2)",
  1287.        NO_STR
  1288.        IP_STR
  1289.        "Routing Information Protocoln"
  1290.        "Advertisement transmissionn"
  1291.        "Version controln"
  1292.        "Version 1n"
  1293.        "Version 2n");
  1294. DEFUN (ip_rip_authentication_mode,
  1295.        ip_rip_authentication_mode_cmd,
  1296.        "ip rip authentication mode (md5|text)",
  1297.        IP_STR
  1298.        "Routing Information Protocoln"
  1299.        "Authentication controln"
  1300.        "Authentication moden"
  1301.        "Keyed message digestn"
  1302.        "Clear text authenticationn")
  1303. {
  1304.   struct interface *ifp;
  1305.   struct rip_interface *ri;
  1306.   ifp = (struct interface *)vty->index;
  1307.   ri = ifp->info;
  1308.   if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
  1309.     ri->auth_type = RIP_AUTH_MD5;
  1310.   else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
  1311.     ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
  1312.   else
  1313.     {
  1314.       vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
  1315.       return CMD_WARNING;
  1316.     }
  1317.   return CMD_SUCCESS;
  1318. }
  1319. DEFUN (no_ip_rip_authentication_mode,
  1320.        no_ip_rip_authentication_mode_cmd,
  1321.        "no ip rip authentication mode",
  1322.        NO_STR
  1323.        IP_STR
  1324.        "Routing Information Protocoln"
  1325.        "Authentication controln"
  1326.        "Authentication moden")
  1327. {
  1328.   struct interface *ifp;
  1329.   struct rip_interface *ri;
  1330.   ifp = (struct interface *)vty->index;
  1331.   ri = ifp->info;
  1332.   /* ri->auth_type = RIP_NO_AUTH; */
  1333.   ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
  1334.   return CMD_SUCCESS;
  1335. }
  1336. ALIAS (no_ip_rip_authentication_mode,
  1337.        no_ip_rip_authentication_mode_type_cmd,
  1338.        "no ip rip authentication mode (md5|text)",
  1339.        NO_STR
  1340.        IP_STR
  1341.        "Routing Information Protocoln"
  1342.        "Authentication controln"
  1343.        "Authentication moden"
  1344.        "Keyed message digestn"
  1345.        "Clear text authenticationn");
  1346. DEFUN (ip_rip_authentication_string,
  1347.        ip_rip_authentication_string_cmd,
  1348.        "ip rip authentication string LINE",
  1349.        IP_STR
  1350.        "Routing Information Protocoln"
  1351.        "Authentication controln"
  1352.        "Authentication stringn"
  1353.        "Authentication stringn")
  1354. {
  1355.   struct interface *ifp;
  1356.   struct rip_interface *ri;
  1357.   ifp = (struct interface *)vty->index;
  1358.   ri = ifp->info;
  1359.   if (strlen (argv[0]) > 16)
  1360.     {
  1361.       vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
  1362.        VTY_NEWLINE);
  1363.       return CMD_WARNING;
  1364.     }
  1365.   if (ri->key_chain)
  1366.     {
  1367.       vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
  1368.       return CMD_WARNING;
  1369.     }
  1370.   if (ri->auth_str)
  1371.     free (ri->auth_str);
  1372.   ri->auth_str = strdup (argv[0]);
  1373.   return CMD_SUCCESS;
  1374. }
  1375. DEFUN (no_ip_rip_authentication_string,
  1376.        no_ip_rip_authentication_string_cmd,
  1377.        "no ip rip authentication string",
  1378.        NO_STR
  1379.        IP_STR
  1380.        "Routing Information Protocoln"
  1381.        "Authentication controln"
  1382.        "Authentication stringn")
  1383. {
  1384.   struct interface *ifp;
  1385.   struct rip_interface *ri;
  1386.   ifp = (struct interface *)vty->index;
  1387.   ri = ifp->info;
  1388.   if (ri->auth_str)
  1389.     free (ri->auth_str);
  1390.   ri->auth_str = NULL;
  1391.   return CMD_SUCCESS;
  1392. }
  1393. ALIAS (no_ip_rip_authentication_string,
  1394.        no_ip_rip_authentication_string2_cmd,
  1395.        "no ip rip authentication string LINE",
  1396.        NO_STR
  1397.        IP_STR
  1398.        "Routing Information Protocoln"
  1399.        "Authentication controln"
  1400.        "Authentication stringn"
  1401.        "Authentication stringn");
  1402. DEFUN (ip_rip_authentication_key_chain,
  1403.        ip_rip_authentication_key_chain_cmd,
  1404.        "ip rip authentication key-chain LINE",
  1405.        IP_STR
  1406.        "Routing Information Protocoln"
  1407.        "Authentication controln"
  1408.        "Authentication key-chainn"
  1409.        "name of key-chainn")
  1410. {
  1411.   struct interface *ifp;
  1412.   struct rip_interface *ri;
  1413.   ifp = (struct interface *) vty->index;
  1414.   ri = ifp->info;
  1415.   if (ri->auth_str)
  1416.     {
  1417.       vty_out (vty, "%% authentication string configuration exists%s",
  1418.        VTY_NEWLINE);
  1419.       return CMD_WARNING;
  1420.     }
  1421.   if (ri->key_chain)
  1422.     free (ri->key_chain);
  1423.   ri->key_chain = strdup (argv[0]);
  1424.   return CMD_SUCCESS;
  1425. }
  1426. DEFUN (no_ip_rip_authentication_key_chain,
  1427.        no_ip_rip_authentication_key_chain_cmd,
  1428.        "no ip rip authentication key-chain",
  1429.        NO_STR
  1430.        IP_STR
  1431.        "Routing Information Protocoln"
  1432.        "Authentication controln"
  1433.        "Authentication key-chainn")
  1434. {
  1435.   struct interface *ifp;
  1436.   struct rip_interface *ri;
  1437.   ifp = (struct interface *) vty->index;
  1438.   ri = ifp->info;
  1439.   if (ri->key_chain)
  1440.     free (ri->key_chain);
  1441.   ri->key_chain = NULL;
  1442.   return CMD_SUCCESS;
  1443. }
  1444. ALIAS (no_ip_rip_authentication_key_chain,
  1445.        no_ip_rip_authentication_key_chain2_cmd,
  1446.        "no ip rip authentication key-chain LINE",
  1447.        NO_STR
  1448.        IP_STR
  1449.        "Routing Information Protocoln"
  1450.        "Authentication controln"
  1451.        "Authentication key-chainn"
  1452.        "name of key-chainn");
  1453. DEFUN (rip_split_horizon,
  1454.        rip_split_horizon_cmd,
  1455.        "ip split-horizon",
  1456.        IP_STR
  1457.        "Perform split horizonn")
  1458. {
  1459.   struct interface *ifp;
  1460.   struct rip_interface *ri;
  1461.   ifp = vty->index;
  1462.   ri = ifp->info;
  1463.   ri->split_horizon = 1;
  1464.   return CMD_SUCCESS;
  1465. }
  1466. DEFUN (no_rip_split_horizon,
  1467.        no_rip_split_horizon_cmd,
  1468.        "no ip split-horizon",
  1469.        NO_STR
  1470.        IP_STR
  1471.        "Perform split horizonn")
  1472. {
  1473.   struct interface *ifp;
  1474.   struct rip_interface *ri;
  1475.   ifp = vty->index;
  1476.   ri = ifp->info;
  1477.   ri->split_horizon = 0;
  1478.   return CMD_SUCCESS;
  1479. }
  1480. DEFUN (rip_passive_interface,
  1481.        rip_passive_interface_cmd,
  1482.        "passive-interface IFNAME",
  1483.        "Suppress routing updates on an interfacen"
  1484.        "Interface namen")
  1485. {
  1486.   return rip_passive_interface_set (vty, argv[0]);
  1487. }
  1488. DEFUN (no_rip_passive_interface,
  1489.        no_rip_passive_interface_cmd,
  1490.        "no passive-interface IFNAME",
  1491.        NO_STR
  1492.        "Suppress routing updates on an interfacen"
  1493.        "Interface namen")
  1494. {
  1495.   return rip_passive_interface_unset (vty, argv[0]);
  1496. }
  1497. /* Write rip configuration of each interface. */
  1498. int
  1499. rip_interface_config_write (struct vty *vty)
  1500. {
  1501.   listnode node;
  1502.   struct interface *ifp;
  1503.   for (node = listhead (iflist); node; nextnode (node))
  1504.     {
  1505.       struct rip_interface *ri;
  1506.       ifp = getdata (node);
  1507.       ri = ifp->info;
  1508.       vty_out (vty, "interface %s%s", ifp->name,
  1509.        VTY_NEWLINE);
  1510.       if (ifp->desc)
  1511. vty_out (vty, " description %s%s", ifp->desc,
  1512.  VTY_NEWLINE);
  1513.       /* Split horizon. */
  1514.       if (ri->split_horizon != ri->split_horizon_default)
  1515. {
  1516.   if (ri->split_horizon)
  1517.     vty_out (vty, " ip split-horizon%s", VTY_NEWLINE);
  1518.   else
  1519.     vty_out (vty, " no ip split-horizon%s", VTY_NEWLINE);
  1520. }
  1521.       /* RIP version setting. */
  1522.       if (ri->ri_send != RI_RIP_UNSPEC)
  1523. vty_out (vty, " ip rip send version %s%s",
  1524.  lookup (ri_version_msg, ri->ri_send),
  1525.  VTY_NEWLINE);
  1526.       if (ri->ri_receive != RI_RIP_UNSPEC)
  1527. vty_out (vty, " ip rip receive version %s%s",
  1528.  lookup (ri_version_msg, ri->ri_receive),
  1529.  VTY_NEWLINE);
  1530.       /* RIP authentication. */
  1531.       if (ri->auth_type == RIP_AUTH_MD5)
  1532. vty_out (vty, " ip rip authentication mode md5%s", VTY_NEWLINE);
  1533.       if (ri->auth_str)
  1534. vty_out (vty, " ip rip authentication string %s%s",
  1535.  ri->auth_str, VTY_NEWLINE);
  1536.       if (ri->key_chain)
  1537. vty_out (vty, " ip rip authentication key-chain %s%s",
  1538.  ri->key_chain, VTY_NEWLINE);
  1539.       vty_out (vty, "!%s", VTY_NEWLINE);
  1540.     }
  1541.   return 0;
  1542. }
  1543. int
  1544. config_write_rip_network (struct vty *vty, int config_mode)
  1545. {
  1546.   int i;
  1547.   char *ifname;
  1548.   struct route_node *node;
  1549.   /* Network type RIP enable interface statement. */
  1550.   for (node = route_top (rip_enable_network); node; node = route_next (node))
  1551.     if (node->info)
  1552.       vty_out (vty, "%s%s/%d%s", 
  1553.        config_mode ? " network " : "    ",
  1554.        inet_ntoa (node->p.u.prefix4),
  1555.        node->p.prefixlen,
  1556.        VTY_NEWLINE);
  1557.   /* Interface name RIP enable statement. */
  1558.   for (i = 0; i < vector_max (rip_enable_interface); i++)
  1559.     if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
  1560.       vty_out (vty, "%s%s%s",
  1561.        config_mode ? " network " : "    ",
  1562.        ifname,
  1563.        VTY_NEWLINE);
  1564.   /* RIP neighbors listing. */
  1565.   for (node = route_top (rip->neighbor); node; node = route_next (node))
  1566.     if (node->info)
  1567.       vty_out (vty, "%s%s%s", 
  1568.        config_mode ? " neighbor " : "    ",
  1569.        inet_ntoa (node->p.u.prefix4),
  1570.        VTY_NEWLINE);
  1571.   /* RIP passive interface listing. */
  1572.   if (config_mode)
  1573.     for (i = 0; i < vector_max (Vrip_passive_interface); i++)
  1574.       if ((ifname = vector_slot (Vrip_passive_interface, i)) != NULL)
  1575. vty_out (vty, " passive-interface %s%s", ifname, VTY_NEWLINE);
  1576.   return 0;
  1577. }
  1578. struct cmd_node interface_node =
  1579. {
  1580.   INTERFACE_NODE,
  1581.   "%s(config-if)# ",
  1582.   1,
  1583. };
  1584. /* Called when interface structure allocated. */
  1585. int
  1586. rip_interface_new_hook (struct interface *ifp)
  1587. {
  1588.   ifp->info = rip_interface_new ();
  1589.   return 0;
  1590. }
  1591. /* Called when interface structure deleted. */
  1592. int
  1593. rip_interface_delete_hook (struct interface *ifp)
  1594. {
  1595.   XFREE (MTYPE_RIP_INTERFACE, ifp->info);
  1596.   return 0;
  1597. }
  1598. /* Allocate and initialize interface vector. */
  1599. void
  1600. rip_if_init ()
  1601. {
  1602.   /* Default initial size of interface vector. */
  1603.   if_init();
  1604.   if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
  1605.   if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
  1606.   
  1607.   /* RIP network init. */
  1608.   rip_enable_interface = vector_init (1);
  1609.   rip_enable_network = route_table_init ();
  1610.   /* RIP passive interface. */
  1611.   Vrip_passive_interface = vector_init (1);
  1612.   /* Install interface node. */
  1613.   install_node (&interface_node, rip_interface_config_write);
  1614.   /* Install commands. */
  1615.   install_element (CONFIG_NODE, &interface_cmd);
  1616.   install_default (INTERFACE_NODE);
  1617.   install_element (INTERFACE_NODE, &interface_desc_cmd);
  1618.   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
  1619.   install_element (RIP_NODE, &rip_network_cmd);
  1620.   install_element (RIP_NODE, &no_rip_network_cmd);
  1621.   install_element (RIP_NODE, &rip_neighbor_cmd);
  1622.   install_element (RIP_NODE, &no_rip_neighbor_cmd);
  1623.   install_element (RIP_NODE, &rip_passive_interface_cmd);
  1624.   install_element (RIP_NODE, &no_rip_passive_interface_cmd);
  1625.   install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
  1626.   install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
  1627.   install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
  1628.   install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
  1629.   install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
  1630.   install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
  1631.   install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
  1632.   install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
  1633.   install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
  1634.   install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
  1635.   install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
  1636.   install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
  1637.   install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
  1638.   install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
  1639.   install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
  1640.   install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
  1641.   install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
  1642.   install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
  1643.   install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
  1644.   install_element (INTERFACE_NODE, &rip_split_horizon_cmd);
  1645.   install_element (INTERFACE_NODE, &no_rip_split_horizon_cmd);
  1646. }