/**
 * VpHalHbiRead(): Sends a command, and receives up to 256 data words over the
 * HBI.
 *
 *  Accepts a uint16 HBI command which is little-endian or big-endian, depending
 * on the host architecture.  Command words on the HBI bus are always big-
 * endian.  This function is responsible for byte-swapping the command word, if
 * required.
 *
 * Retrieves an array of uint16 data words.  No byte-swapping is necessary on
 * data words in this function.  Instead, the HBI bus can be configured in
 * VpHalHbiInit() to match the endianness of the host platform.
 *
 * Params:
 *   uint8 deviceId: Device Id (chip select ID)
 *   uint8 numwords: the number of words to receive, minus 1
 *   uint16p data: where to put them
 *
 * Returns:
 *   TRUE on success, FALSE on failure
 */
uint8 VpHalHbiRead(
    VpDeviceIdType deviceId,
    uint16 cmd,
    uint8 numwords,
    uint16p data)
{
	uint8 i;
	uint16 cmdSwapped = MV_16BIT_BE(cmd);
	uint16p pReadBuff = &readBuff[0];

	if((numwords + 1) > HBI_MAX_DATA_LEN)
	{
		mvOsPrintf("%s: Error, HBI data length too big(%u)\n", __FUNCTION__, (numwords + 1));
		return FALSE;
	}

	DBG("%s: READ(cmd-0x%x), (size-%d bytes)\n", __FUNCTION__, cmd, HBI_DATA_BYTES(numwords));
	mvSysTdmSpiRead(deviceId, (uint8p)&cmdSwapped, HBI_CMD_BYTES, (uint8p)pReadBuff, HBI_DATA_BYTES(numwords));

	for(i = 0;i < (numwords + 1); i++)
		data[i] = MV_16BIT_BE(pReadBuff[i]);

	return TRUE;

} /* VpHalHbiRead() */
Beispiel #2
0
INLINE MV_VOID mvNfpSecBuildIPTunnel(MV_PKT_INFO *pPktInfo, MV_NFP_SEC_SA_ENTRY *pSAEntry)
{
	MV_IP_HEADER *pIpHdr, *pIntIpHdr;
	MV_U16 newIpTotalLength;

	newIpTotalLength = pPktInfo->pFrags[0].dataSize - sizeof(MV_802_3_HEADER);

	pIpHdr = (MV_IP_HEADER *) (pPktInfo->pFrags[0].bufVirtPtr + sizeof(MV_802_3_HEADER));
	pIntIpHdr = (MV_IP_HEADER *) ((MV_U8 *) (pIpHdr) + sizeof(MV_IP_HEADER) + sizeof(MV_ESP_HEADER) +
				      pSAEntry->ivSize);

	/* TBD - review below settings in RFC */
	pIpHdr->version = 0x45;
	pIpHdr->tos = 0;
	pIpHdr->checksum = 0;
	pIpHdr->totalLength = MV_16BIT_BE(newIpTotalLength);
	pIpHdr->identifier = 0;
	pIpHdr->fragmentCtrl = 0;
	pIpHdr->ttl = pIntIpHdr->ttl - 1;
	pIpHdr->protocol = MV_IP_PROTO_ESP;
	pIpHdr->srcIP = pSAEntry->tunnelHdr.sIp;
	pIpHdr->dstIP = pSAEntry->tunnelHdr.dIp;

	pPktInfo->status = ETH_TX_IP_NO_FRAG | ETH_TX_GENERATE_IP_CHKSUM_MASK | (0x5 << ETH_TX_IP_HEADER_LEN_OFFSET);

	return;
}
Beispiel #3
0
/* Print a NFP NAT Rule */
void    mvFpNatRulePrint(const MV_FP_NAT_RULE *rule)
{
	/* Note: some of the fields in the NAT rule may contain invalid values */
    mvOsPrintf("Original packet: ");
    mvOsPrintf("SIP=");
    mvDebugPrintIpAddr(MV_32BIT_BE(rule->srcIp)), 
    mvOsPrintf(", DIP=");
    mvDebugPrintIpAddr(MV_32BIT_BE(rule->dstIp)), 
    mvOsPrintf(", SPort=%d", MV_16BIT_BE(rule->srcPort));
    mvOsPrintf(", DPort=%d", MV_16BIT_BE(rule->dstPort)); 
    mvOsPrintf("\nNAT Info: ");
    mvOsPrintf("count=%u, flags=0x%x", rule->new_count, rule->flags);
    mvOsPrintf(", newIP=");
    mvDebugPrintIpAddr(MV_32BIT_BE(rule->newIp)); 
    mvOsPrintf(", newPort=%d", MV_16BIT_BE(rule->newPort));
    mvOsPrintf("\n");
}
/**
 * VpHalHbiCmd(): Sends a command word over the HBI, with no data words.
 *
 *  Accepts a uint16 HBI command which is little-endian or big-endian,
 * depending on the host architecture.  Command words on the HBI bus are always
 * big-endian. This function is responsible for byte-swapping if required.
 *
 * Params:
 * uint8 deviceId: Device Id (chip select ID)
 * uint16 cmd: the command word to send
 *
 * Returns:
 *   TRUE on success, FALSE on failure
 */
uint8 VpHalHbiCmd(
    VpDeviceIdType deviceId,
    uint16 cmd)
{
	uint16 cmdSwapped = MV_16BIT_BE(cmd);

	DBG("%s: WRITE(cmd-0x%x)\n", __FUNCTION__, cmd);
	mvSysTdmSpiWrite(deviceId, (uint8p)&cmdSwapped, HBI_CMD_BYTES, NULL, 0);

	return TRUE;
} /* VpHalHbiCmd() */
Beispiel #5
0
/* Delete a specified NAT rule from the SNAT + DNAT table */
MV_STATUS mvFpNatRuleDelete(MV_FP_NAT_RULE *natRule)
{
    MV_U32      hash, hash_tr;
    MV_FP_NAT_RULE  *currRule, *prevRule;

    natRuleDeleteCount++;

    hash = mv_jhash_3words(natRule->dstIp, natRule->srcIp, 
                            (MV_U32)((natRule->dstPort << 16) | natRule->srcPort), 
                            (MV_U32)((fp_ip_jhash_iv << 8) | natRule->proto));
    hash_tr = hash & (natRuleDbSize - 1);

    prevRule = NULL;
    for (currRule = natRuleDb[hash_tr].natRuleChain; 
	 currRule != NULL; 
	 prevRule = currRule, currRule = currRule->next) 
    {
	    if (currRule->srcIp == natRule->srcIp && 
		currRule->dstIp == natRule->dstIp && 
		currRule->srcPort == natRule->srcPort && 
		currRule->dstPort == natRule->dstPort && 
		currRule->proto == natRule->proto ) 
	    {		
		    if (prevRule == NULL)
			    natRuleDb[hash_tr].natRuleChain = currRule->next;
		    else
			    prevRule->next = currRule->next;

#ifdef MV_FP_DEBUG
		    mvOsPrintf("DelNAT_%03u: DIP=0x%08x, SIP=0x%08x, proto=%d, DPort=%d, SPort=%d, hash=0x%04x\n",
              	        natRuleDeleteCount, currRule->dstIp, currRule->srcIp, currRule->proto, 
			            MV_16BIT_BE(currRule->dstPort), MV_16BIT_BE(currRule->srcPort), hash_tr);
#endif
		mvOsFree(currRule);	
		return MV_OK;
	    }
    }
    return MV_NOT_FOUND;
}
Beispiel #6
0
	mvOsMemset(nat_hash, 0, bytes);

	mvOsPrintf("NFP (nat) init %d entries, %d bytes\n", NFP_NAT_HASH_SIZE, bytes);

	return MV_OK;
}

static MV_VOID mvNfpNatRulePrint(NFP_RULE_NAT *nat)
{
	mvOsPrintf(MV_IPQUAD_FMT":%d"
				"->"MV_IPQUAD_FMT":%d"
				" %-2d "
				"%s:"MV_IPQUAD_FMT" "
				"age=%x (%p)\n",
				MV_IPQUAD(nat->sip), MV_16BIT_BE(nat->ports & 0xFFFF),
				MV_IPQUAD(nat->dip), MV_16BIT_BE(nat->ports >> 16),
				nat->proto, nat->flags & NFP_F_DNAT ? "DNAT" : "SNAT",
				MV_IPQUAD(nat->nip), nat->age, nat);
}

static INLINE MV_U32 mvNfpNatHash(NFP_RULE_NAT *nat)
{
	int family = MV_INET;
	return mv_jhash_2addr(family, (const MV_U8 *)&nat->sip, (const MV_U8 *)&nat->dip,
					nat->ports | nat->proto, mgr_rule_jhash_iv);

}

static INLINE NFP_RULE_NAT *mvNfpNatLookup(NFP_RULE_NAT *nat2)
{
Beispiel #7
0
MV_STATUS mvNfpSecEspProcess(MV_PKT_INFO *pPktInfo, MV_NFP_SEC_SA_ENTRY *pSAEntry)
{
	MV_CESA_COMMAND *pCesaCmd;
	MV_CESA_MBUF *pCesaMbuf;
	MV_NFP_SEC_CESA_PRIV *pCesaPriv;
	MV_STATUS status;
	MV_IP_HEADER *pIpHdr;
	MV_BUF_INFO *pBuf;

	pCesaCmd = &cesaCmdArray[cesaCmdIndx];
	pCesaMbuf = &cesaMbufArray[cesaCmdIndx];
	cesaCmdIndx++;
	cesaCmdIndx %= MV_NFP_SEC_Q_SIZE;
	pCesaPriv = &cesaPrivArray[cesaPrivIndx++];
	cesaPrivIndx = cesaPrivIndx % (MV_NFP_SEC_Q_SIZE + MV_NFP_SEC_REQ_Q_SIZE);

	pCesaPriv->pPktInfo = pPktInfo;
	pCesaPriv->pSaEntry = pSAEntry;
	pCesaPriv->pCesaCmd = pCesaCmd;

	/*
	 *  Fix, encrypt/decrypt the IP payload only, --BK 20091027
	 */
	pBuf = pPktInfo->pFrags;
	pIpHdr = (MV_IP_HEADER *) (pBuf->bufVirtPtr + sizeof(MV_802_3_HEADER));
	pBuf->dataSize = MV_16BIT_BE(pIpHdr->totalLength) + sizeof(MV_802_3_HEADER);

	pBuf->bufVirtPtr += MV_NFP_SEC_ESP_OFFSET;
	pBuf->bufPhysAddr += MV_NFP_SEC_ESP_OFFSET;
	pBuf->dataSize -= MV_NFP_SEC_ESP_OFFSET;
	pBuf->bufAddrShift -= MV_NFP_SEC_ESP_OFFSET;

	pCesaMbuf->pFrags = pPktInfo->pFrags;
	pCesaMbuf->numFrags = 1;
	pCesaMbuf->mbufSize = pBuf->dataSize;

	pCesaCmd->pReqPrv = (MV_VOID *) pCesaPriv;
	pCesaCmd->sessionId = pSAEntry->sid;
	pCesaCmd->pSrc = pCesaMbuf;
	pCesaCmd->pDst = pCesaMbuf;
	pCesaCmd->skipFlush = MV_TRUE;

	/* Assume ESP */
	pCesaCmd->cryptoOffset = sizeof(MV_ESP_HEADER) + pSAEntry->ivSize;
	pCesaCmd->cryptoLength = pBuf->dataSize - (sizeof(MV_ESP_HEADER)
						   + pSAEntry->ivSize + pSAEntry->digestSize);
	pCesaCmd->ivFromUser = 0;	/* relevant for encode only */
	pCesaCmd->ivOffset = sizeof(MV_ESP_HEADER);
	pCesaCmd->macOffset = 0;
	pCesaCmd->macLength = pBuf->dataSize - pSAEntry->digestSize;
	pCesaCmd->digestOffset = pBuf->dataSize - pSAEntry->digestSize;

	/* save original digest in case of decrypt+auth */
	if (pSAEntry->secOp == MV_NFP_SEC_DECRYPT) {
		memcpy(pCesaPriv->orgDigest, (pBuf->bufVirtPtr + pCesaCmd->digestOffset), pSAEntry->digestSize);
		mvNfpSecInvRange((pBuf->bufVirtPtr + pCesaCmd->digestOffset), pSAEntry->digestSize);
	}

	pSAEntry->stats.bytes += pBuf->dataSize;
	if (pSAEntry->secOp == MV_NFP_SEC_DECRYPT)
		pSAEntry->stats.decrypt++;
	else
		pSAEntry->stats.encrypt++;

	disable_irq(CESA_IRQ);
	status = mvCesaAction(pCesaCmd);
	enable_irq(CESA_IRQ);
	if (status != MV_OK) {
		pSAEntry->stats.rejected++;
		mvOsPrintf("%s: mvCesaAction failed %d\n", __func__, status);
	}

	return status;
}
Beispiel #8
0
/* Set a NAT rule: create a new rule or update an existing rule in the SNAT + DNAT table */
MV_STATUS mvFpNatRuleSet(MV_FP_NAT_RULE *pSetRule)
{
    int             depth = 0;
    MV_U32          hash, hash_tr;
    MV_FP_NAT_RULE  *pNatRule, *pNewRule;

    hash = mv_jhash_3words(pSetRule->dstIp, pSetRule->srcIp, 
                            (MV_U32)((pSetRule->dstPort << 16) | pSetRule->srcPort), 
                            (MV_U32)((fp_ip_jhash_iv << 8) | pSetRule->proto));
    hash_tr = hash & (natRuleDbSize - 1);
    pNatRule = natRuleDb[hash_tr].natRuleChain;

    while(pNatRule)
    {
        /* look for a matching rule */
        if( (pNatRule->dstIp == pSetRule->dstIp) && 
            (pNatRule->srcIp == pSetRule->srcIp) &&
            (pNatRule->proto == pSetRule->proto) &&
            (pNatRule->dstPort  == pSetRule->dstPort) &&
            (pNatRule->srcPort  == pSetRule->srcPort) )
        {
            /* update rule */
            mvFpNatRuleUpdate(pNatRule, pSetRule);
            natRuleUpdateCount++;

#ifdef MV_FP_DEBUG
            mvOsPrintf("UpdNAT_%03u: DIP=0x%08x, SIP=0x%08x, proto=%d, DPort=%d, SPort=%d, hash=0x%04x, flags=0x%02x\n",
                        natRuleUpdateCount, pNatRule->dstIp, pNatRule->srcIp, pNatRule->proto, 
                        MV_16BIT_BE(pNatRule->dstPort), MV_16BIT_BE(pNatRule->srcPort), hash_tr, pNatRule->flags);
#endif
            return MV_OK;
        }
        pNatRule = pNatRule->next;
    }
    /* Allocate new entry */
    pNewRule = mvOsMalloc(sizeof(MV_FP_NAT_RULE));
    if(pNewRule == NULL)
    {
        mvOsPrintf("mvFpNatRuleSet: Can't allocate new rule\n");
        return MV_FAIL;
    }

    memcpy(pNewRule, pSetRule, sizeof(*pNewRule));
    pNewRule->next = NULL;

    if(natRuleDb[hash_tr].natRuleChain == NULL)
    {
        natRuleDb[hash_tr].natRuleChain = pNewRule;
    }
    else 
    {
	    pNatRule = natRuleDb[hash_tr].natRuleChain;
        
        while (pNatRule->next != NULL)
        {
            depth++;
	        pNatRule = pNatRule->next;	    
        }

	    pNatRule->next = pNewRule;
    }
    if(depth > natHashMaxDepth)
        natHashMaxDepth = depth;

    natRuleSetCount++;

#ifdef MV_FP_DEBUG
    mvOsPrintf("SetNAT_%03u: DIP=0x%08x, SIP=0x%08x, proto=%d, DPort=%d, SPort=%d, hash=0x%04x, flags=0x%02x\n",
                natRuleSetCount, pNewRule->dstIp, pNewRule->srcIp, pNewRule->proto, 
                MV_16BIT_BE(pNewRule->dstPort), MV_16BIT_BE(pNewRule->srcPort), hash_tr, pNewRule->flags);
#endif
    return MV_OK;
}