1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Portions of this source code were derived from Berkeley 4.3 BSD 32 * under license from the Regents of the University of California. 33 */ 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 /* 38 * Routing Table Management Daemon 39 */ 40 #include "defs.h" 41 42 int supplyinterval; /* current supply interval */ 43 44 /* 45 * Timer routine. Performs routing information supply 46 * duties and manages timers on routing table entries. 47 * Management of the RTS_CHANGED bit assumes that we multicast 48 * each time called. 49 */ 50 void 51 timer(void) 52 { 53 struct rthash *rh; 54 struct rt_entry *rt; 55 boolean_t timetomulticast = _B_FALSE; 56 int i; 57 static int iftime; /* interface timer */ 58 static int mtime; /* periodic mcast supply timer */ 59 static int alarmtime = 0; /* time elapsed since last call */ 60 int mintime; /* tracks when next timer will expire */ 61 62 /* 63 * On the initial call to timer(), the various times that are kept track 64 * of need to be initialized. After initializing everything, "remember" 65 * (via a static) how long until the next timer expires. 66 */ 67 if (alarmtime == 0) { 68 supplyinterval = GET_RANDOM(MIN_SUPPLY_TIME, MAX_SUPPLY_TIME); 69 iftime = 0; 70 mtime = supplyinterval; 71 alarmtime = supplyinterval; 72 (void) alarm(alarmtime); 73 return; 74 } 75 76 /* 77 * Initialize mintime to a suitable "large" value and then compare it to 78 * other times in the future to determine which event will occur next. 79 */ 80 mintime = INT_MAX; 81 (void) sighold(SIGHUP); 82 (void) sighold(SIGUSR1); 83 (void) sighold(SIGUSR2); 84 85 iftime += alarmtime; 86 if (iftime >= CHECK_INTERVAL) { 87 initifs(); 88 iftime = 0; 89 } 90 mintime = min(mintime, CHECK_INTERVAL - iftime); 91 92 mtime += alarmtime; 93 if (mtime >= supplyinterval) { 94 if (supplier) 95 timetomulticast = _B_TRUE; 96 mtime = 0; 97 supplyinterval = GET_RANDOM(MIN_SUPPLY_TIME, MAX_SUPPLY_TIME); 98 } 99 mintime = min(mintime, supplyinterval - mtime); 100 101 for (i = IPV6_ABITS; i >= 0; i--) { 102 if (net_hashes[i] == NULL) 103 continue; 104 105 for (rh = net_hashes[i]; 106 rh < &net_hashes[i][ROUTEHASHSIZ]; rh++) { 107 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; 108 rt = rt->rt_forw) { 109 /* 110 * We don't advance time on a routing entry for 111 * an interface because we catch 112 * interfaces going up and down in initifs. 113 */ 114 rt->rt_state &= ~RTS_CHANGED; 115 if ((rt->rt_state & RTS_INTERFACE) != 0) 116 continue; 117 rt->rt_timer += alarmtime; 118 if (rt->rt_timer >= GARBAGE_TIME) { 119 rt = rt->rt_back; 120 rtdelete(rt->rt_forw); 121 continue; 122 } 123 if (rt->rt_timer >= EXPIRE_TIME) { 124 rtdown(rt); 125 mintime = min(mintime, 126 GARBAGE_TIME - rt->rt_timer); 127 } else { 128 mintime = min(mintime, 129 EXPIRE_TIME - rt->rt_timer); 130 } 131 } 132 } 133 } 134 135 if (timetomulticast) { 136 supplyall(&allrouters, 0, (struct interface *)NULL, _B_TRUE); 137 (void) gettimeofday(&now, (struct timezone *)NULL); 138 lastmcast = now; 139 lastfullupdate = now; 140 needupdate = _B_FALSE; /* cancel any pending dynamic update */ 141 nextmcast.tv_sec = 0; 142 } 143 (void) sigrelse(SIGUSR2); 144 (void) sigrelse(SIGUSR1); 145 (void) sigrelse(SIGHUP); 146 147 /* 148 * "Remember" (via a static) how long until the next timer expires. 149 */ 150 alarmtime = mintime; 151 (void) alarm(alarmtime); 152 } 153 154 /* 155 * On SIGTERM, let everyone know we're going away. 156 */ 157 void 158 term(void) 159 { 160 struct rthash *rh; 161 struct rt_entry *rt; 162 int i; 163 164 if (!supplier) 165 exit(EXIT_SUCCESS); 166 for (i = IPV6_ABITS; i >= 0; i--) { 167 if (net_hashes[i] == NULL) 168 continue; 169 170 for (rh = net_hashes[i]; rh < &net_hashes[i][ROUTEHASHSIZ]; 171 rh++) { 172 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; 173 rt = rt->rt_forw) { 174 rt->rt_metric = HOPCNT_INFINITY; 175 } 176 } 177 } 178 supplyall(&allrouters, 0, (struct interface *)NULL, _B_TRUE); 179 (void) unlink(PATH_PID); 180 exit(EXIT_SUCCESS); 181 } 182