Message ID | 20230119113842.146884-1-simon.horman@corigine.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next] nfp: support IPsec offloading for NFP3800 | expand |
On Thu, Jan 19, 2023 at 12:38:42PM +0100, Simon Horman wrote: > From: Huanhuan Wang <huanhuan.wang@corigine.com> > > Add IPsec offloading support for NFP3800. > Including data plane and control plane. > > Data plane: add IPsec packet process flow in NFP3800 datapath (NFDK). > > Control plane: add a algorithm support distinction of flow > in xfrm hook function xdo_dev_state_add as NFP3800 > supports a different set of IPsec algorithms. > > This matches existing support for the NFP6000/NFP4000 and > their NFD3 datapath. > > Signed-off-by: Huanhuan Wang <huanhuan.wang@corigine.com> > Signed-off-by: Simon Horman <simon.horman@corigine.com> > --- > drivers/net/ethernet/netronome/nfp/Makefile | 2 +- > .../net/ethernet/netronome/nfp/crypto/ipsec.c | 9 ++++ > drivers/net/ethernet/netronome/nfp/nfd3/dp.c | 5 +- > drivers/net/ethernet/netronome/nfp/nfdk/dp.c | 47 +++++++++++++++++-- > .../net/ethernet/netronome/nfp/nfdk/ipsec.c | 17 +++++++ > .../net/ethernet/netronome/nfp/nfdk/nfdk.h | 8 ++++ > 6 files changed, 79 insertions(+), 9 deletions(-) > create mode 100644 drivers/net/ethernet/netronome/nfp/nfdk/ipsec.c <...> > md_bytes = sizeof(meta_id) + > !!md_dst * NFP_NET_META_PORTID_SIZE + > - vlan_insert * NFP_NET_META_VLAN_SIZE; > + vlan_insert * NFP_NET_META_VLAN_SIZE + > + *ipsec * NFP_NET_META_IPSEC_FIELD_SIZE; *ipsec is boolean variable, so you are assuming that true is always 1. I'm not sure that it is always correct. Thanks
On Sun, Jan 22, 2023 at 10:50:24AM +0200, Leon Romanovsky wrote: > On Thu, Jan 19, 2023 at 12:38:42PM +0100, Simon Horman wrote: > > From: Huanhuan Wang <huanhuan.wang@corigine.com> > > > > Add IPsec offloading support for NFP3800. > > Including data plane and control plane. > > > > Data plane: add IPsec packet process flow in NFP3800 datapath (NFDK). > > > > Control plane: add a algorithm support distinction of flow > > in xfrm hook function xdo_dev_state_add as NFP3800 > > supports a different set of IPsec algorithms. > > > > This matches existing support for the NFP6000/NFP4000 and > > their NFD3 datapath. > > > > Signed-off-by: Huanhuan Wang <huanhuan.wang@corigine.com> > > Signed-off-by: Simon Horman <simon.horman@corigine.com> > > --- > > drivers/net/ethernet/netronome/nfp/Makefile | 2 +- > > .../net/ethernet/netronome/nfp/crypto/ipsec.c | 9 ++++ > > drivers/net/ethernet/netronome/nfp/nfd3/dp.c | 5 +- > > drivers/net/ethernet/netronome/nfp/nfdk/dp.c | 47 +++++++++++++++++-- > > .../net/ethernet/netronome/nfp/nfdk/ipsec.c | 17 +++++++ > > .../net/ethernet/netronome/nfp/nfdk/nfdk.h | 8 ++++ > > 6 files changed, 79 insertions(+), 9 deletions(-) > > create mode 100644 drivers/net/ethernet/netronome/nfp/nfdk/ipsec.c > > <...> > > > md_bytes = sizeof(meta_id) + > > !!md_dst * NFP_NET_META_PORTID_SIZE + > > - vlan_insert * NFP_NET_META_VLAN_SIZE; > > + vlan_insert * NFP_NET_META_VLAN_SIZE + > > + *ipsec * NFP_NET_META_IPSEC_FIELD_SIZE; > > *ipsec is boolean variable, so you are assuming that true is always 1. > I'm not sure that it is always correct. Thanks, I do see what you are saying. But I think what is there is consistent with the existing use if md_dst and vlan_insert.
On Mon, Jan 23, 2023 at 02:15:44PM +0100, Simon Horman wrote: > On Sun, Jan 22, 2023 at 10:50:24AM +0200, Leon Romanovsky wrote: > > On Thu, Jan 19, 2023 at 12:38:42PM +0100, Simon Horman wrote: > > > From: Huanhuan Wang <huanhuan.wang@corigine.com> > > > > > > Add IPsec offloading support for NFP3800. > > > Including data plane and control plane. > > > > > > Data plane: add IPsec packet process flow in NFP3800 datapath (NFDK). > > > > > > Control plane: add a algorithm support distinction of flow > > > in xfrm hook function xdo_dev_state_add as NFP3800 > > > supports a different set of IPsec algorithms. > > > > > > This matches existing support for the NFP6000/NFP4000 and > > > their NFD3 datapath. > > > > > > Signed-off-by: Huanhuan Wang <huanhuan.wang@corigine.com> > > > Signed-off-by: Simon Horman <simon.horman@corigine.com> > > > --- > > > drivers/net/ethernet/netronome/nfp/Makefile | 2 +- > > > .../net/ethernet/netronome/nfp/crypto/ipsec.c | 9 ++++ > > > drivers/net/ethernet/netronome/nfp/nfd3/dp.c | 5 +- > > > drivers/net/ethernet/netronome/nfp/nfdk/dp.c | 47 +++++++++++++++++-- > > > .../net/ethernet/netronome/nfp/nfdk/ipsec.c | 17 +++++++ > > > .../net/ethernet/netronome/nfp/nfdk/nfdk.h | 8 ++++ > > > 6 files changed, 79 insertions(+), 9 deletions(-) > > > create mode 100644 drivers/net/ethernet/netronome/nfp/nfdk/ipsec.c > > > > <...> > > > > > md_bytes = sizeof(meta_id) + > > > !!md_dst * NFP_NET_META_PORTID_SIZE + > > > - vlan_insert * NFP_NET_META_VLAN_SIZE; > > > + vlan_insert * NFP_NET_META_VLAN_SIZE + > > > + *ipsec * NFP_NET_META_IPSEC_FIELD_SIZE; > > > > *ipsec is boolean variable, so you are assuming that true is always 1. > > I'm not sure that it is always correct. > > Thanks, I do see what you are saying. > > But I think what is there is consistent with the existing > use if md_dst and vlan_insert. It doesn't make it correct. Thanks
On Mon, Jan 23, 2023 at 03:36:35PM +0200, Leon Romanovsky wrote: > On Mon, Jan 23, 2023 at 02:15:44PM +0100, Simon Horman wrote: > > On Sun, Jan 22, 2023 at 10:50:24AM +0200, Leon Romanovsky wrote: > > > On Thu, Jan 19, 2023 at 12:38:42PM +0100, Simon Horman wrote: > > > > From: Huanhuan Wang <huanhuan.wang@corigine.com> > > > > > > > > Add IPsec offloading support for NFP3800. > > > > Including data plane and control plane. > > > > > > > > Data plane: add IPsec packet process flow in NFP3800 datapath (NFDK). > > > > > > > > Control plane: add a algorithm support distinction of flow > > > > in xfrm hook function xdo_dev_state_add as NFP3800 > > > > supports a different set of IPsec algorithms. > > > > > > > > This matches existing support for the NFP6000/NFP4000 and > > > > their NFD3 datapath. > > > > > > > > Signed-off-by: Huanhuan Wang <huanhuan.wang@corigine.com> > > > > Signed-off-by: Simon Horman <simon.horman@corigine.com> > > > > --- > > > > drivers/net/ethernet/netronome/nfp/Makefile | 2 +- > > > > .../net/ethernet/netronome/nfp/crypto/ipsec.c | 9 ++++ > > > > drivers/net/ethernet/netronome/nfp/nfd3/dp.c | 5 +- > > > > drivers/net/ethernet/netronome/nfp/nfdk/dp.c | 47 +++++++++++++++++-- > > > > .../net/ethernet/netronome/nfp/nfdk/ipsec.c | 17 +++++++ > > > > .../net/ethernet/netronome/nfp/nfdk/nfdk.h | 8 ++++ > > > > 6 files changed, 79 insertions(+), 9 deletions(-) > > > > create mode 100644 drivers/net/ethernet/netronome/nfp/nfdk/ipsec.c > > > > > > <...> > > > > > > > md_bytes = sizeof(meta_id) + > > > > !!md_dst * NFP_NET_META_PORTID_SIZE + > > > > - vlan_insert * NFP_NET_META_VLAN_SIZE; > > > > + vlan_insert * NFP_NET_META_VLAN_SIZE + > > > > + *ipsec * NFP_NET_META_IPSEC_FIELD_SIZE; > > > > > > *ipsec is boolean variable, so you are assuming that true is always 1. > > > I'm not sure that it is always correct. > > > > Thanks, I do see what you are saying. > > > > But I think what is there is consistent with the existing > > use if md_dst and vlan_insert. > > It doesn't make it correct. Ack, let me see if I can improve this.
diff --git a/drivers/net/ethernet/netronome/nfp/Makefile b/drivers/net/ethernet/netronome/nfp/Makefile index c90d35f5ebca..808599b8066e 100644 --- a/drivers/net/ethernet/netronome/nfp/Makefile +++ b/drivers/net/ethernet/netronome/nfp/Makefile @@ -80,7 +80,7 @@ nfp-objs += \ abm/main.o endif -nfp-$(CONFIG_NFP_NET_IPSEC) += crypto/ipsec.o nfd3/ipsec.o +nfp-$(CONFIG_NFP_NET_IPSEC) += crypto/ipsec.o nfd3/ipsec.o nfdk/ipsec.o nfp-$(CONFIG_NFP_DEBUG) += nfp_net_debugfs.o diff --git a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c index 4632268695cb..06d2f95c91b5 100644 --- a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c +++ b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c @@ -10,6 +10,7 @@ #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" @@ -329,6 +330,10 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x) trunc_len = -1; break; case SADB_AALG_MD5HMAC: + if (nn->pdev->device == PCI_DEVICE_ID_NFP3800) { + nn_err(nn, "Unsupported authentication algorithm\n"); + return -EINVAL; + } set_md5hmac(cfg, &trunc_len); break; case SADB_AALG_SHA1HMAC: @@ -372,6 +377,10 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x) cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_NULL; break; case SADB_EALG_3DESCBC: + if (nn->pdev->device == PCI_DEVICE_ID_NFP3800) { + nn_err(nn, "Unsupported encryption algorithm for offload\n"); + return -EINVAL; + } cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC; cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_3DES; break; diff --git a/drivers/net/ethernet/netronome/nfp/nfd3/dp.c b/drivers/net/ethernet/netronome/nfp/nfd3/dp.c index 861082c5dbff..33b33a77d64e 100644 --- a/drivers/net/ethernet/netronome/nfp/nfd3/dp.c +++ b/drivers/net/ethernet/netronome/nfp/nfd3/dp.c @@ -195,7 +195,7 @@ static int nfp_nfd3_prep_tx_meta(struct nfp_net_dp *dp, struct sk_buff *skb, !!md_dst * NFP_NET_META_PORTID_SIZE + !!tls_handle * NFP_NET_META_CONN_HANDLE_SIZE + vlan_insert * NFP_NET_META_VLAN_SIZE + - *ipsec * NFP_NET_META_IPSEC_FIELD_SIZE; /* IPsec has 12 bytes of metadata */ + *ipsec * NFP_NET_META_IPSEC_FIELD_SIZE; if (unlikely(skb_cow_head(skb, md_bytes))) return -ENOMEM; @@ -226,9 +226,6 @@ static int nfp_nfd3_prep_tx_meta(struct nfp_net_dp *dp, struct sk_buff *skb, meta_id |= NFP_NET_META_VLAN; } if (*ipsec) { - /* IPsec has three consecutive 4-bit IPsec metadata types, - * so in total 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; diff --git a/drivers/net/ethernet/netronome/nfp/nfdk/dp.c b/drivers/net/ethernet/netronome/nfp/nfdk/dp.c index ccacb6ab6c39..efa8259adbd5 100644 --- a/drivers/net/ethernet/netronome/nfp/nfdk/dp.c +++ b/drivers/net/ethernet/netronome/nfp/nfdk/dp.c @@ -6,6 +6,7 @@ #include <linux/overflow.h> #include <linux/sizes.h> #include <linux/bitfield.h> +#include <net/xfrm.h> #include "../nfp_app.h" #include "../nfp_net.h" @@ -172,25 +173,32 @@ nfp_nfdk_tx_maybe_close_block(struct nfp_net_tx_ring *tx_ring, static int nfp_nfdk_prep_tx_meta(struct nfp_net_dp *dp, struct nfp_app *app, - struct sk_buff *skb) + struct sk_buff *skb, 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; +#ifdef CONFIG_NFP_NET_IPSEC + if (xfrm_offload(skb)) + *ipsec = nfp_net_ipsec_tx_prep(dp, skb, &offload_info); +#endif + if (unlikely(md_dst && md_dst->type != METADATA_HW_PORT_MUX)) md_dst = NULL; vlan_insert = skb_vlan_tag_present(skb) && (dp->ctrl & NFP_NET_CFG_CTRL_TXVLAN_V2); - if (!(md_dst || vlan_insert)) + if (!(md_dst || vlan_insert || *ipsec)) return 0; md_bytes = sizeof(meta_id) + !!md_dst * NFP_NET_META_PORTID_SIZE + - vlan_insert * NFP_NET_META_VLAN_SIZE; + vlan_insert * NFP_NET_META_VLAN_SIZE + + *ipsec * NFP_NET_META_IPSEC_FIELD_SIZE; if (unlikely(skb_cow_head(skb, md_bytes))) return -ENOMEM; @@ -212,6 +220,17 @@ nfp_nfdk_prep_tx_meta(struct nfp_net_dp *dp, struct nfp_app *app, meta_id |= NFP_NET_META_VLAN; } + if (*ipsec) { + 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; + } + meta_id = FIELD_PREP(NFDK_META_LEN, md_bytes) | FIELD_PREP(NFDK_META_FIELDS, meta_id); @@ -243,6 +262,7 @@ netdev_tx_t nfp_nfdk_tx(struct sk_buff *skb, struct net_device *netdev) struct nfp_net_dp *dp; int nr_frags, wr_idx; dma_addr_t dma_addr; + bool ipsec = false; u64 metadata; dp = &nn->dp; @@ -263,7 +283,7 @@ netdev_tx_t nfp_nfdk_tx(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_BUSY; } - metadata = nfp_nfdk_prep_tx_meta(dp, nn->app, skb); + metadata = nfp_nfdk_prep_tx_meta(dp, nn->app, skb, &ipsec); if (unlikely((int)metadata < 0)) goto err_flush; @@ -361,6 +381,9 @@ netdev_tx_t nfp_nfdk_tx(struct sk_buff *skb, struct net_device *netdev) (txd - 1)->dma_len_type = cpu_to_le16(dlen_type | NFDK_DESC_TX_EOP); + if (ipsec) + metadata = nfp_nfdk_ipsec_tx(metadata, skb); + if (!skb_is_gso(skb)) { real_len = skb->len; /* Metadata desc */ @@ -760,6 +783,15 @@ nfp_nfdk_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: + /* Note: IPsec packet could have zero saidx, so need add 1 + * to indicate packet is IPsec packet within driver. + */ + meta->ipsec_saidx = get_unaligned_be32(data) + 1; + data += 4; + break; +#endif default: return true; } @@ -1186,6 +1218,13 @@ static int nfp_nfdk_rx(struct nfp_net_rx_ring *rx_ring, int budget) continue; } +#ifdef CONFIG_NFP_NET_IPSEC + if (meta.ipsec_saidx != 0 && unlikely(nfp_net_ipsec_rx(&meta, skb))) { + nfp_nfdk_rx_drop(dp, r_vec, rx_ring, NULL, skb); + continue; + } +#endif + if (meta_len_xdp) skb_metadata_set(skb, meta_len_xdp); diff --git a/drivers/net/ethernet/netronome/nfp/nfdk/ipsec.c b/drivers/net/ethernet/netronome/nfp/nfdk/ipsec.c new file mode 100644 index 000000000000..58d8f59eb885 --- /dev/null +++ b/drivers/net/ethernet/netronome/nfp/nfdk/ipsec.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* Copyright (C) 2023 Corigine, Inc */ + +#include <net/xfrm.h> + +#include "../nfp_net.h" +#include "nfdk.h" + +u64 nfp_nfdk_ipsec_tx(u64 flags, struct sk_buff *skb) +{ + struct xfrm_state *x = xfrm_input_state(skb); + + if (x->xso.dev && (x->xso.dev->features & NETIF_F_HW_ESP_TX_CSUM)) + flags |= NFDK_DESC_TX_L3_CSUM | NFDK_DESC_TX_L4_CSUM; + + return flags; +} diff --git a/drivers/net/ethernet/netronome/nfp/nfdk/nfdk.h b/drivers/net/ethernet/netronome/nfp/nfdk/nfdk.h index 0ea51d9f2325..fe55980348e9 100644 --- a/drivers/net/ethernet/netronome/nfp/nfdk/nfdk.h +++ b/drivers/net/ethernet/netronome/nfp/nfdk/nfdk.h @@ -125,4 +125,12 @@ nfp_nfdk_ctrl_tx_one(struct nfp_net *nn, struct nfp_net_r_vector *r_vec, void nfp_nfdk_ctrl_poll(struct tasklet_struct *t); void nfp_nfdk_rx_ring_fill_freelist(struct nfp_net_dp *dp, struct nfp_net_rx_ring *rx_ring); +#ifndef CONFIG_NFP_NET_IPSEC +static inline u64 nfp_nfdk_ipsec_tx(u64 flags, struct sk_buff *skb) +{ + return flags; +} +#else +u64 nfp_nfdk_ipsec_tx(u64 flags, struct sk_buff *skb); +#endif #endif