summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cmd-inet/usr.lib/in.ripngd/timer.c
diff options
context:
space:
mode:
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.c181
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);
+}