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

📄 bridge.c

📁 Bridge PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 4 页
字号:
        {        DBG_PRINT(("bridgePortAdd: ERROR: \"%s%d\" is not attached to MUX.\n",                   pDevName, unitNum));        return ERROR;        }       /***************************************************************************    * verify that this port is not already attached to the bridge    ***************************************************************************/    if (portListEntryFind(pDevName, unitNum) != NULL)        {        /* port is already in bridge port table */                DBG_PRINT(("bridgePortAdd: ERROR: \"%s%d\" is already attached\n",                   pDevName, unitNum));        return ERROR;        }       /***************************************************************************    * allocate space for bookkeeping info for the port    ***************************************************************************/    pPortInfo = (BRIDGE_PORT_INFO*)malloc(sizeof(BRIDGE_PORT_INFO));        if (pPortInfo == NULL)        {        DBG_PRINT(("bridgePortAdd: ERROR: out of memory, malloc failure.\n"));        return ERROR;        }       /***************************************************************************    * bind bridge to the port as a SNARFer    ***************************************************************************/    pMuxBindCookie = muxTkBind(pDevName,                               unitNum,                               bridgeRcvRtn,                               bridgePortShutdownRtn,                               bridgeRestartRtn,                               bridgeErrorRtn,                               MUX_PROTO_SNARF,                               "bridge",                               pPortInfo,   /* pNetCallBackId */                               NULL,        /* pNetSvcInfo */                               NULL);       /* pNetDrvInfo */    if (pMuxBindCookie == NULL)        {        DBG_PRINT(("bridgePortAdd: ERROR: muxTkBind() failed for \"%s%d\".\n",               pDevName, unitNum));        free(pPortInfo);        return ERROR;        }       /***************************************************************************    * save bookkeeping info for the port    ***************************************************************************/    bzero((char*)pPortInfo, sizeof(BRIDGE_PORT_INFO));        bcopy(pDevName, pPortInfo->name, END_NAME_MAX - 1);    pPortInfo->name[END_NAME_MAX - 1] = EOS;    pPortInfo->unitNum = unitNum;    pPortInfo->pMuxBindCookie = pMuxBindCookie;    pPortInfo->errSndq.ifq_head    = 0;    pPortInfo->errSndq.ifq_tail    = 0;    pPortInfo->errSndq.ifq_len     = 0;    pPortInfo->errSndq.ifq_maxlen  = SNDERRQ_MAX_LEN;    pPortInfo->errSndq.ifq_drops   = 0;     if (muxTkDrvCheck(pDevName) == TRUE)        pPortInfo->portType = BRIDGE_PORT_TYPE_NPT;    else         pPortInfo->portType = BRIDGE_PORT_TYPE_END;        semTake(bridgePortListSemId, WAIT_FOREVER);        lstAdd(&bridgePortList, (NODE*)pPortInfo);        semGive(bridgePortListSemId);        return OK;    }/******************************************************************************** bridgePortRemove - remove a bridge port** This routine removes an existing port from the bridge port list and unbinds* the bridge service from the MUX layer for that port.** RETURNS: OK, or ERROR if port removal fails** ERRNO: N/A*/STATUS  bridgePortRemove    (    char*   pDevName,           /* device name */    int     unitNum             /* unit number */    )    {    BRIDGE_PORT_INFO*   pPortInfo;       /***************************************************************************    * if bridge hasn't been initialized, return ERROR    ***************************************************************************/    if (bridgeInited == FALSE)        return ERROR;       /***************************************************************************    * find the port info and remove it from the bridge    ***************************************************************************/    pPortInfo = portListEntryFind(pDevName, unitNum);    if (pPortInfo != NULL)        return bridgePortShutdownRtn((void*)pPortInfo);   /***************************************************************************    * the port was not found in the list    ***************************************************************************/    return ERROR;    }/******************************************************************************** bridgeMacAdd - add a MAC address to the bridge station cache** This routine provides the ability to add a MAC address to the bridge station* cache directly instead of waiting for the bridge to automatically learn it.* This routine is typically used to add a static entry to the station cache. ** A static entry in the station cache represents a permanent mapping between* a source MAC address and a bridge port. Static entries are useful if you* already know the MAC address to bridge port mapping for your interfaces and* want to set these at initialization time instead of waiting for the bridge* to learn it. Static entries also prevent the MAC address of an interface* from migrating from one port to another, as can happen if you have a* network loop. If the migration happens, the bridge may stop receiving* packets.** RETURNS: OK, or ERROR if adding MAC address to station cache fails** ERRNO: N/A*/STATUS bridgeMacAdd    (    char*    pDevName,    /* device name */    int      unitNum,     /* unit number */    char*    pMacAddr,    /* MAC address to add */     UINT32   flags        /* static entry? */    )    {    BRIDGE_PORT_INFO*       pPortInfo;      STATION_CACHE_ENTRY*    pSCEntry;       UINT16                  bridgeMacAddr[3];    /* if bridge hasn't been initialized, return ERROR */        if (bridgeInited == FALSE)        return ERROR;        /* Find the bridge port matching the device name and unit number */        pPortInfo = portListEntryFind(pDevName, unitNum);            if (pPortInfo == NULL)        {        /* Only add MAC address for known bridge ports */                return ERROR;        }    /* Copy in MAC address */        bcopy(pMacAddr, (char*)bridgeMacAddr, 6);    /* See if there is already an entry for this MAC address */        pSCEntry = stationCacheEntryFind(bridgeMacAddr);        if (pSCEntry != NULL)        {        /* Found an entry - override it */                pSCEntry->pPortInfo = pPortInfo;        pSCEntry->tick = tickGet();        pSCEntry->flags = flags;        }    else        {        /* Didn't find the entry so add it in */                stationCacheEntryAdd(bridgeMacAddr, pPortInfo, flags);        }    return OK;}/******************************************************************************** bridgeMacRemove - remove a MAC address from the bridge station cache** This routines provides the ability to remove a MAC address from the bridge* station cache directly. This routine is typically used to remove a static* entry from the station cache.** RETURNS: OK, or ERROR if the MAC address is not found** ERRNO: N/A*/STATUS  bridgeMacRemove    (    char*    pMacAddr    )    {    UINT16                  bridgeMacAddr[3];    STATION_CACHE_ENTRY*    pSCEntry;       /* Copy in MAC address */        bcopy(pMacAddr, (char*)bridgeMacAddr, 6);        /* Find the MAC address in the station cache */        pSCEntry = stationCacheEntryFind(bridgeMacAddr);    if (pSCEntry != NULL)        {        /* Found it - remove the entry */                stationCacheEntryDelete(pSCEntry);        return OK;        }            /* Didn't find the MAC address in the station cache */        return ERROR;    }    /******************************************************************************** bridgeRcvRtn - dispatch the received packet** This routine performs the bridge's learning function as well as dispatching* the incoming packet to the appropriate bridge ports. This routine is only* invoked from the MUX layer function mux(Tk)Receive().** RETURNS: TRUE, or FALSE if bridge receive routine fails** ERRNO: N/A** NOMANUAL*/LOCAL BOOL bridgeRcvRtn    (    void*       pNetCallBackId,  /* parameter assigned when muxTkBind called */     long        type,            /* not used */    M_BLK*      pMblk,           /* the received packet */    void*       pSpareData       /* not used */    )    {    UINT32               macAddr[4];    /* src and dst mac addresses holder */    BRIDGE_PORT_INFO*    pSrcPortInfo;  /* incoming port info for the packet */    BRIDGE_PORT_INFO*    pDestPortInfo; /* outgoing port info for the packet */    STATION_CACHE_ENTRY* pSCEntry;      /* station cache entry */    UINT16 * pTempAddr;    UINT16 * pMacDstAddr;    UINT16 * pMacSrcAddr;        /* If it is a EAPOL packet, don't bridge it, send it on.... */    if (GETETHERTYPE(pMblk) == 0x888E)        return FALSE;     pSrcPortInfo = (BRIDGE_PORT_INFO*)pNetCallBackId;    pTempAddr = (UINT16 *)(pMblk->mBlkHdr.mData);    /* Extract the received frame's MAC addresses, which is possibely in the     * non cached memory, to the at least two byte aligned local stack variable,     * which most likely is in the cached memory, to acheive the optimal      * performace for this function.     */    if (IS_4BYTE_ALIGNED(pTempAddr))        {        /* the packet is at 4 byte boundary  */        macAddr[0] = *(UINT32 *)pTempAddr;        macAddr[1] = *((UINT32 *)pTempAddr + 1);        macAddr[2] = *((UINT32 *)pTempAddr + 2);        pMacDstAddr = (UINT16 *)macAddr;        pMacSrcAddr = (UINT16 *)macAddr + 3;        }    else if (IS_2BYTE_ALIGNED(pTempAddr))        {        /* at two byte boundary */        *((UINT16 *)macAddr + 1) = pTempAddr[0];        macAddr[1] = *(UINT32 *)(pTempAddr + 1);        macAddr[2] = *(UINT32 *)(pTempAddr + 3);        *(UINT16 *)(macAddr + 3) = pTempAddr[5];        pMacDstAddr = (UINT16 *)macAddr + 1;        pMacSrcAddr = (UINT16 *)macAddr + 4;        }    else        {        /* at byte boundary, very unlikely */        bcopy((char *)pTempAddr, (char *)macAddr,6);        bcopy((char *)pTempAddr + 6, (char *)macAddr + 6, 6);        pMacDstAddr = (UINT16 *)macAddr;        pMacSrcAddr = (UINT16 *)macAddr + 3;        }   /***************************************************************************    * source address processing, perform bridge learning function    ***************************************************************************/    /* check if the source MAC address is in the station cache */        pSCEntry = stationCacheEntryFind(pMacSrcAddr);    if (pSCEntry != NULL)        {        /* source MAC address is in the station cache */        if ((pSrcPortInfo != pSCEntry->pPortInfo) &&            !(pSCEntry->flags & BRIDGE_STATIC_FLAG))            {	    /*             * the source MAC address is now connected to a different port              * update the station cache              */            pSCEntry->pPortInfo = pSrcPortInfo;            }                /* reset the station cache entry's tick count */        pSCEntry->tick = tickGet();        }    else         {	/*         * source MAC address is not in the station cache;         * create new entry in the station cache 	 */        stationCacheEntryAdd(pMacSrcAddr, pSrcPortInfo, 0);        }       /***************************************************************************    * destination address processing    ***************************************************************************/    if (IS_BROADCAST(pMacDstAddr))        {        /* destination MAC address is broadcast, flood forward packet */        if (packetFloodForward(pMblk, pSrcPortInfo) != OK)            return FALSE;        }    else         {        /* destination MAC address is not broadcast */        pSCEntry = stationCacheEntryFind(pMacDstAddr);                if (pSCEntry != NULL)            {            pDestPortInfo = pSCEntry->pPortInfo;            /* destination MAC address is in station cache */            if (pSrcPortInfo == pDestPortInfo)                {                /* destination port is same as source port, discard packet */                netMblkClChainFree(pMblk);                }            else                 {		/*                 * destination port is not the same as source port,                  * forward packet                  */                if (packetForward(pMblk, pDestPortInfo, pSrcPortInfo) != OK)                    return FALSE;                }            }        else             {	    /*             * destination MAC address is not in station cache,              * flood forward packet              */            if (packetFloodForward(pMblk, pSrcPortInfo) != OK)                return FALSE;            }        }        return TRUE;    }/******************************************************************************** bridgePortShutdownRtn - shut down the bridge function on a particular port** This routine removes the bridge service from the MUX interface for this* port and frees the resources allocated. The bridge port must not be* used after this routine executes successfully.** RETURNS: OK always** ERRNO: N/A** NOMANUAL*/LOCAL STATUS  bridgePortShutdownRtn    (    void*   pNetCallBackId    )    {    BRIDGE_PORT_INFO*   pPortInfo;    int                 index;    M_BLK_ID pMblk;        pPortInfo = (BRIDGE_PORT_INFO*)pNetCallBackId;       /***************************************************************************    * unbind the bridge from this port    ***************************************************************************/    muxUnbind(pPortInfo->pMuxBindCookie,              MUX_PROTO_SNARF,              bridgeRcvRtn);   /* give the muxUnbind some time to complete its job which is eventually done    * in netTask context. The port should not be removed until it is unbinded    */   taskDelay(5);         /***************************************************************************    * remove this port from the bridge port list    ***************************************************************************/    semTake(bridgePortListSemId, WAIT_FOREVER);        lstDelete(&bridgePortList, (NODE*)pPortInfo);   /***************************************************************************    * remove all entries regarding this port from the station cache    ***************************************************************************/    for (index = 0; index < STATION_CACHE_SIZE; ++index)        {        if (pStationCache[index].inUse == TRUE)            {            if (pPortInfo == pStationCache[index].pPortInfo)

⌨️ 快捷键说明

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