[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