xref: /openbmc/linux/tools/net/ynl/generated/devlink-user.c (revision 7199c86247e9618981a2916900d3fcb83e5df157)
15d1a30ebSJakub Kicinski // SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
25d1a30ebSJakub Kicinski /* Do not edit directly, auto-generated from: */
35d1a30ebSJakub Kicinski /*	Documentation/netlink/specs/devlink.yaml */
45d1a30ebSJakub Kicinski /* YNL-GEN user source */
55d1a30ebSJakub Kicinski 
65d1a30ebSJakub Kicinski #include <stdlib.h>
79b52fd4bSJakub Kicinski #include <string.h>
85d1a30ebSJakub Kicinski #include "devlink-user.h"
95d1a30ebSJakub Kicinski #include "ynl.h"
105d1a30ebSJakub Kicinski #include <linux/devlink.h>
115d1a30ebSJakub Kicinski 
125d1a30ebSJakub Kicinski #include <libmnl/libmnl.h>
135d1a30ebSJakub Kicinski #include <linux/genetlink.h>
145d1a30ebSJakub Kicinski 
155d1a30ebSJakub Kicinski /* Enums */
165d1a30ebSJakub Kicinski static const char * const devlink_op_strmap[] = {
175d1a30ebSJakub Kicinski 	[3] = "get",
18*7199c862SJiri Pirko 	[7] = "port-get",
19*7199c862SJiri Pirko 	[DEVLINK_CMD_SB_GET] = "sb-get",
20*7199c862SJiri Pirko 	[DEVLINK_CMD_SB_POOL_GET] = "sb-pool-get",
21*7199c862SJiri Pirko 	[DEVLINK_CMD_SB_PORT_POOL_GET] = "sb-port-pool-get",
22*7199c862SJiri Pirko 	[DEVLINK_CMD_SB_TC_POOL_BIND_GET] = "sb-tc-pool-bind-get",
23*7199c862SJiri Pirko 	[DEVLINK_CMD_PARAM_GET] = "param-get",
24*7199c862SJiri Pirko 	[DEVLINK_CMD_REGION_GET] = "region-get",
255d1a30ebSJakub Kicinski 	[DEVLINK_CMD_INFO_GET] = "info-get",
26*7199c862SJiri Pirko 	[DEVLINK_CMD_HEALTH_REPORTER_GET] = "health-reporter-get",
27*7199c862SJiri Pirko 	[DEVLINK_CMD_TRAP_GET] = "trap-get",
28*7199c862SJiri Pirko 	[DEVLINK_CMD_TRAP_GROUP_GET] = "trap-group-get",
29*7199c862SJiri Pirko 	[DEVLINK_CMD_TRAP_POLICER_GET] = "trap-policer-get",
30*7199c862SJiri Pirko 	[DEVLINK_CMD_RATE_GET] = "rate-get",
31*7199c862SJiri Pirko 	[DEVLINK_CMD_LINECARD_GET] = "linecard-get",
32*7199c862SJiri Pirko 	[DEVLINK_CMD_SELFTESTS_GET] = "selftests-get",
335d1a30ebSJakub Kicinski };
345d1a30ebSJakub Kicinski 
355d1a30ebSJakub Kicinski const char *devlink_op_str(int op)
365d1a30ebSJakub Kicinski {
375d1a30ebSJakub Kicinski 	if (op < 0 || op >= (int)MNL_ARRAY_SIZE(devlink_op_strmap))
385d1a30ebSJakub Kicinski 		return NULL;
395d1a30ebSJakub Kicinski 	return devlink_op_strmap[op];
405d1a30ebSJakub Kicinski }
415d1a30ebSJakub Kicinski 
42*7199c862SJiri Pirko static const char * const devlink_sb_pool_type_strmap[] = {
43*7199c862SJiri Pirko 	[0] = "ingress",
44*7199c862SJiri Pirko 	[1] = "egress",
45*7199c862SJiri Pirko };
46*7199c862SJiri Pirko 
47*7199c862SJiri Pirko const char *devlink_sb_pool_type_str(enum devlink_sb_pool_type value)
48*7199c862SJiri Pirko {
49*7199c862SJiri Pirko 	if (value < 0 || value >= (int)MNL_ARRAY_SIZE(devlink_sb_pool_type_strmap))
50*7199c862SJiri Pirko 		return NULL;
51*7199c862SJiri Pirko 	return devlink_sb_pool_type_strmap[value];
52*7199c862SJiri Pirko }
53*7199c862SJiri Pirko 
545d1a30ebSJakub Kicinski /* Policies */
555d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_info_version_policy[DEVLINK_ATTR_MAX + 1] = {
565d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, },
575d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, },
585d1a30ebSJakub Kicinski };
595d1a30ebSJakub Kicinski 
605d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_info_version_nest = {
615d1a30ebSJakub Kicinski 	.max_attr = DEVLINK_ATTR_MAX,
625d1a30ebSJakub Kicinski 	.table = devlink_dl_info_version_policy,
635d1a30ebSJakub Kicinski };
645d1a30ebSJakub Kicinski 
655d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_reload_stats_entry_policy[DEVLINK_ATTR_MAX + 1] = {
665d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, },
675d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, },
685d1a30ebSJakub Kicinski };
695d1a30ebSJakub Kicinski 
705d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_reload_stats_entry_nest = {
715d1a30ebSJakub Kicinski 	.max_attr = DEVLINK_ATTR_MAX,
725d1a30ebSJakub Kicinski 	.table = devlink_dl_reload_stats_entry_policy,
735d1a30ebSJakub Kicinski };
745d1a30ebSJakub Kicinski 
755d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_reload_act_stats_policy[DEVLINK_ATTR_MAX + 1] = {
765d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, },
775d1a30ebSJakub Kicinski };
785d1a30ebSJakub Kicinski 
795d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_reload_act_stats_nest = {
805d1a30ebSJakub Kicinski 	.max_attr = DEVLINK_ATTR_MAX,
815d1a30ebSJakub Kicinski 	.table = devlink_dl_reload_act_stats_policy,
825d1a30ebSJakub Kicinski };
835d1a30ebSJakub Kicinski 
845d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_reload_act_info_policy[DEVLINK_ATTR_MAX + 1] = {
855d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, },
865d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, },
875d1a30ebSJakub Kicinski };
885d1a30ebSJakub Kicinski 
895d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_reload_act_info_nest = {
905d1a30ebSJakub Kicinski 	.max_attr = DEVLINK_ATTR_MAX,
915d1a30ebSJakub Kicinski 	.table = devlink_dl_reload_act_info_policy,
925d1a30ebSJakub Kicinski };
935d1a30ebSJakub Kicinski 
945d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_reload_stats_policy[DEVLINK_ATTR_MAX + 1] = {
955d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, },
965d1a30ebSJakub Kicinski };
975d1a30ebSJakub Kicinski 
985d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_reload_stats_nest = {
995d1a30ebSJakub Kicinski 	.max_attr = DEVLINK_ATTR_MAX,
1005d1a30ebSJakub Kicinski 	.table = devlink_dl_reload_stats_policy,
1015d1a30ebSJakub Kicinski };
1025d1a30ebSJakub Kicinski 
1035d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_dev_stats_policy[DEVLINK_ATTR_MAX + 1] = {
1045d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
1055d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
1065d1a30ebSJakub Kicinski };
1075d1a30ebSJakub Kicinski 
1085d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_dev_stats_nest = {
1095d1a30ebSJakub Kicinski 	.max_attr = DEVLINK_ATTR_MAX,
1105d1a30ebSJakub Kicinski 	.table = devlink_dl_dev_stats_policy,
1115d1a30ebSJakub Kicinski };
1125d1a30ebSJakub Kicinski 
1135d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_policy[DEVLINK_ATTR_MAX + 1] = {
1145d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_BUS_NAME] = { .name = "bus-name", .type = YNL_PT_NUL_STR, },
1155d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_DEV_NAME] = { .name = "dev-name", .type = YNL_PT_NUL_STR, },
1165d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_PORT_INDEX] = { .name = "port-index", .type = YNL_PT_U32, },
117*7199c862SJiri Pirko 	[DEVLINK_ATTR_SB_INDEX] = { .name = "sb-index", .type = YNL_PT_U32, },
118*7199c862SJiri Pirko 	[DEVLINK_ATTR_SB_POOL_INDEX] = { .name = "sb-pool-index", .type = YNL_PT_U16, },
119*7199c862SJiri Pirko 	[DEVLINK_ATTR_SB_POOL_TYPE] = { .name = "sb-pool-type", .type = YNL_PT_U8, },
120*7199c862SJiri Pirko 	[DEVLINK_ATTR_SB_TC_INDEX] = { .name = "sb-tc-index", .type = YNL_PT_U16, },
121*7199c862SJiri Pirko 	[DEVLINK_ATTR_PARAM_NAME] = { .name = "param-name", .type = YNL_PT_NUL_STR, },
122*7199c862SJiri Pirko 	[DEVLINK_ATTR_REGION_NAME] = { .name = "region-name", .type = YNL_PT_NUL_STR, },
1235d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_INFO_DRIVER_NAME] = { .name = "info-driver-name", .type = YNL_PT_NUL_STR, },
1245d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_INFO_SERIAL_NUMBER] = { .name = "info-serial-number", .type = YNL_PT_NUL_STR, },
1255d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_INFO_VERSION_FIXED] = { .name = "info-version-fixed", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
1265d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_INFO_VERSION_RUNNING] = { .name = "info-version-running", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
1275d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_INFO_VERSION_STORED] = { .name = "info-version-stored", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, },
1285d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, },
1295d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, },
130*7199c862SJiri Pirko 	[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .name = "health-reporter-name", .type = YNL_PT_NUL_STR, },
131*7199c862SJiri Pirko 	[DEVLINK_ATTR_TRAP_NAME] = { .name = "trap-name", .type = YNL_PT_NUL_STR, },
132*7199c862SJiri Pirko 	[DEVLINK_ATTR_TRAP_GROUP_NAME] = { .name = "trap-group-name", .type = YNL_PT_NUL_STR, },
1335d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_FAILED] = { .name = "reload-failed", .type = YNL_PT_U8, },
134*7199c862SJiri Pirko 	[DEVLINK_ATTR_TRAP_POLICER_ID] = { .name = "trap-policer-id", .type = YNL_PT_U32, },
1355d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, },
1365d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_DEV_STATS] = { .name = "dev-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_dev_stats_nest, },
1375d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
1385d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, },
1395d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, },
1405d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, },
1415d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, },
1425d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, },
1435d1a30ebSJakub Kicinski 	[DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, },
144*7199c862SJiri Pirko 	[DEVLINK_ATTR_RATE_NODE_NAME] = { .name = "rate-node-name", .type = YNL_PT_NUL_STR, },
145*7199c862SJiri Pirko 	[DEVLINK_ATTR_LINECARD_INDEX] = { .name = "linecard-index", .type = YNL_PT_U32, },
1465d1a30ebSJakub Kicinski };
1475d1a30ebSJakub Kicinski 
1485d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_nest = {
1495d1a30ebSJakub Kicinski 	.max_attr = DEVLINK_ATTR_MAX,
1505d1a30ebSJakub Kicinski 	.table = devlink_policy,
1515d1a30ebSJakub Kicinski };
1525d1a30ebSJakub Kicinski 
1535d1a30ebSJakub Kicinski /* Common nested types */
1545d1a30ebSJakub Kicinski void devlink_dl_info_version_free(struct devlink_dl_info_version *obj)
1555d1a30ebSJakub Kicinski {
1565d1a30ebSJakub Kicinski 	free(obj->info_version_name);
1575d1a30ebSJakub Kicinski 	free(obj->info_version_value);
1585d1a30ebSJakub Kicinski }
1595d1a30ebSJakub Kicinski 
1605d1a30ebSJakub Kicinski int devlink_dl_info_version_parse(struct ynl_parse_arg *yarg,
1615d1a30ebSJakub Kicinski 				  const struct nlattr *nested)
1625d1a30ebSJakub Kicinski {
1635d1a30ebSJakub Kicinski 	struct devlink_dl_info_version *dst = yarg->data;
1645d1a30ebSJakub Kicinski 	const struct nlattr *attr;
1655d1a30ebSJakub Kicinski 
1665d1a30ebSJakub Kicinski 	mnl_attr_for_each_nested(attr, nested) {
1677234415bSJakub Kicinski 		unsigned int type = mnl_attr_get_type(attr);
1687234415bSJakub Kicinski 
1697234415bSJakub Kicinski 		if (type == DEVLINK_ATTR_INFO_VERSION_NAME) {
1705d1a30ebSJakub Kicinski 			unsigned int len;
1715d1a30ebSJakub Kicinski 
1725d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
1735d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
1745d1a30ebSJakub Kicinski 
1755d1a30ebSJakub Kicinski 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1765d1a30ebSJakub Kicinski 			dst->_present.info_version_name_len = len;
1775d1a30ebSJakub Kicinski 			dst->info_version_name = malloc(len + 1);
1785d1a30ebSJakub Kicinski 			memcpy(dst->info_version_name, mnl_attr_get_str(attr), len);
1795d1a30ebSJakub Kicinski 			dst->info_version_name[len] = 0;
1807234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_INFO_VERSION_VALUE) {
1815d1a30ebSJakub Kicinski 			unsigned int len;
1825d1a30ebSJakub Kicinski 
1835d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
1845d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
1855d1a30ebSJakub Kicinski 
1865d1a30ebSJakub Kicinski 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1875d1a30ebSJakub Kicinski 			dst->_present.info_version_value_len = len;
1885d1a30ebSJakub Kicinski 			dst->info_version_value = malloc(len + 1);
1895d1a30ebSJakub Kicinski 			memcpy(dst->info_version_value, mnl_attr_get_str(attr), len);
1905d1a30ebSJakub Kicinski 			dst->info_version_value[len] = 0;
1915d1a30ebSJakub Kicinski 		}
1925d1a30ebSJakub Kicinski 	}
1935d1a30ebSJakub Kicinski 
1945d1a30ebSJakub Kicinski 	return 0;
1955d1a30ebSJakub Kicinski }
1965d1a30ebSJakub Kicinski 
1975d1a30ebSJakub Kicinski void
1985d1a30ebSJakub Kicinski devlink_dl_reload_stats_entry_free(struct devlink_dl_reload_stats_entry *obj)
1995d1a30ebSJakub Kicinski {
2005d1a30ebSJakub Kicinski }
2015d1a30ebSJakub Kicinski 
2025d1a30ebSJakub Kicinski int devlink_dl_reload_stats_entry_parse(struct ynl_parse_arg *yarg,
2035d1a30ebSJakub Kicinski 					const struct nlattr *nested)
2045d1a30ebSJakub Kicinski {
2055d1a30ebSJakub Kicinski 	struct devlink_dl_reload_stats_entry *dst = yarg->data;
2065d1a30ebSJakub Kicinski 	const struct nlattr *attr;
2075d1a30ebSJakub Kicinski 
2085d1a30ebSJakub Kicinski 	mnl_attr_for_each_nested(attr, nested) {
2097234415bSJakub Kicinski 		unsigned int type = mnl_attr_get_type(attr);
2107234415bSJakub Kicinski 
2117234415bSJakub Kicinski 		if (type == DEVLINK_ATTR_RELOAD_STATS_LIMIT) {
2125d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
2135d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
2145d1a30ebSJakub Kicinski 			dst->_present.reload_stats_limit = 1;
2155d1a30ebSJakub Kicinski 			dst->reload_stats_limit = mnl_attr_get_u8(attr);
2167234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_RELOAD_STATS_VALUE) {
2175d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
2185d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
2195d1a30ebSJakub Kicinski 			dst->_present.reload_stats_value = 1;
2205d1a30ebSJakub Kicinski 			dst->reload_stats_value = mnl_attr_get_u32(attr);
2215d1a30ebSJakub Kicinski 		}
2225d1a30ebSJakub Kicinski 	}
2235d1a30ebSJakub Kicinski 
2245d1a30ebSJakub Kicinski 	return 0;
2255d1a30ebSJakub Kicinski }
2265d1a30ebSJakub Kicinski 
2275d1a30ebSJakub Kicinski void devlink_dl_reload_act_stats_free(struct devlink_dl_reload_act_stats *obj)
2285d1a30ebSJakub Kicinski {
2295d1a30ebSJakub Kicinski 	unsigned int i;
2305d1a30ebSJakub Kicinski 
2315d1a30ebSJakub Kicinski 	for (i = 0; i < obj->n_reload_stats_entry; i++)
2325d1a30ebSJakub Kicinski 		devlink_dl_reload_stats_entry_free(&obj->reload_stats_entry[i]);
2335d1a30ebSJakub Kicinski 	free(obj->reload_stats_entry);
2345d1a30ebSJakub Kicinski }
2355d1a30ebSJakub Kicinski 
2365d1a30ebSJakub Kicinski int devlink_dl_reload_act_stats_parse(struct ynl_parse_arg *yarg,
2375d1a30ebSJakub Kicinski 				      const struct nlattr *nested)
2385d1a30ebSJakub Kicinski {
2395d1a30ebSJakub Kicinski 	struct devlink_dl_reload_act_stats *dst = yarg->data;
2405d1a30ebSJakub Kicinski 	unsigned int n_reload_stats_entry = 0;
2415d1a30ebSJakub Kicinski 	const struct nlattr *attr;
2425d1a30ebSJakub Kicinski 	struct ynl_parse_arg parg;
2435d1a30ebSJakub Kicinski 	int i;
2445d1a30ebSJakub Kicinski 
2455d1a30ebSJakub Kicinski 	parg.ys = yarg->ys;
2465d1a30ebSJakub Kicinski 
2475d1a30ebSJakub Kicinski 	if (dst->reload_stats_entry)
2485d1a30ebSJakub Kicinski 		return ynl_error_parse(yarg, "attribute already present (dl-reload-act-stats.reload-stats-entry)");
2495d1a30ebSJakub Kicinski 
2505d1a30ebSJakub Kicinski 	mnl_attr_for_each_nested(attr, nested) {
2517234415bSJakub Kicinski 		unsigned int type = mnl_attr_get_type(attr);
2527234415bSJakub Kicinski 
2537234415bSJakub Kicinski 		if (type == DEVLINK_ATTR_RELOAD_STATS_ENTRY) {
2545d1a30ebSJakub Kicinski 			n_reload_stats_entry++;
2555d1a30ebSJakub Kicinski 		}
2565d1a30ebSJakub Kicinski 	}
2575d1a30ebSJakub Kicinski 
2585d1a30ebSJakub Kicinski 	if (n_reload_stats_entry) {
2595d1a30ebSJakub Kicinski 		dst->reload_stats_entry = calloc(n_reload_stats_entry, sizeof(*dst->reload_stats_entry));
2605d1a30ebSJakub Kicinski 		dst->n_reload_stats_entry = n_reload_stats_entry;
2615d1a30ebSJakub Kicinski 		i = 0;
2625d1a30ebSJakub Kicinski 		parg.rsp_policy = &devlink_dl_reload_stats_entry_nest;
2635d1a30ebSJakub Kicinski 		mnl_attr_for_each_nested(attr, nested) {
2645d1a30ebSJakub Kicinski 			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) {
2655d1a30ebSJakub Kicinski 				parg.data = &dst->reload_stats_entry[i];
2665d1a30ebSJakub Kicinski 				if (devlink_dl_reload_stats_entry_parse(&parg, attr))
2675d1a30ebSJakub Kicinski 					return MNL_CB_ERROR;
2685d1a30ebSJakub Kicinski 				i++;
2695d1a30ebSJakub Kicinski 			}
2705d1a30ebSJakub Kicinski 		}
2715d1a30ebSJakub Kicinski 	}
2725d1a30ebSJakub Kicinski 
2735d1a30ebSJakub Kicinski 	return 0;
2745d1a30ebSJakub Kicinski }
2755d1a30ebSJakub Kicinski 
2765d1a30ebSJakub Kicinski void devlink_dl_reload_act_info_free(struct devlink_dl_reload_act_info *obj)
2775d1a30ebSJakub Kicinski {
2785d1a30ebSJakub Kicinski 	unsigned int i;
2795d1a30ebSJakub Kicinski 
2805d1a30ebSJakub Kicinski 	for (i = 0; i < obj->n_reload_action_stats; i++)
2815d1a30ebSJakub Kicinski 		devlink_dl_reload_act_stats_free(&obj->reload_action_stats[i]);
2825d1a30ebSJakub Kicinski 	free(obj->reload_action_stats);
2835d1a30ebSJakub Kicinski }
2845d1a30ebSJakub Kicinski 
2855d1a30ebSJakub Kicinski int devlink_dl_reload_act_info_parse(struct ynl_parse_arg *yarg,
2865d1a30ebSJakub Kicinski 				     const struct nlattr *nested)
2875d1a30ebSJakub Kicinski {
2885d1a30ebSJakub Kicinski 	struct devlink_dl_reload_act_info *dst = yarg->data;
2895d1a30ebSJakub Kicinski 	unsigned int n_reload_action_stats = 0;
2905d1a30ebSJakub Kicinski 	const struct nlattr *attr;
2915d1a30ebSJakub Kicinski 	struct ynl_parse_arg parg;
2925d1a30ebSJakub Kicinski 	int i;
2935d1a30ebSJakub Kicinski 
2945d1a30ebSJakub Kicinski 	parg.ys = yarg->ys;
2955d1a30ebSJakub Kicinski 
2965d1a30ebSJakub Kicinski 	if (dst->reload_action_stats)
2975d1a30ebSJakub Kicinski 		return ynl_error_parse(yarg, "attribute already present (dl-reload-act-info.reload-action-stats)");
2985d1a30ebSJakub Kicinski 
2995d1a30ebSJakub Kicinski 	mnl_attr_for_each_nested(attr, nested) {
3007234415bSJakub Kicinski 		unsigned int type = mnl_attr_get_type(attr);
3017234415bSJakub Kicinski 
3027234415bSJakub Kicinski 		if (type == DEVLINK_ATTR_RELOAD_ACTION) {
3035d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
3045d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
3055d1a30ebSJakub Kicinski 			dst->_present.reload_action = 1;
3065d1a30ebSJakub Kicinski 			dst->reload_action = mnl_attr_get_u8(attr);
3077234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_RELOAD_ACTION_STATS) {
3085d1a30ebSJakub Kicinski 			n_reload_action_stats++;
3095d1a30ebSJakub Kicinski 		}
3105d1a30ebSJakub Kicinski 	}
3115d1a30ebSJakub Kicinski 
3125d1a30ebSJakub Kicinski 	if (n_reload_action_stats) {
3135d1a30ebSJakub Kicinski 		dst->reload_action_stats = calloc(n_reload_action_stats, sizeof(*dst->reload_action_stats));
3145d1a30ebSJakub Kicinski 		dst->n_reload_action_stats = n_reload_action_stats;
3155d1a30ebSJakub Kicinski 		i = 0;
3165d1a30ebSJakub Kicinski 		parg.rsp_policy = &devlink_dl_reload_act_stats_nest;
3175d1a30ebSJakub Kicinski 		mnl_attr_for_each_nested(attr, nested) {
3185d1a30ebSJakub Kicinski 			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) {
3195d1a30ebSJakub Kicinski 				parg.data = &dst->reload_action_stats[i];
3205d1a30ebSJakub Kicinski 				if (devlink_dl_reload_act_stats_parse(&parg, attr))
3215d1a30ebSJakub Kicinski 					return MNL_CB_ERROR;
3225d1a30ebSJakub Kicinski 				i++;
3235d1a30ebSJakub Kicinski 			}
3245d1a30ebSJakub Kicinski 		}
3255d1a30ebSJakub Kicinski 	}
3265d1a30ebSJakub Kicinski 
3275d1a30ebSJakub Kicinski 	return 0;
3285d1a30ebSJakub Kicinski }
3295d1a30ebSJakub Kicinski 
3305d1a30ebSJakub Kicinski void devlink_dl_reload_stats_free(struct devlink_dl_reload_stats *obj)
3315d1a30ebSJakub Kicinski {
3325d1a30ebSJakub Kicinski 	unsigned int i;
3335d1a30ebSJakub Kicinski 
3345d1a30ebSJakub Kicinski 	for (i = 0; i < obj->n_reload_action_info; i++)
3355d1a30ebSJakub Kicinski 		devlink_dl_reload_act_info_free(&obj->reload_action_info[i]);
3365d1a30ebSJakub Kicinski 	free(obj->reload_action_info);
3375d1a30ebSJakub Kicinski }
3385d1a30ebSJakub Kicinski 
3395d1a30ebSJakub Kicinski int devlink_dl_reload_stats_parse(struct ynl_parse_arg *yarg,
3405d1a30ebSJakub Kicinski 				  const struct nlattr *nested)
3415d1a30ebSJakub Kicinski {
3425d1a30ebSJakub Kicinski 	struct devlink_dl_reload_stats *dst = yarg->data;
3435d1a30ebSJakub Kicinski 	unsigned int n_reload_action_info = 0;
3445d1a30ebSJakub Kicinski 	const struct nlattr *attr;
3455d1a30ebSJakub Kicinski 	struct ynl_parse_arg parg;
3465d1a30ebSJakub Kicinski 	int i;
3475d1a30ebSJakub Kicinski 
3485d1a30ebSJakub Kicinski 	parg.ys = yarg->ys;
3495d1a30ebSJakub Kicinski 
3505d1a30ebSJakub Kicinski 	if (dst->reload_action_info)
3515d1a30ebSJakub Kicinski 		return ynl_error_parse(yarg, "attribute already present (dl-reload-stats.reload-action-info)");
3525d1a30ebSJakub Kicinski 
3535d1a30ebSJakub Kicinski 	mnl_attr_for_each_nested(attr, nested) {
3547234415bSJakub Kicinski 		unsigned int type = mnl_attr_get_type(attr);
3557234415bSJakub Kicinski 
3567234415bSJakub Kicinski 		if (type == DEVLINK_ATTR_RELOAD_ACTION_INFO) {
3575d1a30ebSJakub Kicinski 			n_reload_action_info++;
3585d1a30ebSJakub Kicinski 		}
3595d1a30ebSJakub Kicinski 	}
3605d1a30ebSJakub Kicinski 
3615d1a30ebSJakub Kicinski 	if (n_reload_action_info) {
3625d1a30ebSJakub Kicinski 		dst->reload_action_info = calloc(n_reload_action_info, sizeof(*dst->reload_action_info));
3635d1a30ebSJakub Kicinski 		dst->n_reload_action_info = n_reload_action_info;
3645d1a30ebSJakub Kicinski 		i = 0;
3655d1a30ebSJakub Kicinski 		parg.rsp_policy = &devlink_dl_reload_act_info_nest;
3665d1a30ebSJakub Kicinski 		mnl_attr_for_each_nested(attr, nested) {
3675d1a30ebSJakub Kicinski 			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) {
3685d1a30ebSJakub Kicinski 				parg.data = &dst->reload_action_info[i];
3695d1a30ebSJakub Kicinski 				if (devlink_dl_reload_act_info_parse(&parg, attr))
3705d1a30ebSJakub Kicinski 					return MNL_CB_ERROR;
3715d1a30ebSJakub Kicinski 				i++;
3725d1a30ebSJakub Kicinski 			}
3735d1a30ebSJakub Kicinski 		}
3745d1a30ebSJakub Kicinski 	}
3755d1a30ebSJakub Kicinski 
3765d1a30ebSJakub Kicinski 	return 0;
3775d1a30ebSJakub Kicinski }
3785d1a30ebSJakub Kicinski 
3795d1a30ebSJakub Kicinski void devlink_dl_dev_stats_free(struct devlink_dl_dev_stats *obj)
3805d1a30ebSJakub Kicinski {
3815d1a30ebSJakub Kicinski 	devlink_dl_reload_stats_free(&obj->reload_stats);
3825d1a30ebSJakub Kicinski 	devlink_dl_reload_stats_free(&obj->remote_reload_stats);
3835d1a30ebSJakub Kicinski }
3845d1a30ebSJakub Kicinski 
3855d1a30ebSJakub Kicinski int devlink_dl_dev_stats_parse(struct ynl_parse_arg *yarg,
3865d1a30ebSJakub Kicinski 			       const struct nlattr *nested)
3875d1a30ebSJakub Kicinski {
3885d1a30ebSJakub Kicinski 	struct devlink_dl_dev_stats *dst = yarg->data;
3895d1a30ebSJakub Kicinski 	const struct nlattr *attr;
3905d1a30ebSJakub Kicinski 	struct ynl_parse_arg parg;
3915d1a30ebSJakub Kicinski 
3925d1a30ebSJakub Kicinski 	parg.ys = yarg->ys;
3935d1a30ebSJakub Kicinski 
3945d1a30ebSJakub Kicinski 	mnl_attr_for_each_nested(attr, nested) {
3957234415bSJakub Kicinski 		unsigned int type = mnl_attr_get_type(attr);
3967234415bSJakub Kicinski 
3977234415bSJakub Kicinski 		if (type == DEVLINK_ATTR_RELOAD_STATS) {
3985d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
3995d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4005d1a30ebSJakub Kicinski 			dst->_present.reload_stats = 1;
4015d1a30ebSJakub Kicinski 
4025d1a30ebSJakub Kicinski 			parg.rsp_policy = &devlink_dl_reload_stats_nest;
4035d1a30ebSJakub Kicinski 			parg.data = &dst->reload_stats;
4045d1a30ebSJakub Kicinski 			if (devlink_dl_reload_stats_parse(&parg, attr))
4055d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4067234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_REMOTE_RELOAD_STATS) {
4075d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
4085d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4095d1a30ebSJakub Kicinski 			dst->_present.remote_reload_stats = 1;
4105d1a30ebSJakub Kicinski 
4115d1a30ebSJakub Kicinski 			parg.rsp_policy = &devlink_dl_reload_stats_nest;
4125d1a30ebSJakub Kicinski 			parg.data = &dst->remote_reload_stats;
4135d1a30ebSJakub Kicinski 			if (devlink_dl_reload_stats_parse(&parg, attr))
4145d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4155d1a30ebSJakub Kicinski 		}
4165d1a30ebSJakub Kicinski 	}
4175d1a30ebSJakub Kicinski 
4185d1a30ebSJakub Kicinski 	return 0;
4195d1a30ebSJakub Kicinski }
4205d1a30ebSJakub Kicinski 
4215d1a30ebSJakub Kicinski /* ============== DEVLINK_CMD_GET ============== */
4225d1a30ebSJakub Kicinski /* DEVLINK_CMD_GET - do */
4235d1a30ebSJakub Kicinski void devlink_get_req_free(struct devlink_get_req *req)
4245d1a30ebSJakub Kicinski {
4255d1a30ebSJakub Kicinski 	free(req->bus_name);
4265d1a30ebSJakub Kicinski 	free(req->dev_name);
4275d1a30ebSJakub Kicinski 	free(req);
4285d1a30ebSJakub Kicinski }
4295d1a30ebSJakub Kicinski 
4305d1a30ebSJakub Kicinski void devlink_get_rsp_free(struct devlink_get_rsp *rsp)
4315d1a30ebSJakub Kicinski {
4325d1a30ebSJakub Kicinski 	free(rsp->bus_name);
4335d1a30ebSJakub Kicinski 	free(rsp->dev_name);
4345d1a30ebSJakub Kicinski 	devlink_dl_dev_stats_free(&rsp->dev_stats);
4355d1a30ebSJakub Kicinski 	free(rsp);
4365d1a30ebSJakub Kicinski }
4375d1a30ebSJakub Kicinski 
4385d1a30ebSJakub Kicinski int devlink_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
4395d1a30ebSJakub Kicinski {
4405d1a30ebSJakub Kicinski 	struct ynl_parse_arg *yarg = data;
4415d1a30ebSJakub Kicinski 	struct devlink_get_rsp *dst;
4425d1a30ebSJakub Kicinski 	const struct nlattr *attr;
4435d1a30ebSJakub Kicinski 	struct ynl_parse_arg parg;
4445d1a30ebSJakub Kicinski 
4455d1a30ebSJakub Kicinski 	dst = yarg->data;
4465d1a30ebSJakub Kicinski 	parg.ys = yarg->ys;
4475d1a30ebSJakub Kicinski 
4485d1a30ebSJakub Kicinski 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
4497234415bSJakub Kicinski 		unsigned int type = mnl_attr_get_type(attr);
4507234415bSJakub Kicinski 
4517234415bSJakub Kicinski 		if (type == DEVLINK_ATTR_BUS_NAME) {
4525d1a30ebSJakub Kicinski 			unsigned int len;
4535d1a30ebSJakub Kicinski 
4545d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
4555d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4565d1a30ebSJakub Kicinski 
4575d1a30ebSJakub Kicinski 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
4585d1a30ebSJakub Kicinski 			dst->_present.bus_name_len = len;
4595d1a30ebSJakub Kicinski 			dst->bus_name = malloc(len + 1);
4605d1a30ebSJakub Kicinski 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
4615d1a30ebSJakub Kicinski 			dst->bus_name[len] = 0;
4627234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
4635d1a30ebSJakub Kicinski 			unsigned int len;
4645d1a30ebSJakub Kicinski 
4655d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
4665d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4675d1a30ebSJakub Kicinski 
4685d1a30ebSJakub Kicinski 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
4695d1a30ebSJakub Kicinski 			dst->_present.dev_name_len = len;
4705d1a30ebSJakub Kicinski 			dst->dev_name = malloc(len + 1);
4715d1a30ebSJakub Kicinski 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
4725d1a30ebSJakub Kicinski 			dst->dev_name[len] = 0;
4737234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_RELOAD_FAILED) {
4745d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
4755d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4765d1a30ebSJakub Kicinski 			dst->_present.reload_failed = 1;
4775d1a30ebSJakub Kicinski 			dst->reload_failed = mnl_attr_get_u8(attr);
4787234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_RELOAD_ACTION) {
4795d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
4805d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4815d1a30ebSJakub Kicinski 			dst->_present.reload_action = 1;
4825d1a30ebSJakub Kicinski 			dst->reload_action = mnl_attr_get_u8(attr);
4837234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_DEV_STATS) {
4845d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
4855d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4865d1a30ebSJakub Kicinski 			dst->_present.dev_stats = 1;
4875d1a30ebSJakub Kicinski 
4885d1a30ebSJakub Kicinski 			parg.rsp_policy = &devlink_dl_dev_stats_nest;
4895d1a30ebSJakub Kicinski 			parg.data = &dst->dev_stats;
4905d1a30ebSJakub Kicinski 			if (devlink_dl_dev_stats_parse(&parg, attr))
4915d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
4925d1a30ebSJakub Kicinski 		}
4935d1a30ebSJakub Kicinski 	}
4945d1a30ebSJakub Kicinski 
4955d1a30ebSJakub Kicinski 	return MNL_CB_OK;
4965d1a30ebSJakub Kicinski }
4975d1a30ebSJakub Kicinski 
4985d1a30ebSJakub Kicinski struct devlink_get_rsp *
4995d1a30ebSJakub Kicinski devlink_get(struct ynl_sock *ys, struct devlink_get_req *req)
5005d1a30ebSJakub Kicinski {
5015d1a30ebSJakub Kicinski 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
5025d1a30ebSJakub Kicinski 	struct devlink_get_rsp *rsp;
5035d1a30ebSJakub Kicinski 	struct nlmsghdr *nlh;
5045d1a30ebSJakub Kicinski 	int err;
5055d1a30ebSJakub Kicinski 
5065d1a30ebSJakub Kicinski 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_GET, 1);
5075d1a30ebSJakub Kicinski 	ys->req_policy = &devlink_nest;
5085d1a30ebSJakub Kicinski 	yrs.yarg.rsp_policy = &devlink_nest;
5095d1a30ebSJakub Kicinski 
5105d1a30ebSJakub Kicinski 	if (req->_present.bus_name_len)
5115d1a30ebSJakub Kicinski 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
5125d1a30ebSJakub Kicinski 	if (req->_present.dev_name_len)
5135d1a30ebSJakub Kicinski 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
5145d1a30ebSJakub Kicinski 
5155d1a30ebSJakub Kicinski 	rsp = calloc(1, sizeof(*rsp));
5165d1a30ebSJakub Kicinski 	yrs.yarg.data = rsp;
5175d1a30ebSJakub Kicinski 	yrs.cb = devlink_get_rsp_parse;
5185d1a30ebSJakub Kicinski 	yrs.rsp_cmd = 3;
5195d1a30ebSJakub Kicinski 
5205d1a30ebSJakub Kicinski 	err = ynl_exec(ys, nlh, &yrs);
5215d1a30ebSJakub Kicinski 	if (err < 0)
5225d1a30ebSJakub Kicinski 		goto err_free;
5235d1a30ebSJakub Kicinski 
5245d1a30ebSJakub Kicinski 	return rsp;
5255d1a30ebSJakub Kicinski 
5265d1a30ebSJakub Kicinski err_free:
5275d1a30ebSJakub Kicinski 	devlink_get_rsp_free(rsp);
5285d1a30ebSJakub Kicinski 	return NULL;
5295d1a30ebSJakub Kicinski }
5305d1a30ebSJakub Kicinski 
5315d1a30ebSJakub Kicinski /* DEVLINK_CMD_GET - dump */
5325d1a30ebSJakub Kicinski void devlink_get_list_free(struct devlink_get_list *rsp)
5335d1a30ebSJakub Kicinski {
5345d1a30ebSJakub Kicinski 	struct devlink_get_list *next = rsp;
5355d1a30ebSJakub Kicinski 
5365d1a30ebSJakub Kicinski 	while ((void *)next != YNL_LIST_END) {
5375d1a30ebSJakub Kicinski 		rsp = next;
5385d1a30ebSJakub Kicinski 		next = rsp->next;
5395d1a30ebSJakub Kicinski 
5405d1a30ebSJakub Kicinski 		free(rsp->obj.bus_name);
5415d1a30ebSJakub Kicinski 		free(rsp->obj.dev_name);
5425d1a30ebSJakub Kicinski 		devlink_dl_dev_stats_free(&rsp->obj.dev_stats);
5435d1a30ebSJakub Kicinski 		free(rsp);
5445d1a30ebSJakub Kicinski 	}
5455d1a30ebSJakub Kicinski }
5465d1a30ebSJakub Kicinski 
5475d1a30ebSJakub Kicinski struct devlink_get_list *devlink_get_dump(struct ynl_sock *ys)
5485d1a30ebSJakub Kicinski {
5495d1a30ebSJakub Kicinski 	struct ynl_dump_state yds = {};
5505d1a30ebSJakub Kicinski 	struct nlmsghdr *nlh;
5515d1a30ebSJakub Kicinski 	int err;
5525d1a30ebSJakub Kicinski 
5535d1a30ebSJakub Kicinski 	yds.ys = ys;
5545d1a30ebSJakub Kicinski 	yds.alloc_sz = sizeof(struct devlink_get_list);
5555d1a30ebSJakub Kicinski 	yds.cb = devlink_get_rsp_parse;
5565d1a30ebSJakub Kicinski 	yds.rsp_cmd = 3;
5575d1a30ebSJakub Kicinski 	yds.rsp_policy = &devlink_nest;
5585d1a30ebSJakub Kicinski 
5595d1a30ebSJakub Kicinski 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_GET, 1);
5605d1a30ebSJakub Kicinski 
5615d1a30ebSJakub Kicinski 	err = ynl_exec_dump(ys, nlh, &yds);
5625d1a30ebSJakub Kicinski 	if (err < 0)
5635d1a30ebSJakub Kicinski 		goto free_list;
5645d1a30ebSJakub Kicinski 
5655d1a30ebSJakub Kicinski 	return yds.first;
5665d1a30ebSJakub Kicinski 
5675d1a30ebSJakub Kicinski free_list:
5685d1a30ebSJakub Kicinski 	devlink_get_list_free(yds.first);
5695d1a30ebSJakub Kicinski 	return NULL;
5705d1a30ebSJakub Kicinski }
5715d1a30ebSJakub Kicinski 
572*7199c862SJiri Pirko /* ============== DEVLINK_CMD_PORT_GET ============== */
573*7199c862SJiri Pirko /* DEVLINK_CMD_PORT_GET - do */
574*7199c862SJiri Pirko void devlink_port_get_req_free(struct devlink_port_get_req *req)
575*7199c862SJiri Pirko {
576*7199c862SJiri Pirko 	free(req->bus_name);
577*7199c862SJiri Pirko 	free(req->dev_name);
578*7199c862SJiri Pirko 	free(req);
579*7199c862SJiri Pirko }
580*7199c862SJiri Pirko 
581*7199c862SJiri Pirko void devlink_port_get_rsp_free(struct devlink_port_get_rsp *rsp)
582*7199c862SJiri Pirko {
583*7199c862SJiri Pirko 	free(rsp->bus_name);
584*7199c862SJiri Pirko 	free(rsp->dev_name);
585*7199c862SJiri Pirko 	free(rsp);
586*7199c862SJiri Pirko }
587*7199c862SJiri Pirko 
588*7199c862SJiri Pirko int devlink_port_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
589*7199c862SJiri Pirko {
590*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
591*7199c862SJiri Pirko 	struct devlink_port_get_rsp *dst;
592*7199c862SJiri Pirko 	const struct nlattr *attr;
593*7199c862SJiri Pirko 
594*7199c862SJiri Pirko 	dst = yarg->data;
595*7199c862SJiri Pirko 
596*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
597*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
598*7199c862SJiri Pirko 
599*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
600*7199c862SJiri Pirko 			unsigned int len;
601*7199c862SJiri Pirko 
602*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
603*7199c862SJiri Pirko 				return MNL_CB_ERROR;
604*7199c862SJiri Pirko 
605*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
606*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
607*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
608*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
609*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
610*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
611*7199c862SJiri Pirko 			unsigned int len;
612*7199c862SJiri Pirko 
613*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
614*7199c862SJiri Pirko 				return MNL_CB_ERROR;
615*7199c862SJiri Pirko 
616*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
617*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
618*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
619*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
620*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
621*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
622*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
623*7199c862SJiri Pirko 				return MNL_CB_ERROR;
624*7199c862SJiri Pirko 			dst->_present.port_index = 1;
625*7199c862SJiri Pirko 			dst->port_index = mnl_attr_get_u32(attr);
626*7199c862SJiri Pirko 		}
627*7199c862SJiri Pirko 	}
628*7199c862SJiri Pirko 
629*7199c862SJiri Pirko 	return MNL_CB_OK;
630*7199c862SJiri Pirko }
631*7199c862SJiri Pirko 
632*7199c862SJiri Pirko struct devlink_port_get_rsp *
633*7199c862SJiri Pirko devlink_port_get(struct ynl_sock *ys, struct devlink_port_get_req *req)
634*7199c862SJiri Pirko {
635*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
636*7199c862SJiri Pirko 	struct devlink_port_get_rsp *rsp;
637*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
638*7199c862SJiri Pirko 	int err;
639*7199c862SJiri Pirko 
640*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_GET, 1);
641*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
642*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
643*7199c862SJiri Pirko 
644*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
645*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
646*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
647*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
648*7199c862SJiri Pirko 	if (req->_present.port_index)
649*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
650*7199c862SJiri Pirko 
651*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
652*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
653*7199c862SJiri Pirko 	yrs.cb = devlink_port_get_rsp_parse;
654*7199c862SJiri Pirko 	yrs.rsp_cmd = 7;
655*7199c862SJiri Pirko 
656*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
657*7199c862SJiri Pirko 	if (err < 0)
658*7199c862SJiri Pirko 		goto err_free;
659*7199c862SJiri Pirko 
660*7199c862SJiri Pirko 	return rsp;
661*7199c862SJiri Pirko 
662*7199c862SJiri Pirko err_free:
663*7199c862SJiri Pirko 	devlink_port_get_rsp_free(rsp);
664*7199c862SJiri Pirko 	return NULL;
665*7199c862SJiri Pirko }
666*7199c862SJiri Pirko 
667*7199c862SJiri Pirko /* DEVLINK_CMD_PORT_GET - dump */
668*7199c862SJiri Pirko int devlink_port_get_rsp_dump_parse(const struct nlmsghdr *nlh, void *data)
669*7199c862SJiri Pirko {
670*7199c862SJiri Pirko 	struct devlink_port_get_rsp_dump *dst;
671*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
672*7199c862SJiri Pirko 	const struct nlattr *attr;
673*7199c862SJiri Pirko 
674*7199c862SJiri Pirko 	dst = yarg->data;
675*7199c862SJiri Pirko 
676*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
677*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
678*7199c862SJiri Pirko 
679*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
680*7199c862SJiri Pirko 			unsigned int len;
681*7199c862SJiri Pirko 
682*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
683*7199c862SJiri Pirko 				return MNL_CB_ERROR;
684*7199c862SJiri Pirko 
685*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
686*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
687*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
688*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
689*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
690*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
691*7199c862SJiri Pirko 			unsigned int len;
692*7199c862SJiri Pirko 
693*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
694*7199c862SJiri Pirko 				return MNL_CB_ERROR;
695*7199c862SJiri Pirko 
696*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
697*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
698*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
699*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
700*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
701*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
702*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
703*7199c862SJiri Pirko 				return MNL_CB_ERROR;
704*7199c862SJiri Pirko 			dst->_present.port_index = 1;
705*7199c862SJiri Pirko 			dst->port_index = mnl_attr_get_u32(attr);
706*7199c862SJiri Pirko 		}
707*7199c862SJiri Pirko 	}
708*7199c862SJiri Pirko 
709*7199c862SJiri Pirko 	return MNL_CB_OK;
710*7199c862SJiri Pirko }
711*7199c862SJiri Pirko 
712*7199c862SJiri Pirko void devlink_port_get_rsp_list_free(struct devlink_port_get_rsp_list *rsp)
713*7199c862SJiri Pirko {
714*7199c862SJiri Pirko 	struct devlink_port_get_rsp_list *next = rsp;
715*7199c862SJiri Pirko 
716*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
717*7199c862SJiri Pirko 		rsp = next;
718*7199c862SJiri Pirko 		next = rsp->next;
719*7199c862SJiri Pirko 
720*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
721*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
722*7199c862SJiri Pirko 		free(rsp);
723*7199c862SJiri Pirko 	}
724*7199c862SJiri Pirko }
725*7199c862SJiri Pirko 
726*7199c862SJiri Pirko struct devlink_port_get_rsp_list *devlink_port_get_dump(struct ynl_sock *ys)
727*7199c862SJiri Pirko {
728*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
729*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
730*7199c862SJiri Pirko 	int err;
731*7199c862SJiri Pirko 
732*7199c862SJiri Pirko 	yds.ys = ys;
733*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_port_get_rsp_list);
734*7199c862SJiri Pirko 	yds.cb = devlink_port_get_rsp_dump_parse;
735*7199c862SJiri Pirko 	yds.rsp_cmd = 7;
736*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
737*7199c862SJiri Pirko 
738*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_PORT_GET, 1);
739*7199c862SJiri Pirko 
740*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
741*7199c862SJiri Pirko 	if (err < 0)
742*7199c862SJiri Pirko 		goto free_list;
743*7199c862SJiri Pirko 
744*7199c862SJiri Pirko 	return yds.first;
745*7199c862SJiri Pirko 
746*7199c862SJiri Pirko free_list:
747*7199c862SJiri Pirko 	devlink_port_get_rsp_list_free(yds.first);
748*7199c862SJiri Pirko 	return NULL;
749*7199c862SJiri Pirko }
750*7199c862SJiri Pirko 
751*7199c862SJiri Pirko /* ============== DEVLINK_CMD_SB_GET ============== */
752*7199c862SJiri Pirko /* DEVLINK_CMD_SB_GET - do */
753*7199c862SJiri Pirko void devlink_sb_get_req_free(struct devlink_sb_get_req *req)
754*7199c862SJiri Pirko {
755*7199c862SJiri Pirko 	free(req->bus_name);
756*7199c862SJiri Pirko 	free(req->dev_name);
757*7199c862SJiri Pirko 	free(req);
758*7199c862SJiri Pirko }
759*7199c862SJiri Pirko 
760*7199c862SJiri Pirko void devlink_sb_get_rsp_free(struct devlink_sb_get_rsp *rsp)
761*7199c862SJiri Pirko {
762*7199c862SJiri Pirko 	free(rsp->bus_name);
763*7199c862SJiri Pirko 	free(rsp->dev_name);
764*7199c862SJiri Pirko 	free(rsp);
765*7199c862SJiri Pirko }
766*7199c862SJiri Pirko 
767*7199c862SJiri Pirko int devlink_sb_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
768*7199c862SJiri Pirko {
769*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
770*7199c862SJiri Pirko 	struct devlink_sb_get_rsp *dst;
771*7199c862SJiri Pirko 	const struct nlattr *attr;
772*7199c862SJiri Pirko 
773*7199c862SJiri Pirko 	dst = yarg->data;
774*7199c862SJiri Pirko 
775*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
776*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
777*7199c862SJiri Pirko 
778*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
779*7199c862SJiri Pirko 			unsigned int len;
780*7199c862SJiri Pirko 
781*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
782*7199c862SJiri Pirko 				return MNL_CB_ERROR;
783*7199c862SJiri Pirko 
784*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
785*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
786*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
787*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
788*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
789*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
790*7199c862SJiri Pirko 			unsigned int len;
791*7199c862SJiri Pirko 
792*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
793*7199c862SJiri Pirko 				return MNL_CB_ERROR;
794*7199c862SJiri Pirko 
795*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
796*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
797*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
798*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
799*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
800*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_SB_INDEX) {
801*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
802*7199c862SJiri Pirko 				return MNL_CB_ERROR;
803*7199c862SJiri Pirko 			dst->_present.sb_index = 1;
804*7199c862SJiri Pirko 			dst->sb_index = mnl_attr_get_u32(attr);
805*7199c862SJiri Pirko 		}
806*7199c862SJiri Pirko 	}
807*7199c862SJiri Pirko 
808*7199c862SJiri Pirko 	return MNL_CB_OK;
809*7199c862SJiri Pirko }
810*7199c862SJiri Pirko 
811*7199c862SJiri Pirko struct devlink_sb_get_rsp *
812*7199c862SJiri Pirko devlink_sb_get(struct ynl_sock *ys, struct devlink_sb_get_req *req)
813*7199c862SJiri Pirko {
814*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
815*7199c862SJiri Pirko 	struct devlink_sb_get_rsp *rsp;
816*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
817*7199c862SJiri Pirko 	int err;
818*7199c862SJiri Pirko 
819*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_GET, 1);
820*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
821*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
822*7199c862SJiri Pirko 
823*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
824*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
825*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
826*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
827*7199c862SJiri Pirko 	if (req->_present.sb_index)
828*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index);
829*7199c862SJiri Pirko 
830*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
831*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
832*7199c862SJiri Pirko 	yrs.cb = devlink_sb_get_rsp_parse;
833*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_SB_GET;
834*7199c862SJiri Pirko 
835*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
836*7199c862SJiri Pirko 	if (err < 0)
837*7199c862SJiri Pirko 		goto err_free;
838*7199c862SJiri Pirko 
839*7199c862SJiri Pirko 	return rsp;
840*7199c862SJiri Pirko 
841*7199c862SJiri Pirko err_free:
842*7199c862SJiri Pirko 	devlink_sb_get_rsp_free(rsp);
843*7199c862SJiri Pirko 	return NULL;
844*7199c862SJiri Pirko }
845*7199c862SJiri Pirko 
846*7199c862SJiri Pirko /* DEVLINK_CMD_SB_GET - dump */
847*7199c862SJiri Pirko void devlink_sb_get_list_free(struct devlink_sb_get_list *rsp)
848*7199c862SJiri Pirko {
849*7199c862SJiri Pirko 	struct devlink_sb_get_list *next = rsp;
850*7199c862SJiri Pirko 
851*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
852*7199c862SJiri Pirko 		rsp = next;
853*7199c862SJiri Pirko 		next = rsp->next;
854*7199c862SJiri Pirko 
855*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
856*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
857*7199c862SJiri Pirko 		free(rsp);
858*7199c862SJiri Pirko 	}
859*7199c862SJiri Pirko }
860*7199c862SJiri Pirko 
861*7199c862SJiri Pirko struct devlink_sb_get_list *devlink_sb_get_dump(struct ynl_sock *ys)
862*7199c862SJiri Pirko {
863*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
864*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
865*7199c862SJiri Pirko 	int err;
866*7199c862SJiri Pirko 
867*7199c862SJiri Pirko 	yds.ys = ys;
868*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_sb_get_list);
869*7199c862SJiri Pirko 	yds.cb = devlink_sb_get_rsp_parse;
870*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_SB_GET;
871*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
872*7199c862SJiri Pirko 
873*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_GET, 1);
874*7199c862SJiri Pirko 
875*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
876*7199c862SJiri Pirko 	if (err < 0)
877*7199c862SJiri Pirko 		goto free_list;
878*7199c862SJiri Pirko 
879*7199c862SJiri Pirko 	return yds.first;
880*7199c862SJiri Pirko 
881*7199c862SJiri Pirko free_list:
882*7199c862SJiri Pirko 	devlink_sb_get_list_free(yds.first);
883*7199c862SJiri Pirko 	return NULL;
884*7199c862SJiri Pirko }
885*7199c862SJiri Pirko 
886*7199c862SJiri Pirko /* ============== DEVLINK_CMD_SB_POOL_GET ============== */
887*7199c862SJiri Pirko /* DEVLINK_CMD_SB_POOL_GET - do */
888*7199c862SJiri Pirko void devlink_sb_pool_get_req_free(struct devlink_sb_pool_get_req *req)
889*7199c862SJiri Pirko {
890*7199c862SJiri Pirko 	free(req->bus_name);
891*7199c862SJiri Pirko 	free(req->dev_name);
892*7199c862SJiri Pirko 	free(req);
893*7199c862SJiri Pirko }
894*7199c862SJiri Pirko 
895*7199c862SJiri Pirko void devlink_sb_pool_get_rsp_free(struct devlink_sb_pool_get_rsp *rsp)
896*7199c862SJiri Pirko {
897*7199c862SJiri Pirko 	free(rsp->bus_name);
898*7199c862SJiri Pirko 	free(rsp->dev_name);
899*7199c862SJiri Pirko 	free(rsp);
900*7199c862SJiri Pirko }
901*7199c862SJiri Pirko 
902*7199c862SJiri Pirko int devlink_sb_pool_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
903*7199c862SJiri Pirko {
904*7199c862SJiri Pirko 	struct devlink_sb_pool_get_rsp *dst;
905*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
906*7199c862SJiri Pirko 	const struct nlattr *attr;
907*7199c862SJiri Pirko 
908*7199c862SJiri Pirko 	dst = yarg->data;
909*7199c862SJiri Pirko 
910*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
911*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
912*7199c862SJiri Pirko 
913*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
914*7199c862SJiri Pirko 			unsigned int len;
915*7199c862SJiri Pirko 
916*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
917*7199c862SJiri Pirko 				return MNL_CB_ERROR;
918*7199c862SJiri Pirko 
919*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
920*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
921*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
922*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
923*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
924*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
925*7199c862SJiri Pirko 			unsigned int len;
926*7199c862SJiri Pirko 
927*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
928*7199c862SJiri Pirko 				return MNL_CB_ERROR;
929*7199c862SJiri Pirko 
930*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
931*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
932*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
933*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
934*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
935*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_SB_INDEX) {
936*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
937*7199c862SJiri Pirko 				return MNL_CB_ERROR;
938*7199c862SJiri Pirko 			dst->_present.sb_index = 1;
939*7199c862SJiri Pirko 			dst->sb_index = mnl_attr_get_u32(attr);
940*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_SB_POOL_INDEX) {
941*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
942*7199c862SJiri Pirko 				return MNL_CB_ERROR;
943*7199c862SJiri Pirko 			dst->_present.sb_pool_index = 1;
944*7199c862SJiri Pirko 			dst->sb_pool_index = mnl_attr_get_u16(attr);
945*7199c862SJiri Pirko 		}
946*7199c862SJiri Pirko 	}
947*7199c862SJiri Pirko 
948*7199c862SJiri Pirko 	return MNL_CB_OK;
949*7199c862SJiri Pirko }
950*7199c862SJiri Pirko 
951*7199c862SJiri Pirko struct devlink_sb_pool_get_rsp *
952*7199c862SJiri Pirko devlink_sb_pool_get(struct ynl_sock *ys, struct devlink_sb_pool_get_req *req)
953*7199c862SJiri Pirko {
954*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
955*7199c862SJiri Pirko 	struct devlink_sb_pool_get_rsp *rsp;
956*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
957*7199c862SJiri Pirko 	int err;
958*7199c862SJiri Pirko 
959*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_POOL_GET, 1);
960*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
961*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
962*7199c862SJiri Pirko 
963*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
964*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
965*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
966*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
967*7199c862SJiri Pirko 	if (req->_present.sb_index)
968*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index);
969*7199c862SJiri Pirko 	if (req->_present.sb_pool_index)
970*7199c862SJiri Pirko 		mnl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX, req->sb_pool_index);
971*7199c862SJiri Pirko 
972*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
973*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
974*7199c862SJiri Pirko 	yrs.cb = devlink_sb_pool_get_rsp_parse;
975*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_SB_POOL_GET;
976*7199c862SJiri Pirko 
977*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
978*7199c862SJiri Pirko 	if (err < 0)
979*7199c862SJiri Pirko 		goto err_free;
980*7199c862SJiri Pirko 
981*7199c862SJiri Pirko 	return rsp;
982*7199c862SJiri Pirko 
983*7199c862SJiri Pirko err_free:
984*7199c862SJiri Pirko 	devlink_sb_pool_get_rsp_free(rsp);
985*7199c862SJiri Pirko 	return NULL;
986*7199c862SJiri Pirko }
987*7199c862SJiri Pirko 
988*7199c862SJiri Pirko /* DEVLINK_CMD_SB_POOL_GET - dump */
989*7199c862SJiri Pirko void devlink_sb_pool_get_list_free(struct devlink_sb_pool_get_list *rsp)
990*7199c862SJiri Pirko {
991*7199c862SJiri Pirko 	struct devlink_sb_pool_get_list *next = rsp;
992*7199c862SJiri Pirko 
993*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
994*7199c862SJiri Pirko 		rsp = next;
995*7199c862SJiri Pirko 		next = rsp->next;
996*7199c862SJiri Pirko 
997*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
998*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
999*7199c862SJiri Pirko 		free(rsp);
1000*7199c862SJiri Pirko 	}
1001*7199c862SJiri Pirko }
1002*7199c862SJiri Pirko 
1003*7199c862SJiri Pirko struct devlink_sb_pool_get_list *devlink_sb_pool_get_dump(struct ynl_sock *ys)
1004*7199c862SJiri Pirko {
1005*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
1006*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1007*7199c862SJiri Pirko 	int err;
1008*7199c862SJiri Pirko 
1009*7199c862SJiri Pirko 	yds.ys = ys;
1010*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_sb_pool_get_list);
1011*7199c862SJiri Pirko 	yds.cb = devlink_sb_pool_get_rsp_parse;
1012*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_SB_POOL_GET;
1013*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
1014*7199c862SJiri Pirko 
1015*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_POOL_GET, 1);
1016*7199c862SJiri Pirko 
1017*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
1018*7199c862SJiri Pirko 	if (err < 0)
1019*7199c862SJiri Pirko 		goto free_list;
1020*7199c862SJiri Pirko 
1021*7199c862SJiri Pirko 	return yds.first;
1022*7199c862SJiri Pirko 
1023*7199c862SJiri Pirko free_list:
1024*7199c862SJiri Pirko 	devlink_sb_pool_get_list_free(yds.first);
1025*7199c862SJiri Pirko 	return NULL;
1026*7199c862SJiri Pirko }
1027*7199c862SJiri Pirko 
1028*7199c862SJiri Pirko /* ============== DEVLINK_CMD_SB_PORT_POOL_GET ============== */
1029*7199c862SJiri Pirko /* DEVLINK_CMD_SB_PORT_POOL_GET - do */
1030*7199c862SJiri Pirko void
1031*7199c862SJiri Pirko devlink_sb_port_pool_get_req_free(struct devlink_sb_port_pool_get_req *req)
1032*7199c862SJiri Pirko {
1033*7199c862SJiri Pirko 	free(req->bus_name);
1034*7199c862SJiri Pirko 	free(req->dev_name);
1035*7199c862SJiri Pirko 	free(req);
1036*7199c862SJiri Pirko }
1037*7199c862SJiri Pirko 
1038*7199c862SJiri Pirko void
1039*7199c862SJiri Pirko devlink_sb_port_pool_get_rsp_free(struct devlink_sb_port_pool_get_rsp *rsp)
1040*7199c862SJiri Pirko {
1041*7199c862SJiri Pirko 	free(rsp->bus_name);
1042*7199c862SJiri Pirko 	free(rsp->dev_name);
1043*7199c862SJiri Pirko 	free(rsp);
1044*7199c862SJiri Pirko }
1045*7199c862SJiri Pirko 
1046*7199c862SJiri Pirko int devlink_sb_port_pool_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1047*7199c862SJiri Pirko {
1048*7199c862SJiri Pirko 	struct devlink_sb_port_pool_get_rsp *dst;
1049*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
1050*7199c862SJiri Pirko 	const struct nlattr *attr;
1051*7199c862SJiri Pirko 
1052*7199c862SJiri Pirko 	dst = yarg->data;
1053*7199c862SJiri Pirko 
1054*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1055*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
1056*7199c862SJiri Pirko 
1057*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
1058*7199c862SJiri Pirko 			unsigned int len;
1059*7199c862SJiri Pirko 
1060*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1061*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1062*7199c862SJiri Pirko 
1063*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1064*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
1065*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
1066*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1067*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
1068*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1069*7199c862SJiri Pirko 			unsigned int len;
1070*7199c862SJiri Pirko 
1071*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1072*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1073*7199c862SJiri Pirko 
1074*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1075*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
1076*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
1077*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1078*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
1079*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
1080*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1081*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1082*7199c862SJiri Pirko 			dst->_present.port_index = 1;
1083*7199c862SJiri Pirko 			dst->port_index = mnl_attr_get_u32(attr);
1084*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_SB_INDEX) {
1085*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1086*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1087*7199c862SJiri Pirko 			dst->_present.sb_index = 1;
1088*7199c862SJiri Pirko 			dst->sb_index = mnl_attr_get_u32(attr);
1089*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_SB_POOL_INDEX) {
1090*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1091*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1092*7199c862SJiri Pirko 			dst->_present.sb_pool_index = 1;
1093*7199c862SJiri Pirko 			dst->sb_pool_index = mnl_attr_get_u16(attr);
1094*7199c862SJiri Pirko 		}
1095*7199c862SJiri Pirko 	}
1096*7199c862SJiri Pirko 
1097*7199c862SJiri Pirko 	return MNL_CB_OK;
1098*7199c862SJiri Pirko }
1099*7199c862SJiri Pirko 
1100*7199c862SJiri Pirko struct devlink_sb_port_pool_get_rsp *
1101*7199c862SJiri Pirko devlink_sb_port_pool_get(struct ynl_sock *ys,
1102*7199c862SJiri Pirko 			 struct devlink_sb_port_pool_get_req *req)
1103*7199c862SJiri Pirko {
1104*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1105*7199c862SJiri Pirko 	struct devlink_sb_port_pool_get_rsp *rsp;
1106*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1107*7199c862SJiri Pirko 	int err;
1108*7199c862SJiri Pirko 
1109*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_PORT_POOL_GET, 1);
1110*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
1111*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
1112*7199c862SJiri Pirko 
1113*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
1114*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1115*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
1116*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1117*7199c862SJiri Pirko 	if (req->_present.port_index)
1118*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
1119*7199c862SJiri Pirko 	if (req->_present.sb_index)
1120*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index);
1121*7199c862SJiri Pirko 	if (req->_present.sb_pool_index)
1122*7199c862SJiri Pirko 		mnl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX, req->sb_pool_index);
1123*7199c862SJiri Pirko 
1124*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
1125*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
1126*7199c862SJiri Pirko 	yrs.cb = devlink_sb_port_pool_get_rsp_parse;
1127*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_SB_PORT_POOL_GET;
1128*7199c862SJiri Pirko 
1129*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
1130*7199c862SJiri Pirko 	if (err < 0)
1131*7199c862SJiri Pirko 		goto err_free;
1132*7199c862SJiri Pirko 
1133*7199c862SJiri Pirko 	return rsp;
1134*7199c862SJiri Pirko 
1135*7199c862SJiri Pirko err_free:
1136*7199c862SJiri Pirko 	devlink_sb_port_pool_get_rsp_free(rsp);
1137*7199c862SJiri Pirko 	return NULL;
1138*7199c862SJiri Pirko }
1139*7199c862SJiri Pirko 
1140*7199c862SJiri Pirko /* DEVLINK_CMD_SB_PORT_POOL_GET - dump */
1141*7199c862SJiri Pirko void
1142*7199c862SJiri Pirko devlink_sb_port_pool_get_list_free(struct devlink_sb_port_pool_get_list *rsp)
1143*7199c862SJiri Pirko {
1144*7199c862SJiri Pirko 	struct devlink_sb_port_pool_get_list *next = rsp;
1145*7199c862SJiri Pirko 
1146*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
1147*7199c862SJiri Pirko 		rsp = next;
1148*7199c862SJiri Pirko 		next = rsp->next;
1149*7199c862SJiri Pirko 
1150*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
1151*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
1152*7199c862SJiri Pirko 		free(rsp);
1153*7199c862SJiri Pirko 	}
1154*7199c862SJiri Pirko }
1155*7199c862SJiri Pirko 
1156*7199c862SJiri Pirko struct devlink_sb_port_pool_get_list *
1157*7199c862SJiri Pirko devlink_sb_port_pool_get_dump(struct ynl_sock *ys)
1158*7199c862SJiri Pirko {
1159*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
1160*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1161*7199c862SJiri Pirko 	int err;
1162*7199c862SJiri Pirko 
1163*7199c862SJiri Pirko 	yds.ys = ys;
1164*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_sb_port_pool_get_list);
1165*7199c862SJiri Pirko 	yds.cb = devlink_sb_port_pool_get_rsp_parse;
1166*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_SB_PORT_POOL_GET;
1167*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
1168*7199c862SJiri Pirko 
1169*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_PORT_POOL_GET, 1);
1170*7199c862SJiri Pirko 
1171*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
1172*7199c862SJiri Pirko 	if (err < 0)
1173*7199c862SJiri Pirko 		goto free_list;
1174*7199c862SJiri Pirko 
1175*7199c862SJiri Pirko 	return yds.first;
1176*7199c862SJiri Pirko 
1177*7199c862SJiri Pirko free_list:
1178*7199c862SJiri Pirko 	devlink_sb_port_pool_get_list_free(yds.first);
1179*7199c862SJiri Pirko 	return NULL;
1180*7199c862SJiri Pirko }
1181*7199c862SJiri Pirko 
1182*7199c862SJiri Pirko /* ============== DEVLINK_CMD_SB_TC_POOL_BIND_GET ============== */
1183*7199c862SJiri Pirko /* DEVLINK_CMD_SB_TC_POOL_BIND_GET - do */
1184*7199c862SJiri Pirko void
1185*7199c862SJiri Pirko devlink_sb_tc_pool_bind_get_req_free(struct devlink_sb_tc_pool_bind_get_req *req)
1186*7199c862SJiri Pirko {
1187*7199c862SJiri Pirko 	free(req->bus_name);
1188*7199c862SJiri Pirko 	free(req->dev_name);
1189*7199c862SJiri Pirko 	free(req);
1190*7199c862SJiri Pirko }
1191*7199c862SJiri Pirko 
1192*7199c862SJiri Pirko void
1193*7199c862SJiri Pirko devlink_sb_tc_pool_bind_get_rsp_free(struct devlink_sb_tc_pool_bind_get_rsp *rsp)
1194*7199c862SJiri Pirko {
1195*7199c862SJiri Pirko 	free(rsp->bus_name);
1196*7199c862SJiri Pirko 	free(rsp->dev_name);
1197*7199c862SJiri Pirko 	free(rsp);
1198*7199c862SJiri Pirko }
1199*7199c862SJiri Pirko 
1200*7199c862SJiri Pirko int devlink_sb_tc_pool_bind_get_rsp_parse(const struct nlmsghdr *nlh,
1201*7199c862SJiri Pirko 					  void *data)
1202*7199c862SJiri Pirko {
1203*7199c862SJiri Pirko 	struct devlink_sb_tc_pool_bind_get_rsp *dst;
1204*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
1205*7199c862SJiri Pirko 	const struct nlattr *attr;
1206*7199c862SJiri Pirko 
1207*7199c862SJiri Pirko 	dst = yarg->data;
1208*7199c862SJiri Pirko 
1209*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1210*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
1211*7199c862SJiri Pirko 
1212*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
1213*7199c862SJiri Pirko 			unsigned int len;
1214*7199c862SJiri Pirko 
1215*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1216*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1217*7199c862SJiri Pirko 
1218*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1219*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
1220*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
1221*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1222*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
1223*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1224*7199c862SJiri Pirko 			unsigned int len;
1225*7199c862SJiri Pirko 
1226*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1227*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1228*7199c862SJiri Pirko 
1229*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1230*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
1231*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
1232*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1233*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
1234*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
1235*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1236*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1237*7199c862SJiri Pirko 			dst->_present.port_index = 1;
1238*7199c862SJiri Pirko 			dst->port_index = mnl_attr_get_u32(attr);
1239*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_SB_INDEX) {
1240*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1241*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1242*7199c862SJiri Pirko 			dst->_present.sb_index = 1;
1243*7199c862SJiri Pirko 			dst->sb_index = mnl_attr_get_u32(attr);
1244*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_SB_POOL_TYPE) {
1245*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1246*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1247*7199c862SJiri Pirko 			dst->_present.sb_pool_type = 1;
1248*7199c862SJiri Pirko 			dst->sb_pool_type = mnl_attr_get_u8(attr);
1249*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_SB_TC_INDEX) {
1250*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1251*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1252*7199c862SJiri Pirko 			dst->_present.sb_tc_index = 1;
1253*7199c862SJiri Pirko 			dst->sb_tc_index = mnl_attr_get_u16(attr);
1254*7199c862SJiri Pirko 		}
1255*7199c862SJiri Pirko 	}
1256*7199c862SJiri Pirko 
1257*7199c862SJiri Pirko 	return MNL_CB_OK;
1258*7199c862SJiri Pirko }
1259*7199c862SJiri Pirko 
1260*7199c862SJiri Pirko struct devlink_sb_tc_pool_bind_get_rsp *
1261*7199c862SJiri Pirko devlink_sb_tc_pool_bind_get(struct ynl_sock *ys,
1262*7199c862SJiri Pirko 			    struct devlink_sb_tc_pool_bind_get_req *req)
1263*7199c862SJiri Pirko {
1264*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1265*7199c862SJiri Pirko 	struct devlink_sb_tc_pool_bind_get_rsp *rsp;
1266*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1267*7199c862SJiri Pirko 	int err;
1268*7199c862SJiri Pirko 
1269*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_TC_POOL_BIND_GET, 1);
1270*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
1271*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
1272*7199c862SJiri Pirko 
1273*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
1274*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1275*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
1276*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1277*7199c862SJiri Pirko 	if (req->_present.port_index)
1278*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
1279*7199c862SJiri Pirko 	if (req->_present.sb_index)
1280*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index);
1281*7199c862SJiri Pirko 	if (req->_present.sb_pool_type)
1282*7199c862SJiri Pirko 		mnl_attr_put_u8(nlh, DEVLINK_ATTR_SB_POOL_TYPE, req->sb_pool_type);
1283*7199c862SJiri Pirko 	if (req->_present.sb_tc_index)
1284*7199c862SJiri Pirko 		mnl_attr_put_u16(nlh, DEVLINK_ATTR_SB_TC_INDEX, req->sb_tc_index);
1285*7199c862SJiri Pirko 
1286*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
1287*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
1288*7199c862SJiri Pirko 	yrs.cb = devlink_sb_tc_pool_bind_get_rsp_parse;
1289*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET;
1290*7199c862SJiri Pirko 
1291*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
1292*7199c862SJiri Pirko 	if (err < 0)
1293*7199c862SJiri Pirko 		goto err_free;
1294*7199c862SJiri Pirko 
1295*7199c862SJiri Pirko 	return rsp;
1296*7199c862SJiri Pirko 
1297*7199c862SJiri Pirko err_free:
1298*7199c862SJiri Pirko 	devlink_sb_tc_pool_bind_get_rsp_free(rsp);
1299*7199c862SJiri Pirko 	return NULL;
1300*7199c862SJiri Pirko }
1301*7199c862SJiri Pirko 
1302*7199c862SJiri Pirko /* DEVLINK_CMD_SB_TC_POOL_BIND_GET - dump */
1303*7199c862SJiri Pirko void
1304*7199c862SJiri Pirko devlink_sb_tc_pool_bind_get_list_free(struct devlink_sb_tc_pool_bind_get_list *rsp)
1305*7199c862SJiri Pirko {
1306*7199c862SJiri Pirko 	struct devlink_sb_tc_pool_bind_get_list *next = rsp;
1307*7199c862SJiri Pirko 
1308*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
1309*7199c862SJiri Pirko 		rsp = next;
1310*7199c862SJiri Pirko 		next = rsp->next;
1311*7199c862SJiri Pirko 
1312*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
1313*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
1314*7199c862SJiri Pirko 		free(rsp);
1315*7199c862SJiri Pirko 	}
1316*7199c862SJiri Pirko }
1317*7199c862SJiri Pirko 
1318*7199c862SJiri Pirko struct devlink_sb_tc_pool_bind_get_list *
1319*7199c862SJiri Pirko devlink_sb_tc_pool_bind_get_dump(struct ynl_sock *ys)
1320*7199c862SJiri Pirko {
1321*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
1322*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1323*7199c862SJiri Pirko 	int err;
1324*7199c862SJiri Pirko 
1325*7199c862SJiri Pirko 	yds.ys = ys;
1326*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_sb_tc_pool_bind_get_list);
1327*7199c862SJiri Pirko 	yds.cb = devlink_sb_tc_pool_bind_get_rsp_parse;
1328*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET;
1329*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
1330*7199c862SJiri Pirko 
1331*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_TC_POOL_BIND_GET, 1);
1332*7199c862SJiri Pirko 
1333*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
1334*7199c862SJiri Pirko 	if (err < 0)
1335*7199c862SJiri Pirko 		goto free_list;
1336*7199c862SJiri Pirko 
1337*7199c862SJiri Pirko 	return yds.first;
1338*7199c862SJiri Pirko 
1339*7199c862SJiri Pirko free_list:
1340*7199c862SJiri Pirko 	devlink_sb_tc_pool_bind_get_list_free(yds.first);
1341*7199c862SJiri Pirko 	return NULL;
1342*7199c862SJiri Pirko }
1343*7199c862SJiri Pirko 
1344*7199c862SJiri Pirko /* ============== DEVLINK_CMD_PARAM_GET ============== */
1345*7199c862SJiri Pirko /* DEVLINK_CMD_PARAM_GET - do */
1346*7199c862SJiri Pirko void devlink_param_get_req_free(struct devlink_param_get_req *req)
1347*7199c862SJiri Pirko {
1348*7199c862SJiri Pirko 	free(req->bus_name);
1349*7199c862SJiri Pirko 	free(req->dev_name);
1350*7199c862SJiri Pirko 	free(req->param_name);
1351*7199c862SJiri Pirko 	free(req);
1352*7199c862SJiri Pirko }
1353*7199c862SJiri Pirko 
1354*7199c862SJiri Pirko void devlink_param_get_rsp_free(struct devlink_param_get_rsp *rsp)
1355*7199c862SJiri Pirko {
1356*7199c862SJiri Pirko 	free(rsp->bus_name);
1357*7199c862SJiri Pirko 	free(rsp->dev_name);
1358*7199c862SJiri Pirko 	free(rsp->param_name);
1359*7199c862SJiri Pirko 	free(rsp);
1360*7199c862SJiri Pirko }
1361*7199c862SJiri Pirko 
1362*7199c862SJiri Pirko int devlink_param_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1363*7199c862SJiri Pirko {
1364*7199c862SJiri Pirko 	struct devlink_param_get_rsp *dst;
1365*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
1366*7199c862SJiri Pirko 	const struct nlattr *attr;
1367*7199c862SJiri Pirko 
1368*7199c862SJiri Pirko 	dst = yarg->data;
1369*7199c862SJiri Pirko 
1370*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1371*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
1372*7199c862SJiri Pirko 
1373*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
1374*7199c862SJiri Pirko 			unsigned int len;
1375*7199c862SJiri Pirko 
1376*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1377*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1378*7199c862SJiri Pirko 
1379*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1380*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
1381*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
1382*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1383*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
1384*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1385*7199c862SJiri Pirko 			unsigned int len;
1386*7199c862SJiri Pirko 
1387*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1388*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1389*7199c862SJiri Pirko 
1390*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1391*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
1392*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
1393*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1394*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
1395*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_PARAM_NAME) {
1396*7199c862SJiri Pirko 			unsigned int len;
1397*7199c862SJiri Pirko 
1398*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1399*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1400*7199c862SJiri Pirko 
1401*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1402*7199c862SJiri Pirko 			dst->_present.param_name_len = len;
1403*7199c862SJiri Pirko 			dst->param_name = malloc(len + 1);
1404*7199c862SJiri Pirko 			memcpy(dst->param_name, mnl_attr_get_str(attr), len);
1405*7199c862SJiri Pirko 			dst->param_name[len] = 0;
1406*7199c862SJiri Pirko 		}
1407*7199c862SJiri Pirko 	}
1408*7199c862SJiri Pirko 
1409*7199c862SJiri Pirko 	return MNL_CB_OK;
1410*7199c862SJiri Pirko }
1411*7199c862SJiri Pirko 
1412*7199c862SJiri Pirko struct devlink_param_get_rsp *
1413*7199c862SJiri Pirko devlink_param_get(struct ynl_sock *ys, struct devlink_param_get_req *req)
1414*7199c862SJiri Pirko {
1415*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1416*7199c862SJiri Pirko 	struct devlink_param_get_rsp *rsp;
1417*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1418*7199c862SJiri Pirko 	int err;
1419*7199c862SJiri Pirko 
1420*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PARAM_GET, 1);
1421*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
1422*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
1423*7199c862SJiri Pirko 
1424*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
1425*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1426*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
1427*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1428*7199c862SJiri Pirko 	if (req->_present.param_name_len)
1429*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_NAME, req->param_name);
1430*7199c862SJiri Pirko 
1431*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
1432*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
1433*7199c862SJiri Pirko 	yrs.cb = devlink_param_get_rsp_parse;
1434*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_PARAM_GET;
1435*7199c862SJiri Pirko 
1436*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
1437*7199c862SJiri Pirko 	if (err < 0)
1438*7199c862SJiri Pirko 		goto err_free;
1439*7199c862SJiri Pirko 
1440*7199c862SJiri Pirko 	return rsp;
1441*7199c862SJiri Pirko 
1442*7199c862SJiri Pirko err_free:
1443*7199c862SJiri Pirko 	devlink_param_get_rsp_free(rsp);
1444*7199c862SJiri Pirko 	return NULL;
1445*7199c862SJiri Pirko }
1446*7199c862SJiri Pirko 
1447*7199c862SJiri Pirko /* DEVLINK_CMD_PARAM_GET - dump */
1448*7199c862SJiri Pirko void devlink_param_get_list_free(struct devlink_param_get_list *rsp)
1449*7199c862SJiri Pirko {
1450*7199c862SJiri Pirko 	struct devlink_param_get_list *next = rsp;
1451*7199c862SJiri Pirko 
1452*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
1453*7199c862SJiri Pirko 		rsp = next;
1454*7199c862SJiri Pirko 		next = rsp->next;
1455*7199c862SJiri Pirko 
1456*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
1457*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
1458*7199c862SJiri Pirko 		free(rsp->obj.param_name);
1459*7199c862SJiri Pirko 		free(rsp);
1460*7199c862SJiri Pirko 	}
1461*7199c862SJiri Pirko }
1462*7199c862SJiri Pirko 
1463*7199c862SJiri Pirko struct devlink_param_get_list *devlink_param_get_dump(struct ynl_sock *ys)
1464*7199c862SJiri Pirko {
1465*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
1466*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1467*7199c862SJiri Pirko 	int err;
1468*7199c862SJiri Pirko 
1469*7199c862SJiri Pirko 	yds.ys = ys;
1470*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_param_get_list);
1471*7199c862SJiri Pirko 	yds.cb = devlink_param_get_rsp_parse;
1472*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_PARAM_GET;
1473*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
1474*7199c862SJiri Pirko 
1475*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_PARAM_GET, 1);
1476*7199c862SJiri Pirko 
1477*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
1478*7199c862SJiri Pirko 	if (err < 0)
1479*7199c862SJiri Pirko 		goto free_list;
1480*7199c862SJiri Pirko 
1481*7199c862SJiri Pirko 	return yds.first;
1482*7199c862SJiri Pirko 
1483*7199c862SJiri Pirko free_list:
1484*7199c862SJiri Pirko 	devlink_param_get_list_free(yds.first);
1485*7199c862SJiri Pirko 	return NULL;
1486*7199c862SJiri Pirko }
1487*7199c862SJiri Pirko 
1488*7199c862SJiri Pirko /* ============== DEVLINK_CMD_REGION_GET ============== */
1489*7199c862SJiri Pirko /* DEVLINK_CMD_REGION_GET - do */
1490*7199c862SJiri Pirko void devlink_region_get_req_free(struct devlink_region_get_req *req)
1491*7199c862SJiri Pirko {
1492*7199c862SJiri Pirko 	free(req->bus_name);
1493*7199c862SJiri Pirko 	free(req->dev_name);
1494*7199c862SJiri Pirko 	free(req->region_name);
1495*7199c862SJiri Pirko 	free(req);
1496*7199c862SJiri Pirko }
1497*7199c862SJiri Pirko 
1498*7199c862SJiri Pirko void devlink_region_get_rsp_free(struct devlink_region_get_rsp *rsp)
1499*7199c862SJiri Pirko {
1500*7199c862SJiri Pirko 	free(rsp->bus_name);
1501*7199c862SJiri Pirko 	free(rsp->dev_name);
1502*7199c862SJiri Pirko 	free(rsp->region_name);
1503*7199c862SJiri Pirko 	free(rsp);
1504*7199c862SJiri Pirko }
1505*7199c862SJiri Pirko 
1506*7199c862SJiri Pirko int devlink_region_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1507*7199c862SJiri Pirko {
1508*7199c862SJiri Pirko 	struct devlink_region_get_rsp *dst;
1509*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
1510*7199c862SJiri Pirko 	const struct nlattr *attr;
1511*7199c862SJiri Pirko 
1512*7199c862SJiri Pirko 	dst = yarg->data;
1513*7199c862SJiri Pirko 
1514*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1515*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
1516*7199c862SJiri Pirko 
1517*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
1518*7199c862SJiri Pirko 			unsigned int len;
1519*7199c862SJiri Pirko 
1520*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1521*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1522*7199c862SJiri Pirko 
1523*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1524*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
1525*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
1526*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1527*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
1528*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1529*7199c862SJiri Pirko 			unsigned int len;
1530*7199c862SJiri Pirko 
1531*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1532*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1533*7199c862SJiri Pirko 
1534*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1535*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
1536*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
1537*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1538*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
1539*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
1540*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1541*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1542*7199c862SJiri Pirko 			dst->_present.port_index = 1;
1543*7199c862SJiri Pirko 			dst->port_index = mnl_attr_get_u32(attr);
1544*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_REGION_NAME) {
1545*7199c862SJiri Pirko 			unsigned int len;
1546*7199c862SJiri Pirko 
1547*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1548*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1549*7199c862SJiri Pirko 
1550*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1551*7199c862SJiri Pirko 			dst->_present.region_name_len = len;
1552*7199c862SJiri Pirko 			dst->region_name = malloc(len + 1);
1553*7199c862SJiri Pirko 			memcpy(dst->region_name, mnl_attr_get_str(attr), len);
1554*7199c862SJiri Pirko 			dst->region_name[len] = 0;
1555*7199c862SJiri Pirko 		}
1556*7199c862SJiri Pirko 	}
1557*7199c862SJiri Pirko 
1558*7199c862SJiri Pirko 	return MNL_CB_OK;
1559*7199c862SJiri Pirko }
1560*7199c862SJiri Pirko 
1561*7199c862SJiri Pirko struct devlink_region_get_rsp *
1562*7199c862SJiri Pirko devlink_region_get(struct ynl_sock *ys, struct devlink_region_get_req *req)
1563*7199c862SJiri Pirko {
1564*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1565*7199c862SJiri Pirko 	struct devlink_region_get_rsp *rsp;
1566*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1567*7199c862SJiri Pirko 	int err;
1568*7199c862SJiri Pirko 
1569*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_REGION_GET, 1);
1570*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
1571*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
1572*7199c862SJiri Pirko 
1573*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
1574*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1575*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
1576*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1577*7199c862SJiri Pirko 	if (req->_present.port_index)
1578*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
1579*7199c862SJiri Pirko 	if (req->_present.region_name_len)
1580*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_REGION_NAME, req->region_name);
1581*7199c862SJiri Pirko 
1582*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
1583*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
1584*7199c862SJiri Pirko 	yrs.cb = devlink_region_get_rsp_parse;
1585*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_REGION_GET;
1586*7199c862SJiri Pirko 
1587*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
1588*7199c862SJiri Pirko 	if (err < 0)
1589*7199c862SJiri Pirko 		goto err_free;
1590*7199c862SJiri Pirko 
1591*7199c862SJiri Pirko 	return rsp;
1592*7199c862SJiri Pirko 
1593*7199c862SJiri Pirko err_free:
1594*7199c862SJiri Pirko 	devlink_region_get_rsp_free(rsp);
1595*7199c862SJiri Pirko 	return NULL;
1596*7199c862SJiri Pirko }
1597*7199c862SJiri Pirko 
1598*7199c862SJiri Pirko /* DEVLINK_CMD_REGION_GET - dump */
1599*7199c862SJiri Pirko void devlink_region_get_list_free(struct devlink_region_get_list *rsp)
1600*7199c862SJiri Pirko {
1601*7199c862SJiri Pirko 	struct devlink_region_get_list *next = rsp;
1602*7199c862SJiri Pirko 
1603*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
1604*7199c862SJiri Pirko 		rsp = next;
1605*7199c862SJiri Pirko 		next = rsp->next;
1606*7199c862SJiri Pirko 
1607*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
1608*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
1609*7199c862SJiri Pirko 		free(rsp->obj.region_name);
1610*7199c862SJiri Pirko 		free(rsp);
1611*7199c862SJiri Pirko 	}
1612*7199c862SJiri Pirko }
1613*7199c862SJiri Pirko 
1614*7199c862SJiri Pirko struct devlink_region_get_list *devlink_region_get_dump(struct ynl_sock *ys)
1615*7199c862SJiri Pirko {
1616*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
1617*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1618*7199c862SJiri Pirko 	int err;
1619*7199c862SJiri Pirko 
1620*7199c862SJiri Pirko 	yds.ys = ys;
1621*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_region_get_list);
1622*7199c862SJiri Pirko 	yds.cb = devlink_region_get_rsp_parse;
1623*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_REGION_GET;
1624*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
1625*7199c862SJiri Pirko 
1626*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_REGION_GET, 1);
1627*7199c862SJiri Pirko 
1628*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
1629*7199c862SJiri Pirko 	if (err < 0)
1630*7199c862SJiri Pirko 		goto free_list;
1631*7199c862SJiri Pirko 
1632*7199c862SJiri Pirko 	return yds.first;
1633*7199c862SJiri Pirko 
1634*7199c862SJiri Pirko free_list:
1635*7199c862SJiri Pirko 	devlink_region_get_list_free(yds.first);
1636*7199c862SJiri Pirko 	return NULL;
1637*7199c862SJiri Pirko }
1638*7199c862SJiri Pirko 
16395d1a30ebSJakub Kicinski /* ============== DEVLINK_CMD_INFO_GET ============== */
16405d1a30ebSJakub Kicinski /* DEVLINK_CMD_INFO_GET - do */
16415d1a30ebSJakub Kicinski void devlink_info_get_req_free(struct devlink_info_get_req *req)
16425d1a30ebSJakub Kicinski {
16435d1a30ebSJakub Kicinski 	free(req->bus_name);
16445d1a30ebSJakub Kicinski 	free(req->dev_name);
16455d1a30ebSJakub Kicinski 	free(req);
16465d1a30ebSJakub Kicinski }
16475d1a30ebSJakub Kicinski 
16485d1a30ebSJakub Kicinski void devlink_info_get_rsp_free(struct devlink_info_get_rsp *rsp)
16495d1a30ebSJakub Kicinski {
16505d1a30ebSJakub Kicinski 	unsigned int i;
16515d1a30ebSJakub Kicinski 
16525d1a30ebSJakub Kicinski 	free(rsp->bus_name);
16535d1a30ebSJakub Kicinski 	free(rsp->dev_name);
16545d1a30ebSJakub Kicinski 	free(rsp->info_driver_name);
16555d1a30ebSJakub Kicinski 	free(rsp->info_serial_number);
16565d1a30ebSJakub Kicinski 	for (i = 0; i < rsp->n_info_version_fixed; i++)
16575d1a30ebSJakub Kicinski 		devlink_dl_info_version_free(&rsp->info_version_fixed[i]);
16585d1a30ebSJakub Kicinski 	free(rsp->info_version_fixed);
16595d1a30ebSJakub Kicinski 	for (i = 0; i < rsp->n_info_version_running; i++)
16605d1a30ebSJakub Kicinski 		devlink_dl_info_version_free(&rsp->info_version_running[i]);
16615d1a30ebSJakub Kicinski 	free(rsp->info_version_running);
16625d1a30ebSJakub Kicinski 	for (i = 0; i < rsp->n_info_version_stored; i++)
16635d1a30ebSJakub Kicinski 		devlink_dl_info_version_free(&rsp->info_version_stored[i]);
16645d1a30ebSJakub Kicinski 	free(rsp->info_version_stored);
16655d1a30ebSJakub Kicinski 	free(rsp);
16665d1a30ebSJakub Kicinski }
16675d1a30ebSJakub Kicinski 
16685d1a30ebSJakub Kicinski int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
16695d1a30ebSJakub Kicinski {
16705d1a30ebSJakub Kicinski 	unsigned int n_info_version_running = 0;
16715d1a30ebSJakub Kicinski 	unsigned int n_info_version_stored = 0;
16725d1a30ebSJakub Kicinski 	unsigned int n_info_version_fixed = 0;
16735d1a30ebSJakub Kicinski 	struct ynl_parse_arg *yarg = data;
16745d1a30ebSJakub Kicinski 	struct devlink_info_get_rsp *dst;
16755d1a30ebSJakub Kicinski 	const struct nlattr *attr;
16765d1a30ebSJakub Kicinski 	struct ynl_parse_arg parg;
16775d1a30ebSJakub Kicinski 	int i;
16785d1a30ebSJakub Kicinski 
16795d1a30ebSJakub Kicinski 	dst = yarg->data;
16805d1a30ebSJakub Kicinski 	parg.ys = yarg->ys;
16815d1a30ebSJakub Kicinski 
16825d1a30ebSJakub Kicinski 	if (dst->info_version_fixed)
16835d1a30ebSJakub Kicinski 		return ynl_error_parse(yarg, "attribute already present (devlink.info-version-fixed)");
16845d1a30ebSJakub Kicinski 	if (dst->info_version_running)
16855d1a30ebSJakub Kicinski 		return ynl_error_parse(yarg, "attribute already present (devlink.info-version-running)");
16865d1a30ebSJakub Kicinski 	if (dst->info_version_stored)
16875d1a30ebSJakub Kicinski 		return ynl_error_parse(yarg, "attribute already present (devlink.info-version-stored)");
16885d1a30ebSJakub Kicinski 
16895d1a30ebSJakub Kicinski 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
16907234415bSJakub Kicinski 		unsigned int type = mnl_attr_get_type(attr);
16917234415bSJakub Kicinski 
16927234415bSJakub Kicinski 		if (type == DEVLINK_ATTR_BUS_NAME) {
16935d1a30ebSJakub Kicinski 			unsigned int len;
16945d1a30ebSJakub Kicinski 
16955d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
16965d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
16975d1a30ebSJakub Kicinski 
16985d1a30ebSJakub Kicinski 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
16995d1a30ebSJakub Kicinski 			dst->_present.bus_name_len = len;
17005d1a30ebSJakub Kicinski 			dst->bus_name = malloc(len + 1);
17015d1a30ebSJakub Kicinski 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
17025d1a30ebSJakub Kicinski 			dst->bus_name[len] = 0;
17037234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
17045d1a30ebSJakub Kicinski 			unsigned int len;
17055d1a30ebSJakub Kicinski 
17065d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
17075d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
17085d1a30ebSJakub Kicinski 
17095d1a30ebSJakub Kicinski 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
17105d1a30ebSJakub Kicinski 			dst->_present.dev_name_len = len;
17115d1a30ebSJakub Kicinski 			dst->dev_name = malloc(len + 1);
17125d1a30ebSJakub Kicinski 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
17135d1a30ebSJakub Kicinski 			dst->dev_name[len] = 0;
17147234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_INFO_DRIVER_NAME) {
17155d1a30ebSJakub Kicinski 			unsigned int len;
17165d1a30ebSJakub Kicinski 
17175d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
17185d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
17195d1a30ebSJakub Kicinski 
17205d1a30ebSJakub Kicinski 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
17215d1a30ebSJakub Kicinski 			dst->_present.info_driver_name_len = len;
17225d1a30ebSJakub Kicinski 			dst->info_driver_name = malloc(len + 1);
17235d1a30ebSJakub Kicinski 			memcpy(dst->info_driver_name, mnl_attr_get_str(attr), len);
17245d1a30ebSJakub Kicinski 			dst->info_driver_name[len] = 0;
17257234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_INFO_SERIAL_NUMBER) {
17265d1a30ebSJakub Kicinski 			unsigned int len;
17275d1a30ebSJakub Kicinski 
17285d1a30ebSJakub Kicinski 			if (ynl_attr_validate(yarg, attr))
17295d1a30ebSJakub Kicinski 				return MNL_CB_ERROR;
17305d1a30ebSJakub Kicinski 
17315d1a30ebSJakub Kicinski 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
17325d1a30ebSJakub Kicinski 			dst->_present.info_serial_number_len = len;
17335d1a30ebSJakub Kicinski 			dst->info_serial_number = malloc(len + 1);
17345d1a30ebSJakub Kicinski 			memcpy(dst->info_serial_number, mnl_attr_get_str(attr), len);
17355d1a30ebSJakub Kicinski 			dst->info_serial_number[len] = 0;
17367234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_INFO_VERSION_FIXED) {
17375d1a30ebSJakub Kicinski 			n_info_version_fixed++;
17387234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_INFO_VERSION_RUNNING) {
17395d1a30ebSJakub Kicinski 			n_info_version_running++;
17407234415bSJakub Kicinski 		} else if (type == DEVLINK_ATTR_INFO_VERSION_STORED) {
17415d1a30ebSJakub Kicinski 			n_info_version_stored++;
17425d1a30ebSJakub Kicinski 		}
17435d1a30ebSJakub Kicinski 	}
17445d1a30ebSJakub Kicinski 
17455d1a30ebSJakub Kicinski 	if (n_info_version_fixed) {
17465d1a30ebSJakub Kicinski 		dst->info_version_fixed = calloc(n_info_version_fixed, sizeof(*dst->info_version_fixed));
17475d1a30ebSJakub Kicinski 		dst->n_info_version_fixed = n_info_version_fixed;
17485d1a30ebSJakub Kicinski 		i = 0;
17495d1a30ebSJakub Kicinski 		parg.rsp_policy = &devlink_dl_info_version_nest;
17505d1a30ebSJakub Kicinski 		mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
17515d1a30ebSJakub Kicinski 			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) {
17525d1a30ebSJakub Kicinski 				parg.data = &dst->info_version_fixed[i];
17535d1a30ebSJakub Kicinski 				if (devlink_dl_info_version_parse(&parg, attr))
17545d1a30ebSJakub Kicinski 					return MNL_CB_ERROR;
17555d1a30ebSJakub Kicinski 				i++;
17565d1a30ebSJakub Kicinski 			}
17575d1a30ebSJakub Kicinski 		}
17585d1a30ebSJakub Kicinski 	}
17595d1a30ebSJakub Kicinski 	if (n_info_version_running) {
17605d1a30ebSJakub Kicinski 		dst->info_version_running = calloc(n_info_version_running, sizeof(*dst->info_version_running));
17615d1a30ebSJakub Kicinski 		dst->n_info_version_running = n_info_version_running;
17625d1a30ebSJakub Kicinski 		i = 0;
17635d1a30ebSJakub Kicinski 		parg.rsp_policy = &devlink_dl_info_version_nest;
17645d1a30ebSJakub Kicinski 		mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
17655d1a30ebSJakub Kicinski 			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) {
17665d1a30ebSJakub Kicinski 				parg.data = &dst->info_version_running[i];
17675d1a30ebSJakub Kicinski 				if (devlink_dl_info_version_parse(&parg, attr))
17685d1a30ebSJakub Kicinski 					return MNL_CB_ERROR;
17695d1a30ebSJakub Kicinski 				i++;
17705d1a30ebSJakub Kicinski 			}
17715d1a30ebSJakub Kicinski 		}
17725d1a30ebSJakub Kicinski 	}
17735d1a30ebSJakub Kicinski 	if (n_info_version_stored) {
17745d1a30ebSJakub Kicinski 		dst->info_version_stored = calloc(n_info_version_stored, sizeof(*dst->info_version_stored));
17755d1a30ebSJakub Kicinski 		dst->n_info_version_stored = n_info_version_stored;
17765d1a30ebSJakub Kicinski 		i = 0;
17775d1a30ebSJakub Kicinski 		parg.rsp_policy = &devlink_dl_info_version_nest;
17785d1a30ebSJakub Kicinski 		mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
17795d1a30ebSJakub Kicinski 			if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) {
17805d1a30ebSJakub Kicinski 				parg.data = &dst->info_version_stored[i];
17815d1a30ebSJakub Kicinski 				if (devlink_dl_info_version_parse(&parg, attr))
17825d1a30ebSJakub Kicinski 					return MNL_CB_ERROR;
17835d1a30ebSJakub Kicinski 				i++;
17845d1a30ebSJakub Kicinski 			}
17855d1a30ebSJakub Kicinski 		}
17865d1a30ebSJakub Kicinski 	}
17875d1a30ebSJakub Kicinski 
17885d1a30ebSJakub Kicinski 	return MNL_CB_OK;
17895d1a30ebSJakub Kicinski }
17905d1a30ebSJakub Kicinski 
17915d1a30ebSJakub Kicinski struct devlink_info_get_rsp *
17925d1a30ebSJakub Kicinski devlink_info_get(struct ynl_sock *ys, struct devlink_info_get_req *req)
17935d1a30ebSJakub Kicinski {
17945d1a30ebSJakub Kicinski 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
17955d1a30ebSJakub Kicinski 	struct devlink_info_get_rsp *rsp;
17965d1a30ebSJakub Kicinski 	struct nlmsghdr *nlh;
17975d1a30ebSJakub Kicinski 	int err;
17985d1a30ebSJakub Kicinski 
17995d1a30ebSJakub Kicinski 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1);
18005d1a30ebSJakub Kicinski 	ys->req_policy = &devlink_nest;
18015d1a30ebSJakub Kicinski 	yrs.yarg.rsp_policy = &devlink_nest;
18025d1a30ebSJakub Kicinski 
18035d1a30ebSJakub Kicinski 	if (req->_present.bus_name_len)
18045d1a30ebSJakub Kicinski 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
18055d1a30ebSJakub Kicinski 	if (req->_present.dev_name_len)
18065d1a30ebSJakub Kicinski 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
18075d1a30ebSJakub Kicinski 
18085d1a30ebSJakub Kicinski 	rsp = calloc(1, sizeof(*rsp));
18095d1a30ebSJakub Kicinski 	yrs.yarg.data = rsp;
18105d1a30ebSJakub Kicinski 	yrs.cb = devlink_info_get_rsp_parse;
18115d1a30ebSJakub Kicinski 	yrs.rsp_cmd = DEVLINK_CMD_INFO_GET;
18125d1a30ebSJakub Kicinski 
18135d1a30ebSJakub Kicinski 	err = ynl_exec(ys, nlh, &yrs);
18145d1a30ebSJakub Kicinski 	if (err < 0)
18155d1a30ebSJakub Kicinski 		goto err_free;
18165d1a30ebSJakub Kicinski 
18175d1a30ebSJakub Kicinski 	return rsp;
18185d1a30ebSJakub Kicinski 
18195d1a30ebSJakub Kicinski err_free:
18205d1a30ebSJakub Kicinski 	devlink_info_get_rsp_free(rsp);
18215d1a30ebSJakub Kicinski 	return NULL;
18225d1a30ebSJakub Kicinski }
18235d1a30ebSJakub Kicinski 
1824759f6610SJiri Pirko /* DEVLINK_CMD_INFO_GET - dump */
1825759f6610SJiri Pirko void devlink_info_get_list_free(struct devlink_info_get_list *rsp)
1826759f6610SJiri Pirko {
1827759f6610SJiri Pirko 	struct devlink_info_get_list *next = rsp;
1828759f6610SJiri Pirko 
1829759f6610SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
1830759f6610SJiri Pirko 		unsigned int i;
1831759f6610SJiri Pirko 
1832759f6610SJiri Pirko 		rsp = next;
1833759f6610SJiri Pirko 		next = rsp->next;
1834759f6610SJiri Pirko 
1835759f6610SJiri Pirko 		free(rsp->obj.bus_name);
1836759f6610SJiri Pirko 		free(rsp->obj.dev_name);
1837759f6610SJiri Pirko 		free(rsp->obj.info_driver_name);
1838759f6610SJiri Pirko 		free(rsp->obj.info_serial_number);
1839759f6610SJiri Pirko 		for (i = 0; i < rsp->obj.n_info_version_fixed; i++)
1840759f6610SJiri Pirko 			devlink_dl_info_version_free(&rsp->obj.info_version_fixed[i]);
1841759f6610SJiri Pirko 		free(rsp->obj.info_version_fixed);
1842759f6610SJiri Pirko 		for (i = 0; i < rsp->obj.n_info_version_running; i++)
1843759f6610SJiri Pirko 			devlink_dl_info_version_free(&rsp->obj.info_version_running[i]);
1844759f6610SJiri Pirko 		free(rsp->obj.info_version_running);
1845759f6610SJiri Pirko 		for (i = 0; i < rsp->obj.n_info_version_stored; i++)
1846759f6610SJiri Pirko 			devlink_dl_info_version_free(&rsp->obj.info_version_stored[i]);
1847759f6610SJiri Pirko 		free(rsp->obj.info_version_stored);
1848759f6610SJiri Pirko 		free(rsp);
1849759f6610SJiri Pirko 	}
1850759f6610SJiri Pirko }
1851759f6610SJiri Pirko 
1852759f6610SJiri Pirko struct devlink_info_get_list *devlink_info_get_dump(struct ynl_sock *ys)
1853759f6610SJiri Pirko {
1854759f6610SJiri Pirko 	struct ynl_dump_state yds = {};
1855759f6610SJiri Pirko 	struct nlmsghdr *nlh;
1856759f6610SJiri Pirko 	int err;
1857759f6610SJiri Pirko 
1858759f6610SJiri Pirko 	yds.ys = ys;
1859759f6610SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_info_get_list);
1860759f6610SJiri Pirko 	yds.cb = devlink_info_get_rsp_parse;
1861759f6610SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_INFO_GET;
1862759f6610SJiri Pirko 	yds.rsp_policy = &devlink_nest;
1863759f6610SJiri Pirko 
1864759f6610SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1);
1865759f6610SJiri Pirko 
1866759f6610SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
1867759f6610SJiri Pirko 	if (err < 0)
1868759f6610SJiri Pirko 		goto free_list;
1869759f6610SJiri Pirko 
1870759f6610SJiri Pirko 	return yds.first;
1871759f6610SJiri Pirko 
1872759f6610SJiri Pirko free_list:
1873759f6610SJiri Pirko 	devlink_info_get_list_free(yds.first);
1874759f6610SJiri Pirko 	return NULL;
1875759f6610SJiri Pirko }
1876759f6610SJiri Pirko 
1877*7199c862SJiri Pirko /* ============== DEVLINK_CMD_HEALTH_REPORTER_GET ============== */
1878*7199c862SJiri Pirko /* DEVLINK_CMD_HEALTH_REPORTER_GET - do */
1879*7199c862SJiri Pirko void
1880*7199c862SJiri Pirko devlink_health_reporter_get_req_free(struct devlink_health_reporter_get_req *req)
1881*7199c862SJiri Pirko {
1882*7199c862SJiri Pirko 	free(req->bus_name);
1883*7199c862SJiri Pirko 	free(req->dev_name);
1884*7199c862SJiri Pirko 	free(req->health_reporter_name);
1885*7199c862SJiri Pirko 	free(req);
1886*7199c862SJiri Pirko }
1887*7199c862SJiri Pirko 
1888*7199c862SJiri Pirko void
1889*7199c862SJiri Pirko devlink_health_reporter_get_rsp_free(struct devlink_health_reporter_get_rsp *rsp)
1890*7199c862SJiri Pirko {
1891*7199c862SJiri Pirko 	free(rsp->bus_name);
1892*7199c862SJiri Pirko 	free(rsp->dev_name);
1893*7199c862SJiri Pirko 	free(rsp->health_reporter_name);
1894*7199c862SJiri Pirko 	free(rsp);
1895*7199c862SJiri Pirko }
1896*7199c862SJiri Pirko 
1897*7199c862SJiri Pirko int devlink_health_reporter_get_rsp_parse(const struct nlmsghdr *nlh,
1898*7199c862SJiri Pirko 					  void *data)
1899*7199c862SJiri Pirko {
1900*7199c862SJiri Pirko 	struct devlink_health_reporter_get_rsp *dst;
1901*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
1902*7199c862SJiri Pirko 	const struct nlattr *attr;
1903*7199c862SJiri Pirko 
1904*7199c862SJiri Pirko 	dst = yarg->data;
1905*7199c862SJiri Pirko 
1906*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1907*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
1908*7199c862SJiri Pirko 
1909*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
1910*7199c862SJiri Pirko 			unsigned int len;
1911*7199c862SJiri Pirko 
1912*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1913*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1914*7199c862SJiri Pirko 
1915*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1916*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
1917*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
1918*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
1919*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
1920*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
1921*7199c862SJiri Pirko 			unsigned int len;
1922*7199c862SJiri Pirko 
1923*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1924*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1925*7199c862SJiri Pirko 
1926*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1927*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
1928*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
1929*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
1930*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
1931*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
1932*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1933*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1934*7199c862SJiri Pirko 			dst->_present.port_index = 1;
1935*7199c862SJiri Pirko 			dst->port_index = mnl_attr_get_u32(attr);
1936*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_HEALTH_REPORTER_NAME) {
1937*7199c862SJiri Pirko 			unsigned int len;
1938*7199c862SJiri Pirko 
1939*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
1940*7199c862SJiri Pirko 				return MNL_CB_ERROR;
1941*7199c862SJiri Pirko 
1942*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1943*7199c862SJiri Pirko 			dst->_present.health_reporter_name_len = len;
1944*7199c862SJiri Pirko 			dst->health_reporter_name = malloc(len + 1);
1945*7199c862SJiri Pirko 			memcpy(dst->health_reporter_name, mnl_attr_get_str(attr), len);
1946*7199c862SJiri Pirko 			dst->health_reporter_name[len] = 0;
1947*7199c862SJiri Pirko 		}
1948*7199c862SJiri Pirko 	}
1949*7199c862SJiri Pirko 
1950*7199c862SJiri Pirko 	return MNL_CB_OK;
1951*7199c862SJiri Pirko }
1952*7199c862SJiri Pirko 
1953*7199c862SJiri Pirko struct devlink_health_reporter_get_rsp *
1954*7199c862SJiri Pirko devlink_health_reporter_get(struct ynl_sock *ys,
1955*7199c862SJiri Pirko 			    struct devlink_health_reporter_get_req *req)
1956*7199c862SJiri Pirko {
1957*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1958*7199c862SJiri Pirko 	struct devlink_health_reporter_get_rsp *rsp;
1959*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
1960*7199c862SJiri Pirko 	int err;
1961*7199c862SJiri Pirko 
1962*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_GET, 1);
1963*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
1964*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
1965*7199c862SJiri Pirko 
1966*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
1967*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
1968*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
1969*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
1970*7199c862SJiri Pirko 	if (req->_present.port_index)
1971*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
1972*7199c862SJiri Pirko 	if (req->_present.health_reporter_name_len)
1973*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, req->health_reporter_name);
1974*7199c862SJiri Pirko 
1975*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
1976*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
1977*7199c862SJiri Pirko 	yrs.cb = devlink_health_reporter_get_rsp_parse;
1978*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_HEALTH_REPORTER_GET;
1979*7199c862SJiri Pirko 
1980*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
1981*7199c862SJiri Pirko 	if (err < 0)
1982*7199c862SJiri Pirko 		goto err_free;
1983*7199c862SJiri Pirko 
1984*7199c862SJiri Pirko 	return rsp;
1985*7199c862SJiri Pirko 
1986*7199c862SJiri Pirko err_free:
1987*7199c862SJiri Pirko 	devlink_health_reporter_get_rsp_free(rsp);
1988*7199c862SJiri Pirko 	return NULL;
1989*7199c862SJiri Pirko }
1990*7199c862SJiri Pirko 
1991*7199c862SJiri Pirko /* DEVLINK_CMD_HEALTH_REPORTER_GET - dump */
1992*7199c862SJiri Pirko void
1993*7199c862SJiri Pirko devlink_health_reporter_get_list_free(struct devlink_health_reporter_get_list *rsp)
1994*7199c862SJiri Pirko {
1995*7199c862SJiri Pirko 	struct devlink_health_reporter_get_list *next = rsp;
1996*7199c862SJiri Pirko 
1997*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
1998*7199c862SJiri Pirko 		rsp = next;
1999*7199c862SJiri Pirko 		next = rsp->next;
2000*7199c862SJiri Pirko 
2001*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
2002*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
2003*7199c862SJiri Pirko 		free(rsp->obj.health_reporter_name);
2004*7199c862SJiri Pirko 		free(rsp);
2005*7199c862SJiri Pirko 	}
2006*7199c862SJiri Pirko }
2007*7199c862SJiri Pirko 
2008*7199c862SJiri Pirko struct devlink_health_reporter_get_list *
2009*7199c862SJiri Pirko devlink_health_reporter_get_dump(struct ynl_sock *ys)
2010*7199c862SJiri Pirko {
2011*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
2012*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2013*7199c862SJiri Pirko 	int err;
2014*7199c862SJiri Pirko 
2015*7199c862SJiri Pirko 	yds.ys = ys;
2016*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_health_reporter_get_list);
2017*7199c862SJiri Pirko 	yds.cb = devlink_health_reporter_get_rsp_parse;
2018*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_HEALTH_REPORTER_GET;
2019*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
2020*7199c862SJiri Pirko 
2021*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_GET, 1);
2022*7199c862SJiri Pirko 
2023*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
2024*7199c862SJiri Pirko 	if (err < 0)
2025*7199c862SJiri Pirko 		goto free_list;
2026*7199c862SJiri Pirko 
2027*7199c862SJiri Pirko 	return yds.first;
2028*7199c862SJiri Pirko 
2029*7199c862SJiri Pirko free_list:
2030*7199c862SJiri Pirko 	devlink_health_reporter_get_list_free(yds.first);
2031*7199c862SJiri Pirko 	return NULL;
2032*7199c862SJiri Pirko }
2033*7199c862SJiri Pirko 
2034*7199c862SJiri Pirko /* ============== DEVLINK_CMD_TRAP_GET ============== */
2035*7199c862SJiri Pirko /* DEVLINK_CMD_TRAP_GET - do */
2036*7199c862SJiri Pirko void devlink_trap_get_req_free(struct devlink_trap_get_req *req)
2037*7199c862SJiri Pirko {
2038*7199c862SJiri Pirko 	free(req->bus_name);
2039*7199c862SJiri Pirko 	free(req->dev_name);
2040*7199c862SJiri Pirko 	free(req->trap_name);
2041*7199c862SJiri Pirko 	free(req);
2042*7199c862SJiri Pirko }
2043*7199c862SJiri Pirko 
2044*7199c862SJiri Pirko void devlink_trap_get_rsp_free(struct devlink_trap_get_rsp *rsp)
2045*7199c862SJiri Pirko {
2046*7199c862SJiri Pirko 	free(rsp->bus_name);
2047*7199c862SJiri Pirko 	free(rsp->dev_name);
2048*7199c862SJiri Pirko 	free(rsp->trap_name);
2049*7199c862SJiri Pirko 	free(rsp);
2050*7199c862SJiri Pirko }
2051*7199c862SJiri Pirko 
2052*7199c862SJiri Pirko int devlink_trap_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2053*7199c862SJiri Pirko {
2054*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
2055*7199c862SJiri Pirko 	struct devlink_trap_get_rsp *dst;
2056*7199c862SJiri Pirko 	const struct nlattr *attr;
2057*7199c862SJiri Pirko 
2058*7199c862SJiri Pirko 	dst = yarg->data;
2059*7199c862SJiri Pirko 
2060*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2061*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
2062*7199c862SJiri Pirko 
2063*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
2064*7199c862SJiri Pirko 			unsigned int len;
2065*7199c862SJiri Pirko 
2066*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2067*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2068*7199c862SJiri Pirko 
2069*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2070*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
2071*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
2072*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2073*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
2074*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2075*7199c862SJiri Pirko 			unsigned int len;
2076*7199c862SJiri Pirko 
2077*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2078*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2079*7199c862SJiri Pirko 
2080*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2081*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
2082*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
2083*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2084*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
2085*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_TRAP_NAME) {
2086*7199c862SJiri Pirko 			unsigned int len;
2087*7199c862SJiri Pirko 
2088*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2089*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2090*7199c862SJiri Pirko 
2091*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2092*7199c862SJiri Pirko 			dst->_present.trap_name_len = len;
2093*7199c862SJiri Pirko 			dst->trap_name = malloc(len + 1);
2094*7199c862SJiri Pirko 			memcpy(dst->trap_name, mnl_attr_get_str(attr), len);
2095*7199c862SJiri Pirko 			dst->trap_name[len] = 0;
2096*7199c862SJiri Pirko 		}
2097*7199c862SJiri Pirko 	}
2098*7199c862SJiri Pirko 
2099*7199c862SJiri Pirko 	return MNL_CB_OK;
2100*7199c862SJiri Pirko }
2101*7199c862SJiri Pirko 
2102*7199c862SJiri Pirko struct devlink_trap_get_rsp *
2103*7199c862SJiri Pirko devlink_trap_get(struct ynl_sock *ys, struct devlink_trap_get_req *req)
2104*7199c862SJiri Pirko {
2105*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2106*7199c862SJiri Pirko 	struct devlink_trap_get_rsp *rsp;
2107*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2108*7199c862SJiri Pirko 	int err;
2109*7199c862SJiri Pirko 
2110*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_GET, 1);
2111*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
2112*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
2113*7199c862SJiri Pirko 
2114*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
2115*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2116*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
2117*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2118*7199c862SJiri Pirko 	if (req->_present.trap_name_len)
2119*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_TRAP_NAME, req->trap_name);
2120*7199c862SJiri Pirko 
2121*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
2122*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
2123*7199c862SJiri Pirko 	yrs.cb = devlink_trap_get_rsp_parse;
2124*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_TRAP_GET;
2125*7199c862SJiri Pirko 
2126*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
2127*7199c862SJiri Pirko 	if (err < 0)
2128*7199c862SJiri Pirko 		goto err_free;
2129*7199c862SJiri Pirko 
2130*7199c862SJiri Pirko 	return rsp;
2131*7199c862SJiri Pirko 
2132*7199c862SJiri Pirko err_free:
2133*7199c862SJiri Pirko 	devlink_trap_get_rsp_free(rsp);
2134*7199c862SJiri Pirko 	return NULL;
2135*7199c862SJiri Pirko }
2136*7199c862SJiri Pirko 
2137*7199c862SJiri Pirko /* DEVLINK_CMD_TRAP_GET - dump */
2138*7199c862SJiri Pirko void devlink_trap_get_list_free(struct devlink_trap_get_list *rsp)
2139*7199c862SJiri Pirko {
2140*7199c862SJiri Pirko 	struct devlink_trap_get_list *next = rsp;
2141*7199c862SJiri Pirko 
2142*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
2143*7199c862SJiri Pirko 		rsp = next;
2144*7199c862SJiri Pirko 		next = rsp->next;
2145*7199c862SJiri Pirko 
2146*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
2147*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
2148*7199c862SJiri Pirko 		free(rsp->obj.trap_name);
2149*7199c862SJiri Pirko 		free(rsp);
2150*7199c862SJiri Pirko 	}
2151*7199c862SJiri Pirko }
2152*7199c862SJiri Pirko 
2153*7199c862SJiri Pirko struct devlink_trap_get_list *devlink_trap_get_dump(struct ynl_sock *ys)
2154*7199c862SJiri Pirko {
2155*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
2156*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2157*7199c862SJiri Pirko 	int err;
2158*7199c862SJiri Pirko 
2159*7199c862SJiri Pirko 	yds.ys = ys;
2160*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_trap_get_list);
2161*7199c862SJiri Pirko 	yds.cb = devlink_trap_get_rsp_parse;
2162*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_TRAP_GET;
2163*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
2164*7199c862SJiri Pirko 
2165*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_TRAP_GET, 1);
2166*7199c862SJiri Pirko 
2167*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
2168*7199c862SJiri Pirko 	if (err < 0)
2169*7199c862SJiri Pirko 		goto free_list;
2170*7199c862SJiri Pirko 
2171*7199c862SJiri Pirko 	return yds.first;
2172*7199c862SJiri Pirko 
2173*7199c862SJiri Pirko free_list:
2174*7199c862SJiri Pirko 	devlink_trap_get_list_free(yds.first);
2175*7199c862SJiri Pirko 	return NULL;
2176*7199c862SJiri Pirko }
2177*7199c862SJiri Pirko 
2178*7199c862SJiri Pirko /* ============== DEVLINK_CMD_TRAP_GROUP_GET ============== */
2179*7199c862SJiri Pirko /* DEVLINK_CMD_TRAP_GROUP_GET - do */
2180*7199c862SJiri Pirko void devlink_trap_group_get_req_free(struct devlink_trap_group_get_req *req)
2181*7199c862SJiri Pirko {
2182*7199c862SJiri Pirko 	free(req->bus_name);
2183*7199c862SJiri Pirko 	free(req->dev_name);
2184*7199c862SJiri Pirko 	free(req->trap_group_name);
2185*7199c862SJiri Pirko 	free(req);
2186*7199c862SJiri Pirko }
2187*7199c862SJiri Pirko 
2188*7199c862SJiri Pirko void devlink_trap_group_get_rsp_free(struct devlink_trap_group_get_rsp *rsp)
2189*7199c862SJiri Pirko {
2190*7199c862SJiri Pirko 	free(rsp->bus_name);
2191*7199c862SJiri Pirko 	free(rsp->dev_name);
2192*7199c862SJiri Pirko 	free(rsp->trap_group_name);
2193*7199c862SJiri Pirko 	free(rsp);
2194*7199c862SJiri Pirko }
2195*7199c862SJiri Pirko 
2196*7199c862SJiri Pirko int devlink_trap_group_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2197*7199c862SJiri Pirko {
2198*7199c862SJiri Pirko 	struct devlink_trap_group_get_rsp *dst;
2199*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
2200*7199c862SJiri Pirko 	const struct nlattr *attr;
2201*7199c862SJiri Pirko 
2202*7199c862SJiri Pirko 	dst = yarg->data;
2203*7199c862SJiri Pirko 
2204*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2205*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
2206*7199c862SJiri Pirko 
2207*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
2208*7199c862SJiri Pirko 			unsigned int len;
2209*7199c862SJiri Pirko 
2210*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2211*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2212*7199c862SJiri Pirko 
2213*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2214*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
2215*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
2216*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2217*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
2218*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2219*7199c862SJiri Pirko 			unsigned int len;
2220*7199c862SJiri Pirko 
2221*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2222*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2223*7199c862SJiri Pirko 
2224*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2225*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
2226*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
2227*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2228*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
2229*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_TRAP_GROUP_NAME) {
2230*7199c862SJiri Pirko 			unsigned int len;
2231*7199c862SJiri Pirko 
2232*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2233*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2234*7199c862SJiri Pirko 
2235*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2236*7199c862SJiri Pirko 			dst->_present.trap_group_name_len = len;
2237*7199c862SJiri Pirko 			dst->trap_group_name = malloc(len + 1);
2238*7199c862SJiri Pirko 			memcpy(dst->trap_group_name, mnl_attr_get_str(attr), len);
2239*7199c862SJiri Pirko 			dst->trap_group_name[len] = 0;
2240*7199c862SJiri Pirko 		}
2241*7199c862SJiri Pirko 	}
2242*7199c862SJiri Pirko 
2243*7199c862SJiri Pirko 	return MNL_CB_OK;
2244*7199c862SJiri Pirko }
2245*7199c862SJiri Pirko 
2246*7199c862SJiri Pirko struct devlink_trap_group_get_rsp *
2247*7199c862SJiri Pirko devlink_trap_group_get(struct ynl_sock *ys,
2248*7199c862SJiri Pirko 		       struct devlink_trap_group_get_req *req)
2249*7199c862SJiri Pirko {
2250*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2251*7199c862SJiri Pirko 	struct devlink_trap_group_get_rsp *rsp;
2252*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2253*7199c862SJiri Pirko 	int err;
2254*7199c862SJiri Pirko 
2255*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_GROUP_GET, 1);
2256*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
2257*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
2258*7199c862SJiri Pirko 
2259*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
2260*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2261*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
2262*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2263*7199c862SJiri Pirko 	if (req->_present.trap_group_name_len)
2264*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_TRAP_GROUP_NAME, req->trap_group_name);
2265*7199c862SJiri Pirko 
2266*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
2267*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
2268*7199c862SJiri Pirko 	yrs.cb = devlink_trap_group_get_rsp_parse;
2269*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_TRAP_GROUP_GET;
2270*7199c862SJiri Pirko 
2271*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
2272*7199c862SJiri Pirko 	if (err < 0)
2273*7199c862SJiri Pirko 		goto err_free;
2274*7199c862SJiri Pirko 
2275*7199c862SJiri Pirko 	return rsp;
2276*7199c862SJiri Pirko 
2277*7199c862SJiri Pirko err_free:
2278*7199c862SJiri Pirko 	devlink_trap_group_get_rsp_free(rsp);
2279*7199c862SJiri Pirko 	return NULL;
2280*7199c862SJiri Pirko }
2281*7199c862SJiri Pirko 
2282*7199c862SJiri Pirko /* DEVLINK_CMD_TRAP_GROUP_GET - dump */
2283*7199c862SJiri Pirko void devlink_trap_group_get_list_free(struct devlink_trap_group_get_list *rsp)
2284*7199c862SJiri Pirko {
2285*7199c862SJiri Pirko 	struct devlink_trap_group_get_list *next = rsp;
2286*7199c862SJiri Pirko 
2287*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
2288*7199c862SJiri Pirko 		rsp = next;
2289*7199c862SJiri Pirko 		next = rsp->next;
2290*7199c862SJiri Pirko 
2291*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
2292*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
2293*7199c862SJiri Pirko 		free(rsp->obj.trap_group_name);
2294*7199c862SJiri Pirko 		free(rsp);
2295*7199c862SJiri Pirko 	}
2296*7199c862SJiri Pirko }
2297*7199c862SJiri Pirko 
2298*7199c862SJiri Pirko struct devlink_trap_group_get_list *
2299*7199c862SJiri Pirko devlink_trap_group_get_dump(struct ynl_sock *ys)
2300*7199c862SJiri Pirko {
2301*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
2302*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2303*7199c862SJiri Pirko 	int err;
2304*7199c862SJiri Pirko 
2305*7199c862SJiri Pirko 	yds.ys = ys;
2306*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_trap_group_get_list);
2307*7199c862SJiri Pirko 	yds.cb = devlink_trap_group_get_rsp_parse;
2308*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_TRAP_GROUP_GET;
2309*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
2310*7199c862SJiri Pirko 
2311*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_TRAP_GROUP_GET, 1);
2312*7199c862SJiri Pirko 
2313*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
2314*7199c862SJiri Pirko 	if (err < 0)
2315*7199c862SJiri Pirko 		goto free_list;
2316*7199c862SJiri Pirko 
2317*7199c862SJiri Pirko 	return yds.first;
2318*7199c862SJiri Pirko 
2319*7199c862SJiri Pirko free_list:
2320*7199c862SJiri Pirko 	devlink_trap_group_get_list_free(yds.first);
2321*7199c862SJiri Pirko 	return NULL;
2322*7199c862SJiri Pirko }
2323*7199c862SJiri Pirko 
2324*7199c862SJiri Pirko /* ============== DEVLINK_CMD_TRAP_POLICER_GET ============== */
2325*7199c862SJiri Pirko /* DEVLINK_CMD_TRAP_POLICER_GET - do */
2326*7199c862SJiri Pirko void
2327*7199c862SJiri Pirko devlink_trap_policer_get_req_free(struct devlink_trap_policer_get_req *req)
2328*7199c862SJiri Pirko {
2329*7199c862SJiri Pirko 	free(req->bus_name);
2330*7199c862SJiri Pirko 	free(req->dev_name);
2331*7199c862SJiri Pirko 	free(req);
2332*7199c862SJiri Pirko }
2333*7199c862SJiri Pirko 
2334*7199c862SJiri Pirko void
2335*7199c862SJiri Pirko devlink_trap_policer_get_rsp_free(struct devlink_trap_policer_get_rsp *rsp)
2336*7199c862SJiri Pirko {
2337*7199c862SJiri Pirko 	free(rsp->bus_name);
2338*7199c862SJiri Pirko 	free(rsp->dev_name);
2339*7199c862SJiri Pirko 	free(rsp);
2340*7199c862SJiri Pirko }
2341*7199c862SJiri Pirko 
2342*7199c862SJiri Pirko int devlink_trap_policer_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2343*7199c862SJiri Pirko {
2344*7199c862SJiri Pirko 	struct devlink_trap_policer_get_rsp *dst;
2345*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
2346*7199c862SJiri Pirko 	const struct nlattr *attr;
2347*7199c862SJiri Pirko 
2348*7199c862SJiri Pirko 	dst = yarg->data;
2349*7199c862SJiri Pirko 
2350*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2351*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
2352*7199c862SJiri Pirko 
2353*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
2354*7199c862SJiri Pirko 			unsigned int len;
2355*7199c862SJiri Pirko 
2356*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2357*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2358*7199c862SJiri Pirko 
2359*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2360*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
2361*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
2362*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2363*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
2364*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2365*7199c862SJiri Pirko 			unsigned int len;
2366*7199c862SJiri Pirko 
2367*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2368*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2369*7199c862SJiri Pirko 
2370*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2371*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
2372*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
2373*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2374*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
2375*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_TRAP_POLICER_ID) {
2376*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2377*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2378*7199c862SJiri Pirko 			dst->_present.trap_policer_id = 1;
2379*7199c862SJiri Pirko 			dst->trap_policer_id = mnl_attr_get_u32(attr);
2380*7199c862SJiri Pirko 		}
2381*7199c862SJiri Pirko 	}
2382*7199c862SJiri Pirko 
2383*7199c862SJiri Pirko 	return MNL_CB_OK;
2384*7199c862SJiri Pirko }
2385*7199c862SJiri Pirko 
2386*7199c862SJiri Pirko struct devlink_trap_policer_get_rsp *
2387*7199c862SJiri Pirko devlink_trap_policer_get(struct ynl_sock *ys,
2388*7199c862SJiri Pirko 			 struct devlink_trap_policer_get_req *req)
2389*7199c862SJiri Pirko {
2390*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2391*7199c862SJiri Pirko 	struct devlink_trap_policer_get_rsp *rsp;
2392*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2393*7199c862SJiri Pirko 	int err;
2394*7199c862SJiri Pirko 
2395*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_POLICER_GET, 1);
2396*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
2397*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
2398*7199c862SJiri Pirko 
2399*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
2400*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2401*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
2402*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2403*7199c862SJiri Pirko 	if (req->_present.trap_policer_id)
2404*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_TRAP_POLICER_ID, req->trap_policer_id);
2405*7199c862SJiri Pirko 
2406*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
2407*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
2408*7199c862SJiri Pirko 	yrs.cb = devlink_trap_policer_get_rsp_parse;
2409*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_TRAP_POLICER_GET;
2410*7199c862SJiri Pirko 
2411*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
2412*7199c862SJiri Pirko 	if (err < 0)
2413*7199c862SJiri Pirko 		goto err_free;
2414*7199c862SJiri Pirko 
2415*7199c862SJiri Pirko 	return rsp;
2416*7199c862SJiri Pirko 
2417*7199c862SJiri Pirko err_free:
2418*7199c862SJiri Pirko 	devlink_trap_policer_get_rsp_free(rsp);
2419*7199c862SJiri Pirko 	return NULL;
2420*7199c862SJiri Pirko }
2421*7199c862SJiri Pirko 
2422*7199c862SJiri Pirko /* DEVLINK_CMD_TRAP_POLICER_GET - dump */
2423*7199c862SJiri Pirko void
2424*7199c862SJiri Pirko devlink_trap_policer_get_list_free(struct devlink_trap_policer_get_list *rsp)
2425*7199c862SJiri Pirko {
2426*7199c862SJiri Pirko 	struct devlink_trap_policer_get_list *next = rsp;
2427*7199c862SJiri Pirko 
2428*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
2429*7199c862SJiri Pirko 		rsp = next;
2430*7199c862SJiri Pirko 		next = rsp->next;
2431*7199c862SJiri Pirko 
2432*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
2433*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
2434*7199c862SJiri Pirko 		free(rsp);
2435*7199c862SJiri Pirko 	}
2436*7199c862SJiri Pirko }
2437*7199c862SJiri Pirko 
2438*7199c862SJiri Pirko struct devlink_trap_policer_get_list *
2439*7199c862SJiri Pirko devlink_trap_policer_get_dump(struct ynl_sock *ys)
2440*7199c862SJiri Pirko {
2441*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
2442*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2443*7199c862SJiri Pirko 	int err;
2444*7199c862SJiri Pirko 
2445*7199c862SJiri Pirko 	yds.ys = ys;
2446*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_trap_policer_get_list);
2447*7199c862SJiri Pirko 	yds.cb = devlink_trap_policer_get_rsp_parse;
2448*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_TRAP_POLICER_GET;
2449*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
2450*7199c862SJiri Pirko 
2451*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_TRAP_POLICER_GET, 1);
2452*7199c862SJiri Pirko 
2453*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
2454*7199c862SJiri Pirko 	if (err < 0)
2455*7199c862SJiri Pirko 		goto free_list;
2456*7199c862SJiri Pirko 
2457*7199c862SJiri Pirko 	return yds.first;
2458*7199c862SJiri Pirko 
2459*7199c862SJiri Pirko free_list:
2460*7199c862SJiri Pirko 	devlink_trap_policer_get_list_free(yds.first);
2461*7199c862SJiri Pirko 	return NULL;
2462*7199c862SJiri Pirko }
2463*7199c862SJiri Pirko 
2464*7199c862SJiri Pirko /* ============== DEVLINK_CMD_RATE_GET ============== */
2465*7199c862SJiri Pirko /* DEVLINK_CMD_RATE_GET - do */
2466*7199c862SJiri Pirko void devlink_rate_get_req_free(struct devlink_rate_get_req *req)
2467*7199c862SJiri Pirko {
2468*7199c862SJiri Pirko 	free(req->bus_name);
2469*7199c862SJiri Pirko 	free(req->dev_name);
2470*7199c862SJiri Pirko 	free(req->rate_node_name);
2471*7199c862SJiri Pirko 	free(req);
2472*7199c862SJiri Pirko }
2473*7199c862SJiri Pirko 
2474*7199c862SJiri Pirko void devlink_rate_get_rsp_free(struct devlink_rate_get_rsp *rsp)
2475*7199c862SJiri Pirko {
2476*7199c862SJiri Pirko 	free(rsp->bus_name);
2477*7199c862SJiri Pirko 	free(rsp->dev_name);
2478*7199c862SJiri Pirko 	free(rsp->rate_node_name);
2479*7199c862SJiri Pirko 	free(rsp);
2480*7199c862SJiri Pirko }
2481*7199c862SJiri Pirko 
2482*7199c862SJiri Pirko int devlink_rate_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2483*7199c862SJiri Pirko {
2484*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
2485*7199c862SJiri Pirko 	struct devlink_rate_get_rsp *dst;
2486*7199c862SJiri Pirko 	const struct nlattr *attr;
2487*7199c862SJiri Pirko 
2488*7199c862SJiri Pirko 	dst = yarg->data;
2489*7199c862SJiri Pirko 
2490*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2491*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
2492*7199c862SJiri Pirko 
2493*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
2494*7199c862SJiri Pirko 			unsigned int len;
2495*7199c862SJiri Pirko 
2496*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2497*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2498*7199c862SJiri Pirko 
2499*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2500*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
2501*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
2502*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2503*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
2504*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2505*7199c862SJiri Pirko 			unsigned int len;
2506*7199c862SJiri Pirko 
2507*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2508*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2509*7199c862SJiri Pirko 
2510*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2511*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
2512*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
2513*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2514*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
2515*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_PORT_INDEX) {
2516*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2517*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2518*7199c862SJiri Pirko 			dst->_present.port_index = 1;
2519*7199c862SJiri Pirko 			dst->port_index = mnl_attr_get_u32(attr);
2520*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_RATE_NODE_NAME) {
2521*7199c862SJiri Pirko 			unsigned int len;
2522*7199c862SJiri Pirko 
2523*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2524*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2525*7199c862SJiri Pirko 
2526*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2527*7199c862SJiri Pirko 			dst->_present.rate_node_name_len = len;
2528*7199c862SJiri Pirko 			dst->rate_node_name = malloc(len + 1);
2529*7199c862SJiri Pirko 			memcpy(dst->rate_node_name, mnl_attr_get_str(attr), len);
2530*7199c862SJiri Pirko 			dst->rate_node_name[len] = 0;
2531*7199c862SJiri Pirko 		}
2532*7199c862SJiri Pirko 	}
2533*7199c862SJiri Pirko 
2534*7199c862SJiri Pirko 	return MNL_CB_OK;
2535*7199c862SJiri Pirko }
2536*7199c862SJiri Pirko 
2537*7199c862SJiri Pirko struct devlink_rate_get_rsp *
2538*7199c862SJiri Pirko devlink_rate_get(struct ynl_sock *ys, struct devlink_rate_get_req *req)
2539*7199c862SJiri Pirko {
2540*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2541*7199c862SJiri Pirko 	struct devlink_rate_get_rsp *rsp;
2542*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2543*7199c862SJiri Pirko 	int err;
2544*7199c862SJiri Pirko 
2545*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_RATE_GET, 1);
2546*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
2547*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
2548*7199c862SJiri Pirko 
2549*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
2550*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2551*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
2552*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2553*7199c862SJiri Pirko 	if (req->_present.port_index)
2554*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index);
2555*7199c862SJiri Pirko 	if (req->_present.rate_node_name_len)
2556*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_RATE_NODE_NAME, req->rate_node_name);
2557*7199c862SJiri Pirko 
2558*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
2559*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
2560*7199c862SJiri Pirko 	yrs.cb = devlink_rate_get_rsp_parse;
2561*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_RATE_GET;
2562*7199c862SJiri Pirko 
2563*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
2564*7199c862SJiri Pirko 	if (err < 0)
2565*7199c862SJiri Pirko 		goto err_free;
2566*7199c862SJiri Pirko 
2567*7199c862SJiri Pirko 	return rsp;
2568*7199c862SJiri Pirko 
2569*7199c862SJiri Pirko err_free:
2570*7199c862SJiri Pirko 	devlink_rate_get_rsp_free(rsp);
2571*7199c862SJiri Pirko 	return NULL;
2572*7199c862SJiri Pirko }
2573*7199c862SJiri Pirko 
2574*7199c862SJiri Pirko /* DEVLINK_CMD_RATE_GET - dump */
2575*7199c862SJiri Pirko void devlink_rate_get_list_free(struct devlink_rate_get_list *rsp)
2576*7199c862SJiri Pirko {
2577*7199c862SJiri Pirko 	struct devlink_rate_get_list *next = rsp;
2578*7199c862SJiri Pirko 
2579*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
2580*7199c862SJiri Pirko 		rsp = next;
2581*7199c862SJiri Pirko 		next = rsp->next;
2582*7199c862SJiri Pirko 
2583*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
2584*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
2585*7199c862SJiri Pirko 		free(rsp->obj.rate_node_name);
2586*7199c862SJiri Pirko 		free(rsp);
2587*7199c862SJiri Pirko 	}
2588*7199c862SJiri Pirko }
2589*7199c862SJiri Pirko 
2590*7199c862SJiri Pirko struct devlink_rate_get_list *devlink_rate_get_dump(struct ynl_sock *ys)
2591*7199c862SJiri Pirko {
2592*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
2593*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2594*7199c862SJiri Pirko 	int err;
2595*7199c862SJiri Pirko 
2596*7199c862SJiri Pirko 	yds.ys = ys;
2597*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_rate_get_list);
2598*7199c862SJiri Pirko 	yds.cb = devlink_rate_get_rsp_parse;
2599*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_RATE_GET;
2600*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
2601*7199c862SJiri Pirko 
2602*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_RATE_GET, 1);
2603*7199c862SJiri Pirko 
2604*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
2605*7199c862SJiri Pirko 	if (err < 0)
2606*7199c862SJiri Pirko 		goto free_list;
2607*7199c862SJiri Pirko 
2608*7199c862SJiri Pirko 	return yds.first;
2609*7199c862SJiri Pirko 
2610*7199c862SJiri Pirko free_list:
2611*7199c862SJiri Pirko 	devlink_rate_get_list_free(yds.first);
2612*7199c862SJiri Pirko 	return NULL;
2613*7199c862SJiri Pirko }
2614*7199c862SJiri Pirko 
2615*7199c862SJiri Pirko /* ============== DEVLINK_CMD_LINECARD_GET ============== */
2616*7199c862SJiri Pirko /* DEVLINK_CMD_LINECARD_GET - do */
2617*7199c862SJiri Pirko void devlink_linecard_get_req_free(struct devlink_linecard_get_req *req)
2618*7199c862SJiri Pirko {
2619*7199c862SJiri Pirko 	free(req->bus_name);
2620*7199c862SJiri Pirko 	free(req->dev_name);
2621*7199c862SJiri Pirko 	free(req);
2622*7199c862SJiri Pirko }
2623*7199c862SJiri Pirko 
2624*7199c862SJiri Pirko void devlink_linecard_get_rsp_free(struct devlink_linecard_get_rsp *rsp)
2625*7199c862SJiri Pirko {
2626*7199c862SJiri Pirko 	free(rsp->bus_name);
2627*7199c862SJiri Pirko 	free(rsp->dev_name);
2628*7199c862SJiri Pirko 	free(rsp);
2629*7199c862SJiri Pirko }
2630*7199c862SJiri Pirko 
2631*7199c862SJiri Pirko int devlink_linecard_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2632*7199c862SJiri Pirko {
2633*7199c862SJiri Pirko 	struct devlink_linecard_get_rsp *dst;
2634*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
2635*7199c862SJiri Pirko 	const struct nlattr *attr;
2636*7199c862SJiri Pirko 
2637*7199c862SJiri Pirko 	dst = yarg->data;
2638*7199c862SJiri Pirko 
2639*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2640*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
2641*7199c862SJiri Pirko 
2642*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
2643*7199c862SJiri Pirko 			unsigned int len;
2644*7199c862SJiri Pirko 
2645*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2646*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2647*7199c862SJiri Pirko 
2648*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2649*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
2650*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
2651*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2652*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
2653*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2654*7199c862SJiri Pirko 			unsigned int len;
2655*7199c862SJiri Pirko 
2656*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2657*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2658*7199c862SJiri Pirko 
2659*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2660*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
2661*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
2662*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2663*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
2664*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_LINECARD_INDEX) {
2665*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2666*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2667*7199c862SJiri Pirko 			dst->_present.linecard_index = 1;
2668*7199c862SJiri Pirko 			dst->linecard_index = mnl_attr_get_u32(attr);
2669*7199c862SJiri Pirko 		}
2670*7199c862SJiri Pirko 	}
2671*7199c862SJiri Pirko 
2672*7199c862SJiri Pirko 	return MNL_CB_OK;
2673*7199c862SJiri Pirko }
2674*7199c862SJiri Pirko 
2675*7199c862SJiri Pirko struct devlink_linecard_get_rsp *
2676*7199c862SJiri Pirko devlink_linecard_get(struct ynl_sock *ys, struct devlink_linecard_get_req *req)
2677*7199c862SJiri Pirko {
2678*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2679*7199c862SJiri Pirko 	struct devlink_linecard_get_rsp *rsp;
2680*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2681*7199c862SJiri Pirko 	int err;
2682*7199c862SJiri Pirko 
2683*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_LINECARD_GET, 1);
2684*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
2685*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
2686*7199c862SJiri Pirko 
2687*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
2688*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2689*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
2690*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2691*7199c862SJiri Pirko 	if (req->_present.linecard_index)
2692*7199c862SJiri Pirko 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_LINECARD_INDEX, req->linecard_index);
2693*7199c862SJiri Pirko 
2694*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
2695*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
2696*7199c862SJiri Pirko 	yrs.cb = devlink_linecard_get_rsp_parse;
2697*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_LINECARD_GET;
2698*7199c862SJiri Pirko 
2699*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
2700*7199c862SJiri Pirko 	if (err < 0)
2701*7199c862SJiri Pirko 		goto err_free;
2702*7199c862SJiri Pirko 
2703*7199c862SJiri Pirko 	return rsp;
2704*7199c862SJiri Pirko 
2705*7199c862SJiri Pirko err_free:
2706*7199c862SJiri Pirko 	devlink_linecard_get_rsp_free(rsp);
2707*7199c862SJiri Pirko 	return NULL;
2708*7199c862SJiri Pirko }
2709*7199c862SJiri Pirko 
2710*7199c862SJiri Pirko /* DEVLINK_CMD_LINECARD_GET - dump */
2711*7199c862SJiri Pirko void devlink_linecard_get_list_free(struct devlink_linecard_get_list *rsp)
2712*7199c862SJiri Pirko {
2713*7199c862SJiri Pirko 	struct devlink_linecard_get_list *next = rsp;
2714*7199c862SJiri Pirko 
2715*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
2716*7199c862SJiri Pirko 		rsp = next;
2717*7199c862SJiri Pirko 		next = rsp->next;
2718*7199c862SJiri Pirko 
2719*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
2720*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
2721*7199c862SJiri Pirko 		free(rsp);
2722*7199c862SJiri Pirko 	}
2723*7199c862SJiri Pirko }
2724*7199c862SJiri Pirko 
2725*7199c862SJiri Pirko struct devlink_linecard_get_list *
2726*7199c862SJiri Pirko devlink_linecard_get_dump(struct ynl_sock *ys)
2727*7199c862SJiri Pirko {
2728*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
2729*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2730*7199c862SJiri Pirko 	int err;
2731*7199c862SJiri Pirko 
2732*7199c862SJiri Pirko 	yds.ys = ys;
2733*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_linecard_get_list);
2734*7199c862SJiri Pirko 	yds.cb = devlink_linecard_get_rsp_parse;
2735*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_LINECARD_GET;
2736*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
2737*7199c862SJiri Pirko 
2738*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_LINECARD_GET, 1);
2739*7199c862SJiri Pirko 
2740*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
2741*7199c862SJiri Pirko 	if (err < 0)
2742*7199c862SJiri Pirko 		goto free_list;
2743*7199c862SJiri Pirko 
2744*7199c862SJiri Pirko 	return yds.first;
2745*7199c862SJiri Pirko 
2746*7199c862SJiri Pirko free_list:
2747*7199c862SJiri Pirko 	devlink_linecard_get_list_free(yds.first);
2748*7199c862SJiri Pirko 	return NULL;
2749*7199c862SJiri Pirko }
2750*7199c862SJiri Pirko 
2751*7199c862SJiri Pirko /* ============== DEVLINK_CMD_SELFTESTS_GET ============== */
2752*7199c862SJiri Pirko /* DEVLINK_CMD_SELFTESTS_GET - do */
2753*7199c862SJiri Pirko void devlink_selftests_get_req_free(struct devlink_selftests_get_req *req)
2754*7199c862SJiri Pirko {
2755*7199c862SJiri Pirko 	free(req->bus_name);
2756*7199c862SJiri Pirko 	free(req->dev_name);
2757*7199c862SJiri Pirko 	free(req);
2758*7199c862SJiri Pirko }
2759*7199c862SJiri Pirko 
2760*7199c862SJiri Pirko void devlink_selftests_get_rsp_free(struct devlink_selftests_get_rsp *rsp)
2761*7199c862SJiri Pirko {
2762*7199c862SJiri Pirko 	free(rsp->bus_name);
2763*7199c862SJiri Pirko 	free(rsp->dev_name);
2764*7199c862SJiri Pirko 	free(rsp);
2765*7199c862SJiri Pirko }
2766*7199c862SJiri Pirko 
2767*7199c862SJiri Pirko int devlink_selftests_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2768*7199c862SJiri Pirko {
2769*7199c862SJiri Pirko 	struct devlink_selftests_get_rsp *dst;
2770*7199c862SJiri Pirko 	struct ynl_parse_arg *yarg = data;
2771*7199c862SJiri Pirko 	const struct nlattr *attr;
2772*7199c862SJiri Pirko 
2773*7199c862SJiri Pirko 	dst = yarg->data;
2774*7199c862SJiri Pirko 
2775*7199c862SJiri Pirko 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2776*7199c862SJiri Pirko 		unsigned int type = mnl_attr_get_type(attr);
2777*7199c862SJiri Pirko 
2778*7199c862SJiri Pirko 		if (type == DEVLINK_ATTR_BUS_NAME) {
2779*7199c862SJiri Pirko 			unsigned int len;
2780*7199c862SJiri Pirko 
2781*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2782*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2783*7199c862SJiri Pirko 
2784*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2785*7199c862SJiri Pirko 			dst->_present.bus_name_len = len;
2786*7199c862SJiri Pirko 			dst->bus_name = malloc(len + 1);
2787*7199c862SJiri Pirko 			memcpy(dst->bus_name, mnl_attr_get_str(attr), len);
2788*7199c862SJiri Pirko 			dst->bus_name[len] = 0;
2789*7199c862SJiri Pirko 		} else if (type == DEVLINK_ATTR_DEV_NAME) {
2790*7199c862SJiri Pirko 			unsigned int len;
2791*7199c862SJiri Pirko 
2792*7199c862SJiri Pirko 			if (ynl_attr_validate(yarg, attr))
2793*7199c862SJiri Pirko 				return MNL_CB_ERROR;
2794*7199c862SJiri Pirko 
2795*7199c862SJiri Pirko 			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
2796*7199c862SJiri Pirko 			dst->_present.dev_name_len = len;
2797*7199c862SJiri Pirko 			dst->dev_name = malloc(len + 1);
2798*7199c862SJiri Pirko 			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
2799*7199c862SJiri Pirko 			dst->dev_name[len] = 0;
2800*7199c862SJiri Pirko 		}
2801*7199c862SJiri Pirko 	}
2802*7199c862SJiri Pirko 
2803*7199c862SJiri Pirko 	return MNL_CB_OK;
2804*7199c862SJiri Pirko }
2805*7199c862SJiri Pirko 
2806*7199c862SJiri Pirko struct devlink_selftests_get_rsp *
2807*7199c862SJiri Pirko devlink_selftests_get(struct ynl_sock *ys,
2808*7199c862SJiri Pirko 		      struct devlink_selftests_get_req *req)
2809*7199c862SJiri Pirko {
2810*7199c862SJiri Pirko 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2811*7199c862SJiri Pirko 	struct devlink_selftests_get_rsp *rsp;
2812*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2813*7199c862SJiri Pirko 	int err;
2814*7199c862SJiri Pirko 
2815*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SELFTESTS_GET, 1);
2816*7199c862SJiri Pirko 	ys->req_policy = &devlink_nest;
2817*7199c862SJiri Pirko 	yrs.yarg.rsp_policy = &devlink_nest;
2818*7199c862SJiri Pirko 
2819*7199c862SJiri Pirko 	if (req->_present.bus_name_len)
2820*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name);
2821*7199c862SJiri Pirko 	if (req->_present.dev_name_len)
2822*7199c862SJiri Pirko 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name);
2823*7199c862SJiri Pirko 
2824*7199c862SJiri Pirko 	rsp = calloc(1, sizeof(*rsp));
2825*7199c862SJiri Pirko 	yrs.yarg.data = rsp;
2826*7199c862SJiri Pirko 	yrs.cb = devlink_selftests_get_rsp_parse;
2827*7199c862SJiri Pirko 	yrs.rsp_cmd = DEVLINK_CMD_SELFTESTS_GET;
2828*7199c862SJiri Pirko 
2829*7199c862SJiri Pirko 	err = ynl_exec(ys, nlh, &yrs);
2830*7199c862SJiri Pirko 	if (err < 0)
2831*7199c862SJiri Pirko 		goto err_free;
2832*7199c862SJiri Pirko 
2833*7199c862SJiri Pirko 	return rsp;
2834*7199c862SJiri Pirko 
2835*7199c862SJiri Pirko err_free:
2836*7199c862SJiri Pirko 	devlink_selftests_get_rsp_free(rsp);
2837*7199c862SJiri Pirko 	return NULL;
2838*7199c862SJiri Pirko }
2839*7199c862SJiri Pirko 
2840*7199c862SJiri Pirko /* DEVLINK_CMD_SELFTESTS_GET - dump */
2841*7199c862SJiri Pirko void devlink_selftests_get_list_free(struct devlink_selftests_get_list *rsp)
2842*7199c862SJiri Pirko {
2843*7199c862SJiri Pirko 	struct devlink_selftests_get_list *next = rsp;
2844*7199c862SJiri Pirko 
2845*7199c862SJiri Pirko 	while ((void *)next != YNL_LIST_END) {
2846*7199c862SJiri Pirko 		rsp = next;
2847*7199c862SJiri Pirko 		next = rsp->next;
2848*7199c862SJiri Pirko 
2849*7199c862SJiri Pirko 		free(rsp->obj.bus_name);
2850*7199c862SJiri Pirko 		free(rsp->obj.dev_name);
2851*7199c862SJiri Pirko 		free(rsp);
2852*7199c862SJiri Pirko 	}
2853*7199c862SJiri Pirko }
2854*7199c862SJiri Pirko 
2855*7199c862SJiri Pirko struct devlink_selftests_get_list *
2856*7199c862SJiri Pirko devlink_selftests_get_dump(struct ynl_sock *ys)
2857*7199c862SJiri Pirko {
2858*7199c862SJiri Pirko 	struct ynl_dump_state yds = {};
2859*7199c862SJiri Pirko 	struct nlmsghdr *nlh;
2860*7199c862SJiri Pirko 	int err;
2861*7199c862SJiri Pirko 
2862*7199c862SJiri Pirko 	yds.ys = ys;
2863*7199c862SJiri Pirko 	yds.alloc_sz = sizeof(struct devlink_selftests_get_list);
2864*7199c862SJiri Pirko 	yds.cb = devlink_selftests_get_rsp_parse;
2865*7199c862SJiri Pirko 	yds.rsp_cmd = DEVLINK_CMD_SELFTESTS_GET;
2866*7199c862SJiri Pirko 	yds.rsp_policy = &devlink_nest;
2867*7199c862SJiri Pirko 
2868*7199c862SJiri Pirko 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SELFTESTS_GET, 1);
2869*7199c862SJiri Pirko 
2870*7199c862SJiri Pirko 	err = ynl_exec_dump(ys, nlh, &yds);
2871*7199c862SJiri Pirko 	if (err < 0)
2872*7199c862SJiri Pirko 		goto free_list;
2873*7199c862SJiri Pirko 
2874*7199c862SJiri Pirko 	return yds.first;
2875*7199c862SJiri Pirko 
2876*7199c862SJiri Pirko free_list:
2877*7199c862SJiri Pirko 	devlink_selftests_get_list_free(yds.first);
2878*7199c862SJiri Pirko 	return NULL;
2879*7199c862SJiri Pirko }
2880*7199c862SJiri Pirko 
28815d1a30ebSJakub Kicinski const struct ynl_family ynl_devlink_family =  {
28825d1a30ebSJakub Kicinski 	.name		= "devlink",
28835d1a30ebSJakub Kicinski };
2884