Beispiel #1
0
/* Get the count value for a NAT rule */
MV_U32 mvFpNatCountGet(MV_U32 srcIp, MV_U32 dstIp, MV_U16 srcPort, MV_U16 dstPort, MV_U8 proto)
{
    MV_U32      hash, hash_tr;
    MV_FP_NAT_RULE  *pNatRule;

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

    while(pNatRule)
    {
        /* look for a matching rule */
        if( (pNatRule->dstIp == dstIp) && 
            (pNatRule->srcIp == srcIp) &&
            (pNatRule->proto == proto) &&
            (pNatRule->dstPort  == dstPort) &&
            (pNatRule->srcPort  == srcPort) )
        {
	    return pNatRule->new_count;
	}
	pNatRule = pNatRule->next;
    }
    return 0;
}
MV_STATUS mvFpToSSet(MV_FP_RULE *pSetRule)
{
	MV_U32 hash, hash_tr;
	MV_FP_RULE *pRule;

	hash = mv_jhash_3words(pSetRule->routingInfo.dstIp, pSetRule->routingInfo.srcIp, (MV_U32) 0, fp_ip_jhash_iv);
	hash_tr = hash & (ruleDbSize - 1);

	pRule = ruleDb[hash_tr].ruleChain;
	while (pRule) {
		if ((pRule->routingInfo.srcIp == pSetRule->routingInfo.srcIp &&
		     pRule->routingInfo.dstIp == pSetRule->routingInfo.dstIp)) {
			pRule->routingInfo.txq = pSetRule->routingInfo.txq;
			pRule->routingInfo.dscp = pSetRule->routingInfo.dscp;
			nfpRuleUpdateCount++;
#ifdef MV_FP_DEBUG
			mvOsPrintf("ToSNFP_%03u: DIP=%u.%u.%u.%u, SIP=%u.%u.%u.%u, hash=0x%04x TOS=0x%x TxQ=%d\n",
				   nfpRuleUpdateCount, MV_IP_QUAD(pSetRule->routingInfo.dstIp),
				   MV_IP_QUAD(pSetRule->routingInfo.srcIp), hash_tr,
				   pRule->routingInfo.dscp, pRule->routingInfo.txq);
#endif
			return MV_OK;
		}
		pRule = pRule->next;
	}
	return MV_NOT_FOUND;
}
/* Delete a specified rule from the Routing + ARP information table */
MV_STATUS mvFpRuleDelete(MV_FP_RULE *rule)
{
	MV_U32 hash, hash_tr;
	MV_FP_RULE *currRule, *prevRule;

	nfpRuleDeleteCount++;
	hash = mv_jhash_3words(rule->routingInfo.dstIp, rule->routingInfo.srcIp, (MV_U32) 0, fp_ip_jhash_iv);
	hash_tr = hash & (ruleDbSize - 1);

	prevRule = NULL;
	for (currRule = ruleDb[hash_tr].ruleChain; currRule != NULL; prevRule = currRule, currRule = currRule->next) {
		if ((currRule->routingInfo.srcIp == rule->routingInfo.srcIp) &&
		    (currRule->routingInfo.dstIp == rule->routingInfo.dstIp)) {
			if (prevRule == NULL)
				ruleDb[hash_tr].ruleChain = currRule->next;
			else
				prevRule->next = currRule->next;
#ifdef MV_FP_DEBUG
			mvOsPrintf("DelNFP_%03u: DIP=%u.%u.%u.%u, SIP=%u.%u.%u.%u, hash=0x%04x\n",
				   nfpRuleDeleteCount, MV_IP_QUAD(currRule->routingInfo.dstIp),
				   MV_IP_QUAD(currRule->routingInfo.srcIp), hash_tr);
#endif
			mvOsFree(currRule);
			return MV_OK;
		}
	}
	return MV_NOT_FOUND;
}
MV_STATUS mvFpRuleAwareSet(MV_FP_RULE *pSetRule)
{
	MV_U32 hash, hash_tr;
	MV_FP_RULE *pRule;

	hash = mv_jhash_3words(pSetRule->routingInfo.dstIp, pSetRule->routingInfo.srcIp, (MV_U32) 0, fp_ip_jhash_iv);
	hash_tr = hash & (ruleDbSize - 1);

	pRule = ruleDb[hash_tr].ruleChain;
	while (pRule) {
		if ((pRule->routingInfo.srcIp == pSetRule->routingInfo.srcIp) &&
		    (pRule->routingInfo.dstIp == pSetRule->routingInfo.dstIp)) {

			pRule->routingInfo.aware_flags = pSetRule->routingInfo.aware_flags;
#ifdef MV_FP_DEBUG
			mvOsPrintf("Update FP aware: DIP=%u.%u.%u.%u, SIP=%u.%u.%u.%u, hash0x%x, flags=0x%x\n",
				   MV_IP_QUAD(pSetRule->routingInfo.dstIp),
				   MV_IP_QUAD(pSetRule->routingInfo.srcIp), hash_tr, pSetRule->routingInfo.aware_flags);
#endif
			return MV_OK;
		}
		pRule = pRule->next;
	}
#ifdef MV_FP_DEBUG
	mvOsPrintf("FP aware NOT found: DIP=%u.%u.%u.%u, SIP=%u.%u.%u.%u, hash=0x%x, flags=0x%x\n",
		   MV_IP_QUAD(pSetRule->routingInfo.dstIp),
		   MV_IP_QUAD(pSetRule->routingInfo.srcIp), hash_tr, pSetRule->routingInfo.aware_flags);
#endif
	return MV_NOT_FOUND;
}
Beispiel #5
0
/* Find and return the first matching rule in the Routing + ARP information table */
static INLINE MV_FP_RULE* mvFpRuleFind(MV_U32 dstIp, MV_U32 srcIp)
{
    MV_U32      hash, hash_tr;
    MV_FP_RULE* pRule;
    int         count = 0;

    hash = mv_jhash_3words(dstIp, srcIp, (MV_U32)0, fp_ip_jhash_iv);
    hash_tr = hash & (ruleDbSize - 1);

    pRule = ruleDb[hash_tr].ruleChain;

    while(pRule)
    {
        /* look for a matching rule */
        if( (pRule->routingInfo.dstIp == dstIp) && 
            (pRule->routingInfo.srcIp == srcIp) )
        {
	        pRule->mgmtInfo.new_count++;
            return pRule;
        }
        pRule = pRule->next;
        count++;
    }
    return NULL;
}
/* in the Routing + ARP information table */
MV_STATUS mvFpRuleSet(MV_FP_RULE *pSetRule)
{
	MV_U32 hash, hash_tr;
	int depth = 0;
	MV_FP_RULE *pRule, *pNewRule;

	hash = mv_jhash_3words(pSetRule->routingInfo.dstIp, pSetRule->routingInfo.srcIp, (MV_U32) 0, fp_ip_jhash_iv);
	hash_tr = hash & (ruleDbSize - 1);

	pRule = ruleDb[hash_tr].ruleChain;
	while (pRule) {
		if ((pRule->routingInfo.srcIp == pSetRule->routingInfo.srcIp &&
		     pRule->routingInfo.dstIp == pSetRule->routingInfo.dstIp)) {

			mvFpRuleCopy(pRule, pSetRule);
			nfpRuleUpdateCount++;

#ifdef MV_FP_DEBUG
			mvOsPrintf("UpdNFP_%03u: DIP=%u.%u.%u.%u, SIP=%u.%u.%u.%u, hash=0x%04x TOS=0x%x TxQ=%d\n",
				   nfpRuleUpdateCount, MV_IP_QUAD(pSetRule->routingInfo.dstIp),
				   MV_IP_QUAD(pSetRule->routingInfo.srcIp), hash_tr,
				   pRule->routingInfo.dscp, pRule->routingInfo.txq);
#endif
			return MV_OK;
		}
		pRule = pRule->next;
	}

	/* Allocate new entry */
	pNewRule = mvOsMalloc(sizeof(MV_FP_RULE));
	if (pNewRule == NULL) {
		mvOsPrintf("mvFpRuleSet: Can't allocate new rule\n");
		return MV_FAIL;
	}
	mvFpRuleCopy(pNewRule, pSetRule);
	pNewRule->next = NULL;

	if (ruleDb[hash_tr].ruleChain == NULL)
		ruleDb[hash_tr].ruleChain = pNewRule;
	else {
		pRule = ruleDb[hash_tr].ruleChain;
		while (pRule->next != NULL) {
			depth++;
			pRule = pRule->next;
		}
		pRule->next = pNewRule;
	}
	if (depth > nfpHashMaxDepth)
		nfpHashMaxDepth = depth;
	nfpRuleSetCount++;

#ifdef MV_FP_DEBUG
	mvOsPrintf("SetNFP_%03u: DIP=%u.%u.%u.%u, SIP=%u.%u.%u.%u, hash=0x%04x, aware=0x%02x\n",
		   nfpRuleSetCount, MV_IP_QUAD(pSetRule->routingInfo.dstIp),
		   MV_IP_QUAD(pSetRule->routingInfo.srcIp), hash_tr, pSetRule->routingInfo.aware_flags);
#endif
	return MV_OK;
}
Beispiel #7
0
static MV_FP_FDB_RULE* mvFpFdbLookup(MV_U32 ifIndex, MV_U8* pDA)
{
    MV_U32          hash, hash_tr;
    MV_FP_FDB_RULE* pRule;
	MV_U32          bridgeId;
    int             count = 0;

	if (ifIndex >= ETH_FP_IFINDEX_MAX)
		return NULL;

	if (!(bridgeId = fdbMember[ifIndex]))
		return NULL;

    hash = mv_jhash_3words(bridgeId, 0, *(MV_U32*)(pDA+2), fp_ip_jhash_iv);
    hash_tr = hash & (fdbRuleDbSize - 1);

    pRule = fdbRuleDb[hash_tr].ruleChain;

	while (pRule) {
/*
		MV_NFP_DBG("%s: looking %d %02x:%02x:%02x:%02x:%02x:%02x\n",
			   __FUNCTION__, bridgeId, 
				   pRule->fdbInfo.mac[0],
				   pRule->fdbInfo.mac[1],
				   pRule->fdbInfo.mac[2],
				   pRule->fdbInfo.mac[3],
				   pRule->fdbInfo.mac[4],
				   pRule->fdbInfo.mac[5]);
*/
		if ((bridgeId == pRule->fdbInfo.bridge) &&
			(*((MV_U16*)(pDA+0)) == *(MV_U16*)(&pRule->fdbInfo.mac[0])) &&
			(*((MV_U16*)(pDA+2)) == *(MV_U16*)(&pRule->fdbInfo.mac[2])) &&
			(*((MV_U16*)(pDA+4)) == *(MV_U16*)(&pRule->fdbInfo.mac[4])))
		{
			pRule->mgmtInfo.new_count++;
			break;
		}
		pRule = pRule->next;
		count++;
	}
/*
	if (pRule)
		MV_NFP_DBG("%s: lookup bridge=%d %02x:%02x:%02x:%02x:%02x:%02x => if=%d flags=%x\n",
				__FUNCTION__, bridgeId, pDA[0],pDA[1],pDA[2],pDA[3],pDA[4],pDA[5],
				pRule->fdbInfo.ifIndex, pRule->fdbInfo.flags);
	else
		MV_NFP_DBG("%s: lookup bridge=%d %02x:%02x:%02x:%02x:%02x:%02x => unknown\n",
				__FUNCTION__, bridgeId, pDA[0],pDA[1],pDA[2],pDA[3],pDA[4],pDA[5]);
				
*/
    return pRule;
}
/* Get the count value for a rule that matches the given SIP, DIP */
MV_U32 mvFpRouteCountGet(MV_U32 srcIp, MV_U32 dstIp)
{
	MV_U32 hash, hash_tr;
	MV_FP_RULE *pRule;

	hash = mv_jhash_3words(dstIp, srcIp, (MV_U32) 0, fp_ip_jhash_iv);
	hash_tr = hash & (ruleDbSize - 1);

	pRule = ruleDb[hash_tr].ruleChain;
	while (pRule) {
		/* look for a matching rule */
		if ((pRule->routingInfo.dstIp == dstIp) && (pRule->routingInfo.srcIp == srcIp))
			return pRule->mgmtInfo.new_count;

		pRule = pRule->next;
	}
	return 0;
}
Beispiel #9
0
MV_STATUS l2fw_add(MV_U32 srcIP, MV_U32 dstIP, int port)
{
    L2FW_RULE *l2fw_rule;
    MV_U8	  *srcIPchr, *dstIPchr;

    MV_U32 hash = mv_jhash_3words(srcIP, dstIP, (MV_U32) 0, l2fw_jhash_iv);
    hash &= L2FW_HASH_MASK;
    if (numHashEntries == L2FW_HASH_SIZE) {
        printk(KERN_INFO "cannot add entry, hash table is full, there are %d entires \n", L2FW_HASH_SIZE);
        return MV_ERROR;
    }

    srcIPchr = (MV_U8 *)&(srcIP);
    dstIPchr = (MV_U8 *)&(dstIP);

#ifdef CONFIG_MV_ETH_L2FW_DEBUG
    mvOsPrintf("srcIP=%x dstIP=%x in %s\n", srcIP, dstIP, __func__);
    mvOsPrintf("srcIp = %u.%u.%u.%u in %s\n", MV_IPQUAD(srcIPchr), __func__);
    mvOsPrintf("dstIp = %u.%u.%u.%u in %s\n", MV_IPQUAD(dstIPchr), __func__);
#endif

    l2fw_rule = l2fw_lookup(srcIP, dstIP);
    if (l2fw_rule)
        return MV_OK;

    l2fw_rule = (L2FW_RULE *)mvOsMalloc(sizeof(L2FW_RULE));
    if (!l2fw_rule) {
        mvOsPrintf("%s: OOM\n", __func__);
        return MV_FAIL;
    }
#ifdef CONFIG_MV_ETH_L2FW_DEBUG
    mvOsPrintf("adding a rule to l2fw hash in %s\n", __func__);
#endif
    l2fw_rule->srcIP = srcIP;
    l2fw_rule->dstIP = dstIP;
    l2fw_rule->port = port;

    l2fw_rule->next = l2fw_hash[hash];
    l2fw_hash[hash] = l2fw_rule;
    numHashEntries++;
    return MV_OK;
}
Beispiel #10
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 #11
0
static L2FW_RULE *l2fw_lookup(MV_U32 srcIP, MV_U32 dstIP)
{
    MV_U32 hash;
    L2FW_RULE *rule;

    hash = mv_jhash_3words(srcIP, dstIP, (MV_U32) 0, l2fw_jhash_iv);
    hash &= L2FW_HASH_MASK;
    rule = l2fw_hash[hash];
#ifdef CONFIG_MV_ETH_L2FW_DEBUG
    if (rule)
        printk(KERN_INFO "rule is not NULL in %s\n", __func__);
    else
        printk(KERN_INFO "rule is NULL in %s\n", __func__);
#endif
    while (rule) {
        if ((rule->srcIP == srcIP) && (rule->dstIP == dstIP))
            return rule;

        rule = rule->next;
    }
    return NULL;
}
Beispiel #12
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;
}
Beispiel #13
0
MV_STATUS l2fw_add_ip(const char *buf)
{
    char *addr1, *addr2;
    L2FW_RULE *l2fw_rule;
    MV_U32 srcIP;
    MV_U32 dstIP;
    MV_U8	  *srcIPchr, *dstIPchr;
    char dest1[15];
    char dest2[15];
    char *portStr;
    int offset1, offset2, port;
    MV_U32 hash    = 0;
    if (numHashEntries == L2FW_HASH_SIZE) {
        printk(KERN_INFO "cannot add entry, hash table is full, there are %d entires \n", L2FW_HASH_SIZE);
        return MV_ERROR;
    }

    memset(dest1,   0, sizeof(dest1));
    memset(dest2,   0, sizeof(dest2));

    addr1 = strchr(buf, ',');
    addr2 =	strchr(addr1+1, ',');
    offset1 = addr1-buf;
    offset2 = addr2-addr1;
    if (!addr1) {
        printk(KERN_INFO "first separating comma (',') missing in input in %s\n", __func__);
        return MV_FAIL;
    }
    if (!addr2) {
        printk(KERN_INFO "second separating comma (',') missing in input in %s\n", __func__);
        return MV_FAIL;
    }

    strncpy(dest1, buf, addr1-buf);
    srcIP = in_aton(dest1);
    strncpy(dest2, buf+offset1+1, addr2-addr1-1);
    dstIP = in_aton(dest2);
    srcIPchr = (MV_U8 *)&(srcIP);
    dstIPchr = (MV_U8 *)&(dstIP);
    portStr = addr2+1;
    if (*portStr == 'D') {
        L2FW_RULE *l2fw_rule_to_del, *prev;
        hash = mv_jhash_3words(srcIP, dstIP, (MV_U32) 0, l2fw_jhash_iv);
        hash &= L2FW_HASH_MASK;
        l2fw_rule_to_del = l2fw_hash[hash];
        prev = NULL;

        while (l2fw_rule_to_del) {
            if ((l2fw_rule_to_del->srcIP == srcIP) &&
                    (l2fw_rule_to_del->dstIP == dstIP)) {
                if (prev)
                    prev->next = l2fw_rule_to_del->next;
                else
                    l2fw_hash[hash] = l2fw_rule_to_del->next;
                mvOsPrintf("%u.%u.%u.%u->%u.%u.%u.%u deleted\n", MV_IPQUAD(srcIPchr), MV_IPQUAD(dstIPchr));
                mvOsFree(l2fw_rule_to_del);
                numHashEntries--;
                return MV_OK;
            }

            prev = l2fw_rule_to_del;
            l2fw_rule_to_del = l2fw_rule_to_del->next;
        }
        mvOsPrintf("%u.%u.%u.%u->%u.%u.%u.%u : entry not found\n", MV_IPQUAD(srcIPchr), MV_IPQUAD(dstIPchr));
        return MV_NOT_FOUND;
    }

    port = atoi(portStr);
    hash = mv_jhash_3words(srcIP, dstIP, (MV_U32) 0, l2fw_jhash_iv);
    hash &= L2FW_HASH_MASK;

    l2fw_rule = l2fw_lookup(srcIP, dstIP);
    if (l2fw_rule) {
        mvOsPrintf("%u.%u.%u.%u->%u.%u.%u.%u : entry already exist\n",
                   MV_IPQUAD(srcIPchr), MV_IPQUAD(dstIPchr));
        return MV_OK;
    }

    l2fw_rule = (L2FW_RULE *)mvOsMalloc(sizeof(L2FW_RULE));
    if (!l2fw_rule) {
        mvOsPrintf("%s: OOM\n", __func__);
        return MV_FAIL;
    }
#ifdef CONFIG_MV_ETH_L2FW_DEBUG
    mvOsPrintf("adding a rule to l2fw hash in %s\n", __func__);
#endif
    l2fw_rule->srcIP = srcIP;
    l2fw_rule->dstIP = dstIP;
    l2fw_rule->port = port;

    l2fw_rule->next = l2fw_hash[hash];
    l2fw_hash[hash] = l2fw_rule;
    numHashEntries++;
    return MV_OK;

}
Beispiel #14
0
static INLINE MV_U32 mvFpFdbRuleHash(MV_FP_FDB_RULE *rule)
{
	return mv_jhash_3words(	rule->fdbInfo.bridge, 
				0,*(MV_U32*)(rule->fdbInfo.mac+2), fp_ip_jhash_iv);
}