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

net/mlx5e: Implement MACsec Rx data path using MACsec skb_metadata_dst

MACsec driver need to distinguish to which offload device the MACsec
is target to, in order to handle them correctly.
This can be done by attaching a metadata_dst to a SKB with a SCI,
when there is a match on MACsec rule.
To achieve that, there is a map between fs_id to SCI, so for each RX SC,
there is a unique fs_id allocated when creating RX SC.
fs_id passed to device driver as metadata for packets that passed Rx
MACsec offload to aid the driver to retrieve the matching SCI.
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 3b20949c
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
#include "en.h" #include "en.h"
#include "en/txrx.h" #include "en/txrx.h"
/* Bit31: IPsec marker, Bit30-24: IPsec syndrome, Bit23-0: IPsec obj id */ /* Bit31: IPsec marker, Bit30: reserved, Bit29-24: IPsec syndrome, Bit23-0: IPsec obj id */
#define MLX5_IPSEC_METADATA_MARKER(metadata) (((metadata) >> 31) & 0x1) #define MLX5_IPSEC_METADATA_MARKER(metadata) (((metadata) >> 31) & 0x1)
#define MLX5_IPSEC_METADATA_SYNDROM(metadata) (((metadata) >> 24) & GENMASK(6, 0)) #define MLX5_IPSEC_METADATA_SYNDROM(metadata) (((metadata) >> 24) & GENMASK(5, 0))
#define MLX5_IPSEC_METADATA_HANDLE(metadata) ((metadata) & GENMASK(23, 0)) #define MLX5_IPSEC_METADATA_HANDLE(metadata) ((metadata) & GENMASK(23, 0))
struct mlx5e_accel_tx_ipsec_state { struct mlx5e_accel_tx_ipsec_state {
......
...@@ -39,6 +39,7 @@ struct mlx5e_macsec_rx_sc { ...@@ -39,6 +39,7 @@ struct mlx5e_macsec_rx_sc {
struct mlx5e_macsec_sa *rx_sa[MACSEC_NUM_AN]; struct mlx5e_macsec_sa *rx_sa[MACSEC_NUM_AN];
struct list_head rx_sc_list_element; struct list_head rx_sc_list_element;
struct mlx5e_macsec_rx_sc_xarray_element *sc_xarray_element; struct mlx5e_macsec_rx_sc_xarray_element *sc_xarray_element;
struct metadata_dst *md_dst;
struct rcu_head rcu_head; struct rcu_head rcu_head;
}; };
...@@ -455,16 +456,24 @@ static int mlx5e_macsec_add_rxsc(struct macsec_context *ctx) ...@@ -455,16 +456,24 @@ static int mlx5e_macsec_add_rxsc(struct macsec_context *ctx)
if (err) if (err)
goto destroy_sc_xarray_elemenet; goto destroy_sc_xarray_elemenet;
rx_sc->md_dst = metadata_dst_alloc(0, METADATA_MACSEC, GFP_KERNEL);
if (!rx_sc->md_dst) {
err = -ENOMEM;
goto erase_xa_alloc;
}
rx_sc->sci = ctx_rx_sc->sci; rx_sc->sci = ctx_rx_sc->sci;
rx_sc->active = ctx_rx_sc->active; rx_sc->active = ctx_rx_sc->active;
list_add_rcu(&rx_sc->rx_sc_list_element, &macsec->macsec_rx_sc_list_head); list_add_rcu(&rx_sc->rx_sc_list_element, &macsec->macsec_rx_sc_list_head);
rx_sc->sc_xarray_element = sc_xarray_element; rx_sc->sc_xarray_element = sc_xarray_element;
rx_sc->md_dst->u.macsec_info.sci = rx_sc->sci;
mutex_unlock(&macsec->lock); mutex_unlock(&macsec->lock);
return 0; return 0;
erase_xa_alloc:
xa_erase(&macsec->sc_xarray, sc_xarray_element->fs_id);
destroy_sc_xarray_elemenet: destroy_sc_xarray_elemenet:
kfree(sc_xarray_element); kfree(sc_xarray_element);
destroy_rx_sc: destroy_rx_sc:
...@@ -558,8 +567,15 @@ static int mlx5e_macsec_del_rxsc(struct macsec_context *ctx) ...@@ -558,8 +567,15 @@ static int mlx5e_macsec_del_rxsc(struct macsec_context *ctx)
rx_sc->rx_sa[i] = NULL; rx_sc->rx_sa[i] = NULL;
} }
/*
* At this point the relevant MACsec offload Rx rule already removed at
* mlx5e_macsec_cleanup_sa need to wait for datapath to finish current
* Rx related data propagating using xa_erase which uses rcu to sync,
* once fs_id is erased then this rx_sc is hidden from datapath.
*/
list_del_rcu(&rx_sc->rx_sc_list_element); list_del_rcu(&rx_sc->rx_sc_list_element);
xa_erase(&macsec->sc_xarray, rx_sc->sc_xarray_element->fs_id); xa_erase(&macsec->sc_xarray, rx_sc->sc_xarray_element->fs_id);
metadata_dst_free(rx_sc->md_dst);
kfree(rx_sc->sc_xarray_element); kfree(rx_sc->sc_xarray_element);
kfree_rcu(rx_sc); kfree_rcu(rx_sc);
...@@ -821,6 +837,34 @@ void mlx5e_macsec_tx_build_eseg(struct mlx5e_macsec *macsec, ...@@ -821,6 +837,34 @@ void mlx5e_macsec_tx_build_eseg(struct mlx5e_macsec *macsec,
eseg->flow_table_metadata = cpu_to_be32(MLX5_ETH_WQE_FT_META_MACSEC | fs_id << 2); eseg->flow_table_metadata = cpu_to_be32(MLX5_ETH_WQE_FT_META_MACSEC | fs_id << 2);
} }
void mlx5e_macsec_offload_handle_rx_skb(struct net_device *netdev,
struct sk_buff *skb,
struct mlx5_cqe64 *cqe)
{
struct mlx5e_macsec_rx_sc_xarray_element *sc_xarray_element;
u32 macsec_meta_data = be32_to_cpu(cqe->ft_metadata);
struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5e_macsec_rx_sc *rx_sc;
struct mlx5e_macsec *macsec;
u32 fs_id;
macsec = priv->macsec;
if (!macsec)
return;
fs_id = MLX5_MACSEC_METADATA_HANDLE(macsec_meta_data);
rcu_read_lock();
sc_xarray_element = xa_load(&macsec->sc_xarray, fs_id);
rx_sc = sc_xarray_element->rx_sc;
if (rx_sc) {
dst_hold(&rx_sc->md_dst->dst);
skb_dst_set(skb, &rx_sc->md_dst->dst);
}
rcu_read_unlock();
}
void mlx5e_macsec_build_netdev(struct mlx5e_priv *priv) void mlx5e_macsec_build_netdev(struct mlx5e_priv *priv)
{ {
struct net_device *netdev = priv->netdev; struct net_device *netdev = priv->netdev;
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
#include <net/macsec.h> #include <net/macsec.h>
#include <net/dst_metadata.h> #include <net/dst_metadata.h>
/* Bit31 - 30: MACsec marker, Bit3-0: MACsec id */
#define MLX5_MACSEC_METADATA_MARKER(metadata) ((((metadata) >> 30) & 0x3) == 0x1)
#define MLX5_MACSEC_METADATA_HANDLE(metadata) ((metadata) & GENMASK(3, 0))
struct mlx5e_priv; struct mlx5e_priv;
struct mlx5e_macsec; struct mlx5e_macsec;
...@@ -28,12 +32,25 @@ static inline bool mlx5e_macsec_skb_is_offload(struct sk_buff *skb) ...@@ -28,12 +32,25 @@ static inline bool mlx5e_macsec_skb_is_offload(struct sk_buff *skb)
return md_dst && (md_dst->type == METADATA_MACSEC); return md_dst && (md_dst->type == METADATA_MACSEC);
} }
static inline bool mlx5e_macsec_is_rx_flow(struct mlx5_cqe64 *cqe)
{
return MLX5_MACSEC_METADATA_MARKER(be32_to_cpu(cqe->ft_metadata));
}
void mlx5e_macsec_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
struct mlx5_cqe64 *cqe);
#else #else
static inline void mlx5e_macsec_build_netdev(struct mlx5e_priv *priv) {} static inline void mlx5e_macsec_build_netdev(struct mlx5e_priv *priv) {}
static inline int mlx5e_macsec_init(struct mlx5e_priv *priv) { return 0; } static inline int mlx5e_macsec_init(struct mlx5e_priv *priv) { return 0; }
static inline void mlx5e_macsec_cleanup(struct mlx5e_priv *priv) {} static inline void mlx5e_macsec_cleanup(struct mlx5e_priv *priv) {}
static inline bool mlx5e_macsec_skb_is_offload(struct sk_buff *skb) { return false; } static inline bool mlx5e_macsec_skb_is_offload(struct sk_buff *skb) { return false; }
static inline bool mlx5e_macsec_is_rx_flow(struct mlx5_cqe64 *cqe) { return false; }
static inline void mlx5e_macsec_offload_handle_rx_skb(struct net_device *netdev,
struct sk_buff *skb,
struct mlx5_cqe64 *cqe)
{}
#endif /* CONFIG_MLX5_EN_MACSEC */ #endif /* CONFIG_MLX5_EN_MACSEC */
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "en/rep/tc.h" #include "en/rep/tc.h"
#include "ipoib/ipoib.h" #include "ipoib/ipoib.h"
#include "en_accel/ipsec.h" #include "en_accel/ipsec.h"
#include "en_accel/macsec.h"
#include "en_accel/ipsec_rxtx.h" #include "en_accel/ipsec_rxtx.h"
#include "en_accel/ktls_txrx.h" #include "en_accel/ktls_txrx.h"
#include "en/xdp.h" #include "en/xdp.h"
...@@ -1421,6 +1422,9 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe, ...@@ -1421,6 +1422,9 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
if (unlikely(mlx5_ipsec_is_rx_flow(cqe))) if (unlikely(mlx5_ipsec_is_rx_flow(cqe)))
mlx5e_ipsec_offload_handle_rx_skb(netdev, skb, cqe); mlx5e_ipsec_offload_handle_rx_skb(netdev, skb, cqe);
if (unlikely(mlx5e_macsec_is_rx_flow(cqe)))
mlx5e_macsec_offload_handle_rx_skb(netdev, skb, cqe);
if (lro_num_seg > 1) { if (lro_num_seg > 1) {
mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt); mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);
skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt, lro_num_seg); skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt, lro_num_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