File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ripd / rip_interface.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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: 
   22: #include <zebra.h>
   23: 
   24: #include "command.h"
   25: #include "if.h"
   26: #include "sockunion.h"
   27: #include "prefix.h"
   28: #include "memory.h"
   29: #include "network.h"
   30: #include "table.h"
   31: #include "log.h"
   32: #include "stream.h"
   33: #include "thread.h"
   34: #include "zclient.h"
   35: #include "filter.h"
   36: #include "sockopt.h"
   37: #include "privs.h"
   38: 
   39: #include "zebra/connected.h"
   40: 
   41: #include "ripd/ripd.h"
   42: #include "ripd/rip_debug.h"
   43: #include "ripd/rip_interface.h"
   44: 
   45: /* static prototypes */
   46: static void rip_enable_apply (struct interface *);
   47: static void rip_passive_interface_apply (struct interface *);
   48: static int rip_if_down(struct interface *ifp);
   49: static int rip_enable_if_lookup (const char *ifname);
   50: static int rip_enable_network_lookup2 (struct connected *connected);
   51: static void rip_enable_apply_all (void);
   52: 
   53: struct message ri_version_msg[] = 
   54: {
   55:   {RI_RIP_VERSION_1,       "1"},
   56:   {RI_RIP_VERSION_2,       "2"},
   57:   {RI_RIP_VERSION_1_AND_2, "1 2"},
   58: };
   59: 
   60: extern struct zebra_privs_t ripd_privs;
   61: 
   62: /* RIP enabled network vector. */
   63: vector rip_enable_interface;
   64: 
   65: /* RIP enabled interface table. */
   66: struct route_table *rip_enable_network;
   67: 
   68: /* Vector to store passive-interface name. */
   69: static int passive_default;	/* are we in passive-interface default mode? */
   70: vector Vrip_passive_nondefault;
   71: 
   72: /* Join to the RIP version 2 multicast group. */
   73: static int
   74: ipv4_multicast_join (int sock, 
   75: 		     struct in_addr group, 
   76: 		     struct in_addr ifa,
   77: 		     unsigned int ifindex)
   78: {
   79:   int ret;
   80: 
   81:   ret = setsockopt_ipv4_multicast (sock,
   82: 				   IP_ADD_MEMBERSHIP, 
   83: 				   group.s_addr, 
   84: 				   ifindex); 
   85: 
   86:   if (ret < 0) 
   87:     zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
   88: 	  safe_strerror (errno));
   89: 
   90:   return ret;
   91: }
   92: 
   93: /* Leave from the RIP version 2 multicast group. */
   94: static int
   95: ipv4_multicast_leave (int sock, 
   96: 		      struct in_addr group, 
   97: 		      struct in_addr ifa,
   98: 		      unsigned int ifindex)
   99: {
  100:   int ret;
  101: 
  102:   ret = setsockopt_ipv4_multicast (sock,
  103: 				   IP_DROP_MEMBERSHIP, 
  104: 				   group.s_addr, 
  105: 				   ifindex);
  106: 
  107:   if (ret < 0) 
  108:     zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
  109: 
  110:   return ret;
  111: }
  112: 
  113: /* Allocate new RIP's interface configuration. */
  114: static struct rip_interface *
  115: rip_interface_new (void)
  116: {
  117:   struct rip_interface *ri;
  118: 
  119:   ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
  120: 
  121:   /* Default authentication type is simple password for Cisco
  122:      compatibility. */
  123:   ri->auth_type = RIP_NO_AUTH;
  124:   ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
  125: 
  126:   /* Set default split-horizon behavior.  If the interface is Frame
  127:      Relay or SMDS is enabled, the default value for split-horizon is
  128:      off.  But currently Zebra does detect Frame Relay or SMDS
  129:      interface.  So all interface is set to split horizon.  */
  130:   ri->split_horizon_default = RIP_SPLIT_HORIZON;
  131:   ri->split_horizon = ri->split_horizon_default;
  132: 
  133:   return ri;
  134: }
  135: 
  136: void
  137: rip_interface_multicast_set (int sock, struct connected *connected)
  138: {
  139:   assert (connected != NULL);
  140:   
  141:   if (setsockopt_ipv4_multicast_if (sock, connected->ifp->ifindex) < 0)
  142:     {
  143:       zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
  144: 		 "ifindex %d for interface %s",
  145: 		 sock, connected->ifp->ifindex,
  146: 		 connected->ifp->name);
  147:     }
  148:   
  149:   return;
  150: }
  151: 
  152: /* Send RIP request packet to specified interface. */
  153: static void
  154: rip_request_interface_send (struct interface *ifp, u_char version)
  155: {
  156:   struct sockaddr_in to;
  157: 
  158:   /* RIPv2 support multicast. */
  159:   if (version == RIPv2 && if_is_multicast (ifp))
  160:     {
  161:       
  162:       if (IS_RIP_DEBUG_EVENT)
  163: 	zlog_debug ("multicast request on %s", ifp->name);
  164: 
  165:       rip_request_send (NULL, ifp, version, NULL);
  166:       return;
  167:     }
  168: 
  169:   /* RIPv1 and non multicast interface. */
  170:   if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
  171:     {
  172:       struct listnode *cnode, *cnnode;
  173:       struct connected *connected;
  174: 
  175:       if (IS_RIP_DEBUG_EVENT)
  176: 	zlog_debug ("broadcast request to %s", ifp->name);
  177: 
  178:       for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
  179: 	{
  180: 	  if (connected->address->family == AF_INET)
  181: 	    {
  182: 	      memset (&to, 0, sizeof (struct sockaddr_in));
  183: 	      to.sin_port = htons (RIP_PORT_DEFAULT);
  184:               if (connected->destination)
  185:                 /* use specified broadcast or peer destination addr */
  186:                 to.sin_addr = connected->destination->u.prefix4;
  187:               else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
  188: 	        /* calculate the appropriate broadcast address */
  189:                 to.sin_addr.s_addr =
  190: 		  ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
  191: 				      connected->address->prefixlen);
  192: 	      else
  193: 		/* do not know where to send the packet */
  194: 	        continue;
  195: 
  196: 	      if (IS_RIP_DEBUG_EVENT)
  197: 		zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
  198: 	      
  199: 	      rip_request_send (&to, ifp, version, connected);
  200: 	    }
  201: 	}
  202:     }
  203: }
  204: 
  205: /* This will be executed when interface goes up. */
  206: static void
  207: rip_request_interface (struct interface *ifp)
  208: {
  209:   struct rip_interface *ri;
  210: 
  211:   /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
  212:   if (if_is_loopback (ifp))
  213:     return;
  214: 
  215:   /* If interface is down, don't send RIP packet. */
  216:   if (! if_is_operative (ifp))
  217:     return;
  218: 
  219:   /* Fetch RIP interface information. */
  220:   ri = ifp->info;
  221: 
  222: 
  223:   /* If there is no version configuration in the interface,
  224:      use rip's version setting. */
  225:   {
  226:     int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
  227: 		 rip->version_send : ri->ri_send);
  228:     if (vsend & RIPv1)
  229:       rip_request_interface_send (ifp, RIPv1);
  230:     if (vsend & RIPv2)
  231:       rip_request_interface_send (ifp, RIPv2);
  232:   }
  233: }
  234: 
  235: #if 0
  236: /* Send RIP request to the neighbor. */
  237: static void
  238: rip_request_neighbor (struct in_addr addr)
  239: {
  240:   struct sockaddr_in to;
  241: 
  242:   memset (&to, 0, sizeof (struct sockaddr_in));
  243:   to.sin_port = htons (RIP_PORT_DEFAULT);
  244:   to.sin_addr = addr;
  245: 
  246:   rip_request_send (&to, NULL, rip->version_send, NULL);
  247: }
  248: 
  249: /* Request routes at all interfaces. */
  250: static void
  251: rip_request_neighbor_all (void)
  252: {
  253:   struct route_node *rp;
  254: 
  255:   if (! rip)
  256:     return;
  257: 
  258:   if (IS_RIP_DEBUG_EVENT)
  259:     zlog_debug ("request to the all neighbor");
  260: 
  261:   /* Send request to all neighbor. */
  262:   for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
  263:     if (rp->info)
  264:       rip_request_neighbor (rp->p.u.prefix4);
  265: }
  266: #endif
  267: 
  268: /* Multicast packet receive socket. */
  269: static int
  270: rip_multicast_join (struct interface *ifp, int sock)
  271: {
  272:   struct listnode *cnode;
  273:   struct connected *ifc;
  274: 
  275:   if (if_is_operative (ifp) && if_is_multicast (ifp))
  276:     {
  277:       if (IS_RIP_DEBUG_EVENT)
  278: 	zlog_debug ("multicast join at %s", ifp->name);
  279: 
  280:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
  281: 	{
  282: 	  struct prefix_ipv4 *p;
  283: 	  struct in_addr group;
  284: 	      
  285: 	  p = (struct prefix_ipv4 *) ifc->address;
  286:       
  287: 	  if (p->family != AF_INET)
  288: 	    continue;
  289:       
  290: 	  group.s_addr = htonl (INADDR_RIP_GROUP);
  291: 	  if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
  292: 	    return -1;
  293: 	  else
  294: 	    return 0;
  295: 	}
  296:     }
  297:   return 0;
  298: }
  299: 
  300: /* Leave from multicast group. */
  301: static void
  302: rip_multicast_leave (struct interface *ifp, int sock)
  303: {
  304:   struct listnode *cnode;
  305:   struct connected *connected;
  306: 
  307:   if (if_is_up (ifp) && if_is_multicast (ifp))
  308:     {
  309:       if (IS_RIP_DEBUG_EVENT)
  310: 	zlog_debug ("multicast leave from %s", ifp->name);
  311: 
  312:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
  313: 	{
  314: 	  struct prefix_ipv4 *p;
  315: 	  struct in_addr group;
  316:           
  317: 	  p = (struct prefix_ipv4 *) connected->address;
  318: 	  
  319: 	  if (p->family != AF_INET)
  320: 	    continue;
  321:       
  322: 	  group.s_addr = htonl (INADDR_RIP_GROUP);
  323:           if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
  324: 	    return;
  325:         }
  326:     }
  327: }
  328: 
  329: /* Is there and address on interface that I could use ? */
  330: static int
  331: rip_if_ipv4_address_check (struct interface *ifp)
  332: {
  333:   struct listnode *nn;
  334:   struct connected *connected;
  335:   int count = 0;
  336: 
  337:   for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
  338:     {
  339:       struct prefix *p;
  340: 
  341:       p = connected->address;
  342: 
  343:       if (p->family == AF_INET)
  344:         count++;
  345:     }
  346: 						
  347:   return count;
  348: }
  349: 						
  350: 						
  351: 						
  352: 
  353: /* Does this address belongs to me ? */
  354: int
  355: if_check_address (struct in_addr addr)
  356: {
  357:   struct listnode *node;
  358:   struct interface *ifp;
  359:   
  360:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  361:     {
  362:       struct listnode *cnode;
  363:       struct connected *connected;
  364: 
  365:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
  366: 	{
  367: 	  struct prefix_ipv4 *p;
  368: 
  369: 	  p = (struct prefix_ipv4 *) connected->address;
  370: 
  371: 	  if (p->family != AF_INET)
  372: 	    continue;
  373: 
  374: 	  if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
  375: 	    return 1;
  376: 	}
  377:     }
  378:   return 0;
  379: }
  380: 
  381: /* Inteface link down message processing. */
  382: int
  383: rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
  384: {
  385:   struct interface *ifp;
  386:   struct stream *s;
  387: 
  388:   s = zclient->ibuf;  
  389: 
  390:   /* zebra_interface_state_read() updates interface structure in
  391:      iflist. */
  392:   ifp = zebra_interface_state_read(s);
  393: 
  394:   if (ifp == NULL)
  395:     return 0;
  396: 
  397:   rip_if_down(ifp);
  398:  
  399:   if (IS_RIP_DEBUG_ZEBRA)
  400:     zlog_debug ("interface %s index %d flags %llx metric %d mtu %d is down",
  401: 	       ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
  402: 	       ifp->metric, ifp->mtu);
  403: 
  404:   return 0;
  405: }
  406: 
  407: /* Inteface link up message processing */
  408: int
  409: rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
  410: {
  411:   struct interface *ifp;
  412: 
  413:   /* zebra_interface_state_read () updates interface structure in
  414:      iflist. */
  415:   ifp = zebra_interface_state_read (zclient->ibuf);
  416: 
  417:   if (ifp == NULL)
  418:     return 0;
  419: 
  420:   if (IS_RIP_DEBUG_ZEBRA)
  421:     zlog_debug ("interface %s index %d flags %#llx metric %d mtu %d is up",
  422: 	       ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
  423: 	       ifp->metric, ifp->mtu);
  424: 
  425:   /* Check if this interface is RIP enabled or not.*/
  426:   rip_enable_apply (ifp);
  427:  
  428:   /* Check for a passive interface */
  429:   rip_passive_interface_apply (ifp);
  430: 
  431:   /* Apply distribute list to the all interface. */
  432:   rip_distribute_update_interface (ifp);
  433: 
  434:   return 0;
  435: }
  436: 
  437: /* Inteface addition message from zebra. */
  438: int
  439: rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
  440: {
  441:   struct interface *ifp;
  442: 
  443:   ifp = zebra_interface_add_read (zclient->ibuf);
  444: 
  445:   if (IS_RIP_DEBUG_ZEBRA)
  446:     zlog_debug ("interface add %s index %d flags %#llx metric %d mtu %d",
  447: 		ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
  448: 		ifp->metric, ifp->mtu);
  449: 
  450:   /* Check if this interface is RIP enabled or not.*/
  451:   rip_enable_apply (ifp);
  452:  
  453:   /* Check for a passive interface */
  454:   rip_passive_interface_apply (ifp);
  455: 
  456:   /* Apply distribute list to the all interface. */
  457:   rip_distribute_update_interface (ifp);
  458: 
  459:   /* rip_request_neighbor_all (); */
  460: 
  461:   /* Check interface routemap. */
  462:   rip_if_rmap_update_interface (ifp);
  463: 
  464:   return 0;
  465: }
  466: 
  467: int
  468: rip_interface_delete (int command, struct zclient *zclient,
  469: 		      zebra_size_t length)
  470: {
  471:   struct interface *ifp;
  472:   struct stream *s;
  473: 
  474: 
  475:   s = zclient->ibuf;  
  476:   /* zebra_interface_state_read() updates interface structure in iflist */
  477:   ifp = zebra_interface_state_read(s);
  478: 
  479:   if (ifp == NULL)
  480:     return 0;
  481: 
  482:   if (if_is_up (ifp)) {
  483:     rip_if_down(ifp);
  484:   } 
  485:   
  486:   zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
  487: 	    ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
  488: 	    ifp->metric, ifp->mtu);
  489:   
  490:   /* To support pseudo interface do not free interface structure.  */
  491:   /* if_delete(ifp); */
  492:   ifp->ifindex = IFINDEX_INTERNAL;
  493: 
  494:   return 0;
  495: }
  496: 
  497: void
  498: rip_interface_clean (void)
  499: {
  500:   struct listnode *node;
  501:   struct interface *ifp;
  502:   struct rip_interface *ri;
  503: 
  504:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  505:     {
  506:       ri = ifp->info;
  507: 
  508:       ri->enable_network = 0;
  509:       ri->enable_interface = 0;
  510:       ri->running = 0;
  511: 
  512:       if (ri->t_wakeup)
  513: 	{
  514: 	  thread_cancel (ri->t_wakeup);
  515: 	  ri->t_wakeup = NULL;
  516: 	}
  517:     }
  518: }
  519: 
  520: void
  521: rip_interface_reset (void)
  522: {
  523:   struct listnode *node;
  524:   struct interface *ifp;
  525:   struct rip_interface *ri;
  526: 
  527:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  528:     {
  529:       ri = ifp->info;
  530: 
  531:       ri->enable_network = 0;
  532:       ri->enable_interface = 0;
  533:       ri->running = 0;
  534: 
  535:       ri->ri_send = RI_RIP_UNSPEC;
  536:       ri->ri_receive = RI_RIP_UNSPEC;
  537: 
  538:       ri->auth_type = RIP_NO_AUTH;
  539: 
  540:       if (ri->auth_str)
  541: 	{
  542: 	  free (ri->auth_str);
  543: 	  ri->auth_str = NULL;
  544: 	}
  545:       if (ri->key_chain)
  546: 	{
  547: 	  free (ri->key_chain);
  548: 	  ri->key_chain = NULL;
  549: 	}
  550: 
  551:       ri->split_horizon = RIP_NO_SPLIT_HORIZON;
  552:       ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
  553: 
  554:       ri->list[RIP_FILTER_IN] = NULL;
  555:       ri->list[RIP_FILTER_OUT] = NULL;
  556: 
  557:       ri->prefix[RIP_FILTER_IN] = NULL;
  558:       ri->prefix[RIP_FILTER_OUT] = NULL;
  559:       
  560:       if (ri->t_wakeup)
  561: 	{
  562: 	  thread_cancel (ri->t_wakeup);
  563: 	  ri->t_wakeup = NULL;
  564: 	}
  565: 
  566:       ri->recv_badpackets = 0;
  567:       ri->recv_badroutes = 0;
  568:       ri->sent_updates = 0;
  569: 
  570:       ri->passive = 0;
  571:     }
  572: }
  573: 
  574: int
  575: rip_if_down(struct interface *ifp)
  576: {
  577:   struct route_node *rp;
  578:   struct rip_info *rinfo;
  579:   struct rip_interface *ri = NULL;
  580:   if (rip)
  581:     {
  582:       for (rp = route_top (rip->table); rp; rp = route_next (rp))
  583: 	if ((rinfo = rp->info) != NULL)
  584: 	  {
  585: 	    /* Routes got through this interface. */
  586: 	    if (rinfo->ifindex == ifp->ifindex &&
  587: 		rinfo->type == ZEBRA_ROUTE_RIP &&
  588: 		rinfo->sub_type == RIP_ROUTE_RTE)
  589: 	      {
  590: 		rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
  591: 				       &rinfo->nexthop,
  592: 				       rinfo->metric);
  593: 
  594: 		rip_redistribute_delete (rinfo->type,rinfo->sub_type,
  595: 					 (struct prefix_ipv4 *)&rp->p,
  596: 					 rinfo->ifindex);
  597: 	      }
  598: 	    else
  599: 	      {
  600: 		/* All redistributed routes but static and system */
  601: 		if ((rinfo->ifindex == ifp->ifindex) &&
  602: 		    /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
  603: 		    (rinfo->type != ZEBRA_ROUTE_SYSTEM))
  604: 		  rip_redistribute_delete (rinfo->type,rinfo->sub_type,
  605: 					   (struct prefix_ipv4 *)&rp->p,
  606: 					   rinfo->ifindex);
  607: 	      }
  608: 	  }
  609:     }
  610: 	    
  611:   ri = ifp->info;
  612:   
  613:   if (ri->running)
  614:    {
  615:      if (IS_RIP_DEBUG_EVENT)
  616:        zlog_debug ("turn off %s", ifp->name);
  617: 
  618:      /* Leave from multicast group. */
  619:      rip_multicast_leave (ifp, rip->sock);
  620: 
  621:      ri->running = 0;
  622:    }
  623: 
  624:   return 0;
  625: }
  626: 
  627: /* Needed for stop RIP process. */
  628: void
  629: rip_if_down_all ()
  630: {
  631:   struct interface *ifp;
  632:   struct listnode *node, *nnode;
  633: 
  634:   for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
  635:     rip_if_down (ifp);
  636: }
  637: 
  638: static void
  639: rip_apply_address_add (struct connected *ifc)
  640: {
  641:   struct prefix_ipv4 address;
  642:   struct prefix *p;
  643: 
  644:   if (!rip)
  645:     return;
  646: 
  647:   if (! if_is_up(ifc->ifp))
  648:     return;
  649: 
  650:   p = ifc->address;
  651: 
  652:   memset (&address, 0, sizeof (address));
  653:   address.family = p->family;
  654:   address.prefix = p->u.prefix4;
  655:   address.prefixlen = p->prefixlen;
  656:   apply_mask_ipv4(&address);
  657: 
  658:   /* Check if this interface is RIP enabled or not
  659:      or  Check if this address's prefix is RIP enabled */
  660:   if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
  661:       (rip_enable_network_lookup2(ifc) >= 0))
  662:     rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
  663:                          &address, ifc->ifp->ifindex, NULL, 0, 0);
  664: 
  665: }
  666: 
  667: int
  668: rip_interface_address_add (int command, struct zclient *zclient,
  669: 			   zebra_size_t length)
  670: {
  671:   struct connected *ifc;
  672:   struct prefix *p;
  673: 
  674:   ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, 
  675:                                       zclient->ibuf);
  676: 
  677:   if (ifc == NULL)
  678:     return 0;
  679: 
  680:   p = ifc->address;
  681: 
  682:   if (p->family == AF_INET)
  683:     {
  684:       if (IS_RIP_DEBUG_ZEBRA)
  685: 	zlog_debug ("connected address %s/%d is added", 
  686: 		   inet_ntoa (p->u.prefix4), p->prefixlen);
  687: 
  688:       rip_enable_apply(ifc->ifp);
  689:       /* Check if this prefix needs to be redistributed */
  690:       rip_apply_address_add(ifc);
  691: 
  692: #ifdef HAVE_SNMP
  693:       rip_ifaddr_add (ifc->ifp, ifc);
  694: #endif /* HAVE_SNMP */
  695:     }
  696: 
  697:   return 0;
  698: }
  699: 
  700: static void
  701: rip_apply_address_del (struct connected *ifc) {
  702:   struct prefix_ipv4 address;
  703:   struct prefix *p;
  704: 
  705:   if (!rip)
  706:     return;
  707: 
  708:   if (! if_is_up(ifc->ifp))
  709:     return;
  710: 
  711:   p = ifc->address;
  712: 
  713:   memset (&address, 0, sizeof (address));
  714:   address.family = p->family;
  715:   address.prefix = p->u.prefix4;
  716:   address.prefixlen = p->prefixlen;
  717:   apply_mask_ipv4(&address);
  718: 
  719:   rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
  720:                           &address, ifc->ifp->ifindex);
  721: }
  722: 
  723: int
  724: rip_interface_address_delete (int command, struct zclient *zclient,
  725: 			      zebra_size_t length)
  726: {
  727:   struct connected *ifc;
  728:   struct prefix *p;
  729: 
  730:   ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
  731:                                       zclient->ibuf);
  732:   
  733:   if (ifc)
  734:     {
  735:       p = ifc->address;
  736:       if (p->family == AF_INET)
  737: 	{
  738: 	  if (IS_RIP_DEBUG_ZEBRA)
  739: 	    zlog_debug ("connected address %s/%d is deleted",
  740: 		       inet_ntoa (p->u.prefix4), p->prefixlen);
  741: 
  742: #ifdef HAVE_SNMP
  743: 	  rip_ifaddr_delete (ifc->ifp, ifc);
  744: #endif /* HAVE_SNMP */
  745: 
  746: 	  /* Chech wether this prefix needs to be removed */
  747:           rip_apply_address_del(ifc);
  748: 
  749: 	}
  750: 
  751:       connected_free (ifc);
  752: 
  753:     }
  754: 
  755:   return 0;
  756: }
  757: 
  758: /* Check interface is enabled by network statement. */
  759: /* Check wether the interface has at least a connected prefix that
  760:  * is within the ripng_enable_network table. */
  761: static int
  762: rip_enable_network_lookup_if (struct interface *ifp)
  763: {
  764:   struct listnode *node, *nnode;
  765:   struct connected *connected;
  766:   struct prefix_ipv4 address;
  767: 
  768:   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
  769:     {
  770:       struct prefix *p; 
  771:       struct route_node *node;
  772: 
  773:       p = connected->address;
  774: 
  775:       if (p->family == AF_INET)
  776:         {
  777:           address.family = AF_INET;
  778:           address.prefix = p->u.prefix4;
  779:           address.prefixlen = IPV4_MAX_BITLEN;
  780:           
  781:           node = route_node_match (rip_enable_network,
  782:                                    (struct prefix *)&address);
  783:           if (node)
  784:             {
  785:               route_unlock_node (node);
  786:               return 1;
  787:             }
  788:         }
  789:     }
  790:   return -1;
  791: }
  792: 
  793: /* Check wether connected is within the ripng_enable_network table. */
  794: int
  795: rip_enable_network_lookup2 (struct connected *connected)
  796: {
  797:   struct prefix_ipv4 address;
  798:   struct prefix *p;
  799: 
  800:   p = connected->address;
  801: 
  802:   if (p->family == AF_INET) {
  803:     struct route_node *node;
  804: 
  805:     address.family = p->family;
  806:     address.prefix = p->u.prefix4;
  807:     address.prefixlen = IPV4_MAX_BITLEN;
  808: 
  809:     /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
  810:     node = route_node_match (rip_enable_network,
  811:                              (struct prefix *)&address);
  812: 
  813:     if (node) {
  814:       route_unlock_node (node);
  815:       return 1;
  816:     }
  817:   }
  818: 
  819:   return -1;
  820: }
  821: /* Add RIP enable network. */
  822: static int
  823: rip_enable_network_add (struct prefix *p)
  824: {
  825:   struct route_node *node;
  826: 
  827:   node = route_node_get (rip_enable_network, p);
  828: 
  829:   if (node->info)
  830:     {
  831:       route_unlock_node (node);
  832:       return -1;
  833:     }
  834:   else
  835:     node->info = (char *) "enabled";
  836: 
  837:   /* XXX: One should find a better solution than a generic one */
  838:   rip_enable_apply_all();
  839: 
  840:   return 1;
  841: }
  842: 
  843: /* Delete RIP enable network. */
  844: static int
  845: rip_enable_network_delete (struct prefix *p)
  846: {
  847:   struct route_node *node;
  848: 
  849:   node = route_node_lookup (rip_enable_network, p);
  850:   if (node)
  851:     {
  852:       node->info = NULL;
  853: 
  854:       /* Unlock info lock. */
  855:       route_unlock_node (node);
  856: 
  857:       /* Unlock lookup lock. */
  858:       route_unlock_node (node);
  859: 
  860:       /* XXX: One should find a better solution than a generic one */
  861:       rip_enable_apply_all ();
  862: 
  863:       return 1;
  864:     }
  865:   return -1;
  866: }
  867: 
  868: /* Check interface is enabled by ifname statement. */
  869: static int
  870: rip_enable_if_lookup (const char *ifname)
  871: {
  872:   unsigned int i;
  873:   char *str;
  874: 
  875:   for (i = 0; i < vector_active (rip_enable_interface); i++)
  876:     if ((str = vector_slot (rip_enable_interface, i)) != NULL)
  877:       if (strcmp (str, ifname) == 0)
  878: 	return i;
  879:   return -1;
  880: }
  881: 
  882: /* Add interface to rip_enable_if. */
  883: static int
  884: rip_enable_if_add (const char *ifname)
  885: {
  886:   int ret;
  887: 
  888:   ret = rip_enable_if_lookup (ifname);
  889:   if (ret >= 0)
  890:     return -1;
  891: 
  892:   vector_set (rip_enable_interface, strdup (ifname));
  893: 
  894:   rip_enable_apply_all(); /* TODOVJ */
  895: 
  896:   return 1;
  897: }
  898: 
  899: /* Delete interface from rip_enable_if. */
  900: static int
  901: rip_enable_if_delete (const char *ifname)
  902: {
  903:   int index;
  904:   char *str;
  905: 
  906:   index = rip_enable_if_lookup (ifname);
  907:   if (index < 0)
  908:     return -1;
  909: 
  910:   str = vector_slot (rip_enable_interface, index);
  911:   free (str);
  912:   vector_unset (rip_enable_interface, index);
  913: 
  914:   rip_enable_apply_all(); /* TODOVJ */
  915: 
  916:   return 1;
  917: }
  918: 
  919: /* Join to multicast group and send request to the interface. */
  920: static int
  921: rip_interface_wakeup (struct thread *t)
  922: {
  923:   struct interface *ifp;
  924:   struct rip_interface *ri;
  925: 
  926:   /* Get interface. */
  927:   ifp = THREAD_ARG (t);
  928: 
  929:   ri = ifp->info;
  930:   ri->t_wakeup = NULL;
  931: 
  932:   /* Join to multicast group. */
  933:   if (rip_multicast_join (ifp, rip->sock) < 0)
  934:     {
  935:       zlog_err ("multicast join failed, interface %s not running", ifp->name);
  936:       return 0;
  937:     }
  938: 
  939:   /* Set running flag. */
  940:   ri->running = 1;
  941: 
  942:   /* Send RIP request to the interface. */
  943:   rip_request_interface (ifp);
  944: 
  945:   return 0;
  946: }
  947: 
  948: static void
  949: rip_connect_set (struct interface *ifp, int set)
  950: {
  951:   struct listnode *node, *nnode;
  952:   struct connected *connected;
  953:   struct prefix_ipv4 address;
  954: 
  955:   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
  956:     {
  957:       struct prefix *p; 
  958:       p = connected->address;
  959: 
  960:       if (p->family != AF_INET)
  961:         continue;
  962: 
  963:       address.family = AF_INET;
  964:       address.prefix = p->u.prefix4;
  965:       address.prefixlen = p->prefixlen;
  966:       apply_mask_ipv4 (&address);
  967: 
  968:       if (set) {
  969:         /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
  970:         if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
  971:             (rip_enable_network_lookup2(connected) >= 0))
  972:           rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
  973:                                 &address, connected->ifp->ifindex, 
  974:                                 NULL, 0, 0);
  975:       } else
  976:         {
  977:           rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
  978:                                    &address, connected->ifp->ifindex);
  979:           if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
  980:             rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
  981:                                   &address, connected->ifp->ifindex,
  982:                                   NULL, 0, 0);
  983:         }
  984:     }
  985: }
  986: 
  987: /* Update interface status. */
  988: void
  989: rip_enable_apply (struct interface *ifp)
  990: {
  991:   int ret;
  992:   struct rip_interface *ri = NULL;
  993: 
  994:   /* Check interface. */
  995:   if (! if_is_operative (ifp))
  996:     return;
  997: 
  998:   ri = ifp->info;
  999: 
 1000:   /* Check network configuration. */
 1001:   ret = rip_enable_network_lookup_if (ifp);
 1002: 
 1003:   /* If the interface is matched. */
 1004:   if (ret > 0)
 1005:     ri->enable_network = 1;
 1006:   else
 1007:     ri->enable_network = 0;
 1008: 
 1009:   /* Check interface name configuration. */
 1010:   ret = rip_enable_if_lookup (ifp->name);
 1011:   if (ret >= 0)
 1012:     ri->enable_interface = 1;
 1013:   else
 1014:     ri->enable_interface = 0;
 1015: 
 1016:   /* any interface MUST have an IPv4 address */
 1017:   if ( ! rip_if_ipv4_address_check (ifp) )
 1018:     {
 1019:       ri->enable_network = 0;
 1020:       ri->enable_interface = 0;
 1021:     }
 1022: 
 1023:   /* Update running status of the interface. */
 1024:   if (ri->enable_network || ri->enable_interface)
 1025:     {
 1026: 	{
 1027: 	  if (IS_RIP_DEBUG_EVENT)
 1028: 	    zlog_debug ("turn on %s", ifp->name);
 1029: 
 1030: 	  /* Add interface wake up thread. */
 1031: 	  if (! ri->t_wakeup)
 1032: 	    ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
 1033: 					     ifp, 1);
 1034:           rip_connect_set (ifp, 1);
 1035: 	}
 1036:     }
 1037:   else
 1038:     {
 1039:       if (ri->running)
 1040: 	{
 1041: 	  /* Might as well clean up the route table as well
 1042: 	   * rip_if_down sets to 0 ri->running, and displays "turn off %s"
 1043: 	   **/ 
 1044: 	  rip_if_down(ifp);
 1045: 
 1046:           rip_connect_set (ifp, 0);
 1047: 	}
 1048:     }
 1049: }
 1050: 
 1051: /* Apply network configuration to all interface. */
 1052: void
 1053: rip_enable_apply_all ()
 1054: {
 1055:   struct interface *ifp;
 1056:   struct listnode *node, *nnode;
 1057: 
 1058:   /* Check each interface. */
 1059:   for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
 1060:     rip_enable_apply (ifp);
 1061: }
 1062: 
 1063: int
 1064: rip_neighbor_lookup (struct sockaddr_in *from)
 1065: {
 1066:   struct prefix_ipv4 p;
 1067:   struct route_node *node;
 1068: 
 1069:   memset (&p, 0, sizeof (struct prefix_ipv4));
 1070:   p.family = AF_INET;
 1071:   p.prefix = from->sin_addr;
 1072:   p.prefixlen = IPV4_MAX_BITLEN;
 1073: 
 1074:   node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
 1075:   if (node)
 1076:     {
 1077:       route_unlock_node (node);
 1078:       return 1;
 1079:     }
 1080:   return 0;
 1081: }
 1082: 
 1083: /* Add new RIP neighbor to the neighbor tree. */
 1084: static int
 1085: rip_neighbor_add (struct prefix_ipv4 *p)
 1086: {
 1087:   struct route_node *node;
 1088: 
 1089:   node = route_node_get (rip->neighbor, (struct prefix *) p);
 1090: 
 1091:   if (node->info)
 1092:     return -1;
 1093: 
 1094:   node->info = rip->neighbor;
 1095: 
 1096:   return 0;
 1097: }
 1098: 
 1099: /* Delete RIP neighbor from the neighbor tree. */
 1100: static int
 1101: rip_neighbor_delete (struct prefix_ipv4 *p)
 1102: {
 1103:   struct route_node *node;
 1104: 
 1105:   /* Lock for look up. */
 1106:   node = route_node_lookup (rip->neighbor, (struct prefix *) p);
 1107:   if (! node)
 1108:     return -1;
 1109:   
 1110:   node->info = NULL;
 1111: 
 1112:   /* Unlock lookup lock. */
 1113:   route_unlock_node (node);
 1114: 
 1115:   /* Unlock real neighbor information lock. */
 1116:   route_unlock_node (node);
 1117: 
 1118:   return 0;
 1119: }
 1120: 
 1121: /* Clear all network and neighbor configuration. */
 1122: void
 1123: rip_clean_network ()
 1124: {
 1125:   unsigned int i;
 1126:   char *str;
 1127:   struct route_node *rn;
 1128: 
 1129:   /* rip_enable_network. */
 1130:   for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
 1131:     if (rn->info)
 1132:       {
 1133: 	rn->info = NULL;
 1134: 	route_unlock_node (rn);
 1135:       }
 1136: 
 1137:   /* rip_enable_interface. */
 1138:   for (i = 0; i < vector_active (rip_enable_interface); i++)
 1139:     if ((str = vector_slot (rip_enable_interface, i)) != NULL)
 1140:       {
 1141: 	free (str);
 1142: 	vector_slot (rip_enable_interface, i) = NULL;
 1143:       }
 1144: }
 1145: 
 1146: /* Utility function for looking up passive interface settings. */
 1147: static int
 1148: rip_passive_nondefault_lookup (const char *ifname)
 1149: {
 1150:   unsigned int i;
 1151:   char *str;
 1152: 
 1153:   for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
 1154:     if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
 1155:       if (strcmp (str, ifname) == 0)
 1156: 	return i;
 1157:   return -1;
 1158: }
 1159: 
 1160: void
 1161: rip_passive_interface_apply (struct interface *ifp)
 1162: {
 1163:   struct rip_interface *ri;
 1164: 
 1165:   ri = ifp->info;
 1166: 
 1167:   ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
 1168: 		 passive_default : !passive_default);
 1169: 
 1170:   if (IS_RIP_DEBUG_ZEBRA)
 1171:     zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
 1172: }
 1173: 
 1174: static void
 1175: rip_passive_interface_apply_all (void)
 1176: {
 1177:   struct interface *ifp;
 1178:   struct listnode *node, *nnode;
 1179: 
 1180:   for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
 1181:     rip_passive_interface_apply (ifp);
 1182: }
 1183: 
 1184: /* Passive interface. */
 1185: static int
 1186: rip_passive_nondefault_set (struct vty *vty, const char *ifname)
 1187: {
 1188:   if (rip_passive_nondefault_lookup (ifname) >= 0)
 1189:     return CMD_WARNING;
 1190: 
 1191:   vector_set (Vrip_passive_nondefault, strdup (ifname));
 1192: 
 1193:   rip_passive_interface_apply_all ();
 1194: 
 1195:   return CMD_SUCCESS;
 1196: }
 1197: 
 1198: static int
 1199: rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
 1200: {
 1201:   int i;
 1202:   char *str;
 1203: 
 1204:   i = rip_passive_nondefault_lookup (ifname);
 1205:   if (i < 0)
 1206:     return CMD_WARNING;
 1207: 
 1208:   str = vector_slot (Vrip_passive_nondefault, i);
 1209:   free (str);
 1210:   vector_unset (Vrip_passive_nondefault, i);
 1211: 
 1212:   rip_passive_interface_apply_all ();
 1213: 
 1214:   return CMD_SUCCESS;
 1215: }
 1216: 
 1217: /* Free all configured RIP passive-interface settings. */
 1218: void
 1219: rip_passive_nondefault_clean (void)
 1220: {
 1221:   unsigned int i;
 1222:   char *str;
 1223: 
 1224:   for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
 1225:     if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
 1226:       {
 1227: 	free (str);
 1228: 	vector_slot (Vrip_passive_nondefault, i) = NULL;
 1229:       }
 1230:   rip_passive_interface_apply_all ();
 1231: }
 1232: 
 1233: /* RIP enable network or interface configuration. */
 1234: DEFUN (rip_network,
 1235:        rip_network_cmd,
 1236:        "network (A.B.C.D/M|WORD)",
 1237:        "Enable routing on an IP network\n"
 1238:        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
 1239:        "Interface name\n")
 1240: {
 1241:   int ret;
 1242:   struct prefix_ipv4 p;
 1243: 
 1244:   ret = str2prefix_ipv4 (argv[0], &p);
 1245: 
 1246:   if (ret)
 1247:     ret = rip_enable_network_add ((struct prefix *) &p);
 1248:   else
 1249:     ret = rip_enable_if_add (argv[0]);
 1250: 
 1251:   if (ret < 0)
 1252:     {
 1253:       vty_out (vty, "There is a same network configuration %s%s", argv[0],
 1254: 	       VTY_NEWLINE);
 1255:       return CMD_WARNING;
 1256:     }
 1257: 
 1258:   return CMD_SUCCESS;
 1259: }
 1260: 
 1261: /* RIP enable network or interface configuration. */
 1262: DEFUN (no_rip_network,
 1263:        no_rip_network_cmd,
 1264:        "no network (A.B.C.D/M|WORD)",
 1265:        NO_STR
 1266:        "Enable routing on an IP network\n"
 1267:        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
 1268:        "Interface name\n")
 1269: {
 1270:   int ret;
 1271:   struct prefix_ipv4 p;
 1272: 
 1273:   ret = str2prefix_ipv4 (argv[0], &p);
 1274: 
 1275:   if (ret)
 1276:     ret = rip_enable_network_delete ((struct prefix *) &p);
 1277:   else
 1278:     ret = rip_enable_if_delete (argv[0]);
 1279: 
 1280:   if (ret < 0)
 1281:     {
 1282:       vty_out (vty, "Can't find network configuration %s%s", argv[0],
 1283: 	       VTY_NEWLINE);
 1284:       return CMD_WARNING;
 1285:     }
 1286: 
 1287:   return CMD_SUCCESS;
 1288: }
 1289: 
 1290: /* RIP neighbor configuration set. */
 1291: DEFUN (rip_neighbor,
 1292:        rip_neighbor_cmd,
 1293:        "neighbor A.B.C.D",
 1294:        "Specify a neighbor router\n"
 1295:        "Neighbor address\n")
 1296: {
 1297:   int ret;
 1298:   struct prefix_ipv4 p;
 1299: 
 1300:   ret = str2prefix_ipv4 (argv[0], &p);
 1301: 
 1302:   if (ret <= 0)
 1303:     {
 1304:       vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
 1305:       return CMD_WARNING;
 1306:     }
 1307: 
 1308:   rip_neighbor_add (&p);
 1309:   
 1310:   return CMD_SUCCESS;
 1311: }
 1312: 
 1313: /* RIP neighbor configuration unset. */
 1314: DEFUN (no_rip_neighbor,
 1315:        no_rip_neighbor_cmd,
 1316:        "no neighbor A.B.C.D",
 1317:        NO_STR
 1318:        "Specify a neighbor router\n"
 1319:        "Neighbor address\n")
 1320: {
 1321:   int ret;
 1322:   struct prefix_ipv4 p;
 1323: 
 1324:   ret = str2prefix_ipv4 (argv[0], &p);
 1325: 
 1326:   if (ret <= 0)
 1327:     {
 1328:       vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
 1329:       return CMD_WARNING;
 1330:     }
 1331: 
 1332:   rip_neighbor_delete (&p);
 1333:   
 1334:   return CMD_SUCCESS;
 1335: }
 1336: 
 1337: DEFUN (ip_rip_receive_version,
 1338:        ip_rip_receive_version_cmd,
 1339:        "ip rip receive version (1|2)",
 1340:        IP_STR
 1341:        "Routing Information Protocol\n"
 1342:        "Advertisement reception\n"
 1343:        "Version control\n"
 1344:        "RIP version 1\n"
 1345:        "RIP version 2\n")
 1346: {
 1347:   struct interface *ifp;
 1348:   struct rip_interface *ri;
 1349: 
 1350:   ifp = (struct interface *)vty->index;
 1351:   ri = ifp->info;
 1352: 
 1353:   /* Version 1. */
 1354:   if (atoi (argv[0]) == 1)
 1355:     {
 1356:       ri->ri_receive = RI_RIP_VERSION_1;
 1357:       return CMD_SUCCESS;
 1358:     }
 1359:   if (atoi (argv[0]) == 2)
 1360:     {
 1361:       ri->ri_receive = RI_RIP_VERSION_2;
 1362:       return CMD_SUCCESS;
 1363:     }
 1364:   return CMD_WARNING;
 1365: }
 1366: 
 1367: DEFUN (ip_rip_receive_version_1,
 1368:        ip_rip_receive_version_1_cmd,
 1369:        "ip rip receive version 1 2",
 1370:        IP_STR
 1371:        "Routing Information Protocol\n"
 1372:        "Advertisement reception\n"
 1373:        "Version control\n"
 1374:        "RIP version 1\n"
 1375:        "RIP version 2\n")
 1376: {
 1377:   struct interface *ifp;
 1378:   struct rip_interface *ri;
 1379: 
 1380:   ifp = (struct interface *)vty->index;
 1381:   ri = ifp->info;
 1382: 
 1383:   /* Version 1 and 2. */
 1384:   ri->ri_receive = RI_RIP_VERSION_1_AND_2;
 1385:   return CMD_SUCCESS;
 1386: }
 1387: 
 1388: DEFUN (ip_rip_receive_version_2,
 1389:        ip_rip_receive_version_2_cmd,
 1390:        "ip rip receive version 2 1",
 1391:        IP_STR
 1392:        "Routing Information Protocol\n"
 1393:        "Advertisement reception\n"
 1394:        "Version control\n"
 1395:        "RIP version 2\n"
 1396:        "RIP version 1\n")
 1397: {
 1398:   struct interface *ifp;
 1399:   struct rip_interface *ri;
 1400: 
 1401:   ifp = (struct interface *)vty->index;
 1402:   ri = ifp->info;
 1403: 
 1404:   /* Version 1 and 2. */
 1405:   ri->ri_receive = RI_RIP_VERSION_1_AND_2;
 1406:   return CMD_SUCCESS;
 1407: }
 1408: 
 1409: DEFUN (no_ip_rip_receive_version,
 1410:        no_ip_rip_receive_version_cmd,
 1411:        "no ip rip receive version",
 1412:        NO_STR
 1413:        IP_STR
 1414:        "Routing Information Protocol\n"
 1415:        "Advertisement reception\n"
 1416:        "Version control\n")
 1417: {
 1418:   struct interface *ifp;
 1419:   struct rip_interface *ri;
 1420: 
 1421:   ifp = (struct interface *)vty->index;
 1422:   ri = ifp->info;
 1423: 
 1424:   ri->ri_receive = RI_RIP_UNSPEC;
 1425:   return CMD_SUCCESS;
 1426: }
 1427: 
 1428: ALIAS (no_ip_rip_receive_version,
 1429:        no_ip_rip_receive_version_num_cmd,
 1430:        "no ip rip receive version (1|2)",
 1431:        NO_STR
 1432:        IP_STR
 1433:        "Routing Information Protocol\n"
 1434:        "Advertisement reception\n"
 1435:        "Version control\n"
 1436:        "Version 1\n"
 1437:        "Version 2\n")
 1438: 
 1439: DEFUN (ip_rip_send_version,
 1440:        ip_rip_send_version_cmd,
 1441:        "ip rip send version (1|2)",
 1442:        IP_STR
 1443:        "Routing Information Protocol\n"
 1444:        "Advertisement transmission\n"
 1445:        "Version control\n"
 1446:        "RIP version 1\n"
 1447:        "RIP version 2\n")
 1448: {
 1449:   struct interface *ifp;
 1450:   struct rip_interface *ri;
 1451: 
 1452:   ifp = (struct interface *)vty->index;
 1453:   ri = ifp->info;
 1454: 
 1455:   /* Version 1. */
 1456:   if (atoi (argv[0]) == 1)
 1457:     {
 1458:       ri->ri_send = RI_RIP_VERSION_1;
 1459:       return CMD_SUCCESS;
 1460:     }
 1461:   if (atoi (argv[0]) == 2)
 1462:     {
 1463:       ri->ri_send = RI_RIP_VERSION_2;
 1464:       return CMD_SUCCESS;
 1465:     }
 1466:   return CMD_WARNING;
 1467: }
 1468: 
 1469: DEFUN (ip_rip_send_version_1,
 1470:        ip_rip_send_version_1_cmd,
 1471:        "ip rip send version 1 2",
 1472:        IP_STR
 1473:        "Routing Information Protocol\n"
 1474:        "Advertisement transmission\n"
 1475:        "Version control\n"
 1476:        "RIP version 1\n"
 1477:        "RIP version 2\n")
 1478: {
 1479:   struct interface *ifp;
 1480:   struct rip_interface *ri;
 1481: 
 1482:   ifp = (struct interface *)vty->index;
 1483:   ri = ifp->info;
 1484: 
 1485:   /* Version 1 and 2. */
 1486:   ri->ri_send = RI_RIP_VERSION_1_AND_2;
 1487:   return CMD_SUCCESS;
 1488: }
 1489: 
 1490: DEFUN (ip_rip_send_version_2,
 1491:        ip_rip_send_version_2_cmd,
 1492:        "ip rip send version 2 1",
 1493:        IP_STR
 1494:        "Routing Information Protocol\n"
 1495:        "Advertisement transmission\n"
 1496:        "Version control\n"
 1497:        "RIP version 2\n"
 1498:        "RIP version 1\n")
 1499: {
 1500:   struct interface *ifp;
 1501:   struct rip_interface *ri;
 1502: 
 1503:   ifp = (struct interface *)vty->index;
 1504:   ri = ifp->info;
 1505: 
 1506:   /* Version 1 and 2. */
 1507:   ri->ri_send = RI_RIP_VERSION_1_AND_2;
 1508:   return CMD_SUCCESS;
 1509: }
 1510: 
 1511: DEFUN (no_ip_rip_send_version,
 1512:        no_ip_rip_send_version_cmd,
 1513:        "no ip rip send version",
 1514:        NO_STR
 1515:        IP_STR
 1516:        "Routing Information Protocol\n"
 1517:        "Advertisement transmission\n"
 1518:        "Version control\n")
 1519: {
 1520:   struct interface *ifp;
 1521:   struct rip_interface *ri;
 1522: 
 1523:   ifp = (struct interface *)vty->index;
 1524:   ri = ifp->info;
 1525: 
 1526:   ri->ri_send = RI_RIP_UNSPEC;
 1527:   return CMD_SUCCESS;
 1528: }
 1529: 
 1530: ALIAS (no_ip_rip_send_version,
 1531:        no_ip_rip_send_version_num_cmd,
 1532:        "no ip rip send version (1|2)",
 1533:        NO_STR
 1534:        IP_STR
 1535:        "Routing Information Protocol\n"
 1536:        "Advertisement transmission\n"
 1537:        "Version control\n"
 1538:        "Version 1\n"
 1539:        "Version 2\n")
 1540: 
 1541: DEFUN (ip_rip_authentication_mode,
 1542:        ip_rip_authentication_mode_cmd,
 1543:        "ip rip authentication mode (md5|text)",
 1544:        IP_STR
 1545:        "Routing Information Protocol\n"
 1546:        "Authentication control\n"
 1547:        "Authentication mode\n"
 1548:        "Keyed message digest\n"
 1549:        "Clear text authentication\n")
 1550: {
 1551:   struct interface *ifp;
 1552:   struct rip_interface *ri;
 1553:   int auth_type;
 1554: 
 1555:   ifp = (struct interface *)vty->index;
 1556:   ri = ifp->info;
 1557: 
 1558:   if ( (argc < 1) || (argc > 2) )
 1559:     {
 1560:       vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
 1561:       return CMD_WARNING;
 1562:     }
 1563:     
 1564:   if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
 1565:     auth_type = RIP_AUTH_MD5;
 1566:   else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
 1567:     auth_type = RIP_AUTH_SIMPLE_PASSWORD;
 1568:   else
 1569:     {
 1570:       vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
 1571:       return CMD_WARNING;
 1572:     }
 1573: 
 1574:   if (argc == 1)
 1575:     {
 1576:       ri->auth_type = auth_type;
 1577:       return CMD_SUCCESS;
 1578:     }
 1579: 
 1580:   if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
 1581:     {
 1582:       vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
 1583:       return CMD_WARNING;
 1584:     }
 1585: 
 1586:   if (strncmp ("r", argv[1], 1) == 0)
 1587:     ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
 1588:   else if (strncmp ("o", argv[1], 1) == 0)
 1589:     ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
 1590:   else 
 1591:     return CMD_WARNING;
 1592:     
 1593:   ri->auth_type = auth_type;
 1594:   
 1595:   return CMD_SUCCESS;
 1596: }
 1597: 
 1598: ALIAS (ip_rip_authentication_mode,
 1599:        ip_rip_authentication_mode_authlen_cmd,
 1600:        "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
 1601:        IP_STR
 1602:        "Routing Information Protocol\n"
 1603:        "Authentication control\n"
 1604:        "Authentication mode\n"
 1605:        "Keyed message digest\n"
 1606:        "Clear text authentication\n"
 1607:        "MD5 authentication data length\n"
 1608:        "RFC compatible\n"
 1609:        "Old ripd compatible\n")
 1610: 
 1611: DEFUN (no_ip_rip_authentication_mode,
 1612:        no_ip_rip_authentication_mode_cmd,
 1613:        "no ip rip authentication mode",
 1614:        NO_STR
 1615:        IP_STR
 1616:        "Routing Information Protocol\n"
 1617:        "Authentication control\n"
 1618:        "Authentication mode\n")
 1619: {
 1620:   struct interface *ifp;
 1621:   struct rip_interface *ri;
 1622: 
 1623:   ifp = (struct interface *)vty->index;
 1624:   ri = ifp->info;
 1625: 
 1626:   ri->auth_type = RIP_NO_AUTH;
 1627:   ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
 1628: 
 1629:   return CMD_SUCCESS;
 1630: }
 1631: 
 1632: ALIAS (no_ip_rip_authentication_mode,
 1633:        no_ip_rip_authentication_mode_type_cmd,
 1634:        "no ip rip authentication mode (md5|text)",
 1635:        NO_STR
 1636:        IP_STR
 1637:        "Routing Information Protocol\n"
 1638:        "Authentication control\n"
 1639:        "Authentication mode\n"
 1640:        "Keyed message digest\n"
 1641:        "Clear text authentication\n")
 1642: 
 1643: ALIAS (no_ip_rip_authentication_mode,
 1644:        no_ip_rip_authentication_mode_type_authlen_cmd,
 1645:        "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
 1646:        NO_STR
 1647:        IP_STR
 1648:        "Routing Information Protocol\n"
 1649:        "Authentication control\n"
 1650:        "Authentication mode\n"
 1651:        "Keyed message digest\n"
 1652:        "Clear text authentication\n"
 1653:        "MD5 authentication data length\n"
 1654:        "RFC compatible\n"
 1655:        "Old ripd compatible\n")
 1656: 
 1657: DEFUN (ip_rip_authentication_string,
 1658:        ip_rip_authentication_string_cmd,
 1659:        "ip rip authentication string LINE",
 1660:        IP_STR
 1661:        "Routing Information Protocol\n"
 1662:        "Authentication control\n"
 1663:        "Authentication string\n"
 1664:        "Authentication string\n")
 1665: {
 1666:   struct interface *ifp;
 1667:   struct rip_interface *ri;
 1668: 
 1669:   ifp = (struct interface *)vty->index;
 1670:   ri = ifp->info;
 1671: 
 1672:   if (strlen (argv[0]) > 16)
 1673:     {
 1674:       vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
 1675: 	       VTY_NEWLINE);
 1676:       return CMD_WARNING;
 1677:     }
 1678: 
 1679:   if (ri->key_chain)
 1680:     {
 1681:       vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
 1682:       return CMD_WARNING;
 1683:     }
 1684: 
 1685:   if (ri->auth_str)
 1686:     free (ri->auth_str);
 1687: 
 1688:   ri->auth_str = strdup (argv[0]);
 1689: 
 1690:   return CMD_SUCCESS;
 1691: }
 1692: 
 1693: DEFUN (no_ip_rip_authentication_string,
 1694:        no_ip_rip_authentication_string_cmd,
 1695:        "no ip rip authentication string",
 1696:        NO_STR
 1697:        IP_STR
 1698:        "Routing Information Protocol\n"
 1699:        "Authentication control\n"
 1700:        "Authentication string\n")
 1701: {
 1702:   struct interface *ifp;
 1703:   struct rip_interface *ri;
 1704: 
 1705:   ifp = (struct interface *)vty->index;
 1706:   ri = ifp->info;
 1707: 
 1708:   if (ri->auth_str)
 1709:     free (ri->auth_str);
 1710: 
 1711:   ri->auth_str = NULL;
 1712: 
 1713:   return CMD_SUCCESS;
 1714: }
 1715: 
 1716: ALIAS (no_ip_rip_authentication_string,
 1717:        no_ip_rip_authentication_string2_cmd,
 1718:        "no ip rip authentication string LINE",
 1719:        NO_STR
 1720:        IP_STR
 1721:        "Routing Information Protocol\n"
 1722:        "Authentication control\n"
 1723:        "Authentication string\n"
 1724:        "Authentication string\n")
 1725: 
 1726: DEFUN (ip_rip_authentication_key_chain,
 1727:        ip_rip_authentication_key_chain_cmd,
 1728:        "ip rip authentication key-chain LINE",
 1729:        IP_STR
 1730:        "Routing Information Protocol\n"
 1731:        "Authentication control\n"
 1732:        "Authentication key-chain\n"
 1733:        "name of key-chain\n")
 1734: {
 1735:   struct interface *ifp;
 1736:   struct rip_interface *ri;
 1737: 
 1738:   ifp = (struct interface *) vty->index;
 1739:   ri = ifp->info;
 1740: 
 1741:   if (ri->auth_str)
 1742:     {
 1743:       vty_out (vty, "%% authentication string configuration exists%s",
 1744: 	       VTY_NEWLINE);
 1745:       return CMD_WARNING;
 1746:     }
 1747: 
 1748:   if (ri->key_chain)
 1749:     free (ri->key_chain);
 1750: 
 1751:   ri->key_chain = strdup (argv[0]);
 1752: 
 1753:   return CMD_SUCCESS;
 1754: }
 1755: 
 1756: DEFUN (no_ip_rip_authentication_key_chain,
 1757:        no_ip_rip_authentication_key_chain_cmd,
 1758:        "no ip rip authentication key-chain",
 1759:        NO_STR
 1760:        IP_STR
 1761:        "Routing Information Protocol\n"
 1762:        "Authentication control\n"
 1763:        "Authentication key-chain\n")
 1764: {
 1765:   struct interface *ifp;
 1766:   struct rip_interface *ri;
 1767: 
 1768:   ifp = (struct interface *) vty->index;
 1769:   ri = ifp->info;
 1770: 
 1771:   if (ri->key_chain)
 1772:     free (ri->key_chain);
 1773: 
 1774:   ri->key_chain = NULL;
 1775: 
 1776:   return CMD_SUCCESS;
 1777: }
 1778: 
 1779: ALIAS (no_ip_rip_authentication_key_chain,
 1780:        no_ip_rip_authentication_key_chain2_cmd,
 1781:        "no ip rip authentication key-chain LINE",
 1782:        NO_STR
 1783:        IP_STR
 1784:        "Routing Information Protocol\n"
 1785:        "Authentication control\n"
 1786:        "Authentication key-chain\n"
 1787:        "name of key-chain\n")
 1788: 
 1789: /* CHANGED: ip rip split-horizon
 1790:    Cisco and Zebra's command is
 1791:    ip split-horizon
 1792:  */
 1793: DEFUN (ip_rip_split_horizon,
 1794:        ip_rip_split_horizon_cmd,
 1795:        "ip rip split-horizon",
 1796:        IP_STR
 1797:        "Routing Information Protocol\n"
 1798:        "Perform split horizon\n")
 1799: {
 1800:   struct interface *ifp;
 1801:   struct rip_interface *ri;
 1802: 
 1803:   ifp = vty->index;
 1804:   ri = ifp->info;
 1805: 
 1806:   ri->split_horizon = RIP_SPLIT_HORIZON;
 1807:   return CMD_SUCCESS;
 1808: }
 1809: 
 1810: DEFUN (ip_rip_split_horizon_poisoned_reverse,
 1811:        ip_rip_split_horizon_poisoned_reverse_cmd,
 1812:        "ip rip split-horizon poisoned-reverse",
 1813:        IP_STR
 1814:        "Routing Information Protocol\n"
 1815:        "Perform split horizon\n"
 1816:        "With poisoned-reverse\n")
 1817: {
 1818:   struct interface *ifp;
 1819:   struct rip_interface *ri;
 1820: 
 1821:   ifp = vty->index;
 1822:   ri = ifp->info;
 1823: 
 1824:   ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
 1825:   return CMD_SUCCESS;
 1826: }
 1827: 
 1828: /* CHANGED: no ip rip split-horizon
 1829:    Cisco and Zebra's command is
 1830:    no ip split-horizon
 1831:  */
 1832: DEFUN (no_ip_rip_split_horizon,
 1833:        no_ip_rip_split_horizon_cmd,
 1834:        "no ip rip split-horizon",
 1835:        NO_STR
 1836:        IP_STR
 1837:        "Routing Information Protocol\n"
 1838:        "Perform split horizon\n")
 1839: {
 1840:   struct interface *ifp;
 1841:   struct rip_interface *ri;
 1842: 
 1843:   ifp = vty->index;
 1844:   ri = ifp->info;
 1845: 
 1846:   ri->split_horizon = RIP_NO_SPLIT_HORIZON;
 1847:   return CMD_SUCCESS;
 1848: }
 1849: 
 1850: DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
 1851:        no_ip_rip_split_horizon_poisoned_reverse_cmd,
 1852:        "no ip rip split-horizon poisoned-reverse",
 1853:        NO_STR
 1854:        IP_STR
 1855:        "Routing Information Protocol\n"
 1856:        "Perform split horizon\n"
 1857:        "With poisoned-reverse\n")
 1858: {
 1859:   struct interface *ifp;
 1860:   struct rip_interface *ri;
 1861: 
 1862:   ifp = vty->index;
 1863:   ri = ifp->info;
 1864: 
 1865:   switch( ri->split_horizon )
 1866:   {
 1867: 	case RIP_SPLIT_HORIZON_POISONED_REVERSE:
 1868: 		ri->split_horizon = RIP_SPLIT_HORIZON;
 1869: 	default:
 1870: 		break;
 1871:   }
 1872: 
 1873:   return CMD_SUCCESS;
 1874: }
 1875: 
 1876: DEFUN (rip_passive_interface,
 1877:        rip_passive_interface_cmd,
 1878:        "passive-interface (IFNAME|default)",
 1879:        "Suppress routing updates on an interface\n"
 1880:        "Interface name\n"
 1881:        "default for all interfaces\n")
 1882: {
 1883:   const char *ifname = argv[0];
 1884: 
 1885:   if (!strcmp(ifname,"default")) {
 1886:     passive_default = 1;
 1887:     rip_passive_nondefault_clean();
 1888:     return CMD_SUCCESS;
 1889:   }
 1890:   if (passive_default)
 1891:     return rip_passive_nondefault_unset (vty, ifname);
 1892:   else
 1893:     return rip_passive_nondefault_set (vty, ifname);
 1894: }
 1895: 
 1896: DEFUN (no_rip_passive_interface,
 1897:        no_rip_passive_interface_cmd,
 1898:        "no passive-interface (IFNAME|default)",
 1899:        NO_STR
 1900:        "Suppress routing updates on an interface\n"
 1901:        "Interface name\n"
 1902:        "default for all interfaces\n")
 1903: {
 1904:   const char *ifname = argv[0];
 1905: 
 1906:   if (!strcmp(ifname,"default")) {
 1907:     passive_default = 0;
 1908:     rip_passive_nondefault_clean();
 1909:     return CMD_SUCCESS;
 1910:   }
 1911:   if (passive_default)
 1912:     return rip_passive_nondefault_set (vty, ifname);
 1913:   else
 1914:     return rip_passive_nondefault_unset (vty, ifname);
 1915: }
 1916: 
 1917: /* Write rip configuration of each interface. */
 1918: static int
 1919: rip_interface_config_write (struct vty *vty)
 1920: {
 1921:   struct listnode *node;
 1922:   struct interface *ifp;
 1923: 
 1924:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
 1925:     {
 1926:       struct rip_interface *ri;
 1927: 
 1928:       ri = ifp->info;
 1929: 
 1930:       /* Do not display the interface if there is no
 1931:        * configuration about it.
 1932:        **/
 1933:       if ((!ifp->desc)                                     &&
 1934:           (ri->split_horizon == ri->split_horizon_default) &&
 1935:           (ri->ri_send == RI_RIP_UNSPEC)                   &&
 1936:           (ri->ri_receive == RI_RIP_UNSPEC)                &&
 1937:           (ri->auth_type != RIP_AUTH_MD5)                  &&
 1938:           (ri->md5_auth_len != RIP_AUTH_MD5_SIZE)          &&
 1939:           (!ri->auth_str)                                  &&
 1940:           (!ri->key_chain)                                 )
 1941:         continue;
 1942: 
 1943:       vty_out (vty, "interface %s%s", ifp->name,
 1944: 	       VTY_NEWLINE);
 1945: 
 1946:       if (ifp->desc)
 1947: 	vty_out (vty, " description %s%s", ifp->desc,
 1948: 		 VTY_NEWLINE);
 1949: 
 1950:       /* Split horizon. */
 1951:       if (ri->split_horizon != ri->split_horizon_default)
 1952: 	{
 1953:           switch (ri->split_horizon) {
 1954:           case RIP_SPLIT_HORIZON:
 1955:             vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
 1956:             break;
 1957:           case RIP_SPLIT_HORIZON_POISONED_REVERSE:
 1958:             vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
 1959:                           VTY_NEWLINE);
 1960:             break;
 1961:           case RIP_NO_SPLIT_HORIZON:
 1962:           default:
 1963:             vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
 1964:             break;
 1965:           }
 1966: 	}
 1967: 
 1968:       /* RIP version setting. */
 1969:       if (ri->ri_send != RI_RIP_UNSPEC)
 1970: 	vty_out (vty, " ip rip send version %s%s",
 1971: 		 lookup (ri_version_msg, ri->ri_send),
 1972: 		 VTY_NEWLINE);
 1973: 
 1974:       if (ri->ri_receive != RI_RIP_UNSPEC)
 1975: 	vty_out (vty, " ip rip receive version %s%s",
 1976: 		 lookup (ri_version_msg, ri->ri_receive),
 1977: 		 VTY_NEWLINE);
 1978: 
 1979:       /* RIP authentication. */
 1980:       if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
 1981: 	vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
 1982: 
 1983:       if (ri->auth_type == RIP_AUTH_MD5)
 1984:         {
 1985:           vty_out (vty, " ip rip authentication mode md5");
 1986:           if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
 1987:             vty_out (vty, " auth-length old-ripd");
 1988:           else 
 1989:             vty_out (vty, " auth-length rfc");
 1990:           vty_out (vty, "%s", VTY_NEWLINE);
 1991:         }
 1992: 
 1993:       if (ri->auth_str)
 1994: 	vty_out (vty, " ip rip authentication string %s%s",
 1995: 		 ri->auth_str, VTY_NEWLINE);
 1996: 
 1997:       if (ri->key_chain)
 1998: 	vty_out (vty, " ip rip authentication key-chain %s%s",
 1999: 		 ri->key_chain, VTY_NEWLINE);
 2000: 
 2001:       vty_out (vty, "!%s", VTY_NEWLINE);
 2002:     }
 2003:   return 0;
 2004: }
 2005: 
 2006: int
 2007: config_write_rip_network (struct vty *vty, int config_mode)
 2008: {
 2009:   unsigned int i;
 2010:   char *ifname;
 2011:   struct route_node *node;
 2012: 
 2013:   /* Network type RIP enable interface statement. */
 2014:   for (node = route_top (rip_enable_network); node; node = route_next (node))
 2015:     if (node->info)
 2016:       vty_out (vty, "%s%s/%d%s", 
 2017: 	       config_mode ? " network " : "    ",
 2018: 	       inet_ntoa (node->p.u.prefix4),
 2019: 	       node->p.prefixlen,
 2020: 	       VTY_NEWLINE);
 2021: 
 2022:   /* Interface name RIP enable statement. */
 2023:   for (i = 0; i < vector_active (rip_enable_interface); i++)
 2024:     if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
 2025:       vty_out (vty, "%s%s%s",
 2026: 	       config_mode ? " network " : "    ",
 2027: 	       ifname,
 2028: 	       VTY_NEWLINE);
 2029: 
 2030:   /* RIP neighbors listing. */
 2031:   for (node = route_top (rip->neighbor); node; node = route_next (node))
 2032:     if (node->info)
 2033:       vty_out (vty, "%s%s%s", 
 2034: 	       config_mode ? " neighbor " : "    ",
 2035: 	       inet_ntoa (node->p.u.prefix4),
 2036: 	       VTY_NEWLINE);
 2037: 
 2038:   /* RIP passive interface listing. */
 2039:   if (config_mode) {
 2040:     if (passive_default)
 2041:       vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
 2042:     for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
 2043:       if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
 2044: 	vty_out (vty, " %spassive-interface %s%s",
 2045: 		 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
 2046:   }
 2047: 
 2048:   return 0;
 2049: }
 2050: 
 2051: static struct cmd_node interface_node =
 2052: {
 2053:   INTERFACE_NODE,
 2054:   "%s(config-if)# ",
 2055:   1,
 2056: };
 2057: 
 2058: /* Called when interface structure allocated. */
 2059: static int
 2060: rip_interface_new_hook (struct interface *ifp)
 2061: {
 2062:   ifp->info = rip_interface_new ();
 2063:   return 0;
 2064: }
 2065: 
 2066: /* Called when interface structure deleted. */
 2067: static int
 2068: rip_interface_delete_hook (struct interface *ifp)
 2069: {
 2070:   XFREE (MTYPE_RIP_INTERFACE, ifp->info);
 2071:   ifp->info = NULL;
 2072:   return 0;
 2073: }
 2074: 
 2075: /* Allocate and initialize interface vector. */
 2076: void
 2077: rip_if_init (void)
 2078: {
 2079:   /* Default initial size of interface vector. */
 2080:   if_init();
 2081:   if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
 2082:   if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
 2083:   
 2084:   /* RIP network init. */
 2085:   rip_enable_interface = vector_init (1);
 2086:   rip_enable_network = route_table_init ();
 2087: 
 2088:   /* RIP passive interface. */
 2089:   Vrip_passive_nondefault = vector_init (1);
 2090: 
 2091:   /* Install interface node. */
 2092:   install_node (&interface_node, rip_interface_config_write);
 2093: 
 2094:   /* Install commands. */
 2095:   install_element (CONFIG_NODE, &interface_cmd);
 2096:   install_element (CONFIG_NODE, &no_interface_cmd);
 2097:   install_default (INTERFACE_NODE);
 2098:   install_element (INTERFACE_NODE, &interface_desc_cmd);
 2099:   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
 2100:   install_element (RIP_NODE, &rip_network_cmd);
 2101:   install_element (RIP_NODE, &no_rip_network_cmd);
 2102:   install_element (RIP_NODE, &rip_neighbor_cmd);
 2103:   install_element (RIP_NODE, &no_rip_neighbor_cmd);
 2104: 
 2105:   install_element (RIP_NODE, &rip_passive_interface_cmd);
 2106:   install_element (RIP_NODE, &no_rip_passive_interface_cmd);
 2107: 
 2108:   install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
 2109:   install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
 2110:   install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
 2111:   install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
 2112:   install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
 2113: 
 2114:   install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
 2115:   install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
 2116:   install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
 2117:   install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
 2118:   install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
 2119: 
 2120:   install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
 2121:   install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
 2122:   install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
 2123:   install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
 2124:   install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
 2125: 
 2126:   install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
 2127:   install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
 2128:   install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
 2129: 
 2130:   install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
 2131:   install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
 2132:   install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
 2133: 
 2134:   install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
 2135:   install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
 2136:   install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
 2137:   install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
 2138: }

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