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> 7*9b52fd4bSJakub 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) { 1295d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_NAME) { 1305d1a30ebSJakub Kicinski unsigned int len; 1315d1a30ebSJakub Kicinski 1325d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 1335d1a30ebSJakub Kicinski return MNL_CB_ERROR; 1345d1a30ebSJakub Kicinski 1355d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 1365d1a30ebSJakub Kicinski dst->_present.info_version_name_len = len; 1375d1a30ebSJakub Kicinski dst->info_version_name = malloc(len + 1); 1385d1a30ebSJakub Kicinski memcpy(dst->info_version_name, mnl_attr_get_str(attr), len); 1395d1a30ebSJakub Kicinski dst->info_version_name[len] = 0; 1405d1a30ebSJakub Kicinski } 1415d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_VALUE) { 1425d1a30ebSJakub Kicinski unsigned int len; 1435d1a30ebSJakub Kicinski 1445d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 1455d1a30ebSJakub Kicinski return MNL_CB_ERROR; 1465d1a30ebSJakub Kicinski 1475d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 1485d1a30ebSJakub Kicinski dst->_present.info_version_value_len = len; 1495d1a30ebSJakub Kicinski dst->info_version_value = malloc(len + 1); 1505d1a30ebSJakub Kicinski memcpy(dst->info_version_value, mnl_attr_get_str(attr), len); 1515d1a30ebSJakub Kicinski dst->info_version_value[len] = 0; 1525d1a30ebSJakub Kicinski } 1535d1a30ebSJakub Kicinski } 1545d1a30ebSJakub Kicinski 1555d1a30ebSJakub Kicinski return 0; 1565d1a30ebSJakub Kicinski } 1575d1a30ebSJakub Kicinski 1585d1a30ebSJakub Kicinski void 1595d1a30ebSJakub Kicinski devlink_dl_reload_stats_entry_free(struct devlink_dl_reload_stats_entry *obj) 1605d1a30ebSJakub Kicinski { 1615d1a30ebSJakub Kicinski } 1625d1a30ebSJakub Kicinski 1635d1a30ebSJakub Kicinski int devlink_dl_reload_stats_entry_parse(struct ynl_parse_arg *yarg, 1645d1a30ebSJakub Kicinski const struct nlattr *nested) 1655d1a30ebSJakub Kicinski { 1665d1a30ebSJakub Kicinski struct devlink_dl_reload_stats_entry *dst = yarg->data; 1675d1a30ebSJakub Kicinski const struct nlattr *attr; 1685d1a30ebSJakub Kicinski 1695d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 1705d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_LIMIT) { 1715d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 1725d1a30ebSJakub Kicinski return MNL_CB_ERROR; 1735d1a30ebSJakub Kicinski dst->_present.reload_stats_limit = 1; 1745d1a30ebSJakub Kicinski dst->reload_stats_limit = mnl_attr_get_u8(attr); 1755d1a30ebSJakub Kicinski } 1765d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_VALUE) { 1775d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 1785d1a30ebSJakub Kicinski return MNL_CB_ERROR; 1795d1a30ebSJakub Kicinski dst->_present.reload_stats_value = 1; 1805d1a30ebSJakub Kicinski dst->reload_stats_value = mnl_attr_get_u32(attr); 1815d1a30ebSJakub Kicinski } 1825d1a30ebSJakub Kicinski } 1835d1a30ebSJakub Kicinski 1845d1a30ebSJakub Kicinski return 0; 1855d1a30ebSJakub Kicinski } 1865d1a30ebSJakub Kicinski 1875d1a30ebSJakub Kicinski void devlink_dl_reload_act_stats_free(struct devlink_dl_reload_act_stats *obj) 1885d1a30ebSJakub Kicinski { 1895d1a30ebSJakub Kicinski unsigned int i; 1905d1a30ebSJakub Kicinski 1915d1a30ebSJakub Kicinski for (i = 0; i < obj->n_reload_stats_entry; i++) 1925d1a30ebSJakub Kicinski devlink_dl_reload_stats_entry_free(&obj->reload_stats_entry[i]); 1935d1a30ebSJakub Kicinski free(obj->reload_stats_entry); 1945d1a30ebSJakub Kicinski } 1955d1a30ebSJakub Kicinski 1965d1a30ebSJakub Kicinski int devlink_dl_reload_act_stats_parse(struct ynl_parse_arg *yarg, 1975d1a30ebSJakub Kicinski const struct nlattr *nested) 1985d1a30ebSJakub Kicinski { 1995d1a30ebSJakub Kicinski struct devlink_dl_reload_act_stats *dst = yarg->data; 2005d1a30ebSJakub Kicinski unsigned int n_reload_stats_entry = 0; 2015d1a30ebSJakub Kicinski const struct nlattr *attr; 2025d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 2035d1a30ebSJakub Kicinski int i; 2045d1a30ebSJakub Kicinski 2055d1a30ebSJakub Kicinski parg.ys = yarg->ys; 2065d1a30ebSJakub Kicinski 2075d1a30ebSJakub Kicinski if (dst->reload_stats_entry) 2085d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (dl-reload-act-stats.reload-stats-entry)"); 2095d1a30ebSJakub Kicinski 2105d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 2115d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) { 2125d1a30ebSJakub Kicinski n_reload_stats_entry++; 2135d1a30ebSJakub Kicinski } 2145d1a30ebSJakub Kicinski } 2155d1a30ebSJakub Kicinski 2165d1a30ebSJakub Kicinski if (n_reload_stats_entry) { 2175d1a30ebSJakub Kicinski dst->reload_stats_entry = calloc(n_reload_stats_entry, sizeof(*dst->reload_stats_entry)); 2185d1a30ebSJakub Kicinski dst->n_reload_stats_entry = n_reload_stats_entry; 2195d1a30ebSJakub Kicinski i = 0; 2205d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_stats_entry_nest; 2215d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 2225d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) { 2235d1a30ebSJakub Kicinski parg.data = &dst->reload_stats_entry[i]; 2245d1a30ebSJakub Kicinski if (devlink_dl_reload_stats_entry_parse(&parg, attr)) 2255d1a30ebSJakub Kicinski return MNL_CB_ERROR; 2265d1a30ebSJakub Kicinski i++; 2275d1a30ebSJakub Kicinski } 2285d1a30ebSJakub Kicinski } 2295d1a30ebSJakub Kicinski } 2305d1a30ebSJakub Kicinski 2315d1a30ebSJakub Kicinski return 0; 2325d1a30ebSJakub Kicinski } 2335d1a30ebSJakub Kicinski 2345d1a30ebSJakub Kicinski void devlink_dl_reload_act_info_free(struct devlink_dl_reload_act_info *obj) 2355d1a30ebSJakub Kicinski { 2365d1a30ebSJakub Kicinski unsigned int i; 2375d1a30ebSJakub Kicinski 2385d1a30ebSJakub Kicinski for (i = 0; i < obj->n_reload_action_stats; i++) 2395d1a30ebSJakub Kicinski devlink_dl_reload_act_stats_free(&obj->reload_action_stats[i]); 2405d1a30ebSJakub Kicinski free(obj->reload_action_stats); 2415d1a30ebSJakub Kicinski } 2425d1a30ebSJakub Kicinski 2435d1a30ebSJakub Kicinski int devlink_dl_reload_act_info_parse(struct ynl_parse_arg *yarg, 2445d1a30ebSJakub Kicinski const struct nlattr *nested) 2455d1a30ebSJakub Kicinski { 2465d1a30ebSJakub Kicinski struct devlink_dl_reload_act_info *dst = yarg->data; 2475d1a30ebSJakub Kicinski unsigned int n_reload_action_stats = 0; 2485d1a30ebSJakub Kicinski const struct nlattr *attr; 2495d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 2505d1a30ebSJakub Kicinski int i; 2515d1a30ebSJakub Kicinski 2525d1a30ebSJakub Kicinski parg.ys = yarg->ys; 2535d1a30ebSJakub Kicinski 2545d1a30ebSJakub Kicinski if (dst->reload_action_stats) 2555d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (dl-reload-act-info.reload-action-stats)"); 2565d1a30ebSJakub Kicinski 2575d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 2585d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION) { 2595d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 2605d1a30ebSJakub Kicinski return MNL_CB_ERROR; 2615d1a30ebSJakub Kicinski dst->_present.reload_action = 1; 2625d1a30ebSJakub Kicinski dst->reload_action = mnl_attr_get_u8(attr); 2635d1a30ebSJakub Kicinski } 2645d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) { 2655d1a30ebSJakub Kicinski n_reload_action_stats++; 2665d1a30ebSJakub Kicinski } 2675d1a30ebSJakub Kicinski } 2685d1a30ebSJakub Kicinski 2695d1a30ebSJakub Kicinski if (n_reload_action_stats) { 2705d1a30ebSJakub Kicinski dst->reload_action_stats = calloc(n_reload_action_stats, sizeof(*dst->reload_action_stats)); 2715d1a30ebSJakub Kicinski dst->n_reload_action_stats = n_reload_action_stats; 2725d1a30ebSJakub Kicinski i = 0; 2735d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_act_stats_nest; 2745d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 2755d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) { 2765d1a30ebSJakub Kicinski parg.data = &dst->reload_action_stats[i]; 2775d1a30ebSJakub Kicinski if (devlink_dl_reload_act_stats_parse(&parg, attr)) 2785d1a30ebSJakub Kicinski return MNL_CB_ERROR; 2795d1a30ebSJakub Kicinski i++; 2805d1a30ebSJakub Kicinski } 2815d1a30ebSJakub Kicinski } 2825d1a30ebSJakub Kicinski } 2835d1a30ebSJakub Kicinski 2845d1a30ebSJakub Kicinski return 0; 2855d1a30ebSJakub Kicinski } 2865d1a30ebSJakub Kicinski 2875d1a30ebSJakub Kicinski void devlink_dl_reload_stats_free(struct devlink_dl_reload_stats *obj) 2885d1a30ebSJakub Kicinski { 2895d1a30ebSJakub Kicinski unsigned int i; 2905d1a30ebSJakub Kicinski 2915d1a30ebSJakub Kicinski for (i = 0; i < obj->n_reload_action_info; i++) 2925d1a30ebSJakub Kicinski devlink_dl_reload_act_info_free(&obj->reload_action_info[i]); 2935d1a30ebSJakub Kicinski free(obj->reload_action_info); 2945d1a30ebSJakub Kicinski } 2955d1a30ebSJakub Kicinski 2965d1a30ebSJakub Kicinski int devlink_dl_reload_stats_parse(struct ynl_parse_arg *yarg, 2975d1a30ebSJakub Kicinski const struct nlattr *nested) 2985d1a30ebSJakub Kicinski { 2995d1a30ebSJakub Kicinski struct devlink_dl_reload_stats *dst = yarg->data; 3005d1a30ebSJakub Kicinski unsigned int n_reload_action_info = 0; 3015d1a30ebSJakub Kicinski const struct nlattr *attr; 3025d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 3035d1a30ebSJakub Kicinski int i; 3045d1a30ebSJakub Kicinski 3055d1a30ebSJakub Kicinski parg.ys = yarg->ys; 3065d1a30ebSJakub Kicinski 3075d1a30ebSJakub Kicinski if (dst->reload_action_info) 3085d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (dl-reload-stats.reload-action-info)"); 3095d1a30ebSJakub Kicinski 3105d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 3115d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) { 3125d1a30ebSJakub Kicinski n_reload_action_info++; 3135d1a30ebSJakub Kicinski } 3145d1a30ebSJakub Kicinski } 3155d1a30ebSJakub Kicinski 3165d1a30ebSJakub Kicinski if (n_reload_action_info) { 3175d1a30ebSJakub Kicinski dst->reload_action_info = calloc(n_reload_action_info, sizeof(*dst->reload_action_info)); 3185d1a30ebSJakub Kicinski dst->n_reload_action_info = n_reload_action_info; 3195d1a30ebSJakub Kicinski i = 0; 3205d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_act_info_nest; 3215d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 3225d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) { 3235d1a30ebSJakub Kicinski parg.data = &dst->reload_action_info[i]; 3245d1a30ebSJakub Kicinski if (devlink_dl_reload_act_info_parse(&parg, attr)) 3255d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3265d1a30ebSJakub Kicinski i++; 3275d1a30ebSJakub Kicinski } 3285d1a30ebSJakub Kicinski } 3295d1a30ebSJakub Kicinski } 3305d1a30ebSJakub Kicinski 3315d1a30ebSJakub Kicinski return 0; 3325d1a30ebSJakub Kicinski } 3335d1a30ebSJakub Kicinski 3345d1a30ebSJakub Kicinski void devlink_dl_dev_stats_free(struct devlink_dl_dev_stats *obj) 3355d1a30ebSJakub Kicinski { 3365d1a30ebSJakub Kicinski devlink_dl_reload_stats_free(&obj->reload_stats); 3375d1a30ebSJakub Kicinski devlink_dl_reload_stats_free(&obj->remote_reload_stats); 3385d1a30ebSJakub Kicinski } 3395d1a30ebSJakub Kicinski 3405d1a30ebSJakub Kicinski int devlink_dl_dev_stats_parse(struct ynl_parse_arg *yarg, 3415d1a30ebSJakub Kicinski const struct nlattr *nested) 3425d1a30ebSJakub Kicinski { 3435d1a30ebSJakub Kicinski struct devlink_dl_dev_stats *dst = yarg->data; 3445d1a30ebSJakub Kicinski const struct nlattr *attr; 3455d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 3465d1a30ebSJakub Kicinski 3475d1a30ebSJakub Kicinski parg.ys = yarg->ys; 3485d1a30ebSJakub Kicinski 3495d1a30ebSJakub Kicinski mnl_attr_for_each_nested(attr, nested) { 3505d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS) { 3515d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 3525d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3535d1a30ebSJakub Kicinski dst->_present.reload_stats = 1; 3545d1a30ebSJakub Kicinski 3555d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_stats_nest; 3565d1a30ebSJakub Kicinski parg.data = &dst->reload_stats; 3575d1a30ebSJakub Kicinski if (devlink_dl_reload_stats_parse(&parg, attr)) 3585d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3595d1a30ebSJakub Kicinski } 3605d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_REMOTE_RELOAD_STATS) { 3615d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 3625d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3635d1a30ebSJakub Kicinski dst->_present.remote_reload_stats = 1; 3645d1a30ebSJakub Kicinski 3655d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_reload_stats_nest; 3665d1a30ebSJakub Kicinski parg.data = &dst->remote_reload_stats; 3675d1a30ebSJakub Kicinski if (devlink_dl_reload_stats_parse(&parg, attr)) 3685d1a30ebSJakub Kicinski return MNL_CB_ERROR; 3695d1a30ebSJakub Kicinski } 3705d1a30ebSJakub Kicinski } 3715d1a30ebSJakub Kicinski 3725d1a30ebSJakub Kicinski return 0; 3735d1a30ebSJakub Kicinski } 3745d1a30ebSJakub Kicinski 3755d1a30ebSJakub Kicinski /* ============== DEVLINK_CMD_GET ============== */ 3765d1a30ebSJakub Kicinski /* DEVLINK_CMD_GET - do */ 3775d1a30ebSJakub Kicinski void devlink_get_req_free(struct devlink_get_req *req) 3785d1a30ebSJakub Kicinski { 3795d1a30ebSJakub Kicinski free(req->bus_name); 3805d1a30ebSJakub Kicinski free(req->dev_name); 3815d1a30ebSJakub Kicinski free(req); 3825d1a30ebSJakub Kicinski } 3835d1a30ebSJakub Kicinski 3845d1a30ebSJakub Kicinski void devlink_get_rsp_free(struct devlink_get_rsp *rsp) 3855d1a30ebSJakub Kicinski { 3865d1a30ebSJakub Kicinski free(rsp->bus_name); 3875d1a30ebSJakub Kicinski free(rsp->dev_name); 3885d1a30ebSJakub Kicinski devlink_dl_dev_stats_free(&rsp->dev_stats); 3895d1a30ebSJakub Kicinski free(rsp); 3905d1a30ebSJakub Kicinski } 3915d1a30ebSJakub Kicinski 3925d1a30ebSJakub Kicinski int devlink_get_rsp_parse(const struct nlmsghdr *nlh, void *data) 3935d1a30ebSJakub Kicinski { 3945d1a30ebSJakub Kicinski struct ynl_parse_arg *yarg = data; 3955d1a30ebSJakub Kicinski struct devlink_get_rsp *dst; 3965d1a30ebSJakub Kicinski const struct nlattr *attr; 3975d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 3985d1a30ebSJakub Kicinski 3995d1a30ebSJakub Kicinski dst = yarg->data; 4005d1a30ebSJakub Kicinski parg.ys = yarg->ys; 4015d1a30ebSJakub Kicinski 4025d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 4035d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_BUS_NAME) { 4045d1a30ebSJakub Kicinski unsigned int len; 4055d1a30ebSJakub Kicinski 4065d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4075d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4085d1a30ebSJakub Kicinski 4095d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 4105d1a30ebSJakub Kicinski dst->_present.bus_name_len = len; 4115d1a30ebSJakub Kicinski dst->bus_name = malloc(len + 1); 4125d1a30ebSJakub Kicinski memcpy(dst->bus_name, mnl_attr_get_str(attr), len); 4135d1a30ebSJakub Kicinski dst->bus_name[len] = 0; 4145d1a30ebSJakub Kicinski } 4155d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_DEV_NAME) { 4165d1a30ebSJakub Kicinski unsigned int len; 4175d1a30ebSJakub Kicinski 4185d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4195d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4205d1a30ebSJakub Kicinski 4215d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 4225d1a30ebSJakub Kicinski dst->_present.dev_name_len = len; 4235d1a30ebSJakub Kicinski dst->dev_name = malloc(len + 1); 4245d1a30ebSJakub Kicinski memcpy(dst->dev_name, mnl_attr_get_str(attr), len); 4255d1a30ebSJakub Kicinski dst->dev_name[len] = 0; 4265d1a30ebSJakub Kicinski } 4275d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_FAILED) { 4285d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4295d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4305d1a30ebSJakub Kicinski dst->_present.reload_failed = 1; 4315d1a30ebSJakub Kicinski dst->reload_failed = mnl_attr_get_u8(attr); 4325d1a30ebSJakub Kicinski } 4335d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION) { 4345d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4355d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4365d1a30ebSJakub Kicinski dst->_present.reload_action = 1; 4375d1a30ebSJakub Kicinski dst->reload_action = mnl_attr_get_u8(attr); 4385d1a30ebSJakub Kicinski } 4395d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_DEV_STATS) { 4405d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 4415d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4425d1a30ebSJakub Kicinski dst->_present.dev_stats = 1; 4435d1a30ebSJakub Kicinski 4445d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_dev_stats_nest; 4455d1a30ebSJakub Kicinski parg.data = &dst->dev_stats; 4465d1a30ebSJakub Kicinski if (devlink_dl_dev_stats_parse(&parg, attr)) 4475d1a30ebSJakub Kicinski return MNL_CB_ERROR; 4485d1a30ebSJakub Kicinski } 4495d1a30ebSJakub Kicinski } 4505d1a30ebSJakub Kicinski 4515d1a30ebSJakub Kicinski return MNL_CB_OK; 4525d1a30ebSJakub Kicinski } 4535d1a30ebSJakub Kicinski 4545d1a30ebSJakub Kicinski struct devlink_get_rsp * 4555d1a30ebSJakub Kicinski devlink_get(struct ynl_sock *ys, struct devlink_get_req *req) 4565d1a30ebSJakub Kicinski { 4575d1a30ebSJakub Kicinski struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; 4585d1a30ebSJakub Kicinski struct devlink_get_rsp *rsp; 4595d1a30ebSJakub Kicinski struct nlmsghdr *nlh; 4605d1a30ebSJakub Kicinski int err; 4615d1a30ebSJakub Kicinski 4625d1a30ebSJakub Kicinski nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_GET, 1); 4635d1a30ebSJakub Kicinski ys->req_policy = &devlink_nest; 4645d1a30ebSJakub Kicinski yrs.yarg.rsp_policy = &devlink_nest; 4655d1a30ebSJakub Kicinski 4665d1a30ebSJakub Kicinski if (req->_present.bus_name_len) 4675d1a30ebSJakub Kicinski mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); 4685d1a30ebSJakub Kicinski if (req->_present.dev_name_len) 4695d1a30ebSJakub Kicinski mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); 4705d1a30ebSJakub Kicinski 4715d1a30ebSJakub Kicinski rsp = calloc(1, sizeof(*rsp)); 4725d1a30ebSJakub Kicinski yrs.yarg.data = rsp; 4735d1a30ebSJakub Kicinski yrs.cb = devlink_get_rsp_parse; 4745d1a30ebSJakub Kicinski yrs.rsp_cmd = 3; 4755d1a30ebSJakub Kicinski 4765d1a30ebSJakub Kicinski err = ynl_exec(ys, nlh, &yrs); 4775d1a30ebSJakub Kicinski if (err < 0) 4785d1a30ebSJakub Kicinski goto err_free; 4795d1a30ebSJakub Kicinski 4805d1a30ebSJakub Kicinski return rsp; 4815d1a30ebSJakub Kicinski 4825d1a30ebSJakub Kicinski err_free: 4835d1a30ebSJakub Kicinski devlink_get_rsp_free(rsp); 4845d1a30ebSJakub Kicinski return NULL; 4855d1a30ebSJakub Kicinski } 4865d1a30ebSJakub Kicinski 4875d1a30ebSJakub Kicinski /* DEVLINK_CMD_GET - dump */ 4885d1a30ebSJakub Kicinski void devlink_get_list_free(struct devlink_get_list *rsp) 4895d1a30ebSJakub Kicinski { 4905d1a30ebSJakub Kicinski struct devlink_get_list *next = rsp; 4915d1a30ebSJakub Kicinski 4925d1a30ebSJakub Kicinski while ((void *)next != YNL_LIST_END) { 4935d1a30ebSJakub Kicinski rsp = next; 4945d1a30ebSJakub Kicinski next = rsp->next; 4955d1a30ebSJakub Kicinski 4965d1a30ebSJakub Kicinski free(rsp->obj.bus_name); 4975d1a30ebSJakub Kicinski free(rsp->obj.dev_name); 4985d1a30ebSJakub Kicinski devlink_dl_dev_stats_free(&rsp->obj.dev_stats); 4995d1a30ebSJakub Kicinski free(rsp); 5005d1a30ebSJakub Kicinski } 5015d1a30ebSJakub Kicinski } 5025d1a30ebSJakub Kicinski 5035d1a30ebSJakub Kicinski struct devlink_get_list *devlink_get_dump(struct ynl_sock *ys) 5045d1a30ebSJakub Kicinski { 5055d1a30ebSJakub Kicinski struct ynl_dump_state yds = {}; 5065d1a30ebSJakub Kicinski struct nlmsghdr *nlh; 5075d1a30ebSJakub Kicinski int err; 5085d1a30ebSJakub Kicinski 5095d1a30ebSJakub Kicinski yds.ys = ys; 5105d1a30ebSJakub Kicinski yds.alloc_sz = sizeof(struct devlink_get_list); 5115d1a30ebSJakub Kicinski yds.cb = devlink_get_rsp_parse; 5125d1a30ebSJakub Kicinski yds.rsp_cmd = 3; 5135d1a30ebSJakub Kicinski yds.rsp_policy = &devlink_nest; 5145d1a30ebSJakub Kicinski 5155d1a30ebSJakub Kicinski nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_GET, 1); 5165d1a30ebSJakub Kicinski 5175d1a30ebSJakub Kicinski err = ynl_exec_dump(ys, nlh, &yds); 5185d1a30ebSJakub Kicinski if (err < 0) 5195d1a30ebSJakub Kicinski goto free_list; 5205d1a30ebSJakub Kicinski 5215d1a30ebSJakub Kicinski return yds.first; 5225d1a30ebSJakub Kicinski 5235d1a30ebSJakub Kicinski free_list: 5245d1a30ebSJakub Kicinski devlink_get_list_free(yds.first); 5255d1a30ebSJakub Kicinski return NULL; 5265d1a30ebSJakub Kicinski } 5275d1a30ebSJakub Kicinski 5285d1a30ebSJakub Kicinski /* ============== DEVLINK_CMD_INFO_GET ============== */ 5295d1a30ebSJakub Kicinski /* DEVLINK_CMD_INFO_GET - do */ 5305d1a30ebSJakub Kicinski void devlink_info_get_req_free(struct devlink_info_get_req *req) 5315d1a30ebSJakub Kicinski { 5325d1a30ebSJakub Kicinski free(req->bus_name); 5335d1a30ebSJakub Kicinski free(req->dev_name); 5345d1a30ebSJakub Kicinski free(req); 5355d1a30ebSJakub Kicinski } 5365d1a30ebSJakub Kicinski 5375d1a30ebSJakub Kicinski void devlink_info_get_rsp_free(struct devlink_info_get_rsp *rsp) 5385d1a30ebSJakub Kicinski { 5395d1a30ebSJakub Kicinski unsigned int i; 5405d1a30ebSJakub Kicinski 5415d1a30ebSJakub Kicinski free(rsp->bus_name); 5425d1a30ebSJakub Kicinski free(rsp->dev_name); 5435d1a30ebSJakub Kicinski free(rsp->info_driver_name); 5445d1a30ebSJakub Kicinski free(rsp->info_serial_number); 5455d1a30ebSJakub Kicinski for (i = 0; i < rsp->n_info_version_fixed; i++) 5465d1a30ebSJakub Kicinski devlink_dl_info_version_free(&rsp->info_version_fixed[i]); 5475d1a30ebSJakub Kicinski free(rsp->info_version_fixed); 5485d1a30ebSJakub Kicinski for (i = 0; i < rsp->n_info_version_running; i++) 5495d1a30ebSJakub Kicinski devlink_dl_info_version_free(&rsp->info_version_running[i]); 5505d1a30ebSJakub Kicinski free(rsp->info_version_running); 5515d1a30ebSJakub Kicinski for (i = 0; i < rsp->n_info_version_stored; i++) 5525d1a30ebSJakub Kicinski devlink_dl_info_version_free(&rsp->info_version_stored[i]); 5535d1a30ebSJakub Kicinski free(rsp->info_version_stored); 5545d1a30ebSJakub Kicinski free(rsp); 5555d1a30ebSJakub Kicinski } 5565d1a30ebSJakub Kicinski 5575d1a30ebSJakub Kicinski int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data) 5585d1a30ebSJakub Kicinski { 5595d1a30ebSJakub Kicinski unsigned int n_info_version_running = 0; 5605d1a30ebSJakub Kicinski unsigned int n_info_version_stored = 0; 5615d1a30ebSJakub Kicinski unsigned int n_info_version_fixed = 0; 5625d1a30ebSJakub Kicinski struct ynl_parse_arg *yarg = data; 5635d1a30ebSJakub Kicinski struct devlink_info_get_rsp *dst; 5645d1a30ebSJakub Kicinski const struct nlattr *attr; 5655d1a30ebSJakub Kicinski struct ynl_parse_arg parg; 5665d1a30ebSJakub Kicinski int i; 5675d1a30ebSJakub Kicinski 5685d1a30ebSJakub Kicinski dst = yarg->data; 5695d1a30ebSJakub Kicinski parg.ys = yarg->ys; 5705d1a30ebSJakub Kicinski 5715d1a30ebSJakub Kicinski if (dst->info_version_fixed) 5725d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (devlink.info-version-fixed)"); 5735d1a30ebSJakub Kicinski if (dst->info_version_running) 5745d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (devlink.info-version-running)"); 5755d1a30ebSJakub Kicinski if (dst->info_version_stored) 5765d1a30ebSJakub Kicinski return ynl_error_parse(yarg, "attribute already present (devlink.info-version-stored)"); 5775d1a30ebSJakub Kicinski 5785d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 5795d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_BUS_NAME) { 5805d1a30ebSJakub Kicinski unsigned int len; 5815d1a30ebSJakub Kicinski 5825d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 5835d1a30ebSJakub Kicinski return MNL_CB_ERROR; 5845d1a30ebSJakub Kicinski 5855d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 5865d1a30ebSJakub Kicinski dst->_present.bus_name_len = len; 5875d1a30ebSJakub Kicinski dst->bus_name = malloc(len + 1); 5885d1a30ebSJakub Kicinski memcpy(dst->bus_name, mnl_attr_get_str(attr), len); 5895d1a30ebSJakub Kicinski dst->bus_name[len] = 0; 5905d1a30ebSJakub Kicinski } 5915d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_DEV_NAME) { 5925d1a30ebSJakub Kicinski unsigned int len; 5935d1a30ebSJakub Kicinski 5945d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 5955d1a30ebSJakub Kicinski return MNL_CB_ERROR; 5965d1a30ebSJakub Kicinski 5975d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 5985d1a30ebSJakub Kicinski dst->_present.dev_name_len = len; 5995d1a30ebSJakub Kicinski dst->dev_name = malloc(len + 1); 6005d1a30ebSJakub Kicinski memcpy(dst->dev_name, mnl_attr_get_str(attr), len); 6015d1a30ebSJakub Kicinski dst->dev_name[len] = 0; 6025d1a30ebSJakub Kicinski } 6035d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_DRIVER_NAME) { 6045d1a30ebSJakub Kicinski unsigned int len; 6055d1a30ebSJakub Kicinski 6065d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 6075d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6085d1a30ebSJakub Kicinski 6095d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 6105d1a30ebSJakub Kicinski dst->_present.info_driver_name_len = len; 6115d1a30ebSJakub Kicinski dst->info_driver_name = malloc(len + 1); 6125d1a30ebSJakub Kicinski memcpy(dst->info_driver_name, mnl_attr_get_str(attr), len); 6135d1a30ebSJakub Kicinski dst->info_driver_name[len] = 0; 6145d1a30ebSJakub Kicinski } 6155d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_SERIAL_NUMBER) { 6165d1a30ebSJakub Kicinski unsigned int len; 6175d1a30ebSJakub Kicinski 6185d1a30ebSJakub Kicinski if (ynl_attr_validate(yarg, attr)) 6195d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6205d1a30ebSJakub Kicinski 6215d1a30ebSJakub Kicinski len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr)); 6225d1a30ebSJakub Kicinski dst->_present.info_serial_number_len = len; 6235d1a30ebSJakub Kicinski dst->info_serial_number = malloc(len + 1); 6245d1a30ebSJakub Kicinski memcpy(dst->info_serial_number, mnl_attr_get_str(attr), len); 6255d1a30ebSJakub Kicinski dst->info_serial_number[len] = 0; 6265d1a30ebSJakub Kicinski } 6275d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) { 6285d1a30ebSJakub Kicinski n_info_version_fixed++; 6295d1a30ebSJakub Kicinski } 6305d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) { 6315d1a30ebSJakub Kicinski n_info_version_running++; 6325d1a30ebSJakub Kicinski } 6335d1a30ebSJakub Kicinski else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) { 6345d1a30ebSJakub Kicinski n_info_version_stored++; 6355d1a30ebSJakub Kicinski } 6365d1a30ebSJakub Kicinski } 6375d1a30ebSJakub Kicinski 6385d1a30ebSJakub Kicinski if (n_info_version_fixed) { 6395d1a30ebSJakub Kicinski dst->info_version_fixed = calloc(n_info_version_fixed, sizeof(*dst->info_version_fixed)); 6405d1a30ebSJakub Kicinski dst->n_info_version_fixed = n_info_version_fixed; 6415d1a30ebSJakub Kicinski i = 0; 6425d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_info_version_nest; 6435d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 6445d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) { 6455d1a30ebSJakub Kicinski parg.data = &dst->info_version_fixed[i]; 6465d1a30ebSJakub Kicinski if (devlink_dl_info_version_parse(&parg, attr)) 6475d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6485d1a30ebSJakub Kicinski i++; 6495d1a30ebSJakub Kicinski } 6505d1a30ebSJakub Kicinski } 6515d1a30ebSJakub Kicinski } 6525d1a30ebSJakub Kicinski if (n_info_version_running) { 6535d1a30ebSJakub Kicinski dst->info_version_running = calloc(n_info_version_running, sizeof(*dst->info_version_running)); 6545d1a30ebSJakub Kicinski dst->n_info_version_running = n_info_version_running; 6555d1a30ebSJakub Kicinski i = 0; 6565d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_info_version_nest; 6575d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 6585d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) { 6595d1a30ebSJakub Kicinski parg.data = &dst->info_version_running[i]; 6605d1a30ebSJakub Kicinski if (devlink_dl_info_version_parse(&parg, attr)) 6615d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6625d1a30ebSJakub Kicinski i++; 6635d1a30ebSJakub Kicinski } 6645d1a30ebSJakub Kicinski } 6655d1a30ebSJakub Kicinski } 6665d1a30ebSJakub Kicinski if (n_info_version_stored) { 6675d1a30ebSJakub Kicinski dst->info_version_stored = calloc(n_info_version_stored, sizeof(*dst->info_version_stored)); 6685d1a30ebSJakub Kicinski dst->n_info_version_stored = n_info_version_stored; 6695d1a30ebSJakub Kicinski i = 0; 6705d1a30ebSJakub Kicinski parg.rsp_policy = &devlink_dl_info_version_nest; 6715d1a30ebSJakub Kicinski mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 6725d1a30ebSJakub Kicinski if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) { 6735d1a30ebSJakub Kicinski parg.data = &dst->info_version_stored[i]; 6745d1a30ebSJakub Kicinski if (devlink_dl_info_version_parse(&parg, attr)) 6755d1a30ebSJakub Kicinski return MNL_CB_ERROR; 6765d1a30ebSJakub Kicinski i++; 6775d1a30ebSJakub Kicinski } 6785d1a30ebSJakub Kicinski } 6795d1a30ebSJakub Kicinski } 6805d1a30ebSJakub Kicinski 6815d1a30ebSJakub Kicinski return MNL_CB_OK; 6825d1a30ebSJakub Kicinski } 6835d1a30ebSJakub Kicinski 6845d1a30ebSJakub Kicinski struct devlink_info_get_rsp * 6855d1a30ebSJakub Kicinski devlink_info_get(struct ynl_sock *ys, struct devlink_info_get_req *req) 6865d1a30ebSJakub Kicinski { 6875d1a30ebSJakub Kicinski struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; 6885d1a30ebSJakub Kicinski struct devlink_info_get_rsp *rsp; 6895d1a30ebSJakub Kicinski struct nlmsghdr *nlh; 6905d1a30ebSJakub Kicinski int err; 6915d1a30ebSJakub Kicinski 6925d1a30ebSJakub Kicinski nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1); 6935d1a30ebSJakub Kicinski ys->req_policy = &devlink_nest; 6945d1a30ebSJakub Kicinski yrs.yarg.rsp_policy = &devlink_nest; 6955d1a30ebSJakub Kicinski 6965d1a30ebSJakub Kicinski if (req->_present.bus_name_len) 6975d1a30ebSJakub Kicinski mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); 6985d1a30ebSJakub Kicinski if (req->_present.dev_name_len) 6995d1a30ebSJakub Kicinski mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); 7005d1a30ebSJakub Kicinski 7015d1a30ebSJakub Kicinski rsp = calloc(1, sizeof(*rsp)); 7025d1a30ebSJakub Kicinski yrs.yarg.data = rsp; 7035d1a30ebSJakub Kicinski yrs.cb = devlink_info_get_rsp_parse; 7045d1a30ebSJakub Kicinski yrs.rsp_cmd = DEVLINK_CMD_INFO_GET; 7055d1a30ebSJakub Kicinski 7065d1a30ebSJakub Kicinski err = ynl_exec(ys, nlh, &yrs); 7075d1a30ebSJakub Kicinski if (err < 0) 7085d1a30ebSJakub Kicinski goto err_free; 7095d1a30ebSJakub Kicinski 7105d1a30ebSJakub Kicinski return rsp; 7115d1a30ebSJakub Kicinski 7125d1a30ebSJakub Kicinski err_free: 7135d1a30ebSJakub Kicinski devlink_info_get_rsp_free(rsp); 7145d1a30ebSJakub Kicinski return NULL; 7155d1a30ebSJakub Kicinski } 7165d1a30ebSJakub Kicinski 7175d1a30ebSJakub Kicinski const struct ynl_family ynl_devlink_family = { 7185d1a30ebSJakub Kicinski .name = "devlink", 7195d1a30ebSJakub Kicinski }; 720