xref: /original-bsd/sbin/routed/timer.c (revision 53787e02)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)timer.c	5.1 (Berkeley) 06/04/85";
9 #endif not lint
10 
11 /*
12  * Routing Table Management Daemon
13  */
14 #include "defs.h"
15 
16 int	timeval = -TIMER_RATE;
17 
18 /*
19  * Timer routine.  Performs routing information supply
20  * duties and manages timers on routing table entries.
21  */
22 timer()
23 {
24 	register struct rthash *rh;
25 	register struct rt_entry *rt;
26 	struct rthash *base = hosthash;
27 	int doinghost = 1, timetobroadcast;
28 
29 	timeval += TIMER_RATE;
30 	if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0)
31 		ifinit();
32 	timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0;
33 again:
34 	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
35 		rt = rh->rt_forw;
36 		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
37 			/*
38 			 * We don't advance time on a routing entry for
39 			 * a passive gateway or that for our only interface.
40 			 * The latter is excused because we don't act as
41 			 * a routing information supplier and hence would
42 			 * time it out.  This is fair as if it's down
43 			 * we're cut off from the world anyway and it's
44 			 * not likely we'll grow any new hardware in
45 			 * the mean time.
46 			 */
47 			if (!(rt->rt_state & RTS_PASSIVE) &&
48 			    (supplier || !(rt->rt_state & RTS_INTERFACE)))
49 				rt->rt_timer += TIMER_RATE;
50 			if (rt->rt_timer >= EXPIRE_TIME)
51 				rt->rt_metric = HOPCNT_INFINITY;
52 			if (rt->rt_timer >= GARBAGE_TIME) {
53 				rt = rt->rt_back;
54 				rtdelete(rt->rt_forw);
55 				continue;
56 			}
57 			if (rt->rt_state & RTS_CHANGED) {
58 				rt->rt_state &= ~RTS_CHANGED;
59 				/* don't send extraneous packets */
60 				if (!supplier || timetobroadcast)
61 					continue;
62 				msg->rip_cmd = RIPCMD_RESPONSE;
63 				msg->rip_vers = RIPVERSION;
64 				msg->rip_nets[0].rip_dst = rt->rt_dst;
65 				msg->rip_nets[0].rip_dst.sa_family =
66 				   htons(msg->rip_nets[0].rip_dst.sa_family);
67 				msg->rip_nets[0].rip_metric =
68 				   htonl(min(rt->rt_metric+1, HOPCNT_INFINITY));
69 				toall(sendmsg);
70 			}
71 		}
72 	}
73 	if (doinghost) {
74 		doinghost = 0;
75 		base = nethash;
76 		goto again;
77 	}
78 	if (timetobroadcast)
79 		toall(supply);
80 	alarm(TIMER_RATE);
81 }
82 
83 /*
84  * On hangup, let everyone know we're going away.
85  */
86 hup()
87 {
88 	register struct rthash *rh;
89 	register struct rt_entry *rt;
90 	struct rthash *base = hosthash;
91 	int doinghost = 1;
92 
93 	if (supplier) {
94 again:
95 		for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
96 			rt = rh->rt_forw;
97 			for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
98 				rt->rt_metric = HOPCNT_INFINITY;
99 		}
100 		if (doinghost) {
101 			doinghost = 0;
102 			base = nethash;
103 			goto again;
104 		}
105 		toall(supply);
106 	}
107 	exit(1);
108 }
109