File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ripd / ripd.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 5 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_21, v0_99_20_1, v0_99_20, HEAD
quagga

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

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