[PATCH 06/62] net/null: use kvargs numeric helpers
From: Stephen Hemminger <stephen@networkplumber.org>
Date: 2026-09-14 05:50:07
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
The three device argument handlers each convert with strtoul() and check neither errno nor the end pointer, so "size=foo" is silently taken as zero and "size=99999999999999999999" as ULONG_MAX truncated to unsigned int. The checks for UINT_MAX that follow only catch the truncated overflow case on a 32 bit build. A zero packet size was accepted, and the value is later cast to the 16 bit mbuf data length, so anything above 65535 was silently truncated. Convert with an explicit 1..UINT16_MAX range instead. The copy and no-rx arguments are booleans, so store them as bool and use rte_kvargs_handle_bool. This also means they now accept the word forms such as "copy=on", not only 0 and 1. While here, set an error code when copy and no-rx are both given. The error was logged but the zero return from the last successful rte_kvargs_process() was returned, so probe reported success without ever creating the device. The booleans use rte_kvargs_process_opt(), so that a bare key with no value enables the option. Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> --- doc/guides/nics/null.rst | 2 +- drivers/net/null/rte_eth_null.c | 78 ++++++++++----------------------- 2 files changed, 24 insertions(+), 56 deletions(-)
diff --git a/doc/guides/nics/null.rst b/doc/guides/nics/null.rst
index c0e3199102..fd8d685d83 100644
--- a/doc/guides/nics/null.rst
+++ b/doc/guides/nics/null.rst@@ -30,7 +30,7 @@ Runtime Configuration - ``size`` [optional, default=64 bytes] - Custom packet length value to use.r + Custom packet length value to use, from 1 to 65535. If ``copy`` is enabled, this is the length of copy operation. .. code-block:: console
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 7fba3a661b..60f6f7d799 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c@@ -3,7 +3,8 @@ * All rights reserved. */ -#include <stdlib.h> +#include <stdbool.h> +#include <stdint.h> #include <rte_mbuf.h> #include <ethdev_driver.h>
@@ -19,8 +20,8 @@ #define ETH_NULL_PACKET_NO_RX_ARG "no-rx" static unsigned int default_packet_size = 64; -static unsigned int default_packet_copy; -static unsigned int default_no_rx; +static bool default_packet_copy; +static bool default_no_rx; static const char *valid_arguments[] = { ETH_NULL_PACKET_SIZE_ARG,
@@ -45,15 +46,15 @@ struct null_queue { }; struct pmd_options { - unsigned int packet_copy; + bool packet_copy; unsigned int packet_size; - unsigned int no_rx; + bool no_rx; }; struct pmd_internals { unsigned int packet_size; - unsigned int packet_copy; - unsigned int no_rx; + bool packet_copy; + bool no_rx; uint16_t port_id; struct null_queue rx_null_queues[RTE_MAX_QUEUES_PER_PORT];
@@ -606,55 +607,22 @@ eth_dev_null_create(struct rte_vdev_device *dev, struct pmd_options *args) return 0; } -static inline int -get_packet_size_arg(const char *key __rte_unused, - const char *value, void *extra_args) -{ - const char *a = value; - unsigned int *packet_size = extra_args; - - if ((value == NULL) || (extra_args == NULL)) - return -EINVAL; - - *packet_size = (unsigned int)strtoul(a, NULL, 0); - if (*packet_size == UINT_MAX) - return -1; - - return 0; -} - -static inline int -get_packet_copy_arg(const char *key __rte_unused, - const char *value, void *extra_args) -{ - const char *a = value; - unsigned int *packet_copy = extra_args; - - if ((value == NULL) || (extra_args == NULL)) - return -EINVAL; - - *packet_copy = (unsigned int)strtoul(a, NULL, 0); - if (*packet_copy == UINT_MAX) - return -1; - - return 0; -} - +/* Packet size is stored in a 16 bit mbuf data length, and must not be zero. */ static int -get_packet_no_rx_arg(const char *key __rte_unused, +get_packet_size_arg(const char *key __rte_unused, const char *value, void *extra_args) { - const char *a = value; - unsigned int no_rx; + uint64_t packet_size; + int ret; - if (value == NULL || extra_args == NULL) + if (extra_args == NULL) return -EINVAL; - no_rx = (unsigned int)strtoul(a, NULL, 0); - if (no_rx != 0 && no_rx != 1) - return -1; + ret = rte_kvargs_to_uint(value, 1, UINT16_MAX, &packet_size); + if (ret < 0) + return ret; - *(unsigned int *)extra_args = no_rx; + *(unsigned int *)extra_args = packet_size; return 0; }
@@ -714,16 +682,15 @@ rte_pmd_null_probe(struct rte_vdev_device *dev) if (ret < 0) goto free_kvlist; - - ret = rte_kvargs_process(kvlist, + ret = rte_kvargs_process_opt(kvlist, ETH_NULL_PACKET_COPY_ARG, - &get_packet_copy_arg, &args.packet_copy); + rte_kvargs_handle_bool, &args.packet_copy); if (ret < 0) goto free_kvlist; - ret = rte_kvargs_process(kvlist, + ret = rte_kvargs_process_opt(kvlist, ETH_NULL_PACKET_NO_RX_ARG, - &get_packet_no_rx_arg, &args.no_rx); + rte_kvargs_handle_bool, &args.no_rx); if (ret < 0) goto free_kvlist;
@@ -732,11 +699,12 @@ rte_pmd_null_probe(struct rte_vdev_device *dev) "Both %s and %s arguments at the same time not supported", ETH_NULL_PACKET_COPY_ARG, ETH_NULL_PACKET_NO_RX_ARG); + ret = -EINVAL; goto free_kvlist; } } - PMD_LOG(INFO, "Configure pmd_null: packet size is %d, " + PMD_LOG(INFO, "Configure pmd_null: packet size is %u, " "packet copy is %s", args.packet_size, args.packet_copy ? "enabled" : "disabled");
--
2.53.0