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