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