📄 spantask.c
字号:
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 + -