File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ripd / rip_interface.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

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