check_devargs_handler() is a single handler shared by all five device
arguments, which dispatches on the key to decide how to parse the value.

The dispatch is done with strncmp(key, NAME, strlen(key)), which compares
only as many bytes as the key given by the user is long, so a short key
matches a longer name by prefix. That is harmless today because
rte_kvargs_process() has already selected the pairs by exact key, but it
means the handler cannot tell which argument it was called for except by
accident.

The filtermode and filtermask branch checks errno without clearing it
first, so a stale ERANGE from unrelated earlier code rejects a valid
mask. The boolean branch tests only for "1" and silently ignores
anything else, so "keep_ovlan=yes" leaves the default in place without
complaint.

Pass the handler to cxgbe_get_devargs() instead of having one handler
work out what it was called for: rte_kvargs_handle_hex32() for the two
masks, which are documented as hexadecimal, and rte_kvargs_handle_bool()
for the three flags.

The masks are still read as hexadecimal with or without a 0x prefix, so
"filtermode=44" is unchanged. The flags now also accept "y", "yes",
"on" and "true" as well as "1", and a value which is not a boolean at
all is rejected rather than ignored.

Signed-off-by: Stephen Hemminger <[email protected]>
---
 drivers/net/cxgbe/cxgbe_main.c | 38 ++++++----------------------------
 1 file changed, 6 insertions(+), 32 deletions(-)

diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 2ed21f2d66..e0eefae6c1 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -744,36 +744,8 @@ void cxgbe_print_port_info(struct adapter *adap)
        }
 }
 
-static int check_devargs_handler(const char *key, const char *value, void *p)
-{
-       if (!strncmp(key, CXGBE_DEVARG_CMN_KEEP_OVLAN, strlen(key)) ||
-           !strncmp(key, CXGBE_DEVARG_CMN_TX_MODE_LATENCY, strlen(key)) ||
-           !strncmp(key, CXGBE_DEVARG_VF_FORCE_LINK_UP, strlen(key))) {
-               if (!strncmp(value, "1", 1)) {
-                       bool *dst_val = (bool *)p;
-
-                       *dst_val = true;
-               }
-       }
-
-       if (!strncmp(key, CXGBE_DEVARG_PF_FILTER_MODE, strlen(key)) ||
-           !strncmp(key, CXGBE_DEVARG_PF_FILTER_MASK, strlen(key))) {
-               u32 *dst_val = (u32 *)p;
-               char *endptr = NULL;
-               u32 arg_val;
-
-               arg_val = strtoul(value, &endptr, 16);
-               if (errno || endptr == value)
-                       return -EINVAL;
-
-               *dst_val = arg_val;
-       }
-
-       return 0;
-}
-
 static int cxgbe_get_devargs(struct rte_devargs *devargs, const char *key,
-                            void *p)
+                            arg_handler_t handler, void *p)
 {
        struct rte_kvargs *kvlist;
        int ret = 0;
@@ -788,7 +760,7 @@ static int cxgbe_get_devargs(struct rte_devargs *devargs, 
const char *key,
        if (!rte_kvargs_count(kvlist, key))
                goto out;
 
-       ret = rte_kvargs_process(kvlist, key, check_devargs_handler, p);
+       ret = rte_kvargs_process(kvlist, key, handler, p);
 
 out:
        rte_kvargs_free(kvlist);
@@ -807,7 +779,8 @@ static void cxgbe_get_devargs_int(struct adapter *adap, 
bool *dst,
        if (!pdev)
                return;
 
-       ret = cxgbe_get_devargs(pdev->device.devargs, key, &devarg_value);
+       ret = cxgbe_get_devargs(pdev->device.devargs, key,
+                               rte_kvargs_handle_bool, &devarg_value);
        if (ret)
                return;
 
@@ -825,7 +798,8 @@ static void cxgbe_get_devargs_u32(struct adapter *adap, u32 
*dst,
        if (!pdev)
                return;
 
-       ret = cxgbe_get_devargs(pdev->device.devargs, key, &devarg_value);
+       ret = cxgbe_get_devargs(pdev->device.devargs, key,
+                               rte_kvargs_handle_hex32, &devarg_value);
        if (ret)
                return;
 
-- 
2.53.0

Reply via email to