/*
 **************************************************************************
 * Copyright (c) 2017-2020 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_gre.c
 *  This file implements client for GRE.
 */

#include <linux/version.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <net/ip_tunnels.h>
#include <net/ip6_tunnel.h>
#include <linux/if_ether.h>
#include <net/gre.h>
#include <net/ip.h>

#include <nss_api_if.h>
#include <nss_dynamic_interface.h>
#include <nss_cmn.h>
#include "nss_connmgr_gre_public.h"
#include "nss_connmgr_gre.h"

#define MAX_RETRY_COUNT 100
#define MAX_WIFI_HEADROOM 66

/*
 * GRE connection manager context structure
 */
struct nss_connmgr_gre_context {
	struct list_head list;		/* List of GRE interface instances */
	spinlock_t lock;		/* Lock to protect list */
} gre_connmgr_ctx;

/*
 * GRE interface instance
 */
struct nss_gre_iface_instance {
	struct list_head list;			/* List of GRE interface instances */
	struct net_device *dev;			/* GRE netdevice */
	struct nss_connmgr_gre_cfg gre_cfg;	/* GRE configuration */
	enum nss_connmgr_gre_iftype gre_iftype;	/* GRE interface type */
	uint32_t inner_ifnum;			/* GRE inner dynamic interface */
	uint32_t outer_ifnum;			/* GRE outer dynamic interface */
};

/*
 * Unaligned infra in nss is disabled by default
 */
static bool enable_unalign = 1;
module_param(enable_unalign, bool, 0);

/*
 * nss_connmgr_gre_is_gre()
 *	Check whether device is of type GRE Tap or GRE Tun.
 */
static bool nss_connmgr_gre_is_gre(struct net_device *dev)
{
	if ((dev->type == ARPHRD_IPGRE) ||
	      (dev->type == ARPHRD_IP6GRE) || ((dev->type == ARPHRD_ETHER) &&
	      (dev->priv_flags_ext & (IFF_EXT_GRE_V4_TAP | IFF_EXT_GRE_V6_TAP)))) {
		return true;
	}

	return false;
}

/*
 * nss_connmgr_gre_alloc_instance()
 *	Allocate GRE interface instance.
 */
static struct nss_gre_iface_instance *nss_connmgr_gre_alloc_instance(struct net_device *dev)
{
	struct nss_gre_iface_instance *ngii;

	if (!nss_connmgr_gre_is_gre(dev)) {
		nss_connmgr_gre_warning("%px: dev is not a GRE interface\n", dev);
		return NULL;
	}

	ngii = kzalloc(sizeof(*ngii), GFP_KERNEL);
	if (!ngii)
		return NULL;

	INIT_LIST_HEAD(&ngii->list);
	ngii->dev = dev;
	return ngii;
}

/*
 * nss_connmgr_gre_free_instance()
 *	Free GRE interface instance.
 */
static void nss_connmgr_gre_free_instance(struct nss_gre_iface_instance *ngii)
{
	spin_lock(&gre_connmgr_ctx.lock);
	ngii->dev = NULL;

	if (!list_empty(&ngii->list))
		list_del(&ngii->list);

	spin_unlock(&gre_connmgr_ctx.lock);
	kfree(ngii);
}

/*
 * nss_connmgr_gre_find_instance()
 *	Find GRE interface instance from list.
 */
static struct nss_gre_iface_instance *nss_connmgr_gre_find_instance(struct net_device *dev)
{
	struct nss_gre_iface_instance *ngii;

	if (!nss_connmgr_gre_is_gre(dev)) {
		nss_connmgr_gre_warning("%px: dev is not a GRE interface\n", dev);
		return NULL;
	}

	/*
	 * Check if dev instance is in the list
	 */
	spin_lock(&gre_connmgr_ctx.lock);
	list_for_each_entry(ngii, &gre_connmgr_ctx.list, list) {
		if (ngii->dev == dev) {
			spin_unlock(&gre_connmgr_ctx.lock);
			return ngii;
		}
	}

	spin_unlock(&gre_connmgr_ctx.lock);
	return NULL;
}

/*
 * nss_connmgr_gre_dev_change_mtu()
 *	Netdev ops function to modify MTU of netdevice.
 */
static int nss_connmgr_gre_dev_change_mtu(struct net_device *dev, int new_mtu)
{
	if (new_mtu < 68 ||
	    new_mtu > 0xFFF8 - dev->needed_headroom) {
		return -EINVAL;
	}

	dev->mtu = new_mtu;
	return 0;
}

/*
 * nss_connmgr_gre_dev_init()
 *	Netdev ops function to intialize netdevice.
 */
static int nss_connmgr_gre_dev_init(struct net_device *dev)
{
	int i;
	nss_connmgr_gre_priv_t *priv = netdev_priv(dev);
	int32_t append = priv->pad_len + priv->gre_hlen;

	dev->tstats = alloc_percpu(struct pcpu_sw_netstats);
	if (!dev->tstats) {
		return -ENOMEM;
	}

	for_each_possible_cpu(i) {
		struct pcpu_sw_netstats *stats;
		stats = per_cpu_ptr(dev->tstats, i);
		u64_stats_init(&stats->syncp);
	}

	if ((dev->priv_flags_ext & IFF_EXT_GRE_V4_TAP) || (dev->type == ARPHRD_IPGRE)) {
		dev->needed_headroom = sizeof(struct iphdr) + sizeof(struct ethhdr) + MAX_WIFI_HEADROOM + append;
		dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - append;
		dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA;
		dev->hw_features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA;
		return 0;
	}

	/*
	 * Ipv6
	 */
	dev->needed_headroom = sizeof(struct ipv6hdr) + sizeof(struct ethhdr) + MAX_WIFI_HEADROOM + append;
	dev->mtu = ETH_DATA_LEN - sizeof(struct ipv6hdr) - append;
	if (dev->mtu < IPV6_MIN_MTU) {
		dev->mtu = IPV6_MIN_MTU;
	}

	dev->features |= NETIF_F_NETNS_LOCAL;
	return 0;
}

/*
 * nss_connmgr_gre_dev_uninit()
 *	Netdev ops function to unintialize netdevice.
 */
static void nss_connmgr_gre_dev_uninit(struct net_device *dev)
{
	free_percpu(dev->tstats);
	return;
}

/*
 * nss_connmgr_gre_dev_xmit()
 *	Netdev ops function to send packet to NSS.
 */
static netdev_tx_t nss_connmgr_gre_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{
	nss_tx_status_t status;
	int if_number;
	struct nss_ctx_instance *gre_ctx;
	nss_connmgr_gre_priv_t *priv = netdev_priv(dev);

	if_number = priv->nss_if_number_inner;
	if (unlikely(if_number <= 0)) {
		nss_connmgr_gre_info("%px: GRE dev is not registered with nss\n", dev);
		goto fail;
	}

	gre_ctx = nss_gre_get_context();
	if (unlikely(!gre_ctx)) {
		nss_connmgr_gre_info("%px: NSS GRE context not found for if_number %d\n", dev, if_number);
		goto fail;
	}

	/*
	 * Make room for needed headroom and un-share
	 * the SKB if it is cloned.
	 */
	if (skb_cow_head(skb, dev->needed_headroom)) {
		nss_connmgr_gre_info("%px: NSS GRE insufficient headroom\n", dev);
		goto fail;
	}

	status = nss_gre_tx_buf(gre_ctx, if_number, skb);
	if (unlikely(status != NSS_TX_SUCCESS)) {
		nss_connmgr_gre_info("%px: NSS GRE could not send packet to NSS %d\n", dev, if_number);
		goto fail;
	}

	return NETDEV_TX_OK;

fail:
	dev->stats.tx_dropped++;
	dev_kfree_skb_any(skb);
	return NETDEV_TX_OK;
}

/*
 * nss_connmgr_gre_get_dev_stats64()
 *	To get the netdev stats
 */
static struct rtnl_link_stats64 *nss_connmgr_gre_get_dev_stats64(struct net_device *dev,
						struct rtnl_link_stats64 *tot)
{
	uint64_t rx_packets, rx_bytes, tx_packets, tx_bytes;
	unsigned int start;
	int i;
	for_each_possible_cpu(i) {
		const struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, i);

		do {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
			start = u64_stats_fetch_begin_bh(&tstats->syncp);
#else
			start = u64_stats_fetch_begin_irq(&tstats->syncp);
#endif
			rx_packets = tstats->rx_packets;
			tx_packets = tstats->tx_packets;
			rx_bytes = tstats->rx_bytes;
			tx_bytes = tstats->tx_bytes;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
		} while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
#else
		} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
#endif

		tot->rx_packets += rx_packets;
		tot->tx_packets += tx_packets;
		tot->rx_bytes   += rx_bytes;
		tot->tx_bytes   += tx_bytes;

		tot->rx_dropped = dev->stats.rx_dropped;
		tot->tx_dropped = dev->stats.tx_dropped;
	}

	return tot;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
/*
 * nss_connmgr_gre_dev_stats64()
 *	Netdev ops function to retrieve stats for kernel version < 4.6
 */
static struct rtnl_link_stats64 *nss_connmgr_gre_dev_stats64(struct net_device *dev,
						struct rtnl_link_stats64 *tot)
{
	return nss_connmgr_gre_get_dev_stats64(dev, tot);
}
#else
/*
 * nss_connmgr_gre_dev_stats64()
 *	Netdev ops function to retrieve stats
 */
static void nss_connmgr_gre_dev_stats64(struct net_device *dev,
						struct rtnl_link_stats64 *tot)
{
	nss_connmgr_gre_get_dev_stats64(dev, tot);
}
#endif

/*
 * nss_connmgr_gre_dev_open()
 *	Netdev ops function to open netdevice.
 */
int nss_connmgr_gre_dev_open(struct net_device *dev)
{
	struct nss_ctx_instance *nss_ctx;
	struct nss_gre_msg req;
	struct nss_gre_linkup_msg *linkup = &req.msg.linkup;
	struct nss_gre_linkdown_msg *linkdown = &req.msg.linkdown;
	nss_tx_status_t status;
	int32_t inner_if, outer_if;

	inner_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER);
	if (inner_if < 0) {
		return -EINVAL;
	}

	outer_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER);
	if (outer_if < 0) {
		return -EINVAL;
	}

	nss_ctx = nss_gre_get_context();

	memset(&req, 0, sizeof(struct nss_gre_msg));

	/*
	 * Open inner interface
	 */
	linkup->if_number = inner_if;
	nss_gre_msg_init(&req, inner_if, NSS_IF_OPEN, sizeof(struct nss_gre_linkup_msg), NULL, NULL);

	status = nss_gre_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: open failed for inner interface %s", dev, dev->name);
		return -EFAULT;
	}

	/*
	 * Open outer interface
	 */
	linkup->if_number = outer_if;
	nss_gre_msg_init(&req, outer_if, NSS_IF_OPEN, sizeof(struct nss_gre_linkup_msg), NULL, NULL);

	status = nss_gre_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: open failed for outer interface %s", dev, dev->name);
		linkdown->if_number = inner_if;
		nss_gre_msg_init(&req, inner_if, NSS_IF_CLOSE, sizeof(struct nss_gre_linkdown_msg), NULL, NULL);
		status = nss_gre_tx_msg_sync(nss_ctx, &req);
		if (status != NSS_TX_SUCCESS) {
			nss_connmgr_gre_info("%px: close failed for inner interface %s", dev, dev->name);
		}
		return -EFAULT;
	}

	netif_start_queue(dev);
	return 0;
}
EXPORT_SYMBOL(nss_connmgr_gre_dev_open);

/*
 * nss_connmgr_gre_dev_close()
 *	Netdevice ops function to close netdevice.
 */
int nss_connmgr_gre_dev_close(struct net_device *dev)
{
	struct nss_ctx_instance *nss_ctx;
	struct nss_gre_msg req;
	struct nss_gre_linkdown_msg *linkdown = &req.msg.linkdown;
	struct nss_gre_linkup_msg *linkup = &req.msg.linkup;
	nss_tx_status_t status;
	int32_t inner_if, outer_if;

	netif_stop_queue(dev);

	inner_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER);
	if (inner_if < 0) {
		nss_connmgr_gre_info("%px: close failed for interface %s, inner interface: %d not valid", dev, dev->name, inner_if);
		return -EINVAL;
	}

	outer_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER);
	if (outer_if < 0) {
		nss_connmgr_gre_info("%px: close failed for interface %s, outer interface: %d not valid", dev, dev->name, inner_if);
		return -EINVAL;
	}

	nss_ctx = nss_gre_get_context();

	memset(&req, 0, sizeof(struct nss_gre_msg));

	/*
	 * Close inner interface
	 */
	linkdown->if_number = inner_if;
	nss_gre_msg_init(&req, inner_if, NSS_IF_CLOSE, sizeof(struct nss_gre_linkdown_msg), NULL, NULL);

	status = nss_gre_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: close failed for inner interface %s", dev, dev->name);
		return -EFAULT;
	}

	/*
	 * Close outer interface
	 */
	linkdown->if_number = outer_if;
	nss_gre_msg_init(&req, outer_if, NSS_IF_CLOSE, sizeof(struct nss_gre_linkdown_msg), NULL, NULL);

	status = nss_gre_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: close failed for outer interface %s", dev, dev->name);
		linkup->if_number = inner_if;
		nss_gre_msg_init(&req, inner_if, NSS_IF_OPEN, sizeof(struct nss_gre_linkup_msg), NULL, NULL);
		status = nss_gre_tx_msg_sync(nss_ctx, &req);
		if (status != NSS_TX_SUCCESS) {
			nss_connmgr_gre_info("%px: open failed for inner interface %s", dev, dev->name);
		}
		return -EFAULT;
	}

	return 0;
}
EXPORT_SYMBOL(nss_connmgr_gre_dev_close);

/*
 * Tap net device ops
 */
static const struct net_device_ops nss_connmgr_gre_tap_ops = {
	.ndo_init = nss_connmgr_gre_dev_init,
	.ndo_uninit = nss_connmgr_gre_dev_uninit,
	.ndo_open = nss_connmgr_gre_dev_open,
	.ndo_stop = nss_connmgr_gre_dev_close,
	.ndo_set_mac_address = eth_mac_addr,
	.ndo_validate_addr = eth_validate_addr,
	.ndo_change_mtu	= nss_connmgr_gre_dev_change_mtu,
	.ndo_start_xmit = nss_connmgr_gre_dev_xmit,
	.ndo_get_stats64 = nss_connmgr_gre_dev_stats64,
};

/*
 * Tun netdevice ops
 */
static const struct net_device_ops nss_connmgr_gre_tun_ops = {
	.ndo_init = nss_connmgr_gre_dev_init,
	.ndo_uninit = nss_connmgr_gre_dev_uninit,
	.ndo_open = nss_connmgr_gre_dev_open,
	.ndo_stop = nss_connmgr_gre_dev_close,
	.ndo_change_mtu	= nss_connmgr_gre_dev_change_mtu,
	.ndo_start_xmit = nss_connmgr_gre_dev_xmit,
	.ndo_get_stats64 = nss_connmgr_gre_dev_stats64,
};

/*
 * nss_connmgr_gre_tun_setup()
 */
static void nss_connmgr_gre_tun_setup(struct net_device *dev)
{
	dev->addr_len = 4;
	dev->flags = IFF_NOARP | IFF_POINTOPOINT;
	dev->priv_flags	&= ~IFF_XMIT_DST_RELEASE;
	dev->netdev_ops = &nss_connmgr_gre_tun_ops;
}

/*
 * nss_connmgr_gre_tap_setup()
 */
static void nss_connmgr_gre_tap_setup(struct net_device *dev)
{
	dev->netdev_ops = &nss_connmgr_gre_tap_ops;
	eth_hw_addr_random(dev);
}

/*
 * nss_connmgr_gre_prepare_config_cmd()
 *	Retrieve info from netdevie and fill it in config message to NSS.
 */
static int32_t nss_connmgr_gre_prepare_config_cmd(struct net_device *dev,
						      struct nss_gre_msg *req,
						      struct net_device **next_dev,
						      bool hold)
{
	struct nss_gre_config_msg *cmsg = &req->msg.cmsg;

	if ((dev->type == ARPHRD_ETHER) && (dev->priv_flags_ext & IFF_EXT_GRE_V4_TAP)) {
		cmsg->mode = NSS_GRE_MODE_TAP;
		cmsg->ip_type = NSS_GRE_IP_IPV4;
		if (enable_unalign) {
			cmsg->flags |= NSS_GRE_CONFIG_USE_UNALIGNED;
		}
		return nss_connmgr_gre_v4_get_config(dev, req, next_dev, hold);
	}

	if ((dev->type == ARPHRD_ETHER) && (dev->priv_flags_ext & IFF_EXT_GRE_V6_TAP)) {
		cmsg->mode = NSS_GRE_MODE_TAP;
		cmsg->ip_type = NSS_GRE_IP_IPV6;
		if (enable_unalign) {
			cmsg->flags |= NSS_GRE_CONFIG_USE_UNALIGNED;
		}
		return nss_connmgr_gre_v6_get_config(dev, req, next_dev, hold);
	}

	if (dev->type == ARPHRD_IPGRE) {
		cmsg->mode = NSS_GRE_MODE_TUN;
		cmsg->ip_type = NSS_GRE_IP_IPV4;
		return nss_connmgr_gre_v4_get_config(dev, req, next_dev, hold);
	}

	if (dev->type == ARPHRD_IP6GRE) {
		cmsg->mode = NSS_GRE_MODE_TUN;
		cmsg->ip_type = NSS_GRE_IP_IPV6;
		return nss_connmgr_gre_v6_get_config(dev, req, next_dev, hold);
	}

	return GRE_ERR_NOT_GRE_NETDEV;
}

/*
 * nss_connmgr_gre_tap_inner_exception()
 * 	Exception handler for GRETAP inner device
 *
 * These are the packets exceptioned after decapsulation,
 * and we can send the packet to linux after modifying
 * some skb fields.
 */
static void nss_connmgr_gre_tap_inner_exception(struct net_device *dev, struct sk_buff *skb,
					  __attribute__((unused)) struct napi_struct *napi)
{

	struct ethhdr *eth_hdr = (struct ethhdr *)skb->data;

	nss_connmgr_gre_trace("%px: eth_hdr->h_proto: %d\n", dev, eth_hdr->h_proto);

	if (likely(ntohs(eth_hdr->h_proto) >= ETH_P_802_3_MIN)) {
		switch (ntohs(eth_hdr->h_proto)) {
		case ETH_P_IP:
		case ETH_P_IPV6:
			/*
		 	 * These are decapped packets.
		 	 */
			skb->protocol = eth_type_trans(skb, dev);
			netif_receive_skb(skb);
			return;
		default:
			break;
		}
	}

	/*
	 * These are decapped and exceptioned non IP packets.
	 */
	skb->protocol = eth_type_trans(skb, dev);
	netif_receive_skb(skb);
	return;
}

/*
 * nss_connmgr_gre_tap_outer_exception()
 * 	Exception handler for GRETAP outer device
 *
 * These are the packets exceptioned after encapsulation,
 * and we need to remove the GRE header of the packet and
 * pass it to linux.
 */
static void nss_connmgr_gre_tap_outer_exception(struct net_device *dev, struct sk_buff *skb,
					  __attribute__((unused)) struct napi_struct *napi)
{

	struct ethhdr *eth_hdr;

	eth_hdr = (struct ethhdr *)skb->data;
	nss_connmgr_gre_trace("%px: eth_hdr->h_proto: %d\n", dev, eth_hdr->h_proto);
	if (likely(ntohs(eth_hdr->h_proto) >= ETH_P_802_3_MIN)) {
		switch (ntohs(eth_hdr->h_proto)) {
		case ETH_P_IP:
			return nss_connmgr_gre_tap_v4_outer_exception(dev, skb);
		case ETH_P_IPV6:
			return nss_connmgr_gre_tap_v6_outer_exception(dev, skb);
		default:
			nss_connmgr_gre_warning("%px: invalid skb received:%px with protocol: %d. Freeing the skb.\n", dev, skb, ntohs(eth_hdr->h_proto));
			dev_kfree_skb_any(skb);
		}
	}
}

/*
 * nss_connmgr_gre_tun_inner_exception()
 * 	Exception handler for GRETUN inner device
 *
 * These are the packets exceptioned after decapsulation,
 * and we can send the packet to linux after modifying
 * some skb fields.
 */
static void nss_connmgr_gre_tun_inner_exception(struct net_device *dev, struct sk_buff *skb,
					  __attribute__((unused)) struct napi_struct *napi)
{
	struct iphdr *iph;

	iph = (struct iphdr *)skb->data;
	switch (iph->version) {
	case 4:
		skb->protocol = htons(ETH_P_IP);
		break;
	case 6:
		skb->protocol = htons(ETH_P_IPV6);
		break;
	default:
		nss_connmgr_gre_warning("%px: wrong IP version set to skb:%px\n", dev, skb);
		dev_kfree_skb_any(skb);
		return;
	}

	skb->pkt_type = PACKET_HOST;
	skb->dev = dev;
	netif_receive_skb(skb);
}

/*
 * nss_connmgr_gre_tun_outer_exception()
 * 	Exception handler for GRETUN outer device
 *
 * These are the packets exceptioned after encapsulation,
 * and we need to remove the GRE header of the packet and
 * pass it to linux.
 */
static void nss_connmgr_gre_tun_outer_exception(struct net_device *dev, struct sk_buff *skb,
					  __attribute__((unused)) struct napi_struct *napi)
{
	struct iphdr *iph;

	iph = (struct iphdr *)skb->data;
	switch (iph->version) {
	case 4:
		return nss_connmgr_gre_tun_v4_outer_exception(dev, skb);
	case 6:
		return nss_connmgr_gre_tun_v6_outer_exception(dev, skb);
	default:
		nss_connmgr_gre_warning("%px: wrong IP version set to skb:%px\n", dev, skb);
		dev_kfree_skb_any(skb);
		break;
	}
}

/*
 * nss_connmgr_gre_rx_pkt()
 *	GRE Tap function to receive packet from NSS.
 */
static void nss_connmgr_gre_rx_pkt(struct net_device *dev, struct sk_buff *skb,
				       __attribute__((unused)) struct napi_struct *napi)
{
	skb->dev = dev;
	skb->protocol = eth_type_trans(skb, dev);
	netif_receive_skb(skb);
}

/*
 * nss_connmgr_gre_event_receive()
 *	Event Callback to receive events from NSS
 */
static void nss_connmgr_gre_event_receive(void *if_ctx, struct nss_gre_msg *tnlmsg)
{
	struct net_device *dev = if_ctx;
	struct nss_cmn_node_stats *stats = &tnlmsg->msg.sstats.node_stats;
	struct pcpu_sw_netstats *tstats;
	enum nss_dynamic_interface_type interface_type;

	switch (tnlmsg->cm.type) {
	case NSS_GRE_MSG_SESSION_STATS:
		interface_type = nss_dynamic_interface_get_type(nss_gre_get_context(), tnlmsg->cm.interface);
		tstats = this_cpu_ptr(dev->tstats);
		u64_stats_update_begin(&tstats->syncp);
		if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER) {
			tstats->tx_packets += stats->tx_packets;
			tstats->tx_bytes += stats->tx_bytes;
		} else if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER) {
			tstats->rx_packets += stats->rx_packets;
			tstats->rx_bytes += stats->rx_bytes;
		}
		u64_stats_update_end(&tstats->syncp);
		dev->stats.rx_dropped += nss_cmn_rx_dropped_sum(stats);
		break;

	case NSS_GRE_MSG_BASE_STATS:
		break;

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

/*
 * nss_connmgr_gre_make_name()
 *	Generate a name for netdevice if user does not provide one.
 */
static void nss_connmgr_gre_make_name(struct nss_connmgr_gre_cfg *cfg, char *name)
{
	switch (cfg->mode) {
	case GRE_MODE_TUN:
		strlcpy(name, "tun-%d", IFNAMSIZ);
		break;
	case GRE_MODE_TAP:
		strlcpy(name, "tap-%d", IFNAMSIZ);
		break;
	default:
		break;
	}
}

/*
 * __nss_connmgr_gre_create_interface()
 *	Creates GRE Tap/Tun netdevice and configure GRE node in NSS.
 *	This should be called after acquiring rtnl_lock().
 */
static struct net_device *__nss_connmgr_gre_create_interface(struct nss_connmgr_gre_cfg *cfg,
							     enum nss_connmgr_gre_err_codes *err_code)
{
	struct nss_ctx_instance *nss_ctx;
	struct net_device *dev = NULL;
	struct net_device *next_dev_inner = NULL;
	struct net_device *next_dev_outer = NULL;
	struct nss_gre_iface_instance *ngii;
	struct nss_gre_msg req;
	struct nss_gre_config_msg *cmsg = &req.msg.cmsg;
	nss_connmgr_gre_priv_t *priv;
	nss_tx_status_t status;
	uint32_t features = 0;
	int32_t inner_if, outer_if;
	char name[IFNAMSIZ] = {0};
	int ret = -1, retry, next_if_num_inner = 0, next_if_num_outer = 0;

	if (cfg->name) {
		strlcpy(name, cfg->name, IFNAMSIZ);
	} else {
		nss_connmgr_gre_make_name(cfg, name);
	}

	switch (cfg->mode) {
	case GRE_MODE_TUN:
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0))
		dev = alloc_netdev(sizeof(nss_connmgr_gre_priv_t), name, nss_connmgr_gre_tun_setup);
#else
		dev = alloc_netdev(sizeof(nss_connmgr_gre_priv_t), name, NET_NAME_UNKNOWN, nss_connmgr_gre_tun_setup);
#endif

		if (!dev) {
			nss_connmgr_gre_warning("Allocation of netdev failed\n");
			*err_code = GRE_ERR_ALLOC_NETDEV;
			return NULL;
		}

		if (cfg->is_ipv6) {
			dev->type = ARPHRD_IP6GRE;
			ret = nss_connmgr_gre_v6_set_config(dev, cfg);
		} else {
			dev->type = ARPHRD_IPGRE;
			ret = nss_connmgr_gre_v4_set_config(dev, cfg);
		}

		break;

	case GRE_MODE_TAP:
		dev = alloc_etherdev(sizeof(nss_connmgr_gre_priv_t));
		if (!dev) {
			nss_connmgr_gre_warning("Allocation of netdev failed\n");
			*err_code = GRE_ERR_ALLOC_NETDEV;
			return NULL;
		}

		nss_connmgr_gre_tap_setup(dev);

		if (cfg->is_ipv6) {
			dev->priv_flags_ext |= IFF_EXT_GRE_V6_TAP;
			ret = nss_connmgr_gre_v6_set_config(dev, cfg);
		} else {
			dev->priv_flags_ext |= IFF_EXT_GRE_V4_TAP;
			ret = nss_connmgr_gre_v4_set_config(dev, cfg);
		}
		break;

	default:
		nss_connmgr_gre_warning("Please Specify gre mode\n");
		*err_code = GRE_ERR_INVALID_MODE;
		goto release_ref;
	}

	if (ret) {
		nss_connmgr_gre_warning("%px: gre interface configuration failed\n", dev);
		*err_code = ret;
		goto release_ref;
	}

	/*
	 * Set name
	 */
	memcpy(dev->name, name, IFNAMSIZ);

	/*
	 * Create config cmd for acceleration engine
	 */
	memset(&req, 0, sizeof(struct nss_gre_msg));
	ret = nss_connmgr_gre_prepare_config_cmd(dev, &req, &next_dev_inner, true);
	if (ret) {
		nss_connmgr_gre_warning("%px: gre get config failed\n", dev);
		*err_code = ret;
		goto release_ref;
	}

	/*
	 *  Replace MAC addr and next node with user provided entries.
	 */
	if (cfg->use_mac_hdr) {
		memcpy(cmsg->src_mac, cfg->src_mac, ETH_ALEN);
		memcpy(cmsg->dest_mac, cfg->dest_mac, ETH_ALEN);
		cmsg->flags |= NSS_GRE_CONFIG_SET_MAC;
	}

	/*
	 * If next_dev is NULL, then the set MAC
	 * flag can not be set. Because the packet
	 * will be forwarded to ipv4_rx/ipv6_rx
	 */
	if (!cfg->next_dev) {
		cmsg->flags &= ~NSS_GRE_CONFIG_SET_MAC;
	}

	/*
	 * By now, we should have valid MAC addresses
	 */
	if (!is_valid_ether_addr((const u8 *)cmsg->src_mac) ||
	    !is_valid_ether_addr((const u8 *)cmsg->dest_mac)) {
		nss_connmgr_gre_warning("%px: Could not find MAC address for src/dest IP\n", dev);
		*err_code = GRE_ERR_INVALID_MAC;
		goto release_ref;
	}

	/*
	 * Configure the inner nexthop ifnum
	 */
	if (cfg->next_dev) {
		/*
		 * Release hold on GRE inner's nexthop that we have found,
		 * since it has been passed explicitly via the cfg
		 */
		if (next_dev_inner) {
			dev_put(next_dev_inner);
		}

		dev_hold(cfg->next_dev);

		/*
		 * TODO: Use the dynamic interface type for the inner's nexthop, in addition to the next_dev.
		 */
		next_if_num_inner = nss_cmn_get_interface_number_by_dev(cfg->next_dev);
		next_dev_inner = cfg->next_dev;
		if (next_if_num_inner < 0) {
			nss_connmgr_gre_warning("%px: Next dev inner device= %s is not registered with ae engine\n",
						dev, cfg->next_dev->name);
			*err_code = GRE_ERR_NEXT_NODE_UNREG_IN_AE;
			goto release_ref;
		}

		cmsg->flags |= NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE;
	}

	/*
	 * Configure the outer nexthop ifnum
	 */
	if (cfg->next_dev_outer) {
		dev_hold(cfg->next_dev_outer);

		/*
		 * Verify if dynamic interface type is in range.
		 */
		if (cfg->outer_nss_if_type >= NSS_DYNAMIC_INTERFACE_TYPE_MAX) {
			nss_connmgr_gre_warning("%px: invalid cfg, outer nexthop type %d is not in range\n",
				       dev, cfg->outer_nss_if_type);
			goto release_ref;
		}

		next_if_num_outer = nss_cmn_get_interface_number_by_dev_and_type(cfg->next_dev_outer, cfg->outer_nss_if_type);
		next_dev_outer = cfg->next_dev_outer;

		if (next_if_num_outer < 0) {
			nss_connmgr_gre_warning("%px: Next dev outer device %s with dynamic if num %d not registered with NSS\n",
					dev, cfg->next_dev_outer->name, next_if_num_outer);
			*err_code = GRE_ERR_NEXT_NODE_UNREG_IN_AE;
			goto release_ref;
		}

		/*
		 * Get the NSS ctx for the outer next hop
		 */
		nss_ctx = nss_dynamic_interface_get_nss_ctx_by_type(cfg->outer_nss_if_type);
		if (!nss_ctx) {
			nss_connmgr_gre_warning("Could not get NSS context for type : %d\n", cfg->outer_nss_if_type);
			goto release_ref;
		}

		/*
		 * Append the core-id for the outer next hop ifnum
		 */
		next_if_num_outer = nss_cmn_append_core_id(nss_ctx, next_if_num_outer);
		if (!next_if_num_outer) {
			nss_connmgr_gre_warning("%px: Could not get interface number with core ID for outer nexthop device %s with core ID.\n",
				       nss_ctx, next_dev_outer->name);
			goto release_ref;
		}

		cmsg->flags |= NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE;
	}

	/*
	 * By now, we should have a valid next node for either inner or outer
	 */
	if (!(cmsg->flags & NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE)) {
		nss_connmgr_gre_warning("%px: Next dev is not available\n", dev);
		*err_code = GRE_ERR_NO_NEXT_NETDEV;
		goto release_ref;
	}

	if (cfg->add_padding) {
		cmsg->flags |= NSS_GRE_CONFIG_SET_PADDING;
	}

	if (cfg->copy_metadata) {
		cmsg->flags |= NSS_GRE_CONFIG_COPY_METADATA;
		cmsg->metadata_size = sizeof(struct nss_wifi_append_statsv2_metahdr);
	}

	/*
	 * Set per packet DSCP configuration if needed
	 */
	if (cfg->dscp_valid) {
		cmsg->flags |= NSS_GRE_CONFIG_DSCP_VALID;
	}

	/*
	 * Register net_device
	 */
	ret = register_netdevice(dev);
	if (ret) {
		*err_code = GRE_ERR_NETDEV_REG_FAILED;
		nss_connmgr_gre_warning("%px: Netdevice registration failed\n", dev);
		goto release_ref;
	}

	/*
	 * Create GRE interface instance
	 */
	ngii = nss_connmgr_gre_alloc_instance(dev);
	if (!ngii) {
		nss_connmgr_gre_warning("%px: GRE interfacen intance creation failed\n", dev);
		*err_code = GRE_ERR_ALLOC_GRE_INSTANCE;
		goto unregister_netdev;
	}

	/*
	 * Create nss outer dynamic interface
	 */
	outer_if = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER);
	if (outer_if < 0) {
		nss_connmgr_gre_warning("%px: Request interface number failed\n", dev);
		*err_code = GRE_ERR_DYNMAIC_IFACE_CREATE;
		goto free_gre_instance;
	}

	ngii->outer_ifnum = outer_if;
	priv = (nss_connmgr_gre_priv_t *)netdev_priv(dev);
	priv->next_dev_outer = next_dev_outer;

	/*
	 * Create nss inner dynamic interface
	 */
	inner_if = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER);
	if (inner_if < 0) {
		nss_connmgr_gre_warning("%px: Request interface number failed\n", dev);
		*err_code = GRE_ERR_DYNMAIC_IFACE_CREATE;
		goto free_gre_instance;
	}

	ngii->inner_ifnum = inner_if;
	priv->next_dev_inner = next_dev_inner;
	priv->nss_if_number_inner = inner_if;

	/*
	 * Register outer gre tunnel with NSS
	 */
	nss_ctx = nss_gre_register_if(outer_if,
				NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER,
				nss_connmgr_gre_rx_pkt,
	 			nss_connmgr_gre_event_receive,
				dev,
				features);
	if (!nss_ctx) {
		nss_connmgr_gre_info("%px: nss_register_gre_if failed\n", dev);
		*err_code = GRE_ERR_GRE_IFACE_REG;
		goto dealloc_inner_node;
	}

	/*
	 * Register inner gre tunnel with NSS
	 */
	nss_ctx = nss_gre_register_if(inner_if,
				NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER,
				nss_connmgr_gre_rx_pkt,
	 			nss_connmgr_gre_event_receive,
				dev,
				features);
	if (!nss_ctx) {
		nss_connmgr_gre_info("%px: nss_register_gre_if failed\n", dev);
		*err_code = GRE_ERR_GRE_IFACE_REG;
		goto dealloc_inner_node;
	}

	nss_connmgr_gre_info("%px: nss_register_gre_if() custom successful. nss_ctx = %px. inner_if: %d, outer_if: %d\n", dev, nss_ctx, inner_if, outer_if);

	/*
	 * Send encap config to AE
	 */
	cmsg->flags &= ~NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE;

	/*
	 * Configure nexthop to inner node if available
	 */
	if (next_if_num_inner) {
		cmsg->next_node_if_num = next_if_num_inner;
		cmsg->flags |= NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE;
	}
	cmsg->sibling_if_num = outer_if;
	nss_gre_msg_init(&req, inner_if, NSS_GRE_MSG_ENCAP_CONFIGURE, sizeof(struct nss_gre_config_msg), NULL, NULL);
	nss_connmgr_gre_info("%px: NSS_GRE_MSG_ENCAP_CONFIGURE:: nss_ctx = %px, flags:0x%x, ikey:0x%x, okey:0x%x, mode:%x, next_node_if_num:%u, sibling_if_num:%u, ttl:%u, tos:%u, metadata_size:%u\n",
			dev, nss_ctx, cmsg->flags, cmsg->ikey, cmsg->okey, cmsg->mode, cmsg->next_node_if_num, cmsg->sibling_if_num, cmsg->ttl, cmsg->tos, cmsg->metadata_size);
	status = nss_gre_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		*err_code = GRE_ERR_AE_CONFIG_FAILED;
		nss_connmgr_gre_info("%px: Send Encap config to AE failed\n", next_dev_inner);
		goto unregister_nss_interface;
	}

	/*
	 * Send decap config to AE
	 */
	cmsg->flags &= ~NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE;

	/*
	 * Configure nexthop to outer node if available
	 */
	if (next_if_num_outer) {
		cmsg->next_node_if_num = next_if_num_outer;
		cmsg->flags |= NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE;
	}
	cmsg->sibling_if_num = inner_if;
	nss_gre_msg_init(&req, outer_if, NSS_GRE_MSG_DECAP_CONFIGURE, sizeof(struct nss_gre_config_msg), NULL, NULL);
	nss_connmgr_gre_info("%px: NSS_GRE_MSG_DECAP_CONFIGURE:: nss_ctx = %px, flags:0x%x, ikey:0x%x, okey:0x%x, mode:%x, next_node_if_num:%u, sibling_if_num:%u, ttl:%u, tos:%u, metadata_size:%u\n",
			dev, nss_ctx, cmsg->flags, cmsg->ikey, cmsg->okey, cmsg->mode, cmsg->next_node_if_num, cmsg->sibling_if_num, cmsg->ttl, cmsg->tos, cmsg->metadata_size);
	status = nss_gre_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		*err_code = GRE_ERR_AE_CONFIG_FAILED;
		nss_connmgr_gre_info("%px: Send decap config to AE failed\n", next_dev_outer);
		goto unregister_nss_interface;
	}

	/*
	 * Set vap next hop if next_dev is configured
	 * TODO: Do this in a more generic manner by checking the dynamic interface type of next_dev
	 */
	if (cfg->next_dev) {
		ret = nss_connmgr_gre_set_wifi_next_hop(cfg->next_dev);
		if (ret) {
			nss_connmgr_gre_info("%px: Setting next hop of wifi vdev failed\n", dev);
			*err_code = ret;
			goto unregister_nss_interface;
		}
	}

	memcpy(&ngii->gre_cfg, cfg, sizeof(*cfg));
	ngii->gre_iftype = NSS_CONNMGR_GRE_IFTYPE_CUSTOM_GRE;

	spin_lock(&gre_connmgr_ctx.lock);
	list_add(&ngii->list, &gre_connmgr_ctx.list);
	spin_unlock(&gre_connmgr_ctx.lock);

	/*
	 * Success
	 */
	*err_code = GRE_SUCCESS;
	return dev;

unregister_nss_interface:
	nss_gre_unregister_if(inner_if);
	nss_gre_unregister_if(outer_if);

	retry = 0;
dealloc_inner_node:
	status = nss_dynamic_interface_dealloc_node(inner_if, NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER);
	if (status != NSS_TX_SUCCESS) {
		if (++retry <= MAX_RETRY_COUNT) {
			goto dealloc_inner_node;
		}
		nss_connmgr_gre_error("%px: Fatal Error, Unable to dealloc the node[%d] in the NSS FW!\n", dev, inner_if);
	}

	retry = 0;
dealloc_outer_node:
	status = nss_dynamic_interface_dealloc_node(outer_if, NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER);
	if (status != NSS_TX_SUCCESS) {
		if (++retry <= MAX_RETRY_COUNT) {
			goto dealloc_outer_node;
		}
		nss_connmgr_gre_error("%px: Fatal Error, Unable to dealloc the node[%d] in the NSS FW!\n", dev, outer_if);
	}

free_gre_instance:
	nss_connmgr_gre_free_instance(ngii);

unregister_netdev:
	unregister_netdevice(dev);

release_ref:
	if (next_dev_inner) {
		dev_put(next_dev_inner);
	}

	if (next_dev_outer) {
		dev_put(next_dev_outer);
	}

	return dev;
}

/*
 * nss_connmgr_gre_destroy_inner_interface()
 *	Destroy inner GRE Tap/Tun interface.
 */
static enum nss_connmgr_gre_err_codes nss_connmgr_gre_destroy_inner_interface(struct net_device *dev, int interface_num)
{
	struct nss_gre_msg req;
	struct nss_gre_deconfig_msg *dmsg;
	nss_tx_status_t status;
	int retry = 0;

	memset(&req, 0, sizeof(struct nss_gre_msg));
	dmsg = &req.msg.dmsg;
	dmsg->if_number = interface_num;

deconfig_inner:
	nss_gre_msg_init(&req, interface_num, NSS_GRE_MSG_ENCAP_DECONFIGURE, sizeof(struct nss_gre_deconfig_msg), NULL, NULL);
	status = nss_gre_tx_msg_sync(nss_gre_get_context(), &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: gre instance deconfigure command failed, interface_num = %d\n", dev, interface_num);

		if (++retry <= MAX_RETRY_COUNT) {
			goto deconfig_inner;
		}

		nss_connmgr_gre_error("%px: Fatal Error, failed to send GRE deconfig command to NSS\n", dev);
		return GRE_ERR_AE_DECONFIG_FAILED;
	}
	retry = 0;

	nss_gre_unregister_if(interface_num);

dealloc_inner:
	status = nss_dynamic_interface_dealloc_node(interface_num, NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: gre dealloc node failure for interface_num = %d\n", dev, interface_num);

		if (++retry <= MAX_RETRY_COUNT) {
			goto dealloc_inner;
		}

		nss_connmgr_gre_error("%px: Fatal Error, failed to send GRE dealloc command to NSS\n", dev);
		return GRE_ERR_DYNMAIC_IFACE_DESTROY;
	}

	return GRE_SUCCESS;
}

/*
 * nss_connmgr_gre_destroy_outer_interface()
 *	Destroy outer GRE Tap/Tun interface.
 */
static enum nss_connmgr_gre_err_codes nss_connmgr_gre_destroy_outer_interface(struct net_device *dev, int interface_num)
{
	struct nss_gre_msg req;
	struct nss_gre_deconfig_msg *dmsg;
	nss_tx_status_t status;
	int retry = 0;

	memset(&req, 0, sizeof(struct nss_gre_msg));
	dmsg = &req.msg.dmsg;
	dmsg->if_number = interface_num;

deconfig_outer:
	nss_gre_msg_init(&req, interface_num, NSS_GRE_MSG_DECAP_DECONFIGURE, sizeof(struct nss_gre_deconfig_msg), NULL, NULL);
	status = nss_gre_tx_msg_sync(nss_gre_get_context(), &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: gre instance deconfigure command failed, interface_num = %d\n", dev, interface_num);

		if (++retry <= MAX_RETRY_COUNT) {
			goto deconfig_outer;
		}

		nss_connmgr_gre_error("%px: Fatal Error, failed to send GRE deconfig command to NSS\n", dev);
		return GRE_ERR_AE_DECONFIG_FAILED;
	}

	nss_gre_unregister_if(interface_num);
	retry = 0;

dealloc_outer:
	status = nss_dynamic_interface_dealloc_node(interface_num, NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: gre dealloc node failure for inner_if = %d\n", dev, interface_num);

		if (++retry <= MAX_RETRY_COUNT) {
			goto dealloc_outer;
		}

		nss_connmgr_gre_error("%px: Fatal Error, failed to send GRE dealloc command to NSS\n", dev);
		return GRE_ERR_DYNMAIC_IFACE_DESTROY;
	}

	return GRE_SUCCESS;
}

/*
 * __nss_connmgr_gre_destroy_interface()
 *	Destroy GRE Tap/Tun netdevice. Acquire rtnl_lock() before calling this
 *	function.
 */
static enum nss_connmgr_gre_err_codes __nss_connmgr_gre_destroy_interface(struct net_device *dev)
{
	struct nss_gre_iface_instance *ngii;
	nss_connmgr_gre_priv_t *priv;
	enum nss_connmgr_gre_err_codes ret;

	netif_tx_disable(dev);

	ngii = nss_connmgr_gre_find_instance(dev);
	if(!ngii) {
		nss_connmgr_gre_warning("%px: GRE interface instance is not found.\n", dev);
		return GRE_ERR_NO_GRE_INSTANCE;
	}

	/*
	 * Decrement ref to next_dev
	 */
	priv = (nss_connmgr_gre_priv_t *)netdev_priv(dev);
	if (priv->next_dev_inner) {
		dev_put(priv->next_dev_inner);
	}

	if (priv->next_dev_outer) {
		dev_put(priv->next_dev_outer);
	}

	ret = nss_connmgr_gre_destroy_inner_interface(dev, ngii->inner_ifnum);
	if (ret != GRE_SUCCESS) {
		nss_connmgr_gre_warning("%px: failed to destroy inner interface: %d\n", dev, ngii->inner_ifnum);
		return ret;
	}

	ret = nss_connmgr_gre_destroy_outer_interface(dev, ngii->outer_ifnum);
	if (ret != GRE_SUCCESS) {
		nss_connmgr_gre_warning("%px: failed to destroy outer interface: %d\n", dev, ngii->outer_ifnum);
		return ret;
	}

	nss_connmgr_gre_info("%px: deleted gre instance, inner_if = %d outer_if = %d\n",
			dev, ngii->inner_ifnum, ngii->outer_ifnum);

	nss_connmgr_gre_free_instance(ngii);
	unregister_netdevice(dev);
	return GRE_SUCCESS;
}

/*
 * nss_connmgr_gre_validate_config()
 *	No support for CSUM, SEQ number.
 */
static bool nss_connmgr_gre_validate_config(struct nss_connmgr_gre_cfg *cfg)
{
	/*
	 * TODO:Disallow key for standard GRE TAP/TUN.
	 */
	if (cfg->iseq_valid || cfg->oseq_valid || cfg->icsum_valid || cfg->ocsum_valid) {
		nss_connmgr_gre_info("Bad config, seq and csum are not supported.\n");
		return false;
	}

	/*
	 * Validate DSCP and ToS inherit flags.
	 */
	if (cfg->dscp_valid && cfg->tos_inherit) {
		nss_connmgr_gre_info("Bad config, Both DSCP and ToS inherit flags are set.\n");
		return false;
	}

	return true;
}

/*
 * nss_connmgr_gre_dev_up()
 *	Netdevice notifier call back to configure NSS for GRE Tap/Tun device.
 */
static int nss_connmgr_gre_dev_up(struct net_device *dev)
{
	struct nss_gre_msg req;
	struct nss_gre_config_msg *cmsg = &req.msg.cmsg;
	int inner_if, outer_if;
	uint32_t features = 0;
	struct nss_ctx_instance *nss_ctx = NULL;
	nss_tx_status_t status;
	struct net_device *next_dev = NULL;

	/*
	 * If GRE interface instance is found return, dev is Custom GRE interface type.
	 */
	if (nss_connmgr_gre_find_instance(dev)) {
		nss_connmgr_gre_info("%px: Custom GRE interface is up.\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Create config cmd for acceleration engine
	 */
	memset(&req, 0, sizeof(struct nss_gre_msg));
	if (nss_connmgr_gre_prepare_config_cmd(dev, &req, &next_dev, false)) {
		nss_connmgr_gre_info("%px: gre tunnel get config failed\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Ignore set_mac and next_dev flags for generic GRE
	 */
	cmsg->flags &= ~(NSS_GRE_CONFIG_SET_MAC | NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE);

	/*
	 * Create nss outer dynamic interface
	 */
	outer_if = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER);
	if (outer_if < 0) {
		nss_connmgr_gre_warning("%px: Request interface number failed\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Create nss inner dynamic interface
	 */
	inner_if = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER);
	if (inner_if < 0) {
		nss_connmgr_gre_warning("%px: Request interface number failed\n", dev);
		goto dealloc_outer;
	}

	/*
	 * Register gre inner/outer interface with NSS
	 */
	if ((dev->type == ARPHRD_IPGRE) || (dev->type == ARPHRD_IP6GRE)) {
		/*
		 * GRE Tunnel mode
		 */
		nss_ctx = nss_gre_register_if(inner_if,
				NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER,
				nss_connmgr_gre_tun_inner_exception,
				nss_connmgr_gre_event_receive,
				dev,
				features);

		if (!nss_ctx) {
			nss_connmgr_gre_info("%px: nss_register_gre_if failed\n", dev);
			goto dealloc_inner;
		}

		nss_ctx = nss_gre_register_if(outer_if,
				NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER,
				nss_connmgr_gre_tun_outer_exception,
				nss_connmgr_gre_event_receive,
				dev,
				features);
	} else {
		/*
		 * GRE Tap mode
		 */
		nss_ctx = nss_gre_register_if(inner_if,
				NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER,
				nss_connmgr_gre_tap_inner_exception,
				nss_connmgr_gre_event_receive,
				dev,
				features);

		if (!nss_ctx) {
			nss_connmgr_gre_info("%px: nss_register_gre_if failed\n", dev);
			goto dealloc_inner;
		}

		nss_ctx = nss_gre_register_if(outer_if,
				NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER,
				nss_connmgr_gre_tap_outer_exception,
				nss_connmgr_gre_event_receive,
				dev,
				features);
	}

	if (!nss_ctx) {
		nss_connmgr_gre_info("%px: nss_register_gre_if failed\n", dev);
		goto unregister_inner;
	}

	nss_connmgr_gre_info("%px: nss_register_gre_if() standard successful. nss_ctx = %px. inner_if: %d, outer_if: %d\n", dev, nss_ctx, inner_if, outer_if);

	/*
	 * Send configure command for inner interface
	 */
	cmsg->sibling_if_num = outer_if;
	nss_gre_msg_init(&req, inner_if, NSS_GRE_MSG_ENCAP_CONFIGURE, sizeof(struct nss_gre_config_msg), NULL, NULL);
	nss_connmgr_gre_info("%px: NSS_GRE_MSG_ENCAP_CONFIGURE:: nss_ctx = %px, flags:0x%x, ikey:0x%x, okey:0x%x, mode:%x, next_node_if_num:%u, sibling_if_num:%u, ttl:%u, tos:%u, metadata_size:%u\n",
			dev, nss_ctx, cmsg->flags, cmsg->ikey, cmsg->okey, cmsg->mode, cmsg->next_node_if_num, cmsg->sibling_if_num, cmsg->ttl, cmsg->tos, cmsg->metadata_size);
	status = nss_gre_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_warning("%px: nss gre std configure command error %d\n", dev, status);
		goto unregister_outer;
	}

	/*
	 * Send configure command for outer interface
	 */
	cmsg->sibling_if_num = inner_if;
	nss_gre_msg_init(&req, outer_if, NSS_GRE_MSG_DECAP_CONFIGURE, sizeof(struct nss_gre_config_msg), NULL, NULL);
	nss_connmgr_gre_info("%px: NSS_GRE_MSG_DECAP_CONFIGURE:: nss_ctx = %px, flags:0x%x, ikey:0x%x, okey:0x%x, mode:%x, next_node_if_num:%u, sibling_if_num:%u, ttl:%u, tos:%u, metadata_size:%u\n",
			dev, nss_ctx, cmsg->flags, cmsg->ikey, cmsg->okey, cmsg->mode, cmsg->next_node_if_num, cmsg->sibling_if_num, cmsg->ttl, cmsg->tos, cmsg->metadata_size);
	status = nss_gre_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_warning("%px: nss gre std configure command error %d\n", dev, status);
		goto unregister_outer;
	}

	/*
	 * Open the netdev to accept packets
	 */
	if (nss_connmgr_gre_dev_open(dev)) {
		nss_connmgr_gre_warning("%px: nss gre std device up command failed %d\n", dev, status);
		goto unregister_outer;
	}

	return NOTIFY_DONE;

unregister_outer:
	nss_gre_unregister_if(outer_if);

unregister_inner:
	nss_gre_unregister_if(inner_if);

dealloc_inner:
	status = nss_dynamic_interface_dealloc_node(inner_if, NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_warning("%px: Unable to dealloc the node[%d] in the NSS fw!\n", dev, inner_if);
	}

dealloc_outer:
	status = nss_dynamic_interface_dealloc_node(outer_if, NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_warning("%px: Unable to dealloc the node[%d] in the NSS fw!\n", dev, outer_if);
	}

	return NOTIFY_DONE;
}

/*
 * nss_connmgr_gre_dev_down()
 *	Netdevice notifier call back to destroy GRE interface in NSS.
 */
static int nss_connmgr_gre_dev_down(struct net_device *dev)
{
	struct nss_gre_msg req;
	struct nss_gre_deconfig_msg *dmsg;
	int inner_if, outer_if;
	nss_tx_status_t status;

	/*
	 * If GRE interface instance is found return, dev is Custom GRE interface type.
	 */
	if (nss_connmgr_gre_find_instance(dev)) {
		nss_connmgr_gre_info("%px: Custom GRE interface is down.\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Check if gre inner interface is registered with NSS
	 */
	inner_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER);
	if (inner_if < 0) {
		nss_connmgr_gre_info("%px: Net device is not registered with nss\n", dev);
		return NOTIFY_DONE;
	}

	outer_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER);
	if (outer_if < 0) {
		nss_connmgr_gre_info("%px: Net device is not registered with nss\n", dev);
		return NOTIFY_DONE;
	}

	memset(&req, 0, sizeof(struct nss_gre_msg));
	dmsg = &req.msg.dmsg;
	dmsg->if_number = inner_if;
	nss_gre_msg_init(&req, inner_if, NSS_GRE_MSG_ENCAP_DECONFIGURE, sizeof(struct nss_gre_deconfig_msg), NULL, NULL);
	status = nss_gre_tx_msg_sync(nss_gre_get_context(), &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: gre instance deconfigure command fo encap failed, inner_if = %d\n", dev, inner_if);
		return NOTIFY_DONE;
	}

	dmsg->if_number = outer_if;
	nss_gre_msg_init(&req, outer_if, NSS_GRE_MSG_DECAP_DECONFIGURE, sizeof(struct nss_gre_deconfig_msg), NULL, NULL);
	status = nss_gre_tx_msg_sync(nss_gre_get_context(), &req);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: gre instance deconfigure command for decap failed, inner_if = %d\n", dev, inner_if);
		return NOTIFY_DONE;
	}

	if (nss_connmgr_gre_dev_close(dev)) {
		nss_connmgr_gre_info("%px: gre instance device close command failed, inner_if = %d\n", dev, inner_if);
		return NOTIFY_DONE;
	}

	nss_gre_unregister_if(inner_if);
	status = nss_dynamic_interface_dealloc_node(inner_if, NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: gre dealloc node failure for inner_if = %d\n", dev, inner_if);
		return NOTIFY_DONE;
	}
	nss_connmgr_gre_info("%px: deleting gre instance, inner_if = %d\n", dev, inner_if);

	nss_gre_unregister_if(outer_if);
	status = nss_dynamic_interface_dealloc_node(outer_if, NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: gre dealloc node failure for outer_if = %d\n", dev, outer_if);
		return NOTIFY_DONE;
	}
	nss_connmgr_gre_info("%px: deleted gre instance, outer_if = %d\n", dev, outer_if);

	return NOTIFY_DONE;
}

/*
 * nss_connmgr_gre_dev_event()
 *	Netdevice notifier call back function.
 */
static int nss_connmgr_gre_dev_event(struct notifier_block  *nb,
		unsigned long event, void  *dev)
{
	struct net_device *netdev;
	netdev = netdev_notifier_info_to_dev(dev);

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

	case NETDEV_DOWN:
		return nss_connmgr_gre_dev_down(netdev);

	default:
		break;
	}

	return NOTIFY_DONE;
}

/*
 * Linux Net device Notifier
 */
static struct notifier_block nss_connmgr_gre_notifier = {
	.notifier_call = nss_connmgr_gre_dev_event,
};

/*
 * nss_connmgr_gre_dev_init_module()
 *	Tunnel gre module init function
 */
static int __init nss_connmgr_gre_dev_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
	INIT_LIST_HEAD(&gre_connmgr_ctx.list);
	spin_lock_init(&gre_connmgr_ctx.lock);
	register_netdevice_notifier(&nss_connmgr_gre_notifier);

	return 0;
}

/*
 * nss_connmgr_gre_exit_module
 *	Tunnel gre module exit function
 */
static void __exit nss_connmgr_gre_exit_module(void)
{
	struct nss_gre_iface_instance *ngii, *n;
#ifdef CONFIG_OF
	/*
	 * If the node is not compatible, don't do anything.
	 */
	if (!of_find_node_by_name(NULL, "nss-common")) {
		return;
	}
#endif
	/*
	 * Unregister GRE interfaces created and delete interface
	 * instances.
	 */
	list_for_each_entry_safe(ngii, n, &gre_connmgr_ctx.list, list) {
		rtnl_lock();
		__nss_connmgr_gre_destroy_interface(ngii->dev);
		rtnl_unlock();
	}

	unregister_netdevice_notifier(&nss_connmgr_gre_notifier);
}

/*
 * nss_connmgr_gre_set_next_hop()
 *	Function changes next hop of wifi_vdev to NSS_GRE_INTERFACE
 */
int nss_connmgr_gre_set_wifi_next_hop(struct net_device *wifi_vdev)
{
	nss_tx_status_t status;
	void *ctx;
	int ifnumber;

	if (!wifi_vdev) {
		nss_connmgr_gre_info("wifi interface is NULL\n");
		return GRE_ERR_NO_NEXT_NETDEV;
	}

	ifnumber = nss_cmn_get_interface_number_by_dev(wifi_vdev);
	if (ifnumber < 0) {
		nss_connmgr_gre_info("%px: wifi interface is not recognized by NSS\n", wifi_vdev);
		return GRE_ERR_NEXT_NODE_UNREG_IN_AE;
	}

	ctx = nss_wifi_get_context();
	status = nss_wifi_vdev_set_next_hop(ctx, ifnumber, NSS_GRE_INTERFACE);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_gre_info("%px: wifi drv api failed to set next hop\n", wifi_vdev);
		return GRE_ERR_AE_SET_NEXT_HOP;
	}

	return GRE_SUCCESS;
}

/*
 * nss_connmgr_gre_get_hlen()
 *	Calculates GRE header length
 */
uint32_t nss_connmgr_gre_get_hlen(struct nss_connmgr_gre_cfg *cfg)
{
	uint32_t size = 4;	/* minimum size of GRE packet */

	if (cfg->okey_valid) {
		size += 4;
	}

	if (cfg->oseq_valid) {
		size += 4;
	}

	if (cfg->ocsum_valid) {
		size += 4;
	}

	return size;
}

/*
 * nss_connmgr_gre_set_gre_flags()
 *	Map User configured flags to tunnel specific flag.
 */
void nss_connmgr_gre_set_gre_flags(struct nss_connmgr_gre_cfg *cfg,
					   uint16_t *o_flags, uint16_t *i_flags)

{
	if (cfg->ikey_valid) {
		*i_flags |= TUNNEL_KEY;
	}

	if (cfg->okey_valid) {
		*o_flags |= TUNNEL_KEY;
	}

	if (cfg->iseq_valid) {
		*i_flags |= TUNNEL_SEQ;
	}

	if (cfg->oseq_valid) {
		*o_flags |= TUNNEL_SEQ;
	}

	if (cfg->icsum_valid) {
		*i_flags |= TUNNEL_CSUM;
	}

	if (cfg->ocsum_valid) {
		*o_flags |= TUNNEL_CSUM;
	}
}

/*
 * nss_connmgr_gre_get_nss_config_flags()
 *	Map tunnel specific flags to NSS flags.
 */
uint32_t nss_connmgr_gre_get_nss_config_flags(uint16_t o_flags, uint16_t i_flags,
						  uint8_t tos, uint8_t ttl,
						  uint16_t frag_off)
{
	uint32_t gre_flags = 0;

	if (i_flags & TUNNEL_KEY) {
		gre_flags |= NSS_GRE_CONFIG_IKEY_VALID;
	}

	if (o_flags & TUNNEL_KEY) {
		gre_flags |= NSS_GRE_CONFIG_OKEY_VALID;
	}

	if (i_flags & TUNNEL_SEQ) {
		gre_flags |= NSS_GRE_CONFIG_ISEQ_VALID;
	}

	if (o_flags & TUNNEL_SEQ) {
		gre_flags |= NSS_GRE_CONFIG_OSEQ_VALID;
	}

	if (i_flags & TUNNEL_CSUM) {
		gre_flags |= NSS_GRE_CONFIG_ICSUM_VALID;
	}

	if (o_flags & TUNNEL_CSUM) {
		gre_flags |= NSS_GRE_CONFIG_OCSUM_VALID;
	}

	if (tos & 0x1) {
		gre_flags |= NSS_GRE_CONFIG_TOS_INHERIT;
	}

	if (!ttl) {
		gre_flags |= NSS_GRE_CONFIG_TTL_INHERIT;
	}

	if (frag_off == htons(IP_DF)) {
		gre_flags |= NSS_GRE_CONFIG_SET_DF;
	}

	return gre_flags;
}

 /*
  * nss_connmgr_gre_destroy_interface()
  *	User API to delete interface
  */
enum nss_connmgr_gre_err_codes nss_connmgr_gre_destroy_interface(struct net_device *dev)
{
	enum nss_connmgr_gre_err_codes ret;

	if (!dev) {
		nss_connmgr_gre_info("Please specifiy valid interface to be deleted\n");
		return GRE_ERR_NO_NETDEV;
	}

	if (in_interrupt()) {
		nss_connmgr_gre_info("%px: nss_connmgr_gre_destroy_interface() called in interrupt context\n", dev);
		return GRE_ERR_IN_INTERRUPT_CTX;
	}

	rtnl_lock();
	ret = __nss_connmgr_gre_destroy_interface(dev);
	rtnl_unlock();

	/*
	 * free_netdev() should be called outside of rtnl lock
	 */
	if (!ret) {
		free_netdev(dev);
	}

	return ret;
}
EXPORT_SYMBOL(nss_connmgr_gre_destroy_interface);

/*
 * nss_connmgr_gre_create_interface()
 *	User API to create gre standard interface
 */
struct net_device *nss_connmgr_gre_create_interface(struct nss_connmgr_gre_cfg *cfg,
						    enum nss_connmgr_gre_err_codes *err_code)
{
	struct net_device *dev;

	if ((!cfg) || (!err_code)) {
		nss_connmgr_gre_info("parameter to this function should not be NULL\n");
		return NULL;
	}

	if (in_interrupt()) {
		nss_connmgr_gre_info("nss_connmgr_gre_create_interface() called in interrupt context\n");
		*err_code = GRE_ERR_IN_INTERRUPT_CTX;
		return NULL;
	}

	if (!nss_connmgr_gre_validate_config(cfg)) {
		*err_code = GRE_ERR_UNSUPPORTED_CFG;
		return NULL;
	}

	rtnl_lock();
	dev = __nss_connmgr_gre_create_interface(cfg, err_code);
	rtnl_unlock();

	if (*err_code == GRE_SUCCESS) {
		return dev;
	}

	if (dev) {
		free_netdev(dev);
	}

	return NULL;
}
EXPORT_SYMBOL(nss_connmgr_gre_create_interface);

module_init(nss_connmgr_gre_dev_init_module);
module_exit(nss_connmgr_gre_exit_module);

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