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 * $FreeBSD$ 39 */ 40 41#ifndef lint 42static const 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 register struct sap_hash *sh; 64 register struct sap_entry *sap; 65 struct sap_hash *sap_base = sap_head; 66 int timetobroadcast, ripbroadcast, sapbroadcast; 67 68 timeval += TIMER_RATE; 69 if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) 70 ifinit(); 71 timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0; 72 ripbroadcast = supplier && timetobroadcast && 73 (timeval % RIP_INTERVAL) == 0; 74 sapbroadcast = timetobroadcast && dosap && !ripbroadcast; 75 76 for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) { 77 rt = rh->rt_forw; 78 for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { 79 if (rt->rt_clone) { 80 struct rt_entry *trt, *prt; 81 /* 82 * If a clone expire free it and mark the 83 * main route RTS_CHANGED. 84 */ 85 prt = rt; 86 trt = rt->rt_clone; 87 while (trt) { 88 trt->rt_timer += TIMER_RATE; 89 if (trt->rt_timer >= EXPIRE_TIME) { 90 prt->rt_clone = trt->rt_clone; 91 free((char *)trt); 92 trt = prt->rt_clone; 93 rt->rt_state |= RTS_CHANGED; 94 } else { 95 prt = trt; 96 trt = prt->rt_clone; 97 } 98 } 99 } 100 /* 101 * We don't advance time on a routing entry for 102 * a passive gateway or that for our only interface. 103 * The latter is excused because we don't act as 104 * a routing information supplier and hence would 105 * time it out. This is fair as if it's down 106 * we're cut off from the world anyway and it's 107 * not likely we'll grow any new hardware in 108 * the mean time. 109 */ 110 if (!(rt->rt_state & RTS_PASSIVE) && 111 !(rt->rt_state & RTS_INTERFACE)) 112 rt->rt_timer += TIMER_RATE; 113 if (rt->rt_timer >= EXPIRE_TIME) { 114 rt->rt_metric = HOPCNT_INFINITY; 115 rt->rt_state |= RTS_CHANGED; 116 } 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 if ((rt->rt_metric + 1) == HOPCNT_INFINITY) 129 continue; 130 msg->rip_cmd = htons(RIPCMD_RESPONSE); 131 msg->rip_nets[0].rip_dst = 132 (satoipx_addr(rt->rt_dst)).x_net; 133 msg->rip_nets[0].rip_metric = 134 htons(min(rt->rt_metric+1, HOPCNT_INFINITY)); 135 msg->rip_nets[0].rip_ticks = 136 htons(rt->rt_ticks + 1); 137 toall(sndmsg, rt, 0); 138 } 139 } 140 } 141 if (ripbroadcast) 142 toall(supply, NULL, 0); 143 144 /* 145 * Now do the SAP stuff. 146 */ 147 for (sh = sap_base; sh < &sap_base[SAPHASHSIZ]; sh++) { 148 sap = sh->forw; 149 for (; sap != (struct sap_entry *)sh; sap = sap->forw) { 150 if (sap->clone) { 151 struct sap_entry *tsap, *psap; 152 /* 153 * If a clone expire free it and mark the 154 * main sap entry RTS_CHANGED. 155 */ 156 psap = sap; 157 tsap = sap->clone; 158 while (tsap) { 159 tsap->timer += TIMER_RATE; 160 if (tsap->timer >= EXPIRE_TIME) { 161 psap->clone = tsap->clone; 162 free((char *)tsap); 163 tsap = psap->clone; 164 sap->state |= RTS_CHANGED; 165 } else { 166 psap = tsap; 167 tsap = psap->clone; 168 } 169 } 170 } 171 sap->timer += TIMER_RATE; 172 if (sap->timer >= EXPIRE_TIME) { 173 sap->sap.hops = htons(HOPCNT_INFINITY); 174 sap->state |= RTS_CHANGED; 175 } 176 if (sap->timer >= GARBAGE_TIME) { 177 sap = sap->back; 178 /* Perhaps we should send a REQUEST for this route? */ 179 sap_delete(sap->forw); 180 continue; 181 } 182 /* 183 * XXX sap_sndmsg on RTS_CHANGED 184 */ 185 if (sap->state & RTS_CHANGED) { 186 sap->state &= ~RTS_CHANGED; 187#ifdef notyet 188 /* don't send extraneous packets */ 189 if (!supplier || sapbroadcast) 190 continue; 191 if ((ntohs(sap->sap.hops) + 1) == HOPCNT_INFINITY) 192 continue; 193 sap_msg->sap_cmd = htons(SAP_RESP); 194 sap_msg->sap[0] = sap->sap; 195 sap_msg->sap[0].hops = 196 htons(min(sap->sap.hops+1, HOPCNT_INFINITY)); 197 toall(sapsndmsg, rt, 0); 198#endif 199 } 200 } 201 } 202 if (sapbroadcast) 203 sap_supply_toall(0); 204 if (ftrace && sapbroadcast) 205 dumpsaptable(ftrace, sap_head); 206} 207 208/* 209 * On hangup, let everyone know we're going away. 210 */ 211void 212hup() 213{ 214 register struct rthash *rh; 215 register struct rt_entry *rt; 216 register struct sap_hash *sh; 217 register struct sap_entry *sap; 218 219 if (supplier) { 220 for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) { 221 rt = rh->rt_forw; 222 for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) 223 rt->rt_metric = HOPCNT_INFINITY; 224 } 225 toall(supply, NULL, 0); 226 227 /* 228 * Now for SAP. 229 */ 230 for (sh = sap_head; sh < &sap_head[SAPHASHSIZ]; sh++) { 231 sap = sh->forw; 232 for (; sap != (struct sap_entry *)sh; sap = sap->forw) 233 sap->sap.hops = htons(HOPCNT_INFINITY); 234 } 235 if (dosap) 236 sap_supply_toall(0); 237 } 238 exit(1); 239} 240