|
|
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.