Annotation of embedaddon/quagga/ripd/ripd.c, revision 1.1.1.2

1.1       misho       1: /* RIP version 1 and 2.
                      2:  * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
                      3:  * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
                      4:  *
                      5:  * This file is part of GNU Zebra.
                      6:  *
                      7:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2, or (at your option) any
                     10:  * later version.
                     11:  *
                     12:  * GNU Zebra is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU General Public License
                     18:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
                     19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     20:  * 02111-1307, USA.  
                     21:  */
                     22: 
                     23: #include <zebra.h>
                     24: 
                     25: #include "if.h"
                     26: #include "command.h"
                     27: #include "prefix.h"
                     28: #include "table.h"
                     29: #include "thread.h"
                     30: #include "memory.h"
                     31: #include "log.h"
                     32: #include "stream.h"
                     33: #include "filter.h"
                     34: #include "sockunion.h"
                     35: #include "sockopt.h"
                     36: #include "routemap.h"
                     37: #include "if_rmap.h"
                     38: #include "plist.h"
                     39: #include "distribute.h"
                     40: #include "md5.h"
                     41: #include "keychain.h"
                     42: #include "privs.h"
                     43: 
                     44: #include "ripd/ripd.h"
                     45: #include "ripd/rip_debug.h"
                     46: 
                     47: /* UDP receive buffer size */
                     48: #define RIP_UDP_RCV_BUF 41600
                     49: 
                     50: /* privileges global */
                     51: extern struct zebra_privs_t ripd_privs;
                     52: 
                     53: /* RIP Structure. */
                     54: struct rip *rip = NULL;
                     55: 
                     56: /* RIP neighbor address table. */
                     57: struct route_table *rip_neighbor_table;
                     58: 
                     59: /* RIP route changes. */
                     60: long rip_global_route_changes = 0;
                     61: 
                     62: /* RIP queries. */
                     63: long rip_global_queries = 0;
                     64: 
                     65: /* Prototypes. */
                     66: static void rip_event (enum rip_event, int);
                     67: static void rip_output_process (struct connected *, struct sockaddr_in *, int, u_char);
                     68: static int rip_triggered_update (struct thread *);
                     69: static int rip_update_jitter (unsigned long);
                     70: 
                     71: /* RIP output routes type. */
                     72: enum
                     73: {
                     74:   rip_all_route,
                     75:   rip_changed_route
                     76: };
                     77: 
                     78: /* RIP command strings. */
                     79: static const struct message rip_msg[] =
                     80: {
                     81:   {RIP_REQUEST,    "REQUEST"},
                     82:   {RIP_RESPONSE,   "RESPONSE"},
                     83:   {RIP_TRACEON,    "TRACEON"},
                     84:   {RIP_TRACEOFF,   "TRACEOFF"},
                     85:   {RIP_POLL,       "POLL"},
                     86:   {RIP_POLL_ENTRY, "POLL ENTRY"},
                     87:   {0, NULL},
                     88: };
                     89: 
                     90: /* Utility function to set boradcast option to the socket. */
                     91: static int
                     92: sockopt_broadcast (int sock)
                     93: {
                     94:   int ret;
                     95:   int on = 1;
                     96: 
                     97:   ret = setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof on);
                     98:   if (ret < 0)
                     99:     {
                    100:       zlog_warn ("can't set sockopt SO_BROADCAST to socket %d", sock);
                    101:       return -1;
                    102:     }
                    103:   return 0;
                    104: }
                    105: 
                    106: static int
                    107: rip_route_rte (struct rip_info *rinfo)
                    108: {
                    109:   return (rinfo->type == ZEBRA_ROUTE_RIP && rinfo->sub_type == RIP_ROUTE_RTE);
                    110: }
                    111: 
                    112: static struct rip_info *
                    113: rip_info_new (void)
                    114: {
                    115:   return XCALLOC (MTYPE_RIP_INFO, sizeof (struct rip_info));
                    116: }
                    117: 
                    118: void
                    119: rip_info_free (struct rip_info *rinfo)
                    120: {
                    121:   XFREE (MTYPE_RIP_INFO, rinfo);
                    122: }
                    123: 
                    124: /* RIP route garbage collect timer. */
                    125: static int
                    126: rip_garbage_collect (struct thread *t)
                    127: {
                    128:   struct rip_info *rinfo;
                    129:   struct route_node *rp;
                    130: 
                    131:   rinfo = THREAD_ARG (t);
                    132:   rinfo->t_garbage_collect = NULL;
                    133: 
                    134:   /* Off timeout timer. */
                    135:   RIP_TIMER_OFF (rinfo->t_timeout);
                    136:   
                    137:   /* Get route_node pointer. */
                    138:   rp = rinfo->rp;
                    139: 
                    140:   /* Unlock route_node. */
                    141:   rp->info = NULL;
                    142:   route_unlock_node (rp);
                    143: 
                    144:   /* Free RIP routing information. */
                    145:   rip_info_free (rinfo);
                    146: 
                    147:   return 0;
                    148: }
                    149: 
                    150: /* Timeout RIP routes. */
                    151: static int
                    152: rip_timeout (struct thread *t)
                    153: {
                    154:   struct rip_info *rinfo;
                    155:   struct route_node *rn;
                    156: 
                    157:   rinfo = THREAD_ARG (t);
                    158:   rinfo->t_timeout = NULL;
                    159: 
                    160:   rn = rinfo->rp;
                    161: 
                    162:   /* - The garbage-collection timer is set for 120 seconds. */
                    163:   RIP_TIMER_ON (rinfo->t_garbage_collect, rip_garbage_collect, 
                    164:                rip->garbage_time);
                    165: 
                    166:   rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rn->p, &rinfo->nexthop,
                    167:                         rinfo->metric);
                    168:   /* - The metric for the route is set to 16 (infinity).  This causes
                    169:      the route to be removed from service. */
                    170:   rinfo->metric = RIP_METRIC_INFINITY;
                    171:   rinfo->flags &= ~RIP_RTF_FIB;
                    172: 
                    173:   /* - The route change flag is to indicate that this entry has been
                    174:      changed. */
                    175:   rinfo->flags |= RIP_RTF_CHANGED;
                    176: 
                    177:   /* - The output process is signalled to trigger a response. */
                    178:   rip_event (RIP_TRIGGERED_UPDATE, 0);
                    179: 
                    180:   return 0;
                    181: }
                    182: 
                    183: static void
                    184: rip_timeout_update (struct rip_info *rinfo)
                    185: {
                    186:   if (rinfo->metric != RIP_METRIC_INFINITY)
                    187:     {
                    188:       RIP_TIMER_OFF (rinfo->t_timeout);
                    189:       RIP_TIMER_ON (rinfo->t_timeout, rip_timeout, rip->timeout_time);
                    190:     }
                    191: }
                    192: 
                    193: static int
                    194: rip_incoming_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
                    195: {
                    196:   struct distribute *dist;
                    197:   struct access_list *alist;
                    198:   struct prefix_list *plist;
                    199: 
                    200:   /* Input distribute-list filtering. */
                    201:   if (ri->list[RIP_FILTER_IN])
                    202:     {
                    203:       if (access_list_apply (ri->list[RIP_FILTER_IN], 
                    204:                             (struct prefix *) p) == FILTER_DENY)
                    205:        {
                    206:          if (IS_RIP_DEBUG_PACKET)
                    207:            zlog_debug ("%s/%d filtered by distribute in",
                    208:                       inet_ntoa (p->prefix), p->prefixlen);
                    209:          return -1;
                    210:        }
                    211:     }
                    212:   if (ri->prefix[RIP_FILTER_IN])
                    213:     {
                    214:       if (prefix_list_apply (ri->prefix[RIP_FILTER_IN], 
                    215:                             (struct prefix *) p) == PREFIX_DENY)
                    216:        {
                    217:          if (IS_RIP_DEBUG_PACKET)
                    218:            zlog_debug ("%s/%d filtered by prefix-list in",
                    219:                       inet_ntoa (p->prefix), p->prefixlen);
                    220:          return -1;
                    221:        }
                    222:     }
                    223: 
                    224:   /* All interface filter check. */
                    225:   dist = distribute_lookup (NULL);
                    226:   if (dist)
                    227:     {
                    228:       if (dist->list[DISTRIBUTE_IN])
                    229:        {
                    230:          alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
                    231:            
                    232:          if (alist)
                    233:            {
                    234:              if (access_list_apply (alist,
                    235:                                     (struct prefix *) p) == FILTER_DENY)
                    236:                {
                    237:                  if (IS_RIP_DEBUG_PACKET)
                    238:                    zlog_debug ("%s/%d filtered by distribute in",
                    239:                               inet_ntoa (p->prefix), p->prefixlen);
                    240:                  return -1;
                    241:                }
                    242:            }
                    243:        }
                    244:       if (dist->prefix[DISTRIBUTE_IN])
                    245:        {
                    246:          plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
                    247:          
                    248:          if (plist)
                    249:            {
                    250:              if (prefix_list_apply (plist,
                    251:                                     (struct prefix *) p) == PREFIX_DENY)
                    252:                {
                    253:                  if (IS_RIP_DEBUG_PACKET)
                    254:                    zlog_debug ("%s/%d filtered by prefix-list in",
                    255:                               inet_ntoa (p->prefix), p->prefixlen);
                    256:                  return -1;
                    257:                }
                    258:            }
                    259:        }
                    260:     }
                    261:   return 0;
                    262: }
                    263: 
                    264: static int
                    265: rip_outgoing_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
                    266: {
                    267:   struct distribute *dist;
                    268:   struct access_list *alist;
                    269:   struct prefix_list *plist;
                    270: 
                    271:   if (ri->list[RIP_FILTER_OUT])
                    272:     {
                    273:       if (access_list_apply (ri->list[RIP_FILTER_OUT],
                    274:                             (struct prefix *) p) == FILTER_DENY)
                    275:        {
                    276:          if (IS_RIP_DEBUG_PACKET)
                    277:            zlog_debug ("%s/%d is filtered by distribute out",
                    278:                       inet_ntoa (p->prefix), p->prefixlen);
                    279:          return -1;
                    280:        }
                    281:     }
                    282:   if (ri->prefix[RIP_FILTER_OUT])
                    283:     {
                    284:       if (prefix_list_apply (ri->prefix[RIP_FILTER_OUT],
                    285:                             (struct prefix *) p) == PREFIX_DENY)
                    286:        {
                    287:          if (IS_RIP_DEBUG_PACKET)
                    288:            zlog_debug ("%s/%d is filtered by prefix-list out",
                    289:                       inet_ntoa (p->prefix), p->prefixlen);
                    290:          return -1;
                    291:        }
                    292:     }
                    293: 
                    294:   /* All interface filter check. */
                    295:   dist = distribute_lookup (NULL);
                    296:   if (dist)
                    297:     {
                    298:       if (dist->list[DISTRIBUTE_OUT])
                    299:        {
                    300:          alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
                    301:            
                    302:          if (alist)
                    303:            {
                    304:              if (access_list_apply (alist,
                    305:                                     (struct prefix *) p) == FILTER_DENY)
                    306:                {
                    307:                  if (IS_RIP_DEBUG_PACKET)
                    308:                    zlog_debug ("%s/%d filtered by distribute out",
                    309:                               inet_ntoa (p->prefix), p->prefixlen);
                    310:                  return -1;
                    311:                }
                    312:            }
                    313:        }
                    314:       if (dist->prefix[DISTRIBUTE_OUT])
                    315:        {
                    316:          plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
                    317:          
                    318:          if (plist)
                    319:            {
                    320:              if (prefix_list_apply (plist,
                    321:                                     (struct prefix *) p) == PREFIX_DENY)
                    322:                {
                    323:                  if (IS_RIP_DEBUG_PACKET)
                    324:                    zlog_debug ("%s/%d filtered by prefix-list out",
                    325:                               inet_ntoa (p->prefix), p->prefixlen);
                    326:                  return -1;
                    327:                }
                    328:            }
                    329:        }
                    330:     }
                    331:   return 0;
                    332: }
                    333: 
                    334: /* Check nexthop address validity. */
                    335: static int
                    336: rip_nexthop_check (struct in_addr *addr)
                    337: {
                    338:   struct listnode *node;
                    339:   struct listnode *cnode;
                    340:   struct interface *ifp;
                    341:   struct connected *ifc;
                    342:   struct prefix *p;
                    343: 
                    344:   /* If nexthop address matches local configured address then it is
                    345:      invalid nexthop. */
                    346:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
                    347:     {
                    348:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
                    349:        {           
                    350:          p = ifc->address;
                    351: 
                    352:          if (p->family == AF_INET
                    353:              && IPV4_ADDR_SAME (&p->u.prefix4, addr))
                    354:            return -1;
                    355:        }
                    356:     }
                    357:   return 0;
                    358: }
                    359: 
                    360: /* RIP add route to routing table. */
                    361: static void
                    362: rip_rte_process (struct rte *rte, struct sockaddr_in *from,
                    363:                  struct interface *ifp)
                    364: {
                    365:   int ret;
                    366:   struct prefix_ipv4 p;
                    367:   struct route_node *rp;
                    368:   struct rip_info *rinfo, rinfotmp;
                    369:   struct rip_interface *ri;
                    370:   struct in_addr *nexthop;
                    371:   u_char oldmetric;
                    372:   int same = 0;
                    373:   int route_reuse = 0;
                    374:   unsigned char old_dist, new_dist;
                    375: 
                    376:   /* Make prefix structure. */
                    377:   memset (&p, 0, sizeof (struct prefix_ipv4));
                    378:   p.family = AF_INET;
                    379:   p.prefix = rte->prefix;
                    380:   p.prefixlen = ip_masklen (rte->mask);
                    381: 
                    382:   /* Make sure mask is applied. */
                    383:   apply_mask_ipv4 (&p);
                    384: 
                    385:   /* Apply input filters. */
                    386:   ri = ifp->info;
                    387: 
                    388:   ret = rip_incoming_filter (&p, ri);
                    389:   if (ret < 0)
                    390:     return;
                    391: 
                    392:   /* Modify entry according to the interface routemap. */
                    393:   if (ri->routemap[RIP_FILTER_IN])
                    394:     {
                    395:       int ret;
                    396:       struct rip_info newinfo;
                    397: 
                    398:       memset (&newinfo, 0, sizeof (newinfo));
                    399:       newinfo.type = ZEBRA_ROUTE_RIP;
                    400:       newinfo.sub_type = RIP_ROUTE_RTE;
                    401:       newinfo.nexthop = rte->nexthop;
                    402:       newinfo.from = from->sin_addr;
                    403:       newinfo.ifindex = ifp->ifindex;
                    404:       newinfo.metric = rte->metric;
                    405:       newinfo.metric_out = rte->metric; /* XXX */
                    406:       newinfo.tag = ntohs (rte->tag);   /* XXX */
                    407: 
                    408:       /* The object should be of the type of rip_info */
                    409:       ret = route_map_apply (ri->routemap[RIP_FILTER_IN],
                    410:                              (struct prefix *) &p, RMAP_RIP, &newinfo);
                    411: 
                    412:       if (ret == RMAP_DENYMATCH)
                    413:         {
                    414:           if (IS_RIP_DEBUG_PACKET)
                    415:             zlog_debug ("RIP %s/%d is filtered by route-map in",
                    416:                        inet_ntoa (p.prefix), p.prefixlen);
                    417:           return;
                    418:         }
                    419: 
                    420:       /* Get back the object */
                    421:       rte->nexthop = newinfo.nexthop_out;
                    422:       rte->tag = htons (newinfo.tag_out);       /* XXX */
                    423:       rte->metric = newinfo.metric_out; /* XXX: the routemap uses the metric_out field */
                    424:     }
                    425: 
                    426:   /* Once the entry has been validated, update the metric by
                    427:      adding the cost of the network on wich the message
                    428:      arrived. If the result is greater than infinity, use infinity
                    429:      (RFC2453 Sec. 3.9.2) */
                    430:   /* Zebra ripd can handle offset-list in. */
                    431:   ret = rip_offset_list_apply_in (&p, ifp, &rte->metric);
                    432: 
                    433:   /* If offset-list does not modify the metric use interface's
                    434:      metric. */
                    435:   if (!ret)
                    436:     rte->metric += ifp->metric;
                    437: 
                    438:   if (rte->metric > RIP_METRIC_INFINITY)
                    439:     rte->metric = RIP_METRIC_INFINITY;
                    440: 
                    441:   /* Set nexthop pointer. */
                    442:   if (rte->nexthop.s_addr == 0)
                    443:     nexthop = &from->sin_addr;
                    444:   else
                    445:     nexthop = &rte->nexthop;
                    446: 
                    447:   /* Check if nexthop address is myself, then do nothing. */
                    448:   if (rip_nexthop_check (nexthop) < 0)
                    449:     {
                    450:       if (IS_RIP_DEBUG_PACKET)
                    451:         zlog_debug ("Nexthop address %s is myself", inet_ntoa (*nexthop));
                    452:       return;
                    453:     }
                    454: 
                    455:   /* Get index for the prefix. */
                    456:   rp = route_node_get (rip->table, (struct prefix *) &p);
                    457: 
                    458:   /* Check to see whether there is already RIP route on the table. */
                    459:   rinfo = rp->info;
                    460: 
                    461:   if (rinfo)
                    462:     {
                    463:       /* Local static route. */
                    464:       if (rinfo->type == ZEBRA_ROUTE_RIP
                    465:           && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
                    466:               (rinfo->sub_type == RIP_ROUTE_DEFAULT))
                    467:           && rinfo->metric != RIP_METRIC_INFINITY)
                    468:         {
                    469:           route_unlock_node (rp);
                    470:           return;
                    471:         }
                    472: 
                    473:       /* Redistributed route check. */
                    474:       if (rinfo->type != ZEBRA_ROUTE_RIP
                    475:           && rinfo->metric != RIP_METRIC_INFINITY)
                    476:         {
                    477:           /* Fill in a minimaly temporary rip_info structure, for a future
                    478:              rip_distance_apply() use) */
                    479:           memset (&rinfotmp, 0, sizeof (rinfotmp));
                    480:           IPV4_ADDR_COPY (&rinfotmp.from, &from->sin_addr);
                    481:           rinfotmp.rp = rinfo->rp;
                    482:           new_dist = rip_distance_apply (&rinfotmp);
                    483:           new_dist = new_dist ? new_dist : ZEBRA_RIP_DISTANCE_DEFAULT;
                    484:           old_dist = rinfo->distance;
                    485:           /* Only connected routes may have a valid NULL distance */
                    486:           if (rinfo->type != ZEBRA_ROUTE_CONNECT)
                    487:             old_dist = old_dist ? old_dist : ZEBRA_RIP_DISTANCE_DEFAULT;
                    488:           /* If imported route does not have STRICT precedence, 
                    489:              mark it as a ghost */
                    490:           if (new_dist > old_dist 
                    491:               || rte->metric == RIP_METRIC_INFINITY)
                    492:             {
                    493:               route_unlock_node (rp);
                    494:               return;
                    495:             }
                    496:           else
                    497:             {
                    498:               RIP_TIMER_OFF (rinfo->t_timeout);
                    499:               RIP_TIMER_OFF (rinfo->t_garbage_collect);
                    500:                                                                                 
                    501:               rp->info = NULL;
                    502:               if (rip_route_rte (rinfo))
                    503:                 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p, 
                    504:                                         &rinfo->nexthop, rinfo->metric);
                    505:               rip_info_free (rinfo);
                    506:               rinfo = NULL;
                    507:               route_reuse = 1;
                    508:             }
                    509:         }
                    510:     }
                    511: 
                    512:   if (!rinfo)
                    513:     {
                    514:       /* Now, check to see whether there is already an explicit route
                    515:          for the destination prefix.  If there is no such route, add
                    516:          this route to the routing table, unless the metric is
                    517:          infinity (there is no point in adding a route which
                    518:          unusable). */
                    519:       if (rte->metric != RIP_METRIC_INFINITY)
                    520:         {
                    521:           rinfo = rip_info_new ();
                    522: 
                    523:           /* - Setting the destination prefix and length to those in
                    524:              the RTE. */
                    525:           rinfo->rp = rp;
                    526: 
                    527:           /* - Setting the metric to the newly calculated metric (as
                    528:              described above). */
                    529:           rinfo->metric = rte->metric;
                    530:           rinfo->tag = ntohs (rte->tag);
                    531: 
                    532:           /* - Set the next hop address to be the address of the router
                    533:              from which the datagram came or the next hop address
                    534:              specified by a next hop RTE. */
                    535:           IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
                    536:           IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
                    537:           rinfo->ifindex = ifp->ifindex;
                    538: 
                    539:           /* - Initialize the timeout for the route.  If the
                    540:              garbage-collection timer is running for this route, stop it
                    541:              (see section 2.3 for a discussion of the timers). */
                    542:           rip_timeout_update (rinfo);
                    543: 
                    544:           /* - Set the route change flag. */
                    545:           rinfo->flags |= RIP_RTF_CHANGED;
                    546: 
                    547:           /* - Signal the output process to trigger an update (see section
                    548:              2.5). */
                    549:           rip_event (RIP_TRIGGERED_UPDATE, 0);
                    550: 
                    551:           /* Finally, route goes into the kernel. */
                    552:           rinfo->type = ZEBRA_ROUTE_RIP;
                    553:           rinfo->sub_type = RIP_ROUTE_RTE;
                    554: 
                    555:           /* Set distance value. */
                    556:           rinfo->distance = rip_distance_apply (rinfo);
                    557: 
                    558:           rp->info = rinfo;
                    559:           rip_zebra_ipv4_add (&p, &rinfo->nexthop, rinfo->metric,
                    560:                               rinfo->distance);
                    561:           rinfo->flags |= RIP_RTF_FIB;
                    562:         }
                    563: 
                    564:       /* Unlock temporary lock, i.e. same behaviour */
                    565:       if (route_reuse)
                    566:         route_unlock_node (rp);
                    567:     }
                    568:   else
                    569:     {
                    570:       /* Route is there but we are not sure the route is RIP or not. */
                    571:       rinfo = rp->info;
                    572: 
                    573:       /* If there is an existing route, compare the next hop address
                    574:          to the address of the router from which the datagram came.
                    575:          If this datagram is from the same router as the existing
                    576:          route, reinitialize the timeout.  */
                    577:       same = (IPV4_ADDR_SAME (&rinfo->from, &from->sin_addr)
                    578:               && (rinfo->ifindex == ifp->ifindex));
                    579: 
                    580:       if (same)
                    581:         rip_timeout_update (rinfo);
                    582: 
                    583: 
                    584:       /* Fill in a minimaly temporary rip_info structure, for a future
                    585:          rip_distance_apply() use) */
                    586:       memset (&rinfotmp, 0, sizeof (rinfotmp));
                    587:       IPV4_ADDR_COPY (&rinfotmp.from, &from->sin_addr);
                    588:       rinfotmp.rp = rinfo->rp;
                    589: 
                    590: 
                    591:       /* Next, compare the metrics.  If the datagram is from the same
                    592:          router as the existing route, and the new metric is different
                    593:          than the old one; or, if the new metric is lower than the old
                    594:          one, or if the tag has been changed; or if there is a route
                    595:          with a lower administrave distance; or an update of the
                    596:          distance on the actual route; do the following actions: */
                    597:       if ((same && rinfo->metric != rte->metric)
                    598:           || (rte->metric < rinfo->metric)
                    599:           || ((same)
                    600:               && (rinfo->metric == rte->metric)
                    601:               && ntohs (rte->tag) != rinfo->tag)
                    602:           || (rinfo->distance > rip_distance_apply (&rinfotmp))
                    603:           || ((rinfo->distance != rip_distance_apply (rinfo)) && same))
                    604:         {
                    605:           /* - Adopt the route from the datagram.  That is, put the
                    606:              new metric in, and adjust the next hop address (if
                    607:              necessary). */
                    608:           oldmetric = rinfo->metric;
                    609:           rinfo->metric = rte->metric;
                    610:           rinfo->tag = ntohs (rte->tag);
                    611:           IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
                    612:           rinfo->ifindex = ifp->ifindex;
                    613:           rinfo->distance = rip_distance_apply (rinfo);
                    614: 
                    615:           /* Should a new route to this network be established
                    616:              while the garbage-collection timer is running, the
                    617:              new route will replace the one that is about to be
                    618:              deleted.  In this case the garbage-collection timer
                    619:              must be cleared. */
                    620: 
                    621:           if (oldmetric == RIP_METRIC_INFINITY &&
                    622:               rinfo->metric < RIP_METRIC_INFINITY)
                    623:             {
                    624:               rinfo->type = ZEBRA_ROUTE_RIP;
                    625:               rinfo->sub_type = RIP_ROUTE_RTE;
                    626: 
                    627:               RIP_TIMER_OFF (rinfo->t_garbage_collect);
                    628: 
                    629:               if (!IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
                    630:                 IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
                    631: 
                    632:               rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
                    633:                                   rinfo->distance);
                    634:               rinfo->flags |= RIP_RTF_FIB;
                    635:             }
                    636: 
                    637:           /* Update nexthop and/or metric value.  */
                    638:           if (oldmetric != RIP_METRIC_INFINITY)
                    639:             {
                    640:               rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
                    641:               rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
                    642:                                   rinfo->distance);
                    643:               rinfo->flags |= RIP_RTF_FIB;
                    644: 
                    645:               if (!IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
                    646:                 IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
                    647:             }
                    648: 
                    649:           /* - Set the route change flag and signal the output process
                    650:              to trigger an update. */
                    651:           rinfo->flags |= RIP_RTF_CHANGED;
                    652:           rip_event (RIP_TRIGGERED_UPDATE, 0);
                    653: 
                    654:           /* - If the new metric is infinity, start the deletion
                    655:              process (described above); */
                    656:           if (rinfo->metric == RIP_METRIC_INFINITY)
                    657:             {
                    658:               /* If the new metric is infinity, the deletion process
                    659:                  begins for the route, which is no longer used for
                    660:                  routing packets.  Note that the deletion process is
                    661:                  started only when the metric is first set to
                    662:                  infinity.  If the metric was already infinity, then a
                    663:                  new deletion process is not started. */
                    664:               if (oldmetric != RIP_METRIC_INFINITY)
                    665:                 {
                    666:                   /* - The garbage-collection timer is set for 120 seconds. */
                    667:                   RIP_TIMER_ON (rinfo->t_garbage_collect,
                    668:                                 rip_garbage_collect, rip->garbage_time);
                    669:                   RIP_TIMER_OFF (rinfo->t_timeout);
                    670: 
                    671:                   /* - The metric for the route is set to 16
                    672:                      (infinity).  This causes the route to be removed
                    673:                      from service. */
                    674:                   rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
                    675:                   rinfo->flags &= ~RIP_RTF_FIB;
                    676: 
                    677:                   /* - The route change flag is to indicate that this
                    678:                      entry has been changed. */
                    679:                   /* - The output process is signalled to trigger a
                    680:                      response. */
                    681:                   ;             /* Above processes are already done previously. */
                    682:                 }
                    683:             }
                    684:           else
                    685:             {
                    686:               /* otherwise, re-initialize the timeout. */
                    687:               rip_timeout_update (rinfo);
                    688:             }
                    689:         }
                    690:       /* Unlock tempolary lock of the route. */
                    691:       route_unlock_node (rp);
                    692:     }
                    693: }
                    694: 
                    695: /* Dump RIP packet */
                    696: static void
                    697: rip_packet_dump (struct rip_packet *packet, int size, const char *sndrcv)
                    698: {
                    699:   caddr_t lim;
                    700:   struct rte *rte;
                    701:   const char *command_str;
                    702:   char pbuf[BUFSIZ], nbuf[BUFSIZ];
                    703:   u_char netmask = 0;
                    704:   u_char *p;
                    705: 
                    706:   /* Set command string. */
                    707:   if (packet->command > 0 && packet->command < RIP_COMMAND_MAX)
                    708:     command_str = lookup (rip_msg, packet->command);
                    709:   else
                    710:     command_str = "unknown";
                    711: 
                    712:   /* Dump packet header. */
                    713:   zlog_debug ("%s %s version %d packet size %d",
                    714:             sndrcv, command_str, packet->version, size);
                    715: 
                    716:   /* Dump each routing table entry. */
                    717:   rte = packet->rte;
                    718:   
                    719:   for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
                    720:     {
                    721:       if (packet->version == RIPv2)
                    722:        {
                    723:          netmask = ip_masklen (rte->mask);
                    724: 
                    725:           if (rte->family == htons (RIP_FAMILY_AUTH))
                    726:             {
                    727:               if (rte->tag == htons (RIP_AUTH_SIMPLE_PASSWORD))
                    728:                {
                    729:                  p = (u_char *)&rte->prefix;
                    730: 
                    731:                  zlog_debug ("  family 0x%X type %d auth string: %s",
                    732:                             ntohs (rte->family), ntohs (rte->tag), p);
                    733:                }
                    734:               else if (rte->tag == htons (RIP_AUTH_MD5))
                    735:                {
                    736:                  struct rip_md5_info *md5;
                    737: 
                    738:                  md5 = (struct rip_md5_info *) &packet->rte;
                    739: 
                    740:                  zlog_debug ("  family 0x%X type %d (MD5 authentication)",
                    741:                             ntohs (md5->family), ntohs (md5->type));
                    742:                  zlog_debug ("    RIP-2 packet len %d Key ID %d"
                    743:                              " Auth Data len %d",
                    744:                              ntohs (md5->packet_len), md5->keyid,
                    745:                              md5->auth_len);
                    746:                   zlog_debug ("    Sequence Number %ld",
                    747:                              (u_long) ntohl (md5->sequence));
                    748:                }
                    749:               else if (rte->tag == htons (RIP_AUTH_DATA))
                    750:                {
                    751:                  p = (u_char *)&rte->prefix;
                    752: 
                    753:                  zlog_debug ("  family 0x%X type %d (MD5 data)",
                    754:                             ntohs (rte->family), ntohs (rte->tag));
                    755:                  zlog_debug ("    MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
                    756:                             "%02X%02X%02X%02X%02X%02X%02X",
                    757:                              p[0], p[1], p[2], p[3], p[4], p[5], p[6],
                    758:                              p[7], p[9], p[10], p[11], p[12], p[13],
                    759:                              p[14], p[15]);
                    760:                }
                    761:              else
                    762:                {
                    763:                  zlog_debug ("  family 0x%X type %d (Unknown auth type)",
                    764:                             ntohs (rte->family), ntohs (rte->tag));
                    765:                }
                    766:             }
                    767:          else
                    768:            zlog_debug ("  %s/%d -> %s family %d tag %d metric %ld",
                    769:                        inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),
                    770:                        netmask, inet_ntop (AF_INET, &rte->nexthop, nbuf,
                    771:                                            BUFSIZ), ntohs (rte->family),
                    772:                        ntohs (rte->tag), (u_long) ntohl (rte->metric));
                    773:        }
                    774:       else
                    775:        {
                    776:          zlog_debug ("  %s family %d tag %d metric %ld", 
                    777:                     inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),
                    778:                     ntohs (rte->family), ntohs (rte->tag),
                    779:                     (u_long)ntohl (rte->metric));
                    780:        }
                    781:     }
                    782: }
                    783: 
                    784: /* Check if the destination address is valid (unicast; not net 0
                    785:    or 127) (RFC2453 Section 3.9.2 - Page 26).  But we don't
                    786:    check net 0 because we accept default route. */
                    787: static int
                    788: rip_destination_check (struct in_addr addr)
                    789: {
                    790:   u_int32_t destination;
                    791: 
                    792:   /* Convert to host byte order. */
                    793:   destination = ntohl (addr.s_addr);
                    794: 
                    795:   if (IPV4_NET127 (destination))
                    796:     return 0;
                    797: 
                    798:   /* Net 0 may match to the default route. */
                    799:   if (IPV4_NET0 (destination) && destination != 0)
                    800:     return 0;
                    801: 
                    802:   /* Unicast address must belong to class A, B, C. */
                    803:   if (IN_CLASSA (destination))
                    804:     return 1;
                    805:   if (IN_CLASSB (destination))
                    806:     return 1;
                    807:   if (IN_CLASSC (destination))
                    808:     return 1;
                    809: 
                    810:   return 0;
                    811: }
                    812: 
                    813: /* RIP version 2 authentication. */
                    814: static int
                    815: rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
                    816:                          struct interface *ifp)
                    817: {
                    818:   struct rip_interface *ri;
                    819:   char *auth_str;
                    820: 
                    821:   if (IS_RIP_DEBUG_EVENT)
                    822:     zlog_debug ("RIPv2 simple password authentication from %s",
                    823:               inet_ntoa (from->sin_addr));
                    824: 
                    825:   ri = ifp->info;
                    826: 
                    827:   if (ri->auth_type != RIP_AUTH_SIMPLE_PASSWORD
                    828:       || rte->tag != htons(RIP_AUTH_SIMPLE_PASSWORD))
                    829:     return 0;
                    830: 
                    831:   /* Simple password authentication. */
                    832:   if (ri->auth_str)
                    833:     {
                    834:       auth_str = (char *) &rte->prefix;
                    835:          
                    836:       if (strncmp (auth_str, ri->auth_str, 16) == 0)
                    837:        return 1;
                    838:     }
                    839:   if (ri->key_chain)
                    840:     {
                    841:       struct keychain *keychain;
                    842:       struct key *key;
                    843: 
                    844:       keychain = keychain_lookup (ri->key_chain);
                    845:       if (keychain == NULL)
                    846:        return 0;
                    847: 
                    848:       key = key_match_for_accept (keychain, (char *) &rte->prefix);
                    849:       if (key)
                    850:        return 1;
                    851:     }
                    852:   return 0;
                    853: }
                    854: 
                    855: /* RIP version 2 authentication with MD5. */
                    856: static int
                    857: rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from,
                    858:               int length, struct interface *ifp)
                    859: {
                    860:   struct rip_interface *ri;
                    861:   struct rip_md5_info *md5;
                    862:   struct rip_md5_data *md5data;
                    863:   struct keychain *keychain;
                    864:   struct key *key;
                    865:   MD5_CTX ctx;
                    866:   u_char digest[RIP_AUTH_MD5_SIZE];
                    867:   u_int16_t packet_len;
                    868:   char auth_str[RIP_AUTH_MD5_SIZE];
                    869:   
                    870:   if (IS_RIP_DEBUG_EVENT)
                    871:     zlog_debug ("RIPv2 MD5 authentication from %s",
                    872:                inet_ntoa (from->sin_addr));
                    873: 
                    874:   ri = ifp->info;
                    875:   md5 = (struct rip_md5_info *) &packet->rte;
                    876: 
                    877:   /* Check auth type. */
                    878:   if (ri->auth_type != RIP_AUTH_MD5 || md5->type != htons(RIP_AUTH_MD5))
                    879:     return 0;
                    880: 
                    881:   /* If the authentication length is less than 16, then it must be wrong for
                    882:    * any interpretation of rfc2082. Some implementations also interpret
                    883:    * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka RIP_AUTH_MD5_COMPAT_SIZE.
                    884:    */
                    885:   if ( !((md5->auth_len == RIP_AUTH_MD5_SIZE)
                    886:          || (md5->auth_len == RIP_AUTH_MD5_COMPAT_SIZE)))
                    887:     {
                    888:       if (IS_RIP_DEBUG_EVENT)
                    889:         zlog_debug ("RIPv2 MD5 authentication, strange authentication "
                    890:                    "length field %d", md5->auth_len);
                    891:     return 0;
                    892:     }
                    893: 
                    894:   /* grab and verify check packet length */
                    895:   packet_len = ntohs (md5->packet_len);
                    896: 
                    897:   if (packet_len > (length - RIP_HEADER_SIZE - RIP_AUTH_MD5_SIZE))
                    898:     {
                    899:       if (IS_RIP_DEBUG_EVENT)
                    900:         zlog_debug ("RIPv2 MD5 authentication, packet length field %d "
                    901:                    "greater than received length %d!",
                    902:                    md5->packet_len, length);
                    903:       return 0;
                    904:     }
                    905: 
                    906:   /* retrieve authentication data */
                    907:   md5data = (struct rip_md5_data *) (((u_char *) packet) + packet_len);
                    908:   
                    909:   memset (auth_str, 0, RIP_AUTH_MD5_SIZE);
                    910: 
                    911:   if (ri->key_chain)
                    912:     {
                    913:       keychain = keychain_lookup (ri->key_chain);
                    914:       if (keychain == NULL)
                    915:        return 0;
                    916: 
                    917:       key = key_lookup_for_accept (keychain, md5->keyid);
                    918:       if (key == NULL)
                    919:        return 0;
                    920: 
                    921:       strncpy (auth_str, key->string, RIP_AUTH_MD5_SIZE);
                    922:     }
                    923:   else if (ri->auth_str)
                    924:     strncpy (auth_str, ri->auth_str, RIP_AUTH_MD5_SIZE);
                    925: 
                    926:   if (auth_str[0] == 0)
                    927:     return 0;
                    928:   
                    929:   /* MD5 digest authentication. */
                    930:   memset (&ctx, 0, sizeof(ctx));
                    931:   MD5Init(&ctx);
                    932:   MD5Update(&ctx, packet, packet_len + RIP_HEADER_SIZE);
                    933:   MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE);
                    934:   MD5Final(digest, &ctx);
                    935:   
                    936:   if (memcmp (md5data->digest, digest, RIP_AUTH_MD5_SIZE) == 0)
                    937:     return packet_len;
                    938:   else
                    939:     return 0;
                    940: }
                    941: 
                    942: /* Pick correct auth string for sends, prepare auth_str buffer for use.
                    943:  * (left justified and padded).
                    944:  *
                    945:  * presumes one of ri or key is valid, and that the auth strings they point
                    946:  * to are nul terminated. If neither are present, auth_str will be fully
                    947:  * zero padded.
                    948:  *
                    949:  */
                    950: static void
                    951: rip_auth_prepare_str_send (struct rip_interface *ri, struct key *key, 
                    952:                            char *auth_str, int len)
                    953: {
                    954:   assert (ri || key);
                    955: 
                    956:   memset (auth_str, 0, len);
                    957:   if (key && key->string)
                    958:     strncpy (auth_str, key->string, len);
                    959:   else if (ri->auth_str)
                    960:     strncpy (auth_str, ri->auth_str, len);
                    961: 
                    962:   return;
                    963: }
                    964: 
                    965: /* Write RIPv2 simple password authentication information
                    966:  *
                    967:  * auth_str is presumed to be 2 bytes and correctly prepared 
                    968:  * (left justified and zero padded).
                    969:  */
                    970: static void
                    971: rip_auth_simple_write (struct stream *s, char *auth_str, int len)
                    972: {
                    973:   assert (s && len == RIP_AUTH_SIMPLE_SIZE);
                    974:   
                    975:   stream_putw (s, RIP_FAMILY_AUTH);
                    976:   stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
                    977:   stream_put (s, auth_str, RIP_AUTH_SIMPLE_SIZE);
                    978:   
                    979:   return;
                    980: }
                    981: 
                    982: /* write RIPv2 MD5 "authentication header" 
                    983:  * (uses the auth key data field)
                    984:  *
                    985:  * Digest offset field is set to 0.
                    986:  *
                    987:  * returns: offset of the digest offset field, which must be set when
                    988:  * length to the auth-data MD5 digest is known.
                    989:  */
                    990: static size_t
                    991: rip_auth_md5_ah_write (struct stream *s, struct rip_interface *ri, 
                    992:                        struct key *key)
                    993: {
                    994:   size_t doff = 0;
                    995: 
                    996:   assert (s && ri && ri->auth_type == RIP_AUTH_MD5);
                    997: 
                    998:   /* MD5 authentication. */
                    999:   stream_putw (s, RIP_FAMILY_AUTH);
                   1000:   stream_putw (s, RIP_AUTH_MD5);
                   1001: 
                   1002:   /* MD5 AH digest offset field.
                   1003:    *
                   1004:    * Set to placeholder value here, to true value when RIP-2 Packet length
                   1005:    * is known.  Actual value is set in .....().
                   1006:    */
                   1007:   doff = stream_get_endp(s);
                   1008:   stream_putw (s, 0);
                   1009: 
                   1010:   /* Key ID. */
                   1011:   if (key)
                   1012:     stream_putc (s, key->index % 256);
                   1013:   else
                   1014:     stream_putc (s, 1);
                   1015: 
                   1016:   /* Auth Data Len.  Set 16 for MD5 authentication data. Older ripds 
                   1017:    * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for this
                   1018:    * to be configurable. 
                   1019:    */
                   1020:   stream_putc (s, ri->md5_auth_len);
                   1021: 
                   1022:   /* Sequence Number (non-decreasing). */
                   1023:   /* RFC2080: The value used in the sequence number is
                   1024:      arbitrary, but two suggestions are the time of the
                   1025:      message's creation or a simple message counter. */
                   1026:   stream_putl (s, time (NULL));
                   1027:              
                   1028:   /* Reserved field must be zero. */
                   1029:   stream_putl (s, 0);
                   1030:   stream_putl (s, 0);
                   1031: 
                   1032:   return doff;
                   1033: }
                   1034: 
                   1035: /* If authentication is in used, write the appropriate header
                   1036:  * returns stream offset to which length must later be written
                   1037:  * or 0 if this is not required
                   1038:  */
                   1039: static size_t
                   1040: rip_auth_header_write (struct stream *s, struct rip_interface *ri, 
                   1041:                        struct key *key, char *auth_str, int len)
                   1042: {
                   1043:   assert (ri->auth_type != RIP_NO_AUTH);
                   1044:   
                   1045:   switch (ri->auth_type)
                   1046:     {
                   1047:       case RIP_AUTH_SIMPLE_PASSWORD:
                   1048:         rip_auth_prepare_str_send (ri, key, auth_str, len);
                   1049:         rip_auth_simple_write (s, auth_str, len);
                   1050:         return 0;
                   1051:       case RIP_AUTH_MD5:
                   1052:         return rip_auth_md5_ah_write (s, ri, key);
                   1053:     }
                   1054:   assert (1);
                   1055:   return 0;
                   1056: }
                   1057: 
                   1058: /* Write RIPv2 MD5 authentication data trailer */
                   1059: static void
                   1060: rip_auth_md5_set (struct stream *s, struct rip_interface *ri, size_t doff,
                   1061:                   char *auth_str, int authlen)
                   1062: {
                   1063:   unsigned long len;
                   1064:   MD5_CTX ctx;
                   1065:   unsigned char digest[RIP_AUTH_MD5_SIZE];
                   1066: 
                   1067:   /* Make it sure this interface is configured as MD5
                   1068:      authentication. */
                   1069:   assert ((ri->auth_type == RIP_AUTH_MD5) && (authlen == RIP_AUTH_MD5_SIZE));
                   1070:   assert (doff > 0);
                   1071:   
                   1072:   /* Get packet length. */
                   1073:   len = stream_get_endp(s);
                   1074: 
                   1075:   /* Check packet length. */
                   1076:   if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE))
                   1077:     {
                   1078:       zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len);
                   1079:       return;
                   1080:     }
                   1081: 
                   1082:   /* Set the digest offset length in the header */
                   1083:   stream_putw_at (s, doff, len);
                   1084:   
                   1085:   /* Set authentication data. */
                   1086:   stream_putw (s, RIP_FAMILY_AUTH);
                   1087:   stream_putw (s, RIP_AUTH_DATA);
                   1088: 
                   1089:   /* Generate a digest for the RIP packet. */
                   1090:   memset(&ctx, 0, sizeof(ctx));
                   1091:   MD5Init(&ctx);
                   1092:   MD5Update(&ctx, STREAM_DATA (s), stream_get_endp (s));
                   1093:   MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE);
                   1094:   MD5Final(digest, &ctx);
                   1095: 
                   1096:   /* Copy the digest to the packet. */
                   1097:   stream_write (s, digest, RIP_AUTH_MD5_SIZE);
                   1098: }
                   1099: 
                   1100: /* RIP routing information. */
                   1101: static void
                   1102: rip_response_process (struct rip_packet *packet, int size, 
                   1103:                      struct sockaddr_in *from, struct connected *ifc)
                   1104: {
                   1105:   caddr_t lim;
                   1106:   struct rte *rte;
                   1107:   struct prefix_ipv4 ifaddr;
                   1108:   struct prefix_ipv4 ifaddrclass;
                   1109:   int subnetted;
                   1110:       
                   1111:   /* We don't know yet. */
                   1112:   subnetted = -1;
                   1113: 
                   1114:   /* The Response must be ignored if it is not from the RIP
                   1115:      port. (RFC2453 - Sec. 3.9.2)*/
                   1116:   if (from->sin_port != htons(RIP_PORT_DEFAULT))
                   1117:     {
                   1118:       zlog_info ("response doesn't come from RIP port: %d",
                   1119:                 from->sin_port);
                   1120:       rip_peer_bad_packet (from);
                   1121:       return;
                   1122:     }
                   1123: 
                   1124:   /* The datagram's IPv4 source address should be checked to see
                   1125:      whether the datagram is from a valid neighbor; the source of the
                   1126:      datagram must be on a directly connected network (RFC2453 - Sec. 3.9.2) */
                   1127:   if (if_lookup_address(from->sin_addr) == NULL) 
                   1128:     {
                   1129:       zlog_info ("This datagram doesn't came from a valid neighbor: %s",
                   1130:                 inet_ntoa (from->sin_addr));
                   1131:       rip_peer_bad_packet (from);
                   1132:       return;
                   1133:     }
                   1134: 
                   1135:   /* It is also worth checking to see whether the response is from one
                   1136:      of the router's own addresses. */
                   1137: 
                   1138:   ; /* Alredy done in rip_read () */
                   1139: 
                   1140:   /* Update RIP peer. */
                   1141:   rip_peer_update (from, packet->version);
                   1142: 
                   1143:   /* Set RTE pointer. */
                   1144:   rte = packet->rte;
                   1145: 
                   1146:   for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
                   1147:     {
                   1148:       /* RIPv2 authentication check. */
                   1149:       /* If the Address Family Identifier of the first (and only the
                   1150:         first) entry in the message is 0xFFFF, then the remainder of
                   1151:         the entry contains the authentication. */
                   1152:       /* If the packet gets here it means authentication enabled */
                   1153:       /* Check is done in rip_read(). So, just skipping it */
                   1154:       if (packet->version == RIPv2 &&
                   1155:          rte == packet->rte &&
                   1156:          rte->family == htons(RIP_FAMILY_AUTH))
                   1157:        continue;
                   1158: 
                   1159:       if (rte->family != htons(AF_INET))
                   1160:        {
                   1161:          /* Address family check.  RIP only supports AF_INET. */
                   1162:          zlog_info ("Unsupported family %d from %s.",
                   1163:                     ntohs (rte->family), inet_ntoa (from->sin_addr));
                   1164:          continue;
                   1165:        }
                   1166: 
                   1167:       /* - is the destination address valid (e.g., unicast; not net 0
                   1168:          or 127) */
                   1169:       if (! rip_destination_check (rte->prefix))
                   1170:         {
                   1171:          zlog_info ("Network is net 0 or net 127 or it is not unicast network");
                   1172:          rip_peer_bad_route (from);
                   1173:          continue;
                   1174:        } 
                   1175: 
                   1176:       /* Convert metric value to host byte order. */
                   1177:       rte->metric = ntohl (rte->metric);
                   1178: 
                   1179:       /* - is the metric valid (i.e., between 1 and 16, inclusive) */
                   1180:       if (! (rte->metric >= 1 && rte->metric <= 16))
                   1181:        {
                   1182:          zlog_info ("Route's metric is not in the 1-16 range.");
                   1183:          rip_peer_bad_route (from);
                   1184:          continue;
                   1185:        }
                   1186: 
                   1187:       /* RIPv1 does not have nexthop value. */
                   1188:       if (packet->version == RIPv1 && rte->nexthop.s_addr != 0)
                   1189:        {
                   1190:          zlog_info ("RIPv1 packet with nexthop value %s",
                   1191:                     inet_ntoa (rte->nexthop));
                   1192:          rip_peer_bad_route (from);
                   1193:          continue;
                   1194:        }
                   1195: 
                   1196:       /* That is, if the provided information is ignored, a possibly
                   1197:         sub-optimal, but absolutely valid, route may be taken.  If
                   1198:         the received Next Hop is not directly reachable, it should be
                   1199:         treated as 0.0.0.0. */
                   1200:       if (packet->version == RIPv2 && rte->nexthop.s_addr != 0)
                   1201:        {
                   1202:          u_int32_t addrval;
                   1203: 
                   1204:          /* Multicast address check. */
                   1205:          addrval = ntohl (rte->nexthop.s_addr);
                   1206:          if (IN_CLASSD (addrval))
                   1207:            {
                   1208:              zlog_info ("Nexthop %s is multicast address, skip this rte",
                   1209:                         inet_ntoa (rte->nexthop));
                   1210:              continue;
                   1211:            }
                   1212: 
                   1213:          if (! if_lookup_address (rte->nexthop))
                   1214:            {
                   1215:              struct route_node *rn;
                   1216:              struct rip_info *rinfo;
                   1217: 
                   1218:              rn = route_node_match_ipv4 (rip->table, &rte->nexthop);
                   1219: 
                   1220:              if (rn)
                   1221:                {
                   1222:                  rinfo = rn->info;
                   1223: 
                   1224:                  if (rinfo->type == ZEBRA_ROUTE_RIP
                   1225:                      && rinfo->sub_type == RIP_ROUTE_RTE)
                   1226:                    {
                   1227:                      if (IS_RIP_DEBUG_EVENT)
                   1228:                        zlog_debug ("Next hop %s is on RIP network.  Set nexthop to the packet's originator", inet_ntoa (rte->nexthop));
                   1229:                      rte->nexthop = rinfo->from;
                   1230:                    }
                   1231:                  else
                   1232:                    {
                   1233:                      if (IS_RIP_DEBUG_EVENT)
                   1234:                        zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
                   1235:                      rte->nexthop.s_addr = 0;
                   1236:                    }
                   1237: 
                   1238:                  route_unlock_node (rn);
                   1239:                }
                   1240:              else
                   1241:                {
                   1242:                  if (IS_RIP_DEBUG_EVENT)
                   1243:                    zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
                   1244:                  rte->nexthop.s_addr = 0;
                   1245:                }
                   1246: 
                   1247:            }
                   1248:        }
                   1249: 
                   1250:      /* For RIPv1, there won't be a valid netmask.  
                   1251: 
                   1252:        This is a best guess at the masks.  If everyone was using old
                   1253:        Ciscos before the 'ip subnet zero' option, it would be almost
                   1254:        right too :-)
                   1255:       
                   1256:        Cisco summarize ripv1 advertisments to the classful boundary
                   1257:        (/16 for class B's) except when the RIP packet does to inside
                   1258:        the classful network in question.  */
                   1259: 
                   1260:       if ((packet->version == RIPv1 && rte->prefix.s_addr != 0) 
                   1261:          || (packet->version == RIPv2 
                   1262:              && (rte->prefix.s_addr != 0 && rte->mask.s_addr == 0)))
                   1263:        {
                   1264:          u_int32_t destination;
                   1265: 
                   1266:          if (subnetted == -1)
                   1267:             {
                   1268:               memcpy (&ifaddr, ifc->address, sizeof (struct prefix_ipv4));
                   1269:               memcpy (&ifaddrclass, &ifaddr, sizeof (struct prefix_ipv4));
                   1270:               apply_classful_mask_ipv4 (&ifaddrclass);
                   1271:               subnetted = 0;
                   1272:               if (ifaddr.prefixlen > ifaddrclass.prefixlen)
                   1273:                 subnetted = 1;
                   1274:             }
                   1275: 
                   1276:          destination = ntohl (rte->prefix.s_addr);
                   1277: 
                   1278:          if (IN_CLASSA (destination))
                   1279:              masklen2ip (8, &rte->mask);
                   1280:          else if (IN_CLASSB (destination))
                   1281:              masklen2ip (16, &rte->mask);
                   1282:          else if (IN_CLASSC (destination))
                   1283:              masklen2ip (24, &rte->mask);
                   1284: 
                   1285:          if (subnetted == 1)
                   1286:            masklen2ip (ifaddrclass.prefixlen,
                   1287:                        (struct in_addr *) &destination);
                   1288:          if ((subnetted == 1) && ((rte->prefix.s_addr & destination) ==
                   1289:              ifaddrclass.prefix.s_addr))
                   1290:            {
                   1291:              masklen2ip (ifaddr.prefixlen, &rte->mask);
                   1292:              if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)
                   1293:                masklen2ip (32, &rte->mask);
                   1294:              if (IS_RIP_DEBUG_EVENT)
                   1295:                zlog_debug ("Subnetted route %s", inet_ntoa (rte->prefix));
                   1296:            }
                   1297:          else
                   1298:            {
                   1299:              if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)
                   1300:                continue;
                   1301:            }
                   1302: 
                   1303:          if (IS_RIP_DEBUG_EVENT)
                   1304:            {
                   1305:              zlog_debug ("Resultant route %s", inet_ntoa (rte->prefix));
                   1306:              zlog_debug ("Resultant mask %s", inet_ntoa (rte->mask));
                   1307:            }
                   1308:        }
                   1309: 
                   1310:       /* In case of RIPv2, if prefix in RTE is not netmask applied one
                   1311:          ignore the entry.  */
                   1312:       if ((packet->version == RIPv2) 
                   1313:          && (rte->mask.s_addr != 0) 
                   1314:          && ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr))
                   1315:        {
                   1316:          zlog_warn ("RIPv2 address %s is not mask /%d applied one",
                   1317:                     inet_ntoa (rte->prefix), ip_masklen (rte->mask));
                   1318:          rip_peer_bad_route (from);
                   1319:          continue;
                   1320:        }
                   1321: 
                   1322:       /* Default route's netmask is ignored. */
                   1323:       if (packet->version == RIPv2
                   1324:          && (rte->prefix.s_addr == 0)
                   1325:          && (rte->mask.s_addr != 0))
                   1326:        {
                   1327:          if (IS_RIP_DEBUG_EVENT)
                   1328:            zlog_debug ("Default route with non-zero netmask.  Set zero to netmask");
                   1329:          rte->mask.s_addr = 0;
                   1330:        }
                   1331:          
                   1332:       /* Routing table updates. */
                   1333:       rip_rte_process (rte, from, ifc->ifp);
                   1334:     }
                   1335: }
                   1336: 
                   1337: /* Make socket for RIP protocol. */
                   1338: static int 
                   1339: rip_create_socket (struct sockaddr_in *from)
                   1340: {
                   1341:   int ret;
                   1342:   int sock;
                   1343:   struct sockaddr_in addr;
                   1344:   
                   1345:   memset (&addr, 0, sizeof (struct sockaddr_in));
                   1346:   
                   1347:   if (!from)
                   1348:     {
                   1349:       addr.sin_family = AF_INET;
                   1350:       addr.sin_addr.s_addr = INADDR_ANY;
                   1351: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
                   1352:       addr.sin_len = sizeof (struct sockaddr_in);
                   1353: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
                   1354:     } else {
                   1355:       memcpy(&addr, from, sizeof(addr));
                   1356:     }
                   1357:   
                   1358:   /* sending port must always be the RIP port */
                   1359:   addr.sin_port = htons (RIP_PORT_DEFAULT);
                   1360:   
                   1361:   /* Make datagram socket. */
                   1362:   sock = socket (AF_INET, SOCK_DGRAM, 0);
                   1363:   if (sock < 0) 
                   1364:     {
                   1365:       zlog_err("Cannot create UDP socket: %s", safe_strerror(errno));
                   1366:       exit (1);
                   1367:     }
                   1368: 
                   1369:   sockopt_broadcast (sock);
                   1370:   sockopt_reuseaddr (sock);
                   1371:   sockopt_reuseport (sock);
                   1372: #ifdef RIP_RECVMSG
                   1373:   setsockopt_pktinfo (sock);
                   1374: #endif /* RIP_RECVMSG */
                   1375: #ifdef IPTOS_PREC_INTERNETCONTROL
                   1376:   setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL);
                   1377: #endif
                   1378: 
                   1379:   if (ripd_privs.change (ZPRIVS_RAISE))
                   1380:       zlog_err ("rip_create_socket: could not raise privs");
                   1381:   setsockopt_so_recvbuf (sock, RIP_UDP_RCV_BUF);
                   1382:   if ( (ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr))) < 0)
                   1383:   
                   1384:     {
                   1385:       int save_errno = errno;
                   1386:       if (ripd_privs.change (ZPRIVS_LOWER))
                   1387:         zlog_err ("rip_create_socket: could not lower privs");
                   1388:       
                   1389:       zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__,
                   1390:               sock, inet_ntoa(addr.sin_addr), 
                   1391:               (int) ntohs(addr.sin_port), 
                   1392:               safe_strerror(save_errno));
                   1393:       
                   1394:       close (sock);
                   1395:       return ret;
                   1396:     }
                   1397:   
                   1398:   if (ripd_privs.change (ZPRIVS_LOWER))
                   1399:       zlog_err ("rip_create_socket: could not lower privs");
                   1400:       
                   1401:   return sock;
                   1402: }
                   1403: 
                   1404: /* RIP packet send to destination address, on interface denoted by
                   1405:  * by connected argument. NULL to argument denotes destination should be
                   1406:  * should be RIP multicast group
                   1407:  */
                   1408: static int
                   1409: rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
                   1410:                  struct connected *ifc)
                   1411: {
                   1412:   int ret, send_sock;
                   1413:   struct sockaddr_in sin;
                   1414:   
                   1415:   assert (ifc != NULL);
                   1416:   
                   1417:   if (IS_RIP_DEBUG_PACKET)
                   1418:     {
                   1419: #define ADDRESS_SIZE 20
                   1420:       char dst[ADDRESS_SIZE];
                   1421:       dst[ADDRESS_SIZE - 1] = '\0';
                   1422:       
                   1423:       if (to)
                   1424:         {
                   1425:           strncpy (dst, inet_ntoa(to->sin_addr), ADDRESS_SIZE - 1);
                   1426:         }
                   1427:       else
                   1428:         {
                   1429:           sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
                   1430:           strncpy (dst, inet_ntoa(sin.sin_addr), ADDRESS_SIZE - 1);
                   1431:         }
                   1432: #undef ADDRESS_SIZE
                   1433:       zlog_debug("rip_send_packet %s > %s (%s)",
                   1434:                 inet_ntoa(ifc->address->u.prefix4),
                   1435:                 dst, ifc->ifp->name);
                   1436:     }
                   1437:   
                   1438:   if ( CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY) )
                   1439:     {
                   1440:       /*
                   1441:        * ZEBRA_IFA_SECONDARY is set on linux when an interface is configured
                   1442:        * with multiple addresses on the same subnet: the first address
                   1443:        * on the subnet is configured "primary", and all subsequent addresses
                   1444:        * on that subnet are treated as "secondary" addresses. 
                   1445:        * In order to avoid routing-table bloat on other rip listeners, 
                   1446:        * we do not send out RIP packets with ZEBRA_IFA_SECONDARY source addrs.
                   1447:        * XXX Since Linux is the only system for which the ZEBRA_IFA_SECONDARY
                   1448:        * flag is set, we would end up sending a packet for a "secondary"
                   1449:        * source address on non-linux systems.  
                   1450:        */
                   1451:       if (IS_RIP_DEBUG_PACKET)
                   1452:         zlog_debug("duplicate dropped");
                   1453:       return 0;
                   1454:     }
                   1455: 
                   1456:   /* Make destination address. */
                   1457:   memset (&sin, 0, sizeof (struct sockaddr_in));
                   1458:   sin.sin_family = AF_INET;
                   1459: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
                   1460:   sin.sin_len = sizeof (struct sockaddr_in);
                   1461: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
                   1462: 
                   1463:   /* When destination is specified, use it's port and address. */
                   1464:   if (to)
                   1465:     {
                   1466:       sin.sin_port = to->sin_port;
                   1467:       sin.sin_addr = to->sin_addr;
                   1468:       send_sock = rip->sock;
                   1469:     }
                   1470:   else
                   1471:     {
                   1472:       struct sockaddr_in from;
                   1473:       
                   1474:       sin.sin_port = htons (RIP_PORT_DEFAULT);
                   1475:       sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
                   1476:       
                   1477:       /* multicast send should bind to local interface address */
1.1.1.2 ! misho    1478:       memset (&from, 0, sizeof (from));
1.1       misho    1479:       from.sin_family = AF_INET;
                   1480:       from.sin_port = htons (RIP_PORT_DEFAULT);
                   1481:       from.sin_addr = ifc->address->u.prefix4;
                   1482: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
                   1483:       from.sin_len = sizeof (struct sockaddr_in);
                   1484: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
                   1485:       
                   1486:       /*
                   1487:        * we have to open a new socket for each packet because this
                   1488:        * is the most portable way to bind to a different source
                   1489:        * ipv4 address for each packet. 
                   1490:        */
                   1491:       if ( (send_sock = rip_create_socket (&from)) < 0)
                   1492:         {
                   1493:           zlog_warn("rip_send_packet could not create socket.");
                   1494:           return -1;
                   1495:         }
                   1496:       rip_interface_multicast_set (send_sock, ifc);
                   1497:     }
                   1498: 
                   1499:   ret = sendto (send_sock, buf, size, 0, (struct sockaddr *)&sin,
                   1500:                sizeof (struct sockaddr_in));
                   1501: 
                   1502:   if (IS_RIP_DEBUG_EVENT)
                   1503:       zlog_debug ("SEND to  %s.%d", inet_ntoa(sin.sin_addr), 
                   1504:                   ntohs (sin.sin_port));
                   1505: 
                   1506:   if (ret < 0)
                   1507:     zlog_warn ("can't send packet : %s", safe_strerror (errno));
                   1508: 
                   1509:   if (!to)
                   1510:     close(send_sock);
                   1511: 
                   1512:   return ret;
                   1513: }
                   1514: 
                   1515: /* Add redistributed route to RIP table. */
                   1516: void
                   1517: rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p, 
                   1518:                      unsigned int ifindex, struct in_addr *nexthop,
                   1519:                       unsigned int metric, unsigned char distance)
                   1520: {
                   1521:   int ret;
                   1522:   struct route_node *rp;
                   1523:   struct rip_info *rinfo;
                   1524: 
                   1525:   /* Redistribute route  */
                   1526:   ret = rip_destination_check (p->prefix);
                   1527:   if (! ret)
                   1528:     return;
                   1529: 
                   1530:   rp = route_node_get (rip->table, (struct prefix *) p);
                   1531: 
                   1532:   rinfo = rp->info;
                   1533: 
                   1534:   if (rinfo)
                   1535:     {
                   1536:       if (rinfo->type == ZEBRA_ROUTE_CONNECT 
                   1537:          && rinfo->sub_type == RIP_ROUTE_INTERFACE
                   1538:          && rinfo->metric != RIP_METRIC_INFINITY)
                   1539:        {
                   1540:          route_unlock_node (rp);
                   1541:          return;
                   1542:        }
                   1543: 
                   1544:       /* Manually configured RIP route check. */
                   1545:       if (rinfo->type == ZEBRA_ROUTE_RIP 
                   1546:          && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
                   1547:              (rinfo->sub_type == RIP_ROUTE_DEFAULT)) )
                   1548:        {
                   1549:          if (type != ZEBRA_ROUTE_RIP || ((sub_type != RIP_ROUTE_STATIC) &&
                   1550:                                          (sub_type != RIP_ROUTE_DEFAULT)))
                   1551:            {
                   1552:              route_unlock_node (rp);
                   1553:              return;
                   1554:            }
                   1555:        }
                   1556: 
                   1557:       RIP_TIMER_OFF (rinfo->t_timeout);
                   1558:       RIP_TIMER_OFF (rinfo->t_garbage_collect);
                   1559: 
                   1560:       if (rip_route_rte (rinfo))
                   1561:        rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p, &rinfo->nexthop,
                   1562:                               rinfo->metric);
                   1563:       rp->info = NULL;
                   1564:       rip_info_free (rinfo);
                   1565:       
                   1566:       route_unlock_node (rp);      
                   1567:     }
                   1568: 
                   1569:   rinfo = rip_info_new ();
                   1570:     
                   1571:   rinfo->type = type;
                   1572:   rinfo->sub_type = sub_type;
                   1573:   rinfo->ifindex = ifindex;
                   1574:   rinfo->metric = 1;
                   1575:   rinfo->external_metric = metric;
                   1576:   rinfo->distance = distance;
                   1577:   rinfo->rp = rp;
                   1578: 
                   1579:   if (nexthop)
                   1580:     rinfo->nexthop = *nexthop;
                   1581: 
                   1582:   rinfo->flags |= RIP_RTF_FIB;
                   1583:   rp->info = rinfo;
                   1584: 
                   1585:   rinfo->flags |= RIP_RTF_CHANGED;
                   1586: 
                   1587:   if (IS_RIP_DEBUG_EVENT) {
                   1588:     if (!nexthop)
                   1589:       zlog_debug ("Redistribute new prefix %s/%d on the interface %s",
                   1590:                  inet_ntoa(p->prefix), p->prefixlen,
                   1591:                  ifindex2ifname(ifindex));
                   1592:     else
                   1593:       zlog_debug ("Redistribute new prefix %s/%d with nexthop %s on the interface %s",
                   1594:                  inet_ntoa(p->prefix), p->prefixlen, inet_ntoa(rinfo->nexthop),
                   1595:                  ifindex2ifname(ifindex));
                   1596:   }
                   1597: 
                   1598: 
                   1599:   rip_event (RIP_TRIGGERED_UPDATE, 0);
                   1600: }
                   1601: 
                   1602: /* Delete redistributed route from RIP table. */
                   1603: void
                   1604: rip_redistribute_delete (int type, int sub_type, struct prefix_ipv4 *p, 
                   1605:                           unsigned int ifindex)
                   1606: {
                   1607:   int ret;
                   1608:   struct route_node *rp;
                   1609:   struct rip_info *rinfo;
                   1610: 
                   1611:   ret = rip_destination_check (p->prefix);
                   1612:   if (! ret)
                   1613:     return;
                   1614: 
                   1615:   rp = route_node_lookup (rip->table, (struct prefix *) p);
                   1616:   if (rp)
                   1617:     {
                   1618:       rinfo = rp->info;
                   1619: 
                   1620:       if (rinfo != NULL
                   1621:          && rinfo->type == type 
                   1622:          && rinfo->sub_type == sub_type 
                   1623:          && rinfo->ifindex == ifindex)
                   1624:        {
                   1625:          /* Perform poisoned reverse. */
                   1626:          rinfo->metric = RIP_METRIC_INFINITY;
                   1627:          RIP_TIMER_ON (rinfo->t_garbage_collect, 
                   1628:                        rip_garbage_collect, rip->garbage_time);
                   1629:          RIP_TIMER_OFF (rinfo->t_timeout);
                   1630:          rinfo->flags |= RIP_RTF_CHANGED;
                   1631: 
                   1632:           if (IS_RIP_DEBUG_EVENT)
                   1633:             zlog_debug ("Poisone %s/%d on the interface %s with an infinity metric [delete]",
                   1634:                        inet_ntoa(p->prefix), p->prefixlen,
                   1635:                        ifindex2ifname(ifindex));
                   1636: 
                   1637:          rip_event (RIP_TRIGGERED_UPDATE, 0);
                   1638:        }
                   1639:     }
                   1640: }
                   1641: 
                   1642: /* Response to request called from rip_read ().*/
                   1643: static void
                   1644: rip_request_process (struct rip_packet *packet, int size, 
                   1645:                     struct sockaddr_in *from, struct connected *ifc)
                   1646: {
                   1647:   caddr_t lim;
                   1648:   struct rte *rte;
                   1649:   struct prefix_ipv4 p;
                   1650:   struct route_node *rp;
                   1651:   struct rip_info *rinfo;
                   1652:   struct rip_interface *ri;
                   1653: 
                   1654:   /* Does not reponse to the requests on the loopback interfaces */
                   1655:   if (if_is_loopback (ifc->ifp))
                   1656:     return;
                   1657: 
                   1658:   /* Check RIP process is enabled on this interface. */
                   1659:   ri = ifc->ifp->info;
                   1660:   if (! ri->running)
                   1661:     return;
                   1662: 
                   1663:   /* When passive interface is specified, suppress responses */
                   1664:   if (ri->passive)
                   1665:     return;
                   1666:   
                   1667:   /* RIP peer update. */
                   1668:   rip_peer_update (from, packet->version);
                   1669: 
                   1670:   lim = ((caddr_t) packet) + size;
                   1671:   rte = packet->rte;
                   1672: 
                   1673:   /* The Request is processed entry by entry.  If there are no
                   1674:      entries, no response is given. */
                   1675:   if (lim == (caddr_t) rte)
                   1676:     return;
                   1677: 
                   1678:   /* There is one special case.  If there is exactly one entry in the
                   1679:      request, and it has an address family identifier of zero and a
                   1680:      metric of infinity (i.e., 16), then this is a request to send the
                   1681:      entire routing table. */
                   1682:   if (lim == ((caddr_t) (rte + 1)) &&
                   1683:       ntohs (rte->family) == 0 &&
                   1684:       ntohl (rte->metric) == RIP_METRIC_INFINITY)
                   1685:     {  
                   1686:       struct prefix_ipv4 saddr;
                   1687: 
                   1688:       /* saddr will be used for determining which routes to split-horizon.
                   1689:          Since the source address we'll pick will be on the same subnet as the
                   1690:          destination, for the purpose of split-horizoning, we'll
                   1691:          pretend that "from" is our source address.  */
                   1692:       saddr.family = AF_INET;
                   1693:       saddr.prefixlen = IPV4_MAX_BITLEN;
                   1694:       saddr.prefix = from->sin_addr;
                   1695: 
                   1696:       /* All route with split horizon */
                   1697:       rip_output_process (ifc, from, rip_all_route, packet->version);
                   1698:     }
                   1699:   else
                   1700:     {
                   1701:       /* Examine the list of RTEs in the Request one by one.  For each
                   1702:         entry, look up the destination in the router's routing
                   1703:         database and, if there is a route, put that route's metric in
                   1704:         the metric field of the RTE.  If there is no explicit route
                   1705:         to the specified destination, put infinity in the metric
                   1706:         field.  Once all the entries have been filled in, change the
                   1707:         command from Request to Response and send the datagram back
                   1708:         to the requestor. */
                   1709:       p.family = AF_INET;
                   1710: 
                   1711:       for (; ((caddr_t) rte) < lim; rte++)
                   1712:        {
                   1713:          p.prefix = rte->prefix;
                   1714:          p.prefixlen = ip_masklen (rte->mask);
                   1715:          apply_mask_ipv4 (&p);
                   1716:          
                   1717:          rp = route_node_lookup (rip->table, (struct prefix *) &p);
                   1718:          if (rp)
                   1719:            {
                   1720:              rinfo = rp->info;
                   1721:              rte->metric = htonl (rinfo->metric);
                   1722:              route_unlock_node (rp);
                   1723:            }
                   1724:          else
                   1725:            rte->metric = htonl (RIP_METRIC_INFINITY);
                   1726:        }
                   1727:       packet->command = RIP_RESPONSE;
                   1728: 
                   1729:       rip_send_packet ((u_char *)packet, size, from, ifc);
                   1730:     }
                   1731:   rip_global_queries++;
                   1732: }
                   1733: 
                   1734: #if RIP_RECVMSG
                   1735: /* Set IPv6 packet info to the socket. */
                   1736: static int
                   1737: setsockopt_pktinfo (int sock)
                   1738: {
                   1739:   int ret;
                   1740:   int val = 1;
                   1741:     
                   1742:   ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
                   1743:   if (ret < 0)
                   1744:     zlog_warn ("Can't setsockopt IP_PKTINFO : %s", safe_strerror (errno));
                   1745:   return ret;
                   1746: }
                   1747: 
                   1748: /* Read RIP packet by recvmsg function. */
                   1749: int
                   1750: rip_recvmsg (int sock, u_char *buf, int size, struct sockaddr_in *from,
                   1751:             int *ifindex)
                   1752: {
                   1753:   int ret;
                   1754:   struct msghdr msg;
                   1755:   struct iovec iov;
                   1756:   struct cmsghdr *ptr;
                   1757:   char adata[1024];
                   1758: 
                   1759:   msg.msg_name = (void *) from;
                   1760:   msg.msg_namelen = sizeof (struct sockaddr_in);
                   1761:   msg.msg_iov = &iov;
                   1762:   msg.msg_iovlen = 1;
                   1763:   msg.msg_control = (void *) adata;
                   1764:   msg.msg_controllen = sizeof adata;
                   1765:   iov.iov_base = buf;
                   1766:   iov.iov_len = size;
                   1767: 
                   1768:   ret = recvmsg (sock, &msg, 0);
                   1769:   if (ret < 0)
                   1770:     return ret;
                   1771: 
                   1772:   for (ptr = ZCMSG_FIRSTHDR(&msg); ptr != NULL; ptr = CMSG_NXTHDR(&msg, ptr))
                   1773:     if (ptr->cmsg_level == IPPROTO_IP && ptr->cmsg_type == IP_PKTINFO) 
                   1774:       {
                   1775:        struct in_pktinfo *pktinfo;
                   1776:        int i;
                   1777: 
                   1778:        pktinfo = (struct in_pktinfo *) CMSG_DATA (ptr);
                   1779:        i = pktinfo->ipi_ifindex;
                   1780:       }
                   1781:   return ret;
                   1782: }
                   1783: 
                   1784: /* RIP packet read function. */
                   1785: int
                   1786: rip_read_new (struct thread *t)
                   1787: {
                   1788:   int ret;
                   1789:   int sock;
                   1790:   char buf[RIP_PACKET_MAXSIZ];
                   1791:   struct sockaddr_in from;
                   1792:   unsigned int ifindex;
                   1793:   
                   1794:   /* Fetch socket then register myself. */
                   1795:   sock = THREAD_FD (t);
                   1796:   rip_event (RIP_READ, sock);
                   1797: 
                   1798:   /* Read RIP packet. */
                   1799:   ret = rip_recvmsg (sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex);
                   1800:   if (ret < 0)
                   1801:     {
                   1802:       zlog_warn ("Can't read RIP packet: %s", safe_strerror (errno));
                   1803:       return ret;
                   1804:     }
                   1805: 
                   1806:   return ret;
                   1807: }
                   1808: #endif /* RIP_RECVMSG */
                   1809: 
                   1810: /* First entry point of RIP packet. */
                   1811: static int
                   1812: rip_read (struct thread *t)
                   1813: {
                   1814:   int sock;
                   1815:   int ret;
                   1816:   int rtenum;
                   1817:   union rip_buf rip_buf;
                   1818:   struct rip_packet *packet;
                   1819:   struct sockaddr_in from;
                   1820:   int len;
                   1821:   int vrecv;
                   1822:   socklen_t fromlen;
                   1823:   struct interface *ifp;
                   1824:   struct connected *ifc;
                   1825:   struct rip_interface *ri;
                   1826: 
                   1827:   /* Fetch socket then register myself. */
                   1828:   sock = THREAD_FD (t);
                   1829:   rip->t_read = NULL;
                   1830: 
                   1831:   /* Add myself to tne next event */
                   1832:   rip_event (RIP_READ, sock);
                   1833: 
                   1834:   /* RIPd manages only IPv4. */
                   1835:   memset (&from, 0, sizeof (struct sockaddr_in));
                   1836:   fromlen = sizeof (struct sockaddr_in);
                   1837: 
                   1838:   len = recvfrom (sock, (char *)&rip_buf.buf, sizeof (rip_buf.buf), 0, 
                   1839:                  (struct sockaddr *) &from, &fromlen);
                   1840:   if (len < 0) 
                   1841:     {
                   1842:       zlog_info ("recvfrom failed: %s", safe_strerror (errno));
                   1843:       return len;
                   1844:     }
                   1845: 
                   1846:   /* Check is this packet comming from myself? */
                   1847:   if (if_check_address (from.sin_addr)) 
                   1848:     {
                   1849:       if (IS_RIP_DEBUG_PACKET)
                   1850:        zlog_debug ("ignore packet comes from myself");
                   1851:       return -1;
                   1852:     }
                   1853: 
                   1854:   /* Which interface is this packet comes from. */
                   1855:   ifp = if_lookup_address (from.sin_addr);
                   1856:   
                   1857:   /* RIP packet received */
                   1858:   if (IS_RIP_DEBUG_EVENT)
                   1859:     zlog_debug ("RECV packet from %s port %d on %s",
                   1860:               inet_ntoa (from.sin_addr), ntohs (from.sin_port),
                   1861:               ifp ? ifp->name : "unknown");
                   1862: 
                   1863:   /* If this packet come from unknown interface, ignore it. */
                   1864:   if (ifp == NULL)
                   1865:     {
                   1866:       zlog_info ("rip_read: cannot find interface for packet from %s port %d",
                   1867:                 inet_ntoa(from.sin_addr), ntohs (from.sin_port));
                   1868:       return -1;
                   1869:     }
                   1870:   
                   1871:   ifc = connected_lookup_address (ifp, from.sin_addr);
                   1872:   
                   1873:   if (ifc == NULL)
                   1874:     {
                   1875:       zlog_info ("rip_read: cannot find connected address for packet from %s "
                   1876:                 "port %d on interface %s",
                   1877:                 inet_ntoa(from.sin_addr), ntohs (from.sin_port), ifp->name);
                   1878:       return -1;
                   1879:     }
                   1880: 
                   1881:   /* Packet length check. */
                   1882:   if (len < RIP_PACKET_MINSIZ)
                   1883:     {
                   1884:       zlog_warn ("packet size %d is smaller than minimum size %d",
                   1885:                 len, RIP_PACKET_MINSIZ);
                   1886:       rip_peer_bad_packet (&from);
                   1887:       return len;
                   1888:     }
                   1889:   if (len > RIP_PACKET_MAXSIZ)
                   1890:     {
                   1891:       zlog_warn ("packet size %d is larger than max size %d",
                   1892:                 len, RIP_PACKET_MAXSIZ);
                   1893:       rip_peer_bad_packet (&from);
                   1894:       return len;
                   1895:     }
                   1896: 
                   1897:   /* Packet alignment check. */
                   1898:   if ((len - RIP_PACKET_MINSIZ) % 20)
                   1899:     {
                   1900:       zlog_warn ("packet size %d is wrong for RIP packet alignment", len);
                   1901:       rip_peer_bad_packet (&from);
                   1902:       return len;
                   1903:     }
                   1904: 
                   1905:   /* Set RTE number. */
                   1906:   rtenum = ((len - RIP_PACKET_MINSIZ) / 20);
                   1907: 
                   1908:   /* For easy to handle. */
                   1909:   packet = &rip_buf.rip_packet;
                   1910: 
                   1911:   /* RIP version check. */
                   1912:   if (packet->version == 0)
                   1913:     {
                   1914:       zlog_info ("version 0 with command %d received.", packet->command);
                   1915:       rip_peer_bad_packet (&from);
                   1916:       return -1;
                   1917:     }
                   1918: 
                   1919:   /* Dump RIP packet. */
                   1920:   if (IS_RIP_DEBUG_RECV)
                   1921:     rip_packet_dump (packet, len, "RECV");
                   1922: 
                   1923:   /* RIP version adjust.  This code should rethink now.  RFC1058 says
                   1924:      that "Version 1 implementations are to ignore this extra data and
                   1925:      process only the fields specified in this document.". So RIPv3
                   1926:      packet should be treated as RIPv1 ignoring must be zero field. */
                   1927:   if (packet->version > RIPv2)
                   1928:     packet->version = RIPv2;
                   1929: 
                   1930:   /* Is RIP running or is this RIP neighbor ?*/
                   1931:   ri = ifp->info;
                   1932:   if (! ri->running && ! rip_neighbor_lookup (&from))
                   1933:     {
                   1934:       if (IS_RIP_DEBUG_EVENT)
                   1935:        zlog_debug ("RIP is not enabled on interface %s.", ifp->name);
                   1936:       rip_peer_bad_packet (&from);
                   1937:       return -1;
                   1938:     }
                   1939: 
                   1940:   /* RIP Version check. RFC2453, 4.6 and 5.1 */
                   1941:   vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ?
                   1942:            rip->version_recv : ri->ri_receive);
                   1943:   if ((packet->version == RIPv1) && !(vrecv & RIPv1))
                   1944:     {
                   1945:       if (IS_RIP_DEBUG_PACKET)
                   1946:         zlog_debug ("  packet's v%d doesn't fit to if version spec", 
                   1947:                    packet->version);
                   1948:       rip_peer_bad_packet (&from);
                   1949:       return -1;
                   1950:     }
                   1951:   if ((packet->version == RIPv2) && !(vrecv & RIPv2))
                   1952:     {
                   1953:       if (IS_RIP_DEBUG_PACKET)
                   1954:         zlog_debug ("  packet's v%d doesn't fit to if version spec", 
                   1955:                    packet->version);
                   1956:       rip_peer_bad_packet (&from);
                   1957:       return -1;
                   1958:     }
                   1959:   
                   1960:   /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
                   1961:      messages, then RIP-1 and unauthenticated RIP-2 messages will be
                   1962:      accepted; authenticated RIP-2 messages shall be discarded.  */
                   1963:   if ((ri->auth_type == RIP_NO_AUTH) 
                   1964:       && rtenum 
                   1965:       && (packet->version == RIPv2) 
                   1966:       && (packet->rte->family == htons(RIP_FAMILY_AUTH)))
                   1967:     {
                   1968:       if (IS_RIP_DEBUG_EVENT)
                   1969:        zlog_debug ("packet RIPv%d is dropped because authentication disabled", 
                   1970:                   packet->version);
                   1971:       rip_peer_bad_packet (&from);
                   1972:       return -1;
                   1973:     }
                   1974:   
                   1975:   /* RFC:
                   1976:      If the router is configured to authenticate RIP-2 messages, then
                   1977:      RIP-1 messages and RIP-2 messages which pass authentication
                   1978:      testing shall be accepted; unauthenticated and failed
                   1979:      authentication RIP-2 messages shall be discarded.  For maximum
                   1980:      security, RIP-1 messages should be ignored when authentication is
                   1981:      in use (see section 4.1); otherwise, the routing information from
                   1982:      authenticated messages will be propagated by RIP-1 routers in an
                   1983:      unauthenticated manner. 
                   1984:   */
                   1985:   /* We make an exception for RIPv1 REQUEST packets, to which we'll
                   1986:    * always reply regardless of authentication settings, because:
                   1987:    *
                   1988:    * - if there other authorised routers on-link, the REQUESTor can
                   1989:    *   passively obtain the routing updates anyway
                   1990:    * - if there are no other authorised routers on-link, RIP can
                   1991:    *   easily be disabled for the link to prevent giving out information
                   1992:    *   on state of this routers RIP routing table..
                   1993:    *
                   1994:    * I.e. if RIPv1 has any place anymore these days, it's as a very
                   1995:    * simple way to distribute routing information (e.g. to embedded
                   1996:    * hosts / appliances) and the ability to give out RIPv1
                   1997:    * routing-information freely, while still requiring RIPv2
                   1998:    * authentication for any RESPONSEs might be vaguely useful.
                   1999:    */
                   2000:   if (ri->auth_type != RIP_NO_AUTH 
                   2001:       && packet->version == RIPv1)
                   2002:     {
                   2003:       /* Discard RIPv1 messages other than REQUESTs */
                   2004:       if (packet->command != RIP_REQUEST)
                   2005:         {
                   2006:           if (IS_RIP_DEBUG_PACKET)
                   2007:             zlog_debug ("RIPv1" " dropped because authentication enabled");
                   2008:           rip_peer_bad_packet (&from);
                   2009:           return -1;
                   2010:         }
                   2011:     }
                   2012:   else if (ri->auth_type != RIP_NO_AUTH)
                   2013:     {
                   2014:       const char *auth_desc;
                   2015:       
                   2016:       if (rtenum == 0)
                   2017:         {
                   2018:           /* There definitely is no authentication in the packet. */
                   2019:           if (IS_RIP_DEBUG_PACKET)
                   2020:             zlog_debug ("RIPv2 authentication failed: no auth RTE in packet");
                   2021:           rip_peer_bad_packet (&from);
                   2022:           return -1;
                   2023:         }
                   2024:       
                   2025:       /* First RTE must be an Authentication Family RTE */
                   2026:       if (packet->rte->family != htons(RIP_FAMILY_AUTH))
                   2027:         {
                   2028:           if (IS_RIP_DEBUG_PACKET)
                   2029:             zlog_debug ("RIPv2" " dropped because authentication enabled");
                   2030:          rip_peer_bad_packet (&from);
                   2031:          return -1;
                   2032:         }
                   2033:       
                   2034:       /* Check RIPv2 authentication. */
                   2035:       switch (ntohs(packet->rte->tag))
                   2036:         {
                   2037:           case RIP_AUTH_SIMPLE_PASSWORD:
                   2038:             auth_desc = "simple";
                   2039:             ret = rip_auth_simple_password (packet->rte, &from, ifp);
                   2040:             break;
                   2041:           
                   2042:           case RIP_AUTH_MD5:
                   2043:             auth_desc = "MD5";
                   2044:             ret = rip_auth_md5 (packet, &from, len, ifp);
                   2045:             /* Reset RIP packet length to trim MD5 data. */
                   2046:             len = ret;
                   2047:             break;
                   2048:           
                   2049:           default:
                   2050:             ret = 0;
                   2051:             auth_desc = "unknown type";
                   2052:             if (IS_RIP_DEBUG_PACKET)
                   2053:               zlog_debug ("RIPv2 Unknown authentication type %d",
                   2054:                           ntohs (packet->rte->tag));
                   2055:         }
                   2056:       
                   2057:       if (ret)
                   2058:         {
                   2059:           if (IS_RIP_DEBUG_PACKET)
                   2060:             zlog_debug ("RIPv2 %s authentication success", auth_desc);
                   2061:         }
                   2062:       else
                   2063:         {
                   2064:           if (IS_RIP_DEBUG_PACKET)
                   2065:             zlog_debug ("RIPv2 %s authentication failure", auth_desc);
                   2066:           rip_peer_bad_packet (&from);
                   2067:           return -1;
                   2068:         }
                   2069:     }
                   2070:   
                   2071:   /* Process each command. */
                   2072:   switch (packet->command)
                   2073:     {
                   2074:     case RIP_RESPONSE:
                   2075:       rip_response_process (packet, len, &from, ifc);
                   2076:       break;
                   2077:     case RIP_REQUEST:
                   2078:     case RIP_POLL:
                   2079:       rip_request_process (packet, len, &from, ifc);
                   2080:       break;
                   2081:     case RIP_TRACEON:
                   2082:     case RIP_TRACEOFF:
                   2083:       zlog_info ("Obsolete command %s received, please sent it to routed", 
                   2084:                 lookup (rip_msg, packet->command));
                   2085:       rip_peer_bad_packet (&from);
                   2086:       break;
                   2087:     case RIP_POLL_ENTRY:
                   2088:       zlog_info ("Obsolete command %s received", 
                   2089:                 lookup (rip_msg, packet->command));
                   2090:       rip_peer_bad_packet (&from);
                   2091:       break;
                   2092:     default:
                   2093:       zlog_info ("Unknown RIP command %d received", packet->command);
                   2094:       rip_peer_bad_packet (&from);
                   2095:       break;
                   2096:     }
                   2097: 
                   2098:   return len;
                   2099: }
                   2100: 
                   2101: /* Write routing table entry to the stream and return next index of
                   2102:    the routing table entry in the stream. */
                   2103: static int
                   2104: rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,
                   2105:                u_char version, struct rip_info *rinfo)
                   2106: {
                   2107:   struct in_addr mask;
                   2108: 
                   2109:   /* Write routing table entry. */
                   2110:   if (version == RIPv1)
                   2111:     {
                   2112:       stream_putw (s, AF_INET);
                   2113:       stream_putw (s, 0);
                   2114:       stream_put_ipv4 (s, p->prefix.s_addr);
                   2115:       stream_put_ipv4 (s, 0);
                   2116:       stream_put_ipv4 (s, 0);
                   2117:       stream_putl (s, rinfo->metric_out);
                   2118:     }
                   2119:   else
                   2120:     {
                   2121:       masklen2ip (p->prefixlen, &mask);
                   2122: 
                   2123:       stream_putw (s, AF_INET);
                   2124:       stream_putw (s, rinfo->tag_out);
                   2125:       stream_put_ipv4 (s, p->prefix.s_addr);
                   2126:       stream_put_ipv4 (s, mask.s_addr);
                   2127:       stream_put_ipv4 (s, rinfo->nexthop_out.s_addr);
                   2128:       stream_putl (s, rinfo->metric_out);
                   2129:     }
                   2130: 
                   2131:   return ++num;
                   2132: }
                   2133: 
                   2134: /* Send update to the ifp or spcified neighbor. */
                   2135: void
                   2136: rip_output_process (struct connected *ifc, struct sockaddr_in *to, 
                   2137:                     int route_type, u_char version)
                   2138: {
                   2139:   int ret;
                   2140:   struct stream *s;
                   2141:   struct route_node *rp;
                   2142:   struct rip_info *rinfo;
                   2143:   struct rip_interface *ri;
                   2144:   struct prefix_ipv4 *p;
                   2145:   struct prefix_ipv4 classfull;
                   2146:   struct prefix_ipv4 ifaddrclass;
                   2147:   struct key *key = NULL;
                   2148:   /* this might need to made dynamic if RIP ever supported auth methods
                   2149:      with larger key string sizes */
                   2150:   char auth_str[RIP_AUTH_SIMPLE_SIZE];
                   2151:   size_t doff = 0; /* offset of digest offset field */
                   2152:   int num = 0;
                   2153:   int rtemax;
                   2154:   int subnetted = 0;
                   2155: 
                   2156:   /* Logging output event. */
                   2157:   if (IS_RIP_DEBUG_EVENT)
                   2158:     {
                   2159:       if (to)
                   2160:        zlog_debug ("update routes to neighbor %s", inet_ntoa (to->sin_addr));
                   2161:       else
                   2162:        zlog_debug ("update routes on interface %s ifindex %d",
                   2163:                   ifc->ifp->name, ifc->ifp->ifindex);
                   2164:     }
                   2165: 
                   2166:   /* Set output stream. */
                   2167:   s = rip->obuf;
                   2168: 
                   2169:   /* Reset stream and RTE counter. */
                   2170:   stream_reset (s);
                   2171:   rtemax = (RIP_PACKET_MAXSIZ - 4) / 20;
                   2172: 
                   2173:   /* Get RIP interface. */
                   2174:   ri = ifc->ifp->info;
                   2175:     
                   2176:   /* If output interface is in simple password authentication mode, we
                   2177:      need space for authentication data.  */
                   2178:   if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
                   2179:     rtemax -= 1;
                   2180: 
                   2181:   /* If output interface is in MD5 authentication mode, we need space
                   2182:      for authentication header and data. */
                   2183:   if (ri->auth_type == RIP_AUTH_MD5)
                   2184:     rtemax -= 2;
                   2185: 
                   2186:   /* If output interface is in simple password authentication mode
                   2187:      and string or keychain is specified we need space for auth. data */
                   2188:   if (ri->auth_type != RIP_NO_AUTH)
                   2189:     {
                   2190:       if (ri->key_chain)
                   2191:        {
                   2192:          struct keychain *keychain;
                   2193: 
                   2194:          keychain = keychain_lookup (ri->key_chain);
                   2195:          if (keychain)
                   2196:            key = key_lookup_for_send (keychain);
                   2197:        }
                   2198:       /* to be passed to auth functions later */
                   2199:       rip_auth_prepare_str_send (ri, key, auth_str, RIP_AUTH_SIMPLE_SIZE);
                   2200:     }
                   2201: 
                   2202:   if (version == RIPv1)
                   2203:     {
                   2204:       memcpy (&ifaddrclass, ifc->address, sizeof (struct prefix_ipv4));
                   2205:       apply_classful_mask_ipv4 (&ifaddrclass);
                   2206:       subnetted = 0;
                   2207:       if (ifc->address->prefixlen > ifaddrclass.prefixlen)
                   2208:         subnetted = 1;
                   2209:     }
                   2210: 
                   2211:   for (rp = route_top (rip->table); rp; rp = route_next (rp))
                   2212:     if ((rinfo = rp->info) != NULL)
                   2213:       {
                   2214:        /* For RIPv1, if we are subnetted, output subnets in our network    */
                   2215:        /* that have the same mask as the output "interface". For other     */
                   2216:        /* networks, only the classfull version is output.                  */
                   2217:        
                   2218:        if (version == RIPv1)
                   2219:          {
                   2220:            p = (struct prefix_ipv4 *) &rp->p;
                   2221: 
                   2222:            if (IS_RIP_DEBUG_PACKET)
                   2223:              zlog_debug("RIPv1 mask check, %s/%d considered for output",
                   2224:                        inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
                   2225: 
                   2226:            if (subnetted &&
                   2227:                prefix_match ((struct prefix *) &ifaddrclass, &rp->p))
                   2228:              {
                   2229:                if ((ifc->address->prefixlen != rp->p.prefixlen) &&
                   2230:                    (rp->p.prefixlen != 32))
                   2231:                  continue;
                   2232:              }
                   2233:            else
                   2234:              {
                   2235:                memcpy (&classfull, &rp->p, sizeof(struct prefix_ipv4));
                   2236:                apply_classful_mask_ipv4(&classfull);
                   2237:                if (rp->p.u.prefix4.s_addr != 0 &&
                   2238:                    classfull.prefixlen != rp->p.prefixlen)
                   2239:                  continue;
                   2240:              }
                   2241:            if (IS_RIP_DEBUG_PACKET)
                   2242:              zlog_debug("RIPv1 mask check, %s/%d made it through",
                   2243:                        inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
                   2244:          }
                   2245:        else 
                   2246:          p = (struct prefix_ipv4 *) &rp->p;
                   2247: 
                   2248:        /* Apply output filters. */
                   2249:        ret = rip_outgoing_filter (p, ri);
                   2250:        if (ret < 0)
                   2251:          continue;
                   2252: 
                   2253:        /* Changed route only output. */
                   2254:        if (route_type == rip_changed_route &&
                   2255:            (! (rinfo->flags & RIP_RTF_CHANGED)))
                   2256:          continue;
                   2257: 
                   2258:        /* Split horizon. */
                   2259:        /* if (split_horizon == rip_split_horizon) */
                   2260:        if (ri->split_horizon == RIP_SPLIT_HORIZON)
                   2261:          {
                   2262:            /* 
                   2263:             * We perform split horizon for RIP and connected route. 
                   2264:             * For rip routes, we want to suppress the route if we would
                   2265:              * end up sending the route back on the interface that we
                   2266:              * learned it from, with a higher metric. For connected routes,
                   2267:              * we suppress the route if the prefix is a subset of the
                   2268:              * source address that we are going to use for the packet 
                   2269:              * (in order to handle the case when multiple subnets are
                   2270:              * configured on the same interface).
                   2271:              */
                   2272:            if (rinfo->type == ZEBRA_ROUTE_RIP  &&
                   2273:                  rinfo->ifindex == ifc->ifp->ifindex) 
                   2274:              continue;
                   2275:            if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
                   2276:                  prefix_match((struct prefix *)p, ifc->address))
                   2277:              continue;
                   2278:          }
                   2279: 
                   2280:        /* Preparation for route-map. */
                   2281:        rinfo->metric_set = 0;
                   2282:        rinfo->nexthop_out.s_addr = 0;
                   2283:        rinfo->metric_out = rinfo->metric;
                   2284:        rinfo->tag_out = rinfo->tag;
                   2285:        rinfo->ifindex_out = ifc->ifp->ifindex;
                   2286: 
                   2287:        /* In order to avoid some local loops,
                   2288:         * if the RIP route has a nexthop via this interface, keep the nexthop,
                   2289:         * otherwise set it to 0. The nexthop should not be propagated
                   2290:         * beyond the local broadcast/multicast area in order
                   2291:         * to avoid an IGP multi-level recursive look-up.
                   2292:         * see (4.4)
                   2293:         */
                   2294:        if (rinfo->ifindex == ifc->ifp->ifindex)
                   2295:          rinfo->nexthop_out = rinfo->nexthop;
                   2296: 
                   2297:        /* Interface route-map */
                   2298:        if (ri->routemap[RIP_FILTER_OUT])
                   2299:          {
                   2300:            ret = route_map_apply (ri->routemap[RIP_FILTER_OUT], 
                   2301:                                     (struct prefix *) p, RMAP_RIP, 
                   2302:                                     rinfo);
                   2303: 
                   2304:            if (ret == RMAP_DENYMATCH)
                   2305:              {
                   2306:                if (IS_RIP_DEBUG_PACKET)
                   2307:                  zlog_debug ("RIP %s/%d is filtered by route-map out",
                   2308:                             inet_ntoa (p->prefix), p->prefixlen);
                   2309:                  continue;
                   2310:              }
                   2311:          }
                   2312:            
                   2313:        /* Apply redistribute route map - continue, if deny */
                   2314:        if (rip->route_map[rinfo->type].name
                   2315:            && rinfo->sub_type != RIP_ROUTE_INTERFACE)
                   2316:          {
                   2317:            ret = route_map_apply (rip->route_map[rinfo->type].map,
                   2318:                                   (struct prefix *)p, RMAP_RIP, rinfo);
                   2319: 
                   2320:            if (ret == RMAP_DENYMATCH) 
                   2321:              {
                   2322:                if (IS_RIP_DEBUG_PACKET)
                   2323:                  zlog_debug ("%s/%d is filtered by route-map",
                   2324:                             inet_ntoa (p->prefix), p->prefixlen);
                   2325:                continue;
                   2326:              }
                   2327:          }
                   2328: 
                   2329:        /* When route-map does not set metric. */
                   2330:        if (! rinfo->metric_set)
                   2331:          {
                   2332:            /* If redistribute metric is set. */
                   2333:            if (rip->route_map[rinfo->type].metric_config
                   2334:                && rinfo->metric != RIP_METRIC_INFINITY)
                   2335:              {
                   2336:                rinfo->metric_out = rip->route_map[rinfo->type].metric;
                   2337:              }
                   2338:            else
                   2339:              {
                   2340:                /* If the route is not connected or localy generated
                   2341:                   one, use default-metric value*/
                   2342:                if (rinfo->type != ZEBRA_ROUTE_RIP 
                   2343:                    && rinfo->type != ZEBRA_ROUTE_CONNECT
                   2344:                    && rinfo->metric != RIP_METRIC_INFINITY)
                   2345:                  rinfo->metric_out = rip->default_metric;
                   2346:              }
                   2347:          }
                   2348: 
                   2349:        /* Apply offset-list */
                   2350:        if (rinfo->metric != RIP_METRIC_INFINITY)
                   2351:          rip_offset_list_apply_out (p, ifc->ifp, &rinfo->metric_out);
                   2352: 
                   2353:        if (rinfo->metric_out > RIP_METRIC_INFINITY)
                   2354:          rinfo->metric_out = RIP_METRIC_INFINITY;
                   2355: 
                   2356:        /* Perform split-horizon with poisoned reverse 
                   2357:         * for RIP and connected routes.
                   2358:         **/
                   2359:        if (ri->split_horizon == RIP_SPLIT_HORIZON_POISONED_REVERSE) {
                   2360:            /* 
                   2361:             * We perform split horizon for RIP and connected route. 
                   2362:             * For rip routes, we want to suppress the route if we would
                   2363:              * end up sending the route back on the interface that we
                   2364:              * learned it from, with a higher metric. For connected routes,
                   2365:              * we suppress the route if the prefix is a subset of the
                   2366:              * source address that we are going to use for the packet 
                   2367:              * (in order to handle the case when multiple subnets are
                   2368:              * configured on the same interface).
                   2369:              */
                   2370:          if (rinfo->type == ZEBRA_ROUTE_RIP  &&
                   2371:               rinfo->ifindex == ifc->ifp->ifindex)
                   2372:               rinfo->metric_out = RIP_METRIC_INFINITY;
                   2373:          if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
                   2374:               prefix_match((struct prefix *)p, ifc->address))
                   2375:               rinfo->metric_out = RIP_METRIC_INFINITY;
                   2376:        }
                   2377:        
                   2378:        /* Prepare preamble, auth headers, if needs be */
                   2379:        if (num == 0)
                   2380:          {
                   2381:            stream_putc (s, RIP_RESPONSE);
                   2382:            stream_putc (s, version);
                   2383:            stream_putw (s, 0);
                   2384:            
                   2385:            /* auth header for !v1 && !no_auth */
                   2386:             if ( (ri->auth_type != RIP_NO_AUTH) && (version != RIPv1) )
                   2387:               doff = rip_auth_header_write (s, ri, key, auth_str, 
                   2388:                                               RIP_AUTH_SIMPLE_SIZE);
                   2389:           }
                   2390:         
                   2391:        /* Write RTE to the stream. */
                   2392:        num = rip_write_rte (num, s, p, version, rinfo);
                   2393:        if (num == rtemax)
                   2394:          {
                   2395:            if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
                   2396:               rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE);
                   2397: 
                   2398:            ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s),
                   2399:                                   to, ifc);
                   2400: 
                   2401:            if (ret >= 0 && IS_RIP_DEBUG_SEND)
                   2402:              rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
                   2403:                               stream_get_endp(s), "SEND");
                   2404:            num = 0;
                   2405:            stream_reset (s);
                   2406:          }
                   2407:       }
                   2408: 
                   2409:   /* Flush unwritten RTE. */
                   2410:   if (num != 0)
                   2411:     {
                   2412:       if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
                   2413:         rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE);
                   2414: 
                   2415:       ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifc);
                   2416: 
                   2417:       if (ret >= 0 && IS_RIP_DEBUG_SEND)
                   2418:        rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
                   2419:                         stream_get_endp (s), "SEND");
                   2420:       num = 0;
                   2421:       stream_reset (s);
                   2422:     }
                   2423: 
                   2424:   /* Statistics updates. */
                   2425:   ri->sent_updates++;
                   2426: }
                   2427: 
                   2428: /* Send RIP packet to the interface. */
                   2429: static void
                   2430: rip_update_interface (struct connected *ifc, u_char version, int route_type)
                   2431: {
                   2432:   struct sockaddr_in to;
                   2433: 
                   2434:   /* When RIP version is 2 and multicast enable interface. */
                   2435:   if (version == RIPv2 && if_is_multicast (ifc->ifp)) 
                   2436:     {
                   2437:       if (IS_RIP_DEBUG_EVENT)
                   2438:        zlog_debug ("multicast announce on %s ", ifc->ifp->name);
                   2439: 
                   2440:       rip_output_process (ifc, NULL, route_type, version);
                   2441:       return;
                   2442:     }
                   2443:   
                   2444:   /* If we can't send multicast packet, send it with unicast. */
                   2445:   if (if_is_broadcast (ifc->ifp) || if_is_pointopoint (ifc->ifp))
                   2446:     {
                   2447:       if (ifc->address->family == AF_INET)
                   2448:         {
                   2449:           /* Destination address and port setting. */
                   2450:           memset (&to, 0, sizeof (struct sockaddr_in));
                   2451:           if (ifc->destination)
                   2452:             /* use specified broadcast or peer destination addr */
                   2453:             to.sin_addr = ifc->destination->u.prefix4;
                   2454:           else if (ifc->address->prefixlen < IPV4_MAX_PREFIXLEN)
                   2455:             /* calculate the appropriate broadcast address */
                   2456:             to.sin_addr.s_addr =
                   2457:               ipv4_broadcast_addr(ifc->address->u.prefix4.s_addr,
                   2458:                                   ifc->address->prefixlen);
                   2459:          else
                   2460:            /* do not know where to send the packet */
                   2461:            return;
                   2462:           to.sin_port = htons (RIP_PORT_DEFAULT);
                   2463: 
                   2464:           if (IS_RIP_DEBUG_EVENT)
                   2465:             zlog_debug("%s announce to %s on %s",
                   2466:                       CONNECTED_PEER(ifc) ? "unicast" : "broadcast",
                   2467:                       inet_ntoa (to.sin_addr), ifc->ifp->name);
                   2468: 
                   2469:           rip_output_process (ifc, &to, route_type, version);
                   2470:         }
                   2471:     }
                   2472: }
                   2473: 
                   2474: /* Update send to all interface and neighbor. */
                   2475: static void
                   2476: rip_update_process (int route_type)
                   2477: {
                   2478:   struct listnode *node;
                   2479:   struct listnode *ifnode, *ifnnode;
                   2480:   struct connected *connected;
                   2481:   struct interface *ifp;
                   2482:   struct rip_interface *ri;
                   2483:   struct route_node *rp;
                   2484:   struct sockaddr_in to;
                   2485:   struct prefix_ipv4 *p;
                   2486: 
                   2487:   /* Send RIP update to each interface. */
                   2488:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
                   2489:     {
                   2490:       if (if_is_loopback (ifp))
                   2491:        continue;
                   2492: 
                   2493:       if (! if_is_operative (ifp))
                   2494:        continue;
                   2495: 
                   2496:       /* Fetch RIP interface information. */
                   2497:       ri = ifp->info;
                   2498: 
                   2499:       /* When passive interface is specified, suppress announce to the
                   2500:          interface. */
                   2501:       if (ri->passive)
                   2502:        continue;
                   2503: 
                   2504:       if (ri->running)
                   2505:        {
                   2506:          /* 
                   2507:           * If there is no version configuration in the interface,
                   2508:           * use rip's version setting. 
                   2509:           */
                   2510:          int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
                   2511:                       rip->version_send : ri->ri_send);
                   2512: 
                   2513:          if (IS_RIP_DEBUG_EVENT) 
                   2514:            zlog_debug("SEND UPDATE to %s ifindex %d",
                   2515:                       (ifp->name ? ifp->name : "_unknown_"), ifp->ifindex);
                   2516: 
                   2517:           /* send update on each connected network */
                   2518:          for (ALL_LIST_ELEMENTS (ifp->connected, ifnode, ifnnode, connected))
                   2519:            {
                   2520:              if (connected->address->family == AF_INET)
                   2521:                {
                   2522:                  if (vsend & RIPv1)
                   2523:                    rip_update_interface (connected, RIPv1, route_type);
                   2524:                  if ((vsend & RIPv2) && if_is_multicast(ifp))
                   2525:                    rip_update_interface (connected, RIPv2, route_type);
                   2526:                }
                   2527:            }
                   2528:        }
                   2529:     }
                   2530: 
                   2531:   /* RIP send updates to each neighbor. */
                   2532:   for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
                   2533:     if (rp->info != NULL)
                   2534:       {
                   2535:        p = (struct prefix_ipv4 *) &rp->p;
                   2536: 
                   2537:        ifp = if_lookup_address (p->prefix);
                   2538:        if (! ifp)
                   2539:          {
                   2540:            zlog_warn ("Neighbor %s doesnt have connected interface!",
                   2541:                       inet_ntoa (p->prefix));
                   2542:            continue;
                   2543:          }
                   2544:         
                   2545:         if ( (connected = connected_lookup_address (ifp, p->prefix)) == NULL)
                   2546:           {
                   2547:             zlog_warn ("Neighbor %s doesnt have connected network",
                   2548:                        inet_ntoa (p->prefix));
                   2549:             continue;
                   2550:           }
                   2551:         
                   2552:        /* Set destination address and port */
                   2553:        memset (&to, 0, sizeof (struct sockaddr_in));
                   2554:        to.sin_addr = p->prefix;
                   2555:        to.sin_port = htons (RIP_PORT_DEFAULT);
                   2556: 
                   2557:        /* RIP version is rip's configuration. */
                   2558:        rip_output_process (connected, &to, route_type, rip->version_send);
                   2559:       }
                   2560: }
                   2561: 
                   2562: /* RIP's periodical timer. */
                   2563: static int
                   2564: rip_update (struct thread *t)
                   2565: {
                   2566:   /* Clear timer pointer. */
                   2567:   rip->t_update = NULL;
                   2568: 
                   2569:   if (IS_RIP_DEBUG_EVENT)
                   2570:     zlog_debug ("update timer fire!");
                   2571: 
                   2572:   /* Process update output. */
                   2573:   rip_update_process (rip_all_route);
                   2574: 
                   2575:   /* Triggered updates may be suppressed if a regular update is due by
                   2576:      the time the triggered update would be sent. */
                   2577:   if (rip->t_triggered_interval)
                   2578:     {
                   2579:       thread_cancel (rip->t_triggered_interval);
                   2580:       rip->t_triggered_interval = NULL;
                   2581:     }
                   2582:   rip->trigger = 0;
                   2583: 
                   2584:   /* Register myself. */
                   2585:   rip_event (RIP_UPDATE_EVENT, 0);
                   2586: 
                   2587:   return 0;
                   2588: }
                   2589: 
                   2590: /* Walk down the RIP routing table then clear changed flag. */
                   2591: static void
                   2592: rip_clear_changed_flag (void)
                   2593: {
                   2594:   struct route_node *rp;
                   2595:   struct rip_info *rinfo;
                   2596: 
                   2597:   for (rp = route_top (rip->table); rp; rp = route_next (rp))
                   2598:     if ((rinfo = rp->info) != NULL)
                   2599:       if (rinfo->flags & RIP_RTF_CHANGED)
                   2600:        rinfo->flags &= ~RIP_RTF_CHANGED;
                   2601: }
                   2602: 
                   2603: /* Triggered update interval timer. */
                   2604: static int
                   2605: rip_triggered_interval (struct thread *t)
                   2606: {
                   2607:   int rip_triggered_update (struct thread *);
                   2608: 
                   2609:   rip->t_triggered_interval = NULL;
                   2610: 
                   2611:   if (rip->trigger)
                   2612:     {
                   2613:       rip->trigger = 0;
                   2614:       rip_triggered_update (t);
                   2615:     }
                   2616:   return 0;
                   2617: }     
                   2618: 
                   2619: /* Execute triggered update. */
                   2620: static int
                   2621: rip_triggered_update (struct thread *t)
                   2622: {
                   2623:   int interval;
                   2624: 
                   2625:   /* Clear thred pointer. */
                   2626:   rip->t_triggered_update = NULL;
                   2627: 
                   2628:   /* Cancel interval timer. */
                   2629:   if (rip->t_triggered_interval)
                   2630:     {
                   2631:       thread_cancel (rip->t_triggered_interval);
                   2632:       rip->t_triggered_interval = NULL;
                   2633:     }
                   2634:   rip->trigger = 0;
                   2635: 
                   2636:   /* Logging triggered update. */
                   2637:   if (IS_RIP_DEBUG_EVENT)
                   2638:     zlog_debug ("triggered update!");
                   2639: 
                   2640:   /* Split Horizon processing is done when generating triggered
                   2641:      updates as well as normal updates (see section 2.6). */
                   2642:   rip_update_process (rip_changed_route);
                   2643: 
                   2644:   /* Once all of the triggered updates have been generated, the route
                   2645:      change flags should be cleared. */
                   2646:   rip_clear_changed_flag ();
                   2647: 
                   2648:   /* After a triggered update is sent, a timer should be set for a
                   2649:    random interval between 1 and 5 seconds.  If other changes that
                   2650:    would trigger updates occur before the timer expires, a single
                   2651:    update is triggered when the timer expires. */
                   2652:   interval = (random () % 5) + 1;
                   2653: 
                   2654:   rip->t_triggered_interval = 
                   2655:     thread_add_timer (master, rip_triggered_interval, NULL, interval);
                   2656: 
                   2657:   return 0;
                   2658: }
                   2659: 
                   2660: /* Withdraw redistributed route. */
                   2661: void
                   2662: rip_redistribute_withdraw (int type)
                   2663: {
                   2664:   struct route_node *rp;
                   2665:   struct rip_info *rinfo;
                   2666: 
                   2667:   if (!rip)
                   2668:     return;
                   2669: 
                   2670:   for (rp = route_top (rip->table); rp; rp = route_next (rp))
                   2671:     if ((rinfo = rp->info) != NULL)
                   2672:       {
                   2673:        if (rinfo->type == type
                   2674:            && rinfo->sub_type != RIP_ROUTE_INTERFACE)
                   2675:          {
                   2676:            /* Perform poisoned reverse. */
                   2677:            rinfo->metric = RIP_METRIC_INFINITY;
                   2678:            RIP_TIMER_ON (rinfo->t_garbage_collect, 
                   2679:                          rip_garbage_collect, rip->garbage_time);
                   2680:            RIP_TIMER_OFF (rinfo->t_timeout);
                   2681:            rinfo->flags |= RIP_RTF_CHANGED;
                   2682: 
                   2683:            if (IS_RIP_DEBUG_EVENT) {
                   2684:               struct prefix_ipv4 *p = (struct prefix_ipv4 *) &rp->p;
                   2685: 
                   2686:               zlog_debug ("Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
                   2687:                          inet_ntoa(p->prefix), p->prefixlen,
                   2688:                          ifindex2ifname(rinfo->ifindex));
                   2689:            }
                   2690: 
                   2691:            rip_event (RIP_TRIGGERED_UPDATE, 0);
                   2692:          }
                   2693:       }
                   2694: }
                   2695: 
                   2696: /* Create new RIP instance and set it to global variable. */
                   2697: static int
                   2698: rip_create (void)
                   2699: {
                   2700:   rip = XCALLOC (MTYPE_RIP, sizeof (struct rip));
                   2701: 
                   2702:   /* Set initial value. */
                   2703:   rip->version_send = RI_RIP_VERSION_2;
                   2704:   rip->version_recv = RI_RIP_VERSION_1_AND_2;
                   2705:   rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
                   2706:   rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
                   2707:   rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
                   2708:   rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
                   2709: 
                   2710:   /* Initialize RIP routig table. */
                   2711:   rip->table = route_table_init ();
                   2712:   rip->route = route_table_init ();
                   2713:   rip->neighbor = route_table_init ();
                   2714: 
                   2715:   /* Make output stream. */
                   2716:   rip->obuf = stream_new (1500);
                   2717: 
                   2718:   /* Make socket. */
                   2719:   rip->sock = rip_create_socket (NULL);
                   2720:   if (rip->sock < 0)
                   2721:     return rip->sock;
                   2722: 
                   2723:   /* Create read and timer thread. */
                   2724:   rip_event (RIP_READ, rip->sock);
                   2725:   rip_event (RIP_UPDATE_EVENT, 1);
                   2726: 
                   2727:   return 0;
                   2728: }
                   2729: 
                   2730: /* Sned RIP request to the destination. */
                   2731: int
                   2732: rip_request_send (struct sockaddr_in *to, struct interface *ifp,
                   2733:                  u_char version, struct connected *connected)
                   2734: {
                   2735:   struct rte *rte;
                   2736:   struct rip_packet rip_packet;
                   2737:   struct listnode *node, *nnode;
                   2738: 
                   2739:   memset (&rip_packet, 0, sizeof (rip_packet));
                   2740: 
                   2741:   rip_packet.command = RIP_REQUEST;
                   2742:   rip_packet.version = version;
                   2743:   rte = rip_packet.rte;
                   2744:   rte->metric = htonl (RIP_METRIC_INFINITY);
                   2745: 
                   2746:   if (connected) 
                   2747:     {
                   2748:       /* 
                   2749:        * connected is only sent for ripv1 case, or when
                   2750:        * interface does not support multicast.  Caller loops
                   2751:        * over each connected address for this case.
                   2752:        */
                   2753:       if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet), 
                   2754:                             to, connected) != sizeof (rip_packet))
                   2755:         return -1;
                   2756:       else
                   2757:         return sizeof (rip_packet);
                   2758:     }
                   2759:        
                   2760:   /* send request on each connected network */
                   2761:   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
                   2762:     {
                   2763:       struct prefix_ipv4 *p;
                   2764: 
                   2765:       p = (struct prefix_ipv4 *) connected->address;
                   2766: 
                   2767:       if (p->family != AF_INET)
                   2768:         continue;
                   2769: 
                   2770:       if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet), 
                   2771:                             to, connected) != sizeof (rip_packet))
                   2772:         return -1;
                   2773:     }
                   2774:   return sizeof (rip_packet);
                   2775: }
                   2776: 
                   2777: static int
                   2778: rip_update_jitter (unsigned long time)
                   2779: {
                   2780: #define JITTER_BOUND 4
                   2781:   /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
                   2782:      Given that, we cannot let time be less than JITTER_BOUND seconds.
                   2783:      The RIPv2 RFC says jitter should be small compared to
                   2784:      update_time.  We consider 1/JITTER_BOUND to be small.
                   2785:   */
                   2786:   
                   2787:   int jitter_input = time;
                   2788:   int jitter;
                   2789:   
                   2790:   if (jitter_input < JITTER_BOUND)
                   2791:     jitter_input = JITTER_BOUND;
                   2792:   
                   2793:   jitter = (((rand () % ((jitter_input * 2) + 1)) - jitter_input));  
                   2794: 
                   2795:   return jitter/JITTER_BOUND;
                   2796: }
                   2797: 
                   2798: void
                   2799: rip_event (enum rip_event event, int sock)
                   2800: {
                   2801:   int jitter = 0;
                   2802: 
                   2803:   switch (event)
                   2804:     {
                   2805:     case RIP_READ:
                   2806:       rip->t_read = thread_add_read (master, rip_read, NULL, sock);
                   2807:       break;
                   2808:     case RIP_UPDATE_EVENT:
                   2809:       if (rip->t_update)
                   2810:        {
                   2811:          thread_cancel (rip->t_update);
                   2812:          rip->t_update = NULL;
                   2813:        }
                   2814:       jitter = rip_update_jitter (rip->update_time);
                   2815:       rip->t_update = 
                   2816:        thread_add_timer (master, rip_update, NULL, 
                   2817:                          sock ? 2 : rip->update_time + jitter);
                   2818:       break;
                   2819:     case RIP_TRIGGERED_UPDATE:
                   2820:       if (rip->t_triggered_interval)
                   2821:        rip->trigger = 1;
                   2822:       else if (! rip->t_triggered_update)
                   2823:        rip->t_triggered_update = 
                   2824:          thread_add_event (master, rip_triggered_update, NULL, 0);
                   2825:       break;
                   2826:     default:
                   2827:       break;
                   2828:     }
                   2829: }
                   2830: 
                   2831: DEFUN (router_rip,
                   2832:        router_rip_cmd,
                   2833:        "router rip",
                   2834:        "Enable a routing process\n"
                   2835:        "Routing Information Protocol (RIP)\n")
                   2836: {
                   2837:   int ret;
                   2838: 
                   2839:   /* If rip is not enabled before. */
                   2840:   if (! rip)
                   2841:     {
                   2842:       ret = rip_create ();
                   2843:       if (ret < 0)
                   2844:        {
                   2845:          zlog_info ("Can't create RIP");
                   2846:          return CMD_WARNING;
                   2847:        }
                   2848:     }
                   2849:   vty->node = RIP_NODE;
                   2850:   vty->index = rip;
                   2851: 
                   2852:   return CMD_SUCCESS;
                   2853: }
                   2854: 
                   2855: DEFUN (no_router_rip,
                   2856:        no_router_rip_cmd,
                   2857:        "no router rip",
                   2858:        NO_STR
                   2859:        "Enable a routing process\n"
                   2860:        "Routing Information Protocol (RIP)\n")
                   2861: {
                   2862:   if (rip)
                   2863:     rip_clean ();
                   2864:   return CMD_SUCCESS;
                   2865: }
                   2866: 
                   2867: DEFUN (rip_version,
                   2868:        rip_version_cmd,
                   2869:        "version <1-2>",
                   2870:        "Set routing protocol version\n"
                   2871:        "version\n")
                   2872: {
                   2873:   int version;
                   2874: 
                   2875:   version = atoi (argv[0]);
                   2876:   if (version != RIPv1 && version != RIPv2)
                   2877:     {
                   2878:       vty_out (vty, "invalid rip version %d%s", version,
                   2879:               VTY_NEWLINE);
                   2880:       return CMD_WARNING;
                   2881:     }
                   2882:   rip->version_send = version;
                   2883:   rip->version_recv = version;
                   2884: 
                   2885:   return CMD_SUCCESS;
                   2886: } 
                   2887: 
                   2888: DEFUN (no_rip_version,
                   2889:        no_rip_version_cmd,
                   2890:        "no version",
                   2891:        NO_STR
                   2892:        "Set routing protocol version\n")
                   2893: {
                   2894:   /* Set RIP version to the default. */
                   2895:   rip->version_send = RI_RIP_VERSION_2;
                   2896:   rip->version_recv = RI_RIP_VERSION_1_AND_2;
                   2897: 
                   2898:   return CMD_SUCCESS;
                   2899: } 
                   2900: 
                   2901: ALIAS (no_rip_version,
                   2902:        no_rip_version_val_cmd,
                   2903:        "no version <1-2>",
                   2904:        NO_STR
                   2905:        "Set routing protocol version\n"
                   2906:        "version\n")
                   2907: 
                   2908: DEFUN (rip_route,
                   2909:        rip_route_cmd,
                   2910:        "route A.B.C.D/M",
                   2911:        "RIP static route configuration\n"
                   2912:        "IP prefix <network>/<length>\n")
                   2913: {
                   2914:   int ret;
                   2915:   struct prefix_ipv4 p;
                   2916:   struct route_node *node;
                   2917: 
                   2918:   ret = str2prefix_ipv4 (argv[0], &p);
                   2919:   if (ret < 0)
                   2920:     {
                   2921:       vty_out (vty, "Malformed address%s", VTY_NEWLINE);
                   2922:       return CMD_WARNING;
                   2923:     }
                   2924:   apply_mask_ipv4 (&p);
                   2925: 
                   2926:   /* For router rip configuration. */
                   2927:   node = route_node_get (rip->route, (struct prefix *) &p);
                   2928: 
                   2929:   if (node->info)
                   2930:     {
                   2931:       vty_out (vty, "There is already same static route.%s", VTY_NEWLINE);
                   2932:       route_unlock_node (node);
                   2933:       return CMD_WARNING;
                   2934:     }
                   2935: 
                   2936:   node->info = (char *)"static";
                   2937: 
                   2938:   rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL, 0, 0);
                   2939: 
                   2940:   return CMD_SUCCESS;
                   2941: }
                   2942: 
                   2943: DEFUN (no_rip_route,
                   2944:        no_rip_route_cmd,
                   2945:        "no route A.B.C.D/M",
                   2946:        NO_STR
                   2947:        "RIP static route configuration\n"
                   2948:        "IP prefix <network>/<length>\n")
                   2949: {
                   2950:   int ret;
                   2951:   struct prefix_ipv4 p;
                   2952:   struct route_node *node;
                   2953: 
                   2954:   ret = str2prefix_ipv4 (argv[0], &p);
                   2955:   if (ret < 0)
                   2956:     {
                   2957:       vty_out (vty, "Malformed address%s", VTY_NEWLINE);
                   2958:       return CMD_WARNING;
                   2959:     }
                   2960:   apply_mask_ipv4 (&p);
                   2961: 
                   2962:   /* For router rip configuration. */
                   2963:   node = route_node_lookup (rip->route, (struct prefix *) &p);
                   2964:   if (! node)
                   2965:     {
                   2966:       vty_out (vty, "Can't find route %s.%s", argv[0],
                   2967:               VTY_NEWLINE);
                   2968:       return CMD_WARNING;
                   2969:     }
                   2970: 
                   2971:   rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
                   2972:   route_unlock_node (node);
                   2973: 
                   2974:   node->info = NULL;
                   2975:   route_unlock_node (node);
                   2976: 
                   2977:   return CMD_SUCCESS;
                   2978: }
                   2979: 
                   2980: #if 0
                   2981: static void
                   2982: rip_update_default_metric (void)
                   2983: {
                   2984:   struct route_node *np;
                   2985:   struct rip_info *rinfo;
                   2986: 
                   2987:   for (np = route_top (rip->table); np; np = route_next (np))
                   2988:     if ((rinfo = np->info) != NULL)
                   2989:       if (rinfo->type != ZEBRA_ROUTE_RIP && rinfo->type != ZEBRA_ROUTE_CONNECT)
                   2990:         rinfo->metric = rip->default_metric;
                   2991: }
                   2992: #endif
                   2993: 
                   2994: DEFUN (rip_default_metric,
                   2995:        rip_default_metric_cmd,
                   2996:        "default-metric <1-16>",
                   2997:        "Set a metric of redistribute routes\n"
                   2998:        "Default metric\n")
                   2999: {
                   3000:   if (rip)
                   3001:     {
                   3002:       rip->default_metric = atoi (argv[0]);
                   3003:       /* rip_update_default_metric (); */
                   3004:     }
                   3005:   return CMD_SUCCESS;
                   3006: }
                   3007: 
                   3008: DEFUN (no_rip_default_metric,
                   3009:        no_rip_default_metric_cmd,
                   3010:        "no default-metric",
                   3011:        NO_STR
                   3012:        "Set a metric of redistribute routes\n"
                   3013:        "Default metric\n")
                   3014: {
                   3015:   if (rip)
                   3016:     {
                   3017:       rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
                   3018:       /* rip_update_default_metric (); */
                   3019:     }
                   3020:   return CMD_SUCCESS;
                   3021: }
                   3022: 
                   3023: ALIAS (no_rip_default_metric,
                   3024:        no_rip_default_metric_val_cmd,
                   3025:        "no default-metric <1-16>",
                   3026:        NO_STR
                   3027:        "Set a metric of redistribute routes\n"
                   3028:        "Default metric\n")
                   3029: 
                   3030: DEFUN (rip_timers,
                   3031:        rip_timers_cmd,
                   3032:        "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
                   3033:        "Adjust routing timers\n"
                   3034:        "Basic routing protocol update timers\n"
                   3035:        "Routing table update timer value in second. Default is 30.\n"
                   3036:        "Routing information timeout timer. Default is 180.\n"
                   3037:        "Garbage collection timer. Default is 120.\n")
                   3038: {
                   3039:   unsigned long update;
                   3040:   unsigned long timeout;
                   3041:   unsigned long garbage;
                   3042:   char *endptr = NULL;
                   3043:   unsigned long RIP_TIMER_MAX = 2147483647;
                   3044:   unsigned long RIP_TIMER_MIN = 5;
                   3045: 
                   3046:   update = strtoul (argv[0], &endptr, 10);
                   3047:   if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN || *endptr != '\0')  
                   3048:     {
                   3049:       vty_out (vty, "update timer value error%s", VTY_NEWLINE);
                   3050:       return CMD_WARNING;
                   3051:     }
                   3052:   
                   3053:   timeout = strtoul (argv[1], &endptr, 10);
                   3054:   if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN || *endptr != '\0') 
                   3055:     {
                   3056:       vty_out (vty, "timeout timer value error%s", VTY_NEWLINE);
                   3057:       return CMD_WARNING;
                   3058:     }
                   3059:   
                   3060:   garbage = strtoul (argv[2], &endptr, 10);
                   3061:   if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN || *endptr != '\0') 
                   3062:     {
                   3063:       vty_out (vty, "garbage timer value error%s", VTY_NEWLINE);
                   3064:       return CMD_WARNING;
                   3065:     }
                   3066: 
                   3067:   /* Set each timer value. */
                   3068:   rip->update_time = update;
                   3069:   rip->timeout_time = timeout;
                   3070:   rip->garbage_time = garbage;
                   3071: 
                   3072:   /* Reset update timer thread. */
                   3073:   rip_event (RIP_UPDATE_EVENT, 0);
                   3074: 
                   3075:   return CMD_SUCCESS;
                   3076: }
                   3077: 
                   3078: DEFUN (no_rip_timers,
                   3079:        no_rip_timers_cmd,
                   3080:        "no timers basic",
                   3081:        NO_STR
                   3082:        "Adjust routing timers\n"
                   3083:        "Basic routing protocol update timers\n")
                   3084: {
                   3085:   /* Set each timer value to the default. */
                   3086:   rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
                   3087:   rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
                   3088:   rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
                   3089: 
                   3090:   /* Reset update timer thread. */
                   3091:   rip_event (RIP_UPDATE_EVENT, 0);
                   3092: 
                   3093:   return CMD_SUCCESS;
                   3094: }
                   3095: 
                   3096: ALIAS (no_rip_timers,
                   3097:        no_rip_timers_val_cmd,
                   3098:        "no timers basic <0-65535> <0-65535> <0-65535>",
                   3099:        NO_STR
                   3100:        "Adjust routing timers\n"
                   3101:        "Basic routing protocol update timers\n"
                   3102:        "Routing table update timer value in second. Default is 30.\n"
                   3103:        "Routing information timeout timer. Default is 180.\n"
                   3104:        "Garbage collection timer. Default is 120.\n")
                   3105: 
                   3106: 
                   3107: struct route_table *rip_distance_table;
                   3108: 
                   3109: struct rip_distance
                   3110: {
                   3111:   /* Distance value for the IP source prefix. */
                   3112:   u_char distance;
                   3113: 
                   3114:   /* Name of the access-list to be matched. */
                   3115:   char *access_list;
                   3116: };
                   3117: 
                   3118: static struct rip_distance *
                   3119: rip_distance_new (void)
                   3120: {
                   3121:   return XCALLOC (MTYPE_RIP_DISTANCE, sizeof (struct rip_distance));
                   3122: }
                   3123: 
                   3124: static void
                   3125: rip_distance_free (struct rip_distance *rdistance)
                   3126: {
                   3127:   XFREE (MTYPE_RIP_DISTANCE, rdistance);
                   3128: }
                   3129: 
                   3130: static int
                   3131: rip_distance_set (struct vty *vty, const char *distance_str, const char *ip_str,
                   3132:                  const char *access_list_str)
                   3133: {
                   3134:   int ret;
                   3135:   struct prefix_ipv4 p;
                   3136:   u_char distance;
                   3137:   struct route_node *rn;
                   3138:   struct rip_distance *rdistance;
                   3139: 
                   3140:   ret = str2prefix_ipv4 (ip_str, &p);
                   3141:   if (ret == 0)
                   3142:     {
                   3143:       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
                   3144:       return CMD_WARNING;
                   3145:     }
                   3146: 
                   3147:   distance = atoi (distance_str);
                   3148: 
                   3149:   /* Get RIP distance node. */
                   3150:   rn = route_node_get (rip_distance_table, (struct prefix *) &p);
                   3151:   if (rn->info)
                   3152:     {
                   3153:       rdistance = rn->info;
                   3154:       route_unlock_node (rn);
                   3155:     }
                   3156:   else
                   3157:     {
                   3158:       rdistance = rip_distance_new ();
                   3159:       rn->info = rdistance;
                   3160:     }
                   3161: 
                   3162:   /* Set distance value. */
                   3163:   rdistance->distance = distance;
                   3164: 
                   3165:   /* Reset access-list configuration. */
                   3166:   if (rdistance->access_list)
                   3167:     {
                   3168:       free (rdistance->access_list);
                   3169:       rdistance->access_list = NULL;
                   3170:     }
                   3171:   if (access_list_str)
                   3172:     rdistance->access_list = strdup (access_list_str);
                   3173: 
                   3174:   return CMD_SUCCESS;
                   3175: }
                   3176: 
                   3177: static int
                   3178: rip_distance_unset (struct vty *vty, const char *distance_str,
                   3179:                    const char *ip_str, const char *access_list_str)
                   3180: {
                   3181:   int ret;
                   3182:   struct prefix_ipv4 p;
                   3183:   u_char distance;
                   3184:   struct route_node *rn;
                   3185:   struct rip_distance *rdistance;
                   3186: 
                   3187:   ret = str2prefix_ipv4 (ip_str, &p);
                   3188:   if (ret == 0)
                   3189:     {
                   3190:       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
                   3191:       return CMD_WARNING;
                   3192:     }
                   3193: 
                   3194:   distance = atoi (distance_str);
                   3195: 
                   3196:   rn = route_node_lookup (rip_distance_table, (struct prefix *)&p);
                   3197:   if (! rn)
                   3198:     {
                   3199:       vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
                   3200:       return CMD_WARNING;
                   3201:     }
                   3202: 
                   3203:   rdistance = rn->info;
                   3204: 
                   3205:   if (rdistance->access_list)
                   3206:     free (rdistance->access_list);
                   3207:   rip_distance_free (rdistance);
                   3208: 
                   3209:   rn->info = NULL;
                   3210:   route_unlock_node (rn);
                   3211:   route_unlock_node (rn);
                   3212: 
                   3213:   return CMD_SUCCESS;
                   3214: }
                   3215: 
                   3216: static void
                   3217: rip_distance_reset (void)
                   3218: {
                   3219:   struct route_node *rn;
                   3220:   struct rip_distance *rdistance;
                   3221: 
                   3222:   for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
                   3223:     if ((rdistance = rn->info) != NULL)
                   3224:       {
                   3225:        if (rdistance->access_list)
                   3226:          free (rdistance->access_list);
                   3227:        rip_distance_free (rdistance);
                   3228:        rn->info = NULL;
                   3229:        route_unlock_node (rn);
                   3230:       }
                   3231: }
                   3232: 
                   3233: /* Apply RIP information to distance method. */
                   3234: u_char
                   3235: rip_distance_apply (struct rip_info *rinfo)
                   3236: {
                   3237:   struct route_node *rn;
                   3238:   struct prefix_ipv4 p;
                   3239:   struct rip_distance *rdistance;
                   3240:   struct access_list *alist;
                   3241: 
                   3242:   if (! rip)
                   3243:     return 0;
                   3244: 
                   3245:   memset (&p, 0, sizeof (struct prefix_ipv4));
                   3246:   p.family = AF_INET;
                   3247:   p.prefix = rinfo->from;
                   3248:   p.prefixlen = IPV4_MAX_BITLEN;
                   3249: 
                   3250:   /* Check source address. */
                   3251:   rn = route_node_match (rip_distance_table, (struct prefix *) &p);
                   3252:   if (rn)
                   3253:     {
                   3254:       rdistance = rn->info;
                   3255:       route_unlock_node (rn);
                   3256: 
                   3257:       if (rdistance->access_list)
                   3258:        {
                   3259:          alist = access_list_lookup (AFI_IP, rdistance->access_list);
                   3260:          if (alist == NULL)
                   3261:            return 0;
                   3262:          if (access_list_apply (alist, &rinfo->rp->p) == FILTER_DENY)
                   3263:            return 0;
                   3264: 
                   3265:          return rdistance->distance;
                   3266:        }
                   3267:       else
                   3268:        return rdistance->distance;
                   3269:     }
                   3270: 
                   3271:   if (rip->distance)
                   3272:     return rip->distance;
                   3273: 
                   3274:   return 0;
                   3275: }
                   3276: 
                   3277: static void
                   3278: rip_distance_show (struct vty *vty)
                   3279: {
                   3280:   struct route_node *rn;
                   3281:   struct rip_distance *rdistance;
                   3282:   int header = 1;
                   3283:   char buf[BUFSIZ];
                   3284:   
                   3285:   vty_out (vty, "  Distance: (default is %d)%s",
                   3286:           rip->distance ? rip->distance :ZEBRA_RIP_DISTANCE_DEFAULT,
                   3287:           VTY_NEWLINE);
                   3288: 
                   3289:   for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
                   3290:     if ((rdistance = rn->info) != NULL)
                   3291:       {
                   3292:        if (header)
                   3293:          {
                   3294:            vty_out (vty, "    Address           Distance  List%s",
                   3295:                     VTY_NEWLINE);
                   3296:            header = 0;
                   3297:          }
                   3298:        sprintf (buf, "%s/%d", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
                   3299:        vty_out (vty, "    %-20s  %4d  %s%s",
                   3300:                 buf, rdistance->distance,
                   3301:                 rdistance->access_list ? rdistance->access_list : "",
                   3302:                 VTY_NEWLINE);
                   3303:       }
                   3304: }
                   3305: 
                   3306: DEFUN (rip_distance,
                   3307:        rip_distance_cmd,
                   3308:        "distance <1-255>",
                   3309:        "Administrative distance\n"
                   3310:        "Distance value\n")
                   3311: {
                   3312:   rip->distance = atoi (argv[0]);
                   3313:   return CMD_SUCCESS;
                   3314: }
                   3315: 
                   3316: DEFUN (no_rip_distance,
                   3317:        no_rip_distance_cmd,
                   3318:        "no distance <1-255>",
                   3319:        NO_STR
                   3320:        "Administrative distance\n"
                   3321:        "Distance value\n")
                   3322: {
                   3323:   rip->distance = 0;
                   3324:   return CMD_SUCCESS;
                   3325: }
                   3326: 
                   3327: DEFUN (rip_distance_source,
                   3328:        rip_distance_source_cmd,
                   3329:        "distance <1-255> A.B.C.D/M",
                   3330:        "Administrative distance\n"
                   3331:        "Distance value\n"
                   3332:        "IP source prefix\n")
                   3333: {
                   3334:   rip_distance_set (vty, argv[0], argv[1], NULL);
                   3335:   return CMD_SUCCESS;
                   3336: }
                   3337: 
                   3338: DEFUN (no_rip_distance_source,
                   3339:        no_rip_distance_source_cmd,
                   3340:        "no distance <1-255> A.B.C.D/M",
                   3341:        NO_STR
                   3342:        "Administrative distance\n"
                   3343:        "Distance value\n"
                   3344:        "IP source prefix\n")
                   3345: {
                   3346:   rip_distance_unset (vty, argv[0], argv[1], NULL);
                   3347:   return CMD_SUCCESS;
                   3348: }
                   3349: 
                   3350: DEFUN (rip_distance_source_access_list,
                   3351:        rip_distance_source_access_list_cmd,
                   3352:        "distance <1-255> A.B.C.D/M WORD",
                   3353:        "Administrative distance\n"
                   3354:        "Distance value\n"
                   3355:        "IP source prefix\n"
                   3356:        "Access list name\n")
                   3357: {
                   3358:   rip_distance_set (vty, argv[0], argv[1], argv[2]);
                   3359:   return CMD_SUCCESS;
                   3360: }
                   3361: 
                   3362: DEFUN (no_rip_distance_source_access_list,
                   3363:        no_rip_distance_source_access_list_cmd,
                   3364:        "no distance <1-255> A.B.C.D/M WORD",
                   3365:        NO_STR
                   3366:        "Administrative distance\n"
                   3367:        "Distance value\n"
                   3368:        "IP source prefix\n"
                   3369:        "Access list name\n")
                   3370: {
                   3371:   rip_distance_unset (vty, argv[0], argv[1], argv[2]);
                   3372:   return CMD_SUCCESS;
                   3373: }
                   3374: 
                   3375: /* Print out routes update time. */
                   3376: static void
                   3377: rip_vty_out_uptime (struct vty *vty, struct rip_info *rinfo)
                   3378: {
                   3379:   time_t clock;
                   3380:   struct tm *tm;
                   3381: #define TIME_BUF 25
                   3382:   char timebuf [TIME_BUF];
                   3383:   struct thread *thread;
                   3384: 
                   3385:   if ((thread = rinfo->t_timeout) != NULL)
                   3386:     {
                   3387:       clock = thread_timer_remain_second (thread);
                   3388:       tm = gmtime (&clock);
                   3389:       strftime (timebuf, TIME_BUF, "%M:%S", tm);
                   3390:       vty_out (vty, "%5s", timebuf);
                   3391:     }
                   3392:   else if ((thread = rinfo->t_garbage_collect) != NULL)
                   3393:     {
                   3394:       clock = thread_timer_remain_second (thread);
                   3395:       tm = gmtime (&clock);
                   3396:       strftime (timebuf, TIME_BUF, "%M:%S", tm);
                   3397:       vty_out (vty, "%5s", timebuf);
                   3398:     }
                   3399: }
                   3400: 
                   3401: static const char *
                   3402: rip_route_type_print (int sub_type)
                   3403: {
                   3404:   switch (sub_type)
                   3405:     {
                   3406:       case RIP_ROUTE_RTE:
                   3407:        return "n";
                   3408:       case RIP_ROUTE_STATIC:
                   3409:        return "s";
                   3410:       case RIP_ROUTE_DEFAULT:
                   3411:        return "d";
                   3412:       case RIP_ROUTE_REDISTRIBUTE:
                   3413:        return "r";
                   3414:       case RIP_ROUTE_INTERFACE:
                   3415:        return "i";
                   3416:       default:
                   3417:        return "?";
                   3418:     }
                   3419: }
                   3420: 
                   3421: DEFUN (show_ip_rip,
                   3422:        show_ip_rip_cmd,
                   3423:        "show ip rip",
                   3424:        SHOW_STR
                   3425:        IP_STR
                   3426:        "Show RIP routes\n")
                   3427: {
                   3428:   struct route_node *np;
                   3429:   struct rip_info *rinfo;
                   3430: 
                   3431:   if (! rip)
                   3432:     return CMD_SUCCESS;
                   3433: 
                   3434:   vty_out (vty, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP%s"
                   3435:           "Sub-codes:%s"
                   3436:            "      (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
                   3437:           "      (i) - interface%s%s"
                   3438:           "     Network            Next Hop         Metric From            Tag Time%s",
                   3439:           VTY_NEWLINE, VTY_NEWLINE,  VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
                   3440:   
                   3441:   for (np = route_top (rip->table); np; np = route_next (np))
                   3442:     if ((rinfo = np->info) != NULL)
                   3443:       {
                   3444:        int len;
                   3445: 
                   3446:        len = vty_out (vty, "%c(%s) %s/%d",
                   3447:                       /* np->lock, For debugging. */
                   3448:                       zebra_route_char(rinfo->type),
                   3449:                       rip_route_type_print (rinfo->sub_type),
                   3450:                       inet_ntoa (np->p.u.prefix4), np->p.prefixlen);
                   3451:        
                   3452:        len = 24 - len;
                   3453: 
                   3454:        if (len > 0)
                   3455:          vty_out (vty, "%*s", len, " ");
                   3456: 
                   3457:         if (rinfo->nexthop.s_addr) 
                   3458:          vty_out (vty, "%-20s %2d ", inet_ntoa (rinfo->nexthop),
                   3459:                   rinfo->metric);
                   3460:         else
                   3461:          vty_out (vty, "0.0.0.0              %2d ", rinfo->metric);
                   3462: 
                   3463:        /* Route which exist in kernel routing table. */
                   3464:        if ((rinfo->type == ZEBRA_ROUTE_RIP) && 
                   3465:            (rinfo->sub_type == RIP_ROUTE_RTE))
                   3466:          {
                   3467:            vty_out (vty, "%-15s ", inet_ntoa (rinfo->from));
                   3468:            vty_out (vty, "%3d ", rinfo->tag);
                   3469:            rip_vty_out_uptime (vty, rinfo);
                   3470:          }
                   3471:        else if (rinfo->metric == RIP_METRIC_INFINITY)
                   3472:          {
                   3473:            vty_out (vty, "self            ");
                   3474:            vty_out (vty, "%3d ", rinfo->tag);
                   3475:            rip_vty_out_uptime (vty, rinfo);
                   3476:          }
                   3477:        else
                   3478:          {
                   3479:            if (rinfo->external_metric)
                   3480:              {
                   3481:                len = vty_out (vty, "self (%s:%d)", 
                   3482:                               zebra_route_string(rinfo->type),
                   3483:                               rinfo->external_metric);
                   3484:                len = 16 - len;
                   3485:                if (len > 0)
                   3486:                  vty_out (vty, "%*s", len, " ");
                   3487:              }
                   3488:            else
                   3489:              vty_out (vty, "self            ");
                   3490:            vty_out (vty, "%3d", rinfo->tag);
                   3491:          }
                   3492: 
                   3493:        vty_out (vty, "%s", VTY_NEWLINE);
                   3494:       }
                   3495:   return CMD_SUCCESS;
                   3496: }
                   3497: 
                   3498: /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
                   3499: DEFUN (show_ip_rip_status,
                   3500:        show_ip_rip_status_cmd,
                   3501:        "show ip rip status",
                   3502:        SHOW_STR
                   3503:        IP_STR
                   3504:        "Show RIP routes\n"
                   3505:        "IP routing protocol process parameters and statistics\n")
                   3506: {
                   3507:   struct listnode *node;
                   3508:   struct interface *ifp;
                   3509:   struct rip_interface *ri;
                   3510:   extern const struct message ri_version_msg[];
                   3511:   const char *send_version;
                   3512:   const char *receive_version;
                   3513: 
                   3514:   if (! rip)
                   3515:     return CMD_SUCCESS;
                   3516: 
                   3517:   vty_out (vty, "Routing Protocol is \"rip\"%s", VTY_NEWLINE);
                   3518:   vty_out (vty, "  Sending updates every %ld seconds with +/-50%%,",
                   3519:           rip->update_time);
                   3520:   vty_out (vty, " next due in %lu seconds%s", 
                   3521:           thread_timer_remain_second(rip->t_update),
                   3522:           VTY_NEWLINE);
                   3523:   vty_out (vty, "  Timeout after %ld seconds,", rip->timeout_time);
                   3524:   vty_out (vty, " garbage collect after %ld seconds%s", rip->garbage_time,
                   3525:           VTY_NEWLINE);
                   3526: 
                   3527:   /* Filtering status show. */
                   3528:   config_show_distribute (vty);
                   3529:                 
                   3530:   /* Default metric information. */
                   3531:   vty_out (vty, "  Default redistribution metric is %d%s",
                   3532:           rip->default_metric, VTY_NEWLINE);
                   3533: 
                   3534:   /* Redistribute information. */
                   3535:   vty_out (vty, "  Redistributing:");
                   3536:   config_write_rip_redistribute (vty, 0);
                   3537:   vty_out (vty, "%s", VTY_NEWLINE);
                   3538: 
                   3539:   vty_out (vty, "  Default version control: send version %s,",
                   3540:           lookup(ri_version_msg,rip->version_send));
                   3541:   if (rip->version_recv == RI_RIP_VERSION_1_AND_2)
                   3542:     vty_out (vty, " receive any version %s", VTY_NEWLINE);
                   3543:   else
                   3544:     vty_out (vty, " receive version %s %s",
                   3545:             lookup(ri_version_msg,rip->version_recv), VTY_NEWLINE);
                   3546: 
                   3547:   vty_out (vty, "    Interface        Send  Recv   Key-chain%s", VTY_NEWLINE);
                   3548: 
                   3549:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
                   3550:     {
                   3551:       ri = ifp->info;
                   3552: 
                   3553:       if (!ri->running)
                   3554:        continue;
                   3555: 
                   3556:       if (ri->enable_network || ri->enable_interface)
                   3557:        {
                   3558:          if (ri->ri_send == RI_RIP_UNSPEC)
                   3559:            send_version = lookup (ri_version_msg, rip->version_send);
                   3560:          else
                   3561:            send_version = lookup (ri_version_msg, ri->ri_send);
                   3562: 
                   3563:          if (ri->ri_receive == RI_RIP_UNSPEC)
                   3564:            receive_version = lookup (ri_version_msg, rip->version_recv);
                   3565:          else
                   3566:            receive_version = lookup (ri_version_msg, ri->ri_receive);
                   3567:        
                   3568:          vty_out (vty, "    %-17s%-3s   %-3s    %s%s", ifp->name,
                   3569:                   send_version,
                   3570:                   receive_version,
                   3571:                   ri->key_chain ? ri->key_chain : "",
                   3572:                   VTY_NEWLINE);
                   3573:        }
                   3574:     }
                   3575: 
                   3576:   vty_out (vty, "  Routing for Networks:%s", VTY_NEWLINE);
                   3577:   config_write_rip_network (vty, 0);  
                   3578: 
                   3579:   {
                   3580:     int found_passive = 0;
                   3581:     for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
                   3582:       {
                   3583:        ri = ifp->info;
                   3584: 
                   3585:        if ((ri->enable_network || ri->enable_interface) && ri->passive)
                   3586:          {
                   3587:            if (!found_passive)
                   3588:              {
                   3589:                vty_out (vty, "  Passive Interface(s):%s", VTY_NEWLINE);
                   3590:                found_passive = 1;
                   3591:              }
                   3592:            vty_out (vty, "    %s%s", ifp->name, VTY_NEWLINE);
                   3593:          }
                   3594:       }
                   3595:   }
                   3596: 
                   3597:   vty_out (vty, "  Routing Information Sources:%s", VTY_NEWLINE);
                   3598:   vty_out (vty, "    Gateway          BadPackets BadRoutes  Distance Last Update%s", VTY_NEWLINE);
                   3599:   rip_peer_display (vty);
                   3600: 
                   3601:   rip_distance_show (vty);
                   3602: 
                   3603:   return CMD_SUCCESS;
                   3604: }
                   3605: 
                   3606: /* RIP configuration write function. */
                   3607: static int
                   3608: config_write_rip (struct vty *vty)
                   3609: {
                   3610:   int write = 0;
                   3611:   struct route_node *rn;
                   3612:   struct rip_distance *rdistance;
                   3613: 
                   3614:   if (rip)
                   3615:     {
                   3616:       /* Router RIP statement. */
                   3617:       vty_out (vty, "router rip%s", VTY_NEWLINE);
                   3618:       write++;
                   3619:   
                   3620:       /* RIP version statement.  Default is RIP version 2. */
                   3621:       if (rip->version_send != RI_RIP_VERSION_2
                   3622:          || rip->version_recv != RI_RIP_VERSION_1_AND_2)
                   3623:        vty_out (vty, " version %d%s", rip->version_send,
                   3624:                 VTY_NEWLINE);
                   3625:  
                   3626:       /* RIP timer configuration. */
                   3627:       if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT 
                   3628:          || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT 
                   3629:          || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT)
                   3630:        vty_out (vty, " timers basic %lu %lu %lu%s",
                   3631:                 rip->update_time,
                   3632:                 rip->timeout_time,
                   3633:                 rip->garbage_time,
                   3634:                 VTY_NEWLINE);
                   3635: 
                   3636:       /* Default information configuration. */
                   3637:       if (rip->default_information)
                   3638:        {
                   3639:          if (rip->default_information_route_map)
                   3640:            vty_out (vty, " default-information originate route-map %s%s",
                   3641:                     rip->default_information_route_map, VTY_NEWLINE);
                   3642:          else
                   3643:            vty_out (vty, " default-information originate%s",
                   3644:                     VTY_NEWLINE);
                   3645:        }
                   3646: 
                   3647:       /* Redistribute configuration. */
                   3648:       config_write_rip_redistribute (vty, 1);
                   3649: 
                   3650:       /* RIP offset-list configuration. */
                   3651:       config_write_rip_offset_list (vty);
                   3652: 
                   3653:       /* RIP enabled network and interface configuration. */
                   3654:       config_write_rip_network (vty, 1);
                   3655:                        
                   3656:       /* RIP default metric configuration */
                   3657:       if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT)
                   3658:         vty_out (vty, " default-metric %d%s",
                   3659:                 rip->default_metric, VTY_NEWLINE);
                   3660: 
                   3661:       /* Distribute configuration. */
                   3662:       write += config_write_distribute (vty);
                   3663: 
                   3664:       /* Interface routemap configuration */
                   3665:       write += config_write_if_rmap (vty);
                   3666: 
                   3667:       /* Distance configuration. */
                   3668:       if (rip->distance)
                   3669:        vty_out (vty, " distance %d%s", rip->distance, VTY_NEWLINE);
                   3670: 
                   3671:       /* RIP source IP prefix distance configuration. */
                   3672:       for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
                   3673:        if ((rdistance = rn->info) != NULL)
                   3674:          vty_out (vty, " distance %d %s/%d %s%s", rdistance->distance,
                   3675:                   inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
                   3676:                   rdistance->access_list ? rdistance->access_list : "",
                   3677:                   VTY_NEWLINE);
                   3678: 
                   3679:       /* RIP static route configuration. */
                   3680:       for (rn = route_top (rip->route); rn; rn = route_next (rn))
                   3681:        if (rn->info)
                   3682:          vty_out (vty, " route %s/%d%s", 
                   3683:                   inet_ntoa (rn->p.u.prefix4),
                   3684:                   rn->p.prefixlen,
                   3685:                   VTY_NEWLINE);
                   3686: 
                   3687:     }
                   3688:   return write;
                   3689: }
                   3690: 
                   3691: /* RIP node structure. */
                   3692: static struct cmd_node rip_node =
                   3693: {
                   3694:   RIP_NODE,
                   3695:   "%s(config-router)# ",
                   3696:   1
                   3697: };
                   3698: 
                   3699: /* Distribute-list update functions. */
                   3700: static void
                   3701: rip_distribute_update (struct distribute *dist)
                   3702: {
                   3703:   struct interface *ifp;
                   3704:   struct rip_interface *ri;
                   3705:   struct access_list *alist;
                   3706:   struct prefix_list *plist;
                   3707: 
                   3708:   if (! dist->ifname)
                   3709:     return;
                   3710: 
                   3711:   ifp = if_lookup_by_name (dist->ifname);
                   3712:   if (ifp == NULL)
                   3713:     return;
                   3714: 
                   3715:   ri = ifp->info;
                   3716: 
                   3717:   if (dist->list[DISTRIBUTE_IN])
                   3718:     {
                   3719:       alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
                   3720:       if (alist)
                   3721:        ri->list[RIP_FILTER_IN] = alist;
                   3722:       else
                   3723:        ri->list[RIP_FILTER_IN] = NULL;
                   3724:     }
                   3725:   else
                   3726:     ri->list[RIP_FILTER_IN] = NULL;
                   3727: 
                   3728:   if (dist->list[DISTRIBUTE_OUT])
                   3729:     {
                   3730:       alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
                   3731:       if (alist)
                   3732:        ri->list[RIP_FILTER_OUT] = alist;
                   3733:       else
                   3734:        ri->list[RIP_FILTER_OUT] = NULL;
                   3735:     }
                   3736:   else
                   3737:     ri->list[RIP_FILTER_OUT] = NULL;
                   3738: 
                   3739:   if (dist->prefix[DISTRIBUTE_IN])
                   3740:     {
                   3741:       plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
                   3742:       if (plist)
                   3743:        ri->prefix[RIP_FILTER_IN] = plist;
                   3744:       else
                   3745:        ri->prefix[RIP_FILTER_IN] = NULL;
                   3746:     }
                   3747:   else
                   3748:     ri->prefix[RIP_FILTER_IN] = NULL;
                   3749: 
                   3750:   if (dist->prefix[DISTRIBUTE_OUT])
                   3751:     {
                   3752:       plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
                   3753:       if (plist)
                   3754:        ri->prefix[RIP_FILTER_OUT] = plist;
                   3755:       else
                   3756:        ri->prefix[RIP_FILTER_OUT] = NULL;
                   3757:     }
                   3758:   else
                   3759:     ri->prefix[RIP_FILTER_OUT] = NULL;
                   3760: }
                   3761: 
                   3762: void
                   3763: rip_distribute_update_interface (struct interface *ifp)
                   3764: {
                   3765:   struct distribute *dist;
                   3766: 
                   3767:   dist = distribute_lookup (ifp->name);
                   3768:   if (dist)
                   3769:     rip_distribute_update (dist);
                   3770: }
                   3771: 
                   3772: /* Update all interface's distribute list. */
                   3773: /* ARGSUSED */
                   3774: static void
                   3775: rip_distribute_update_all (struct prefix_list *notused)
                   3776: {
                   3777:   struct interface *ifp;
                   3778:   struct listnode *node, *nnode;
                   3779: 
                   3780:   for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
                   3781:     rip_distribute_update_interface (ifp);
                   3782: }
                   3783: /* ARGSUSED */
                   3784: static void
                   3785: rip_distribute_update_all_wrapper(struct access_list *notused)
                   3786: {
                   3787:         rip_distribute_update_all(NULL);
                   3788: }
                   3789: 
                   3790: /* Delete all added rip route. */
                   3791: void
                   3792: rip_clean (void)
                   3793: {
                   3794:   int i;
                   3795:   struct route_node *rp;
                   3796:   struct rip_info *rinfo;
                   3797: 
                   3798:   if (rip)
                   3799:     {
                   3800:       /* Clear RIP routes */
                   3801:       for (rp = route_top (rip->table); rp; rp = route_next (rp))
                   3802:        if ((rinfo = rp->info) != NULL)
                   3803:          {
                   3804:            if (rinfo->type == ZEBRA_ROUTE_RIP &&
                   3805:                rinfo->sub_type == RIP_ROUTE_RTE)
                   3806:              rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p,
                   3807:                                     &rinfo->nexthop, rinfo->metric);
                   3808:        
                   3809:            RIP_TIMER_OFF (rinfo->t_timeout);
                   3810:            RIP_TIMER_OFF (rinfo->t_garbage_collect);
                   3811: 
                   3812:            rp->info = NULL;
                   3813:            route_unlock_node (rp);
                   3814: 
                   3815:            rip_info_free (rinfo);
                   3816:          }
                   3817: 
                   3818:       /* Cancel RIP related timers. */
                   3819:       RIP_TIMER_OFF (rip->t_update);
                   3820:       RIP_TIMER_OFF (rip->t_triggered_update);
                   3821:       RIP_TIMER_OFF (rip->t_triggered_interval);
                   3822: 
                   3823:       /* Cancel read thread. */
                   3824:       if (rip->t_read)
                   3825:        {
                   3826:          thread_cancel (rip->t_read);
                   3827:          rip->t_read = NULL;
                   3828:        }
                   3829: 
                   3830:       /* Close RIP socket. */
                   3831:       if (rip->sock >= 0)
                   3832:        {
                   3833:          close (rip->sock);
                   3834:          rip->sock = -1;
                   3835:        }
                   3836: 
                   3837:       /* Static RIP route configuration. */
                   3838:       for (rp = route_top (rip->route); rp; rp = route_next (rp))
                   3839:        if (rp->info)
                   3840:          {
                   3841:            rp->info = NULL;
                   3842:            route_unlock_node (rp);
                   3843:          }
                   3844: 
                   3845:       /* RIP neighbor configuration. */
                   3846:       for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
                   3847:        if (rp->info)
                   3848:          {
                   3849:            rp->info = NULL;
                   3850:            route_unlock_node (rp);
                   3851:          }
                   3852: 
                   3853:       /* Redistribute related clear. */
                   3854:       if (rip->default_information_route_map)
                   3855:        free (rip->default_information_route_map);
                   3856: 
                   3857:       for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                   3858:        if (rip->route_map[i].name)
                   3859:          free (rip->route_map[i].name);
                   3860: 
                   3861:       XFREE (MTYPE_ROUTE_TABLE, rip->table);
                   3862:       XFREE (MTYPE_ROUTE_TABLE, rip->route);
                   3863:       XFREE (MTYPE_ROUTE_TABLE, rip->neighbor);
                   3864:       
                   3865:       XFREE (MTYPE_RIP, rip);
                   3866:       rip = NULL;
                   3867:     }
                   3868: 
                   3869:   rip_clean_network ();
                   3870:   rip_passive_nondefault_clean ();
                   3871:   rip_offset_clean ();
                   3872:   rip_interface_clean ();
                   3873:   rip_distance_reset ();
                   3874:   rip_redistribute_clean ();
                   3875: }
                   3876: 
                   3877: /* Reset all values to the default settings. */
                   3878: void
                   3879: rip_reset (void)
                   3880: {
                   3881:   /* Reset global counters. */
                   3882:   rip_global_route_changes = 0;
                   3883:   rip_global_queries = 0;
                   3884: 
                   3885:   /* Call ripd related reset functions. */
                   3886:   rip_debug_reset ();
                   3887:   rip_route_map_reset ();
                   3888: 
                   3889:   /* Call library reset functions. */
                   3890:   vty_reset ();
                   3891:   access_list_reset ();
                   3892:   prefix_list_reset ();
                   3893: 
                   3894:   distribute_list_reset ();
                   3895: 
                   3896:   rip_interface_reset ();
                   3897:   rip_distance_reset ();
                   3898: 
                   3899:   rip_zclient_reset ();
                   3900: }
                   3901: 
                   3902: static void
                   3903: rip_if_rmap_update (struct if_rmap *if_rmap)
                   3904: {
                   3905:   struct interface *ifp;
                   3906:   struct rip_interface *ri;
                   3907:   struct route_map *rmap;
                   3908: 
                   3909:   ifp = if_lookup_by_name (if_rmap->ifname);
                   3910:   if (ifp == NULL)
                   3911:     return;
                   3912: 
                   3913:   ri = ifp->info;
                   3914: 
                   3915:   if (if_rmap->routemap[IF_RMAP_IN])
                   3916:     {
                   3917:       rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_IN]);
                   3918:       if (rmap)
                   3919:        ri->routemap[IF_RMAP_IN] = rmap;
                   3920:       else
                   3921:        ri->routemap[IF_RMAP_IN] = NULL;
                   3922:     }
                   3923:   else
                   3924:     ri->routemap[RIP_FILTER_IN] = NULL;
                   3925: 
                   3926:   if (if_rmap->routemap[IF_RMAP_OUT])
                   3927:     {
                   3928:       rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_OUT]);
                   3929:       if (rmap)
                   3930:        ri->routemap[IF_RMAP_OUT] = rmap;
                   3931:       else
                   3932:        ri->routemap[IF_RMAP_OUT] = NULL;
                   3933:     }
                   3934:   else
                   3935:     ri->routemap[RIP_FILTER_OUT] = NULL;
                   3936: }
                   3937: 
                   3938: void
                   3939: rip_if_rmap_update_interface (struct interface *ifp)
                   3940: {
                   3941:   struct if_rmap *if_rmap;
                   3942: 
                   3943:   if_rmap = if_rmap_lookup (ifp->name);
                   3944:   if (if_rmap)
                   3945:     rip_if_rmap_update (if_rmap);
                   3946: }
                   3947: 
                   3948: static void
                   3949: rip_routemap_update_redistribute (void)
                   3950: {
                   3951:   int i;
                   3952: 
                   3953:   if (rip)
                   3954:     {
                   3955:       for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
                   3956:        {
                   3957:          if (rip->route_map[i].name)
                   3958:            rip->route_map[i].map = 
                   3959:              route_map_lookup_by_name (rip->route_map[i].name);
                   3960:        }
                   3961:     }
                   3962: }
                   3963: 
                   3964: /* ARGSUSED */
                   3965: static void
                   3966: rip_routemap_update (const char *notused)
                   3967: {
                   3968:   struct interface *ifp;
                   3969:   struct listnode *node, *nnode;
                   3970: 
                   3971:   for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
                   3972:     rip_if_rmap_update_interface (ifp);
                   3973: 
                   3974:   rip_routemap_update_redistribute ();
                   3975: }
                   3976: 
                   3977: /* Allocate new rip structure and set default value. */
                   3978: void
                   3979: rip_init (void)
                   3980: {
                   3981:   /* Randomize for triggered update random(). */
                   3982:   srand (time (NULL));
                   3983: 
                   3984:   /* Install top nodes. */
                   3985:   install_node (&rip_node, config_write_rip);
                   3986: 
                   3987:   /* Install rip commands. */
                   3988:   install_element (VIEW_NODE, &show_ip_rip_cmd);
                   3989:   install_element (VIEW_NODE, &show_ip_rip_status_cmd);
                   3990:   install_element (ENABLE_NODE, &show_ip_rip_cmd);
                   3991:   install_element (ENABLE_NODE, &show_ip_rip_status_cmd);
                   3992:   install_element (CONFIG_NODE, &router_rip_cmd);
                   3993:   install_element (CONFIG_NODE, &no_router_rip_cmd);
                   3994: 
                   3995:   install_default (RIP_NODE);
                   3996:   install_element (RIP_NODE, &rip_version_cmd);
                   3997:   install_element (RIP_NODE, &no_rip_version_cmd);
                   3998:   install_element (RIP_NODE, &no_rip_version_val_cmd);
                   3999:   install_element (RIP_NODE, &rip_default_metric_cmd);
                   4000:   install_element (RIP_NODE, &no_rip_default_metric_cmd);
                   4001:   install_element (RIP_NODE, &no_rip_default_metric_val_cmd);
                   4002:   install_element (RIP_NODE, &rip_timers_cmd);
                   4003:   install_element (RIP_NODE, &no_rip_timers_cmd);
                   4004:   install_element (RIP_NODE, &no_rip_timers_val_cmd);
                   4005:   install_element (RIP_NODE, &rip_route_cmd);
                   4006:   install_element (RIP_NODE, &no_rip_route_cmd);
                   4007:   install_element (RIP_NODE, &rip_distance_cmd);
                   4008:   install_element (RIP_NODE, &no_rip_distance_cmd);
                   4009:   install_element (RIP_NODE, &rip_distance_source_cmd);
                   4010:   install_element (RIP_NODE, &no_rip_distance_source_cmd);
                   4011:   install_element (RIP_NODE, &rip_distance_source_access_list_cmd);
                   4012:   install_element (RIP_NODE, &no_rip_distance_source_access_list_cmd);
                   4013: 
                   4014:   /* Debug related init. */
                   4015:   rip_debug_init ();
                   4016: 
                   4017:   /* SNMP init. */
                   4018: #ifdef HAVE_SNMP
                   4019:   rip_snmp_init ();
                   4020: #endif /* HAVE_SNMP */
                   4021: 
                   4022:   /* Access list install. */
                   4023:   access_list_init ();
                   4024:   access_list_add_hook (rip_distribute_update_all_wrapper);
                   4025:   access_list_delete_hook (rip_distribute_update_all_wrapper);
                   4026: 
                   4027:   /* Prefix list initialize.*/
                   4028:   prefix_list_init ();
                   4029:   prefix_list_add_hook (rip_distribute_update_all);
                   4030:   prefix_list_delete_hook (rip_distribute_update_all);
                   4031: 
                   4032:   /* Distribute list install. */
                   4033:   distribute_list_init (RIP_NODE);
                   4034:   distribute_list_add_hook (rip_distribute_update);
                   4035:   distribute_list_delete_hook (rip_distribute_update);
                   4036: 
                   4037:   /* Route-map */
                   4038:   rip_route_map_init ();
                   4039:   rip_offset_init ();
                   4040: 
                   4041:   route_map_add_hook (rip_routemap_update);
                   4042:   route_map_delete_hook (rip_routemap_update);
                   4043: 
                   4044:   if_rmap_init (RIP_NODE);
                   4045:   if_rmap_hook_add (rip_if_rmap_update);
                   4046:   if_rmap_hook_delete (rip_if_rmap_update);
                   4047: 
                   4048:   /* Distance control. */
                   4049:   rip_distance_table = route_table_init ();
                   4050: }

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