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

📄 bridge.c

📁 Bridge PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 4 页
字号:
                stationCacheEntryDelete(&pStationCache[index]);            }        }    /* remove all the queue packets if any */    while(pPortInfo->errSndq.ifq_head)        {        /* Dequeue a packet. */        IF_DEQUEUE (&pPortInfo->errSndq, pMblk);        netMblkClChainFree(pMblk);        }    semGive(bridgePortListSemId);        free(pPortInfo);        return OK;    }/******************************************************************************** bridgeRestartRtn - bridge restart routine** This is the entry point for the bridge restart routine.** RETURNS: OK, or ERROR if bridge restart fails** ERRNO: N/A** NOMANUAL*/LOCAL STATUS  bridgeRestartRtn    (    void*   pNetCallBackId    )    {    BRIDGE_PORT_INFO* pPortInfo;    M_BLK_ID pMblk;    int status = OK;    pPortInfo = (BRIDGE_PORT_INFO *)pNetCallBackId;    /* check if there is packets in the ERR_BLOCK send queue */    while(pPortInfo->errSndq.ifq_head)        {        /* Dequeue a packet. */        IF_DEQUEUE (&pPortInfo->errSndq, pMblk);        status = packetToPortSend (pMblk, pPortInfo,NULL);        if (status == END_ERR_BLOCK)            break;        }    if (status == OK)	{        /* only after the queue is emptied, enable mirror0 restart */        if (pMirrorStackEnd == NULL)            {            if ((pMirrorStackEnd = endFindByName(MIRROR_DEV_NAME,                                   MIRROR_STACK_UNIT_NUM)) == NULL)                {                printf("ERROR: restart fails, can't find mirror0 device\n");                return ERROR;                }            }        /* already in tNetTask context */        muxTxRestart(pMirrorStackEnd);        }    return OK;    }/******************************************************************************** bridgeErrorRtn - bridge Error routine ** This is the entry point for the bridge error routine.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/LOCAL void    bridgeErrorRtn    (    void*       pNetCallBackId,     END_ERR*    pError    )    {    return;    }/********************************************************************************* pktToQueuePut - put the unsent packets to the queue** Only the packets originated from another physical bridge port will be put* into this queue. The packet originated from local stack will be returned* back to the IP layer. Therefore this queue is only accessed by the restart* and driver's receive routines. Both are assumed to be invoked from the* 'tNetTask' context through netJobAdd() function.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/LOCAL void pktToQueuePut    (    BRIDGE_PORT_INFO*   pPortInfo,    M_BLK_ID            pMblk,    BOOL                atHead    )    {    /* packets not originated from the local stack */    /* put it in the queue, and let restart routine send them out */    if (IF_QFULL(&pPortInfo->errSndq))        {        IF_DROP(&pPortInfo->errSndq);        netMblkClChainFree(pMblk);        }    else if (atHead == TRUE)        {        IF_PREPEND(&pPortInfo->errSndq,pMblk);        }    else        {        IF_ENQUEUE(&pPortInfo->errSndq,pMblk);        }    }/********************************************************************************* packetToPortSend - send a packet to the given port** This routine sends a packet to the given port** RETURNS: OK or ERROR** ERRNO: N/A** NOMANUAL*/LOCAL int  packetToPortSend    (    M_BLK*              pMblk,    BRIDGE_PORT_INFO*   pDestPortInfo,    BRIDGE_PORT_INFO*   pSrcPortInfo    )    {    int status = OK;      /* Attempt to send the packet */    switch (pDestPortInfo->portType)        {        case BRIDGE_PORT_TYPE_END:            status = muxSend(pDestPortInfo->pMuxBindCookie, pMblk);            break;        case BRIDGE_PORT_TYPE_NPT:            /* pMblk->mBlkHdr.mFlags |= M_L2HDR; */            status = muxTkSend(pDestPortInfo->pMuxBindCookie, pMblk,                               NULL, 0, NULL);            break;        default:            netMblkClChainFree(pMblk);            break;        }    if (status == END_ERR_BLOCK)        {        /*         * The device is currently unable to transmit because of         * insufficient resources. Put the packet in the error send          * queue for that device. When the device has enough resources          * to transmit, MUX will call the Bridge restart routine.         * The restart routine will try to re-send the packet.         */        DBG_PRINT(("ERROR: packetForward: packet sent to %s%d returned \                  END_ERR_BLOCK\n",                  pDestPortInfo->name, pDestPortInfo->unitNum));	/* Did this error originate from mirror1? */        if (pMirrorPortInfo == NULL)            {            pMirrorPortInfo = portListEntryFind(MIRROR_DEV_NAME,                                            MIRROR_BRIDGE_UNIT_NUM);            if (pMirrorPortInfo == NULL)                {                printf("ERROR: packetToPortSend, can't find mirror port\n");                return ERROR;                }            }        if (pSrcPortInfo == pMirrorPortInfo)            {            /* packet originated from the local stack */            DBG_PRINT(("END_ERR_BLOCK packet sent from mirror 1\n"));            /* notify the mirrorSend routine */            mirrorSendStatus = END_ERR_BLOCK;            }        else            {            /*             * If the source port is NULL, it means the Bridge restart             * routine has unsuccessfully tried to re-send the packet.             * To preserve the transmit order, put the packet at the head             * of the device's error send queue.             *             * Otherwise, this the first attempt to send the packet. Put             * the packet at the tail of the device's error send queue.             */            pktToQueuePut(pDestPortInfo, pMblk, (pSrcPortInfo == NULL));            }        }    return status;    }/******************************************************************************** packetForward - forward the packet to the destination port** This routine forwards the provided packet out the indicated destination* port.  ** If the destination port is driven by a NPT device driver, the* the transmission is accomplished by simply calling muxTkSend() and setting* the M_L2HDR flag in the mBlk header.  The presence of this flag indicates* to the NPT device driver that a fully formed physical layer header is* already present in the packet.  Although this flag is mentioned in the NPT* docs, it is not defined in any header files.** If the destination port is driven by an END device driver, transmission* cannot be accomplished by calling muxTkSend() since muxTkSend() will* prepend a physical layer header with a source MAC address of the system* itself.  However, muxSend() can be called to accomplish the transmission* to an END driver.** RETURNS: OK, or ERROR if bridge forward packets fails** ERRNO: N/A** NOMANUAL*/LOCAL STATUS  packetForward    (    M_BLK*              pMblk,     BRIDGE_PORT_INFO*   pDestPortInfo,    BRIDGE_PORT_INFO*   pSrcPortInfo    )    {    if (pDestPortInfo->errSndq.ifq_head)        {        /*         * If the error send queue is not empty, there must be one restart         * called later on. If the current function is called from a task         * other than tNetTask(packet from local stack), it may get switched out         * here to execute the restart routine in tNetTask context. But the         * muxTxRestart on mirror0 device will get blocked by splnet semaphore         * in ipTxStartup from ipTxRestart until this function completed. Then         * it will find this packet in the IP ifqueue. So we're OK.          * If the current function is called from tNetTask context(packet from         * another physical bridge port), the restart(always from tNetTask          * context) can't start until we're finished here.         */        if (pMirrorPortInfo == NULL)            {            pMirrorPortInfo = portListEntryFind(MIRROR_DEV_NAME,                                            MIRROR_BRIDGE_UNIT_NUM);            if (pMirrorPortInfo == NULL)                {                printf("ERROR: packetForward, can't find bridge mirror port\n");                return ERROR;                }            }        if (pSrcPortInfo == pMirrorPortInfo)            {            /* notify the mirrorSend routine */            mirrorSendStatus = END_ERR_BLOCK;            }        else            pktToQueuePut(pDestPortInfo,pMblk,FALSE);        }    else        packetToPortSend(pMblk, pDestPortInfo, pSrcPortInfo);    return OK;    }/******************************************************************************** packetFloodForward - send packet to all the bridge ports except source port** This routine sends packet to all the bridge ports except source port** RETURNS: OK, or ERROR if bridge flood forward packets fails** ERRNO: N/A** NOMANUAL*/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)            {            if (strcmp(MIRROR_DEV_NAME,pDestPortInfo->name) == 0)                {                /* must be mirror 1 bridge port.  */                if (bcastPktToStackSend (pMblk,  pDestPortInfo, pSrcPortInfo)                    != OK)                    /* don't attempt more forwarding if error is encountered */                    break;                }            else                {                                                /*duplicate the packet (FYI - this does not copy the payload) */                pMblkDup = netMblkChainDup(_pNetDpool,                                       pMblk,                                       0,                                       M_COPYALL,                                       M_DONTWAIT);                                if (pMblkDup == NULL)                    /* don't attempt more forwarding if error is encountered */                    break;                            if (packetForward(pMblkDup, pDestPortInfo, pSrcPortInfo) != OK)                    {                    /* don't attempt more forwarding if error is encountered */                    netMblkClChainFree(pMblkDup);                    break;                    }                if (mirrorSendStatus == END_ERR_BLOCK)                     {                    if (pSrcPortInfo == pMirrorPortInfo)                        {                        /* packet originated from local stack and END_ERR_BLOCK                         * code is return from the packetForward(). Then stop                         * all forwardings. don't free the original pMblk which                         * will be put in the ifq which is emptied by the                          * stack's restart routine                         */                        netMblkClChainFree(pMblkDup);                        return OK;                        }                    }                }            }        }  /* end for loop */        /* forwarding has been with duplicates, free the original */    netMblkClChainFree(pMblk);        return OK;    }/********************************************************************************* bcastPktToStackSend - send the broadcast packet to the local stack** This routine sends the broadcast packet to the local stack** RETURNS: OK or ERROR** ERRNO: N/A** NOMANUAL*/LOCAL STATUS bcastPktToStackSend     (    M_BLK_ID pMblk,    BRIDGE_PORT_INFO*   pDestPortInfo,    BRIDGE_PORT_INFO*   pSrcPortInfo    )    {    M_BLK_ID pOrgMblk;    M_BLK_ID p1stMblk;    M_BLK_ID pNewMblk;    M_BLK_ID pPreMblk;       /*      * Need to make a real copy of the packet when it is delivered     * to the IP stack because the IP stack may modify the IP     * header before the packet is sent out to the other bridge     * ports.     */    pOrgMblk = pMblk;    p1stMblk = NULL;    pPreMblk = NULL;    while (pOrgMblk)        {        pNewMblk = netTupleGet(_pNetDpool,                             pOrgMblk->pClBlk->clSize, M_DONTWAIT,                             MT_DATA,0);        if (pNewMblk == NULL ||            (pNewMblk->pClBlk->clSize < pOrgMblk->mBlkHdr.mLen + 2) )            {            if (p1stMblk)                netMblkClChainFree(p1stMblk);            if (pNewMblk)                netMblkClChainFree(pNewMblk);            DBG_PRINT(("ERROR: can't get a buf\n"));

⌨️ 快捷键说明

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