/*
 *  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.
 *
 *
 */

#include "module_ipv6.h"
#include "module_timer.h"
#include "module_hidrv.h"
#include "module_ipsec.h"
#include "module_rtp_relay.h"
#include "Module_ipv6frag.h"
#include "fpp.h"
#include "module_socket.h"
#include "control_socket.h"



int IPv6_Get_Next_Hash_CTEntry(PCtExCommandIPv6 pV6CtCmd, int reset_action);


/**
 * IPv6_delete_CTpair()
 *
 *
 */
int IPv6_delete_CTpair(PCtEntryIPv6 ctEntry)
{
	PCtEntryIPv6 twin_entry;
	struct _tCtCommandIPv6 *message;
	HostMessage *pmsg;

	twin_entry = CT6_TWIN(ctEntry);
	if ((twin_entry->status & CONNTRACK_ORIG) == CONNTRACK_ORIG)
	{
		ctEntry = twin_entry;
		twin_entry = CT6_TWIN(ctEntry);
	}

	// Send indication message
	pmsg = msg_alloc();
	if (!pmsg)
		goto err;

	message = (struct _tCtCommandIPv6 *)pmsg->data;

	// Prepare indication message
	message->action = (ctEntry->status & CONNTRACK_TCP_FIN) ? ACTION_TCP_FIN : ACTION_REMOVED;
	SFL_memcpy(message->Saddr, ctEntry->Saddr_v6, IPV6_ADDRESS_LENGTH);
	SFL_memcpy(message->Daddr, ctEntry->Daddr_v6, IPV6_ADDRESS_LENGTH);
	message->Sport= ctEntry->Sport;
	message->Dport= ctEntry->Dport;
	SFL_memcpy(message->SaddrReply, twin_entry->Saddr_v6, IPV6_ADDRESS_LENGTH);
	SFL_memcpy(message->DaddrReply, twin_entry->Daddr_v6, IPV6_ADDRESS_LENGTH);
	message->SportReply= twin_entry->Sport;
	message->DportReply= twin_entry->Dport;
	message->protocol= GET_PROTOCOL(ctEntry); 
	message->fwmark = 0;

	pmsg->code = CMD_IPV6_CONNTRACK_CHANGE;
	pmsg->length = sizeof(*message);

	if (msg_send(pmsg) < 0)
		goto err;

	//Remove conntrack from list
	ct_remove((PCtEntry)ctEntry, (PCtEntry)twin_entry, Get_Ctentry_Hash(ctEntry), Get_Ctentry_Hash(twin_entry));

	return 0;

err:
	/* Can't send indication, try later from timeout routine */
	IP_expire((PCtEntry)ctEntry);
	IP_expire((PCtEntry)twin_entry);

	return 1;
}




/**
 * IPv6_handle_RESET
 *
 *	-- called from IPv4 reset handler
 *
 *
 */
int IPv6_handle_RESET(void)
{
	int rc = NO_ERR;

	/* free IPv4 sockets entries */
	SOCKET6_free_entries();

	return rc;
}


static PCtEntryIPv6 IPv6_find_ctentry(U32 hash, U32 *saddr, U32 *daddr, U16 sport, U16 dport)
{
	PCtEntryIPv6 pEntry;
	struct slist_entry *entry;

	slist_for_each(pEntry, entry, &ct_cache[hash], list)
	{
		// Note: we don't need to check for protocol match, since if all of the other fields match then the
		//	protocol will always match.
		if (IS_IPV6(pEntry) && !IPV6_CMP(pEntry->Saddr_v6, saddr) && !IPV6_CMP(pEntry->Daddr_v6, daddr) && pEntry->Sport == sport && pEntry->Dport == dport)
			return pEntry;
	}

	return NULL;
}


PCtEntryIPv6 IPv6_get_ctentry(U32 *saddr, U32 *daddr, U16 sport, U16 dport, U16 proto)
{
	U32 hash;
	hash = HASH_CT6(saddr, daddr, sport, dport, proto);
	return IPv6_find_ctentry(hash, saddr, daddr, sport, dport);
}


static int IPv6_HandleIP_Get_Timeout(U16 * p, U16 Length)
{
	int rc = NO_ERR;
	PTimeoutCommand TimeoutCmd;
	CtCommandIPv6 	Ctcmd;
	U32 			hash_key_ct_orig;
	PCtEntryIPv6	pEntry, twin_entry;
	// Check length
	if (Length != sizeof(CtCommandIPv6))
		return ERR_WRONG_COMMAND_SIZE;

	// Ensure alignment
	SFL_memcpy((U8*)&Ctcmd, (U8*)p,  Length);

	hash_key_ct_orig = HASH_CT6(Ctcmd.Saddr, Ctcmd.Daddr, Ctcmd.Sport, Ctcmd.Dport, Ctcmd.protocol);

	if ((pEntry = IPv6_find_ctentry(hash_key_ct_orig, Ctcmd.Saddr, Ctcmd.Daddr, Ctcmd.Sport, Ctcmd.Dport)) != NULL)
	{
		BOOL bidir_flag;
		int timeout_value;
		U32 current_timer, twin_timer;
		memset(p, 0, 256);
		TimeoutCmd = (PTimeoutCommand)(p+1); // first word is for rc
		TimeoutCmd->protocol = GET_PROTOCOL(pEntry); 
		twin_entry = CT6_TWIN(pEntry);
		current_timer = ct_timer - pEntry->last_ct_timer;
		bidir_flag = twin_entry->last_ct_timer != UDP_REPLY_TIMER_INIT;
		if (bidir_flag)
		{
			twin_timer = ct_timer - twin_entry->last_ct_timer;
			if (twin_timer < current_timer)
				current_timer = twin_timer;
		}
		timeout_value = GET_TIMEOUT_VALUE(pEntry, bidir_flag) - current_timer;
		if (timeout_value < 0)
			timeout_value = 0;
		TimeoutCmd->timeout_value1 = (U32)timeout_value / CT_TICKS_PER_SECOND;
	}
	else
	{
		return CMD_ERR;
	}					
	
	
	return rc;
}





/**
 * IPv6_handle_CONNTRACK
 *
 *
 */
int IPv6_handle_CONNTRACK(U16 *p, U16 Length)
{
	PCtEntryIPv6 pEntry_orig = NULL, pEntry_rep = NULL;
	CtExCommandIPv6 Ctcmd;
	U32 hash_key_ct_orig, hash_key_ct_rep;
	int i, reset_action = 0;

	/* Check length */
	/* Legacy support TO BE REMOVED */	
	if ((Length != sizeof(CtCommandIPv6)) && (Length != sizeof(CtExCommandIPv6)) && (Length != sizeof(CtExCommandIPv6_old)))
		return ERR_WRONG_COMMAND_SIZE;

	SFL_memcpy((U8*)&Ctcmd, (U8*)p,  Length);

	hash_key_ct_orig = HASH_CT6(Ctcmd.Saddr, Ctcmd.Daddr, Ctcmd.Sport, Ctcmd.Dport, Ctcmd.protocol);
	hash_key_ct_rep = HASH_CT6(Ctcmd.SaddrReply, Ctcmd.DaddrReply, Ctcmd.SportReply, Ctcmd.DportReply, Ctcmd.protocol);
		
	switch(Ctcmd.action)
	{
		case ACTION_DEREGISTER: 

				pEntry_orig = IPv6_find_ctentry(hash_key_ct_orig, Ctcmd.Saddr, Ctcmd.Daddr, Ctcmd.Sport, Ctcmd.Dport);
				pEntry_rep = IPv6_find_ctentry(hash_key_ct_rep, Ctcmd.SaddrReply, Ctcmd.DaddrReply, Ctcmd.SportReply, Ctcmd.DportReply);
				if (pEntry_orig == NULL || pEntry_rep == NULL ||
								CT6_TWIN(pEntry_orig) != pEntry_rep || CT6_TWIN(pEntry_rep) != pEntry_orig)
					return ERR_CT_ENTRY_NOT_FOUND;

				ct_remove((PCtEntry)pEntry_orig, (PCtEntry)pEntry_rep, hash_key_ct_orig, hash_key_ct_rep);
				break;
	
		case ACTION_REGISTER: //Add entry
		
				pEntry_orig = IPv6_find_ctentry(hash_key_ct_orig, Ctcmd.Saddr, Ctcmd.Daddr, Ctcmd.Sport, Ctcmd.Dport);
				pEntry_rep = IPv6_find_ctentry(hash_key_ct_rep, Ctcmd.SaddrReply, Ctcmd.DaddrReply, Ctcmd.SportReply, Ctcmd.DportReply);
				if (pEntry_orig != NULL || pEntry_rep != NULL)
					    return ERR_CT_ENTRY_ALREADY_REGISTERED; //trying to add exactly the same conntrack

				if (Ctcmd.format & CT_SECURE) {
					if (Ctcmd.SA_nr > SA_MAX_OP)
						return ERR_CT_ENTRY_TOO_MANY_SA_OP;
					for (i=0;i<Ctcmd.SA_nr;i++) {
						if (M_ipsec_sa_cache_lookup_by_h(Ctcmd.SA_handle[i]) == NULL)
							return ERR_CT_ENTRY_INVALID_SA; 
						}	

					if (Ctcmd.SAReply_nr > SA_MAX_OP)
						return ERR_CT_ENTRY_TOO_MANY_SA_OP;
					for (i=0;i<Ctcmd.SAReply_nr;i++) {
						if (M_ipsec_sa_cache_lookup_by_h(Ctcmd.SAReply_handle[i]) == NULL)
							return ERR_CT_ENTRY_INVALID_SA; 
						}	
				}

				/* originator -----------------------------*/					
				if ((pEntry_orig = (PCtEntryIPv6)ct_alloc()) == NULL)
	    			{
		  			return ERR_NOT_ENOUGH_MEMORY;
				}

				SFL_memcpy(pEntry_orig->Daddr_v6, Ctcmd.Daddr, IPV6_ADDRESS_LENGTH);
				SFL_memcpy(pEntry_orig->Saddr_v6, Ctcmd.Saddr, IPV6_ADDRESS_LENGTH);
	  			pEntry_orig->Sport = Ctcmd.Sport;
	  			pEntry_orig->Dport = Ctcmd.Dport;
				
				pEntry_orig->last_ct_timer = ct_timer;
				pEntry_orig->fwmark = Ctcmd.fwmark & 0xFFFF;
				pEntry_orig->status = CONNTRACK_ORIG | CONNTRACK_IPv6;

				if (Ctcmd.flags & CTCMD_FLAGS_ORIG_DISABLED)
					pEntry_orig->status |= CONNTRACK_FF_DISABLED;

				pEntry_orig->route_id = Ctcmd.route_id;

	  			if (Ctcmd.format & CT_SECURE) {
	  				pEntry_orig->status |= CONNTRACK_SEC;
					for (i=0;i < SA_MAX_OP;i++) 
						pEntry_orig->hSAEntry[i] = 
						    (i<Ctcmd.SA_nr) ? Ctcmd.SA_handle[i] : 0;
					if (pEntry_orig->hSAEntry[0])
						pEntry_orig->status &= ~CONNTRACK_SEC_noSA;
					else
						pEntry_orig->status |= CONNTRACK_SEC_noSA;
	  			}


				/* Replier ----------------------------------------*/ 	
				pEntry_rep = CT6_TWIN(pEntry_orig);
				SFL_memcpy(pEntry_rep->Daddr_v6, Ctcmd.DaddrReply, IPV6_ADDRESS_LENGTH);
				SFL_memcpy(pEntry_rep->Saddr_v6, Ctcmd.SaddrReply, IPV6_ADDRESS_LENGTH);
	  			pEntry_rep->Sport = Ctcmd.SportReply;
	  			pEntry_rep->Dport = Ctcmd.DportReply;
				
				
				if (Ctcmd.fwmark & 0x80000000)
					pEntry_rep->fwmark = ((Ctcmd.fwmark >> 16) & 0x7FFF) | (Ctcmd.fwmark & 0x8000);
				else
					pEntry_rep->fwmark = pEntry_orig->fwmark;
				pEntry_rep->status = CONNTRACK_IPv6;
				SET_PROTOCOL(pEntry_orig, pEntry_rep, Ctcmd.protocol);

	  			if(Ctcmd.protocol == IPPROTOCOL_UDP)
	  				pEntry_rep->last_ct_timer = UDP_REPLY_TIMER_INIT;
				else
					pEntry_rep->last_ct_timer = ct_timer;

				if (Ctcmd.flags & CTCMD_FLAGS_REP_DISABLED)
					pEntry_rep->status |= CONNTRACK_FF_DISABLED;

				pEntry_rep->route_id = Ctcmd.route_id_reply;

	  			if (Ctcmd.format & CT_SECURE) {
	  				pEntry_rep->status |= CONNTRACK_SEC;
					for (i=0; i < SA_MAX_OP;i++) 
						pEntry_rep->hSAEntry[i]= 
						    (i<Ctcmd.SAReply_nr) ? Ctcmd.SAReply_handle[i] : 0;
					if (pEntry_rep->hSAEntry[0])
						pEntry_rep->status &= ~CONNTRACK_SEC_noSA;
					else
						pEntry_rep->status |= CONNTRACK_SEC_noSA;
	  			}

				if ((Ctcmd.format & CT_ORIG_TUNNEL_SIT) && !(Ctcmd.flags & CTCMD_FLAGS_ORIG_DISABLED))
				{
					pEntry_orig->tnl_route = L2_route_get(Ctcmd.tunnel_route_id);
					if (IS_NULL_ROUTE(pEntry_orig->tnl_route))
					{
						ct_free((PCtEntry)pEntry_orig);
						return ERR_RT_LINK_NOT_POSSIBLE;
					}
			  	}

				if ((Ctcmd.format & CT_REPL_TUNNEL_SIT) && !(Ctcmd.flags & CTCMD_FLAGS_REP_DISABLED))
				{
					pEntry_rep->tnl_route = L2_route_get(Ctcmd.tunnel_route_id_reply);
					if (IS_NULL_ROUTE(pEntry_rep->tnl_route))
					{
						L2_route_put(pEntry_orig->tnl_route);
						ct_free((PCtEntry)pEntry_orig);
						return ERR_RT_LINK_NOT_POSSIBLE;
					}
			  	}

				// Check for NAT processing
				if (IPV6_CMP(Ctcmd.Saddr, Ctcmd.DaddrReply))
				{
					pEntry_orig->status |= CONNTRACK_SNAT;
					pEntry_rep->status |= CONNTRACK_DNAT;
				}
				else if (IPV6_CMP(Ctcmd.Daddr, Ctcmd.SaddrReply))
				{
					pEntry_orig->status |= CONNTRACK_DNAT;
					pEntry_rep->status |= CONNTRACK_SNAT;
				}

				/* Everything went Ok. We can safely put querier and replier entries in hash tables */

				return ct_add((PCtEntry)pEntry_orig, (PCtEntry)pEntry_rep, hash_key_ct_orig, hash_key_ct_rep);

		case ACTION_UPDATE: 

				pEntry_orig = IPv6_find_ctentry(hash_key_ct_orig, Ctcmd.Saddr, Ctcmd.Daddr, Ctcmd.Sport, Ctcmd.Dport);
				pEntry_rep = IPv6_find_ctentry(hash_key_ct_rep, Ctcmd.SaddrReply, Ctcmd.DaddrReply, Ctcmd.SportReply, Ctcmd.DportReply);
				// Check for errors before changing anything
				if (pEntry_orig == NULL || pEntry_rep == NULL ||
								CT6_TWIN(pEntry_orig) != pEntry_rep || CT6_TWIN(pEntry_rep) != pEntry_orig)
					return ERR_CT_ENTRY_NOT_FOUND;

				if ((Ctcmd.format & CT_ORIG_TUNNEL_SIT) && !(Ctcmd.flags & CTCMD_FLAGS_ORIG_DISABLED))
				{
					PRouteEntry tnl_route;
					tnl_route = L2_route_get(Ctcmd.tunnel_route_id);  // do "dry run"
					if (IS_NULL_ROUTE(tnl_route))
						return ERR_RT_LINK_NOT_POSSIBLE;
					L2_route_put(tnl_route);			  // undo "dry run"
			  	}
				if ((Ctcmd.format & CT_REPL_TUNNEL_SIT) && !(Ctcmd.flags & CTCMD_FLAGS_REP_DISABLED))
				{
					PRouteEntry tnl_route;
					tnl_route = L2_route_get(Ctcmd.tunnel_route_id_reply);  // do "dry run"
					if (IS_NULL_ROUTE(tnl_route))
						return ERR_RT_LINK_NOT_POSSIBLE;
					L2_route_put(tnl_route);			  // undo "dry run"
			  	}
				if (Ctcmd.format & CT_SECURE) {
					if (Ctcmd.SA_nr > SA_MAX_OP)
						return ERR_CT_ENTRY_TOO_MANY_SA_OP;

					for (i = 0; i < Ctcmd.SA_nr; i++) {
						if (pEntry_orig->hSAEntry[i] != Ctcmd.SA_handle[i])
							if (M_ipsec_sa_cache_lookup_by_h(Ctcmd.SA_handle[i]) == NULL)
								return ERR_CT_ENTRY_INVALID_SA; 
					}

					if (Ctcmd.SAReply_nr > SA_MAX_OP)
						return ERR_CT_ENTRY_TOO_MANY_SA_OP;

					for (i = 0; i < Ctcmd.SAReply_nr; i++) {
						if (pEntry_rep->hSAEntry[i] != Ctcmd.SAReply_handle[i])
							if (M_ipsec_sa_cache_lookup_by_h(Ctcmd.SAReply_handle[i]) == NULL)
								return ERR_CT_ENTRY_INVALID_SA;
					}
				}

				pEntry_orig->fwmark = Ctcmd.fwmark & 0xFFFF;

				if (Ctcmd.flags & CTCMD_FLAGS_ORIG_DISABLED) {
					pEntry_orig->status |= CONNTRACK_FF_DISABLED;
					IP_delete_CT_route((PCtEntry)pEntry_orig);
				} else
					pEntry_orig->status &= ~CONNTRACK_FF_DISABLED;

				if (Ctcmd.format & CT_SECURE) {
					pEntry_orig->status |= CONNTRACK_SEC;

					for (i = 0;i < SA_MAX_OP; i++)
						pEntry_orig->hSAEntry[i] = 
						    (i<Ctcmd.SA_nr) ? Ctcmd.SA_handle[i] : 0;

					if (pEntry_orig->hSAEntry[0])
						pEntry_orig->status &= ~ CONNTRACK_SEC_noSA;
					else 
						pEntry_orig->status |= CONNTRACK_SEC_noSA;
				} else
					pEntry_orig->status &= ~CONNTRACK_SEC;

				if (Ctcmd.fwmark & 0x80000000)
					pEntry_rep->fwmark = ((Ctcmd.fwmark >> 16) & 0x7FFF) | (Ctcmd.fwmark & 0x8000);
				else
					pEntry_rep->fwmark = pEntry_orig->fwmark;

				if (Ctcmd.flags & CTCMD_FLAGS_REP_DISABLED) {
					pEntry_rep->status |= CONNTRACK_FF_DISABLED;
					IP_delete_CT_route((PCtEntry)pEntry_rep);
				} else
					pEntry_rep->status &= ~CONNTRACK_FF_DISABLED;

				if (Ctcmd.format & CT_SECURE) {
					pEntry_rep->status |= CONNTRACK_SEC;

					for (i = 0; i < SA_MAX_OP; i++) 
						pEntry_rep->hSAEntry[i]= 
						    (i<Ctcmd.SAReply_nr) ? (Ctcmd.SAReply_handle[i]) : 0;

					if ( pEntry_rep->hSAEntry[0])
						pEntry_rep->status &= ~CONNTRACK_SEC_noSA;
					else 
						pEntry_rep->status |= CONNTRACK_SEC_noSA;
				} else
					pEntry_rep->status &= ~CONNTRACK_SEC;


				/* Update route entries if needed */
				if (IS_NULL_ROUTE(pEntry_orig->pRtEntry))
				{
					pEntry_orig->route_id = Ctcmd.route_id;
				}
				else if (pEntry_orig->route_id != Ctcmd.route_id)
				{
					IP_delete_CT_route((PCtEntry)pEntry_orig);
					pEntry_orig->route_id = Ctcmd.route_id;
				}

				if (IS_NULL_ROUTE(pEntry_rep->pRtEntry))
				{
					pEntry_rep->route_id = Ctcmd.route_id_reply;
				}
				else if (pEntry_rep->route_id != Ctcmd.route_id_reply)
				{
					IP_delete_CT_route((PCtEntry)pEntry_rep);
					pEntry_rep->route_id = Ctcmd.route_id_reply;
				}

				if (pEntry_orig->tnl_route)
				{
					L2_route_put(pEntry_orig->tnl_route);
					pEntry_orig->tnl_route = NULL;
				}
				if ((Ctcmd.format & CT_ORIG_TUNNEL_SIT) && !(Ctcmd.flags & CTCMD_FLAGS_ORIG_DISABLED))
				{
					pEntry_orig->tnl_route = L2_route_get(Ctcmd.tunnel_route_id);
			  	}

				if (pEntry_rep->tnl_route)
				{
					L2_route_put(pEntry_rep->tnl_route);
					pEntry_rep->tnl_route = NULL;
				}
				if ((Ctcmd.format & CT_REPL_TUNNEL_SIT) && !(Ctcmd.flags & CTCMD_FLAGS_REP_DISABLED))
				{
					pEntry_rep->tnl_route = L2_route_get(Ctcmd.tunnel_route_id_reply);
			  	}

				ct_update((PCtEntry)pEntry_orig, (PCtEntry)pEntry_rep, hash_key_ct_orig, hash_key_ct_rep);
				return NO_ERR;

		case ACTION_QUERY:
			reset_action = 1;

		case ACTION_QUERY_CONT:
		{
			PCtExCommandIPv6 pCt = (CtExCommandIPv6*)p;
			int rc;

			rc = IPv6_Get_Next_Hash_CTEntry(pCt, reset_action);

			return rc;
		}

		default :
			return ERR_UNKNOWN_COMMAND;

	}

	return NO_ERR;

}


/**
 * M_ipv6_cmdproc
 *
 *
 *
 */
U16 M_ipv6_cmdproc(U16 cmd_code, U16 cmd_len, U16 *pcmd)
{
	U16 rc;
	U16 querySize = 0;
	U16 action;

	switch (cmd_code)
	{
		case CMD_IPV6_CONNTRACK:			
			action = *pcmd;
			rc = IPv6_handle_CONNTRACK(pcmd, cmd_len);
			if (rc == NO_ERR && (action == ACTION_QUERY || action == ACTION_QUERY_CONT))
				querySize = sizeof(CtExCommandIPv6);
			break;

		case CMD_IPV6_RESET:			
			//now handled as part of IPv4 reset -- just return success
			rc = NO_ERR;
			break;

		case CMD_IPV6_GET_TIMEOUT:
			rc = IPv6_HandleIP_Get_Timeout(pcmd, cmd_len);
			if (rc == NO_ERR)
				querySize = sizeof(TimeoutCommand);
			break;

		case CMD_IPV6_SOCK_OPEN:
			rc = SOCKET6_HandleIP_Socket_Open(pcmd, cmd_len);
			break;

		case CMD_IPV6_SOCK_CLOSE:
			rc = SOCKET6_HandleIP_Socket_Close(pcmd, cmd_len);
			break;

		case CMD_IPV6_SOCK_UPDATE:
			rc = SOCKET6_HandleIP_Socket_Update(pcmd, cmd_len);
			break;

		case CMD_IPV6_FRAGTIMEOUT:
			rc = IPv6_HandleIP_Set_FragTimeout(pcmd, cmd_len);
			break;

		default:
			rc = ERR_UNKNOWN_COMMAND;
			break;
	}

	*pcmd = rc;
	return 2 + querySize;
}


int ipv6_init(void)
{
#if !defined(COMCERTO_2000)
	set_event_handler(EVENT_IPV6, M_ipv6_entry);
#endif

	set_cmd_handler(EVENT_IPV6, M_ipv6_cmdproc);


	return 0;
}

void ipv6_exit(void)
{

}
