Thread (65 messages) flat view 65 messages, 3 authors, 1d ago
WARM1d

[PATCH 37/62] net/cnxk: use kvargs numeric helpers

From: Stephen Hemminger <stephen@networkplumber.org>
Date: 2026-09-14 05:53:06
Subsystem: networking drivers, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

Most handlers in this file used atoi(), which cannot report an error, so
a malformed value was silently taken as zero. Several of them also
assigned a uint32_t into a uint16_t without a range check, so a value
such as "65536" wrapped to zero.

parse_ipsec_in_spi_range(), parse_ipsec_out_max_sa() and
parse_meta_bufsize() went further and deliberately swallowed the error,
setting the value to zero and returning success.

Seven of the handlers were left doing nothing beyond a plain range
checked store, so drop them and pass rte_kvargs_handle_u16() or
rte_kvargs_handle_u32() to rte_kvargs_process() directly. The rest keep
a local handler because they have a narrower range or non-numeric
syntax.

Since the handlers can now fail, propagate the rte_kvargs_process()
return value instead of discarding it, so that a bad argument fails
probe rather than being ignored.

The pre_l2 header and SDP channel mask parsers are left alone: each
packs several fields into one value separated by punctuation, as in
flow_pre_l2_info=0x2/0x7e/0x1, which no single arg_handler_t can parse.

The eleven boolean arguments become bool and use
rte_kvargs_handle_bool(): scalar_enable, tx_compl_ena, tag_as_xor,
lock_rx_ctx, no_inl_dev, custom_sa_act, rx_inj_ena,
custom_meta_aura_dis, custom_inb_sa, force_tail_drop and
disable_xqe_drop. Most of the fields behind them are already bool, so
the "!!" coercions on the way in are no longer needed. A bare key now
enables the option, and the usual spellings are accepted.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/cnxk/cnxk_ethdev_devargs.c | 277 ++++++++-----------------
 1 file changed, 91 insertions(+), 186 deletions(-)
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index ea18090919..25ba203027 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -5,6 +5,8 @@
 #include <inttypes.h>
 #include <math.h>
 
+#include <rte_kvargs.h>
+
 #include "cnxk_ethdev.h"
 
 struct sdp_channel {
@@ -19,28 +21,14 @@ struct flow_pre_l2_size_info {
 	uint8_t pre_l2_size_shift_dir;
 };
 
-static int
-parse_outb_nb_desc(const char *key, const char *value, void *extra_args)
-{
-	RTE_SET_USED(key);
-	uint32_t val;
-
-	val = atoi(value);
-
-	*(uint16_t *)extra_args = val;
-
-	return 0;
-}
-
 static int
 parse_outb_nb_crypto_qs(const char *key, const char *value, void *extra_args)
 {
-	RTE_SET_USED(key);
-	uint32_t val;
+	uint64_t val;
 
-	val = atoi(value);
+	RTE_SET_USED(key);
 
-	if (val < 1 || val > 64)
+	if (rte_kvargs_to_uint(value, 1, 64, &val) < 0)
 		return -EINVAL;
 
 	*(uint16_t *)extra_args = val;
@@ -48,51 +36,15 @@ parse_outb_nb_crypto_qs(const char *key, const char *value, void *extra_args)
 	return 0;
 }
 
-static int
-parse_ipsec_in_spi_range(const char *key, const char *value, void *extra_args)
-{
-	RTE_SET_USED(key);
-	uint32_t val;
-
-	errno = 0;
-	val = strtoul(value, NULL, 0);
-	if (errno)
-		val = 0;
-
-	*(uint32_t *)extra_args = val;
-
-	return 0;
-}
-
 static int
 parse_rxc_step(const char *key, const char *value, void *extra_args)
 {
-	RTE_SET_USED(key);
-	uint32_t val;
+	uint64_t val;
 
-	errno = 0;
-	val = strtoul(value, NULL, 0);
-	if (errno)
-		return -EINVAL;
-
-	if (val > ROC_NIX_INL_REAS_STEP_MAX)
-		return -EINVAL;
-
-	*(uint32_t *)extra_args = val;
-
-	return 0;
-}
-
-static int
-parse_ipsec_out_max_sa(const char *key, const char *value, void *extra_args)
-{
 	RTE_SET_USED(key);
-	uint32_t val;
 
-	errno = 0;
-	val = strtoul(value, NULL, 0);
-	if (errno)
-		val = 0;
+	if (rte_kvargs_to_uint(value, 0, ROC_NIX_INL_REAS_STEP_MAX, &val) < 0)
+		return -EINVAL;
 
 	*(uint32_t *)extra_args = val;
 
@@ -102,12 +54,11 @@ parse_ipsec_out_max_sa(const char *key, const char *value, void *extra_args)
 static int
 parse_flow_max_priority(const char *key, const char *value, void *extra_args)
 {
-	RTE_SET_USED(key);
-	uint16_t val;
+	uint64_t val;
 
-	val = atoi(value);
+	RTE_SET_USED(key);
 
-	if (val < 1 || val > ROC_NPC_MAX_MCAM_PRIORITY)
+	if (rte_kvargs_to_uint(value, 1, ROC_NPC_MAX_MCAM_PRIORITY, &val) < 0)
 		return -EINVAL;
 
 	*(uint16_t *)extra_args = val;
@@ -118,13 +69,12 @@ parse_flow_max_priority(const char *key, const char *value, void *extra_args)
 static int
 parse_flow_prealloc_size(const char *key, const char *value, void *extra_args)
 {
-	RTE_SET_USED(key);
-	uint16_t val;
+	uint64_t val;
 
-	val = atoi(value);
+	RTE_SET_USED(key);
 
 	/* Limit the prealloc size to 32 */
-	if (val < 1 || val > 32)
+	if (rte_kvargs_to_uint(value, 1, 32, &val) < 0)
 		return -EINVAL;
 
 	*(uint16_t *)extra_args = val;
@@ -135,10 +85,12 @@ parse_flow_prealloc_size(const char *key, const char *value, void *extra_args)
 static int
 parse_reta_size(const char *key, const char *value, void *extra_args)
 {
+	uint64_t val;
+
 	RTE_SET_USED(key);
-	uint32_t val;
 
-	val = atoi(value);
+	if (rte_kvargs_to_uint(value, 0, UINT32_MAX, &val) < 0)
+		return -EINVAL;
 
 	if (val <= RTE_ETH_RSS_RETA_SIZE_64)
 		val = ROC_NIX_RSS_RETA_SZ_64;
@@ -177,45 +129,6 @@ parse_pre_l2_hdr_info(const char *key, const char *value, void *extra_args)
 	return 0;
 }
 
-static int
-parse_flag(const char *key, const char *value, void *extra_args)
-{
-	RTE_SET_USED(key);
-
-	*(uint16_t *)extra_args = atoi(value);
-
-	return 0;
-}
-
-static int
-parse_sqb_count(const char *key, const char *value, void *extra_args)
-{
-	RTE_SET_USED(key);
-	uint32_t val;
-
-	val = atoi(value);
-
-	*(uint16_t *)extra_args = val;
-
-	return 0;
-}
-
-static int
-parse_meta_bufsize(const char *key, const char *value, void *extra_args)
-{
-	RTE_SET_USED(key);
-	uint32_t val;
-
-	errno = 0;
-	val = strtoul(value, NULL, 0);
-	if (errno)
-		val = 0;
-
-	*(uint32_t *)extra_args = val;
-
-	return 0;
-}
-
 static int
 parse_switch_header_type(const char *key, const char *value, void *extra_args)
 {
@@ -248,12 +161,11 @@ parse_switch_header_type(const char *key, const char *value, void *extra_args)
 static int
 parse_skip_size_info(const char *key, const char *value, void *extra_args)
 {
+	uint64_t val;
+
 	RTE_SET_USED(key);
-	uint32_t val;
 
-	errno = 0;
-	val = strtoul(value, NULL, 0);
-	if (errno || val > 255)
+	if (rte_kvargs_to_uint(value, 0, 255, &val) < 0)
 		return -EINVAL;
 
 	*(uint16_t *)extra_args = val;
@@ -282,19 +194,6 @@ parse_sdp_channel_mask(const char *key, const char *value, void *extra_args)
 	return 0;
 }
 
-static int
-parse_val_u16(const char *key, const char *value, void *extra_args)
-{
-	RTE_SET_USED(key);
-	uint16_t val;
-
-	val = atoi(value);
-
-	*(uint16_t *)extra_args = val;
-
-	return 0;
-}
-
 #define CNXK_RSS_RETA_SIZE	"reta_size"
 #define CNXK_SCL_ENABLE		"scalar_enable"
 #define CNXK_TX_COMPL_ENA       "tx_compl_ena"
@@ -334,7 +233,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	uint32_t ipsec_in_max_spi = BIT(8) - 1;
 	uint16_t sqb_slack = ROC_NIX_SQB_SLACK;
 	uint32_t ipsec_out_max_sa = BIT(12);
-	uint16_t custom_meta_aura_dis = 0;
+	bool custom_meta_aura_dis = false;
 	uint16_t flow_prealloc_size = 1;
 	uint16_t switch_header_type = 0;
 	uint16_t skip_size_info = 0;
@@ -343,19 +242,20 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	uint32_t ipsec_in_min_spi = 0;
 	uint16_t outb_nb_desc = 8200;
 	struct sdp_channel sdp_chan;
-	uint16_t rss_tag_as_xor = 0;
-	uint16_t force_tail_drop = 0;
-	uint16_t scalar_enable = 0;
-	uint16_t tx_compl_ena = 0;
-	uint16_t custom_sa_act = 0;
-	uint16_t custom_inb_sa = 0;
+	bool rss_tag_as_xor = false;
+	bool force_tail_drop = false;
+	bool scalar_enable = false;
+	bool tx_compl_ena = false;
+	bool custom_sa_act = false;
+	bool custom_inb_sa = false;
 	struct rte_kvargs *kvlist;
-	uint16_t dis_xqe_drop = 0;
+	bool dis_xqe_drop = false;
 	uint32_t meta_buf_sz = 0;
-	uint16_t lock_rx_ctx = 0;
-	uint16_t rx_inj_ena = 0;
-	uint16_t no_inl_dev = 0;
+	bool lock_rx_ctx = false;
+	bool rx_inj_ena = false;
+	bool no_inl_dev = false;
 	uint32_t rxc_step = 0;
+	int ret;
 
 	memset(&sdp_chan, 0, sizeof(sdp_chan));
 	memset(&pre_l2_info, 0, sizeof(struct flow_pre_l2_size_info));
@@ -367,60 +267,65 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	if (kvlist == NULL)
 		goto exit;
 
-	rte_kvargs_process(kvlist, CNXK_RSS_RETA_SIZE, &parse_reta_size,
-			   &reta_sz);
-	rte_kvargs_process(kvlist, CNXK_SCL_ENABLE, &parse_flag,
-			   &scalar_enable);
-	rte_kvargs_process(kvlist, CNXK_TX_COMPL_ENA, &parse_flag,
-			   &tx_compl_ena);
-	rte_kvargs_process(kvlist, CNXK_MAX_SQB_COUNT, &parse_sqb_count,
-			   &sqb_count);
-	rte_kvargs_process(kvlist, CNXK_FLOW_PREALLOC_SIZE,
-			   &parse_flow_prealloc_size, &flow_prealloc_size);
-	rte_kvargs_process(kvlist, CNXK_FLOW_MAX_PRIORITY,
-			   &parse_flow_max_priority, &flow_max_priority);
-	rte_kvargs_process(kvlist, CNXK_SWITCH_HEADER_TYPE,
-			   &parse_switch_header_type, &switch_header_type);
-	rte_kvargs_process(kvlist, CNXK_RSS_TAG_AS_XOR, &parse_flag,
-			   &rss_tag_as_xor);
-	rte_kvargs_process(kvlist, CNXK_LOCK_RX_CTX, &parse_flag, &lock_rx_ctx);
-	rte_kvargs_process(kvlist, CNXK_IPSEC_IN_MIN_SPI,
-			   &parse_ipsec_in_spi_range, &ipsec_in_min_spi);
-	rte_kvargs_process(kvlist, CNXK_IPSEC_IN_MAX_SPI,
-			   &parse_ipsec_in_spi_range, &ipsec_in_max_spi);
-	rte_kvargs_process(kvlist, CNXK_IPSEC_OUT_MAX_SA,
-			   &parse_ipsec_out_max_sa, &ipsec_out_max_sa);
-	rte_kvargs_process(kvlist, CNXK_OUTB_NB_DESC, &parse_outb_nb_desc,
-			   &outb_nb_desc);
-	rte_kvargs_process(kvlist, CNXK_OUTB_NB_CRYPTO_QS,
-			   &parse_outb_nb_crypto_qs, &outb_nb_crypto_qs);
-	rte_kvargs_process(kvlist, CNXK_NO_INL_DEV, &parse_flag, &no_inl_dev);
-	rte_kvargs_process(kvlist, CNXK_SDP_CHANNEL_MASK,
-			   &parse_sdp_channel_mask, &sdp_chan);
-	rte_kvargs_process(kvlist, CNXK_FLOW_PRE_L2_INFO,
-			   &parse_pre_l2_hdr_info, &pre_l2_info);
-	rte_kvargs_process(kvlist, CNXK_CUSTOM_SA_ACT, &parse_flag,
-			   &custom_sa_act);
-	rte_kvargs_process(kvlist, CNXK_SQB_SLACK, &parse_sqb_count,
-			   &sqb_slack);
-	rte_kvargs_process(kvlist, CNXK_NIX_META_BUF_SZ, &parse_meta_bufsize, &meta_buf_sz);
-	rte_kvargs_process(kvlist, CNXK_FLOW_AGING_POLL_FREQ, &parse_val_u16,
-			   &aging_thread_poll_freq);
-	rte_kvargs_process(kvlist, CNXK_NIX_RX_INJ_ENABLE, &parse_flag, &rx_inj_ena);
-	rte_kvargs_process(kvlist, CNXK_CUSTOM_META_AURA_DIS, &parse_flag,
-			   &custom_meta_aura_dis);
-	rte_kvargs_process(kvlist, CNXK_CUSTOM_INB_SA, &parse_flag, &custom_inb_sa);
-	rte_kvargs_process(kvlist, CNXK_FORCE_TAIL_DROP, &parse_flag, &force_tail_drop);
-	rte_kvargs_process(kvlist, CNXK_DIS_XQE_DROP, &parse_flag, &dis_xqe_drop);
-	rte_kvargs_process(kvlist, CNXK_RXC_STEP, &parse_rxc_step, &rxc_step);
-	rte_kvargs_process(kvlist, CNXK_SKIP_SIZE_INFO, &parse_skip_size_info,
-			   &skip_size_info);
+	ret = 0;
+	ret |= rte_kvargs_process(kvlist, CNXK_RSS_RETA_SIZE, &parse_reta_size,
+				  &reta_sz);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_SCL_ENABLE, rte_kvargs_handle_bool,
+				  &scalar_enable);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_TX_COMPL_ENA, rte_kvargs_handle_bool,
+				  &tx_compl_ena);
+	ret |= rte_kvargs_process(kvlist, CNXK_MAX_SQB_COUNT, rte_kvargs_handle_u16,
+				  &sqb_count);
+	ret |= rte_kvargs_process(kvlist, CNXK_FLOW_PREALLOC_SIZE,
+				  &parse_flow_prealloc_size, &flow_prealloc_size);
+	ret |= rte_kvargs_process(kvlist, CNXK_FLOW_MAX_PRIORITY,
+				  &parse_flow_max_priority, &flow_max_priority);
+	ret |= rte_kvargs_process(kvlist, CNXK_SWITCH_HEADER_TYPE,
+				  &parse_switch_header_type, &switch_header_type);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_RSS_TAG_AS_XOR, rte_kvargs_handle_bool,
+				  &rss_tag_as_xor);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_LOCK_RX_CTX, rte_kvargs_handle_bool, &lock_rx_ctx);
+	ret |= rte_kvargs_process(kvlist, CNXK_IPSEC_IN_MIN_SPI,
+				  rte_kvargs_handle_u32, &ipsec_in_min_spi);
+	ret |= rte_kvargs_process(kvlist, CNXK_IPSEC_IN_MAX_SPI,
+				  rte_kvargs_handle_u32, &ipsec_in_max_spi);
+	ret |= rte_kvargs_process(kvlist, CNXK_IPSEC_OUT_MAX_SA,
+				  rte_kvargs_handle_u32, &ipsec_out_max_sa);
+	ret |= rte_kvargs_process(kvlist, CNXK_OUTB_NB_DESC, rte_kvargs_handle_u16,
+				  &outb_nb_desc);
+	ret |= rte_kvargs_process(kvlist, CNXK_OUTB_NB_CRYPTO_QS,
+				  &parse_outb_nb_crypto_qs, &outb_nb_crypto_qs);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_NO_INL_DEV, rte_kvargs_handle_bool, &no_inl_dev);
+	ret |= rte_kvargs_process(kvlist, CNXK_SDP_CHANNEL_MASK,
+				  &parse_sdp_channel_mask, &sdp_chan);
+	ret |= rte_kvargs_process(kvlist, CNXK_FLOW_PRE_L2_INFO,
+				  &parse_pre_l2_hdr_info, &pre_l2_info);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_CUSTOM_SA_ACT, rte_kvargs_handle_bool,
+				  &custom_sa_act);
+	ret |= rte_kvargs_process(kvlist, CNXK_SQB_SLACK, rte_kvargs_handle_u16,
+				  &sqb_slack);
+	ret |= rte_kvargs_process(kvlist, CNXK_NIX_META_BUF_SZ, rte_kvargs_handle_u32, &meta_buf_sz);
+	ret |= rte_kvargs_process(kvlist, CNXK_FLOW_AGING_POLL_FREQ, rte_kvargs_handle_u16,
+				  &aging_thread_poll_freq);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_NIX_RX_INJ_ENABLE, rte_kvargs_handle_bool, &rx_inj_ena);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_CUSTOM_META_AURA_DIS, rte_kvargs_handle_bool,
+				  &custom_meta_aura_dis);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_CUSTOM_INB_SA, rte_kvargs_handle_bool, &custom_inb_sa);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_FORCE_TAIL_DROP, rte_kvargs_handle_bool,
+				  &force_tail_drop);
+	ret |= rte_kvargs_process_opt(kvlist, CNXK_DIS_XQE_DROP, rte_kvargs_handle_bool, &dis_xqe_drop);
+	ret |= rte_kvargs_process(kvlist, CNXK_RXC_STEP, &parse_rxc_step, &rxc_step);
+	ret |= rte_kvargs_process(kvlist, CNXK_SKIP_SIZE_INFO, &parse_skip_size_info,
+				  &skip_size_info);
 	rte_kvargs_free(kvlist);
 
+	if (ret != 0)
+		goto exit;
+
 null_devargs:
-	dev->scalar_ena = !!scalar_enable;
-	dev->tx_compl_ena = !!tx_compl_ena;
-	dev->inb.no_inl_dev = !!no_inl_dev;
+	dev->scalar_ena = scalar_enable;
+	dev->tx_compl_ena = tx_compl_ena;
+	dev->inb.no_inl_dev = no_inl_dev;
 	dev->inb.min_spi = ipsec_in_min_spi;
 	dev->inb.max_spi = ipsec_in_max_spi;
 	dev->inb.custom_meta_aura_dis = custom_meta_aura_dis;
@@ -428,7 +333,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	dev->outb.nb_desc = outb_nb_desc;
 	dev->outb.nb_crypto_qs = outb_nb_crypto_qs;
 	dev->nix.ipsec_out_max_sa = ipsec_out_max_sa;
-	dev->nix.rss_tag_as_xor = !!rss_tag_as_xor;
+	dev->nix.rss_tag_as_xor = rss_tag_as_xor;
 	dev->nix.max_sqb_count = sqb_count;
 	dev->nix.reta_sz = reta_sz;
 	dev->nix.lock_rx_ctx = lock_rx_ctx;
@@ -458,7 +363,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	if (roc_feature_nix_has_rx_inject())
 		dev->nix.rx_inj_ena = rx_inj_ena;
 	dev->nix.force_tail_drop = force_tail_drop;
-	dev->nix.dis_xqe_drop = !!dis_xqe_drop;
+	dev->nix.dis_xqe_drop = dis_xqe_drop;
 	dev->nix.rxc_step = rxc_step;
 	return 0;
 exit:
-- 
2.53.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help