2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_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 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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1996 Apple Computer, Inc.
31 * Created April 8, 1996 by Tuyen Nguyen
32 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
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>
43 #include <sys/filedesc.h>
44 #include <sys/fcntl.h>
46 #include <sys/socket.h>
47 #include <sys/socketvar.h>
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>
60 static void AURPsndRIRsp(aurp_state_t
*);
63 void AURPsndRIAck(state
, m
, flags
)
68 unsigned short sequence_number
;
70 int msize
= sizeof(aurp_hdr_t
);
73 sequence_number
= ((aurp_hdr_t
*)gbuf_rptr(m
))->sequence_number
;
74 gbuf_wset(m
,sizeof(aurp_hdr_t
));
76 sequence_number
= state
->rcv_sequence_number
;
77 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) == 0)
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
;
90 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIAck: node=%d\n",
92 AURPsend(m
, AUD_AURP
, state
->rem_node
);
95 /* locked version of AURPsndRIReq */
96 void AURPsndRIReq_locked(state
)
105 void AURPsndRIReq(state
)
113 if (state
->rcv_state
== AURPSTATE_Unconnected
) {
116 if (state
->rcv_tmo
&& (state
->rcv_state
!= AURPSTATE_WaitingForRIRsp
)) {
120 msize
= sizeof(aurp_hdr_t
);
121 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) != 0) {
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
;
131 /* update state info */
132 state
->rcv_state
= AURPSTATE_WaitingForRIRsp
;
134 /* send the packet */
135 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIReq: node=%d\n",
137 AURPsend(m
, AUD_AURP
, state
->rem_node
);
140 /* start the retry timer */
141 timeout(AURPsndRIReq_locked
, state
, AURP_RetryInterval
*HZ
);
145 /* locked version of AURPsndRIRsp */
146 void AURPsndRIRsp_locked(state
)
155 void AURPsndRIRsp(state
)
163 ATDISABLE(s
, aurpgen_lock
);
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
);
172 /* update state info */
173 state
->snd_state
= AURPSTATE_WaitingForRIAck1
;
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
);
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
;
193 /* get routing info of the local networks */
194 state
->snd_next_entry
= AURPgetri(
195 state
->snd_next_entry
, gbuf_wptr(m
), &len
);
198 /* set the last flag if this is the last response packet */
199 if (!state
->snd_next_entry
)
200 hdrp
->flags
= AURPFLG_LAST
;
203 /* keep a copy of the packet for retry */
204 m
= (gbuf_t
*)gbuf_dupb(state
->rsp_m
);
206 /* start the retry timer */
207 timeout(AURPsndRIRsp_locked
, state
, AURP_RetryInterval
*HZ
);
211 ATENABLE(s
, aurpgen_lock
);
213 /* send the packet */
215 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIRsp: len=%d\n", len
));
216 AURPsend(m
, AUD_AURP
, state
->rem_node
);
221 void AURPsndRIUpd_locked(state
)
230 void AURPsndRIUpd(state
)
238 ATDISABLE(s
, aurpgen_lock
);
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
);
248 /* update state info */
249 state
->snd_state
= AURPSTATE_WaitingForRIAck2
;
251 if (state
->snd_tmo
== 0) {
252 ATENABLE(s
, aurpgen_lock
);
253 msize
= sizeof(aurp_hdr_t
);
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
;
266 /* keep a copy of the packet for retry */
267 m
= (gbuf_t
*)gbuf_dupb(state
->upd_m
);
269 /* start the retry timer */
270 timeout(AURPsndRIUpd_locked
, state
, AURP_RetryInterval
*HZ
);
274 ATENABLE(s
, aurpgen_lock
);
276 /* send the packet */
278 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIUpd: len=%d\n", len
));
279 AURPsend(m
, AUD_AURP
, state
->rem_node
);
285 void AURPrcvRIReq(state
, m
)
289 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
292 ATDISABLE(s
, aurpgen_lock
);
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"));
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
));
313 if (state
->snd_state
!= AURPSTATE_WaitingForRIAck1
) {
314 state
->snd_next_entry
= 0;
316 gbuf_freem(state
->rsp_m
);
319 ATENABLE(s
, aurpgen_lock
);
322 ATENABLE(s
, aurpgen_lock
);
328 void AURPrcvRIRsp(state
, m
)
332 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
335 ATDISABLE(s
, aurpgen_lock
);
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"));
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
));
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
);
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
));
370 gbuf_rinc(m
,sizeof(*hdrp
));
371 if (hdrp
->flags
& AURPFLG_LAST
)
372 state
->rcv_state
= AURPSTATE_Connected
;
373 ATENABLE(s
, aurpgen_lock
);
375 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIRsp: len=%ld\n", gbuf_len(m
)));
377 /* cancel the retry timer */
378 untimeout(AURPsndRIReq_locked
, state
);
382 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
384 /* update state info */
385 if (++state
->rcv_sequence_number
== 0)
386 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
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"));
394 /* set the get zone flag to get zone info later if required */
395 if (state
->rcv_state
== AURPSTATE_Connected
)
400 void AURPrcvRIUpd(state
, m
)
404 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
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"));
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
));
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
);
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
));
436 gbuf_rinc(m
,sizeof(*hdrp
));
438 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIUpd: len=%ld\n", gbuf_len(m
)));
441 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
443 /* update state info */
444 if (++state
->rcv_sequence_number
== 0)
445 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
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"));
452 /* set the get zone flag to get zone info later if required */
459 void AURPrcvRIAck(state
, m
)
464 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
465 unsigned char snd_state
;
469 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIAck: state=%d\n",
471 ATDISABLE(s
, aurpgen_lock
);
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
)) {
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
;
486 /* ack from the tunnel peer to our RI update */
487 untimeout(AURPsndRIUpd_locked
, state
);
488 dat_m
= state
->upd_m
;
493 gbuf_rinc(dat_m
,sizeof(aurp_hdr_t
));
495 /* increment the sequence number */
496 if (++state
->snd_sequence_number
== 0)
497 state
->snd_sequence_number
= AURP_FirstSeqNum
;
499 /* update state info */
500 state
->snd_state
= AURPSTATE_Connected
;
501 ATENABLE(s
, aurpgen_lock
);
503 if (state
->snd_next_entry
) /* more RI responses to send? */
506 /* check to see if we need to send ZI responses */
507 if (hdrp
->flags
& AURPFLG_SZI
)
508 AURPsndZRsp(state
, dat_m
, flag
);
512 ATENABLE(s
, aurpgen_lock
);
518 int AURPgetri(next_entry
, buf
, len
)
523 short entry_num
= next_entry
;
524 RT_entry
*entry
= (RT_entry
*)&RT_table
[next_entry
];
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);
540 /* route info for non-extended network */
541 *(short *)buf
= entry
->NetStop
;
542 buf
+= sizeof(short);
543 *buf
++ = (entry
->NetDist
& 0x1F);
548 if (*len
> AURP_MaxPktSize
)
552 return (entry_num
== RT_maxentry
) ? 0 : entry_num
;
556 int AURPsetri(node
, m
)
561 unsigned char *tuples_ptr
;
562 RT_entry new_rt
, *curr_rt
;
564 new_rt
.NextIRNet
= 0;
565 new_rt
.NextIRNode
= node
;
566 new_rt
.NetPort
= net_port
;
569 * Process all the tuples against our routing table
571 tuples_ptr
= (char *)gbuf_rptr(m
);
572 tuples_cnt
= (gbuf_len(m
))/3;
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
);
579 if (tuples_ptr
[-1] & 0x80) {
580 new_rt
.NetStop
= TUPLENET((tuples_ptr
));
584 new_rt
.NetStop
= new_rt
.NetStart
;
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
));
594 if ((curr_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
595 /* ignore loop if present */
596 if (curr_rt
->NetPort
!= net_port
)
599 if (new_rt
.NetDist
< 16) {
601 * check if the definition of the route has changed
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
));
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
);
629 if ((new_rt
.NetDist
<= curr_rt
->NetDist
) &&
630 (new_rt
.NetDist
< 16)) {
632 * found a shorter or more recent route,
633 * replace with the new entry
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
));
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
));
659 } /* end of main while */
665 int AURPupdateri(node
, m
)
670 RT_entry new_rt
, *old_rt
;
672 while (gbuf_len(m
) > 0) {
673 ev
= *gbuf_rptr(m
); /* event code */
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;
682 /* event tuple for non-extended network */
684 new_rt
.NetStop
= *(unsigned short *)gbuf_rptr(m
);
685 new_rt
.NetDist
= gbuf_rptr(m
)[2];
693 case AURPEV_NetAdded
:
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
));
706 if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
707 if (old_rt
->NetPort
== net_port
) {
709 * process this event as if it was an NDC event;
710 * update the route's distance
712 old_rt
->NetDist
= new_rt
.NetDist
;
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
));
733 case AURPEV_NetDeleted
:
734 case AURPEV_NetRouteChange
:
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
);
744 case AURPEV_NetDistChange
:
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
) {
751 * update the route's distance
753 old_rt
->NetDist
= new_rt
.NetDist
;
756 goto l_add
; /* process this event as if was an NA event */
759 case AURPEV_NetZoneChange
:
768 void AURPpurgeri(node
)
772 RT_entry
*entry
= (RT_entry
*)RT_table
;
775 * purge all routes associated with the tunnel peer
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
);
786 void AURPrtupdate(entry
, ev
)
790 unsigned char i
, node
, ev_len
, ev_tuple
[6];
792 aurp_state_t
*state
= (aurp_state_t
*)&aurp_state
[1];
793 int s
, msize
= sizeof(aurp_hdr_t
);
795 dPrintf(D_M_AURP
, D_L_TRACE
, ("AURPrtupdate: event=%d, net=[%d-%d]\n",
796 ev
, entry
->NetStart
, entry
->NetStop
));
799 * check that the network can be exported; if not,
800 * we must not make it visible beyond the local networks
803 for (i
=0; i
< net_access_cnt
; i
++) {
804 if ((net_access
[i
] == entry
->NetStart
) ||
805 (net_access
[i
] == entry
->NetStop
))
808 if (i
== net_access_cnt
)
811 for (i
=0; i
< net_access_cnt
; i
++) {
812 if ((net_access
[i
] == entry
->NetStart
) ||
813 (net_access
[i
] == entry
->NetStop
))
819 * create the update event tuple
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
;
828 *(unsigned short *)&ev_tuple
[1] = entry
->NetStop
;
829 ev_tuple
[3] = (entry
->NetDist
& 0x1F);
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) {
845 * we don't have the RI update buffer yet, allocate one
847 ATENABLE(s
, aurpgen_lock
);
848 if ((m
= (gbuf_t
*)gbuf_alloc(msize
+AURP_MaxPktSize
, PRI_HI
)) == 0)
850 ATDISABLE(s
, aurpgen_lock
);
857 * add the update event tuple to the RI update buffer;
858 * the RI update buffer will be sent when the periodic update
861 bcopy(ev_tuple
, gbuf_wptr(m
), ev_len
);
865 * if the RI update buffer is full, send the RI update now
867 if (gbuf_len(m
) > (AURP_MaxPktSize
-6)) {
868 ATENABLE(s
, aurpgen_lock
);
873 ATENABLE(s
, aurpgen_lock
);