📄 bridge.c
字号:
default: netMblkClChainFree(pMblk); break; } /* set the mirror driver flag according to the return status*/ if (status == END_ERR_BLOCK) { DBG_PRINT(("ERROR: packetForward: packet sent from %s%d returned \ END_ERR_BLOCK at %s%d\n", pSrcPortInfo->name, pSrcPortInfo->unitNum, pDestPortInfo->name, pDestPortInfo->unitNum)); netMblkClChainFree(pMblk); /* * check whether the pMuxBindcokkie->pEnd is mirror 1. If it is, we * should propogate the END_ERR_BLOCK to mirror , then forward to * IP proto, otherwise, ignore it */ if ((strcmp(pSrcPortInfo->name,MIRROR_DEV_NAME) == 0) && (pSrcPortInfo->unitNum == MIRROR_BRIDGE_UNIT_NUM)) { if (muxIoctl(pSrcPortInfo->pMuxBindCookie, ENDERRBLOCK, (caddr_t)MIRROR_END_ERR_BLOCK) != OK) { printf ("Setting END_ERR_BLOCK failed for mirror 1\n"); muxDevStop (pSrcPortInfo->pMuxBindCookie); muxDevUnload (MIRROR_DEV_NAME, MIRROR_BRIDGE_UNIT_NUM); return ERROR; } } } return OK; }/******************************************************************************** packetFloodForward - Send packet to all the bridge ports except source port** NOMANUAL** RETURNS: OK, or ERROR if bridge flood forward packets fails*/LOCAL STATUS packetFloodForward ( M_BLK* pMblk, BRIDGE_PORT_INFO* pSrcPortInfo ) { BRIDGE_PORT_INFO* pDestPortInfo; M_BLK* pMblkDup; /*************************************************************************** * forward the packet to all ports except for the source port ***************************************************************************/ for (pDestPortInfo = (BRIDGE_PORT_INFO*)lstFirst(&bridgePortList); pDestPortInfo != NULL; pDestPortInfo = (BRIDGE_PORT_INFO*)lstNext((NODE*)pDestPortInfo)) { if (pDestPortInfo != pSrcPortInfo) { /* duplicate the packet (FYI - this does not copy the payload) */ pMblkDup = netMblkChainDup(pMblk->pClBlk->pNetPool, pMblk, 0, M_COPYALL, M_DONTWAIT); if (pMblkDup != NULL) { if (packetForward(pMblkDup, pDestPortInfo, pSrcPortInfo) != OK) { /* forwarding has been with duplicates, free the original */ netMblkClChainFree(pMblk); return ERROR; } } } } /* end for loop */ /* forwarding has been with duplicates, free the original */ netMblkClChainFree(pMblk); return OK; }/******************************************************************************** bridgeAgingTask - Perform the deletion of the obsolete station cache entry. ** NOMANUAL** RETURNS: N/A*/LOCAL void bridgeAgingTask ( void ) { int index; UINT32 timeoutTick; UINT32 currentTick; UINT32 deltaTick; /* convert timeout from seconds to vxWorks ticks */ timeoutTick = sysClkRateGet() * AGING_TIMEOUT_SECONDS; while (TRUE) { taskDelay(sysClkRateGet() * AGING_CHECK_DELAY_SECONDS); currentTick = tickGet(); for (index = 0; index < STATION_CACHE_SIZE; ++index) { if ((pStationCache[index].inUse == TRUE) && !(pStationCache[index].flags & BRIDGE_STATIC_FLAG)) { deltaTick = currentTick >= pStationCache[index].tick? /* tick wrap around? */ currentTick - pStationCache[index].tick : /* no */ (UINT32)0xffffffff - pStationCache[index].tick + currentTick; /* yes */ if (deltaTick >= timeoutTick) { /**************************************** * station cache entry has timed out ****************************************/ stationCacheEntryDelete(&pStationCache[index]); } } } } /**************************************** * function never returns ****************************************/ }/******************************************************************************** stationCacheEntryAdd - Add one entry to station cache** NOMANUAL** RETURNS: N/A*/LOCAL void stationCacheEntryAdd ( UINT16* pMacAddr, BRIDGE_PORT_INFO* pPortInfo, UINT32 flags ) { BOOL found = FALSE; UINT32 baseIndex; UINT32 count; UINT32 index = 0; UINT32 oldestIndex; UINT32 oldestAge; UINT32 currentTick; UINT32 age; semTake(stationCacheSemId, WAIT_FOREVER); /*************************************************************************** * if there's a free one in the associative set, use it ***************************************************************************/ baseIndex = (UINT32)(pMacAddr[2]); baseIndex &= (STATION_CACHE_SIZE - 1); for (count = 0; count < SC_ASSOCIATIVE_SET_SIZE; ++count) { index = (baseIndex + count) & (STATION_CACHE_SIZE - 1); if (pStationCache[index].inUse == FALSE) { found = TRUE; break; } } /*************************************************************************** * There isn't a free one in the associative set. So, free the oldest one * and reuse it ***************************************************************************/ if (found == FALSE) { oldestIndex = baseIndex; /* fail safe */ oldestAge = 0; currentTick = tickGet(); for (count = 0; count < SC_ASSOCIATIVE_SET_SIZE; ++count) { index = (baseIndex + count) & (STATION_CACHE_SIZE - 1); age = currentTick >= pStationCache[index].tick? /* tick wrap around? */ currentTick - pStationCache[index].tick : /* no */ (UINT32)0xffffffff - pStationCache[index].tick + currentTick; /* yes */ if (age > oldestAge) { oldestAge = age; oldestIndex = index; } } index = oldestIndex; } /*************************************************************************** * initialize the entry ***************************************************************************/ pStationCache[index].inUse = TRUE; pStationCache[index].pPortInfo = pPortInfo; pStationCache[index].tick = tickGet(); pStationCache[index].macAddr[0] = pMacAddr[0]; pStationCache[index].macAddr[1] = pMacAddr[1]; pStationCache[index].macAddr[2] = pMacAddr[2]; pStationCache[index].flags = flags; semGive(stationCacheSemId); }/******************************************************************************** stationCacheEntryDelete - Delete one entry from station cache ** NOMANUAL** RETURNS: N/A*/LOCAL void stationCacheEntryDelete ( STATION_CACHE_ENTRY* pSCEntry ) { semTake(stationCacheSemId, WAIT_FOREVER); pSCEntry->inUse = FALSE; pSCEntry->flags = 0; semGive(stationCacheSemId); }/******************************************************************************** stationCacheEntryFind - Find an entry matching the MAC address** NOMANUAL** RETURNS: station cache entry found*/LOCAL STATION_CACHE_ENTRY* stationCacheEntryFind ( UINT16* pMacAddr ) { UINT32 count; UINT32 index; UINT16 * pTemp; UINT32 baseIndex = 0; baseIndex = (UINT32)(pMacAddr[2]); baseIndex &= (STATION_CACHE_SIZE - 1); for (count = 0; count < SC_ASSOCIATIVE_SET_SIZE; ++count) { index = (baseIndex + count) & (STATION_CACHE_SIZE - 1); pTemp = (UINT16 *)(pStationCache[index].macAddr); if ((pStationCache[index].inUse == TRUE) && MAC_ADDR_EQ(pMacAddr,pTemp)) { return &pStationCache[index]; } } return NULL; }/******************************************************************************** bridgePortListShow - Show a list of all bridge ports* Show a list of all bridge ports.** RETURNS: N/A*/void bridgePortListShow ( void ) { BRIDGE_PORT_INFO* pPortInfo; /*************************************************************************** * if bridge hasn't been initialized, return ***************************************************************************/ if (bridgeInited == FALSE) return; /*************************************************************************** * print out banner ***************************************************************************/ printf("Bridge Port Info List:\n"); printf("EntryAddr DevName Num MuxCookie Type\n"); printf("-------------------------------------------\n"); /*************************************************************************** * print out the contents of each entry in the bridge port info list ***************************************************************************/ for (pPortInfo = (BRIDGE_PORT_INFO*)lstFirst(&bridgePortList); pPortInfo != NULL; pPortInfo = (BRIDGE_PORT_INFO*)lstNext((NODE*)pPortInfo)) { printf("0x%08X %-8s %1d 0x%08X ", (UINT32)pPortInfo, pPortInfo->name, pPortInfo->unitNum, (UINT32)pPortInfo->pMuxBindCookie); switch (pPortInfo->portType) { case BRIDGE_PORT_TYPE_END: printf("END"); break; case BRIDGE_PORT_TYPE_NPT: printf("NPT"); break; default: printf("UNKNOWN"); break; } printf("\n"); } }/******************************************************************************* bridgeNextPhyDevEndGet - Return the next END descriptor of physical device.**/STATUS bridgeNextPhyDevEndGet ( char * pNameBuf, int * pUnit ) { BRIDGE_PORT_INFO * pPortInfo; if (pNameBuf[0] == 0) { /* get the first one */ pPortInfo = (BRIDGE_PORT_INFO*)lstFirst(&bridgePortList); if (pPortInfo != NULL) { strcpy(pNameBuf,pPortInfo->name); *pUnit = pPortInfo->unitNum; return OK; } } else { /* get the next after the one specified by caller */ for (pPortInfo = (BRIDGE_PORT_INFO*)lstFirst(&bridgePortList); pPortInfo != NULL; pPortInfo = (BRIDGE_PORT_INFO*)lstNext((NODE*)pPortInfo)) { if ((strcmp(pPortInfo->name,pNameBuf) == 0) && (*pUnit == pPortInfo->unitNum)) { pPortInfo = (BRIDGE_PORT_INFO*)lstNext((NODE*)pPortInfo); if (pPortInfo == NULL) return ERROR; else { strcpy(pNameBuf,pPortInfo->name); *pUnit = pPortInfo->unitNum; return OK; } } } /* end for loop */ } return ERROR; } /******************************************************************************** bridgeStationCacheShow - Display all entries in bridge station cache* Display all entries in bridge station cache.** RETURNS: N/A*/void bridgeStationCacheShow ( void ) { int index; unsigned char * pTemp; /*************************************************************************** * if bridge hasn't been initialized, return ***************************************************************************/ if (bridgeInited == FALSE) return; /*************************************************************************** * print out banner ***************************************************************************/ printf("Bridge Station Cache Contents:\n"); printf("MAC Address Tick pPortInfo \n"); printf("-----------------------------------------------\n"); /*************************************************************************** * print out contents of each allocated station cache entry ***************************************************************************/ for (index = 0; index < STATION_CACHE_SIZE; ++index) { if (pStationCache[index].inUse == TRUE) { pTemp = (unsigned char *)(pStationCache[index].macAddr); printf("%02X:%02X:%02X:%02X:%02X:%02X ", pTemp[0], pTemp[1], pTemp[2],pTemp[3],pTemp[4],pTemp[5]); printf("0x%08X ", pStationCache[index].tick); printf("%s ", (pStationCache[index].flags & BRIDGE_STATIC_FLAG)? "STATIC ":"DYNAMIC"); if(pStationCache[index].pPortInfo) printf("%s%d\n", pStationCache[index].pPortInfo->name,pStationCache[index].pPortInfo->unitNum); else printf("0x%08X\n", (UINT32)pStationCache[index].pPortInfo); } } } /******************************************************************************** portListEntryFind - Find the bridge port that matches the specified device* name and unit number* * NOMANUAL** RETURNS: bridge port entry if found, NULL otherwise*/LOCAL BRIDGE_PORT_INFO* portListEntryFind ( char* pDevName, /* device name */ int unitNum /* unit number */ ) { BRIDGE_PORT_INFO* pPortInfo; for (pPortInfo = (BRIDGE_PORT_INFO*)lstFirst(&bridgePortList); pPortInfo != NULL; pPortInfo = (BRIDGE_PORT_INFO*)lstNext((NODE*)pPortInfo)) { if ((STR_EQ(pDevName, pPortInfo->name)) && (unitNum == pPortInfo->unitNum)) { break; } } return pPortInfo; } /*************************************************************************** * END OF FILE ***************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -