Commit e467b283 authored by Lior Nahmanson's avatar Lior Nahmanson Committed by David S. Miller

net/mlx5e: Add MACsec TX steering rules

Tx flow steering consists of two flow tables (FTs).

The first FT (crypto table) has two fixed rules:
One default miss rule so non MACsec offloaded packets bypass the MACSec
tables, another rule to make sure that MACsec key exchange (MKE) traffic
passes unencrypted as expected (matched of ethertype).
On each new MACsec offload flow, a new MACsec rule is added.
This rule is matched on metadata_reg_a (which contains the id of the
flow) and invokes the MACsec offload action on match.

The second FT (check table) has two fixed rules:
One rule for verifying that the previous offload actions were
finished successfully and packet need to be transmitted.
Another default rule for dropping packets that were failed in the
offload actions.

The MACsec FTs should be created on demand when the first MACsec rule is
added and destroyed when the last MACsec rule is deleted.
Signed-off-by: default avatarLior Nahmanson <liorna@nvidia.com>
Reviewed-by: default avatarRaed Salem <raeds@nvidia.com>
Signed-off-by: default avatarRaed Salem <raeds@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ee534d7f
......@@ -92,7 +92,7 @@ mlx5_core-$(CONFIG_MLX5_CORE_IPOIB) += ipoib/ipoib.o ipoib/ethtool.o ipoib/ipoib
#
mlx5_core-$(CONFIG_MLX5_FPGA) += fpga/cmd.o fpga/core.o fpga/conn.o fpga/sdk.o
mlx5_core-$(CONFIG_MLX5_EN_MACSEC) += en_accel/macsec.o
mlx5_core-$(CONFIG_MLX5_EN_MACSEC) += en_accel/macsec.o en_accel/macsec_fs.o
mlx5_core-$(CONFIG_MLX5_EN_IPSEC) += en_accel/ipsec.o en_accel/ipsec_rxtx.o \
en_accel/ipsec_stats.o en_accel/ipsec_fs.o \
......
......@@ -7,6 +7,7 @@
#include "en.h"
#include "lib/mlx5.h"
#include "en_accel/macsec.h"
#include "en_accel/macsec_fs.h"
#define MLX5_MACSEC_ASO_INC_SN 0x2
#define MLX5_MACSEC_ASO_REG_C_4_5 0x2
......@@ -18,9 +19,12 @@ struct mlx5e_macsec_sa {
u32 enc_key_id;
u32 next_pn;
sci_t sci;
struct mlx5e_macsec_tx_rule *tx_rule;
};
struct mlx5e_macsec {
struct mlx5e_macsec_fs *macsec_fs;
struct mlx5e_macsec_sa *tx_sa[MACSEC_NUM_AN];
struct mutex lock; /* Protects mlx5e_macsec internal contexts */
......@@ -90,18 +94,26 @@ static void mlx5e_macsec_destroy_object(struct mlx5_core_dev *mdev, u32 macsec_o
mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
}
static void mlx5e_macsec_cleanup_object(struct mlx5e_macsec *macsec,
struct mlx5e_macsec_sa *sa)
static void mlx5e_macsec_cleanup_sa(struct mlx5e_macsec *macsec, struct mlx5e_macsec_sa *sa)
{
if (!sa->tx_rule)
return;
mlx5e_macsec_fs_del_rule(macsec->macsec_fs, sa->tx_rule,
MLX5_ACCEL_MACSEC_ACTION_ENCRYPT);
mlx5e_macsec_destroy_object(macsec->mdev, sa->macsec_obj_id);
sa->tx_rule = NULL;
}
static int mlx5e_macsec_init_object(struct macsec_context *ctx,
struct mlx5e_macsec_sa *sa,
bool encrypt)
static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
struct mlx5e_macsec_sa *sa,
bool encrypt)
{
struct mlx5e_priv *priv = netdev_priv(ctx->netdev);
struct mlx5e_macsec *macsec = priv->macsec;
struct mlx5_macsec_rule_attrs rule_attrs;
struct mlx5e_macsec_tx_rule *tx_rule;
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5_macsec_obj_attrs obj_attrs;
int err;
......@@ -116,7 +128,21 @@ static int mlx5e_macsec_init_object(struct macsec_context *ctx,
if (err)
return err;
rule_attrs.macsec_obj_id = sa->macsec_obj_id;
rule_attrs.action = MLX5_ACCEL_MACSEC_ACTION_ENCRYPT;
tx_rule = mlx5e_macsec_fs_add_rule(macsec->macsec_fs, ctx, &rule_attrs);
if (IS_ERR_OR_NULL(tx_rule))
goto destroy_macsec_object;
sa->tx_rule = tx_rule;
return 0;
destroy_macsec_object:
mlx5e_macsec_destroy_object(mdev, sa->macsec_obj_id);
return err;
}
static int mlx5e_macsec_add_txsa(struct macsec_context *ctx)
......@@ -168,7 +194,7 @@ static int mlx5e_macsec_add_txsa(struct macsec_context *ctx)
!tx_sa->active)
goto out;
err = mlx5e_macsec_init_object(ctx, tx_sa, tx_sc->encrypt);
err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt);
if (err)
goto destroy_encryption_key;
......@@ -228,15 +254,17 @@ static int mlx5e_macsec_upd_txsa(struct macsec_context *ctx)
goto out;
if (ctx_tx_sa->active) {
err = mlx5e_macsec_init_object(ctx, tx_sa, tx_sc->encrypt);
err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt);
if (err)
goto out;
} else {
mlx5e_macsec_cleanup_object(macsec, tx_sa);
if (!tx_sa->tx_rule)
return -EINVAL;
mlx5e_macsec_cleanup_sa(macsec, tx_sa);
}
tx_sa->active = ctx_tx_sa->active;
out:
mutex_unlock(&macsec->lock);
......@@ -246,7 +274,6 @@ static int mlx5e_macsec_upd_txsa(struct macsec_context *ctx)
static int mlx5e_macsec_del_txsa(struct macsec_context *ctx)
{
struct mlx5e_priv *priv = netdev_priv(ctx->netdev);
struct mlx5_core_dev *mdev = priv->mdev;
u8 assoc_num = ctx->sa.assoc_num;
struct mlx5e_macsec_sa *tx_sa;
struct mlx5e_macsec *macsec;
......@@ -266,10 +293,8 @@ static int mlx5e_macsec_del_txsa(struct macsec_context *ctx)
goto out;
}
mlx5e_macsec_cleanup_object(macsec, tx_sa);
mlx5_destroy_encryption_key(mdev, tx_sa->enc_key_id);
mlx5e_macsec_cleanup_sa(macsec, tx_sa);
mlx5_destroy_encryption_key(macsec->mdev, tx_sa->enc_key_id);
kfree(tx_sa);
macsec->tx_sa[assoc_num] = NULL;
......@@ -334,6 +359,7 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
{
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5e_macsec *macsec = NULL;
struct mlx5e_macsec_fs *macsec_fs;
int err;
if (!mlx5e_is_macsec_device(priv->mdev)) {
......@@ -359,12 +385,21 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
macsec->mdev = mdev;
macsec_fs = mlx5e_macsec_fs_init(mdev, priv->netdev);
if (IS_ERR_OR_NULL(macsec_fs))
goto err_out;
macsec->macsec_fs = macsec_fs;
mlx5_core_dbg(mdev, "MACsec attached to netdevice\n");
return 0;
err_out:
mlx5_core_dealloc_pd(priv->mdev, macsec->aso_pdn);
err_pd:
kfree(macsec);
priv->macsec = NULL;
return err;
}
......@@ -375,6 +410,8 @@ void mlx5e_macsec_cleanup(struct mlx5e_priv *priv)
if (!macsec)
return;
mlx5e_macsec_fs_cleanup(macsec->macsec_fs);
priv->macsec = NULL;
mlx5_core_dealloc_pd(priv->mdev, macsec->aso_pdn);
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
#ifndef __MLX5_MACSEC_STEERING_H__
#define __MLX5_MACSEC_STEERING_H__
#ifdef CONFIG_MLX5_EN_MACSEC
#include "en_accel/macsec.h"
#define MLX5_MACSEC_NUM_OF_SUPPORTED_INTERFACES 16
struct mlx5e_macsec_fs;
struct mlx5e_macsec_tx_rule;
struct mlx5_macsec_rule_attrs {
u32 macsec_obj_id;
int action;
};
enum mlx5_macsec_action {
MLX5_ACCEL_MACSEC_ACTION_ENCRYPT,
};
void mlx5e_macsec_fs_cleanup(struct mlx5e_macsec_fs *macsec_fs);
struct mlx5e_macsec_fs *
mlx5e_macsec_fs_init(struct mlx5_core_dev *mdev, struct net_device *netdev);
struct mlx5e_macsec_tx_rule *
mlx5e_macsec_fs_add_rule(struct mlx5e_macsec_fs *macsec_fs,
const struct macsec_context *ctx,
struct mlx5_macsec_rule_attrs *attrs);
void mlx5e_macsec_fs_del_rule(struct mlx5e_macsec_fs *macsec_fs,
struct mlx5e_macsec_tx_rule *macsec_rule,
int action);
#endif
#endif /* __MLX5_MACSEC_STEERING_H__ */
......@@ -252,6 +252,7 @@ enum {
enum {
MLX5_ETH_WQE_FT_META_IPSEC = BIT(0),
MLX5_ETH_WQE_FT_META_MACSEC = BIT(1),
};
struct mlx5_wqe_eth_seg {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment