Annotation of embedaddon/quagga/ripd/rip_interface.c, revision 1.1

1.1     ! misho       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>