Annotation of kernel/bsd/netat/aurp_ri.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.