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

#include <linux/version.h>
#include <linux/types.h>
#include <linux/debugfs.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/etherdevice.h>
#include <linux/inet.h>

#include "exports/ecm_sfe_common_public.h"

/*
 * Global WAN interface name parameter.
 */
char wan_name[IFNAMSIZ];
int wan_name_len;

/*
 * DebugFS entry object.
 */
static struct dentry *ecm_sfe_l2_dentry;

/*
 * Policy rule directions.
 */
enum ecm_sfe_l2_policy_rule_dir {
	ECM_SFE_L2_POLICY_RULE_EGRESS = 1,
	ECM_SFE_L2_POLICY_RULE_INGRESS,
	ECM_SFE_L2_POLICY_RULE_EGRESS_INGRESS,
};

/*
 * Policy rule commands.
 */
enum ecm_sfe_l2_policy_rule_cmd {
	ECM_SFE_L2_POLICY_RULE_ADD = 1,
	ECM_SFE_L2_POLICY_RULE_DEL,
	ECM_SFE_L2_POLICY_RULE_FLUSH_ALL
};

/*
 *  ECM tuple directions.
 */
enum ecm_sfe_l2_tuple_dir {
	ECM_SFE_L2_TUPLE_DIR_ORIGINAL,
	ECM_SFE_L2_TUPLE_DIR_REPLY,
};

/*
 * Defunct by 5-tuple command option types.
 */
enum ecm_sfe_l2_defunct_by_5tuple_options {
	ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_IP_VERSION,
	ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_SIP,
	ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_SPORT,
	ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_DIP,
	ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_DPORT,
	ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_PROTOCOL,
	ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_MAX,
};

/*
 * Policy rule structure
 */
struct ecm_sfe_l2_policy_rule {
	struct list_head list;
	int protocol;
	int src_port;
	int dest_port;
	uint32_t src_addr[4];
	uint32_t dest_addr[4];
	int ip_ver;
	enum ecm_sfe_l2_policy_rule_dir direction;
};

LIST_HEAD(ecm_sfe_l2_policy_rules);
DEFINE_SPINLOCK(ecm_sfe_l2_policy_rules_lock);

/*
 * ecm_sfe_l2_policy_rule_find()
 *	Finds a policy rule with the given parameters.
 */
static struct ecm_sfe_l2_policy_rule *ecm_sfe_l2_policy_rule_find(int ip_ver, uint32_t *sip_addr, int sport,
								  uint32_t *dip_addr, int dport,
								  int protocol)
{
	struct ecm_sfe_l2_policy_rule *rule = NULL;

	list_for_each_entry(rule , &ecm_sfe_l2_policy_rules, list) {
		if (rule->ip_ver != ip_ver)
			continue;

		if (rule->protocol && (rule->protocol != protocol))
			continue;

		if (rule->dest_port && (rule->dest_port != dport))
			continue;

		if (rule->src_port && (rule->src_port != sport))
			continue;

		if (ip_ver == 4) {
			if (rule->dest_addr[0] && (rule->dest_addr[0] != dip_addr[0]))
				continue;
		} else {
			if (rule->dest_addr[0] && memcmp(rule->dest_addr, dip_addr, sizeof(uint32_t) * 4))
				continue;
		}

		if (ip_ver == 4) {
			if (rule->src_addr[0] && (rule->src_addr[0] != sip_addr[0]))
				continue;
		} else {
			if (rule->src_addr[0] && memcmp(rule->src_addr, sip_addr, sizeof(uint32_t) * 4))
				continue;
		}

		return rule;
	}
	return NULL;
}

/*
 * ecm_sfe_l2_connection_check_with_policy_rules()
 *	Checks the ECM tuple with the policy rules in our rules list and
 *	set the L2 acceleration accordingly, if there is a match.
 */
static uint32_t ecm_sfe_l2_connection_check_with_policy_rules(struct ecm_sfe_common_tuple *tuple, enum ecm_sfe_l2_tuple_dir tuple_dir)
{
	struct ecm_sfe_l2_policy_rule *rule = NULL;
	enum ecm_sfe_l2_policy_rule_dir direction;
	uint32_t l2_accel_bits = (ECM_SFE_COMMON_FLOW_L2_ACCEL_ALLOWED | ECM_SFE_COMMON_RETURN_L2_ACCEL_ALLOWED);

	if (tuple_dir == ECM_SFE_L2_TUPLE_DIR_ORIGINAL) {
		spin_lock_bh(&ecm_sfe_l2_policy_rules_lock);
		rule = ecm_sfe_l2_policy_rule_find(tuple->ip_ver, tuple->src_addr, tuple->src_port,
						   tuple->dest_addr, tuple->dest_port, tuple->protocol);
		if (!rule) {
			spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
			pr_warn("No rule with this tuple\n");
			goto done;
		}
		direction = rule->direction;
		spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);

		if (direction == ECM_SFE_L2_POLICY_RULE_EGRESS) {
			pr_debug("flow side should be L3 interface\n");
			l2_accel_bits &= ~ECM_SFE_COMMON_FLOW_L2_ACCEL_ALLOWED;
		} else if (direction == ECM_SFE_L2_POLICY_RULE_INGRESS) {
			pr_debug("return side should be L3 interface\n");
			l2_accel_bits &= ~ECM_SFE_COMMON_RETURN_L2_ACCEL_ALLOWED;
		}
	} else if (tuple_dir == ECM_SFE_L2_TUPLE_DIR_REPLY) {
		spin_lock_bh(&ecm_sfe_l2_policy_rules_lock);
		rule = ecm_sfe_l2_policy_rule_find(tuple->ip_ver, tuple->dest_addr, tuple->dest_port,
						   tuple->src_addr, tuple->src_port, tuple->protocol);

		if (!rule) {
			spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
			pr_warn("No rule with this tuple\n");
			goto done;
		}
		direction = rule->direction;
		spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);

		if (direction == ECM_SFE_L2_POLICY_RULE_EGRESS) {
			pr_debug("return side should be L3 interface\n");
			l2_accel_bits &= ~ECM_SFE_COMMON_RETURN_L2_ACCEL_ALLOWED;
		} else if (direction == ECM_SFE_L2_POLICY_RULE_INGRESS) {
			pr_debug("flow side should be L3 interface\n");
			l2_accel_bits &= ~ECM_SFE_COMMON_FLOW_L2_ACCEL_ALLOWED;
		}
	} else {
		pr_err("unknow tuple_dir: %d\n", tuple_dir);
		goto done;
	}

	if (direction == ECM_SFE_L2_POLICY_RULE_EGRESS_INGRESS) {
		pr_debug("both sides should be L3 interface\n");
		l2_accel_bits &= ~ECM_SFE_COMMON_FLOW_L2_ACCEL_ALLOWED;
		l2_accel_bits &= ~ECM_SFE_COMMON_RETURN_L2_ACCEL_ALLOWED;
	}
done:
	return l2_accel_bits;
}

/*
 * ecm_sfe_l2_accel_check_callback()
 *	L2 acceleration check function callback.
 */
uint32_t ecm_sfe_l2_accel_check_callback(struct ecm_sfe_common_tuple *tuple)
{
	struct net_device *flow_dev;
	struct net_device *return_dev;
	struct net_device *wan_dev;
	uint32_t l2_accel_bits = (ECM_SFE_COMMON_FLOW_L2_ACCEL_ALLOWED | ECM_SFE_COMMON_RETURN_L2_ACCEL_ALLOWED);

	if (strlen(wan_name) == 0) {
		pr_debug("WAN interface is not set in the debugfs\n");
		goto done;
	}

	wan_dev =  dev_get_by_name(&init_net, wan_name);
	if (!wan_dev) {
		pr_debug("WAN interface: %s couldn't be found\n", wan_name);
		goto done;
	}

	flow_dev = dev_get_by_index(&init_net, tuple->src_ifindex);
	if (!flow_dev) {
		pr_debug("flow netdevice couldn't be found with index: %d\n", tuple->src_ifindex);
		dev_put(wan_dev);
		goto done;
	}

	return_dev = dev_get_by_index(&init_net, tuple->dest_ifindex);
	if (!return_dev) {
		pr_debug("return netdevice couldn't be found with index: %d\n", tuple->dest_ifindex);
		dev_put(wan_dev);
		dev_put(flow_dev);
		goto done;
	}

	if (wan_dev == return_dev) {
		/*
		 * Check the tuple with the policy rules in the ORIGINAL direction of the tuple.
		 */
		l2_accel_bits = ecm_sfe_l2_connection_check_with_policy_rules(tuple, ECM_SFE_L2_TUPLE_DIR_ORIGINAL);
	} else if (wan_dev == flow_dev) {
		/*
		 * Check the tuple with the policy rules in the REPLY direction of the tuple.
		 */
		l2_accel_bits = ecm_sfe_l2_connection_check_with_policy_rules(tuple, ECM_SFE_L2_TUPLE_DIR_REPLY);
	}
	dev_put(wan_dev);
	dev_put(flow_dev);
	dev_put(return_dev);

done:
	return l2_accel_bits;
}

/*
 * ecm_sfe_l2_flush_policy_rules()
 *	Flushes all the policy rules.
 */
static void ecm_sfe_l2_flush_policy_rules(void)
{
	struct ecm_sfe_l2_policy_rule *rule;
	struct ecm_sfe_l2_policy_rule *tmp;

	spin_lock_bh(&ecm_sfe_l2_policy_rules_lock);
	list_for_each_entry_safe(rule , tmp, &ecm_sfe_l2_policy_rules, list) {
		list_del(&rule->list);
		spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
		kfree(rule);
		spin_lock_bh(&ecm_sfe_l2_policy_rules_lock);
	}
	spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
}

/*
 * ecm_sfe_l2_delete_policy_rule()
 *	Deletes a policy rule with the given parameters.
 */
static bool ecm_sfe_l2_delete_policy_rule(int ip_ver, uint32_t *sip_addr, int sport, uint32_t *dip_addr, int dport, int protocol)
{
	struct ecm_sfe_l2_policy_rule *rule;

	spin_lock_bh(&ecm_sfe_l2_policy_rules_lock);
	rule = ecm_sfe_l2_policy_rule_find(ip_ver, sip_addr, sport, dip_addr, dport, protocol);
	if (!rule) {
		spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
		pr_warn("rule cannot be found in the list\n");
		return false;
	}
	list_del(&rule->list);
	spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
	kfree(rule);

	pr_info("rule deleted\n");
	return true;
}

/*
 * ecm_sfe_l2_add_policy_rule()
 *	Adds a policy rule with the given parameters.
 */
static bool ecm_sfe_l2_add_policy_rule(int ip_ver, uint32_t *sip_addr, int sport, uint32_t *dip_addr, int dport, int protocol, enum ecm_sfe_l2_policy_rule_dir direction)
{
	struct ecm_sfe_l2_policy_rule *rule;

	spin_lock_bh(&ecm_sfe_l2_policy_rules_lock);
	rule = ecm_sfe_l2_policy_rule_find(ip_ver, sip_addr, sport, dip_addr, dport, protocol);
	if (rule) {
		if (rule->direction != direction) {
			pr_info("Update direction of the rule from %d to %d\n", rule->direction, direction);
			rule->direction = direction;
		}
		spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
		pr_warn("rule is already present\n");
		return true;
	}
	spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);

	rule = kzalloc(sizeof(struct ecm_sfe_l2_policy_rule), GFP_ATOMIC);
	if (!rule) {
		pr_warn("alloc failed for new rule\n");
		return false;
	}

	rule->ip_ver = ip_ver;
	rule->protocol = protocol;
	rule->src_port = sport;
	rule->dest_port = dport;
	memcpy(rule->src_addr, sip_addr, sizeof(uint32_t) * 4);
	memcpy(rule->dest_addr, dip_addr, sizeof(uint32_t) * 4);
	rule->direction = direction;

	INIT_LIST_HEAD(&rule->list);

	spin_lock_bh(&ecm_sfe_l2_policy_rules_lock);
	list_add(&rule->list, &ecm_sfe_l2_policy_rules);
	spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);

	pr_info("rule added\n");
	return true;
}

/*
 * ecm_sfe_l2_policy_rule_write()
 *	Adds a policy rule to the rule table.
 *
 * Policy rule must include cmd, ip_ver and direction. It can also include src/dest IP and ports, protocol.
 * cmd and ip_ver MUST be the first 2 options in the command.
 */
static ssize_t ecm_sfe_l2_policy_rule_write(struct file *file,
		const char __user *user_buf, size_t count, loff_t *offset)
{
	char *cmd_buf;
	char *fields;
	char *token;
	char *option, *value;
	int cmd = 0;		/* must be present in the rule */
	int ip_ver = 0;	/* must be present in the rule */
	uint32_t sip_addr[4] = {0};
	uint32_t dip_addr[4] = {0};
	int sport = 0;
	int dport = 0;
	int protocol = 0;
	int direction = 0;	/* must be present in the rule */

	/*
	 * Command is formed as:
	 * echo "cmd=1 ip_ver=4 dport=443 protocol=6 direction=1" > /sys/kernel/debug/ecm_sfe_l2/policy_rules
	 *
	 * cmd: 1 is to add, 2 is to delete a rule.
	 * direction: 1 is egress, 2 is ingress, 3 is both
	 */
	cmd_buf = kzalloc(count + 1, GFP_ATOMIC);
	if (!cmd_buf) {
		pr_warn("unable to allocate memory for cmd buffer\n");
		return -ENOMEM;
	}

	count = simple_write_to_buffer(cmd_buf, count, offset, user_buf, count);

	/*
	 * Split the buffer into tokens
	 */
	fields = cmd_buf;
	while ((token = strsep(&fields, " "))) {
		pr_info("\ntoken: %s\n", token);

		option = strsep(&token, "=");
		value = token;

		pr_info("\t\toption: %s\n", option);
		pr_info("\t\tvalue: %s\n", value);

		if (!strcmp(option, "cmd")) {
			if (sscanf(value, "%d", &cmd)) {
				if (cmd != ECM_SFE_L2_POLICY_RULE_ADD && cmd != ECM_SFE_L2_POLICY_RULE_DEL &&
					cmd != ECM_SFE_L2_POLICY_RULE_FLUSH_ALL) {
					pr_err("invalid cmd value: %d\n", cmd);
					goto fail;
				}
				continue;
			}
			pr_warn("cannot read value\n");
			goto fail;
		}

		if (!strcmp(option, "ip_ver")) {
			if (sscanf(value, "%d", &ip_ver)) {
				if (ip_ver != 4 && ip_ver != 6) {
					pr_err("invalid ip_ver: %d\n", ip_ver);
					goto fail;
				}
				continue;
			}
			pr_warn("cannot read value\n");
			goto fail;
		}

		if (!strcmp(option, "protocol")) {
			if (sscanf(value, "%d", &protocol)) {
				continue;
			}
			pr_warn("cannot read value\n");
			goto fail;
		}

		if (!strcmp(option, "sport")) {
			if (sscanf(value, "%d", &sport)) {
				continue;
			}
			pr_warn("cannot read value\n");
			goto fail;
		}

		if (!strcmp(option, "dport")) {
			if (sscanf(value, "%d", &dport)) {
				continue;
			}
			pr_warn("cannot read value\n");
			goto fail;
		}

		if (!strcmp(option, "direction")) {
			if (cmd == ECM_SFE_L2_POLICY_RULE_DEL) {
				pr_err("direction is not allowed in delete command\n");
				goto fail;
			}

			if (sscanf(value, "%d", &direction)) {
				if (direction != ECM_SFE_L2_POLICY_RULE_EGRESS
					&& direction != ECM_SFE_L2_POLICY_RULE_INGRESS
					&& direction != ECM_SFE_L2_POLICY_RULE_EGRESS_INGRESS) {

					pr_err("invalid direction: %d\n", direction);
					goto fail;
				}
				continue;
			}
			pr_warn("cannot read value\n");
			goto fail;
		}

		if (!strcmp(option, "sip")) {
			if (ip_ver == 4) {
				if (!in4_pton(value, -1, (uint8_t *)&sip_addr[0], -1, NULL)) {
					pr_err("invalid source IP V4 value: %s\n", value);
					goto fail;
				}
			} else if (ip_ver ==6) {
				if (!in6_pton(value, -1, (uint8_t *)sip_addr, -1, NULL)) {
					pr_err("invalid source IP V6 value: %s\n", value);
					goto fail;
				}
			} else {
				pr_err("ip_ver hasn't been set yet\n");
				goto fail;
			}
			continue;
		}

		if (!strcmp(option, "dip")) {
			if (ip_ver == 4) {
				if (!in4_pton(value, -1, (uint8_t *)&dip_addr[0], -1, NULL)) {
					pr_err("invalid destination IP V4 value: %s\n", value);
					goto fail;
				}
			} else if (ip_ver == 6) {
				if (!in6_pton(value, -1, (uint8_t *)dip_addr, -1, NULL)) {
					pr_err("invalid destination IP V6 value: %s\n", value);
					goto fail;
				}
			} else {
				pr_err("ip_ver hasn't been set yet\n");
				goto fail;
			}
			continue;
		}

		pr_warn("unrecognized option: %s\n", option);
		goto fail;
	}

	kfree(cmd_buf);

	if (cmd == ECM_SFE_L2_POLICY_RULE_ADD) {
		if (!ecm_sfe_l2_add_policy_rule(ip_ver, sip_addr, sport, dip_addr, dport, protocol, direction)) {
			pr_err("Add policy rule failed\n");
			return -ENOMEM;
		}
	} else if (cmd == ECM_SFE_L2_POLICY_RULE_DEL) {
		if (!ecm_sfe_l2_delete_policy_rule(ip_ver, sip_addr, sport, dip_addr, dport, protocol)) {
			pr_err("Delete policy rule failed\n");
			return -ENOMEM;
		}
	} else if (cmd == ECM_SFE_L2_POLICY_RULE_FLUSH_ALL) {
		ecm_sfe_l2_flush_policy_rules();
	}

	return count;
fail:
	kfree(cmd_buf);
	return -EINVAL;
}

/*
 * ecm_sfe_l2_policy_rule_seq_show()
 */
static int ecm_sfe_l2_policy_rule_seq_show(struct seq_file *m, void *v)
{
	struct ecm_sfe_l2_policy_rule *rule;

	rule = list_entry(v, struct ecm_sfe_l2_policy_rule, list);

	if (rule->ip_ver == 4) {
		seq_printf(m,	"ip_ver: %d"
				"\tprotocol: %d"
				"\tsip_addr: %pI4"
				"\tdip_addr: %pI4"
				"\tsport: %d"
				"\tdport: %d"
				"\tdirection: %d\n",
				rule->ip_ver,
				rule->protocol,
				&rule->src_addr[0],
				&rule->dest_addr[0],
				rule->src_port,
				rule->dest_port,
				rule->direction);
	} else {
		struct in6_addr saddr;
		struct in6_addr daddr;

		memcpy(&saddr.s6_addr32, rule->src_addr, sizeof(uint32_t) * 4);
		memcpy(&daddr.s6_addr32, rule->dest_addr, sizeof(uint32_t) * 4);

		seq_printf(m,	"ip_ver: %d"
				"\tprotocol: %d"
				"\tsip_addr: %pI6"
				"\tdip_addr: %pI6"
				"\tsport: %d"
				"\tdport: %d"
				"\tdirection: %d\n",
				rule->ip_ver,
				rule->protocol,
				&saddr,
				&daddr,
				rule->src_port,
				rule->dest_port,
				rule->direction);
	}

	return 0;
}

/*
 * ecm_sfe_l2_policy_rule_seq_stop()
 */
static void ecm_sfe_l2_policy_rule_seq_stop(struct seq_file *p, void *v)
{
	spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
}

/*
 * ecm_sfe_l2_policy_rule_seq_next()
 */
static void *ecm_sfe_l2_policy_rule_seq_next(struct seq_file *p, void *v,
					loff_t *pos)
{
	return seq_list_next(v, &ecm_sfe_l2_policy_rules, pos);
}

/*
 * ecm_sfe_l2_policy_rule_seq_start()
 */
static void *ecm_sfe_l2_policy_rule_seq_start(struct seq_file *m, loff_t *_pos)
{
	spin_lock_bh(&ecm_sfe_l2_policy_rules_lock);
	return seq_list_start(&ecm_sfe_l2_policy_rules, *_pos);
}

static const struct seq_operations ecm_sfe_l2_policy_rule_seq_ops = {
	.start = ecm_sfe_l2_policy_rule_seq_start,
	.next  = ecm_sfe_l2_policy_rule_seq_next,
	.stop  = ecm_sfe_l2_policy_rule_seq_stop,
	.show  = ecm_sfe_l2_policy_rule_seq_show,
};

/*
 * ecm_sfe_l2_policy_rule_open()
 */
static int ecm_sfe_l2_policy_rule_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &ecm_sfe_l2_policy_rule_seq_ops);
}

/*
 * File operations for policy rules add/delete/list operations.
 */
static const struct file_operations ecm_sfe_l2_policy_rule_fops = {
	.owner		= THIS_MODULE,
	.open		= ecm_sfe_l2_policy_rule_open,
	.write		= ecm_sfe_l2_policy_rule_write,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

/*
 * ecm_sfe_l2_defunct_by_5tuple_write()
 *	Writes the defunct by 5-tuple command to the debugfs node.
 */
static ssize_t ecm_sfe_l2_defunct_by_5tuple_write(struct file *f, const char *user_buf,
					  size_t count, loff_t *offset)
{
	int ret = -EINVAL;
	char *cmd_buf;
	int field_count;
	char *fields_ptr;
	char *fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_MAX];
	char *option, *value;
	int ip_ver;
	uint32_t sip_addr_v4;
	uint32_t dip_addr_v4;
	struct in6_addr sip_addr_v6;
	struct in6_addr dip_addr_v6;
	int sport, dport;
	int protocol;
	bool defunct_result;

	/*
	 * Command is formed as for IPv4 and IPv6 5-tuples as below respectively.
	 *
	 * echo "ip_ver=4 sip=192.168.1.100 sport=443 dip=192.168.2.100 dport=1000 protocol=6" > /sys/kernel/debug/ecm_sfe_l2/defunct_by_5tuple
	 * echo “ip_ver=6 sip=2aaa::100 sport=443 dip=3bbb::200 dport=1000 protocol=6” > /sys/kernel/debug/ecm_sfe_l2/defunct_by_5tuple
	 *
	 * The order of the options MUST be as above and it MUST contain all the 5-tuple fields and the ip_ver.
	 */
	cmd_buf = kzalloc(count + 1, GFP_ATOMIC);
	if (!cmd_buf) {
		pr_warn("unable to allocate memory for cmd buffer\n");
		return -ENOMEM;
	}

	count = simple_write_to_buffer(cmd_buf, count, offset, user_buf, count);

	/*
	 * Split the buffer into its fields
	 */
	field_count = 0;
	fields_ptr = cmd_buf;
	fields[field_count] = strsep(&fields_ptr, " ");
	while (fields[field_count] != NULL) {
		pr_info("Field %d: %s\n", field_count, fields[field_count]);
		field_count++;
		if (field_count == ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_MAX)
			break;

		fields[field_count] = strsep(&fields_ptr, " ");
	}

	if (field_count != ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_MAX) {
		kfree(cmd_buf);
		pr_err("Invalid field count %d\n", field_count);
		return -EINVAL;
	}

	/*
	 * IP version (ip_ver) field validation.
	 */
	option = strsep(&fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_IP_VERSION], "=");
	if (!option || strcmp(option, "ip_ver")) {
		pr_err("invalid IP version option name: %s\n", option);
		goto fail;
	}
	value = fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_IP_VERSION];
	if (!sscanf(value, "%d", &ip_ver)) {
		pr_err("Unable to read IP version value %s\n", value);
		goto fail;
	}
	if (ip_ver != 4 && ip_ver != 6) {
		pr_err("invalid IP version: %d\n", ip_ver);
		goto fail;
	}

	/*
	 * Source IP (sip) field validation.
	 */
	option = strsep(&fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_SIP], "=");
	if (!option || strcmp(option, "sip")) {
		pr_err("invalid source IP option name: %s\n", option);
		goto fail;
	}
	value = fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_SIP];

	if (ip_ver == 4) {
		if (!in4_pton(value, -1, (uint8_t *)&sip_addr_v4, -1, NULL)) {
			pr_err("invalid source IP V4 value: %s\n", value);
			goto fail;
		}
	} else {
		if (!in6_pton(value, -1, (uint8_t *)sip_addr_v6.s6_addr, -1, NULL)) {
			pr_err("invalid source IP V6 value: %s\n", value);
			goto fail;
		}
	}

	/*
	 * Source port (sport) field validadtion.
	 */
	option = strsep(&fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_SPORT], "=");
	if (!option || strcmp(option, "sport")) {
		pr_err("invalid source port option name: %s\n", option);
		goto fail;
	}
	value = fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_SPORT];
	if (!sscanf(value, "%d", &sport)) {
		pr_err("Unable to read source port value %s\n", value);
		goto fail;
	}

	/*
	 * Destination IP (dip) field validation.
	 */
	option = strsep(&fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_DIP], "=");
	if (!option || strcmp(option, "dip")) {
		pr_err("invalid destination IP option name: %s\n", option);
		goto fail;
	}
	value = fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_DIP];

	if (ip_ver == 4) {
		if (!in4_pton(value, -1, (uint8_t *)&dip_addr_v4, -1, NULL)) {
			pr_err("invalid destination IP V4 value: %s\n", value);
			goto fail;
		}
	} else {
		if (!in6_pton(value, -1, (uint8_t *)dip_addr_v6.s6_addr, -1, NULL)) {
			pr_err("invalid destination IP V6 value: %s\n", value);
			goto fail;
		}
	}

	/*
	 * Destination port (dport) field validadtion.
	 */
	option = strsep(&fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_DPORT], "=");
	if (!option || strcmp(option, "dport")) {
		pr_err("invalid destination port option name: %s\n", option);
		goto fail;
	}
	value = fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_DPORT];
	if (!sscanf(value, "%d", &dport)) {
		pr_err("Unable to read destination port value %s\n", value);
		goto fail;
	}

	/*
	 * Protocol field validadtion.
	 */
	option = strsep(&fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_PROTOCOL], "=");
	if (!option || strcmp(option, "protocol")) {
		pr_err("invalid protocol option name: %s\n", option);
		goto fail;
	}
	value = fields[ECM_SFE_L2_DEFUNCT_BY_5TUPLE_OPTION_PROTOCOL];
	if (!sscanf(value, "%d", &protocol)) {
		pr_err("Unable to read protocol value %s\n", value);
		goto fail;
	}

	/*
	 * Call 5-tuple defunct functions.
	 */
	if (ip_ver == 4) {
		pr_debug("sip: %pI4 sport: %d dip: %pI4 dport: %d protocol: %d\n", &sip_addr_v4, sport, &dip_addr_v4, dport, protocol);
		defunct_result = ecm_sfe_common_defunct_ipv4_connection(sip_addr_v4, htons(sport), dip_addr_v4, htons(dport), protocol);
	} else {
		pr_debug("sip: %pI6 sport: %d dip: %pI6 dport: %d protocol: %d\n", &sip_addr_v6, sport, &dip_addr_v6, dport, protocol);
		defunct_result = ecm_sfe_common_defunct_ipv6_connection(&sip_addr_v6, htons(sport), &dip_addr_v6, htons(dport), protocol);
	}

	if (!defunct_result) {
		pr_warn("No connection found with this 5-tuple\n");
	}

	ret = count;
fail:
	kfree(cmd_buf);

	return ret;
}

/*
 * File operations for defunct by 5-tuple operations.
 */
static struct file_operations ecm_sfe_l2_defunct_by_5tuple_fops = {
	.owner = THIS_MODULE,
	.write = ecm_sfe_l2_defunct_by_5tuple_write,
};

/*
 * ecm_sfe_l2_defunct_by_port_write()
 *	Writes the defunct by port command to the debugfs node.
 */
static ssize_t ecm_sfe_l2_defunct_by_port_write(struct file *f, const char *user_buf,
					  size_t count, loff_t *offset)
{
	char *cmd_buf;
	char *fields;
	char *option, *value;
	int port;
	int direction;

	/*
	 * Command is formed as:
	 *
	 * echo “sport=443” > /sys/kernel/debug/ecm_sfe_l2/defunct_by_port
	 * echo “dport=443” > /sys/kernel/debug/ecm_sfe_l2/defunct_by_port
	 */
	cmd_buf = kzalloc(count + 1, GFP_ATOMIC);
	if (!cmd_buf) {
		pr_warn("unable to allocate memory for cmd buffer\n");
		return -ENOMEM;
	}

	count = simple_write_to_buffer(cmd_buf, count, offset, user_buf, count);

	/*
	 * Split the buffer into its fields
	 */
	fields = cmd_buf;
	option = strsep(&fields, "=");
	if (!strcmp(option, "sport")) {
		direction = 0;
	} else if (!strcmp(option, "dport")) {
		direction = 1;
	} else {
		pr_err("invalid option name: %s\n", option);
		kfree(cmd_buf);
		return -EINVAL;
	}

	value = fields;
	if (!sscanf(value, "%d", &port)) {
		pr_err("Unable to read port value %s\n", value);
		kfree(cmd_buf);
		return -EINVAL;
	}
	pr_debug("option: %s value: %d\n", option, port);

	kfree(cmd_buf);

	/*
	 * Call port based defunct function.
	 */
	ecm_sfe_common_defunct_by_port(port, direction, wan_name);

	return count;
}

/*
 * File operations for defunct by port operations.
 */
static struct file_operations ecm_sfe_l2_defunct_by_port_fops = {
	.owner = THIS_MODULE,
	.write = ecm_sfe_l2_defunct_by_port_write,
};

/*
 * ecm_sfe_l2_defunct_by_protocol_write()
 *	Writes the defunct by protocol command to the debugfs node.
 */
static ssize_t ecm_sfe_l2_defunct_by_protocol_write(struct file *f, const char *user_buf,
					  size_t count, loff_t *offset)
{
	char *cmd_buf;
	char *fields;
	char *option, *value;
	int protocol;

	/*
	 * Command is formed as:
	 *
	 * echo “protocol=6” > /sys/kernel/debug/ecm_sfe_l2/defunct_by_protocol
	 */
	cmd_buf = kzalloc(count + 1, GFP_ATOMIC);
	if (!cmd_buf) {
		pr_warn("unable to allocate memory for cmd buffer\n");
		return -ENOMEM;
	}

	count = simple_write_to_buffer(cmd_buf, count, offset, user_buf, count);

	/*
	 * Split the buffer into its fields
	 */
	fields = cmd_buf;
	option = strsep(&fields, "=");
	if (strcmp(option, "protocol")) {
		pr_err("invalid option name: %s\n", option);
		kfree(cmd_buf);
		return -EINVAL;
	}

	value = fields;
	if (!sscanf(value, "%d", &protocol)) {
		pr_err("Unable to read protocol value %s\n", value);
		kfree(cmd_buf);
		return -EINVAL;
	}
	pr_debug("option: %s value: %d\n", option, protocol);

	kfree(cmd_buf);

	/*
	 * Defunct the connections which has this protocol number.
	 */
	ecm_sfe_common_defunct_by_protocol(protocol);

	return count;
}

/*
 * File operations for defunct by protocol operations.
 */
static struct file_operations ecm_sfe_l2_defunct_by_protocol_fops = {
	.owner = THIS_MODULE,
	.write = ecm_sfe_l2_defunct_by_protocol_write,
};

/*
 * ecm_sfe_l2_wan_name_read()
 *	Reads the WAN interface name from the debugfs node wan_name
 */
static ssize_t ecm_sfe_l2_wan_name_read(struct file *f, char *buffer,
					 size_t len, loff_t *offset)
{
	return simple_read_from_buffer(buffer, len, offset, wan_name, wan_name_len);
}

/*
 * ecm_sfe_l2_wan_name_write()
 *	Writes the WAN interface name to the debugfs node wan_name
 */
static ssize_t ecm_sfe_l2_wan_name_write(struct file *f, const char *buffer,
					  size_t len, loff_t *offset)
{
	ssize_t ret;

	if (len > IFNAMSIZ) {
		pr_err("WAN interface name is too long\n");
		return -EINVAL;
	}

	ret = simple_write_to_buffer(wan_name, IFNAMSIZ, offset, buffer, len);
	if (ret < 0) {
		pr_err("WAN interface name cannot be written\n");
		return ret;
	}

	wan_name[ret - 1] = '\0';
	wan_name_len = ret;

	return ret;
}

/*
 * File operations for wan interface name.
 */
static struct file_operations ecm_sfe_l2_wan_name_fops = {
	.owner = THIS_MODULE,
	.write = ecm_sfe_l2_wan_name_write,
	.read = ecm_sfe_l2_wan_name_read,
};

struct ecm_sfe_common_callbacks sfe_cbs = {
	.l2_accel_check = ecm_sfe_l2_accel_check_callback,	/**< Callback to decide if L2 acceleration is wanted for the flow. */
};

/*
 * ecm_sfe_l2_init()
 */
static int __init ecm_sfe_l2_init(void)
{
	pr_debug("ECM SFE L2 module INIT\n");

	/*
	 * Create entries in DebugFS for control functions
	 */
	ecm_sfe_l2_dentry = debugfs_create_dir("ecm_sfe_l2", NULL);
	if (!ecm_sfe_l2_dentry) {
		pr_info("Failed to create SFE L2 directory entry\n");
		return -1;
	}

	if (!debugfs_create_file("wan_name", S_IWUSR, ecm_sfe_l2_dentry,
					NULL, &ecm_sfe_l2_wan_name_fops)) {
		pr_debug("Failed to create ecm wan interface file in debugfs\n");
		debugfs_remove_recursive(ecm_sfe_l2_dentry);
		return -1;
	}

	if (!debugfs_create_file("policy_rules", S_IWUSR, ecm_sfe_l2_dentry,
					NULL, &ecm_sfe_l2_policy_rule_fops)) {
		pr_debug("Failed to create ecm SFE L2 policy rules file in debugfs\n");
		debugfs_remove_recursive(ecm_sfe_l2_dentry);
		return -1;
	}

	if (!debugfs_create_file("defunct_by_protocol", S_IWUSR, ecm_sfe_l2_dentry,
					NULL, &ecm_sfe_l2_defunct_by_protocol_fops)) {
		pr_debug("Failed to create ecm defunct by protocol file in debugfs\n");
		debugfs_remove_recursive(ecm_sfe_l2_dentry);
		return -1;
	}

	if (!debugfs_create_file("defunct_by_5tuple", S_IWUSR, ecm_sfe_l2_dentry,
					NULL, &ecm_sfe_l2_defunct_by_5tuple_fops)) {
		pr_debug("Failed to create ecm defunct by 5tuple file in debugfs\n");
		debugfs_remove_recursive(ecm_sfe_l2_dentry);
		return -1;
	}

	if (!debugfs_create_file("defunct_by_port", S_IWUSR, ecm_sfe_l2_dentry,
					NULL, &ecm_sfe_l2_defunct_by_port_fops)) {
		pr_debug("Failed to create ecm defunct by port file in debugfs\n");
		debugfs_remove_recursive(ecm_sfe_l2_dentry);
		return -1;
	}

	if (ecm_sfe_common_callbacks_register(&sfe_cbs)) {
		pr_debug("Failed to register callbacks\n");
		debugfs_remove_recursive(ecm_sfe_l2_dentry);
		return -1;
	}
	return 0;
}

/*
 * ecm_sfe_l2_exit()
 */
static void __exit ecm_sfe_l2_exit(void)
{
	pr_debug("ECM SFE L2 check module EXIT\n");

	ecm_sfe_common_callbacks_unregister();

	/*
	 * Remove the debugfs files recursively.
	 */
	debugfs_remove_recursive(ecm_sfe_l2_dentry);
}

module_init(ecm_sfe_l2_init)
module_exit(ecm_sfe_l2_exit)

MODULE_DESCRIPTION("ECM SFE L2 Module");
#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual BSD/GPL");
#endif
