diff options
Diffstat (limited to 'usr/src/cmd/cmd-inet/usr.lib/in.ripngd/timer.c')
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.lib/in.ripngd/timer.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.lib/in.ripngd/timer.c b/usr/src/cmd/cmd-inet/usr.lib/in.ripngd/timer.c new file mode 100644 index 0000000000..5339b56907 --- /dev/null +++ b/usr/src/cmd/cmd-inet/usr.lib/in.ripngd/timer.c @@ -0,0 +1,181 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +/* + * Portions of this source code were derived from Berkeley 4.3 BSD + * under license from the Regents of the University of California. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Routing Table Management Daemon + */ +#include "defs.h" + +int supplyinterval; /* current supply interval */ + +/* + * Timer routine. Performs routing information supply + * duties and manages timers on routing table entries. + * Management of the RTS_CHANGED bit assumes that we multicast + * each time called. + */ +void +timer(void) +{ + struct rthash *rh; + struct rt_entry *rt; + boolean_t timetomulticast = _B_FALSE; + int i; + static int iftime; /* interface timer */ + static int mtime; /* periodic mcast supply timer */ + static int alarmtime = 0; /* time elapsed since last call */ + int mintime; /* tracks when next timer will expire */ + + /* + * On the initial call to timer(), the various times that are kept track + * of need to be initialized. After initializing everything, "remember" + * (via a static) how long until the next timer expires. + */ + if (alarmtime == 0) { + supplyinterval = GET_RANDOM(MIN_SUPPLY_TIME, MAX_SUPPLY_TIME); + iftime = 0; + mtime = supplyinterval; + alarmtime = supplyinterval; + (void) alarm(alarmtime); + return; + } + + /* + * Initialize mintime to a suitable "large" value and then compare it to + * other times in the future to determine which event will occur next. + */ + mintime = INT_MAX; + (void) sighold(SIGHUP); + (void) sighold(SIGUSR1); + (void) sighold(SIGUSR2); + + iftime += alarmtime; + if (iftime >= CHECK_INTERVAL) { + initifs(); + iftime = 0; + } + mintime = min(mintime, CHECK_INTERVAL - iftime); + + mtime += alarmtime; + if (mtime >= supplyinterval) { + if (supplier) + timetomulticast = _B_TRUE; + mtime = 0; + supplyinterval = GET_RANDOM(MIN_SUPPLY_TIME, MAX_SUPPLY_TIME); + } + mintime = min(mintime, supplyinterval - mtime); + + for (i = IPV6_ABITS; i >= 0; i--) { + if (net_hashes[i] == NULL) + continue; + + for (rh = net_hashes[i]; + rh < &net_hashes[i][ROUTEHASHSIZ]; rh++) { + for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; + rt = rt->rt_forw) { + /* + * We don't advance time on a routing entry for + * an interface because we catch + * interfaces going up and down in initifs. + */ + rt->rt_state &= ~RTS_CHANGED; + if ((rt->rt_state & RTS_INTERFACE) != 0) + continue; + rt->rt_timer += alarmtime; + if (rt->rt_timer >= GARBAGE_TIME) { + rt = rt->rt_back; + rtdelete(rt->rt_forw); + continue; + } + if (rt->rt_timer >= EXPIRE_TIME) { + rtdown(rt); + mintime = min(mintime, + GARBAGE_TIME - rt->rt_timer); + } else { + mintime = min(mintime, + EXPIRE_TIME - rt->rt_timer); + } + } + } + } + + if (timetomulticast) { + supplyall(&allrouters, 0, (struct interface *)NULL, _B_TRUE); + (void) gettimeofday(&now, (struct timezone *)NULL); + lastmcast = now; + lastfullupdate = now; + needupdate = _B_FALSE; /* cancel any pending dynamic update */ + nextmcast.tv_sec = 0; + } + (void) sigrelse(SIGUSR2); + (void) sigrelse(SIGUSR1); + (void) sigrelse(SIGHUP); + + /* + * "Remember" (via a static) how long until the next timer expires. + */ + alarmtime = mintime; + (void) alarm(alarmtime); +} + +/* + * On SIGTERM, let everyone know we're going away. + */ +void +term(void) +{ + struct rthash *rh; + struct rt_entry *rt; + int i; + + if (!supplier) + exit(EXIT_SUCCESS); + for (i = IPV6_ABITS; i >= 0; i--) { + if (net_hashes[i] == NULL) + continue; + + for (rh = net_hashes[i]; rh < &net_hashes[i][ROUTEHASHSIZ]; + rh++) { + for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; + rt = rt->rt_forw) { + rt->rt_metric = HOPCNT_INFINITY; + } + } + } + supplyall(&allrouters, 0, (struct interface *)NULL, _B_TRUE); + (void) unlink(PATH_PID); + exit(EXIT_SUCCESS); +} |