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