timer.c revision 22997
1/* 2 * Copyright (c) 1985, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Copyright (c) 1995 John Hay. All rights reserved. 6 * 7 * This file includes significant work done at Cornell University by 8 * Bill Nesheim. That work included by permission. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * $Id$ 39 */ 40 41#ifndef lint 42static char sccsid[] = "@(#)timer.c 8.1 (Berkeley) 6/5/93"; 43#endif /* not lint */ 44 45/* 46 * Routing Table Management Daemon 47 */ 48#include "defs.h" 49#include <unistd.h> 50#include <stdlib.h> 51 52int timeval = -TIMER_RATE; 53 54/* 55 * Timer routine. Performs routing information supply 56 * duties and manages timers on routing and SAP table entries. 57 */ 58void 59timer() 60{ 61 register struct rthash *rh; 62 register struct rt_entry *rt; 63 struct rthash *base = hosthash; 64 register struct sap_hash *sh; 65 register struct sap_entry *sap; 66 struct sap_hash *sap_base = sap_head; 67 int doinghost = 1, timetobroadcast, ripbroadcast, sapbroadcast; 68 69 timeval += TIMER_RATE; 70 if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) 71 ifinit(); 72 timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0; 73 ripbroadcast = supplier && timetobroadcast && 74 (timeval % RIP_INTERVAL) == 0; 75 sapbroadcast = timetobroadcast && dosap && !ripbroadcast; 76 77again: 78 for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { 79 rt = rh->rt_forw; 80 for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { 81 if (rt->rt_clone) { 82 struct rt_entry *trt, *prt; 83 /* 84 * If a clone expire free it and mark the 85 * main route RTS_CHANGED. 86 */ 87 prt = rt; 88 trt = rt->rt_clone; 89 while (trt) { 90 trt->rt_timer += TIMER_RATE; 91 if (trt->rt_timer >= EXPIRE_TIME) { 92 prt->rt_clone = trt->rt_clone; 93 free((char *)trt); 94 trt = prt->rt_clone; 95 rt->rt_state |= RTS_CHANGED; 96 } else { 97 prt = trt; 98 trt = prt->rt_clone; 99 } 100 } 101 } 102 /* 103 * We don't advance time on a routing entry for 104 * a passive gateway or that for our only interface. 105 * The latter is excused because we don't act as 106 * a routing information supplier and hence would 107 * time it out. This is fair as if it's down 108 * we're cut off from the world anyway and it's 109 * not likely we'll grow any new hardware in 110 * the mean time. 111 */ 112 if (!(rt->rt_state & RTS_PASSIVE) && 113 !(rt->rt_state & RTS_INTERFACE)) 114 rt->rt_timer += TIMER_RATE; 115 if (rt->rt_timer >= EXPIRE_TIME) 116 rt->rt_metric = HOPCNT_INFINITY; 117 if (rt->rt_timer >= GARBAGE_TIME) { 118 rt = rt->rt_back; 119 /* Perhaps we should send a REQUEST for this route? */ 120 rtdelete(rt->rt_forw); 121 continue; 122 } 123 if (rt->rt_state & RTS_CHANGED) { 124 rt->rt_state &= ~RTS_CHANGED; 125 /* don't send extraneous packets */ 126 if (!supplier || ripbroadcast) 127 continue; 128 msg->rip_cmd = htons(RIPCMD_RESPONSE); 129 msg->rip_nets[0].rip_dst = 130 (satoipx_addr(rt->rt_dst)).x_net; 131 msg->rip_nets[0].rip_metric = 132 htons(min(rt->rt_metric+1, HOPCNT_INFINITY)); 133 msg->rip_nets[0].rip_ticks = 134 htons(rt->rt_ticks + 1); 135 toall(sndmsg, rt); 136 } 137 } 138 } 139 if (doinghost) { 140 doinghost = 0; 141 base = nethash; 142 goto again; 143 } 144 if (ripbroadcast) 145 toall(supply, NULL); 146 147 /* 148 * Now do the SAP stuff. 149 */ 150 for (sh = sap_base; sh < &sap_base[SAPHASHSIZ]; sh++) { 151 sap = sh->forw; 152 for (; sap != (struct sap_entry *)sh; sap = sap->forw) { 153 if (sap->clone) { 154 struct sap_entry *tsap, *psap; 155 /* 156 * If a clone expire free it and mark the 157 * main sap entry RTS_CHANGED. 158 */ 159 psap = sap; 160 tsap = sap->clone; 161 while (tsap) { 162 tsap->timer += TIMER_RATE; 163 if (tsap->timer >= EXPIRE_TIME) { 164 psap->clone = tsap->clone; 165 free((char *)tsap); 166 tsap = psap->clone; 167 sap->state |= RTS_CHANGED; 168 } else { 169 psap = tsap; 170 tsap = psap->clone; 171 } 172 } 173 } 174 sap->timer += TIMER_RATE; 175 if (sap->timer >= EXPIRE_TIME) 176 sap->metric = HOPCNT_INFINITY; 177 if (sap->timer >= GARBAGE_TIME) { 178 sap = sap->back; 179 /* Perhaps we should send a REQUEST for this route? */ 180 sap_delete(sap->forw); 181 continue; 182 } 183 /* 184 * XXX sap_sndmsg on RTS_CHANGED 185 */ 186 } 187 } 188 if (sapbroadcast) 189 sap_supply_toall(); 190 if (ftrace && sapbroadcast) 191 dumpsaptable(ftrace, sap_head); 192 alarm(TIMER_RATE); 193} 194 195/* 196 * On hangup, let everyone know we're going away. 197 */ 198void 199hup() 200{ 201 register struct rthash *rh; 202 register struct rt_entry *rt; 203 struct rthash *base = hosthash; 204 register struct sap_hash *sh; 205 register struct sap_entry *sap; 206 int doinghost = 1; 207 208 if (supplier) { 209again: 210 for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { 211 rt = rh->rt_forw; 212 for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) 213 rt->rt_metric = HOPCNT_INFINITY; 214 } 215 if (doinghost) { 216 doinghost = 0; 217 base = nethash; 218 goto again; 219 } 220 toall(supply, NULL); 221 222 /* 223 * Now for SAP. 224 */ 225 for (sh = sap_head; sh < &sap_head[SAPHASHSIZ]; sh++) { 226 sap = sh->forw; 227 for (; sap != (struct sap_entry *)sh; sap = sap->forw) 228 sap->sap.hops = htons(HOPCNT_INFINITY); 229 } 230 if (dosap) 231 sap_supply_toall(); 232 } 233 exit(1); 234} 235