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