2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
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
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
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.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
31 * Copyright (c) 1996 Apple Computer, Inc.
33 * Created April 8, 1996 by Tuyen Nguyen
34 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
38 #include <sys/errno.h>
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <machine/spl.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
45 #include <sys/filedesc.h>
46 #include <sys/fcntl.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
52 #include <netat/sysglue.h>
53 #include <netat/appletalk.h>
54 #include <netat/at_var.h>
55 #include <netat/rtmp.h>
56 #include <netat/routing_tables.h>
57 #include <netat/at_pcb.h>
58 #include <netat/aurp.h>
59 #include <netat/debug.h>
62 static void AURPsndRIRsp(aurp_state_t
*);
65 void AURPsndRIAck(state
, m
, flags
)
70 unsigned short sequence_number
;
72 int msize
= sizeof(aurp_hdr_t
);
75 sequence_number
= ((aurp_hdr_t
*)gbuf_rptr(m
))->sequence_number
;
76 gbuf_wset(m
,sizeof(aurp_hdr_t
));
78 sequence_number
= state
->rcv_sequence_number
;
79 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) == 0)
84 /* construct the RI Ack packet */
85 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
86 hdrp
->connection_id
= state
->rcv_connection_id
;
87 hdrp
->sequence_number
= sequence_number
;
88 hdrp
->command_code
= AURPCMD_RIAck
;
92 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIAck: node=%d\n",
94 AURPsend(m
, AUD_AURP
, state
->rem_node
);
97 /* locked version of AURPsndRIReq */
98 void AURPsndRIReq_locked(state
)
107 void AURPsndRIReq(state
)
115 if (state
->rcv_state
== AURPSTATE_Unconnected
) {
118 if (state
->rcv_tmo
&& (state
->rcv_state
!= AURPSTATE_WaitingForRIRsp
)) {
122 msize
= sizeof(aurp_hdr_t
);
123 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) != 0) {
126 /* construct the RI request packet */
127 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
128 hdrp
->connection_id
= state
->rcv_connection_id
;
129 hdrp
->sequence_number
= 0;
130 hdrp
->command_code
= AURPCMD_RIReq
;
133 /* update state info */
134 state
->rcv_state
= AURPSTATE_WaitingForRIRsp
;
136 /* send the packet */
137 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIReq: node=%d\n",
139 AURPsend(m
, AUD_AURP
, state
->rem_node
);
142 /* start the retry timer */
143 timeout(AURPsndRIReq_locked
, state
, AURP_RetryInterval
*HZ
);
147 /* locked version of AURPsndRIRsp */
148 void AURPsndRIRsp_locked(state
)
157 void AURPsndRIRsp(state
)
165 ATDISABLE(s
, aurpgen_lock
);
167 /* make sure we're in a valid state to send RI response */
168 if ((state
->snd_state
== AURPSTATE_Unconnected
) ||
169 (state
->snd_state
== AURPSTATE_WaitingForRIAck2
)) {
170 ATENABLE(s
, aurpgen_lock
);
174 /* update state info */
175 state
->snd_state
= AURPSTATE_WaitingForRIAck1
;
177 if (state
->rsp_m
== 0) {
178 ATENABLE(s
, aurpgen_lock
);
179 msize
= sizeof(aurp_hdr_t
);
180 if ((m
= (gbuf_t
*)gbuf_alloc(msize
+AURP_MaxPktSize
, PRI_MED
)) == 0) {
181 timeout(AURPsndRIRsp_locked
, state
, AURP_RetryInterval
*HZ
);
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
;
195 /* get routing info of the local networks */
196 state
->snd_next_entry
= AURPgetri(
197 state
->snd_next_entry
, gbuf_wptr(m
), &len
);
200 /* set the last flag if this is the last response packet */
201 if (!state
->snd_next_entry
)
202 hdrp
->flags
= AURPFLG_LAST
;
205 /* keep a copy of the packet for retry */
206 m
= (gbuf_t
*)gbuf_dupb(state
->rsp_m
);
208 /* start the retry timer */
209 timeout(AURPsndRIRsp_locked
, state
, AURP_RetryInterval
*HZ
);
213 ATENABLE(s
, aurpgen_lock
);
215 /* send the packet */
217 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIRsp: len=%d\n", len
));
218 AURPsend(m
, AUD_AURP
, state
->rem_node
);
223 void AURPsndRIUpd_locked(state
)
232 void AURPsndRIUpd(state
)
240 ATDISABLE(s
, aurpgen_lock
);
242 /* make sure we're in a valid state to send update */
243 if (state
->snd_next_entry
|| (state
->upd_m
== 0) ||
244 (state
->snd_state
== AURPSTATE_Unconnected
) ||
245 (state
->snd_state
== AURPSTATE_WaitingForRIAck1
)) {
246 ATENABLE(s
, aurpgen_lock
);
250 /* update state info */
251 state
->snd_state
= AURPSTATE_WaitingForRIAck2
;
253 if (state
->snd_tmo
== 0) {
254 ATENABLE(s
, aurpgen_lock
);
255 msize
= sizeof(aurp_hdr_t
);
260 /* construct the RI update packet */
261 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
262 hdrp
->connection_id
= state
->snd_connection_id
;
263 hdrp
->sequence_number
= state
->snd_sequence_number
;
264 hdrp
->command_code
= AURPCMD_RIUpd
;
268 /* keep a copy of the packet for retry */
269 m
= (gbuf_t
*)gbuf_dupb(state
->upd_m
);
271 /* start the retry timer */
272 timeout(AURPsndRIUpd_locked
, state
, AURP_RetryInterval
*HZ
);
276 ATENABLE(s
, aurpgen_lock
);
278 /* send the packet */
280 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIUpd: len=%d\n", len
));
281 AURPsend(m
, AUD_AURP
, state
->rem_node
);
287 void AURPrcvRIReq(state
, m
)
291 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
294 ATDISABLE(s
, aurpgen_lock
);
296 /* make sure we're in a valid state to accept it */
297 if ((state
->snd_state
== AURPSTATE_Unconnected
) ||
298 (state
->snd_state
== AURPSTATE_WaitingForRIAck2
)) {
299 ATENABLE(s
, aurpgen_lock
);
300 dPrintf(D_M_AURP
, D_L_WARNING
, ("AURPrcvRIReq: unexpected request\n"));
305 /* check for the correct connection id */
306 if (hdrp
->connection_id
!= state
->snd_connection_id
) {
307 ATENABLE(s
, aurpgen_lock
);
308 dPrintf(D_M_AURP
, D_L_WARNING
,
309 ("AURPrcvRIReq: invalid connection id, r=%d, m=%d\n",
310 hdrp
->connection_id
, state
->snd_connection_id
));
315 if (state
->snd_state
!= AURPSTATE_WaitingForRIAck1
) {
316 state
->snd_next_entry
= 0;
318 gbuf_freem(state
->rsp_m
);
321 ATENABLE(s
, aurpgen_lock
);
324 ATENABLE(s
, aurpgen_lock
);
330 void AURPrcvRIRsp(state
, m
)
334 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
337 ATDISABLE(s
, aurpgen_lock
);
339 /* make sure we're in a valid state to accept it */
340 if (state
->rcv_state
!= AURPSTATE_WaitingForRIRsp
) {
341 ATENABLE(s
, aurpgen_lock
);
342 dPrintf(D_M_AURP
, D_L_WARNING
, ("AURPrcvRIRsp: unexpected response\n"));
347 /* check for the correct connection id */
348 if (hdrp
->connection_id
!= state
->rcv_connection_id
) {
349 ATENABLE(s
, aurpgen_lock
);
350 dPrintf(D_M_AURP
, D_L_WARNING
,
351 ("AURPrcvRIRsp: invalid connection id, r=%d, m=%d\n",
352 hdrp
->connection_id
, state
->rcv_connection_id
));
357 /* check for the correct sequence number */
358 if (hdrp
->sequence_number
!= state
->rcv_sequence_number
) {
359 ATENABLE(s
, aurpgen_lock
);
360 if ( ((state
->rcv_sequence_number
== AURP_FirstSeqNum
) &&
361 (hdrp
->sequence_number
== AURP_LastSeqNum
)) ||
362 (hdrp
->sequence_number
== (state
->rcv_sequence_number
-1)) ) {
363 AURPsndRIAck(state
, m
, AURPFLG_SZI
);
365 dPrintf(D_M_AURP
, D_L_WARNING
,
366 ("AURPrcvRIRsp: invalid sequence number, r=%d, m=%d\n",
367 hdrp
->sequence_number
, state
->rcv_sequence_number
));
372 gbuf_rinc(m
,sizeof(*hdrp
));
373 if (hdrp
->flags
& AURPFLG_LAST
)
374 state
->rcv_state
= AURPSTATE_Connected
;
375 ATENABLE(s
, aurpgen_lock
);
377 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIRsp: len=%ld\n", gbuf_len(m
)));
379 /* cancel the retry timer */
380 untimeout(AURPsndRIReq_locked
, state
);
384 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
386 /* update state info */
387 if (++state
->rcv_sequence_number
== 0)
388 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
390 /* process routing info of the tunnel peer */
391 if (AURPsetri(state
->rem_node
, m
)) {
392 dPrintf(D_M_AURP
, D_L_ERROR
, ("AURPrcvRIRsp: AURPsetri() error\n"));
396 /* set the get zone flag to get zone info later if required */
397 if (state
->rcv_state
== AURPSTATE_Connected
)
402 void AURPrcvRIUpd(state
, m
)
406 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
408 /* make sure we're in a valid state to accept it */
409 if (state
->rcv_state
== AURPSTATE_Unconnected
) {
410 dPrintf(D_M_AURP
, D_L_WARNING
, ("AURPrcvRIUpd: unexpected response\n"));
415 /* check for the correct connection id */
416 if (hdrp
->connection_id
!= state
->rcv_connection_id
) {
417 dPrintf(D_M_AURP
, D_L_WARNING
,
418 ("AURPrcvRIUpd: invalid connection id, r=%d, m=%d\n",
419 hdrp
->connection_id
, state
->rcv_connection_id
));
424 /* check for the correct sequence number */
425 if (hdrp
->sequence_number
!= state
->rcv_sequence_number
) {
426 if ( ((state
->rcv_sequence_number
== AURP_FirstSeqNum
) &&
427 (hdrp
->sequence_number
== AURP_LastSeqNum
)) ||
428 (hdrp
->sequence_number
== (state
->rcv_sequence_number
-1)) ) {
429 AURPsndRIAck(state
, m
, AURPFLG_SZI
);
431 dPrintf(D_M_AURP
, D_L_WARNING
,
432 ("AURPrcvRIUpd: invalid sequence number, r=%d, m=%d\n",
433 hdrp
->sequence_number
, state
->rcv_sequence_number
));
438 gbuf_rinc(m
,sizeof(*hdrp
));
440 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIUpd: len=%ld\n", gbuf_len(m
)));
443 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
445 /* update state info */
446 if (++state
->rcv_sequence_number
== 0)
447 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
449 /* process update routing info of the tunnel peer */
450 if (AURPupdateri(state
->rem_node
, m
)) {
451 dPrintf(D_M_AURP
, D_L_ERROR
, ("AURPrcvRIUpd: AURPupdateri() error\n"));
454 /* set the get zone flag to get zone info later if required */
461 void AURPrcvRIAck(state
, m
)
466 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
467 unsigned char snd_state
;
471 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIAck: state=%d\n",
473 ATDISABLE(s
, aurpgen_lock
);
475 /* make sure we're in a valid state to accept it */
476 snd_state
= state
->snd_state
;
477 if (((snd_state
== AURPSTATE_WaitingForRIAck1
) ||
478 (snd_state
== AURPSTATE_WaitingForRIAck2
)) &&
479 (hdrp
->sequence_number
== state
->snd_sequence_number
)) {
481 if (snd_state
== AURPSTATE_WaitingForRIAck1
) {
482 /* ack from the tunnel peer to our RI response */
483 untimeout(AURPsndRIRsp_locked
, state
);
484 dat_m
= state
->rsp_m
;
488 /* ack from the tunnel peer to our RI update */
489 untimeout(AURPsndRIUpd_locked
, state
);
490 dat_m
= state
->upd_m
;
495 gbuf_rinc(dat_m
,sizeof(aurp_hdr_t
));
497 /* increment the sequence number */
498 if (++state
->snd_sequence_number
== 0)
499 state
->snd_sequence_number
= AURP_FirstSeqNum
;
501 /* update state info */
502 state
->snd_state
= AURPSTATE_Connected
;
503 ATENABLE(s
, aurpgen_lock
);
505 if (state
->snd_next_entry
) /* more RI responses to send? */
508 /* check to see if we need to send ZI responses */
509 if (hdrp
->flags
& AURPFLG_SZI
)
510 AURPsndZRsp(state
, dat_m
, flag
);
514 ATENABLE(s
, aurpgen_lock
);
520 int AURPgetri(next_entry
, buf
, len
)
525 short entry_num
= next_entry
;
526 RT_entry
*entry
= (RT_entry
*)&RT_table
[next_entry
];
528 for (*len
=0; entry_num
< RT_maxentry
; entry_num
++,entry
++) {
529 if ((net_port
!= entry
->NetPort
) &&
530 !(entry
->AURPFlag
& AURP_NetHiden
)) {
531 if ((entry
->EntryState
& 0x0F) >= RTE_STATE_SUSPECT
) {
532 if (entry
->NetStart
) {
533 /* route info for extended network */
534 *(short *)buf
= entry
->NetStart
;
535 buf
+= sizeof(short);
536 *buf
++ = 0x80 | (entry
->NetDist
& 0x1F);
537 *(short *)buf
= entry
->NetStop
;
538 buf
+= sizeof(short);
542 /* route info for non-extended network */
543 *(short *)buf
= entry
->NetStop
;
544 buf
+= sizeof(short);
545 *buf
++ = (entry
->NetDist
& 0x1F);
550 if (*len
> AURP_MaxPktSize
)
554 return (entry_num
== RT_maxentry
) ? 0 : entry_num
;
558 int AURPsetri(node
, m
)
563 unsigned char *tuples_ptr
;
564 RT_entry new_rt
, *curr_rt
;
566 new_rt
.NextIRNet
= 0;
567 new_rt
.NextIRNode
= node
;
568 new_rt
.NetPort
= net_port
;
571 * Process all the tuples against our routing table
573 tuples_ptr
= (char *)gbuf_rptr(m
);
574 tuples_cnt
= (gbuf_len(m
))/3;
576 while (tuples_cnt
--) {
577 new_rt
.NetDist
= TUPLEDIST(tuples_ptr
) + 1;
578 new_rt
.EntryState
= RTE_STATE_GOOD
;
579 new_rt
.NetStart
= TUPLENET(tuples_ptr
);
581 if (tuples_ptr
[-1] & 0x80) {
582 new_rt
.NetStop
= TUPLENET((tuples_ptr
));
586 new_rt
.NetStop
= new_rt
.NetStart
;
589 if ((new_rt
.NetStop
== 0) || (new_rt
.NetStop
< new_rt
.NetStart
)) {
590 dPrintf(D_M_AURP
, D_L_WARNING
,
591 ("AURPsetri: %d, invalid tuple received [%d-%d]\n",
592 net_port
, new_rt
.NetStart
, new_rt
.NetStop
));
596 if ((curr_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
597 /* ignore loop if present */
598 if (curr_rt
->NetPort
!= net_port
)
601 if (new_rt
.NetDist
< 16) {
603 * check if the definition of the route has changed
605 if ((new_rt
.NetStop
!= curr_rt
->NetStop
) ||
606 (new_rt
.NetStart
!= curr_rt
->NetStart
)) {
607 if ((new_rt
.NetStop
== curr_rt
->NetStop
) &&
608 (new_rt
.NetStop
== curr_rt
->NetStart
) &&
609 (new_rt
.NetStart
== 0)) {
610 new_rt
.NetStart
= new_rt
.NetStop
;
611 } else if ((new_rt
.NetStop
== curr_rt
->NetStop
) &&
612 (new_rt
.NetStart
== new_rt
.NetStop
) &&
613 (curr_rt
->NetStart
== 0)) {
614 dPrintf(D_M_AURP
, D_L_WARNING
,
615 ("AURPsetri: [%d-%d] has changed to [%d-%d], Dist=%d\n",
616 curr_rt
->NetStart
, curr_rt
->NetStop
,
617 new_rt
.NetStart
, new_rt
.NetStop
, new_rt
.NetDist
));
620 dPrintf(D_M_AURP
, D_L_WARNING
,
621 ("AURPsetri: Net Conflict, Curr=[%d-%d], New=[%d-%d]\n",
622 curr_rt
->NetStart
,curr_rt
->NetStop
,
623 new_rt
.NetStart
,new_rt
.NetStop
));
624 zt_remove_zones(curr_rt
->ZoneBitMap
);
625 rt_delete(curr_rt
->NetStop
, curr_rt
->NetStart
);
631 if ((new_rt
.NetDist
<= curr_rt
->NetDist
) &&
632 (new_rt
.NetDist
< 16)) {
634 * found a shorter or more recent route,
635 * replace with the new entry
637 curr_rt
->NetDist
= new_rt
.NetDist
;
638 curr_rt
->NextIRNode
= new_rt
.NextIRNode
;
639 dPrintf(D_M_AURP_LOW
,D_L_INFO
,
640 ("AURPsetri: shorter route found [%d-%d], update\n",
641 new_rt
.NetStart
,new_rt
.NetStop
));
644 } else { /* no entry found */
645 if (new_rt
.NetDist
< 16) {
646 new_rt
.EntryState
= RTE_STATE_GOOD
;
647 dPrintf(D_M_AURP
, D_L_INFO
,
648 ("AURPsetri: new_rt [%d-%d], tuple #%d\n",
649 new_rt
.NetStart
, new_rt
.NetStop
, tuples_cnt
));
650 if (rt_insert(new_rt
.NetStop
, new_rt
.NetStart
,
651 new_rt
.NextIRNet
, new_rt
.NextIRNode
,
652 new_rt
.NetDist
, new_rt
.NetPort
,
653 new_rt
.EntryState
) == (RT_entry
*)0) {
654 dPrintf(D_M_AURP
,D_L_ERROR
,
655 ("AURPsetri: RTMP table full [%d-%d]\n",
656 new_rt
.NetStart
,new_rt
.NetStop
));
661 } /* end of main while */
667 int AURPupdateri(node
, m
)
672 RT_entry new_rt
, *old_rt
;
674 while (gbuf_len(m
) > 0) {
675 ev
= *gbuf_rptr(m
); /* event code */
677 if (gbuf_rptr(m
)[2] & 0x80) {
678 /* event tuple for extended network */
679 new_rt
.NetStart
= *(unsigned short *)gbuf_rptr(m
);
680 new_rt
.NetStop
= *(unsigned short *)&gbuf_rptr(m
)[3];
681 new_rt
.NetDist
= gbuf_rptr(m
)[2] & 0x7f;
684 /* event tuple for non-extended network */
686 new_rt
.NetStop
= *(unsigned short *)gbuf_rptr(m
);
687 new_rt
.NetDist
= gbuf_rptr(m
)[2];
695 case AURPEV_NetAdded
:
697 new_rt
.NextIRNet
= 0;
698 new_rt
.NextIRNode
= node
;
699 new_rt
.NetPort
= net_port
;
700 if ((new_rt
.NetDist
== 0) || (new_rt
.NetStop
== 0) ||
701 (new_rt
.NetStop
< new_rt
.NetStart
)) {
702 dPrintf(D_M_AURP
,D_L_WARNING
,
703 ("AURPupdateri: %d, invalid NetAdded received [%d-%d]\n",
704 net_port
, new_rt
.NetStart
, new_rt
.NetStop
));
708 if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
709 if (old_rt
->NetPort
== net_port
) {
711 * process this event as if it was an NDC event;
712 * update the route's distance
714 old_rt
->NetDist
= new_rt
.NetDist
;
717 l_add
: if ((new_rt
.NetDist
< 16) && (new_rt
.NetDist
!= NOTIFY_N_DIST
)) {
718 new_rt
.EntryState
= RTE_STATE_GOOD
;
719 dPrintf(D_M_AURP
, D_L_INFO
,
720 ("AURPupdateri: NetAdded [%d-%d]\n",
721 new_rt
.NetStart
, new_rt
.NetStop
));
722 if (rt_insert(new_rt
.NetStop
, new_rt
.NetStart
,
723 new_rt
.NextIRNet
, new_rt
.NextIRNode
,
724 new_rt
.NetDist
, new_rt
.NetPort
,
725 new_rt
.EntryState
) == (RT_entry
*)0) {
726 dPrintf(D_M_AURP
, D_L_WARNING
,
727 ("AURPupdateri: RTMP table full [%d-%d]\n",
728 new_rt
.NetStart
,new_rt
.NetStop
));
735 case AURPEV_NetDeleted
:
736 case AURPEV_NetRouteChange
:
738 l_delete
: if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
739 if (old_rt
->NetPort
== net_port
) {
740 zt_remove_zones(old_rt
->ZoneBitMap
);
741 rt_delete(old_rt
->NetStop
, old_rt
->NetStart
);
746 case AURPEV_NetDistChange
:
748 if (new_rt
.NetDist
== 15)
749 goto l_delete
; /* process this event as if was an ND event */
750 if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
751 if (old_rt
->NetPort
== net_port
) {
753 * update the route's distance
755 old_rt
->NetDist
= new_rt
.NetDist
;
758 goto l_add
; /* process this event as if was an NA event */
761 case AURPEV_NetZoneChange
:
770 void AURPpurgeri(node
)
774 RT_entry
*entry
= (RT_entry
*)RT_table
;
777 * purge all routes associated with the tunnel peer
779 for (entry_num
=0; entry_num
< RT_maxentry
; entry_num
++,entry
++) {
780 if ((net_port
== entry
->NetPort
) && (node
== entry
->NextIRNode
)) {
781 zt_remove_zones(entry
->ZoneBitMap
);
782 rt_delete(entry
->NetStop
, entry
->NetStart
);
788 void AURPrtupdate(entry
, ev
)
792 unsigned char i
, node
, ev_len
, ev_tuple
[6];
794 aurp_state_t
*state
= (aurp_state_t
*)&aurp_state
[1];
795 int s
, msize
= sizeof(aurp_hdr_t
);
797 dPrintf(D_M_AURP
, D_L_TRACE
, ("AURPrtupdate: event=%d, net=[%d-%d]\n",
798 ev
, entry
->NetStart
, entry
->NetStop
));
801 * check that the network can be exported; if not,
802 * we must not make it visible beyond the local networks
805 for (i
=0; i
< net_access_cnt
; i
++) {
806 if ((net_access
[i
] == entry
->NetStart
) ||
807 (net_access
[i
] == entry
->NetStop
))
810 if (i
== net_access_cnt
)
813 for (i
=0; i
< net_access_cnt
; i
++) {
814 if ((net_access
[i
] == entry
->NetStart
) ||
815 (net_access
[i
] == entry
->NetStop
))
821 * create the update event tuple
823 ev_tuple
[0] = ev
; /* event code */
824 if (entry
->NetStart
) {
825 *(unsigned short *)&ev_tuple
[1] = entry
->NetStart
;
826 ev_tuple
[3] = 0x80 | (entry
->NetDist
& 0x1F);
827 *(unsigned short *)&ev_tuple
[4] = entry
->NetStop
;
830 *(unsigned short *)&ev_tuple
[1] = entry
->NetStop
;
831 ev_tuple
[3] = (entry
->NetDist
& 0x1F);
835 for (node
=1; node
<= dst_addr_cnt
; node
++, state
++) {
836 if ((ev
== AURPEV_NetAdded
) &&
837 (!(state
->snd_sui
& AURPFLG_NA
))) continue;
838 if ((ev
== AURPEV_NetDeleted
) &&
839 (!(state
->snd_sui
& AURPFLG_ND
))) continue;
840 if ((ev
== AURPEV_NetDistChange
) &&
841 (!(state
->snd_sui
& AURPFLG_NDC
))) continue;
842 ATDISABLE(s
, aurpgen_lock
);
843 if ((state
->snd_state
!= AURPSTATE_Unconnected
) &&
844 (state
->snd_state
!= AURPSTATE_WaitingForRIAck2
)) {
845 if ((m
= state
->upd_m
) == 0) {
847 * we don't have the RI update buffer yet, allocate one
849 ATENABLE(s
, aurpgen_lock
);
850 if ((m
= (gbuf_t
*)gbuf_alloc(msize
+AURP_MaxPktSize
, PRI_HI
)) == 0)
852 ATDISABLE(s
, aurpgen_lock
);
859 * add the update event tuple to the RI update buffer;
860 * the RI update buffer will be sent when the periodic update
863 bcopy(ev_tuple
, gbuf_wptr(m
), ev_len
);
867 * if the RI update buffer is full, send the RI update now
869 if (gbuf_len(m
) > (AURP_MaxPktSize
-6)) {
870 ATENABLE(s
, aurpgen_lock
);
875 ATENABLE(s
, aurpgen_lock
);