Skip to content

Commit 3b20949

Browse files
Lior Nahmansondavem330
authored andcommitted
net/mlx5e: Add MACsec RX steering rules
Rx flow steering consists of two flow tables (FTs). The first FT (crypto table) have one default miss rule so non MACsec offloaded packets bypass the MACSec tables. All others flow table entries (FTEs) are divided to two equal groups size, both of them are for MACsec packets: The first group is for MACsec packets which contains SCI field in the SecTAG header. The second group is for MACsec packets which doesn't contain SCI, where need to match on the source MAC address (only if the SCI is built from default MACsec port). Destination MAC address, ethertype and some of SecTAG fields are also matched for both groups. In case of match, invoke decrypt action on the packet. For each MACsec Rx offloaded SA two rules are created: one with SCI and one without SCI. The second FT (check table) has two fixed rules: One rule is for verifying that the previous offload actions were finished successfully. In this case, need to decap the SecTAG header and forward the packet for further processing. Another default rule for dropping packets that failed in the previous decrypt actions. The MACsec FTs are created on demand when the first MACsec rule is added and destroyed when the last MACsec rule is deleted. Signed-off-by: Lior Nahmanson <liorna@nvidia.com> Reviewed-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 15d187e commit 3b20949

File tree

3 files changed

+823
-95
lines changed

3 files changed

+823
-95
lines changed

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

Lines changed: 77 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <linux/mlx5/device.h>
55
#include <linux/mlx5/mlx5_ifc.h>
6+
#include <linux/xarray.h>
67

78
#include "en.h"
89
#include "lib/mlx5.h"
@@ -22,15 +23,22 @@ struct mlx5e_macsec_sa {
2223

2324
struct rhash_head hash;
2425
u32 fs_id;
25-
struct mlx5e_macsec_tx_rule *tx_rule;
26+
union mlx5e_macsec_rule *macsec_rule;
2627
struct rcu_head rcu_head;
2728
};
2829

30+
struct mlx5e_macsec_rx_sc;
31+
struct mlx5e_macsec_rx_sc_xarray_element {
32+
u32 fs_id;
33+
struct mlx5e_macsec_rx_sc *rx_sc;
34+
};
35+
2936
struct mlx5e_macsec_rx_sc {
3037
bool active;
3138
sci_t sci;
3239
struct mlx5e_macsec_sa *rx_sa[MACSEC_NUM_AN];
3340
struct list_head rx_sc_list_element;
41+
struct mlx5e_macsec_rx_sc_xarray_element *sc_xarray_element;
3442
struct rcu_head rcu_head;
3543
};
3644

@@ -54,6 +62,9 @@ struct mlx5e_macsec {
5462
/* Tx sci -> fs id mapping handling */
5563
struct rhashtable sci_hash; /* sci -> mlx5e_macsec_sa */
5664

65+
/* Rx fs_id -> rx_sc mapping */
66+
struct xarray sc_xarray;
67+
5768
struct mlx5_core_dev *mdev;
5869
};
5970

@@ -120,21 +131,25 @@ static void mlx5e_macsec_destroy_object(struct mlx5_core_dev *mdev, u32 macsec_o
120131
mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
121132
}
122133

123-
static void mlx5e_macsec_cleanup_sa(struct mlx5e_macsec *macsec, struct mlx5e_macsec_sa *sa)
134+
static void mlx5e_macsec_cleanup_sa(struct mlx5e_macsec *macsec,
135+
struct mlx5e_macsec_sa *sa,
136+
bool is_tx)
124137
{
125-
if (sa->fs_id) {
138+
int action = (is_tx) ? MLX5_ACCEL_MACSEC_ACTION_ENCRYPT :
139+
MLX5_ACCEL_MACSEC_ACTION_DECRYPT;
140+
141+
if ((is_tx) && sa->fs_id) {
126142
/* Make sure ongoing datapath readers sees a valid SA */
127143
rhashtable_remove_fast(&macsec->sci_hash, &sa->hash, rhash_sci);
128144
sa->fs_id = 0;
129145
}
130146

131-
if (!sa->tx_rule)
147+
if (!sa->macsec_rule)
132148
return;
133149

134-
mlx5e_macsec_fs_del_rule(macsec->macsec_fs, sa->tx_rule,
135-
MLX5_ACCEL_MACSEC_ACTION_ENCRYPT);
150+
mlx5e_macsec_fs_del_rule(macsec->macsec_fs, sa->macsec_rule, action);
136151
mlx5e_macsec_destroy_object(macsec->mdev, sa->macsec_obj_id);
137-
sa->tx_rule = NULL;
152+
sa->macsec_rule = NULL;
138153
}
139154

140155
static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
@@ -145,9 +160,9 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
145160
struct mlx5e_priv *priv = netdev_priv(ctx->netdev);
146161
struct mlx5e_macsec *macsec = priv->macsec;
147162
struct mlx5_macsec_rule_attrs rule_attrs;
148-
struct mlx5e_macsec_tx_rule *tx_rule;
149163
struct mlx5_core_dev *mdev = priv->mdev;
150164
struct mlx5_macsec_obj_attrs obj_attrs;
165+
union mlx5e_macsec_rule *macsec_rule;
151166
int err;
152167

153168
obj_attrs.next_pn = sa->next_pn;
@@ -161,21 +176,27 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
161176
return err;
162177

163178
rule_attrs.macsec_obj_id = sa->macsec_obj_id;
164-
rule_attrs.action = MLX5_ACCEL_MACSEC_ACTION_ENCRYPT;
179+
rule_attrs.sci = sa->sci;
180+
rule_attrs.assoc_num = sa->assoc_num;
181+
rule_attrs.action = (is_tx) ? MLX5_ACCEL_MACSEC_ACTION_ENCRYPT :
182+
MLX5_ACCEL_MACSEC_ACTION_DECRYPT;
165183

166-
tx_rule = mlx5e_macsec_fs_add_rule(macsec->macsec_fs, ctx, &rule_attrs, &sa->fs_id);
167-
if (IS_ERR_OR_NULL(tx_rule))
184+
macsec_rule = mlx5e_macsec_fs_add_rule(macsec->macsec_fs, ctx, &rule_attrs, &sa->fs_id);
185+
if (IS_ERR_OR_NULL(macsec_rule))
168186
goto destroy_macsec_object;
169187

170-
err = rhashtable_insert_fast(&macsec->sci_hash, &sa->hash, rhash_sci);
171-
if (err)
172-
goto destroy_macsec_rule;
188+
sa->macsec_rule = macsec_rule;
189+
190+
if (is_tx) {
191+
err = rhashtable_insert_fast(&macsec->sci_hash, &sa->hash, rhash_sci);
192+
if (err)
193+
goto destroy_macsec_object_and_rule;
194+
}
173195

174-
sa->tx_rule = tx_rule;
175196
return 0;
176197

177-
destroy_macsec_rule:
178-
mlx5e_macsec_fs_del_rule(macsec->macsec_fs, tx_rule, MLX5_ACCEL_MACSEC_ACTION_ENCRYPT);
198+
destroy_macsec_object_and_rule:
199+
mlx5e_macsec_cleanup_sa(macsec, sa, is_tx);
179200
destroy_macsec_object:
180201
mlx5e_macsec_destroy_object(mdev, sa->macsec_obj_id);
181202

@@ -208,7 +229,7 @@ static int mlx5e_macsec_update_rx_sa(struct mlx5e_macsec *macsec,
208229

209230
rx_sa->active = active;
210231
if (!active) {
211-
mlx5e_macsec_destroy_object(mdev, rx_sa->macsec_obj_id);
232+
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
212233
return 0;
213234
}
214235

@@ -334,10 +355,10 @@ static int mlx5e_macsec_upd_txsa(struct macsec_context *ctx)
334355
if (err)
335356
goto out;
336357
} else {
337-
if (!tx_sa->tx_rule)
358+
if (!tx_sa->macsec_rule)
338359
return -EINVAL;
339360

340-
mlx5e_macsec_cleanup_sa(macsec, tx_sa);
361+
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
341362
}
342363

343364
tx_sa->active = ctx_tx_sa->active;
@@ -369,7 +390,7 @@ static int mlx5e_macsec_del_txsa(struct macsec_context *ctx)
369390
goto out;
370391
}
371392

372-
mlx5e_macsec_cleanup_sa(macsec, tx_sa);
393+
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
373394
mlx5_destroy_encryption_key(macsec->mdev, tx_sa->enc_key_id);
374395
kfree_rcu(tx_sa);
375396
macsec->tx_sa[assoc_num] = NULL;
@@ -396,6 +417,7 @@ static u32 mlx5e_macsec_get_sa_from_hashtable(struct rhashtable *sci_hash, sci_t
396417

397418
static int mlx5e_macsec_add_rxsc(struct macsec_context *ctx)
398419
{
420+
struct mlx5e_macsec_rx_sc_xarray_element *sc_xarray_element;
399421
struct mlx5e_priv *priv = netdev_priv(ctx->netdev);
400422
const struct macsec_rx_sc *ctx_rx_sc = ctx->rx_sc;
401423
struct mlx5e_macsec_rx_sc *rx_sc;
@@ -421,10 +443,33 @@ static int mlx5e_macsec_add_rxsc(struct macsec_context *ctx)
421443
goto out;
422444
}
423445

446+
sc_xarray_element = kzalloc(sizeof(*sc_xarray_element), GFP_KERNEL);
447+
if (!sc_xarray_element) {
448+
err = -ENOMEM;
449+
goto destroy_rx_sc;
450+
}
451+
452+
sc_xarray_element->rx_sc = rx_sc;
453+
err = xa_alloc(&macsec->sc_xarray, &sc_xarray_element->fs_id, sc_xarray_element,
454+
XA_LIMIT(1, USHRT_MAX), GFP_KERNEL);
455+
if (err)
456+
goto destroy_sc_xarray_elemenet;
457+
424458
rx_sc->sci = ctx_rx_sc->sci;
425459
rx_sc->active = ctx_rx_sc->active;
426460
list_add_rcu(&rx_sc->rx_sc_list_element, &macsec->macsec_rx_sc_list_head);
427461

462+
rx_sc->sc_xarray_element = sc_xarray_element;
463+
464+
mutex_unlock(&macsec->lock);
465+
466+
return 0;
467+
468+
destroy_sc_xarray_elemenet:
469+
kfree(sc_xarray_element);
470+
destroy_rx_sc:
471+
kfree(rx_sc);
472+
428473
out:
429474
mutex_unlock(&macsec->lock);
430475

@@ -478,7 +523,6 @@ static int mlx5e_macsec_upd_rxsc(struct macsec_context *ctx)
478523
static int mlx5e_macsec_del_rxsc(struct macsec_context *ctx)
479524
{
480525
struct mlx5e_priv *priv = netdev_priv(ctx->netdev);
481-
struct mlx5_core_dev *mdev = priv->mdev;
482526
struct mlx5e_macsec_rx_sc *rx_sc;
483527
struct mlx5e_macsec_sa *rx_sa;
484528
struct mlx5e_macsec *macsec;
@@ -507,14 +551,16 @@ static int mlx5e_macsec_del_rxsc(struct macsec_context *ctx)
507551
if (!rx_sa)
508552
continue;
509553

510-
mlx5e_macsec_destroy_object(mdev, rx_sa->macsec_obj_id);
511-
mlx5_destroy_encryption_key(mdev, rx_sa->enc_key_id);
554+
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
555+
mlx5_destroy_encryption_key(macsec->mdev, rx_sa->enc_key_id);
512556

513557
kfree(rx_sa);
514558
rx_sc->rx_sa[i] = NULL;
515559
}
516560

517561
list_del_rcu(&rx_sc->rx_sc_list_element);
562+
xa_erase(&macsec->sc_xarray, rx_sc->sc_xarray_element->fs_id);
563+
kfree(rx_sc->sc_xarray_element);
518564

519565
kfree_rcu(rx_sc);
520566

@@ -529,7 +575,6 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx)
529575
const struct macsec_rx_sa *ctx_rx_sa = ctx->sa.rx_sa;
530576
struct mlx5e_priv *priv = netdev_priv(ctx->netdev);
531577
struct mlx5_core_dev *mdev = priv->mdev;
532-
struct mlx5_macsec_obj_attrs attrs;
533578
u8 assoc_num = ctx->sa.assoc_num;
534579
struct mlx5e_macsec_rx_sc *rx_sc;
535580
sci_t sci = ctx_rx_sa->sc->sci;
@@ -572,6 +617,8 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx)
572617
rx_sa->next_pn = ctx_rx_sa->next_pn;
573618
rx_sa->sci = sci;
574619
rx_sa->assoc_num = assoc_num;
620+
rx_sa->fs_id = rx_sc->sc_xarray_element->fs_id;
621+
575622
err = mlx5_create_encryption_key(mdev, ctx->sa.key, ctx->secy->key_len,
576623
MLX5_ACCEL_OBJ_MACSEC_KEY,
577624
&rx_sa->enc_key_id);
@@ -582,11 +629,8 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx)
582629
if (!rx_sa->active)
583630
goto out;
584631

585-
attrs.sci = rx_sa->sci;
586-
attrs.enc_key_id = rx_sa->enc_key_id;
587-
588632
//TODO - add support for both authentication and encryption flows
589-
err = mlx5e_macsec_create_object(mdev, &attrs, false, &rx_sa->macsec_obj_id);
633+
err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false);
590634
if (err)
591635
goto destroy_encryption_key;
592636

@@ -660,7 +704,6 @@ static int mlx5e_macsec_upd_rxsa(struct macsec_context *ctx)
660704
static int mlx5e_macsec_del_rxsa(struct macsec_context *ctx)
661705
{
662706
struct mlx5e_priv *priv = netdev_priv(ctx->netdev);
663-
struct mlx5_core_dev *mdev = priv->mdev;
664707
sci_t sci = ctx->sa.rx_sa->sc->sci;
665708
struct mlx5e_macsec_rx_sc *rx_sc;
666709
u8 assoc_num = ctx->sa.assoc_num;
@@ -694,9 +737,8 @@ static int mlx5e_macsec_del_rxsa(struct macsec_context *ctx)
694737
goto out;
695738
}
696739

697-
mlx5e_macsec_destroy_object(mdev, rx_sa->macsec_obj_id);
698-
mlx5_destroy_encryption_key(mdev, rx_sa->enc_key_id);
699-
740+
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
741+
mlx5_destroy_encryption_key(macsec->mdev, rx_sa->enc_key_id);
700742
kfree(rx_sa);
701743
rx_sc->rx_sa[assoc_num] = NULL;
702744

@@ -827,6 +869,8 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
827869
goto err_out;
828870
}
829871

872+
xa_init_flags(&macsec->sc_xarray, XA_FLAGS_ALLOC1);
873+
830874
priv->macsec = macsec;
831875

832876
macsec->mdev = mdev;

0 commit comments

Comments
 (0)