ripTimer.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:10k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ripTimer.c - routines to handle RIP periodic updates*/
  2. /* Copyright 1984 - 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright (c) 1983, 1988, 1993
  6.  * The Regents of the University of California.  All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  * This product includes software developed by the University of
  19.  * California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  * @(#)timer.c 8.1 (Berkeley) 6/5/93
  36.  */
  37. /*
  38. modification history
  39. --------------------
  40. 01l,22mar02,niq  Merged from Synth view, tor3_x.synth branch, ver 01p
  41. 01k,24jan02,niq  SPR 72415 - Added support for Route tags
  42. 01j,15oct01,rae  merge from truestack ver 01k, base 01h (VIRTUAL_STACK etc.)
  43. 01i,10nov00,spm  merged from version 01i of tor3_x branch (SPR #29099 fix)
  44. 01h,11sep98,spm  moved expanded ripShutdown routine to ripLib.c (SPR #22352);
  45.                  added mutual exclusion to prevent collisions with RIP 
  46.                  message processing (SPR #22350)
  47. 01g,01sep98,spm  corrected error preventing expiration of routes stored
  48.                  in hosthash table (SPR #22066)
  49. 01f,06oct97,gnn  fixed SPR 9211 and cleaned up warnings
  50. 01e,11aug97,gnn  name change.
  51. 01d,02jun97,gnn  fixed SPR 8685 so that the timer task does not respawn.
  52. 01c,12mar97,gnn  added multicast support.
  53.                  added time variables.
  54. 01b,24feb97,gnn  fixed bugs in interface aging.
  55. 01a,26nov96,gnn  created from BSD4.4 routed
  56. */
  57. /*
  58. DESCRIPTION
  59. */
  60. /*
  61.  * Routing Table Management Daemon
  62.  */
  63. #include "vxWorks.h"
  64. #include "rip/defs.h"
  65. #include "wdLib.h"
  66. #include "semLib.h"
  67. #include "intLib.h"
  68. #include "logLib.h"
  69. #ifdef VIRTUAL_STACK
  70. #include "netinet/vsLib.h"
  71. #include "netinet/vsRip.h"
  72. #endif /* VIRTUAL_STACK */
  73. /* globals */
  74. #ifndef VIRTUAL_STACK
  75. IMPORT int  routedDebug;
  76. IMPORT RIP  ripState;
  77. #endif /* VIRTUAL_STACK */
  78. /* forward declarations. */
  79. #ifdef VIRTUAL_STACK
  80. void ripTimer(int stackNum);
  81. #else
  82. void ripTimer(void);
  83. #endif /* VIRTUAL_STACK */
  84. IMPORT void ripTimerArm (long timeout);
  85. IMPORT STATUS routedIfInit (BOOL resetFlag, long ifIndex);
  86. IMPORT void ripTimeSet (struct timeval *pTimer);
  87. /*
  88.  * Timer routine.  Performs routing information supply
  89.  * duties and manages timers on routing table entries.
  90.  * Management of the RTS_CHANGED bit assumes that we broadcast
  91.  * each time called.
  92.  */
  93. void ripTimer
  94.     (
  95. #ifdef VIRTUAL_STACK
  96.     int stackNum
  97. #else
  98.     void
  99. #endif
  100.     )
  101.     {
  102.     register struct rthash *rh;
  103.     register struct rt_entry *rt;
  104.     struct rthash *base;
  105.     int doinghost;
  106.     int timetobroadcast;
  107.     int diffTime;
  108.     int deltaTime;
  109.     int time;
  110.     int timeLeft;
  111. #ifdef VIRTUAL_STACK
  112.     /* Assign virtual stack number to access appropriate data structures. */
  113.     if (virtualStackNumTaskIdSet (stackNum) == ERROR)
  114.         {
  115.         if (routedDebug)
  116.             logMsg ("ripTimerTask: unable to access stack data.n",
  117.                     0, 0, 0, 0, 0, 0);
  118.         return;
  119.         }
  120. #endif /* VIRTUAL_STACK */
  121.     FOREVER 
  122.         {
  123.         /* Wait for the semaphore given by the watchdog routine. */
  124.         semTake(ripState.timerSem, WAIT_FOREVER);
  125.         /* 
  126.          * Block until any processing of incoming messages has completed.
  127.          * This exclusion guarantees that the routing entries are stable
  128.          * during updates and that the timer values shared with the
  129.          * triggered update scheduling will be set atomically.
  130.          */
  131.         semTake (ripLockSem, WAIT_FOREVER);
  132.         ripTimeSet (&ripState.now);
  133.         /* Calculate the time difference from when we last checked */
  134.         diffTime = (u_long)ripState.now.tv_sec - (u_long)ripState.then.tv_sec;
  135.         /* If the timer has wrapped around, account for that */
  136.         if (diffTime < 0)
  137.             diffTime = -diffTime;
  138.         /* 
  139.          * Now round off the time to an integer multiple of timerRate.
  140.          * Whatever time remains after rounding off, will be adjusted
  141.          * when we restart the timer below
  142.          */
  143.         if (diffTime < ripState.timerRate)
  144.             {
  145.             deltaTime = 0;
  146.             diffTime = ripState.timerRate;
  147.             }
  148.         else
  149.             {
  150.             deltaTime =  diffTime % ripState.timerRate;
  151.             diffTime = (diffTime / ripState.timerRate) * ripState.timerRate;
  152.             }
  153.         /* Record the time we got above */
  154.         ripState.then = ripState.now;
  155.         /*
  156.          * Now check if the time elapsed (diffTime) covers an update
  157.          * point. If so we missed an update. We should send an update
  158.          * right now. Since the calculation below sends out updates
  159.          * only at multiples of the supply interval, we should
  160.          * increment the time only to the extent that it becomes an
  161.          * integer multiple of the supply interval. After deciding that we need
  162.          * to send an update, we'll add the remaining time. Note, that
  163.          * if so much time had elapsed such that 2 updates (supplies)
  164.          * could have been sent, we still send out only one as in the RIP
  165.          * protocol two or more immediate updates are equivalent to
  166.          * a single update
  167.          *
  168.          *        |last update             | new update (scheduled)
  169.          *        |                        |
  170.          *        |                        |      actual update (delayed)
  171.          *        |________________________|_____|________________
  172.          *        0              |         30                     | 60
  173.          *                       |<-------------->                |
  174.          *                       |   diffTime                     | next update
  175.          *                       |
  176.          *                       fake time
  177.          *
  178.          */
  179.         time = ripState.faketime % ripState.supplyInterval;
  180.         if ((time + diffTime) > ripState.supplyInterval)
  181.             {
  182.             time = ripState.supplyInterval - time;
  183.             timeLeft = diffTime - time;
  184.             diffTime -= timeLeft;
  185.             }
  186.         else
  187.             timeLeft = 0;
  188.         ripState.faketime += diffTime;
  189.         if (ripState.lookforinterfaces)
  190.             {
  191.             if (routedDebug)
  192.                 logMsg ("Calling routedIfInit.n", 0, 0, 0, 0, 0, 0);
  193.             routedIfInit (FALSE, 0);
  194.             }
  195.         timetobroadcast = ripState.supplier &&
  196.             ((ripState.faketime % ripState.supplyInterval) == 0);
  197.         ripState.faketime += timeLeft;
  198.         /* Restart the timer. */
  199.         ripTimerArm (ripState.timerRate - deltaTime);
  200.         base = hosthash;
  201.         doinghost = 1;
  202.         again:
  203.         for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)
  204.             {
  205.             rt = rh->rt_forw;
  206.             for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
  207.                 {
  208.                 /*
  209.                  * We don't advance time on a routing entry for
  210.                  * a passive gateway, or any interface.
  211.                  */
  212.                 if (!(rt->rt_state & RTS_PASSIVE) &&
  213.                     !(rt->rt_state & RTS_INTERFACE) &&
  214.                     !(rt->rt_state & RTS_OTHER))
  215.                     rt->rt_timer += ripState.timerRate;
  216.                 if (rt->rt_timer >= ripState.garbage)
  217.                     {
  218.                     rt = rt->rt_back;
  219.                     rtdelete (rt->rt_forw);
  220.                     continue;
  221.                     }
  222.                 /* 
  223.                  * If the timer expired, then we should delete the 
  224.                  * route from the system routing database. The 
  225.                  * check for inKernel allows us to delete valid routes
  226.                  * that were advertised with a metric of 15 (and added
  227.                  * to our table with a metric of 16). After deleting the
  228.                  * route, rt->inKernel will become FALSE and rt->rt_metric
  229.                  * will be set to HOPCNT_INFINITY (16) so that we would
  230.                  * not call rtchange again.
  231.                  */
  232.                 if (rt->rt_timer >= ripState.expire && 
  233.                     (rt->inKernel || rt->rt_metric < HOPCNT_INFINITY))
  234.                     rtchange(rt, &rt->rt_router, HOPCNT_INFINITY, NULL,
  235.                              rt->rt_tag, 0, NULL);
  236. /* 
  237.  * Only reset the flag after a broadcast is done
  238.  */
  239.                 if (timetobroadcast)
  240.     rt->rt_state &= ~RTS_CHANGED;
  241.                 }
  242.             }
  243.         if (doinghost)
  244.             {
  245.             doinghost = 0;
  246.             base = nethash;
  247.             goto again;
  248.             }
  249.         /*
  250.          * Send a periodic update if necessary and reset the timer
  251.          * and flag settings to suppress any pending triggered updates.
  252.          */
  253.         if (timetobroadcast)
  254.             {
  255.             toall (supply, 0, (struct interface *)NULL);
  256.             ripState.lastbcast = ripState.now;
  257.             ripState.lastfullupdate = ripState.now;
  258.             ripState.needupdate = 0;
  259.             ripState.nextbcast.tv_sec = 0;
  260.             }
  261.         semGive (ripLockSem);  /* End of critical section. */
  262.         }
  263.     }