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 */
5
6#include <stdlib.h>
7#include <string.h>
8#include "devlink-user.h"
9#include "ynl.h"
10#include <linux/devlink.h>
11
12#include <libmnl/libmnl.h>
13#include <linux/genetlink.h>
14
15/* Enums */
16static const char * const devlink_op_strmap[] = {
17	[3] = "get",
18	[7] = "port-get",
19	[13] = "sb-get",
20	[17] = "sb-pool-get",
21	[21] = "sb-port-pool-get",
22	[25] = "sb-tc-pool-bind-get",
23	[DEVLINK_CMD_PARAM_GET] = "param-get",
24	[DEVLINK_CMD_REGION_GET] = "region-get",
25	[DEVLINK_CMD_INFO_GET] = "info-get",
26	[DEVLINK_CMD_HEALTH_REPORTER_GET] = "health-reporter-get",
27	[63] = "trap-get",
28	[67] = "trap-group-get",
29	[71] = "trap-policer-get",
30	[76] = "rate-get",
31	[80] = "linecard-get",
32	[DEVLINK_CMD_SELFTESTS_GET] = "selftests-get",
33};
34
35const char *devlink_op_str(int op)
36{
37	if (op < 0 || op >= (int)MNL_ARRAY_SIZE(devlink_op_strmap))
38		return NULL;
39	return devlink_op_strmap[op];
40}
41
42static const char * const devlink_sb_pool_type_strmap[] = {
43	[0] = "ingress",
44	[1] = "egress",
45};
46
47const char *devlink_sb_pool_type_str(enum devlink_sb_pool_type value)
48{
49	if (value < 0 || value >= (int)MNL_ARRAY_SIZE(devlink_sb_pool_type_strmap))
50		return NULL;
51	return devlink_sb_pool_type_strmap[value];
52}
53
54/* Policies */
55struct ynl_policy_attr devlink_dl_info_version_policy[DEVLINK_ATTR_MAX + 1] = {
56	[DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, },
57	[DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, },
58};
59
60struct ynl_policy_nest devlink_dl_info_version_nest = {
61	.max_attr = DEVLINK_ATTR_MAX,
62	.table = devlink_dl_info_version_policy,
63};
64
65struct ynl_policy_attr devlink_dl_reload_stats_entry_policy[DEVLINK_ATTR_MAX + 1] = {
66	[DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, },
67	[DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, },
68};
69
70struct ynl_policy_nest devlink_dl_reload_stats_entry_nest = {
71	.max_attr = DEVLINK_ATTR_MAX,
72	.table = devlink_dl_reload_stats_entry_policy,
73};
74
75struct ynl_policy_attr devlink_dl_reload_act_stats_policy[DEVLINK_ATTR_MAX + 1] = {
76	[DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, },
77};
78
79struct ynl_policy_nest devlink_dl_reload_act_stats_nest = {
80	.max_attr = DEVLINK_ATTR_MAX,
81	.table = devlink_dl_reload_act_stats_policy,
82};
83
84struct ynl_policy_attr devlink_dl_reload_act_info_policy[DEVLINK_ATTR_MAX + 1] = {
85	[DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, },
86	[DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, },
87};
88
89struct ynl_policy_nest devlink_dl_reload_act_info_nest = {
90	.max_attr = DEVLINK_ATTR_MAX,
91	.table = devlink_dl_reload_act_info_policy,
92};
93
94struct ynl_policy_attr devlink_dl_reload_stats_policy[DEVLINK_ATTR_MAX + 1] = {
95	[DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, },
96};
97
98struct ynl_policy_nest devlink_dl_reload_stats_nest = {
99	.max_attr = DEVLINK_ATTR_MAX,
100	.table = devlink_dl_reload_stats_policy,
101};
102
103struct ynl_policy_attr devlink_dl_dev_stats_policy[DEVLINK_ATTR_MAX + 1] = {
104	[DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
105	[DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
106};
107
108struct ynl_policy_nest devlink_dl_dev_stats_nest = {
109	.max_attr = DEVLINK_ATTR_MAX,
110	.table = devlink_dl_dev_stats_policy,
111};
112
113struct ynl_policy_attr devlink_policy[DEVLINK_ATTR_MAX + 1] = {
114	[DEVLINK_ATTR_BUS_NAME] = { .name = "bus-name", .type = YNL_PT_NUL_STR, },
115	[DEVLINK_ATTR_DEV_NAME] = { .name = "dev-name", .type = YNL_PT_NUL_STR, },
116	[DEVLINK_ATTR_PORT_INDEX] = { .name = "port-index", .type = YNL_PT_U32, },
117	[DEVLINK_ATTR_SB_INDEX] = { .name = "sb-index", .type = YNL_PT_U32, },
118	[DEVLINK_ATTR_SB_POOL_INDEX] = { .name = "sb-pool-index", .type = YNL_PT_U16, },
119	[DEVLINK_ATTR_SB_POOL_TYPE] = { .name = "sb-pool-type", .type = YNL_PT_U8, },
120	[DEVLINK_ATTR_SB_TC_INDEX] = { .name = "sb-tc-index", .type = YNL_PT_U16, },
121	[DEVLINK_ATTR_PARAM_NAME] = { .name = "param-name", .type = YNL_PT_NUL_STR, },
122	[DEVLINK_ATTR_REGION_NAME] = { .name = "region-name", .type = YNL_PT_NUL_STR, },
123	[DEVLINK_ATTR_INFO_DRIVER_NAME] = { .name = "info-driver-name", .type = YNL_PT_NUL_STR, },
124	[DEVLINK_ATTR_INFO_SERIAL_NUMBER] = { .name = "info-serial-number", .type = YNL_PT_NUL_STR, },
125	[DEVLINK_ATTR_INFO_VERSION_FIXED] = { .name = "info-version-fixed", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
126	[DEVLINK_ATTR_INFO_VERSION_RUNNING] = { .name = "info-version-running", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
127	[DEVLINK_ATTR_INFO_VERSION_STORED] = { .name = "info-version-stored", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
128	[DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, },
129	[DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, },
130	[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .name = "health-reporter-name", .type = YNL_PT_NUL_STR, },
131	[DEVLINK_ATTR_TRAP_NAME] = { .name = "trap-name", .type = YNL_PT_NUL_STR, },
132	[DEVLINK_ATTR_TRAP_GROUP_NAME] = { .name = "trap-group-name", .type = YNL_PT_NUL_STR, },
133	[DEVLINK_ATTR_RELOAD_FAILED] = { .name = "reload-failed", .type = YNL_PT_U8, },
134	[DEVLINK_ATTR_TRAP_POLICER_ID] = { .name = "trap-policer-id", .type = YNL_PT_U32, },
135	[DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, },
136	[DEVLINK_ATTR_DEV_STATS] = { .name = "dev-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_dev_stats_nest, },
137	[DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
138	[DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, },
139	[DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, },
140	[DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, },
141	[DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
142	[DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, },
143	[DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, },
144	[DEVLINK_ATTR_RATE_NODE_NAME] = { .name = "rate-node-name", .type = YNL_PT_NUL_STR, },
145	[DEVLINK_ATTR_LINECARD_INDEX] = { .name = "linecard-index", .type = YNL_PT_U32, },
146};
147
148struct ynl_policy_nest devlink_nest = {
149	.max_attr = DEVLINK_ATTR_MAX,
150	.table = devlink_policy,
151};
152
153/* Common nested types */
154void devlink_dl_info_version_free(struct devlink_dl_info_version *obj)
155{
156	free(obj->info_version_name);
157	free(obj->info_version_value);
158}
159
160int devlink_dl_info_version_parse(struct ynl_parse_arg *yarg,
161				  const struct nlattr *nested)
162{
163	struct devlink_dl_info_version *dst = yarg->data;
164	const struct nlattr *attr;
165
166	mnl_attr_for_each_nested(attr, nested) {
167		unsigned int type = mnl_attr_get_type(attr);
168
169		if (type == DEVLINK_ATTR_INFO_VERSION_NAME) {
170			unsigned int len;
171
172			if (ynl_attr_validate(yarg, attr))
173				return MNL_CB_ERROR;
174
175			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
176			dst->_present.info_version_name_len = len;
177			dst->info_version_name = malloc(len + 1);
178			memcpy(dst->info_version_name, mnl_attr_get_str(attr), len);
179			dst->info_version_name[len] = 0;
180		} else if (type == DEVLINK_ATTR_INFO_VERSION_VALUE) {
181			unsigned int len;
182
183			if (ynl_attr_validate(yarg, attr))
184				return MNL_CB_ERROR;
185
186			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
187			dst->_present.info_version_value_len = len;
188			dst->info_version_value = malloc(len + 1);
189			memcpy(dst->info_version_value, mnl_attr_get_str(attr), len);
190			dst->info_version_value[len] = 0;
191		}
192	}
193
194	return 0;
195}
196
197void
198devlink_dl_reload_stats_entry_free(struct devlink_dl_reload_stats_entry *obj)
199{
200}
201
202int devlink_dl_reload_stats_entry_parse(struct ynl_parse_arg *yarg,
203					const struct nlattr *nested)
204{
205	struct devlink_dl_reload_stats_entry *dst = yarg->data;
206	const struct nlattr *attr;
207
208	mnl_attr_for_each_nested(attr, nested) {
209		unsigned int type = mnl_attr_get_type(attr);
210
211		if (type == DEVLINK_ATTR_RELOAD_STATS_LIMIT) {
212			if (ynl_attr_validate(yarg, attr))
213				return MNL_CB_ERROR;
214			dst->_present.reload_stats_limit = 1;
215			dst->reload_stats_limit = mnl_attr_get_u8(attr);
216		} else if (type == DEVLINK_ATTR_RELOAD_STATS_VALUE) {
217			if (ynl_attr_validate(yarg, attr))
218				return MNL_CB_ERROR;
219			dst->_present.reload_stats_value = 1;
220			dst->reload_stats_value = mnl_attr_get_u32(attr);
221		}
222	}
223
224	return 0;
225}
226
227void devlink_dl_reload_act_stats_free(struct devlink_dl_reload_act_stats *obj)
228{
229	unsigned int i;
230
231	for (i = 0; i < obj->n_reload_stats_entry; i++)
232		devlink_dl_reload_stats_entry_free(&obj->reload_stats_entry[i]);
233	free(obj->reload_stats_entry);
234}
235
236int devlink_dl_reload_act_stats_parse(struct ynl_parse_arg *yarg,
237				      const struct nlattr *nested)
238{
239	struct devlink_dl_reload_act_stats *dst = yarg->data;
240	unsigned int n_reload_stats_entry = 0;
241	const struct nlattr *attr;
242	struct ynl_parse_arg parg;
243	int i;
244
245	parg.ys = yarg->ys;
246
247	if (dst->reload_stats_entry)
248		return ynl_error_parse(yarg, "attribute already present (dl-reload-act-stats.reload-stats-entry)");
249
250	mnl_attr_for_each_nested(attr, nested) {
251		unsigned int type = mnl_attr_get_type(attr);
252
253		if (type == DEVLINK_ATTR_RELOAD_STATS_ENTRY) {
254			n_reload_stats_entry++;
255		}
256	}
257
258	if (n_reload_stats_entry) {
259		dst->reload_stats_entry = calloc(n_reload_stats_entry, sizeof(*dst->reload_stats_entry));
260		dst->n_reload_stats_entry = n_reload_stats_entry;
261		i = 0;
262		parg.rsp_policy = &devlink_dl_reload_stats_entry_nest;
263		mnl_attr_for_each_nested(attr, nested) {
264			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) {
265				parg.data = &dst->reload_stats_entry[i];
266				if (devlink_dl_reload_stats_entry_parse(&parg, attr))
267					return MNL_CB_ERROR;
268				i++;
269			}
270		}
271	}
272
273	return 0;
274}
275
276void devlink_dl_reload_act_info_free(struct devlink_dl_reload_act_info *obj)
277{
278	unsigned int i;
279
280	for (i = 0; i < obj->n_reload_action_stats; i++)
281		devlink_dl_reload_act_stats_free(&obj->reload_action_stats[i]);
282	free(obj->reload_action_stats);
283}
284
285int devlink_dl_reload_act_info_parse(struct ynl_parse_arg *yarg,
286				     const struct nlattr *nested)
287{
288	struct devlink_dl_reload_act_info *dst = yarg->data;
289	unsigned int n_reload_action_stats = 0;
290	const struct nlattr *attr;
291	struct ynl_parse_arg parg;
292	int i;
293
294	parg.ys = yarg->ys;
295
296	if (dst->reload_action_stats)
297		return ynl_error_parse(yarg, "attribute already present (dl-reload-act-info.reload-action-stats)");
298
299	mnl_attr_for_each_nested(attr, nested) {
300		unsigned int type = mnl_attr_get_type(attr);
301
302		if (type == DEVLINK_ATTR_RELOAD_ACTION) {
303			if (ynl_attr_validate(yarg, attr))
304				return MNL_CB_ERROR;
305			dst->_present.reload_action = 1;
306			dst->reload_action = mnl_attr_get_u8(attr);
307		} else if (type == DEVLINK_ATTR_RELOAD_ACTION_STATS) {
308			n_reload_action_stats++;
309		}
310	}
311
312	if (n_reload_action_stats) {
313		dst->reload_action_stats = calloc(n_reload_action_stats, sizeof(*dst->reload_action_stats));
314		dst->n_reload_action_stats = n_reload_action_stats;
315		i = 0;
316		parg.rsp_policy = &devlink_dl_reload_act_stats_nest;
317		mnl_attr_for_each_nested(attr, nested) {
318			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) {
319				parg.data = &dst->reload_action_stats[i];
320				if (devlink_dl_reload_act_stats_parse(&parg, attr))
321					return MNL_CB_ERROR;
322				i++;
323			}
324		}
325	}
326
327	return 0;
328}
329
330void devlink_dl_reload_stats_free(struct devlink_dl_reload_stats *obj)
331{
332	unsigned int i;
333
334	for (i = 0; i < obj->n_reload_action_info; i++)
335		devlink_dl_reload_act_info_free(&obj->reload_action_info[i]);
336	free(obj->reload_action_info);
337}
338
339int devlink_dl_reload_stats_parse(struct ynl_parse_arg *yarg,
340				  const struct nlattr *nested)
341{
342	struct devlink_dl_reload_stats *dst = yarg->data;
343	unsigned int n_reload_action_info = 0;
344	const struct nlattr *attr;
345	struct ynl_parse_arg parg;
346	int i;
347
348	parg.ys = yarg->ys;
349
350	if (dst->reload_action_info)
351		return ynl_error_parse(yarg, "attribute already present (dl-reload-stats.reload-action-info)");
352
353	mnl_attr_for_each_nested(attr, nested) {
354		unsigned int type = mnl_attr_get_type(attr);
355
356		if (type == DEVLINK_ATTR_RELOAD_ACTION_INFO) {
357			n_reload_action_info++;
358		}
359	}
360
361	if (n_reload_action_info) {
362		dst->reload_action_info = calloc(n_reload_action_info, sizeof(*dst->reload_action_info));
363		dst->n_reload_action_info = n_reload_action_info;
364		i = 0;
365		parg.rsp_policy = &devlink_dl_reload_act_info_nest;
366		mnl_attr_for_each_nested(attr, nested) {
367			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) {
368				parg.data = &dst->reload_action_info[i];
369				if (devlink_dl_reload_act_info_parse(&parg, attr))
370					return MNL_CB_ERROR;
371				i++;
372			}
373		}
374	}
375
376	return 0;
377}
378
379void devlink_dl_dev_stats_free(struct devlink_dl_dev_stats *obj)
380{
381	devlink_dl_reload_stats_free(&obj->reload_stats);
382	devlink_dl_reload_stats_free(&obj->remote_reload_stats);
383}
384
385int devlink_dl_dev_stats_parse(struct ynl_parse_arg *yarg,
386			       const struct nlattr *nested)
387{
388	struct devlink_dl_dev_stats *dst = yarg->data;
389	const struct nlattr *attr;
390	struct ynl_parse_arg parg;
391
392	parg.ys = yarg->ys;
393
394	mnl_attr_for_each_nested(attr, nested) {
395		unsigned int type = mnl_attr_get_type(attr);
396
397		if (type == DEVLINK_ATTR_RELOAD_STATS) {
398			if (ynl_attr_validate(yarg, attr))
399				return MNL_CB_ERROR;
400			dst->_present.reload_stats = 1;
401
402			parg.rsp_policy = &devlink_dl_reload_stats_nest;
403			parg.data = &dst->reload_stats;
404			if (devlink_dl_reload_stats_parse(&parg, attr))
405				return MNL_CB_ERROR;
406		} else if (type == DEVLINK_ATTR_REMOTE_RELOAD_STATS) {
407			if (ynl_attr_validate(yarg, attr))
408				return MNL_CB_ERROR;
409			dst->_present.remote_reload_stats = 1;
410
411			parg.rsp_policy = &devlink_dl_reload_stats_nest;
412			parg.data = &dst->remote_reload_stats;
413			if (devlink_dl_reload_stats_parse(&parg, attr))
414				return MNL_CB_ERROR;
415		}
416	}
417
418	return 0;
419}
420
421/* ============== DEVLINK_CMD_GET ============== */
422/* DEVLINK_CMD_GET - do */
423void devlink_get_req_free(struct devlink_get_req *req)
424{
425	free(req->bus_name);
426	free(req->dev_name);
427	free(req);
428}
429
430void devlink_get_rsp_free(struct devlink_get_rsp *rsp)
431{
432	free(rsp->bus_name);
433	free(rsp->dev_name);
434	devlink_dl_dev_stats_free(&rsp->dev_stats);
435	free(rsp);
436}
437
438int devlink_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
439{
440	struct ynl_parse_arg *yarg = data;
441	struct devlink_get_rsp *dst;
442	const struct nlattr *attr;
443	struct ynl_parse_arg parg;
444
445	dst = yarg->data;
446	parg.ys = yarg->ys;
447
448	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
449		unsigned int type = mnl_attr_get_type(attr);
450
451		if (type == DEVLINK_ATTR_BUS_NAME) {
452			unsigned int len;
453
454			if (ynl_attr_validate(yarg, attr))
455				return MNL_CB_ERROR;
456
457			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
458			dst->_present.bus_name_len = len;
459			dst->bus_name = malloc(len + 1);
460			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
461			dst->bus_name[len] = 0;
462		} else if (type == DEVLINK_ATTR_DEV_NAME) {
463			unsigned int len;
464
465			if (ynl_attr_validate(yarg, attr))
466				return MNL_CB_ERROR;
467
468			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
469			dst->_present.dev_name_len = len;
470			dst->dev_name = malloc(len + 1);
471			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
472			dst->dev_name[len] = 0;
473		} else if (type == DEVLINK_ATTR_RELOAD_FAILED) {
474			if (ynl_attr_validate(yarg, attr))
475				return MNL_CB_ERROR;
476			dst->_present.reload_failed = 1;
477			dst->reload_failed = mnl_attr_get_u8(attr);
478		} else if (type == DEVLINK_ATTR_RELOAD_ACTION) {
479			if (ynl_attr_validate(yarg, attr))
480				return MNL_CB_ERROR;
481			dst->_present.reload_action = 1;
482			dst->reload_action = mnl_attr_get_u8(attr);
483		} else if (type == DEVLINK_ATTR_DEV_STATS) {
484			if (ynl_attr_validate(yarg, attr))
485				return MNL_CB_ERROR;
486			dst->_present.dev_stats = 1;
487
488			parg.rsp_policy = &devlink_dl_dev_stats_nest;
489			parg.data = &dst->dev_stats;
490			if (devlink_dl_dev_stats_parse(&parg, attr))
491				return MNL_CB_ERROR;
492		}
493	}
494
495	return MNL_CB_OK;
496}
497
498struct devlink_get_rsp *
499devlink_get(struct ynl_sock *ys, struct devlink_get_req *req)
500{
501	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
502	struct devlink_get_rsp *rsp;
503	struct nlmsghdr *nlh;
504	int err;
505
506	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_GET, 1);
507	ys->req_policy = &devlink_nest;
508	yrs.yarg.rsp_policy = &devlink_nest;
509
510	if (req->_present.bus_name_len)
511		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
512	if (req->_present.dev_name_len)
513		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
514
515	rsp = calloc(1, sizeof(*rsp));
516	yrs.yarg.data = rsp;
517	yrs.cb = devlink_get_rsp_parse;
518	yrs.rsp_cmd = 3;
519
520	err = ynl_exec(ys, nlh, &yrs);
521	if (err < 0)
522		goto err_free;
523
524	return rsp;
525
526err_free:
527	devlink_get_rsp_free(rsp);
528	return NULL;
529}
530
531/* DEVLINK_CMD_GET - dump */
532void devlink_get_list_free(struct devlink_get_list *rsp)
533{
534	struct devlink_get_list *next = rsp;
535
536	while ((void *)next != YNL_LIST_END) {
537		rsp = next;
538		next = rsp->next;
539
540		free(rsp->obj.bus_name);
541		free(rsp->obj.dev_name);
542		devlink_dl_dev_stats_free(&rsp->obj.dev_stats);
543		free(rsp);
544	}
545}
546
547struct devlink_get_list *devlink_get_dump(struct ynl_sock *ys)
548{
549	struct ynl_dump_state yds = {};
550	struct nlmsghdr *nlh;
551	int err;
552
553	yds.ys = ys;
554	yds.alloc_sz = sizeof(struct devlink_get_list);
555	yds.cb = devlink_get_rsp_parse;
556	yds.rsp_cmd = 3;
557	yds.rsp_policy = &devlink_nest;
558
559	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_GET, 1);
560
561	err = ynl_exec_dump(ys, nlh, &yds);
562	if (err < 0)
563		goto free_list;
564
565	return yds.first;
566
567free_list:
568	devlink_get_list_free(yds.first);
569	return NULL;
570}
571
572/* ============== DEVLINK_CMD_PORT_GET ============== */
573/* DEVLINK_CMD_PORT_GET - do */
574void devlink_port_get_req_free(struct devlink_port_get_req *req)
575{
576	free(req->bus_name);
577	free(req->dev_name);
578	free(req);
579}
580
581void devlink_port_get_rsp_free(struct devlink_port_get_rsp *rsp)
582{
583	free(rsp->bus_name);
584	free(rsp->dev_name);
585	free(rsp);
586}
587
588int devlink_port_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
589{
590	struct ynl_parse_arg *yarg = data;
591	struct devlink_port_get_rsp *dst;
592	const struct nlattr *attr;
593
594	dst = yarg->data;
595
596	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
597		unsigned int type = mnl_attr_get_type(attr);
598
599		if (type == DEVLINK_ATTR_BUS_NAME) {
600			unsigned int len;
601
602			if (ynl_attr_validate(yarg, attr))
603				return MNL_CB_ERROR;
604
605			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
606			dst->_present.bus_name_len = len;
607			dst->bus_name = malloc(len + 1);
608			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
609			dst->bus_name[len] = 0;
610		} else if (type == DEVLINK_ATTR_DEV_NAME) {
611			unsigned int len;
612
613			if (ynl_attr_validate(yarg, attr))
614				return MNL_CB_ERROR;
615
616			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
617			dst->_present.dev_name_len = len;
618			dst->dev_name = malloc(len + 1);
619			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
620			dst->dev_name[len] = 0;
621		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
622			if (ynl_attr_validate(yarg, attr))
623				return MNL_CB_ERROR;
624			dst->_present.port_index = 1;
625			dst->port_index = mnl_attr_get_u32(attr);
626		}
627	}
628
629	return MNL_CB_OK;
630}
631
632struct devlink_port_get_rsp *
633devlink_port_get(struct ynl_sock *ys, struct devlink_port_get_req *req)
634{
635	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
636	struct devlink_port_get_rsp *rsp;
637	struct nlmsghdr *nlh;
638	int err;
639
640	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_GET, 1);
641	ys->req_policy = &devlink_nest;
642	yrs.yarg.rsp_policy = &devlink_nest;
643
644	if (req->_present.bus_name_len)
645		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
646	if (req->_present.dev_name_len)
647		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
648	if (req->_present.port_index)
649		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
650
651	rsp = calloc(1, sizeof(*rsp));
652	yrs.yarg.data = rsp;
653	yrs.cb = devlink_port_get_rsp_parse;
654	yrs.rsp_cmd = 7;
655
656	err = ynl_exec(ys, nlh, &yrs);
657	if (err < 0)
658		goto err_free;
659
660	return rsp;
661
662err_free:
663	devlink_port_get_rsp_free(rsp);
664	return NULL;
665}
666
667/* DEVLINK_CMD_PORT_GET - dump */
668int devlink_port_get_rsp_dump_parse(const struct nlmsghdr *nlh, void *data)
669{
670	struct devlink_port_get_rsp_dump *dst;
671	struct ynl_parse_arg *yarg = data;
672	const struct nlattr *attr;
673
674	dst = yarg->data;
675
676	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
677		unsigned int type = mnl_attr_get_type(attr);
678
679		if (type == DEVLINK_ATTR_BUS_NAME) {
680			unsigned int len;
681
682			if (ynl_attr_validate(yarg, attr))
683				return MNL_CB_ERROR;
684
685			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
686			dst->_present.bus_name_len = len;
687			dst->bus_name = malloc(len + 1);
688			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
689			dst->bus_name[len] = 0;
690		} else if (type == DEVLINK_ATTR_DEV_NAME) {
691			unsigned int len;
692
693			if (ynl_attr_validate(yarg, attr))
694				return MNL_CB_ERROR;
695
696			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
697			dst->_present.dev_name_len = len;
698			dst->dev_name = malloc(len + 1);
699			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
700			dst->dev_name[len] = 0;
701		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
702			if (ynl_attr_validate(yarg, attr))
703				return MNL_CB_ERROR;
704			dst->_present.port_index = 1;
705			dst->port_index = mnl_attr_get_u32(attr);
706		}
707	}
708
709	return MNL_CB_OK;
710}
711
712void devlink_port_get_rsp_list_free(struct devlink_port_get_rsp_list *rsp)
713{
714	struct devlink_port_get_rsp_list *next = rsp;
715
716	while ((void *)next != YNL_LIST_END) {
717		rsp = next;
718		next = rsp->next;
719
720		free(rsp->obj.bus_name);
721		free(rsp->obj.dev_name);
722		free(rsp);
723	}
724}
725
726struct devlink_port_get_rsp_list *
727devlink_port_get_dump(struct ynl_sock *ys,
728		      struct devlink_port_get_req_dump *req)
729{
730	struct ynl_dump_state yds = {};
731	struct nlmsghdr *nlh;
732	int err;
733
734	yds.ys = ys;
735	yds.alloc_sz = sizeof(struct devlink_port_get_rsp_list);
736	yds.cb = devlink_port_get_rsp_dump_parse;
737	yds.rsp_cmd = 7;
738	yds.rsp_policy = &devlink_nest;
739
740	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_PORT_GET, 1);
741	ys->req_policy = &devlink_nest;
742
743	if (req->_present.bus_name_len)
744		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
745	if (req->_present.dev_name_len)
746		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
747
748	err = ynl_exec_dump(ys, nlh, &yds);
749	if (err < 0)
750		goto free_list;
751
752	return yds.first;
753
754free_list:
755	devlink_port_get_rsp_list_free(yds.first);
756	return NULL;
757}
758
759/* ============== DEVLINK_CMD_SB_GET ============== */
760/* DEVLINK_CMD_SB_GET - do */
761void devlink_sb_get_req_free(struct devlink_sb_get_req *req)
762{
763	free(req->bus_name);
764	free(req->dev_name);
765	free(req);
766}
767
768void devlink_sb_get_rsp_free(struct devlink_sb_get_rsp *rsp)
769{
770	free(rsp->bus_name);
771	free(rsp->dev_name);
772	free(rsp);
773}
774
775int devlink_sb_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
776{
777	struct ynl_parse_arg *yarg = data;
778	struct devlink_sb_get_rsp *dst;
779	const struct nlattr *attr;
780
781	dst = yarg->data;
782
783	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
784		unsigned int type = mnl_attr_get_type(attr);
785
786		if (type == DEVLINK_ATTR_BUS_NAME) {
787			unsigned int len;
788
789			if (ynl_attr_validate(yarg, attr))
790				return MNL_CB_ERROR;
791
792			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
793			dst->_present.bus_name_len = len;
794			dst->bus_name = malloc(len + 1);
795			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
796			dst->bus_name[len] = 0;
797		} else if (type == DEVLINK_ATTR_DEV_NAME) {
798			unsigned int len;
799
800			if (ynl_attr_validate(yarg, attr))
801				return MNL_CB_ERROR;
802
803			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
804			dst->_present.dev_name_len = len;
805			dst->dev_name = malloc(len + 1);
806			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
807			dst->dev_name[len] = 0;
808		} else if (type == DEVLINK_ATTR_SB_INDEX) {
809			if (ynl_attr_validate(yarg, attr))
810				return MNL_CB_ERROR;
811			dst->_present.sb_index = 1;
812			dst->sb_index = mnl_attr_get_u32(attr);
813		}
814	}
815
816	return MNL_CB_OK;
817}
818
819struct devlink_sb_get_rsp *
820devlink_sb_get(struct ynl_sock *ys, struct devlink_sb_get_req *req)
821{
822	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
823	struct devlink_sb_get_rsp *rsp;
824	struct nlmsghdr *nlh;
825	int err;
826
827	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_GET, 1);
828	ys->req_policy = &devlink_nest;
829	yrs.yarg.rsp_policy = &devlink_nest;
830
831	if (req->_present.bus_name_len)
832		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
833	if (req->_present.dev_name_len)
834		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
835	if (req->_present.sb_index)
836		mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index);
837
838	rsp = calloc(1, sizeof(*rsp));
839	yrs.yarg.data = rsp;
840	yrs.cb = devlink_sb_get_rsp_parse;
841	yrs.rsp_cmd = 13;
842
843	err = ynl_exec(ys, nlh, &yrs);
844	if (err < 0)
845		goto err_free;
846
847	return rsp;
848
849err_free:
850	devlink_sb_get_rsp_free(rsp);
851	return NULL;
852}
853
854/* DEVLINK_CMD_SB_GET - dump */
855void devlink_sb_get_list_free(struct devlink_sb_get_list *rsp)
856{
857	struct devlink_sb_get_list *next = rsp;
858
859	while ((void *)next != YNL_LIST_END) {
860		rsp = next;
861		next = rsp->next;
862
863		free(rsp->obj.bus_name);
864		free(rsp->obj.dev_name);
865		free(rsp);
866	}
867}
868
869struct devlink_sb_get_list *
870devlink_sb_get_dump(struct ynl_sock *ys, struct devlink_sb_get_req_dump *req)
871{
872	struct ynl_dump_state yds = {};
873	struct nlmsghdr *nlh;
874	int err;
875
876	yds.ys = ys;
877	yds.alloc_sz = sizeof(struct devlink_sb_get_list);
878	yds.cb = devlink_sb_get_rsp_parse;
879	yds.rsp_cmd = 13;
880	yds.rsp_policy = &devlink_nest;
881
882	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_GET, 1);
883	ys->req_policy = &devlink_nest;
884
885	if (req->_present.bus_name_len)
886		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
887	if (req->_present.dev_name_len)
888		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
889
890	err = ynl_exec_dump(ys, nlh, &yds);
891	if (err < 0)
892		goto free_list;
893
894	return yds.first;
895
896free_list:
897	devlink_sb_get_list_free(yds.first);
898	return NULL;
899}
900
901/* ============== DEVLINK_CMD_SB_POOL_GET ============== */
902/* DEVLINK_CMD_SB_POOL_GET - do */
903void devlink_sb_pool_get_req_free(struct devlink_sb_pool_get_req *req)
904{
905	free(req->bus_name);
906	free(req->dev_name);
907	free(req);
908}
909
910void devlink_sb_pool_get_rsp_free(struct devlink_sb_pool_get_rsp *rsp)
911{
912	free(rsp->bus_name);
913	free(rsp->dev_name);
914	free(rsp);
915}
916
917int devlink_sb_pool_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
918{
919	struct devlink_sb_pool_get_rsp *dst;
920	struct ynl_parse_arg *yarg = data;
921	const struct nlattr *attr;
922
923	dst = yarg->data;
924
925	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
926		unsigned int type = mnl_attr_get_type(attr);
927
928		if (type == DEVLINK_ATTR_BUS_NAME) {
929			unsigned int len;
930
931			if (ynl_attr_validate(yarg, attr))
932				return MNL_CB_ERROR;
933
934			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
935			dst->_present.bus_name_len = len;
936			dst->bus_name = malloc(len + 1);
937			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
938			dst->bus_name[len] = 0;
939		} else if (type == DEVLINK_ATTR_DEV_NAME) {
940			unsigned int len;
941
942			if (ynl_attr_validate(yarg, attr))
943				return MNL_CB_ERROR;
944
945			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
946			dst->_present.dev_name_len = len;
947			dst->dev_name = malloc(len + 1);
948			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
949			dst->dev_name[len] = 0;
950		} else if (type == DEVLINK_ATTR_SB_INDEX) {
951			if (ynl_attr_validate(yarg, attr))
952				return MNL_CB_ERROR;
953			dst->_present.sb_index = 1;
954			dst->sb_index = mnl_attr_get_u32(attr);
955		} else if (type == DEVLINK_ATTR_SB_POOL_INDEX) {
956			if (ynl_attr_validate(yarg, attr))
957				return MNL_CB_ERROR;
958			dst->_present.sb_pool_index = 1;
959			dst->sb_pool_index = mnl_attr_get_u16(attr);
960		}
961	}
962
963	return MNL_CB_OK;
964}
965
966struct devlink_sb_pool_get_rsp *
967devlink_sb_pool_get(struct ynl_sock *ys, struct devlink_sb_pool_get_req *req)
968{
969	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
970	struct devlink_sb_pool_get_rsp *rsp;
971	struct nlmsghdr *nlh;
972	int err;
973
974	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_POOL_GET, 1);
975	ys->req_policy = &devlink_nest;
976	yrs.yarg.rsp_policy = &devlink_nest;
977
978	if (req->_present.bus_name_len)
979		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
980	if (req->_present.dev_name_len)
981		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
982	if (req->_present.sb_index)
983		mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index);
984	if (req->_present.sb_pool_index)
985		mnl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX, req->sb_pool_index);
986
987	rsp = calloc(1, sizeof(*rsp));
988	yrs.yarg.data = rsp;
989	yrs.cb = devlink_sb_pool_get_rsp_parse;
990	yrs.rsp_cmd = 17;
991
992	err = ynl_exec(ys, nlh, &yrs);
993	if (err < 0)
994		goto err_free;
995
996	return rsp;
997
998err_free:
999	devlink_sb_pool_get_rsp_free(rsp);
1000	return NULL;
1001}
1002
1003/* DEVLINK_CMD_SB_POOL_GET - dump */
1004void devlink_sb_pool_get_list_free(struct devlink_sb_pool_get_list *rsp)
1005{
1006	struct devlink_sb_pool_get_list *next = rsp;
1007
1008	while ((void *)next != YNL_LIST_END) {
1009		rsp = next;
1010		next = rsp->next;
1011
1012		free(rsp->obj.bus_name);
1013		free(rsp->obj.dev_name);
1014		free(rsp);
1015	}
1016}
1017
1018struct devlink_sb_pool_get_list *
1019devlink_sb_pool_get_dump(struct ynl_sock *ys,
1020			 struct devlink_sb_pool_get_req_dump *req)
1021{
1022	struct ynl_dump_state yds = {};
1023	struct nlmsghdr *nlh;
1024	int err;
1025
1026	yds.ys = ys;
1027	yds.alloc_sz = sizeof(struct devlink_sb_pool_get_list);
1028	yds.cb = devlink_sb_pool_get_rsp_parse;
1029	yds.rsp_cmd = 17;
1030	yds.rsp_policy = &devlink_nest;
1031
1032	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_POOL_GET, 1);
1033	ys->req_policy = &devlink_nest;
1034
1035	if (req->_present.bus_name_len)
1036		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1037	if (req->_present.dev_name_len)
1038		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1039
1040	err = ynl_exec_dump(ys, nlh, &yds);
1041	if (err < 0)
1042		goto free_list;
1043
1044	return yds.first;
1045
1046free_list:
1047	devlink_sb_pool_get_list_free(yds.first);
1048	return NULL;
1049}
1050
1051/* ============== DEVLINK_CMD_SB_PORT_POOL_GET ============== */
1052/* DEVLINK_CMD_SB_PORT_POOL_GET - do */
1053void
1054devlink_sb_port_pool_get_req_free(struct devlink_sb_port_pool_get_req *req)
1055{
1056	free(req->bus_name);
1057	free(req->dev_name);
1058	free(req);
1059}
1060
1061void
1062devlink_sb_port_pool_get_rsp_free(struct devlink_sb_port_pool_get_rsp *rsp)
1063{
1064	free(rsp->bus_name);
1065	free(rsp->dev_name);
1066	free(rsp);
1067}
1068
1069int devlink_sb_port_pool_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1070{
1071	struct devlink_sb_port_pool_get_rsp *dst;
1072	struct ynl_parse_arg *yarg = data;
1073	const struct nlattr *attr;
1074
1075	dst = yarg->data;
1076
1077	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1078		unsigned int type = mnl_attr_get_type(attr);
1079
1080		if (type == DEVLINK_ATTR_BUS_NAME) {
1081			unsigned int len;
1082
1083			if (ynl_attr_validate(yarg, attr))
1084				return MNL_CB_ERROR;
1085
1086			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1087			dst->_present.bus_name_len = len;
1088			dst->bus_name = malloc(len + 1);
1089			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1090			dst->bus_name[len] = 0;
1091		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1092			unsigned int len;
1093
1094			if (ynl_attr_validate(yarg, attr))
1095				return MNL_CB_ERROR;
1096
1097			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1098			dst->_present.dev_name_len = len;
1099			dst->dev_name = malloc(len + 1);
1100			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1101			dst->dev_name[len] = 0;
1102		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
1103			if (ynl_attr_validate(yarg, attr))
1104				return MNL_CB_ERROR;
1105			dst->_present.port_index = 1;
1106			dst->port_index = mnl_attr_get_u32(attr);
1107		} else if (type == DEVLINK_ATTR_SB_INDEX) {
1108			if (ynl_attr_validate(yarg, attr))
1109				return MNL_CB_ERROR;
1110			dst->_present.sb_index = 1;
1111			dst->sb_index = mnl_attr_get_u32(attr);
1112		} else if (type == DEVLINK_ATTR_SB_POOL_INDEX) {
1113			if (ynl_attr_validate(yarg, attr))
1114				return MNL_CB_ERROR;
1115			dst->_present.sb_pool_index = 1;
1116			dst->sb_pool_index = mnl_attr_get_u16(attr);
1117		}
1118	}
1119
1120	return MNL_CB_OK;
1121}
1122
1123struct devlink_sb_port_pool_get_rsp *
1124devlink_sb_port_pool_get(struct ynl_sock *ys,
1125			 struct devlink_sb_port_pool_get_req *req)
1126{
1127	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1128	struct devlink_sb_port_pool_get_rsp *rsp;
1129	struct nlmsghdr *nlh;
1130	int err;
1131
1132	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_PORT_POOL_GET, 1);
1133	ys->req_policy = &devlink_nest;
1134	yrs.yarg.rsp_policy = &devlink_nest;
1135
1136	if (req->_present.bus_name_len)
1137		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1138	if (req->_present.dev_name_len)
1139		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1140	if (req->_present.port_index)
1141		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
1142	if (req->_present.sb_index)
1143		mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index);
1144	if (req->_present.sb_pool_index)
1145		mnl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX, req->sb_pool_index);
1146
1147	rsp = calloc(1, sizeof(*rsp));
1148	yrs.yarg.data = rsp;
1149	yrs.cb = devlink_sb_port_pool_get_rsp_parse;
1150	yrs.rsp_cmd = 21;
1151
1152	err = ynl_exec(ys, nlh, &yrs);
1153	if (err < 0)
1154		goto err_free;
1155
1156	return rsp;
1157
1158err_free:
1159	devlink_sb_port_pool_get_rsp_free(rsp);
1160	return NULL;
1161}
1162
1163/* DEVLINK_CMD_SB_PORT_POOL_GET - dump */
1164void
1165devlink_sb_port_pool_get_list_free(struct devlink_sb_port_pool_get_list *rsp)
1166{
1167	struct devlink_sb_port_pool_get_list *next = rsp;
1168
1169	while ((void *)next != YNL_LIST_END) {
1170		rsp = next;
1171		next = rsp->next;
1172
1173		free(rsp->obj.bus_name);
1174		free(rsp->obj.dev_name);
1175		free(rsp);
1176	}
1177}
1178
1179struct devlink_sb_port_pool_get_list *
1180devlink_sb_port_pool_get_dump(struct ynl_sock *ys,
1181			      struct devlink_sb_port_pool_get_req_dump *req)
1182{
1183	struct ynl_dump_state yds = {};
1184	struct nlmsghdr *nlh;
1185	int err;
1186
1187	yds.ys = ys;
1188	yds.alloc_sz = sizeof(struct devlink_sb_port_pool_get_list);
1189	yds.cb = devlink_sb_port_pool_get_rsp_parse;
1190	yds.rsp_cmd = 21;
1191	yds.rsp_policy = &devlink_nest;
1192
1193	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_PORT_POOL_GET, 1);
1194	ys->req_policy = &devlink_nest;
1195
1196	if (req->_present.bus_name_len)
1197		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1198	if (req->_present.dev_name_len)
1199		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1200
1201	err = ynl_exec_dump(ys, nlh, &yds);
1202	if (err < 0)
1203		goto free_list;
1204
1205	return yds.first;
1206
1207free_list:
1208	devlink_sb_port_pool_get_list_free(yds.first);
1209	return NULL;
1210}
1211
1212/* ============== DEVLINK_CMD_SB_TC_POOL_BIND_GET ============== */
1213/* DEVLINK_CMD_SB_TC_POOL_BIND_GET - do */
1214void
1215devlink_sb_tc_pool_bind_get_req_free(struct devlink_sb_tc_pool_bind_get_req *req)
1216{
1217	free(req->bus_name);
1218	free(req->dev_name);
1219	free(req);
1220}
1221
1222void
1223devlink_sb_tc_pool_bind_get_rsp_free(struct devlink_sb_tc_pool_bind_get_rsp *rsp)
1224{
1225	free(rsp->bus_name);
1226	free(rsp->dev_name);
1227	free(rsp);
1228}
1229
1230int devlink_sb_tc_pool_bind_get_rsp_parse(const struct nlmsghdr *nlh,
1231					  void *data)
1232{
1233	struct devlink_sb_tc_pool_bind_get_rsp *dst;
1234	struct ynl_parse_arg *yarg = data;
1235	const struct nlattr *attr;
1236
1237	dst = yarg->data;
1238
1239	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1240		unsigned int type = mnl_attr_get_type(attr);
1241
1242		if (type == DEVLINK_ATTR_BUS_NAME) {
1243			unsigned int len;
1244
1245			if (ynl_attr_validate(yarg, attr))
1246				return MNL_CB_ERROR;
1247
1248			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1249			dst->_present.bus_name_len = len;
1250			dst->bus_name = malloc(len + 1);
1251			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1252			dst->bus_name[len] = 0;
1253		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1254			unsigned int len;
1255
1256			if (ynl_attr_validate(yarg, attr))
1257				return MNL_CB_ERROR;
1258
1259			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1260			dst->_present.dev_name_len = len;
1261			dst->dev_name = malloc(len + 1);
1262			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1263			dst->dev_name[len] = 0;
1264		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
1265			if (ynl_attr_validate(yarg, attr))
1266				return MNL_CB_ERROR;
1267			dst->_present.port_index = 1;
1268			dst->port_index = mnl_attr_get_u32(attr);
1269		} else if (type == DEVLINK_ATTR_SB_INDEX) {
1270			if (ynl_attr_validate(yarg, attr))
1271				return MNL_CB_ERROR;
1272			dst->_present.sb_index = 1;
1273			dst->sb_index = mnl_attr_get_u32(attr);
1274		} else if (type == DEVLINK_ATTR_SB_POOL_TYPE) {
1275			if (ynl_attr_validate(yarg, attr))
1276				return MNL_CB_ERROR;
1277			dst->_present.sb_pool_type = 1;
1278			dst->sb_pool_type = mnl_attr_get_u8(attr);
1279		} else if (type == DEVLINK_ATTR_SB_TC_INDEX) {
1280			if (ynl_attr_validate(yarg, attr))
1281				return MNL_CB_ERROR;
1282			dst->_present.sb_tc_index = 1;
1283			dst->sb_tc_index = mnl_attr_get_u16(attr);
1284		}
1285	}
1286
1287	return MNL_CB_OK;
1288}
1289
1290struct devlink_sb_tc_pool_bind_get_rsp *
1291devlink_sb_tc_pool_bind_get(struct ynl_sock *ys,
1292			    struct devlink_sb_tc_pool_bind_get_req *req)
1293{
1294	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1295	struct devlink_sb_tc_pool_bind_get_rsp *rsp;
1296	struct nlmsghdr *nlh;
1297	int err;
1298
1299	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_TC_POOL_BIND_GET, 1);
1300	ys->req_policy = &devlink_nest;
1301	yrs.yarg.rsp_policy = &devlink_nest;
1302
1303	if (req->_present.bus_name_len)
1304		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1305	if (req->_present.dev_name_len)
1306		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1307	if (req->_present.port_index)
1308		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
1309	if (req->_present.sb_index)
1310		mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index);
1311	if (req->_present.sb_pool_type)
1312		mnl_attr_put_u8(nlh, DEVLINK_ATTR_SB_POOL_TYPE, req->sb_pool_type);
1313	if (req->_present.sb_tc_index)
1314		mnl_attr_put_u16(nlh, DEVLINK_ATTR_SB_TC_INDEX, req->sb_tc_index);
1315
1316	rsp = calloc(1, sizeof(*rsp));
1317	yrs.yarg.data = rsp;
1318	yrs.cb = devlink_sb_tc_pool_bind_get_rsp_parse;
1319	yrs.rsp_cmd = 25;
1320
1321	err = ynl_exec(ys, nlh, &yrs);
1322	if (err < 0)
1323		goto err_free;
1324
1325	return rsp;
1326
1327err_free:
1328	devlink_sb_tc_pool_bind_get_rsp_free(rsp);
1329	return NULL;
1330}
1331
1332/* DEVLINK_CMD_SB_TC_POOL_BIND_GET - dump */
1333void
1334devlink_sb_tc_pool_bind_get_list_free(struct devlink_sb_tc_pool_bind_get_list *rsp)
1335{
1336	struct devlink_sb_tc_pool_bind_get_list *next = rsp;
1337
1338	while ((void *)next != YNL_LIST_END) {
1339		rsp = next;
1340		next = rsp->next;
1341
1342		free(rsp->obj.bus_name);
1343		free(rsp->obj.dev_name);
1344		free(rsp);
1345	}
1346}
1347
1348struct devlink_sb_tc_pool_bind_get_list *
1349devlink_sb_tc_pool_bind_get_dump(struct ynl_sock *ys,
1350				 struct devlink_sb_tc_pool_bind_get_req_dump *req)
1351{
1352	struct ynl_dump_state yds = {};
1353	struct nlmsghdr *nlh;
1354	int err;
1355
1356	yds.ys = ys;
1357	yds.alloc_sz = sizeof(struct devlink_sb_tc_pool_bind_get_list);
1358	yds.cb = devlink_sb_tc_pool_bind_get_rsp_parse;
1359	yds.rsp_cmd = 25;
1360	yds.rsp_policy = &devlink_nest;
1361
1362	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_TC_POOL_BIND_GET, 1);
1363	ys->req_policy = &devlink_nest;
1364
1365	if (req->_present.bus_name_len)
1366		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1367	if (req->_present.dev_name_len)
1368		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1369
1370	err = ynl_exec_dump(ys, nlh, &yds);
1371	if (err < 0)
1372		goto free_list;
1373
1374	return yds.first;
1375
1376free_list:
1377	devlink_sb_tc_pool_bind_get_list_free(yds.first);
1378	return NULL;
1379}
1380
1381/* ============== DEVLINK_CMD_PARAM_GET ============== */
1382/* DEVLINK_CMD_PARAM_GET - do */
1383void devlink_param_get_req_free(struct devlink_param_get_req *req)
1384{
1385	free(req->bus_name);
1386	free(req->dev_name);
1387	free(req->param_name);
1388	free(req);
1389}
1390
1391void devlink_param_get_rsp_free(struct devlink_param_get_rsp *rsp)
1392{
1393	free(rsp->bus_name);
1394	free(rsp->dev_name);
1395	free(rsp->param_name);
1396	free(rsp);
1397}
1398
1399int devlink_param_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1400{
1401	struct devlink_param_get_rsp *dst;
1402	struct ynl_parse_arg *yarg = data;
1403	const struct nlattr *attr;
1404
1405	dst = yarg->data;
1406
1407	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1408		unsigned int type = mnl_attr_get_type(attr);
1409
1410		if (type == DEVLINK_ATTR_BUS_NAME) {
1411			unsigned int len;
1412
1413			if (ynl_attr_validate(yarg, attr))
1414				return MNL_CB_ERROR;
1415
1416			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1417			dst->_present.bus_name_len = len;
1418			dst->bus_name = malloc(len + 1);
1419			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1420			dst->bus_name[len] = 0;
1421		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1422			unsigned int len;
1423
1424			if (ynl_attr_validate(yarg, attr))
1425				return MNL_CB_ERROR;
1426
1427			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1428			dst->_present.dev_name_len = len;
1429			dst->dev_name = malloc(len + 1);
1430			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1431			dst->dev_name[len] = 0;
1432		} else if (type == DEVLINK_ATTR_PARAM_NAME) {
1433			unsigned int len;
1434
1435			if (ynl_attr_validate(yarg, attr))
1436				return MNL_CB_ERROR;
1437
1438			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1439			dst->_present.param_name_len = len;
1440			dst->param_name = malloc(len + 1);
1441			memcpy(dst->param_name, mnl_attr_get_str(attr), len);
1442			dst->param_name[len] = 0;
1443		}
1444	}
1445
1446	return MNL_CB_OK;
1447}
1448
1449struct devlink_param_get_rsp *
1450devlink_param_get(struct ynl_sock *ys, struct devlink_param_get_req *req)
1451{
1452	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1453	struct devlink_param_get_rsp *rsp;
1454	struct nlmsghdr *nlh;
1455	int err;
1456
1457	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PARAM_GET, 1);
1458	ys->req_policy = &devlink_nest;
1459	yrs.yarg.rsp_policy = &devlink_nest;
1460
1461	if (req->_present.bus_name_len)
1462		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1463	if (req->_present.dev_name_len)
1464		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1465	if (req->_present.param_name_len)
1466		mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_NAME, req->param_name);
1467
1468	rsp = calloc(1, sizeof(*rsp));
1469	yrs.yarg.data = rsp;
1470	yrs.cb = devlink_param_get_rsp_parse;
1471	yrs.rsp_cmd = DEVLINK_CMD_PARAM_GET;
1472
1473	err = ynl_exec(ys, nlh, &yrs);
1474	if (err < 0)
1475		goto err_free;
1476
1477	return rsp;
1478
1479err_free:
1480	devlink_param_get_rsp_free(rsp);
1481	return NULL;
1482}
1483
1484/* DEVLINK_CMD_PARAM_GET - dump */
1485void devlink_param_get_list_free(struct devlink_param_get_list *rsp)
1486{
1487	struct devlink_param_get_list *next = rsp;
1488
1489	while ((void *)next != YNL_LIST_END) {
1490		rsp = next;
1491		next = rsp->next;
1492
1493		free(rsp->obj.bus_name);
1494		free(rsp->obj.dev_name);
1495		free(rsp->obj.param_name);
1496		free(rsp);
1497	}
1498}
1499
1500struct devlink_param_get_list *
1501devlink_param_get_dump(struct ynl_sock *ys,
1502		       struct devlink_param_get_req_dump *req)
1503{
1504	struct ynl_dump_state yds = {};
1505	struct nlmsghdr *nlh;
1506	int err;
1507
1508	yds.ys = ys;
1509	yds.alloc_sz = sizeof(struct devlink_param_get_list);
1510	yds.cb = devlink_param_get_rsp_parse;
1511	yds.rsp_cmd = DEVLINK_CMD_PARAM_GET;
1512	yds.rsp_policy = &devlink_nest;
1513
1514	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_PARAM_GET, 1);
1515	ys->req_policy = &devlink_nest;
1516
1517	if (req->_present.bus_name_len)
1518		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1519	if (req->_present.dev_name_len)
1520		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1521
1522	err = ynl_exec_dump(ys, nlh, &yds);
1523	if (err < 0)
1524		goto free_list;
1525
1526	return yds.first;
1527
1528free_list:
1529	devlink_param_get_list_free(yds.first);
1530	return NULL;
1531}
1532
1533/* ============== DEVLINK_CMD_REGION_GET ============== */
1534/* DEVLINK_CMD_REGION_GET - do */
1535void devlink_region_get_req_free(struct devlink_region_get_req *req)
1536{
1537	free(req->bus_name);
1538	free(req->dev_name);
1539	free(req->region_name);
1540	free(req);
1541}
1542
1543void devlink_region_get_rsp_free(struct devlink_region_get_rsp *rsp)
1544{
1545	free(rsp->bus_name);
1546	free(rsp->dev_name);
1547	free(rsp->region_name);
1548	free(rsp);
1549}
1550
1551int devlink_region_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1552{
1553	struct devlink_region_get_rsp *dst;
1554	struct ynl_parse_arg *yarg = data;
1555	const struct nlattr *attr;
1556
1557	dst = yarg->data;
1558
1559	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1560		unsigned int type = mnl_attr_get_type(attr);
1561
1562		if (type == DEVLINK_ATTR_BUS_NAME) {
1563			unsigned int len;
1564
1565			if (ynl_attr_validate(yarg, attr))
1566				return MNL_CB_ERROR;
1567
1568			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1569			dst->_present.bus_name_len = len;
1570			dst->bus_name = malloc(len + 1);
1571			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1572			dst->bus_name[len] = 0;
1573		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1574			unsigned int len;
1575
1576			if (ynl_attr_validate(yarg, attr))
1577				return MNL_CB_ERROR;
1578
1579			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1580			dst->_present.dev_name_len = len;
1581			dst->dev_name = malloc(len + 1);
1582			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1583			dst->dev_name[len] = 0;
1584		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
1585			if (ynl_attr_validate(yarg, attr))
1586				return MNL_CB_ERROR;
1587			dst->_present.port_index = 1;
1588			dst->port_index = mnl_attr_get_u32(attr);
1589		} else if (type == DEVLINK_ATTR_REGION_NAME) {
1590			unsigned int len;
1591
1592			if (ynl_attr_validate(yarg, attr))
1593				return MNL_CB_ERROR;
1594
1595			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1596			dst->_present.region_name_len = len;
1597			dst->region_name = malloc(len + 1);
1598			memcpy(dst->region_name, mnl_attr_get_str(attr), len);
1599			dst->region_name[len] = 0;
1600		}
1601	}
1602
1603	return MNL_CB_OK;
1604}
1605
1606struct devlink_region_get_rsp *
1607devlink_region_get(struct ynl_sock *ys, struct devlink_region_get_req *req)
1608{
1609	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1610	struct devlink_region_get_rsp *rsp;
1611	struct nlmsghdr *nlh;
1612	int err;
1613
1614	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_REGION_GET, 1);
1615	ys->req_policy = &devlink_nest;
1616	yrs.yarg.rsp_policy = &devlink_nest;
1617
1618	if (req->_present.bus_name_len)
1619		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1620	if (req->_present.dev_name_len)
1621		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1622	if (req->_present.port_index)
1623		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
1624	if (req->_present.region_name_len)
1625		mnl_attr_put_strz(nlh, DEVLINK_ATTR_REGION_NAME, req->region_name);
1626
1627	rsp = calloc(1, sizeof(*rsp));
1628	yrs.yarg.data = rsp;
1629	yrs.cb = devlink_region_get_rsp_parse;
1630	yrs.rsp_cmd = DEVLINK_CMD_REGION_GET;
1631
1632	err = ynl_exec(ys, nlh, &yrs);
1633	if (err < 0)
1634		goto err_free;
1635
1636	return rsp;
1637
1638err_free:
1639	devlink_region_get_rsp_free(rsp);
1640	return NULL;
1641}
1642
1643/* DEVLINK_CMD_REGION_GET - dump */
1644void devlink_region_get_list_free(struct devlink_region_get_list *rsp)
1645{
1646	struct devlink_region_get_list *next = rsp;
1647
1648	while ((void *)next != YNL_LIST_END) {
1649		rsp = next;
1650		next = rsp->next;
1651
1652		free(rsp->obj.bus_name);
1653		free(rsp->obj.dev_name);
1654		free(rsp->obj.region_name);
1655		free(rsp);
1656	}
1657}
1658
1659struct devlink_region_get_list *
1660devlink_region_get_dump(struct ynl_sock *ys,
1661			struct devlink_region_get_req_dump *req)
1662{
1663	struct ynl_dump_state yds = {};
1664	struct nlmsghdr *nlh;
1665	int err;
1666
1667	yds.ys = ys;
1668	yds.alloc_sz = sizeof(struct devlink_region_get_list);
1669	yds.cb = devlink_region_get_rsp_parse;
1670	yds.rsp_cmd = DEVLINK_CMD_REGION_GET;
1671	yds.rsp_policy = &devlink_nest;
1672
1673	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_REGION_GET, 1);
1674	ys->req_policy = &devlink_nest;
1675
1676	if (req->_present.bus_name_len)
1677		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1678	if (req->_present.dev_name_len)
1679		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1680
1681	err = ynl_exec_dump(ys, nlh, &yds);
1682	if (err < 0)
1683		goto free_list;
1684
1685	return yds.first;
1686
1687free_list:
1688	devlink_region_get_list_free(yds.first);
1689	return NULL;
1690}
1691
1692/* ============== DEVLINK_CMD_INFO_GET ============== */
1693/* DEVLINK_CMD_INFO_GET - do */
1694void devlink_info_get_req_free(struct devlink_info_get_req *req)
1695{
1696	free(req->bus_name);
1697	free(req->dev_name);
1698	free(req);
1699}
1700
1701void devlink_info_get_rsp_free(struct devlink_info_get_rsp *rsp)
1702{
1703	unsigned int i;
1704
1705	free(rsp->bus_name);
1706	free(rsp->dev_name);
1707	free(rsp->info_driver_name);
1708	free(rsp->info_serial_number);
1709	for (i = 0; i < rsp->n_info_version_fixed; i++)
1710		devlink_dl_info_version_free(&rsp->info_version_fixed[i]);
1711	free(rsp->info_version_fixed);
1712	for (i = 0; i < rsp->n_info_version_running; i++)
1713		devlink_dl_info_version_free(&rsp->info_version_running[i]);
1714	free(rsp->info_version_running);
1715	for (i = 0; i < rsp->n_info_version_stored; i++)
1716		devlink_dl_info_version_free(&rsp->info_version_stored[i]);
1717	free(rsp->info_version_stored);
1718	free(rsp);
1719}
1720
1721int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1722{
1723	unsigned int n_info_version_running = 0;
1724	unsigned int n_info_version_stored = 0;
1725	unsigned int n_info_version_fixed = 0;
1726	struct ynl_parse_arg *yarg = data;
1727	struct devlink_info_get_rsp *dst;
1728	const struct nlattr *attr;
1729	struct ynl_parse_arg parg;
1730	int i;
1731
1732	dst = yarg->data;
1733	parg.ys = yarg->ys;
1734
1735	if (dst->info_version_fixed)
1736		return ynl_error_parse(yarg, "attribute already present (devlink.info-version-fixed)");
1737	if (dst->info_version_running)
1738		return ynl_error_parse(yarg, "attribute already present (devlink.info-version-running)");
1739	if (dst->info_version_stored)
1740		return ynl_error_parse(yarg, "attribute already present (devlink.info-version-stored)");
1741
1742	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1743		unsigned int type = mnl_attr_get_type(attr);
1744
1745		if (type == DEVLINK_ATTR_BUS_NAME) {
1746			unsigned int len;
1747
1748			if (ynl_attr_validate(yarg, attr))
1749				return MNL_CB_ERROR;
1750
1751			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1752			dst->_present.bus_name_len = len;
1753			dst->bus_name = malloc(len + 1);
1754			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1755			dst->bus_name[len] = 0;
1756		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1757			unsigned int len;
1758
1759			if (ynl_attr_validate(yarg, attr))
1760				return MNL_CB_ERROR;
1761
1762			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1763			dst->_present.dev_name_len = len;
1764			dst->dev_name = malloc(len + 1);
1765			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1766			dst->dev_name[len] = 0;
1767		} else if (type == DEVLINK_ATTR_INFO_DRIVER_NAME) {
1768			unsigned int len;
1769
1770			if (ynl_attr_validate(yarg, attr))
1771				return MNL_CB_ERROR;
1772
1773			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1774			dst->_present.info_driver_name_len = len;
1775			dst->info_driver_name = malloc(len + 1);
1776			memcpy(dst->info_driver_name, mnl_attr_get_str(attr), len);
1777			dst->info_driver_name[len] = 0;
1778		} else if (type == DEVLINK_ATTR_INFO_SERIAL_NUMBER) {
1779			unsigned int len;
1780
1781			if (ynl_attr_validate(yarg, attr))
1782				return MNL_CB_ERROR;
1783
1784			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1785			dst->_present.info_serial_number_len = len;
1786			dst->info_serial_number = malloc(len + 1);
1787			memcpy(dst->info_serial_number, mnl_attr_get_str(attr), len);
1788			dst->info_serial_number[len] = 0;
1789		} else if (type == DEVLINK_ATTR_INFO_VERSION_FIXED) {
1790			n_info_version_fixed++;
1791		} else if (type == DEVLINK_ATTR_INFO_VERSION_RUNNING) {
1792			n_info_version_running++;
1793		} else if (type == DEVLINK_ATTR_INFO_VERSION_STORED) {
1794			n_info_version_stored++;
1795		}
1796	}
1797
1798	if (n_info_version_fixed) {
1799		dst->info_version_fixed = calloc(n_info_version_fixed, sizeof(*dst->info_version_fixed));
1800		dst->n_info_version_fixed = n_info_version_fixed;
1801		i = 0;
1802		parg.rsp_policy = &devlink_dl_info_version_nest;
1803		mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1804			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) {
1805				parg.data = &dst->info_version_fixed[i];
1806				if (devlink_dl_info_version_parse(&parg, attr))
1807					return MNL_CB_ERROR;
1808				i++;
1809			}
1810		}
1811	}
1812	if (n_info_version_running) {
1813		dst->info_version_running = calloc(n_info_version_running, sizeof(*dst->info_version_running));
1814		dst->n_info_version_running = n_info_version_running;
1815		i = 0;
1816		parg.rsp_policy = &devlink_dl_info_version_nest;
1817		mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1818			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) {
1819				parg.data = &dst->info_version_running[i];
1820				if (devlink_dl_info_version_parse(&parg, attr))
1821					return MNL_CB_ERROR;
1822				i++;
1823			}
1824		}
1825	}
1826	if (n_info_version_stored) {
1827		dst->info_version_stored = calloc(n_info_version_stored, sizeof(*dst->info_version_stored));
1828		dst->n_info_version_stored = n_info_version_stored;
1829		i = 0;
1830		parg.rsp_policy = &devlink_dl_info_version_nest;
1831		mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1832			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) {
1833				parg.data = &dst->info_version_stored[i];
1834				if (devlink_dl_info_version_parse(&parg, attr))
1835					return MNL_CB_ERROR;
1836				i++;
1837			}
1838		}
1839	}
1840
1841	return MNL_CB_OK;
1842}
1843
1844struct devlink_info_get_rsp *
1845devlink_info_get(struct ynl_sock *ys, struct devlink_info_get_req *req)
1846{
1847	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1848	struct devlink_info_get_rsp *rsp;
1849	struct nlmsghdr *nlh;
1850	int err;
1851
1852	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1);
1853	ys->req_policy = &devlink_nest;
1854	yrs.yarg.rsp_policy = &devlink_nest;
1855
1856	if (req->_present.bus_name_len)
1857		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1858	if (req->_present.dev_name_len)
1859		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1860
1861	rsp = calloc(1, sizeof(*rsp));
1862	yrs.yarg.data = rsp;
1863	yrs.cb = devlink_info_get_rsp_parse;
1864	yrs.rsp_cmd = DEVLINK_CMD_INFO_GET;
1865
1866	err = ynl_exec(ys, nlh, &yrs);
1867	if (err < 0)
1868		goto err_free;
1869
1870	return rsp;
1871
1872err_free:
1873	devlink_info_get_rsp_free(rsp);
1874	return NULL;
1875}
1876
1877/* DEVLINK_CMD_INFO_GET - dump */
1878void devlink_info_get_list_free(struct devlink_info_get_list *rsp)
1879{
1880	struct devlink_info_get_list *next = rsp;
1881
1882	while ((void *)next != YNL_LIST_END) {
1883		unsigned int i;
1884
1885		rsp = next;
1886		next = rsp->next;
1887
1888		free(rsp->obj.bus_name);
1889		free(rsp->obj.dev_name);
1890		free(rsp->obj.info_driver_name);
1891		free(rsp->obj.info_serial_number);
1892		for (i = 0; i < rsp->obj.n_info_version_fixed; i++)
1893			devlink_dl_info_version_free(&rsp->obj.info_version_fixed[i]);
1894		free(rsp->obj.info_version_fixed);
1895		for (i = 0; i < rsp->obj.n_info_version_running; i++)
1896			devlink_dl_info_version_free(&rsp->obj.info_version_running[i]);
1897		free(rsp->obj.info_version_running);
1898		for (i = 0; i < rsp->obj.n_info_version_stored; i++)
1899			devlink_dl_info_version_free(&rsp->obj.info_version_stored[i]);
1900		free(rsp->obj.info_version_stored);
1901		free(rsp);
1902	}
1903}
1904
1905struct devlink_info_get_list *devlink_info_get_dump(struct ynl_sock *ys)
1906{
1907	struct ynl_dump_state yds = {};
1908	struct nlmsghdr *nlh;
1909	int err;
1910
1911	yds.ys = ys;
1912	yds.alloc_sz = sizeof(struct devlink_info_get_list);
1913	yds.cb = devlink_info_get_rsp_parse;
1914	yds.rsp_cmd = DEVLINK_CMD_INFO_GET;
1915	yds.rsp_policy = &devlink_nest;
1916
1917	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1);
1918
1919	err = ynl_exec_dump(ys, nlh, &yds);
1920	if (err < 0)
1921		goto free_list;
1922
1923	return yds.first;
1924
1925free_list:
1926	devlink_info_get_list_free(yds.first);
1927	return NULL;
1928}
1929
1930/* ============== DEVLINK_CMD_HEALTH_REPORTER_GET ============== */
1931/* DEVLINK_CMD_HEALTH_REPORTER_GET - do */
1932void
1933devlink_health_reporter_get_req_free(struct devlink_health_reporter_get_req *req)
1934{
1935	free(req->bus_name);
1936	free(req->dev_name);
1937	free(req->health_reporter_name);
1938	free(req);
1939}
1940
1941void
1942devlink_health_reporter_get_rsp_free(struct devlink_health_reporter_get_rsp *rsp)
1943{
1944	free(rsp->bus_name);
1945	free(rsp->dev_name);
1946	free(rsp->health_reporter_name);
1947	free(rsp);
1948}
1949
1950int devlink_health_reporter_get_rsp_parse(const struct nlmsghdr *nlh,
1951					  void *data)
1952{
1953	struct devlink_health_reporter_get_rsp *dst;
1954	struct ynl_parse_arg *yarg = data;
1955	const struct nlattr *attr;
1956
1957	dst = yarg->data;
1958
1959	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1960		unsigned int type = mnl_attr_get_type(attr);
1961
1962		if (type == DEVLINK_ATTR_BUS_NAME) {
1963			unsigned int len;
1964
1965			if (ynl_attr_validate(yarg, attr))
1966				return MNL_CB_ERROR;
1967
1968			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1969			dst->_present.bus_name_len = len;
1970			dst->bus_name = malloc(len + 1);
1971			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1972			dst->bus_name[len] = 0;
1973		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1974			unsigned int len;
1975
1976			if (ynl_attr_validate(yarg, attr))
1977				return MNL_CB_ERROR;
1978
1979			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1980			dst->_present.dev_name_len = len;
1981			dst->dev_name = malloc(len + 1);
1982			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1983			dst->dev_name[len] = 0;
1984		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
1985			if (ynl_attr_validate(yarg, attr))
1986				return MNL_CB_ERROR;
1987			dst->_present.port_index = 1;
1988			dst->port_index = mnl_attr_get_u32(attr);
1989		} else if (type == DEVLINK_ATTR_HEALTH_REPORTER_NAME) {
1990			unsigned int len;
1991
1992			if (ynl_attr_validate(yarg, attr))
1993				return MNL_CB_ERROR;
1994
1995			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1996			dst->_present.health_reporter_name_len = len;
1997			dst->health_reporter_name = malloc(len + 1);
1998			memcpy(dst->health_reporter_name, mnl_attr_get_str(attr), len);
1999			dst->health_reporter_name[len] = 0;
2000		}
2001	}
2002
2003	return MNL_CB_OK;
2004}
2005
2006struct devlink_health_reporter_get_rsp *
2007devlink_health_reporter_get(struct ynl_sock *ys,
2008			    struct devlink_health_reporter_get_req *req)
2009{
2010	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2011	struct devlink_health_reporter_get_rsp *rsp;
2012	struct nlmsghdr *nlh;
2013	int err;
2014
2015	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_GET, 1);
2016	ys->req_policy = &devlink_nest;
2017	yrs.yarg.rsp_policy = &devlink_nest;
2018
2019	if (req->_present.bus_name_len)
2020		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2021	if (req->_present.dev_name_len)
2022		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2023	if (req->_present.port_index)
2024		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
2025	if (req->_present.health_reporter_name_len)
2026		mnl_attr_put_strz(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, req->health_reporter_name);
2027
2028	rsp = calloc(1, sizeof(*rsp));
2029	yrs.yarg.data = rsp;
2030	yrs.cb = devlink_health_reporter_get_rsp_parse;
2031	yrs.rsp_cmd = DEVLINK_CMD_HEALTH_REPORTER_GET;
2032
2033	err = ynl_exec(ys, nlh, &yrs);
2034	if (err < 0)
2035		goto err_free;
2036
2037	return rsp;
2038
2039err_free:
2040	devlink_health_reporter_get_rsp_free(rsp);
2041	return NULL;
2042}
2043
2044/* DEVLINK_CMD_HEALTH_REPORTER_GET - dump */
2045void
2046devlink_health_reporter_get_list_free(struct devlink_health_reporter_get_list *rsp)
2047{
2048	struct devlink_health_reporter_get_list *next = rsp;
2049
2050	while ((void *)next != YNL_LIST_END) {
2051		rsp = next;
2052		next = rsp->next;
2053
2054		free(rsp->obj.bus_name);
2055		free(rsp->obj.dev_name);
2056		free(rsp->obj.health_reporter_name);
2057		free(rsp);
2058	}
2059}
2060
2061struct devlink_health_reporter_get_list *
2062devlink_health_reporter_get_dump(struct ynl_sock *ys,
2063				 struct devlink_health_reporter_get_req_dump *req)
2064{
2065	struct ynl_dump_state yds = {};
2066	struct nlmsghdr *nlh;
2067	int err;
2068
2069	yds.ys = ys;
2070	yds.alloc_sz = sizeof(struct devlink_health_reporter_get_list);
2071	yds.cb = devlink_health_reporter_get_rsp_parse;
2072	yds.rsp_cmd = DEVLINK_CMD_HEALTH_REPORTER_GET;
2073	yds.rsp_policy = &devlink_nest;
2074
2075	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_GET, 1);
2076	ys->req_policy = &devlink_nest;
2077
2078	if (req->_present.bus_name_len)
2079		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2080	if (req->_present.dev_name_len)
2081		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2082	if (req->_present.port_index)
2083		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
2084
2085	err = ynl_exec_dump(ys, nlh, &yds);
2086	if (err < 0)
2087		goto free_list;
2088
2089	return yds.first;
2090
2091free_list:
2092	devlink_health_reporter_get_list_free(yds.first);
2093	return NULL;
2094}
2095
2096/* ============== DEVLINK_CMD_TRAP_GET ============== */
2097/* DEVLINK_CMD_TRAP_GET - do */
2098void devlink_trap_get_req_free(struct devlink_trap_get_req *req)
2099{
2100	free(req->bus_name);
2101	free(req->dev_name);
2102	free(req->trap_name);
2103	free(req);
2104}
2105
2106void devlink_trap_get_rsp_free(struct devlink_trap_get_rsp *rsp)
2107{
2108	free(rsp->bus_name);
2109	free(rsp->dev_name);
2110	free(rsp->trap_name);
2111	free(rsp);
2112}
2113
2114int devlink_trap_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2115{
2116	struct ynl_parse_arg *yarg = data;
2117	struct devlink_trap_get_rsp *dst;
2118	const struct nlattr *attr;
2119
2120	dst = yarg->data;
2121
2122	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2123		unsigned int type = mnl_attr_get_type(attr);
2124
2125		if (type == DEVLINK_ATTR_BUS_NAME) {
2126			unsigned int len;
2127
2128			if (ynl_attr_validate(yarg, attr))
2129				return MNL_CB_ERROR;
2130
2131			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2132			dst->_present.bus_name_len = len;
2133			dst->bus_name = malloc(len + 1);
2134			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2135			dst->bus_name[len] = 0;
2136		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2137			unsigned int len;
2138
2139			if (ynl_attr_validate(yarg, attr))
2140				return MNL_CB_ERROR;
2141
2142			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2143			dst->_present.dev_name_len = len;
2144			dst->dev_name = malloc(len + 1);
2145			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2146			dst->dev_name[len] = 0;
2147		} else if (type == DEVLINK_ATTR_TRAP_NAME) {
2148			unsigned int len;
2149
2150			if (ynl_attr_validate(yarg, attr))
2151				return MNL_CB_ERROR;
2152
2153			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2154			dst->_present.trap_name_len = len;
2155			dst->trap_name = malloc(len + 1);
2156			memcpy(dst->trap_name, mnl_attr_get_str(attr), len);
2157			dst->trap_name[len] = 0;
2158		}
2159	}
2160
2161	return MNL_CB_OK;
2162}
2163
2164struct devlink_trap_get_rsp *
2165devlink_trap_get(struct ynl_sock *ys, struct devlink_trap_get_req *req)
2166{
2167	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2168	struct devlink_trap_get_rsp *rsp;
2169	struct nlmsghdr *nlh;
2170	int err;
2171
2172	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_GET, 1);
2173	ys->req_policy = &devlink_nest;
2174	yrs.yarg.rsp_policy = &devlink_nest;
2175
2176	if (req->_present.bus_name_len)
2177		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2178	if (req->_present.dev_name_len)
2179		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2180	if (req->_present.trap_name_len)
2181		mnl_attr_put_strz(nlh, DEVLINK_ATTR_TRAP_NAME, req->trap_name);
2182
2183	rsp = calloc(1, sizeof(*rsp));
2184	yrs.yarg.data = rsp;
2185	yrs.cb = devlink_trap_get_rsp_parse;
2186	yrs.rsp_cmd = 63;
2187
2188	err = ynl_exec(ys, nlh, &yrs);
2189	if (err < 0)
2190		goto err_free;
2191
2192	return rsp;
2193
2194err_free:
2195	devlink_trap_get_rsp_free(rsp);
2196	return NULL;
2197}
2198
2199/* DEVLINK_CMD_TRAP_GET - dump */
2200void devlink_trap_get_list_free(struct devlink_trap_get_list *rsp)
2201{
2202	struct devlink_trap_get_list *next = rsp;
2203
2204	while ((void *)next != YNL_LIST_END) {
2205		rsp = next;
2206		next = rsp->next;
2207
2208		free(rsp->obj.bus_name);
2209		free(rsp->obj.dev_name);
2210		free(rsp->obj.trap_name);
2211		free(rsp);
2212	}
2213}
2214
2215struct devlink_trap_get_list *
2216devlink_trap_get_dump(struct ynl_sock *ys,
2217		      struct devlink_trap_get_req_dump *req)
2218{
2219	struct ynl_dump_state yds = {};
2220	struct nlmsghdr *nlh;
2221	int err;
2222
2223	yds.ys = ys;
2224	yds.alloc_sz = sizeof(struct devlink_trap_get_list);
2225	yds.cb = devlink_trap_get_rsp_parse;
2226	yds.rsp_cmd = 63;
2227	yds.rsp_policy = &devlink_nest;
2228
2229	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_TRAP_GET, 1);
2230	ys->req_policy = &devlink_nest;
2231
2232	if (req->_present.bus_name_len)
2233		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2234	if (req->_present.dev_name_len)
2235		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2236
2237	err = ynl_exec_dump(ys, nlh, &yds);
2238	if (err < 0)
2239		goto free_list;
2240
2241	return yds.first;
2242
2243free_list:
2244	devlink_trap_get_list_free(yds.first);
2245	return NULL;
2246}
2247
2248/* ============== DEVLINK_CMD_TRAP_GROUP_GET ============== */
2249/* DEVLINK_CMD_TRAP_GROUP_GET - do */
2250void devlink_trap_group_get_req_free(struct devlink_trap_group_get_req *req)
2251{
2252	free(req->bus_name);
2253	free(req->dev_name);
2254	free(req->trap_group_name);
2255	free(req);
2256}
2257
2258void devlink_trap_group_get_rsp_free(struct devlink_trap_group_get_rsp *rsp)
2259{
2260	free(rsp->bus_name);
2261	free(rsp->dev_name);
2262	free(rsp->trap_group_name);
2263	free(rsp);
2264}
2265
2266int devlink_trap_group_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2267{
2268	struct devlink_trap_group_get_rsp *dst;
2269	struct ynl_parse_arg *yarg = data;
2270	const struct nlattr *attr;
2271
2272	dst = yarg->data;
2273
2274	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2275		unsigned int type = mnl_attr_get_type(attr);
2276
2277		if (type == DEVLINK_ATTR_BUS_NAME) {
2278			unsigned int len;
2279
2280			if (ynl_attr_validate(yarg, attr))
2281				return MNL_CB_ERROR;
2282
2283			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2284			dst->_present.bus_name_len = len;
2285			dst->bus_name = malloc(len + 1);
2286			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2287			dst->bus_name[len] = 0;
2288		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2289			unsigned int len;
2290
2291			if (ynl_attr_validate(yarg, attr))
2292				return MNL_CB_ERROR;
2293
2294			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2295			dst->_present.dev_name_len = len;
2296			dst->dev_name = malloc(len + 1);
2297			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2298			dst->dev_name[len] = 0;
2299		} else if (type == DEVLINK_ATTR_TRAP_GROUP_NAME) {
2300			unsigned int len;
2301
2302			if (ynl_attr_validate(yarg, attr))
2303				return MNL_CB_ERROR;
2304
2305			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2306			dst->_present.trap_group_name_len = len;
2307			dst->trap_group_name = malloc(len + 1);
2308			memcpy(dst->trap_group_name, mnl_attr_get_str(attr), len);
2309			dst->trap_group_name[len] = 0;
2310		}
2311	}
2312
2313	return MNL_CB_OK;
2314}
2315
2316struct devlink_trap_group_get_rsp *
2317devlink_trap_group_get(struct ynl_sock *ys,
2318		       struct devlink_trap_group_get_req *req)
2319{
2320	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2321	struct devlink_trap_group_get_rsp *rsp;
2322	struct nlmsghdr *nlh;
2323	int err;
2324
2325	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_GROUP_GET, 1);
2326	ys->req_policy = &devlink_nest;
2327	yrs.yarg.rsp_policy = &devlink_nest;
2328
2329	if (req->_present.bus_name_len)
2330		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2331	if (req->_present.dev_name_len)
2332		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2333	if (req->_present.trap_group_name_len)
2334		mnl_attr_put_strz(nlh, DEVLINK_ATTR_TRAP_GROUP_NAME, req->trap_group_name);
2335
2336	rsp = calloc(1, sizeof(*rsp));
2337	yrs.yarg.data = rsp;
2338	yrs.cb = devlink_trap_group_get_rsp_parse;
2339	yrs.rsp_cmd = 67;
2340
2341	err = ynl_exec(ys, nlh, &yrs);
2342	if (err < 0)
2343		goto err_free;
2344
2345	return rsp;
2346
2347err_free:
2348	devlink_trap_group_get_rsp_free(rsp);
2349	return NULL;
2350}
2351
2352/* DEVLINK_CMD_TRAP_GROUP_GET - dump */
2353void devlink_trap_group_get_list_free(struct devlink_trap_group_get_list *rsp)
2354{
2355	struct devlink_trap_group_get_list *next = rsp;
2356
2357	while ((void *)next != YNL_LIST_END) {
2358		rsp = next;
2359		next = rsp->next;
2360
2361		free(rsp->obj.bus_name);
2362		free(rsp->obj.dev_name);
2363		free(rsp->obj.trap_group_name);
2364		free(rsp);
2365	}
2366}
2367
2368struct devlink_trap_group_get_list *
2369devlink_trap_group_get_dump(struct ynl_sock *ys,
2370			    struct devlink_trap_group_get_req_dump *req)
2371{
2372	struct ynl_dump_state yds = {};
2373	struct nlmsghdr *nlh;
2374	int err;
2375
2376	yds.ys = ys;
2377	yds.alloc_sz = sizeof(struct devlink_trap_group_get_list);
2378	yds.cb = devlink_trap_group_get_rsp_parse;
2379	yds.rsp_cmd = 67;
2380	yds.rsp_policy = &devlink_nest;
2381
2382	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_TRAP_GROUP_GET, 1);
2383	ys->req_policy = &devlink_nest;
2384
2385	if (req->_present.bus_name_len)
2386		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2387	if (req->_present.dev_name_len)
2388		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2389
2390	err = ynl_exec_dump(ys, nlh, &yds);
2391	if (err < 0)
2392		goto free_list;
2393
2394	return yds.first;
2395
2396free_list:
2397	devlink_trap_group_get_list_free(yds.first);
2398	return NULL;
2399}
2400
2401/* ============== DEVLINK_CMD_TRAP_POLICER_GET ============== */
2402/* DEVLINK_CMD_TRAP_POLICER_GET - do */
2403void
2404devlink_trap_policer_get_req_free(struct devlink_trap_policer_get_req *req)
2405{
2406	free(req->bus_name);
2407	free(req->dev_name);
2408	free(req);
2409}
2410
2411void
2412devlink_trap_policer_get_rsp_free(struct devlink_trap_policer_get_rsp *rsp)
2413{
2414	free(rsp->bus_name);
2415	free(rsp->dev_name);
2416	free(rsp);
2417}
2418
2419int devlink_trap_policer_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2420{
2421	struct devlink_trap_policer_get_rsp *dst;
2422	struct ynl_parse_arg *yarg = data;
2423	const struct nlattr *attr;
2424
2425	dst = yarg->data;
2426
2427	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2428		unsigned int type = mnl_attr_get_type(attr);
2429
2430		if (type == DEVLINK_ATTR_BUS_NAME) {
2431			unsigned int len;
2432
2433			if (ynl_attr_validate(yarg, attr))
2434				return MNL_CB_ERROR;
2435
2436			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2437			dst->_present.bus_name_len = len;
2438			dst->bus_name = malloc(len + 1);
2439			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2440			dst->bus_name[len] = 0;
2441		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2442			unsigned int len;
2443
2444			if (ynl_attr_validate(yarg, attr))
2445				return MNL_CB_ERROR;
2446
2447			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2448			dst->_present.dev_name_len = len;
2449			dst->dev_name = malloc(len + 1);
2450			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2451			dst->dev_name[len] = 0;
2452		} else if (type == DEVLINK_ATTR_TRAP_POLICER_ID) {
2453			if (ynl_attr_validate(yarg, attr))
2454				return MNL_CB_ERROR;
2455			dst->_present.trap_policer_id = 1;
2456			dst->trap_policer_id = mnl_attr_get_u32(attr);
2457		}
2458	}
2459
2460	return MNL_CB_OK;
2461}
2462
2463struct devlink_trap_policer_get_rsp *
2464devlink_trap_policer_get(struct ynl_sock *ys,
2465			 struct devlink_trap_policer_get_req *req)
2466{
2467	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2468	struct devlink_trap_policer_get_rsp *rsp;
2469	struct nlmsghdr *nlh;
2470	int err;
2471
2472	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_POLICER_GET, 1);
2473	ys->req_policy = &devlink_nest;
2474	yrs.yarg.rsp_policy = &devlink_nest;
2475
2476	if (req->_present.bus_name_len)
2477		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2478	if (req->_present.dev_name_len)
2479		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2480	if (req->_present.trap_policer_id)
2481		mnl_attr_put_u32(nlh, DEVLINK_ATTR_TRAP_POLICER_ID, req->trap_policer_id);
2482
2483	rsp = calloc(1, sizeof(*rsp));
2484	yrs.yarg.data = rsp;
2485	yrs.cb = devlink_trap_policer_get_rsp_parse;
2486	yrs.rsp_cmd = 71;
2487
2488	err = ynl_exec(ys, nlh, &yrs);
2489	if (err < 0)
2490		goto err_free;
2491
2492	return rsp;
2493
2494err_free:
2495	devlink_trap_policer_get_rsp_free(rsp);
2496	return NULL;
2497}
2498
2499/* DEVLINK_CMD_TRAP_POLICER_GET - dump */
2500void
2501devlink_trap_policer_get_list_free(struct devlink_trap_policer_get_list *rsp)
2502{
2503	struct devlink_trap_policer_get_list *next = rsp;
2504
2505	while ((void *)next != YNL_LIST_END) {
2506		rsp = next;
2507		next = rsp->next;
2508
2509		free(rsp->obj.bus_name);
2510		free(rsp->obj.dev_name);
2511		free(rsp);
2512	}
2513}
2514
2515struct devlink_trap_policer_get_list *
2516devlink_trap_policer_get_dump(struct ynl_sock *ys,
2517			      struct devlink_trap_policer_get_req_dump *req)
2518{
2519	struct ynl_dump_state yds = {};
2520	struct nlmsghdr *nlh;
2521	int err;
2522
2523	yds.ys = ys;
2524	yds.alloc_sz = sizeof(struct devlink_trap_policer_get_list);
2525	yds.cb = devlink_trap_policer_get_rsp_parse;
2526	yds.rsp_cmd = 71;
2527	yds.rsp_policy = &devlink_nest;
2528
2529	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_TRAP_POLICER_GET, 1);
2530	ys->req_policy = &devlink_nest;
2531
2532	if (req->_present.bus_name_len)
2533		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2534	if (req->_present.dev_name_len)
2535		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2536
2537	err = ynl_exec_dump(ys, nlh, &yds);
2538	if (err < 0)
2539		goto free_list;
2540
2541	return yds.first;
2542
2543free_list:
2544	devlink_trap_policer_get_list_free(yds.first);
2545	return NULL;
2546}
2547
2548/* ============== DEVLINK_CMD_RATE_GET ============== */
2549/* DEVLINK_CMD_RATE_GET - do */
2550void devlink_rate_get_req_free(struct devlink_rate_get_req *req)
2551{
2552	free(req->bus_name);
2553	free(req->dev_name);
2554	free(req->rate_node_name);
2555	free(req);
2556}
2557
2558void devlink_rate_get_rsp_free(struct devlink_rate_get_rsp *rsp)
2559{
2560	free(rsp->bus_name);
2561	free(rsp->dev_name);
2562	free(rsp->rate_node_name);
2563	free(rsp);
2564}
2565
2566int devlink_rate_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2567{
2568	struct ynl_parse_arg *yarg = data;
2569	struct devlink_rate_get_rsp *dst;
2570	const struct nlattr *attr;
2571
2572	dst = yarg->data;
2573
2574	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2575		unsigned int type = mnl_attr_get_type(attr);
2576
2577		if (type == DEVLINK_ATTR_BUS_NAME) {
2578			unsigned int len;
2579
2580			if (ynl_attr_validate(yarg, attr))
2581				return MNL_CB_ERROR;
2582
2583			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2584			dst->_present.bus_name_len = len;
2585			dst->bus_name = malloc(len + 1);
2586			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2587			dst->bus_name[len] = 0;
2588		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2589			unsigned int len;
2590
2591			if (ynl_attr_validate(yarg, attr))
2592				return MNL_CB_ERROR;
2593
2594			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2595			dst->_present.dev_name_len = len;
2596			dst->dev_name = malloc(len + 1);
2597			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2598			dst->dev_name[len] = 0;
2599		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
2600			if (ynl_attr_validate(yarg, attr))
2601				return MNL_CB_ERROR;
2602			dst->_present.port_index = 1;
2603			dst->port_index = mnl_attr_get_u32(attr);
2604		} else if (type == DEVLINK_ATTR_RATE_NODE_NAME) {
2605			unsigned int len;
2606
2607			if (ynl_attr_validate(yarg, attr))
2608				return MNL_CB_ERROR;
2609
2610			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2611			dst->_present.rate_node_name_len = len;
2612			dst->rate_node_name = malloc(len + 1);
2613			memcpy(dst->rate_node_name, mnl_attr_get_str(attr), len);
2614			dst->rate_node_name[len] = 0;
2615		}
2616	}
2617
2618	return MNL_CB_OK;
2619}
2620
2621struct devlink_rate_get_rsp *
2622devlink_rate_get(struct ynl_sock *ys, struct devlink_rate_get_req *req)
2623{
2624	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2625	struct devlink_rate_get_rsp *rsp;
2626	struct nlmsghdr *nlh;
2627	int err;
2628
2629	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_RATE_GET, 1);
2630	ys->req_policy = &devlink_nest;
2631	yrs.yarg.rsp_policy = &devlink_nest;
2632
2633	if (req->_present.bus_name_len)
2634		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2635	if (req->_present.dev_name_len)
2636		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2637	if (req->_present.port_index)
2638		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
2639	if (req->_present.rate_node_name_len)
2640		mnl_attr_put_strz(nlh, DEVLINK_ATTR_RATE_NODE_NAME, req->rate_node_name);
2641
2642	rsp = calloc(1, sizeof(*rsp));
2643	yrs.yarg.data = rsp;
2644	yrs.cb = devlink_rate_get_rsp_parse;
2645	yrs.rsp_cmd = 76;
2646
2647	err = ynl_exec(ys, nlh, &yrs);
2648	if (err < 0)
2649		goto err_free;
2650
2651	return rsp;
2652
2653err_free:
2654	devlink_rate_get_rsp_free(rsp);
2655	return NULL;
2656}
2657
2658/* DEVLINK_CMD_RATE_GET - dump */
2659void devlink_rate_get_list_free(struct devlink_rate_get_list *rsp)
2660{
2661	struct devlink_rate_get_list *next = rsp;
2662
2663	while ((void *)next != YNL_LIST_END) {
2664		rsp = next;
2665		next = rsp->next;
2666
2667		free(rsp->obj.bus_name);
2668		free(rsp->obj.dev_name);
2669		free(rsp->obj.rate_node_name);
2670		free(rsp);
2671	}
2672}
2673
2674struct devlink_rate_get_list *
2675devlink_rate_get_dump(struct ynl_sock *ys,
2676		      struct devlink_rate_get_req_dump *req)
2677{
2678	struct ynl_dump_state yds = {};
2679	struct nlmsghdr *nlh;
2680	int err;
2681
2682	yds.ys = ys;
2683	yds.alloc_sz = sizeof(struct devlink_rate_get_list);
2684	yds.cb = devlink_rate_get_rsp_parse;
2685	yds.rsp_cmd = 76;
2686	yds.rsp_policy = &devlink_nest;
2687
2688	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_RATE_GET, 1);
2689	ys->req_policy = &devlink_nest;
2690
2691	if (req->_present.bus_name_len)
2692		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2693	if (req->_present.dev_name_len)
2694		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2695
2696	err = ynl_exec_dump(ys, nlh, &yds);
2697	if (err < 0)
2698		goto free_list;
2699
2700	return yds.first;
2701
2702free_list:
2703	devlink_rate_get_list_free(yds.first);
2704	return NULL;
2705}
2706
2707/* ============== DEVLINK_CMD_LINECARD_GET ============== */
2708/* DEVLINK_CMD_LINECARD_GET - do */
2709void devlink_linecard_get_req_free(struct devlink_linecard_get_req *req)
2710{
2711	free(req->bus_name);
2712	free(req->dev_name);
2713	free(req);
2714}
2715
2716void devlink_linecard_get_rsp_free(struct devlink_linecard_get_rsp *rsp)
2717{
2718	free(rsp->bus_name);
2719	free(rsp->dev_name);
2720	free(rsp);
2721}
2722
2723int devlink_linecard_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2724{
2725	struct devlink_linecard_get_rsp *dst;
2726	struct ynl_parse_arg *yarg = data;
2727	const struct nlattr *attr;
2728
2729	dst = yarg->data;
2730
2731	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2732		unsigned int type = mnl_attr_get_type(attr);
2733
2734		if (type == DEVLINK_ATTR_BUS_NAME) {
2735			unsigned int len;
2736
2737			if (ynl_attr_validate(yarg, attr))
2738				return MNL_CB_ERROR;
2739
2740			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2741			dst->_present.bus_name_len = len;
2742			dst->bus_name = malloc(len + 1);
2743			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2744			dst->bus_name[len] = 0;
2745		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2746			unsigned int len;
2747
2748			if (ynl_attr_validate(yarg, attr))
2749				return MNL_CB_ERROR;
2750
2751			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2752			dst->_present.dev_name_len = len;
2753			dst->dev_name = malloc(len + 1);
2754			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2755			dst->dev_name[len] = 0;
2756		} else if (type == DEVLINK_ATTR_LINECARD_INDEX) {
2757			if (ynl_attr_validate(yarg, attr))
2758				return MNL_CB_ERROR;
2759			dst->_present.linecard_index = 1;
2760			dst->linecard_index = mnl_attr_get_u32(attr);
2761		}
2762	}
2763
2764	return MNL_CB_OK;
2765}
2766
2767struct devlink_linecard_get_rsp *
2768devlink_linecard_get(struct ynl_sock *ys, struct devlink_linecard_get_req *req)
2769{
2770	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2771	struct devlink_linecard_get_rsp *rsp;
2772	struct nlmsghdr *nlh;
2773	int err;
2774
2775	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_LINECARD_GET, 1);
2776	ys->req_policy = &devlink_nest;
2777	yrs.yarg.rsp_policy = &devlink_nest;
2778
2779	if (req->_present.bus_name_len)
2780		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2781	if (req->_present.dev_name_len)
2782		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2783	if (req->_present.linecard_index)
2784		mnl_attr_put_u32(nlh, DEVLINK_ATTR_LINECARD_INDEX, req->linecard_index);
2785
2786	rsp = calloc(1, sizeof(*rsp));
2787	yrs.yarg.data = rsp;
2788	yrs.cb = devlink_linecard_get_rsp_parse;
2789	yrs.rsp_cmd = 80;
2790
2791	err = ynl_exec(ys, nlh, &yrs);
2792	if (err < 0)
2793		goto err_free;
2794
2795	return rsp;
2796
2797err_free:
2798	devlink_linecard_get_rsp_free(rsp);
2799	return NULL;
2800}
2801
2802/* DEVLINK_CMD_LINECARD_GET - dump */
2803void devlink_linecard_get_list_free(struct devlink_linecard_get_list *rsp)
2804{
2805	struct devlink_linecard_get_list *next = rsp;
2806
2807	while ((void *)next != YNL_LIST_END) {
2808		rsp = next;
2809		next = rsp->next;
2810
2811		free(rsp->obj.bus_name);
2812		free(rsp->obj.dev_name);
2813		free(rsp);
2814	}
2815}
2816
2817struct devlink_linecard_get_list *
2818devlink_linecard_get_dump(struct ynl_sock *ys,
2819			  struct devlink_linecard_get_req_dump *req)
2820{
2821	struct ynl_dump_state yds = {};
2822	struct nlmsghdr *nlh;
2823	int err;
2824
2825	yds.ys = ys;
2826	yds.alloc_sz = sizeof(struct devlink_linecard_get_list);
2827	yds.cb = devlink_linecard_get_rsp_parse;
2828	yds.rsp_cmd = 80;
2829	yds.rsp_policy = &devlink_nest;
2830
2831	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_LINECARD_GET, 1);
2832	ys->req_policy = &devlink_nest;
2833
2834	if (req->_present.bus_name_len)
2835		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2836	if (req->_present.dev_name_len)
2837		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2838
2839	err = ynl_exec_dump(ys, nlh, &yds);
2840	if (err < 0)
2841		goto free_list;
2842
2843	return yds.first;
2844
2845free_list:
2846	devlink_linecard_get_list_free(yds.first);
2847	return NULL;
2848}
2849
2850/* ============== DEVLINK_CMD_SELFTESTS_GET ============== */
2851/* DEVLINK_CMD_SELFTESTS_GET - do */
2852void devlink_selftests_get_req_free(struct devlink_selftests_get_req *req)
2853{
2854	free(req->bus_name);
2855	free(req->dev_name);
2856	free(req);
2857}
2858
2859void devlink_selftests_get_rsp_free(struct devlink_selftests_get_rsp *rsp)
2860{
2861	free(rsp->bus_name);
2862	free(rsp->dev_name);
2863	free(rsp);
2864}
2865
2866int devlink_selftests_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2867{
2868	struct devlink_selftests_get_rsp *dst;
2869	struct ynl_parse_arg *yarg = data;
2870	const struct nlattr *attr;
2871
2872	dst = yarg->data;
2873
2874	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2875		unsigned int type = mnl_attr_get_type(attr);
2876
2877		if (type == DEVLINK_ATTR_BUS_NAME) {
2878			unsigned int len;
2879
2880			if (ynl_attr_validate(yarg, attr))
2881				return MNL_CB_ERROR;
2882
2883			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2884			dst->_present.bus_name_len = len;
2885			dst->bus_name = malloc(len + 1);
2886			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2887			dst->bus_name[len] = 0;
2888		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2889			unsigned int len;
2890
2891			if (ynl_attr_validate(yarg, attr))
2892				return MNL_CB_ERROR;
2893
2894			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2895			dst->_present.dev_name_len = len;
2896			dst->dev_name = malloc(len + 1);
2897			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2898			dst->dev_name[len] = 0;
2899		}
2900	}
2901
2902	return MNL_CB_OK;
2903}
2904
2905struct devlink_selftests_get_rsp *
2906devlink_selftests_get(struct ynl_sock *ys,
2907		      struct devlink_selftests_get_req *req)
2908{
2909	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2910	struct devlink_selftests_get_rsp *rsp;
2911	struct nlmsghdr *nlh;
2912	int err;
2913
2914	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SELFTESTS_GET, 1);
2915	ys->req_policy = &devlink_nest;
2916	yrs.yarg.rsp_policy = &devlink_nest;
2917
2918	if (req->_present.bus_name_len)
2919		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2920	if (req->_present.dev_name_len)
2921		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2922
2923	rsp = calloc(1, sizeof(*rsp));
2924	yrs.yarg.data = rsp;
2925	yrs.cb = devlink_selftests_get_rsp_parse;
2926	yrs.rsp_cmd = DEVLINK_CMD_SELFTESTS_GET;
2927
2928	err = ynl_exec(ys, nlh, &yrs);
2929	if (err < 0)
2930		goto err_free;
2931
2932	return rsp;
2933
2934err_free:
2935	devlink_selftests_get_rsp_free(rsp);
2936	return NULL;
2937}
2938
2939/* DEVLINK_CMD_SELFTESTS_GET - dump */
2940void devlink_selftests_get_list_free(struct devlink_selftests_get_list *rsp)
2941{
2942	struct devlink_selftests_get_list *next = rsp;
2943
2944	while ((void *)next != YNL_LIST_END) {
2945		rsp = next;
2946		next = rsp->next;
2947
2948		free(rsp->obj.bus_name);
2949		free(rsp->obj.dev_name);
2950		free(rsp);
2951	}
2952}
2953
2954struct devlink_selftests_get_list *
2955devlink_selftests_get_dump(struct ynl_sock *ys)
2956{
2957	struct ynl_dump_state yds = {};
2958	struct nlmsghdr *nlh;
2959	int err;
2960
2961	yds.ys = ys;
2962	yds.alloc_sz = sizeof(struct devlink_selftests_get_list);
2963	yds.cb = devlink_selftests_get_rsp_parse;
2964	yds.rsp_cmd = DEVLINK_CMD_SELFTESTS_GET;
2965	yds.rsp_policy = &devlink_nest;
2966
2967	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SELFTESTS_GET, 1);
2968
2969	err = ynl_exec_dump(ys, nlh, &yds);
2970	if (err < 0)
2971		goto free_list;
2972
2973	return yds.first;
2974
2975free_list:
2976	devlink_selftests_get_list_free(yds.first);
2977	return NULL;
2978}
2979
2980const struct ynl_family ynl_devlink_family =  {
2981	.name		= "devlink",
2982};
2983