timer.c revision 122760
131921Sbrian/* 285965Sbrian * Copyright (c) 1985, 1993 377690Sbrian * The Regents of the University of California. All rights reserved. 477690Sbrian * 531921Sbrian * Copyright (c) 1995 John Hay. All rights reserved. 677690Sbrian * 777690Sbrian * This file includes significant work done at Cornell University by 877690Sbrian * Bill Nesheim. That work included by permission. 977690Sbrian * 1077690Sbrian * Redistribution and use in source and binary forms, with or without 1177690Sbrian * modification, are permitted provided that the following conditions 1277690Sbrian * are met: 1377690Sbrian * 1. Redistributions of source code must retain the above copyright 1477690Sbrian * notice, this list of conditions and the following disclaimer. 1577690Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1677690Sbrian * notice, this list of conditions and the following disclaimer in the 1777690Sbrian * documentation and/or other materials provided with the distribution. 1877690Sbrian * 3. All advertising materials mentioning features or use of this software 1977690Sbrian * must display the following acknowledgement: 2077690Sbrian * This product includes software developed by the University of 2177690Sbrian * California, Berkeley and its contributors. 2277690Sbrian * 4. Neither the name of the University nor the names of its contributors 2377690Sbrian * may be used to endorse or promote products derived from this software 2477690Sbrian * without specific prior written permission. 2577690Sbrian * 2677690Sbrian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2750479Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2830715Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2926034Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3043313Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3126034Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3226034Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3330715Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3437191Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3537191Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3681634Sbrian * SUCH DAMAGE. 3737191Sbrian * 3826034Sbrian * $FreeBSD: head/usr.sbin/IPXrouted/timer.c 122760 2003-11-15 17:10:56Z trhodes $ 39102500Sbrian */ 4030715Sbrian 4130715Sbrian#ifndef lint 4230715Sbrianstatic const char sccsid[] = "@(#)timer.c 8.1 (Berkeley) 6/5/93"; 4336285Sbrian#endif /* not lint */ 4430715Sbrian 4558037Sbrian/* 4658037Sbrian * Routing Table Management Daemon 4758037Sbrian */ 4846086Sbrian#include "defs.h" 4939395Sbrian#include <unistd.h> 5058037Sbrian#include <stdlib.h> 5146686Sbrian 5246686Sbrianint timeval = -TIMER_RATE; 5337009Sbrian 5431343Sbrian/* 5530715Sbrian * Timer routine. Performs routing information supply 5651075Sbrian * duties and manages timers on routing and SAP table entries. 5736285Sbrian */ 5836285Sbrianvoid 5937191Sbriantimer() 6037191Sbrian{ 6137191Sbrian register struct rthash *rh; 6237191Sbrian register struct rt_entry *rt; 6337191Sbrian register struct sap_hash *sh; 6438557Sbrian register struct sap_entry *sap; 6537191Sbrian struct sap_hash *sap_base = sap_head; 6637191Sbrian int timetobroadcast, ripbroadcast, sapbroadcast; 6781634Sbrian 6881634Sbrian timeval += TIMER_RATE; 6938557Sbrian if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) 7081634Sbrian ifinit(); 7137191Sbrian timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0; 7237191Sbrian ripbroadcast = supplier && timetobroadcast && 7337191Sbrian (timeval % RIP_INTERVAL) == 0; 7437191Sbrian sapbroadcast = timetobroadcast && dosap && !ripbroadcast; 7537191Sbrian 7643313Sbrian for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) { 7743313Sbrian rt = rh->rt_forw; 7843313Sbrian for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { 7981634Sbrian if (rt->rt_clone) { 8037191Sbrian struct rt_entry *trt, *prt; 8126034Sbrian /* 8226034Sbrian * If a clone expire free it and mark the 8355353Sbrian * main route RTS_CHANGED. 8455353Sbrian */ 8531343Sbrian prt = rt; 8645042Sbrian trt = rt->rt_clone; 8745042Sbrian while (trt) { 8845042Sbrian trt->rt_timer += TIMER_RATE; 8926034Sbrian if (trt->rt_timer >= EXPIRE_TIME) { 90177100Spiso prt->rt_clone = trt->rt_clone; 91177100Spiso free((char *)trt); 9247860Sbrian trt = prt->rt_clone; 9347860Sbrian rt->rt_state |= RTS_CHANGED; 9447860Sbrian } else { 9547860Sbrian prt = trt; 9647860Sbrian trt = prt->rt_clone; 9726034Sbrian } 9847860Sbrian } 9947860Sbrian } 10047860Sbrian /* 10147860Sbrian * We don't advance time on a routing entry for 10247860Sbrian * a passive gateway or that for our only interface. 10347860Sbrian * The latter is excused because we don't act as 10426034Sbrian * a routing information supplier and hence would 10550059Sbrian * time it out. This is fair as if it's down 10626034Sbrian * we're cut off from the world anyway and it's 10750059Sbrian * not likely we'll grow any new hardware in 10836285Sbrian * the mean time. 10931756Sbrian */ 11047860Sbrian if (!(rt->rt_state & RTS_PASSIVE) && 11128679Sbrian !(rt->rt_state & RTS_INTERFACE)) 11231343Sbrian rt->rt_timer += TIMER_RATE; 11347860Sbrian if (rt->rt_timer >= EXPIRE_TIME) { 11447860Sbrian rt->rt_metric = HOPCNT_INFINITY; 11547860Sbrian rt->rt_state |= RTS_CHANGED; 11647860Sbrian } 11747860Sbrian if (rt->rt_timer >= GARBAGE_TIME) { 11847860Sbrian rt = rt->rt_back; 11947860Sbrian /* Perhaps we should send a REQUEST for this route? */ 12028679Sbrian rtdelete(rt->rt_forw); 12126034Sbrian continue; 12236285Sbrian } 12328679Sbrian if (rt->rt_state & RTS_CHANGED) { 12428679Sbrian rt->rt_state &= ~RTS_CHANGED; 12528679Sbrian /* don't send extraneous packets */ 12628679Sbrian if (!supplier || ripbroadcast) 12728679Sbrian continue; 12836285Sbrian if ((rt->rt_metric + 1) == HOPCNT_INFINITY) 12936285Sbrian continue; 13045042Sbrian msg->rip_cmd = htons(RIPCMD_RESPONSE); 13128679Sbrian msg->rip_nets[0].rip_dst = 13226034Sbrian (satoipx_addr(rt->rt_dst)).x_net; 13347860Sbrian msg->rip_nets[0].rip_metric = 13445042Sbrian htons(min(rt->rt_metric+1, HOPCNT_INFINITY)); 13528679Sbrian msg->rip_nets[0].rip_ticks = 13650059Sbrian htons(rt->rt_ticks + 1); 13745042Sbrian toall(sndmsg, rt, 0); 13828679Sbrian } 13947860Sbrian } 14045042Sbrian } 14145042Sbrian if (ripbroadcast) 14228679Sbrian toall(supply, NULL, 0); 14350059Sbrian 14445042Sbrian /* 14528679Sbrian * Now do the SAP stuff. 14647860Sbrian */ 14726034Sbrian for (sh = sap_base; sh < &sap_base[SAPHASHSIZ]; sh++) { 14847860Sbrian sap = sh->forw; 14947860Sbrian for (; sap != (struct sap_entry *)sh; sap = sap->forw) { 15047860Sbrian if (sap->clone) { 15147860Sbrian struct sap_entry *tsap, *psap; 15250059Sbrian /* 15347860Sbrian * If a clone expire free it and mark the 15447860Sbrian * main sap entry RTS_CHANGED. 15547860Sbrian */ 15647860Sbrian psap = sap; 15747860Sbrian tsap = sap->clone; 15847860Sbrian while (tsap) { 15945042Sbrian tsap->timer += TIMER_RATE; 16026034Sbrian if (tsap->timer >= EXPIRE_TIME) { 16147860Sbrian psap->clone = tsap->clone; 16247860Sbrian free((char *)tsap); 16347860Sbrian tsap = psap->clone; 16445042Sbrian sap->state |= RTS_CHANGED; 16545042Sbrian } else { 16650059Sbrian psap = tsap; 16747860Sbrian tsap = psap->clone; 16845042Sbrian } 16945042Sbrian } 17045042Sbrian } 17147860Sbrian sap->timer += TIMER_RATE; 17250059Sbrian if (sap->timer >= EXPIRE_TIME) { 17347860Sbrian sap->sap.hops = htons(HOPCNT_INFINITY); 17447860Sbrian sap->state |= RTS_CHANGED; 17547860Sbrian } 17647860Sbrian if (sap->timer >= GARBAGE_TIME) { 177195772Sbrian sap = sap->back; 178177100Spiso /* Perhaps we should send a REQUEST for this route? */ 17947860Sbrian sap_delete(sap->forw); 18047860Sbrian continue; 18145042Sbrian } 18245042Sbrian /* 18345042Sbrian * XXX sap_sndmsg on RTS_CHANGED 18450059Sbrian */ 18547860Sbrian if (sap->state & RTS_CHANGED) { 18645042Sbrian sap->state &= ~RTS_CHANGED; 18745042Sbrian#ifdef notyet 18847860Sbrian /* don't send extraneous packets */ 18947860Sbrian if (!supplier || sapbroadcast) 19047860Sbrian continue; 191195772Sbrian if ((ntohs(sap->sap.hops) + 1) == HOPCNT_INFINITY) 19226034Sbrian continue; 19347860Sbrian sap_msg->sap_cmd = htons(SAP_RESP); 19447860Sbrian sap_msg->sap[0] = sap->sap; 19547860Sbrian sap_msg->sap[0].hops = 19647860Sbrian htons(min(sap->sap.hops+1, HOPCNT_INFINITY)); 19726034Sbrian toall(sapsndmsg, rt, 0); 19826034Sbrian#endif 19926034Sbrian } 20026034Sbrian } 20150059Sbrian } 20226034Sbrian if (sapbroadcast) 20350059Sbrian sap_supply_toall(0); 20450059Sbrian if (ftrace && sapbroadcast) 20531756Sbrian dumpsaptable(ftrace, sap_head); 20636285Sbrian} 20728679Sbrian 20847860Sbrian/* 20928679Sbrian * On hangup, let everyone know we're going away. 21028679Sbrian */ 21147860Sbrianvoid 21228679Sbrianhup() 21336285Sbrian{ 21428679Sbrian register struct rthash *rh; 21528679Sbrian register struct rt_entry *rt; 21647860Sbrian register struct sap_hash *sh; 21728679Sbrian register struct sap_entry *sap; 21836285Sbrian 21995258Sdes if (supplier) { 22036285Sbrian for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) { 22128679Sbrian rt = rh->rt_forw; 22228679Sbrian for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) 223177100Spiso rt->rt_metric = HOPCNT_INFINITY; 22436285Sbrian } 22536285Sbrian toall(supply, NULL, 0); 22636285Sbrian 22795258Sdes /* 22836285Sbrian * Now for SAP. 22928679Sbrian */ 23031756Sbrian for (sh = sap_head; sh < &sap_head[SAPHASHSIZ]; sh++) { 23131756Sbrian sap = sh->forw; 23226034Sbrian for (; sap != (struct sap_entry *)sh; sap = sap->forw) 23331756Sbrian sap->sap.hops = htons(HOPCNT_INFINITY); 23426034Sbrian } 23526034Sbrian if (dosap) 23626034Sbrian sap_supply_toall(0); 23779433Sbrian } 23879433Sbrian exit(1); 23979433Sbrian} 24079433Sbrian