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