// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (C) 2018 Netronome Systems, Inc */
/* Copyright (C) 2021 Corigine, Inc */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/unaligned.h>
#include <linux/ktime.h>
#include <net/xfrm.h>

#include "../nfpcore/nfp_dev.h"
#include "../nfp_net_ctrl.h"
#include "../nfp_net.h"
#include "crypto.h"

#define NFP_NET_IPSEC_MAX_SA_CNT  (16 * 1024) /* Firmware support a maximum of 16K SA offload */

/* IPsec config message cmd codes */
enum nfp_ipsec_cfg_mssg_cmd_codes {
	NFP_IPSEC_CFG_MSSG_ADD_SA,	 /* Add a new SA */
	NFP_IPSEC_CFG_MSSG_INV_SA	 /* Invalidate an existing SA */
};

/* IPsec config message response codes */
enum nfp_ipsec_cfg_mssg_rsp_codes {
	NFP_IPSEC_CFG_MSSG_OK,
	NFP_IPSEC_CFG_MSSG_FAILED,
	NFP_IPSEC_CFG_MSSG_SA_VALID,
	NFP_IPSEC_CFG_MSSG_SA_HASH_ADD_FAILED,
	NFP_IPSEC_CFG_MSSG_SA_HASH_DEL_FAILED,
	NFP_IPSEC_CFG_MSSG_SA_INVALID_CMD
};

/* Protocol */
enum nfp_ipsec_sa_prot {
	NFP_IPSEC_PROTOCOL_AH = 0,
	NFP_IPSEC_PROTOCOL_ESP = 1
};

/* Mode */
enum nfp_ipsec_sa_mode {
	NFP_IPSEC_PROTMODE_TRANSPORT = 0,
	NFP_IPSEC_PROTMODE_TUNNEL = 1
};

/* Cipher types */
enum nfp_ipsec_sa_cipher {
	NFP_IPSEC_CIPHER_NULL,
	NFP_IPSEC_CIPHER_3DES,
	NFP_IPSEC_CIPHER_AES128,
	NFP_IPSEC_CIPHER_AES192,
	NFP_IPSEC_CIPHER_AES256,
	NFP_IPSEC_CIPHER_AES128_NULL,
	NFP_IPSEC_CIPHER_AES192_NULL,
	NFP_IPSEC_CIPHER_AES256_NULL,
	NFP_IPSEC_CIPHER_CHACHA20
};

/* Cipher modes */
enum nfp_ipsec_sa_cipher_mode {
	NFP_IPSEC_CIMODE_ECB,
	NFP_IPSEC_CIMODE_CBC,
	NFP_IPSEC_CIMODE_CFB,
	NFP_IPSEC_CIMODE_OFB,
	NFP_IPSEC_CIMODE_CTR
};

/* Hash types */
enum nfp_ipsec_sa_hash_type {
	NFP_IPSEC_HASH_NONE,
	NFP_IPSEC_HASH_MD5_96,
	NFP_IPSEC_HASH_SHA1_96,
	NFP_IPSEC_HASH_SHA256_96,
	NFP_IPSEC_HASH_SHA384_96,
	NFP_IPSEC_HASH_SHA512_96,
	NFP_IPSEC_HASH_MD5_128,
	NFP_IPSEC_HASH_SHA1_80,
	NFP_IPSEC_HASH_SHA256_128,
	NFP_IPSEC_HASH_SHA384_192,
	NFP_IPSEC_HASH_SHA512_256,
	NFP_IPSEC_HASH_GF128_128,
	NFP_IPSEC_HASH_POLY1305_128
};

/* IPSEC_CFG_MSSG_ADD_SA */
struct nfp_ipsec_cfg_add_sa {
	u32 ciph_key[8];		  /* Cipher Key */
	union {
		u32 auth_key[16];	  /* Authentication Key */
		struct nfp_ipsec_aesgcm { /* AES-GCM-ESP fields */
			u32 salt;	  /* Initialized with SA */
			u32 resv[15];
		} aesgcm_fields;
	};
	struct sa_ctrl_word {
		uint32_t hash   :4;	  /* From nfp_ipsec_sa_hash_type */
		uint32_t cimode :4;	  /* From nfp_ipsec_sa_cipher_mode */
		uint32_t cipher :4;	  /* From nfp_ipsec_sa_cipher */
		uint32_t mode   :2;	  /* From nfp_ipsec_sa_mode */
		uint32_t proto  :2;	  /* From nfp_ipsec_sa_prot */
		uint32_t dir :1;	  /* SA direction */
		uint32_t resv0 :12;
		uint32_t encap_dsbl:1;	  /* Encap/Decap disable */
		uint32_t resv1 :2;	  /* Must be set to 0 */
	} ctrl_word;
	u32 spi;			  /* SPI Value */
	uint32_t pmtu_limit :16;          /* PMTU Limit */
	uint32_t resv0 :5;
	uint32_t ipv6       :1;		  /* Outbound IPv6 addr format */
	uint32_t resv1	 :10;
	u32 resv2[2];
	u32 src_ip[4];			  /* Src IP addr */
	u32 dst_ip[4];			  /* Dst IP addr */
	u32 resv3[6];
};

/* IPSEC_CFG_MSSG */
struct nfp_ipsec_cfg_mssg {
	union {
		struct{
			uint32_t cmd:16;     /* One of nfp_ipsec_cfg_mssg_cmd_codes */
			uint32_t rsp:16;     /* One of nfp_ipsec_cfg_mssg_rsp_codes */
			uint32_t sa_idx:16;  /* SA table index */
			uint32_t spare0:16;
			struct nfp_ipsec_cfg_add_sa cfg_add_sa;
		};
		u32 raw[64];
	};
};

static int nfp_net_ipsec_cfg(struct nfp_net *nn, struct nfp_mbox_amsg_entry *entry)
{
	unsigned int offset = nn->tlv_caps.mbox_off + NFP_NET_CFG_MBOX_SIMPLE_VAL;
	struct nfp_ipsec_cfg_mssg *msg = (struct nfp_ipsec_cfg_mssg *)entry->msg;
	int i, msg_size, ret;

	ret = nfp_net_mbox_lock(nn, sizeof(*msg));
	if (ret)
		return ret;

	msg_size = ARRAY_SIZE(msg->raw);
	for (i = 0; i < msg_size; i++)
		nn_writel(nn, offset + 4 * i, msg->raw[i]);

	ret = nfp_net_mbox_reconfig(nn, entry->cmd);
	if (ret < 0) {
		nn_ctrl_bar_unlock(nn);
		return ret;
	}

	/* For now we always read the whole message response back */
	for (i = 0; i < msg_size; i++)
		msg->raw[i] = nn_readl(nn, offset + 4 * i);

	nn_ctrl_bar_unlock(nn);

	switch (msg->rsp) {
	case NFP_IPSEC_CFG_MSSG_OK:
		return 0;
	case NFP_IPSEC_CFG_MSSG_SA_INVALID_CMD:
		return -EINVAL;
	case NFP_IPSEC_CFG_MSSG_SA_VALID:
		return -EEXIST;
	case NFP_IPSEC_CFG_MSSG_FAILED:
	case NFP_IPSEC_CFG_MSSG_SA_HASH_ADD_FAILED:
	case NFP_IPSEC_CFG_MSSG_SA_HASH_DEL_FAILED:
		return -EIO;
	default:
		return -EINVAL;
	}
}

static int set_aes_keylen(struct nfp_ipsec_cfg_add_sa *cfg, int alg, int keylen)
{
	bool aes_gmac = (alg == SADB_X_EALG_NULL_AES_GMAC);

	switch (keylen) {
	case 128:
		cfg->ctrl_word.cipher = aes_gmac ? NFP_IPSEC_CIPHER_AES128_NULL :
						   NFP_IPSEC_CIPHER_AES128;
		break;
	case 192:
		cfg->ctrl_word.cipher = aes_gmac ? NFP_IPSEC_CIPHER_AES192_NULL :
						   NFP_IPSEC_CIPHER_AES192;
		break;
	case 256:
		cfg->ctrl_word.cipher = aes_gmac ? NFP_IPSEC_CIPHER_AES256_NULL :
						   NFP_IPSEC_CIPHER_AES256;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static void set_md5hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len)
{
	switch (*trunc_len) {
	case 96:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_MD5_96;
		break;
	case 128:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_MD5_128;
		break;
	default:
		*trunc_len = 0;
	}
}

static void set_sha1hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len)
{
	switch (*trunc_len) {
	case 96:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA1_96;
		break;
	case 80:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA1_80;
		break;
	default:
		*trunc_len = 0;
	}
}

static void set_sha2_256hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len)
{
	switch (*trunc_len) {
	case 96:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA256_96;
		break;
	case 128:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA256_128;
		break;
	default:
		*trunc_len = 0;
	}
}

static void set_sha2_384hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len)
{
	switch (*trunc_len) {
	case 96:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA384_96;
		break;
	case 192:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA384_192;
		break;
	default:
		*trunc_len = 0;
	}
}

static void set_sha2_512hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len)
{
	switch (*trunc_len) {
	case 96:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA512_96;
		break;
	case 256:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA512_256;
		break;
	default:
		*trunc_len = 0;
	}
}

static int nfp_net_xfrm_add_state(struct xfrm_state *x,
				  struct netlink_ext_ack *extack)
{
	struct net_device *netdev = x->xso.real_dev;
	struct nfp_ipsec_cfg_mssg msg = {};
	int i, key_len, trunc_len, err = 0;
	struct nfp_ipsec_cfg_add_sa *cfg;
	struct nfp_net *nn;
	unsigned int saidx;

	nn = netdev_priv(netdev);
	cfg = &msg.cfg_add_sa;

	/* General */
	switch (x->props.mode) {
	case XFRM_MODE_TUNNEL:
		cfg->ctrl_word.mode = NFP_IPSEC_PROTMODE_TUNNEL;
		break;
	case XFRM_MODE_TRANSPORT:
		cfg->ctrl_word.mode = NFP_IPSEC_PROTMODE_TRANSPORT;
		break;
	default:
		NL_SET_ERR_MSG_MOD(extack, "Unsupported mode for xfrm offload");
		return -EINVAL;
	}

	switch (x->id.proto) {
	case IPPROTO_ESP:
		cfg->ctrl_word.proto = NFP_IPSEC_PROTOCOL_ESP;
		break;
	case IPPROTO_AH:
		cfg->ctrl_word.proto = NFP_IPSEC_PROTOCOL_AH;
		break;
	default:
		NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol for xfrm offload");
		return -EINVAL;
	}

	if (x->props.flags & XFRM_STATE_ESN) {
		NL_SET_ERR_MSG_MOD(extack, "Unsupported XFRM_REPLAY_MODE_ESN for xfrm offload");
		return -EINVAL;
	}

	if (x->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
		NL_SET_ERR_MSG_MOD(extack, "Unsupported xfrm offload type");
		return -EINVAL;
	}

	cfg->spi = ntohl(x->id.spi);

	/* Hash/Authentication */
	if (x->aalg)
		trunc_len = x->aalg->alg_trunc_len;
	else
		trunc_len = 0;

	switch (x->props.aalgo) {
	case SADB_AALG_NONE:
		if (x->aead) {
			trunc_len = -1;
		} else {
			NL_SET_ERR_MSG_MOD(extack, "Unsupported authentication algorithm");
			return -EINVAL;
		}
		break;
	case SADB_X_AALG_NULL:
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_NONE;
		trunc_len = -1;
		break;
	case SADB_AALG_MD5HMAC:
		if (nn->pdev->device == PCI_DEVICE_ID_NFP3800) {
			NL_SET_ERR_MSG_MOD(extack, "Unsupported authentication algorithm");
			return -EINVAL;
		}
		set_md5hmac(cfg, &trunc_len);
		break;
	case SADB_AALG_SHA1HMAC:
		set_sha1hmac(cfg, &trunc_len);
		break;
	case SADB_X_AALG_SHA2_256HMAC:
		set_sha2_256hmac(cfg, &trunc_len);
		break;
	case SADB_X_AALG_SHA2_384HMAC:
		set_sha2_384hmac(cfg, &trunc_len);
		break;
	case SADB_X_AALG_SHA2_512HMAC:
		set_sha2_512hmac(cfg, &trunc_len);
		break;
	default:
		NL_SET_ERR_MSG_MOD(extack, "Unsupported authentication algorithm");
		return -EINVAL;
	}

	if (!trunc_len) {
		NL_SET_ERR_MSG_MOD(extack, "Unsupported authentication algorithm trunc length");
		return -EINVAL;
	}

	if (x->aalg) {
		key_len = DIV_ROUND_UP(x->aalg->alg_key_len, BITS_PER_BYTE);
		if (key_len > sizeof(cfg->auth_key)) {
			NL_SET_ERR_MSG_MOD(extack, "Insufficient space for offloaded auth key");
			return -EINVAL;
		}
		for (i = 0; i < key_len / sizeof(cfg->auth_key[0]) ; i++)
			cfg->auth_key[i] = get_unaligned_be32(x->aalg->alg_key +
							      sizeof(cfg->auth_key[0]) * i);
	}

	/* Encryption */
	switch (x->props.ealgo) {
	case SADB_EALG_NONE:
		/* The xfrm descriptor for CHACAH20_POLY1305 does not set the algorithm id, which
		 * is the default value SADB_EALG_NONE. In the branch of SADB_EALG_NONE, driver
		 * uses algorithm name to identify CHACAH20_POLY1305's algorithm.
		 */
		if (x->aead && !strcmp(x->aead->alg_name, "rfc7539esp(chacha20,poly1305)")) {
			if (nn->pdev->device != PCI_DEVICE_ID_NFP3800) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Unsupported encryption algorithm for offload");
				return -EINVAL;
			}
			if (x->aead->alg_icv_len != 128) {
				NL_SET_ERR_MSG_MOD(extack,
						   "ICV must be 128bit with CHACHA20_POLY1305");
				return -EINVAL;
			}

			/* Aead->alg_key_len includes 32-bit salt */
			if (x->aead->alg_key_len - 32 != 256) {
				NL_SET_ERR_MSG_MOD(extack, "Unsupported CHACHA20 key length");
				return -EINVAL;
			}

			/* The CHACHA20's mode is not configured */
			cfg->ctrl_word.hash = NFP_IPSEC_HASH_POLY1305_128;
			cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_CHACHA20;
			break;
		}
		fallthrough;
	case SADB_EALG_NULL:
		cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC;
		cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_NULL;
		break;
	case SADB_EALG_3DESCBC:
		if (nn->pdev->device == PCI_DEVICE_ID_NFP3800) {
			NL_SET_ERR_MSG_MOD(extack, "Unsupported encryption algorithm for offload");
			return -EINVAL;
		}
		cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC;
		cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_3DES;
		break;
	case SADB_X_EALG_AES_GCM_ICV16:
	case SADB_X_EALG_NULL_AES_GMAC:
		if (!x->aead) {
			NL_SET_ERR_MSG_MOD(extack, "Invalid AES key data");
			return -EINVAL;
		}

		if (x->aead->alg_icv_len != 128) {
			NL_SET_ERR_MSG_MOD(extack, "ICV must be 128bit with SADB_X_EALG_AES_GCM_ICV16");
			return -EINVAL;
		}
		cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CTR;
		cfg->ctrl_word.hash = NFP_IPSEC_HASH_GF128_128;

		/* Aead->alg_key_len includes 32-bit salt */
		if (set_aes_keylen(cfg, x->props.ealgo, x->aead->alg_key_len - 32)) {
			NL_SET_ERR_MSG_MOD(extack, "Unsupported AES key length");
			return -EINVAL;
		}
		break;
	case SADB_X_EALG_AESCBC:
		cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC;
		if (!x->ealg) {
			NL_SET_ERR_MSG_MOD(extack, "Invalid AES key data");
			return -EINVAL;
		}
		if (set_aes_keylen(cfg, x->props.ealgo, x->ealg->alg_key_len) < 0) {
			NL_SET_ERR_MSG_MOD(extack, "Unsupported AES key length");
			return -EINVAL;
		}
		break;
	default:
		NL_SET_ERR_MSG_MOD(extack, "Unsupported encryption algorithm for offload");
		return -EINVAL;
	}

	if (x->aead) {
		int key_offset = 0;
		int salt_len = 4;

		key_len = DIV_ROUND_UP(x->aead->alg_key_len, BITS_PER_BYTE);
		key_len -= salt_len;

		if (key_len > sizeof(cfg->ciph_key)) {
			NL_SET_ERR_MSG_MOD(extack, "aead: Insufficient space for offloaded key");
			return -EINVAL;
		}

		/* The CHACHA20's key order needs to be adjusted based on hardware design.
		 * Other's key order: {K0, K1, K2, K3, K4, K5, K6, K7}
		 * CHACHA20's key order: {K4, K5, K6, K7, K0, K1, K2, K3}
		 */
		if (!strcmp(x->aead->alg_name, "rfc7539esp(chacha20,poly1305)"))
			key_offset = key_len / sizeof(cfg->ciph_key[0]) >> 1;

		for (i = 0; i < key_len / sizeof(cfg->ciph_key[0]); i++) {
			int index = (i + key_offset) % (key_len / sizeof(cfg->ciph_key[0]));

			cfg->ciph_key[index] = get_unaligned_be32(x->aead->alg_key +
								  sizeof(cfg->ciph_key[0]) * i);
		}

		/* Load up the salt */
		cfg->aesgcm_fields.salt = get_unaligned_be32(x->aead->alg_key + key_len);
	}

	if (x->ealg) {
		key_len = DIV_ROUND_UP(x->ealg->alg_key_len, BITS_PER_BYTE);

		if (key_len > sizeof(cfg->ciph_key)) {
			NL_SET_ERR_MSG_MOD(extack, "ealg: Insufficient space for offloaded key");
			return -EINVAL;
		}
		for (i = 0; i < key_len / sizeof(cfg->ciph_key[0]) ; i++)
			cfg->ciph_key[i] = get_unaligned_be32(x->ealg->alg_key +
							      sizeof(cfg->ciph_key[0]) * i);
	}

	/* IP related info */
	switch (x->props.family) {
	case AF_INET:
		cfg->ipv6 = 0;
		cfg->src_ip[0] = ntohl(x->props.saddr.a4);
		cfg->dst_ip[0] = ntohl(x->id.daddr.a4);
		break;
	case AF_INET6:
		cfg->ipv6 = 1;
		for (i = 0; i < 4; i++) {
			cfg->src_ip[i] = ntohl(x->props.saddr.a6[i]);
			cfg->dst_ip[i] = ntohl(x->id.daddr.a6[i]);
		}
		break;
	default:
		NL_SET_ERR_MSG_MOD(extack, "Unsupported address family");
		return -EINVAL;
	}

	/* Maximum nic IPsec code could handle. Other limits may apply. */
	cfg->pmtu_limit = 0xffff;
	cfg->ctrl_word.encap_dsbl = 1;

	/* SA direction */
	cfg->ctrl_word.dir = x->xso.dir;

	/* Find unused SA data*/
	err = xa_alloc(&nn->xa_ipsec, &saidx, x,
		       XA_LIMIT(0, NFP_NET_IPSEC_MAX_SA_CNT - 1), GFP_KERNEL);
	if (err < 0) {
		NL_SET_ERR_MSG_MOD(extack, "Unable to get sa_data number for IPsec");
		return err;
	}

	/* Allocate saidx and commit the SA */
	msg.cmd = NFP_IPSEC_CFG_MSSG_ADD_SA;
	msg.sa_idx = saidx;
	err = nfp_net_sched_mbox_amsg_work(nn, NFP_NET_CFG_MBOX_CMD_IPSEC, &msg,
					   sizeof(msg), nfp_net_ipsec_cfg);
	if (err) {
		xa_erase(&nn->xa_ipsec, saidx);
		NL_SET_ERR_MSG_MOD(extack, "Failed to issue IPsec command");
		return err;
	}

	/* 0 is invalid offload_handle for kernel */
	x->xso.offload_handle = saidx + 1;
	return 0;
}

static void nfp_net_xfrm_del_state(struct xfrm_state *x)
{
	struct nfp_ipsec_cfg_mssg msg = {
		.cmd = NFP_IPSEC_CFG_MSSG_INV_SA,
		.sa_idx = x->xso.offload_handle - 1,
	};
	struct net_device *netdev = x->xso.real_dev;
	struct nfp_net *nn;
	int err;

	nn = netdev_priv(netdev);
	err = nfp_net_sched_mbox_amsg_work(nn, NFP_NET_CFG_MBOX_CMD_IPSEC, &msg,
					   sizeof(msg), nfp_net_ipsec_cfg);
	if (err)
		nn_warn(nn, "Failed to invalidate SA in hardware\n");

	xa_erase(&nn->xa_ipsec, x->xso.offload_handle - 1);
}

static bool nfp_net_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
{
	if (x->props.family == AF_INET)
		/* Offload with IPv4 options is not supported yet */
		return ip_hdr(skb)->ihl == 5;

	/* Offload with IPv6 extension headers is not support yet */
	return !(ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr));
}

static const struct xfrmdev_ops nfp_net_ipsec_xfrmdev_ops = {
	.xdo_dev_state_add = nfp_net_xfrm_add_state,
	.xdo_dev_state_delete = nfp_net_xfrm_del_state,
	.xdo_dev_offload_ok = nfp_net_ipsec_offload_ok,
};

void nfp_net_ipsec_init(struct nfp_net *nn)
{
	if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_IPSEC))
		return;

	xa_init_flags(&nn->xa_ipsec, XA_FLAGS_ALLOC);
	nn->dp.netdev->xfrmdev_ops = &nfp_net_ipsec_xfrmdev_ops;
}

void nfp_net_ipsec_clean(struct nfp_net *nn)
{
	if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_IPSEC))
		return;

	WARN_ON(!xa_empty(&nn->xa_ipsec));
	xa_destroy(&nn->xa_ipsec);
}

bool nfp_net_ipsec_tx_prep(struct nfp_net_dp *dp, struct sk_buff *skb,
			   struct nfp_ipsec_offload *offload_info)
{
	struct xfrm_offload *xo = xfrm_offload(skb);
	struct xfrm_state *x;

	x = xfrm_input_state(skb);
	if (!x)
		return false;

	offload_info->seq_hi = xo->seq.hi;
	offload_info->seq_low = xo->seq.low;
	offload_info->handle = x->xso.offload_handle;

	return true;
}

int nfp_net_ipsec_rx(struct nfp_meta_parsed *meta, struct sk_buff *skb)
{
	struct net_device *netdev = skb->dev;
	struct xfrm_offload *xo;
	struct xfrm_state *x;
	struct sec_path *sp;
	struct nfp_net *nn;
	u32 saidx;

	nn = netdev_priv(netdev);

	saidx = meta->ipsec_saidx - 1;
	if (saidx >= NFP_NET_IPSEC_MAX_SA_CNT)
		return -EINVAL;

	sp = secpath_set(skb);
	if (unlikely(!sp))
		return -ENOMEM;

	xa_lock(&nn->xa_ipsec);
	x = xa_load(&nn->xa_ipsec, saidx);
	xa_unlock(&nn->xa_ipsec);
	if (!x)
		return -EINVAL;

	xfrm_state_hold(x);
	sp->xvec[sp->len++] = x;
	sp->olen++;
	xo = xfrm_offload(skb);
	xo->flags = CRYPTO_DONE;
	xo->status = CRYPTO_SUCCESS;

	return 0;
}
