⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spantask.c

📁 基于vxworks操作系统,Tornado2.0平台,生成树STP源码.直接在其对应的设备中添加即可.
💻 C
📖 第 1 页 / 共 4 页
字号:
    if ( spanClDescTbl[0].memArea == NULL)
    {
        perror("spanTask: Memory for buffers unavailable");
        cfree( (char *)SpanDrvCtrl->pNetPool );
        cfree( (char *)SpanDrvCtrl->muxInfo );
        cfree( (char *)SpanDrvCtrl );
        return ERROR;
    }

    if (netPoolInit(SpanDrvCtrl->pNetPool, &spanMclConfig,
                    &spanClDescTbl[0], spanClDescTblNumEnt, NULL) == ERROR)
    {
        perror("spanTask: Could not init buffers");
        cfree( (char *)spanClDescTbl[0].memArea );
        cfree( (char *)SpanDrvCtrl->pNetPool );
        cfree( (char *)SpanDrvCtrl->muxInfo );
        cfree( (char *)SpanDrvCtrl );
        return ERROR;
    }
    /* Store the cluster pool id as others need it later. */
    SpanDrvCtrl->pClPoolId = clPoolIdGet(SpanDrvCtrl->pNetPool,
                                         SPAN_BUFSIZ, FALSE);
    if (SpanDrvCtrl->pClPoolId == NULL) {
        cfree( (char *)spanClDescTbl[0].memArea );
        cfree( (char *)SpanDrvCtrl->pNetPool );
        cfree( (char *)SpanDrvCtrl->muxInfo );
        cfree( (char *)SpanDrvCtrl );
        return ERROR;
    }

    /* LACP/STP/GARP intergation */
    if ( stpPortBitmask(INIT_BITMAP, SpanDrvCtrl->numPorts) == ERROR )
    {
        cfree( (char *)spanClDescTbl[0].memArea );
        cfree( (char *)SpanDrvCtrl->pNetPool );
        cfree( (char *)SpanDrvCtrl->muxInfo );
        cfree( (char *)SpanDrvCtrl );
        return ERROR;
    }
 
#ifdef DEBUGGER_SYNC
    span_debug_sync_sem = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
#endif
    span_task_sem = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
 
    /* Start up the Spanning Tree Timer Task */
    sprintf(tName, "%sTimer", appName);
    taskSpawn(tName,
              30,  
              0,
              (3 * 1024),  
              stpTimerTask,
              (int)appName, (int)arg1, (int)arg2, 0, 0, 0, 0, 0, 0, 0);

    return OK;
}

/*******************************************************************************
* stpTimerTask  - Spanning Tree timer task
*
* This is the Spanning Tree timer task.
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
LOCAL STATUS stpTimerTask
    (
    char * appName,
    void * arg1,
    void * arg2
    )
{
    ulong_t err;
    ulong_t i;
    ulong_t errCnt;
    char    tName[16];

#if 0
    {
    void sysPauseTask( char *, int );
    sysPauseTask("in stpTimerTask", 30);
    }
#endif

#ifdef DEBUGGER_SYNC
    semTake(span_debug_sync_sem, WAIT_FOREVER);     /* wait for sync from windSh */
#endif
 
    /* wait on it */
    /* aaaa appManagerWait( (APP_MANAGER_NVM | APP_MANAGER_IDB | APP_MANAGER_DRIVER),
            APP_MANAGER_WAIT_FOREVER); */

 
 

     /* Obtain the real Bridge Priority, get_stp_priority() host order. */
    SpanDrvCtrl->bridge_id.priority = htons((ushort_t)apCfgStpPriorityGet());
    memcpy((char *)&bridge_info.bridge_id,(char *)&SpanDrvCtrl->bridge_id, sizeof(Identifier));

    bridge_info.bridge_max_age = apCfgStpMaxAgeGet();
    bridge_info.bridge_hello_time = apCfgStpHelloTimeGet(); 
    bridge_info.bridge_forward_delay = apCfgStpForwardDelayGet(); 
    bridge_info.hold_time = (ushort_t)get_stp_hold_time();

    bridge_info.topology_change_time =
        bridge_info.bridge_max_age + bridge_info.bridge_forward_delay;
 
    /* Need to initialize Port_id in the infos */
    for (i = One; i <= SpanDrvCtrl->numPorts; i++)
    { 
        port_info[i].path_cost = apCfgStpPortPathCostGet(i);   
        port_info[i].protocol_enabled = apCfgStpPortEnableGet(i);

        /* Force to highest value. */
        memset((char *)&port_info[i].designated_root, 0xff, sizeof(Identifier));

#if (FORCE_PRIORITY_ZERO > 0)
        port_info[i].port_id = i;
#else
        port_info[i].port_id = (ushort_t) ((apCfgStpPortPriorityGet(i) << 8) | i);
#endif
    }
    Span_Queue = msgQCreate(SPAN_MSG_COUNT, sizeof(span_msg_t), MSG_Q_FIFO);
	set_span_tree_enable(True);    /*aaaa*/
 
    SpanDrvCtrl->spanInitialized = True;

    /* Start up the Spanning Tree Receive Task */
    sprintf(tName, "%sRecv", appName);
    taskSpawn(tName,
              35,  
              0,
              (5 * 1024),  
              stpRecvTask,
              (int)appName, (int)arg1, (int)arg2, 0, 0, 0, 0, 0, 0, 0);

    semGive(span_task_sem);     /* Allow the receive task to run */

    /* Next 3 lines; Fix for PR# 1393 */
    taskDelay( sysClkRateGet() );
    if(True == get_stp_global_enable())
        stpQSend( SPAN_ON, (void *)0, 0 );
 
    for (i = One; i <= SpanDrvCtrl->numPorts; i++){
	 set_stp_port_enable(i,1,False);
	set_stp_port_enable(i,1,True); 	 
	}


    /* Spanning Tree forever loop. */
    for (errCnt = 0;;)
    {
        taskDelay( sysClkRateGet() );

        /*
         * Send a special message to the receive task to process a
         * timer tick. If the port is SPAN_TIMER_TICK it is
         * a special message meaning a STP tick.
         */
        err = (ulong_t)stpQSend( SPAN_TIMER_TICK, (void *)0, 0 );
        if (err)
        {
            printf("stpTimerTask: Timer Tick send failed.\n");
            if ( ++errCnt > 25 )
                break;              /* we had 25 errors in a row */
        }
        else
            errCnt = 0;

    }

    printf("stpTimerTask: Exiting.\n");
    return ERROR;
}

/*******************************************************************************
* stpRecvTask  - Handle all of the receive messages.
*
* This routine loops forever parsing and processing messages. 
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
/* ARGSUSED */
LOCAL STATUS stpRecvTask
    (
    char * appName,
    void * arg1,
    void * arg2
    )
{
    STATUS status;
    ulong_t port;
    M_BLK_ID pMblk;
    span_msg_t Message;
    ulong_t i;
    ulong_t one_time;

#if 0
    {
    void sysPauseTask( char *, int );
    sysPauseTask("in stpRecvTask", 30);
    }
#endif

    semTake(span_task_sem, WAIT_FOREVER);   /* wait for sync from timer task */

    one_time = 0;
    for (;;)
    {
        /* Wait for a message from span_tick_task or received BPDUs. */
        status = msgQReceive(Span_Queue,
                             (void *) &Message,
                             sizeof(span_msg_t),
                             WAIT_FOREVER);
        if ( status == ERROR )
            break;

        switch (Message.code)
        {
        case SPAN_ON:
            /* Enable Spanning Tree at this point. */
            span_init();
            break;

        case SPAN_OFF:
            /* Set all ports to forwarding, spanning tree is disabled. */
            for (i = One; i <= SpanDrvCtrl->numPorts; i++)
            {
                if (get_stp_port_state(i) != 0)
                    set_port_state((int)i, Forwarding);
            }

            /* Set a flag to tell us what state spanning tree is in. */
            SpanDrvCtrl->spanState = False;
            break;

        case SPAN_TIMER_TICK:
            if ( one_time == 0 )
            {
                if ( SpanDrvCtrl->spanState == False )
                {
                    /* Set all ports to forwarding, spanning tree is disabled. */
                    for (i = One; i <= SpanDrvCtrl->numPorts; i++)
                        set_port_state((int)i, Forwarding);
                }
                one_time = 1;
                /* aaaa appManagerSet(APP_MANAGER_STP); */
            }
            if (SpanDrvCtrl->spanState == True)
                span_tick();
            break;

        case SPAN_RX_BPDU:
            pMblk = (M_BLK_ID) Message.data;
            if (SpanDrvCtrl->spanState == True)
            {	
                /*
                 * Port number is in the upper 16 bits of extra word. The
                 * port number is zero based must be bumped for STP.
                 */
		Port_data *tmp=Message.extra;
                port = (unsigned char)(tmp->port_id & 0xff);  
                if ( port <= SpanDrvCtrl->numPorts )
                {
			unsigned char *p=(unsigned char *)pMblk->mBlkHdr.mData;  
                    if (port_info[port].protocol_enabled == True)
                        span_process((Bpdu_header_t *)(p+17), port);
                }
            }
            netMblkClChainFree(pMblk);
            break;

        case SPAN_PORT_ENABLE:
            port = (ulong_t) Message.data;
             dbgPrintf (STP_DEBUG_LINK, ("\nSTP Port Enable: %d", (int)port));
            port_info[port].path_cost = apCfgStpPortPathCostGet(port);
            port_info[port].state =
                (SpanDrvCtrl->spanState == True ?  Blocking : Forwarding);
            enable_port((int)port);
            break;

        case SPAN_PORT_DISABLE:
            port = (ulong_t) Message.data;
            dbgPrintf (STP_DEBUG_LINK, ("\nSTP Port Disable: %d", (int)port));
#ifdef ST_FAST
            if (SpanDrvCtrl->spanState == True)
            {
                if (stGetPortFast (port) == stFastON)
                {
                    port_info[port].state = Forwarding;
                    set_port_state(port, Forwarding);
                }
                else
                {
                    port_info[port].state = Disabled;
                    disable_port(port);
                }
            }
            else
            {
                port_info[port].state = Forwarding;
                set_port_state(port, Forwarding);
            }
#else
            port_info[port].state = Disabled;
            disable_port((int)port);
#endif /* ST_FAST */
            break;

        case SPAN_PROTO_ENABLE:
            port = (ulong_t) Message.data;
            port_info[port].protocol_enabled = True;
            break;

        case SPAN_PROTO_DISABLE:
            port = (ulong_t) Message.data;
            port_info[port].protocol_enabled = False;
            break;

        case SPAN_PRIO_CHANGE:
            {
                Identifier new_id;

                memcpy( (char *)&new_id,
                        (char *)&bridge_info.bridge_id, sizeof(Identifier));
                new_id.priority = htons((ushort_t)((ulong_t) Message.data));
                set_bridge_priority(new_id);
            }
            break;

        case SPAN_PORT_PRIO_CHANGE:
            set_port_priority((int) Message.data, (ushort_t)Message.extra);
            break;

        case SPAN_UPDATE_BRIDGE:
            bridgeParmsUpdated();
            break;

        case SPAN_PORT_PATH_COST_CHANGE:
            set_path_cost((int)Message.data, (Cost_t) Message.extra);
            break;

        default:
            break;
        }
    }

    return ERROR;
}

/*******************************************************************************
* span_set_port_state  - Set the port state (lowest layer)
*
* INPUTS: 
* \ml
* \m <port_no> - 
* port number
* 
* \m <state> - 
* state of the port to set (valid states are DISABLED(1),
* \m 
* BLOCKING(2), LISTENING(3), LEARNING(4), FORWARDING(5), and BROKEN(6)) 
* \me
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
*/
void span_set_port_state
    (
    int port_no,
    State_t state
    )
{
    ulong_t value;
    STATUS  rc;
    int     i;


#if 0
    switch (state)
    {
    case Disabled:
        value = Edot1dStpPortState_disabled;
        break;
    case Listening:
        value = Edot1dStpPortState_listening;
        break;
    case Learning:
        value = Edot1dStpPortState_learning;
        break;
    case Forwarding:
        value = Edot1dStpPortState_forwarding;
        break;
    case Blocking:
        value = Edot1dStpPortState_blocking;
        break;
    default:
        value = Edot1dStpPortState_broken;
        break;
    }

#endif
}

/*******************************************************************************
* set_stp_global_enable  - send message to set the global Spanning Tree state
*
* The valid Spanning Tree states are disable/enable.
*
* INPUTS: 
* state
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void  set_stp_global_enable
    (
    Boolean state
    )
{
    if (state != SpanDrvCtrl->spanState)
    {
        SpanDrvCtrl->spanState = state;
        (void)stpQSend( (state == True) ? SPAN_ON : SPAN_OFF, (void *)0, 0 );
    }
}

/*******************************************************************************
* get_stp_global_enable  - get the global Spanning Tree state
*
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
Boolean 
get_stp_global_enable(void)
{
    return SpanDrvCtrl->spanState;
}

/*******************************************************************************
* set_stp_port_enable  - set Spanning Tree port state
*
* This routune sets the Spanning Tree port state to disable/enable.
*
* INPUTS:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -