[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250228021837.880041-4-saeed@kernel.org>
Date: Thu, 27 Feb 2025 18:18:30 -0800
From: Saeed Mahameed <saeed@...nel.org>
To: stephen@...workplumber.org,
dsahern@...il.com,
Jiri Pirko <jiri@...dia.com>,
jiri@...nulli.us
Cc: netdev@...r.kernel.org,
Saeed Mahameed <saeedm@...dia.com>
Subject: [PATCH iproute2 03/10] devlink: param show: handle multi-attribute values
From: Saeed Mahameed <saeedm@...dia.com>
Param value attribute DEVLINK_ATTR_PARAM_VALUE_DATA can be passed to/from
kernel as with type DEVLINK_DYN_ATTR_TYPE_U32_ARRAY, as such encoded data
would be U32 list of values.
Handle this case by outputting the value as comma separated list or
json list objects for get/dump requests.
example:
$ devlink dev param show <dev> name foo
<dev>
name foo type driver-specific
values:
cmode permanent value: 1,2,3,4,5,6,7,8
Signed-off-by: Saeed Mahameed <saeedm@...dia.com>
---
devlink/devlink.c | 77 ++++++++++++++++++++++++++++++++++++
include/uapi/linux/devlink.h | 1 +
2 files changed, 78 insertions(+)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index 777f769c..d659b769 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -556,6 +556,30 @@ static void pr_out_array_end(struct dl *dl)
}
}
+static void pr_out_val_array_start(struct dl *dl, const char *name,
+ const char *delimeter)
+{
+ if (dl->json_output) {
+ open_json_array(PRINT_JSON, name);
+ } else {
+ __pr_out_indent_inc();
+ pr_out(" %s:", name);
+ if (delimeter)
+ pr_out("%s", delimeter);
+ __pr_out_indent_inc();
+ }
+}
+
+static void pr_out_val_array_end(struct dl *dl)
+{
+ if (dl->json_output) {
+ close_json_array(PRINT_JSON, NULL);
+ } else {
+ __pr_out_indent_dec();
+ __pr_out_indent_dec();
+ }
+}
+
static void pr_out_object_start(struct dl *dl, const char *name)
{
if (dl->json_output) {
@@ -3396,6 +3420,41 @@ static const struct param_val_conv param_val_conv[] = {
},
};
+struct dl_param_val_list {
+ size_t len;
+ uint32_t vu32[];
+};
+
+/* Parse nested param value list
+ * @val_list_attr: nested attribute containing the list of values
+ * usually : val_list_attr = nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA]
+ * @list: pointer to the list of values, reallocated to the new size
+ * Returns: 0 on success, -errno on failure
+ */
+static int
+dl_mnl_parse_param_val_nested(struct nlattr *val_list_attr,
+ struct dl_param_val_list **list)
+{
+ struct dl_param_val_list *new_list;
+ struct nlattr *val_attr;
+ int i = 0, len = 0;
+
+ len = mnl_attr_get_payload_len(val_list_attr)/(MNL_ATTR_HDRLEN + sizeof(uint32_t));
+ if (!len)
+ return -EINVAL;
+
+ new_list = realloc(*list, sizeof(new_list) + len * sizeof(uint32_t));
+ if (!new_list)
+ return -ENOMEM;
+
+ mnl_attr_for_each_nested(val_attr, val_list_attr)
+ new_list->vu32[i++] = mnl_attr_get_u32(val_attr);
+
+ new_list->len = i;
+ *list = new_list;
+ return 0;
+}
+
#define PARAM_VAL_CONV_LEN ARRAY_SIZE(param_val_conv)
static void pr_out_param_value(struct dl *dl, const char *nla_name,
@@ -3479,6 +3538,24 @@ static void pr_out_param_value(struct dl *dl, const char *nla_name,
case DEVLINK_DYN_ATTR_TYPE_FLAG:
print_bool(PRINT_ANY, "value", " value %s", val_attr);
break;
+ case DEVLINK_DYN_ATTR_TYPE_U32_ARRAY: {
+ struct dl_param_val_list *list = NULL;
+ int err;
+ int i;
+
+ err = dl_mnl_parse_param_val_nested(val_attr, &list);
+ if (err)
+ return;
+
+ pr_out_val_array_start(dl, "value", " ");
+
+ for (i = 0; i < list->len - 1; i++)
+ print_uint(PRINT_ANY, NULL, "%u,", list->vu32[i]);
+ print_uint(PRINT_ANY, NULL, "%u", list->vu32[i]);
+ pr_out_val_array_end(dl);
+ free(list);
+ break;
+ }
default:
break;
}
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index b822baf9..5338db89 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -400,6 +400,7 @@ enum devlink_dyn_attr_type {
DEVLINK_DYN_ATTR_TYPE_BINARY,
__DEVLINK_DYN_ATTR_TYPE_CUSTOM_BASE = 0x80,
/* Any possible custom types, unrelated to NLA_* values go below */
+ DEVLINK_DYN_ATTR_TYPE_U32_ARRAY,
};
enum devlink_attr {
--
2.48.1
Powered by blists - more mailing lists