|
|
1.1 ! root 1: #include "ch.h" ! 2: #include "chroute.h" ! 3: #if NCHROUTE > 0 ! 4: #include "../h/param.h" ! 5: #include "../h/systm.h" ! 6: #include "../h/chaos.h" ! 7: #include "../chaosld/types.h" ! 8: #include "../chaosld/constants.h" ! 9: #include "../chaosld/globals.h" ! 10: #include "../chaosld/chrouteld.h" ! 11: ! 12: /* ! 13: * Clock level processing. ! 14: * ch_rtimer should be called each clock tick (HZ per second) ! 15: * at a priority equal to or higher than LOCK. ! 16: * ! 17: * Terminology: ! 18: * Route aging: Increase the cost of transmitting over gateways so we ! 19: * will use another gateway if the current gateway goes ! 20: * down. ! 21: * Route broadcast: If we are connected to more than one subnet, broad ! 22: * cast our bridge status every BRIDGERATE seconds. ! 23: * ! 24: * These rates might want to vary with the cost of getting to the host. ! 25: * ! 26: * Since these rates are dependent on a run-time variable ! 27: * (This is a good idea if you think about it long enough), ! 28: * We might want to initialize specific variables at run-time to ! 29: * avoid recalculation if the profile of chclock is disturbing. ! 30: */ ! 31: #define MINRATE ROUTERATE /* Minimum of following rates */ ! 32: ! 33: #define ROUTERATE (hz<<2) /* Route aging rate */ ! 34: #define BRIDGERATE (hz*15) /* Routing broadcast rate */ ! 35: ! 36: extern int NChropen; ! 37: extern int Chrtimer; ! 38: extern struct chroute Chroute[]; ! 39: int Chnobridge; ! 40: chtime Chrclock; ! 41: ! 42: ! 43: ch_rtimer() ! 44: { ! 45: int aging; /* are we aging routing this time? */ ! 46: int sending; /* are we sending routing this time? */ ! 47: static chtime nextclock = 1; /* next time to do anything */ ! 48: static chtime nextroute = 1; /* next time to age routing */ ! 49: static chtime nextbridge = 1; /* next time to send routing */ ! 50: ! 51: Chrtimer = 1; ! 52: ++Chrclock; ! 53: if (cmp_lt(Chrclock, nextclock)) ! 54: goto leave; ! 55: if (cmp_gt(Chrclock, nextroute)) { ! 56: aging = 1; ! 57: nextroute += ROUTERATE; ! 58: } else ! 59: aging = 0; ! 60: if (cmp_gt(Chrclock, nextbridge)) { ! 61: sending = 1; ! 62: nextbridge += BRIDGERATE; ! 63: } else ! 64: sending = 0; ! 65: debug(DNOCLK,goto leave); ! 66: ! 67: if (aging) ! 68: chroutage(); ! 69: if (sending && !ch_busy) ! 70: chbridge(); ! 71: ! 72: leave: ! 73: if (NChropen == 0) ! 74: Chrtimer = 0; ! 75: else ! 76: timeout(ch_rtimer, (caddr_t)0, 1); ! 77: } ! 78: ! 79: ! 80: /* ! 81: * Increase the cost of accessing a subnet via a gateway ! 82: */ ! 83: chroutage() ! 84: { ! 85: register struct chroute *r; ! 86: ! 87: for (r = Chroute; r < &Chroute[CHNSUBNET]; r++) ! 88: if ((r->rt_type == CHBRIDGE || r->rt_type == CHDIRECT) && ! 89: r->rt_cost < HIGH_COST) ! 90: r->rt_cost++; ! 91: } ! 92: ! 93: ! 94: /* ! 95: * Send routing packets on all directly connected subnets, unless we are on ! 96: * only one. ! 97: */ ! 98: chbridge() ! 99: { ! 100: register struct chroute *r; ! 101: register struct packet *pkt; ! 102: register struct rut_data rd; ! 103: register int ndirect; ! 104: register int n; ! 105: ! 106: if (Chnobridge) ! 107: return; ! 108: /* ! 109: * Count the number of subnets to which we are directly connected. ! 110: * If not more than one, then we are not a bridge and shouldn't ! 111: * send out routing packets at all. ! 112: * While we're at it, count the number of subnets we know we ! 113: * have any access to. This number determines the size of the ! 114: * routine packet we need to send, if any. ! 115: */ ! 116: n = ndirect = 0; ! 117: for (r = Chroute; r < &Chroute[CHNSUBNET]; r++) ! 118: if (r->rt_cost < HIGH_COST) ! 119: switch(r->rt_type) { ! 120: case CHDIRECT: ! 121: ndirect++; ! 122: default: ! 123: n++; ! 124: break; ! 125: case CHNOPATH: ! 126: ; ! 127: } ! 128: if (ndirect <= 1 || (pkt = new_packet()) == NOPKT) ! 129: return; ! 130: /* ! 131: * Build the routing packet to send out on each directly connected ! 132: * subnet. It is complete except for the cost of the directly ! 133: * connected subnet we are sending it out on. This cost must be ! 134: * added to each entry in the packet each time it is sent. ! 135: */ ! 136: pkt->pk_op = RUTOP; ! 137: for (n = 0, r = Chroute; r < &Chroute[CHNSUBNET]; r++, n++) ! 138: if (r->rt_cost < HIGH_COST && r->rt_type != CHNOPATH) { ! 139: rd.rd_subnet = n; ! 140: rd.rd_cost = r->rt_cost; ! 141: append_packet(pkt, &rd, sizeof(rd)); ! 142: } ! 143: flatten(pkt); ! 144: /* ! 145: * Now send out this packet on each directly connected subnet. ! 146: * ndirect becomes zero on last such subnet. ! 147: */ ! 148: for (r = Chroute; r < &Chroute[CHNSUBNET]; r++) ! 149: if (r->rt_type == CHDIRECT && r->rt_cost < HIGH_COST) ! 150: sendrut(pkt, r->rt_path.ifp, r->rt_cost, --ndirect); ! 151: } ! 152: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.