/*
 **************************************************************************
 * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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_node_instance *ecm_db_nodes = NULL;

/*
 * Node hash table
 */
#define ECM_DB_NODE_HASH_SLOTS 32768
static struct ecm_db_node_instance **ecm_db_node_table;
							/* Slots of the node hash table */
static int *ecm_db_node_table_lengths;
							/* Tracks how long each chain is */
static int ecm_db_node_count = 0;			/* Number of nodes allocated */

/*
 * Node flags
 */
#define ECM_DB_NODE_FLAGS_INSERTED 1			/* Node is inserted into connection database tables */

/*
 * ecm_db_node_generate_hash_index()
 * 	Calculate the hash index.
 */
static inline ecm_db_node_hash_t ecm_db_node_generate_hash_index(uint8_t *address)
{
	uint32_t hash_val;

	hash_val = (uint32_t)jhash(address, 6, ecm_db_jhash_rnd);
	hash_val &= (ECM_DB_NODE_HASH_SLOTS - 1);

	return (ecm_db_node_hash_t)hash_val;
}

/*
 * _ecm_db_node_count_get()
 *	Return the node count (lockless).
 */
int _ecm_db_node_count_get(void)
{
	return ecm_db_node_count;
}

/*
 * _ecm_db_node_ref()
 */
void _ecm_db_node_ref(struct ecm_db_node_instance *ni)
{
	DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed\n", ni);
	ni->refs++;
	DEBUG_TRACE("%px: node ref %d\n", ni, ni->refs);
	DEBUG_ASSERT(ni->refs > 0, "%px: ref wrap\n", ni);
}

/*
 * ecm_db_node_ref()
 */
void ecm_db_node_ref(struct ecm_db_node_instance *ni)
{
	spin_lock_bh(&ecm_db_lock);
	_ecm_db_node_ref(ni);
	spin_unlock_bh(&ecm_db_lock);
}
EXPORT_SYMBOL(ecm_db_node_ref);

#ifdef ECM_DB_ADVANCED_STATS_ENABLE
/*
 * ecm_db_node_data_stats_get()
 *	Return data stats for the instance
 */
void ecm_db_node_data_stats_get(struct ecm_db_node_instance *ni, 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(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed", ni);
	spin_lock_bh(&ecm_db_lock);
	if (from_data_total) {
		*from_data_total = ni->from_data_total;
	}
	if (to_data_total) {
		*to_data_total = ni->to_data_total;
	}
	if (from_packet_total) {
		*from_packet_total = ni->from_packet_total;
	}
	if (to_packet_total) {
		*to_packet_total = ni->to_packet_total;
	}
	if (from_data_total_dropped) {
		*from_data_total_dropped = ni->from_data_total_dropped;
	}
	if (to_data_total_dropped) {
		*to_data_total_dropped = ni->to_data_total_dropped;
	}
	if (from_packet_total_dropped) {
		*from_packet_total_dropped = ni->from_packet_total_dropped;
	}
	if (to_packet_total_dropped) {
		*to_packet_total_dropped = ni->to_packet_total_dropped;
	}
	spin_unlock_bh(&ecm_db_lock);
}
EXPORT_SYMBOL(ecm_db_node_data_stats_get);
#endif

/*
 * ecm_db_node_adress_get()
 *	Return address
 */
void ecm_db_node_adress_get(struct ecm_db_node_instance *ni, uint8_t *address_buffer)
{
	DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed", ni);
	memcpy(address_buffer, ni->address, ETH_ALEN);
}
EXPORT_SYMBOL(ecm_db_node_adress_get);

/*
 * ecm_db_nodes_get_and_ref_first()
 *	Obtain a ref to the first node instance, if any
 */
struct ecm_db_node_instance *ecm_db_nodes_get_and_ref_first(void)
{
	struct ecm_db_node_instance *ni;
	spin_lock_bh(&ecm_db_lock);
	ni = ecm_db_nodes;
	if (ni) {
		_ecm_db_node_ref(ni);
	}
	spin_unlock_bh(&ecm_db_lock);
	return ni;
}
EXPORT_SYMBOL(ecm_db_nodes_get_and_ref_first);

/*
 * ecm_db_node_get_and_ref_next()
 *	Return the next node in the list given a node
 */
struct ecm_db_node_instance *ecm_db_node_get_and_ref_next(struct ecm_db_node_instance *ni)
{
	struct ecm_db_node_instance *nin;
	DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed", ni);
	spin_lock_bh(&ecm_db_lock);
	nin = ni->next;
	if (nin) {
		_ecm_db_node_ref(nin);
	}
	spin_unlock_bh(&ecm_db_lock);
	return nin;
}
EXPORT_SYMBOL(ecm_db_node_get_and_ref_next);

/*
 * ecm_db_node_deref()
 *	Deref a node.  Removing it on the last ref and destroying it.
 */
int ecm_db_node_deref(struct ecm_db_node_instance *ni)
{
#if (DEBUG_LEVEL >= 1)
	int dir;
#endif
	DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed\n", ni);

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

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

#ifdef ECM_DB_XREF_ENABLE
#if (DEBUG_LEVEL >= 1)
	for (dir = 0; dir < ECM_DB_OBJ_DIR_MAX; dir++) {
		DEBUG_ASSERT((ni->connections[dir] == NULL) && (ni->connections_count[dir] == 0), "%px: %s connections not null\n", ni, ecm_db_obj_dir_strings[dir]);
	}
#endif
#endif

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

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

		/*
		 * Link out of hash table
		 */
		if (!ni->hash_prev) {
			DEBUG_ASSERT(ecm_db_node_table[ni->hash_index] == ni, "%px: hash table bad\n", ni);
			ecm_db_node_table[ni->hash_index] = ni->hash_next;
		} else {
			ni->hash_prev->hash_next = ni->hash_next;
		}
		if (ni->hash_next) {
			ni->hash_next->hash_prev = ni->hash_prev;
		}
		ni->hash_next = NULL;
		ni->hash_prev = NULL;
		ecm_db_node_table_lengths[ni->hash_index]--;
		DEBUG_ASSERT(ecm_db_node_table_lengths[ni->hash_index] >= 0, "%px: invalid table len %d\n", ni, ecm_db_node_table_lengths[ni->hash_index]);

#ifdef ECM_DB_XREF_ENABLE
		/*
		 * Unlink it from the iface node list
		 */
		if (!ni->node_prev) {
			DEBUG_ASSERT(ni->iface->nodes == ni, "%px: nodes table bad\n", ni);
			ni->iface->nodes = ni->node_next;
		} else {
			ni->node_prev->node_next = ni->node_next;
		}
		if (ni->node_next) {
			ni->node_next->node_prev = ni->node_prev;
		}
		ni->node_next = NULL;
		ni->node_prev = NULL;
		ni->iface->node_count--;
#endif

		spin_unlock_bh(&ecm_db_lock);

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

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

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

	/*
	 * Now release the iface instance if the node had one
	 */
	if (ni->iface) {
		ecm_db_iface_deref(ni->iface);
	}

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

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

	return 0;
}
EXPORT_SYMBOL(ecm_db_node_deref);

/*
 * ecm_db_node_is_mac_addr_equal()
 *	Compares the node's mac address with the given mac address.
 */
bool ecm_db_node_is_mac_addr_equal(struct ecm_db_node_instance *ni, uint8_t *address)
{
	DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed", ni);

	if (ecm_mac_addr_equal(ni->address, address)) {
		return false;
	}

	return true;
}
EXPORT_SYMBOL(ecm_db_node_is_mac_addr_equal);

/*
 * ecm_db_node_find_and_ref()
 *	Lookup and return a node reference if any
 */
struct ecm_db_node_instance *ecm_db_node_find_and_ref(uint8_t *address, struct ecm_db_iface_instance *ii)
{
	ecm_db_node_hash_t hash_index;
	struct ecm_db_node_instance *ni;

	DEBUG_TRACE("Lookup node with addr %pMi and iface %px\n", address, ii);

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

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

		if (ni->iface != ii) {
			ni = ni->hash_next;
			continue;
		}

		_ecm_db_node_ref(ni);
		spin_unlock_bh(&ecm_db_lock);
		DEBUG_TRACE("node found %px\n", ni);
		return ni;
	}
	spin_unlock_bh(&ecm_db_lock);
	DEBUG_TRACE("Node not found\n");
	return NULL;
}
EXPORT_SYMBOL(ecm_db_node_find_and_ref);

/*
 * ecm_db_node_chain_get_and_ref_first()
 *	Gets and refs the first node in the chain of that mac address.
 */
struct ecm_db_node_instance *ecm_db_node_chain_get_and_ref_first(uint8_t *address)
{
	ecm_db_node_hash_t hash_index;
	struct ecm_db_node_instance *ni;

	DEBUG_TRACE("Get the first node with addr %pMi in the chain\n", address);

	/*
	 * Compute the hash chain index.
	 */
	hash_index = ecm_db_node_generate_hash_index(address);

	spin_lock_bh(&ecm_db_lock);
	ni = ecm_db_node_table[hash_index];
	if (ni) {
		_ecm_db_node_ref(ni);
	}
	spin_unlock_bh(&ecm_db_lock);

	return ni;
}
EXPORT_SYMBOL(ecm_db_node_chain_get_and_ref_first);

/*
 * ecm_db_node_chain_get_and_ref_next()
 *	Gets and refs the next node in the chain..
 */
struct ecm_db_node_instance *ecm_db_node_chain_get_and_ref_next(struct ecm_db_node_instance *ni)
{
	struct ecm_db_node_instance *nin;
	DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed", ni);

	spin_lock_bh(&ecm_db_lock);
	nin = ni->hash_next;
	if (nin) {
		_ecm_db_node_ref(nin);
	}
	spin_unlock_bh(&ecm_db_lock);
	return nin;
}
EXPORT_SYMBOL(ecm_db_node_chain_get_and_ref_next);

/*
 * ecm_db_node_iface_get_and_ref()
 */
struct ecm_db_iface_instance *ecm_db_node_iface_get_and_ref(struct ecm_db_node_instance *ni)
{
	DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed\n", ni);

	spin_lock_bh(&ecm_db_lock);
	_ecm_db_iface_ref(ni->iface);
	spin_unlock_bh(&ecm_db_lock);
	return ni->iface;
}
EXPORT_SYMBOL(ecm_db_node_iface_get_and_ref);

/*
 * ecm_db_node_add()
 *	Add a node instance into the database
 */
void ecm_db_node_add(struct ecm_db_node_instance *ni, struct ecm_db_iface_instance *ii, uint8_t *address,
					ecm_db_node_final_callback_t final, void *arg)
{
#if (DEBUG_LEVEL >= 1)
	int dir;
#endif
	ecm_db_node_hash_t hash_index;
	struct ecm_db_listener_instance *li;

	spin_lock_bh(&ecm_db_lock);
	DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed\n", ni);
	DEBUG_CHECK_MAGIC(ii, ECM_DB_IFACE_INSTANCE_MAGIC, "%px: magic failed\n", ii);
	DEBUG_ASSERT(address, "%px: address null\n", ni);
	DEBUG_ASSERT((ni->iface == NULL), "%px: iface not null\n", ni);
	DEBUG_ASSERT(!(ni->flags & ECM_DB_NODE_FLAGS_INSERTED), "%px: inserted\n", ni);
#ifdef ECM_DB_XREF_ENABLE
#if (DEBUG_LEVEL >= 1)
	for (dir = 0; dir < ECM_DB_OBJ_DIR_MAX; dir++) {
		DEBUG_ASSERT((ni->connections[dir] == NULL) && (ni->connections_count[dir] == 0), "%px: %s connections not null\n", ni, ecm_db_obj_dir_strings[dir]);
	}
#endif
#endif
	spin_unlock_bh(&ecm_db_lock);

	memcpy(ni->address, address, ETH_ALEN);
	ni->arg = arg;
	ni->final = final;

	/*
	 * Compute hash chain for insertion
	 */
	hash_index = ecm_db_node_generate_hash_index(address);
	ni->hash_index = hash_index;

	/*
	 * Node takes a ref to the iface
	 */
	ecm_db_iface_ref(ii);
	ni->iface = ii;

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

	/*
	 * Insert into the hash chain
	 */
	ni->hash_prev = NULL;
	ni->hash_next = ecm_db_node_table[hash_index];
	if (ecm_db_node_table[hash_index]) {
		ecm_db_node_table[hash_index]->hash_prev = ni;
	}
	ecm_db_node_table[hash_index] = ni;
	ecm_db_node_table_lengths[hash_index]++;
	DEBUG_ASSERT(ecm_db_node_table_lengths[hash_index] > 0, "%px: invalid table len %d\n", ni, ecm_db_node_table_lengths[hash_index]);

	/*
	 * Set time of add
	 */
	ni->time_added = ecm_db_time;

#ifdef ECM_DB_XREF_ENABLE
	/*
	 * Insert node into the iface nodes list
	 */
	ni->node_prev = NULL;
	ni->node_next = ii->nodes;
	if (ii->nodes) {
		ii->nodes->node_prev = ni;
	}
	ii->nodes = ni;
	ii->node_count++;
#endif
	spin_unlock_bh(&ecm_db_lock);

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

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

/*
 * ecm_db_node_state_get()
 *	Prepare a node message
 */
int ecm_db_node_state_get(struct ecm_state_file_instance *sfi, struct ecm_db_node_instance *ni)
{
	int result;
	char address[ECM_MAC_ADDR_STR_BUFF_SIZE];
#ifdef ECM_DB_XREF_ENABLE
	int dir;
	int connections_count[ECM_DB_OBJ_DIR_MAX];
#endif
	uint32_t time_added;
#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 node msg for %px\n", ni);

	/*
	 * Create a small xml stats block for our managed node, like:
	 * <node address="" hosts="" time_added="" from_data_total="" to_data_total="" />
	 *
	 * Extract information from the node for inclusion into the message
	 */
#ifdef ECM_DB_XREF_ENABLE
	spin_lock_bh(&ecm_db_lock);
	for (dir = 0; dir < ECM_DB_OBJ_DIR_MAX; dir++) {
		connections_count[dir] = ni->connections_count[dir];
	}
	spin_unlock_bh(&ecm_db_lock);
#endif
	time_added = ni->time_added;
	snprintf(address, sizeof(address), "%pM", ni->address);

#ifdef ECM_DB_ADVANCED_STATS_ENABLE
	ecm_db_node_data_stats_get(ni, &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, "node"))) {
		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;
	}
#ifdef ECM_DB_XREF_ENABLE
	for (dir = 0; dir < ECM_DB_OBJ_DIR_MAX; dir++) {
		/*
		 * ECM_DB_NODE_CONN_COUNT_STR_SIZE is the size of "FROM_NAT_connections_count"
		 * string which can be the max length of these strings
		 */
		char name[ECM_DB_NODE_CONN_COUNT_STR_SIZE];
		snprintf(name, ECM_DB_NODE_CONN_COUNT_STR_SIZE, "%s_connections_count", ecm_db_obj_dir_strings[dir]);
		if ((result = ecm_state_write(sfi, name, "%d", connections_count[dir]))) {
			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_node_state_get);

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

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

/*
 * ecm_db_node_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_node_hash_index_get_next(int index)
{
	index++;
	if (index >= ECM_DB_NODE_HASH_SLOTS) {
		return -1;
	}
	return index;
}
EXPORT_SYMBOL(ecm_db_node_hash_index_get_next);

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

/*
 * ecm_db_node_get_connections_count()
 *	Returns the connections count on the node in the given direction.
 */
int ecm_db_node_get_connections_count(struct ecm_db_node_instance *ni, ecm_db_obj_dir_t dir)
{
	DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed\n", ni);

	return ni->connections_count[dir];
}

/*
 * ecm_db_node_alloc()
 *	Allocate a node instance
 */
struct ecm_db_node_instance *ecm_db_node_alloc(void)
{
	struct ecm_db_node_instance *ni;

	ni = (struct ecm_db_node_instance *)kzalloc(sizeof(struct ecm_db_node_instance), GFP_ATOMIC | __GFP_NOWARN);
	if (!ni) {
		DEBUG_WARN("Alloc failed\n");
		return NULL;
	}

	ni->refs = 1;
	DEBUG_SET_MAGIC(ni, ECM_DB_NODE_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(ni);
		return NULL;
	}

	ecm_db_node_count++;
	spin_unlock_bh(&ecm_db_lock);

	DEBUG_TRACE("Node created %px\n", ni);
	return ni;
}
EXPORT_SYMBOL(ecm_db_node_alloc);

#ifdef ECM_DB_XREF_ENABLE
/*
 * ecm_db_node_connections_get_and_ref_first()
 *	Obtain a ref to the first connection instance of node on this direction, if any
 */
static inline struct ecm_db_connection_instance *
ecm_db_node_connections_get_and_ref_first(struct ecm_db_node_instance *node,
					  ecm_db_obj_dir_t dir)
{
	struct ecm_db_connection_instance *ci;
	DEBUG_CHECK_MAGIC(node, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed", node);
	spin_lock_bh(&ecm_db_lock);
	ci = node->connections[dir];
	if (ci) {
		_ecm_db_connection_ref(ci);
	}
	spin_unlock_bh(&ecm_db_lock);
	return ci;
}

/*
 * ecm_db_node_connection_get_and_ref_next()
 *	Return the next connection in the specified direction of given a connection
 */
static inline struct ecm_db_connection_instance *
ecm_db_node_connection_get_and_ref_next(struct ecm_db_connection_instance *ci,
					ecm_db_obj_dir_t dir)
{
	struct ecm_db_connection_instance *cin;
	DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%px: magic failed", ci);
	spin_lock_bh(&ecm_db_lock);
	cin = ci->node_next[dir];
	if (cin) {
		_ecm_db_connection_ref(cin);
	}
	spin_unlock_bh(&ecm_db_lock);
	return cin;
}

/*
 * ecm_db_should_keep_connection()
 *	check if any classifier believes this connection should
 *	be kept
 */
static bool ecm_db_should_keep_connection(
	struct ecm_db_connection_instance *ci, uint8_t *mac)
{
	bool should_keep_connection = false;
	int assignment_count;
	int aci_index;
	struct ecm_classifier_instance *assignments[ECM_CLASSIFIER_TYPES];

	assignment_count =
		ecm_db_connection_classifier_assignments_get_and_ref(ci, assignments);
	for (aci_index = 0; aci_index < assignment_count; ++aci_index) {
		struct ecm_classifier_instance *aci;
		aci = assignments[aci_index];
		if (aci->should_keep_connection &&
			aci->should_keep_connection(aci, mac)) {
			should_keep_connection = true;
			break;
		}
	}
	ecm_db_connection_assignments_release(assignment_count, assignments);

	return should_keep_connection;
}

/*
 * ecm_db_traverse_node_connection_list_and_defunct()
 *	traverse a node in the specified direction and calls ecm_db_connection_make_defunct()
 *	for each entry.  If ip_version is valid (non-zero), then defunct the
 *	connections matching version.
 */
void ecm_db_traverse_node_connection_list_and_defunct(
	struct ecm_db_node_instance *node, ecm_db_obj_dir_t dir, int ip_version)
{
	struct ecm_db_connection_instance *ci = NULL;

	/*
	 * Iterate all from connections
	 */
	ci = ecm_db_node_connections_get_and_ref_first(node, dir);
	while (ci) {
		struct ecm_db_connection_instance *cin;

		if (!ecm_db_should_keep_connection(ci, node->address)) {
			if (ip_version != ECM_DB_IP_VERSION_IGNORE && (ecm_db_connection_ip_version_get(ci) != ip_version)) {
				DEBUG_TRACE("%px: keeping connection, ip_version mismatch %d\n", ci, ci->serial);
				goto keep_node_conn;
			}

			DEBUG_TRACE("%px: defunct %d\n", ci, ci->serial);
			ecm_db_connection_make_defunct(ci);
		} else {
			DEBUG_TRACE("%px: keeping connection %d\n", ci, ci->serial);
		}
keep_node_conn:
		cin = ecm_db_node_connection_get_and_ref_next(ci, dir);
		ecm_db_connection_deref(ci);
		ci = cin;
	}
	DEBUG_INFO("%px: Defuncting from node connection list complete\n", node);
}

#ifdef ECM_INTERFACE_OVS_BRIDGE_ENABLE

/*
 * ecm_db_node_ovs_connections_masked_defunct()
 *	Destroy connections created on the node
 */
void ecm_db_node_ovs_connections_masked_defunct(int ip_ver, uint8_t *src_mac, bool src_mac_check, ip_addr_t src_addr_mask,
							uint16_t src_port_mask, uint8_t *dest_mac, bool dest_mac_check,
							ip_addr_t dest_addr_mask, uint16_t dest_port_mask,
							int proto_mask, ecm_db_obj_dir_t dir, bool is_routed)
{
	struct ecm_db_node_instance *ni;
	uint8_t smac[ETH_ALEN], dmac[ETH_ALEN];
	uint8_t *mac;
	ip_addr_t sip, dip;
	uint16_t sport, dport;
	int proto;
	int cnt = 0;
	char *direction = NULL;

	mac = (dir == ECM_DB_OBJ_DIR_FROM) ? src_mac : dest_mac;

	ni = ecm_db_node_chain_get_and_ref_first(mac);
	if (!ni) {
		DEBUG_WARN("Unable to find first instance node\n");
		return;
	}

	/*
	 * Iterate through all node instances
	 */
	while (ni) {
		struct ecm_db_connection_instance *ci;
		struct ecm_db_node_instance *nni;

		DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed", ni);

		if (!ecm_db_node_is_mac_addr_equal(ni, mac)) {
			nni = ecm_db_node_chain_get_and_ref_next(ni);
			ecm_db_node_deref(ni);
			ni = nni;
			continue;
		}

		ci = ecm_db_node_connections_get_and_ref_first(ni, dir);
		while (ci) {
			struct ecm_db_connection_instance *cin;

			DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%px: magic failed", ci);

			/*
			 * Skip routed CI for brided flows
			 * Skip bridged CI for routed flows
			 */
			if (is_routed != ecm_db_connection_is_routed_get(ci)) {
				goto next_ci;
			}

			/*
			 * Check IP version
			 */
			if (ip_ver != ECM_DB_IP_VERSION_IGNORE && (ecm_db_connection_ip_version_get(ci) != ip_ver)) {
				goto next_ci;
			}

			/*
			 * Check protocol if specified
			 */
			proto = ecm_db_connection_protocol_get(ci);
			if (!ECM_PROTO_MASK_MATCH(proto, proto_mask)) {
				goto next_ci;
			}

			/*
			 * A : PCI < ------- br-home ----------bridging----------------br-wan ---->PC2
			 *
			 * B : PCI < ------- br-home ----------Routing----------------br-wan ---->PC2
			 *
			 *							DNAT
			 * C : PCI < ------- br-home ----------Routing----------------br-wan ----> PC2
			 *							SNAT
			 * D : PCI < ------- br-home ----------Routing----------------br-wan ----> PC2
			 *
			 */
			ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, smac);
			ecm_db_connection_node_address_get(ci,  ECM_DB_OBJ_DIR_TO, dmac);
			ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, sip);
			ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dip);
			sport = ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM);
			dport = ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO);

			/*
			 * 1. For topology A, B, C, D  if drop rule is added in br-home or br-wan
			 * 2. For topoloy  A, B  if drop rule is added in br-wan
			 * Match in flow direction
			 */

			if ((!src_mac_check || ECM_MAC_ADDR_MATCH(smac, src_mac)) &&
			    (!dest_mac_check || ECM_MAC_ADDR_MATCH(dmac, dest_mac)) &&
			    ECM_IP_ADDR_MASK_MATCH(sip, src_addr_mask) &&
			    ECM_IP_ADDR_MASK_MATCH(dip, dest_addr_mask) &&
			    ECM_PORT_MASK_MATCH(sport, src_port_mask) &&
			    ECM_PORT_MASK_MATCH(dport, dest_port_mask)) {
				direction = "flow";
				goto defunct_conn;
			}
			/*
			 * 1. For topology A, B, C, D  if drop rule is added in br-home or br-wan
			 * 2. For topoloy  A, B  if drop rule is added in br-wan
			 * Match in reverse direction
			 */
			if ((!src_mac_check || ECM_MAC_ADDR_MATCH(dmac, src_mac)) &&
			    (!dest_mac_check || ECM_MAC_ADDR_MATCH(smac, dest_mac)) &&
			    ECM_IP_ADDR_MASK_MATCH(dip, src_addr_mask) &&
			    ECM_IP_ADDR_MASK_MATCH(sip, dest_addr_mask) &&
			    ECM_PORT_MASK_MATCH(dport, src_port_mask) &&
			    ECM_PORT_MASK_MATCH(sport, dest_port_mask)) {
				direction = "reverse";
				goto defunct_conn;
			}

			/*
			 * There is no NATing in case of bridging
			 */
			if (!is_routed) {
				goto next_ci;
			}

			ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM_NAT, smac);
			ecm_db_connection_node_address_get(ci,  ECM_DB_OBJ_DIR_TO_NAT, dmac);
			ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM_NAT, sip);
			ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO_NAT, dip);
			sport = ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM_NAT);
			dport = ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO_NAT);

			/*
			 * 1. For topoloy  C, D  if drop rule is added in br-wan
			 * Match in flow direction
			 */
			if ((!src_mac_check || ECM_MAC_ADDR_MATCH(smac, src_mac)) &&
			    (!dest_mac_check || ECM_MAC_ADDR_MATCH(dmac, dest_mac)) &&
			    ECM_IP_ADDR_MASK_MATCH(sip, src_addr_mask) &&
			    ECM_IP_ADDR_MASK_MATCH(dip, dest_addr_mask) &&
			    ECM_PORT_MASK_MATCH(sport, src_port_mask) &&
			    ECM_PORT_MASK_MATCH(dport, dest_port_mask)) {
				direction = "flow (nat)";
				goto defunct_conn;
			}

			/*
			 * 1. For topoloy  C, D  if drop rule is added in br-wan
			 * Match in reverse direction
			 */
			if ((!src_mac_check || ECM_MAC_ADDR_MATCH(dmac, src_mac)) &&
			    (!dest_mac_check || ECM_MAC_ADDR_MATCH(smac, dest_mac)) &&
			    ECM_IP_ADDR_MASK_MATCH(dip, src_addr_mask) &&
			    ECM_IP_ADDR_MASK_MATCH(sip, dest_addr_mask) &&
			    ECM_PORT_MASK_MATCH(dport, src_port_mask) &&
			    ECM_PORT_MASK_MATCH(sport, dest_port_mask)) {
				direction = "reverse (nat)";
				goto defunct_conn;
			}

			goto next_ci;

defunct_conn:
			cnt++;

			DEBUG_TRACE("%px: Defuncting 7 tuple %s connection\n", ci, is_routed ? "routed" : "bridged");
			if (ECM_IP_ADDR_IS_V4(src_addr_mask)) {
				DEBUG_TRACE("%px: Defunct CI masked 7 tuple match(%s) smac=%pM(%d) src=" ECM_IP_ADDR_DOT_FMT " sport=%d "
					    "dmac=%pM(%d) dest=" ECM_IP_ADDR_DOT_FMT ", dport=%d, proto=%d cnt=%d\n", ci, direction, smac,
					    src_mac_check, ECM_IP_ADDR_TO_DOT(sip), sport, dmac, dest_mac_check,
					    ECM_IP_ADDR_TO_DOT(dip), dport, proto, cnt);
			} else {
				DEBUG_TRACE("%px: Defunct CI masked 7 tuple match(%s) src=%pM(%d)" ECM_IP_ADDR_OCTAL_FMT " sport=%d "
					    "dmac=%pM(%d) dest=" ECM_IP_ADDR_OCTAL_FMT ", dport=%d, proto=%d, cnt=%d\n", ci, direction,
					    smac, src_mac_check, ECM_IP_ADDR_TO_OCTAL(sip), sport, dmac, dest_mac_check,
					    ECM_IP_ADDR_TO_OCTAL(dip), dport, proto, cnt);
			}

			ecm_db_connection_make_defunct(ci);
next_ci:
			cin = ecm_db_node_connection_get_and_ref_next(ci, dir);

			ecm_db_connection_deref(ci);
			ci = cin;
		}

		ecm_db_node_deref(ni);
		break;
	}

	DEBUG_TRACE("Completed OVS 7 tuple %s connections (cnt=%d) masked defunct\n",  is_routed ? "routed" : "bridged", cnt);

	if (ECM_IP_ADDR_IS_V4(src_addr_mask)) {
		DEBUG_TRACE("Defunct request by masked 7 tuple smac_mask=%pM(%d) src_mask=" ECM_IP_ADDR_DOT_FMT " sport_mask=%d, "
			    "dmac_mask=%pM(%d) dest_mask=" ECM_IP_ADDR_DOT_FMT " dport_mask=%d, proto_mask=%d\n",  src_mac,
			    src_mac_check, ECM_IP_ADDR_TO_DOT(src_addr_mask), src_port_mask, dest_mac, dest_mac_check,
			    ECM_IP_ADDR_TO_DOT(dest_addr_mask), dest_port_mask, proto_mask);
	} else {
		DEBUG_TRACE("Defunct request by masked 7 tuple smac_mask=%pM(%d) src_mask=" ECM_IP_ADDR_OCTAL_FMT " sport_mask=%d "
			    "dmac_mask=%pM(%d) dest_mask=" ECM_IP_ADDR_OCTAL_FMT " dport_mask=%d, proto_mask=%d cnt=%d\n",
			    src_mac, src_mac_check, ECM_IP_ADDR_TO_OCTAL(src_addr_mask), src_port_mask, dest_mac, dest_mac_check,
			    ECM_IP_ADDR_TO_OCTAL(dest_addr_mask), dest_port_mask, proto_mask, cnt);
	}

}

/*
 * ecm_db_node_ovs_routed_connections_defunct()
 *	Destroy the routed connections created on the node in the given
 *	direction which is related to the ovs_br interface.
 */
void ecm_db_node_ovs_routed_connections_defunct(uint8_t *node_mac, struct net_device *ovs_br, int ip_version, ecm_db_obj_dir_t dir)
{
	struct ecm_db_iface_instance *ii;
	struct ecm_db_node_instance *ni;
	struct ecm_db_connection_instance *ci;

	ii =  ecm_db_iface_find_and_ref_by_interface_identifier(ovs_br->ifindex);
	if (!ii) {
		DEBUG_WARN("%px: Unable to find OVS bridge iface instance\n", ovs_br);
		return;
	}

	/*
	 * Find the node instance which has the node_mac and related to the ovs_br.
	 * Nodes are stored in the database with their related interface instances.
	 */
	ni = ecm_db_node_find_and_ref(node_mac, ii);
	if(!ni) {
		DEBUG_WARN("%px: Unable to find node instance related to %pM and %s\n", ovs_br, node_mac, ovs_br->name);
		ecm_db_iface_deref(ii);
		return;
	}

	/*
	 * Iterate all routed connections on this node in the dir direction.
	 */
	ci = ecm_db_node_connections_get_and_ref_first(ni, dir);
	while (ci) {
		struct ecm_db_connection_instance *cin;

		if (ecm_db_connection_is_routed_get(ci) && (ecm_db_connection_ip_version_get(ci) == ip_version)) {
			DEBUG_TRACE("%px: Defuncting connection %p\n", ovs_br, ci);
			ecm_db_connection_make_defunct(ci);
		}

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

	ecm_db_node_deref(ni);
	ecm_db_iface_deref(ii);

	DEBUG_TRACE("%px: Completed OVS routed connection defunct\n", ovs_br);
}

/*
 * ecm_db_traverse_snode_dnode_connection_list_and_defunct()
 *	Defunct connections between node1 (sni) and node2 (which has dmac address)
 */
void ecm_db_traverse_snode_dnode_connection_list_and_defunct(
	struct ecm_db_node_instance *sni, uint8_t *dmac, int ip_version, ecm_db_obj_dir_t dir)
{
	struct ecm_db_connection_instance *ci = NULL;

	if (dir != ECM_DB_OBJ_DIR_FROM && dir != ECM_DB_OBJ_DIR_TO) {
		DEBUG_WARN("Direction is incorrect: %d\n", dir);
		return;
	}

	/*
	 * Iterate all connection instances which are sent or received from
	 * given node instannce (sni).
	 */
	ci = ecm_db_node_connections_get_and_ref_first(sni, dir);
	while (ci) {
		struct ecm_db_connection_instance *cin;
		struct ecm_db_node_instance *dni;

		/*
		 * Find the connection instance which match given MAC address (dmac)
		 */
		if (dir == ECM_DB_OBJ_DIR_FROM) {
			/*
			 * Direction is FROM, then sni is source node.
			 * find the node in TO direction.
			 */
			dni = ci->node[ECM_DB_OBJ_DIR_TO];
		} else {
			/*
			 * Direction is TO, then sni is destination node.
			 * find the node in FROM direction.
			 */
			dni = ci->node[ECM_DB_OBJ_DIR_FROM];
		}

		/*
		 * if the MAC address of node (dni) match MAC address (dmac)
		 * then delete the connection instance.
		 */
		if (ecm_db_node_is_mac_addr_equal(dni, dmac)) {
			if (ip_version != ECM_DB_IP_VERSION_IGNORE && (ecm_db_connection_ip_version_get(ci) != ip_version)) {
				DEBUG_TRACE("%px: keeping connection, ip_version mismatch %d\n", ci, ci->serial);
				goto keep_sni_conn;
			}

			DEBUG_TRACE("%px: defunct %d\n", ci, ci->serial);
			ecm_db_connection_make_defunct(ci);
		}
keep_sni_conn:
		cin = ecm_db_node_connection_get_and_ref_next(ci, dir);
		ecm_db_connection_deref(ci);
		ci = cin;
	}
	DEBUG_INFO("%px: Defuncting from node connection list complete\n", sni);
}
#endif
#endif

/*
 * ecm_db_node_init()
 */
bool ecm_db_node_init(struct dentry *dentry)
{
	if (!debugfs_create_u32("node_count", S_IRUGO, dentry,
					(u32 *)&ecm_db_node_count)) {
		DEBUG_ERROR("Failed to create ecm db node count file in debugfs\n");
		return false;
	}

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

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

	return true;
}

/*
 * ecm_db_node_exit()
 */
void ecm_db_node_exit(void)
{
	vfree(ecm_db_node_table_lengths);
	vfree(ecm_db_node_table);
}
