1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 5 */ 6 7 #include <net/genetlink.h> 8 #include <net/sock.h> 9 #include "devl_internal.h" 10 11 struct devlink_info_req { 12 struct sk_buff *msg; 13 void (*version_cb)(const char *version_name, 14 enum devlink_info_version_type version_type, 15 void *version_cb_priv); 16 void *version_cb_priv; 17 }; 18 19 struct devlink_reload_combination { 20 enum devlink_reload_action action; 21 enum devlink_reload_limit limit; 22 }; 23 24 static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = { 25 { 26 /* can't reinitialize driver with no down time */ 27 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 28 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET, 29 }, 30 }; 31 32 static bool 33 devlink_reload_combination_is_invalid(enum devlink_reload_action action, 34 enum devlink_reload_limit limit) 35 { 36 int i; 37 38 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) 39 if (devlink_reload_invalid_combinations[i].action == action && 40 devlink_reload_invalid_combinations[i].limit == limit) 41 return true; 42 return false; 43 } 44 45 static bool 46 devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action) 47 { 48 return test_bit(action, &devlink->ops->reload_actions); 49 } 50 51 static bool 52 devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit) 53 { 54 return test_bit(limit, &devlink->ops->reload_limits); 55 } 56 57 static int devlink_reload_stat_put(struct sk_buff *msg, 58 enum devlink_reload_limit limit, u32 value) 59 { 60 struct nlattr *reload_stats_entry; 61 62 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY); 63 if (!reload_stats_entry) 64 return -EMSGSIZE; 65 66 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || 67 nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) 68 goto nla_put_failure; 69 nla_nest_end(msg, reload_stats_entry); 70 return 0; 71 72 nla_put_failure: 73 nla_nest_cancel(msg, reload_stats_entry); 74 return -EMSGSIZE; 75 } 76 77 static int 78 devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) 79 { 80 struct nlattr *reload_stats_attr, *act_info, *act_stats; 81 int i, j, stat_idx; 82 u32 value; 83 84 if (!is_remote) 85 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS); 86 else 87 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS); 88 89 if (!reload_stats_attr) 90 return -EMSGSIZE; 91 92 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { 93 if ((!is_remote && 94 !devlink_reload_action_is_supported(devlink, i)) || 95 i == DEVLINK_RELOAD_ACTION_UNSPEC) 96 continue; 97 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO); 98 if (!act_info) 99 goto nla_put_failure; 100 101 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i)) 102 goto action_info_nest_cancel; 103 act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS); 104 if (!act_stats) 105 goto action_info_nest_cancel; 106 107 for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { 108 /* Remote stats are shown even if not locally supported. 109 * Stats of actions with unspecified limit are shown 110 * though drivers don't need to register unspecified 111 * limit. 112 */ 113 if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && 114 !devlink_reload_limit_is_supported(devlink, j)) || 115 devlink_reload_combination_is_invalid(i, j)) 116 continue; 117 118 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i; 119 if (!is_remote) 120 value = devlink->stats.reload_stats[stat_idx]; 121 else 122 value = devlink->stats.remote_reload_stats[stat_idx]; 123 if (devlink_reload_stat_put(msg, j, value)) 124 goto action_stats_nest_cancel; 125 } 126 nla_nest_end(msg, act_stats); 127 nla_nest_end(msg, act_info); 128 } 129 nla_nest_end(msg, reload_stats_attr); 130 return 0; 131 132 action_stats_nest_cancel: 133 nla_nest_cancel(msg, act_stats); 134 action_info_nest_cancel: 135 nla_nest_cancel(msg, act_info); 136 nla_put_failure: 137 nla_nest_cancel(msg, reload_stats_attr); 138 return -EMSGSIZE; 139 } 140 141 static int devlink_nl_nested_fill(struct sk_buff *msg, struct devlink *devlink) 142 { 143 unsigned long rel_index; 144 void *unused; 145 int err; 146 147 xa_for_each(&devlink->nested_rels, rel_index, unused) { 148 err = devlink_rel_devlink_handle_put(msg, devlink, 149 rel_index, 150 DEVLINK_ATTR_NESTED_DEVLINK, 151 NULL); 152 if (err) 153 return err; 154 } 155 return 0; 156 } 157 158 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink, 159 enum devlink_command cmd, u32 portid, 160 u32 seq, int flags) 161 { 162 struct nlattr *dev_stats; 163 void *hdr; 164 165 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 166 if (!hdr) 167 return -EMSGSIZE; 168 169 if (devlink_nl_put_handle(msg, devlink)) 170 goto nla_put_failure; 171 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed)) 172 goto nla_put_failure; 173 174 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS); 175 if (!dev_stats) 176 goto nla_put_failure; 177 178 if (devlink_reload_stats_put(msg, devlink, false)) 179 goto dev_stats_nest_cancel; 180 if (devlink_reload_stats_put(msg, devlink, true)) 181 goto dev_stats_nest_cancel; 182 183 nla_nest_end(msg, dev_stats); 184 185 if (devlink_nl_nested_fill(msg, devlink)) 186 goto nla_put_failure; 187 188 genlmsg_end(msg, hdr); 189 return 0; 190 191 dev_stats_nest_cancel: 192 nla_nest_cancel(msg, dev_stats); 193 nla_put_failure: 194 genlmsg_cancel(msg, hdr); 195 return -EMSGSIZE; 196 } 197 198 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd) 199 { 200 struct sk_buff *msg; 201 int err; 202 203 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL); 204 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)); 205 206 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 207 if (!msg) 208 return; 209 210 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0); 211 if (err) { 212 nlmsg_free(msg); 213 return; 214 } 215 216 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 217 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 218 } 219 220 int devlink_nl_get_doit(struct sk_buff *skb, struct genl_info *info) 221 { 222 struct devlink *devlink = info->user_ptr[0]; 223 struct sk_buff *msg; 224 int err; 225 226 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 227 if (!msg) 228 return -ENOMEM; 229 230 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 231 info->snd_portid, info->snd_seq, 0); 232 if (err) { 233 nlmsg_free(msg); 234 return err; 235 } 236 237 return genlmsg_reply(msg, info); 238 } 239 240 static int 241 devlink_nl_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 242 struct netlink_callback *cb, int flags) 243 { 244 return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 245 NETLINK_CB(cb->skb).portid, 246 cb->nlh->nlmsg_seq, flags); 247 } 248 249 int devlink_nl_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) 250 { 251 return devlink_nl_dumpit(msg, cb, devlink_nl_get_dump_one); 252 } 253 254 static void devlink_rel_notify_cb(struct devlink *devlink, u32 obj_index) 255 { 256 devlink_notify(devlink, DEVLINK_CMD_NEW); 257 } 258 259 static void devlink_rel_cleanup_cb(struct devlink *devlink, u32 obj_index, 260 u32 rel_index) 261 { 262 xa_erase(&devlink->nested_rels, rel_index); 263 } 264 265 int devl_nested_devlink_set(struct devlink *devlink, 266 struct devlink *nested_devlink) 267 { 268 u32 rel_index; 269 int err; 270 271 err = devlink_rel_nested_in_add(&rel_index, devlink->index, 0, 272 devlink_rel_notify_cb, 273 devlink_rel_cleanup_cb, 274 nested_devlink); 275 if (err) 276 return err; 277 return xa_insert(&devlink->nested_rels, rel_index, 278 xa_mk_value(0), GFP_KERNEL); 279 } 280 EXPORT_SYMBOL_GPL(devl_nested_devlink_set); 281 282 void devlink_notify_register(struct devlink *devlink) 283 { 284 devlink_notify(devlink, DEVLINK_CMD_NEW); 285 devlink_linecards_notify_register(devlink); 286 devlink_ports_notify_register(devlink); 287 devlink_trap_policers_notify_register(devlink); 288 devlink_trap_groups_notify_register(devlink); 289 devlink_traps_notify_register(devlink); 290 devlink_rates_notify_register(devlink); 291 devlink_regions_notify_register(devlink); 292 devlink_params_notify_register(devlink); 293 } 294 295 void devlink_notify_unregister(struct devlink *devlink) 296 { 297 devlink_params_notify_unregister(devlink); 298 devlink_regions_notify_unregister(devlink); 299 devlink_rates_notify_unregister(devlink); 300 devlink_traps_notify_unregister(devlink); 301 devlink_trap_groups_notify_unregister(devlink); 302 devlink_trap_policers_notify_unregister(devlink); 303 devlink_ports_notify_unregister(devlink); 304 devlink_linecards_notify_unregister(devlink); 305 devlink_notify(devlink, DEVLINK_CMD_DEL); 306 } 307 308 static void devlink_reload_failed_set(struct devlink *devlink, 309 bool reload_failed) 310 { 311 if (devlink->reload_failed == reload_failed) 312 return; 313 devlink->reload_failed = reload_failed; 314 devlink_notify(devlink, DEVLINK_CMD_NEW); 315 } 316 317 bool devlink_is_reload_failed(const struct devlink *devlink) 318 { 319 return devlink->reload_failed; 320 } 321 EXPORT_SYMBOL_GPL(devlink_is_reload_failed); 322 323 static void 324 __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats, 325 enum devlink_reload_limit limit, u32 actions_performed) 326 { 327 unsigned long actions = actions_performed; 328 int stat_idx; 329 int action; 330 331 for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) { 332 stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action; 333 reload_stats[stat_idx]++; 334 } 335 devlink_notify(devlink, DEVLINK_CMD_NEW); 336 } 337 338 static void 339 devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit, 340 u32 actions_performed) 341 { 342 __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit, 343 actions_performed); 344 } 345 346 /** 347 * devlink_remote_reload_actions_performed - Update devlink on reload actions 348 * performed which are not a direct result of devlink reload call. 349 * 350 * This should be called by a driver after performing reload actions in case it was not 351 * a result of devlink reload call. For example fw_activate was performed as a result 352 * of devlink reload triggered fw_activate on another host. 353 * The motivation for this function is to keep data on reload actions performed on this 354 * function whether it was done due to direct devlink reload call or not. 355 * 356 * @devlink: devlink 357 * @limit: reload limit 358 * @actions_performed: bitmask of actions performed 359 */ 360 void devlink_remote_reload_actions_performed(struct devlink *devlink, 361 enum devlink_reload_limit limit, 362 u32 actions_performed) 363 { 364 if (WARN_ON(!actions_performed || 365 actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 366 actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) || 367 limit > DEVLINK_RELOAD_LIMIT_MAX)) 368 return; 369 370 __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit, 371 actions_performed); 372 } 373 EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed); 374 375 static struct net *devlink_netns_get(struct sk_buff *skb, 376 struct genl_info *info) 377 { 378 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID]; 379 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD]; 380 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID]; 381 struct net *net; 382 383 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) { 384 NL_SET_ERR_MSG(info->extack, "multiple netns identifying attributes specified"); 385 return ERR_PTR(-EINVAL); 386 } 387 388 if (netns_pid_attr) { 389 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr)); 390 } else if (netns_fd_attr) { 391 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr)); 392 } else if (netns_id_attr) { 393 net = get_net_ns_by_id(sock_net(skb->sk), 394 nla_get_u32(netns_id_attr)); 395 if (!net) 396 net = ERR_PTR(-EINVAL); 397 } else { 398 WARN_ON(1); 399 net = ERR_PTR(-EINVAL); 400 } 401 if (IS_ERR(net)) { 402 NL_SET_ERR_MSG(info->extack, "Unknown network namespace"); 403 return ERR_PTR(-EINVAL); 404 } 405 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { 406 put_net(net); 407 return ERR_PTR(-EPERM); 408 } 409 return net; 410 } 411 412 static void devlink_reload_netns_change(struct devlink *devlink, 413 struct net *curr_net, 414 struct net *dest_net) 415 { 416 /* Userspace needs to be notified about devlink objects 417 * removed from original and entering new network namespace. 418 * The rest of the devlink objects are re-created during 419 * reload process so the notifications are generated separatelly. 420 */ 421 devlink_notify_unregister(devlink); 422 write_pnet(&devlink->_net, dest_net); 423 devlink_notify_register(devlink); 424 devlink_rel_nested_in_notify(devlink); 425 } 426 427 int devlink_reload(struct devlink *devlink, struct net *dest_net, 428 enum devlink_reload_action action, 429 enum devlink_reload_limit limit, 430 u32 *actions_performed, struct netlink_ext_ack *extack) 431 { 432 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; 433 struct net *curr_net; 434 int err; 435 436 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats, 437 sizeof(remote_reload_stats)); 438 439 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack); 440 if (err) 441 return err; 442 443 curr_net = devlink_net(devlink); 444 if (dest_net && !net_eq(dest_net, curr_net)) 445 devlink_reload_netns_change(devlink, curr_net, dest_net); 446 447 if (action == DEVLINK_RELOAD_ACTION_DRIVER_REINIT) 448 devlink_params_driverinit_load_new(devlink); 449 450 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack); 451 devlink_reload_failed_set(devlink, !!err); 452 if (err) 453 return err; 454 455 WARN_ON(!(*actions_performed & BIT(action))); 456 /* Catch driver on updating the remote action within devlink reload */ 457 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats, 458 sizeof(remote_reload_stats))); 459 devlink_reload_stats_update(devlink, limit, *actions_performed); 460 return 0; 461 } 462 463 static int 464 devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed, 465 enum devlink_command cmd, struct genl_info *info) 466 { 467 struct sk_buff *msg; 468 void *hdr; 469 470 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 471 if (!msg) 472 return -ENOMEM; 473 474 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd); 475 if (!hdr) 476 goto free_msg; 477 478 if (devlink_nl_put_handle(msg, devlink)) 479 goto nla_put_failure; 480 481 if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed, 482 actions_performed)) 483 goto nla_put_failure; 484 genlmsg_end(msg, hdr); 485 486 return genlmsg_reply(msg, info); 487 488 nla_put_failure: 489 genlmsg_cancel(msg, hdr); 490 free_msg: 491 nlmsg_free(msg); 492 return -EMSGSIZE; 493 } 494 495 int devlink_nl_reload_doit(struct sk_buff *skb, struct genl_info *info) 496 { 497 struct devlink *devlink = info->user_ptr[0]; 498 enum devlink_reload_action action; 499 enum devlink_reload_limit limit; 500 struct net *dest_net = NULL; 501 u32 actions_performed; 502 int err; 503 504 err = devlink_resources_validate(devlink, NULL, info); 505 if (err) { 506 NL_SET_ERR_MSG(info->extack, "resources size validation failed"); 507 return err; 508 } 509 510 if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION]) 511 action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]); 512 else 513 action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT; 514 515 if (!devlink_reload_action_is_supported(devlink, action)) { 516 NL_SET_ERR_MSG(info->extack, "Requested reload action is not supported by the driver"); 517 return -EOPNOTSUPP; 518 } 519 520 limit = DEVLINK_RELOAD_LIMIT_UNSPEC; 521 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) { 522 struct nla_bitfield32 limits; 523 u32 limits_selected; 524 525 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]); 526 limits_selected = limits.value & limits.selector; 527 if (!limits_selected) { 528 NL_SET_ERR_MSG(info->extack, "Invalid limit selected"); 529 return -EINVAL; 530 } 531 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++) 532 if (limits_selected & BIT(limit)) 533 break; 534 /* UAPI enables multiselection, but currently it is not used */ 535 if (limits_selected != BIT(limit)) { 536 NL_SET_ERR_MSG(info->extack, "Multiselection of limit is not supported"); 537 return -EOPNOTSUPP; 538 } 539 if (!devlink_reload_limit_is_supported(devlink, limit)) { 540 NL_SET_ERR_MSG(info->extack, "Requested limit is not supported by the driver"); 541 return -EOPNOTSUPP; 542 } 543 if (devlink_reload_combination_is_invalid(action, limit)) { 544 NL_SET_ERR_MSG(info->extack, "Requested limit is invalid for this action"); 545 return -EINVAL; 546 } 547 } 548 if (info->attrs[DEVLINK_ATTR_NETNS_PID] || 549 info->attrs[DEVLINK_ATTR_NETNS_FD] || 550 info->attrs[DEVLINK_ATTR_NETNS_ID]) { 551 dest_net = devlink_netns_get(skb, info); 552 if (IS_ERR(dest_net)) 553 return PTR_ERR(dest_net); 554 if (!net_eq(dest_net, devlink_net(devlink)) && 555 action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT) { 556 NL_SET_ERR_MSG_MOD(info->extack, 557 "Changing namespace is only supported for reinit action"); 558 return -EOPNOTSUPP; 559 } 560 } 561 562 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); 563 564 if (dest_net) 565 put_net(dest_net); 566 567 if (err) 568 return err; 569 /* For backward compatibility generate reply only if attributes used by user */ 570 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) 571 return 0; 572 573 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed, 574 DEVLINK_CMD_RELOAD, info); 575 } 576 577 bool devlink_reload_actions_valid(const struct devlink_ops *ops) 578 { 579 const struct devlink_reload_combination *comb; 580 int i; 581 582 if (!devlink_reload_supported(ops)) { 583 if (WARN_ON(ops->reload_actions)) 584 return false; 585 return true; 586 } 587 588 if (WARN_ON(!ops->reload_actions || 589 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 590 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) 591 return false; 592 593 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || 594 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) 595 return false; 596 597 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { 598 comb = &devlink_reload_invalid_combinations[i]; 599 if (ops->reload_actions == BIT(comb->action) && 600 ops->reload_limits == BIT(comb->limit)) 601 return false; 602 } 603 return true; 604 } 605 606 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink, 607 enum devlink_command cmd, u32 portid, 608 u32 seq, int flags) 609 { 610 const struct devlink_ops *ops = devlink->ops; 611 enum devlink_eswitch_encap_mode encap_mode; 612 u8 inline_mode; 613 void *hdr; 614 int err = 0; 615 u16 mode; 616 617 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 618 if (!hdr) 619 return -EMSGSIZE; 620 621 err = devlink_nl_put_handle(msg, devlink); 622 if (err) 623 goto nla_put_failure; 624 625 if (ops->eswitch_mode_get) { 626 err = ops->eswitch_mode_get(devlink, &mode); 627 if (err) 628 goto nla_put_failure; 629 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode); 630 if (err) 631 goto nla_put_failure; 632 } 633 634 if (ops->eswitch_inline_mode_get) { 635 err = ops->eswitch_inline_mode_get(devlink, &inline_mode); 636 if (err) 637 goto nla_put_failure; 638 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, 639 inline_mode); 640 if (err) 641 goto nla_put_failure; 642 } 643 644 if (ops->eswitch_encap_mode_get) { 645 err = ops->eswitch_encap_mode_get(devlink, &encap_mode); 646 if (err) 647 goto nla_put_failure; 648 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); 649 if (err) 650 goto nla_put_failure; 651 } 652 653 genlmsg_end(msg, hdr); 654 return 0; 655 656 nla_put_failure: 657 genlmsg_cancel(msg, hdr); 658 return err; 659 } 660 661 int devlink_nl_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info) 662 { 663 struct devlink *devlink = info->user_ptr[0]; 664 struct sk_buff *msg; 665 int err; 666 667 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 668 if (!msg) 669 return -ENOMEM; 670 671 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET, 672 info->snd_portid, info->snd_seq, 0); 673 674 if (err) { 675 nlmsg_free(msg); 676 return err; 677 } 678 679 return genlmsg_reply(msg, info); 680 } 681 682 int devlink_nl_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info) 683 { 684 struct devlink *devlink = info->user_ptr[0]; 685 const struct devlink_ops *ops = devlink->ops; 686 enum devlink_eswitch_encap_mode encap_mode; 687 u8 inline_mode; 688 int err = 0; 689 u16 mode; 690 691 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { 692 if (!ops->eswitch_mode_set) 693 return -EOPNOTSUPP; 694 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]); 695 err = devlink_rate_nodes_check(devlink, mode, info->extack); 696 if (err) 697 return err; 698 err = ops->eswitch_mode_set(devlink, mode, info->extack); 699 if (err) 700 return err; 701 } 702 703 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) { 704 if (!ops->eswitch_inline_mode_set) 705 return -EOPNOTSUPP; 706 inline_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]); 707 err = ops->eswitch_inline_mode_set(devlink, inline_mode, 708 info->extack); 709 if (err) 710 return err; 711 } 712 713 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { 714 if (!ops->eswitch_encap_mode_set) 715 return -EOPNOTSUPP; 716 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); 717 err = ops->eswitch_encap_mode_set(devlink, encap_mode, 718 info->extack); 719 if (err) 720 return err; 721 } 722 723 return 0; 724 } 725 726 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) 727 { 728 if (!req->msg) 729 return 0; 730 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); 731 } 732 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); 733 734 int devlink_info_board_serial_number_put(struct devlink_info_req *req, 735 const char *bsn) 736 { 737 if (!req->msg) 738 return 0; 739 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, 740 bsn); 741 } 742 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); 743 744 static int devlink_info_version_put(struct devlink_info_req *req, int attr, 745 const char *version_name, 746 const char *version_value, 747 enum devlink_info_version_type version_type) 748 { 749 struct nlattr *nest; 750 int err; 751 752 if (req->version_cb) 753 req->version_cb(version_name, version_type, 754 req->version_cb_priv); 755 756 if (!req->msg) 757 return 0; 758 759 nest = nla_nest_start_noflag(req->msg, attr); 760 if (!nest) 761 return -EMSGSIZE; 762 763 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, 764 version_name); 765 if (err) 766 goto nla_put_failure; 767 768 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, 769 version_value); 770 if (err) 771 goto nla_put_failure; 772 773 nla_nest_end(req->msg, nest); 774 775 return 0; 776 777 nla_put_failure: 778 nla_nest_cancel(req->msg, nest); 779 return err; 780 } 781 782 int devlink_info_version_fixed_put(struct devlink_info_req *req, 783 const char *version_name, 784 const char *version_value) 785 { 786 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, 787 version_name, version_value, 788 DEVLINK_INFO_VERSION_TYPE_NONE); 789 } 790 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); 791 792 int devlink_info_version_stored_put(struct devlink_info_req *req, 793 const char *version_name, 794 const char *version_value) 795 { 796 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 797 version_name, version_value, 798 DEVLINK_INFO_VERSION_TYPE_NONE); 799 } 800 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); 801 802 int devlink_info_version_stored_put_ext(struct devlink_info_req *req, 803 const char *version_name, 804 const char *version_value, 805 enum devlink_info_version_type version_type) 806 { 807 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 808 version_name, version_value, 809 version_type); 810 } 811 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext); 812 813 int devlink_info_version_running_put(struct devlink_info_req *req, 814 const char *version_name, 815 const char *version_value) 816 { 817 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 818 version_name, version_value, 819 DEVLINK_INFO_VERSION_TYPE_NONE); 820 } 821 EXPORT_SYMBOL_GPL(devlink_info_version_running_put); 822 823 int devlink_info_version_running_put_ext(struct devlink_info_req *req, 824 const char *version_name, 825 const char *version_value, 826 enum devlink_info_version_type version_type) 827 { 828 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 829 version_name, version_value, 830 version_type); 831 } 832 EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext); 833 834 static int devlink_nl_driver_info_get(struct device_driver *drv, 835 struct devlink_info_req *req) 836 { 837 if (!drv) 838 return 0; 839 840 if (drv->name[0]) 841 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, 842 drv->name); 843 844 return 0; 845 } 846 847 static int 848 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, 849 enum devlink_command cmd, u32 portid, 850 u32 seq, int flags, struct netlink_ext_ack *extack) 851 { 852 struct device *dev = devlink_to_dev(devlink); 853 struct devlink_info_req req = {}; 854 void *hdr; 855 int err; 856 857 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 858 if (!hdr) 859 return -EMSGSIZE; 860 861 err = -EMSGSIZE; 862 if (devlink_nl_put_handle(msg, devlink)) 863 goto err_cancel_msg; 864 865 req.msg = msg; 866 if (devlink->ops->info_get) { 867 err = devlink->ops->info_get(devlink, &req, extack); 868 if (err) 869 goto err_cancel_msg; 870 } 871 872 err = devlink_nl_driver_info_get(dev->driver, &req); 873 if (err) 874 goto err_cancel_msg; 875 876 genlmsg_end(msg, hdr); 877 return 0; 878 879 err_cancel_msg: 880 genlmsg_cancel(msg, hdr); 881 return err; 882 } 883 884 int devlink_nl_info_get_doit(struct sk_buff *skb, struct genl_info *info) 885 { 886 struct devlink *devlink = info->user_ptr[0]; 887 struct sk_buff *msg; 888 int err; 889 890 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 891 if (!msg) 892 return -ENOMEM; 893 894 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 895 info->snd_portid, info->snd_seq, 0, 896 info->extack); 897 if (err) { 898 nlmsg_free(msg); 899 return err; 900 } 901 902 return genlmsg_reply(msg, info); 903 } 904 905 static int 906 devlink_nl_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 907 struct netlink_callback *cb, int flags) 908 { 909 int err; 910 911 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 912 NETLINK_CB(cb->skb).portid, 913 cb->nlh->nlmsg_seq, flags, 914 cb->extack); 915 if (err == -EOPNOTSUPP) 916 err = 0; 917 return err; 918 } 919 920 int devlink_nl_info_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) 921 { 922 return devlink_nl_dumpit(msg, cb, devlink_nl_info_get_dump_one); 923 } 924 925 static int devlink_nl_flash_update_fill(struct sk_buff *msg, 926 struct devlink *devlink, 927 enum devlink_command cmd, 928 struct devlink_flash_notify *params) 929 { 930 void *hdr; 931 932 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd); 933 if (!hdr) 934 return -EMSGSIZE; 935 936 if (devlink_nl_put_handle(msg, devlink)) 937 goto nla_put_failure; 938 939 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS) 940 goto out; 941 942 if (params->status_msg && 943 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG, 944 params->status_msg)) 945 goto nla_put_failure; 946 if (params->component && 947 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, 948 params->component)) 949 goto nla_put_failure; 950 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, 951 params->done, DEVLINK_ATTR_PAD)) 952 goto nla_put_failure; 953 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, 954 params->total, DEVLINK_ATTR_PAD)) 955 goto nla_put_failure; 956 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, 957 params->timeout, DEVLINK_ATTR_PAD)) 958 goto nla_put_failure; 959 960 out: 961 genlmsg_end(msg, hdr); 962 return 0; 963 964 nla_put_failure: 965 genlmsg_cancel(msg, hdr); 966 return -EMSGSIZE; 967 } 968 969 static void __devlink_flash_update_notify(struct devlink *devlink, 970 enum devlink_command cmd, 971 struct devlink_flash_notify *params) 972 { 973 struct sk_buff *msg; 974 int err; 975 976 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE && 977 cmd != DEVLINK_CMD_FLASH_UPDATE_END && 978 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS); 979 980 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 981 return; 982 983 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 984 if (!msg) 985 return; 986 987 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params); 988 if (err) 989 goto out_free_msg; 990 991 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 992 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 993 return; 994 995 out_free_msg: 996 nlmsg_free(msg); 997 } 998 999 static void devlink_flash_update_begin_notify(struct devlink *devlink) 1000 { 1001 struct devlink_flash_notify params = {}; 1002 1003 __devlink_flash_update_notify(devlink, 1004 DEVLINK_CMD_FLASH_UPDATE, 1005 ¶ms); 1006 } 1007 1008 static void devlink_flash_update_end_notify(struct devlink *devlink) 1009 { 1010 struct devlink_flash_notify params = {}; 1011 1012 __devlink_flash_update_notify(devlink, 1013 DEVLINK_CMD_FLASH_UPDATE_END, 1014 ¶ms); 1015 } 1016 1017 void devlink_flash_update_status_notify(struct devlink *devlink, 1018 const char *status_msg, 1019 const char *component, 1020 unsigned long done, 1021 unsigned long total) 1022 { 1023 struct devlink_flash_notify params = { 1024 .status_msg = status_msg, 1025 .component = component, 1026 .done = done, 1027 .total = total, 1028 }; 1029 1030 __devlink_flash_update_notify(devlink, 1031 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1032 ¶ms); 1033 } 1034 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); 1035 1036 void devlink_flash_update_timeout_notify(struct devlink *devlink, 1037 const char *status_msg, 1038 const char *component, 1039 unsigned long timeout) 1040 { 1041 struct devlink_flash_notify params = { 1042 .status_msg = status_msg, 1043 .component = component, 1044 .timeout = timeout, 1045 }; 1046 1047 __devlink_flash_update_notify(devlink, 1048 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1049 ¶ms); 1050 } 1051 EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); 1052 1053 struct devlink_flash_component_lookup_ctx { 1054 const char *lookup_name; 1055 bool lookup_name_found; 1056 }; 1057 1058 static void 1059 devlink_flash_component_lookup_cb(const char *version_name, 1060 enum devlink_info_version_type version_type, 1061 void *version_cb_priv) 1062 { 1063 struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv; 1064 1065 if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT || 1066 lookup_ctx->lookup_name_found) 1067 return; 1068 1069 lookup_ctx->lookup_name_found = 1070 !strcmp(lookup_ctx->lookup_name, version_name); 1071 } 1072 1073 static int devlink_flash_component_get(struct devlink *devlink, 1074 struct nlattr *nla_component, 1075 const char **p_component, 1076 struct netlink_ext_ack *extack) 1077 { 1078 struct devlink_flash_component_lookup_ctx lookup_ctx = {}; 1079 struct devlink_info_req req = {}; 1080 const char *component; 1081 int ret; 1082 1083 if (!nla_component) 1084 return 0; 1085 1086 component = nla_data(nla_component); 1087 1088 if (!devlink->ops->info_get) { 1089 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1090 "component update is not supported by this device"); 1091 return -EOPNOTSUPP; 1092 } 1093 1094 lookup_ctx.lookup_name = component; 1095 req.version_cb = devlink_flash_component_lookup_cb; 1096 req.version_cb_priv = &lookup_ctx; 1097 1098 ret = devlink->ops->info_get(devlink, &req, NULL); 1099 if (ret) 1100 return ret; 1101 1102 if (!lookup_ctx.lookup_name_found) { 1103 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1104 "selected component is not supported by this device"); 1105 return -EINVAL; 1106 } 1107 *p_component = component; 1108 return 0; 1109 } 1110 1111 int devlink_nl_flash_update_doit(struct sk_buff *skb, struct genl_info *info) 1112 { 1113 struct nlattr *nla_overwrite_mask, *nla_file_name; 1114 struct devlink_flash_update_params params = {}; 1115 struct devlink *devlink = info->user_ptr[0]; 1116 const char *file_name; 1117 u32 supported_params; 1118 int ret; 1119 1120 if (!devlink->ops->flash_update) 1121 return -EOPNOTSUPP; 1122 1123 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME)) 1124 return -EINVAL; 1125 1126 ret = devlink_flash_component_get(devlink, 1127 info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT], 1128 ¶ms.component, info->extack); 1129 if (ret) 1130 return ret; 1131 1132 supported_params = devlink->ops->supported_flash_update_params; 1133 1134 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK]; 1135 if (nla_overwrite_mask) { 1136 struct nla_bitfield32 sections; 1137 1138 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) { 1139 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask, 1140 "overwrite settings are not supported by this device"); 1141 return -EOPNOTSUPP; 1142 } 1143 sections = nla_get_bitfield32(nla_overwrite_mask); 1144 params.overwrite_mask = sections.value & sections.selector; 1145 } 1146 1147 nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]; 1148 file_name = nla_data(nla_file_name); 1149 ret = request_firmware(¶ms.fw, file_name, devlink->dev); 1150 if (ret) { 1151 NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, 1152 "failed to locate the requested firmware file"); 1153 return ret; 1154 } 1155 1156 devlink_flash_update_begin_notify(devlink); 1157 ret = devlink->ops->flash_update(devlink, ¶ms, info->extack); 1158 devlink_flash_update_end_notify(devlink); 1159 1160 release_firmware(params.fw); 1161 1162 return ret; 1163 } 1164 1165 static void __devlink_compat_running_version(struct devlink *devlink, 1166 char *buf, size_t len) 1167 { 1168 struct devlink_info_req req = {}; 1169 const struct nlattr *nlattr; 1170 struct sk_buff *msg; 1171 int rem, err; 1172 1173 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1174 if (!msg) 1175 return; 1176 1177 req.msg = msg; 1178 err = devlink->ops->info_get(devlink, &req, NULL); 1179 if (err) 1180 goto free_msg; 1181 1182 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) { 1183 const struct nlattr *kv; 1184 int rem_kv; 1185 1186 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING) 1187 continue; 1188 1189 nla_for_each_nested(kv, nlattr, rem_kv) { 1190 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE) 1191 continue; 1192 1193 strlcat(buf, nla_data(kv), len); 1194 strlcat(buf, " ", len); 1195 } 1196 } 1197 free_msg: 1198 nlmsg_free(msg); 1199 } 1200 1201 void devlink_compat_running_version(struct devlink *devlink, 1202 char *buf, size_t len) 1203 { 1204 if (!devlink->ops->info_get) 1205 return; 1206 1207 devl_lock(devlink); 1208 if (devl_is_registered(devlink)) 1209 __devlink_compat_running_version(devlink, buf, len); 1210 devl_unlock(devlink); 1211 } 1212 1213 int devlink_compat_flash_update(struct devlink *devlink, const char *file_name) 1214 { 1215 struct devlink_flash_update_params params = {}; 1216 int ret; 1217 1218 devl_lock(devlink); 1219 if (!devl_is_registered(devlink)) { 1220 ret = -ENODEV; 1221 goto out_unlock; 1222 } 1223 1224 if (!devlink->ops->flash_update) { 1225 ret = -EOPNOTSUPP; 1226 goto out_unlock; 1227 } 1228 1229 ret = request_firmware(¶ms.fw, file_name, devlink->dev); 1230 if (ret) 1231 goto out_unlock; 1232 1233 devlink_flash_update_begin_notify(devlink); 1234 ret = devlink->ops->flash_update(devlink, ¶ms, NULL); 1235 devlink_flash_update_end_notify(devlink); 1236 1237 release_firmware(params.fw); 1238 out_unlock: 1239 devl_unlock(devlink); 1240 1241 return ret; 1242 } 1243 1244 static int 1245 devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink, 1246 u32 portid, u32 seq, int flags, 1247 struct netlink_ext_ack *extack) 1248 { 1249 struct nlattr *selftests; 1250 void *hdr; 1251 int err; 1252 int i; 1253 1254 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, 1255 DEVLINK_CMD_SELFTESTS_GET); 1256 if (!hdr) 1257 return -EMSGSIZE; 1258 1259 err = -EMSGSIZE; 1260 if (devlink_nl_put_handle(msg, devlink)) 1261 goto err_cancel_msg; 1262 1263 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1264 if (!selftests) 1265 goto err_cancel_msg; 1266 1267 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1268 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1269 if (devlink->ops->selftest_check(devlink, i, extack)) { 1270 err = nla_put_flag(msg, i); 1271 if (err) 1272 goto err_cancel_msg; 1273 } 1274 } 1275 1276 nla_nest_end(msg, selftests); 1277 genlmsg_end(msg, hdr); 1278 return 0; 1279 1280 err_cancel_msg: 1281 genlmsg_cancel(msg, hdr); 1282 return err; 1283 } 1284 1285 int devlink_nl_selftests_get_doit(struct sk_buff *skb, struct genl_info *info) 1286 { 1287 struct devlink *devlink = info->user_ptr[0]; 1288 struct sk_buff *msg; 1289 int err; 1290 1291 if (!devlink->ops->selftest_check) 1292 return -EOPNOTSUPP; 1293 1294 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1295 if (!msg) 1296 return -ENOMEM; 1297 1298 err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid, 1299 info->snd_seq, 0, info->extack); 1300 if (err) { 1301 nlmsg_free(msg); 1302 return err; 1303 } 1304 1305 return genlmsg_reply(msg, info); 1306 } 1307 1308 static int devlink_nl_selftests_get_dump_one(struct sk_buff *msg, 1309 struct devlink *devlink, 1310 struct netlink_callback *cb, 1311 int flags) 1312 { 1313 if (!devlink->ops->selftest_check) 1314 return 0; 1315 1316 return devlink_nl_selftests_fill(msg, devlink, 1317 NETLINK_CB(cb->skb).portid, 1318 cb->nlh->nlmsg_seq, flags, 1319 cb->extack); 1320 } 1321 1322 int devlink_nl_selftests_get_dumpit(struct sk_buff *skb, 1323 struct netlink_callback *cb) 1324 { 1325 return devlink_nl_dumpit(skb, cb, devlink_nl_selftests_get_dump_one); 1326 } 1327 1328 static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id, 1329 enum devlink_selftest_status test_status) 1330 { 1331 struct nlattr *result_attr; 1332 1333 result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT); 1334 if (!result_attr) 1335 return -EMSGSIZE; 1336 1337 if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) || 1338 nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS, 1339 test_status)) 1340 goto nla_put_failure; 1341 1342 nla_nest_end(skb, result_attr); 1343 return 0; 1344 1345 nla_put_failure: 1346 nla_nest_cancel(skb, result_attr); 1347 return -EMSGSIZE; 1348 } 1349 1350 static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = { 1351 [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG }, 1352 }; 1353 1354 int devlink_nl_selftests_run_doit(struct sk_buff *skb, struct genl_info *info) 1355 { 1356 struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1]; 1357 struct devlink *devlink = info->user_ptr[0]; 1358 struct nlattr *attrs, *selftests; 1359 struct sk_buff *msg; 1360 void *hdr; 1361 int err; 1362 int i; 1363 1364 if (!devlink->ops->selftest_run || !devlink->ops->selftest_check) 1365 return -EOPNOTSUPP; 1366 1367 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS)) 1368 return -EINVAL; 1369 1370 attrs = info->attrs[DEVLINK_ATTR_SELFTESTS]; 1371 1372 err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs, 1373 devlink_selftest_nl_policy, info->extack); 1374 if (err < 0) 1375 return err; 1376 1377 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1378 if (!msg) 1379 return -ENOMEM; 1380 1381 err = -EMSGSIZE; 1382 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, 1383 &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN); 1384 if (!hdr) 1385 goto free_msg; 1386 1387 if (devlink_nl_put_handle(msg, devlink)) 1388 goto genlmsg_cancel; 1389 1390 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1391 if (!selftests) 1392 goto genlmsg_cancel; 1393 1394 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1395 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1396 enum devlink_selftest_status test_status; 1397 1398 if (nla_get_flag(tb[i])) { 1399 if (!devlink->ops->selftest_check(devlink, i, 1400 info->extack)) { 1401 if (devlink_selftest_result_put(msg, i, 1402 DEVLINK_SELFTEST_STATUS_SKIP)) 1403 goto selftests_nest_cancel; 1404 continue; 1405 } 1406 1407 test_status = devlink->ops->selftest_run(devlink, i, 1408 info->extack); 1409 if (devlink_selftest_result_put(msg, i, test_status)) 1410 goto selftests_nest_cancel; 1411 } 1412 } 1413 1414 nla_nest_end(msg, selftests); 1415 genlmsg_end(msg, hdr); 1416 return genlmsg_reply(msg, info); 1417 1418 selftests_nest_cancel: 1419 nla_nest_cancel(msg, selftests); 1420 genlmsg_cancel: 1421 genlmsg_cancel(msg, hdr); 1422 free_msg: 1423 nlmsg_free(msg); 1424 return err; 1425 } 1426