/*******************************************************************************
Copyright (C) Marvell International Ltd. and its affiliates

This software file (the "File") is owned and distributed by Marvell
International Ltd. and/or its affiliates ("Marvell") under the following
alternative licensing terms.  Once you have made an election to distribute the
File under one of the following license alternatives, please (i) delete this
introductory statement regarding license alternatives, (ii) delete the two
license alternatives that you have not elected to use and (iii) preserve the
Marvell copyright notice above.

********************************************************************************
Marvell Commercial License Option

If you received this File from Marvell and you have entered into a commercial
license agreement (a "Commercial License") with Marvell, the File is licensed
to you under the terms of the applicable Commercial License.

********************************************************************************
Marvell GPL License Option

If you received this File from Marvell, you may opt to use, redistribute and/or
modify this File in accordance with the terms and conditions of the General
Public License Version 2, June 1991 (the "GPL License"), a copy of which is
available along with the File in the license.txt file or by writing to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
on the worldwide web at http://www.gnu.org/licenses/gpl.txt.

THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
DISCLAIMED.  The GPL License provides additional details about this warranty
disclaimer.
********************************************************************************
Marvell BSD License Option

If you received this File from Marvell, you may opt to use, redistribute and/or
modify this File under the following licensing terms.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    *   Redistributions of source code must retain the above copyright notice,
	this list of conditions and the following disclaimer.

    *   Redistributions in binary form must reproduce the above copyright
	notice, this list of conditions and the following disclaimer in the
	documentation and/or other materials provided with the distribution.

    *   Neither the name of Marvell nor the names of its contributors may be
	used to endorse or promote products derived from this software without
	specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*******************************************************************************/

/* includes */
#include "mvTypes.h"
#include "mvOs.h"
#include "mvStack.h"
#include "mvDebug.h"
#include "eth/nfp/mvNfp.h"
#include "eth/mvEth.h"

struct natRuleHashBucket *natRuleDb;
MV_U32 natRuleDbSize;

MV_U32 natRuleUpdateCount = 0;
MV_U32 natRuleSetCount = 0;
MV_U32 natRuleDeleteCount = 0;
MV_U32 natHashMaxDepth = 0;

/* Initialize NFP NAT Rule Database (SNAT + DNAT table) */
MV_STATUS mvFpNatDbInit(MV_U32 dbSize)
{
	natRuleDb = (struct natRuleHashBucket *)mvOsMalloc(sizeof(struct natRuleHashBucket) * dbSize);
	if (natRuleDb == NULL) {
		mvOsPrintf("NFP NAT Rule DB: Not Enough Memory\n");
		return MV_NO_RESOURCE;
	}
	natRuleDbSize = dbSize;
	memset(natRuleDb, 0, sizeof(struct natRuleHashBucket) * natRuleDbSize);

	natRuleSetCount = natRuleDeleteCount = natRuleUpdateCount = 0;

	mvOsPrintf("mvFpNatDb (%p): %d entries, %d bytes\n",
		   natRuleDb, natRuleDbSize, sizeof(struct natRuleHashBucket) * natRuleDbSize);

	return MV_OK;
}

/* Clear NFP NAT Rule Database (SNAT + DNAT table) */
MV_STATUS mvFpNatDbClear(void)
{
	MV_U32 i = 0;
	MV_FP_NAT_RULE *currRule;
	MV_FP_NAT_RULE *tmpRule;

	if (natRuleDb == NULL)
		return MV_NOT_INITIALIZED;

	for (i = 0; i < natRuleDbSize; i++) {
		currRule = natRuleDb[i].natRuleChain;
		while (currRule != NULL) {
			tmpRule = currRule;
			currRule = currRule->next;
			mvOsFree(tmpRule);
		}
		natRuleDb[i].natRuleChain = NULL;
	}
	return MV_OK;
}

/* Free NAT Database memory */
void mvFpNatDbDestroy(void)
{
	if (natRuleDb != NULL)
		mvOsFree(natRuleDb);
}

static void mvFpNatRuleUpdate(MV_FP_NAT_RULE *dstRule, const MV_FP_NAT_RULE *srcRule)
{
	dstRule->flags = srcRule->flags;
	dstRule->newIp = srcRule->newIp;
	dstRule->newPort = srcRule->newPort;
	dstRule->new_count = srcRule->new_count;
	dstRule->old_count = srcRule->old_count;
}

/* 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;
}

/* 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;
}

int mvFpNatPktUpdate(MV_IP_HEADER *pIpHdr, MV_FP_NAT_RULE *pDnatRule, MV_FP_NAT_RULE *pSnatRule)
{
	MV_UDP_HEADER *pUdpHdr;
	MV_TCP_HEADER *pTcpHdr;
	MV_ICMP_ECHO_HEADER *pIcmpHdr;
	int hdr_size = 0;
	MV_U16 *pDstPort = NULL, *pSrcPort = NULL;

	switch (pIpHdr->protocol) {
	case MV_IP_PROTO_TCP:
		pTcpHdr = (MV_TCP_HEADER *) ((unsigned)pIpHdr + sizeof(MV_IP_HEADER));
		pDstPort = &pTcpHdr->dest;
		pSrcPort = &pTcpHdr->source;
		hdr_size = sizeof(MV_TCP_HEADER);
		break;

	case MV_IP_PROTO_UDP:
		pUdpHdr = (MV_UDP_HEADER *) ((unsigned)pIpHdr + sizeof(MV_IP_HEADER));
		pDstPort = &pUdpHdr->dest;
		pSrcPort = &pUdpHdr->source;
		hdr_size = sizeof(MV_UDP_HEADER);
		break;

	case MV_IP_PROTO_ICMP:
		pIcmpHdr = (MV_ICMP_ECHO_HEADER *) ((unsigned)pIpHdr + sizeof(MV_IP_HEADER));
		if ((pIcmpHdr->type == MV_ICMP_ECHO) || (pIcmpHdr->type == MV_ICMP_ECHOREPLY)) {
			pDstPort = &pIcmpHdr->id;
			pSrcPort = &pIcmpHdr->id;
			hdr_size = sizeof(MV_ICMP_ECHO_HEADER);
		} else {
			mvOsPrintf("Wrong ICMP type: 0x%x\n", pIcmpHdr->type & 0xFF);
		}
		break;

	case MV_IP_PROTO_ZERO_HOP:
		/* Do nothing - only IP addresses are updated for this protocol */
		break;

	default:
		mvOsPrintf("Unexpected IP protocol: 0x%x\n", pIpHdr->protocol);
	}
	if (pDnatRule != NULL) {
		if (pDnatRule->flags & MV_FP_DIP_CMD_MAP)
			pIpHdr->dstIP = pDnatRule->newIp;
		if ((pDnatRule->flags & MV_FP_DPORT_CMD_MAP) && (pDstPort != NULL))
			*pDstPort = pDnatRule->newPort;
	}

	if (pSnatRule != NULL) {
		if (pSnatRule->flags & MV_FP_SIP_CMD_MAP)
			pIpHdr->srcIP = pSnatRule->newIp;

		if ((pSnatRule->flags & MV_FP_SPORT_CMD_MAP) && (pSrcPort != NULL))
			*pSrcPort = pSnatRule->newPort;
	}
	return hdr_size;
}

/* 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");
}

/* Print NFP NAT Rule Database (SNAT + DNAT table) */
MV_STATUS mvFpNatDbPrint(void)
{
	MV_U32 count, i = 0;
	MV_FP_NAT_RULE *currRule;

	mvOsPrintf("\nPrinting NFP NAT Rule Database: \n");
	count = 0;
	for (i = 0; i < natRuleDbSize; i++) {
		currRule = natRuleDb[i].natRuleChain;

		if (currRule != NULL)
			mvOsPrintf("\n%03u: NAT DB hash=0x%x\n", count, i);

		while (currRule != NULL) {
			if ((currRule->flags != MV_FP_NULL_BINDING) || (currRule->new_count > 0)) {
				mvOsPrintf("%03u: Rule=%p, Next=%p\n", count, currRule, currRule->next);
				mvFpNatRulePrint(currRule);
			}
			currRule = currRule->next;
			count++;
		}
	}
	return MV_OK;
}

/* 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;
}
