[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <YzVS5IVrynGFYXwi@unreal>
Date: Thu, 29 Sep 2022 11:10:12 +0300
From: Leon Romanovsky <leon@...nel.org>
To: Simon Horman <simon.horman@...igine.com>
Cc: David Miller <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>, netdev@...r.kernel.org,
oss-drivers@...igine.com,
Huanhuan Wang <huanhuan.wang@...igine.com>
Subject: Re: [PATCH net-next v2 2/3] nfp: add framework to support ipsec
offloading
On Tue, Sep 27, 2022 at 12:27:06PM +0200, Simon Horman wrote:
> From: Huanhuan Wang <huanhuan.wang@...igine.com>
>
> A new metadata type and config structure are introduced to
> interact with firmware to support ipsec offloading. This
> feature relies on specific firmware that supports ipsec
> encrypt/decrypt by advertising related capability bit.
>
> The xfrm callbacks which interact with upper layer are
> implemented in the following patch.
>
> Based on initial work of Norm Bagley <norman.bagley@...ronome.com>.
>
> Signed-off-by: Huanhuan Wang <huanhuan.wang@...igine.com>
> Signed-off-by: Simon Horman <simon.horman@...igine.com>
> ---
> drivers/net/ethernet/netronome/Kconfig | 11 +
> drivers/net/ethernet/netronome/nfp/Makefile | 6 +
> .../ethernet/netronome/nfp/crypto/crypto.h | 35 +++
> .../net/ethernet/netronome/nfp/crypto/ipsec.c | 216 ++++++++++++++++++
> drivers/net/ethernet/netronome/nfp/nfd3/dp.c | 43 +++-
> .../net/ethernet/netronome/nfp/nfd3/ipsec.c | 19 ++
> .../net/ethernet/netronome/nfp/nfd3/nfd3.h | 8 +
> drivers/net/ethernet/netronome/nfp/nfp_net.h | 9 +
> .../ethernet/netronome/nfp/nfp_net_common.c | 10 +-
> .../net/ethernet/netronome/nfp/nfp_net_ctrl.h | 4 +
> 10 files changed, 354 insertions(+), 7 deletions(-)
> create mode 100644 drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
> create mode 100644 drivers/net/ethernet/netronome/nfp/nfd3/ipsec.c
>
> diff --git a/drivers/net/ethernet/netronome/Kconfig b/drivers/net/ethernet/netronome/Kconfig
> index 8844d1ac053a..7f669d39e471 100644
> --- a/drivers/net/ethernet/netronome/Kconfig
> +++ b/drivers/net/ethernet/netronome/Kconfig
> @@ -54,6 +54,17 @@ config NFP_APP_ABM_NIC
> functionality.
> Code will be built into the nfp.ko driver.
>
> +config NFP_NET_IPSEC
> + bool "NFP Ipsec offload support"
You are adding "IPsec crypto offload", please be specific in all places.
> + depends on NFP
> + depends on XFRM_OFFLOAD
> + default y
> + help
> + Enable driver support Ipsec offload on NFP NIC. Say Y, if
> + you are planning to make use of Ipsec offload.
> + NOTE that Ipsec offload on NFP Nic requires specific FW to
> + work.
> +
> config NFP_DEBUG
> bool "Debug support for Netronome(R) NFP4000/NFP6000 NIC drivers"
> depends on NFP
> diff --git a/drivers/net/ethernet/netronome/nfp/Makefile b/drivers/net/ethernet/netronome/nfp/Makefile
> index 9c0861d03634..3d33b2838e0d 100644
> --- a/drivers/net/ethernet/netronome/nfp/Makefile
> +++ b/drivers/net/ethernet/netronome/nfp/Makefile
> @@ -80,4 +80,10 @@ nfp-objs += \
> abm/main.o
> endif
>
> +ifeq ($(CONFIG_NFP_NET_IPSEC),y)
Just curious, why ifeq and not nfp-$(...) format?
> +nfp-objs += \
> + crypto/ipsec.o \
> + nfd3/ipsec.o
> +endif
> +
> nfp-$(CONFIG_NFP_DEBUG) += nfp_net_debugfs.o
> diff --git a/drivers/net/ethernet/netronome/nfp/crypto/crypto.h b/drivers/net/ethernet/netronome/nfp/crypto/crypto.h
> index bffe58bb2f27..a27a378e3ebe 100644
> --- a/drivers/net/ethernet/netronome/nfp/crypto/crypto.h
> +++ b/drivers/net/ethernet/netronome/nfp/crypto/crypto.h
> @@ -39,4 +39,39 @@ nfp_net_tls_rx_resync_req(struct net_device *netdev,
> }
> #endif
>
> +/* Ipsec related structures and functions */
> +struct nfp_ipsec_offload {
> + u32 seq_hi;
> + u32 seq_low;
> + u32 handle;
> +};
> +
> +#ifndef CONFIG_NFP_NET_IPSEC
> +static inline int nfp_net_ipsec_init(struct nfp_net *nn)
> +{
> + return 0;
> +}
> +
> +static inline void nfp_net_ipsec_clean(struct nfp_net *nn)
> +{
> +}
> +
> +static inline bool nfp_net_ipsec_tx_prep(struct nfp_net_dp *dp, struct sk_buff *skb,
> + struct nfp_ipsec_offload *offload_info)
> +{
> + return false;
> +}
> +
> +static inline int nfp_net_ipsec_rx(struct nfp_meta_parsed *meta, struct sk_buff *skb)
> +{
> + return 0;
> +}
> +#else
> +int nfp_net_ipsec_init(struct nfp_net *nn);
> +void nfp_net_ipsec_clean(struct nfp_net *nn);
> +bool nfp_net_ipsec_tx_prep(struct nfp_net_dp *dp, struct sk_buff *skb,
> + struct nfp_ipsec_offload *offload_info);
> +int nfp_net_ipsec_rx(struct nfp_meta_parsed *meta, struct sk_buff *skb);
> +#endif
> +
> #endif
> diff --git a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
> new file mode 100644
> index 000000000000..658fcba8e733
> --- /dev/null
> +++ b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
> @@ -0,0 +1,216 @@
> +// 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 <asm/unaligned.h>
> +#include <linux/ktime.h>
> +#include <net/xfrm.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 */
> +#define OFFLOAD_HANDLE_ERROR 0xffffffff
You don't set this define in this patch, so why can't 0 be non-valid?
> +
> +/* 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 iv[2]; /* Firmware use only */
> + u32 cntr;
> + u32 zeros[4]; /* Init to 0 with sa */
> + u32 len_a[2]; /* Firmware use only */
> + u32 len_c[2];
> + u32 spare0[4];
> + } 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 ena_arw:1; /* Anti-Replay Window */
> + uint32_t ext_seq:1; /* 64-bit Sequence Num */
> + uint32_t ext_arw:1; /* 64b Anti-Replay Window */
> + uint32_t spare2 :9; /* Must be set to 0 */
> + uint32_t encap_dsbl:1; /* Encap/decap disable */
> + uint32_t gen_seq:1; /* Firmware Generate Seq */
> + uint32_t spare8 :1; /* Must be set to 0 */
> + } ctrl_word;
> + u32 spi; /* SPI Value */
> + uint32_t pmtu_limit :16; /* PMTU Limit */
> + uint32_t spare3 :1;
> + uint32_t frag_check :1; /* Stateful fragment checking flag */
> + uint32_t bypass_DSCP:1; /* Bypass DSCP Flag */
> + uint32_t df_ctrl :2; /* DF Control bits */
> + uint32_t ipv6 :1; /* Outbound IPv6 addr format */
> + uint32_t udp_enable :1; /* Add/Remove UDP header for NAT */
> + uint32_t tfc_enable :1; /* Traffic Flow Confidentiality */
> + uint32_t spare4 :8;
> + u32 soft_lifetime_byte_count;
> + u32 hard_lifetime_byte_count;
> + u32 src_ip[4]; /* Src IP addr */
> + u32 dst_ip[4]; /* Dst IP addr */
> + uint32_t natt_dst_port :16; /* NAT-T UDP Header dst port */
> + uint32_t natt_src_port :16; /* NAT-T UDP Header src port */
> + u32 soft_lifetime_time_limit;
> + u32 hard_lifetime_time_limit;
> + u32 sa_creation_time_lo_32; /* Ucode fills this in */
> + u32 sa_creation_time_hi_32; /* Ucode fills this in */
> + uint32_t reserved0 :16;
> + uint32_t tfc_padding :16; /* Traffic Flow Confidential Pad */
> +};
> +
> +struct nfp_net_ipsec_sa_data {
> + struct nfp_ipsec_cfg_add_sa nfp_sa;
> + struct xfrm_state *x;
> + int invalidated;
> +};
> +
> +struct nfp_net_ipsec_data {
> + struct nfp_net_ipsec_sa_data sa_entries[NFP_NET_IPSEC_MAX_SA_CNT];
> + unsigned int sa_free_stack[NFP_NET_IPSEC_MAX_SA_CNT];
> + unsigned int sa_free_cnt;
I don't see in this patch what are you doing with this free_stack array,
but whole nfp_net_ipsec_data is more than 32Kb of arrays.
> + struct mutex lock; /* Protects nfp_net_ipsec_data struct */
> +};
> +
> +static int nfp_net_xfrm_add_state(struct xfrm_state *x)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> +static void nfp_net_xfrm_del_state(struct xfrm_state *x)
> +{
> +}
> +
> +static void nfp_net_xfrm_free_state(struct xfrm_state *x)
> +{
> +}
> +
> +static bool nfp_net_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
> +{
> + return false;
> +}
> +
> +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_state_free = nfp_net_xfrm_free_state,
> + .xdo_dev_offload_ok = nfp_net_ipsec_offload_ok,
> +};
> +
> +int nfp_net_ipsec_init(struct nfp_net *nn)
> +{
> + if (nn->cap_w1 & NFP_NET_CFG_CTRL_IPSEC) {
Success oriented flow, please
If (...)
return 0;
....
> + struct nfp_net_ipsec_data *ipd;
> + int i;
> +
> + nn->dp.netdev->xfrmdev_ops = &nfp_net_ipsec_xfrmdev_ops;
You set ops before nn->ipsec_data which requires from you always check
the validity of nn->ipsec_data in xfrm calls.
Please set it when this init can't fail and remove checks in your xfrm
callbacks, because XFRM will call for already initialized nfp ipsec
core.
> +
> + ipd = kzalloc(sizeof(*ipd), GFP_KERNEL);
> + if (!ipd)
> + return -ENOMEM;
> +
> + for (i = 0; i < NFP_NET_IPSEC_MAX_SA_CNT; i++)
> + ipd->sa_free_stack[i] = NFP_NET_IPSEC_MAX_SA_CNT - i - 1;
> +
> + ipd->sa_free_cnt = NFP_NET_IPSEC_MAX_SA_CNT;
> + mutex_init(&ipd->lock);
> + nn->ipsec_data = ipd;
> + }
> +
> + return 0;
> +}
> +
> +void nfp_net_ipsec_clean(struct nfp_net *nn)
> +{
> + if (!nn->ipsec_data)
> + return;
> +
> + mutex_destroy(&nn->ipsec_data->lock);
> + kfree(nn->ipsec_data);
> + nn->ipsec_data = NULL;
Can you call again to nfp_net_ipsec_clean() after this line?
If not, please remove NULL assignment. It hides bugs.
> +}
> +
> +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;
> +
> + if (!xo)
> + return false;
How is it possible in offload path?
Why do all drivers check sec_path length and not xo?
> +
> + x = xfrm_input_state(skb);
> + if (!x)
> + return false;
> +
> + if (x->xso.offload_handle == OFFLOAD_HANDLE_ERROR) {
> + nn_dp_warn(dp, "Invalid xfrm offload handle\n");
> + 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 nfp_net_ipsec_sa_data *sa_data;
> + struct net_device *netdev = skb->dev;
> + struct nfp_net_ipsec_data *ipd;
> + struct xfrm_offload *xo;
> + struct nfp_net_dp *dp;
> + struct xfrm_state *x;
> + struct sec_path *sp;
> + struct nfp_net *nn;
> + int saidx;
> +
> + nn = netdev_priv(netdev);
> + ipd = nn->ipsec_data;
> + dp = &nn->dp;
> +
> + if (meta->ipsec_saidx == 0)
> + return 0; /* No offload took place */
> +
> + saidx = meta->ipsec_saidx - 1;
> + if (saidx > NFP_NET_IPSEC_MAX_SA_CNT || saidx < 0) {
> + nn_dp_warn(dp, "Invalid SAIDX from NIC %d\n", saidx);
No prints in data path that can be triggered from the network, please.
> + return -EINVAL;
> + }
> +
> + sa_data = &ipd->sa_entries[saidx];
> + if (!sa_data->x) {
> + nn_dp_warn(dp, "Unused SAIDX from NIC %d\n", saidx);
> + return -EINVAL;
> + }
> +
> + x = sa_data->x;
> + xfrm_state_hold(x);
You should call to xfrm_state_hold() after secpath_set(), because in
failure of latter you will leak reference to state.
> + sp = secpath_set(skb);
> + if (unlikely(!sp)) {
> + nn_dp_warn(dp, "Failed to alloc secpath for RX offload\n");
> + return -ENOMEM;
> + }
> +
> + sp->xvec[sp->len++] = x;
> + sp->olen++;
> + xo = xfrm_offload(skb);
> + xo->flags = CRYPTO_DONE;
> + xo->status = CRYPTO_SUCCESS;
> +
> + return 0;
> +}
> diff --git a/drivers/net/ethernet/netronome/nfp/nfd3/dp.c b/drivers/net/ethernet/netronome/nfp/nfd3/dp.c
> index 448c1c1afaee..db53e0392923 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfd3/dp.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfd3/dp.c
> @@ -167,14 +167,18 @@ nfp_nfd3_tx_csum(struct nfp_net_dp *dp, struct nfp_net_r_vector *r_vec,
> u64_stats_update_end(&r_vec->tx_sync);
> }
>
> -static int nfp_nfd3_prep_tx_meta(struct nfp_net_dp *dp, struct sk_buff *skb, u64 tls_handle)
> +static int nfp_nfd3_prep_tx_meta(struct nfp_net_dp *dp, struct sk_buff *skb,
> + u64 tls_handle, bool *ipsec)
> {
> struct metadata_dst *md_dst = skb_metadata_dst(skb);
> + struct nfp_ipsec_offload offload_info;
> unsigned char *data;
> bool vlan_insert;
> u32 meta_id = 0;
> int md_bytes;
>
> + *ipsec = nfp_net_ipsec_tx_prep(dp, skb, &offload_info);
> +
> if (unlikely(md_dst || tls_handle)) {
> if (unlikely(md_dst && md_dst->type != METADATA_HW_PORT_MUX))
> md_dst = NULL;
> @@ -182,13 +186,14 @@ static int nfp_nfd3_prep_tx_meta(struct nfp_net_dp *dp, struct sk_buff *skb, u64
>
> vlan_insert = skb_vlan_tag_present(skb) && (dp->ctrl & NFP_NET_CFG_CTRL_TXVLAN_V2);
>
> - if (!(md_dst || tls_handle || vlan_insert))
> + if (!(md_dst || tls_handle || vlan_insert || *ipsec))
> return 0;
>
> md_bytes = sizeof(meta_id) +
> !!md_dst * NFP_NET_META_PORTID_SIZE +
> !!tls_handle * NFP_NET_META_CONN_HANDLE_SIZE +
> - vlan_insert * NFP_NET_META_VLAN_SIZE;
> + vlan_insert * NFP_NET_META_VLAN_SIZE +
> + *ipsec * NFP_NET_META_IPSEC_FIELD_SIZE; /* Ipsec has 12-bytes metadata */
>
> if (unlikely(skb_cow_head(skb, md_bytes)))
> return -ENOMEM;
> @@ -218,6 +223,19 @@ static int nfp_nfd3_prep_tx_meta(struct nfp_net_dp *dp, struct sk_buff *skb, u64
> meta_id <<= NFP_NET_META_FIELD_SIZE;
> meta_id |= NFP_NET_META_VLAN;
> }
> + if (*ipsec) {
> + /* The ipsec has three consecutive 4-bit ipsec Metadate types
> + * so ipsec has three 4-bytes of Metadata
> + */
> + data -= NFP_NET_META_IPSEC_SIZE;
> + put_unaligned_be32(offload_info.seq_hi, data);
> + data -= NFP_NET_META_IPSEC_SIZE;
> + put_unaligned_be32(offload_info.seq_low, data);
> + data -= NFP_NET_META_IPSEC_SIZE;
> + put_unaligned_be32(offload_info.handle - 1, data);
> + meta_id <<= NFP_NET_META_IPSEC_FIELD_SIZE;
> + meta_id |= NFP_NET_META_IPSEC << 8 | NFP_NET_META_IPSEC << 4 | NFP_NET_META_IPSEC;
> + }
>
> data -= sizeof(meta_id);
> put_unaligned_be32(meta_id, data);
> @@ -246,6 +264,7 @@ netdev_tx_t nfp_nfd3_tx(struct sk_buff *skb, struct net_device *netdev)
> dma_addr_t dma_addr;
> unsigned int fsize;
> u64 tls_handle = 0;
> + bool ipsec = false;
> u16 qidx;
>
> dp = &nn->dp;
> @@ -273,7 +292,7 @@ netdev_tx_t nfp_nfd3_tx(struct sk_buff *skb, struct net_device *netdev)
> return NETDEV_TX_OK;
> }
>
> - md_bytes = nfp_nfd3_prep_tx_meta(dp, skb, tls_handle);
> + md_bytes = nfp_nfd3_prep_tx_meta(dp, skb, tls_handle, &ipsec);
> if (unlikely(md_bytes < 0))
> goto err_flush;
>
> @@ -312,6 +331,8 @@ netdev_tx_t nfp_nfd3_tx(struct sk_buff *skb, struct net_device *netdev)
> txd->vlan = cpu_to_le16(skb_vlan_tag_get(skb));
> }
>
> + if (ipsec)
> + nfp_nfd3_ipsec_tx(txd, skb);
> /* Gather DMA */
> if (nr_frags > 0) {
> __le64 second_half;
> @@ -764,6 +785,12 @@ nfp_nfd3_parse_meta(struct net_device *netdev, struct nfp_meta_parsed *meta,
> return false;
> data += sizeof(struct nfp_net_tls_resync_req);
> break;
> +#ifdef CONFIG_NFP_NET_IPSEC
> + case NFP_NET_META_IPSEC:
> + meta->ipsec_saidx = get_unaligned_be32(data) + 1;
> + data += 4;
> + break;
> +#endif
> default:
> return true;
> }
> @@ -876,12 +903,11 @@ static int nfp_nfd3_rx(struct nfp_net_rx_ring *rx_ring, int budget)
> struct nfp_net_dp *dp = &r_vec->nfp_net->dp;
> struct nfp_net_tx_ring *tx_ring;
> struct bpf_prog *xdp_prog;
> + int idx, pkts_polled = 0;
> bool xdp_tx_cmpl = false;
> unsigned int true_bufsz;
> struct sk_buff *skb;
> - int pkts_polled = 0;
> struct xdp_buff xdp;
> - int idx;
>
> xdp_prog = READ_ONCE(dp->xdp_prog);
> true_bufsz = xdp_prog ? PAGE_SIZE : dp->fl_bufsz;
> @@ -1081,6 +1107,11 @@ static int nfp_nfd3_rx(struct nfp_net_rx_ring *rx_ring, int budget)
> continue;
> }
>
> + if (unlikely(nfp_net_ipsec_rx(&meta, skb))) {
> + nfp_nfd3_rx_drop(dp, r_vec, rx_ring, NULL, skb);
Silent drop without any user visible counters, ok.
> + continue;
> + }
> +
> if (meta_len_xdp)
> skb_metadata_set(skb, meta_len_xdp);
>
> diff --git a/drivers/net/ethernet/netronome/nfp/nfd3/ipsec.c b/drivers/net/ethernet/netronome/nfp/nfd3/ipsec.c
> new file mode 100644
> index 000000000000..f0d74d6b49d0
> --- /dev/null
> +++ b/drivers/net/ethernet/netronome/nfp/nfd3/ipsec.c
> @@ -0,0 +1,19 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/* Copyright (C) 2018 Netronome Systems, Inc */
> +/* Copyright (C) 2021 Corigine, Inc */
> +
> +#include <net/xfrm.h>
> +
> +#include "../nfp_net.h"
> +#include "nfd3.h"
> +
> +void nfp_nfd3_ipsec_tx(struct nfp_nfd3_tx_desc *txd, struct sk_buff *skb)
> +{
> + struct xfrm_state *x;
> +
> + x = xfrm_input_state(skb);
> + if (x->xso.dev && (x->xso.dev->features & NETIF_F_HW_ESP_TX_CSUM)) {
> + txd->flags |= NFD3_DESC_TX_CSUM | NFD3_DESC_TX_IP4_CSUM |
> + NFD3_DESC_TX_TCP_CSUM | NFD3_DESC_TX_UDP_CSUM;
> + }
> +}
> diff --git a/drivers/net/ethernet/netronome/nfp/nfd3/nfd3.h b/drivers/net/ethernet/netronome/nfp/nfd3/nfd3.h
> index 7a0df9e6c3c4..9c1c10dcbaee 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfd3/nfd3.h
> +++ b/drivers/net/ethernet/netronome/nfp/nfd3/nfd3.h
> @@ -103,4 +103,12 @@ void nfp_nfd3_rx_ring_fill_freelist(struct nfp_net_dp *dp,
> void nfp_nfd3_xsk_tx_free(struct nfp_nfd3_tx_buf *txbuf);
> int nfp_nfd3_xsk_poll(struct napi_struct *napi, int budget);
>
> +#ifndef CONFIG_NFP_NET_IPSEC
> +static inline void nfp_nfd3_ipsec_tx(struct nfp_nfd3_tx_desc *txd, struct sk_buff *skb)
> +{
> +}
> +#else
> +void nfp_nfd3_ipsec_tx(struct nfp_nfd3_tx_desc *txd, struct sk_buff *skb);
> +#endif
> +
> #endif
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
> index 0c3e7e2f856d..768539f12214 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
> @@ -263,6 +263,10 @@ struct nfp_meta_parsed {
> u8 tpid;
> u16 tci;
> } vlan;
> +
> +#ifdef CONFIG_NFP_NET_IPSEC
> + u32 ipsec_saidx;
> +#endif
> };
>
> struct nfp_net_rx_hash {
> @@ -584,6 +588,7 @@ struct nfp_net_dp {
> * @qcp_cfg: Pointer to QCP queue used for configuration notification
> * @tx_bar: Pointer to mapped TX queues
> * @rx_bar: Pointer to mapped FL/RX queues
> + * @ipsec_data: Ipsec Sa data
> * @tlv_caps: Parsed TLV capabilities
> * @ktls_tx_conn_cnt: Number of offloaded kTLS TX connections
> * @ktls_rx_conn_cnt: Number of offloaded kTLS RX connections
> @@ -672,6 +677,10 @@ struct nfp_net {
> u8 __iomem *tx_bar;
> u8 __iomem *rx_bar;
>
> +#ifdef CONFIG_NFP_NET_IPSEC
> + struct nfp_net_ipsec_data *ipsec_data;
> +#endif
> +
> struct nfp_net_tlv_caps tlv_caps;
>
> unsigned int ktls_tx_conn_cnt;
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> index 7e4424d626a6..040c0c2aad80 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> @@ -2565,9 +2565,13 @@ int nfp_net_init(struct nfp_net *nn)
> if (err)
> return err;
>
> - err = nfp_net_tls_init(nn);
> + err = nfp_net_ipsec_init(nn);
> if (err)
> goto err_clean_mbox;
> +
> + err = nfp_net_tls_init(nn);
> + if (err)
> + goto err_clean_ipsec;
> }
>
> nfp_net_vecs_init(nn);
> @@ -2576,6 +2580,9 @@ int nfp_net_init(struct nfp_net *nn)
> return 0;
> return register_netdev(nn->dp.netdev);
>
> +err_clean_ipsec:
> + nfp_net_ipsec_clean(nn);
> +
> err_clean_mbox:
> nfp_ccm_mbox_clean(nn);
> return err;
> @@ -2591,6 +2598,7 @@ void nfp_net_clean(struct nfp_net *nn)
> return;
>
> unregister_netdev(nn->dp.netdev);
> + nfp_net_ipsec_clean(nn);
> nfp_ccm_mbox_clean(nn);
> nfp_net_reconfig_wait_posted(nn);
> }
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
> index 80346c1c266b..fff05496152d 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
> @@ -45,6 +45,7 @@
> #define NFP_NET_META_CSUM 6 /* checksum complete type */
> #define NFP_NET_META_CONN_HANDLE 7
> #define NFP_NET_META_RESYNC_INFO 8 /* RX resync info request */
> +#define NFP_NET_META_IPSEC 9 /* IPSec SA index for tx and rx */
>
> #define NFP_META_PORT_ID_CTRL ~0U
>
> @@ -52,6 +53,8 @@
> #define NFP_NET_META_VLAN_SIZE 4
> #define NFP_NET_META_PORTID_SIZE 4
> #define NFP_NET_META_CONN_HANDLE_SIZE 8
> +#define NFP_NET_META_IPSEC_SIZE 4
> +#define NFP_NET_META_IPSEC_FIELD_SIZE 12
> /* Hash type pre-pended when a RSS hash was computed */
> #define NFP_NET_RSS_NONE 0
> #define NFP_NET_RSS_IPV4 1
> @@ -260,6 +263,7 @@
> */
> #define NFP_NET_CFG_CTRL_WORD1 0x0098
> #define NFP_NET_CFG_CTRL_PKT_TYPE (0x1 << 0) /* Pkttype offload */
> +#define NFP_NET_CFG_CTRL_IPSEC (0x1 << 1) /* IPSec offload */
>
> #define NFP_NET_CFG_CAP_WORD1 0x00a4
>
> --
> 2.30.2
>
Powered by blists - more mailing lists