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

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

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