1 // SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
2 /* Do not edit directly, auto-generated from: */
3 /* Documentation/netlink/specs/devlink.yaml */
4 /* YNL-GEN user source */
8 #include "devlink-user.h"
10 #include <linux/devlink.h>
12 #include <libmnl/libmnl.h>
13 #include <linux/genetlink.h>
16 static const char * const devlink_op_strmap[] = {
18 [DEVLINK_CMD_INFO_GET] = "info-get",
21 const char *devlink_op_str(int op)
23 if (op < 0 || op >= (int)MNL_ARRAY_SIZE(devlink_op_strmap))
25 return devlink_op_strmap[op];
29 struct ynl_policy_attr devlink_dl_info_version_policy[DEVLINK_ATTR_MAX + 1] = {
30 [DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, },
31 [DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, },
34 struct ynl_policy_nest devlink_dl_info_version_nest = {
35 .max_attr = DEVLINK_ATTR_MAX,
36 .table = devlink_dl_info_version_policy,
39 struct ynl_policy_attr devlink_dl_reload_stats_entry_policy[DEVLINK_ATTR_MAX + 1] = {
40 [DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, },
41 [DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, },
44 struct ynl_policy_nest devlink_dl_reload_stats_entry_nest = {
45 .max_attr = DEVLINK_ATTR_MAX,
46 .table = devlink_dl_reload_stats_entry_policy,
49 struct ynl_policy_attr devlink_dl_reload_act_stats_policy[DEVLINK_ATTR_MAX + 1] = {
50 [DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, },
53 struct ynl_policy_nest devlink_dl_reload_act_stats_nest = {
54 .max_attr = DEVLINK_ATTR_MAX,
55 .table = devlink_dl_reload_act_stats_policy,
58 struct ynl_policy_attr devlink_dl_reload_act_info_policy[DEVLINK_ATTR_MAX + 1] = {
59 [DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, },
60 [DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, },
63 struct ynl_policy_nest devlink_dl_reload_act_info_nest = {
64 .max_attr = DEVLINK_ATTR_MAX,
65 .table = devlink_dl_reload_act_info_policy,
68 struct ynl_policy_attr devlink_dl_reload_stats_policy[DEVLINK_ATTR_MAX + 1] = {
69 [DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, },
72 struct ynl_policy_nest devlink_dl_reload_stats_nest = {
73 .max_attr = DEVLINK_ATTR_MAX,
74 .table = devlink_dl_reload_stats_policy,
77 struct ynl_policy_attr devlink_dl_dev_stats_policy[DEVLINK_ATTR_MAX + 1] = {
78 [DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
79 [DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
82 struct ynl_policy_nest devlink_dl_dev_stats_nest = {
83 .max_attr = DEVLINK_ATTR_MAX,
84 .table = devlink_dl_dev_stats_policy,
87 struct ynl_policy_attr devlink_policy[DEVLINK_ATTR_MAX + 1] = {
88 [DEVLINK_ATTR_BUS_NAME] = { .name = "bus-name", .type = YNL_PT_NUL_STR, },
89 [DEVLINK_ATTR_DEV_NAME] = { .name = "dev-name", .type = YNL_PT_NUL_STR, },
90 [DEVLINK_ATTR_PORT_INDEX] = { .name = "port-index", .type = YNL_PT_U32, },
91 [DEVLINK_ATTR_INFO_DRIVER_NAME] = { .name = "info-driver-name", .type = YNL_PT_NUL_STR, },
92 [DEVLINK_ATTR_INFO_SERIAL_NUMBER] = { .name = "info-serial-number", .type = YNL_PT_NUL_STR, },
93 [DEVLINK_ATTR_INFO_VERSION_FIXED] = { .name = "info-version-fixed", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
94 [DEVLINK_ATTR_INFO_VERSION_RUNNING] = { .name = "info-version-running", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
95 [DEVLINK_ATTR_INFO_VERSION_STORED] = { .name = "info-version-stored", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
96 [DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, },
97 [DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, },
98 [DEVLINK_ATTR_RELOAD_FAILED] = { .name = "reload-failed", .type = YNL_PT_U8, },
99 [DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, },
100 [DEVLINK_ATTR_DEV_STATS] = { .name = "dev-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_dev_stats_nest, },
101 [DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
102 [DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, },
103 [DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, },
104 [DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, },
105 [DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
106 [DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, },
107 [DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, },
110 struct ynl_policy_nest devlink_nest = {
111 .max_attr = DEVLINK_ATTR_MAX,
112 .table = devlink_policy,
115 /* Common nested types */
116 void devlink_dl_info_version_free(struct devlink_dl_info_version *obj)
118 free(obj->info_version_name);
119 free(obj->info_version_value);
122 int devlink_dl_info_version_parse(struct ynl_parse_arg *yarg,
123 const struct nlattr *nested)
125 struct devlink_dl_info_version *dst = yarg->data;
126 const struct nlattr *attr;
128 mnl_attr_for_each_nested(attr, nested) {
129 unsigned int type = mnl_attr_get_type(attr);
131 if (type == DEVLINK_ATTR_INFO_VERSION_NAME) {
134 if (ynl_attr_validate(yarg, attr))
137 len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
138 dst->_present.info_version_name_len = len;
139 dst->info_version_name = malloc(len + 1);
140 memcpy(dst->info_version_name, mnl_attr_get_str(attr), len);
141 dst->info_version_name[len] = 0;
142 } else if (type == DEVLINK_ATTR_INFO_VERSION_VALUE) {
145 if (ynl_attr_validate(yarg, attr))
148 len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
149 dst->_present.info_version_value_len = len;
150 dst->info_version_value = malloc(len + 1);
151 memcpy(dst->info_version_value, mnl_attr_get_str(attr), len);
152 dst->info_version_value[len] = 0;
160 devlink_dl_reload_stats_entry_free(struct devlink_dl_reload_stats_entry *obj)
164 int devlink_dl_reload_stats_entry_parse(struct ynl_parse_arg *yarg,
165 const struct nlattr *nested)
167 struct devlink_dl_reload_stats_entry *dst = yarg->data;
168 const struct nlattr *attr;
170 mnl_attr_for_each_nested(attr, nested) {
171 unsigned int type = mnl_attr_get_type(attr);
173 if (type == DEVLINK_ATTR_RELOAD_STATS_LIMIT) {
174 if (ynl_attr_validate(yarg, attr))
176 dst->_present.reload_stats_limit = 1;
177 dst->reload_stats_limit = mnl_attr_get_u8(attr);
178 } else if (type == DEVLINK_ATTR_RELOAD_STATS_VALUE) {
179 if (ynl_attr_validate(yarg, attr))
181 dst->_present.reload_stats_value = 1;
182 dst->reload_stats_value = mnl_attr_get_u32(attr);
189 void devlink_dl_reload_act_stats_free(struct devlink_dl_reload_act_stats *obj)
193 for (i = 0; i < obj->n_reload_stats_entry; i++)
194 devlink_dl_reload_stats_entry_free(&obj->reload_stats_entry[i]);
195 free(obj->reload_stats_entry);
198 int devlink_dl_reload_act_stats_parse(struct ynl_parse_arg *yarg,
199 const struct nlattr *nested)
201 struct devlink_dl_reload_act_stats *dst = yarg->data;
202 unsigned int n_reload_stats_entry = 0;
203 const struct nlattr *attr;
204 struct ynl_parse_arg parg;
209 if (dst->reload_stats_entry)
210 return ynl_error_parse(yarg, "attribute already present (dl-reload-act-stats.reload-stats-entry)");
212 mnl_attr_for_each_nested(attr, nested) {
213 unsigned int type = mnl_attr_get_type(attr);
215 if (type == DEVLINK_ATTR_RELOAD_STATS_ENTRY) {
216 n_reload_stats_entry++;
220 if (n_reload_stats_entry) {
221 dst->reload_stats_entry = calloc(n_reload_stats_entry, sizeof(*dst->reload_stats_entry));
222 dst->n_reload_stats_entry = n_reload_stats_entry;
224 parg.rsp_policy = &devlink_dl_reload_stats_entry_nest;
225 mnl_attr_for_each_nested(attr, nested) {
226 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) {
227 parg.data = &dst->reload_stats_entry[i];
228 if (devlink_dl_reload_stats_entry_parse(&parg, attr))
238 void devlink_dl_reload_act_info_free(struct devlink_dl_reload_act_info *obj)
242 for (i = 0; i < obj->n_reload_action_stats; i++)
243 devlink_dl_reload_act_stats_free(&obj->reload_action_stats[i]);
244 free(obj->reload_action_stats);
247 int devlink_dl_reload_act_info_parse(struct ynl_parse_arg *yarg,
248 const struct nlattr *nested)
250 struct devlink_dl_reload_act_info *dst = yarg->data;
251 unsigned int n_reload_action_stats = 0;
252 const struct nlattr *attr;
253 struct ynl_parse_arg parg;
258 if (dst->reload_action_stats)
259 return ynl_error_parse(yarg, "attribute already present (dl-reload-act-info.reload-action-stats)");
261 mnl_attr_for_each_nested(attr, nested) {
262 unsigned int type = mnl_attr_get_type(attr);
264 if (type == DEVLINK_ATTR_RELOAD_ACTION) {
265 if (ynl_attr_validate(yarg, attr))
267 dst->_present.reload_action = 1;
268 dst->reload_action = mnl_attr_get_u8(attr);
269 } else if (type == DEVLINK_ATTR_RELOAD_ACTION_STATS) {
270 n_reload_action_stats++;
274 if (n_reload_action_stats) {
275 dst->reload_action_stats = calloc(n_reload_action_stats, sizeof(*dst->reload_action_stats));
276 dst->n_reload_action_stats = n_reload_action_stats;
278 parg.rsp_policy = &devlink_dl_reload_act_stats_nest;
279 mnl_attr_for_each_nested(attr, nested) {
280 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) {
281 parg.data = &dst->reload_action_stats[i];
282 if (devlink_dl_reload_act_stats_parse(&parg, attr))
292 void devlink_dl_reload_stats_free(struct devlink_dl_reload_stats *obj)
296 for (i = 0; i < obj->n_reload_action_info; i++)
297 devlink_dl_reload_act_info_free(&obj->reload_action_info[i]);
298 free(obj->reload_action_info);
301 int devlink_dl_reload_stats_parse(struct ynl_parse_arg *yarg,
302 const struct nlattr *nested)
304 struct devlink_dl_reload_stats *dst = yarg->data;
305 unsigned int n_reload_action_info = 0;
306 const struct nlattr *attr;
307 struct ynl_parse_arg parg;
312 if (dst->reload_action_info)
313 return ynl_error_parse(yarg, "attribute already present (dl-reload-stats.reload-action-info)");
315 mnl_attr_for_each_nested(attr, nested) {
316 unsigned int type = mnl_attr_get_type(attr);
318 if (type == DEVLINK_ATTR_RELOAD_ACTION_INFO) {
319 n_reload_action_info++;
323 if (n_reload_action_info) {
324 dst->reload_action_info = calloc(n_reload_action_info, sizeof(*dst->reload_action_info));
325 dst->n_reload_action_info = n_reload_action_info;
327 parg.rsp_policy = &devlink_dl_reload_act_info_nest;
328 mnl_attr_for_each_nested(attr, nested) {
329 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) {
330 parg.data = &dst->reload_action_info[i];
331 if (devlink_dl_reload_act_info_parse(&parg, attr))
341 void devlink_dl_dev_stats_free(struct devlink_dl_dev_stats *obj)
343 devlink_dl_reload_stats_free(&obj->reload_stats);
344 devlink_dl_reload_stats_free(&obj->remote_reload_stats);
347 int devlink_dl_dev_stats_parse(struct ynl_parse_arg *yarg,
348 const struct nlattr *nested)
350 struct devlink_dl_dev_stats *dst = yarg->data;
351 const struct nlattr *attr;
352 struct ynl_parse_arg parg;
356 mnl_attr_for_each_nested(attr, nested) {
357 unsigned int type = mnl_attr_get_type(attr);
359 if (type == DEVLINK_ATTR_RELOAD_STATS) {
360 if (ynl_attr_validate(yarg, attr))
362 dst->_present.reload_stats = 1;
364 parg.rsp_policy = &devlink_dl_reload_stats_nest;
365 parg.data = &dst->reload_stats;
366 if (devlink_dl_reload_stats_parse(&parg, attr))
368 } else if (type == DEVLINK_ATTR_REMOTE_RELOAD_STATS) {
369 if (ynl_attr_validate(yarg, attr))
371 dst->_present.remote_reload_stats = 1;
373 parg.rsp_policy = &devlink_dl_reload_stats_nest;
374 parg.data = &dst->remote_reload_stats;
375 if (devlink_dl_reload_stats_parse(&parg, attr))
383 /* ============== DEVLINK_CMD_GET ============== */
384 /* DEVLINK_CMD_GET - do */
385 void devlink_get_req_free(struct devlink_get_req *req)
392 void devlink_get_rsp_free(struct devlink_get_rsp *rsp)
396 devlink_dl_dev_stats_free(&rsp->dev_stats);
400 int devlink_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
402 struct ynl_parse_arg *yarg = data;
403 struct devlink_get_rsp *dst;
404 const struct nlattr *attr;
405 struct ynl_parse_arg parg;
410 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
411 unsigned int type = mnl_attr_get_type(attr);
413 if (type == DEVLINK_ATTR_BUS_NAME) {
416 if (ynl_attr_validate(yarg, attr))
419 len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
420 dst->_present.bus_name_len = len;
421 dst->bus_name = malloc(len + 1);
422 memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
423 dst->bus_name[len] = 0;
424 } else if (type == DEVLINK_ATTR_DEV_NAME) {
427 if (ynl_attr_validate(yarg, attr))
430 len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
431 dst->_present.dev_name_len = len;
432 dst->dev_name = malloc(len + 1);
433 memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
434 dst->dev_name[len] = 0;
435 } else if (type == DEVLINK_ATTR_RELOAD_FAILED) {
436 if (ynl_attr_validate(yarg, attr))
438 dst->_present.reload_failed = 1;
439 dst->reload_failed = mnl_attr_get_u8(attr);
440 } else if (type == DEVLINK_ATTR_RELOAD_ACTION) {
441 if (ynl_attr_validate(yarg, attr))
443 dst->_present.reload_action = 1;
444 dst->reload_action = mnl_attr_get_u8(attr);
445 } else if (type == DEVLINK_ATTR_DEV_STATS) {
446 if (ynl_attr_validate(yarg, attr))
448 dst->_present.dev_stats = 1;
450 parg.rsp_policy = &devlink_dl_dev_stats_nest;
451 parg.data = &dst->dev_stats;
452 if (devlink_dl_dev_stats_parse(&parg, attr))
460 struct devlink_get_rsp *
461 devlink_get(struct ynl_sock *ys, struct devlink_get_req *req)
463 struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
464 struct devlink_get_rsp *rsp;
465 struct nlmsghdr *nlh;
468 nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_GET, 1);
469 ys->req_policy = &devlink_nest;
470 yrs.yarg.rsp_policy = &devlink_nest;
472 if (req->_present.bus_name_len)
473 mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
474 if (req->_present.dev_name_len)
475 mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
477 rsp = calloc(1, sizeof(*rsp));
479 yrs.cb = devlink_get_rsp_parse;
482 err = ynl_exec(ys, nlh, &yrs);
489 devlink_get_rsp_free(rsp);
493 /* DEVLINK_CMD_GET - dump */
494 void devlink_get_list_free(struct devlink_get_list *rsp)
496 struct devlink_get_list *next = rsp;
498 while ((void *)next != YNL_LIST_END) {
502 free(rsp->obj.bus_name);
503 free(rsp->obj.dev_name);
504 devlink_dl_dev_stats_free(&rsp->obj.dev_stats);
509 struct devlink_get_list *devlink_get_dump(struct ynl_sock *ys)
511 struct ynl_dump_state yds = {};
512 struct nlmsghdr *nlh;
516 yds.alloc_sz = sizeof(struct devlink_get_list);
517 yds.cb = devlink_get_rsp_parse;
519 yds.rsp_policy = &devlink_nest;
521 nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_GET, 1);
523 err = ynl_exec_dump(ys, nlh, &yds);
530 devlink_get_list_free(yds.first);
534 /* ============== DEVLINK_CMD_INFO_GET ============== */
535 /* DEVLINK_CMD_INFO_GET - do */
536 void devlink_info_get_req_free(struct devlink_info_get_req *req)
543 void devlink_info_get_rsp_free(struct devlink_info_get_rsp *rsp)
549 free(rsp->info_driver_name);
550 free(rsp->info_serial_number);
551 for (i = 0; i < rsp->n_info_version_fixed; i++)
552 devlink_dl_info_version_free(&rsp->info_version_fixed[i]);
553 free(rsp->info_version_fixed);
554 for (i = 0; i < rsp->n_info_version_running; i++)
555 devlink_dl_info_version_free(&rsp->info_version_running[i]);
556 free(rsp->info_version_running);
557 for (i = 0; i < rsp->n_info_version_stored; i++)
558 devlink_dl_info_version_free(&rsp->info_version_stored[i]);
559 free(rsp->info_version_stored);
563 int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
565 unsigned int n_info_version_running = 0;
566 unsigned int n_info_version_stored = 0;
567 unsigned int n_info_version_fixed = 0;
568 struct ynl_parse_arg *yarg = data;
569 struct devlink_info_get_rsp *dst;
570 const struct nlattr *attr;
571 struct ynl_parse_arg parg;
577 if (dst->info_version_fixed)
578 return ynl_error_parse(yarg, "attribute already present (devlink.info-version-fixed)");
579 if (dst->info_version_running)
580 return ynl_error_parse(yarg, "attribute already present (devlink.info-version-running)");
581 if (dst->info_version_stored)
582 return ynl_error_parse(yarg, "attribute already present (devlink.info-version-stored)");
584 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
585 unsigned int type = mnl_attr_get_type(attr);
587 if (type == DEVLINK_ATTR_BUS_NAME) {
590 if (ynl_attr_validate(yarg, attr))
593 len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
594 dst->_present.bus_name_len = len;
595 dst->bus_name = malloc(len + 1);
596 memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
597 dst->bus_name[len] = 0;
598 } else if (type == DEVLINK_ATTR_DEV_NAME) {
601 if (ynl_attr_validate(yarg, attr))
604 len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
605 dst->_present.dev_name_len = len;
606 dst->dev_name = malloc(len + 1);
607 memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
608 dst->dev_name[len] = 0;
609 } else if (type == DEVLINK_ATTR_INFO_DRIVER_NAME) {
612 if (ynl_attr_validate(yarg, attr))
615 len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
616 dst->_present.info_driver_name_len = len;
617 dst->info_driver_name = malloc(len + 1);
618 memcpy(dst->info_driver_name, mnl_attr_get_str(attr), len);
619 dst->info_driver_name[len] = 0;
620 } else if (type == DEVLINK_ATTR_INFO_SERIAL_NUMBER) {
623 if (ynl_attr_validate(yarg, attr))
626 len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
627 dst->_present.info_serial_number_len = len;
628 dst->info_serial_number = malloc(len + 1);
629 memcpy(dst->info_serial_number, mnl_attr_get_str(attr), len);
630 dst->info_serial_number[len] = 0;
631 } else if (type == DEVLINK_ATTR_INFO_VERSION_FIXED) {
632 n_info_version_fixed++;
633 } else if (type == DEVLINK_ATTR_INFO_VERSION_RUNNING) {
634 n_info_version_running++;
635 } else if (type == DEVLINK_ATTR_INFO_VERSION_STORED) {
636 n_info_version_stored++;
640 if (n_info_version_fixed) {
641 dst->info_version_fixed = calloc(n_info_version_fixed, sizeof(*dst->info_version_fixed));
642 dst->n_info_version_fixed = n_info_version_fixed;
644 parg.rsp_policy = &devlink_dl_info_version_nest;
645 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
646 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) {
647 parg.data = &dst->info_version_fixed[i];
648 if (devlink_dl_info_version_parse(&parg, attr))
654 if (n_info_version_running) {
655 dst->info_version_running = calloc(n_info_version_running, sizeof(*dst->info_version_running));
656 dst->n_info_version_running = n_info_version_running;
658 parg.rsp_policy = &devlink_dl_info_version_nest;
659 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
660 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) {
661 parg.data = &dst->info_version_running[i];
662 if (devlink_dl_info_version_parse(&parg, attr))
668 if (n_info_version_stored) {
669 dst->info_version_stored = calloc(n_info_version_stored, sizeof(*dst->info_version_stored));
670 dst->n_info_version_stored = n_info_version_stored;
672 parg.rsp_policy = &devlink_dl_info_version_nest;
673 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
674 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) {
675 parg.data = &dst->info_version_stored[i];
676 if (devlink_dl_info_version_parse(&parg, attr))
686 struct devlink_info_get_rsp *
687 devlink_info_get(struct ynl_sock *ys, struct devlink_info_get_req *req)
689 struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
690 struct devlink_info_get_rsp *rsp;
691 struct nlmsghdr *nlh;
694 nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1);
695 ys->req_policy = &devlink_nest;
696 yrs.yarg.rsp_policy = &devlink_nest;
698 if (req->_present.bus_name_len)
699 mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
700 if (req->_present.dev_name_len)
701 mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
703 rsp = calloc(1, sizeof(*rsp));
705 yrs.cb = devlink_info_get_rsp_parse;
706 yrs.rsp_cmd = DEVLINK_CMD_INFO_GET;
708 err = ynl_exec(ys, nlh, &yrs);
715 devlink_info_get_rsp_free(rsp);
719 /* DEVLINK_CMD_INFO_GET - dump */
720 void devlink_info_get_list_free(struct devlink_info_get_list *rsp)
722 struct devlink_info_get_list *next = rsp;
724 while ((void *)next != YNL_LIST_END) {
730 free(rsp->obj.bus_name);
731 free(rsp->obj.dev_name);
732 free(rsp->obj.info_driver_name);
733 free(rsp->obj.info_serial_number);
734 for (i = 0; i < rsp->obj.n_info_version_fixed; i++)
735 devlink_dl_info_version_free(&rsp->obj.info_version_fixed[i]);
736 free(rsp->obj.info_version_fixed);
737 for (i = 0; i < rsp->obj.n_info_version_running; i++)
738 devlink_dl_info_version_free(&rsp->obj.info_version_running[i]);
739 free(rsp->obj.info_version_running);
740 for (i = 0; i < rsp->obj.n_info_version_stored; i++)
741 devlink_dl_info_version_free(&rsp->obj.info_version_stored[i]);
742 free(rsp->obj.info_version_stored);
747 struct devlink_info_get_list *devlink_info_get_dump(struct ynl_sock *ys)
749 struct ynl_dump_state yds = {};
750 struct nlmsghdr *nlh;
754 yds.alloc_sz = sizeof(struct devlink_info_get_list);
755 yds.cb = devlink_info_get_rsp_parse;
756 yds.rsp_cmd = DEVLINK_CMD_INFO_GET;
757 yds.rsp_policy = &devlink_nest;
759 nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1);
761 err = ynl_exec_dump(ys, nlh, &yds);
768 devlink_info_get_list_free(yds.first);
772 const struct ynl_family ynl_devlink_family = {