[PATCH v3 09/10] net/gve: enforce DQO Tx packet length limits

Tathagat Priyadarshi tathagat.dpdk at gmail.com
Fri Oct 16 08:26:46 CEST 2026


The device requires non-TSO packets to be 17 to 9728 bytes long, as
noted in the Linux driver, but packets of any length are posted. The
device treats an out-of-range packet as coming from a malicious
driver: it drops the packet and disables the datapath, stalling all
queues.

Drop such packets in the driver and count them in a new invalid_pkts
counter.

Fixes: 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
Cc: stable at dpdk.org

Signed-off-by: Tathagat Priyadarshi <tathagat.dpdk at gmail.com>
---
 drivers/net/gve/base/gve_desc_dqo.h |  2 ++
 drivers/net/gve/gve_ethdev.c        |  1 +
 drivers/net/gve/gve_ethdev.h        |  1 +
 drivers/net/gve/gve_tx_dqo.c        | 17 +++++++++++++++++
 4 files changed, 21 insertions(+)

diff --git a/drivers/net/gve/base/gve_desc_dqo.h b/drivers/net/gve/base/gve_desc_dqo.h
index c1534959c2..d50d88765e 100644
--- a/drivers/net/gve/base/gve_desc_dqo.h
+++ b/drivers/net/gve/base/gve_desc_dqo.h
@@ -12,6 +12,8 @@
 
 #define GVE_TX_MAX_HDR_SIZE_DQO 255
 #define GVE_TX_MIN_TSO_MSS_DQO 88
+#define GVE_TX_MIN_PKT_SIZE_DQO 17
+#define GVE_TX_MAX_PKT_SIZE_DQO 9728
 
 /* Basic TX descriptor (DTYPE 0x0C) */
 struct gve_tx_pkt_desc_dqo {
diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index cbfb07edf6..167dcbce7b 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -985,6 +985,7 @@ static const struct gve_xstats_name_offset tx_xstats_name_offset[] = {
 	{ "errors",  TX_QUEUE_STATS_OFFSET(errors) },
 	{ "too_many_descs", TX_QUEUE_STATS_OFFSET(too_many_descs) },
 	{ "invalid_mbufs", TX_QUEUE_STATS_OFFSET(invalid_mbufs) },
+	{ "invalid_pkts", TX_QUEUE_STATS_OFFSET(invalid_pkts) },
 };
 
 static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h
index 24ef3a4552..2464474426 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -115,6 +115,7 @@ struct gve_tx_stats {
 	uint64_t errors;
 	uint64_t too_many_descs;
 	uint64_t invalid_mbufs;
+	uint64_t invalid_pkts;
 };
 
 struct gve_rx_stats {
diff --git a/drivers/net/gve/gve_tx_dqo.c b/drivers/net/gve/gve_tx_dqo.c
index fd36d92fab..c23b222ada 100644
--- a/drivers/net/gve/gve_tx_dqo.c
+++ b/drivers/net/gve/gve_tx_dqo.c
@@ -126,6 +126,17 @@ gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
 		gve_tx_clean_dqo(txq);
 }
 
+/* Validate packet lengths against the device limits. */
+static inline bool
+gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)
+{
+	if (!is_tso)
+		return tx_pkt->pkt_len >= GVE_TX_MIN_PKT_SIZE_DQO &&
+		       tx_pkt->pkt_len <= GVE_TX_MAX_PKT_SIZE_DQO;
+
+	return true;
+}
+
 /* Max descriptors a single packet may use. A larger packet can never pass
  * gve_can_tx(): one slot is always reserved, the cacheline overlap margin
  * must stay free, and up to GVE_TX_MIN_RE_INTERVAL - 1 descriptors posted
@@ -309,6 +320,12 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		tso = !!(ol_flags & RTE_MBUF_F_TX_TCP_SEG);
 		csum = !!(ol_flags & GVE_TX_CKSUM_OFFLOAD_MASK_DQO);
 
+		if (!gve_tx_validate_pkt(tx_pkt, tso)) {
+			txq->stats.invalid_pkts++;
+			rte_pktmbuf_free(tx_pkt);
+			continue;
+		}
+
 		nb_descs = gve_tx_pkt_nb_data_descs(tx_pkt);
 		nb_descs += tso;
 
-- 
2.43.0



More information about the dev mailing list