diff mbox series

[RFC,net-next,14/15] net/mlx5e: Add Rx data path offload

Message ID 20240510030435.120935-15-kuba@kernel.org (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series add basic PSP encryption for TCP connections | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next, async
netdev/ynl success Generated files up to date; no warnings/errors; GEN HAS DIFF 2 files changed, 877 insertions(+);
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 930 this patch: 931
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 5 maintainers not CCed: linux-rdma@vger.kernel.org jianbol@nvidia.com saeedm@nvidia.com edumazet@google.com leon@kernel.org
netdev/build_clang fail Errors and warnings before: 941 this patch: 943
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 941 this patch: 942
netdev/checkpatch warning WARNING: line length of 100 exceeds 80 columns WARNING: line length of 81 exceeds 80 columns WARNING: line length of 82 exceeds 80 columns WARNING: line length of 85 exceeds 80 columns WARNING: line length of 95 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jakub Kicinski May 10, 2024, 3:04 a.m. UTC
From: Raed Salem <raeds@nvidia.com>

On receive flow inspect received packets for PSP offload indication using
the cqe, for PSP offloaded packets set SKB PSP metadata i.e spi, header
length and key generation number to stack for further processing.

Signed-off-by: Raed Salem <raeds@nvidia.com>
Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 .../mellanox/mlx5/core/en_accel/ipsec_rxtx.h  |  2 +-
 .../mellanox/mlx5/core/en_accel/nisp_rxtx.c   | 79 +++++++++++++++++++
 .../mellanox/mlx5/core/en_accel/nisp_rxtx.h   | 28 +++++++
 .../net/ethernet/mellanox/mlx5/core/en_rx.c   | 10 +++
 4 files changed, 118 insertions(+), 1 deletion(-)

Comments

Willem de Bruijn May 13, 2024, 1:54 a.m. UTC | #1
Jakub Kicinski wrote:
> From: Raed Salem <raeds@nvidia.com>
> 
> On receive flow inspect received packets for PSP offload indication using
> the cqe, for PSP offloaded packets set SKB PSP metadata i.e spi, header
> length and key generation number to stack for further processing.
> 
> Signed-off-by: Raed Salem <raeds@nvidia.com>
> Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
>  .../mellanox/mlx5/core/en_accel/ipsec_rxtx.h  |  2 +-
>  .../mellanox/mlx5/core/en_accel/nisp_rxtx.c   | 79 +++++++++++++++++++
>  .../mellanox/mlx5/core/en_accel/nisp_rxtx.h   | 28 +++++++
>  .../net/ethernet/mellanox/mlx5/core/en_rx.c   | 10 +++
>  4 files changed, 118 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
> index 82064614846f..9f025c80a6ef 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
> @@ -40,7 +40,7 @@
>  #include "en/txrx.h"
>  
>  /* 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) >> 30) & 0x3) == 0x2)
>  #define MLX5_IPSEC_METADATA_SYNDROM(metadata) (((metadata) >> 24) & GENMASK(5, 0))
>  #define MLX5_IPSEC_METADATA_HANDLE(metadata)  ((metadata) & GENMASK(23, 0))
>  
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c
> index c719b2916677..17f42b8d9fd8 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c
> @@ -15,6 +15,12 @@
>  #include "en_accel/nisp.h"
>  #include "lib/psp_defs.h"
>  
> +enum {
> +	MLX5E_NISP_OFFLOAD_RX_SYNDROME_DECRYPTED,
> +	MLX5E_NISP_OFFLOAD_RX_SYNDROME_AUTH_FAILED,
> +	MLX5E_NISP_OFFLOAD_RX_SYNDROME_BAD_TRAILER,
> +};
> +
>  static void mlx5e_nisp_set_swp(struct sk_buff *skb,
>  			       struct mlx5e_accel_tx_nisp_state *nisp_st,
>  			       struct mlx5_wqe_eth_seg *eseg)
> @@ -114,6 +120,79 @@ static bool mlx5e_nisp_set_state(struct mlx5e_priv *priv,
>  	return ret;
>  }
>  
> +void mlx5e_nisp_csum_complete(struct net_device *netdev, struct sk_buff *skb)
> +{
> +	pskb_trim(skb, skb->len - PSP_TRL_SIZE);
> +}
> +
> +/* Receive handler for PSP packets.
> + *
> + * Presently it accepts only already-authenticated packets and does not
> + * support optional fields, such as virtualization cookies.
> + */
> +static int psp_rcv(struct sk_buff *skb)
> +{
> +	const struct psphdr *psph;
> +	int depth = 0, end_depth;
> +	struct psp_skb_ext *pse;
> +	struct ipv6hdr *ipv6h;
> +	struct ethhdr *eth;
> +	__be16 proto;
> +	u32 spi;
> +
> +	eth = (struct ethhdr *)(skb->data);
> +	proto = __vlan_get_protocol(skb, eth->h_proto, &depth);
> +	if (proto != htons(ETH_P_IPV6))
> +		return -EINVAL;
> +
> +	ipv6h = (struct ipv6hdr *)(skb->data + depth);
> +	depth += sizeof(*ipv6h);
> +	end_depth = depth + sizeof(struct udphdr) + sizeof(struct psphdr);
> +
> +	if (unlikely(end_depth > skb_headlen(skb)))
> +		return -EINVAL;
> +
> +	pse = skb_ext_add(skb, SKB_EXT_PSP);
> +	if (!pse)
> +		return -EINVAL;
> +
> +	psph = (const struct psphdr *)(skb->data + depth + sizeof(struct udphdr));
> +	pse->spi = psph->spi;
> +	spi = ntohl(psph->spi);
> +	pse->generation = 0;
> +	pse->version = FIELD_GET(PSPHDR_VERFL_VERSION, psph->verfl);
> +
> +	ipv6h->nexthdr = psph->nexthdr;
> +	ipv6h->payload_len =
> +		htons(ntohs(ipv6h->payload_len) - PSP_ENCAP_HLEN - PSP_TRL_SIZE);
> +
> +	memmove(skb->data + PSP_ENCAP_HLEN, skb->data, depth);
> +	skb_pull(skb, PSP_ENCAP_HLEN);
> +
> +	return 0;
> +}
> +
> +void mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
> +				      struct mlx5_cqe64 *cqe)
> +{
> +	u32 nisp_meta_data = be32_to_cpu(cqe->ft_metadata);
> +
> +	/* TBD: report errors as SW counters to ethtool, any further handling ? */
> +	switch (MLX5_NISP_METADATA_SYNDROM(nisp_meta_data)) {
> +	case MLX5E_NISP_OFFLOAD_RX_SYNDROME_DECRYPTED:
> +		if (psp_rcv(skb))
> +			netdev_warn_once(netdev, "PSP handling failed");
> +		skb->decrypted = 1;

Do not set skb->decrypted if psp_rcv failed? But drop the packet and
account the drop, likely.

> +		break;
> +	case MLX5E_NISP_OFFLOAD_RX_SYNDROME_AUTH_FAILED:
> +		break;
> +	case MLX5E_NISP_OFFLOAD_RX_SYNDROME_BAD_TRAILER:
> +		break;
> +	default:
> +		break;
> +	}
> +}
Jakub Kicinski May 29, 2024, 6:38 p.m. UTC | #2
On Sun, 12 May 2024 21:54:38 -0400 Willem de Bruijn wrote:
> > +	/* TBD: report errors as SW counters to ethtool, any further handling ? */
> > +	switch (MLX5_NISP_METADATA_SYNDROM(nisp_meta_data)) {
> > +	case MLX5E_NISP_OFFLOAD_RX_SYNDROME_DECRYPTED:
> > +		if (psp_rcv(skb))
> > +			netdev_warn_once(netdev, "PSP handling failed");
> > +		skb->decrypted = 1;  
> 
> Do not set skb->decrypted if psp_rcv failed? But drop the packet and
> account the drop, likely.

nVidia folks does this seem reasonable?

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c
index 7ae3e8246d8f..8cf6a8daf721 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c
@@ -172,22 +172,24 @@ static int psp_rcv(struct sk_buff *skb)
 	return 0;
 }
 
-void mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
+bool mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
 				      struct mlx5_cqe64 *cqe)
 {
 	u32 nisp_meta_data = be32_to_cpu(cqe->ft_metadata);
 
 	/* TBD: report errors as SW counters to ethtool, any further handling ? */
-	switch (MLX5_NISP_METADATA_SYNDROM(nisp_meta_data)) {
-	case MLX5E_NISP_OFFLOAD_RX_SYNDROME_DECRYPTED:
-		if (psp_rcv(skb))
-			netdev_warn_once(netdev, "PSP handling failed");
-		skb->decrypted = 1;
-		break;
-	default:
-		WARN_ON_ONCE(true);
-		break;
-	}
+	if (MLX5_NISP_METADATA_SYNDROM(nisp_meta_data) != MLX5E_NISP_OFFLOAD_RX_SYNDROME_DECRYPTED)
+		goto drop;
+
+	if (psp_rcv(skb))
+		goto drop;
+
+	skb->decrypted = 1;
+	return false;
+
+drop:
+	kfree_skb(skb);
+	return true;
 }
 
 void mlx5e_nisp_tx_build_eseg(struct mlx5e_priv *priv, struct sk_buff *skb,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.h
index 834481232b21..1e13b09b3522 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.h
@@ -86,7 +86,7 @@ static inline bool mlx5e_nisp_is_rx_flow(struct mlx5_cqe64 *cqe)
 	return MLX5_NISP_METADATA_MARKER(be32_to_cpu(cqe->ft_metadata));
 }
 
-void mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
+bool mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
 				      struct mlx5_cqe64 *cqe);
 
 void mlx5e_nisp_csum_complete(struct net_device *netdev, struct sk_buff *skb);
@@ -113,10 +113,11 @@ static inline bool mlx5e_nisp_is_rx_flow(struct mlx5_cqe64 *cqe)
 	return false;
 }
 
-static inline void mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev,
+static inline bool mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev,
 						    struct sk_buff *skb,
 						    struct mlx5_cqe64 *cqe)
 {
+	return false;
 }
 
 static inline void mlx5e_nisp_csum_complete(struct net_device *netdev, struct sk_buff *skb) { }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index ed3c7d8cf99d..22cf1c563844 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -1552,7 +1552,7 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
 
 #define MLX5E_CE_BIT_MASK 0x80
 
-static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
+static inline bool mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
 				      u32 cqe_bcnt,
 				      struct mlx5e_rq *rq,
 				      struct sk_buff *skb)
@@ -1566,8 +1566,10 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
 	if (unlikely(get_cqe_tls_offload(cqe)))
 		mlx5e_ktls_handle_rx_skb(rq, skb, cqe, &cqe_bcnt);
 
-	if (unlikely(mlx5e_nisp_is_rx_flow(cqe)))
-		mlx5e_nisp_offload_handle_rx_skb(netdev, skb, cqe);
+	if (unlikely(mlx5e_nisp_is_rx_flow(cqe))) {
+		if (mlx5e_nisp_offload_handle_rx_skb(netdev, skb, cqe))
+			return true;
+	}
 
 	if (unlikely(mlx5_ipsec_is_rx_flow(cqe)))
 		mlx5e_ipsec_offload_handle_rx_skb(netdev, skb,
@@ -1612,9 +1614,11 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
 
 	if (unlikely(mlx5e_skb_is_multicast(skb)))
 		stats->mcast_packets++;
+
+	return false;
 }
 
-static void mlx5e_shampo_complete_rx_cqe(struct mlx5e_rq *rq,
+static bool mlx5e_shampo_complete_rx_cqe(struct mlx5e_rq *rq,
 					 struct mlx5_cqe64 *cqe,
 					 u32 cqe_bcnt,
 					 struct sk_buff *skb)
@@ -1626,16 +1630,20 @@ static void mlx5e_shampo_complete_rx_cqe(struct mlx5e_rq *rq,
 	stats->bytes += cqe_bcnt;
 	stats->gro_bytes += cqe_bcnt;
 	if (NAPI_GRO_CB(skb)->count != 1)
-		return;
-	mlx5e_build_rx_skb(cqe, cqe_bcnt, rq, skb);
+		return false;
+
+	if (mlx5e_build_rx_skb(cqe, cqe_bcnt, rq, skb))
+		return true;
+
 	skb_reset_network_header(skb);
 	if (!skb_flow_dissect_flow_keys(skb, &rq->hw_gro_data->fk, 0)) {
 		napi_gro_receive(rq->cq.napi, skb);
 		rq->hw_gro_data->skb = NULL;
 	}
+	return false;
 }
 
-static inline void mlx5e_complete_rx_cqe(struct mlx5e_rq *rq,
+static inline bool mlx5e_complete_rx_cqe(struct mlx5e_rq *rq,
 					 struct mlx5_cqe64 *cqe,
 					 u32 cqe_bcnt,
 					 struct sk_buff *skb)
@@ -1644,7 +1652,7 @@ static inline void mlx5e_complete_rx_cqe(struct mlx5e_rq *rq,
 
 	stats->packets++;
 	stats->bytes += cqe_bcnt;
-	mlx5e_build_rx_skb(cqe, cqe_bcnt, rq, skb);
+	return mlx5e_build_rx_skb(cqe, cqe_bcnt, rq, skb);
 }
 
 static inline
@@ -1858,7 +1866,8 @@ static void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
 		goto wq_cyc_pop;
 	}
 
-	mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
+	if (mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb))
+		goto wq_cyc_pop;
 
 	if (mlx5e_cqe_regb_chain(cqe))
 		if (!mlx5e_tc_update_skb_nic(cqe, skb)) {
@@ -1905,7 +1914,8 @@ static void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
 		goto wq_cyc_pop;
 	}
 
-	mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
+	if (mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb))
+		goto wq_cyc_pop;
 
 	if (rep->vlan && skb_vlan_tag_present(skb))
 		skb_vlan_pop(skb);
@@ -1954,7 +1964,8 @@ static void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq, struct mlx5_cqe64
 	if (!skb)
 		goto mpwrq_cqe_out;
 
-	mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
+	if (mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb))
+		goto mpwrq_cqe_out;
 
 	mlx5e_rep_tc_receive(cqe, rq, skb);
 
@@ -2375,7 +2386,10 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
 		mlx5e_fill_skb_data(*skb, rq, frag_page, data_bcnt, data_offset);
 	}
 
-	mlx5e_shampo_complete_rx_cqe(rq, cqe, cqe_bcnt, *skb);
+	if (mlx5e_shampo_complete_rx_cqe(rq, cqe, cqe_bcnt, *skb)) {
+		*skb = NULL;
+		goto free_hd_entry;
+	}
 	if (flush)
 		mlx5e_shampo_flush_skb(rq, cqe, match);
 free_hd_entry:
@@ -2429,7 +2443,8 @@ static void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cq
 	if (!skb)
 		goto mpwrq_cqe_out;
 
-	mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
+	if (mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb))
+		goto mpwrq_cqe_out;
 
 	if (mlx5e_cqe_regb_chain(cqe))
 		if (!mlx5e_tc_update_skb_nic(cqe, skb)) {
@@ -2762,7 +2777,8 @@ static void mlx5e_trap_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe
 	if (!skb)
 		goto wq_cyc_pop;
 
-	mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
+	if (mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb))
+		goto wq_cyc_pop;
 	skb_push(skb, ETH_HLEN);
 
 	mlx5_devlink_trap_report(rq->mdev, trap_id, skb,
Cosmin Ratiu May 30, 2024, 9:04 a.m. UTC | #3
On Wed, 2024-05-29 at 11:38 -0700, Jakub Kicinski wrote:
> On Sun, 12 May 2024 21:54:38 -0400 Willem de Bruijn wrote:
> > > +	/* TBD: report errors as SW counters to ethtool, any further handling ? */
> > > +	switch (MLX5_NISP_METADATA_SYNDROM(nisp_meta_data)) {
> > > +	case MLX5E_NISP_OFFLOAD_RX_SYNDROME_DECRYPTED:
> > > +		if (psp_rcv(skb))
> > > +			netdev_warn_once(netdev, "PSP handling failed");
> > > +		skb->decrypted = 1;  
> > 
> > Do not set skb->decrypted if psp_rcv failed? But drop the packet and
> > account the drop, likely.
> 
> nVidia folks does this seem reasonable?

This seems reasonable. It's also what the comment above the switch
suggests should be done.
psp_rcv unrefs the skb on errors (doesn't even return error in all
cases) and I think it's no longer safe to touch it, unless there's
another ref held somewhere.

I've tried implementing this tweak in the shared repo we have, but it
seems it doesn't have the versions of this patch that you sent.

Cosmin.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
index 82064614846f..9f025c80a6ef 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
@@ -40,7 +40,7 @@ 
 #include "en/txrx.h"
 
 /* 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) >> 30) & 0x3) == 0x2)
 #define MLX5_IPSEC_METADATA_SYNDROM(metadata) (((metadata) >> 24) & GENMASK(5, 0))
 #define MLX5_IPSEC_METADATA_HANDLE(metadata)  ((metadata) & GENMASK(23, 0))
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c
index c719b2916677..17f42b8d9fd8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.c
@@ -15,6 +15,12 @@ 
 #include "en_accel/nisp.h"
 #include "lib/psp_defs.h"
 
+enum {
+	MLX5E_NISP_OFFLOAD_RX_SYNDROME_DECRYPTED,
+	MLX5E_NISP_OFFLOAD_RX_SYNDROME_AUTH_FAILED,
+	MLX5E_NISP_OFFLOAD_RX_SYNDROME_BAD_TRAILER,
+};
+
 static void mlx5e_nisp_set_swp(struct sk_buff *skb,
 			       struct mlx5e_accel_tx_nisp_state *nisp_st,
 			       struct mlx5_wqe_eth_seg *eseg)
@@ -114,6 +120,79 @@  static bool mlx5e_nisp_set_state(struct mlx5e_priv *priv,
 	return ret;
 }
 
+void mlx5e_nisp_csum_complete(struct net_device *netdev, struct sk_buff *skb)
+{
+	pskb_trim(skb, skb->len - PSP_TRL_SIZE);
+}
+
+/* Receive handler for PSP packets.
+ *
+ * Presently it accepts only already-authenticated packets and does not
+ * support optional fields, such as virtualization cookies.
+ */
+static int psp_rcv(struct sk_buff *skb)
+{
+	const struct psphdr *psph;
+	int depth = 0, end_depth;
+	struct psp_skb_ext *pse;
+	struct ipv6hdr *ipv6h;
+	struct ethhdr *eth;
+	__be16 proto;
+	u32 spi;
+
+	eth = (struct ethhdr *)(skb->data);
+	proto = __vlan_get_protocol(skb, eth->h_proto, &depth);
+	if (proto != htons(ETH_P_IPV6))
+		return -EINVAL;
+
+	ipv6h = (struct ipv6hdr *)(skb->data + depth);
+	depth += sizeof(*ipv6h);
+	end_depth = depth + sizeof(struct udphdr) + sizeof(struct psphdr);
+
+	if (unlikely(end_depth > skb_headlen(skb)))
+		return -EINVAL;
+
+	pse = skb_ext_add(skb, SKB_EXT_PSP);
+	if (!pse)
+		return -EINVAL;
+
+	psph = (const struct psphdr *)(skb->data + depth + sizeof(struct udphdr));
+	pse->spi = psph->spi;
+	spi = ntohl(psph->spi);
+	pse->generation = 0;
+	pse->version = FIELD_GET(PSPHDR_VERFL_VERSION, psph->verfl);
+
+	ipv6h->nexthdr = psph->nexthdr;
+	ipv6h->payload_len =
+		htons(ntohs(ipv6h->payload_len) - PSP_ENCAP_HLEN - PSP_TRL_SIZE);
+
+	memmove(skb->data + PSP_ENCAP_HLEN, skb->data, depth);
+	skb_pull(skb, PSP_ENCAP_HLEN);
+
+	return 0;
+}
+
+void mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
+				      struct mlx5_cqe64 *cqe)
+{
+	u32 nisp_meta_data = be32_to_cpu(cqe->ft_metadata);
+
+	/* TBD: report errors as SW counters to ethtool, any further handling ? */
+	switch (MLX5_NISP_METADATA_SYNDROM(nisp_meta_data)) {
+	case MLX5E_NISP_OFFLOAD_RX_SYNDROME_DECRYPTED:
+		if (psp_rcv(skb))
+			netdev_warn_once(netdev, "PSP handling failed");
+		skb->decrypted = 1;
+		break;
+	case MLX5E_NISP_OFFLOAD_RX_SYNDROME_AUTH_FAILED:
+		break;
+	case MLX5E_NISP_OFFLOAD_RX_SYNDROME_BAD_TRAILER:
+		break;
+	default:
+		break;
+	}
+}
+
 void mlx5e_nisp_tx_build_eseg(struct mlx5e_priv *priv, struct sk_buff *skb,
 			      struct mlx5e_accel_tx_nisp_state *nisp_st,
 			      struct mlx5_wqe_eth_seg *eseg)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.h
index 1350a73c2019..834481232b21 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/nisp_rxtx.h
@@ -10,6 +10,11 @@ 
 #include "en.h"
 #include "en/txrx.h"
 
+/* Bit30: NISP marker, Bit29-23: NISP syndrome, Bit22-0: NISP obj id */
+#define MLX5_NISP_METADATA_MARKER(metadata)  ((((metadata) >> 30) & 0x3) == 0x3)
+#define MLX5_NISP_METADATA_SYNDROM(metadata) (((metadata) >> 23) & GENMASK(6, 0))
+#define MLX5_NISP_METADATA_HANDLE(metadata)  ((metadata) & GENMASK(22, 0))
+
 struct mlx5e_accel_tx_nisp_state {
 	u32 tailen;
 	u32 keyid;
@@ -75,6 +80,16 @@  static inline unsigned int mlx5e_nisp_tx_ids_len(struct mlx5e_accel_tx_nisp_stat
 {
 	return nisp_st->tailen;
 }
+
+static inline bool mlx5e_nisp_is_rx_flow(struct mlx5_cqe64 *cqe)
+{
+	return MLX5_NISP_METADATA_MARKER(be32_to_cpu(cqe->ft_metadata));
+}
+
+void mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
+				      struct mlx5_cqe64 *cqe);
+
+void mlx5e_nisp_csum_complete(struct net_device *netdev, struct sk_buff *skb);
 #else
 static inline bool mlx5e_psp_is_offload_state(struct mlx5e_accel_tx_nisp_state *nisp_state)
 {
@@ -92,5 +107,18 @@  static inline bool mlx5e_nisp_txwqe_build_eseg_csum(struct mlx5e_txqsq *sq, stru
 {
 	return false;
 }
+
+static inline bool mlx5e_nisp_is_rx_flow(struct mlx5_cqe64 *cqe)
+{
+	return false;
+}
+
+static inline void mlx5e_nisp_offload_handle_rx_skb(struct net_device *netdev,
+						    struct sk_buff *skb,
+						    struct mlx5_cqe64 *cqe)
+{
+}
+
+static inline void mlx5e_nisp_csum_complete(struct net_device *netdev, struct sk_buff *skb) { }
 #endif
 #endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index d601b5faaed5..41a4f8832f2f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -51,6 +51,7 @@ 
 #include "ipoib/ipoib.h"
 #include "en_accel/ipsec.h"
 #include "en_accel/macsec.h"
+#include "en_accel/nisp_rxtx.h"
 #include "en_accel/ipsec_rxtx.h"
 #include "en_accel/ktls_txrx.h"
 #include "en/xdp.h"
@@ -1517,6 +1518,12 @@  static inline void mlx5e_handle_csum(struct net_device *netdev,
 		skb->ip_summed = CHECKSUM_COMPLETE;
 		skb->csum = csum_unfold((__force __sum16)cqe->check_sum);
 
+		if (unlikely(mlx5e_nisp_is_rx_flow(cqe))) {
+			/* TBD: PSP csum complete corrections for now chose csum_unnecessary path */
+			mlx5e_nisp_csum_complete(netdev, skb);
+			goto csum_unnecessary;
+		}
+
 		if (test_bit(MLX5E_RQ_STATE_CSUM_FULL, &rq->state))
 			return; /* CQE csum covers all received bytes */
 
@@ -1559,6 +1566,9 @@  static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
 	if (unlikely(get_cqe_tls_offload(cqe)))
 		mlx5e_ktls_handle_rx_skb(rq, skb, cqe, &cqe_bcnt);
 
+	if (unlikely(mlx5e_nisp_is_rx_flow(cqe)))
+		mlx5e_nisp_offload_handle_rx_skb(netdev, skb, cqe);
+
 	if (unlikely(mlx5_ipsec_is_rx_flow(cqe)))
 		mlx5e_ipsec_offload_handle_rx_skb(netdev, skb,
 						  be32_to_cpu(cqe->ft_metadata));