/*
 *  Copyright (c) 2009 Mindspeed Technologies, Inc.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.

 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 *
 */


#ifndef _MODULE_IPV4_H_
#define _MODULE_IPV4_H_

#include "channels.h"
#include "modules.h"
#include "fe.h"
#include "common_hdrs.h"
#include "layer2.h"
#include "module_socket.h"


#define UDP_REPLY_TIMER_INIT 0xFFFFFFFF

#define MAX_L2_HEADER	18

//Conntrack entry
#if !defined(COMCERTO_2000)
typedef struct _tCtEntry{
	// start of common header -- must match IPv6
	struct slist_entry list;
	U32 last_ct_timer;
	union {
	    U16 fwmark;
	    struct {
		U16 queue : 5;
		U16 vlan_pbits : 3;
		U16 dscp_mark_flag : 1;
		U16 dscp_mark_value : 6;
		U16 set_vlan_pbits : 1;
	    } __attribute__((packed));
	};
	U16 status;
	union {
		PRouteEntry pRtEntry;
		U32 route_id;
	};
	// end of common header
	U32 Saddr_v4;
	U32 Daddr_v4;
	U16 Sport;
	U16 Dport;
	U16 ip_chksm_corr;
	U16 tcp_udp_chksm_corr;
// DC line boundary
	U32 twin_Saddr;
	U32 twin_Daddr;
	U16 twin_Sport;
	U16 twin_Dport;
	U16 unused1;
	U16 unused2;
	//U32 unused2;
	PRouteEntry tnl_route;
	U16 hSAEntry[SA_MAX_OP];
	U8 rtpqos_slot;
}CtEntry, *PCtEntry;

static inline PRouteEntry ct_tnl_route(PCtEntry pCtEntry)
{
	return pCtEntry->tnl_route;
}

static inline PRouteEntry ct_route(PCtEntry pCtEntry)
{
	return pCtEntry->pRtEntry;
}

static inline U8 GET_PROTOCOL(PCtEntry pCtEntry)
{
	return ct_proto[pCtEntry->status & CONNTRACK_PROTO_MASK]; 
}

static inline void SET_PROTOCOL(PCtEntry pCtEntry_orig,PCtEntry pCtEntry_rep, U8 Proto)
{
	switch(Proto)
	{
	case IPPROTOCOL_UDP:
		pCtEntry_orig->status |= CONNTRACK_UDP;
		pCtEntry_rep->status |= CONNTRACK_UDP;
	break;
	case IPPROTOCOL_IPIP:
		pCtEntry_orig->status |= CONNTRACK_IPIP;
		pCtEntry_rep->status |= CONNTRACK_IPIP;
	break;
	case IPPROTOCOL_TCP:
	default:
	break;
}

#elif defined(COMCERTO_2000_CONTROL)

struct hw_ct {
	U32	next;
	U32	flags;

	/******* !!!!!!!!!!!!!!!!!! *********/
	/* Be careful about adding/moving fields in this structure -- hw_ct_delayed_remove() does a
	partial structure copy that depends on the exact layout of the structure */
	/******* !!!!!!!!!!!!!!!!!! *********/

	U16	Sport;
	U16	Dport;
	U8	proto;
	U8	rtpqos_slot;
	U16	hash;

	union {
		struct {
			U32 Saddr_v4;
			U32 Daddr_v4;
			U32 twin_Saddr;
			U32 twin_Daddr;
			U16 twin_Sport;
			U16 twin_Dport;
			struct hw_route_4o6 tnl4o6_route;
		};

		struct {
			U32 Saddr_v6[4];
			U32 Daddr_v6[4];
			struct hw_route tnl6o4_route;
		};

	};

	/* End of fields used by hardware */
	struct hw_route route;

	union {
		U16 fwmark;

		struct {
			U16 set_vlan_pbits : 1;
			U16 dscp_mark_value : 6;
			U16 dscp_mark_flag : 1;
			U16 vlan_pbits : 3;
			U16 queue : 5;
		};
	};

	U16 status;

	U32 active;

	U16 ip_chksm_corr;
	U16 tcp_udp_chksm_corr;

	U16 hSAEntry[SA_MAX_OP];

	U32 twin_dma_addr;

	/******* !!!!!!!!!!!!!!!!!! *********/
	/* Be careful about adding/moving fields in this structure -- hw_ct_delayed_remove() does a
	partial structure copy that depends on the exact layout of the structure */
	/******* !!!!!!!!!!!!!!!!!! *********/

	U32 dma_addr;			/** Physical address of the hardware conntrack, used for keepalive writeback and delayed removal*/

	/* The bellow fields are only used by host software, so keep them at the end of the structure */
	struct dlist_head list;		/** if the entry is in the hash array, this is the list head for the hash bucket,
					 otherwise it's a list entry in the hash bucket list */
	struct dlist_head rlist;
	struct _tCtEntry *pCtEntry;	/** pointer to the software conntrack */
	unsigned long removal_time;
};


typedef struct _tCtEntry {
	struct slist_entry list;
	U16	Sport;
	U16	Dport;
	U8	proto;
	U8	inPhyPortNum;
	U16	hash;

	union {
		struct {
			U32 Saddr_v4;
			U32 Daddr_v4;
			U32 unused1;
			U32 unused2;
			U32 twin_Saddr;
			U32 twin_Daddr;
			U16 twin_Sport;
			U16 twin_Dport;
			U32 unused3;
		};

		struct {
			U32 Saddr_v6[4];
			U32 Daddr_v6[4];
		};
	};

	/* End of fields used by hardware */

	U32 route_id;
	PRouteEntry pRtEntry;

	union {
		U16 fwmark;

		struct {
			U16 set_vlan_pbits : 1;
			U16 dscp_mark_value : 6;
			U16 dscp_mark_flag : 1;
			U16 vlan_pbits : 3;
			U16 queue : 5;
		};
	};

	U16 status;

	U32 last_ct_timer;

	U16 ip_chksm_corr;
	U16 tcp_udp_chksm_corr;

	PRouteEntry tnl_route;
	U16 hSAEntry[SA_MAX_OP];

	struct _tCtEntry *twin;

	struct hw_ct *ct;	/** pointer to the hardware conntrack */
}CtEntry, *PCtEntry;

static inline U8 GET_PROTOCOL(PCtEntry pCtEntry)
{
	return pCtEntry->proto; 
}

static inline void SET_PROTOCOL(PCtEntry pCtEntry_orig,PCtEntry pCtEntry_rep, U8 Proto)
{
	pCtEntry_orig->proto = Proto;
	pCtEntry_rep->proto  = Proto;
}

#define IS_HASH_ARRAY(ctrl, ct_addr)	(((unsigned long)(ct_addr) >= (unsigned long)(ctrl->hash_array_baseaddr)) \
	&& ((unsigned long)(ct_addr) < ((unsigned long)(ctrl->hash_array_baseaddr) + (NUM_CT_ENTRIES * CLASS_ROUTE_SIZE))))
#else	// defined(COMCERTO_2000)

void M_IPV4_rtp_process_from_util(PMetadata mtd, lmem_trailer_t *trailer);
void M_IPV4_process_from_util(PMetadata mtd, lmem_trailer_t *trailer);


typedef struct _tCtEntry{
	struct slist_entry list;
	U32	flags;
	U16	Sport;
	U16	Dport;
	U8	proto;
	U8	rtpqos_slot;
	U16	hash;

	union {

	struct {
			U32 Saddr_v4;
			U32 Daddr_v4;
			U32 twin_Saddr;
			U32 twin_Daddr;
			U16 twin_Sport;
			U16 twin_Dport;
			RouteEntry_4o6 tnl4o6_route;
		};

		struct {
			U32 Saddr_v6[4];
			U32 Daddr_v6[4];
			RouteEntry tnl6o4_route;
		};

	};

	/* End of fields used by hardware */
	RouteEntry route;

	union {
		U16 fwmark;

		struct {
			U16 set_vlan_pbits : 1;
			U16 dscp_mark_value : 6;
			U16 dscp_mark_flag : 1;
			U16 vlan_pbits : 3;
			U16 queue : 5;
		};
	};

	U16 status;
	U32 active;
	U16 ip_chksm_corr;
	U16 tcp_udp_chksm_corr;
	U16 hSAEntry[SA_MAX_OP];

	U32 twin_dma_addr;
	U32 dma_addr;			/** Physical address of the hardware conntrack, used for keepalive writeback and delayed removal*/
}CtEntry, *PCtEntry;


#if !defined(COMCERTO_2000_CONTROL)
static inline PRouteEntry_4o6 ct_tnl_route(PCtEntry pCtEntry)
{
	return &pCtEntry->tnl4o6_route;
}
#endif

static inline PRouteEntry ct_route(PCtEntry pCtEntry)
{
	return &pCtEntry->route;
}

#if defined(CFG_STANDALONE)
static inline void temp_route_setup(PRouteEntry pRtEntry, PCtEntry pCtEntry, PMetadata mtd)
{
//#define TEST_PPPOE
#if !defined(TEST_PPPOE)
	pRtEntry->itf = (mtd->input_port == 0 ? &phy_port[1].itf : &phy_port[0].itf);
	
	if (pRtEntry->mtu == 0)
		pRtEntry->mtu = 1500;

#else /* to test PPPoE */
	pRtEntry->itf = (mtd->input_port == 0 ? &phy_port[1].itf : &pppoe_itf[0].itf);

	if (pRtEntry->mtu == 0)
		pRtEntry->mtu = 1492;
#endif
}
#endif

#endif	/* !defined(COMCERTO_2000) */

#if defined(COMCERTO_2000_CONTROL)
#define CT_TWIN(pentry)		(((PCtEntry)(pentry))->twin)
#define CT6_TWIN(pentry)	CT_TWIN(pentry)
#define CT_ORIG(pentry)		((((PCtEntry)(pentry))->status & CONNTRACK_ORIG) ? (PCtEntry)(pentry) : ((PCtEntry)(pentry))->twin)
#define CT6_ORIG(pentry)	CT_ORIG(pentry)
#define CT_REPLY_BIT(pentry)	(!(((PCtEntry)(pentry))->status & CONNTRACK_ORIG))
#elif defined(COMCERTO_2000)
#define CT_TWIN(pentry)		(((PCtEntry)(pentry))->twin_dma_addr)
#define CT6_TWIN(pentry)	CT_TWIN(pentry)
#else
#define CT_TWIN(pentry)		(PCtEntry)((U32)(pentry) ^ CTENTRY_UNIDIR_SIZE)
#define CT6_TWIN(pentry)	(PCtEntryIPv6)((U32)(pentry) ^ CTENTRY_UNIDIR_SIZE)
#define CT_ORIG(pentry)		(PCtEntry)((U32)(pentry) & ~CTENTRY_UNIDIR_SIZE)
#define CT6_ORIG(pentry)	(PCtEntryIPv6)((U32)(pentry) & ~CTENTRY_UNIDIR_SIZE)
#define CT_REPLY_BIT(pentry)	((U32)(pentry) & CTENTRY_UNIDIR_SIZE)
#endif



extern struct slist_head rt_cache[];

PCtEntry ct_alloc(void);
void ct_free(PCtEntry pEntry_orig);
int ct_add(PCtEntry pEntry_orig, PCtEntry pEntry_rep, U32 hash_orig, U32 hash_rep);
void ct_update(PCtEntry pEntry_orig, PCtEntry pEntry_rep, U32 hash_orig, U32 hash_rep);
void ct_remove(PCtEntry pEntry_orig, PCtEntry pEntry_rep, U32 hash_orig, U32 hash_rep);

int ipv4_init(void);
void ipv4_exit(void);

#if defined(COMCERTO_2000_CONTROL) || !defined(COMCERTO_2000)
U32 Get_Ctentry_Hash(PVOID pblock) __attribute__ ((noinline));
int IPv4_delete_CTpair(PCtEntry ctEntry) __attribute__ ((noinline));
void IP_deleteCt_from_onif_index(U32 if_index) __attribute__ ((noinline));
void IP_MarkSwap(PCtEntry pCtEntry, PCtEntry pCtTwin) __attribute__ ((noinline));
PRouteEntry IP_Check_Route(PCtEntry pCtEntry);
void IP_delete_CT_route(PCtEntry pCtEntry) __attribute__ ((noinline));
void IP_expire(PCtEntry pCtEntry);
U32 IP_get_fwmark(PCtEntry pOrigEntry, PCtEntry pReplEntry);
#endif

#if !defined(COMCERTO_2000)
void M_ipv4_entry(void) __attribute__((section ("fast_path")));
#endif

PCtEntry IPv4_get_ctentry(U32 saddr, U32 daddr, U16 sport, U16 dport, U16 proto) __attribute__ ((noinline));

void M_IPV4_process_packet(PMetadata mtd) __attribute__((section ("fast_path")));

void M_RTP_RELAY_process_packet(PMetadata mtd);


PMetadata IPv4_fragment_packet(PMetadata mtd, ipv4_hdr_t *ipv4_hdr, U32 mtu, U32 preL2_len, U32 if_type);
#if defined(COMCERTO_2000)
PMetadata IPv4_fragment_packet_ipsec(PMetadata mtd, ipv4_hdr_t *ipv4_hdr, U32 mtu, U32 preL2_len, U32 if_type);
#endif


int IPv4_xmit_on_socket(PMetadata mtd, PSockEntry pSocket, BOOL ipv4_update, U32 payload_diff, U8* inner_ipv4hdr);


#if defined(COMCERTO_2000)

#define CT_VALID	(1 << 0)
#define CT_USED		(1 << 1)
#define CT_UPDATING	(1 << 2)

extern U32 class_route_table_base;
extern U32 class_route_table_hash_mask;

#if defined(COMCERTO_2000_CONTROL)
extern struct slist_head ct_cache[];
#else
extern PCtEntry ct_cache[];

static inline void ct_keepalive(PCtEntry pCtEntry)
{
	/* If host has marked connection inactive, update ddr structure */
	if (!pCtEntry->active)
	{
		PCtEntry ddr_ct = (PCtEntry)pCtEntry->dma_addr;

		ddr_ct->active = 1;
	}
}
#endif

#define CRCPOLY_BE 0x04c11db7
static inline U32 crc32_be(U8 *data)
{
	int i, j;
	U32 crc = 0xffffffff;

	for (i = 0; i < 4; i++) {
		crc ^= *data++ << 24;

		for (j = 0; j < 8; j++)
			crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
	}

	return crc;
}

static __inline U32 HASH_CT(U32 Saddr, U32 Daddr, U32 Sport, U32 Dport, U16 Proto)
{
	U32 sum;

	sum = Saddr ^ htonl(ntohs(Sport));
	sum = crc32_be((u8 *)&sum);

	sum += ntohl(Daddr);
	sum += Proto;
	sum += ntohs(Dport);
//	sum += phy_no;

	return sum & CT_TABLE_HASH_MASK;
}

PCtEntry M_ipv4_frag_ConntrackMatch(PMetadata mtd, ipv4_hdr_t * ipv4_hdr);

#else

extern struct slist_head ct_cache[];

static __inline U32 HASH_CT(U32 Saddr, U32 Daddr, U32 Sport, U32 Dport, U16 Proto)
{
	U32 sum;
	sum = Saddr + ((Daddr << 7) | (Daddr >> 25));
	sum ^= Sport + ((Dport << 11) | (Dport >> 21));
	sum ^= (sum >> 16);
	sum ^= (sum >> 8);
	return (sum ^ Proto) & CT_TABLE_HASH_MASK;
}

// Fast CTData

extern U8 Fast_CTData[];
extern U8 *pFast_CTData_freelist;

#define Is_FastCT_block(pblock) (((U32)(pblock) & 0xFF000000) == 0x0a000000)

void Fast_CTData_CopyBlock(PVOID newblock, PVOID origblock) __attribute__ ((noinline));

static INLINE U8 *Fast_CTData_Alloc(void)
{
	U8 *pblock;
	if (pFast_CTData_freelist != NULL)
	{
		pblock = pFast_CTData_freelist;
		pFast_CTData_freelist = *(U8 **)pblock;
	}
	else
	{
		pblock = Heap_Alloc(CTENTRY_BIDIR_SIZE);
	}
	return pblock;
}


static INLINE void CTData_Free(PVOID pblock)
{
	if (Is_FastCT_block(pblock))
	{
		*(U8 **)pblock = pFast_CTData_freelist;
		pFast_CTData_freelist = (U8 *)pblock;
	}
	else
		Heap_Free(pblock);
}

static inline void ct_keepalive(PCtEntry pCtEntry)
{
        // we update the timeout since we saw a new packet
        pCtEntry->last_ct_timer = ct_timer;
}


#endif /* COMCERTO_2000 */

#endif /* _MODULE_IPV4_H_ */
