On 9/30/2026 12:36 AM, Stephen Hemminger wrote: > Drivers which take numeric values in devargs each open code the > conversion from string to integer, and often get it wrong. > A survey of the tree finds at least fifteen separate > implementations of "parse an unsigned integer devarg", of which two are > exported from lib/ and byte for byte identical to each other. > > The recurring bugs are: > > - atoi() is used, so overflow is undefined and nothing is validated; > - errno is checked without being reset first, so an unrelated earlier > failure rejects a valid value; > - errno is checked but endptr is not, so "foo" is silently accepted > as zero; > - endptr is checked but errno is not, so an overflowing value is > accepted as ULLONG_MAX; > - the result is stored into a narrower type with no range check, so > nb_desc=65537 silently becomes 1; > - strtoul() is used for an unsigned target, so a leading '-' is > accepted and wrapped around, and dev_caps_mask=-1 enables > everything; > - the value is dereferenced without checking for NULL, so a key given > with no value segfaults; > - base 0 is passed, so a leading zero unexpectedly selects octal. > > Add a set of helpers matching arg_handler_t, so they can be passed > straight to rte_kvargs_process(), covering the integer types drivers > actually store into. Each validates the whole string and only writes > the target on success, so a caller supplied default survives a bad > argument. > > Add rte_kvargs_handle_bool for on/off style arguments. It accepts the > word forms which only sfc supports today, and treats a key given > without a value as true. > > Where a driver needs a range narrower than the target type, expose the > underlying rte_kvargs_to_uint and rte_kvargs_to_int. > > Octal is deliberately not supported: no driver documents it, and > reading "010" as eight has been a recurring surprise. > > Signed-off-by: Stephen Hemminger <[email protected]> > ---
... > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice. > + * > + * Convert a string to a signed integer, checking it against a range. > + * > + * This is the signed counterpart of rte_kvargs_to_uint(). > + * > + * @param value > + * The string to convert. Must be non-NULL and non-empty. See > + * rte_kvargs_handle_u8() for the accepted syntax. > + * @param min > + * Smallest acceptable value, inclusive. > + * @param max > + * Largest acceptable value, inclusive. > + * @param result > + * Where to store the converted value. Left unmodified on error. > + * > + * @return > + * - 0 on success. > + * - -EINVAL if the value is missing or malformed, or if @p result is NULL. > + * - -ERANGE if the value is outside [@p min, @p max]. > + */ > +__rte_experimental > +int rte_kvargs_to_int(const char *value, int64_t min, int64_t max, > + int64_t *result); How about rte_kvargs_handle_int_range() ? > + > #ifdef __cplusplus > } > #endif

