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 /* 36 * Routing Table Management Daemon 37 */ 38 #include "defs.h" 39 40 int supplyinterval; /* current supply interval */ 41 42 /* 43 * Timer routine. Performs routing information supply 44 * duties and manages timers on routing table entries. 45 * Management of the RTS_CHANGED bit assumes that we multicast 46 * each time called. 47 */ 48 void 49 timer(void) 50 { 51 struct rthash *rh; 52 struct rt_entry *rt; 53 boolean_t timetomulticast = _B_FALSE; 54 int i; 55 static int iftime; /* interface timer */ 56 static int mtime; /* periodic mcast supply timer */ 57 static int alarmtime = 0; /* time elapsed since last call */ 58 int mintime; /* tracks when next timer will expire */ 59 60 /* 61 * On the initial call to timer(), the various times that are kept track 62 * of need to be initialized. After initializing everything, "remember" 63 * (via a static) how long until the next timer expires. 64 */ 65 if (alarmtime == 0) { 66 supplyinterval = GET_RANDOM(MIN_SUPPLY_TIME, MAX_SUPPLY_TIME); 67 iftime = 0; 68 mtime = supplyinterval; 69 alarmtime = supplyinterval; 70 (void) alarm(alarmtime); 71 return; 72 } 73 74 /* 75 * Initialize mintime to a suitable "large" value and then compare it to 76 * other times in the future to determine which event will occur next. 77 */ 78 mintime = INT_MAX; 79 (void) sighold(SIGHUP); 80 (void) sighold(SIGUSR1); 81 (void) sighold(SIGUSR2); 82 83 iftime += alarmtime; 84 if (iftime >= CHECK_INTERVAL) { 85 initifs(); 86 iftime = 0; 87 } 88 mintime = min(mintime, CHECK_INTERVAL - iftime); 89 90 mtime += alarmtime; 91 if (mtime >= supplyinterval) { 92 if (supplier) 93 timetomulticast = _B_TRUE; 94 mtime = 0; 95 supplyinterval = GET_RANDOM(MIN_SUPPLY_TIME, MAX_SUPPLY_TIME); 96 } 97 mintime = min(mintime, supplyinterval - mtime); 98 99 for (i = IPV6_ABITS; i >= 0; i--) { 100 if (net_hashes[i] == NULL) 101 continue; 102 103 for (rh = net_hashes[i]; 104 rh < &net_hashes[i][ROUTEHASHSIZ]; rh++) { 105 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; 106 rt = rt->rt_forw) { 107 /* 108 * We don't advance time on a routing entry for 109 * an interface because we catch 110 * interfaces going up and down in initifs. 111 */ 112 rt->rt_state &= ~RTS_CHANGED; 113 if ((rt->rt_state & RTS_INTERFACE) != 0) 114 continue; 115 rt->rt_timer += alarmtime; 116 if (rt->rt_timer >= GARBAGE_TIME) { 117 rt = rt->rt_back; 118 rtdelete(rt->rt_forw); 119 continue; 120 } 121 if (rt->rt_timer >= EXPIRE_TIME) { 122 rtdown(rt); 123 mintime = min(mintime, 124 GARBAGE_TIME - rt->rt_timer); 125 } else { 126 mintime = min(mintime, 127 EXPIRE_TIME - rt->rt_timer); 128 } 129 } 130 } 131 } 132 133 if (timetomulticast) { 134 supplyall(&allrouters, 0, (struct interface *)NULL, _B_TRUE); 135 (void) gettimeofday(&now, (struct timezone *)NULL); 136 lastmcast = now; 137 lastfullupdate = now; 138 needupdate = _B_FALSE; /* cancel any pending dynamic update */ 139 nextmcast.tv_sec = 0; 140 } 141 (void) sigrelse(SIGUSR2); 142 (void) sigrelse(SIGUSR1); 143 (void) sigrelse(SIGHUP); 144 145 /* 146 * "Remember" (via a static) how long until the next timer expires. 147 */ 148 alarmtime = mintime; 149 (void) alarm(alarmtime); 150 } 151 152 /* 153 * On SIGTERM, let everyone know we're going away. 154 */ 155 void 156 term(void) 157 { 158 struct rthash *rh; 159 struct rt_entry *rt; 160 int i; 161 162 if (!supplier) 163 exit(EXIT_SUCCESS); 164 for (i = IPV6_ABITS; i >= 0; i--) { 165 if (net_hashes[i] == NULL) 166 continue; 167 168 for (rh = net_hashes[i]; rh < &net_hashes[i][ROUTEHASHSIZ]; 169 rh++) { 170 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; 171 rt = rt->rt_forw) { 172 rt->rt_metric = HOPCNT_INFINITY; 173 } 174 } 175 } 176 supplyall(&allrouters, 0, (struct interface *)NULL, _B_TRUE); 177 (void) unlink(PATH_PID); 178 exit(EXIT_SUCCESS); 179 } 180