Skip to content

Commit 9515978

Browse files
Lior Nahmansondavem330
authored andcommitted
net/mlx5e: Implement MACsec Tx data path using MACsec skb_metadata_dst
MACsec driver marks Tx packets for device offload using a dedicated skb_metadata_dst which holds a 64 bits SCI number. A previously set rule will match on this number so the correct SA is used for the MACsec operation. As device driver can only provide 32 bits of metadata to flow tables, need to used a mapping from 64 bit to 32 bits marker or id, which is can be achieved by provide a 32 bit unique flow id in the control path, and used a hash table to map 64 bit to the unique id in the datapath. Signed-off-by: Lior Nahmanson <liorna@nvidia.com> Reviewed-by: Raed Salem <raeds@nvidia.com> Signed-off-by: Raed Salem <raeds@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent e467b28 commit 9515978

File tree

6 files changed

+119
-8
lines changed

6 files changed

+119
-8
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "en_accel/ipsec_rxtx.h"
4040
#include "en_accel/ktls.h"
4141
#include "en_accel/ktls_txrx.h"
42+
#include <en_accel/macsec.h>
4243
#include "en.h"
4344
#include "en/txrx.h"
4445

@@ -137,6 +138,15 @@ static inline bool mlx5e_accel_tx_begin(struct net_device *dev,
137138
}
138139
#endif
139140

141+
#ifdef CONFIG_MLX5_EN_MACSEC
142+
if (unlikely(mlx5e_macsec_skb_is_offload(skb))) {
143+
struct mlx5e_priv *priv = netdev_priv(dev);
144+
145+
if (unlikely(!mlx5e_macsec_handle_tx_skb(priv->macsec, skb)))
146+
return false;
147+
}
148+
#endif
149+
140150
return true;
141151
}
142152

@@ -163,6 +173,11 @@ static inline void mlx5e_accel_tx_eseg(struct mlx5e_priv *priv,
163173
mlx5e_ipsec_tx_build_eseg(priv, skb, eseg);
164174
#endif
165175

176+
#ifdef CONFIG_MLX5_EN_MACSEC
177+
if (unlikely(mlx5e_macsec_skb_is_offload(skb)))
178+
mlx5e_macsec_tx_build_eseg(priv->macsec, skb, eseg);
179+
#endif
180+
166181
#if IS_ENABLED(CONFIG_GENEVE)
167182
if (skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL)
168183
mlx5e_tx_tunnel_accel(skb, eseg, ihs);

drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,18 @@ struct mlx5e_macsec_sa {
2020
u32 next_pn;
2121
sci_t sci;
2222

23+
struct rhash_head hash;
24+
u32 fs_id;
2325
struct mlx5e_macsec_tx_rule *tx_rule;
26+
struct rcu_head rcu_head;
27+
};
28+
29+
static const struct rhashtable_params rhash_sci = {
30+
.key_len = sizeof_field(struct mlx5e_macsec_sa, sci),
31+
.key_offset = offsetof(struct mlx5e_macsec_sa, sci),
32+
.head_offset = offsetof(struct mlx5e_macsec_sa, hash),
33+
.automatic_shrinking = true,
34+
.min_size = 1,
2435
};
2536

2637
struct mlx5e_macsec {
@@ -31,6 +42,9 @@ struct mlx5e_macsec {
3142
/* Global PD for MACsec object ASO context */
3243
u32 aso_pdn;
3344

45+
/* Tx sci -> fs id mapping handling */
46+
struct rhashtable sci_hash; /* sci -> mlx5e_macsec_sa */
47+
3448
struct mlx5_core_dev *mdev;
3549
};
3650

@@ -96,6 +110,11 @@ static void mlx5e_macsec_destroy_object(struct mlx5_core_dev *mdev, u32 macsec_o
96110

97111
static void mlx5e_macsec_cleanup_sa(struct mlx5e_macsec *macsec, struct mlx5e_macsec_sa *sa)
98112
{
113+
if (sa->fs_id) {
114+
/* Make sure ongoing datapath readers sees a valid SA */
115+
rhashtable_remove_fast(&macsec->sci_hash, &sa->hash, rhash_sci);
116+
sa->fs_id = 0;
117+
}
99118

100119
if (!sa->tx_rule)
101120
return;
@@ -131,14 +150,19 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
131150
rule_attrs.macsec_obj_id = sa->macsec_obj_id;
132151
rule_attrs.action = MLX5_ACCEL_MACSEC_ACTION_ENCRYPT;
133152

134-
tx_rule = mlx5e_macsec_fs_add_rule(macsec->macsec_fs, ctx, &rule_attrs);
153+
tx_rule = mlx5e_macsec_fs_add_rule(macsec->macsec_fs, ctx, &rule_attrs, &sa->fs_id);
135154
if (IS_ERR_OR_NULL(tx_rule))
136155
goto destroy_macsec_object;
137156

138-
sa->tx_rule = tx_rule;
157+
err = rhashtable_insert_fast(&macsec->sci_hash, &sa->hash, rhash_sci);
158+
if (err)
159+
goto destroy_macsec_rule;
139160

161+
sa->tx_rule = tx_rule;
140162
return 0;
141163

164+
destroy_macsec_rule:
165+
mlx5e_macsec_fs_del_rule(macsec->macsec_fs, tx_rule, MLX5_ACCEL_MACSEC_ACTION_ENCRYPT);
142166
destroy_macsec_object:
143167
mlx5e_macsec_destroy_object(mdev, sa->macsec_obj_id);
144168

@@ -295,7 +319,7 @@ static int mlx5e_macsec_del_txsa(struct macsec_context *ctx)
295319

296320
mlx5e_macsec_cleanup_sa(macsec, tx_sa);
297321
mlx5_destroy_encryption_key(macsec->mdev, tx_sa->enc_key_id);
298-
kfree(tx_sa);
322+
kfree_rcu(tx_sa);
299323
macsec->tx_sa[assoc_num] = NULL;
300324

301325
out:
@@ -304,6 +328,20 @@ static int mlx5e_macsec_del_txsa(struct macsec_context *ctx)
304328
return err;
305329
}
306330

331+
static u32 mlx5e_macsec_get_sa_from_hashtable(struct rhashtable *sci_hash, sci_t *sci)
332+
{
333+
struct mlx5e_macsec_sa *macsec_sa;
334+
u32 fs_id = 0;
335+
336+
rcu_read_lock();
337+
macsec_sa = rhashtable_lookup(sci_hash, sci, rhash_sci);
338+
if (macsec_sa)
339+
fs_id = macsec_sa->fs_id;
340+
rcu_read_unlock();
341+
342+
return fs_id;
343+
}
344+
307345
static bool mlx5e_is_macsec_device(const struct mlx5_core_dev *mdev)
308346
{
309347
if (!(MLX5_CAP_GEN_64(mdev, general_obj_types) &
@@ -341,6 +379,36 @@ static const struct macsec_ops macsec_offload_ops = {
341379
.mdo_del_txsa = mlx5e_macsec_del_txsa,
342380
};
343381

382+
bool mlx5e_macsec_handle_tx_skb(struct mlx5e_macsec *macsec, struct sk_buff *skb)
383+
{
384+
struct metadata_dst *md_dst = skb_metadata_dst(skb);
385+
u32 fs_id;
386+
387+
fs_id = mlx5e_macsec_get_sa_from_hashtable(&macsec->sci_hash, &md_dst->u.macsec_info.sci);
388+
if (!fs_id)
389+
goto err_out;
390+
391+
return true;
392+
393+
err_out:
394+
dev_kfree_skb_any(skb);
395+
return false;
396+
}
397+
398+
void mlx5e_macsec_tx_build_eseg(struct mlx5e_macsec *macsec,
399+
struct sk_buff *skb,
400+
struct mlx5_wqe_eth_seg *eseg)
401+
{
402+
struct metadata_dst *md_dst = skb_metadata_dst(skb);
403+
u32 fs_id;
404+
405+
fs_id = mlx5e_macsec_get_sa_from_hashtable(&macsec->sci_hash, &md_dst->u.macsec_info.sci);
406+
if (!fs_id)
407+
return;
408+
409+
eseg->flow_table_metadata = cpu_to_be32(MLX5_ETH_WQE_FT_META_MACSEC | fs_id << 2);
410+
}
411+
344412
void mlx5e_macsec_build_netdev(struct mlx5e_priv *priv)
345413
{
346414
struct net_device *netdev = priv->netdev;
@@ -381,6 +449,13 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
381449
goto err_pd;
382450
}
383451

452+
err = rhashtable_init(&macsec->sci_hash, &rhash_sci);
453+
if (err) {
454+
mlx5_core_err(mdev, "MACsec offload: Failed to init SCI hash table, err=%d\n",
455+
err);
456+
goto err_out;
457+
}
458+
384459
priv->macsec = macsec;
385460

386461
macsec->mdev = mdev;
@@ -416,6 +491,8 @@ void mlx5e_macsec_cleanup(struct mlx5e_priv *priv)
416491

417492
mlx5_core_dealloc_pd(priv->mdev, macsec->aso_pdn);
418493

494+
rhashtable_destroy(&macsec->sci_hash);
495+
419496
mutex_destroy(&macsec->lock);
420497

421498
kfree(macsec);

drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,32 @@
88

99
#include <linux/mlx5/driver.h>
1010
#include <net/macsec.h>
11+
#include <net/dst_metadata.h>
1112

1213
struct mlx5e_priv;
14+
struct mlx5e_macsec;
1315

1416
void mlx5e_macsec_build_netdev(struct mlx5e_priv *priv);
1517
int mlx5e_macsec_init(struct mlx5e_priv *priv);
1618
void mlx5e_macsec_cleanup(struct mlx5e_priv *priv);
19+
bool mlx5e_macsec_handle_tx_skb(struct mlx5e_macsec *macsec, struct sk_buff *skb);
20+
void mlx5e_macsec_tx_build_eseg(struct mlx5e_macsec *macsec,
21+
struct sk_buff *skb,
22+
struct mlx5_wqe_eth_seg *eseg);
23+
24+
static inline bool mlx5e_macsec_skb_is_offload(struct sk_buff *skb)
25+
{
26+
struct metadata_dst *md_dst = skb_metadata_dst(skb);
27+
28+
return md_dst && (md_dst->type == METADATA_MACSEC);
29+
}
1730

1831
#else
1932

2033
static inline void mlx5e_macsec_build_netdev(struct mlx5e_priv *priv) {}
2134
static inline int mlx5e_macsec_init(struct mlx5e_priv *priv) { return 0; }
2235
static inline void mlx5e_macsec_cleanup(struct mlx5e_priv *priv) {}
36+
static inline bool mlx5e_macsec_skb_is_offload(struct sk_buff *skb) { return false; }
2337

2438
#endif /* CONFIG_MLX5_EN_MACSEC */
2539

drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,8 @@ static void macsec_fs_tx_del_rule(struct mlx5e_macsec_fs *macsec_fs,
464464
static struct mlx5e_macsec_tx_rule *
465465
macsec_fs_tx_add_rule(struct mlx5e_macsec_fs *macsec_fs,
466466
const struct macsec_context *macsec_ctx,
467-
struct mlx5_macsec_rule_attrs *attrs)
467+
struct mlx5_macsec_rule_attrs *attrs,
468+
u32 *sa_fs_id)
468469
{
469470
char reformatbf[MLX5_MACSEC_TAG_LEN + MACSEC_SCI_LEN];
470471
struct mlx5_pkt_reformat_params reformat_params = {};
@@ -518,6 +519,7 @@ macsec_fs_tx_add_rule(struct mlx5e_macsec_fs *macsec_fs,
518519
}
519520

520521
tx_rule->fs_id = fs_id;
522+
*sa_fs_id = fs_id;
521523

522524
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
523525
MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT |
@@ -626,10 +628,11 @@ static int macsec_fs_tx_init(struct mlx5e_macsec_fs *macsec_fs)
626628
struct mlx5e_macsec_tx_rule *
627629
mlx5e_macsec_fs_add_rule(struct mlx5e_macsec_fs *macsec_fs,
628630
const struct macsec_context *macsec_ctx,
629-
struct mlx5_macsec_rule_attrs *attrs)
631+
struct mlx5_macsec_rule_attrs *attrs,
632+
u32 *sa_fs_id)
630633
{
631634
if (attrs->action == MLX5_ACCEL_MACSEC_ACTION_ENCRYPT)
632-
return macsec_fs_tx_add_rule(macsec_fs, macsec_ctx, attrs);
635+
return macsec_fs_tx_add_rule(macsec_fs, macsec_ctx, attrs, sa_fs_id);
633636

634637
return NULL;
635638
}

drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ mlx5e_macsec_fs_init(struct mlx5_core_dev *mdev, struct net_device *netdev);
3030
struct mlx5e_macsec_tx_rule *
3131
mlx5e_macsec_fs_add_rule(struct mlx5e_macsec_fs *macsec_fs,
3232
const struct macsec_context *ctx,
33-
struct mlx5_macsec_rule_attrs *attrs);
33+
struct mlx5_macsec_rule_attrs *attrs,
34+
u32 *sa_fs_id);
3435

3536
void mlx5e_macsec_fs_del_rule(struct mlx5e_macsec_fs *macsec_fs,
3637
struct mlx5e_macsec_tx_rule *macsec_rule,

drivers/net/ethernet/mellanox/mlx5/core/en_tx.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "ipoib/ipoib.h"
4040
#include "en_accel/en_accel.h"
4141
#include "en_accel/ipsec_rxtx.h"
42+
#include "en_accel/macsec.h"
4243
#include "en/ptp.h"
4344
#include <net/ipv6.h>
4445

@@ -485,7 +486,7 @@ mlx5e_sq_xmit_wqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
485486
static bool mlx5e_tx_skb_supports_mpwqe(struct sk_buff *skb, struct mlx5e_tx_attr *attr)
486487
{
487488
return !skb_is_nonlinear(skb) && !skb_vlan_tag_present(skb) && !attr->ihs &&
488-
!attr->insz;
489+
!attr->insz && !mlx5e_macsec_skb_is_offload(skb);
489490
}
490491

491492
static bool mlx5e_tx_mpwqe_same_eseg(struct mlx5e_txqsq *sq, struct mlx5_wqe_eth_seg *eseg)

0 commit comments

Comments
 (0)