]> git.saurik.com Git - apple/xnu.git/blob - bsd/netat/aurp_ri.c
b1344f79ddbcb0fcd32d2443b122af8a4aec8123
[apple/xnu.git] / bsd / netat / aurp_ri.c
1 /*
2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
5 *
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
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
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.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30 /*
31 * Copyright (c) 1996 Apple Computer, Inc.
32 *
33 * Created April 8, 1996 by Tuyen Nguyen
34 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
35 *
36 * File: ri.c
37 */
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>
44 #include <sys/proc.h>
45 #include <sys/filedesc.h>
46 #include <sys/fcntl.h>
47 #include <sys/mbuf.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
50 #include <net/if.h>
51
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>
60
61
62 static void AURPsndRIRsp(aurp_state_t *);
63
64 /* */
65 void AURPsndRIAck(state, m, flags)
66 aurp_state_t *state;
67 gbuf_t *m;
68 unsigned short flags;
69 {
70 unsigned short sequence_number;
71 aurp_hdr_t *hdrp;
72 int msize = sizeof(aurp_hdr_t);
73
74 if (m) {
75 sequence_number = ((aurp_hdr_t *)gbuf_rptr(m))->sequence_number;
76 gbuf_wset(m,sizeof(aurp_hdr_t));
77 } else {
78 sequence_number = state->rcv_sequence_number;
79 if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) == 0)
80 return;
81 gbuf_wset(m,msize);
82 }
83
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;
89 hdrp->flags = flags;
90
91 /* send the packet */
92 dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIAck: node=%d\n",
93 state->rem_node));
94 AURPsend(m, AUD_AURP, state->rem_node);
95 }
96
97 /* locked version of AURPsndRIReq */
98 void AURPsndRIReq_locked(state)
99 aurp_state_t *state;
100 {
101 atalk_lock();
102 AURPsndRIReq(state);
103 atalk_unlock();
104 }
105
106 /* */
107 void AURPsndRIReq(state)
108 aurp_state_t *state;
109 {
110 int msize;
111 gbuf_t *m;
112 aurp_hdr_t *hdrp;
113
114
115 if (state->rcv_state == AURPSTATE_Unconnected) {
116 return;
117 }
118 if (state->rcv_tmo && (state->rcv_state != AURPSTATE_WaitingForRIRsp)) {
119 return;
120 }
121
122 msize = sizeof(aurp_hdr_t);
123 if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) != 0) {
124 gbuf_wset(m,msize);
125
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;
131 hdrp->flags = 0;
132
133 /* update state info */
134 state->rcv_state = AURPSTATE_WaitingForRIRsp;
135
136 /* send the packet */
137 dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIReq: node=%d\n",
138 state->rem_node));
139 AURPsend(m, AUD_AURP, state->rem_node);
140 }
141
142 /* start the retry timer */
143 timeout(AURPsndRIReq_locked, state, AURP_RetryInterval*HZ);
144 state->rcv_tmo = 1;
145 }
146
147 /* locked version of AURPsndRIRsp */
148 void AURPsndRIRsp_locked(state)
149 aurp_state_t *state;
150 {
151 atalk_lock();
152 AURPsndRIRsp(state);
153 atalk_unlock();
154 }
155
156 /* */
157 void AURPsndRIRsp(state)
158 aurp_state_t *state;
159 {
160 gbuf_t *m;
161 aurp_hdr_t *hdrp;
162 short len = 0;
163 int s, msize = 0;
164
165 ATDISABLE(s, aurpgen_lock);
166
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);
171 return;
172 }
173
174 /* update state info */
175 state->snd_state = AURPSTATE_WaitingForRIAck1;
176
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);
182 state->snd_tmo = 1;
183 return;
184 }
185 gbuf_wset(m,msize);
186 state->rsp_m = m;
187
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;
193 hdrp->flags = 0;
194
195 /* get routing info of the local networks */
196 state->snd_next_entry = AURPgetri(
197 state->snd_next_entry, gbuf_wptr(m), &len);
198 gbuf_winc(m,len);
199
200 /* set the last flag if this is the last response packet */
201 if (!state->snd_next_entry)
202 hdrp->flags = AURPFLG_LAST;
203 }
204
205 /* keep a copy of the packet for retry */
206 m = (gbuf_t *)gbuf_dupb(state->rsp_m);
207
208 /* start the retry timer */
209 timeout(AURPsndRIRsp_locked, state, AURP_RetryInterval*HZ);
210 state->snd_tmo = 1;
211
212 if (msize == 0)
213 ATENABLE(s, aurpgen_lock);
214
215 /* send the packet */
216 if (m) {
217 dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIRsp: len=%d\n", len));
218 AURPsend(m, AUD_AURP, state->rem_node);
219 }
220
221 }
222
223 void AURPsndRIUpd_locked(state)
224 aurp_state_t *state;
225 {
226 atalk_lock();
227 AURPsndRIUpd(state);
228 atalk_unlock();
229 }
230
231 /* */
232 void AURPsndRIUpd(state)
233 aurp_state_t *state;
234 {
235 gbuf_t *m;
236 aurp_hdr_t *hdrp;
237 short len = 0;
238 int s, msize = 0;
239
240 ATDISABLE(s, aurpgen_lock);
241
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);
247 return;
248 }
249
250 /* update state info */
251 state->snd_state = AURPSTATE_WaitingForRIAck2;
252
253 if (state->snd_tmo == 0) {
254 ATENABLE(s, aurpgen_lock);
255 msize = sizeof(aurp_hdr_t);
256 m = state->upd_m;
257 len = gbuf_len(m);
258 gbuf_rdec(m,msize);
259
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;
265 hdrp->flags = 0;
266 }
267
268 /* keep a copy of the packet for retry */
269 m = (gbuf_t *)gbuf_dupb(state->upd_m);
270
271 /* start the retry timer */
272 timeout(AURPsndRIUpd_locked, state, AURP_RetryInterval*HZ);
273 state->snd_tmo = 1;
274
275 if (msize == 0)
276 ATENABLE(s, aurpgen_lock);
277
278 /* send the packet */
279 if (m) {
280 dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIUpd: len=%d\n", len));
281 AURPsend(m, AUD_AURP, state->rem_node);
282 }
283
284 }
285
286 /* */
287 void AURPrcvRIReq(state, m)
288 aurp_state_t *state;
289 gbuf_t *m;
290 {
291 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
292 int s;
293
294 ATDISABLE(s, aurpgen_lock);
295
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"));
301 gbuf_freem(m);
302 return;
303 }
304
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));
311 gbuf_freem(m);
312 return;
313 }
314
315 if (state->snd_state != AURPSTATE_WaitingForRIAck1) {
316 state->snd_next_entry = 0;
317 if (state->rsp_m) {
318 gbuf_freem(state->rsp_m);
319 state->rsp_m = 0;
320 }
321 ATENABLE(s, aurpgen_lock);
322 AURPsndRIRsp(state);
323 } else
324 ATENABLE(s, aurpgen_lock);
325
326 gbuf_freem(m);
327 }
328
329 /* */
330 void AURPrcvRIRsp(state, m)
331 aurp_state_t *state;
332 gbuf_t *m;
333 {
334 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
335 int s;
336
337 ATDISABLE(s, aurpgen_lock);
338
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"));
343 gbuf_freem(m);
344 return;
345 }
346
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));
353 gbuf_freem(m);
354 return;
355 }
356
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);
364 } else {
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));
368 gbuf_freem(m);
369 }
370 return;
371 }
372 gbuf_rinc(m,sizeof(*hdrp));
373 if (hdrp->flags & AURPFLG_LAST)
374 state->rcv_state = AURPSTATE_Connected;
375 ATENABLE(s, aurpgen_lock);
376
377 dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIRsp: len=%ld\n", gbuf_len(m)));
378
379 /* cancel the retry timer */
380 untimeout(AURPsndRIReq_locked, state);
381 state->rcv_tmo = 0;
382
383 /* send RI ack */
384 AURPsndRIAck(state, 0, AURPFLG_SZI);
385
386 /* update state info */
387 if (++state->rcv_sequence_number == 0)
388 state->rcv_sequence_number = AURP_FirstSeqNum;
389
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"));
393 }
394 gbuf_freem(m);
395
396 /* set the get zone flag to get zone info later if required */
397 if (state->rcv_state == AURPSTATE_Connected)
398 state->get_zi = 1;
399 }
400
401 /* */
402 void AURPrcvRIUpd(state, m)
403 aurp_state_t *state;
404 gbuf_t *m;
405 {
406 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
407
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"));
411 gbuf_freem(m);
412 return;
413 }
414
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));
420 gbuf_freem(m);
421 return;
422 }
423
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);
430 } else {
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));
434 gbuf_freem(m);
435 }
436 return;
437 }
438 gbuf_rinc(m,sizeof(*hdrp));
439
440 dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIUpd: len=%ld\n", gbuf_len(m)));
441
442 /* send RI ack */
443 AURPsndRIAck(state, 0, AURPFLG_SZI);
444
445 /* update state info */
446 if (++state->rcv_sequence_number == 0)
447 state->rcv_sequence_number = AURP_FirstSeqNum;
448
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"));
452 }
453
454 /* set the get zone flag to get zone info later if required */
455 state->get_zi = 1;
456
457 gbuf_freem(m);
458 }
459
460 /* */
461 void AURPrcvRIAck(state, m)
462 aurp_state_t *state;
463 gbuf_t *m;
464 {
465 gbuf_t *dat_m;
466 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
467 unsigned char snd_state;
468 int s;
469 int flag;
470
471 dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIAck: state=%d\n",
472 state->snd_state));
473 ATDISABLE(s, aurpgen_lock);
474
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)) {
480
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;
485 state->rsp_m = 0;
486 flag = 1;
487 } else {
488 /* ack from the tunnel peer to our RI update */
489 untimeout(AURPsndRIUpd_locked, state);
490 dat_m = state->upd_m;
491 state->upd_m = 0;
492 flag = 2;
493 }
494 state->snd_tmo = 0;
495 gbuf_rinc(dat_m,sizeof(aurp_hdr_t));
496
497 /* increment the sequence number */
498 if (++state->snd_sequence_number == 0)
499 state->snd_sequence_number = AURP_FirstSeqNum;
500
501 /* update state info */
502 state->snd_state = AURPSTATE_Connected;
503 ATENABLE(s, aurpgen_lock);
504
505 if (state->snd_next_entry) /* more RI responses to send? */
506 AURPsndRIRsp(state);
507
508 /* check to see if we need to send ZI responses */
509 if (hdrp->flags & AURPFLG_SZI)
510 AURPsndZRsp(state, dat_m, flag);
511 else if (dat_m)
512 gbuf_freem(dat_m);
513 } else
514 ATENABLE(s, aurpgen_lock);
515
516 gbuf_freem(m);
517 }
518
519 /* */
520 int AURPgetri(next_entry, buf, len)
521 short next_entry;
522 unsigned char *buf;
523 short *len;
524 {
525 short entry_num = next_entry;
526 RT_entry *entry = (RT_entry *)&RT_table[next_entry];
527
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);
539 *buf++ = 0;
540 *len += 6;
541 } else {
542 /* route info for non-extended network */
543 *(short *)buf = entry->NetStop;
544 buf += sizeof(short);
545 *buf++ = (entry->NetDist & 0x1F);
546 *len += 3;
547 }
548 }
549 }
550 if (*len > AURP_MaxPktSize)
551 break;
552 }
553
554 return (entry_num == RT_maxentry) ? 0 : entry_num;
555 }
556
557 /* */
558 int AURPsetri(node, m)
559 unsigned char node;
560 gbuf_t *m;
561 {
562 int tuples_cnt;
563 unsigned char *tuples_ptr;
564 RT_entry new_rt, *curr_rt;
565
566 new_rt.NextIRNet = 0;
567 new_rt.NextIRNode = node;
568 new_rt.NetPort = net_port;
569
570 /*
571 * Process all the tuples against our routing table
572 */
573 tuples_ptr = (char *)gbuf_rptr(m);
574 tuples_cnt = (gbuf_len(m))/3;
575
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);
580 tuples_ptr += 3;
581 if (tuples_ptr[-1] & 0x80) {
582 new_rt.NetStop = TUPLENET((tuples_ptr));
583 tuples_ptr += 3;
584 tuples_cnt--;
585 } else {
586 new_rt.NetStop = new_rt.NetStart;
587 new_rt.NetStart = 0;
588 }
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));
593 continue;
594 }
595
596 if ((curr_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
597 /* ignore loop if present */
598 if (curr_rt->NetPort != net_port)
599 continue;
600
601 if (new_rt.NetDist < 16) {
602 /*
603 * check if the definition of the route has changed
604 */
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));
618 new_rt.NetStart = 0;
619 } else {
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);
626 continue;
627 }
628 }
629 }
630
631 if ((new_rt.NetDist <= curr_rt->NetDist) &&
632 (new_rt.NetDist < 16)) {
633 /*
634 * found a shorter or more recent route,
635 * replace with the new entry
636 */
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));
642 }
643
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));
657 return -1;
658 }
659 }
660 }
661 } /* end of main while */
662
663 return 0;
664 }
665
666 /* */
667 int AURPupdateri(node, m)
668 unsigned char node;
669 gbuf_t *m;
670 {
671 char ev, ev_len;
672 RT_entry new_rt, *old_rt;
673
674 while (gbuf_len(m) > 0) {
675 ev = *gbuf_rptr(m); /* event code */
676 gbuf_rinc(m,1);
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;
682 ev_len = 5;
683 } else {
684 /* event tuple for non-extended network */
685 new_rt.NetStart = 0;
686 new_rt.NetStop = *(unsigned short *)gbuf_rptr(m);
687 new_rt.NetDist = gbuf_rptr(m)[2];
688 ev_len = 3;
689 }
690
691 switch (ev) {
692 case AURPEV_Null:
693 break;
694
695 case AURPEV_NetAdded:
696 gbuf_rinc(m,ev_len);
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));
705 break;
706 }
707
708 if ((old_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
709 if (old_rt->NetPort == net_port) {
710 /*
711 * process this event as if it was an NDC event;
712 * update the route's distance
713 */
714 old_rt->NetDist = new_rt.NetDist;
715 }
716 } else {
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));
729 return 0;
730 }
731 }
732 }
733 break;
734
735 case AURPEV_NetDeleted:
736 case AURPEV_NetRouteChange:
737 gbuf_rinc(m,ev_len);
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);
742 }
743 }
744 break;
745
746 case AURPEV_NetDistChange:
747 gbuf_rinc(m,ev_len);
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) {
752 /*
753 * update the route's distance
754 */
755 old_rt->NetDist = new_rt.NetDist;
756 }
757 } else
758 goto l_add; /* process this event as if was an NA event */
759 break;
760
761 case AURPEV_NetZoneChange:
762 break;
763 }
764 }
765
766 return 0;
767 }
768
769 /* */
770 void AURPpurgeri(node)
771 unsigned char node;
772 {
773 short entry_num;
774 RT_entry *entry = (RT_entry *)RT_table;
775
776 /*
777 * purge all routes associated with the tunnel peer
778 */
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);
783 }
784 }
785 }
786
787 /* */
788 void AURPrtupdate(entry, ev)
789 RT_entry *entry;
790 unsigned char ev;
791 {
792 unsigned char i, node, ev_len, ev_tuple[6];
793 gbuf_t *m;
794 aurp_state_t *state = (aurp_state_t *)&aurp_state[1];
795 int s, msize = sizeof(aurp_hdr_t);
796
797 dPrintf(D_M_AURP, D_L_TRACE, ("AURPrtupdate: event=%d, net=[%d-%d]\n",
798 ev, entry->NetStart, entry->NetStop));
799
800 /*
801 * check that the network can be exported; if not,
802 * we must not make it visible beyond the local networks
803 */
804 if (net_export) {
805 for (i=0; i < net_access_cnt; i++) {
806 if ((net_access[i] == entry->NetStart) ||
807 (net_access[i] == entry->NetStop))
808 break;
809 }
810 if (i == net_access_cnt)
811 return;
812 } else {
813 for (i=0; i < net_access_cnt; i++) {
814 if ((net_access[i] == entry->NetStart) ||
815 (net_access[i] == entry->NetStop))
816 return;
817 }
818 }
819
820 /*
821 * create the update event tuple
822 */
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;
828 ev_len = 6;
829 } else {
830 *(unsigned short *)&ev_tuple[1] = entry->NetStop;
831 ev_tuple[3] = (entry->NetDist & 0x1F);
832 ev_len = 4;
833 }
834
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) {
846 /*
847 * we don't have the RI update buffer yet, allocate one
848 */
849 ATENABLE(s, aurpgen_lock);
850 if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_HI)) == 0)
851 continue;
852 ATDISABLE(s, aurpgen_lock);
853 state->upd_m = m;
854 gbuf_rinc(m,msize);
855 gbuf_wset(m,0);
856 }
857
858 /*
859 * add the update event tuple to the RI update buffer;
860 * the RI update buffer will be sent when the periodic update
861 * timer expires
862 */
863 bcopy(ev_tuple, gbuf_wptr(m), ev_len);
864 gbuf_winc(m,ev_len);
865
866 /*
867 * if the RI update buffer is full, send the RI update now
868 */
869 if (gbuf_len(m) > (AURP_MaxPktSize-6)) {
870 ATENABLE(s, aurpgen_lock);
871 AURPsndRIUpd(state);
872 continue;
873 }
874 }
875 ATENABLE(s, aurpgen_lock);
876 }
877 }