tools: ynl: regen: cleanup user space header includes
[platform/kernel/linux-rpi.git] / tools / net / ynl / generated / devlink-user.c
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 */
16 static const char * const devlink_op_strmap[] = {
17         [3] = "get",
18         [DEVLINK_CMD_INFO_GET] = "info-get",
19 };
20
21 const char *devlink_op_str(int op)
22 {
23         if (op < 0 || op >= (int)MNL_ARRAY_SIZE(devlink_op_strmap))
24                 return NULL;
25         return devlink_op_strmap[op];
26 }
27
28 /* Policies */
29 struct ynl_policy_attr devlink_dl_info_version_policy[DEVLINK_ATTR_MAX + 1] = {
30         [DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, },
31         [DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, },
32 };
33
34 struct ynl_policy_nest devlink_dl_info_version_nest = {
35         .max_attr = DEVLINK_ATTR_MAX,
36         .table = devlink_dl_info_version_policy,
37 };
38
39 struct ynl_policy_attr devlink_dl_reload_stats_entry_policy[DEVLINK_ATTR_MAX + 1] = {
40         [DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, },
41         [DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, },
42 };
43
44 struct ynl_policy_nest devlink_dl_reload_stats_entry_nest = {
45         .max_attr = DEVLINK_ATTR_MAX,
46         .table = devlink_dl_reload_stats_entry_policy,
47 };
48
49 struct ynl_policy_attr devlink_dl_reload_act_stats_policy[DEVLINK_ATTR_MAX + 1] = {
50         [DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, },
51 };
52
53 struct ynl_policy_nest devlink_dl_reload_act_stats_nest = {
54         .max_attr = DEVLINK_ATTR_MAX,
55         .table = devlink_dl_reload_act_stats_policy,
56 };
57
58 struct ynl_policy_attr devlink_dl_reload_act_info_policy[DEVLINK_ATTR_MAX + 1] = {
59         [DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, },
60         [DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, },
61 };
62
63 struct ynl_policy_nest devlink_dl_reload_act_info_nest = {
64         .max_attr = DEVLINK_ATTR_MAX,
65         .table = devlink_dl_reload_act_info_policy,
66 };
67
68 struct ynl_policy_attr devlink_dl_reload_stats_policy[DEVLINK_ATTR_MAX + 1] = {
69         [DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, },
70 };
71
72 struct ynl_policy_nest devlink_dl_reload_stats_nest = {
73         .max_attr = DEVLINK_ATTR_MAX,
74         .table = devlink_dl_reload_stats_policy,
75 };
76
77 struct ynl_policy_attr devlink_dl_dev_stats_policy[DEVLINK_ATTR_MAX + 1] = {
78         [DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
79         [DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
80 };
81
82 struct ynl_policy_nest devlink_dl_dev_stats_nest = {
83         .max_attr = DEVLINK_ATTR_MAX,
84         .table = devlink_dl_dev_stats_policy,
85 };
86
87 struct ynl_policy_attr devlink_policy[DEVLINK_ATTR_MAX + 1] = {
88         [DEVLINK_ATTR_BUS_NAME] = { .name = "bus-name", .type = YNL_PT_NUL_STR, },
89         [DEVLINK_ATTR_DEV_NAME] = { .name = "dev-name", .type = YNL_PT_NUL_STR, },
90         [DEVLINK_ATTR_PORT_INDEX] = { .name = "port-index", .type = YNL_PT_U32, },
91         [DEVLINK_ATTR_INFO_DRIVER_NAME] = { .name = "info-driver-name", .type = YNL_PT_NUL_STR, },
92         [DEVLINK_ATTR_INFO_SERIAL_NUMBER] = { .name = "info-serial-number", .type = YNL_PT_NUL_STR, },
93         [DEVLINK_ATTR_INFO_VERSION_FIXED] = { .name = "info-version-fixed", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
94         [DEVLINK_ATTR_INFO_VERSION_RUNNING] = { .name = "info-version-running", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
95         [DEVLINK_ATTR_INFO_VERSION_STORED] = { .name = "info-version-stored", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
96         [DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, },
97         [DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, },
98         [DEVLINK_ATTR_RELOAD_FAILED] = { .name = "reload-failed", .type = YNL_PT_U8, },
99         [DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, },
100         [DEVLINK_ATTR_DEV_STATS] = { .name = "dev-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_dev_stats_nest, },
101         [DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
102         [DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, },
103         [DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, },
104         [DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, },
105         [DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
106         [DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, },
107         [DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, },
108 };
109
110 struct ynl_policy_nest devlink_nest = {
111         .max_attr = DEVLINK_ATTR_MAX,
112         .table = devlink_policy,
113 };
114
115 /* Common nested types */
116 void devlink_dl_info_version_free(struct devlink_dl_info_version *obj)
117 {
118         free(obj->info_version_name);
119         free(obj->info_version_value);
120 }
121
122 int devlink_dl_info_version_parse(struct ynl_parse_arg *yarg,
123                                   const struct nlattr *nested)
124 {
125         struct devlink_dl_info_version *dst = yarg->data;
126         const struct nlattr *attr;
127
128         mnl_attr_for_each_nested(attr, nested) {
129                 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_NAME) {
130                         unsigned int len;
131
132                         if (ynl_attr_validate(yarg, attr))
133                                 return MNL_CB_ERROR;
134
135                         len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
136                         dst->_present.info_version_name_len = len;
137                         dst->info_version_name = malloc(len + 1);
138                         memcpy(dst->info_version_name, mnl_attr_get_str(attr), len);
139                         dst->info_version_name[len] = 0;
140                 }
141                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_VALUE) {
142                         unsigned int len;
143
144                         if (ynl_attr_validate(yarg, attr))
145                                 return MNL_CB_ERROR;
146
147                         len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
148                         dst->_present.info_version_value_len = len;
149                         dst->info_version_value = malloc(len + 1);
150                         memcpy(dst->info_version_value, mnl_attr_get_str(attr), len);
151                         dst->info_version_value[len] = 0;
152                 }
153         }
154
155         return 0;
156 }
157
158 void
159 devlink_dl_reload_stats_entry_free(struct devlink_dl_reload_stats_entry *obj)
160 {
161 }
162
163 int devlink_dl_reload_stats_entry_parse(struct ynl_parse_arg *yarg,
164                                         const struct nlattr *nested)
165 {
166         struct devlink_dl_reload_stats_entry *dst = yarg->data;
167         const struct nlattr *attr;
168
169         mnl_attr_for_each_nested(attr, nested) {
170                 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_LIMIT) {
171                         if (ynl_attr_validate(yarg, attr))
172                                 return MNL_CB_ERROR;
173                         dst->_present.reload_stats_limit = 1;
174                         dst->reload_stats_limit = mnl_attr_get_u8(attr);
175                 }
176                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_VALUE) {
177                         if (ynl_attr_validate(yarg, attr))
178                                 return MNL_CB_ERROR;
179                         dst->_present.reload_stats_value = 1;
180                         dst->reload_stats_value = mnl_attr_get_u32(attr);
181                 }
182         }
183
184         return 0;
185 }
186
187 void devlink_dl_reload_act_stats_free(struct devlink_dl_reload_act_stats *obj)
188 {
189         unsigned int i;
190
191         for (i = 0; i < obj->n_reload_stats_entry; i++)
192                 devlink_dl_reload_stats_entry_free(&obj->reload_stats_entry[i]);
193         free(obj->reload_stats_entry);
194 }
195
196 int devlink_dl_reload_act_stats_parse(struct ynl_parse_arg *yarg,
197                                       const struct nlattr *nested)
198 {
199         struct devlink_dl_reload_act_stats *dst = yarg->data;
200         unsigned int n_reload_stats_entry = 0;
201         const struct nlattr *attr;
202         struct ynl_parse_arg parg;
203         int i;
204
205         parg.ys = yarg->ys;
206
207         if (dst->reload_stats_entry)
208                 return ynl_error_parse(yarg, "attribute already present (dl-reload-act-stats.reload-stats-entry)");
209
210         mnl_attr_for_each_nested(attr, nested) {
211                 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) {
212                         n_reload_stats_entry++;
213                 }
214         }
215
216         if (n_reload_stats_entry) {
217                 dst->reload_stats_entry = calloc(n_reload_stats_entry, sizeof(*dst->reload_stats_entry));
218                 dst->n_reload_stats_entry = n_reload_stats_entry;
219                 i = 0;
220                 parg.rsp_policy = &devlink_dl_reload_stats_entry_nest;
221                 mnl_attr_for_each_nested(attr, nested) {
222                         if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) {
223                                 parg.data = &dst->reload_stats_entry[i];
224                                 if (devlink_dl_reload_stats_entry_parse(&parg, attr))
225                                         return MNL_CB_ERROR;
226                                 i++;
227                         }
228                 }
229         }
230
231         return 0;
232 }
233
234 void devlink_dl_reload_act_info_free(struct devlink_dl_reload_act_info *obj)
235 {
236         unsigned int i;
237
238         for (i = 0; i < obj->n_reload_action_stats; i++)
239                 devlink_dl_reload_act_stats_free(&obj->reload_action_stats[i]);
240         free(obj->reload_action_stats);
241 }
242
243 int devlink_dl_reload_act_info_parse(struct ynl_parse_arg *yarg,
244                                      const struct nlattr *nested)
245 {
246         struct devlink_dl_reload_act_info *dst = yarg->data;
247         unsigned int n_reload_action_stats = 0;
248         const struct nlattr *attr;
249         struct ynl_parse_arg parg;
250         int i;
251
252         parg.ys = yarg->ys;
253
254         if (dst->reload_action_stats)
255                 return ynl_error_parse(yarg, "attribute already present (dl-reload-act-info.reload-action-stats)");
256
257         mnl_attr_for_each_nested(attr, nested) {
258                 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION) {
259                         if (ynl_attr_validate(yarg, attr))
260                                 return MNL_CB_ERROR;
261                         dst->_present.reload_action = 1;
262                         dst->reload_action = mnl_attr_get_u8(attr);
263                 }
264                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) {
265                         n_reload_action_stats++;
266                 }
267         }
268
269         if (n_reload_action_stats) {
270                 dst->reload_action_stats = calloc(n_reload_action_stats, sizeof(*dst->reload_action_stats));
271                 dst->n_reload_action_stats = n_reload_action_stats;
272                 i = 0;
273                 parg.rsp_policy = &devlink_dl_reload_act_stats_nest;
274                 mnl_attr_for_each_nested(attr, nested) {
275                         if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) {
276                                 parg.data = &dst->reload_action_stats[i];
277                                 if (devlink_dl_reload_act_stats_parse(&parg, attr))
278                                         return MNL_CB_ERROR;
279                                 i++;
280                         }
281                 }
282         }
283
284         return 0;
285 }
286
287 void devlink_dl_reload_stats_free(struct devlink_dl_reload_stats *obj)
288 {
289         unsigned int i;
290
291         for (i = 0; i < obj->n_reload_action_info; i++)
292                 devlink_dl_reload_act_info_free(&obj->reload_action_info[i]);
293         free(obj->reload_action_info);
294 }
295
296 int devlink_dl_reload_stats_parse(struct ynl_parse_arg *yarg,
297                                   const struct nlattr *nested)
298 {
299         struct devlink_dl_reload_stats *dst = yarg->data;
300         unsigned int n_reload_action_info = 0;
301         const struct nlattr *attr;
302         struct ynl_parse_arg parg;
303         int i;
304
305         parg.ys = yarg->ys;
306
307         if (dst->reload_action_info)
308                 return ynl_error_parse(yarg, "attribute already present (dl-reload-stats.reload-action-info)");
309
310         mnl_attr_for_each_nested(attr, nested) {
311                 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) {
312                         n_reload_action_info++;
313                 }
314         }
315
316         if (n_reload_action_info) {
317                 dst->reload_action_info = calloc(n_reload_action_info, sizeof(*dst->reload_action_info));
318                 dst->n_reload_action_info = n_reload_action_info;
319                 i = 0;
320                 parg.rsp_policy = &devlink_dl_reload_act_info_nest;
321                 mnl_attr_for_each_nested(attr, nested) {
322                         if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) {
323                                 parg.data = &dst->reload_action_info[i];
324                                 if (devlink_dl_reload_act_info_parse(&parg, attr))
325                                         return MNL_CB_ERROR;
326                                 i++;
327                         }
328                 }
329         }
330
331         return 0;
332 }
333
334 void devlink_dl_dev_stats_free(struct devlink_dl_dev_stats *obj)
335 {
336         devlink_dl_reload_stats_free(&obj->reload_stats);
337         devlink_dl_reload_stats_free(&obj->remote_reload_stats);
338 }
339
340 int devlink_dl_dev_stats_parse(struct ynl_parse_arg *yarg,
341                                const struct nlattr *nested)
342 {
343         struct devlink_dl_dev_stats *dst = yarg->data;
344         const struct nlattr *attr;
345         struct ynl_parse_arg parg;
346
347         parg.ys = yarg->ys;
348
349         mnl_attr_for_each_nested(attr, nested) {
350                 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS) {
351                         if (ynl_attr_validate(yarg, attr))
352                                 return MNL_CB_ERROR;
353                         dst->_present.reload_stats = 1;
354
355                         parg.rsp_policy = &devlink_dl_reload_stats_nest;
356                         parg.data = &dst->reload_stats;
357                         if (devlink_dl_reload_stats_parse(&parg, attr))
358                                 return MNL_CB_ERROR;
359                 }
360                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_REMOTE_RELOAD_STATS) {
361                         if (ynl_attr_validate(yarg, attr))
362                                 return MNL_CB_ERROR;
363                         dst->_present.remote_reload_stats = 1;
364
365                         parg.rsp_policy = &devlink_dl_reload_stats_nest;
366                         parg.data = &dst->remote_reload_stats;
367                         if (devlink_dl_reload_stats_parse(&parg, attr))
368                                 return MNL_CB_ERROR;
369                 }
370         }
371
372         return 0;
373 }
374
375 /* ============== DEVLINK_CMD_GET ============== */
376 /* DEVLINK_CMD_GET - do */
377 void devlink_get_req_free(struct devlink_get_req *req)
378 {
379         free(req->bus_name);
380         free(req->dev_name);
381         free(req);
382 }
383
384 void devlink_get_rsp_free(struct devlink_get_rsp *rsp)
385 {
386         free(rsp->bus_name);
387         free(rsp->dev_name);
388         devlink_dl_dev_stats_free(&rsp->dev_stats);
389         free(rsp);
390 }
391
392 int devlink_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
393 {
394         struct ynl_parse_arg *yarg = data;
395         struct devlink_get_rsp *dst;
396         const struct nlattr *attr;
397         struct ynl_parse_arg parg;
398
399         dst = yarg->data;
400         parg.ys = yarg->ys;
401
402         mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
403                 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_BUS_NAME) {
404                         unsigned int len;
405
406                         if (ynl_attr_validate(yarg, attr))
407                                 return MNL_CB_ERROR;
408
409                         len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
410                         dst->_present.bus_name_len = len;
411                         dst->bus_name = malloc(len + 1);
412                         memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
413                         dst->bus_name[len] = 0;
414                 }
415                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_DEV_NAME) {
416                         unsigned int len;
417
418                         if (ynl_attr_validate(yarg, attr))
419                                 return MNL_CB_ERROR;
420
421                         len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
422                         dst->_present.dev_name_len = len;
423                         dst->dev_name = malloc(len + 1);
424                         memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
425                         dst->dev_name[len] = 0;
426                 }
427                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_FAILED) {
428                         if (ynl_attr_validate(yarg, attr))
429                                 return MNL_CB_ERROR;
430                         dst->_present.reload_failed = 1;
431                         dst->reload_failed = mnl_attr_get_u8(attr);
432                 }
433                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION) {
434                         if (ynl_attr_validate(yarg, attr))
435                                 return MNL_CB_ERROR;
436                         dst->_present.reload_action = 1;
437                         dst->reload_action = mnl_attr_get_u8(attr);
438                 }
439                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_DEV_STATS) {
440                         if (ynl_attr_validate(yarg, attr))
441                                 return MNL_CB_ERROR;
442                         dst->_present.dev_stats = 1;
443
444                         parg.rsp_policy = &devlink_dl_dev_stats_nest;
445                         parg.data = &dst->dev_stats;
446                         if (devlink_dl_dev_stats_parse(&parg, attr))
447                                 return MNL_CB_ERROR;
448                 }
449         }
450
451         return MNL_CB_OK;
452 }
453
454 struct devlink_get_rsp *
455 devlink_get(struct ynl_sock *ys, struct devlink_get_req *req)
456 {
457         struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
458         struct devlink_get_rsp *rsp;
459         struct nlmsghdr *nlh;
460         int err;
461
462         nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_GET, 1);
463         ys->req_policy = &devlink_nest;
464         yrs.yarg.rsp_policy = &devlink_nest;
465
466         if (req->_present.bus_name_len)
467                 mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
468         if (req->_present.dev_name_len)
469                 mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
470
471         rsp = calloc(1, sizeof(*rsp));
472         yrs.yarg.data = rsp;
473         yrs.cb = devlink_get_rsp_parse;
474         yrs.rsp_cmd = 3;
475
476         err = ynl_exec(ys, nlh, &yrs);
477         if (err < 0)
478                 goto err_free;
479
480         return rsp;
481
482 err_free:
483         devlink_get_rsp_free(rsp);
484         return NULL;
485 }
486
487 /* DEVLINK_CMD_GET - dump */
488 void devlink_get_list_free(struct devlink_get_list *rsp)
489 {
490         struct devlink_get_list *next = rsp;
491
492         while ((void *)next != YNL_LIST_END) {
493                 rsp = next;
494                 next = rsp->next;
495
496                 free(rsp->obj.bus_name);
497                 free(rsp->obj.dev_name);
498                 devlink_dl_dev_stats_free(&rsp->obj.dev_stats);
499                 free(rsp);
500         }
501 }
502
503 struct devlink_get_list *devlink_get_dump(struct ynl_sock *ys)
504 {
505         struct ynl_dump_state yds = {};
506         struct nlmsghdr *nlh;
507         int err;
508
509         yds.ys = ys;
510         yds.alloc_sz = sizeof(struct devlink_get_list);
511         yds.cb = devlink_get_rsp_parse;
512         yds.rsp_cmd = 3;
513         yds.rsp_policy = &devlink_nest;
514
515         nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_GET, 1);
516
517         err = ynl_exec_dump(ys, nlh, &yds);
518         if (err < 0)
519                 goto free_list;
520
521         return yds.first;
522
523 free_list:
524         devlink_get_list_free(yds.first);
525         return NULL;
526 }
527
528 /* ============== DEVLINK_CMD_INFO_GET ============== */
529 /* DEVLINK_CMD_INFO_GET - do */
530 void devlink_info_get_req_free(struct devlink_info_get_req *req)
531 {
532         free(req->bus_name);
533         free(req->dev_name);
534         free(req);
535 }
536
537 void devlink_info_get_rsp_free(struct devlink_info_get_rsp *rsp)
538 {
539         unsigned int i;
540
541         free(rsp->bus_name);
542         free(rsp->dev_name);
543         free(rsp->info_driver_name);
544         free(rsp->info_serial_number);
545         for (i = 0; i < rsp->n_info_version_fixed; i++)
546                 devlink_dl_info_version_free(&rsp->info_version_fixed[i]);
547         free(rsp->info_version_fixed);
548         for (i = 0; i < rsp->n_info_version_running; i++)
549                 devlink_dl_info_version_free(&rsp->info_version_running[i]);
550         free(rsp->info_version_running);
551         for (i = 0; i < rsp->n_info_version_stored; i++)
552                 devlink_dl_info_version_free(&rsp->info_version_stored[i]);
553         free(rsp->info_version_stored);
554         free(rsp);
555 }
556
557 int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
558 {
559         unsigned int n_info_version_running = 0;
560         unsigned int n_info_version_stored = 0;
561         unsigned int n_info_version_fixed = 0;
562         struct ynl_parse_arg *yarg = data;
563         struct devlink_info_get_rsp *dst;
564         const struct nlattr *attr;
565         struct ynl_parse_arg parg;
566         int i;
567
568         dst = yarg->data;
569         parg.ys = yarg->ys;
570
571         if (dst->info_version_fixed)
572                 return ynl_error_parse(yarg, "attribute already present (devlink.info-version-fixed)");
573         if (dst->info_version_running)
574                 return ynl_error_parse(yarg, "attribute already present (devlink.info-version-running)");
575         if (dst->info_version_stored)
576                 return ynl_error_parse(yarg, "attribute already present (devlink.info-version-stored)");
577
578         mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
579                 if (mnl_attr_get_type(attr) == DEVLINK_ATTR_BUS_NAME) {
580                         unsigned int len;
581
582                         if (ynl_attr_validate(yarg, attr))
583                                 return MNL_CB_ERROR;
584
585                         len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
586                         dst->_present.bus_name_len = len;
587                         dst->bus_name = malloc(len + 1);
588                         memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
589                         dst->bus_name[len] = 0;
590                 }
591                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_DEV_NAME) {
592                         unsigned int len;
593
594                         if (ynl_attr_validate(yarg, attr))
595                                 return MNL_CB_ERROR;
596
597                         len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
598                         dst->_present.dev_name_len = len;
599                         dst->dev_name = malloc(len + 1);
600                         memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
601                         dst->dev_name[len] = 0;
602                 }
603                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_DRIVER_NAME) {
604                         unsigned int len;
605
606                         if (ynl_attr_validate(yarg, attr))
607                                 return MNL_CB_ERROR;
608
609                         len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
610                         dst->_present.info_driver_name_len = len;
611                         dst->info_driver_name = malloc(len + 1);
612                         memcpy(dst->info_driver_name, mnl_attr_get_str(attr), len);
613                         dst->info_driver_name[len] = 0;
614                 }
615                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_SERIAL_NUMBER) {
616                         unsigned int len;
617
618                         if (ynl_attr_validate(yarg, attr))
619                                 return MNL_CB_ERROR;
620
621                         len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
622                         dst->_present.info_serial_number_len = len;
623                         dst->info_serial_number = malloc(len + 1);
624                         memcpy(dst->info_serial_number, mnl_attr_get_str(attr), len);
625                         dst->info_serial_number[len] = 0;
626                 }
627                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) {
628                         n_info_version_fixed++;
629                 }
630                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) {
631                         n_info_version_running++;
632                 }
633                 else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) {
634                         n_info_version_stored++;
635                 }
636         }
637
638         if (n_info_version_fixed) {
639                 dst->info_version_fixed = calloc(n_info_version_fixed, sizeof(*dst->info_version_fixed));
640                 dst->n_info_version_fixed = n_info_version_fixed;
641                 i = 0;
642                 parg.rsp_policy = &devlink_dl_info_version_nest;
643                 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
644                         if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) {
645                                 parg.data = &dst->info_version_fixed[i];
646                                 if (devlink_dl_info_version_parse(&parg, attr))
647                                         return MNL_CB_ERROR;
648                                 i++;
649                         }
650                 }
651         }
652         if (n_info_version_running) {
653                 dst->info_version_running = calloc(n_info_version_running, sizeof(*dst->info_version_running));
654                 dst->n_info_version_running = n_info_version_running;
655                 i = 0;
656                 parg.rsp_policy = &devlink_dl_info_version_nest;
657                 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
658                         if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) {
659                                 parg.data = &dst->info_version_running[i];
660                                 if (devlink_dl_info_version_parse(&parg, attr))
661                                         return MNL_CB_ERROR;
662                                 i++;
663                         }
664                 }
665         }
666         if (n_info_version_stored) {
667                 dst->info_version_stored = calloc(n_info_version_stored, sizeof(*dst->info_version_stored));
668                 dst->n_info_version_stored = n_info_version_stored;
669                 i = 0;
670                 parg.rsp_policy = &devlink_dl_info_version_nest;
671                 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
672                         if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) {
673                                 parg.data = &dst->info_version_stored[i];
674                                 if (devlink_dl_info_version_parse(&parg, attr))
675                                         return MNL_CB_ERROR;
676                                 i++;
677                         }
678                 }
679         }
680
681         return MNL_CB_OK;
682 }
683
684 struct devlink_info_get_rsp *
685 devlink_info_get(struct ynl_sock *ys, struct devlink_info_get_req *req)
686 {
687         struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
688         struct devlink_info_get_rsp *rsp;
689         struct nlmsghdr *nlh;
690         int err;
691
692         nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1);
693         ys->req_policy = &devlink_nest;
694         yrs.yarg.rsp_policy = &devlink_nest;
695
696         if (req->_present.bus_name_len)
697                 mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
698         if (req->_present.dev_name_len)
699                 mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
700
701         rsp = calloc(1, sizeof(*rsp));
702         yrs.yarg.data = rsp;
703         yrs.cb = devlink_info_get_rsp_parse;
704         yrs.rsp_cmd = DEVLINK_CMD_INFO_GET;
705
706         err = ynl_exec(ys, nlh, &yrs);
707         if (err < 0)
708                 goto err_free;
709
710         return rsp;
711
712 err_free:
713         devlink_info_get_rsp_free(rsp);
714         return NULL;
715 }
716
717 const struct ynl_family ynl_devlink_family =  {
718         .name           = "devlink",
719 };