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