|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1996 Apple Computer, Inc.
24: *
25: * Created April 8, 1996 by Tuyen Nguyen
26: * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
27: *
28: * File: ri.c
29: */
30: #include <sys/errno.h>
31: #include <sys/types.h>
32: #include <sys/param.h>
33: #include <machine/spl.h>
34: #include <sys/systm.h>
35: #include <sys/kernel.h>
36: #include <sys/proc.h>
37: #include <sys/filedesc.h>
38: #include <sys/fcntl.h>
39: #include <sys/mbuf.h>
40: #include <sys/socket.h>
41: #include <sys/socketvar.h>
42: #include <net/if.h>
43:
44: #include <netat/sysglue.h>
45: #include <netat/appletalk.h>
46: #include <netat/at_var.h>
47: #include <netat/rtmp.h>
48: #include <netat/routing_tables.h>
49: #include <netat/at_pcb.h>
50: #include <netat/aurp.h>
51: #include <netat/debug.h>
52:
53: /* */
54: void AURPsndRIAck(state, m, flags)
55: aurp_state_t *state;
56: gbuf_t *m;
57: unsigned short flags;
58: {
59: unsigned short sequence_number;
60: aurp_hdr_t *hdrp;
61: int msize = sizeof(aurp_hdr_t);
62:
63: if (m) {
64: sequence_number = ((aurp_hdr_t *)gbuf_rptr(m))->sequence_number;
65: gbuf_wset(m,sizeof(aurp_hdr_t));
66: } else {
67: sequence_number = state->rcv_sequence_number;
68: if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) == 0)
69: return;
70: gbuf_wset(m,msize);
71: }
72:
73: /* construct the RI Ack packet */
74: hdrp = (aurp_hdr_t *)gbuf_rptr(m);
75: hdrp->connection_id = state->rcv_connection_id;
76: hdrp->sequence_number = sequence_number;
77: hdrp->command_code = AURPCMD_RIAck;
78: hdrp->flags = flags;
79:
80: /* send the packet */
81: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIAck: node=%d\n",
82: state->rem_node));
83: AURPsend(m, AUD_AURP, state->rem_node);
84: }
85:
86: /* */
87: void AURPsndRIReq(state)
88: aurp_state_t *state;
89: {
90: int msize;
91: gbuf_t *m;
92: aurp_hdr_t *hdrp;
93:
94: if (state->rcv_state == AURPSTATE_Unconnected)
95: return;
96: if (state->rcv_tmo && (state->rcv_state != AURPSTATE_WaitingForRIRsp))
97: return;
98:
99: msize = sizeof(aurp_hdr_t);
100: if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) != 0) {
101: gbuf_wset(m,msize);
102:
103: /* construct the RI request packet */
104: hdrp = (aurp_hdr_t *)gbuf_rptr(m);
105: hdrp->connection_id = state->rcv_connection_id;
106: hdrp->sequence_number = 0;
107: hdrp->command_code = AURPCMD_RIReq;
108: hdrp->flags = 0;
109:
110: /* update state info */
111: state->rcv_state = AURPSTATE_WaitingForRIRsp;
112:
113: /* send the packet */
114: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIReq: node=%d\n",
115: state->rem_node));
116: AURPsend(m, AUD_AURP, state->rem_node);
117: }
118:
119: /* start the retry timer */
120: timeout(AURPsndRIReq, state, AURP_RetryInterval*HZ);
121: state->rcv_tmo = 1;
122: }
123:
124: /* */
125: void AURPsndRIRsp(state)
126: aurp_state_t *state;
127: {
128: gbuf_t *m;
129: aurp_hdr_t *hdrp;
130: short len = 0;
131: int s, msize = 0;
132:
133: ATDISABLE(s, aurpgen_lock);
134:
135: /* make sure we're in a valid state to send RI response */
136: if ((state->snd_state == AURPSTATE_Unconnected) ||
137: (state->snd_state == AURPSTATE_WaitingForRIAck2)) {
138: ATENABLE(s, aurpgen_lock);
139: return;
140: }
141:
142: /* update state info */
143: state->snd_state = AURPSTATE_WaitingForRIAck1;
144:
145: if (state->rsp_m == 0) {
146: ATENABLE(s, aurpgen_lock);
147: msize = sizeof(aurp_hdr_t);
148: if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
149: timeout(AURPsndRIRsp, state, AURP_RetryInterval*HZ);
150: state->snd_tmo = 1;
151: return;
152: }
153: gbuf_wset(m,msize);
154: state->rsp_m = m;
155:
156: /* construct the RI response packet */
157: hdrp = (aurp_hdr_t *)gbuf_rptr(m);
158: hdrp->connection_id = state->snd_connection_id;
159: hdrp->sequence_number = state->snd_sequence_number;
160: hdrp->command_code = AURPCMD_RIRsp;
161: hdrp->flags = 0;
162:
163: /* get routing info of the local networks */
164: state->snd_next_entry = AURPgetri(
165: state->snd_next_entry, gbuf_wptr(m), &len);
166: gbuf_winc(m,len);
167:
168: /* set the last flag if this is the last response packet */
169: if (!state->snd_next_entry)
170: hdrp->flags = AURPFLG_LAST;
171: }
172:
173: /* keep a copy of the packet for retry */
174: m = (gbuf_t *)gbuf_dupb(state->rsp_m);
175:
176: /* start the retry timer */
177: timeout(AURPsndRIRsp, state, AURP_RetryInterval*HZ);
178: state->snd_tmo = 1;
179:
180: if (msize == 0)
181: ATENABLE(s, aurpgen_lock);
182:
183: /* send the packet */
184: if (m) {
185: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIRsp: len=%d\n", len));
186: AURPsend(m, AUD_AURP, state->rem_node);
187: }
188: }
189:
190: /* */
191: void AURPsndRIUpd(state)
192: aurp_state_t *state;
193: {
194: gbuf_t *m;
195: aurp_hdr_t *hdrp;
196: short len = 0;
197: int s, msize = 0;
198:
199: ATDISABLE(s, aurpgen_lock);
200:
201: /* make sure we're in a valid state to send update */
202: if (state->snd_next_entry || (state->upd_m == 0) ||
203: (state->snd_state == AURPSTATE_Unconnected) ||
204: (state->snd_state == AURPSTATE_WaitingForRIAck1)) {
205: ATENABLE(s, aurpgen_lock);
206: return;
207: }
208:
209: /* update state info */
210: state->snd_state = AURPSTATE_WaitingForRIAck2;
211:
212: if (state->snd_tmo == 0) {
213: ATENABLE(s, aurpgen_lock);
214: msize = sizeof(aurp_hdr_t);
215: m = state->upd_m;
216: len = gbuf_len(m);
217: gbuf_rdec(m,msize);
218:
219: /* construct the RI update packet */
220: hdrp = (aurp_hdr_t *)gbuf_rptr(m);
221: hdrp->connection_id = state->snd_connection_id;
222: hdrp->sequence_number = state->snd_sequence_number;
223: hdrp->command_code = AURPCMD_RIUpd;
224: hdrp->flags = 0;
225: }
226:
227: /* keep a copy of the packet for retry */
228: m = (gbuf_t *)gbuf_dupb(state->upd_m);
229:
230: /* start the retry timer */
231: timeout(AURPsndRIUpd, state, AURP_RetryInterval*HZ);
232: state->snd_tmo = 1;
233:
234: if (msize == 0)
235: ATENABLE(s, aurpgen_lock);
236:
237: /* send the packet */
238: if (m) {
239: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIUpd: len=%d\n", len));
240: AURPsend(m, AUD_AURP, state->rem_node);
241: }
242: }
243:
244: /* */
245: void AURPrcvRIReq(state, m)
246: aurp_state_t *state;
247: gbuf_t *m;
248: {
249: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
250: int s;
251:
252: ATDISABLE(s, aurpgen_lock);
253:
254: /* make sure we're in a valid state to accept it */
255: if ((state->snd_state == AURPSTATE_Unconnected) ||
256: (state->snd_state == AURPSTATE_WaitingForRIAck2)) {
257: ATENABLE(s, aurpgen_lock);
258: dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvRIReq: unexpected request\n"));
259: gbuf_freem(m);
260: return;
261: }
262:
263: /* check for the correct connection id */
264: if (hdrp->connection_id != state->snd_connection_id) {
265: ATENABLE(s, aurpgen_lock);
266: dPrintf(D_M_AURP, D_L_WARNING,
267: ("AURPrcvRIReq: invalid connection id, r=%d, m=%d\n",
268: hdrp->connection_id, state->snd_connection_id));
269: gbuf_freem(m);
270: return;
271: }
272:
273: if (state->snd_state != AURPSTATE_WaitingForRIAck1) {
274: state->snd_next_entry = 0;
275: if (state->rsp_m) {
276: gbuf_freem(state->rsp_m);
277: state->rsp_m = 0;
278: }
279: ATENABLE(s, aurpgen_lock);
280: AURPsndRIRsp(state);
281: } else
282: ATENABLE(s, aurpgen_lock);
283:
284: gbuf_freem(m);
285: }
286:
287: /* */
288: void AURPrcvRIRsp(state, m)
289: aurp_state_t *state;
290: gbuf_t *m;
291: {
292: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
293: int s;
294:
295: ATDISABLE(s, aurpgen_lock);
296:
297: /* make sure we're in a valid state to accept it */
298: if (state->rcv_state != AURPSTATE_WaitingForRIRsp) {
299: ATENABLE(s, aurpgen_lock);
300: dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvRIRsp: unexpected response\n"));
301: gbuf_freem(m);
302: return;
303: }
304:
305: /* check for the correct connection id */
306: if (hdrp->connection_id != state->rcv_connection_id) {
307: ATENABLE(s, aurpgen_lock);
308: dPrintf(D_M_AURP, D_L_WARNING,
309: ("AURPrcvRIRsp: invalid connection id, r=%d, m=%d\n",
310: hdrp->connection_id, state->rcv_connection_id));
311: gbuf_freem(m);
312: return;
313: }
314:
315: /* check for the correct sequence number */
316: if (hdrp->sequence_number != state->rcv_sequence_number) {
317: ATENABLE(s, aurpgen_lock);
318: if ( ((state->rcv_sequence_number == AURP_FirstSeqNum) &&
319: (hdrp->sequence_number == AURP_LastSeqNum)) ||
320: (hdrp->sequence_number == (state->rcv_sequence_number-1)) ) {
321: AURPsndRIAck(state, m, AURPFLG_SZI);
322: } else {
323: dPrintf(D_M_AURP, D_L_WARNING,
324: ("AURPrcvRIRsp: invalid sequence number, r=%d, m=%d\n",
325: hdrp->sequence_number, state->rcv_sequence_number));
326: gbuf_freem(m);
327: }
328: return;
329: }
330: gbuf_rinc(m,sizeof(*hdrp));
331: if (hdrp->flags & AURPFLG_LAST)
332: state->rcv_state = AURPSTATE_Connected;
333: ATENABLE(s, aurpgen_lock);
334:
335: dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIRsp: len=%ld\n", gbuf_len(m)));
336:
337: /* cancel the retry timer */
338: untimeout(AURPsndRIReq, state);
339: state->rcv_tmo = 0;
340:
341: /* send RI ack */
342: AURPsndRIAck(state, 0, AURPFLG_SZI);
343:
344: /* update state info */
345: if (++state->rcv_sequence_number == 0)
346: state->rcv_sequence_number = AURP_FirstSeqNum;
347:
348: /* process routing info of the tunnel peer */
349: if (AURPsetri(state->rem_node, m)) {
350: dPrintf(D_M_AURP, D_L_ERROR, ("AURPrcvRIRsp: AURPsetri() error\n"));
351: }
352: gbuf_freem(m);
353:
354: /* set the get zone flag to get zone info later if required */
355: if (state->rcv_state == AURPSTATE_Connected)
356: state->get_zi = 1;
357: }
358:
359: /* */
360: void AURPrcvRIUpd(state, m)
361: aurp_state_t *state;
362: gbuf_t *m;
363: {
364: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
365:
366: /* make sure we're in a valid state to accept it */
367: if (state->rcv_state == AURPSTATE_Unconnected) {
368: dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvRIUpd: unexpected response\n"));
369: gbuf_freem(m);
370: return;
371: }
372:
373: /* check for the correct connection id */
374: if (hdrp->connection_id != state->rcv_connection_id) {
375: dPrintf(D_M_AURP, D_L_WARNING,
376: ("AURPrcvRIUpd: invalid connection id, r=%d, m=%d\n",
377: hdrp->connection_id, state->rcv_connection_id));
378: gbuf_freem(m);
379: return;
380: }
381:
382: /* check for the correct sequence number */
383: if (hdrp->sequence_number != state->rcv_sequence_number) {
384: if ( ((state->rcv_sequence_number == AURP_FirstSeqNum) &&
385: (hdrp->sequence_number == AURP_LastSeqNum)) ||
386: (hdrp->sequence_number == (state->rcv_sequence_number-1)) ) {
387: AURPsndRIAck(state, m, AURPFLG_SZI);
388: } else {
389: dPrintf(D_M_AURP, D_L_WARNING,
390: ("AURPrcvRIUpd: invalid sequence number, r=%d, m=%d\n",
391: hdrp->sequence_number, state->rcv_sequence_number));
392: gbuf_freem(m);
393: }
394: return;
395: }
396: gbuf_rinc(m,sizeof(*hdrp));
397:
398: dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIUpd: len=%ld\n", gbuf_len(m)));
399:
400: /* send RI ack */
401: AURPsndRIAck(state, 0, AURPFLG_SZI);
402:
403: /* update state info */
404: if (++state->rcv_sequence_number == 0)
405: state->rcv_sequence_number = AURP_FirstSeqNum;
406:
407: /* process update routing info of the tunnel peer */
408: if (AURPupdateri(state->rem_node, m)) {
409: dPrintf(D_M_AURP, D_L_ERROR, ("AURPrcvRIUpd: AURPupdateri() error\n"));
410: }
411:
412: /* set the get zone flag to get zone info later if required */
413: state->get_zi = 1;
414:
415: gbuf_freem(m);
416: }
417:
418: /* */
419: void AURPrcvRIAck(state, m)
420: aurp_state_t *state;
421: gbuf_t *m;
422: {
423: gbuf_t *dat_m;
424: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
425: unsigned char snd_state;
426: int s;
427: int flag;
428:
429: dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIAck: state=%d\n",
430: state->snd_state));
431: ATDISABLE(s, aurpgen_lock);
432:
433: /* make sure we're in a valid state to accept it */
434: snd_state = state->snd_state;
435: if (((snd_state == AURPSTATE_WaitingForRIAck1) ||
436: (snd_state == AURPSTATE_WaitingForRIAck2)) &&
437: (hdrp->sequence_number == state->snd_sequence_number)) {
438:
439: if (snd_state == AURPSTATE_WaitingForRIAck1) {
440: /* ack from the tunnel peer to our RI response */
441: untimeout(AURPsndRIRsp, state);
442: dat_m = state->rsp_m;
443: state->rsp_m = 0;
444: flag = 1;
445: } else {
446: /* ack from the tunnel peer to our RI update */
447: untimeout(AURPsndRIUpd, state);
448: dat_m = state->upd_m;
449: state->upd_m = 0;
450: flag = 2;
451: }
452: state->snd_tmo = 0;
453: gbuf_rinc(dat_m,sizeof(aurp_hdr_t));
454:
455: /* increment the sequence number */
456: if (++state->snd_sequence_number == 0)
457: state->snd_sequence_number = AURP_FirstSeqNum;
458:
459: /* update state info */
460: state->snd_state = AURPSTATE_Connected;
461: ATENABLE(s, aurpgen_lock);
462:
463: if (state->snd_next_entry) /* more RI responses to send? */
464: AURPsndRIRsp(state);
465:
466: /* check to see if we need to send ZI responses */
467: if (hdrp->flags & AURPFLG_SZI)
468: AURPsndZRsp(state, dat_m, flag);
469: else if (dat_m)
470: gbuf_freem(dat_m);
471: } else
472: ATENABLE(s, aurpgen_lock);
473:
474: gbuf_freem(m);
475: }
476:
477: /* */
478: int AURPgetri(next_entry, buf, len)
479: short next_entry;
480: unsigned char *buf;
481: short *len;
482: {
483: short entry_num = next_entry;
484: RT_entry *entry = (RT_entry *)&RT_table[next_entry];
485:
486: for (*len=0; entry_num < RT_maxentry; entry_num++,entry++) {
487: if ((net_port != entry->NetPort) &&
488: !(entry->AURPFlag & AURP_NetHiden)) {
489: if ((entry->EntryState & 0x0F) >= RTE_STATE_SUSPECT) {
490: if (entry->NetStart) {
491: /* route info for extended network */
492: *(short *)buf = entry->NetStart;
493: buf += sizeof(short);
494: *buf++ = 0x80 | (entry->NetDist & 0x1F);
495: *(short *)buf = entry->NetStop;
496: buf += sizeof(short);
497: *buf++ = 0;
498: *len += 6;
499: } else {
500: /* route info for non-extended network */
501: *(short *)buf = entry->NetStop;
502: buf += sizeof(short);
503: *buf++ = (entry->NetDist & 0x1F);
504: *len += 3;
505: }
506: }
507: }
508: if (*len > AURP_MaxPktSize)
509: break;
510: }
511:
512: return (entry_num == RT_maxentry) ? 0 : entry_num;
513: }
514:
515: /* */
516: int AURPsetri(node, m)
517: unsigned char node;
518: gbuf_t *m;
519: {
520: int tuples_cnt;
521: unsigned char *tuples_ptr;
522: RT_entry new_rt, *curr_rt;
523:
524: new_rt.NextIRNet = 0;
525: new_rt.NextIRNode = node;
526: new_rt.NetPort = net_port;
527:
528: /*
529: * Process all the tuples against our routing table
530: */
531: tuples_ptr = (char *)gbuf_rptr(m);
532: tuples_cnt = (gbuf_len(m))/3;
533:
534: while (tuples_cnt--) {
535: new_rt.NetDist = TUPLEDIST(tuples_ptr) + 1;
536: new_rt.EntryState = RTE_STATE_GOOD;
537: new_rt.NetStart = TUPLENET(tuples_ptr);
538: tuples_ptr += 3;
539: if (tuples_ptr[-1] & 0x80) {
540: new_rt.NetStop = TUPLENET((tuples_ptr));
541: tuples_ptr += 3;
542: tuples_cnt--;
543: } else {
544: new_rt.NetStop = new_rt.NetStart;
545: new_rt.NetStart = 0;
546: }
547: if ((new_rt.NetStop == 0) || (new_rt.NetStop < new_rt.NetStart)) {
548: dPrintf(D_M_AURP, D_L_WARNING,
549: ("AURPsetri: %d, invalid tuple received [%d-%d]\n",
550: net_port, new_rt.NetStart, new_rt.NetStop));
551: continue;
552: }
553:
554: if ((curr_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
555: /* ignore loop if present */
556: if (curr_rt->NetPort != net_port)
557: continue;
558:
559: if (new_rt.NetDist < 16) {
560: /*
561: * check if the definition of the route has changed
562: */
563: if ((new_rt.NetStop != curr_rt->NetStop) ||
564: (new_rt.NetStart != curr_rt->NetStart)) {
565: if ((new_rt.NetStop == curr_rt->NetStop) &&
566: (new_rt.NetStop == curr_rt->NetStart) &&
567: (new_rt.NetStart == 0)) {
568: new_rt.NetStart = new_rt.NetStop;
569: } else if ((new_rt.NetStop == curr_rt->NetStop) &&
570: (new_rt.NetStart == new_rt.NetStop) &&
571: (curr_rt->NetStart == 0)) {
572: dPrintf(D_M_AURP, D_L_WARNING,
573: ("AURPsetri: [%d-%d] has changed to [%d-%d], Dist=%d\n",
574: curr_rt->NetStart, curr_rt->NetStop,
575: new_rt.NetStart, new_rt.NetStop, new_rt.NetDist));
576: new_rt.NetStart = 0;
577: } else {
578: dPrintf(D_M_AURP, D_L_WARNING,
579: ("AURPsetri: Net Conflict, Curr=[%d-%d], New=[%d-%d]\n",
580: curr_rt->NetStart,curr_rt->NetStop,
581: new_rt.NetStart,new_rt.NetStop));
582: zt_remove_zones(curr_rt->ZoneBitMap);
583: rt_delete(curr_rt->NetStop, curr_rt->NetStart);
584: continue;
585: }
586: }
587: }
588:
589: if ((new_rt.NetDist <= curr_rt->NetDist) &&
590: (new_rt.NetDist < 16)) {
591: /*
592: * found a shorter or more recent route,
593: * replace with the new entry
594: */
595: curr_rt->NetDist = new_rt.NetDist;
596: curr_rt->NextIRNode = new_rt.NextIRNode;
597: dPrintf(D_M_AURP_LOW,D_L_INFO,
598: ("AURPsetri: shorter route found [%d-%d], update\n",
599: new_rt.NetStart,new_rt.NetStop));
600: }
601:
602: } else { /* no entry found */
603: if (new_rt.NetDist < 16) {
604: new_rt.EntryState = RTE_STATE_GOOD;
605: dPrintf(D_M_AURP, D_L_INFO,
606: ("AURPsetri: new_rt [%d-%d], tuple #%d\n",
607: new_rt.NetStart, new_rt.NetStop, tuples_cnt));
608: if (rt_insert(new_rt.NetStop, new_rt.NetStart,
609: new_rt.NextIRNet, new_rt.NextIRNode,
610: new_rt.NetDist, new_rt.NetPort,
611: new_rt.EntryState) == (RT_entry *)0) {
612: dPrintf(D_M_AURP,D_L_ERROR,
613: ("AURPsetri: RTMP table full [%d-%d]\n",
614: new_rt.NetStart,new_rt.NetStop));
615: return -1;
616: }
617: }
618: }
619: } /* end of main while */
620:
621: return 0;
622: }
623:
624: /* */
625: int AURPupdateri(node, m)
626: unsigned char node;
627: gbuf_t *m;
628: {
629: char ev, ev_len;
630: RT_entry new_rt, *old_rt;
631:
632: while (gbuf_len(m) > 0) {
633: ev = *gbuf_rptr(m); /* event code */
634: gbuf_rinc(m,1);
635: if (gbuf_rptr(m)[2] & 0x80) {
636: /* event tuple for extended network */
637: new_rt.NetStart = *(unsigned short *)gbuf_rptr(m);
638: new_rt.NetStop = *(unsigned short *)&gbuf_rptr(m)[3];
639: new_rt.NetDist = gbuf_rptr(m)[2] & 0x7f;
640: ev_len = 5;
641: } else {
642: /* event tuple for non-extended network */
643: new_rt.NetStart = 0;
644: new_rt.NetStop = *(unsigned short *)gbuf_rptr(m);
645: new_rt.NetDist = gbuf_rptr(m)[2];
646: ev_len = 3;
647: }
648:
649: switch (ev) {
650: case AURPEV_Null:
651: break;
652:
653: case AURPEV_NetAdded:
654: gbuf_rinc(m,ev_len);
655: new_rt.NextIRNet = 0;
656: new_rt.NextIRNode = node;
657: new_rt.NetPort = net_port;
658: if ((new_rt.NetDist == 0) || (new_rt.NetStop == 0) ||
659: (new_rt.NetStop < new_rt.NetStart)) {
660: dPrintf(D_M_AURP,D_L_WARNING,
661: ("AURPupdateri: %d, invalid NetAdded received [%d-%d]\n",
662: net_port, new_rt.NetStart, new_rt.NetStop));
663: break;
664: }
665:
666: if ((old_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
667: if (old_rt->NetPort == net_port) {
668: /*
669: * process this event as if it was an NDC event;
670: * update the route's distance
671: */
672: old_rt->NetDist = new_rt.NetDist;
673: }
674: } else {
675: l_add: if ((new_rt.NetDist < 16) && (new_rt.NetDist != NOTIFY_N_DIST)) {
676: new_rt.EntryState = RTE_STATE_GOOD;
677: dPrintf(D_M_AURP, D_L_INFO,
678: ("AURPupdateri: NetAdded [%d-%d]\n",
679: new_rt.NetStart, new_rt.NetStop));
680: if (rt_insert(new_rt.NetStop, new_rt.NetStart,
681: new_rt.NextIRNet, new_rt.NextIRNode,
682: new_rt.NetDist, new_rt.NetPort,
683: new_rt.EntryState) == (RT_entry *)0) {
684: dPrintf(D_M_AURP, D_L_WARNING,
685: ("AURPupdateri: RTMP table full [%d-%d]\n",
686: new_rt.NetStart,new_rt.NetStop));
687: return 0;
688: }
689: }
690: }
691: break;
692:
693: case AURPEV_NetDeleted:
694: case AURPEV_NetRouteChange:
695: gbuf_rinc(m,ev_len);
696: l_delete: if ((old_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
697: if (old_rt->NetPort == net_port) {
698: zt_remove_zones(old_rt->ZoneBitMap);
699: rt_delete(old_rt->NetStop, old_rt->NetStart);
700: }
701: }
702: break;
703:
704: case AURPEV_NetDistChange:
705: gbuf_rinc(m,ev_len);
706: if (new_rt.NetDist == 15)
707: goto l_delete; /* process this event as if was an ND event */
708: if ((old_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
709: if (old_rt->NetPort == net_port) {
710: /*
711: * update the route's distance
712: */
713: old_rt->NetDist = new_rt.NetDist;
714: }
715: } else
716: goto l_add; /* process this event as if was an NA event */
717: break;
718:
719: case AURPEV_NetZoneChange:
720: break;
721: }
722: }
723:
724: return 0;
725: }
726:
727: /* */
728: void AURPpurgeri(node)
729: unsigned char node;
730: {
731: short entry_num;
732: RT_entry *entry = (RT_entry *)RT_table;
733:
734: /*
735: * purge all routes associated with the tunnel peer
736: */
737: for (entry_num=0; entry_num < RT_maxentry; entry_num++,entry++) {
738: if ((net_port == entry->NetPort) && (node == entry->NextIRNode)) {
739: zt_remove_zones(entry->ZoneBitMap);
740: rt_delete(entry->NetStop, entry->NetStart);
741: }
742: }
743: }
744:
745: /* */
746: void AURPrtupdate(entry, ev)
747: RT_entry *entry;
748: unsigned char ev;
749: {
750: unsigned char i, node, ev_len, ev_tuple[6];
751: gbuf_t *m;
752: aurp_state_t *state = (aurp_state_t *)&aurp_state[1];
753: int s, msize = sizeof(aurp_hdr_t);
754:
755: dPrintf(D_M_AURP, D_L_TRACE, ("AURPrtupdate: event=%d, net=[%d-%d]\n",
756: ev, entry->NetStart, entry->NetStop));
757:
758: /*
759: * check that the network can be exported; if not,
760: * we must not make it visible beyond the local networks
761: */
762: if (net_export) {
763: for (i=0; i < net_access_cnt; i++) {
764: if ((net_access[i] == entry->NetStart) ||
765: (net_access[i] == entry->NetStop))
766: break;
767: }
768: if (i == net_access_cnt)
769: return;
770: } else {
771: for (i=0; i < net_access_cnt; i++) {
772: if ((net_access[i] == entry->NetStart) ||
773: (net_access[i] == entry->NetStop))
774: return;
775: }
776: }
777:
778: /*
779: * create the update event tuple
780: */
781: ev_tuple[0] = ev; /* event code */
782: if (entry->NetStart) {
783: *(unsigned short *)&ev_tuple[1] = entry->NetStart;
784: ev_tuple[3] = 0x80 | (entry->NetDist & 0x1F);
785: *(unsigned short *)&ev_tuple[4] = entry->NetStop;
786: ev_len = 6;
787: } else {
788: *(unsigned short *)&ev_tuple[1] = entry->NetStop;
789: ev_tuple[3] = (entry->NetDist & 0x1F);
790: ev_len = 4;
791: }
792:
793: for (node=1; node <= dst_addr_cnt; node++, state++) {
794: if ((ev == AURPEV_NetAdded) &&
795: (!(state->snd_sui & AURPFLG_NA))) continue;
796: if ((ev == AURPEV_NetDeleted) &&
797: (!(state->snd_sui & AURPFLG_ND))) continue;
798: if ((ev == AURPEV_NetDistChange) &&
799: (!(state->snd_sui & AURPFLG_NDC))) continue;
800: ATDISABLE(s, aurpgen_lock);
801: if ((state->snd_state != AURPSTATE_Unconnected) &&
802: (state->snd_state != AURPSTATE_WaitingForRIAck2)) {
803: if ((m = state->upd_m) == 0) {
804: /*
805: * we don't have the RI update buffer yet, allocate one
806: */
807: ATENABLE(s, aurpgen_lock);
808: if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_HI)) == 0)
809: continue;
810: ATDISABLE(s, aurpgen_lock);
811: state->upd_m = m;
812: gbuf_rinc(m,msize);
813: gbuf_wset(m,0);
814: }
815:
816: /*
817: * add the update event tuple to the RI update buffer;
818: * the RI update buffer will be sent when the periodic update
819: * timer expires
820: */
821: bcopy(ev_tuple, gbuf_wptr(m), ev_len);
822: gbuf_winc(m,ev_len);
823:
824: /*
825: * if the RI update buffer is full, send the RI update now
826: */
827: if (gbuf_len(m) > (AURP_MaxPktSize-6)) {
828: ATENABLE(s, aurpgen_lock);
829: AURPsndRIUpd(state);
830: continue;
831: }
832: }
833: ATENABLE(s, aurpgen_lock);
834: }
835: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.