/*
 **************************************************************************
 * Copyright (c) 2016, 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_connmgr_dtls_netdev.c
 *	NSS DTLS Manager netdev module
 */

#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <net/ipv6.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/udp.h>
#include <linux/ipv6.h>

#include <nss_api_if.h>
#include <nss_dynamic_interface.h>

#include "nss_connmgr_dtls.h"

/*
 * Maximum tailroom required by crypto
 */
#define NSS_DTLSMGR_TROOM (128 + (2 * NSS_CRYPTO_MAX_HASHLEN_SHA256))

/*
 * Maximum headroom for encapsulating headers
 */
#define NSS_DTLSMGR_MAX_HDR_LEN ((NSS_DTLSMGR_HDR_LEN + 3)	\
				 + NSS_DTLSMGR_CAPWAPHDR_LEN	\
				 + (2 * NSS_CRYPTO_MAX_IVLEN_AES)	\
				 + sizeof(struct ipv6hdr)	\
				 + sizeof(struct udphdr))

/*
 * nss_dtlsmgr_session_xmit()
 */
static netdev_tx_t nss_dtlsmgr_session_xmit(struct sk_buff *skb,
					    struct net_device *dev)
{
	struct nss_dtlsmgr_netdev_priv *priv;
	struct nss_dtlsmgr_session *s;
	int32_t  nhead, ntail;

	priv = netdev_priv(dev);
	s = priv->s;

	switch (skb->protocol) {
	case htons(ETH_P_IP):
		if (s->flags & NSS_DTLSMGR_HDR_IPV6) {
			nss_dtlsmgr_info("%px: NSS DTLS I/F %d: skb(%px) invalid L3 protocol 0x%x\n", dev, s->nss_dtls_if, skb, ETH_P_IP);
			return NETDEV_TX_BUSY;
		}
		break;

	case htons(ETH_P_IPV6):
		if (!(s->flags & NSS_DTLSMGR_HDR_IPV6)) {
			nss_dtlsmgr_info("%px: NSS DTLS I/F %d: skb(%px) invalid L3 protocol 0x%x\n", dev, s->nss_dtls_if, skb, ETH_P_IPV6);
			return NETDEV_TX_BUSY;
		}
		break;

	default:
		nss_dtlsmgr_info("%px: NSS DTLS I/F %d: skb(%px) unsupported IP protocol 0x%x\n", dev, s->nss_dtls_if, skb, ntohs(skb->protocol));
		return NETDEV_TX_BUSY;
	}

	nhead = dev->needed_headroom;
	ntail = dev->needed_tailroom;

	if (skb_is_nonlinear(skb)) {
		nss_dtlsmgr_info("%px: NSS DTLS does not support non-linear skb %px\n", dev, skb);
		return NETDEV_TX_BUSY;
	}

	if (unlikely(skb_shared(skb))) {
		nss_dtlsmgr_info("%px: Shared skb:%px is not supported\n",
				 dev, skb);
		return NETDEV_TX_BUSY;
	}

	if (skb_cloned(skb) || (skb_headroom(skb) < nhead)
	    || (skb_tailroom(skb) < ntail)) {
		if (pskb_expand_head(skb, nhead, ntail, GFP_KERNEL)) {
			nss_dtlsmgr_info("%px: skb:%px unable to expand buffer\n",
					 dev, skb);
			return NETDEV_TX_BUSY;
		}
	}

	if (skb->data != skb_network_header(skb)) {
		skb_pull(skb, skb_network_offset(skb));
	}

	if (nss_dtls_tx_buf(skb, s->nss_dtls_if, s->nss_ctx) != NSS_TX_SUCCESS) {
		return NETDEV_TX_BUSY;
	}

	return NETDEV_TX_OK;
}

/*
 * nss_dtlsmgr_session_stop()
 */
static int nss_dtlsmgr_session_stop(struct net_device *dev)
{
	netif_stop_queue(dev);
	return 0;
}

/*
 * nss_dtlsmgr_session_open()
 */
static int nss_dtlsmgr_session_open(struct net_device *dev)
{
	netif_start_queue(dev);
	return 0;
}

/*
 * DTLS netdev ops
 */
static const struct net_device_ops nss_dtlsmgr_session_ops = {
	.ndo_start_xmit = nss_dtlsmgr_session_xmit,
	.ndo_open = nss_dtlsmgr_session_open,
	.ndo_stop = nss_dtlsmgr_session_stop,
	.ndo_set_mac_address = eth_mac_addr,
};

/*
 * nss_dtlsmgr_dev_setup()
 */
static void nss_dtlsmgr_dev_setup(struct net_device *dev)
{
	dev->addr_len = ETH_ALEN;
	dev->mtu = ETH_DATA_LEN;
	dev->hard_header_len = NSS_DTLSMGR_MAX_HDR_LEN;
	dev->needed_headroom = 0;
	dev->needed_tailroom = NSS_DTLSMGR_TROOM;

	dev->type = ARPHRD_ETHER;
	dev->ethtool_ops = NULL;
	dev->header_ops = NULL;
	dev->netdev_ops = &nss_dtlsmgr_session_ops;
	dev->destructor = NULL;

	memcpy(dev->dev_addr, "\xaa\xbb\xcc\xdd\xee\xff", dev->addr_len);
	memset(dev->broadcast, 0xff, dev->addr_len);
	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
}

/*
 * nss_dtlsmgr_netdev_create()
 */
nss_dtlsmgr_status_t nss_dtlsmgr_netdev_create(struct nss_dtlsmgr_session *ds)
{
	struct net_device *dev;
	struct nss_dtlsmgr_netdev_priv *priv;
	int32_t err = 0;

#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 16, 0))
	dev = alloc_netdev(sizeof(struct nss_dtlsmgr_netdev_priv),
			   "qca-nss-dtls%d", nss_dtlsmgr_dev_setup);
#else
	dev = alloc_netdev(sizeof(struct nss_dtlsmgr_netdev_priv),
			   "qca-nss-dtls%d", NET_NAME_UNKNOWN,
			   nss_dtlsmgr_dev_setup);
#endif

	if (!dev) {
		nss_dtlsmgr_info("DTLS netdev alloc failed\n");
		return NSS_DTLSMGR_FAIL;
	}

	priv = netdev_priv(dev);
	priv->s = ds;

	err = rtnl_is_locked() ? register_netdevice(dev) : register_netdev(dev);
	if (err < 0) {
		nss_dtlsmgr_info("DTLS netdev register failed\n");
		free_netdev(dev);
		return NSS_DTLSMGR_FAIL;
	}

	ds->netdev = dev;
	return NSS_DTLSMGR_OK;
}

/*
 * nss_dtlsmgr_netdev_destroy()
 */
nss_dtlsmgr_status_t nss_dtlsmgr_netdev_destroy(struct nss_dtlsmgr_session *ds)
{
	if (!ds || !ds->netdev) {
		return NSS_DTLSMGR_FAIL;
	}

	rtnl_is_locked() ? unregister_netdevice(ds->netdev)
			 : unregister_netdev(ds->netdev);

	free_netdev(ds->netdev);
	ds->netdev = NULL;
	return NSS_DTLSMGR_OK;
}
