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", 185d1a30ebSJakub Kicinski [DEVLINK_CMD_INFO_GET] = "info-get", 195d1a30ebSJakub Kicinski }; 205d1a30ebSJakub Kicinski 215d1a30ebSJakub Kicinski const char *devlink_op_str(int op) 225d1a30ebSJakub Kicinski { 235d1a30ebSJakub Kicinski if (op < 0 || op >= (int)MNL_ARRAY_SIZE(devlink_op_strmap)) 245d1a30ebSJakub Kicinski return NULL; 255d1a30ebSJakub Kicinski return devlink_op_strmap[op]; 265d1a30ebSJakub Kicinski } 275d1a30ebSJakub Kicinski 285d1a30ebSJakub Kicinski /* Policies */ 295d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_info_version_policy[DEVLINK_ATTR_MAX + 1] = { 305d1a30ebSJakub Kicinski [DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, }, 315d1a30ebSJakub Kicinski [DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, }, 325d1a30ebSJakub Kicinski }; 335d1a30ebSJakub Kicinski 345d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_info_version_nest = { 355d1a30ebSJakub Kicinski .max_attr = DEVLINK_ATTR_MAX, 365d1a30ebSJakub Kicinski .table = devlink_dl_info_version_policy, 375d1a30ebSJakub Kicinski }; 385d1a30ebSJakub Kicinski 395d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_reload_stats_entry_policy[DEVLINK_ATTR_MAX + 1] = { 405d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, }, 415d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, }, 425d1a30ebSJakub Kicinski }; 435d1a30ebSJakub Kicinski 445d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_reload_stats_entry_nest = { 455d1a30ebSJakub Kicinski .max_attr = DEVLINK_ATTR_MAX, 465d1a30ebSJakub Kicinski .table = devlink_dl_reload_stats_entry_policy, 475d1a30ebSJakub Kicinski }; 485d1a30ebSJakub Kicinski 495d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_reload_act_stats_policy[DEVLINK_ATTR_MAX + 1] = { 505d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, }, 515d1a30ebSJakub Kicinski }; 525d1a30ebSJakub Kicinski 535d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_reload_act_stats_nest = { 545d1a30ebSJakub Kicinski .max_attr = DEVLINK_ATTR_MAX, 555d1a30ebSJakub Kicinski .table = devlink_dl_reload_act_stats_policy, 565d1a30ebSJakub Kicinski }; 575d1a30ebSJakub Kicinski 585d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_reload_act_info_policy[DEVLINK_ATTR_MAX + 1] = { 595d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, }, 605d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, }, 615d1a30ebSJakub Kicinski }; 625d1a30ebSJakub Kicinski 635d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_reload_act_info_nest = { 645d1a30ebSJakub Kicinski .max_attr = DEVLINK_ATTR_MAX, 655d1a30ebSJakub Kicinski .table = devlink_dl_reload_act_info_policy, 665d1a30ebSJakub Kicinski }; 675d1a30ebSJakub Kicinski 685d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_reload_stats_policy[DEVLINK_ATTR_MAX + 1] = { 695d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, }, 705d1a30ebSJakub Kicinski }; 715d1a30ebSJakub Kicinski 725d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_reload_stats_nest = { 735d1a30ebSJakub Kicinski .max_attr = DEVLINK_ATTR_MAX, 745d1a30ebSJakub Kicinski .table = devlink_dl_reload_stats_policy, 755d1a30ebSJakub Kicinski }; 765d1a30ebSJakub Kicinski 775d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_dl_dev_stats_policy[DEVLINK_ATTR_MAX + 1] = { 785d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, }, 795d1a30ebSJakub Kicinski [DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, }, 805d1a30ebSJakub Kicinski }; 815d1a30ebSJakub Kicinski 825d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_dl_dev_stats_nest = { 835d1a30ebSJakub Kicinski .max_attr = DEVLINK_ATTR_MAX, 845d1a30ebSJakub Kicinski .table = devlink_dl_dev_stats_policy, 855d1a30ebSJakub Kicinski }; 865d1a30ebSJakub Kicinski 875d1a30ebSJakub Kicinski struct ynl_policy_attr devlink_policy[DEVLINK_ATTR_MAX + 1] = { 885d1a30ebSJakub Kicinski [DEVLINK_ATTR_BUS_NAME] = { .name = "bus-name", .type = YNL_PT_NUL_STR, }, 895d1a30ebSJakub Kicinski [DEVLINK_ATTR_DEV_NAME] = { .name = "dev-name", .type = YNL_PT_NUL_STR, }, 905d1a30ebSJakub Kicinski [DEVLINK_ATTR_PORT_INDEX] = { .name = "port-index", .type = YNL_PT_U32, }, 915d1a30ebSJakub Kicinski [DEVLINK_ATTR_INFO_DRIVER_NAME] = { .name = "info-driver-name", .type = YNL_PT_NUL_STR, }, 925d1a30ebSJakub Kicinski [DEVLINK_ATTR_INFO_SERIAL_NUMBER] = { .name = "info-serial-number", .type = YNL_PT_NUL_STR, }, 935d1a30ebSJakub Kicinski [DEVLINK_ATTR_INFO_VERSION_FIXED] = { .name = "info-version-fixed", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, }, 945d1a30ebSJakub Kicinski [DEVLINK_ATTR_INFO_VERSION_RUNNING] = { .name = "info-version-running", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, }, 955d1a30ebSJakub Kicinski [DEVLINK_ATTR_INFO_VERSION_STORED] = { .name = "info-version-stored", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, }, 965d1a30ebSJakub Kicinski [DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, }, 975d1a30ebSJakub Kicinski [DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, }, 985d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_FAILED] = { .name = "reload-failed", .type = YNL_PT_U8, }, 995d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, }, 1005d1a30ebSJakub Kicinski [DEVLINK_ATTR_DEV_STATS] = { .name = "dev-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_dev_stats_nest, }, 1015d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, }, 1025d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, }, 1035d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, }, 1045d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, }, 1055d1a30ebSJakub Kicinski [DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, }, 1065d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, }, 1075d1a30ebSJakub Kicinski [DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, }, 1085d1a30ebSJakub Kicinski }; 1095d1a30ebSJakub Kicinski 1105d1a30ebSJakub Kicinski struct ynl_policy_nest devlink_nest = { 1115d1a30ebSJakub Kicinski .max_attr = DEVLINK_ATTR_MAX, 1125d1a30ebSJakub Kicinski .table = devlink_policy, 1135d1a30ebSJakub Kicinski }; 1145d1a30ebSJakub Kicinski 1155d1a30ebSJakub Kicinski /* Common nested types */ 1165d1a30ebSJakub Kicinski void devlink_dl_info_version_free(struct devlink_dl_info_version *obj) 1175d1a30ebSJakub Kicinski { 1185d1a30ebSJakub Kicinski free(obj->info_version_name); 1195d1a30ebSJakub Kicinski free(obj->info_version_value); 1205d1a30ebSJakub Kicinski } 1215d1a30ebSJakub Kicinski 1225d1a30ebSJakub Kicinski int devlink_dl_info_version_parse(struct ynl_parse_arg *yarg, 1235d1a30ebSJakub Kicinski const struct nlattr *nested) 1245d1a30ebSJakub Kicinski { 1255d1a30ebSJakub Kicinski struct devlink_dl_info_version *dst = yarg->data; 1265d1a30ebSJakub Kicinski const struct nlattr *attr; 1275d1a30ebSJakub Kicinski 1285d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 1297234415bSJakub Kicinski unsigned int type = mnl_attr_get_type(attr); 1307234415bSJakub Kicinski 1317234415bSJakub Kicinski if (type == DEVLINK_ATTR_INFO_VERSION_NAME) { 1325d1a30ebSJakub Kicinski unsigned int len; 1335d1a30ebSJakub Kicinski 1345d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 1355d1a30ebSJakub Kicinski return MNL_CB_ERROR; 1365d1a30ebSJakub Kicinski 1375d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 1385d1a30ebSJakub Kicinski dst->_present.info_version_name_len = len; 1395d1a30ebSJakub Kicinski dst->info_version_name = malloc(len + 1); 1405d1a30ebSJakub Kicinski memcpy(dst->info_version_name, mnl_attr_get_str(attr), len); 1415d1a30ebSJakub Kicinski dst->info_version_name[len] = 0; 1427234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_INFO_VERSION_VALUE) { 1435d1a30ebSJakub Kicinski unsigned int len; 1445d1a30ebSJakub Kicinski 1455d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 1465d1a30ebSJakub Kicinski return MNL_CB_ERROR; 1475d1a30ebSJakub Kicinski 1485d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 1495d1a30ebSJakub Kicinski dst->_present.info_version_value_len = len; 1505d1a30ebSJakub Kicinski dst->info_version_value = malloc(len + 1); 1515d1a30ebSJakub Kicinski memcpy(dst->info_version_value, mnl_attr_get_str(attr), len); 1525d1a30ebSJakub Kicinski dst->info_version_value[len] = 0; 1535d1a30ebSJakub Kicinski } 1545d1a30ebSJakub Kicinski } 1555d1a30ebSJakub Kicinski 1565d1a30ebSJakub Kicinski return 0; 1575d1a30ebSJakub Kicinski } 1585d1a30ebSJakub Kicinski 1595d1a30ebSJakub Kicinski void 1605d1a30ebSJakub Kicinski devlink_dl_reload_stats_entry_free(struct devlink_dl_reload_stats_entry *obj) 1615d1a30ebSJakub Kicinski { 1625d1a30ebSJakub Kicinski } 1635d1a30ebSJakub Kicinski 1645d1a30ebSJakub Kicinski int devlink_dl_reload_stats_entry_parse(struct ynl_parse_arg *yarg, 1655d1a30ebSJakub Kicinski const struct nlattr *nested) 1665d1a30ebSJakub Kicinski { 1675d1a30ebSJakub Kicinski struct devlink_dl_reload_stats_entry *dst = yarg->data; 1685d1a30ebSJakub Kicinski const struct nlattr *attr; 1695d1a30ebSJakub Kicinski 1705d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 1717234415bSJakub Kicinski unsigned int type = mnl_attr_get_type(attr); 1727234415bSJakub Kicinski 1737234415bSJakub Kicinski if (type == DEVLINK_ATTR_RELOAD_STATS_LIMIT) { 1745d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 1755d1a30ebSJakub Kicinski return MNL_CB_ERROR; 1765d1a30ebSJakub Kicinski dst->_present.reload_stats_limit = 1; 1775d1a30ebSJakub Kicinski dst->reload_stats_limit = mnl_attr_get_u8(attr); 1787234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_RELOAD_STATS_VALUE) { 1795d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 1805d1a30ebSJakub Kicinski return MNL_CB_ERROR; 1815d1a30ebSJakub Kicinski dst->_present.reload_stats_value = 1; 1825d1a30ebSJakub Kicinski dst->reload_stats_value = mnl_attr_get_u32(attr); 1835d1a30ebSJakub Kicinski } 1845d1a30ebSJakub Kicinski } 1855d1a30ebSJakub Kicinski 1865d1a30ebSJakub Kicinski return 0; 1875d1a30ebSJakub Kicinski } 1885d1a30ebSJakub Kicinski 1895d1a30ebSJakub Kicinski void devlink_dl_reload_act_stats_free(struct devlink_dl_reload_act_stats *obj) 1905d1a30ebSJakub Kicinski { 1915d1a30ebSJakub Kicinski unsigned int i; 1925d1a30ebSJakub Kicinski 1935d1a30ebSJakub Kicinski for (i = 0; i < obj->n_reload_stats_entry; i++) 1945d1a30ebSJakub Kicinski devlink_dl_reload_stats_entry_free(&obj->reload_stats_entry[i]); 1955d1a30ebSJakub Kicinski free(obj->reload_stats_entry); 1965d1a30ebSJakub Kicinski } 1975d1a30ebSJakub Kicinski 1985d1a30ebSJakub Kicinski int devlink_dl_reload_act_stats_parse(struct ynl_parse_arg *yarg, 1995d1a30ebSJakub Kicinski const struct nlattr *nested) 2005d1a30ebSJakub Kicinski { 2015d1a30ebSJakub Kicinski struct devlink_dl_reload_act_stats *dst = yarg->data; 2025d1a30ebSJakub Kicinski unsigned int n_reload_stats_entry = 0; 2035d1a30ebSJakub Kicinski const struct nlattr *attr; 2045d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 2055d1a30ebSJakub Kicinski int i; 2065d1a30ebSJakub Kicinski 2075d1a30ebSJakub Kicinski parg.ys = yarg->ys; 2085d1a30ebSJakub Kicinski 2095d1a30ebSJakub Kicinski if (dst->reload_stats_entry) 2105d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (dl-reload-act-stats.reload-stats-entry)"); 2115d1a30ebSJakub Kicinski 2125d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 2137234415bSJakub Kicinski unsigned int type = mnl_attr_get_type(attr); 2147234415bSJakub Kicinski 2157234415bSJakub Kicinski if (type == DEVLINK_ATTR_RELOAD_STATS_ENTRY) { 2165d1a30ebSJakub Kicinski n_reload_stats_entry++; 2175d1a30ebSJakub Kicinski } 2185d1a30ebSJakub Kicinski } 2195d1a30ebSJakub Kicinski 2205d1a30ebSJakub Kicinski if (n_reload_stats_entry) { 2215d1a30ebSJakub Kicinski dst->reload_stats_entry = calloc(n_reload_stats_entry, sizeof(*dst->reload_stats_entry)); 2225d1a30ebSJakub Kicinski dst->n_reload_stats_entry = n_reload_stats_entry; 2235d1a30ebSJakub Kicinski i = 0; 2245d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_stats_entry_nest; 2255d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 2265d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) { 2275d1a30ebSJakub Kicinski parg.data = &dst->reload_stats_entry[i]; 2285d1a30ebSJakub Kicinski if (devlink_dl_reload_stats_entry_parse(&parg, attr)) 2295d1a30ebSJakub Kicinski return MNL_CB_ERROR; 2305d1a30ebSJakub Kicinski i++; 2315d1a30ebSJakub Kicinski } 2325d1a30ebSJakub Kicinski } 2335d1a30ebSJakub Kicinski } 2345d1a30ebSJakub Kicinski 2355d1a30ebSJakub Kicinski return 0; 2365d1a30ebSJakub Kicinski } 2375d1a30ebSJakub Kicinski 2385d1a30ebSJakub Kicinski void devlink_dl_reload_act_info_free(struct devlink_dl_reload_act_info *obj) 2395d1a30ebSJakub Kicinski { 2405d1a30ebSJakub Kicinski unsigned int i; 2415d1a30ebSJakub Kicinski 2425d1a30ebSJakub Kicinski for (i = 0; i < obj->n_reload_action_stats; i++) 2435d1a30ebSJakub Kicinski devlink_dl_reload_act_stats_free(&obj->reload_action_stats[i]); 2445d1a30ebSJakub Kicinski free(obj->reload_action_stats); 2455d1a30ebSJakub Kicinski } 2465d1a30ebSJakub Kicinski 2475d1a30ebSJakub Kicinski int devlink_dl_reload_act_info_parse(struct ynl_parse_arg *yarg, 2485d1a30ebSJakub Kicinski const struct nlattr *nested) 2495d1a30ebSJakub Kicinski { 2505d1a30ebSJakub Kicinski struct devlink_dl_reload_act_info *dst = yarg->data; 2515d1a30ebSJakub Kicinski unsigned int n_reload_action_stats = 0; 2525d1a30ebSJakub Kicinski const struct nlattr *attr; 2535d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 2545d1a30ebSJakub Kicinski int i; 2555d1a30ebSJakub Kicinski 2565d1a30ebSJakub Kicinski parg.ys = yarg->ys; 2575d1a30ebSJakub Kicinski 2585d1a30ebSJakub Kicinski if (dst->reload_action_stats) 2595d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (dl-reload-act-info.reload-action-stats)"); 2605d1a30ebSJakub Kicinski 2615d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 2627234415bSJakub Kicinski unsigned int type = mnl_attr_get_type(attr); 2637234415bSJakub Kicinski 2647234415bSJakub Kicinski if (type == DEVLINK_ATTR_RELOAD_ACTION) { 2655d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 2665d1a30ebSJakub Kicinski return MNL_CB_ERROR; 2675d1a30ebSJakub Kicinski dst->_present.reload_action = 1; 2685d1a30ebSJakub Kicinski dst->reload_action = mnl_attr_get_u8(attr); 2697234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_RELOAD_ACTION_STATS) { 2705d1a30ebSJakub Kicinski n_reload_action_stats++; 2715d1a30ebSJakub Kicinski } 2725d1a30ebSJakub Kicinski } 2735d1a30ebSJakub Kicinski 2745d1a30ebSJakub Kicinski if (n_reload_action_stats) { 2755d1a30ebSJakub Kicinski dst->reload_action_stats = calloc(n_reload_action_stats, sizeof(*dst->reload_action_stats)); 2765d1a30ebSJakub Kicinski dst->n_reload_action_stats = n_reload_action_stats; 2775d1a30ebSJakub Kicinski i = 0; 2785d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_act_stats_nest; 2795d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 2805d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) { 2815d1a30ebSJakub Kicinski parg.data = &dst->reload_action_stats[i]; 2825d1a30ebSJakub Kicinski if (devlink_dl_reload_act_stats_parse(&parg, attr)) 2835d1a30ebSJakub Kicinski return MNL_CB_ERROR; 2845d1a30ebSJakub Kicinski i++; 2855d1a30ebSJakub Kicinski } 2865d1a30ebSJakub Kicinski } 2875d1a30ebSJakub Kicinski } 2885d1a30ebSJakub Kicinski 2895d1a30ebSJakub Kicinski return 0; 2905d1a30ebSJakub Kicinski } 2915d1a30ebSJakub Kicinski 2925d1a30ebSJakub Kicinski void devlink_dl_reload_stats_free(struct devlink_dl_reload_stats *obj) 2935d1a30ebSJakub Kicinski { 2945d1a30ebSJakub Kicinski unsigned int i; 2955d1a30ebSJakub Kicinski 2965d1a30ebSJakub Kicinski for (i = 0; i < obj->n_reload_action_info; i++) 2975d1a30ebSJakub Kicinski devlink_dl_reload_act_info_free(&obj->reload_action_info[i]); 2985d1a30ebSJakub Kicinski free(obj->reload_action_info); 2995d1a30ebSJakub Kicinski } 3005d1a30ebSJakub Kicinski 3015d1a30ebSJakub Kicinski int devlink_dl_reload_stats_parse(struct ynl_parse_arg *yarg, 3025d1a30ebSJakub Kicinski const struct nlattr *nested) 3035d1a30ebSJakub Kicinski { 3045d1a30ebSJakub Kicinski struct devlink_dl_reload_stats *dst = yarg->data; 3055d1a30ebSJakub Kicinski unsigned int n_reload_action_info = 0; 3065d1a30ebSJakub Kicinski const struct nlattr *attr; 3075d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 3085d1a30ebSJakub Kicinski int i; 3095d1a30ebSJakub Kicinski 3105d1a30ebSJakub Kicinski parg.ys = yarg->ys; 3115d1a30ebSJakub Kicinski 3125d1a30ebSJakub Kicinski if (dst->reload_action_info) 3135d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (dl-reload-stats.reload-action-info)"); 3145d1a30ebSJakub Kicinski 3155d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 3167234415bSJakub Kicinski unsigned int type = mnl_attr_get_type(attr); 3177234415bSJakub Kicinski 3187234415bSJakub Kicinski if (type == DEVLINK_ATTR_RELOAD_ACTION_INFO) { 3195d1a30ebSJakub Kicinski n_reload_action_info++; 3205d1a30ebSJakub Kicinski } 3215d1a30ebSJakub Kicinski } 3225d1a30ebSJakub Kicinski 3235d1a30ebSJakub Kicinski if (n_reload_action_info) { 3245d1a30ebSJakub Kicinski dst->reload_action_info = calloc(n_reload_action_info, sizeof(*dst->reload_action_info)); 3255d1a30ebSJakub Kicinski dst->n_reload_action_info = n_reload_action_info; 3265d1a30ebSJakub Kicinski i = 0; 3275d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_act_info_nest; 3285d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 3295d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) { 3305d1a30ebSJakub Kicinski parg.data = &dst->reload_action_info[i]; 3315d1a30ebSJakub Kicinski if (devlink_dl_reload_act_info_parse(&parg, attr)) 3325d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3335d1a30ebSJakub Kicinski i++; 3345d1a30ebSJakub Kicinski } 3355d1a30ebSJakub Kicinski } 3365d1a30ebSJakub Kicinski } 3375d1a30ebSJakub Kicinski 3385d1a30ebSJakub Kicinski return 0; 3395d1a30ebSJakub Kicinski } 3405d1a30ebSJakub Kicinski 3415d1a30ebSJakub Kicinski void devlink_dl_dev_stats_free(struct devlink_dl_dev_stats *obj) 3425d1a30ebSJakub Kicinski { 3435d1a30ebSJakub Kicinski devlink_dl_reload_stats_free(&obj->reload_stats); 3445d1a30ebSJakub Kicinski devlink_dl_reload_stats_free(&obj->remote_reload_stats); 3455d1a30ebSJakub Kicinski } 3465d1a30ebSJakub Kicinski 3475d1a30ebSJakub Kicinski int devlink_dl_dev_stats_parse(struct ynl_parse_arg *yarg, 3485d1a30ebSJakub Kicinski const struct nlattr *nested) 3495d1a30ebSJakub Kicinski { 3505d1a30ebSJakub Kicinski struct devlink_dl_dev_stats *dst = yarg->data; 3515d1a30ebSJakub Kicinski const struct nlattr *attr; 3525d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 3535d1a30ebSJakub Kicinski 3545d1a30ebSJakub Kicinski parg.ys = yarg->ys; 3555d1a30ebSJakub Kicinski 3565d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 3577234415bSJakub Kicinski unsigned int type = mnl_attr_get_type(attr); 3587234415bSJakub Kicinski 3597234415bSJakub Kicinski if (type == DEVLINK_ATTR_RELOAD_STATS) { 3605d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 3615d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3625d1a30ebSJakub Kicinski dst->_present.reload_stats = 1; 3635d1a30ebSJakub Kicinski 3645d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_stats_nest; 3655d1a30ebSJakub Kicinski parg.data = &dst->reload_stats; 3665d1a30ebSJakub Kicinski if (devlink_dl_reload_stats_parse(&parg, attr)) 3675d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3687234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_REMOTE_RELOAD_STATS) { 3695d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 3705d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3715d1a30ebSJakub Kicinski dst->_present.remote_reload_stats = 1; 3725d1a30ebSJakub Kicinski 3735d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_stats_nest; 3745d1a30ebSJakub Kicinski parg.data = &dst->remote_reload_stats; 3755d1a30ebSJakub Kicinski if (devlink_dl_reload_stats_parse(&parg, attr)) 3765d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3775d1a30ebSJakub Kicinski } 3785d1a30ebSJakub Kicinski } 3795d1a30ebSJakub Kicinski 3805d1a30ebSJakub Kicinski return 0; 3815d1a30ebSJakub Kicinski } 3825d1a30ebSJakub Kicinski 3835d1a30ebSJakub Kicinski /* ============== DEVLINK_CMD_GET ============== */ 3845d1a30ebSJakub Kicinski /* DEVLINK_CMD_GET - do */ 3855d1a30ebSJakub Kicinski void devlink_get_req_free(struct devlink_get_req *req) 3865d1a30ebSJakub Kicinski { 3875d1a30ebSJakub Kicinski free(req->bus_name); 3885d1a30ebSJakub Kicinski free(req->dev_name); 3895d1a30ebSJakub Kicinski free(req); 3905d1a30ebSJakub Kicinski } 3915d1a30ebSJakub Kicinski 3925d1a30ebSJakub Kicinski void devlink_get_rsp_free(struct devlink_get_rsp *rsp) 3935d1a30ebSJakub Kicinski { 3945d1a30ebSJakub Kicinski free(rsp->bus_name); 3955d1a30ebSJakub Kicinski free(rsp->dev_name); 3965d1a30ebSJakub Kicinski devlink_dl_dev_stats_free(&rsp->dev_stats); 3975d1a30ebSJakub Kicinski free(rsp); 3985d1a30ebSJakub Kicinski } 3995d1a30ebSJakub Kicinski 4005d1a30ebSJakub Kicinski int devlink_get_rsp_parse(const struct nlmsghdr *nlh, void *data) 4015d1a30ebSJakub Kicinski { 4025d1a30ebSJakub Kicinski struct ynl_parse_arg *yarg = data; 4035d1a30ebSJakub Kicinski struct devlink_get_rsp *dst; 4045d1a30ebSJakub Kicinski const struct nlattr *attr; 4055d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 4065d1a30ebSJakub Kicinski 4075d1a30ebSJakub Kicinski dst = yarg->data; 4085d1a30ebSJakub Kicinski parg.ys = yarg->ys; 4095d1a30ebSJakub Kicinski 4105d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 4117234415bSJakub Kicinski unsigned int type = mnl_attr_get_type(attr); 4127234415bSJakub Kicinski 4137234415bSJakub Kicinski if (type == DEVLINK_ATTR_BUS_NAME) { 4145d1a30ebSJakub Kicinski unsigned int len; 4155d1a30ebSJakub Kicinski 4165d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4175d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4185d1a30ebSJakub Kicinski 4195d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 4205d1a30ebSJakub Kicinski dst->_present.bus_name_len = len; 4215d1a30ebSJakub Kicinski dst->bus_name = malloc(len + 1); 4225d1a30ebSJakub Kicinski memcpy(dst->bus_name, mnl_attr_get_str(attr), len); 4235d1a30ebSJakub Kicinski dst->bus_name[len] = 0; 4247234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_DEV_NAME) { 4255d1a30ebSJakub Kicinski unsigned int len; 4265d1a30ebSJakub Kicinski 4275d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4285d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4295d1a30ebSJakub Kicinski 4305d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 4315d1a30ebSJakub Kicinski dst->_present.dev_name_len = len; 4325d1a30ebSJakub Kicinski dst->dev_name = malloc(len + 1); 4335d1a30ebSJakub Kicinski memcpy(dst->dev_name, mnl_attr_get_str(attr), len); 4345d1a30ebSJakub Kicinski dst->dev_name[len] = 0; 4357234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_RELOAD_FAILED) { 4365d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4375d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4385d1a30ebSJakub Kicinski dst->_present.reload_failed = 1; 4395d1a30ebSJakub Kicinski dst->reload_failed = mnl_attr_get_u8(attr); 4407234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_RELOAD_ACTION) { 4415d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4425d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4435d1a30ebSJakub Kicinski dst->_present.reload_action = 1; 4445d1a30ebSJakub Kicinski dst->reload_action = mnl_attr_get_u8(attr); 4457234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_DEV_STATS) { 4465d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4475d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4485d1a30ebSJakub Kicinski dst->_present.dev_stats = 1; 4495d1a30ebSJakub Kicinski 4505d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_dev_stats_nest; 4515d1a30ebSJakub Kicinski parg.data = &dst->dev_stats; 4525d1a30ebSJakub Kicinski if (devlink_dl_dev_stats_parse(&parg, attr)) 4535d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4545d1a30ebSJakub Kicinski } 4555d1a30ebSJakub Kicinski } 4565d1a30ebSJakub Kicinski 4575d1a30ebSJakub Kicinski return MNL_CB_OK; 4585d1a30ebSJakub Kicinski } 4595d1a30ebSJakub Kicinski 4605d1a30ebSJakub Kicinski struct devlink_get_rsp * 4615d1a30ebSJakub Kicinski devlink_get(struct ynl_sock *ys, struct devlink_get_req *req) 4625d1a30ebSJakub Kicinski { 4635d1a30ebSJakub Kicinski struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; 4645d1a30ebSJakub Kicinski struct devlink_get_rsp *rsp; 4655d1a30ebSJakub Kicinski struct nlmsghdr *nlh; 4665d1a30ebSJakub Kicinski int err; 4675d1a30ebSJakub Kicinski 4685d1a30ebSJakub Kicinski nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_GET, 1); 4695d1a30ebSJakub Kicinski ys->req_policy = &devlink_nest; 4705d1a30ebSJakub Kicinski yrs.yarg.rsp_policy = &devlink_nest; 4715d1a30ebSJakub Kicinski 4725d1a30ebSJakub Kicinski if (req->_present.bus_name_len) 4735d1a30ebSJakub Kicinski mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); 4745d1a30ebSJakub Kicinski if (req->_present.dev_name_len) 4755d1a30ebSJakub Kicinski mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); 4765d1a30ebSJakub Kicinski 4775d1a30ebSJakub Kicinski rsp = calloc(1, sizeof(*rsp)); 4785d1a30ebSJakub Kicinski yrs.yarg.data = rsp; 4795d1a30ebSJakub Kicinski yrs.cb = devlink_get_rsp_parse; 4805d1a30ebSJakub Kicinski yrs.rsp_cmd = 3; 4815d1a30ebSJakub Kicinski 4825d1a30ebSJakub Kicinski err = ynl_exec(ys, nlh, &yrs); 4835d1a30ebSJakub Kicinski if (err < 0) 4845d1a30ebSJakub Kicinski goto err_free; 4855d1a30ebSJakub Kicinski 4865d1a30ebSJakub Kicinski return rsp; 4875d1a30ebSJakub Kicinski 4885d1a30ebSJakub Kicinski err_free: 4895d1a30ebSJakub Kicinski devlink_get_rsp_free(rsp); 4905d1a30ebSJakub Kicinski return NULL; 4915d1a30ebSJakub Kicinski } 4925d1a30ebSJakub Kicinski 4935d1a30ebSJakub Kicinski /* DEVLINK_CMD_GET - dump */ 4945d1a30ebSJakub Kicinski void devlink_get_list_free(struct devlink_get_list *rsp) 4955d1a30ebSJakub Kicinski { 4965d1a30ebSJakub Kicinski struct devlink_get_list *next = rsp; 4975d1a30ebSJakub Kicinski 4985d1a30ebSJakub Kicinski while ((void *)next != YNL_LIST_END) { 4995d1a30ebSJakub Kicinski rsp = next; 5005d1a30ebSJakub Kicinski next = rsp->next; 5015d1a30ebSJakub Kicinski 5025d1a30ebSJakub Kicinski free(rsp->obj.bus_name); 5035d1a30ebSJakub Kicinski free(rsp->obj.dev_name); 5045d1a30ebSJakub Kicinski devlink_dl_dev_stats_free(&rsp->obj.dev_stats); 5055d1a30ebSJakub Kicinski free(rsp); 5065d1a30ebSJakub Kicinski } 5075d1a30ebSJakub Kicinski } 5085d1a30ebSJakub Kicinski 5095d1a30ebSJakub Kicinski struct devlink_get_list *devlink_get_dump(struct ynl_sock *ys) 5105d1a30ebSJakub Kicinski { 5115d1a30ebSJakub Kicinski struct ynl_dump_state yds = {}; 5125d1a30ebSJakub Kicinski struct nlmsghdr *nlh; 5135d1a30ebSJakub Kicinski int err; 5145d1a30ebSJakub Kicinski 5155d1a30ebSJakub Kicinski yds.ys = ys; 5165d1a30ebSJakub Kicinski yds.alloc_sz = sizeof(struct devlink_get_list); 5175d1a30ebSJakub Kicinski yds.cb = devlink_get_rsp_parse; 5185d1a30ebSJakub Kicinski yds.rsp_cmd = 3; 5195d1a30ebSJakub Kicinski yds.rsp_policy = &devlink_nest; 5205d1a30ebSJakub Kicinski 5215d1a30ebSJakub Kicinski nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_GET, 1); 5225d1a30ebSJakub Kicinski 5235d1a30ebSJakub Kicinski err = ynl_exec_dump(ys, nlh, &yds); 5245d1a30ebSJakub Kicinski if (err < 0) 5255d1a30ebSJakub Kicinski goto free_list; 5265d1a30ebSJakub Kicinski 5275d1a30ebSJakub Kicinski return yds.first; 5285d1a30ebSJakub Kicinski 5295d1a30ebSJakub Kicinski free_list: 5305d1a30ebSJakub Kicinski devlink_get_list_free(yds.first); 5315d1a30ebSJakub Kicinski return NULL; 5325d1a30ebSJakub Kicinski } 5335d1a30ebSJakub Kicinski 5345d1a30ebSJakub Kicinski /* ============== DEVLINK_CMD_INFO_GET ============== */ 5355d1a30ebSJakub Kicinski /* DEVLINK_CMD_INFO_GET - do */ 5365d1a30ebSJakub Kicinski void devlink_info_get_req_free(struct devlink_info_get_req *req) 5375d1a30ebSJakub Kicinski { 5385d1a30ebSJakub Kicinski free(req->bus_name); 5395d1a30ebSJakub Kicinski free(req->dev_name); 5405d1a30ebSJakub Kicinski free(req); 5415d1a30ebSJakub Kicinski } 5425d1a30ebSJakub Kicinski 5435d1a30ebSJakub Kicinski void devlink_info_get_rsp_free(struct devlink_info_get_rsp *rsp) 5445d1a30ebSJakub Kicinski { 5455d1a30ebSJakub Kicinski unsigned int i; 5465d1a30ebSJakub Kicinski 5475d1a30ebSJakub Kicinski free(rsp->bus_name); 5485d1a30ebSJakub Kicinski free(rsp->dev_name); 5495d1a30ebSJakub Kicinski free(rsp->info_driver_name); 5505d1a30ebSJakub Kicinski free(rsp->info_serial_number); 5515d1a30ebSJakub Kicinski for (i = 0; i < rsp->n_info_version_fixed; i++) 5525d1a30ebSJakub Kicinski devlink_dl_info_version_free(&rsp->info_version_fixed[i]); 5535d1a30ebSJakub Kicinski free(rsp->info_version_fixed); 5545d1a30ebSJakub Kicinski for (i = 0; i < rsp->n_info_version_running; i++) 5555d1a30ebSJakub Kicinski devlink_dl_info_version_free(&rsp->info_version_running[i]); 5565d1a30ebSJakub Kicinski free(rsp->info_version_running); 5575d1a30ebSJakub Kicinski for (i = 0; i < rsp->n_info_version_stored; i++) 5585d1a30ebSJakub Kicinski devlink_dl_info_version_free(&rsp->info_version_stored[i]); 5595d1a30ebSJakub Kicinski free(rsp->info_version_stored); 5605d1a30ebSJakub Kicinski free(rsp); 5615d1a30ebSJakub Kicinski } 5625d1a30ebSJakub Kicinski 5635d1a30ebSJakub Kicinski int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data) 5645d1a30ebSJakub Kicinski { 5655d1a30ebSJakub Kicinski unsigned int n_info_version_running = 0; 5665d1a30ebSJakub Kicinski unsigned int n_info_version_stored = 0; 5675d1a30ebSJakub Kicinski unsigned int n_info_version_fixed = 0; 5685d1a30ebSJakub Kicinski struct ynl_parse_arg *yarg = data; 5695d1a30ebSJakub Kicinski struct devlink_info_get_rsp *dst; 5705d1a30ebSJakub Kicinski const struct nlattr *attr; 5715d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 5725d1a30ebSJakub Kicinski int i; 5735d1a30ebSJakub Kicinski 5745d1a30ebSJakub Kicinski dst = yarg->data; 5755d1a30ebSJakub Kicinski parg.ys = yarg->ys; 5765d1a30ebSJakub Kicinski 5775d1a30ebSJakub Kicinski if (dst->info_version_fixed) 5785d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (devlink.info-version-fixed)"); 5795d1a30ebSJakub Kicinski if (dst->info_version_running) 5805d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (devlink.info-version-running)"); 5815d1a30ebSJakub Kicinski if (dst->info_version_stored) 5825d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (devlink.info-version-stored)"); 5835d1a30ebSJakub Kicinski 5845d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 5857234415bSJakub Kicinski unsigned int type = mnl_attr_get_type(attr); 5867234415bSJakub Kicinski 5877234415bSJakub Kicinski if (type == DEVLINK_ATTR_BUS_NAME) { 5885d1a30ebSJakub Kicinski unsigned int len; 5895d1a30ebSJakub Kicinski 5905d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 5915d1a30ebSJakub Kicinski return MNL_CB_ERROR; 5925d1a30ebSJakub Kicinski 5935d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 5945d1a30ebSJakub Kicinski dst->_present.bus_name_len = len; 5955d1a30ebSJakub Kicinski dst->bus_name = malloc(len + 1); 5965d1a30ebSJakub Kicinski memcpy(dst->bus_name, mnl_attr_get_str(attr), len); 5975d1a30ebSJakub Kicinski dst->bus_name[len] = 0; 5987234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_DEV_NAME) { 5995d1a30ebSJakub Kicinski unsigned int len; 6005d1a30ebSJakub Kicinski 6015d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 6025d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6035d1a30ebSJakub Kicinski 6045d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 6055d1a30ebSJakub Kicinski dst->_present.dev_name_len = len; 6065d1a30ebSJakub Kicinski dst->dev_name = malloc(len + 1); 6075d1a30ebSJakub Kicinski memcpy(dst->dev_name, mnl_attr_get_str(attr), len); 6085d1a30ebSJakub Kicinski dst->dev_name[len] = 0; 6097234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_INFO_DRIVER_NAME) { 6105d1a30ebSJakub Kicinski unsigned int len; 6115d1a30ebSJakub Kicinski 6125d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 6135d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6145d1a30ebSJakub Kicinski 6155d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 6165d1a30ebSJakub Kicinski dst->_present.info_driver_name_len = len; 6175d1a30ebSJakub Kicinski dst->info_driver_name = malloc(len + 1); 6185d1a30ebSJakub Kicinski memcpy(dst->info_driver_name, mnl_attr_get_str(attr), len); 6195d1a30ebSJakub Kicinski dst->info_driver_name[len] = 0; 6207234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_INFO_SERIAL_NUMBER) { 6215d1a30ebSJakub Kicinski unsigned int len; 6225d1a30ebSJakub Kicinski 6235d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 6245d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6255d1a30ebSJakub Kicinski 6265d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 6275d1a30ebSJakub Kicinski dst->_present.info_serial_number_len = len; 6285d1a30ebSJakub Kicinski dst->info_serial_number = malloc(len + 1); 6295d1a30ebSJakub Kicinski memcpy(dst->info_serial_number, mnl_attr_get_str(attr), len); 6305d1a30ebSJakub Kicinski dst->info_serial_number[len] = 0; 6317234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_INFO_VERSION_FIXED) { 6325d1a30ebSJakub Kicinski n_info_version_fixed++; 6337234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_INFO_VERSION_RUNNING) { 6345d1a30ebSJakub Kicinski n_info_version_running++; 6357234415bSJakub Kicinski } else if (type == DEVLINK_ATTR_INFO_VERSION_STORED) { 6365d1a30ebSJakub Kicinski n_info_version_stored++; 6375d1a30ebSJakub Kicinski } 6385d1a30ebSJakub Kicinski } 6395d1a30ebSJakub Kicinski 6405d1a30ebSJakub Kicinski if (n_info_version_fixed) { 6415d1a30ebSJakub Kicinski dst->info_version_fixed = calloc(n_info_version_fixed, sizeof(*dst->info_version_fixed)); 6425d1a30ebSJakub Kicinski dst->n_info_version_fixed = n_info_version_fixed; 6435d1a30ebSJakub Kicinski i = 0; 6445d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_info_version_nest; 6455d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 6465d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) { 6475d1a30ebSJakub Kicinski parg.data = &dst->info_version_fixed[i]; 6485d1a30ebSJakub Kicinski if (devlink_dl_info_version_parse(&parg, attr)) 6495d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6505d1a30ebSJakub Kicinski i++; 6515d1a30ebSJakub Kicinski } 6525d1a30ebSJakub Kicinski } 6535d1a30ebSJakub Kicinski } 6545d1a30ebSJakub Kicinski if (n_info_version_running) { 6555d1a30ebSJakub Kicinski dst->info_version_running = calloc(n_info_version_running, sizeof(*dst->info_version_running)); 6565d1a30ebSJakub Kicinski dst->n_info_version_running = n_info_version_running; 6575d1a30ebSJakub Kicinski i = 0; 6585d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_info_version_nest; 6595d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 6605d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) { 6615d1a30ebSJakub Kicinski parg.data = &dst->info_version_running[i]; 6625d1a30ebSJakub Kicinski if (devlink_dl_info_version_parse(&parg, attr)) 6635d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6645d1a30ebSJakub Kicinski i++; 6655d1a30ebSJakub Kicinski } 6665d1a30ebSJakub Kicinski } 6675d1a30ebSJakub Kicinski } 6685d1a30ebSJakub Kicinski if (n_info_version_stored) { 6695d1a30ebSJakub Kicinski dst->info_version_stored = calloc(n_info_version_stored, sizeof(*dst->info_version_stored)); 6705d1a30ebSJakub Kicinski dst->n_info_version_stored = n_info_version_stored; 6715d1a30ebSJakub Kicinski i = 0; 6725d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_info_version_nest; 6735d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 6745d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) { 6755d1a30ebSJakub Kicinski parg.data = &dst->info_version_stored[i]; 6765d1a30ebSJakub Kicinski if (devlink_dl_info_version_parse(&parg, attr)) 6775d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6785d1a30ebSJakub Kicinski i++; 6795d1a30ebSJakub Kicinski } 6805d1a30ebSJakub Kicinski } 6815d1a30ebSJakub Kicinski } 6825d1a30ebSJakub Kicinski 6835d1a30ebSJakub Kicinski return MNL_CB_OK; 6845d1a30ebSJakub Kicinski } 6855d1a30ebSJakub Kicinski 6865d1a30ebSJakub Kicinski struct devlink_info_get_rsp * 6875d1a30ebSJakub Kicinski devlink_info_get(struct ynl_sock *ys, struct devlink_info_get_req *req) 6885d1a30ebSJakub Kicinski { 6895d1a30ebSJakub Kicinski struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; 6905d1a30ebSJakub Kicinski struct devlink_info_get_rsp *rsp; 6915d1a30ebSJakub Kicinski struct nlmsghdr *nlh; 6925d1a30ebSJakub Kicinski int err; 6935d1a30ebSJakub Kicinski 6945d1a30ebSJakub Kicinski nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1); 6955d1a30ebSJakub Kicinski ys->req_policy = &devlink_nest; 6965d1a30ebSJakub Kicinski yrs.yarg.rsp_policy = &devlink_nest; 6975d1a30ebSJakub Kicinski 6985d1a30ebSJakub Kicinski if (req->_present.bus_name_len) 6995d1a30ebSJakub Kicinski mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); 7005d1a30ebSJakub Kicinski if (req->_present.dev_name_len) 7015d1a30ebSJakub Kicinski mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); 7025d1a30ebSJakub Kicinski 7035d1a30ebSJakub Kicinski rsp = calloc(1, sizeof(*rsp)); 7045d1a30ebSJakub Kicinski yrs.yarg.data = rsp; 7055d1a30ebSJakub Kicinski yrs.cb = devlink_info_get_rsp_parse; 7065d1a30ebSJakub Kicinski yrs.rsp_cmd = DEVLINK_CMD_INFO_GET; 7075d1a30ebSJakub Kicinski 7085d1a30ebSJakub Kicinski err = ynl_exec(ys, nlh, &yrs); 7095d1a30ebSJakub Kicinski if (err < 0) 7105d1a30ebSJakub Kicinski goto err_free; 7115d1a30ebSJakub Kicinski 7125d1a30ebSJakub Kicinski return rsp; 7135d1a30ebSJakub Kicinski 7145d1a30ebSJakub Kicinski err_free: 7155d1a30ebSJakub Kicinski devlink_info_get_rsp_free(rsp); 7165d1a30ebSJakub Kicinski return NULL; 7175d1a30ebSJakub Kicinski } 7185d1a30ebSJakub Kicinski 719*759f6610SJiri Pirko /* DEVLINK_CMD_INFO_GET - dump */ 720*759f6610SJiri Pirko void devlink_info_get_list_free(struct devlink_info_get_list *rsp) 721*759f6610SJiri Pirko { 722*759f6610SJiri Pirko struct devlink_info_get_list *next = rsp; 723*759f6610SJiri Pirko 724*759f6610SJiri Pirko while ((void *)next != YNL_LIST_END) { 725*759f6610SJiri Pirko unsigned int i; 726*759f6610SJiri Pirko 727*759f6610SJiri Pirko rsp = next; 728*759f6610SJiri Pirko next = rsp->next; 729*759f6610SJiri Pirko 730*759f6610SJiri Pirko free(rsp->obj.bus_name); 731*759f6610SJiri Pirko free(rsp->obj.dev_name); 732*759f6610SJiri Pirko free(rsp->obj.info_driver_name); 733*759f6610SJiri Pirko free(rsp->obj.info_serial_number); 734*759f6610SJiri Pirko for (i = 0; i < rsp->obj.n_info_version_fixed; i++) 735*759f6610SJiri Pirko devlink_dl_info_version_free(&rsp->obj.info_version_fixed[i]); 736*759f6610SJiri Pirko free(rsp->obj.info_version_fixed); 737*759f6610SJiri Pirko for (i = 0; i < rsp->obj.n_info_version_running; i++) 738*759f6610SJiri Pirko devlink_dl_info_version_free(&rsp->obj.info_version_running[i]); 739*759f6610SJiri Pirko free(rsp->obj.info_version_running); 740*759f6610SJiri Pirko for (i = 0; i < rsp->obj.n_info_version_stored; i++) 741*759f6610SJiri Pirko devlink_dl_info_version_free(&rsp->obj.info_version_stored[i]); 742*759f6610SJiri Pirko free(rsp->obj.info_version_stored); 743*759f6610SJiri Pirko free(rsp); 744*759f6610SJiri Pirko } 745*759f6610SJiri Pirko } 746*759f6610SJiri Pirko 747*759f6610SJiri Pirko struct devlink_info_get_list *devlink_info_get_dump(struct ynl_sock *ys) 748*759f6610SJiri Pirko { 749*759f6610SJiri Pirko struct ynl_dump_state yds = {}; 750*759f6610SJiri Pirko struct nlmsghdr *nlh; 751*759f6610SJiri Pirko int err; 752*759f6610SJiri Pirko 753*759f6610SJiri Pirko yds.ys = ys; 754*759f6610SJiri Pirko yds.alloc_sz = sizeof(struct devlink_info_get_list); 755*759f6610SJiri Pirko yds.cb = devlink_info_get_rsp_parse; 756*759f6610SJiri Pirko yds.rsp_cmd = DEVLINK_CMD_INFO_GET; 757*759f6610SJiri Pirko yds.rsp_policy = &devlink_nest; 758*759f6610SJiri Pirko 759*759f6610SJiri Pirko nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1); 760*759f6610SJiri Pirko 761*759f6610SJiri Pirko err = ynl_exec_dump(ys, nlh, &yds); 762*759f6610SJiri Pirko if (err < 0) 763*759f6610SJiri Pirko goto free_list; 764*759f6610SJiri Pirko 765*759f6610SJiri Pirko return yds.first; 766*759f6610SJiri Pirko 767*759f6610SJiri Pirko free_list: 768*759f6610SJiri Pirko devlink_info_get_list_free(yds.first); 769*759f6610SJiri Pirko return NULL; 770*759f6610SJiri Pirko } 771*759f6610SJiri Pirko 7725d1a30ebSJakub Kicinski const struct ynl_family ynl_devlink_family = { 7735d1a30ebSJakub Kicinski .name = "devlink", 7745d1a30ebSJakub Kicinski }; 775