📄 bridge.c
字号:
return ERROR; } /* assign the packet header info for first mblk */ if (p1stMblk == NULL) { p1stMblk = pNewMblk; pNewMblk->mBlkHdr.mFlags = pMblk->mBlkHdr.mFlags; pNewMblk->mBlkPktHdr = pMblk->mBlkPktHdr; /* align the IP header at 4 byte boundary */ pNewMblk->mBlkHdr.mData += 2; } /* copy the data */ bcopy(pOrgMblk->mBlkHdr.mData, pNewMblk->mBlkHdr.mData, pOrgMblk->mBlkHdr.mLen); pNewMblk->mBlkHdr.mLen = pOrgMblk->mBlkHdr.mLen; if (pPreMblk) pPreMblk->mBlkHdr.mNext = pNewMblk; pPreMblk = pNewMblk; pOrgMblk = pOrgMblk->mBlkHdr.mNext; } if (packetForward(p1stMblk, pDestPortInfo, pSrcPortInfo) != OK) { /* free the original */ netMblkClChainFree(p1stMblk); return ERROR; } return OK; }/******************************************************************************** bridgeAgingTask - perform the deletion of the obsolete station cache entry ** This routine performs the deletion of the obsolete station cache entry** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/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** This routine adds one entry to the station cache.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/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 ** This routine deletes one entry from the station cache.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/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** This routine finds an entry matching the MAC address from the station cache.** RETURNS: station cache entry found** ERRNO: N/A** NOMANUAL*/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 - display a list of all bridge ports* * This routine displays the contents of the bridge port information list.** RETURNS: N/A** ERRNO: 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** This routine returns the next END descriptor of physical device.** RETURNS: OK or ERROR** ERRNO: N/A** NOMANUAL*/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** This routine displays the contents of the bridge station cache. The cache* contains what the bridge has learned and remembered about the mapping of* MAC addresses and bridge ports.** RETURNS: N/A** ERRNO: 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 matching device name and unit number** This routine finds the bridge port matching device name and unit number** RETURNS: bridge port entry if found, NULL otherwise** ERRNO: N/A** NOMANUAL*/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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -