/*
 **************************************************************************
 * Copyright (c) 2014-2018, 2020-2021, The Linux Foundation. All rights reserved.
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **************************************************************************
 */
#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/icmp.h>
#include <linux/kthread.h>
#include <linux/debugfs.h>
#include <linux/pkt_sched.h>
#include <linux/string.h>
#include <linux/random.h>
#include <net/route.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <asm/unaligned.h>
#include <asm/uaccess.h>	/* for put_user */
#include <net/ipv6.h>
#include <net/ip6_route.h>
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_bridge.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
#include <net/netfilter/ipv4/nf_defrag_ipv4.h>

/*
 * Debug output levels
 * 0 = OFF
 * 1 = ASSERTS / ERRORS
 * 2 = 1 + WARN
 * 3 = 2 + INFO
 * 4 = 3 + TRACE
 */
#define DEBUG_LEVEL ECM_DB_DEBUG_LEVEL

#include "ecm_types.h"
#include "ecm_db_types.h"
#include "ecm_state.h"
#include "ecm_tracker.h"
#include "ecm_classifier.h"
#include "ecm_front_end_types.h"
#include "ecm_classifier_default.h"
#include "ecm_db.h"

/*
 * Global list.
 * All instances are inserted into global list - this allows easy iteration of all instances of a particular type.
 * The list is doubly linked for fast removal.  The list is in no particular order.
 */
struct ecm_db_host_instance *ecm_db_hosts;

/*
 * Host hash table
 */
#define ECM_DB_HOST_HASH_SLOTS 32768
static struct ecm_db_host_instance **ecm_db_host_table;	/* Slots of the host hash table */
static int *ecm_db_host_table_lengths;			/* Tracks how long each chain is */

static int ecm_db_host_count = 0;	/* Number of hosts allocated */

/*
 * ecm_db_host_generate_hash_index()
 *	Calculate the hash index.
 */
static inline ecm_db_host_hash_t ecm_db_host_generate_hash_index(ip_addr_t address)
{
	uint32_t tuple;
	uint32_t hash_val;

	ECM_IP_ADDR_HASH(tuple, address);
	hash_val = (uint32_t)jhash_1word(tuple, ecm_db_jhash_rnd);
	return (ecm_db_host_hash_t)(hash_val & (ECM_DB_HOST_HASH_SLOTS - 1));
}

/*
 * _ecm_db_host_count_get()
 *	Return the host count (lockless).
 */
int _ecm_db_host_count_get(void)
{
	return ecm_db_host_count;
}

/*
 * _ecm_db_host_ref()
 */
void _ecm_db_host_ref(struct ecm_db_host_instance *hi)
{
	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed\n", hi);
	hi->refs++;
	DEBUG_TRACE("%px: host ref %d\n", hi, hi->refs);
	DEBUG_ASSERT(hi->refs > 0, "%px: ref wrap\n", hi);
}

/*
 * ecm_db_host_ref()
 */
void ecm_db_host_ref(struct ecm_db_host_instance *hi)
{
	spin_lock_bh(&ecm_db_lock);
	_ecm_db_host_ref(hi);
	spin_unlock_bh(&ecm_db_lock);
}
EXPORT_SYMBOL(ecm_db_host_ref);

/*
 * ecm_db_hosts_get_and_ref_first()
 *	Obtain a ref to the first host instance, if any
 */
struct ecm_db_host_instance *ecm_db_hosts_get_and_ref_first(void)
{
	struct ecm_db_host_instance *hi;
	spin_lock_bh(&ecm_db_lock);
	hi = ecm_db_hosts;
	if (hi) {
		_ecm_db_host_ref(hi);
	}
	spin_unlock_bh(&ecm_db_lock);
	return hi;
}
EXPORT_SYMBOL(ecm_db_hosts_get_and_ref_first);

/*
 * ecm_db_host_get_and_ref_next()
 *	Return the next host in the list given a host
 */
struct ecm_db_host_instance *ecm_db_host_get_and_ref_next(struct ecm_db_host_instance *hi)
{
	struct ecm_db_host_instance *hin;
	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed", hi);
	spin_lock_bh(&ecm_db_lock);
	hin = hi->next;
	if (hin) {
		_ecm_db_host_ref(hin);
	}
	spin_unlock_bh(&ecm_db_lock);
	return hin;
}
EXPORT_SYMBOL(ecm_db_host_get_and_ref_next);

#ifdef ECM_DB_ADVANCED_STATS_ENABLE
/*
 * ecm_db_host_data_stats_get()
 *	Return data stats for the instance
 */
void ecm_db_host_data_stats_get(struct ecm_db_host_instance *hi, uint64_t *from_data_total, uint64_t *to_data_total,
						uint64_t *from_packet_total, uint64_t *to_packet_total,
						uint64_t *from_data_total_dropped, uint64_t *to_data_total_dropped,
						uint64_t *from_packet_total_dropped, uint64_t *to_packet_total_dropped)
{
	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed", hi);
	spin_lock_bh(&ecm_db_lock);
	if (from_data_total) {
		*from_data_total = hi->from_data_total;
	}
	if (to_data_total) {
		*to_data_total = hi->to_data_total;
	}
	if (from_packet_total) {
		*from_packet_total = hi->from_packet_total;
	}
	if (to_packet_total) {
		*to_packet_total = hi->to_packet_total;
	}
	if (from_data_total_dropped) {
		*from_data_total_dropped = hi->from_data_total_dropped;
	}
	if (to_data_total_dropped) {
		*to_data_total_dropped = hi->to_data_total_dropped;
	}
	if (from_packet_total_dropped) {
		*from_packet_total_dropped = hi->from_packet_total_dropped;
	}
	if (to_packet_total_dropped) {
		*to_packet_total_dropped = hi->to_packet_total_dropped;
	}
	spin_unlock_bh(&ecm_db_lock);
}
EXPORT_SYMBOL(ecm_db_host_data_stats_get);
#endif

/*
 * ecm_db_host_address_get()
 *	Return address of host
 */
void ecm_db_host_address_get(struct ecm_db_host_instance *hi, ip_addr_t addr)
{
	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed", hi);
	ECM_IP_ADDR_COPY(addr, hi->address);
}
EXPORT_SYMBOL(ecm_db_host_address_get);

/*
 * ecm_db_host_on_link_get()
 *	Return on link status of host
 */
bool ecm_db_host_on_link_get(struct ecm_db_host_instance *hi)
{
	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed", hi);
	return hi->on_link;
}
EXPORT_SYMBOL(ecm_db_host_on_link_get);

/*
 * ecm_db_host_deref()
 *	Release a ref to a host instance, possibly causing removal from the database and destruction of the instance
 */
int ecm_db_host_deref(struct ecm_db_host_instance *hi)
{
	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed\n", hi);

	spin_lock_bh(&ecm_db_lock);
	hi->refs--;
	DEBUG_TRACE("%px: host deref %d\n", hi, hi->refs);
	DEBUG_ASSERT(hi->refs >= 0, "%px: ref wrap\n", hi);

	if (hi->refs > 0) {
		int refs = hi->refs;
		spin_unlock_bh(&ecm_db_lock);
		return refs;
	}

#ifdef ECM_DB_XREF_ENABLE
	DEBUG_ASSERT((hi->mappings == NULL) && (hi->mapping_count == 0), "%px: mappings not null\n", hi);
#endif

	/*
	 * Remove from database if inserted
	 */
	if (!(hi->flags & ECM_DB_HOST_FLAGS_INSERTED)) {
		spin_unlock_bh(&ecm_db_lock);
	} else {
		struct ecm_db_listener_instance *li;

		/*
		 * Remove from the global list
		 */
		if (!hi->prev) {
			DEBUG_ASSERT(ecm_db_hosts == hi, "%px: host table bad\n", hi);
			ecm_db_hosts = hi->next;
		} else {
			hi->prev->next = hi->next;
		}
		if (hi->next) {
			hi->next->prev = hi->prev;
		}
		hi->prev = NULL;
		hi->next = NULL;

		/*
		 * Unlink it from the host hash table
		 */
		if (!hi->hash_prev) {
			DEBUG_ASSERT(ecm_db_host_table[hi->hash_index] == hi, "%px: hash table bad\n", hi);
			ecm_db_host_table[hi->hash_index] = hi->hash_next;
		} else {
			hi->hash_prev->hash_next = hi->hash_next;
		}
		if (hi->hash_next) {
			hi->hash_next->hash_prev = hi->hash_prev;
		}
		hi->hash_next = NULL;
		hi->hash_prev = NULL;
		ecm_db_host_table_lengths[hi->hash_index]--;
		DEBUG_ASSERT(ecm_db_host_table_lengths[hi->hash_index] >= 0, "%px: invalid table len %d\n", hi, ecm_db_host_table_lengths[hi->hash_index]);

		spin_unlock_bh(&ecm_db_lock);

		/*
		 * Throw removed event to listeners
		 */
		DEBUG_TRACE("%px: Throw host removed event\n", hi);
		li = ecm_db_listeners_get_and_ref_first();
		while (li) {
			struct ecm_db_listener_instance *lin;
			if (li->host_removed) {
				li->host_removed(li->arg, hi);
			}

			/*
			 * Get next listener
			 */
			lin = ecm_db_listener_get_and_ref_next(li);
			ecm_db_listener_deref(li);
			li = lin;
		}
	}

	/*
	 * Throw final event
	 */
	if (hi->final) {
		hi->final(hi->arg);
	}

	/*
	 * We can now destroy the instance
	 */
	DEBUG_CLEAR_MAGIC(hi);
	kfree(hi);

	/*
	 * Decrease global host count
	 */
	spin_lock_bh(&ecm_db_lock);
	ecm_db_host_count--;
	DEBUG_ASSERT(ecm_db_host_count >= 0, "%px: host count wrap\n", hi);
	spin_unlock_bh(&ecm_db_lock);

	return 0;
}
EXPORT_SYMBOL(ecm_db_host_deref);

/*
 * ecm_db_host_find_and_ref()
 *	Lookup and return a host reference if any
 */
struct ecm_db_host_instance *ecm_db_host_find_and_ref(ip_addr_t address)
{
	ecm_db_host_hash_t hash_index;
	struct ecm_db_host_instance *hi;

	DEBUG_TRACE("Lookup host with addr " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(address));

	/*
	 * Compute the hash chain index and prepare to walk the chain
	 */
	hash_index = ecm_db_host_generate_hash_index(address);

	/*
	 * Iterate the chain looking for a host with matching details
	 */
	spin_lock_bh(&ecm_db_lock);
	hi = ecm_db_host_table[hash_index];
	while (hi) {
		if (!ECM_IP_ADDR_MATCH(hi->address, address)) {
			hi = hi->hash_next;
			continue;
		}

		_ecm_db_host_ref(hi);
		spin_unlock_bh(&ecm_db_lock);
		DEBUG_TRACE("host found %px\n", hi);
		return hi;
	}
	spin_unlock_bh(&ecm_db_lock);
	DEBUG_TRACE("Host not found\n");
	return NULL;
}
EXPORT_SYMBOL(ecm_db_host_find_and_ref);

#ifdef ECM_DB_XREF_ENABLE
/*
 * ecm_db_host_mappings_get_and_ref_first()
 *	Return a reference to the first mapping of this host
 */
static struct ecm_db_mapping_instance *ecm_db_host_mappings_get_and_ref_first(struct ecm_db_host_instance *hi)
{
	struct ecm_db_mapping_instance *mi = NULL;

	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%p: magic failed", hi);

	spin_lock_bh(&ecm_db_lock);
	mi = hi->mappings;
	if (mi) {
		_ecm_db_mapping_ref(mi);
	}
	spin_unlock_bh(&ecm_db_lock);

	return mi;
}

/*
 * ecm_db_host_mapping_get_and_ref_next()
 *	Return the next host mapping in the list given a mapping
 */
static struct ecm_db_mapping_instance *ecm_db_host_mapping_get_and_ref_next(struct ecm_db_mapping_instance *mi)
{
	struct ecm_db_mapping_instance *nmi = NULL;

	DEBUG_CHECK_MAGIC(mi, ECM_DB_MAPPING_INSTANCE_MAGIC, "%p: magic failed", mi);

	spin_lock_bh(&ecm_db_lock);
	nmi = mi->mapping_next;
	if (nmi) {
		_ecm_db_mapping_ref(nmi);
	}
	spin_unlock_bh(&ecm_db_lock);

	return nmi;
}

/*
 * ecm_db_host_connections_defunct_by_dir()
 *	Defunct the connections associated with the IP address in the given direction.
 */
void ecm_db_host_connections_defunct_by_dir(ip_addr_t addr, ecm_db_obj_dir_t dir)
{
	struct ecm_db_host_instance *hi;
	struct ecm_db_mapping_instance *mi;

	hi = ecm_db_host_find_and_ref(addr);
	if (!hi) {
		DEBUG_WARN("Unable to find host instance\n");
		return;
	}

	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed\n", hi);

	mi = ecm_db_host_mappings_get_and_ref_first(hi);
	while (mi) {
		struct ecm_db_connection_instance *ci;
		struct ecm_db_mapping_instance *min;

		ci = ecm_db_mapping_connections_get_and_ref_first(mi, dir);
		while (ci) {
			struct ecm_db_connection_instance *cin;
			DEBUG_TRACE("%px: defunct %d\n", ci, ci->serial);
			ecm_db_connection_make_defunct(ci);

			cin = ecm_db_connection_mapping_get_and_ref_next(ci, dir);
			ecm_db_connection_deref(ci);
			ci = cin;
		}

		min = ecm_db_host_mapping_get_and_ref_next(mi);
		ecm_db_mapping_deref(mi);
		mi = min;
	}

	if (ECM_IP_ADDR_IS_V4(addr)) {
		DEBUG_INFO("%px: Defuncting connections %s " ECM_IP_ADDR_DOT_FMT "\n",
			   hi, ecm_db_obj_dir_strings[dir], ECM_IP_ADDR_TO_DOT(addr));
	} else {
		DEBUG_INFO("%px: Defuncting connections %s " ECM_IP_ADDR_OCTAL_FMT "\n",
			   hi, ecm_db_obj_dir_strings[dir], ECM_IP_ADDR_TO_OCTAL(addr));
	}
}

/*
 * ecm_db_host_connections_defunct_by_src_and_dest()
 *	Defunct the connections with the given source and destination IP addresses.
 */
void ecm_db_host_connections_defunct_by_src_and_dest(ip_addr_t src_addr, ip_addr_t dest_addr)
{
	struct ecm_db_host_instance *src_hi;
	struct ecm_db_mapping_instance *src_mi;

	src_hi = ecm_db_host_find_and_ref(src_addr);
	if (!src_hi) {
		DEBUG_WARN("Unable to find host instance\n");
		return;
	}

	DEBUG_CHECK_MAGIC(src_hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed\n", src_hi);

	src_mi = ecm_db_host_mappings_get_and_ref_first(src_hi);
	while (src_mi) {
		struct ecm_db_connection_instance *ci;
		struct ecm_db_mapping_instance *src_min;

		ci = ecm_db_mapping_connections_get_and_ref_first(src_mi, ECM_DB_OBJ_DIR_FROM);
		while (ci) {
			struct ecm_db_connection_instance *cin;
			ip_addr_t dst_ip;

			ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);

			if (ECM_IP_ADDR_MATCH(dest_addr, dst_ip)) {
				DEBUG_TRACE("%px: defunct %d\n", ci, ci->serial);
				ecm_db_connection_make_defunct(ci);
			}

			cin = ecm_db_connection_mapping_get_and_ref_next(ci, ECM_DB_OBJ_DIR_FROM);
			ecm_db_connection_deref(ci);
			ci = cin;
		}

		src_min = ecm_db_host_mapping_get_and_ref_next(src_mi);
		ecm_db_mapping_deref(src_mi);
		src_mi = src_min;
	}

	if (ECM_IP_ADDR_IS_V4(src_addr)) {
		DEBUG_INFO("%px: Defuncting connections from " ECM_IP_ADDR_DOT_FMT "to " ECM_IP_ADDR_DOT_FMT "\n",
			   src_hi, ECM_IP_ADDR_TO_DOT(src_addr), ECM_IP_ADDR_TO_DOT(dest_addr));
	} else {
		DEBUG_INFO("%px: Defuncting connections from " ECM_IP_ADDR_OCTAL_FMT "to " ECM_IP_ADDR_OCTAL_FMT "\n",
			   src_hi, ECM_IP_ADDR_TO_OCTAL(src_addr), ECM_IP_ADDR_TO_OCTAL(dest_addr));
	}
}

/*
 * ecm_db_host_mapping_count_get()
 *	Return the number of mappings to this host
 */
int ecm_db_host_mapping_count_get(struct ecm_db_host_instance *hi)
{
	int count;

	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed\n", hi);

	spin_lock_bh(&ecm_db_lock);
	count = hi->mapping_count;
	spin_unlock_bh(&ecm_db_lock);
	return count;
}
EXPORT_SYMBOL(ecm_db_host_mapping_count_get);
#endif

/*
 * ecm_db_host_add()
 *	Add a host instance into the database
 */
void ecm_db_host_add(struct ecm_db_host_instance *hi, ip_addr_t address, bool on_link, ecm_db_host_final_callback_t final, void *arg)
{
	ecm_db_host_hash_t hash_index;
	struct ecm_db_listener_instance *li;

	spin_lock_bh(&ecm_db_lock);
	DEBUG_CHECK_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC, "%px: magic failed\n", hi);
	DEBUG_ASSERT(!(hi->flags & ECM_DB_HOST_FLAGS_INSERTED), "%px: inserted\n", hi);
#ifdef ECM_DB_XREF_ENABLE
	DEBUG_ASSERT((hi->mappings == NULL) && (hi->mapping_count == 0), "%px: mappings not null\n", hi);
#endif
	spin_unlock_bh(&ecm_db_lock);

	hi->arg = arg;
	hi->final = final;
	ECM_IP_ADDR_COPY(hi->address, address);
	hi->on_link = on_link;

	/*
	 * Compute hash index into which host will be added
	 */
	hash_index = ecm_db_host_generate_hash_index(address);
	hi->hash_index = hash_index;

	/*
	 * Add into the global list
	 */
	spin_lock_bh(&ecm_db_lock);
	hi->flags |= ECM_DB_HOST_FLAGS_INSERTED;
	hi->prev = NULL;
	hi->next = ecm_db_hosts;
	if (ecm_db_hosts) {
		ecm_db_hosts->prev = hi;
	}
	ecm_db_hosts = hi;

	/*
	 * Add host into the hash table
	 */
	hi->hash_prev = NULL;
	hi->hash_next = ecm_db_host_table[hash_index];
	if (ecm_db_host_table[hash_index]) {
		ecm_db_host_table[hash_index]->hash_prev = hi;
	}
	ecm_db_host_table[hash_index] = hi;
	ecm_db_host_table_lengths[hash_index]++;
	DEBUG_ASSERT(ecm_db_host_table_lengths[hash_index] > 0, "%px: invalid table len %d\n", hi, ecm_db_host_table_lengths[hash_index]);

	/*
	 * Set time of add
	 */
	hi->time_added = ecm_db_time;
	spin_unlock_bh(&ecm_db_lock);

	/*
	 * Throw add event to the listeners
	 */
	DEBUG_TRACE("%px: Throw host added event\n", hi);
	li = ecm_db_listeners_get_and_ref_first();
	while (li) {
		struct ecm_db_listener_instance *lin;
		if (li->host_added) {
			li->host_added(li->arg, hi);
		}

		/*
		 * Get next listener
		 */
		lin = ecm_db_listener_get_and_ref_next(li);
		ecm_db_listener_deref(li);
		li = lin;
	}
}
EXPORT_SYMBOL(ecm_db_host_add);

/*
 * ecm_db_host_state_get()
 *	Prepare a host message
 */
int ecm_db_host_state_get(struct ecm_state_file_instance *sfi, struct ecm_db_host_instance *hi)
{
	int result;
	char address[ECM_IP_ADDR_STR_BUFF_SIZE];
#ifdef ECM_DB_XREF_ENABLE
	int mapping_count;
#endif
	uint32_t time_added;
	bool on_link;
#ifdef ECM_DB_ADVANCED_STATS_ENABLE
	uint64_t from_data_total;
	uint64_t to_data_total;
	uint64_t from_packet_total;
	uint64_t to_packet_total;
	uint64_t from_data_total_dropped;
	uint64_t to_data_total_dropped;
	uint64_t from_packet_total_dropped;
	uint64_t to_packet_total_dropped;
#endif

	DEBUG_TRACE("Prep host msg for %px\n", hi);

	/*
	 * Create a small xml stats element for our host.
	 * Extract information from the host for inclusion into the message
	 */
#ifdef ECM_DB_XREF_ENABLE
	mapping_count = ecm_db_host_mapping_count_get(hi);
#endif
	ecm_ip_addr_to_string(address, hi->address);
	time_added = hi->time_added;
	on_link = hi->on_link;

#ifdef ECM_DB_ADVANCED_STATS_ENABLE
	ecm_db_host_data_stats_get(hi, &from_data_total, &to_data_total,
			&from_packet_total, &to_packet_total,
			&from_data_total_dropped, &to_data_total_dropped,
			&from_packet_total_dropped, &to_packet_total_dropped);
#endif

	if ((result = ecm_state_prefix_add(sfi, "host"))) {
		return result;
	}

	if ((result = ecm_state_write(sfi, "address", "%s", address))) {
		return result;
	}
	if ((result = ecm_state_write(sfi, "time_added", "%u", time_added))) {
		return result;
	}
	if ((result = ecm_state_write(sfi, "on_link", "%d", on_link))) {
		return result;
	}

#ifdef ECM_DB_XREF_ENABLE
	if ((result = ecm_state_write(sfi, "mappings", "%d", mapping_count))) {
		return result;
	}
#endif

#ifdef ECM_DB_ADVANCED_STATS_ENABLE
	if ((result = ecm_db_adv_stats_state_write(sfi, from_data_total, to_data_total,
			from_packet_total, to_packet_total, from_data_total_dropped,
			to_data_total_dropped, from_packet_total_dropped,
			to_packet_total_dropped))) {
		return result;
	}
#endif

	return ecm_state_prefix_remove(sfi);
}
EXPORT_SYMBOL(ecm_db_host_state_get);

/*
 * ecm_db_host_hash_table_lengths_get()
 *	Return hash table length
 */
int ecm_db_host_hash_table_lengths_get(int index)
{
	int length;

	DEBUG_ASSERT((index >= 0) && (index < ECM_DB_HOST_HASH_SLOTS), "Bad protocol: %d\n", index);
	spin_lock_bh(&ecm_db_lock);
	length = ecm_db_host_table_lengths[index];
	spin_unlock_bh(&ecm_db_lock);
	return length;
}
EXPORT_SYMBOL(ecm_db_host_hash_table_lengths_get);

/*
 * ecm_db_host_hash_index_get_next()
 * Given a hash index, return the next one OR return -1 for no more hash indicies to return.
 */
int ecm_db_host_hash_index_get_next(int index)
{
	index++;
	if (index >= ECM_DB_HOST_HASH_SLOTS) {
		return -1;
	}
	return index;
}
EXPORT_SYMBOL(ecm_db_host_hash_index_get_next);

/*
 * ecm_db_host_hash_index_get_first()
 * Return first hash index
 */
int ecm_db_host_hash_index_get_first(void)
{
	return 0;
}
EXPORT_SYMBOL(ecm_db_host_hash_index_get_first);

/*
 * ecm_db_host_alloc()
 *	Allocate a host instance
 */
struct ecm_db_host_instance *ecm_db_host_alloc(void)
{
	struct ecm_db_host_instance *hi;
	hi = (struct ecm_db_host_instance *)kzalloc(sizeof(struct ecm_db_host_instance), GFP_ATOMIC | __GFP_NOWARN);
	if (!hi) {
		DEBUG_WARN("Alloc failed\n");
		return NULL;
	}

	hi->refs = 1;
	DEBUG_SET_MAGIC(hi, ECM_DB_HOST_INSTANCE_MAGIC);

	/*
	 * Alloc operation must be atomic to ensure thread and module can be held
	 */
	spin_lock_bh(&ecm_db_lock);

	/*
	 * If the event processing thread is terminating then we cannot create new instances
	 */
	if (ecm_db_terminate_pending) {
		spin_unlock_bh(&ecm_db_lock);
		DEBUG_WARN("Thread terminating\n");
		kfree(hi);
		return NULL;
	}

	ecm_db_host_count++;
	spin_unlock_bh(&ecm_db_lock);

	DEBUG_TRACE("Host created %px\n", hi);
	return hi;
}
EXPORT_SYMBOL(ecm_db_host_alloc);

/*
 * ecm_db_host_init()
 */
bool ecm_db_host_init(struct dentry *dentry)
{

	if (!debugfs_create_u32("host_count", S_IRUGO, dentry,
					(u32 *)&ecm_db_host_count)) {
		DEBUG_ERROR("Failed to create ecm db host count file in debugfs\n");
		return false;;
	}

	ecm_db_host_table = vzalloc(sizeof(struct ecm_db_host_instance *) * ECM_DB_HOST_HASH_SLOTS);
	if (!ecm_db_host_table) {
		DEBUG_ERROR("Failed to allocate virtual memory for ecm_db_host_table\n");
		return false;
	}

	ecm_db_host_table_lengths = vzalloc(sizeof(int) * ECM_DB_HOST_HASH_SLOTS);
	if (!ecm_db_host_table_lengths) {
		DEBUG_ERROR("Failed to allocate virtual memory for ecm_db_host_table_lengths\n");
		vfree(ecm_db_host_table);
		return false;
	}

	return true;
}

/*
 * ecm_db_host_exit()
 */
void ecm_db_host_exit(void)
{
	vfree(ecm_db_host_table_lengths);
	vfree(ecm_db_host_table);
}
