/*
 **************************************************************************
 * 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_dtlsmgr_ctx.c
 *	NSS DTLS Manager Context
 */

#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/crypto.h>
#include <linux/debugfs.h>
#include <linux/rtnetlink.h>
#include <net/ipv6.h>
#include <net/vxlan.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/atomic.h>
#include <asm/cmpxchg.h>

#include <crypto/algapi.h>
#include <crypto/aead.h>
#include <crypto/aes.h>
#include <crypto/authenc.h>
#include <crypto/des.h>
#include <crypto/sha.h>
#include <crypto/skcipher.h>
#include <crypto/hash.h>

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

#include <nss_cryptoapi.h>
#include <nss_dtls_cmn.h>
#include <nss_dtlsmgr.h>

#include "nss_dtlsmgr_private.h"

#define NSS_DTLSMGR_KEY_PARAM_SIZE RTA_SPACE(sizeof(struct crypto_authenc_key_param))

extern struct nss_dtlsmgr g_dtls;

static struct nss_dtlsmgr_algo_info dtlsmgr_algo_info[NSS_DTLSMGR_ALGO_MAX] = {
	{"echainiv(authenc(hmac(sha1),cbc(aes)))", NSS_DTLSMGR_KEY_PARAM_SIZE},
	{"echainiv(authenc(hmac(sha256),cbc(aes)))", NSS_DTLSMGR_KEY_PARAM_SIZE},
	{"echainiv(authenc(hmac(sha1),cbc(des3_ede)))", NSS_DTLSMGR_KEY_PARAM_SIZE},
	{"echainiv(authenc(hmac(sha256),cbc(des3_ede)))", NSS_DTLSMGR_KEY_PARAM_SIZE},
	{"rfc4106(gcm(aes))", 0}
};

/*
 * nss_dtlsmgr_ctx_alloc_crypto()
 *	Allocate a crypto session through Linux CryptoAPI framework.
 */
static int nss_dtlsmgr_ctx_alloc_crypto(struct nss_dtlsmgr_ctx *ctx, struct nss_dtlsmgr_dtls_data *dtls,
					struct nss_dtlsmgr_crypto *crypto)
{
	struct crypto_authenc_key_param *key_param;
	struct nss_dtlsmgr_algo_info *info;
	struct rtattr *rta;
	char *keys, *p;
	uint16_t keylen;

	if (crypto->algo >= ARRAY_SIZE(dtlsmgr_algo_info)) {
		nss_dtlsmgr_warn("%px: invalid crypto algorithm", ctx);
		return -EINVAL;
	}

	info = &dtlsmgr_algo_info[crypto->algo];
	dtls->aead = crypto_alloc_aead(info->name, 0, 0);
	if (IS_ERR(dtls->aead)) {
		nss_dtlsmgr_warn("%px: failed to allocate crypto aead context", ctx);
		return -ENOMEM;
	}

	nss_dtlsmgr_trace("cipher_keylen:%d auth_keylen:%d nonce_len:%d\n",
			  crypto->cipher_key.len, crypto->auth_key.len, crypto->nonce.len);

	/*
	 * Construct keys
	 */
	keylen = info->rta_key_size;
	keylen += crypto->cipher_key.len;
	keylen += crypto->auth_key.len;
	keylen += crypto->nonce.len;

	keys = vzalloc(keylen);
	if (!keys) {
		nss_dtlsmgr_warn("%px: failed to allocate key memory", ctx);
		crypto_free_aead(dtls->aead);
		return -ENOMEM;
	}

	if (crypto->algo == NSS_DTLSMGR_ALGO_AES_GCM) {
		memcpy(keys, crypto->cipher_key.data, crypto->cipher_key.len);
		/* Copy nonce after the key */
		memcpy(keys + crypto->cipher_key.len, crypto->nonce.data, crypto->nonce.len);
		goto setkey;
	}

	p = keys;
	rta = (void *)p;
	rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM;
	rta->rta_len = RTA_LENGTH(sizeof(*key_param));
	key_param = RTA_DATA(rta);
	p += RTA_SPACE(sizeof(*key_param));

	/*
	 * Copy authentication key
	 */
	memcpy(p, crypto->auth_key.data, crypto->auth_key.len);
	p += crypto->auth_key.len;

	/*
	 * Copy cipher Key
	 */
	key_param->enckeylen = cpu_to_be32(crypto->cipher_key.len);
	memcpy(p, crypto->cipher_key.data, crypto->cipher_key.len);

setkey:

	if (crypto_aead_setkey(dtls->aead, keys, keylen)) {
		nss_dtlsmgr_warn("%px: failed to configure keys", ctx);
		vfree(keys);
		crypto_free_aead(dtls->aead);
		return -ENOSPC;
	}

	nss_cryptoapi_aead_ctx2session(dtls->aead, &dtls->crypto_idx);
	dtls->blk_len = (uint8_t)crypto_aead_blocksize(dtls->aead);
	dtls->hash_len = (uint8_t)crypto_aead_authsize(dtls->aead);
	dtls->iv_len = (uint8_t)crypto_aead_ivsize(dtls->aead);

	vfree(keys);
	return 0;
}

/*
 * nss_dtlsmgr_ctx_alloc_dtls()
 *	Allocate a DTLS session.
 */
static struct nss_dtlsmgr_dtls_data *nss_dtlsmgr_ctx_alloc_dtls(struct nss_dtlsmgr_ctx *ctx,
								struct nss_dtlsmgr_ctx_data *data,
								struct nss_dtlsmgr_crypto *crypto)
{
	struct nss_dtlsmgr_dtls_data *dtls;
	int error;

	nss_dtlsmgr_trace("%px: allocating context data(%u)", ctx, data->di_type);

	dtls = vzalloc(sizeof(*dtls));
	if (!dtls) {
		nss_dtlsmgr_warn("%px: failed to allocate dtls data(%u) ", ctx, data->di_type);
		return NULL;
	}

	INIT_LIST_HEAD(&dtls->list);

	error = nss_dtlsmgr_ctx_alloc_crypto(ctx, dtls, crypto);
	if (error < 0) {
		nss_dtlsmgr_warn("%px: unable to allocate crypto(%u) - error(%d)", ctx, data->di_type, error);
		vfree(dtls);
		return NULL;
	}

	nss_dtlsmgr_trace("%px: crypto_aead allocated", ctx);
	return dtls;
}

/*
 * nss_dtlsmgr_ctx_free_dtls()
 *	Free the DTLS context.
 */
static void nss_dtlsmgr_ctx_free_dtls(struct nss_dtlsmgr_dtls_data *dtls)
{
	crypto_free_aead(dtls->aead);
	vfree(dtls);
}

/*
 * nss_dtlsmgr_ctx_configure_hdr()
 *	Configure the DTLS header related information.
 */
static bool nss_dtlsmgr_ctx_configure_hdr(struct nss_dtlsmgr_ctx_data *data)
{
	const uint32_t type = NSS_DTLS_CMN_MSG_TYPE_CONFIGURE_HDR;
	enum nss_dtls_cmn_error resp = NSS_DTLS_CMN_ERROR_NONE;
	struct nss_dtls_cmn_ctx_config_hdr *cfg;
	struct nss_dtls_cmn_msg ndcm = { {0} };
	nss_tx_status_t status;
	uint32_t mask = 0;

	BUG_ON(in_atomic());

	mask |= NSS_DTLS_CMN_CTX_HDR_IPV6;
	mask |= NSS_DTLS_CMN_CTX_HDR_UDPLITE;
	mask |= NSS_DTLS_CMN_CTX_HDR_CAPWAP;
	mask |= NSS_DTLS_CMN_CTX_CIPHER_MODE_GCM;
	mask |= NSS_DTLS_CMN_CTX_ENCAP_UDPLITE_CSUM;
	mask |= NSS_DTLS_CMN_CTX_ENCAP_METADATA;
	mask |= NSS_DTLS_CMN_CTX_DECAP_ACCEPT_ALL;

	cfg = &ndcm.msg.hdr_cfg;
	cfg->flags = data->flags & mask;
	cfg->dest_ifnum = data->dest_ifnum;
	cfg->src_ifnum = data->src_ifnum;

	memcpy(cfg->sip, data->flow.sip, sizeof(cfg->sip));
	memcpy(cfg->dip, data->flow.dip, sizeof(cfg->dip));

	cfg->sport = data->flow.sport;
	cfg->dport = data->flow.dport;
	cfg->hop_limit_ttl = data->flow.hop_limit_ttl;
	cfg->dscp = data->flow.dscp;
	cfg->dscp_copy = data->flow.dscp_copy;
	cfg->df = data->flow.df;

	nss_dtlsmgr_trace("flags:0x%x dest_ifnum:0x%x src_ifnum:0x%x sport:0x%x dport:0x%x sip:0x%x dip:0x%x",
			  cfg->flags, cfg->dest_ifnum, cfg->src_ifnum, cfg->sport, cfg->dport,
			  cfg->sip[0], cfg->dip[0]);

	status = nss_dtls_cmn_tx_msg_sync(data->nss_ctx, data->ifnum, type, sizeof(*cfg), &ndcm, &resp);
	if (status != NSS_TX_SUCCESS) {
		nss_dtlsmgr_warn("%px: msg_sync failed, if_num(%u), status(%d), type(%d), resp(%d)",
				 data, data->ifnum, type, status, resp);
		return false;
	}

	return true;
}

/*
 * nss_dtlsmgr_ctx_configure_dtls()
 *	Configure the DTLS version, crypto related data, window size and epoch.
 */
static bool nss_dtlsmgr_ctx_configure_dtls(struct nss_dtlsmgr_ctx_data *data, struct nss_dtlsmgr_dtls_data *dtls)
{
	const uint32_t type = NSS_DTLS_CMN_MSG_TYPE_CONFIGURE_DTLS;
	enum nss_dtls_cmn_error resp = NSS_DTLS_CMN_ERROR_NONE;
	struct nss_dtls_cmn_ctx_config_dtls *cfg;
	struct nss_dtls_cmn_msg ndcm = {0};
	nss_tx_status_t status;

	BUG_ON(in_atomic());

	cfg = &ndcm.msg.dtls_cfg;
	cfg->ver = dtls->ver;
	cfg->crypto_idx = dtls->crypto_idx;
	cfg->epoch = dtls->epoch;
	cfg->window_size = dtls->window_size;
	cfg->iv_len = dtls->iv_len;
	cfg->hash_len = dtls->hash_len;
	cfg->blk_len = dtls->blk_len;

	status = nss_dtls_cmn_tx_msg_sync(data->nss_ctx, data->ifnum, type, sizeof(*cfg), &ndcm, &resp);
	if (status != NSS_TX_SUCCESS) {
		nss_dtlsmgr_warn("%px: msg_sync failed, if_num(%u), status(%d), type(%d), resp(%d)",
				data, data->ifnum, type, status, resp);
		return false;
	}

	return true;
}

/*
 * nss_dtlsmgr_ctx_deconfigure()
 *	Deconfigure the DTLS context and free all the related data.
 */
static bool nss_dtlsmgr_ctx_deconfigure(struct nss_dtlsmgr_ctx *ctx, struct nss_dtlsmgr_ctx_data *data)
{
	const uint32_t type = NSS_DTLS_CMN_MSG_TYPE_DECONFIGURE;
	enum nss_dtls_cmn_error resp = NSS_DTLS_CMN_ERROR_NONE;
	struct nss_dtls_cmn_msg ndcm = {0};
	struct nss_dtlsmgr_dtls_data *cur;
	nss_tx_status_t status;

	status = nss_dtls_cmn_tx_msg_sync(data->nss_ctx, data->ifnum, type, 0, &ndcm, &resp);
	if (status != NSS_TX_SUCCESS) {
		nss_dtlsmgr_warn("%px: msg_sync failed, if_num(%u), status(%d), type(%d), resp(%d)",
				ctx, data->ifnum, type, status, resp);
		return false;
	}

	nss_dtls_cmn_unregister_if(data->ifnum);

	for (;;) {
		write_lock(&ctx->lock);
		cur = list_first_entry_or_null(&data->dtls_active, struct nss_dtlsmgr_dtls_data, list);
		if (!cur) {
			write_unlock(&ctx->lock);
			break;
		}

		list_del(&cur->list);
		write_unlock(&ctx->lock);
		nss_dtlsmgr_ctx_free_dtls(cur);
	}

	status = nss_dynamic_interface_dealloc_node(data->ifnum, data->di_type);
	if (status != NSS_TX_SUCCESS) {
		nss_dtlsmgr_warn("%px: fail to deallocate dynamic(%d) interface(%u)", ctx, data->di_type, data->ifnum);
		return false;
	}

	data->ifnum = -1;
	return true;
}

/*
 * nss_dtlsmgr_ctx_create_encap()
 *	Create DTLS encapsulation dynamic interface and configure the DTLS context.
 */
static int nss_dtlsmgr_ctx_create_encap(struct nss_dtlsmgr_ctx *ctx, uint32_t ifnum,
					uint32_t src_ifnum, struct nss_dtlsmgr_config *ndc)
{
	struct nss_dtlsmgr_encap_config *cfg = &ndc->encap;
	struct nss_dtlsmgr_ctx_data *data = &ctx->encap;
	struct nss_dtlsmgr_flow_data *flow = &data->flow;
	struct nss_dtlsmgr_dtls_data *dtls;

	dtls = nss_dtlsmgr_ctx_alloc_dtls(ctx, &ctx->encap, &cfg->crypto);
	if (!dtls) {
		nss_dtlsmgr_warn("%px: unable to allocate encap context data", ctx);
		return -ENOMEM;
	}

	INIT_LIST_HEAD(&data->dtls_active);

	data->di_type = NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER;
	data->ifnum = ifnum;
	data->src_ifnum = src_ifnum;
	data->flags = ndc->flags & (NSS_DTLSMGR_HDR_MASK | NSS_DTLSMGR_CRYPTO_MASK | NSS_DTLSMGR_ENCAP_MASK);
	data->tailroom = dtls->blk_len + dtls->hash_len;
	data->headroom = dtls->iv_len;

	memcpy(&flow->sip, cfg->sip, sizeof(flow->sip));
	memcpy(&flow->dip, cfg->dip, sizeof(flow->dip));

	flow->sport = cfg->sport;
	flow->dport = cfg->dport;
	flow->dscp = cfg->dscp;
	flow->dscp_copy = cfg->dscp_copy;
	flow->df = cfg->df;
	flow->hop_limit_ttl = cfg->ip_ttl;

	dtls->epoch = cfg->epoch;
	dtls->ver = cfg->ver;

	data->headroom += NSS_DTLSMGR_DTLS_HDR_SZ;

	/*
	 * We need to provide the firmware the source and
	 * destination interface number. This allows it
	 * to work with dynamically created interfaces
	 *
	 */
	switch (data->flags & (NSS_DTLSMGR_HDR_IPV6 | NSS_DTLSMGR_HDR_CAPWAP)) {
	case NSS_DTLSMGR_HDR_IPV6 | NSS_DTLSMGR_HDR_CAPWAP:
		data->dest_ifnum = NSS_IPV6_RX_INTERFACE;
		data->headroom += sizeof(struct ipv6hdr);
		data->headroom += NSS_DTLSMGR_CAPWAP_DTLS_HDR_SZ;
		data->headroom += NSS_DTLSMGR_SGT_HDR_SZ;
		break;
	case NSS_DTLSMGR_HDR_IPV6:
		data->dest_ifnum = NSS_IPV6_RX_INTERFACE;
		data->headroom += sizeof(struct ipv6hdr);
		break;
	case NSS_DTLSMGR_HDR_CAPWAP:
		data->dest_ifnum = NSS_IPV4_RX_INTERFACE;
		data->headroom += sizeof(struct iphdr);
		data->headroom += NSS_DTLSMGR_CAPWAP_DTLS_HDR_SZ;
		data->headroom += NSS_DTLSMGR_SGT_HDR_SZ;
		break;
	default:
		data->dest_ifnum = NSS_IPV4_RX_INTERFACE;
		data->headroom += sizeof(struct iphdr);
		break;
	}

	/*
	 * Header size is same for UDP and UDPLite
	 */
	data->headroom += sizeof(struct ethhdr) + sizeof(struct vlan_hdr) + sizeof(struct udphdr);

	nss_dtlsmgr_trace("%px: encap ifnum(%u), src(%u), dest(0x%x)", ctx, data->ifnum,
			  data->src_ifnum, data->dest_ifnum);

	/*
	 * Register NSS DTLS Encap I/F
	 */
	data->nss_ctx = nss_dtls_cmn_register_if(data->ifnum,
						nss_dtlsmgr_ctx_dev_rx_inner,
						nss_dtlsmgr_ctx_dev_event_inner,
						ctx->dev,
						0,
						data->di_type,
						(void *)data);
	if (!data->nss_ctx) {
		nss_dtlsmgr_warn("%px: NSS register interface(%u) failed", ctx, data->ifnum);
		nss_dtlsmgr_ctx_free_dtls(dtls);
		return -ENODEV;
	}

	if (!nss_dtlsmgr_ctx_configure_hdr(data)) {
		nss_dtlsmgr_warn("%px: unable to configure(%d) hdr", ctx, data->di_type);
		goto fail;
	}

	if (!nss_dtlsmgr_ctx_configure_dtls(data, dtls)) {
		nss_dtlsmgr_warn("%px: unable to configure(%d) dtls", ctx, data->di_type);
		goto fail;
	}

	write_lock(&ctx->lock);
	list_add(&dtls->list, &data->dtls_active);
	write_unlock(&ctx->lock);

	return 0;
fail:
	nss_dtls_cmn_unregister_if(data->ifnum);
	nss_dtlsmgr_ctx_free_dtls(dtls);
	return -EBUSY;
}

/*
 * nss_dtlsmgr_ctx_create_decap()
 *	Create DTLS decapsulation dynamic interface and configure the DTLS context.
 */
static int nss_dtlsmgr_ctx_create_decap(struct nss_dtlsmgr_ctx *ctx, uint32_t ifnum, uint32_t src_ifnum,
					struct nss_dtlsmgr_config *cfg)
{
	struct nss_dtlsmgr_ctx_data *data = &ctx->decap;
	struct nss_dtlsmgr_dtls_data *dtls;

	dtls = nss_dtlsmgr_ctx_alloc_dtls(ctx, &ctx->decap, &cfg->decap.crypto);
	if (!dtls) {
		nss_dtlsmgr_warn("%px: unable to allocate decap context data", ctx);
		return -ENOMEM;
	}

	INIT_LIST_HEAD(&data->dtls_active);

	data->di_type = NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER;
	data->ifnum = ifnum;

	/*
	 * We need to provide the firmware the source and
	 * destination interface number. This allows it
	 * to work with dynamically created interfaces
	 *
	 */
	data->src_ifnum = src_ifnum;
	data->dest_ifnum = cfg->decap.nexthop_ifnum;
	data->tailroom = data->headroom = 0;
	data->flags = cfg->flags & (NSS_DTLSMGR_HDR_MASK | NSS_DTLSMGR_CRYPTO_MASK | NSS_DTLSMGR_DECAP_MASK);

	nss_dtlsmgr_trace("%px: decap ifnum(%u), src(%u), dest(%u)", ctx, data->ifnum,
			  data->src_ifnum, data->dest_ifnum);

	dtls->window_size = cfg->decap.window_size;
	dtls->ver = cfg->encap.ver;

	/*
	 * Register NSS DTLS Decap I/F
	 */
	data->nss_ctx = nss_dtls_cmn_register_if(data->ifnum,
						nss_dtlsmgr_ctx_dev_rx_outer,
						nss_dtlsmgr_ctx_dev_event_outer,
						ctx->dev,
						0,
						data->di_type,
						(void *)data);
	if (!data->nss_ctx) {
		nss_dtlsmgr_warn("%px: NSS register interface(%u) failed", ctx, data->ifnum);
		nss_dtlsmgr_ctx_free_dtls(dtls);
		return -ENODEV;
	}

	if (!nss_dtlsmgr_ctx_configure_hdr(data)) {
		nss_dtlsmgr_warn("%px: unable to configure(%d) hdr", ctx, data->di_type);
		goto fail;
	}

	if (!nss_dtlsmgr_ctx_configure_dtls(data, dtls)) {
		nss_dtlsmgr_warn("%px: unable to configure(%d) hdr", ctx, data->di_type);
		goto fail;
	}

	write_lock(&ctx->lock);
	list_add(&dtls->list, &data->dtls_active);
	write_unlock(&ctx->lock);

	return 0;
fail:
	nss_dtls_cmn_unregister_if(data->ifnum);
	nss_dtlsmgr_ctx_free_dtls(dtls);
	return -EBUSY;
}

/*
 * nss_dtlsmgr_session_switch()
 *	Send a switch message to firmware to use new cipher spec
 *
 * Note: This deletes the older cipher spec and pops the next cipher spec
 * for use.
 */
static bool nss_dtlsmgr_session_switch(struct nss_dtlsmgr_ctx *ctx, struct nss_dtlsmgr_ctx_data *data)
{
	const uint32_t type = NSS_DTLS_CMN_MSG_TYPE_SWITCH_DTLS;
	enum nss_dtls_cmn_error resp = NSS_DTLS_CMN_ERROR_NONE;
	struct nss_dtls_cmn_msg ndcm = {0};
	struct nss_dtlsmgr_dtls_data *dtls;
	nss_tx_status_t status;

	BUG_ON(in_atomic());

	/*
	 * TODO: Add retry messaging to ensure that in case of failures, due to queue
	 * full conditions we do attempt few retries before aborting.
	 */
	status = nss_dtls_cmn_tx_msg_sync(data->nss_ctx, data->ifnum, type, 0, &ndcm, &resp);
	if (status != NSS_TX_SUCCESS) {
		nss_dtlsmgr_warn("%px: msg_sync failed, if_num(%u), status(%d), type(%d), resp(%d)",
				ctx, data->ifnum, type, status, resp);
		return false;
	}

	/*
	 * We essentially pop the head of the dtls list.
	 * It is expected that an update should have already
	 * added a new dtls entry at the tail of the list
	 */
	write_lock(&ctx->lock);
	dtls = list_first_entry_or_null(&data->dtls_active, struct nss_dtlsmgr_dtls_data, list);
	if (!dtls) {
		write_unlock(&ctx->lock);
		return false;
	}

	list_del(&dtls->list);
	write_unlock(&ctx->lock);

	nss_dtlsmgr_ctx_free_dtls(dtls);
	return true;
}

/*
 * nss_dtlsmgr_session_create()
 *	Create DTLS session and associated crypto sessions.
 */
struct net_device *nss_dtlsmgr_session_create(struct nss_dtlsmgr_config *cfg)
{
	struct nss_dtlsmgr *drv = &g_dtls;
	struct nss_dtlsmgr_ctx *ctx = NULL;
	struct net_device *dev;
	int32_t encap_ifnum;
	int32_t decap_ifnum;
	int error;

	if (!atomic_read(&drv->is_configured)) {
		nss_dtlsmgr_warn("%px: dtls firmware not ready", drv);
		return NULL;
	}

	if ((cfg->encap.ver != NSS_DTLSMGR_VERSION_1_0) && (cfg->encap.ver != NSS_DTLSMGR_VERSION_1_2)) {
		nss_dtlsmgr_warn("%px: invalid encapsulation version(%d)", drv, cfg->encap.ver);
		return NULL;
	}

	encap_ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER);
	if (encap_ifnum < 0) {
		nss_dtlsmgr_warn("%px: failed to allocate encap dynamic interface(%u)", drv, encap_ifnum);
		return NULL;
	}

	decap_ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER);
	if (decap_ifnum < 0) {
		nss_dtlsmgr_warn("%px: failed to allocate decap dynamic interface(%u)", drv, decap_ifnum);
		goto dealloc_encap_node;
	}

	nss_dtlsmgr_trace("dynamic interfaces, encap(%u), decap(%u)", encap_ifnum, decap_ifnum);

	dev = alloc_netdev(sizeof(*ctx), "dtls%d", NET_NAME_ENUM, nss_dtlsmgr_ctx_dev_setup);
	if (!dev) {
		nss_dtlsmgr_warn("%px: unable to allocate dtls device", ctx);
		goto dealloc_decap_node;
	}

	ctx = netdev_priv(dev);
	ctx->dev = dev;
	rwlock_init(&ctx->lock);

	NSS_DTLSMGR_SET_MAGIC(ctx, NSS_DTLSMGR_CTX_MAGIC);

	error = nss_dtlsmgr_ctx_create_encap(ctx, encap_ifnum, decap_ifnum, cfg);
	if (error < 0) {
		nss_dtlsmgr_warn("%px: unable to create encap context, error(%d)", ctx, error);
		goto free_dev;
	}

	error = nss_dtlsmgr_ctx_create_decap(ctx, decap_ifnum, encap_ifnum, cfg);
	if (error < 0) {
		nss_dtlsmgr_warn("%px: unable to create decap context, error(%d)", ctx, error);
		goto destroy_encap;
	}

	/*
	 * Set the needed headroom and tailroom as a multiple of 4 bytes
	 * so that the skb data pointer remains 4 byte aligned when the
	 * headroom/tailroom is adjusted.
	 */
	dev->needed_headroom = NSS_DTLSMGR_NEEDED_HEADROOM_SZ;
	dev->needed_tailroom = NSS_DTLSMGR_NEEDED_TAILROOM_SZ;

	ctx->app_data = cfg->app_data;
	ctx->notify_cb = cfg->notify;
	ctx->data_cb = cfg->data;

	/*
	 * If, the user has not provided the callback function then
	 * we will register the default callback handler
	 */
	if (!ctx->data_cb) {
		ctx->data_cb = nss_dtlsmgr_ctx_dev_data_callback;
		ctx->app_data = ctx;
	}

	error = register_netdev(dev);
	if (error < 0) {
		nss_dtlsmgr_warn("%px: unable register net_device(%s)", ctx, dev->name);
		goto destroy_decap;
	}

	dev->mtu = dev->mtu - (ctx->encap.headroom + ctx->encap.tailroom);

	nss_dtlsmgr_trace("%px: dtls session(%s) created, encap(%u), decap(%u)",
			  ctx, dev->name, ctx->encap.ifnum, ctx->decap.ifnum);

	if (nss_dtlsmgr_create_debugfs(ctx)) {
		nss_dtlsmgr_warn("Failed to create debugfs for ctx(%px)", ctx);
	}

	return dev;

destroy_decap:
	nss_dtlsmgr_ctx_deconfigure(ctx, &ctx->decap);

destroy_encap:
	nss_dtlsmgr_ctx_deconfigure(ctx, &ctx->encap);

free_dev:
	free_netdev(dev);

dealloc_decap_node:
	nss_dynamic_interface_dealloc_node(decap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER);

dealloc_encap_node:
	nss_dynamic_interface_dealloc_node(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER);
	return NULL;
}
EXPORT_SYMBOL(nss_dtlsmgr_session_create);

/*
 * nss_dtlsmgr_session_destroy()
 *	Destroy DTLS session
 */
nss_dtlsmgr_status_t nss_dtlsmgr_session_destroy(struct net_device *dev)
{
	struct nss_dtlsmgr_ctx *ctx = netdev_priv(dev);
	NSS_DTLSMGR_VERIFY_MAGIC(ctx);

	/*
	 * Reset the callback handlers atomically
	 */
	xchg(&ctx->notify_cb, NULL);
	xchg(&ctx->data_cb, NULL);

	nss_dtlsmgr_trace("%px: destroying encap(%u) and decap(%u) sessions",
			  ctx, ctx->encap.ifnum, ctx->decap.ifnum);

	if (!nss_dtlsmgr_ctx_deconfigure(ctx, &ctx->encap)) {
		nss_dtlsmgr_warn("%px: unable to deconfigure encap", ctx);
		return NSS_DTLSMGR_FAIL;
	}

	if (!nss_dtlsmgr_ctx_deconfigure(ctx, &ctx->decap)) {
		nss_dtlsmgr_warn("%px: unable to deconfigure decap", ctx);
		return NSS_DTLSMGR_FAIL;
	}

	NSS_DTLSMGR_SET_MAGIC(ctx, 0);

	unregister_netdev(dev);

	return NSS_DTLSMGR_OK;
}
EXPORT_SYMBOL(nss_dtlsmgr_session_destroy);

/*
 * nss_dtlsmgr_session_update_encap()
 *	Update the encapsulation crypto keys.
 */
nss_dtlsmgr_status_t nss_dtlsmgr_session_update_encap(struct net_device *dev, struct nss_dtlsmgr_config_update *cfg)
{
	struct nss_dtlsmgr_ctx *ctx = netdev_priv(dev);
	struct nss_dtlsmgr_ctx_data *data = &ctx->encap;
	struct nss_dtlsmgr_dtls_data *dtls, *prev_dtls;

	NSS_DTLSMGR_VERIFY_MAGIC(ctx);

	dtls = nss_dtlsmgr_ctx_alloc_dtls(ctx, &ctx->encap, &cfg->crypto);
	if (!dtls) {
		nss_dtlsmgr_warn("%px: unable to update encap context data", ctx);
		return NSS_DTLSMGR_FAIL_NOMEM;
	}

	/*
	 * Get the first entry in the list to compare the crypto key lengths
	 */
	prev_dtls = list_first_entry_or_null(&data->dtls_active, struct nss_dtlsmgr_dtls_data, list);
	if (!prev_dtls) {
		nss_dtlsmgr_warn("%px: dtls list is emtpy\n", ctx);
		return NSS_DTLSMGR_FAIL_NOCRYPTO;
	}

	/*
	 * If the new keys lengths are longer, then there isn't enough headroom and tailroom.
	 */
	BUG_ON(prev_dtls->iv_len < dtls->iv_len);
	BUG_ON(prev_dtls->blk_len < dtls->blk_len);
	BUG_ON(prev_dtls->hash_len < dtls->hash_len);

	nss_dtlsmgr_trace("%px: encap context update allocated (%u)", ctx, ctx->encap.ifnum);

	dtls->epoch = cfg->epoch;
	dtls->window_size = cfg->window_size;

	if (!nss_dtlsmgr_ctx_configure_dtls(&ctx->encap, dtls)) {
		nss_dtlsmgr_warn("%px: unable to configure encap dtls", ctx);
		nss_dtlsmgr_ctx_free_dtls(dtls);
		return NSS_DTLSMGR_FAIL_MESSAGE;
	}

	write_lock(&ctx->lock);
	list_add_tail(&dtls->list, &ctx->encap.dtls_active);
	write_unlock(&ctx->lock);

	nss_dtlsmgr_trace("%px: encap context update done", ctx);
	return NSS_DTLSMGR_OK;
}
EXPORT_SYMBOL(nss_dtlsmgr_session_update_encap);

/*
 * nss_dtlsmgr_session_update_decap()
 *	Update the decapsulation crypto keys.
 */
nss_dtlsmgr_status_t nss_dtlsmgr_session_update_decap(struct net_device *dev, struct nss_dtlsmgr_config_update *cfg)
{
	struct nss_dtlsmgr_ctx *ctx = netdev_priv(dev);
	struct nss_dtlsmgr_dtls_data *dtls;

	NSS_DTLSMGR_VERIFY_MAGIC(ctx);

	dtls = nss_dtlsmgr_ctx_alloc_dtls(ctx, &ctx->decap, &cfg->crypto);
	if (!dtls) {
		nss_dtlsmgr_warn("%px: unable to update decap context data", ctx);
		return NSS_DTLSMGR_FAIL_NOMEM;
	}

	nss_dtlsmgr_trace("%px: decap context update allocated (%u)", ctx, ctx->decap.ifnum);

	dtls->epoch = cfg->epoch;
	dtls->window_size = cfg->window_size;

	if (!nss_dtlsmgr_ctx_configure_dtls(&ctx->decap, dtls)) {
		nss_dtlsmgr_warn("%px: unable to configure decap dtls", ctx);
		nss_dtlsmgr_ctx_free_dtls(dtls);
		return NSS_DTLSMGR_FAIL_MESSAGE;
	}

	write_lock(&ctx->lock);
	list_add_tail(&dtls->list, &ctx->decap.dtls_active);
	write_unlock(&ctx->lock);

	nss_dtlsmgr_trace("%px: decap context update done", ctx);
	return NSS_DTLSMGR_OK;
}
EXPORT_SYMBOL(nss_dtlsmgr_session_update_decap);

/*
 * nss_dtlsmgr_session_switch_encap()
 *	Send a message to encapsulation DTLS interface to switch to the new crypto keys.
 */
bool nss_dtlsmgr_session_switch_encap(struct net_device *dev)
{
	struct nss_dtlsmgr_ctx *ctx = netdev_priv(dev);
	struct nss_dtlsmgr_ctx_data *data = &ctx->encap;

	NSS_DTLSMGR_VERIFY_MAGIC(ctx);

	if (!nss_dtlsmgr_session_switch(ctx, data)) {
		nss_dtlsmgr_warn("%px: failed to send encap switch_dtls(%u)", ctx, data->ifnum);
		return false;
	}

	nss_dtlsmgr_trace("%px: encap(%u) cipher switch done", ctx, data->ifnum);
	return true;
}
EXPORT_SYMBOL(nss_dtlsmgr_session_switch_encap);

/*
 * nss_dtlsmgr_session_switch_decap()
 *	Send a message to decapsulation DTLS interface to switch to the new crypto keys.
 */
bool nss_dtlsmgr_session_switch_decap(struct net_device *dev)
{
	struct nss_dtlsmgr_ctx *ctx = netdev_priv(dev);
	struct nss_dtlsmgr_ctx_data *data = &ctx->decap;

	NSS_DTLSMGR_VERIFY_MAGIC(ctx);

	if (!nss_dtlsmgr_session_switch(ctx, data)) {
		nss_dtlsmgr_warn("%px: failed to send decap switch_dtls(%u)", ctx, data->ifnum);
		return false;
	}

	nss_dtlsmgr_trace("%px: decap(%u) cipher switch done", ctx, data->ifnum);
	return true;
}
EXPORT_SYMBOL(nss_dtlsmgr_session_switch_decap);

/*
 * nss_dtlsmgr_get_interface()
 *	Returns NSS DTLS interface number for encap/decap on success.
 */
int32_t nss_dtlsmgr_get_interface(struct net_device *dev, enum nss_dtlsmgr_interface_type type)
{
	int32_t ifnum;

	switch (type) {
	case NSS_DTLSMGR_INTERFACE_TYPE_INNER:
		ifnum = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER);
		break;

	case NSS_DTLSMGR_INTERFACE_TYPE_OUTER:
		ifnum = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER);
		break;

	default:
		nss_dtlsmgr_warn("%px: invalid interface type %d", dev, type);
		return -EINVAL;
	}

	if (ifnum < 0) {
		nss_dtlsmgr_warn("%px: couldn't find DTLS interface number (%d)", dev, ifnum);
		return ifnum;
	}

	return nss_dtls_cmn_get_ifnum(ifnum);
}
EXPORT_SYMBOL(nss_dtlsmgr_get_interface);
