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