/*
 **************************************************************************
 * Copyright (c) 2016-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.
 **************************************************************************
 */

/*
 * nss_connnmgr_map_t.c
 *
 * This file implements NSS map-t client module
 */
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/module.h>
#include <linux/of.h>
#include <net/ipv6.h>
#include <linux/rwlock_types.h>
#include <linux/inetdevice.h>
#include <linux/if_arp.h>
#include <linux/version.h>
#include <linux/list_sort.h>
#include <linux/ipv6.h>
#include <linux/debugfs.h>

#include <nss_api_if.h>
#include <nss_dynamic_interface.h>
#include "nss_connmgr_map_t.h"
#include <nat46-core.h>
#include <nat46-netdev.h>

/*
 * NSS map_t debug macros
 */
#if (NSS_MAP_T_DEBUG_LEVEL < 1)
#define nss_connmgr_map_t_assert(fmt, args...)
#else
#define nss_connmgr_map_t_assert(c) BUG_ON(!(c));
#endif

/*
 * Compile messages for dynamic enable/disable
 */
#if defined(CONFIG_DYNAMIC_DEBUG)
#define nss_connmgr_map_t_warning(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
#define nss_connmgr_map_t_info(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
#define nss_connmgr_map_t_trace(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
#else

/*
 * Statically compile messages at different levels
 */
#if (NSS_MAP_T_DEBUG_LEVEL < 2)
#define nss_connmgr_map_t_warning(s, ...)
#else
#define nss_connmgr_map_t_warning(s, ...) pr_warn("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
#endif

#if (NSS_MAP_T_DEBUG_LEVEL < 3)
#define nss_connmgr_map_t_info(s, ...)
#else
#define nss_connmgr_map_t_info(s, ...) pr_notice("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
#endif

#if (NSS_MAP_T_DEBUG_LEVEL < 4)
#define nss_connmgr_map_t_trace(s, ...)
#else
#define nss_connmgr_map_t_trace(s, ...) pr_info("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
#endif
#endif

/*
 * Format for header: "netdevice = eth0\n"
 */
#define MAP_T_NETDEVICE_SZ (strlen("netdevice = ") + IFNAMSIZ + 1)

/*
 * Format for a rule: <11 digits decmal> + ": 0x" + <16 hex digits for long long> + newline
 */
#define MAP_T_INT_TO_DEC 11
#define MAP_T_LONG_LONG_TO_HEX 16
#define MAP_T_RULE_SZ ((MAP_T_INT_TO_DEC) + (MAP_T_LONG_LONG_TO_HEX) + 5)

#define MAP_T_IPV6_CLASS_SHIFT 20
#define MAP_T_IPV6_CLASS_MASK  0x0FF00000

/*
 * Max map-t interfaces supported = NSS_MAX_MAP_T_DYNAMIC_INTERFACES
 */
static int mapt_interfaces_count;

/*
 * MAP-T flags.
 */
static uint8_t map_t_flags;

/*
 * client code check for correctness of rule. This debug stats helps in
 * to see those stats
 */
static struct dentry *map_t_debugfs;

/*
 *      net_device1--------->net_device_2--------->net_device_3
 *		|		|			|
 *		|		|			|
 *		|		|			|
 *	     rule_set	     rule_set		      rule_set
 *
 */
static LIST_HEAD(list_dev_to_map_t_rules_head);

/*
 * nss_connmgr_map_t_dump_rules()
 *	dumps the rule list. Should only call this func from nss_connmgr_map_t_dev_up()
 *
 * This function dumps map-t rules read from nat-46 module. This function is
 * only for debug purpose.
 */
static void __maybe_unused nss_connmgr_map_t_dump_rules(struct net_device *dev __maybe_unused, struct nat46_xlate_rulepair *apair __maybe_unused, int count)
{
	const char *style_to_string[] __maybe_unused = {"NONE", "MAP", "MAP-0", "RFC6052"};
	int i = 0;

	if (!apair) {
		return;
	}

	for (i = 0; i < count; i++) {
		nss_connmgr_map_t_info("%px: local.v4 %pI4/%d local.v6 %pI6c/%d local.style %s local.ea-len %d local.psid-offset %d remote.v4 %pI4/%d remote.v6 %pI6c/%d remote.style %s remote.ea-len %d remote.psid-offset %d\n", dev,
			 &apair->local.v4_pref,
			 apair->local.v4_pref_len,
			 &apair->local.v6_pref,
			 apair->local.v6_pref_len,
			 style_to_string[apair->local.style],
			 apair->local.ea_len,
			 apair->local.psid_offset,

			 &apair->remote.v4_pref,
			 apair->remote.v4_pref_len,
			 &apair->remote.v6_pref,
			 apair->remote.v6_pref_len,
			 style_to_string[apair->remote.style],
			 apair->remote.ea_len,
			 apair->remote.psid_offset);

		apair++;
	}
}

/*
 * nss_connmgr_map_t_dump_list()
 *	dump sorted list. Should only call this func from nss_connmgr_map_t_dev_up()
 *
 * client module will sort map-t rules based on local ipv4 prefix len, remote
 * ipv4 prefix len, local ipv6 prefix len, remote ipv6 prefix len. This function
 * can dump those sorted list. This function is only for debug purpose.
 * We may call this function once sort is done.
 */
static void __maybe_unused nss_connmgr_map_t_dump_list(struct net_device *dev __maybe_unused, struct list_head *head)
{
	const char *style_to_string[] __maybe_unused = {"NONE", "MAP", "MAP-0", "RFC6052"};
	struct list_lookup_entry_t *entry;
	list_for_each_entry(entry, head, list) {
		struct nat46_xlate_rulepair *apair __maybe_unused = entry->ptr_rule_set;
		nss_connmgr_map_t_info("%px: local.v4 %pI4/%d local.v6 %pI6c/%d local.style %s local.ea-len %d local.psid-offset %d remote.v4 %pI4/%d remote.v6 %pI6c/%d remote.style %s remote.ea-len %d remote.psid-offset %d\n", dev,
			&apair->local.v4_pref,
			apair->local.v4_pref_len,
			&apair->local.v6_pref,
			apair->local.v6_pref_len,
			style_to_string[apair->local.style],
			apair->local.ea_len,
			apair->local.psid_offset,

			&apair->remote.v4_pref,
			apair->remote.v4_pref_len,
			&apair->remote.v6_pref,
			apair->remote.v6_pref_len,
			style_to_string[apair->remote.style],
			apair->remote.ea_len,
			apair->remote.psid_offset);
	}
}

/*
 * nss_connmgr_map_t_debugfs_set_rule_status()
 */
static void nss_connmgr_map_t_debugfs_set_rule_status(struct net_device *dev, int rule_num, uint64_t status)
{
	struct list_dev_to_map_t_rules_entry_t *entry;

	if (rule_num < 1) {
		return;
	}

	rule_num--;

	list_for_each_entry(entry, &list_dev_to_map_t_rules_head, list) {
		if (entry->dev != dev) {
			continue;
		}
		entry->rule_status[rule_num] = status;
		return;
	}
}

/*
 * nss_connmgr_map_t_free_all()
 *	Free up all memory allocated for linked list
 */
static void nss_connmgr_map_t_free_all(struct net_device *dev)
{
	struct list_dev_to_map_t_rules_entry_t *entry, *tmp;

	list_for_each_entry_safe(entry, tmp, &list_dev_to_map_t_rules_head, list) {

		if (entry->dev != dev) {
			continue;
		}

		kfree(entry->rule_status);

		list_del(&entry->list);
		kfree(entry);
	}
}

/*
 * nss_connmgr_map_t_allocate_all()
 *	allocate all data structures
 */
static void nss_connmgr_map_t_allocate_all(struct net_device *dev, struct nat46_xlate_rulepair *rule_pairs, int rule_pair_count)
{
	struct list_dev_to_map_t_rules_entry_t *entry;

	entry = (struct list_dev_to_map_t_rules_entry_t *)
					kmalloc(sizeof(struct list_dev_to_map_t_rules_entry_t), GFP_KERNEL);
	if (!entry) {
		nss_connmgr_map_t_warning("%px: Allocation for dev_to_map_t_rules_list_entry failed for netdev = %s\n", dev, dev->name);
		nss_connmgr_map_t_free_all(dev);
		return;
	}

	/*
	 * Add to map-t netdevice list
	 */
	INIT_LIST_HEAD(&entry->list);

	entry->dev = dev;
	entry->rule_set = rule_pairs;

	list_add(&entry->list, &list_dev_to_map_t_rules_head);

	entry->rule_pair_count = rule_pair_count;

	/*
	 * allocate memory for rule validation status
	 */
	entry->rule_status = kzalloc(sizeof(uint64_t) * rule_pair_count, GFP_KERNEL);

	if (!entry->rule_status) {
		nss_connmgr_map_t_free_all(dev);
	}

}

/*
 * nss_connmgr_mapt_validate_rule_style_mapt()
 *	Validate map-t style rule
 */
static bool nss_connmgr_mapt_validate_rule_style_mapt(struct net_device *dev, struct nat46_xlate_rule *rule, int rule_num,
						       bool is_local_rule, uint64_t *stats)
{
	int psid_len;

	/*
	 * Validate rule parameters
	 */
	if (rule->ea_len < 0 || rule->ea_len > 48) {
		nss_connmgr_map_t_warning("%px: mapt rule %d is invalid as ea_len < 0 or ea_len > 48\n", dev, rule_num);
		*stats |= 1 << (is_local_rule ? MAP_T_LOCAL_EA_BITS_LEN_IS_INVALID : MAP_T_REMOTE_EA_BITS_LEN_IS_INVALID);
		return false;
	}

	if (rule->v4_pref_len + rule->ea_len > 32) {
		psid_len = rule->ea_len - (32 - rule->v4_pref_len);
	} else {
		psid_len = 0;
	}

	if (psid_len + rule->psid_offset > 16) {
		nss_connmgr_map_t_warning("%px: mapt rule %d is invalid as psid offset + psid len > 16\n", dev, rule_num);
		*stats |= 1 << (is_local_rule ? MAP_T_LOCAL_PSID_LEN_PLUS_PSID_OFFSET_IS_GREATER_THAN_16 : MAP_T_REMOTE_PSID_LEN_PLUS_REMOTE_PSID_OFFSET_IS_GREATER_THAN_16);
		return false;
	}

	return true;
}

/*
 * nss_connmgr_mapt_validate_rule_style_rfc6052()
 *	Validate map-t style rule
 */
static bool nss_connmgr_mapt_validate_rule_style_rfc6052(struct net_device *dev, struct nat46_xlate_rule *rule, int rule_num, bool is_local_rule, uint64_t *stats)
{
	if (!(rule->v6_pref_len == 32 || rule->v6_pref_len == 40 ||
	      rule->v6_pref_len == 48 || rule->v6_pref_len == 56 ||
	      rule->v6_pref_len == 64 || rule->v6_pref_len == 96)) {
		nss_connmgr_map_t_warning("%px: mapt rule %d is invalid as rfc6052 end user prefix is invalid\n", dev, rule_num);
		*stats |= 1 << (is_local_rule ? MAP_T_LOCAL_IPV6_PREFIX_LEN_IS_NOT_32_40_48_56_64_OR_96 : MAP_T_REMOTE_IPV6_PREFIX_LEN_IS_NOT_32_40_48_56_64_OR_96);
		return false;
	}

	return true;
}

/*
 * nss_connmgr_mapt_check_correctness_of_mapt_rule()
 *	Check each mapt rule params and validate each field.
 *
 * Returns true if all parameters are correct.
 * As per RFC7599 (map-t rfc), local style should be map-t. Remote style
 * of FMR must be map-t, but remote syle of DMR is RFC6052.
 * map-t user space process doesnot really mandates this restriction and
 * allows style of rule can be anything irrespective of FMR or DMR. So
 * this check also won't fails on style mismatch.
 */
static bool nss_connmgr_mapt_check_correctness_of_mapt_rule(struct net_device *dev, struct nat46_xlate_rulepair *rule_pair, int rule_num, uint64_t *stats)
{
	/*
	 * Validate local rule parameters
	 */
	switch (rule_pair->local.style) {
	case NAT46_XLATE_NONE:
		break;

	case NAT46_XLATE_MAP:
		if (!nss_connmgr_mapt_validate_rule_style_mapt(dev, &rule_pair->local, rule_num, true, stats)) {
			return false;
		}
		break;

	case NAT46_XLATE_RFC6052:
		if (!nss_connmgr_mapt_validate_rule_style_rfc6052(dev, &rule_pair->local, rule_num, true, stats)) {
			return false;
		}
		break;

	default:
		*stats |= 1 << MAP_T_LOCAL_STYLE_IS_NOT_MAP_T_OR_RFC6052;
		return false;
	}

	/*
	 * Validate remote rule parameters
	 */
	switch (rule_pair->remote.style) {
	case NAT46_XLATE_MAP:
		if (!nss_connmgr_mapt_validate_rule_style_mapt(dev, &rule_pair->remote, rule_num, false, stats)) {
			return false;
		}
		break;

	case NAT46_XLATE_RFC6052:
		if (!nss_connmgr_mapt_validate_rule_style_rfc6052(dev, &rule_pair->remote, rule_num, false, stats)) {
			return false;
		}
		break;

	default:
		*stats |= 1 << MAP_T_REMOTE_STYLE_IS_NOT_MAP_T_OR_RFC6052;
		return false;
	}

	return true;
}

 /*
 * nss_connmgr_map_t_ipv6_get_tclass()
 * 	Get traffic class from IPv6 header.
 */
static inline uint8_t nss_connmgr_map_t_ipv6_get_tclass(struct ipv6hdr *ip6hdr)
{
	uint32_t verclassflow = ntohl(*(uint32_t *)ip6hdr);
	return  (verclassflow & MAP_T_IPV6_CLASS_MASK) >>
		 MAP_T_IPV6_CLASS_SHIFT;
}

/*
 * nss_connmgr_map_t_ipv6_set_tclass()
 * 	Set traffic class in IPv6 header.
 */
static inline void nss_connmgr_map_t_ipv6_set_tclass(struct ipv6hdr *ip6hdr, uint8_t tclass)
{
	uint32_t *ptr = (uint32_t *)ip6hdr;
	uint32_t verclassflow = ntohl(*ptr);

	verclassflow &= (uint32_t)~MAP_T_IPV6_CLASS_MASK;
	verclassflow |= (tclass << MAP_T_IPV6_CLASS_SHIFT) & MAP_T_IPV6_CLASS_MASK;
	*ptr = htonl(verclassflow);
}

/*
 * nss_connmgr_map_t_decap_exception()
 *	Exception handler registered to NSS for handling map_t ipv6 pkts
 */
static void nss_connmgr_map_t_decap_exception(struct net_device *dev,
			struct sk_buff *skb,
			__attribute__((unused)) struct napi_struct *napi)

{
	struct iphdr *ip4_hdr;
	struct ipv6hdr *ip6_hdr;
	uint32_t v4saddr = 0, v4daddr = 0;
	struct ipv6hdr ip6_hdr_r;
	uint8_t next_hdr, hop_limit, tclass, l4_proto;
	int total_len;
	uint32_t identifier = 0;
	bool df_bit = false;
	uint16_t skip_sz = 0;
	struct nss_map_t_mdata *mdata;

	mdata = (struct nss_map_t_mdata *)skb->data;

	/* discard meta data header */
	skb_pull(skb, sizeof(struct nss_map_t_mdata));
	skb_reset_mac_header(skb);

	skb_reset_network_header(skb);

	ip6_hdr = ipv6_hdr(skb);
	skb_set_transport_header(skb, sizeof(struct ipv6hdr));

	/*
	 * IPv4 packet is xlated to ipv6 packet by acceleration engine. But there is no ipv6 rule.
	 * Call xlate_6_to_4() [ which is exported by nat46.ko ] to find original ipv4 src and ipv4 dest address.
	 * These function is designed for packets from wan to lan. Since this packet is from lan, need to call
	 * this function with parameters reversed. ipv6_hdr_r is used for reversing ip addresses.
	 */
	memcpy(&ip6_hdr_r.saddr, &ip6_hdr->daddr, sizeof(struct in6_addr));
	memcpy(&ip6_hdr_r.daddr, &ip6_hdr->saddr, sizeof(struct in6_addr));

	if (unlikely(!xlate_6_to_4(dev, &ip6_hdr_r, ip6_hdr->nexthdr, &v4saddr, &v4daddr))) {  /* packet needs to be xlated v6 to v4 */
		nss_connmgr_map_t_warning("%px: Martian ipv6 packet !!..free it. (saddr=%pI6c daddr=%pI6c)\n", dev,\
					  &ip6_hdr->saddr, &ip6_hdr->daddr);
		dev_kfree_skb_any(skb);
		return;
	}

	next_hdr = ip6_hdr->nexthdr;
	total_len = sizeof(struct iphdr) + ntohs(ip6_hdr->payload_len);
	hop_limit = ip6_hdr->hop_limit;
	tclass = nss_connmgr_map_t_ipv6_get_tclass(ip6_hdr);

	if (likely(next_hdr != NEXTHDR_FRAGMENT)) {

		/*
		 * Set DF bit
		 */
		df_bit = !!(mdata->flags & NSS_MAPT_MDATA_FLAG_DF_BIT);

		l4_proto = next_hdr;
	} else {
		struct frag_hdr tmp_fh, *fh;
		const __be32 *fh_addr = skb_header_pointer(skb, sizeof(struct ipv6hdr), sizeof(struct frag_hdr), &tmp_fh);
		skip_sz = sizeof(struct frag_hdr);
		if (!fh_addr) {
			nss_connmgr_map_t_warning("%px: Not able to offset to frag header while v6 -->v4 xlate\n", dev);
			dev_kfree_skb_any(skb);
			return;
		}

		fh = (struct frag_hdr *)fh_addr;
		identifier = ntohl(fh->identification);
		l4_proto = fh->nexthdr;
	}

	skb_pull(skb, sizeof(struct ipv6hdr) + skip_sz - sizeof(struct iphdr));
	skb_reset_network_header(skb);
	skb_reset_mac_header(skb);

	ip4_hdr = ip_hdr(skb);
	memset(ip4_hdr, 0, sizeof(struct iphdr));

	skb_set_transport_header(skb, sizeof(struct iphdr));
	skb->protocol = htons(ETH_P_IP);

	ip4_hdr->ihl = 5;
	ip4_hdr->version = 4;
	ip4_hdr->tot_len = htons(total_len - skip_sz);
	ip4_hdr->ttl = hop_limit;
	ip4_hdr->protocol = l4_proto;
	ip4_hdr->saddr = v4daddr;
	ip4_hdr->daddr = v4saddr;
	ip4_hdr->tos = tclass;
	if (unlikely(df_bit)) {
		ip4_hdr->frag_off = htons(IP_DF);
	}

	if (unlikely(identifier)) {
		ip4_hdr->id = htons(identifier & 0xffff);
	} else {
		/*
		 * Generate the new identifier value and set it
		 * in the IPv4 Identification field.
		 */
		__ip_select_ident(dev_net(dev), ip4_hdr, 1);
	}

	skb->pkt_type = PACKET_HOST;
	skb->skb_iif = dev->ifindex;
	skb->ip_summed = CHECKSUM_NONE;
	skb->dev = dev;

	nss_connmgr_map_t_trace("%px: ipv6 packet exceptioned after v4 ---> v6 xlate, created original ipv4 packet\n", dev);
	nss_connmgr_map_t_trace("%px: Calculated ipv4 params: src_addr=0x%x dest_addr=0x%x totallen=%d\n", dev, ip4_hdr->saddr, ip4_hdr->daddr, total_len);

	dev_queue_xmit(skb);
	return;
}

/*
 * nss_connmgr_map_t_encap_exception()
 *	Exception handler registered to NSS for handling map_t ipv4 pkts
 * Translates ipv4 packet back to ipv6 and send to nat46 device directly.
 */
static void nss_connmgr_map_t_encap_exception(struct net_device *dev,
			struct sk_buff *skb,
			__attribute__((unused)) struct napi_struct *napi)

{
	struct iphdr *ip4_hdr;
	struct ipv6hdr *ip6_hdr;
	uint8_t v6saddr[16], v6daddr[16];
	struct tcphdr *tcph = NULL;
	struct udphdr *udph = NULL;
	struct iphdr ip4_hdr_r;
	__be16 sport, dport;
	uint8_t nexthdr, hop_limit, tos;
	int payload_len;
	bool df_bit = false;
	uint16_t append_hdr_sz = 0;
	uint16_t identifier;
	uint32_t l4_csum, orig_csum;
	uint16_t csum;

	/*
	 * Discard L2 header.
	 */
	skb_pull(skb, sizeof(struct ethhdr));
	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);

	ip4_hdr = ip_hdr(skb);
	skb_set_transport_header(skb, ip4_hdr->ihl * 4);

	if (ip4_hdr->protocol == IPPROTO_TCP) {
		tcph = tcp_hdr(skb);
		l4_csum = tcph->check;
		sport = tcph->source;
		dport = tcph->dest;
	} else if (ip4_hdr->protocol == IPPROTO_UDP) {
		udph = udp_hdr(skb);
		orig_csum = l4_csum = udph->check;
		sport = udph->source;
		dport = udph->dest;
	} else {
		nss_connmgr_map_t_warning("%px: Unsupported protocol, free it up\n", dev);
		dev_kfree_skb_any(skb);
		return;
	}

	/*
	 * Undo the checksum of the IPv4 source and destinationIPv4 address.
	 */
	csum = ip_compute_csum(&ip4_hdr->saddr, 2 * sizeof(ip4_hdr->saddr));
	l4_csum += ((~csum) & 0xFFFF);

	/*`
	 * IPv6 packet is xlated to ipv4 packet by acceleration engine. But there is no ipv4 rule.
	 * Call xlate_4_to_6() [ which is exported by nat46.ko ] to find original ipv6 src and ipv6 dest address.
	 * These functions is designed for packets from lan to wan. Since this packet is from wan, need to call
	 * this function with parameters reversed. ipv4_hdr_r is used for reversing ip addresses.
	 */
	ip4_hdr_r.daddr = ip4_hdr->saddr;
	ip4_hdr_r.saddr = ip4_hdr->daddr;

	if (unlikely(!xlate_4_to_6(dev, &ip4_hdr_r, dport, sport, v6saddr, v6daddr))) { /* exception happened after packet got xlated */
		nss_connmgr_map_t_warning("%px: Martian ipv4 packet !!..free it. (saddr = 0x%x daddr = 0x%x sport = %d dport = %d)\n", dev,\
					  ip4_hdr->saddr, ip4_hdr->daddr, sport, dport);
		dev_kfree_skb_any(skb);
		return;
	}

	nexthdr = ip4_hdr->protocol;
	payload_len = ntohs(ip4_hdr->tot_len) - sizeof(struct iphdr);
	hop_limit = ip4_hdr->ttl;
	tos = ip4_hdr->tos;
	identifier = ntohs(ip4_hdr->id);

	if (ip4_hdr->frag_off & htons(IP_DF)) {
		df_bit = true;
	}  else if (map_t_flags & MAPT_FLAG_ADD_DUMMY_HDR) {
		append_hdr_sz = sizeof(struct frag_hdr);
	}

	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + append_hdr_sz - sizeof(struct iphdr))) {
		nss_connmgr_map_t_warning("%px: Not enough headroom for ipv6 packet...Freeing the packet\n", dev);
		dev_kfree_skb_any(skb);
		return;
	}

	skb_push(skb, sizeof(struct ipv6hdr) + append_hdr_sz - sizeof(struct iphdr));
	skb_reset_network_header(skb);
	skb_reset_mac_header(skb);

	skb->protocol = htons(ETH_P_IPV6);

	ip6_hdr = ipv6_hdr(skb);
	memset(ip6_hdr, 0, sizeof(struct ipv6hdr));

	ip6_hdr->version = 6;
	ip6_hdr->payload_len = htons(payload_len + append_hdr_sz);
	ip6_hdr->hop_limit = hop_limit;

	nss_connmgr_map_t_ipv6_set_tclass(ip6_hdr, tos);
	memcpy(&ip6_hdr->daddr, v6saddr, sizeof(struct in6_addr));
	memcpy(&ip6_hdr->saddr, v6daddr, sizeof(struct in6_addr));

	if (unlikely(df_bit) || !(map_t_flags & MAPT_FLAG_ADD_DUMMY_HDR))  {
		ip6_hdr->nexthdr = nexthdr;
	} else {
		struct frag_hdr tmp_fh, *fh;
		const __be32 *fh_addr = skb_header_pointer(skb, sizeof(struct ipv6hdr), sizeof(struct frag_hdr), &tmp_fh);
		if (!fh_addr) {
			nss_connmgr_map_t_warning("%px: Not able to offset to frag header\n", dev);
			dev_kfree_skb_any(skb);
			return;
		}
		fh = (struct frag_hdr *)fh_addr;
		memset(fh, 0, sizeof(struct frag_hdr));
		fh->identification = htonl(identifier);
		fh->nexthdr = nexthdr;
		ip6_hdr->nexthdr = NEXTHDR_FRAGMENT;
	}

	skb_set_transport_header(skb, sizeof(struct ipv6hdr) + append_hdr_sz);

	/*
	 * Add the checksum of the IPv6 source and destination address.
	 */
	l4_csum += ip_compute_csum(ip6_hdr->saddr.s6_addr16, 2 * sizeof(ip6_hdr->saddr));
	/*
	 * Fold the 32 bits checksum to 16 bits
	 */
	l4_csum = (l4_csum & 0x0000FFFF) + (l4_csum >> 16);
	l4_csum = (l4_csum & 0x0000FFFF) + (l4_csum >> 16);

	if (nexthdr == IPPROTO_TCP) {
		tcph->check = (uint16_t)l4_csum;
	} else {
		udph->check = (orig_csum == 0)? 0:(uint16_t)l4_csum;
	}

	skb->pkt_type = PACKET_HOST;
	skb->skb_iif = dev->ifindex;
	skb->ip_summed = CHECKSUM_NONE;
	skb->dev = dev;

	nss_connmgr_map_t_trace("%p: ipv4 packet exceptioned after v6 ---> v4 xlate, created original ipv6 packet\n", dev);
	nss_connmgr_map_t_trace("%p: Calculted ipv6 params: src_addr=%pI6, dest_addr=%pI6, payload_len=%d, checksum=%x\n", dev, v6saddr, v6daddr, payload_len, l4_csum);

	dev_queue_xmit(skb);
	return;
}

/*
 * nss_map_t_update_dev_stats()
 */
void nss_map_t_update_dev_stats(struct net_device *dev, struct nss_map_t_sync_stats_msg *sync_stats)
{
	if (!dev) {
		nss_connmgr_map_t_warning("dev is null\n");
		return;
	}

	dev_hold(dev);

	nat46_update_stats(dev,
		sync_stats->node_stats.rx_packets,
		sync_stats->node_stats.rx_bytes,
		sync_stats->node_stats.tx_packets,
		sync_stats->node_stats.tx_bytes,
		nss_cmn_rx_dropped_sum(&sync_stats->node_stats),
		sync_stats->tx_dropped);

	dev_put(dev);
}

/*
 * nss_connmgr_map_t_event_receive()
 *	Event Callback to receive events from NSS
 */
static void nss_connmgr_map_t_event_receive(void *if_ctx, struct nss_map_t_msg *tnlmsg)
{
	struct net_device *netdev = if_ctx;

	switch (tnlmsg->cm.type) {
	case NSS_MAP_T_MSG_SYNC_STATS:
		nss_map_t_update_dev_stats(netdev, (struct nss_map_t_sync_stats_msg *)&tnlmsg->msg.stats);
		break;

	default:
		nss_connmgr_map_t_info("%px: Unknown Event from NSS\n", netdev);
		break;
	}
}

/*
 * nss_connmgr_map_t_dev_up()
 */
static int nss_connmgr_map_t_dev_up(struct net_device *dev)
{
	struct nat46_xlate_rulepair *rule_pairs;
	struct nss_ctx_instance *nss_ctx;
	struct nss_map_t_msg maptmsg;
	struct nss_map_t_instance_rule_config_msg *maptcfg;
	int rule_pair_count = 0;
	int if_inner, if_outer;
	nss_tx_status_t status;
	uint32_t features = 0;
	int i, j;
	uint64_t map_t_rule_validation_stats;

	/*
	 * Get MAP-T interface's information.
	 */
	if (!nat46_get_info(dev, &rule_pairs, &rule_pair_count, &map_t_flags)) {
		nss_connmgr_map_t_warning("%px: Failed to get ruleset on map-t netdevice (%s)\n", dev, dev->name);
		return NOTIFY_DONE;
	}

	/*
	 * Return, if number of  rules configured for the map-t
	 * interface is < 1 or > 64
	 */

	if (rule_pair_count < MAP_T_MIN_NUM_RULES_PER_MAP_T_INSTANCE || rule_pair_count > MAP_T_MAX_NUM_RULES_PER_MAP_T_INSTANCE) {
		nss_connmgr_map_t_warning("%px: No accleration supported if number of rules configured is %d\n", dev, rule_pair_count);
		return NOTIFY_DONE;
	}

	if (mapt_interfaces_count == NSS_MAX_MAP_T_DYNAMIC_INTERFACES) {
		nss_connmgr_map_t_warning("%px: Max number of mapt interfaces supported is %d\n", dev, NSS_MAX_MAP_T_DYNAMIC_INTERFACES);
		return NOTIFY_DONE;
	}

	/*
	 * Create MAP-T inner dynamic interface
	 */
	if_inner = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_INNER);
	if (if_inner < 0) {
		nss_connmgr_map_t_warning("%px: Request interface number failed\n", dev);
		return NOTIFY_DONE;
	}
	nss_connmgr_map_t_info("%px: encap nss_dynamic_interface_alloc_node() successful. if_number = %d\n", dev, if_inner);

	/*
	 * Create MAP-T outer dynamic interface
	 */
	if_outer = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_OUTER);
	if (if_outer < 0) {
		nss_connmgr_map_t_warning("%px: Request interface number failed\n", dev);
		goto outer_alloc_fail;
	}
	nss_connmgr_map_t_info("%px: decap nss_dynamic_interface_alloc_node() successful. if_number = %d\n", dev, if_outer);

	/*
	 * Register MAP-T encap interface with NSS
	 */
	nss_ctx = nss_map_t_register_if(if_inner,
			NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_INNER,
			nss_connmgr_map_t_encap_exception,
			nss_connmgr_map_t_event_receive,
			dev,
			features);

	if (!nss_ctx) {
		nss_connmgr_map_t_warning("%px: encap nss_register_map_t_if failed\n", dev);
		goto inner_register_fail;
	}
	nss_connmgr_map_t_info("%px: encap nss_register_map_t_if() successful. nss_ctx = %px\n", dev, nss_ctx);

	/*
	 * Register MAP-T decap interface with NSS
	 */
	nss_ctx = nss_map_t_register_if(if_outer,
			NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_OUTER,
			nss_connmgr_map_t_decap_exception,
			nss_connmgr_map_t_event_receive,
			dev,
			features);

	if (!nss_ctx) {
		nss_connmgr_map_t_warning("%px: decap nss_register_map_t_if failed\n", dev);
		goto outer_register_fail;
	}

	/*
	 * allocate needed data structures
	 */
	nss_connmgr_map_t_allocate_all(dev, rule_pairs, rule_pair_count);

	/*
	 * Send Rule configuration to acceleration engine.
	 */
	for (i = 0; i < rule_pair_count; i++) {
		map_t_rule_validation_stats = 0;

		memset(&maptmsg, 0, sizeof(struct nss_map_t_msg));
		maptcfg = &maptmsg.msg.create_msg;

		/*
		 * These info is used by nss to decide if all rules are
		 * sent to accleration engine. ie rule_num == rule_pair_count
		 */
		maptcfg->rule_num = i + 1;
		maptcfg->total_rules = rule_pair_count;

		/*
		 * Set local rule params
		 */
		maptcfg->local_map_style = (rule_pairs + i)->local.style;

		for (j = 0; j < 4; j++) {
			*((uint32_t *)(&maptcfg->local_ipv6_prefix) + j) = ntohl(*((uint32_t *)((rule_pairs + i)->local.v6_pref.s6_addr) + j));
		}
		maptcfg->local_ipv6_prefix_len = (rule_pairs + i)->local.v6_pref_len;

		maptcfg->local_ipv4_prefix = ntohl((rule_pairs + i)->local.v4_pref);
		maptcfg->local_ipv4_prefix_len = (rule_pairs + i)->local.v4_pref_len;
		maptcfg->local_ea_len = (rule_pairs + i)->local.ea_len;
		maptcfg->local_psid_offset = (rule_pairs + i)->local.psid_offset;

		maptcfg->valid_rule = 1;

		/*
		 * Set remote rule params
		 */
		maptcfg->remote_map_style = (rule_pairs + i)->remote.style;
		for (j = 0; j < 4; j++) {
			*((uint32_t *)(&maptcfg->remote_ipv6_prefix) + j) = ntohl(*((uint32_t *)((rule_pairs + i)->remote.v6_pref.s6_addr) + j));
		}
		maptcfg->remote_ipv6_prefix_len = (rule_pairs + i)->remote.v6_pref_len;

		maptcfg->remote_ipv4_prefix = ntohl((rule_pairs + i)->remote.v4_pref);
		maptcfg->remote_ipv4_prefix_len = (rule_pairs + i)->remote.v4_pref_len;
		maptcfg->remote_ea_len = (rule_pairs + i)->remote.ea_len;
		maptcfg->remote_psid_offset = (rule_pairs + i)->remote.psid_offset;

		/*
		 * check correctness of a map-t rule
		 */
		maptcfg->valid_rule = nss_connmgr_mapt_check_correctness_of_mapt_rule(dev, rule_pairs + i, i, &map_t_rule_validation_stats);

		/*
		 * Debugfs stats file <debug-fs-dir>/map-t helps to figure out
		 * goodness of a map-t rule. All bits should be 0, if rule is good
		 * and valid.
		 */
		if (unlikely(!maptcfg->valid_rule)) {
			map_t_rule_validation_stats |= 1 << MAP_T_INVALID_RULE;
		}

		/*
		 * set the sibling interface number
		 */
		maptcfg->sibling_if = if_outer;

		/*
		 * set MAP-T flags
		 */
		maptcfg->flags = map_t_flags;

		/*
		 * Send configure message to MAP-T encap interface.
		 */
		nss_map_t_msg_init(&maptmsg, if_inner, NSS_MAP_T_MSG_INSTANCE_RULE_CONFIGURE, sizeof(struct nss_map_t_instance_rule_config_msg), NULL, NULL);
		status = nss_map_t_tx_sync(nss_ctx, &maptmsg);
		if (status != NSS_TX_SUCCESS) {
			nss_connmgr_map_t_warning("%px: nss encap MAP-T instance configure command error %d\n", dev, status);

			map_t_rule_validation_stats |= ((uint64_t)(1)) << (64 - MAPT_AE_ERR_CONFIGURE);
			nss_connmgr_map_t_debugfs_set_rule_status(dev, i + 1, map_t_rule_validation_stats);

			goto config_fail;
		}

		nss_connmgr_map_t_debugfs_set_rule_status(dev, i + 1, map_t_rule_validation_stats);
		nss_connmgr_map_t_info("%px: encap nss_map_t_tx() rule #%d configuration successful\n", dev, i + 1);

		/*
		 * set the sibling interface number
		 */
		maptcfg->sibling_if = if_inner;

		/*
		 * Send configure message to MAP-T decap interface.
		 */
		nss_map_t_msg_init(&maptmsg, if_outer, NSS_MAP_T_MSG_INSTANCE_RULE_CONFIGURE, sizeof(struct nss_map_t_instance_rule_config_msg), NULL, NULL);
		status = nss_map_t_tx_sync(nss_ctx, &maptmsg);
		if (status != NSS_TX_SUCCESS) {
			nss_connmgr_map_t_warning("%px: nss decap MAP-T instance configure command error %d\n", dev, status);

			map_t_rule_validation_stats |= ((uint64_t)(1)) << (64 - MAPT_AE_ERR_CONFIGURE);
			nss_connmgr_map_t_debugfs_set_rule_status(dev, i + 1, map_t_rule_validation_stats);

			goto config_fail;
		}

		nss_connmgr_map_t_debugfs_set_rule_status(dev, i + 1, map_t_rule_validation_stats);
		nss_connmgr_map_t_info("%px: decap nss_map_t_tx() rule #%d configuration successful\n", dev, i + 1);
	}

	/*
	 * Increment map-t interface count
	 */
	mapt_interfaces_count++;
	nss_connmgr_map_t_info("%px: MAP-T interface count is #%d\n", dev, mapt_interfaces_count);

	return NOTIFY_DONE;

config_fail:
	nss_connmgr_map_t_free_all(dev);
	nss_map_t_unregister_if(if_outer);
outer_register_fail:
	nss_map_t_unregister_if(if_inner);
inner_register_fail:
	status = nss_dynamic_interface_dealloc_node(if_outer, NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_OUTER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_map_t_warning("%px: Unable to dealloc the decap node[%d] in the NSS FW!\n", dev, if_outer);
	}
outer_alloc_fail:
	status = nss_dynamic_interface_dealloc_node(if_inner, NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_INNER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_map_t_warning("%px: Unable to dealloc the encap node[%d] in the NSS FW!\n", dev, if_inner);
	}
	return NOTIFY_DONE;
}

/*
 * nss_connmgr_map_t_dev_down()
 */
static int nss_connmgr_map_t_dev_down(struct net_device *dev)
{
	int if_inner, if_outer;
	nss_tx_status_t status;
	struct nss_map_t_msg maptmsg;
	struct nss_map_t_instance_rule_deconfig_msg *maptcfg;

	/*
	 * Check if MAP-T encap interface is registered with NSS
	 */
	if_inner = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_INNER);
	if (if_inner < 0) {
		nss_connmgr_map_t_warning("%px: MAP-T encap net device is not registered with nss\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Check if MAP-T decap interface is registered with NSS
	 */
	if_outer = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_OUTER);
	if (if_outer < 0) {
		nss_connmgr_map_t_warning("%px: MAP-T decap net device is not registered with nss\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Free all allocated data structures.
	 */
	nss_connmgr_map_t_free_all(dev);

	memset(&maptmsg, 0, sizeof(struct nss_map_t_msg));
	maptcfg = &maptmsg.msg.destroy_msg;
	maptcfg->if_number = if_inner;

	/*
	 * Send deconfigure message to MAP-T encap interface.
	 */
	nss_map_t_msg_init(&maptmsg, if_inner, NSS_MAP_T_MSG_INSTANCE_RULE_DECONFIGURE, sizeof(struct nss_map_t_instance_rule_deconfig_msg), NULL, NULL);
	status = nss_map_t_tx_sync(nss_map_t_get_context(), &maptmsg);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_map_t_warning("%px: map_t encap instance deconfigure command failed, if_number = %d\n", dev, if_inner);
		return NOTIFY_DONE;
	}

	memset(&maptmsg, 0, sizeof(struct nss_map_t_msg));
	maptcfg = &maptmsg.msg.destroy_msg;
	maptcfg->if_number = if_outer;

	/*
	 * Send deconfigure message to MAP-T decap interface.
	 */
	nss_map_t_msg_init(&maptmsg, if_outer, NSS_MAP_T_MSG_INSTANCE_RULE_DECONFIGURE, sizeof(struct nss_map_t_instance_rule_deconfig_msg), NULL, NULL);
	status = nss_map_t_tx_sync(nss_map_t_get_context(), &maptmsg);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_map_t_warning("%px: map_t decap instance deconfigure command failed, if_number = %d\n", dev, if_outer);
		return NOTIFY_DONE;
	}

	nss_map_t_unregister_if(if_inner);
	nss_map_t_unregister_if(if_outer);

	status = nss_dynamic_interface_dealloc_node(if_inner, NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_INNER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_map_t_warning("%px: map_t encap dealloc node failure for if_number = %d\n", dev, if_inner);
		return NOTIFY_DONE;
	}
	nss_connmgr_map_t_info("%px: deleted map_t encap instance, if_number = %d\n", dev, if_inner);

	status = nss_dynamic_interface_dealloc_node(if_outer, NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_OUTER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_map_t_warning("%px: map_t decap dealloc node failure for if_number = %d\n", dev, if_outer);
		return NOTIFY_DONE;
	}
	nss_connmgr_map_t_info("%px: deleted map_t decap instance, if_number = %d\n", dev, if_outer);

	/*
	 * Decrement interface count
	 */
	mapt_interfaces_count--;
	nss_connmgr_map_t_info("%px: MAP-T interface count is #%d\n", dev, mapt_interfaces_count);

	return NOTIFY_DONE;
}

/*
 * nss_connmgr_map_t_dev_event()
 *	Net device notifier for nss map_t module
 */
static int nss_connmgr_map_t_dev_event(struct notifier_block *nb,
		unsigned long event, void *dev)
{
	struct net_device *netdev;
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 0))
	netdev = (struct net_device *)dev;
#else
	netdev = netdev_notifier_info_to_dev(dev);
#endif

	/*
	 * Check for map-t device
	 */
	if (!is_map_t_dev(netdev)) {
		return NOTIFY_DONE;
	}

	switch (event) {
	case NETDEV_UP:
		return nss_connmgr_map_t_dev_up(netdev);

	case NETDEV_DOWN:
		return nss_connmgr_map_t_dev_down(netdev);

	default:
		break;
	}

	return NOTIFY_DONE;
}

/*
 * map_t_debugfs_read()
 *	Read function of <DEBUGFS>/map-t entry
 *
 * map-t client code does a map-t rule validation before pushing ae-engine
 * rules. This helps to easily figure out problems in rules and hence quick
 * debuggging. <DEBUG-FS-DIR>/map-t has a 64bit value for each rule. All
 * bits '0' indicate that there is no validation error.
 */
static ssize_t map_t_debugfs_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
{
	struct list_head *list_head_ptr = file->private_data;
	struct list_dev_to_map_t_rules_entry_t *entry;
	char *buf;
	int total_rules = 0;
	int num_net_devices = 0;
	int user_copy_len = 0;
	int err = -EFAULT;

	/*
	 * Process context should sleep if the netdevice is going down and
	 * list_head_ptr is being emptied so that 'cat' of this debugfs
	 * entry won't race in smp
	 */
	rtnl_lock();

	/*
	 * Allocate memory
	 */
	list_for_each_entry(entry, list_head_ptr, list) {
		total_rules += entry->rule_pair_count;
		num_net_devices++;
	}

	/*
	 * Allocate buffer
	 */
	buf = kzalloc((MAP_T_NETDEVICE_SZ * num_net_devices) + (MAP_T_RULE_SZ * total_rules) + 1, GFP_KERNEL);
	if (!buf) {
		rtnl_unlock();
		return err;
	}

	list_for_each_entry(entry, list_head_ptr, list) {
		int i;
		int copied_len;
		copied_len = scnprintf(buf + user_copy_len, MAP_T_NETDEVICE_SZ, "netdevice = %s\n", entry->dev->name);
		if (unlikely(copied_len == -1)) {
			kfree(buf);
			rtnl_unlock();
			return err;
		}
		user_copy_len += copied_len;

		for (i = 0; i < entry->rule_pair_count; i++) {

			copied_len = scnprintf(buf + user_copy_len, MAP_T_RULE_SZ, "%d: 0x%016llx\n",
					      i + 1, entry->rule_status[i]);

			if (unlikely(copied_len == -1)) {
				kfree(buf);
				rtnl_unlock();
				return err;
			}
			user_copy_len += copied_len;
		}
	}

	err = simple_read_from_buffer(user_buf, count, ppos, buf, user_copy_len);
	kfree(buf);
	rtnl_unlock();
	return err;
}

/*
 * debugfs file ops structure
 */
static const struct file_operations map_t_debugfs_fops = {
	.open = simple_open,
	.read = map_t_debugfs_read,
};

/*
 * Linux Net device Notifier
 */
struct notifier_block nss_connmgr_map_t_notifier = {
	.notifier_call = nss_connmgr_map_t_dev_event,
};

/*
 * nss_connmgr_map_t_init_module()
 *	map_t module init function
 */
int __init nss_connmgr_map_t_init_module(void)
{
#ifdef CONFIG_OF
	/*
	 * If the node is not compatible, don't do anything.
	 */
	if (!of_find_node_by_name(NULL, "nss-common")) {
		return 0;
	}
#endif

	map_t_debugfs = debugfs_create_file("map-t", 0444, NULL, &list_dev_to_map_t_rules_head, &map_t_debugfs_fops);

	register_netdevice_notifier(&nss_connmgr_map_t_notifier);
	return 0;
}

/*
 * nss_connmgr_map_t_exit_module
 *	map_t module exit function
 */
void __exit nss_connmgr_map_t_exit_module(void)
{
#ifdef CONFIG_OF
	/*
	 * If the node is not compatible, don't do anything.
	 */
	if (!of_find_node_by_name(NULL, "nss-common")) {
		return;
	}
#endif

	if (map_t_debugfs) {
		debugfs_remove(map_t_debugfs);
	}

	unregister_netdevice_notifier(&nss_connmgr_map_t_notifier);
}

module_init(nss_connmgr_map_t_init_module);
module_exit(nss_connmgr_map_t_exit_module);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("NSS map_t offload manager");
