File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ripd / ripd.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

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