Annotation of XNU/bsd/netat/aurp_ri.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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