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