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