File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ripd / ripd.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:40 2013 UTC (11 years ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

    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:       memset (&from, 0, sizeof (from));
 1479:       from.sin_family = AF_INET;
 1480:       from.sin_port = htons (RIP_PORT_DEFAULT);
 1481:       from.sin_addr = ifc->address->u.prefix4;
 1482: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
 1483:       from.sin_len = sizeof (struct sockaddr_in);
 1484: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
 1485:       
 1486:       /*
 1487:        * we have to open a new socket for each packet because this
 1488:        * is the most portable way to bind to a different source
 1489:        * ipv4 address for each packet. 
 1490:        */
 1491:       if ( (send_sock = rip_create_socket (&from)) < 0)
 1492:         {
 1493:           zlog_warn("rip_send_packet could not create socket.");
 1494:           return -1;
 1495:         }
 1496:       rip_interface_multicast_set (send_sock, ifc);
 1497:     }
 1498: 
 1499:   ret = sendto (send_sock, buf, size, 0, (struct sockaddr *)&sin,
 1500: 		sizeof (struct sockaddr_in));
 1501: 
 1502:   if (IS_RIP_DEBUG_EVENT)
 1503:       zlog_debug ("SEND to  %s.%d", inet_ntoa(sin.sin_addr), 
 1504:                   ntohs (sin.sin_port));
 1505: 
 1506:   if (ret < 0)
 1507:     zlog_warn ("can't send packet : %s", safe_strerror (errno));
 1508: 
 1509:   if (!to)
 1510:     close(send_sock);
 1511: 
 1512:   return ret;
 1513: }
 1514: 
 1515: /* Add redistributed route to RIP table. */
 1516: void
 1517: rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p, 
 1518: 		      unsigned int ifindex, struct in_addr *nexthop,
 1519:                       unsigned int metric, unsigned char distance)
 1520: {
 1521:   int ret;
 1522:   struct route_node *rp;
 1523:   struct rip_info *rinfo;
 1524: 
 1525:   /* Redistribute route  */
 1526:   ret = rip_destination_check (p->prefix);
 1527:   if (! ret)
 1528:     return;
 1529: 
 1530:   rp = route_node_get (rip->table, (struct prefix *) p);
 1531: 
 1532:   rinfo = rp->info;
 1533: 
 1534:   if (rinfo)
 1535:     {
 1536:       if (rinfo->type == ZEBRA_ROUTE_CONNECT 
 1537: 	  && rinfo->sub_type == RIP_ROUTE_INTERFACE
 1538: 	  && rinfo->metric != RIP_METRIC_INFINITY)
 1539: 	{
 1540: 	  route_unlock_node (rp);
 1541: 	  return;
 1542: 	}
 1543: 
 1544:       /* Manually configured RIP route check. */
 1545:       if (rinfo->type == ZEBRA_ROUTE_RIP 
 1546: 	  && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
 1547: 	      (rinfo->sub_type == RIP_ROUTE_DEFAULT)) )
 1548: 	{
 1549: 	  if (type != ZEBRA_ROUTE_RIP || ((sub_type != RIP_ROUTE_STATIC) &&
 1550: 	                                  (sub_type != RIP_ROUTE_DEFAULT)))
 1551: 	    {
 1552: 	      route_unlock_node (rp);
 1553: 	      return;
 1554: 	    }
 1555: 	}
 1556: 
 1557:       RIP_TIMER_OFF (rinfo->t_timeout);
 1558:       RIP_TIMER_OFF (rinfo->t_garbage_collect);
 1559: 
 1560:       if (rip_route_rte (rinfo))
 1561: 	rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p, &rinfo->nexthop,
 1562: 			       rinfo->metric);
 1563:       rp->info = NULL;
 1564:       rip_info_free (rinfo);
 1565:       
 1566:       route_unlock_node (rp);      
 1567:     }
 1568: 
 1569:   rinfo = rip_info_new ();
 1570:     
 1571:   rinfo->type = type;
 1572:   rinfo->sub_type = sub_type;
 1573:   rinfo->ifindex = ifindex;
 1574:   rinfo->metric = 1;
 1575:   rinfo->external_metric = metric;
 1576:   rinfo->distance = distance;
 1577:   rinfo->rp = rp;
 1578: 
 1579:   if (nexthop)
 1580:     rinfo->nexthop = *nexthop;
 1581: 
 1582:   rinfo->flags |= RIP_RTF_FIB;
 1583:   rp->info = rinfo;
 1584: 
 1585:   rinfo->flags |= RIP_RTF_CHANGED;
 1586: 
 1587:   if (IS_RIP_DEBUG_EVENT) {
 1588:     if (!nexthop)
 1589:       zlog_debug ("Redistribute new prefix %s/%d on the interface %s",
 1590:                  inet_ntoa(p->prefix), p->prefixlen,
 1591:                  ifindex2ifname(ifindex));
 1592:     else
 1593:       zlog_debug ("Redistribute new prefix %s/%d with nexthop %s on the interface %s",
 1594:                  inet_ntoa(p->prefix), p->prefixlen, inet_ntoa(rinfo->nexthop),
 1595:                  ifindex2ifname(ifindex));
 1596:   }
 1597: 
 1598: 
 1599:   rip_event (RIP_TRIGGERED_UPDATE, 0);
 1600: }
 1601: 
 1602: /* Delete redistributed route from RIP table. */
 1603: void
 1604: rip_redistribute_delete (int type, int sub_type, struct prefix_ipv4 *p, 
 1605: 			   unsigned int ifindex)
 1606: {
 1607:   int ret;
 1608:   struct route_node *rp;
 1609:   struct rip_info *rinfo;
 1610: 
 1611:   ret = rip_destination_check (p->prefix);
 1612:   if (! ret)
 1613:     return;
 1614: 
 1615:   rp = route_node_lookup (rip->table, (struct prefix *) p);
 1616:   if (rp)
 1617:     {
 1618:       rinfo = rp->info;
 1619: 
 1620:       if (rinfo != NULL
 1621: 	  && rinfo->type == type 
 1622: 	  && rinfo->sub_type == sub_type 
 1623: 	  && rinfo->ifindex == ifindex)
 1624: 	{
 1625: 	  /* Perform poisoned reverse. */
 1626: 	  rinfo->metric = RIP_METRIC_INFINITY;
 1627: 	  RIP_TIMER_ON (rinfo->t_garbage_collect, 
 1628: 			rip_garbage_collect, rip->garbage_time);
 1629: 	  RIP_TIMER_OFF (rinfo->t_timeout);
 1630: 	  rinfo->flags |= RIP_RTF_CHANGED;
 1631: 
 1632:           if (IS_RIP_DEBUG_EVENT)
 1633:             zlog_debug ("Poisone %s/%d on the interface %s with an infinity metric [delete]",
 1634:                        inet_ntoa(p->prefix), p->prefixlen,
 1635:                        ifindex2ifname(ifindex));
 1636: 
 1637: 	  rip_event (RIP_TRIGGERED_UPDATE, 0);
 1638: 	}
 1639:     }
 1640: }
 1641: 
 1642: /* Response to request called from rip_read ().*/
 1643: static void
 1644: rip_request_process (struct rip_packet *packet, int size, 
 1645: 		     struct sockaddr_in *from, struct connected *ifc)
 1646: {
 1647:   caddr_t lim;
 1648:   struct rte *rte;
 1649:   struct prefix_ipv4 p;
 1650:   struct route_node *rp;
 1651:   struct rip_info *rinfo;
 1652:   struct rip_interface *ri;
 1653: 
 1654:   /* Does not reponse to the requests on the loopback interfaces */
 1655:   if (if_is_loopback (ifc->ifp))
 1656:     return;
 1657: 
 1658:   /* Check RIP process is enabled on this interface. */
 1659:   ri = ifc->ifp->info;
 1660:   if (! ri->running)
 1661:     return;
 1662: 
 1663:   /* When passive interface is specified, suppress responses */
 1664:   if (ri->passive)
 1665:     return;
 1666:   
 1667:   /* RIP peer update. */
 1668:   rip_peer_update (from, packet->version);
 1669: 
 1670:   lim = ((caddr_t) packet) + size;
 1671:   rte = packet->rte;
 1672: 
 1673:   /* The Request is processed entry by entry.  If there are no
 1674:      entries, no response is given. */
 1675:   if (lim == (caddr_t) rte)
 1676:     return;
 1677: 
 1678:   /* There is one special case.  If there is exactly one entry in the
 1679:      request, and it has an address family identifier of zero and a
 1680:      metric of infinity (i.e., 16), then this is a request to send the
 1681:      entire routing table. */
 1682:   if (lim == ((caddr_t) (rte + 1)) &&
 1683:       ntohs (rte->family) == 0 &&
 1684:       ntohl (rte->metric) == RIP_METRIC_INFINITY)
 1685:     {	
 1686:       struct prefix_ipv4 saddr;
 1687: 
 1688:       /* saddr will be used for determining which routes to split-horizon.
 1689:          Since the source address we'll pick will be on the same subnet as the
 1690:          destination, for the purpose of split-horizoning, we'll
 1691:          pretend that "from" is our source address.  */
 1692:       saddr.family = AF_INET;
 1693:       saddr.prefixlen = IPV4_MAX_BITLEN;
 1694:       saddr.prefix = from->sin_addr;
 1695: 
 1696:       /* All route with split horizon */
 1697:       rip_output_process (ifc, from, rip_all_route, packet->version);
 1698:     }
 1699:   else
 1700:     {
 1701:       /* Examine the list of RTEs in the Request one by one.  For each
 1702: 	 entry, look up the destination in the router's routing
 1703: 	 database and, if there is a route, put that route's metric in
 1704: 	 the metric field of the RTE.  If there is no explicit route
 1705: 	 to the specified destination, put infinity in the metric
 1706: 	 field.  Once all the entries have been filled in, change the
 1707: 	 command from Request to Response and send the datagram back
 1708: 	 to the requestor. */
 1709:       p.family = AF_INET;
 1710: 
 1711:       for (; ((caddr_t) rte) < lim; rte++)
 1712: 	{
 1713: 	  p.prefix = rte->prefix;
 1714: 	  p.prefixlen = ip_masklen (rte->mask);
 1715: 	  apply_mask_ipv4 (&p);
 1716: 	  
 1717: 	  rp = route_node_lookup (rip->table, (struct prefix *) &p);
 1718: 	  if (rp)
 1719: 	    {
 1720: 	      rinfo = rp->info;
 1721: 	      rte->metric = htonl (rinfo->metric);
 1722: 	      route_unlock_node (rp);
 1723: 	    }
 1724: 	  else
 1725: 	    rte->metric = htonl (RIP_METRIC_INFINITY);
 1726: 	}
 1727:       packet->command = RIP_RESPONSE;
 1728: 
 1729:       rip_send_packet ((u_char *)packet, size, from, ifc);
 1730:     }
 1731:   rip_global_queries++;
 1732: }
 1733: 
 1734: #if RIP_RECVMSG
 1735: /* Set IPv6 packet info to the socket. */
 1736: static int
 1737: setsockopt_pktinfo (int sock)
 1738: {
 1739:   int ret;
 1740:   int val = 1;
 1741:     
 1742:   ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
 1743:   if (ret < 0)
 1744:     zlog_warn ("Can't setsockopt IP_PKTINFO : %s", safe_strerror (errno));
 1745:   return ret;
 1746: }
 1747: 
 1748: /* Read RIP packet by recvmsg function. */
 1749: int
 1750: rip_recvmsg (int sock, u_char *buf, int size, struct sockaddr_in *from,
 1751: 	     int *ifindex)
 1752: {
 1753:   int ret;
 1754:   struct msghdr msg;
 1755:   struct iovec iov;
 1756:   struct cmsghdr *ptr;
 1757:   char adata[1024];
 1758: 
 1759:   msg.msg_name = (void *) from;
 1760:   msg.msg_namelen = sizeof (struct sockaddr_in);
 1761:   msg.msg_iov = &iov;
 1762:   msg.msg_iovlen = 1;
 1763:   msg.msg_control = (void *) adata;
 1764:   msg.msg_controllen = sizeof adata;
 1765:   iov.iov_base = buf;
 1766:   iov.iov_len = size;
 1767: 
 1768:   ret = recvmsg (sock, &msg, 0);
 1769:   if (ret < 0)
 1770:     return ret;
 1771: 
 1772:   for (ptr = ZCMSG_FIRSTHDR(&msg); ptr != NULL; ptr = CMSG_NXTHDR(&msg, ptr))
 1773:     if (ptr->cmsg_level == IPPROTO_IP && ptr->cmsg_type == IP_PKTINFO) 
 1774:       {
 1775: 	struct in_pktinfo *pktinfo;
 1776: 	int i;
 1777: 
 1778: 	pktinfo = (struct in_pktinfo *) CMSG_DATA (ptr);
 1779: 	i = pktinfo->ipi_ifindex;
 1780:       }
 1781:   return ret;
 1782: }
 1783: 
 1784: /* RIP packet read function. */
 1785: int
 1786: rip_read_new (struct thread *t)
 1787: {
 1788:   int ret;
 1789:   int sock;
 1790:   char buf[RIP_PACKET_MAXSIZ];
 1791:   struct sockaddr_in from;
 1792:   unsigned int ifindex;
 1793:   
 1794:   /* Fetch socket then register myself. */
 1795:   sock = THREAD_FD (t);
 1796:   rip_event (RIP_READ, sock);
 1797: 
 1798:   /* Read RIP packet. */
 1799:   ret = rip_recvmsg (sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex);
 1800:   if (ret < 0)
 1801:     {
 1802:       zlog_warn ("Can't read RIP packet: %s", safe_strerror (errno));
 1803:       return ret;
 1804:     }
 1805: 
 1806:   return ret;
 1807: }
 1808: #endif /* RIP_RECVMSG */
 1809: 
 1810: /* First entry point of RIP packet. */
 1811: static int
 1812: rip_read (struct thread *t)
 1813: {
 1814:   int sock;
 1815:   int ret;
 1816:   int rtenum;
 1817:   union rip_buf rip_buf;
 1818:   struct rip_packet *packet;
 1819:   struct sockaddr_in from;
 1820:   int len;
 1821:   int vrecv;
 1822:   socklen_t fromlen;
 1823:   struct interface *ifp;
 1824:   struct connected *ifc;
 1825:   struct rip_interface *ri;
 1826: 
 1827:   /* Fetch socket then register myself. */
 1828:   sock = THREAD_FD (t);
 1829:   rip->t_read = NULL;
 1830: 
 1831:   /* Add myself to tne next event */
 1832:   rip_event (RIP_READ, sock);
 1833: 
 1834:   /* RIPd manages only IPv4. */
 1835:   memset (&from, 0, sizeof (struct sockaddr_in));
 1836:   fromlen = sizeof (struct sockaddr_in);
 1837: 
 1838:   len = recvfrom (sock, (char *)&rip_buf.buf, sizeof (rip_buf.buf), 0, 
 1839: 		  (struct sockaddr *) &from, &fromlen);
 1840:   if (len < 0) 
 1841:     {
 1842:       zlog_info ("recvfrom failed: %s", safe_strerror (errno));
 1843:       return len;
 1844:     }
 1845: 
 1846:   /* Check is this packet comming from myself? */
 1847:   if (if_check_address (from.sin_addr)) 
 1848:     {
 1849:       if (IS_RIP_DEBUG_PACKET)
 1850: 	zlog_debug ("ignore packet comes from myself");
 1851:       return -1;
 1852:     }
 1853: 
 1854:   /* Which interface is this packet comes from. */
 1855:   ifp = if_lookup_address (from.sin_addr);
 1856:   
 1857:   /* RIP packet received */
 1858:   if (IS_RIP_DEBUG_EVENT)
 1859:     zlog_debug ("RECV packet from %s port %d on %s",
 1860: 	       inet_ntoa (from.sin_addr), ntohs (from.sin_port),
 1861: 	       ifp ? ifp->name : "unknown");
 1862: 
 1863:   /* If this packet come from unknown interface, ignore it. */
 1864:   if (ifp == NULL)
 1865:     {
 1866:       zlog_info ("rip_read: cannot find interface for packet from %s port %d",
 1867: 		 inet_ntoa(from.sin_addr), ntohs (from.sin_port));
 1868:       return -1;
 1869:     }
 1870:   
 1871:   ifc = connected_lookup_address (ifp, from.sin_addr);
 1872:   
 1873:   if (ifc == NULL)
 1874:     {
 1875:       zlog_info ("rip_read: cannot find connected address for packet from %s "
 1876: 		 "port %d on interface %s",
 1877: 		 inet_ntoa(from.sin_addr), ntohs (from.sin_port), ifp->name);
 1878:       return -1;
 1879:     }
 1880: 
 1881:   /* Packet length check. */
 1882:   if (len < RIP_PACKET_MINSIZ)
 1883:     {
 1884:       zlog_warn ("packet size %d is smaller than minimum size %d",
 1885: 		 len, RIP_PACKET_MINSIZ);
 1886:       rip_peer_bad_packet (&from);
 1887:       return len;
 1888:     }
 1889:   if (len > RIP_PACKET_MAXSIZ)
 1890:     {
 1891:       zlog_warn ("packet size %d is larger than max size %d",
 1892: 		 len, RIP_PACKET_MAXSIZ);
 1893:       rip_peer_bad_packet (&from);
 1894:       return len;
 1895:     }
 1896: 
 1897:   /* Packet alignment check. */
 1898:   if ((len - RIP_PACKET_MINSIZ) % 20)
 1899:     {
 1900:       zlog_warn ("packet size %d is wrong for RIP packet alignment", len);
 1901:       rip_peer_bad_packet (&from);
 1902:       return len;
 1903:     }
 1904: 
 1905:   /* Set RTE number. */
 1906:   rtenum = ((len - RIP_PACKET_MINSIZ) / 20);
 1907: 
 1908:   /* For easy to handle. */
 1909:   packet = &rip_buf.rip_packet;
 1910: 
 1911:   /* RIP version check. */
 1912:   if (packet->version == 0)
 1913:     {
 1914:       zlog_info ("version 0 with command %d received.", packet->command);
 1915:       rip_peer_bad_packet (&from);
 1916:       return -1;
 1917:     }
 1918: 
 1919:   /* Dump RIP packet. */
 1920:   if (IS_RIP_DEBUG_RECV)
 1921:     rip_packet_dump (packet, len, "RECV");
 1922: 
 1923:   /* RIP version adjust.  This code should rethink now.  RFC1058 says
 1924:      that "Version 1 implementations are to ignore this extra data and
 1925:      process only the fields specified in this document.". So RIPv3
 1926:      packet should be treated as RIPv1 ignoring must be zero field. */
 1927:   if (packet->version > RIPv2)
 1928:     packet->version = RIPv2;
 1929: 
 1930:   /* Is RIP running or is this RIP neighbor ?*/
 1931:   ri = ifp->info;
 1932:   if (! ri->running && ! rip_neighbor_lookup (&from))
 1933:     {
 1934:       if (IS_RIP_DEBUG_EVENT)
 1935: 	zlog_debug ("RIP is not enabled on interface %s.", ifp->name);
 1936:       rip_peer_bad_packet (&from);
 1937:       return -1;
 1938:     }
 1939: 
 1940:   /* RIP Version check. RFC2453, 4.6 and 5.1 */
 1941:   vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ?
 1942:            rip->version_recv : ri->ri_receive);
 1943:   if ((packet->version == RIPv1) && !(vrecv & RIPv1))
 1944:     {
 1945:       if (IS_RIP_DEBUG_PACKET)
 1946:         zlog_debug ("  packet's v%d doesn't fit to if version spec", 
 1947:                    packet->version);
 1948:       rip_peer_bad_packet (&from);
 1949:       return -1;
 1950:     }
 1951:   if ((packet->version == RIPv2) && !(vrecv & RIPv2))
 1952:     {
 1953:       if (IS_RIP_DEBUG_PACKET)
 1954:         zlog_debug ("  packet's v%d doesn't fit to if version spec", 
 1955:                    packet->version);
 1956:       rip_peer_bad_packet (&from);
 1957:       return -1;
 1958:     }
 1959:   
 1960:   /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
 1961:      messages, then RIP-1 and unauthenticated RIP-2 messages will be
 1962:      accepted; authenticated RIP-2 messages shall be discarded.  */
 1963:   if ((ri->auth_type == RIP_NO_AUTH) 
 1964:       && rtenum 
 1965:       && (packet->version == RIPv2) 
 1966:       && (packet->rte->family == htons(RIP_FAMILY_AUTH)))
 1967:     {
 1968:       if (IS_RIP_DEBUG_EVENT)
 1969: 	zlog_debug ("packet RIPv%d is dropped because authentication disabled", 
 1970: 		   packet->version);
 1971:       rip_peer_bad_packet (&from);
 1972:       return -1;
 1973:     }
 1974:   
 1975:   /* RFC:
 1976:      If the router is configured to authenticate RIP-2 messages, then
 1977:      RIP-1 messages and RIP-2 messages which pass authentication
 1978:      testing shall be accepted; unauthenticated and failed
 1979:      authentication RIP-2 messages shall be discarded.  For maximum
 1980:      security, RIP-1 messages should be ignored when authentication is
 1981:      in use (see section 4.1); otherwise, the routing information from
 1982:      authenticated messages will be propagated by RIP-1 routers in an
 1983:      unauthenticated manner. 
 1984:   */
 1985:   /* We make an exception for RIPv1 REQUEST packets, to which we'll
 1986:    * always reply regardless of authentication settings, because:
 1987:    *
 1988:    * - if there other authorised routers on-link, the REQUESTor can
 1989:    *   passively obtain the routing updates anyway
 1990:    * - if there are no other authorised routers on-link, RIP can
 1991:    *   easily be disabled for the link to prevent giving out information
 1992:    *   on state of this routers RIP routing table..
 1993:    *
 1994:    * I.e. if RIPv1 has any place anymore these days, it's as a very
 1995:    * simple way to distribute routing information (e.g. to embedded
 1996:    * hosts / appliances) and the ability to give out RIPv1
 1997:    * routing-information freely, while still requiring RIPv2
 1998:    * authentication for any RESPONSEs might be vaguely useful.
 1999:    */
 2000:   if (ri->auth_type != RIP_NO_AUTH 
 2001:       && packet->version == RIPv1)
 2002:     {
 2003:       /* Discard RIPv1 messages other than REQUESTs */
 2004:       if (packet->command != RIP_REQUEST)
 2005:         {
 2006:           if (IS_RIP_DEBUG_PACKET)
 2007:             zlog_debug ("RIPv1" " dropped because authentication enabled");
 2008:           rip_peer_bad_packet (&from);
 2009:           return -1;
 2010:         }
 2011:     }
 2012:   else if (ri->auth_type != RIP_NO_AUTH)
 2013:     {
 2014:       const char *auth_desc;
 2015:       
 2016:       if (rtenum == 0)
 2017:         {
 2018:           /* There definitely is no authentication in the packet. */
 2019:           if (IS_RIP_DEBUG_PACKET)
 2020:             zlog_debug ("RIPv2 authentication failed: no auth RTE in packet");
 2021:           rip_peer_bad_packet (&from);
 2022:           return -1;
 2023:         }
 2024:       
 2025:       /* First RTE must be an Authentication Family RTE */
 2026:       if (packet->rte->family != htons(RIP_FAMILY_AUTH))
 2027:         {
 2028:           if (IS_RIP_DEBUG_PACKET)
 2029:             zlog_debug ("RIPv2" " dropped because authentication enabled");
 2030: 	  rip_peer_bad_packet (&from);
 2031: 	  return -1;
 2032:         }
 2033:       
 2034:       /* Check RIPv2 authentication. */
 2035:       switch (ntohs(packet->rte->tag))
 2036:         {
 2037:           case RIP_AUTH_SIMPLE_PASSWORD:
 2038:             auth_desc = "simple";
 2039:             ret = rip_auth_simple_password (packet->rte, &from, ifp);
 2040:             break;
 2041:           
 2042:           case RIP_AUTH_MD5:
 2043:             auth_desc = "MD5";
 2044:             ret = rip_auth_md5 (packet, &from, len, ifp);
 2045:             /* Reset RIP packet length to trim MD5 data. */
 2046:             len = ret;
 2047:             break;
 2048:           
 2049:           default:
 2050:             ret = 0;
 2051:             auth_desc = "unknown type";
 2052:             if (IS_RIP_DEBUG_PACKET)
 2053:               zlog_debug ("RIPv2 Unknown authentication type %d",
 2054:                           ntohs (packet->rte->tag));
 2055:         }
 2056:       
 2057:       if (ret)
 2058:         {
 2059:           if (IS_RIP_DEBUG_PACKET)
 2060:             zlog_debug ("RIPv2 %s authentication success", auth_desc);
 2061:         }
 2062:       else
 2063:         {
 2064:           if (IS_RIP_DEBUG_PACKET)
 2065:             zlog_debug ("RIPv2 %s authentication failure", auth_desc);
 2066:           rip_peer_bad_packet (&from);
 2067:           return -1;
 2068:         }
 2069:     }
 2070:   
 2071:   /* Process each command. */
 2072:   switch (packet->command)
 2073:     {
 2074:     case RIP_RESPONSE:
 2075:       rip_response_process (packet, len, &from, ifc);
 2076:       break;
 2077:     case RIP_REQUEST:
 2078:     case RIP_POLL:
 2079:       rip_request_process (packet, len, &from, ifc);
 2080:       break;
 2081:     case RIP_TRACEON:
 2082:     case RIP_TRACEOFF:
 2083:       zlog_info ("Obsolete command %s received, please sent it to routed", 
 2084: 		 lookup (rip_msg, packet->command));
 2085:       rip_peer_bad_packet (&from);
 2086:       break;
 2087:     case RIP_POLL_ENTRY:
 2088:       zlog_info ("Obsolete command %s received", 
 2089: 		 lookup (rip_msg, packet->command));
 2090:       rip_peer_bad_packet (&from);
 2091:       break;
 2092:     default:
 2093:       zlog_info ("Unknown RIP command %d received", packet->command);
 2094:       rip_peer_bad_packet (&from);
 2095:       break;
 2096:     }
 2097: 
 2098:   return len;
 2099: }
 2100: 
 2101: /* Write routing table entry to the stream and return next index of
 2102:    the routing table entry in the stream. */
 2103: static int
 2104: rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,
 2105:                u_char version, struct rip_info *rinfo)
 2106: {
 2107:   struct in_addr mask;
 2108: 
 2109:   /* Write routing table entry. */
 2110:   if (version == RIPv1)
 2111:     {
 2112:       stream_putw (s, AF_INET);
 2113:       stream_putw (s, 0);
 2114:       stream_put_ipv4 (s, p->prefix.s_addr);
 2115:       stream_put_ipv4 (s, 0);
 2116:       stream_put_ipv4 (s, 0);
 2117:       stream_putl (s, rinfo->metric_out);
 2118:     }
 2119:   else
 2120:     {
 2121:       masklen2ip (p->prefixlen, &mask);
 2122: 
 2123:       stream_putw (s, AF_INET);
 2124:       stream_putw (s, rinfo->tag_out);
 2125:       stream_put_ipv4 (s, p->prefix.s_addr);
 2126:       stream_put_ipv4 (s, mask.s_addr);
 2127:       stream_put_ipv4 (s, rinfo->nexthop_out.s_addr);
 2128:       stream_putl (s, rinfo->metric_out);
 2129:     }
 2130: 
 2131:   return ++num;
 2132: }
 2133: 
 2134: /* Send update to the ifp or spcified neighbor. */
 2135: void
 2136: rip_output_process (struct connected *ifc, struct sockaddr_in *to, 
 2137:                     int route_type, u_char version)
 2138: {
 2139:   int ret;
 2140:   struct stream *s;
 2141:   struct route_node *rp;
 2142:   struct rip_info *rinfo;
 2143:   struct rip_interface *ri;
 2144:   struct prefix_ipv4 *p;
 2145:   struct prefix_ipv4 classfull;
 2146:   struct prefix_ipv4 ifaddrclass;
 2147:   struct key *key = NULL;
 2148:   /* this might need to made dynamic if RIP ever supported auth methods
 2149:      with larger key string sizes */
 2150:   char auth_str[RIP_AUTH_SIMPLE_SIZE];
 2151:   size_t doff = 0; /* offset of digest offset field */
 2152:   int num = 0;
 2153:   int rtemax;
 2154:   int subnetted = 0;
 2155: 
 2156:   /* Logging output event. */
 2157:   if (IS_RIP_DEBUG_EVENT)
 2158:     {
 2159:       if (to)
 2160: 	zlog_debug ("update routes to neighbor %s", inet_ntoa (to->sin_addr));
 2161:       else
 2162: 	zlog_debug ("update routes on interface %s ifindex %d",
 2163: 		   ifc->ifp->name, ifc->ifp->ifindex);
 2164:     }
 2165: 
 2166:   /* Set output stream. */
 2167:   s = rip->obuf;
 2168: 
 2169:   /* Reset stream and RTE counter. */
 2170:   stream_reset (s);
 2171:   rtemax = (RIP_PACKET_MAXSIZ - 4) / 20;
 2172: 
 2173:   /* Get RIP interface. */
 2174:   ri = ifc->ifp->info;
 2175:     
 2176:   /* If output interface is in simple password authentication mode, we
 2177:      need space for authentication data.  */
 2178:   if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
 2179:     rtemax -= 1;
 2180: 
 2181:   /* If output interface is in MD5 authentication mode, we need space
 2182:      for authentication header and data. */
 2183:   if (ri->auth_type == RIP_AUTH_MD5)
 2184:     rtemax -= 2;
 2185: 
 2186:   /* If output interface is in simple password authentication mode
 2187:      and string or keychain is specified we need space for auth. data */
 2188:   if (ri->auth_type != RIP_NO_AUTH)
 2189:     {
 2190:       if (ri->key_chain)
 2191:        {
 2192:          struct keychain *keychain;
 2193: 
 2194:          keychain = keychain_lookup (ri->key_chain);
 2195:          if (keychain)
 2196:            key = key_lookup_for_send (keychain);
 2197:        }
 2198:       /* to be passed to auth functions later */
 2199:       rip_auth_prepare_str_send (ri, key, auth_str, RIP_AUTH_SIMPLE_SIZE);
 2200:     }
 2201: 
 2202:   if (version == RIPv1)
 2203:     {
 2204:       memcpy (&ifaddrclass, ifc->address, sizeof (struct prefix_ipv4));
 2205:       apply_classful_mask_ipv4 (&ifaddrclass);
 2206:       subnetted = 0;
 2207:       if (ifc->address->prefixlen > ifaddrclass.prefixlen)
 2208:         subnetted = 1;
 2209:     }
 2210: 
 2211:   for (rp = route_top (rip->table); rp; rp = route_next (rp))
 2212:     if ((rinfo = rp->info) != NULL)
 2213:       {
 2214: 	/* For RIPv1, if we are subnetted, output subnets in our network    */
 2215: 	/* that have the same mask as the output "interface". For other     */
 2216: 	/* networks, only the classfull version is output.                  */
 2217: 	
 2218: 	if (version == RIPv1)
 2219: 	  {
 2220: 	    p = (struct prefix_ipv4 *) &rp->p;
 2221: 
 2222: 	    if (IS_RIP_DEBUG_PACKET)
 2223: 	      zlog_debug("RIPv1 mask check, %s/%d considered for output",
 2224: 			inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
 2225: 
 2226: 	    if (subnetted &&
 2227: 		prefix_match ((struct prefix *) &ifaddrclass, &rp->p))
 2228: 	      {
 2229: 		if ((ifc->address->prefixlen != rp->p.prefixlen) &&
 2230: 		    (rp->p.prefixlen != 32))
 2231: 		  continue;
 2232: 	      }
 2233: 	    else
 2234: 	      {
 2235: 		memcpy (&classfull, &rp->p, sizeof(struct prefix_ipv4));
 2236: 		apply_classful_mask_ipv4(&classfull);
 2237: 		if (rp->p.u.prefix4.s_addr != 0 &&
 2238: 		    classfull.prefixlen != rp->p.prefixlen)
 2239: 		  continue;
 2240: 	      }
 2241: 	    if (IS_RIP_DEBUG_PACKET)
 2242: 	      zlog_debug("RIPv1 mask check, %s/%d made it through",
 2243: 			inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
 2244: 	  }
 2245: 	else 
 2246: 	  p = (struct prefix_ipv4 *) &rp->p;
 2247: 
 2248: 	/* Apply output filters. */
 2249: 	ret = rip_outgoing_filter (p, ri);
 2250: 	if (ret < 0)
 2251: 	  continue;
 2252: 
 2253: 	/* Changed route only output. */
 2254: 	if (route_type == rip_changed_route &&
 2255: 	    (! (rinfo->flags & RIP_RTF_CHANGED)))
 2256: 	  continue;
 2257: 
 2258: 	/* Split horizon. */
 2259: 	/* if (split_horizon == rip_split_horizon) */
 2260: 	if (ri->split_horizon == RIP_SPLIT_HORIZON)
 2261: 	  {
 2262: 	    /* 
 2263: 	     * We perform split horizon for RIP and connected route. 
 2264: 	     * For rip routes, we want to suppress the route if we would
 2265:              * end up sending the route back on the interface that we
 2266:              * learned it from, with a higher metric. For connected routes,
 2267:              * we suppress the route if the prefix is a subset of the
 2268:              * source address that we are going to use for the packet 
 2269:              * (in order to handle the case when multiple subnets are
 2270:              * configured on the same interface).
 2271:              */
 2272: 	    if (rinfo->type == ZEBRA_ROUTE_RIP  &&
 2273:                  rinfo->ifindex == ifc->ifp->ifindex) 
 2274: 	      continue;
 2275: 	    if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
 2276:                  prefix_match((struct prefix *)p, ifc->address))
 2277: 	      continue;
 2278: 	  }
 2279: 
 2280: 	/* Preparation for route-map. */
 2281: 	rinfo->metric_set = 0;
 2282: 	rinfo->nexthop_out.s_addr = 0;
 2283: 	rinfo->metric_out = rinfo->metric;
 2284: 	rinfo->tag_out = rinfo->tag;
 2285: 	rinfo->ifindex_out = ifc->ifp->ifindex;
 2286: 
 2287: 	/* In order to avoid some local loops,
 2288: 	 * if the RIP route has a nexthop via this interface, keep the nexthop,
 2289: 	 * otherwise set it to 0. The nexthop should not be propagated
 2290: 	 * beyond the local broadcast/multicast area in order
 2291: 	 * to avoid an IGP multi-level recursive look-up.
 2292: 	 * see (4.4)
 2293: 	 */
 2294: 	if (rinfo->ifindex == ifc->ifp->ifindex)
 2295: 	  rinfo->nexthop_out = rinfo->nexthop;
 2296: 
 2297: 	/* Interface route-map */
 2298: 	if (ri->routemap[RIP_FILTER_OUT])
 2299: 	  {
 2300: 	    ret = route_map_apply (ri->routemap[RIP_FILTER_OUT], 
 2301: 				     (struct prefix *) p, RMAP_RIP, 
 2302: 				     rinfo);
 2303: 
 2304: 	    if (ret == RMAP_DENYMATCH)
 2305: 	      {
 2306: 	        if (IS_RIP_DEBUG_PACKET)
 2307: 	          zlog_debug ("RIP %s/%d is filtered by route-map out",
 2308: 			     inet_ntoa (p->prefix), p->prefixlen);
 2309: 		  continue;
 2310: 	      }
 2311: 	  }
 2312:            
 2313: 	/* Apply redistribute route map - continue, if deny */
 2314: 	if (rip->route_map[rinfo->type].name
 2315: 	    && rinfo->sub_type != RIP_ROUTE_INTERFACE)
 2316: 	  {
 2317: 	    ret = route_map_apply (rip->route_map[rinfo->type].map,
 2318: 				   (struct prefix *)p, RMAP_RIP, rinfo);
 2319: 
 2320: 	    if (ret == RMAP_DENYMATCH) 
 2321: 	      {
 2322: 		if (IS_RIP_DEBUG_PACKET)
 2323: 		  zlog_debug ("%s/%d is filtered by route-map",
 2324: 			     inet_ntoa (p->prefix), p->prefixlen);
 2325: 		continue;
 2326: 	      }
 2327: 	  }
 2328: 
 2329: 	/* When route-map does not set metric. */
 2330: 	if (! rinfo->metric_set)
 2331: 	  {
 2332: 	    /* If redistribute metric is set. */
 2333: 	    if (rip->route_map[rinfo->type].metric_config
 2334: 		&& rinfo->metric != RIP_METRIC_INFINITY)
 2335: 	      {
 2336: 		rinfo->metric_out = rip->route_map[rinfo->type].metric;
 2337: 	      }
 2338: 	    else
 2339: 	      {
 2340: 		/* If the route is not connected or localy generated
 2341: 		   one, use default-metric value*/
 2342: 		if (rinfo->type != ZEBRA_ROUTE_RIP 
 2343: 		    && rinfo->type != ZEBRA_ROUTE_CONNECT
 2344: 		    && rinfo->metric != RIP_METRIC_INFINITY)
 2345: 		  rinfo->metric_out = rip->default_metric;
 2346: 	      }
 2347: 	  }
 2348: 
 2349: 	/* Apply offset-list */
 2350: 	if (rinfo->metric != RIP_METRIC_INFINITY)
 2351: 	  rip_offset_list_apply_out (p, ifc->ifp, &rinfo->metric_out);
 2352: 
 2353: 	if (rinfo->metric_out > RIP_METRIC_INFINITY)
 2354: 	  rinfo->metric_out = RIP_METRIC_INFINITY;
 2355: 
 2356: 	/* Perform split-horizon with poisoned reverse 
 2357: 	 * for RIP and connected routes.
 2358: 	 **/
 2359: 	if (ri->split_horizon == RIP_SPLIT_HORIZON_POISONED_REVERSE) {
 2360: 	    /* 
 2361: 	     * We perform split horizon for RIP and connected route. 
 2362: 	     * For rip routes, we want to suppress the route if we would
 2363:              * end up sending the route back on the interface that we
 2364:              * learned it from, with a higher metric. For connected routes,
 2365:              * we suppress the route if the prefix is a subset of the
 2366:              * source address that we are going to use for the packet 
 2367:              * (in order to handle the case when multiple subnets are
 2368:              * configured on the same interface).
 2369:              */
 2370: 	  if (rinfo->type == ZEBRA_ROUTE_RIP  &&
 2371: 	       rinfo->ifindex == ifc->ifp->ifindex)
 2372: 	       rinfo->metric_out = RIP_METRIC_INFINITY;
 2373: 	  if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
 2374:               prefix_match((struct prefix *)p, ifc->address))
 2375: 	       rinfo->metric_out = RIP_METRIC_INFINITY;
 2376: 	}
 2377: 	
 2378: 	/* Prepare preamble, auth headers, if needs be */
 2379: 	if (num == 0)
 2380: 	  {
 2381: 	    stream_putc (s, RIP_RESPONSE);
 2382: 	    stream_putc (s, version);
 2383: 	    stream_putw (s, 0);
 2384: 	    
 2385: 	    /* auth header for !v1 && !no_auth */
 2386:             if ( (ri->auth_type != RIP_NO_AUTH) && (version != RIPv1) )
 2387:               doff = rip_auth_header_write (s, ri, key, auth_str, 
 2388:                                               RIP_AUTH_SIMPLE_SIZE);
 2389:           }
 2390:         
 2391: 	/* Write RTE to the stream. */
 2392: 	num = rip_write_rte (num, s, p, version, rinfo);
 2393: 	if (num == rtemax)
 2394: 	  {
 2395: 	    if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
 2396:               rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE);
 2397: 
 2398: 	    ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s),
 2399: 				   to, ifc);
 2400: 
 2401: 	    if (ret >= 0 && IS_RIP_DEBUG_SEND)
 2402: 	      rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
 2403: 			       stream_get_endp(s), "SEND");
 2404: 	    num = 0;
 2405: 	    stream_reset (s);
 2406: 	  }
 2407:       }
 2408: 
 2409:   /* Flush unwritten RTE. */
 2410:   if (num != 0)
 2411:     {
 2412:       if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
 2413:         rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE);
 2414: 
 2415:       ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifc);
 2416: 
 2417:       if (ret >= 0 && IS_RIP_DEBUG_SEND)
 2418: 	rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
 2419: 			 stream_get_endp (s), "SEND");
 2420:       num = 0;
 2421:       stream_reset (s);
 2422:     }
 2423: 
 2424:   /* Statistics updates. */
 2425:   ri->sent_updates++;
 2426: }
 2427: 
 2428: /* Send RIP packet to the interface. */
 2429: static void
 2430: rip_update_interface (struct connected *ifc, u_char version, int route_type)
 2431: {
 2432:   struct sockaddr_in to;
 2433: 
 2434:   /* When RIP version is 2 and multicast enable interface. */
 2435:   if (version == RIPv2 && if_is_multicast (ifc->ifp)) 
 2436:     {
 2437:       if (IS_RIP_DEBUG_EVENT)
 2438: 	zlog_debug ("multicast announce on %s ", ifc->ifp->name);
 2439: 
 2440:       rip_output_process (ifc, NULL, route_type, version);
 2441:       return;
 2442:     }
 2443:   
 2444:   /* If we can't send multicast packet, send it with unicast. */
 2445:   if (if_is_broadcast (ifc->ifp) || if_is_pointopoint (ifc->ifp))
 2446:     {
 2447:       if (ifc->address->family == AF_INET)
 2448:         {
 2449:           /* Destination address and port setting. */
 2450:           memset (&to, 0, sizeof (struct sockaddr_in));
 2451:           if (ifc->destination)
 2452:             /* use specified broadcast or peer destination addr */
 2453:             to.sin_addr = ifc->destination->u.prefix4;
 2454:           else if (ifc->address->prefixlen < IPV4_MAX_PREFIXLEN)
 2455:             /* calculate the appropriate broadcast address */
 2456:             to.sin_addr.s_addr =
 2457:               ipv4_broadcast_addr(ifc->address->u.prefix4.s_addr,
 2458:                                   ifc->address->prefixlen);
 2459: 	  else
 2460: 	    /* do not know where to send the packet */
 2461: 	    return;
 2462:           to.sin_port = htons (RIP_PORT_DEFAULT);
 2463: 
 2464:           if (IS_RIP_DEBUG_EVENT)
 2465:             zlog_debug("%s announce to %s on %s",
 2466: 		       CONNECTED_PEER(ifc) ? "unicast" : "broadcast",
 2467: 		       inet_ntoa (to.sin_addr), ifc->ifp->name);
 2468: 
 2469:           rip_output_process (ifc, &to, route_type, version);
 2470:         }
 2471:     }
 2472: }
 2473: 
 2474: /* Update send to all interface and neighbor. */
 2475: static void
 2476: rip_update_process (int route_type)
 2477: {
 2478:   struct listnode *node;
 2479:   struct listnode *ifnode, *ifnnode;
 2480:   struct connected *connected;
 2481:   struct interface *ifp;
 2482:   struct rip_interface *ri;
 2483:   struct route_node *rp;
 2484:   struct sockaddr_in to;
 2485:   struct prefix_ipv4 *p;
 2486: 
 2487:   /* Send RIP update to each interface. */
 2488:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
 2489:     {
 2490:       if (if_is_loopback (ifp))
 2491: 	continue;
 2492: 
 2493:       if (! if_is_operative (ifp))
 2494: 	continue;
 2495: 
 2496:       /* Fetch RIP interface information. */
 2497:       ri = ifp->info;
 2498: 
 2499:       /* When passive interface is specified, suppress announce to the
 2500:          interface. */
 2501:       if (ri->passive)
 2502: 	continue;
 2503: 
 2504:       if (ri->running)
 2505: 	{
 2506: 	  /* 
 2507: 	   * If there is no version configuration in the interface,
 2508: 	   * use rip's version setting. 
 2509: 	   */
 2510: 	  int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
 2511: 		       rip->version_send : ri->ri_send);
 2512: 
 2513: 	  if (IS_RIP_DEBUG_EVENT) 
 2514: 	    zlog_debug("SEND UPDATE to %s ifindex %d",
 2515: 		       (ifp->name ? ifp->name : "_unknown_"), ifp->ifindex);
 2516: 
 2517:           /* send update on each connected network */
 2518: 	  for (ALL_LIST_ELEMENTS (ifp->connected, ifnode, ifnnode, connected))
 2519: 	    {
 2520: 	      if (connected->address->family == AF_INET)
 2521: 	        {
 2522: 		  if (vsend & RIPv1)
 2523: 		    rip_update_interface (connected, RIPv1, route_type);
 2524: 		  if ((vsend & RIPv2) && if_is_multicast(ifp))
 2525: 		    rip_update_interface (connected, RIPv2, route_type);
 2526: 		}
 2527: 	    }
 2528: 	}
 2529:     }
 2530: 
 2531:   /* RIP send updates to each neighbor. */
 2532:   for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
 2533:     if (rp->info != NULL)
 2534:       {
 2535: 	p = (struct prefix_ipv4 *) &rp->p;
 2536: 
 2537: 	ifp = if_lookup_address (p->prefix);
 2538: 	if (! ifp)
 2539: 	  {
 2540: 	    zlog_warn ("Neighbor %s doesnt have connected interface!",
 2541: 		       inet_ntoa (p->prefix));
 2542: 	    continue;
 2543: 	  }
 2544:         
 2545:         if ( (connected = connected_lookup_address (ifp, p->prefix)) == NULL)
 2546:           {
 2547:             zlog_warn ("Neighbor %s doesnt have connected network",
 2548:                        inet_ntoa (p->prefix));
 2549:             continue;
 2550:           }
 2551:         
 2552: 	/* Set destination address and port */
 2553: 	memset (&to, 0, sizeof (struct sockaddr_in));
 2554: 	to.sin_addr = p->prefix;
 2555: 	to.sin_port = htons (RIP_PORT_DEFAULT);
 2556: 
 2557: 	/* RIP version is rip's configuration. */
 2558: 	rip_output_process (connected, &to, route_type, rip->version_send);
 2559:       }
 2560: }
 2561: 
 2562: /* RIP's periodical timer. */
 2563: static int
 2564: rip_update (struct thread *t)
 2565: {
 2566:   /* Clear timer pointer. */
 2567:   rip->t_update = NULL;
 2568: 
 2569:   if (IS_RIP_DEBUG_EVENT)
 2570:     zlog_debug ("update timer fire!");
 2571: 
 2572:   /* Process update output. */
 2573:   rip_update_process (rip_all_route);
 2574: 
 2575:   /* Triggered updates may be suppressed if a regular update is due by
 2576:      the time the triggered update would be sent. */
 2577:   if (rip->t_triggered_interval)
 2578:     {
 2579:       thread_cancel (rip->t_triggered_interval);
 2580:       rip->t_triggered_interval = NULL;
 2581:     }
 2582:   rip->trigger = 0;
 2583: 
 2584:   /* Register myself. */
 2585:   rip_event (RIP_UPDATE_EVENT, 0);
 2586: 
 2587:   return 0;
 2588: }
 2589: 
 2590: /* Walk down the RIP routing table then clear changed flag. */
 2591: static void
 2592: rip_clear_changed_flag (void)
 2593: {
 2594:   struct route_node *rp;
 2595:   struct rip_info *rinfo;
 2596: 
 2597:   for (rp = route_top (rip->table); rp; rp = route_next (rp))
 2598:     if ((rinfo = rp->info) != NULL)
 2599:       if (rinfo->flags & RIP_RTF_CHANGED)
 2600: 	rinfo->flags &= ~RIP_RTF_CHANGED;
 2601: }
 2602: 
 2603: /* Triggered update interval timer. */
 2604: static int
 2605: rip_triggered_interval (struct thread *t)
 2606: {
 2607:   int rip_triggered_update (struct thread *);
 2608: 
 2609:   rip->t_triggered_interval = NULL;
 2610: 
 2611:   if (rip->trigger)
 2612:     {
 2613:       rip->trigger = 0;
 2614:       rip_triggered_update (t);
 2615:     }
 2616:   return 0;
 2617: }     
 2618: 
 2619: /* Execute triggered update. */
 2620: static int
 2621: rip_triggered_update (struct thread *t)
 2622: {
 2623:   int interval;
 2624: 
 2625:   /* Clear thred pointer. */
 2626:   rip->t_triggered_update = NULL;
 2627: 
 2628:   /* Cancel interval timer. */
 2629:   if (rip->t_triggered_interval)
 2630:     {
 2631:       thread_cancel (rip->t_triggered_interval);
 2632:       rip->t_triggered_interval = NULL;
 2633:     }
 2634:   rip->trigger = 0;
 2635: 
 2636:   /* Logging triggered update. */
 2637:   if (IS_RIP_DEBUG_EVENT)
 2638:     zlog_debug ("triggered update!");
 2639: 
 2640:   /* Split Horizon processing is done when generating triggered
 2641:      updates as well as normal updates (see section 2.6). */
 2642:   rip_update_process (rip_changed_route);
 2643: 
 2644:   /* Once all of the triggered updates have been generated, the route
 2645:      change flags should be cleared. */
 2646:   rip_clear_changed_flag ();
 2647: 
 2648:   /* After a triggered update is sent, a timer should be set for a
 2649:    random interval between 1 and 5 seconds.  If other changes that
 2650:    would trigger updates occur before the timer expires, a single
 2651:    update is triggered when the timer expires. */
 2652:   interval = (random () % 5) + 1;
 2653: 
 2654:   rip->t_triggered_interval = 
 2655:     thread_add_timer (master, rip_triggered_interval, NULL, interval);
 2656: 
 2657:   return 0;
 2658: }
 2659: 
 2660: /* Withdraw redistributed route. */
 2661: void
 2662: rip_redistribute_withdraw (int type)
 2663: {
 2664:   struct route_node *rp;
 2665:   struct rip_info *rinfo;
 2666: 
 2667:   if (!rip)
 2668:     return;
 2669: 
 2670:   for (rp = route_top (rip->table); rp; rp = route_next (rp))
 2671:     if ((rinfo = rp->info) != NULL)
 2672:       {
 2673: 	if (rinfo->type == type
 2674: 	    && rinfo->sub_type != RIP_ROUTE_INTERFACE)
 2675: 	  {
 2676: 	    /* Perform poisoned reverse. */
 2677: 	    rinfo->metric = RIP_METRIC_INFINITY;
 2678: 	    RIP_TIMER_ON (rinfo->t_garbage_collect, 
 2679: 			  rip_garbage_collect, rip->garbage_time);
 2680: 	    RIP_TIMER_OFF (rinfo->t_timeout);
 2681: 	    rinfo->flags |= RIP_RTF_CHANGED;
 2682: 
 2683: 	    if (IS_RIP_DEBUG_EVENT) {
 2684:               struct prefix_ipv4 *p = (struct prefix_ipv4 *) &rp->p;
 2685: 
 2686:               zlog_debug ("Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
 2687:                          inet_ntoa(p->prefix), p->prefixlen,
 2688:                          ifindex2ifname(rinfo->ifindex));
 2689: 	    }
 2690: 
 2691: 	    rip_event (RIP_TRIGGERED_UPDATE, 0);
 2692: 	  }
 2693:       }
 2694: }
 2695: 
 2696: /* Create new RIP instance and set it to global variable. */
 2697: static int
 2698: rip_create (void)
 2699: {
 2700:   rip = XCALLOC (MTYPE_RIP, sizeof (struct rip));
 2701: 
 2702:   /* Set initial value. */
 2703:   rip->version_send = RI_RIP_VERSION_2;
 2704:   rip->version_recv = RI_RIP_VERSION_1_AND_2;
 2705:   rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
 2706:   rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
 2707:   rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
 2708:   rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
 2709: 
 2710:   /* Initialize RIP routig table. */
 2711:   rip->table = route_table_init ();
 2712:   rip->route = route_table_init ();
 2713:   rip->neighbor = route_table_init ();
 2714: 
 2715:   /* Make output stream. */
 2716:   rip->obuf = stream_new (1500);
 2717: 
 2718:   /* Make socket. */
 2719:   rip->sock = rip_create_socket (NULL);
 2720:   if (rip->sock < 0)
 2721:     return rip->sock;
 2722: 
 2723:   /* Create read and timer thread. */
 2724:   rip_event (RIP_READ, rip->sock);
 2725:   rip_event (RIP_UPDATE_EVENT, 1);
 2726: 
 2727:   return 0;
 2728: }
 2729: 
 2730: /* Sned RIP request to the destination. */
 2731: int
 2732: rip_request_send (struct sockaddr_in *to, struct interface *ifp,
 2733: 		  u_char version, struct connected *connected)
 2734: {
 2735:   struct rte *rte;
 2736:   struct rip_packet rip_packet;
 2737:   struct listnode *node, *nnode;
 2738: 
 2739:   memset (&rip_packet, 0, sizeof (rip_packet));
 2740: 
 2741:   rip_packet.command = RIP_REQUEST;
 2742:   rip_packet.version = version;
 2743:   rte = rip_packet.rte;
 2744:   rte->metric = htonl (RIP_METRIC_INFINITY);
 2745: 
 2746:   if (connected) 
 2747:     {
 2748:       /* 
 2749:        * connected is only sent for ripv1 case, or when
 2750:        * interface does not support multicast.  Caller loops
 2751:        * over each connected address for this case.
 2752:        */
 2753:       if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet), 
 2754:                             to, connected) != sizeof (rip_packet))
 2755:         return -1;
 2756:       else
 2757:         return sizeof (rip_packet);
 2758:     }
 2759: 	
 2760:   /* send request on each connected network */
 2761:   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
 2762:     {
 2763:       struct prefix_ipv4 *p;
 2764: 
 2765:       p = (struct prefix_ipv4 *) connected->address;
 2766: 
 2767:       if (p->family != AF_INET)
 2768:         continue;
 2769: 
 2770:       if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet), 
 2771:                             to, connected) != sizeof (rip_packet))
 2772:         return -1;
 2773:     }
 2774:   return sizeof (rip_packet);
 2775: }
 2776: 
 2777: static int
 2778: rip_update_jitter (unsigned long time)
 2779: {
 2780: #define JITTER_BOUND 4
 2781:   /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
 2782:      Given that, we cannot let time be less than JITTER_BOUND seconds.
 2783:      The RIPv2 RFC says jitter should be small compared to
 2784:      update_time.  We consider 1/JITTER_BOUND to be small.
 2785:   */
 2786:   
 2787:   int jitter_input = time;
 2788:   int jitter;
 2789:   
 2790:   if (jitter_input < JITTER_BOUND)
 2791:     jitter_input = JITTER_BOUND;
 2792:   
 2793:   jitter = (((rand () % ((jitter_input * 2) + 1)) - jitter_input));  
 2794: 
 2795:   return jitter/JITTER_BOUND;
 2796: }
 2797: 
 2798: void
 2799: rip_event (enum rip_event event, int sock)
 2800: {
 2801:   int jitter = 0;
 2802: 
 2803:   switch (event)
 2804:     {
 2805:     case RIP_READ:
 2806:       rip->t_read = thread_add_read (master, rip_read, NULL, sock);
 2807:       break;
 2808:     case RIP_UPDATE_EVENT:
 2809:       if (rip->t_update)
 2810: 	{
 2811: 	  thread_cancel (rip->t_update);
 2812: 	  rip->t_update = NULL;
 2813: 	}
 2814:       jitter = rip_update_jitter (rip->update_time);
 2815:       rip->t_update = 
 2816: 	thread_add_timer (master, rip_update, NULL, 
 2817: 			  sock ? 2 : rip->update_time + jitter);
 2818:       break;
 2819:     case RIP_TRIGGERED_UPDATE:
 2820:       if (rip->t_triggered_interval)
 2821: 	rip->trigger = 1;
 2822:       else if (! rip->t_triggered_update)
 2823: 	rip->t_triggered_update = 
 2824: 	  thread_add_event (master, rip_triggered_update, NULL, 0);
 2825:       break;
 2826:     default:
 2827:       break;
 2828:     }
 2829: }
 2830: 
 2831: DEFUN (router_rip,
 2832:        router_rip_cmd,
 2833:        "router rip",
 2834:        "Enable a routing process\n"
 2835:        "Routing Information Protocol (RIP)\n")
 2836: {
 2837:   int ret;
 2838: 
 2839:   /* If rip is not enabled before. */
 2840:   if (! rip)
 2841:     {
 2842:       ret = rip_create ();
 2843:       if (ret < 0)
 2844: 	{
 2845: 	  zlog_info ("Can't create RIP");
 2846: 	  return CMD_WARNING;
 2847: 	}
 2848:     }
 2849:   vty->node = RIP_NODE;
 2850:   vty->index = rip;
 2851: 
 2852:   return CMD_SUCCESS;
 2853: }
 2854: 
 2855: DEFUN (no_router_rip,
 2856:        no_router_rip_cmd,
 2857:        "no router rip",
 2858:        NO_STR
 2859:        "Enable a routing process\n"
 2860:        "Routing Information Protocol (RIP)\n")
 2861: {
 2862:   if (rip)
 2863:     rip_clean ();
 2864:   return CMD_SUCCESS;
 2865: }
 2866: 
 2867: DEFUN (rip_version,
 2868:        rip_version_cmd,
 2869:        "version <1-2>",
 2870:        "Set routing protocol version\n"
 2871:        "version\n")
 2872: {
 2873:   int version;
 2874: 
 2875:   version = atoi (argv[0]);
 2876:   if (version != RIPv1 && version != RIPv2)
 2877:     {
 2878:       vty_out (vty, "invalid rip version %d%s", version,
 2879: 	       VTY_NEWLINE);
 2880:       return CMD_WARNING;
 2881:     }
 2882:   rip->version_send = version;
 2883:   rip->version_recv = version;
 2884: 
 2885:   return CMD_SUCCESS;
 2886: } 
 2887: 
 2888: DEFUN (no_rip_version,
 2889:        no_rip_version_cmd,
 2890:        "no version",
 2891:        NO_STR
 2892:        "Set routing protocol version\n")
 2893: {
 2894:   /* Set RIP version to the default. */
 2895:   rip->version_send = RI_RIP_VERSION_2;
 2896:   rip->version_recv = RI_RIP_VERSION_1_AND_2;
 2897: 
 2898:   return CMD_SUCCESS;
 2899: } 
 2900: 
 2901: ALIAS (no_rip_version,
 2902:        no_rip_version_val_cmd,
 2903:        "no version <1-2>",
 2904:        NO_STR
 2905:        "Set routing protocol version\n"
 2906:        "version\n")
 2907: 
 2908: DEFUN (rip_route,
 2909:        rip_route_cmd,
 2910:        "route A.B.C.D/M",
 2911:        "RIP static route configuration\n"
 2912:        "IP prefix <network>/<length>\n")
 2913: {
 2914:   int ret;
 2915:   struct prefix_ipv4 p;
 2916:   struct route_node *node;
 2917: 
 2918:   ret = str2prefix_ipv4 (argv[0], &p);
 2919:   if (ret < 0)
 2920:     {
 2921:       vty_out (vty, "Malformed address%s", VTY_NEWLINE);
 2922:       return CMD_WARNING;
 2923:     }
 2924:   apply_mask_ipv4 (&p);
 2925: 
 2926:   /* For router rip configuration. */
 2927:   node = route_node_get (rip->route, (struct prefix *) &p);
 2928: 
 2929:   if (node->info)
 2930:     {
 2931:       vty_out (vty, "There is already same static route.%s", VTY_NEWLINE);
 2932:       route_unlock_node (node);
 2933:       return CMD_WARNING;
 2934:     }
 2935: 
 2936:   node->info = (char *)"static";
 2937: 
 2938:   rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL, 0, 0);
 2939: 
 2940:   return CMD_SUCCESS;
 2941: }
 2942: 
 2943: DEFUN (no_rip_route,
 2944:        no_rip_route_cmd,
 2945:        "no route A.B.C.D/M",
 2946:        NO_STR
 2947:        "RIP static route configuration\n"
 2948:        "IP prefix <network>/<length>\n")
 2949: {
 2950:   int ret;
 2951:   struct prefix_ipv4 p;
 2952:   struct route_node *node;
 2953: 
 2954:   ret = str2prefix_ipv4 (argv[0], &p);
 2955:   if (ret < 0)
 2956:     {
 2957:       vty_out (vty, "Malformed address%s", VTY_NEWLINE);
 2958:       return CMD_WARNING;
 2959:     }
 2960:   apply_mask_ipv4 (&p);
 2961: 
 2962:   /* For router rip configuration. */
 2963:   node = route_node_lookup (rip->route, (struct prefix *) &p);
 2964:   if (! node)
 2965:     {
 2966:       vty_out (vty, "Can't find route %s.%s", argv[0],
 2967: 	       VTY_NEWLINE);
 2968:       return CMD_WARNING;
 2969:     }
 2970: 
 2971:   rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
 2972:   route_unlock_node (node);
 2973: 
 2974:   node->info = NULL;
 2975:   route_unlock_node (node);
 2976: 
 2977:   return CMD_SUCCESS;
 2978: }
 2979: 
 2980: #if 0
 2981: static void
 2982: rip_update_default_metric (void)
 2983: {
 2984:   struct route_node *np;
 2985:   struct rip_info *rinfo;
 2986: 
 2987:   for (np = route_top (rip->table); np; np = route_next (np))
 2988:     if ((rinfo = np->info) != NULL)
 2989:       if (rinfo->type != ZEBRA_ROUTE_RIP && rinfo->type != ZEBRA_ROUTE_CONNECT)
 2990:         rinfo->metric = rip->default_metric;
 2991: }
 2992: #endif
 2993: 
 2994: DEFUN (rip_default_metric,
 2995:        rip_default_metric_cmd,
 2996:        "default-metric <1-16>",
 2997:        "Set a metric of redistribute routes\n"
 2998:        "Default metric\n")
 2999: {
 3000:   if (rip)
 3001:     {
 3002:       rip->default_metric = atoi (argv[0]);
 3003:       /* rip_update_default_metric (); */
 3004:     }
 3005:   return CMD_SUCCESS;
 3006: }
 3007: 
 3008: DEFUN (no_rip_default_metric,
 3009:        no_rip_default_metric_cmd,
 3010:        "no default-metric",
 3011:        NO_STR
 3012:        "Set a metric of redistribute routes\n"
 3013:        "Default metric\n")
 3014: {
 3015:   if (rip)
 3016:     {
 3017:       rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
 3018:       /* rip_update_default_metric (); */
 3019:     }
 3020:   return CMD_SUCCESS;
 3021: }
 3022: 
 3023: ALIAS (no_rip_default_metric,
 3024:        no_rip_default_metric_val_cmd,
 3025:        "no default-metric <1-16>",
 3026:        NO_STR
 3027:        "Set a metric of redistribute routes\n"
 3028:        "Default metric\n")
 3029: 
 3030: DEFUN (rip_timers,
 3031:        rip_timers_cmd,
 3032:        "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
 3033:        "Adjust routing timers\n"
 3034:        "Basic routing protocol update timers\n"
 3035:        "Routing table update timer value in second. Default is 30.\n"
 3036:        "Routing information timeout timer. Default is 180.\n"
 3037:        "Garbage collection timer. Default is 120.\n")
 3038: {
 3039:   unsigned long update;
 3040:   unsigned long timeout;
 3041:   unsigned long garbage;
 3042:   char *endptr = NULL;
 3043:   unsigned long RIP_TIMER_MAX = 2147483647;
 3044:   unsigned long RIP_TIMER_MIN = 5;
 3045: 
 3046:   update = strtoul (argv[0], &endptr, 10);
 3047:   if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN || *endptr != '\0')  
 3048:     {
 3049:       vty_out (vty, "update timer value error%s", VTY_NEWLINE);
 3050:       return CMD_WARNING;
 3051:     }
 3052:   
 3053:   timeout = strtoul (argv[1], &endptr, 10);
 3054:   if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN || *endptr != '\0') 
 3055:     {
 3056:       vty_out (vty, "timeout timer value error%s", VTY_NEWLINE);
 3057:       return CMD_WARNING;
 3058:     }
 3059:   
 3060:   garbage = strtoul (argv[2], &endptr, 10);
 3061:   if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN || *endptr != '\0') 
 3062:     {
 3063:       vty_out (vty, "garbage timer value error%s", VTY_NEWLINE);
 3064:       return CMD_WARNING;
 3065:     }
 3066: 
 3067:   /* Set each timer value. */
 3068:   rip->update_time = update;
 3069:   rip->timeout_time = timeout;
 3070:   rip->garbage_time = garbage;
 3071: 
 3072:   /* Reset update timer thread. */
 3073:   rip_event (RIP_UPDATE_EVENT, 0);
 3074: 
 3075:   return CMD_SUCCESS;
 3076: }
 3077: 
 3078: DEFUN (no_rip_timers,
 3079:        no_rip_timers_cmd,
 3080:        "no timers basic",
 3081:        NO_STR
 3082:        "Adjust routing timers\n"
 3083:        "Basic routing protocol update timers\n")
 3084: {
 3085:   /* Set each timer value to the default. */
 3086:   rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
 3087:   rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
 3088:   rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
 3089: 
 3090:   /* Reset update timer thread. */
 3091:   rip_event (RIP_UPDATE_EVENT, 0);
 3092: 
 3093:   return CMD_SUCCESS;
 3094: }
 3095: 
 3096: ALIAS (no_rip_timers,
 3097:        no_rip_timers_val_cmd,
 3098:        "no timers basic <0-65535> <0-65535> <0-65535>",
 3099:        NO_STR
 3100:        "Adjust routing timers\n"
 3101:        "Basic routing protocol update timers\n"
 3102:        "Routing table update timer value in second. Default is 30.\n"
 3103:        "Routing information timeout timer. Default is 180.\n"
 3104:        "Garbage collection timer. Default is 120.\n")
 3105: 
 3106: 
 3107: struct route_table *rip_distance_table;
 3108: 
 3109: struct rip_distance
 3110: {
 3111:   /* Distance value for the IP source prefix. */
 3112:   u_char distance;
 3113: 
 3114:   /* Name of the access-list to be matched. */
 3115:   char *access_list;
 3116: };
 3117: 
 3118: static struct rip_distance *
 3119: rip_distance_new (void)
 3120: {
 3121:   return XCALLOC (MTYPE_RIP_DISTANCE, sizeof (struct rip_distance));
 3122: }
 3123: 
 3124: static void
 3125: rip_distance_free (struct rip_distance *rdistance)
 3126: {
 3127:   XFREE (MTYPE_RIP_DISTANCE, rdistance);
 3128: }
 3129: 
 3130: static int
 3131: rip_distance_set (struct vty *vty, const char *distance_str, const char *ip_str,
 3132: 		  const char *access_list_str)
 3133: {
 3134:   int ret;
 3135:   struct prefix_ipv4 p;
 3136:   u_char distance;
 3137:   struct route_node *rn;
 3138:   struct rip_distance *rdistance;
 3139: 
 3140:   ret = str2prefix_ipv4 (ip_str, &p);
 3141:   if (ret == 0)
 3142:     {
 3143:       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
 3144:       return CMD_WARNING;
 3145:     }
 3146: 
 3147:   distance = atoi (distance_str);
 3148: 
 3149:   /* Get RIP distance node. */
 3150:   rn = route_node_get (rip_distance_table, (struct prefix *) &p);
 3151:   if (rn->info)
 3152:     {
 3153:       rdistance = rn->info;
 3154:       route_unlock_node (rn);
 3155:     }
 3156:   else
 3157:     {
 3158:       rdistance = rip_distance_new ();
 3159:       rn->info = rdistance;
 3160:     }
 3161: 
 3162:   /* Set distance value. */
 3163:   rdistance->distance = distance;
 3164: 
 3165:   /* Reset access-list configuration. */
 3166:   if (rdistance->access_list)
 3167:     {
 3168:       free (rdistance->access_list);
 3169:       rdistance->access_list = NULL;
 3170:     }
 3171:   if (access_list_str)
 3172:     rdistance->access_list = strdup (access_list_str);
 3173: 
 3174:   return CMD_SUCCESS;
 3175: }
 3176: 
 3177: static int
 3178: rip_distance_unset (struct vty *vty, const char *distance_str,
 3179: 		    const char *ip_str, const char *access_list_str)
 3180: {
 3181:   int ret;
 3182:   struct prefix_ipv4 p;
 3183:   u_char distance;
 3184:   struct route_node *rn;
 3185:   struct rip_distance *rdistance;
 3186: 
 3187:   ret = str2prefix_ipv4 (ip_str, &p);
 3188:   if (ret == 0)
 3189:     {
 3190:       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
 3191:       return CMD_WARNING;
 3192:     }
 3193: 
 3194:   distance = atoi (distance_str);
 3195: 
 3196:   rn = route_node_lookup (rip_distance_table, (struct prefix *)&p);
 3197:   if (! rn)
 3198:     {
 3199:       vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
 3200:       return CMD_WARNING;
 3201:     }
 3202: 
 3203:   rdistance = rn->info;
 3204: 
 3205:   if (rdistance->access_list)
 3206:     free (rdistance->access_list);
 3207:   rip_distance_free (rdistance);
 3208: 
 3209:   rn->info = NULL;
 3210:   route_unlock_node (rn);
 3211:   route_unlock_node (rn);
 3212: 
 3213:   return CMD_SUCCESS;
 3214: }
 3215: 
 3216: static void
 3217: rip_distance_reset (void)
 3218: {
 3219:   struct route_node *rn;
 3220:   struct rip_distance *rdistance;
 3221: 
 3222:   for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
 3223:     if ((rdistance = rn->info) != NULL)
 3224:       {
 3225: 	if (rdistance->access_list)
 3226: 	  free (rdistance->access_list);
 3227: 	rip_distance_free (rdistance);
 3228: 	rn->info = NULL;
 3229: 	route_unlock_node (rn);
 3230:       }
 3231: }
 3232: 
 3233: /* Apply RIP information to distance method. */
 3234: u_char
 3235: rip_distance_apply (struct rip_info *rinfo)
 3236: {
 3237:   struct route_node *rn;
 3238:   struct prefix_ipv4 p;
 3239:   struct rip_distance *rdistance;
 3240:   struct access_list *alist;
 3241: 
 3242:   if (! rip)
 3243:     return 0;
 3244: 
 3245:   memset (&p, 0, sizeof (struct prefix_ipv4));
 3246:   p.family = AF_INET;
 3247:   p.prefix = rinfo->from;
 3248:   p.prefixlen = IPV4_MAX_BITLEN;
 3249: 
 3250:   /* Check source address. */
 3251:   rn = route_node_match (rip_distance_table, (struct prefix *) &p);
 3252:   if (rn)
 3253:     {
 3254:       rdistance = rn->info;
 3255:       route_unlock_node (rn);
 3256: 
 3257:       if (rdistance->access_list)
 3258: 	{
 3259: 	  alist = access_list_lookup (AFI_IP, rdistance->access_list);
 3260: 	  if (alist == NULL)
 3261: 	    return 0;
 3262: 	  if (access_list_apply (alist, &rinfo->rp->p) == FILTER_DENY)
 3263: 	    return 0;
 3264: 
 3265: 	  return rdistance->distance;
 3266: 	}
 3267:       else
 3268: 	return rdistance->distance;
 3269:     }
 3270: 
 3271:   if (rip->distance)
 3272:     return rip->distance;
 3273: 
 3274:   return 0;
 3275: }
 3276: 
 3277: static void
 3278: rip_distance_show (struct vty *vty)
 3279: {
 3280:   struct route_node *rn;
 3281:   struct rip_distance *rdistance;
 3282:   int header = 1;
 3283:   char buf[BUFSIZ];
 3284:   
 3285:   vty_out (vty, "  Distance: (default is %d)%s",
 3286: 	   rip->distance ? rip->distance :ZEBRA_RIP_DISTANCE_DEFAULT,
 3287: 	   VTY_NEWLINE);
 3288: 
 3289:   for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
 3290:     if ((rdistance = rn->info) != NULL)
 3291:       {
 3292: 	if (header)
 3293: 	  {
 3294: 	    vty_out (vty, "    Address           Distance  List%s",
 3295: 		     VTY_NEWLINE);
 3296: 	    header = 0;
 3297: 	  }
 3298: 	sprintf (buf, "%s/%d", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
 3299: 	vty_out (vty, "    %-20s  %4d  %s%s",
 3300: 		 buf, rdistance->distance,
 3301: 		 rdistance->access_list ? rdistance->access_list : "",
 3302: 		 VTY_NEWLINE);
 3303:       }
 3304: }
 3305: 
 3306: DEFUN (rip_distance,
 3307:        rip_distance_cmd,
 3308:        "distance <1-255>",
 3309:        "Administrative distance\n"
 3310:        "Distance value\n")
 3311: {
 3312:   rip->distance = atoi (argv[0]);
 3313:   return CMD_SUCCESS;
 3314: }
 3315: 
 3316: DEFUN (no_rip_distance,
 3317:        no_rip_distance_cmd,
 3318:        "no distance <1-255>",
 3319:        NO_STR
 3320:        "Administrative distance\n"
 3321:        "Distance value\n")
 3322: {
 3323:   rip->distance = 0;
 3324:   return CMD_SUCCESS;
 3325: }
 3326: 
 3327: DEFUN (rip_distance_source,
 3328:        rip_distance_source_cmd,
 3329:        "distance <1-255> A.B.C.D/M",
 3330:        "Administrative distance\n"
 3331:        "Distance value\n"
 3332:        "IP source prefix\n")
 3333: {
 3334:   rip_distance_set (vty, argv[0], argv[1], NULL);
 3335:   return CMD_SUCCESS;
 3336: }
 3337: 
 3338: DEFUN (no_rip_distance_source,
 3339:        no_rip_distance_source_cmd,
 3340:        "no distance <1-255> A.B.C.D/M",
 3341:        NO_STR
 3342:        "Administrative distance\n"
 3343:        "Distance value\n"
 3344:        "IP source prefix\n")
 3345: {
 3346:   rip_distance_unset (vty, argv[0], argv[1], NULL);
 3347:   return CMD_SUCCESS;
 3348: }
 3349: 
 3350: DEFUN (rip_distance_source_access_list,
 3351:        rip_distance_source_access_list_cmd,
 3352:        "distance <1-255> A.B.C.D/M WORD",
 3353:        "Administrative distance\n"
 3354:        "Distance value\n"
 3355:        "IP source prefix\n"
 3356:        "Access list name\n")
 3357: {
 3358:   rip_distance_set (vty, argv[0], argv[1], argv[2]);
 3359:   return CMD_SUCCESS;
 3360: }
 3361: 
 3362: DEFUN (no_rip_distance_source_access_list,
 3363:        no_rip_distance_source_access_list_cmd,
 3364:        "no distance <1-255> A.B.C.D/M WORD",
 3365:        NO_STR
 3366:        "Administrative distance\n"
 3367:        "Distance value\n"
 3368:        "IP source prefix\n"
 3369:        "Access list name\n")
 3370: {
 3371:   rip_distance_unset (vty, argv[0], argv[1], argv[2]);
 3372:   return CMD_SUCCESS;
 3373: }
 3374: 
 3375: /* Print out routes update time. */
 3376: static void
 3377: rip_vty_out_uptime (struct vty *vty, struct rip_info *rinfo)
 3378: {
 3379:   time_t clock;
 3380:   struct tm *tm;
 3381: #define TIME_BUF 25
 3382:   char timebuf [TIME_BUF];
 3383:   struct thread *thread;
 3384: 
 3385:   if ((thread = rinfo->t_timeout) != NULL)
 3386:     {
 3387:       clock = thread_timer_remain_second (thread);
 3388:       tm = gmtime (&clock);
 3389:       strftime (timebuf, TIME_BUF, "%M:%S", tm);
 3390:       vty_out (vty, "%5s", timebuf);
 3391:     }
 3392:   else if ((thread = rinfo->t_garbage_collect) != NULL)
 3393:     {
 3394:       clock = thread_timer_remain_second (thread);
 3395:       tm = gmtime (&clock);
 3396:       strftime (timebuf, TIME_BUF, "%M:%S", tm);
 3397:       vty_out (vty, "%5s", timebuf);
 3398:     }
 3399: }
 3400: 
 3401: static const char *
 3402: rip_route_type_print (int sub_type)
 3403: {
 3404:   switch (sub_type)
 3405:     {
 3406:       case RIP_ROUTE_RTE:
 3407: 	return "n";
 3408:       case RIP_ROUTE_STATIC:
 3409: 	return "s";
 3410:       case RIP_ROUTE_DEFAULT:
 3411: 	return "d";
 3412:       case RIP_ROUTE_REDISTRIBUTE:
 3413: 	return "r";
 3414:       case RIP_ROUTE_INTERFACE:
 3415: 	return "i";
 3416:       default:
 3417: 	return "?";
 3418:     }
 3419: }
 3420: 
 3421: DEFUN (show_ip_rip,
 3422:        show_ip_rip_cmd,
 3423:        "show ip rip",
 3424:        SHOW_STR
 3425:        IP_STR
 3426:        "Show RIP routes\n")
 3427: {
 3428:   struct route_node *np;
 3429:   struct rip_info *rinfo;
 3430: 
 3431:   if (! rip)
 3432:     return CMD_SUCCESS;
 3433: 
 3434:   vty_out (vty, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP%s"
 3435: 	   "Sub-codes:%s"
 3436:            "      (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
 3437: 	   "      (i) - interface%s%s"
 3438: 	   "     Network            Next Hop         Metric From            Tag Time%s",
 3439: 	   VTY_NEWLINE, VTY_NEWLINE,  VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
 3440:   
 3441:   for (np = route_top (rip->table); np; np = route_next (np))
 3442:     if ((rinfo = np->info) != NULL)
 3443:       {
 3444: 	int len;
 3445: 
 3446: 	len = vty_out (vty, "%c(%s) %s/%d",
 3447: 		       /* np->lock, For debugging. */
 3448: 		       zebra_route_char(rinfo->type),
 3449: 		       rip_route_type_print (rinfo->sub_type),
 3450: 		       inet_ntoa (np->p.u.prefix4), np->p.prefixlen);
 3451: 	
 3452: 	len = 24 - len;
 3453: 
 3454: 	if (len > 0)
 3455: 	  vty_out (vty, "%*s", len, " ");
 3456: 
 3457:         if (rinfo->nexthop.s_addr) 
 3458: 	  vty_out (vty, "%-20s %2d ", inet_ntoa (rinfo->nexthop),
 3459: 		   rinfo->metric);
 3460:         else
 3461: 	  vty_out (vty, "0.0.0.0              %2d ", rinfo->metric);
 3462: 
 3463: 	/* Route which exist in kernel routing table. */
 3464: 	if ((rinfo->type == ZEBRA_ROUTE_RIP) && 
 3465: 	    (rinfo->sub_type == RIP_ROUTE_RTE))
 3466: 	  {
 3467: 	    vty_out (vty, "%-15s ", inet_ntoa (rinfo->from));
 3468: 	    vty_out (vty, "%3d ", rinfo->tag);
 3469: 	    rip_vty_out_uptime (vty, rinfo);
 3470: 	  }
 3471: 	else if (rinfo->metric == RIP_METRIC_INFINITY)
 3472: 	  {
 3473: 	    vty_out (vty, "self            ");
 3474: 	    vty_out (vty, "%3d ", rinfo->tag);
 3475: 	    rip_vty_out_uptime (vty, rinfo);
 3476: 	  }
 3477: 	else
 3478: 	  {
 3479: 	    if (rinfo->external_metric)
 3480: 	      {
 3481: 	        len = vty_out (vty, "self (%s:%d)", 
 3482: 			       zebra_route_string(rinfo->type),
 3483: 	                       rinfo->external_metric);
 3484: 	        len = 16 - len;
 3485: 	        if (len > 0)
 3486: 	          vty_out (vty, "%*s", len, " ");
 3487: 	      }
 3488: 	    else
 3489: 	      vty_out (vty, "self            ");
 3490: 	    vty_out (vty, "%3d", rinfo->tag);
 3491: 	  }
 3492: 
 3493: 	vty_out (vty, "%s", VTY_NEWLINE);
 3494:       }
 3495:   return CMD_SUCCESS;
 3496: }
 3497: 
 3498: /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
 3499: DEFUN (show_ip_rip_status,
 3500:        show_ip_rip_status_cmd,
 3501:        "show ip rip status",
 3502:        SHOW_STR
 3503:        IP_STR
 3504:        "Show RIP routes\n"
 3505:        "IP routing protocol process parameters and statistics\n")
 3506: {
 3507:   struct listnode *node;
 3508:   struct interface *ifp;
 3509:   struct rip_interface *ri;
 3510:   extern const struct message ri_version_msg[];
 3511:   const char *send_version;
 3512:   const char *receive_version;
 3513: 
 3514:   if (! rip)
 3515:     return CMD_SUCCESS;
 3516: 
 3517:   vty_out (vty, "Routing Protocol is \"rip\"%s", VTY_NEWLINE);
 3518:   vty_out (vty, "  Sending updates every %ld seconds with +/-50%%,",
 3519: 	   rip->update_time);
 3520:   vty_out (vty, " next due in %lu seconds%s", 
 3521: 	   thread_timer_remain_second(rip->t_update),
 3522: 	   VTY_NEWLINE);
 3523:   vty_out (vty, "  Timeout after %ld seconds,", rip->timeout_time);
 3524:   vty_out (vty, " garbage collect after %ld seconds%s", rip->garbage_time,
 3525: 	   VTY_NEWLINE);
 3526: 
 3527:   /* Filtering status show. */
 3528:   config_show_distribute (vty);
 3529: 		 
 3530:   /* Default metric information. */
 3531:   vty_out (vty, "  Default redistribution metric is %d%s",
 3532: 	   rip->default_metric, VTY_NEWLINE);
 3533: 
 3534:   /* Redistribute information. */
 3535:   vty_out (vty, "  Redistributing:");
 3536:   config_write_rip_redistribute (vty, 0);
 3537:   vty_out (vty, "%s", VTY_NEWLINE);
 3538: 
 3539:   vty_out (vty, "  Default version control: send version %s,",
 3540: 	   lookup(ri_version_msg,rip->version_send));
 3541:   if (rip->version_recv == RI_RIP_VERSION_1_AND_2)
 3542:     vty_out (vty, " receive any version %s", VTY_NEWLINE);
 3543:   else
 3544:     vty_out (vty, " receive version %s %s",
 3545: 	     lookup(ri_version_msg,rip->version_recv), VTY_NEWLINE);
 3546: 
 3547:   vty_out (vty, "    Interface        Send  Recv   Key-chain%s", VTY_NEWLINE);
 3548: 
 3549:   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
 3550:     {
 3551:       ri = ifp->info;
 3552: 
 3553:       if (!ri->running)
 3554: 	continue;
 3555: 
 3556:       if (ri->enable_network || ri->enable_interface)
 3557: 	{
 3558: 	  if (ri->ri_send == RI_RIP_UNSPEC)
 3559: 	    send_version = lookup (ri_version_msg, rip->version_send);
 3560: 	  else
 3561: 	    send_version = lookup (ri_version_msg, ri->ri_send);
 3562: 
 3563: 	  if (ri->ri_receive == RI_RIP_UNSPEC)
 3564: 	    receive_version = lookup (ri_version_msg, rip->version_recv);
 3565: 	  else
 3566: 	    receive_version = lookup (ri_version_msg, ri->ri_receive);
 3567: 	
 3568: 	  vty_out (vty, "    %-17s%-3s   %-3s    %s%s", ifp->name,
 3569: 		   send_version,
 3570: 		   receive_version,
 3571: 		   ri->key_chain ? ri->key_chain : "",
 3572: 		   VTY_NEWLINE);
 3573: 	}
 3574:     }
 3575: 
 3576:   vty_out (vty, "  Routing for Networks:%s", VTY_NEWLINE);
 3577:   config_write_rip_network (vty, 0);  
 3578: 
 3579:   {
 3580:     int found_passive = 0;
 3581:     for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
 3582:       {
 3583: 	ri = ifp->info;
 3584: 
 3585: 	if ((ri->enable_network || ri->enable_interface) && ri->passive)
 3586: 	  {
 3587: 	    if (!found_passive)
 3588: 	      {
 3589: 		vty_out (vty, "  Passive Interface(s):%s", VTY_NEWLINE);
 3590: 		found_passive = 1;
 3591: 	      }
 3592: 	    vty_out (vty, "    %s%s", ifp->name, VTY_NEWLINE);
 3593: 	  }
 3594:       }
 3595:   }
 3596: 
 3597:   vty_out (vty, "  Routing Information Sources:%s", VTY_NEWLINE);
 3598:   vty_out (vty, "    Gateway          BadPackets BadRoutes  Distance Last Update%s", VTY_NEWLINE);
 3599:   rip_peer_display (vty);
 3600: 
 3601:   rip_distance_show (vty);
 3602: 
 3603:   return CMD_SUCCESS;
 3604: }
 3605: 
 3606: /* RIP configuration write function. */
 3607: static int
 3608: config_write_rip (struct vty *vty)
 3609: {
 3610:   int write = 0;
 3611:   struct route_node *rn;
 3612:   struct rip_distance *rdistance;
 3613: 
 3614:   if (rip)
 3615:     {
 3616:       /* Router RIP statement. */
 3617:       vty_out (vty, "router rip%s", VTY_NEWLINE);
 3618:       write++;
 3619:   
 3620:       /* RIP version statement.  Default is RIP version 2. */
 3621:       if (rip->version_send != RI_RIP_VERSION_2
 3622: 	  || rip->version_recv != RI_RIP_VERSION_1_AND_2)
 3623: 	vty_out (vty, " version %d%s", rip->version_send,
 3624: 		 VTY_NEWLINE);
 3625:  
 3626:       /* RIP timer configuration. */
 3627:       if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT 
 3628: 	  || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT 
 3629: 	  || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT)
 3630: 	vty_out (vty, " timers basic %lu %lu %lu%s",
 3631: 		 rip->update_time,
 3632: 		 rip->timeout_time,
 3633: 		 rip->garbage_time,
 3634: 		 VTY_NEWLINE);
 3635: 
 3636:       /* Default information configuration. */
 3637:       if (rip->default_information)
 3638: 	{
 3639: 	  if (rip->default_information_route_map)
 3640: 	    vty_out (vty, " default-information originate route-map %s%s",
 3641: 		     rip->default_information_route_map, VTY_NEWLINE);
 3642: 	  else
 3643: 	    vty_out (vty, " default-information originate%s",
 3644: 		     VTY_NEWLINE);
 3645: 	}
 3646: 
 3647:       /* Redistribute configuration. */
 3648:       config_write_rip_redistribute (vty, 1);
 3649: 
 3650:       /* RIP offset-list configuration. */
 3651:       config_write_rip_offset_list (vty);
 3652: 
 3653:       /* RIP enabled network and interface configuration. */
 3654:       config_write_rip_network (vty, 1);
 3655: 			
 3656:       /* RIP default metric configuration */
 3657:       if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT)
 3658:         vty_out (vty, " default-metric %d%s",
 3659: 		 rip->default_metric, VTY_NEWLINE);
 3660: 
 3661:       /* Distribute configuration. */
 3662:       write += config_write_distribute (vty);
 3663: 
 3664:       /* Interface routemap configuration */
 3665:       write += config_write_if_rmap (vty);
 3666: 
 3667:       /* Distance configuration. */
 3668:       if (rip->distance)
 3669: 	vty_out (vty, " distance %d%s", rip->distance, VTY_NEWLINE);
 3670: 
 3671:       /* RIP source IP prefix distance configuration. */
 3672:       for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
 3673: 	if ((rdistance = rn->info) != NULL)
 3674: 	  vty_out (vty, " distance %d %s/%d %s%s", rdistance->distance,
 3675: 		   inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
 3676: 		   rdistance->access_list ? rdistance->access_list : "",
 3677: 		   VTY_NEWLINE);
 3678: 
 3679:       /* RIP static route configuration. */
 3680:       for (rn = route_top (rip->route); rn; rn = route_next (rn))
 3681: 	if (rn->info)
 3682: 	  vty_out (vty, " route %s/%d%s", 
 3683: 		   inet_ntoa (rn->p.u.prefix4),
 3684: 		   rn->p.prefixlen,
 3685: 		   VTY_NEWLINE);
 3686: 
 3687:     }
 3688:   return write;
 3689: }
 3690: 
 3691: /* RIP node structure. */
 3692: static struct cmd_node rip_node =
 3693: {
 3694:   RIP_NODE,
 3695:   "%s(config-router)# ",
 3696:   1
 3697: };
 3698: 
 3699: /* Distribute-list update functions. */
 3700: static void
 3701: rip_distribute_update (struct distribute *dist)
 3702: {
 3703:   struct interface *ifp;
 3704:   struct rip_interface *ri;
 3705:   struct access_list *alist;
 3706:   struct prefix_list *plist;
 3707: 
 3708:   if (! dist->ifname)
 3709:     return;
 3710: 
 3711:   ifp = if_lookup_by_name (dist->ifname);
 3712:   if (ifp == NULL)
 3713:     return;
 3714: 
 3715:   ri = ifp->info;
 3716: 
 3717:   if (dist->list[DISTRIBUTE_IN])
 3718:     {
 3719:       alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
 3720:       if (alist)
 3721: 	ri->list[RIP_FILTER_IN] = alist;
 3722:       else
 3723: 	ri->list[RIP_FILTER_IN] = NULL;
 3724:     }
 3725:   else
 3726:     ri->list[RIP_FILTER_IN] = NULL;
 3727: 
 3728:   if (dist->list[DISTRIBUTE_OUT])
 3729:     {
 3730:       alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
 3731:       if (alist)
 3732: 	ri->list[RIP_FILTER_OUT] = alist;
 3733:       else
 3734: 	ri->list[RIP_FILTER_OUT] = NULL;
 3735:     }
 3736:   else
 3737:     ri->list[RIP_FILTER_OUT] = NULL;
 3738: 
 3739:   if (dist->prefix[DISTRIBUTE_IN])
 3740:     {
 3741:       plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
 3742:       if (plist)
 3743: 	ri->prefix[RIP_FILTER_IN] = plist;
 3744:       else
 3745: 	ri->prefix[RIP_FILTER_IN] = NULL;
 3746:     }
 3747:   else
 3748:     ri->prefix[RIP_FILTER_IN] = NULL;
 3749: 
 3750:   if (dist->prefix[DISTRIBUTE_OUT])
 3751:     {
 3752:       plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
 3753:       if (plist)
 3754: 	ri->prefix[RIP_FILTER_OUT] = plist;
 3755:       else
 3756: 	ri->prefix[RIP_FILTER_OUT] = NULL;
 3757:     }
 3758:   else
 3759:     ri->prefix[RIP_FILTER_OUT] = NULL;
 3760: }
 3761: 
 3762: void
 3763: rip_distribute_update_interface (struct interface *ifp)
 3764: {
 3765:   struct distribute *dist;
 3766: 
 3767:   dist = distribute_lookup (ifp->name);
 3768:   if (dist)
 3769:     rip_distribute_update (dist);
 3770: }
 3771: 
 3772: /* Update all interface's distribute list. */
 3773: /* ARGSUSED */
 3774: static void
 3775: rip_distribute_update_all (struct prefix_list *notused)
 3776: {
 3777:   struct interface *ifp;
 3778:   struct listnode *node, *nnode;
 3779: 
 3780:   for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
 3781:     rip_distribute_update_interface (ifp);
 3782: }
 3783: /* ARGSUSED */
 3784: static void
 3785: rip_distribute_update_all_wrapper(struct access_list *notused)
 3786: {
 3787:         rip_distribute_update_all(NULL);
 3788: }
 3789: 
 3790: /* Delete all added rip route. */
 3791: void
 3792: rip_clean (void)
 3793: {
 3794:   int i;
 3795:   struct route_node *rp;
 3796:   struct rip_info *rinfo;
 3797: 
 3798:   if (rip)
 3799:     {
 3800:       /* Clear RIP routes */
 3801:       for (rp = route_top (rip->table); rp; rp = route_next (rp))
 3802: 	if ((rinfo = rp->info) != NULL)
 3803: 	  {
 3804: 	    if (rinfo->type == ZEBRA_ROUTE_RIP &&
 3805: 		rinfo->sub_type == RIP_ROUTE_RTE)
 3806: 	      rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p,
 3807: 				     &rinfo->nexthop, rinfo->metric);
 3808: 	
 3809: 	    RIP_TIMER_OFF (rinfo->t_timeout);
 3810: 	    RIP_TIMER_OFF (rinfo->t_garbage_collect);
 3811: 
 3812: 	    rp->info = NULL;
 3813: 	    route_unlock_node (rp);
 3814: 
 3815: 	    rip_info_free (rinfo);
 3816: 	  }
 3817: 
 3818:       /* Cancel RIP related timers. */
 3819:       RIP_TIMER_OFF (rip->t_update);
 3820:       RIP_TIMER_OFF (rip->t_triggered_update);
 3821:       RIP_TIMER_OFF (rip->t_triggered_interval);
 3822: 
 3823:       /* Cancel read thread. */
 3824:       if (rip->t_read)
 3825: 	{
 3826: 	  thread_cancel (rip->t_read);
 3827: 	  rip->t_read = NULL;
 3828: 	}
 3829: 
 3830:       /* Close RIP socket. */
 3831:       if (rip->sock >= 0)
 3832: 	{
 3833: 	  close (rip->sock);
 3834: 	  rip->sock = -1;
 3835: 	}
 3836: 
 3837:       /* Static RIP route configuration. */
 3838:       for (rp = route_top (rip->route); rp; rp = route_next (rp))
 3839: 	if (rp->info)
 3840: 	  {
 3841: 	    rp->info = NULL;
 3842: 	    route_unlock_node (rp);
 3843: 	  }
 3844: 
 3845:       /* RIP neighbor configuration. */
 3846:       for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
 3847: 	if (rp->info)
 3848: 	  {
 3849: 	    rp->info = NULL;
 3850: 	    route_unlock_node (rp);
 3851: 	  }
 3852: 
 3853:       /* Redistribute related clear. */
 3854:       if (rip->default_information_route_map)
 3855: 	free (rip->default_information_route_map);
 3856: 
 3857:       for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 3858: 	if (rip->route_map[i].name)
 3859: 	  free (rip->route_map[i].name);
 3860: 
 3861:       XFREE (MTYPE_ROUTE_TABLE, rip->table);
 3862:       XFREE (MTYPE_ROUTE_TABLE, rip->route);
 3863:       XFREE (MTYPE_ROUTE_TABLE, rip->neighbor);
 3864:       
 3865:       XFREE (MTYPE_RIP, rip);
 3866:       rip = NULL;
 3867:     }
 3868: 
 3869:   rip_clean_network ();
 3870:   rip_passive_nondefault_clean ();
 3871:   rip_offset_clean ();
 3872:   rip_interface_clean ();
 3873:   rip_distance_reset ();
 3874:   rip_redistribute_clean ();
 3875: }
 3876: 
 3877: /* Reset all values to the default settings. */
 3878: void
 3879: rip_reset (void)
 3880: {
 3881:   /* Reset global counters. */
 3882:   rip_global_route_changes = 0;
 3883:   rip_global_queries = 0;
 3884: 
 3885:   /* Call ripd related reset functions. */
 3886:   rip_debug_reset ();
 3887:   rip_route_map_reset ();
 3888: 
 3889:   /* Call library reset functions. */
 3890:   vty_reset ();
 3891:   access_list_reset ();
 3892:   prefix_list_reset ();
 3893: 
 3894:   distribute_list_reset ();
 3895: 
 3896:   rip_interface_reset ();
 3897:   rip_distance_reset ();
 3898: 
 3899:   rip_zclient_reset ();
 3900: }
 3901: 
 3902: static void
 3903: rip_if_rmap_update (struct if_rmap *if_rmap)
 3904: {
 3905:   struct interface *ifp;
 3906:   struct rip_interface *ri;
 3907:   struct route_map *rmap;
 3908: 
 3909:   ifp = if_lookup_by_name (if_rmap->ifname);
 3910:   if (ifp == NULL)
 3911:     return;
 3912: 
 3913:   ri = ifp->info;
 3914: 
 3915:   if (if_rmap->routemap[IF_RMAP_IN])
 3916:     {
 3917:       rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_IN]);
 3918:       if (rmap)
 3919: 	ri->routemap[IF_RMAP_IN] = rmap;
 3920:       else
 3921: 	ri->routemap[IF_RMAP_IN] = NULL;
 3922:     }
 3923:   else
 3924:     ri->routemap[RIP_FILTER_IN] = NULL;
 3925: 
 3926:   if (if_rmap->routemap[IF_RMAP_OUT])
 3927:     {
 3928:       rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_OUT]);
 3929:       if (rmap)
 3930: 	ri->routemap[IF_RMAP_OUT] = rmap;
 3931:       else
 3932: 	ri->routemap[IF_RMAP_OUT] = NULL;
 3933:     }
 3934:   else
 3935:     ri->routemap[RIP_FILTER_OUT] = NULL;
 3936: }
 3937: 
 3938: void
 3939: rip_if_rmap_update_interface (struct interface *ifp)
 3940: {
 3941:   struct if_rmap *if_rmap;
 3942: 
 3943:   if_rmap = if_rmap_lookup (ifp->name);
 3944:   if (if_rmap)
 3945:     rip_if_rmap_update (if_rmap);
 3946: }
 3947: 
 3948: static void
 3949: rip_routemap_update_redistribute (void)
 3950: {
 3951:   int i;
 3952: 
 3953:   if (rip)
 3954:     {
 3955:       for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
 3956: 	{
 3957: 	  if (rip->route_map[i].name)
 3958: 	    rip->route_map[i].map = 
 3959: 	      route_map_lookup_by_name (rip->route_map[i].name);
 3960: 	}
 3961:     }
 3962: }
 3963: 
 3964: /* ARGSUSED */
 3965: static void
 3966: rip_routemap_update (const char *notused)
 3967: {
 3968:   struct interface *ifp;
 3969:   struct listnode *node, *nnode;
 3970: 
 3971:   for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
 3972:     rip_if_rmap_update_interface (ifp);
 3973: 
 3974:   rip_routemap_update_redistribute ();
 3975: }
 3976: 
 3977: /* Allocate new rip structure and set default value. */
 3978: void
 3979: rip_init (void)
 3980: {
 3981:   /* Randomize for triggered update random(). */
 3982:   srand (time (NULL));
 3983: 
 3984:   /* Install top nodes. */
 3985:   install_node (&rip_node, config_write_rip);
 3986: 
 3987:   /* Install rip commands. */
 3988:   install_element (VIEW_NODE, &show_ip_rip_cmd);
 3989:   install_element (VIEW_NODE, &show_ip_rip_status_cmd);
 3990:   install_element (ENABLE_NODE, &show_ip_rip_cmd);
 3991:   install_element (ENABLE_NODE, &show_ip_rip_status_cmd);
 3992:   install_element (CONFIG_NODE, &router_rip_cmd);
 3993:   install_element (CONFIG_NODE, &no_router_rip_cmd);
 3994: 
 3995:   install_default (RIP_NODE);
 3996:   install_element (RIP_NODE, &rip_version_cmd);
 3997:   install_element (RIP_NODE, &no_rip_version_cmd);
 3998:   install_element (RIP_NODE, &no_rip_version_val_cmd);
 3999:   install_element (RIP_NODE, &rip_default_metric_cmd);
 4000:   install_element (RIP_NODE, &no_rip_default_metric_cmd);
 4001:   install_element (RIP_NODE, &no_rip_default_metric_val_cmd);
 4002:   install_element (RIP_NODE, &rip_timers_cmd);
 4003:   install_element (RIP_NODE, &no_rip_timers_cmd);
 4004:   install_element (RIP_NODE, &no_rip_timers_val_cmd);
 4005:   install_element (RIP_NODE, &rip_route_cmd);
 4006:   install_element (RIP_NODE, &no_rip_route_cmd);
 4007:   install_element (RIP_NODE, &rip_distance_cmd);
 4008:   install_element (RIP_NODE, &no_rip_distance_cmd);
 4009:   install_element (RIP_NODE, &rip_distance_source_cmd);
 4010:   install_element (RIP_NODE, &no_rip_distance_source_cmd);
 4011:   install_element (RIP_NODE, &rip_distance_source_access_list_cmd);
 4012:   install_element (RIP_NODE, &no_rip_distance_source_access_list_cmd);
 4013: 
 4014:   /* Debug related init. */
 4015:   rip_debug_init ();
 4016: 
 4017:   /* SNMP init. */
 4018: #ifdef HAVE_SNMP
 4019:   rip_snmp_init ();
 4020: #endif /* HAVE_SNMP */
 4021: 
 4022:   /* Access list install. */
 4023:   access_list_init ();
 4024:   access_list_add_hook (rip_distribute_update_all_wrapper);
 4025:   access_list_delete_hook (rip_distribute_update_all_wrapper);
 4026: 
 4027:   /* Prefix list initialize.*/
 4028:   prefix_list_init ();
 4029:   prefix_list_add_hook (rip_distribute_update_all);
 4030:   prefix_list_delete_hook (rip_distribute_update_all);
 4031: 
 4032:   /* Distribute list install. */
 4033:   distribute_list_init (RIP_NODE);
 4034:   distribute_list_add_hook (rip_distribute_update);
 4035:   distribute_list_delete_hook (rip_distribute_update);
 4036: 
 4037:   /* Route-map */
 4038:   rip_route_map_init ();
 4039:   rip_offset_init ();
 4040: 
 4041:   route_map_add_hook (rip_routemap_update);
 4042:   route_map_delete_hook (rip_routemap_update);
 4043: 
 4044:   if_rmap_init (RIP_NODE);
 4045:   if_rmap_hook_add (rip_if_rmap_update);
 4046:   if_rmap_hook_delete (rip_if_rmap_update);
 4047: 
 4048:   /* Distance control. */
 4049:   rip_distance_table = route_table_init ();
 4050: }

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