Message ID | 20220110015636.245666-8-dmichail@fungible.com (mailing list archive) |
---|---|
State | Deferred |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | new Fungible Ethernet driver | expand |
On Sun, 9 Jan 2022 17:56:35 -0800 Dimitris Michailidis wrote: > +static inline int fun_ktls_init(struct net_device *netdev) > +{ > + return -ENOTSUPP; ENOTSUPP is best avoided - EOPNOTSUPP is the proper error code which can be returned to user space if needed. But you should make this function void since the return value is ignored, anyway.
On Sun, 9 Jan 2022 17:56:35 -0800 Dimitris Michailidis wrote: > This provides the control pieces for kTLS Tx offload, implementinng the > offload operations. > > Signed-off-by: Dimitris Michailidis <dmichail@fungible.com> > --- > .../ethernet/fungible/funeth/funeth_ktls.c | 181 ++++++++++++++++++ > .../ethernet/fungible/funeth/funeth_ktls.h | 33 ++++ > 2 files changed, 214 insertions(+) > create mode 100644 drivers/net/ethernet/fungible/funeth/funeth_ktls.c > create mode 100644 drivers/net/ethernet/fungible/funeth/funeth_ktls.h > > diff --git a/drivers/net/ethernet/fungible/funeth/funeth_ktls.c b/drivers/net/ethernet/fungible/funeth/funeth_ktls.c > new file mode 100644 > index 000000000000..bdcf3365bb16 > --- /dev/null > +++ b/drivers/net/ethernet/fungible/funeth/funeth_ktls.c > @@ -0,0 +1,181 @@ > +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) > + > +#include "funeth.h" > +#include "funeth_ktls.h" > + > +static int fun_admin_ktls_create(struct funeth_priv *fp, unsigned int id) > +{ > + struct fun_admin_ktls_create_req req = { > + .common = FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_KTLS, > + sizeof(req)), > + .subop = FUN_ADMIN_SUBOP_CREATE, > + .id = cpu_to_be32(id), > + }; > + > + return fun_submit_admin_sync_cmd(fp->fdev, &req.common, NULL, 0, 0); > +} > + > +static int fun_ktls_add(struct net_device *netdev, struct sock *sk, > + enum tls_offload_ctx_dir direction, > + struct tls_crypto_info *crypto_info, > + u32 start_offload_tcp_sn) > +{ > + struct funeth_priv *fp = netdev_priv(netdev); > + struct fun_admin_ktls_modify_req req = { > + .common = FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_KTLS, > + sizeof(req)), > + .subop = FUN_ADMIN_SUBOP_MODIFY, > + .id = cpu_to_be32(fp->ktls_id), > + .tcp_seq = cpu_to_be32(start_offload_tcp_sn), > + }; > + struct fun_admin_ktls_modify_rsp rsp; > + struct fun_ktls_tx_ctx *tx_ctx; > + int rc; > + > + if (direction != TLS_OFFLOAD_CTX_DIR_TX) > + return -EOPNOTSUPP; > + > + if (crypto_info->version == TLS_1_2_VERSION) > + req.version = FUN_KTLS_TLSV2; > + else if (crypto_info->version == TLS_1_3_VERSION) > + req.version = FUN_KTLS_TLSV3; > + else > + return -EOPNOTSUPP; > + > + switch (crypto_info->cipher_type) { > + case TLS_CIPHER_AES_GCM_128: { > + struct tls12_crypto_info_aes_gcm_128 *c = (void *)crypto_info; > + > + req.cipher = FUN_KTLS_CIPHER_AES_GCM_128; > + memcpy(req.key, c->key, sizeof(c->key)); > + memcpy(req.iv, c->iv, sizeof(c->iv)); > + memcpy(req.salt, c->salt, sizeof(c->salt)); > + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); > + break; > + } > + > + case TLS_CIPHER_AES_GCM_256: { > + struct tls12_crypto_info_aes_gcm_256 *c = (void *)crypto_info; > + > + req.cipher = FUN_KTLS_CIPHER_AES_GCM_256; > + memcpy(req.key, c->key, sizeof(c->key)); > + memcpy(req.iv, c->iv, sizeof(c->iv)); > + memcpy(req.salt, c->salt, sizeof(c->salt)); > + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); > + break; > + } > + > + case TLS_CIPHER_CHACHA20_POLY1305: { > + struct tls12_crypto_info_chacha20_poly1305 *c; > + > + c = (void *)crypto_info; > + req.cipher = FUN_KTLS_CIPHER_CHACHA20_POLY1305; > + memcpy(req.key, c->key, sizeof(c->key)); > + memcpy(req.iv, c->iv, sizeof(c->iv)); > + memcpy(req.salt, c->salt, sizeof(c->salt)); > + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); > + break; > + } > + > + default: > + return -EOPNOTSUPP; > + } > + > + rc = fun_submit_admin_sync_cmd(fp->fdev, &req.common, &rsp, > + sizeof(rsp), 0); > + memzero_explicit(&req, sizeof(req)); > + if (rc) > + return rc; > + > + tx_ctx = tls_driver_ctx(sk, direction); > + tx_ctx->tlsid = rsp.tlsid; > + tx_ctx->next_seq = start_offload_tcp_sn; > + atomic64_inc(&fp->tx_tls_add); > + return 0; > +} > + > +static void fun_ktls_del(struct net_device *netdev, > + struct tls_context *tls_ctx, > + enum tls_offload_ctx_dir direction) > +{ > + struct funeth_priv *fp = netdev_priv(netdev); > + struct fun_admin_ktls_modify_req req; > + struct fun_ktls_tx_ctx *tx_ctx; > + > + if (direction != TLS_OFFLOAD_CTX_DIR_TX) > + return; > + > + tx_ctx = __tls_driver_ctx(tls_ctx, direction); > + > + req.common = FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_KTLS, > + offsetof(struct fun_admin_ktls_modify_req, tcp_seq)); > + req.subop = FUN_ADMIN_SUBOP_MODIFY; > + req.flags = cpu_to_be16(FUN_KTLS_MODIFY_REMOVE); > + req.id = cpu_to_be32(fp->ktls_id); > + req.tlsid = tx_ctx->tlsid; > + > + fun_submit_admin_sync_cmd(fp->fdev, &req.common, NULL, 0, 0); > + atomic64_inc(&fp->tx_tls_del); > +} > + > +static int fun_ktls_resync(struct net_device *netdev, struct sock *sk, u32 seq, > + u8 *rcd_sn, enum tls_offload_ctx_dir direction) > +{ > + struct funeth_priv *fp = netdev_priv(netdev); > + struct fun_admin_ktls_modify_req req; > + struct fun_ktls_tx_ctx *tx_ctx; > + int rc; > + > + if (direction != TLS_OFFLOAD_CTX_DIR_TX) > + return -EOPNOTSUPP; > + > + tx_ctx = tls_driver_ctx(sk, direction); > + > + req.common = FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_KTLS, > + offsetof(struct fun_admin_ktls_modify_req, key)); > + req.subop = FUN_ADMIN_SUBOP_MODIFY; > + req.flags = 0; > + req.id = cpu_to_be32(fp->ktls_id); > + req.tlsid = tx_ctx->tlsid; > + req.tcp_seq = cpu_to_be32(seq); > + req.version = 0; > + req.cipher = 0; > + memcpy(req.record_seq, rcd_sn, sizeof(req.record_seq)); > + > + atomic64_inc(&fp->tx_tls_resync); > + rc = fun_submit_admin_sync_cmd(fp->fdev, &req.common, NULL, 0, 0); > + if (!rc) > + tx_ctx->next_seq = seq; > + return rc; > +} > + > +static const struct tlsdev_ops fun_ktls_ops = { > + .tls_dev_add = fun_ktls_add, > + .tls_dev_del = fun_ktls_del, > + .tls_dev_resync = fun_ktls_resync, > +}; > + > +int fun_ktls_init(struct net_device *netdev) > +{ > + struct funeth_priv *fp = netdev_priv(netdev); > + int rc; > + > + rc = fun_admin_ktls_create(fp, netdev->dev_port); > + if (rc) > + return rc; > + > + fp->ktls_id = netdev->dev_port; > + netdev->tlsdev_ops = &fun_ktls_ops; > + netdev->hw_features |= NETIF_F_HW_TLS_TX; > + netdev->features |= NETIF_F_HW_TLS_TX; > + return 0; > +} > + > +void fun_ktls_cleanup(struct funeth_priv *fp) > +{ > + if (fp->ktls_id == FUN_HCI_ID_INVALID) > + return; > + > + fun_res_destroy(fp->fdev, FUN_ADMIN_OP_KTLS, 0, fp->ktls_id); > + fp->ktls_id = FUN_HCI_ID_INVALID; > +} > diff --git a/drivers/net/ethernet/fungible/funeth/funeth_ktls.h b/drivers/net/ethernet/fungible/funeth/funeth_ktls.h > new file mode 100644 > index 000000000000..1b433ac8cd7b > --- /dev/null > +++ b/drivers/net/ethernet/fungible/funeth/funeth_ktls.h > @@ -0,0 +1,33 @@ > +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ > + > +#ifndef _FUN_KTLS_H > +#define _FUN_KTLS_H > + > +struct net_device; > +struct funeth_priv; > + > +#ifdef CONFIG_TLS_DEVICE > +#include <net/tls.h> > + > +struct fun_ktls_tx_ctx { > + __be64 tlsid; > + u32 next_seq; > +}; > + > +int fun_ktls_init(struct net_device *netdev); > +void fun_ktls_cleanup(struct funeth_priv *fp); > + > +#else > +#include <linux/errno.h> > + > +static inline int fun_ktls_init(struct net_device *netdev) > +{ > + return -ENOTSUPP; > +} > + > +static inline void fun_ktls_cleanup(struct funeth_priv *fp) > +{ > +} > +#endif > + > +#endif /* _FUN_KTLS_H */
On Wed, 12 Jan 2022 14:35:32 -0800 Jakub Kicinski wrote: > > + if (crypto_info->version == TLS_1_2_VERSION) > > + req.version = FUN_KTLS_TLSV2; > > + else if (crypto_info->version == TLS_1_3_VERSION) > > + req.version = FUN_KTLS_TLSV3; I don't think offload of TLS 1.3 is supported by the kernel. > > + else > > + return -EOPNOTSUPP; > > + > > + switch (crypto_info->cipher_type) { > > + case TLS_CIPHER_AES_GCM_128: { > > + struct tls12_crypto_info_aes_gcm_128 *c = (void *)crypto_info; > > + > > + req.cipher = FUN_KTLS_CIPHER_AES_GCM_128; > > + memcpy(req.key, c->key, sizeof(c->key)); > > + memcpy(req.iv, c->iv, sizeof(c->iv)); > > + memcpy(req.salt, c->salt, sizeof(c->salt)); > > + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); > > + break; > > + } Neither are all the algos below. Please remove dead code. > > + case TLS_CIPHER_AES_GCM_256: { > > + struct tls12_crypto_info_aes_gcm_256 *c = (void *)crypto_info; > > + > > + req.cipher = FUN_KTLS_CIPHER_AES_GCM_256; > > + memcpy(req.key, c->key, sizeof(c->key)); > > + memcpy(req.iv, c->iv, sizeof(c->iv)); > > + memcpy(req.salt, c->salt, sizeof(c->salt)); > > + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); > > + break; > > + } > > + > > + case TLS_CIPHER_CHACHA20_POLY1305: { > > + struct tls12_crypto_info_chacha20_poly1305 *c; > > + > > + c = (void *)crypto_info; > > + req.cipher = FUN_KTLS_CIPHER_CHACHA20_POLY1305; > > + memcpy(req.key, c->key, sizeof(c->key)); > > + memcpy(req.iv, c->iv, sizeof(c->iv)); > > + memcpy(req.salt, c->salt, sizeof(c->salt)); > > + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); > > + break; > > + }
On Wed, Jan 12, 2022 at 2:40 PM Jakub Kicinski <kuba@kernel.org> wrote: > > On Wed, 12 Jan 2022 14:35:32 -0800 Jakub Kicinski wrote: > > > + if (crypto_info->version == TLS_1_2_VERSION) > > > + req.version = FUN_KTLS_TLSV2; > > > + else if (crypto_info->version == TLS_1_3_VERSION) > > > + req.version = FUN_KTLS_TLSV3; > > I don't think offload of TLS 1.3 is supported by the kernel. > > > > + else > > > + return -EOPNOTSUPP; > > > + > > > + switch (crypto_info->cipher_type) { > > > + case TLS_CIPHER_AES_GCM_128: { > > > + struct tls12_crypto_info_aes_gcm_128 *c = (void *)crypto_info; > > > + > > > + req.cipher = FUN_KTLS_CIPHER_AES_GCM_128; > > > + memcpy(req.key, c->key, sizeof(c->key)); > > > + memcpy(req.iv, c->iv, sizeof(c->iv)); > > > + memcpy(req.salt, c->salt, sizeof(c->salt)); > > > + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); > > > + break; > > > + } > > Neither are all the algos below. Please remove dead code. I've removed the TLS 1.3 pieces and the non-offloaded 1.2 algos. > > > > + case TLS_CIPHER_AES_GCM_256: { > > > + struct tls12_crypto_info_aes_gcm_256 *c = (void *)crypto_info; > > > + > > > + req.cipher = FUN_KTLS_CIPHER_AES_GCM_256; > > > + memcpy(req.key, c->key, sizeof(c->key)); > > > + memcpy(req.iv, c->iv, sizeof(c->iv)); > > > + memcpy(req.salt, c->salt, sizeof(c->salt)); > > > + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); > > > + break; > > > + } > > > + > > > + case TLS_CIPHER_CHACHA20_POLY1305: { > > > + struct tls12_crypto_info_chacha20_poly1305 *c; > > > + > > > + c = (void *)crypto_info; > > > + req.cipher = FUN_KTLS_CIPHER_CHACHA20_POLY1305; > > > + memcpy(req.key, c->key, sizeof(c->key)); > > > + memcpy(req.iv, c->iv, sizeof(c->iv)); > > > + memcpy(req.salt, c->salt, sizeof(c->salt)); > > > + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); > > > + break; > > > + }
diff --git a/drivers/net/ethernet/fungible/funeth/funeth_ktls.c b/drivers/net/ethernet/fungible/funeth/funeth_ktls.c new file mode 100644 index 000000000000..bdcf3365bb16 --- /dev/null +++ b/drivers/net/ethernet/fungible/funeth/funeth_ktls.c @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) + +#include "funeth.h" +#include "funeth_ktls.h" + +static int fun_admin_ktls_create(struct funeth_priv *fp, unsigned int id) +{ + struct fun_admin_ktls_create_req req = { + .common = FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_KTLS, + sizeof(req)), + .subop = FUN_ADMIN_SUBOP_CREATE, + .id = cpu_to_be32(id), + }; + + return fun_submit_admin_sync_cmd(fp->fdev, &req.common, NULL, 0, 0); +} + +static int fun_ktls_add(struct net_device *netdev, struct sock *sk, + enum tls_offload_ctx_dir direction, + struct tls_crypto_info *crypto_info, + u32 start_offload_tcp_sn) +{ + struct funeth_priv *fp = netdev_priv(netdev); + struct fun_admin_ktls_modify_req req = { + .common = FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_KTLS, + sizeof(req)), + .subop = FUN_ADMIN_SUBOP_MODIFY, + .id = cpu_to_be32(fp->ktls_id), + .tcp_seq = cpu_to_be32(start_offload_tcp_sn), + }; + struct fun_admin_ktls_modify_rsp rsp; + struct fun_ktls_tx_ctx *tx_ctx; + int rc; + + if (direction != TLS_OFFLOAD_CTX_DIR_TX) + return -EOPNOTSUPP; + + if (crypto_info->version == TLS_1_2_VERSION) + req.version = FUN_KTLS_TLSV2; + else if (crypto_info->version == TLS_1_3_VERSION) + req.version = FUN_KTLS_TLSV3; + else + return -EOPNOTSUPP; + + switch (crypto_info->cipher_type) { + case TLS_CIPHER_AES_GCM_128: { + struct tls12_crypto_info_aes_gcm_128 *c = (void *)crypto_info; + + req.cipher = FUN_KTLS_CIPHER_AES_GCM_128; + memcpy(req.key, c->key, sizeof(c->key)); + memcpy(req.iv, c->iv, sizeof(c->iv)); + memcpy(req.salt, c->salt, sizeof(c->salt)); + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); + break; + } + + case TLS_CIPHER_AES_GCM_256: { + struct tls12_crypto_info_aes_gcm_256 *c = (void *)crypto_info; + + req.cipher = FUN_KTLS_CIPHER_AES_GCM_256; + memcpy(req.key, c->key, sizeof(c->key)); + memcpy(req.iv, c->iv, sizeof(c->iv)); + memcpy(req.salt, c->salt, sizeof(c->salt)); + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); + break; + } + + case TLS_CIPHER_CHACHA20_POLY1305: { + struct tls12_crypto_info_chacha20_poly1305 *c; + + c = (void *)crypto_info; + req.cipher = FUN_KTLS_CIPHER_CHACHA20_POLY1305; + memcpy(req.key, c->key, sizeof(c->key)); + memcpy(req.iv, c->iv, sizeof(c->iv)); + memcpy(req.salt, c->salt, sizeof(c->salt)); + memcpy(req.record_seq, c->rec_seq, sizeof(c->rec_seq)); + break; + } + + default: + return -EOPNOTSUPP; + } + + rc = fun_submit_admin_sync_cmd(fp->fdev, &req.common, &rsp, + sizeof(rsp), 0); + memzero_explicit(&req, sizeof(req)); + if (rc) + return rc; + + tx_ctx = tls_driver_ctx(sk, direction); + tx_ctx->tlsid = rsp.tlsid; + tx_ctx->next_seq = start_offload_tcp_sn; + atomic64_inc(&fp->tx_tls_add); + return 0; +} + +static void fun_ktls_del(struct net_device *netdev, + struct tls_context *tls_ctx, + enum tls_offload_ctx_dir direction) +{ + struct funeth_priv *fp = netdev_priv(netdev); + struct fun_admin_ktls_modify_req req; + struct fun_ktls_tx_ctx *tx_ctx; + + if (direction != TLS_OFFLOAD_CTX_DIR_TX) + return; + + tx_ctx = __tls_driver_ctx(tls_ctx, direction); + + req.common = FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_KTLS, + offsetof(struct fun_admin_ktls_modify_req, tcp_seq)); + req.subop = FUN_ADMIN_SUBOP_MODIFY; + req.flags = cpu_to_be16(FUN_KTLS_MODIFY_REMOVE); + req.id = cpu_to_be32(fp->ktls_id); + req.tlsid = tx_ctx->tlsid; + + fun_submit_admin_sync_cmd(fp->fdev, &req.common, NULL, 0, 0); + atomic64_inc(&fp->tx_tls_del); +} + +static int fun_ktls_resync(struct net_device *netdev, struct sock *sk, u32 seq, + u8 *rcd_sn, enum tls_offload_ctx_dir direction) +{ + struct funeth_priv *fp = netdev_priv(netdev); + struct fun_admin_ktls_modify_req req; + struct fun_ktls_tx_ctx *tx_ctx; + int rc; + + if (direction != TLS_OFFLOAD_CTX_DIR_TX) + return -EOPNOTSUPP; + + tx_ctx = tls_driver_ctx(sk, direction); + + req.common = FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_KTLS, + offsetof(struct fun_admin_ktls_modify_req, key)); + req.subop = FUN_ADMIN_SUBOP_MODIFY; + req.flags = 0; + req.id = cpu_to_be32(fp->ktls_id); + req.tlsid = tx_ctx->tlsid; + req.tcp_seq = cpu_to_be32(seq); + req.version = 0; + req.cipher = 0; + memcpy(req.record_seq, rcd_sn, sizeof(req.record_seq)); + + atomic64_inc(&fp->tx_tls_resync); + rc = fun_submit_admin_sync_cmd(fp->fdev, &req.common, NULL, 0, 0); + if (!rc) + tx_ctx->next_seq = seq; + return rc; +} + +static const struct tlsdev_ops fun_ktls_ops = { + .tls_dev_add = fun_ktls_add, + .tls_dev_del = fun_ktls_del, + .tls_dev_resync = fun_ktls_resync, +}; + +int fun_ktls_init(struct net_device *netdev) +{ + struct funeth_priv *fp = netdev_priv(netdev); + int rc; + + rc = fun_admin_ktls_create(fp, netdev->dev_port); + if (rc) + return rc; + + fp->ktls_id = netdev->dev_port; + netdev->tlsdev_ops = &fun_ktls_ops; + netdev->hw_features |= NETIF_F_HW_TLS_TX; + netdev->features |= NETIF_F_HW_TLS_TX; + return 0; +} + +void fun_ktls_cleanup(struct funeth_priv *fp) +{ + if (fp->ktls_id == FUN_HCI_ID_INVALID) + return; + + fun_res_destroy(fp->fdev, FUN_ADMIN_OP_KTLS, 0, fp->ktls_id); + fp->ktls_id = FUN_HCI_ID_INVALID; +} diff --git a/drivers/net/ethernet/fungible/funeth/funeth_ktls.h b/drivers/net/ethernet/fungible/funeth/funeth_ktls.h new file mode 100644 index 000000000000..1b433ac8cd7b --- /dev/null +++ b/drivers/net/ethernet/fungible/funeth/funeth_ktls.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ + +#ifndef _FUN_KTLS_H +#define _FUN_KTLS_H + +struct net_device; +struct funeth_priv; + +#ifdef CONFIG_TLS_DEVICE +#include <net/tls.h> + +struct fun_ktls_tx_ctx { + __be64 tlsid; + u32 next_seq; +}; + +int fun_ktls_init(struct net_device *netdev); +void fun_ktls_cleanup(struct funeth_priv *fp); + +#else +#include <linux/errno.h> + +static inline int fun_ktls_init(struct net_device *netdev) +{ + return -ENOTSUPP; +} + +static inline void fun_ktls_cleanup(struct funeth_priv *fp) +{ +} +#endif + +#endif /* _FUN_KTLS_H */
This provides the control pieces for kTLS Tx offload, implementinng the offload operations. Signed-off-by: Dimitris Michailidis <dmichail@fungible.com> --- .../ethernet/fungible/funeth/funeth_ktls.c | 181 ++++++++++++++++++ .../ethernet/fungible/funeth/funeth_ktls.h | 33 ++++ 2 files changed, 214 insertions(+) create mode 100644 drivers/net/ethernet/fungible/funeth/funeth_ktls.c create mode 100644 drivers/net/ethernet/fungible/funeth/funeth_ktls.h