2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1996 Apple Computer, Inc.
25 * Created April 8, 1996 by Tuyen Nguyen
26 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
30 #include <sys/errno.h>
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <machine/spl.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
37 #include <sys/filedesc.h>
38 #include <sys/fcntl.h>
40 #include <sys/socket.h>
41 #include <sys/socketvar.h>
44 #include <netat/sysglue.h>
45 #include <netat/appletalk.h>
46 #include <netat/at_var.h>
47 #include <netat/rtmp.h>
48 #include <netat/routing_tables.h>
49 #include <netat/at_pcb.h>
50 #include <netat/aurp.h>
51 #include <netat/debug.h>
54 void AURPsndRIAck(state
, m
, flags
)
59 unsigned short sequence_number
;
61 int msize
= sizeof(aurp_hdr_t
);
64 sequence_number
= ((aurp_hdr_t
*)gbuf_rptr(m
))->sequence_number
;
65 gbuf_wset(m
,sizeof(aurp_hdr_t
));
67 sequence_number
= state
->rcv_sequence_number
;
68 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) == 0)
73 /* construct the RI Ack packet */
74 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
75 hdrp
->connection_id
= state
->rcv_connection_id
;
76 hdrp
->sequence_number
= sequence_number
;
77 hdrp
->command_code
= AURPCMD_RIAck
;
81 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIAck: node=%d\n",
83 AURPsend(m
, AUD_AURP
, state
->rem_node
);
86 /* funneled version of AURPsndRIReq */
87 void AURPsndRIReq_funnel(state
)
90 thread_funnel_set(network_flock
, TRUE
);
92 thread_funnel_set(network_flock
, FALSE
);
96 void AURPsndRIReq(state
)
104 if (state
->rcv_state
== AURPSTATE_Unconnected
) {
107 if (state
->rcv_tmo
&& (state
->rcv_state
!= AURPSTATE_WaitingForRIRsp
)) {
111 msize
= sizeof(aurp_hdr_t
);
112 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) != 0) {
115 /* construct the RI request packet */
116 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
117 hdrp
->connection_id
= state
->rcv_connection_id
;
118 hdrp
->sequence_number
= 0;
119 hdrp
->command_code
= AURPCMD_RIReq
;
122 /* update state info */
123 state
->rcv_state
= AURPSTATE_WaitingForRIRsp
;
125 /* send the packet */
126 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIReq: node=%d\n",
128 AURPsend(m
, AUD_AURP
, state
->rem_node
);
131 /* start the retry timer */
132 timeout(AURPsndRIReq_funnel
, state
, AURP_RetryInterval
*HZ
);
136 /* funneled version of AURPsndRIRsp */
137 void AURPsndRIRsp_funnel(state
)
140 thread_funnel_set(network_flock
, TRUE
);
142 thread_funnel_set(network_flock
, FALSE
);
146 void AURPsndRIRsp(state
)
154 ATDISABLE(s
, aurpgen_lock
);
156 /* make sure we're in a valid state to send RI response */
157 if ((state
->snd_state
== AURPSTATE_Unconnected
) ||
158 (state
->snd_state
== AURPSTATE_WaitingForRIAck2
)) {
159 ATENABLE(s
, aurpgen_lock
);
163 /* update state info */
164 state
->snd_state
= AURPSTATE_WaitingForRIAck1
;
166 if (state
->rsp_m
== 0) {
167 ATENABLE(s
, aurpgen_lock
);
168 msize
= sizeof(aurp_hdr_t
);
169 if ((m
= (gbuf_t
*)gbuf_alloc(msize
+AURP_MaxPktSize
, PRI_MED
)) == 0) {
170 timeout(AURPsndRIRsp_funnel
, state
, AURP_RetryInterval
*HZ
);
177 /* construct the RI response packet */
178 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
179 hdrp
->connection_id
= state
->snd_connection_id
;
180 hdrp
->sequence_number
= state
->snd_sequence_number
;
181 hdrp
->command_code
= AURPCMD_RIRsp
;
184 /* get routing info of the local networks */
185 state
->snd_next_entry
= AURPgetri(
186 state
->snd_next_entry
, gbuf_wptr(m
), &len
);
189 /* set the last flag if this is the last response packet */
190 if (!state
->snd_next_entry
)
191 hdrp
->flags
= AURPFLG_LAST
;
194 /* keep a copy of the packet for retry */
195 m
= (gbuf_t
*)gbuf_dupb(state
->rsp_m
);
197 /* start the retry timer */
198 timeout(AURPsndRIRsp_funnel
, state
, AURP_RetryInterval
*HZ
);
202 ATENABLE(s
, aurpgen_lock
);
204 /* send the packet */
206 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIRsp: len=%d\n", len
));
207 AURPsend(m
, AUD_AURP
, state
->rem_node
);
212 void AURPsndRIUpd_funnel(state
)
215 thread_funnel_set(network_flock
, TRUE
);
217 thread_funnel_set(network_flock
, FALSE
);
221 void AURPsndRIUpd(state
)
229 ATDISABLE(s
, aurpgen_lock
);
231 /* make sure we're in a valid state to send update */
232 if (state
->snd_next_entry
|| (state
->upd_m
== 0) ||
233 (state
->snd_state
== AURPSTATE_Unconnected
) ||
234 (state
->snd_state
== AURPSTATE_WaitingForRIAck1
)) {
235 ATENABLE(s
, aurpgen_lock
);
239 /* update state info */
240 state
->snd_state
= AURPSTATE_WaitingForRIAck2
;
242 if (state
->snd_tmo
== 0) {
243 ATENABLE(s
, aurpgen_lock
);
244 msize
= sizeof(aurp_hdr_t
);
249 /* construct the RI update packet */
250 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
251 hdrp
->connection_id
= state
->snd_connection_id
;
252 hdrp
->sequence_number
= state
->snd_sequence_number
;
253 hdrp
->command_code
= AURPCMD_RIUpd
;
257 /* keep a copy of the packet for retry */
258 m
= (gbuf_t
*)gbuf_dupb(state
->upd_m
);
260 /* start the retry timer */
261 timeout(AURPsndRIUpd_funnel
, state
, AURP_RetryInterval
*HZ
);
265 ATENABLE(s
, aurpgen_lock
);
267 /* send the packet */
269 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIUpd: len=%d\n", len
));
270 AURPsend(m
, AUD_AURP
, state
->rem_node
);
276 void AURPrcvRIReq(state
, m
)
280 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
283 ATDISABLE(s
, aurpgen_lock
);
285 /* make sure we're in a valid state to accept it */
286 if ((state
->snd_state
== AURPSTATE_Unconnected
) ||
287 (state
->snd_state
== AURPSTATE_WaitingForRIAck2
)) {
288 ATENABLE(s
, aurpgen_lock
);
289 dPrintf(D_M_AURP
, D_L_WARNING
, ("AURPrcvRIReq: unexpected request\n"));
294 /* check for the correct connection id */
295 if (hdrp
->connection_id
!= state
->snd_connection_id
) {
296 ATENABLE(s
, aurpgen_lock
);
297 dPrintf(D_M_AURP
, D_L_WARNING
,
298 ("AURPrcvRIReq: invalid connection id, r=%d, m=%d\n",
299 hdrp
->connection_id
, state
->snd_connection_id
));
304 if (state
->snd_state
!= AURPSTATE_WaitingForRIAck1
) {
305 state
->snd_next_entry
= 0;
307 gbuf_freem(state
->rsp_m
);
310 ATENABLE(s
, aurpgen_lock
);
313 ATENABLE(s
, aurpgen_lock
);
319 void AURPrcvRIRsp(state
, m
)
323 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
326 ATDISABLE(s
, aurpgen_lock
);
328 /* make sure we're in a valid state to accept it */
329 if (state
->rcv_state
!= AURPSTATE_WaitingForRIRsp
) {
330 ATENABLE(s
, aurpgen_lock
);
331 dPrintf(D_M_AURP
, D_L_WARNING
, ("AURPrcvRIRsp: unexpected response\n"));
336 /* check for the correct connection id */
337 if (hdrp
->connection_id
!= state
->rcv_connection_id
) {
338 ATENABLE(s
, aurpgen_lock
);
339 dPrintf(D_M_AURP
, D_L_WARNING
,
340 ("AURPrcvRIRsp: invalid connection id, r=%d, m=%d\n",
341 hdrp
->connection_id
, state
->rcv_connection_id
));
346 /* check for the correct sequence number */
347 if (hdrp
->sequence_number
!= state
->rcv_sequence_number
) {
348 ATENABLE(s
, aurpgen_lock
);
349 if ( ((state
->rcv_sequence_number
== AURP_FirstSeqNum
) &&
350 (hdrp
->sequence_number
== AURP_LastSeqNum
)) ||
351 (hdrp
->sequence_number
== (state
->rcv_sequence_number
-1)) ) {
352 AURPsndRIAck(state
, m
, AURPFLG_SZI
);
354 dPrintf(D_M_AURP
, D_L_WARNING
,
355 ("AURPrcvRIRsp: invalid sequence number, r=%d, m=%d\n",
356 hdrp
->sequence_number
, state
->rcv_sequence_number
));
361 gbuf_rinc(m
,sizeof(*hdrp
));
362 if (hdrp
->flags
& AURPFLG_LAST
)
363 state
->rcv_state
= AURPSTATE_Connected
;
364 ATENABLE(s
, aurpgen_lock
);
366 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIRsp: len=%ld\n", gbuf_len(m
)));
368 /* cancel the retry timer */
369 untimeout(AURPsndRIReq_funnel
, state
);
373 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
375 /* update state info */
376 if (++state
->rcv_sequence_number
== 0)
377 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
379 /* process routing info of the tunnel peer */
380 if (AURPsetri(state
->rem_node
, m
)) {
381 dPrintf(D_M_AURP
, D_L_ERROR
, ("AURPrcvRIRsp: AURPsetri() error\n"));
385 /* set the get zone flag to get zone info later if required */
386 if (state
->rcv_state
== AURPSTATE_Connected
)
391 void AURPrcvRIUpd(state
, m
)
395 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
397 /* make sure we're in a valid state to accept it */
398 if (state
->rcv_state
== AURPSTATE_Unconnected
) {
399 dPrintf(D_M_AURP
, D_L_WARNING
, ("AURPrcvRIUpd: unexpected response\n"));
404 /* check for the correct connection id */
405 if (hdrp
->connection_id
!= state
->rcv_connection_id
) {
406 dPrintf(D_M_AURP
, D_L_WARNING
,
407 ("AURPrcvRIUpd: invalid connection id, r=%d, m=%d\n",
408 hdrp
->connection_id
, state
->rcv_connection_id
));
413 /* check for the correct sequence number */
414 if (hdrp
->sequence_number
!= state
->rcv_sequence_number
) {
415 if ( ((state
->rcv_sequence_number
== AURP_FirstSeqNum
) &&
416 (hdrp
->sequence_number
== AURP_LastSeqNum
)) ||
417 (hdrp
->sequence_number
== (state
->rcv_sequence_number
-1)) ) {
418 AURPsndRIAck(state
, m
, AURPFLG_SZI
);
420 dPrintf(D_M_AURP
, D_L_WARNING
,
421 ("AURPrcvRIUpd: invalid sequence number, r=%d, m=%d\n",
422 hdrp
->sequence_number
, state
->rcv_sequence_number
));
427 gbuf_rinc(m
,sizeof(*hdrp
));
429 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIUpd: len=%ld\n", gbuf_len(m
)));
432 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
434 /* update state info */
435 if (++state
->rcv_sequence_number
== 0)
436 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
438 /* process update routing info of the tunnel peer */
439 if (AURPupdateri(state
->rem_node
, m
)) {
440 dPrintf(D_M_AURP
, D_L_ERROR
, ("AURPrcvRIUpd: AURPupdateri() error\n"));
443 /* set the get zone flag to get zone info later if required */
450 void AURPrcvRIAck(state
, m
)
455 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
456 unsigned char snd_state
;
460 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIAck: state=%d\n",
462 ATDISABLE(s
, aurpgen_lock
);
464 /* make sure we're in a valid state to accept it */
465 snd_state
= state
->snd_state
;
466 if (((snd_state
== AURPSTATE_WaitingForRIAck1
) ||
467 (snd_state
== AURPSTATE_WaitingForRIAck2
)) &&
468 (hdrp
->sequence_number
== state
->snd_sequence_number
)) {
470 if (snd_state
== AURPSTATE_WaitingForRIAck1
) {
471 /* ack from the tunnel peer to our RI response */
472 untimeout(AURPsndRIRsp_funnel
, state
);
473 dat_m
= state
->rsp_m
;
477 /* ack from the tunnel peer to our RI update */
478 untimeout(AURPsndRIUpd_funnel
, state
);
479 dat_m
= state
->upd_m
;
484 gbuf_rinc(dat_m
,sizeof(aurp_hdr_t
));
486 /* increment the sequence number */
487 if (++state
->snd_sequence_number
== 0)
488 state
->snd_sequence_number
= AURP_FirstSeqNum
;
490 /* update state info */
491 state
->snd_state
= AURPSTATE_Connected
;
492 ATENABLE(s
, aurpgen_lock
);
494 if (state
->snd_next_entry
) /* more RI responses to send? */
497 /* check to see if we need to send ZI responses */
498 if (hdrp
->flags
& AURPFLG_SZI
)
499 AURPsndZRsp(state
, dat_m
, flag
);
503 ATENABLE(s
, aurpgen_lock
);
509 int AURPgetri(next_entry
, buf
, len
)
514 short entry_num
= next_entry
;
515 RT_entry
*entry
= (RT_entry
*)&RT_table
[next_entry
];
517 for (*len
=0; entry_num
< RT_maxentry
; entry_num
++,entry
++) {
518 if ((net_port
!= entry
->NetPort
) &&
519 !(entry
->AURPFlag
& AURP_NetHiden
)) {
520 if ((entry
->EntryState
& 0x0F) >= RTE_STATE_SUSPECT
) {
521 if (entry
->NetStart
) {
522 /* route info for extended network */
523 *(short *)buf
= entry
->NetStart
;
524 buf
+= sizeof(short);
525 *buf
++ = 0x80 | (entry
->NetDist
& 0x1F);
526 *(short *)buf
= entry
->NetStop
;
527 buf
+= sizeof(short);
531 /* route info for non-extended network */
532 *(short *)buf
= entry
->NetStop
;
533 buf
+= sizeof(short);
534 *buf
++ = (entry
->NetDist
& 0x1F);
539 if (*len
> AURP_MaxPktSize
)
543 return (entry_num
== RT_maxentry
) ? 0 : entry_num
;
547 int AURPsetri(node
, m
)
552 unsigned char *tuples_ptr
;
553 RT_entry new_rt
, *curr_rt
;
555 new_rt
.NextIRNet
= 0;
556 new_rt
.NextIRNode
= node
;
557 new_rt
.NetPort
= net_port
;
560 * Process all the tuples against our routing table
562 tuples_ptr
= (char *)gbuf_rptr(m
);
563 tuples_cnt
= (gbuf_len(m
))/3;
565 while (tuples_cnt
--) {
566 new_rt
.NetDist
= TUPLEDIST(tuples_ptr
) + 1;
567 new_rt
.EntryState
= RTE_STATE_GOOD
;
568 new_rt
.NetStart
= TUPLENET(tuples_ptr
);
570 if (tuples_ptr
[-1] & 0x80) {
571 new_rt
.NetStop
= TUPLENET((tuples_ptr
));
575 new_rt
.NetStop
= new_rt
.NetStart
;
578 if ((new_rt
.NetStop
== 0) || (new_rt
.NetStop
< new_rt
.NetStart
)) {
579 dPrintf(D_M_AURP
, D_L_WARNING
,
580 ("AURPsetri: %d, invalid tuple received [%d-%d]\n",
581 net_port
, new_rt
.NetStart
, new_rt
.NetStop
));
585 if ((curr_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
586 /* ignore loop if present */
587 if (curr_rt
->NetPort
!= net_port
)
590 if (new_rt
.NetDist
< 16) {
592 * check if the definition of the route has changed
594 if ((new_rt
.NetStop
!= curr_rt
->NetStop
) ||
595 (new_rt
.NetStart
!= curr_rt
->NetStart
)) {
596 if ((new_rt
.NetStop
== curr_rt
->NetStop
) &&
597 (new_rt
.NetStop
== curr_rt
->NetStart
) &&
598 (new_rt
.NetStart
== 0)) {
599 new_rt
.NetStart
= new_rt
.NetStop
;
600 } else if ((new_rt
.NetStop
== curr_rt
->NetStop
) &&
601 (new_rt
.NetStart
== new_rt
.NetStop
) &&
602 (curr_rt
->NetStart
== 0)) {
603 dPrintf(D_M_AURP
, D_L_WARNING
,
604 ("AURPsetri: [%d-%d] has changed to [%d-%d], Dist=%d\n",
605 curr_rt
->NetStart
, curr_rt
->NetStop
,
606 new_rt
.NetStart
, new_rt
.NetStop
, new_rt
.NetDist
));
609 dPrintf(D_M_AURP
, D_L_WARNING
,
610 ("AURPsetri: Net Conflict, Curr=[%d-%d], New=[%d-%d]\n",
611 curr_rt
->NetStart
,curr_rt
->NetStop
,
612 new_rt
.NetStart
,new_rt
.NetStop
));
613 zt_remove_zones(curr_rt
->ZoneBitMap
);
614 rt_delete(curr_rt
->NetStop
, curr_rt
->NetStart
);
620 if ((new_rt
.NetDist
<= curr_rt
->NetDist
) &&
621 (new_rt
.NetDist
< 16)) {
623 * found a shorter or more recent route,
624 * replace with the new entry
626 curr_rt
->NetDist
= new_rt
.NetDist
;
627 curr_rt
->NextIRNode
= new_rt
.NextIRNode
;
628 dPrintf(D_M_AURP_LOW
,D_L_INFO
,
629 ("AURPsetri: shorter route found [%d-%d], update\n",
630 new_rt
.NetStart
,new_rt
.NetStop
));
633 } else { /* no entry found */
634 if (new_rt
.NetDist
< 16) {
635 new_rt
.EntryState
= RTE_STATE_GOOD
;
636 dPrintf(D_M_AURP
, D_L_INFO
,
637 ("AURPsetri: new_rt [%d-%d], tuple #%d\n",
638 new_rt
.NetStart
, new_rt
.NetStop
, tuples_cnt
));
639 if (rt_insert(new_rt
.NetStop
, new_rt
.NetStart
,
640 new_rt
.NextIRNet
, new_rt
.NextIRNode
,
641 new_rt
.NetDist
, new_rt
.NetPort
,
642 new_rt
.EntryState
) == (RT_entry
*)0) {
643 dPrintf(D_M_AURP
,D_L_ERROR
,
644 ("AURPsetri: RTMP table full [%d-%d]\n",
645 new_rt
.NetStart
,new_rt
.NetStop
));
650 } /* end of main while */
656 int AURPupdateri(node
, m
)
661 RT_entry new_rt
, *old_rt
;
663 while (gbuf_len(m
) > 0) {
664 ev
= *gbuf_rptr(m
); /* event code */
666 if (gbuf_rptr(m
)[2] & 0x80) {
667 /* event tuple for extended network */
668 new_rt
.NetStart
= *(unsigned short *)gbuf_rptr(m
);
669 new_rt
.NetStop
= *(unsigned short *)&gbuf_rptr(m
)[3];
670 new_rt
.NetDist
= gbuf_rptr(m
)[2] & 0x7f;
673 /* event tuple for non-extended network */
675 new_rt
.NetStop
= *(unsigned short *)gbuf_rptr(m
);
676 new_rt
.NetDist
= gbuf_rptr(m
)[2];
684 case AURPEV_NetAdded
:
686 new_rt
.NextIRNet
= 0;
687 new_rt
.NextIRNode
= node
;
688 new_rt
.NetPort
= net_port
;
689 if ((new_rt
.NetDist
== 0) || (new_rt
.NetStop
== 0) ||
690 (new_rt
.NetStop
< new_rt
.NetStart
)) {
691 dPrintf(D_M_AURP
,D_L_WARNING
,
692 ("AURPupdateri: %d, invalid NetAdded received [%d-%d]\n",
693 net_port
, new_rt
.NetStart
, new_rt
.NetStop
));
697 if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
698 if (old_rt
->NetPort
== net_port
) {
700 * process this event as if it was an NDC event;
701 * update the route's distance
703 old_rt
->NetDist
= new_rt
.NetDist
;
706 l_add
: if ((new_rt
.NetDist
< 16) && (new_rt
.NetDist
!= NOTIFY_N_DIST
)) {
707 new_rt
.EntryState
= RTE_STATE_GOOD
;
708 dPrintf(D_M_AURP
, D_L_INFO
,
709 ("AURPupdateri: NetAdded [%d-%d]\n",
710 new_rt
.NetStart
, new_rt
.NetStop
));
711 if (rt_insert(new_rt
.NetStop
, new_rt
.NetStart
,
712 new_rt
.NextIRNet
, new_rt
.NextIRNode
,
713 new_rt
.NetDist
, new_rt
.NetPort
,
714 new_rt
.EntryState
) == (RT_entry
*)0) {
715 dPrintf(D_M_AURP
, D_L_WARNING
,
716 ("AURPupdateri: RTMP table full [%d-%d]\n",
717 new_rt
.NetStart
,new_rt
.NetStop
));
724 case AURPEV_NetDeleted
:
725 case AURPEV_NetRouteChange
:
727 l_delete
: if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
728 if (old_rt
->NetPort
== net_port
) {
729 zt_remove_zones(old_rt
->ZoneBitMap
);
730 rt_delete(old_rt
->NetStop
, old_rt
->NetStart
);
735 case AURPEV_NetDistChange
:
737 if (new_rt
.NetDist
== 15)
738 goto l_delete
; /* process this event as if was an ND event */
739 if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
740 if (old_rt
->NetPort
== net_port
) {
742 * update the route's distance
744 old_rt
->NetDist
= new_rt
.NetDist
;
747 goto l_add
; /* process this event as if was an NA event */
750 case AURPEV_NetZoneChange
:
759 void AURPpurgeri(node
)
763 RT_entry
*entry
= (RT_entry
*)RT_table
;
766 * purge all routes associated with the tunnel peer
768 for (entry_num
=0; entry_num
< RT_maxentry
; entry_num
++,entry
++) {
769 if ((net_port
== entry
->NetPort
) && (node
== entry
->NextIRNode
)) {
770 zt_remove_zones(entry
->ZoneBitMap
);
771 rt_delete(entry
->NetStop
, entry
->NetStart
);
777 void AURPrtupdate(entry
, ev
)
781 unsigned char i
, node
, ev_len
, ev_tuple
[6];
783 aurp_state_t
*state
= (aurp_state_t
*)&aurp_state
[1];
784 int s
, msize
= sizeof(aurp_hdr_t
);
786 dPrintf(D_M_AURP
, D_L_TRACE
, ("AURPrtupdate: event=%d, net=[%d-%d]\n",
787 ev
, entry
->NetStart
, entry
->NetStop
));
790 * check that the network can be exported; if not,
791 * we must not make it visible beyond the local networks
794 for (i
=0; i
< net_access_cnt
; i
++) {
795 if ((net_access
[i
] == entry
->NetStart
) ||
796 (net_access
[i
] == entry
->NetStop
))
799 if (i
== net_access_cnt
)
802 for (i
=0; i
< net_access_cnt
; i
++) {
803 if ((net_access
[i
] == entry
->NetStart
) ||
804 (net_access
[i
] == entry
->NetStop
))
810 * create the update event tuple
812 ev_tuple
[0] = ev
; /* event code */
813 if (entry
->NetStart
) {
814 *(unsigned short *)&ev_tuple
[1] = entry
->NetStart
;
815 ev_tuple
[3] = 0x80 | (entry
->NetDist
& 0x1F);
816 *(unsigned short *)&ev_tuple
[4] = entry
->NetStop
;
819 *(unsigned short *)&ev_tuple
[1] = entry
->NetStop
;
820 ev_tuple
[3] = (entry
->NetDist
& 0x1F);
824 for (node
=1; node
<= dst_addr_cnt
; node
++, state
++) {
825 if ((ev
== AURPEV_NetAdded
) &&
826 (!(state
->snd_sui
& AURPFLG_NA
))) continue;
827 if ((ev
== AURPEV_NetDeleted
) &&
828 (!(state
->snd_sui
& AURPFLG_ND
))) continue;
829 if ((ev
== AURPEV_NetDistChange
) &&
830 (!(state
->snd_sui
& AURPFLG_NDC
))) continue;
831 ATDISABLE(s
, aurpgen_lock
);
832 if ((state
->snd_state
!= AURPSTATE_Unconnected
) &&
833 (state
->snd_state
!= AURPSTATE_WaitingForRIAck2
)) {
834 if ((m
= state
->upd_m
) == 0) {
836 * we don't have the RI update buffer yet, allocate one
838 ATENABLE(s
, aurpgen_lock
);
839 if ((m
= (gbuf_t
*)gbuf_alloc(msize
+AURP_MaxPktSize
, PRI_HI
)) == 0)
841 ATDISABLE(s
, aurpgen_lock
);
848 * add the update event tuple to the RI update buffer;
849 * the RI update buffer will be sent when the periodic update
852 bcopy(ev_tuple
, gbuf_wptr(m
), ev_len
);
856 * if the RI update buffer is full, send the RI update now
858 if (gbuf_len(m
) > (AURP_MaxPktSize
-6)) {
859 ATENABLE(s
, aurpgen_lock
);
864 ATENABLE(s
, aurpgen_lock
);