/* Send a packet to the IP stack like it was received by the virtual IP interface indexed by pp->ifnum_in. */ void ssh_virtual_adapter_send(SshInterceptor interceptor, SshInterceptorPacket pp) { SshInterceptorInternalPacket ipp; VxWorksVa *va; M_BLK_ID m; if (!(va = vxworks_va_find_va(pp->ifnum_out))) { SSH_TRACE( SSH_D_ERROR, ("trying to send to a nonexistent ifnum %d", (int)pp->ifnum_out)); ssh_interceptor_packet_free(pp); return; } if (pp->protocol != SSH_PROTOCOL_ETHERNET) { SSH_TRACE(SSH_D_ERROR, ("%s: dropping non-ethernet packet", va->name)); ssh_interceptor_packet_free(pp); return; } ipp = (void *)pp; m = ipp->head; ipp->head = NULL; ssh_interceptor_packet_free_header(ipp); SSH_DEBUG( SSH_D_LOWOK, ("feeding receive packet to %s, ifnum %d", va->name, (int)va->ifnum)); END_RCV_RTN_CALL(&va->end, m); }
/* * Send the received packet to END driver */ int NetdrvSendToEnd(bcm_pkt_t *pPkt) { int len; M_BLK_ID pMblk; char* pCluster = NULL; CL_BLK_ID pClBlk; END_DEVICE *pDrvCtrl = __netDriver; if (pDrvCtrl == NULL) { return ERROR; } /* Add one to our unicast data. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); /* * We implicitly are loaning here, if copying is necessary this * step may be skipped, but the data must be copied before being * passed up to the protocols. */ pCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId); if (pCluster == NULL) { DRV_LOG (1, "Cannot loan!\n",1,2,3,4,5,6); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } /* Grab a cluster block to marry to the cluster we received. */ if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL) { netClFree (pDrvCtrl->end.pNetPool, (UCHAR *)pCluster); DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } /* * OK we've got a spare, let's get an M_BLK_ID and marry it to the * one in the ring. */ if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) { netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk); netClFree (pDrvCtrl->end.pNetPool, (UCHAR *)pCluster); DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } /* remove tag */ len = pPkt->tot_len - 8; memcpy(pCluster + 2, (unsigned char *)(&(pPkt->_pkt_data.data[0])), 12); memcpy(pCluster + 14, (unsigned char *)(&(pPkt->_pkt_data.data[16])), len-12); /* Free buffer previously stolen */ bcm_rx_free(pPkt->unit, pPkt->_pkt_data.data); /* Join the cluster to the MBlock */ netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0); netMblkClJoin (pMblk, pClBlk); pMblk->mBlkHdr.mLen = len; pMblk->mBlkHdr.mData += 2; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkPktHdr.len = len; /* Send the packet to END driver */ END_RCV_RTN_CALL(&__netDriver->end, pMblk); g_ulPktUp++; return OK; cleanRXD: return (ERROR); }
LOCAL void mirrorEndReceive ( END_CTRL* pDrvCtrl, /* pointer to END_CTRL structure */ M_BLK* pMblk ) { UINT16 * pTmp; UINT16 enetAddr[3]; LOG_MSG("mirrorEndReceive: unit: %d, ", (int)pDrvCtrl->unit, 2, 3, 4, 5, 6); LOG_MSG("dst:%02X:%02X:%02X:%02X:%02X:%02X, ", *(UCHAR *)(pMblk->mBlkHdr.mData), *((UCHAR *)(pMblk->mBlkHdr.mData) + 1), *((UCHAR *)(pMblk->mBlkHdr.mData) + 2), *((UCHAR *)(pMblk->mBlkHdr.mData) + 3), *((UCHAR *)(pMblk->mBlkHdr.mData) + 4), *((UCHAR *)(pMblk->mBlkHdr.mData) + 5)); LOG_MSG("src:%02X:%02X:%02X:%02X:%02X:%02X\n", *((UCHAR *)(pMblk->mBlkHdr.mData) + 6), *((UCHAR *)(pMblk->mBlkHdr.mData) + 7), *((UCHAR *)(pMblk->mBlkHdr.mData) + 8), *((UCHAR *)(pMblk->mBlkHdr.mData) + 9), *((UCHAR *)(pMblk->mBlkHdr.mData) + 10), *((UCHAR *)(pMblk->mBlkHdr.mData) + 11)); /* don't allow the packet through if in polling mode */ if (pDrvCtrl->polling == TRUE) { netMblkClChainFree(pMblk); return; } /* if unit is not in promiscuous mode, filter packets to receive only * packets for our MAC address or broadcasts. */ if (pDrvCtrl->promiscuous == FALSE) { pTmp = (UINT16 *)(pMblk->mBlkHdr.mData); if (((UINT32)(pTmp) & 0x01) == 0) { /* address is aligned on a 2 or 4 byte boundary */ enetAddr[0] = pTmp[0]; enetAddr[1] = pTmp[1]; enetAddr[2] = pTmp[2]; } else { /* address is aligned on a byte-boundary */ bcopy((char *)pTmp, (char *)enetAddr, 6); } if ((MAC_ADDR_EQ(enetAddr, pDrvCtrl->enetAddr) == 0) && (IS_BROADCAST(enetAddr) == 0) && (isInMulticastList(pDrvCtrl, enetAddr) == FALSE)) { LOG_MSG("Dest addr not my addr/broadcast/multicast - dropping!\n", 1, 2, 3, 4, 5, 6); netMblkClChainFree(pMblk); return; } } LOG_MSG("Sending up the packet to my network stack\n", 1, 2, 3, 4, 5, 6); /* send up to protocol */ END_RCV_RTN_CALL(&pDrvCtrl->endObject, pMblk); /* bump input packet counter */ END_ERR_ADD(&pDrvCtrl->endObject, MIB2_IN_UCAST, +1); }
void socend_receive_netjob(int pi, int pckti, int pckt_size) /* * Function: socend_receive_netjob * Purpose: Called from netjob after packet arrives. * Parameters: p - pointer to (se), cookied passed on registration * pckpi - pointer to packet data (int form). * pckt_size - received length of packet. * Returns: Nothing */ { socend_t *se = (socend_t *)pi; struct end_object *eo = &se->se_eo; void *pckt = (void *)pckti; bcm_vlan_t vid; CL_BLK_ID cb = NULL; M_BLK_ID mb = NULL; /* Check the DCB for errors */ #if defined(BROADCOM_DEBUG) /* Only compile in for debug */ if (LOG_CHECK(BSL_LS_SYS_END | BSL_INFO) && LOG_CHECK(BSL_LS_SOC_PACKET | BSL_INFO)) { d_packet_format("socend RX", DECODE_ETHER, pckt, pckt_size, NULL); } #endif /* BROADCOM_DEBUG */ /* * Build Cluster - then attach to mblks, 1 for each interface that * should get the packet. Broadcast/Multicast packets go up all the stacks. * * For multicast, it should only go up stacks that have registered for that * address, but for now, this will allow multiple interfaces to work. */ if ((NULL == (cb = netClBlkGet(eo->pNetPool, M_DONTWAIT)))) { if (mb) netMblkFree(eo->pNetPool, mb); netClFree(eo->pNetPool, pckt); /* Free packet */ END_ERR_ADD(eo, MIB2_IN_ERRS, +1); return; } #if defined(__mips__) if (SOC_IS_ESW(se->se_unit)) { seu_t *seu = &socend_seu[se->se_unit]; void *tmp; sal_memcpy((UINT8 *)seu->pkt_align_buf + 2, (UINT8 *)pckt, pckt_size); tmp = seu->pkt_align_buf; seu->pkt_align_buf = pckt; pckt = tmp; } #endif /* __mips__ */ /* 1 MBLK for each interface */ if ((mb = mBlkGet(eo->pNetPool, M_DONTWAIT, MT_DATA))) { netClBlkJoin(cb, pckt, SOC_END_PK_SZ, NULL, 0, 0, 0); netMblkClJoin(mb, cb); mb->mBlkPktHdr.len = mb->mBlkHdr.mLen = pckt_size; mb->mBlkHdr.mFlags |= M_PKTHDR; #if defined(__mips__) if (SOC_IS_ESW(se->se_unit)) { mb->mBlkHdr.mData +=2; } #endif /* __mips__ */ vid = VLAN_CTRL_ID(soc_ntohs(((enet_hdr_t *)mb->mBlkHdr.mData)->en_tag_ctrl)); if (SOC_IS_ESW(se->se_unit)) { socend_untag(mb); /* Untag packet for now */ } else { robo_socend_untag(mb); /* Untag packet for now */ } } else { netClBlkFree(eo->pNetPool, cb); netClFree(eo->pNetPool, pckt); /* Free packet */ return; } { M_BLK_ID tmb, fmb = mb; seu_t *seu = &socend_seu[se->se_unit]; /* * Duplicate MBLK, and point to same cluster. */ for (se = seu->seu_devices; se != NULL; se = se->se_next) { if (vid != se->se_vlan) { continue; } eo = &se->se_eo; if (se->se_next != NULL) { tmb = mBlkGet(eo->pNetPool, M_DONTWAIT, MT_DATA); netMblkDup(mb, tmb); } else { fmb = NULL; tmb = mb; } END_RCV_RTN_CALL(eo, tmb); } if (fmb) { netMblkClFree(fmb); } } }