[PATCH v6 05/12] net/ixgbe: fix wrong pointer handling in IPsec

Anatoly Burakov anatoly.burakov at intel.com
Fri Feb 13 10:10:07 CET 2026


The original IPsec "add SA from flow" function expected a void* pointer to
security session as its first argument. However, the actual code was not
passing that, instead it passed `rte_flow_action_security` which was a
*container* for security session pointer.

Fix it by passing correct pointer type, as well as make typing more
explicit to let compiler catch such bugs in the future.

Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: radu.nicolau at intel.com
Cc: stable at dpdk.org

Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
Acked-by: Radu Nicolau <radu.nicolau at intel.com>
---
 drivers/net/intel/ixgbe/ixgbe_flow.c  | 24 ++++++++++++++++++++++--
 drivers/net/intel/ixgbe/ixgbe_ipsec.c | 18 ++++++------------
 drivers/net/intel/ixgbe/ixgbe_ipsec.h | 16 +++++++++++++---
 3 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/drivers/net/intel/ixgbe/ixgbe_flow.c b/drivers/net/intel/ixgbe/ixgbe_flow.c
index 90a24806d2..6a7edc6377 100644
--- a/drivers/net/intel/ixgbe/ixgbe_flow.c
+++ b/drivers/net/intel/ixgbe/ixgbe_flow.c
@@ -221,6 +221,9 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
 	act = next_no_void_action(actions, NULL);
 	if (act->type == RTE_FLOW_ACTION_TYPE_SECURITY) {
 		const void *conf = act->conf;
+		const struct rte_flow_action_security *sec_act;
+		struct rte_security_session *session;
+		struct ip_spec spec;
 
 		if (conf == NULL) {
 			rte_flow_error_set(error, EINVAL,
@@ -259,8 +262,25 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
 		}
 
 		filter->proto = IPPROTO_ESP;
-		return ixgbe_crypto_add_ingress_sa_from_flow(conf, item->spec,
-					item->type == RTE_FLOW_ITEM_TYPE_IPV6);
+		sec_act = (const struct rte_flow_action_security *)conf;
+		spec.is_ipv6 = item->type == RTE_FLOW_ITEM_TYPE_IPV6;
+		if (spec.is_ipv6) {
+			const struct rte_flow_item_ipv6 *ipv6 = item->spec;
+			spec.spec.ipv6 = *ipv6;
+		} else {
+			const struct rte_flow_item_ipv4 *ipv4 = item->spec;
+			spec.spec.ipv4 = *ipv4;
+		}
+
+		/*
+		 * we get pointer to security session from security action,
+		 * which is const. however, we do need to act on the session, so
+		 * either we do some kind of pointer based lookup to get session
+		 * pointer internally (which quickly gets unwieldy for lots of
+		 * flows case), or we simply cast away constness.
+		 */
+		session = RTE_CAST_PTR(struct rte_security_session *, sec_act->security_session);
+		return ixgbe_crypto_add_ingress_sa_from_flow(session, &spec);
 	}
 #endif
 
diff --git a/drivers/net/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/intel/ixgbe/ixgbe_ipsec.c
index df0964a51d..fe9a96c54d 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/intel/ixgbe/ixgbe_ipsec.c
@@ -664,20 +664,14 @@ ixgbe_crypto_enable_ipsec(struct rte_eth_dev *dev)
 }
 
 int
-ixgbe_crypto_add_ingress_sa_from_flow(const void *sess,
-				      const void *ip_spec,
-				      uint8_t is_ipv6)
+ixgbe_crypto_add_ingress_sa_from_flow(struct rte_security_session *sess,
+		const struct ip_spec *spec)
 {
-	/**
-	 * FIXME Updating the session priv data when the session is const.
-	 * Typecasting done here is wrong and the implementation need to be corrected.
-	 */
-	struct ixgbe_crypto_session *ic_session = (void *)(uintptr_t)
-			((const struct rte_security_session *)sess)->driver_priv_data;
+	struct ixgbe_crypto_session *ic_session = SECURITY_GET_SESS_PRIV(sess);
 
 	if (ic_session->op == IXGBE_OP_AUTHENTICATED_DECRYPTION) {
-		if (is_ipv6) {
-			const struct rte_flow_item_ipv6 *ipv6 = ip_spec;
+		if (spec->is_ipv6) {
+			const struct rte_flow_item_ipv6 *ipv6 = &spec->spec.ipv6;
 			ic_session->src_ip.type = IPv6;
 			ic_session->dst_ip.type = IPv6;
 			rte_memcpy(ic_session->src_ip.ipv6,
@@ -685,7 +679,7 @@ ixgbe_crypto_add_ingress_sa_from_flow(const void *sess,
 			rte_memcpy(ic_session->dst_ip.ipv6,
 				   &ipv6->hdr.dst_addr, 16);
 		} else {
-			const struct rte_flow_item_ipv4 *ipv4 = ip_spec;
+			const struct rte_flow_item_ipv4 *ipv4 = &spec->spec.ipv4;
 			ic_session->src_ip.type = IPv4;
 			ic_session->dst_ip.type = IPv4;
 			ic_session->src_ip.ipv4 = ipv4->hdr.src_addr;
diff --git a/drivers/net/intel/ixgbe/ixgbe_ipsec.h b/drivers/net/intel/ixgbe/ixgbe_ipsec.h
index be39199be1..e7c7186264 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ipsec.h
+++ b/drivers/net/intel/ixgbe/ixgbe_ipsec.h
@@ -6,6 +6,9 @@
 #define IXGBE_IPSEC_H_
 
 #include <rte_security.h>
+#include <rte_security_driver.h>
+
+#include <rte_flow.h>
 
 #define IPSRXIDX_RX_EN                                    0x00000001
 #define IPSRXIDX_TABLE_IP                                 0x00000002
@@ -109,9 +112,16 @@ struct ixgbe_ipsec {
 
 int ixgbe_ipsec_ctx_create(struct rte_eth_dev *dev);
 int ixgbe_crypto_enable_ipsec(struct rte_eth_dev *dev);
-int ixgbe_crypto_add_ingress_sa_from_flow(const void *sess,
-					  const void *ip_spec,
-					  uint8_t is_ipv6);
+
+struct ip_spec {
+	bool is_ipv6;
+	union {
+		struct rte_flow_item_ipv4 ipv4;
+		struct rte_flow_item_ipv6 ipv6;
+	} spec;
+};
+int ixgbe_crypto_add_ingress_sa_from_flow(struct rte_security_session *sess,
+		const struct ip_spec *ip_spec);
 
 
 
-- 
2.47.3



More information about the dev mailing list