2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1996 Apple Computer, Inc.
28 * Created April 8, 1996 by Tuyen Nguyen
29 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
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>
40 #include <sys/filedesc.h>
41 #include <sys/fcntl.h>
43 #include <sys/socket.h>
44 #include <sys/socketvar.h>
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>
57 static void AURPsndRIRsp(aurp_state_t
*);
60 void AURPsndRIAck(state
, m
, flags
)
65 unsigned short sequence_number
;
67 int msize
= sizeof(aurp_hdr_t
);
70 sequence_number
= ((aurp_hdr_t
*)gbuf_rptr(m
))->sequence_number
;
71 gbuf_wset(m
,sizeof(aurp_hdr_t
));
73 sequence_number
= state
->rcv_sequence_number
;
74 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) == 0)
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
;
87 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIAck: node=%d\n",
89 AURPsend(m
, AUD_AURP
, state
->rem_node
);
92 /* funneled version of AURPsndRIReq */
93 void AURPsndRIReq_funnel(state
)
96 thread_funnel_set(network_flock
, TRUE
);
98 thread_funnel_set(network_flock
, FALSE
);
102 void AURPsndRIReq(state
)
110 if (state
->rcv_state
== AURPSTATE_Unconnected
) {
113 if (state
->rcv_tmo
&& (state
->rcv_state
!= AURPSTATE_WaitingForRIRsp
)) {
117 msize
= sizeof(aurp_hdr_t
);
118 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) != 0) {
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
;
128 /* update state info */
129 state
->rcv_state
= AURPSTATE_WaitingForRIRsp
;
131 /* send the packet */
132 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIReq: node=%d\n",
134 AURPsend(m
, AUD_AURP
, state
->rem_node
);
137 /* start the retry timer */
138 timeout(AURPsndRIReq_funnel
, state
, AURP_RetryInterval
*HZ
);
142 /* funneled version of AURPsndRIRsp */
143 void AURPsndRIRsp_funnel(state
)
146 thread_funnel_set(network_flock
, TRUE
);
148 thread_funnel_set(network_flock
, FALSE
);
152 void AURPsndRIRsp(state
)
160 ATDISABLE(s
, aurpgen_lock
);
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
);
169 /* update state info */
170 state
->snd_state
= AURPSTATE_WaitingForRIAck1
;
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
);
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
;
190 /* get routing info of the local networks */
191 state
->snd_next_entry
= AURPgetri(
192 state
->snd_next_entry
, gbuf_wptr(m
), &len
);
195 /* set the last flag if this is the last response packet */
196 if (!state
->snd_next_entry
)
197 hdrp
->flags
= AURPFLG_LAST
;
200 /* keep a copy of the packet for retry */
201 m
= (gbuf_t
*)gbuf_dupb(state
->rsp_m
);
203 /* start the retry timer */
204 timeout(AURPsndRIRsp_funnel
, state
, AURP_RetryInterval
*HZ
);
208 ATENABLE(s
, aurpgen_lock
);
210 /* send the packet */
212 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIRsp: len=%d\n", len
));
213 AURPsend(m
, AUD_AURP
, state
->rem_node
);
218 void AURPsndRIUpd_funnel(state
)
221 thread_funnel_set(network_flock
, TRUE
);
223 thread_funnel_set(network_flock
, FALSE
);
227 void AURPsndRIUpd(state
)
235 ATDISABLE(s
, aurpgen_lock
);
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
);
245 /* update state info */
246 state
->snd_state
= AURPSTATE_WaitingForRIAck2
;
248 if (state
->snd_tmo
== 0) {
249 ATENABLE(s
, aurpgen_lock
);
250 msize
= sizeof(aurp_hdr_t
);
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
;
263 /* keep a copy of the packet for retry */
264 m
= (gbuf_t
*)gbuf_dupb(state
->upd_m
);
266 /* start the retry timer */
267 timeout(AURPsndRIUpd_funnel
, state
, AURP_RetryInterval
*HZ
);
271 ATENABLE(s
, aurpgen_lock
);
273 /* send the packet */
275 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIUpd: len=%d\n", len
));
276 AURPsend(m
, AUD_AURP
, state
->rem_node
);
282 void AURPrcvRIReq(state
, m
)
286 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
289 ATDISABLE(s
, aurpgen_lock
);
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"));
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
));
310 if (state
->snd_state
!= AURPSTATE_WaitingForRIAck1
) {
311 state
->snd_next_entry
= 0;
313 gbuf_freem(state
->rsp_m
);
316 ATENABLE(s
, aurpgen_lock
);
319 ATENABLE(s
, aurpgen_lock
);
325 void AURPrcvRIRsp(state
, m
)
329 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
332 ATDISABLE(s
, aurpgen_lock
);
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"));
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
));
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
);
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
));
367 gbuf_rinc(m
,sizeof(*hdrp
));
368 if (hdrp
->flags
& AURPFLG_LAST
)
369 state
->rcv_state
= AURPSTATE_Connected
;
370 ATENABLE(s
, aurpgen_lock
);
372 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIRsp: len=%ld\n", gbuf_len(m
)));
374 /* cancel the retry timer */
375 untimeout(AURPsndRIReq_funnel
, state
);
379 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
381 /* update state info */
382 if (++state
->rcv_sequence_number
== 0)
383 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
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"));
391 /* set the get zone flag to get zone info later if required */
392 if (state
->rcv_state
== AURPSTATE_Connected
)
397 void AURPrcvRIUpd(state
, m
)
401 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
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"));
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
));
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
);
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
));
433 gbuf_rinc(m
,sizeof(*hdrp
));
435 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIUpd: len=%ld\n", gbuf_len(m
)));
438 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
440 /* update state info */
441 if (++state
->rcv_sequence_number
== 0)
442 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
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"));
449 /* set the get zone flag to get zone info later if required */
456 void AURPrcvRIAck(state
, m
)
461 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
462 unsigned char snd_state
;
466 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIAck: state=%d\n",
468 ATDISABLE(s
, aurpgen_lock
);
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
)) {
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
;
483 /* ack from the tunnel peer to our RI update */
484 untimeout(AURPsndRIUpd_funnel
, state
);
485 dat_m
= state
->upd_m
;
490 gbuf_rinc(dat_m
,sizeof(aurp_hdr_t
));
492 /* increment the sequence number */
493 if (++state
->snd_sequence_number
== 0)
494 state
->snd_sequence_number
= AURP_FirstSeqNum
;
496 /* update state info */
497 state
->snd_state
= AURPSTATE_Connected
;
498 ATENABLE(s
, aurpgen_lock
);
500 if (state
->snd_next_entry
) /* more RI responses to send? */
503 /* check to see if we need to send ZI responses */
504 if (hdrp
->flags
& AURPFLG_SZI
)
505 AURPsndZRsp(state
, dat_m
, flag
);
509 ATENABLE(s
, aurpgen_lock
);
515 int AURPgetri(next_entry
, buf
, len
)
520 short entry_num
= next_entry
;
521 RT_entry
*entry
= (RT_entry
*)&RT_table
[next_entry
];
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);
537 /* route info for non-extended network */
538 *(short *)buf
= entry
->NetStop
;
539 buf
+= sizeof(short);
540 *buf
++ = (entry
->NetDist
& 0x1F);
545 if (*len
> AURP_MaxPktSize
)
549 return (entry_num
== RT_maxentry
) ? 0 : entry_num
;
553 int AURPsetri(node
, m
)
558 unsigned char *tuples_ptr
;
559 RT_entry new_rt
, *curr_rt
;
561 new_rt
.NextIRNet
= 0;
562 new_rt
.NextIRNode
= node
;
563 new_rt
.NetPort
= net_port
;
566 * Process all the tuples against our routing table
568 tuples_ptr
= (char *)gbuf_rptr(m
);
569 tuples_cnt
= (gbuf_len(m
))/3;
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
);
576 if (tuples_ptr
[-1] & 0x80) {
577 new_rt
.NetStop
= TUPLENET((tuples_ptr
));
581 new_rt
.NetStop
= new_rt
.NetStart
;
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
));
591 if ((curr_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
592 /* ignore loop if present */
593 if (curr_rt
->NetPort
!= net_port
)
596 if (new_rt
.NetDist
< 16) {
598 * check if the definition of the route has changed
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
));
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
);
626 if ((new_rt
.NetDist
<= curr_rt
->NetDist
) &&
627 (new_rt
.NetDist
< 16)) {
629 * found a shorter or more recent route,
630 * replace with the new entry
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
));
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
));
656 } /* end of main while */
662 int AURPupdateri(node
, m
)
667 RT_entry new_rt
, *old_rt
;
669 while (gbuf_len(m
) > 0) {
670 ev
= *gbuf_rptr(m
); /* event code */
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;
679 /* event tuple for non-extended network */
681 new_rt
.NetStop
= *(unsigned short *)gbuf_rptr(m
);
682 new_rt
.NetDist
= gbuf_rptr(m
)[2];
690 case AURPEV_NetAdded
:
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
));
703 if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
704 if (old_rt
->NetPort
== net_port
) {
706 * process this event as if it was an NDC event;
707 * update the route's distance
709 old_rt
->NetDist
= new_rt
.NetDist
;
712 l_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
));
730 case AURPEV_NetDeleted
:
731 case AURPEV_NetRouteChange
:
733 l_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
);
741 case AURPEV_NetDistChange
:
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
) {
748 * update the route's distance
750 old_rt
->NetDist
= new_rt
.NetDist
;
753 goto l_add
; /* process this event as if was an NA event */
756 case AURPEV_NetZoneChange
:
765 void AURPpurgeri(node
)
769 RT_entry
*entry
= (RT_entry
*)RT_table
;
772 * purge all routes associated with the tunnel peer
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
);
783 void AURPrtupdate(entry
, ev
)
787 unsigned char i
, node
, ev_len
, ev_tuple
[6];
789 aurp_state_t
*state
= (aurp_state_t
*)&aurp_state
[1];
790 int s
, msize
= sizeof(aurp_hdr_t
);
792 dPrintf(D_M_AURP
, D_L_TRACE
, ("AURPrtupdate: event=%d, net=[%d-%d]\n",
793 ev
, entry
->NetStart
, entry
->NetStop
));
796 * check that the network can be exported; if not,
797 * we must not make it visible beyond the local networks
800 for (i
=0; i
< net_access_cnt
; i
++) {
801 if ((net_access
[i
] == entry
->NetStart
) ||
802 (net_access
[i
] == entry
->NetStop
))
805 if (i
== net_access_cnt
)
808 for (i
=0; i
< net_access_cnt
; i
++) {
809 if ((net_access
[i
] == entry
->NetStart
) ||
810 (net_access
[i
] == entry
->NetStop
))
816 * create the update event tuple
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
;
825 *(unsigned short *)&ev_tuple
[1] = entry
->NetStop
;
826 ev_tuple
[3] = (entry
->NetDist
& 0x1F);
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) {
842 * we don't have the RI update buffer yet, allocate one
844 ATENABLE(s
, aurpgen_lock
);
845 if ((m
= (gbuf_t
*)gbuf_alloc(msize
+AURP_MaxPktSize
, PRI_HI
)) == 0)
847 ATDISABLE(s
, aurpgen_lock
);
854 * add the update event tuple to the RI update buffer;
855 * the RI update buffer will be sent when the periodic update
858 bcopy(ev_tuple
, gbuf_wptr(m
), ev_len
);
862 * if the RI update buffer is full, send the RI update now
864 if (gbuf_len(m
) > (AURP_MaxPktSize
-6)) {
865 ATENABLE(s
, aurpgen_lock
);
870 ATENABLE(s
, aurpgen_lock
);