1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * net/core/devlink.c - Network physical/parent device Netlink interface 4 * 5 * Heavily inspired by net/wireless/ 6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 8 */ 9 10#include <linux/kernel.h> 11#include <linux/module.h> 12#include <linux/types.h> 13#include <linux/slab.h> 14#include <linux/gfp.h> 15#include <linux/device.h> 16#include <linux/list.h> 17#include <linux/netdevice.h> 18#include <linux/spinlock.h> 19#include <linux/refcount.h> 20#include <linux/workqueue.h> 21#include <linux/u64_stats_sync.h> 22#include <linux/timekeeping.h> 23#include <rdma/ib_verbs.h> 24#include <net/netlink.h> 25#include <net/genetlink.h> 26#include <net/rtnetlink.h> 27#include <net/net_namespace.h> 28#include <net/sock.h> 29#include <net/devlink.h> 30#define CREATE_TRACE_POINTS 31#include <trace/events/devlink.h> 32 33static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = { 34 { 35 .name = "destination mac", 36 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC, 37 .bitwidth = 48, 38 }, 39}; 40 41struct devlink_dpipe_header devlink_dpipe_header_ethernet = { 42 .name = "ethernet", 43 .id = DEVLINK_DPIPE_HEADER_ETHERNET, 44 .fields = devlink_dpipe_fields_ethernet, 45 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet), 46 .global = true, 47}; 48EXPORT_SYMBOL(devlink_dpipe_header_ethernet); 49 50static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = { 51 { 52 .name = "destination ip", 53 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP, 54 .bitwidth = 32, 55 }, 56}; 57 58struct devlink_dpipe_header devlink_dpipe_header_ipv4 = { 59 .name = "ipv4", 60 .id = DEVLINK_DPIPE_HEADER_IPV4, 61 .fields = devlink_dpipe_fields_ipv4, 62 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4), 63 .global = true, 64}; 65EXPORT_SYMBOL(devlink_dpipe_header_ipv4); 66 67static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = { 68 { 69 .name = "destination ip", 70 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP, 71 .bitwidth = 128, 72 }, 73}; 74 75struct devlink_dpipe_header devlink_dpipe_header_ipv6 = { 76 .name = "ipv6", 77 .id = DEVLINK_DPIPE_HEADER_IPV6, 78 .fields = devlink_dpipe_fields_ipv6, 79 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6), 80 .global = true, 81}; 82EXPORT_SYMBOL(devlink_dpipe_header_ipv6); 83 84EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg); 85EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr); 86EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report); 87 88static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = { 89 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY }, 90}; 91 92static LIST_HEAD(devlink_list); 93 94/* devlink_mutex 95 * 96 * An overall lock guarding every operation coming from userspace. 97 * It also guards devlink devices list and it is taken when 98 * driver registers/unregisters it. 99 */ 100static DEFINE_MUTEX(devlink_mutex); 101 102struct net *devlink_net(const struct devlink *devlink) 103{ 104 return read_pnet(&devlink->_net); 105} 106EXPORT_SYMBOL_GPL(devlink_net); 107 108static void __devlink_net_set(struct devlink *devlink, struct net *net) 109{ 110 write_pnet(&devlink->_net, net); 111} 112 113void devlink_net_set(struct devlink *devlink, struct net *net) 114{ 115 if (WARN_ON(devlink->registered)) 116 return; 117 __devlink_net_set(devlink, net); 118} 119EXPORT_SYMBOL_GPL(devlink_net_set); 120 121static struct devlink *devlink_get_from_attrs(struct net *net, 122 struct nlattr **attrs) 123{ 124 struct devlink *devlink; 125 char *busname; 126 char *devname; 127 128 if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME]) 129 return ERR_PTR(-EINVAL); 130 131 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]); 132 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]); 133 134 lockdep_assert_held(&devlink_mutex); 135 136 list_for_each_entry(devlink, &devlink_list, list) { 137 if (strcmp(devlink->dev->bus->name, busname) == 0 && 138 strcmp(dev_name(devlink->dev), devname) == 0 && 139 net_eq(devlink_net(devlink), net)) 140 return devlink; 141 } 142 143 return ERR_PTR(-ENODEV); 144} 145 146static struct devlink *devlink_get_from_info(struct genl_info *info) 147{ 148 return devlink_get_from_attrs(genl_info_net(info), info->attrs); 149} 150 151static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink, 152 unsigned int port_index) 153{ 154 struct devlink_port *devlink_port; 155 156 list_for_each_entry(devlink_port, &devlink->port_list, list) { 157 if (devlink_port->index == port_index) 158 return devlink_port; 159 } 160 return NULL; 161} 162 163static bool devlink_port_index_exists(struct devlink *devlink, 164 unsigned int port_index) 165{ 166 return devlink_port_get_by_index(devlink, port_index); 167} 168 169static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink, 170 struct nlattr **attrs) 171{ 172 if (attrs[DEVLINK_ATTR_PORT_INDEX]) { 173 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]); 174 struct devlink_port *devlink_port; 175 176 devlink_port = devlink_port_get_by_index(devlink, port_index); 177 if (!devlink_port) 178 return ERR_PTR(-ENODEV); 179 return devlink_port; 180 } 181 return ERR_PTR(-EINVAL); 182} 183 184static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink, 185 struct genl_info *info) 186{ 187 return devlink_port_get_from_attrs(devlink, info->attrs); 188} 189 190struct devlink_sb { 191 struct list_head list; 192 unsigned int index; 193 u32 size; 194 u16 ingress_pools_count; 195 u16 egress_pools_count; 196 u16 ingress_tc_count; 197 u16 egress_tc_count; 198}; 199 200static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb) 201{ 202 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count; 203} 204 205static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink, 206 unsigned int sb_index) 207{ 208 struct devlink_sb *devlink_sb; 209 210 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 211 if (devlink_sb->index == sb_index) 212 return devlink_sb; 213 } 214 return NULL; 215} 216 217static bool devlink_sb_index_exists(struct devlink *devlink, 218 unsigned int sb_index) 219{ 220 return devlink_sb_get_by_index(devlink, sb_index); 221} 222 223static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink, 224 struct nlattr **attrs) 225{ 226 if (attrs[DEVLINK_ATTR_SB_INDEX]) { 227 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]); 228 struct devlink_sb *devlink_sb; 229 230 devlink_sb = devlink_sb_get_by_index(devlink, sb_index); 231 if (!devlink_sb) 232 return ERR_PTR(-ENODEV); 233 return devlink_sb; 234 } 235 return ERR_PTR(-EINVAL); 236} 237 238static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink, 239 struct genl_info *info) 240{ 241 return devlink_sb_get_from_attrs(devlink, info->attrs); 242} 243 244static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb, 245 struct nlattr **attrs, 246 u16 *p_pool_index) 247{ 248 u16 val; 249 250 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX]) 251 return -EINVAL; 252 253 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]); 254 if (val >= devlink_sb_pool_count(devlink_sb)) 255 return -EINVAL; 256 *p_pool_index = val; 257 return 0; 258} 259 260static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb, 261 struct genl_info *info, 262 u16 *p_pool_index) 263{ 264 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs, 265 p_pool_index); 266} 267 268static int 269devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs, 270 enum devlink_sb_pool_type *p_pool_type) 271{ 272 u8 val; 273 274 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE]) 275 return -EINVAL; 276 277 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]); 278 if (val != DEVLINK_SB_POOL_TYPE_INGRESS && 279 val != DEVLINK_SB_POOL_TYPE_EGRESS) 280 return -EINVAL; 281 *p_pool_type = val; 282 return 0; 283} 284 285static int 286devlink_sb_pool_type_get_from_info(struct genl_info *info, 287 enum devlink_sb_pool_type *p_pool_type) 288{ 289 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type); 290} 291 292static int 293devlink_sb_th_type_get_from_attrs(struct nlattr **attrs, 294 enum devlink_sb_threshold_type *p_th_type) 295{ 296 u8 val; 297 298 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]) 299 return -EINVAL; 300 301 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]); 302 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC && 303 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC) 304 return -EINVAL; 305 *p_th_type = val; 306 return 0; 307} 308 309static int 310devlink_sb_th_type_get_from_info(struct genl_info *info, 311 enum devlink_sb_threshold_type *p_th_type) 312{ 313 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type); 314} 315 316static int 317devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb, 318 struct nlattr **attrs, 319 enum devlink_sb_pool_type pool_type, 320 u16 *p_tc_index) 321{ 322 u16 val; 323 324 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX]) 325 return -EINVAL; 326 327 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]); 328 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS && 329 val >= devlink_sb->ingress_tc_count) 330 return -EINVAL; 331 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS && 332 val >= devlink_sb->egress_tc_count) 333 return -EINVAL; 334 *p_tc_index = val; 335 return 0; 336} 337 338static int 339devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb, 340 struct genl_info *info, 341 enum devlink_sb_pool_type pool_type, 342 u16 *p_tc_index) 343{ 344 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs, 345 pool_type, p_tc_index); 346} 347 348struct devlink_region { 349 struct devlink *devlink; 350 struct devlink_port *port; 351 struct list_head list; 352 union { 353 const struct devlink_region_ops *ops; 354 const struct devlink_port_region_ops *port_ops; 355 }; 356 struct list_head snapshot_list; 357 u32 max_snapshots; 358 u32 cur_snapshots; 359 u64 size; 360}; 361 362struct devlink_snapshot { 363 struct list_head list; 364 struct devlink_region *region; 365 u8 *data; 366 u32 id; 367}; 368 369static struct devlink_region * 370devlink_region_get_by_name(struct devlink *devlink, const char *region_name) 371{ 372 struct devlink_region *region; 373 374 list_for_each_entry(region, &devlink->region_list, list) 375 if (!strcmp(region->ops->name, region_name)) 376 return region; 377 378 return NULL; 379} 380 381static struct devlink_region * 382devlink_port_region_get_by_name(struct devlink_port *port, 383 const char *region_name) 384{ 385 struct devlink_region *region; 386 387 list_for_each_entry(region, &port->region_list, list) 388 if (!strcmp(region->ops->name, region_name)) 389 return region; 390 391 return NULL; 392} 393 394static struct devlink_snapshot * 395devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id) 396{ 397 struct devlink_snapshot *snapshot; 398 399 list_for_each_entry(snapshot, ®ion->snapshot_list, list) 400 if (snapshot->id == id) 401 return snapshot; 402 403 return NULL; 404} 405 406#define DEVLINK_NL_FLAG_NEED_PORT BIT(0) 407#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1) 408 409/* The per devlink instance lock is taken by default in the pre-doit 410 * operation, yet several commands do not require this. The global 411 * devlink lock is taken and protects from disruption by user-calls. 412 */ 413#define DEVLINK_NL_FLAG_NO_LOCK BIT(2) 414 415static int devlink_nl_pre_doit(const struct genl_ops *ops, 416 struct sk_buff *skb, struct genl_info *info) 417{ 418 struct devlink_port *devlink_port; 419 struct devlink *devlink; 420 int err; 421 422 mutex_lock(&devlink_mutex); 423 devlink = devlink_get_from_info(info); 424 if (IS_ERR(devlink)) { 425 mutex_unlock(&devlink_mutex); 426 return PTR_ERR(devlink); 427 } 428 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK) 429 mutex_lock(&devlink->lock); 430 info->user_ptr[0] = devlink; 431 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) { 432 devlink_port = devlink_port_get_from_info(devlink, info); 433 if (IS_ERR(devlink_port)) { 434 err = PTR_ERR(devlink_port); 435 goto unlock; 436 } 437 info->user_ptr[1] = devlink_port; 438 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) { 439 devlink_port = devlink_port_get_from_info(devlink, info); 440 if (!IS_ERR(devlink_port)) 441 info->user_ptr[1] = devlink_port; 442 } 443 return 0; 444 445unlock: 446 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK) 447 mutex_unlock(&devlink->lock); 448 mutex_unlock(&devlink_mutex); 449 return err; 450} 451 452static void devlink_nl_post_doit(const struct genl_ops *ops, 453 struct sk_buff *skb, struct genl_info *info) 454{ 455 struct devlink *devlink; 456 457 devlink = info->user_ptr[0]; 458 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK) 459 mutex_unlock(&devlink->lock); 460 mutex_unlock(&devlink_mutex); 461} 462 463static struct genl_family devlink_nl_family; 464 465enum devlink_multicast_groups { 466 DEVLINK_MCGRP_CONFIG, 467}; 468 469static const struct genl_multicast_group devlink_nl_mcgrps[] = { 470 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME }, 471}; 472 473static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink) 474{ 475 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name)) 476 return -EMSGSIZE; 477 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev))) 478 return -EMSGSIZE; 479 return 0; 480} 481 482struct devlink_reload_combination { 483 enum devlink_reload_action action; 484 enum devlink_reload_limit limit; 485}; 486 487static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = { 488 { 489 /* can't reinitialize driver with no down time */ 490 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 491 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET, 492 }, 493}; 494 495static bool 496devlink_reload_combination_is_invalid(enum devlink_reload_action action, 497 enum devlink_reload_limit limit) 498{ 499 int i; 500 501 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) 502 if (devlink_reload_invalid_combinations[i].action == action && 503 devlink_reload_invalid_combinations[i].limit == limit) 504 return true; 505 return false; 506} 507 508static bool 509devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action) 510{ 511 return test_bit(action, &devlink->ops->reload_actions); 512} 513 514static bool 515devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit) 516{ 517 return test_bit(limit, &devlink->ops->reload_limits); 518} 519 520static int devlink_reload_stat_put(struct sk_buff *msg, 521 enum devlink_reload_limit limit, u32 value) 522{ 523 struct nlattr *reload_stats_entry; 524 525 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY); 526 if (!reload_stats_entry) 527 return -EMSGSIZE; 528 529 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || 530 nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) 531 goto nla_put_failure; 532 nla_nest_end(msg, reload_stats_entry); 533 return 0; 534 535nla_put_failure: 536 nla_nest_cancel(msg, reload_stats_entry); 537 return -EMSGSIZE; 538} 539 540static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) 541{ 542 struct nlattr *reload_stats_attr, *act_info, *act_stats; 543 int i, j, stat_idx; 544 u32 value; 545 546 if (!is_remote) 547 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS); 548 else 549 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS); 550 551 if (!reload_stats_attr) 552 return -EMSGSIZE; 553 554 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { 555 if ((!is_remote && 556 !devlink_reload_action_is_supported(devlink, i)) || 557 i == DEVLINK_RELOAD_ACTION_UNSPEC) 558 continue; 559 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO); 560 if (!act_info) 561 goto nla_put_failure; 562 563 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i)) 564 goto action_info_nest_cancel; 565 act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS); 566 if (!act_stats) 567 goto action_info_nest_cancel; 568 569 for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { 570 /* Remote stats are shown even if not locally supported. 571 * Stats of actions with unspecified limit are shown 572 * though drivers don't need to register unspecified 573 * limit. 574 */ 575 if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && 576 !devlink_reload_limit_is_supported(devlink, j)) || 577 devlink_reload_combination_is_invalid(i, j)) 578 continue; 579 580 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i; 581 if (!is_remote) 582 value = devlink->stats.reload_stats[stat_idx]; 583 else 584 value = devlink->stats.remote_reload_stats[stat_idx]; 585 if (devlink_reload_stat_put(msg, j, value)) 586 goto action_stats_nest_cancel; 587 } 588 nla_nest_end(msg, act_stats); 589 nla_nest_end(msg, act_info); 590 } 591 nla_nest_end(msg, reload_stats_attr); 592 return 0; 593 594action_stats_nest_cancel: 595 nla_nest_cancel(msg, act_stats); 596action_info_nest_cancel: 597 nla_nest_cancel(msg, act_info); 598nla_put_failure: 599 nla_nest_cancel(msg, reload_stats_attr); 600 return -EMSGSIZE; 601} 602 603static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink, 604 enum devlink_command cmd, u32 portid, 605 u32 seq, int flags) 606{ 607 struct nlattr *dev_stats; 608 void *hdr; 609 610 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 611 if (!hdr) 612 return -EMSGSIZE; 613 614 if (devlink_nl_put_handle(msg, devlink)) 615 goto nla_put_failure; 616 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed)) 617 goto nla_put_failure; 618 619 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS); 620 if (!dev_stats) 621 goto nla_put_failure; 622 623 if (devlink_reload_stats_put(msg, devlink, false)) 624 goto dev_stats_nest_cancel; 625 if (devlink_reload_stats_put(msg, devlink, true)) 626 goto dev_stats_nest_cancel; 627 628 nla_nest_end(msg, dev_stats); 629 genlmsg_end(msg, hdr); 630 return 0; 631 632dev_stats_nest_cancel: 633 nla_nest_cancel(msg, dev_stats); 634nla_put_failure: 635 genlmsg_cancel(msg, hdr); 636 return -EMSGSIZE; 637} 638 639static void devlink_notify(struct devlink *devlink, enum devlink_command cmd) 640{ 641 struct sk_buff *msg; 642 int err; 643 644 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL); 645 646 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 647 if (!msg) 648 return; 649 650 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0); 651 if (err) { 652 nlmsg_free(msg); 653 return; 654 } 655 656 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 657 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 658} 659 660static int devlink_nl_port_attrs_put(struct sk_buff *msg, 661 struct devlink_port *devlink_port) 662{ 663 struct devlink_port_attrs *attrs = &devlink_port->attrs; 664 665 if (!devlink_port->attrs_set) 666 return 0; 667 if (attrs->lanes) { 668 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes)) 669 return -EMSGSIZE; 670 } 671 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable)) 672 return -EMSGSIZE; 673 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour)) 674 return -EMSGSIZE; 675 switch (devlink_port->attrs.flavour) { 676 case DEVLINK_PORT_FLAVOUR_PCI_PF: 677 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, 678 attrs->pci_pf.controller) || 679 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf)) 680 return -EMSGSIZE; 681 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external)) 682 return -EMSGSIZE; 683 break; 684 case DEVLINK_PORT_FLAVOUR_PCI_VF: 685 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, 686 attrs->pci_vf.controller) || 687 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) || 688 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf)) 689 return -EMSGSIZE; 690 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external)) 691 return -EMSGSIZE; 692 break; 693 case DEVLINK_PORT_FLAVOUR_PHYSICAL: 694 case DEVLINK_PORT_FLAVOUR_CPU: 695 case DEVLINK_PORT_FLAVOUR_DSA: 696 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, 697 attrs->phys.port_number)) 698 return -EMSGSIZE; 699 if (!attrs->split) 700 return 0; 701 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, 702 attrs->phys.port_number)) 703 return -EMSGSIZE; 704 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER, 705 attrs->phys.split_subport_number)) 706 return -EMSGSIZE; 707 break; 708 default: 709 break; 710 } 711 return 0; 712} 713 714static int 715devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port, 716 struct netlink_ext_ack *extack) 717{ 718 struct devlink *devlink = port->devlink; 719 const struct devlink_ops *ops; 720 struct nlattr *function_attr; 721 bool empty_nest = true; 722 int err = 0; 723 724 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION); 725 if (!function_attr) 726 return -EMSGSIZE; 727 728 ops = devlink->ops; 729 if (ops->port_function_hw_addr_get) { 730 int hw_addr_len; 731 u8 hw_addr[MAX_ADDR_LEN]; 732 733 err = ops->port_function_hw_addr_get(devlink, port, hw_addr, &hw_addr_len, extack); 734 if (err == -EOPNOTSUPP) { 735 /* Port function attributes are optional for a port. If port doesn't 736 * support function attribute, returning -EOPNOTSUPP is not an error. 737 */ 738 err = 0; 739 goto out; 740 } else if (err) { 741 goto out; 742 } 743 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr); 744 if (err) 745 goto out; 746 empty_nest = false; 747 } 748 749out: 750 if (err || empty_nest) 751 nla_nest_cancel(msg, function_attr); 752 else 753 nla_nest_end(msg, function_attr); 754 return err; 755} 756 757static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink, 758 struct devlink_port *devlink_port, 759 enum devlink_command cmd, u32 portid, 760 u32 seq, int flags, 761 struct netlink_ext_ack *extack) 762{ 763 void *hdr; 764 765 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 766 if (!hdr) 767 return -EMSGSIZE; 768 769 if (devlink_nl_put_handle(msg, devlink)) 770 goto nla_put_failure; 771 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 772 goto nla_put_failure; 773 774 /* Hold rtnl lock while accessing port's netdev attributes. */ 775 rtnl_lock(); 776 spin_lock_bh(&devlink_port->type_lock); 777 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type)) 778 goto nla_put_failure_type_locked; 779 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET && 780 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE, 781 devlink_port->desired_type)) 782 goto nla_put_failure_type_locked; 783 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) { 784 struct net *net = devlink_net(devlink_port->devlink); 785 struct net_device *netdev = devlink_port->type_dev; 786 787 if (netdev && net_eq(net, dev_net(netdev)) && 788 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX, 789 netdev->ifindex) || 790 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME, 791 netdev->name))) 792 goto nla_put_failure_type_locked; 793 } 794 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) { 795 struct ib_device *ibdev = devlink_port->type_dev; 796 797 if (ibdev && 798 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME, 799 ibdev->name)) 800 goto nla_put_failure_type_locked; 801 } 802 spin_unlock_bh(&devlink_port->type_lock); 803 rtnl_unlock(); 804 if (devlink_nl_port_attrs_put(msg, devlink_port)) 805 goto nla_put_failure; 806 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack)) 807 goto nla_put_failure; 808 809 genlmsg_end(msg, hdr); 810 return 0; 811 812nla_put_failure_type_locked: 813 spin_unlock_bh(&devlink_port->type_lock); 814 rtnl_unlock(); 815nla_put_failure: 816 genlmsg_cancel(msg, hdr); 817 return -EMSGSIZE; 818} 819 820static void devlink_port_notify(struct devlink_port *devlink_port, 821 enum devlink_command cmd) 822{ 823 struct devlink *devlink = devlink_port->devlink; 824 struct sk_buff *msg; 825 int err; 826 827 if (!devlink_port->registered) 828 return; 829 830 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL); 831 832 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 833 if (!msg) 834 return; 835 836 err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0, 837 NULL); 838 if (err) { 839 nlmsg_free(msg); 840 return; 841 } 842 843 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 844 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 845} 846 847static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info) 848{ 849 struct devlink *devlink = info->user_ptr[0]; 850 struct sk_buff *msg; 851 int err; 852 853 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 854 if (!msg) 855 return -ENOMEM; 856 857 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 858 info->snd_portid, info->snd_seq, 0); 859 if (err) { 860 nlmsg_free(msg); 861 return err; 862 } 863 864 return genlmsg_reply(msg, info); 865} 866 867static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg, 868 struct netlink_callback *cb) 869{ 870 struct devlink *devlink; 871 int start = cb->args[0]; 872 int idx = 0; 873 int err; 874 875 mutex_lock(&devlink_mutex); 876 list_for_each_entry(devlink, &devlink_list, list) { 877 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 878 continue; 879 if (idx < start) { 880 idx++; 881 continue; 882 } 883 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 884 NETLINK_CB(cb->skb).portid, 885 cb->nlh->nlmsg_seq, NLM_F_MULTI); 886 if (err) 887 goto out; 888 idx++; 889 } 890out: 891 mutex_unlock(&devlink_mutex); 892 893 cb->args[0] = idx; 894 return msg->len; 895} 896 897static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb, 898 struct genl_info *info) 899{ 900 struct devlink_port *devlink_port = info->user_ptr[1]; 901 struct devlink *devlink = devlink_port->devlink; 902 struct sk_buff *msg; 903 int err; 904 905 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 906 if (!msg) 907 return -ENOMEM; 908 909 err = devlink_nl_port_fill(msg, devlink, devlink_port, 910 DEVLINK_CMD_PORT_NEW, 911 info->snd_portid, info->snd_seq, 0, 912 info->extack); 913 if (err) { 914 nlmsg_free(msg); 915 return err; 916 } 917 918 return genlmsg_reply(msg, info); 919} 920 921static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg, 922 struct netlink_callback *cb) 923{ 924 struct devlink *devlink; 925 struct devlink_port *devlink_port; 926 int start = cb->args[0]; 927 int idx = 0; 928 int err; 929 930 mutex_lock(&devlink_mutex); 931 list_for_each_entry(devlink, &devlink_list, list) { 932 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 933 continue; 934 mutex_lock(&devlink->lock); 935 list_for_each_entry(devlink_port, &devlink->port_list, list) { 936 if (idx < start) { 937 idx++; 938 continue; 939 } 940 err = devlink_nl_port_fill(msg, devlink, devlink_port, 941 DEVLINK_CMD_NEW, 942 NETLINK_CB(cb->skb).portid, 943 cb->nlh->nlmsg_seq, 944 NLM_F_MULTI, 945 cb->extack); 946 if (err) { 947 mutex_unlock(&devlink->lock); 948 goto out; 949 } 950 idx++; 951 } 952 mutex_unlock(&devlink->lock); 953 } 954out: 955 mutex_unlock(&devlink_mutex); 956 957 cb->args[0] = idx; 958 return msg->len; 959} 960 961static int devlink_port_type_set(struct devlink *devlink, 962 struct devlink_port *devlink_port, 963 enum devlink_port_type port_type) 964 965{ 966 int err; 967 968 if (devlink->ops->port_type_set) { 969 if (port_type == devlink_port->type) 970 return 0; 971 err = devlink->ops->port_type_set(devlink_port, port_type); 972 if (err) 973 return err; 974 devlink_port->desired_type = port_type; 975 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 976 return 0; 977 } 978 return -EOPNOTSUPP; 979} 980 981static int 982devlink_port_function_hw_addr_set(struct devlink *devlink, struct devlink_port *port, 983 const struct nlattr *attr, struct netlink_ext_ack *extack) 984{ 985 const struct devlink_ops *ops; 986 const u8 *hw_addr; 987 int hw_addr_len; 988 int err; 989 990 hw_addr = nla_data(attr); 991 hw_addr_len = nla_len(attr); 992 if (hw_addr_len > MAX_ADDR_LEN) { 993 NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long"); 994 return -EINVAL; 995 } 996 if (port->type == DEVLINK_PORT_TYPE_ETH) { 997 if (hw_addr_len != ETH_ALEN) { 998 NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device"); 999 return -EINVAL; 1000 } 1001 if (!is_unicast_ether_addr(hw_addr)) { 1002 NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported"); 1003 return -EINVAL; 1004 } 1005 } 1006 1007 ops = devlink->ops; 1008 if (!ops->port_function_hw_addr_set) { 1009 NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes"); 1010 return -EOPNOTSUPP; 1011 } 1012 1013 err = ops->port_function_hw_addr_set(devlink, port, hw_addr, hw_addr_len, extack); 1014 if (err) 1015 return err; 1016 1017 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW); 1018 return 0; 1019} 1020 1021static int 1022devlink_port_function_set(struct devlink *devlink, struct devlink_port *port, 1023 const struct nlattr *attr, struct netlink_ext_ack *extack) 1024{ 1025 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1]; 1026 int err; 1027 1028 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr, 1029 devlink_function_nl_policy, extack); 1030 if (err < 0) { 1031 NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes"); 1032 return err; 1033 } 1034 1035 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR]; 1036 if (attr) 1037 err = devlink_port_function_hw_addr_set(devlink, port, attr, extack); 1038 1039 return err; 1040} 1041 1042static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb, 1043 struct genl_info *info) 1044{ 1045 struct devlink_port *devlink_port = info->user_ptr[1]; 1046 struct devlink *devlink = devlink_port->devlink; 1047 int err; 1048 1049 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) { 1050 enum devlink_port_type port_type; 1051 1052 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]); 1053 err = devlink_port_type_set(devlink, devlink_port, port_type); 1054 if (err) 1055 return err; 1056 } 1057 1058 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) { 1059 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION]; 1060 struct netlink_ext_ack *extack = info->extack; 1061 1062 err = devlink_port_function_set(devlink, devlink_port, attr, extack); 1063 if (err) 1064 return err; 1065 } 1066 1067 return 0; 1068} 1069 1070static int devlink_port_split(struct devlink *devlink, u32 port_index, 1071 u32 count, struct netlink_ext_ack *extack) 1072 1073{ 1074 if (devlink->ops->port_split) 1075 return devlink->ops->port_split(devlink, port_index, count, 1076 extack); 1077 return -EOPNOTSUPP; 1078} 1079 1080static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, 1081 struct genl_info *info) 1082{ 1083 struct devlink *devlink = info->user_ptr[0]; 1084 struct devlink_port *devlink_port; 1085 u32 port_index; 1086 u32 count; 1087 1088 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] || 1089 !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]) 1090 return -EINVAL; 1091 1092 devlink_port = devlink_port_get_from_info(devlink, info); 1093 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 1094 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]); 1095 1096 if (IS_ERR(devlink_port)) 1097 return -EINVAL; 1098 1099 if (!devlink_port->attrs.splittable) { 1100 /* Split ports cannot be split. */ 1101 if (devlink_port->attrs.split) 1102 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further"); 1103 else 1104 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split"); 1105 return -EINVAL; 1106 } 1107 1108 if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) { 1109 NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count"); 1110 return -EINVAL; 1111 } 1112 1113 return devlink_port_split(devlink, port_index, count, info->extack); 1114} 1115 1116static int devlink_port_unsplit(struct devlink *devlink, u32 port_index, 1117 struct netlink_ext_ack *extack) 1118 1119{ 1120 if (devlink->ops->port_unsplit) 1121 return devlink->ops->port_unsplit(devlink, port_index, extack); 1122 return -EOPNOTSUPP; 1123} 1124 1125static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb, 1126 struct genl_info *info) 1127{ 1128 struct devlink *devlink = info->user_ptr[0]; 1129 u32 port_index; 1130 1131 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX]) 1132 return -EINVAL; 1133 1134 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 1135 return devlink_port_unsplit(devlink, port_index, info->extack); 1136} 1137 1138static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink, 1139 struct devlink_sb *devlink_sb, 1140 enum devlink_command cmd, u32 portid, 1141 u32 seq, int flags) 1142{ 1143 void *hdr; 1144 1145 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 1146 if (!hdr) 1147 return -EMSGSIZE; 1148 1149 if (devlink_nl_put_handle(msg, devlink)) 1150 goto nla_put_failure; 1151 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 1152 goto nla_put_failure; 1153 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size)) 1154 goto nla_put_failure; 1155 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT, 1156 devlink_sb->ingress_pools_count)) 1157 goto nla_put_failure; 1158 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT, 1159 devlink_sb->egress_pools_count)) 1160 goto nla_put_failure; 1161 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT, 1162 devlink_sb->ingress_tc_count)) 1163 goto nla_put_failure; 1164 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT, 1165 devlink_sb->egress_tc_count)) 1166 goto nla_put_failure; 1167 1168 genlmsg_end(msg, hdr); 1169 return 0; 1170 1171nla_put_failure: 1172 genlmsg_cancel(msg, hdr); 1173 return -EMSGSIZE; 1174} 1175 1176static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb, 1177 struct genl_info *info) 1178{ 1179 struct devlink *devlink = info->user_ptr[0]; 1180 struct devlink_sb *devlink_sb; 1181 struct sk_buff *msg; 1182 int err; 1183 1184 devlink_sb = devlink_sb_get_from_info(devlink, info); 1185 if (IS_ERR(devlink_sb)) 1186 return PTR_ERR(devlink_sb); 1187 1188 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1189 if (!msg) 1190 return -ENOMEM; 1191 1192 err = devlink_nl_sb_fill(msg, devlink, devlink_sb, 1193 DEVLINK_CMD_SB_NEW, 1194 info->snd_portid, info->snd_seq, 0); 1195 if (err) { 1196 nlmsg_free(msg); 1197 return err; 1198 } 1199 1200 return genlmsg_reply(msg, info); 1201} 1202 1203static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg, 1204 struct netlink_callback *cb) 1205{ 1206 struct devlink *devlink; 1207 struct devlink_sb *devlink_sb; 1208 int start = cb->args[0]; 1209 int idx = 0; 1210 int err; 1211 1212 mutex_lock(&devlink_mutex); 1213 list_for_each_entry(devlink, &devlink_list, list) { 1214 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 1215 continue; 1216 mutex_lock(&devlink->lock); 1217 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 1218 if (idx < start) { 1219 idx++; 1220 continue; 1221 } 1222 err = devlink_nl_sb_fill(msg, devlink, devlink_sb, 1223 DEVLINK_CMD_SB_NEW, 1224 NETLINK_CB(cb->skb).portid, 1225 cb->nlh->nlmsg_seq, 1226 NLM_F_MULTI); 1227 if (err) { 1228 mutex_unlock(&devlink->lock); 1229 goto out; 1230 } 1231 idx++; 1232 } 1233 mutex_unlock(&devlink->lock); 1234 } 1235out: 1236 mutex_unlock(&devlink_mutex); 1237 1238 cb->args[0] = idx; 1239 return msg->len; 1240} 1241 1242static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink, 1243 struct devlink_sb *devlink_sb, 1244 u16 pool_index, enum devlink_command cmd, 1245 u32 portid, u32 seq, int flags) 1246{ 1247 struct devlink_sb_pool_info pool_info; 1248 void *hdr; 1249 int err; 1250 1251 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index, 1252 pool_index, &pool_info); 1253 if (err) 1254 return err; 1255 1256 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 1257 if (!hdr) 1258 return -EMSGSIZE; 1259 1260 if (devlink_nl_put_handle(msg, devlink)) 1261 goto nla_put_failure; 1262 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 1263 goto nla_put_failure; 1264 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) 1265 goto nla_put_failure; 1266 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type)) 1267 goto nla_put_failure; 1268 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size)) 1269 goto nla_put_failure; 1270 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE, 1271 pool_info.threshold_type)) 1272 goto nla_put_failure; 1273 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE, 1274 pool_info.cell_size)) 1275 goto nla_put_failure; 1276 1277 genlmsg_end(msg, hdr); 1278 return 0; 1279 1280nla_put_failure: 1281 genlmsg_cancel(msg, hdr); 1282 return -EMSGSIZE; 1283} 1284 1285static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb, 1286 struct genl_info *info) 1287{ 1288 struct devlink *devlink = info->user_ptr[0]; 1289 struct devlink_sb *devlink_sb; 1290 struct sk_buff *msg; 1291 u16 pool_index; 1292 int err; 1293 1294 devlink_sb = devlink_sb_get_from_info(devlink, info); 1295 if (IS_ERR(devlink_sb)) 1296 return PTR_ERR(devlink_sb); 1297 1298 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 1299 &pool_index); 1300 if (err) 1301 return err; 1302 1303 if (!devlink->ops->sb_pool_get) 1304 return -EOPNOTSUPP; 1305 1306 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1307 if (!msg) 1308 return -ENOMEM; 1309 1310 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index, 1311 DEVLINK_CMD_SB_POOL_NEW, 1312 info->snd_portid, info->snd_seq, 0); 1313 if (err) { 1314 nlmsg_free(msg); 1315 return err; 1316 } 1317 1318 return genlmsg_reply(msg, info); 1319} 1320 1321static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, 1322 struct devlink *devlink, 1323 struct devlink_sb *devlink_sb, 1324 u32 portid, u32 seq) 1325{ 1326 u16 pool_count = devlink_sb_pool_count(devlink_sb); 1327 u16 pool_index; 1328 int err; 1329 1330 for (pool_index = 0; pool_index < pool_count; pool_index++) { 1331 if (*p_idx < start) { 1332 (*p_idx)++; 1333 continue; 1334 } 1335 err = devlink_nl_sb_pool_fill(msg, devlink, 1336 devlink_sb, 1337 pool_index, 1338 DEVLINK_CMD_SB_POOL_NEW, 1339 portid, seq, NLM_F_MULTI); 1340 if (err) 1341 return err; 1342 (*p_idx)++; 1343 } 1344 return 0; 1345} 1346 1347static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg, 1348 struct netlink_callback *cb) 1349{ 1350 struct devlink *devlink; 1351 struct devlink_sb *devlink_sb; 1352 int start = cb->args[0]; 1353 int idx = 0; 1354 int err = 0; 1355 1356 mutex_lock(&devlink_mutex); 1357 list_for_each_entry(devlink, &devlink_list, list) { 1358 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || 1359 !devlink->ops->sb_pool_get) 1360 continue; 1361 mutex_lock(&devlink->lock); 1362 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 1363 err = __sb_pool_get_dumpit(msg, start, &idx, devlink, 1364 devlink_sb, 1365 NETLINK_CB(cb->skb).portid, 1366 cb->nlh->nlmsg_seq); 1367 if (err == -EOPNOTSUPP) { 1368 err = 0; 1369 } else if (err) { 1370 mutex_unlock(&devlink->lock); 1371 goto out; 1372 } 1373 } 1374 mutex_unlock(&devlink->lock); 1375 } 1376out: 1377 mutex_unlock(&devlink_mutex); 1378 1379 if (err != -EMSGSIZE) 1380 return err; 1381 1382 cb->args[0] = idx; 1383 return msg->len; 1384} 1385 1386static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index, 1387 u16 pool_index, u32 size, 1388 enum devlink_sb_threshold_type threshold_type, 1389 struct netlink_ext_ack *extack) 1390 1391{ 1392 const struct devlink_ops *ops = devlink->ops; 1393 1394 if (ops->sb_pool_set) 1395 return ops->sb_pool_set(devlink, sb_index, pool_index, 1396 size, threshold_type, extack); 1397 return -EOPNOTSUPP; 1398} 1399 1400static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb, 1401 struct genl_info *info) 1402{ 1403 struct devlink *devlink = info->user_ptr[0]; 1404 enum devlink_sb_threshold_type threshold_type; 1405 struct devlink_sb *devlink_sb; 1406 u16 pool_index; 1407 u32 size; 1408 int err; 1409 1410 devlink_sb = devlink_sb_get_from_info(devlink, info); 1411 if (IS_ERR(devlink_sb)) 1412 return PTR_ERR(devlink_sb); 1413 1414 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 1415 &pool_index); 1416 if (err) 1417 return err; 1418 1419 err = devlink_sb_th_type_get_from_info(info, &threshold_type); 1420 if (err) 1421 return err; 1422 1423 if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]) 1424 return -EINVAL; 1425 1426 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]); 1427 return devlink_sb_pool_set(devlink, devlink_sb->index, 1428 pool_index, size, threshold_type, 1429 info->extack); 1430} 1431 1432static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg, 1433 struct devlink *devlink, 1434 struct devlink_port *devlink_port, 1435 struct devlink_sb *devlink_sb, 1436 u16 pool_index, 1437 enum devlink_command cmd, 1438 u32 portid, u32 seq, int flags) 1439{ 1440 const struct devlink_ops *ops = devlink->ops; 1441 u32 threshold; 1442 void *hdr; 1443 int err; 1444 1445 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index, 1446 pool_index, &threshold); 1447 if (err) 1448 return err; 1449 1450 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 1451 if (!hdr) 1452 return -EMSGSIZE; 1453 1454 if (devlink_nl_put_handle(msg, devlink)) 1455 goto nla_put_failure; 1456 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 1457 goto nla_put_failure; 1458 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 1459 goto nla_put_failure; 1460 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) 1461 goto nla_put_failure; 1462 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) 1463 goto nla_put_failure; 1464 1465 if (ops->sb_occ_port_pool_get) { 1466 u32 cur; 1467 u32 max; 1468 1469 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index, 1470 pool_index, &cur, &max); 1471 if (err && err != -EOPNOTSUPP) 1472 goto sb_occ_get_failure; 1473 if (!err) { 1474 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) 1475 goto nla_put_failure; 1476 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) 1477 goto nla_put_failure; 1478 } 1479 } 1480 1481 genlmsg_end(msg, hdr); 1482 return 0; 1483 1484nla_put_failure: 1485 err = -EMSGSIZE; 1486sb_occ_get_failure: 1487 genlmsg_cancel(msg, hdr); 1488 return err; 1489} 1490 1491static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb, 1492 struct genl_info *info) 1493{ 1494 struct devlink_port *devlink_port = info->user_ptr[1]; 1495 struct devlink *devlink = devlink_port->devlink; 1496 struct devlink_sb *devlink_sb; 1497 struct sk_buff *msg; 1498 u16 pool_index; 1499 int err; 1500 1501 devlink_sb = devlink_sb_get_from_info(devlink, info); 1502 if (IS_ERR(devlink_sb)) 1503 return PTR_ERR(devlink_sb); 1504 1505 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 1506 &pool_index); 1507 if (err) 1508 return err; 1509 1510 if (!devlink->ops->sb_port_pool_get) 1511 return -EOPNOTSUPP; 1512 1513 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1514 if (!msg) 1515 return -ENOMEM; 1516 1517 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port, 1518 devlink_sb, pool_index, 1519 DEVLINK_CMD_SB_PORT_POOL_NEW, 1520 info->snd_portid, info->snd_seq, 0); 1521 if (err) { 1522 nlmsg_free(msg); 1523 return err; 1524 } 1525 1526 return genlmsg_reply(msg, info); 1527} 1528 1529static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, 1530 struct devlink *devlink, 1531 struct devlink_sb *devlink_sb, 1532 u32 portid, u32 seq) 1533{ 1534 struct devlink_port *devlink_port; 1535 u16 pool_count = devlink_sb_pool_count(devlink_sb); 1536 u16 pool_index; 1537 int err; 1538 1539 list_for_each_entry(devlink_port, &devlink->port_list, list) { 1540 for (pool_index = 0; pool_index < pool_count; pool_index++) { 1541 if (*p_idx < start) { 1542 (*p_idx)++; 1543 continue; 1544 } 1545 err = devlink_nl_sb_port_pool_fill(msg, devlink, 1546 devlink_port, 1547 devlink_sb, 1548 pool_index, 1549 DEVLINK_CMD_SB_PORT_POOL_NEW, 1550 portid, seq, 1551 NLM_F_MULTI); 1552 if (err) 1553 return err; 1554 (*p_idx)++; 1555 } 1556 } 1557 return 0; 1558} 1559 1560static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg, 1561 struct netlink_callback *cb) 1562{ 1563 struct devlink *devlink; 1564 struct devlink_sb *devlink_sb; 1565 int start = cb->args[0]; 1566 int idx = 0; 1567 int err = 0; 1568 1569 mutex_lock(&devlink_mutex); 1570 list_for_each_entry(devlink, &devlink_list, list) { 1571 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || 1572 !devlink->ops->sb_port_pool_get) 1573 continue; 1574 mutex_lock(&devlink->lock); 1575 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 1576 err = __sb_port_pool_get_dumpit(msg, start, &idx, 1577 devlink, devlink_sb, 1578 NETLINK_CB(cb->skb).portid, 1579 cb->nlh->nlmsg_seq); 1580 if (err == -EOPNOTSUPP) { 1581 err = 0; 1582 } else if (err) { 1583 mutex_unlock(&devlink->lock); 1584 goto out; 1585 } 1586 } 1587 mutex_unlock(&devlink->lock); 1588 } 1589out: 1590 mutex_unlock(&devlink_mutex); 1591 1592 if (err != -EMSGSIZE) 1593 return err; 1594 1595 cb->args[0] = idx; 1596 return msg->len; 1597} 1598 1599static int devlink_sb_port_pool_set(struct devlink_port *devlink_port, 1600 unsigned int sb_index, u16 pool_index, 1601 u32 threshold, 1602 struct netlink_ext_ack *extack) 1603 1604{ 1605 const struct devlink_ops *ops = devlink_port->devlink->ops; 1606 1607 if (ops->sb_port_pool_set) 1608 return ops->sb_port_pool_set(devlink_port, sb_index, 1609 pool_index, threshold, extack); 1610 return -EOPNOTSUPP; 1611} 1612 1613static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb, 1614 struct genl_info *info) 1615{ 1616 struct devlink_port *devlink_port = info->user_ptr[1]; 1617 struct devlink *devlink = info->user_ptr[0]; 1618 struct devlink_sb *devlink_sb; 1619 u16 pool_index; 1620 u32 threshold; 1621 int err; 1622 1623 devlink_sb = devlink_sb_get_from_info(devlink, info); 1624 if (IS_ERR(devlink_sb)) 1625 return PTR_ERR(devlink_sb); 1626 1627 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 1628 &pool_index); 1629 if (err) 1630 return err; 1631 1632 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD]) 1633 return -EINVAL; 1634 1635 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); 1636 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index, 1637 pool_index, threshold, info->extack); 1638} 1639 1640static int 1641devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink, 1642 struct devlink_port *devlink_port, 1643 struct devlink_sb *devlink_sb, u16 tc_index, 1644 enum devlink_sb_pool_type pool_type, 1645 enum devlink_command cmd, 1646 u32 portid, u32 seq, int flags) 1647{ 1648 const struct devlink_ops *ops = devlink->ops; 1649 u16 pool_index; 1650 u32 threshold; 1651 void *hdr; 1652 int err; 1653 1654 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index, 1655 tc_index, pool_type, 1656 &pool_index, &threshold); 1657 if (err) 1658 return err; 1659 1660 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 1661 if (!hdr) 1662 return -EMSGSIZE; 1663 1664 if (devlink_nl_put_handle(msg, devlink)) 1665 goto nla_put_failure; 1666 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 1667 goto nla_put_failure; 1668 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 1669 goto nla_put_failure; 1670 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index)) 1671 goto nla_put_failure; 1672 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type)) 1673 goto nla_put_failure; 1674 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) 1675 goto nla_put_failure; 1676 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) 1677 goto nla_put_failure; 1678 1679 if (ops->sb_occ_tc_port_bind_get) { 1680 u32 cur; 1681 u32 max; 1682 1683 err = ops->sb_occ_tc_port_bind_get(devlink_port, 1684 devlink_sb->index, 1685 tc_index, pool_type, 1686 &cur, &max); 1687 if (err && err != -EOPNOTSUPP) 1688 return err; 1689 if (!err) { 1690 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) 1691 goto nla_put_failure; 1692 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) 1693 goto nla_put_failure; 1694 } 1695 } 1696 1697 genlmsg_end(msg, hdr); 1698 return 0; 1699 1700nla_put_failure: 1701 genlmsg_cancel(msg, hdr); 1702 return -EMSGSIZE; 1703} 1704 1705static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb, 1706 struct genl_info *info) 1707{ 1708 struct devlink_port *devlink_port = info->user_ptr[1]; 1709 struct devlink *devlink = devlink_port->devlink; 1710 struct devlink_sb *devlink_sb; 1711 struct sk_buff *msg; 1712 enum devlink_sb_pool_type pool_type; 1713 u16 tc_index; 1714 int err; 1715 1716 devlink_sb = devlink_sb_get_from_info(devlink, info); 1717 if (IS_ERR(devlink_sb)) 1718 return PTR_ERR(devlink_sb); 1719 1720 err = devlink_sb_pool_type_get_from_info(info, &pool_type); 1721 if (err) 1722 return err; 1723 1724 err = devlink_sb_tc_index_get_from_info(devlink_sb, info, 1725 pool_type, &tc_index); 1726 if (err) 1727 return err; 1728 1729 if (!devlink->ops->sb_tc_pool_bind_get) 1730 return -EOPNOTSUPP; 1731 1732 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1733 if (!msg) 1734 return -ENOMEM; 1735 1736 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port, 1737 devlink_sb, tc_index, pool_type, 1738 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 1739 info->snd_portid, 1740 info->snd_seq, 0); 1741 if (err) { 1742 nlmsg_free(msg); 1743 return err; 1744 } 1745 1746 return genlmsg_reply(msg, info); 1747} 1748 1749static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, 1750 int start, int *p_idx, 1751 struct devlink *devlink, 1752 struct devlink_sb *devlink_sb, 1753 u32 portid, u32 seq) 1754{ 1755 struct devlink_port *devlink_port; 1756 u16 tc_index; 1757 int err; 1758 1759 list_for_each_entry(devlink_port, &devlink->port_list, list) { 1760 for (tc_index = 0; 1761 tc_index < devlink_sb->ingress_tc_count; tc_index++) { 1762 if (*p_idx < start) { 1763 (*p_idx)++; 1764 continue; 1765 } 1766 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, 1767 devlink_port, 1768 devlink_sb, 1769 tc_index, 1770 DEVLINK_SB_POOL_TYPE_INGRESS, 1771 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 1772 portid, seq, 1773 NLM_F_MULTI); 1774 if (err) 1775 return err; 1776 (*p_idx)++; 1777 } 1778 for (tc_index = 0; 1779 tc_index < devlink_sb->egress_tc_count; tc_index++) { 1780 if (*p_idx < start) { 1781 (*p_idx)++; 1782 continue; 1783 } 1784 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, 1785 devlink_port, 1786 devlink_sb, 1787 tc_index, 1788 DEVLINK_SB_POOL_TYPE_EGRESS, 1789 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 1790 portid, seq, 1791 NLM_F_MULTI); 1792 if (err) 1793 return err; 1794 (*p_idx)++; 1795 } 1796 } 1797 return 0; 1798} 1799 1800static int 1801devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, 1802 struct netlink_callback *cb) 1803{ 1804 struct devlink *devlink; 1805 struct devlink_sb *devlink_sb; 1806 int start = cb->args[0]; 1807 int idx = 0; 1808 int err = 0; 1809 1810 mutex_lock(&devlink_mutex); 1811 list_for_each_entry(devlink, &devlink_list, list) { 1812 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || 1813 !devlink->ops->sb_tc_pool_bind_get) 1814 continue; 1815 1816 mutex_lock(&devlink->lock); 1817 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 1818 err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx, 1819 devlink, 1820 devlink_sb, 1821 NETLINK_CB(cb->skb).portid, 1822 cb->nlh->nlmsg_seq); 1823 if (err == -EOPNOTSUPP) { 1824 err = 0; 1825 } else if (err) { 1826 mutex_unlock(&devlink->lock); 1827 goto out; 1828 } 1829 } 1830 mutex_unlock(&devlink->lock); 1831 } 1832out: 1833 mutex_unlock(&devlink_mutex); 1834 1835 if (err != -EMSGSIZE) 1836 return err; 1837 1838 cb->args[0] = idx; 1839 return msg->len; 1840} 1841 1842static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port, 1843 unsigned int sb_index, u16 tc_index, 1844 enum devlink_sb_pool_type pool_type, 1845 u16 pool_index, u32 threshold, 1846 struct netlink_ext_ack *extack) 1847 1848{ 1849 const struct devlink_ops *ops = devlink_port->devlink->ops; 1850 1851 if (ops->sb_tc_pool_bind_set) 1852 return ops->sb_tc_pool_bind_set(devlink_port, sb_index, 1853 tc_index, pool_type, 1854 pool_index, threshold, extack); 1855 return -EOPNOTSUPP; 1856} 1857 1858static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb, 1859 struct genl_info *info) 1860{ 1861 struct devlink_port *devlink_port = info->user_ptr[1]; 1862 struct devlink *devlink = info->user_ptr[0]; 1863 enum devlink_sb_pool_type pool_type; 1864 struct devlink_sb *devlink_sb; 1865 u16 tc_index; 1866 u16 pool_index; 1867 u32 threshold; 1868 int err; 1869 1870 devlink_sb = devlink_sb_get_from_info(devlink, info); 1871 if (IS_ERR(devlink_sb)) 1872 return PTR_ERR(devlink_sb); 1873 1874 err = devlink_sb_pool_type_get_from_info(info, &pool_type); 1875 if (err) 1876 return err; 1877 1878 err = devlink_sb_tc_index_get_from_info(devlink_sb, info, 1879 pool_type, &tc_index); 1880 if (err) 1881 return err; 1882 1883 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 1884 &pool_index); 1885 if (err) 1886 return err; 1887 1888 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD]) 1889 return -EINVAL; 1890 1891 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); 1892 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index, 1893 tc_index, pool_type, 1894 pool_index, threshold, info->extack); 1895} 1896 1897static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb, 1898 struct genl_info *info) 1899{ 1900 struct devlink *devlink = info->user_ptr[0]; 1901 const struct devlink_ops *ops = devlink->ops; 1902 struct devlink_sb *devlink_sb; 1903 1904 devlink_sb = devlink_sb_get_from_info(devlink, info); 1905 if (IS_ERR(devlink_sb)) 1906 return PTR_ERR(devlink_sb); 1907 1908 if (ops->sb_occ_snapshot) 1909 return ops->sb_occ_snapshot(devlink, devlink_sb->index); 1910 return -EOPNOTSUPP; 1911} 1912 1913static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb, 1914 struct genl_info *info) 1915{ 1916 struct devlink *devlink = info->user_ptr[0]; 1917 const struct devlink_ops *ops = devlink->ops; 1918 struct devlink_sb *devlink_sb; 1919 1920 devlink_sb = devlink_sb_get_from_info(devlink, info); 1921 if (IS_ERR(devlink_sb)) 1922 return PTR_ERR(devlink_sb); 1923 1924 if (ops->sb_occ_max_clear) 1925 return ops->sb_occ_max_clear(devlink, devlink_sb->index); 1926 return -EOPNOTSUPP; 1927} 1928 1929static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink, 1930 enum devlink_command cmd, u32 portid, 1931 u32 seq, int flags) 1932{ 1933 const struct devlink_ops *ops = devlink->ops; 1934 enum devlink_eswitch_encap_mode encap_mode; 1935 u8 inline_mode; 1936 void *hdr; 1937 int err = 0; 1938 u16 mode; 1939 1940 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 1941 if (!hdr) 1942 return -EMSGSIZE; 1943 1944 err = devlink_nl_put_handle(msg, devlink); 1945 if (err) 1946 goto nla_put_failure; 1947 1948 if (ops->eswitch_mode_get) { 1949 err = ops->eswitch_mode_get(devlink, &mode); 1950 if (err) 1951 goto nla_put_failure; 1952 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode); 1953 if (err) 1954 goto nla_put_failure; 1955 } 1956 1957 if (ops->eswitch_inline_mode_get) { 1958 err = ops->eswitch_inline_mode_get(devlink, &inline_mode); 1959 if (err) 1960 goto nla_put_failure; 1961 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, 1962 inline_mode); 1963 if (err) 1964 goto nla_put_failure; 1965 } 1966 1967 if (ops->eswitch_encap_mode_get) { 1968 err = ops->eswitch_encap_mode_get(devlink, &encap_mode); 1969 if (err) 1970 goto nla_put_failure; 1971 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); 1972 if (err) 1973 goto nla_put_failure; 1974 } 1975 1976 genlmsg_end(msg, hdr); 1977 return 0; 1978 1979nla_put_failure: 1980 genlmsg_cancel(msg, hdr); 1981 return err; 1982} 1983 1984static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb, 1985 struct genl_info *info) 1986{ 1987 struct devlink *devlink = info->user_ptr[0]; 1988 struct sk_buff *msg; 1989 int err; 1990 1991 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1992 if (!msg) 1993 return -ENOMEM; 1994 1995 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET, 1996 info->snd_portid, info->snd_seq, 0); 1997 1998 if (err) { 1999 nlmsg_free(msg); 2000 return err; 2001 } 2002 2003 return genlmsg_reply(msg, info); 2004} 2005 2006static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, 2007 struct genl_info *info) 2008{ 2009 struct devlink *devlink = info->user_ptr[0]; 2010 const struct devlink_ops *ops = devlink->ops; 2011 enum devlink_eswitch_encap_mode encap_mode; 2012 u8 inline_mode; 2013 int err = 0; 2014 u16 mode; 2015 2016 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { 2017 if (!ops->eswitch_mode_set) 2018 return -EOPNOTSUPP; 2019 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]); 2020 err = ops->eswitch_mode_set(devlink, mode, info->extack); 2021 if (err) 2022 return err; 2023 } 2024 2025 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) { 2026 if (!ops->eswitch_inline_mode_set) 2027 return -EOPNOTSUPP; 2028 inline_mode = nla_get_u8( 2029 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]); 2030 err = ops->eswitch_inline_mode_set(devlink, inline_mode, 2031 info->extack); 2032 if (err) 2033 return err; 2034 } 2035 2036 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { 2037 if (!ops->eswitch_encap_mode_set) 2038 return -EOPNOTSUPP; 2039 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); 2040 err = ops->eswitch_encap_mode_set(devlink, encap_mode, 2041 info->extack); 2042 if (err) 2043 return err; 2044 } 2045 2046 return 0; 2047} 2048 2049int devlink_dpipe_match_put(struct sk_buff *skb, 2050 struct devlink_dpipe_match *match) 2051{ 2052 struct devlink_dpipe_header *header = match->header; 2053 struct devlink_dpipe_field *field = &header->fields[match->field_id]; 2054 struct nlattr *match_attr; 2055 2056 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH); 2057 if (!match_attr) 2058 return -EMSGSIZE; 2059 2060 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) || 2061 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) || 2062 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 2063 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 2064 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 2065 goto nla_put_failure; 2066 2067 nla_nest_end(skb, match_attr); 2068 return 0; 2069 2070nla_put_failure: 2071 nla_nest_cancel(skb, match_attr); 2072 return -EMSGSIZE; 2073} 2074EXPORT_SYMBOL_GPL(devlink_dpipe_match_put); 2075 2076static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table, 2077 struct sk_buff *skb) 2078{ 2079 struct nlattr *matches_attr; 2080 2081 matches_attr = nla_nest_start_noflag(skb, 2082 DEVLINK_ATTR_DPIPE_TABLE_MATCHES); 2083 if (!matches_attr) 2084 return -EMSGSIZE; 2085 2086 if (table->table_ops->matches_dump(table->priv, skb)) 2087 goto nla_put_failure; 2088 2089 nla_nest_end(skb, matches_attr); 2090 return 0; 2091 2092nla_put_failure: 2093 nla_nest_cancel(skb, matches_attr); 2094 return -EMSGSIZE; 2095} 2096 2097int devlink_dpipe_action_put(struct sk_buff *skb, 2098 struct devlink_dpipe_action *action) 2099{ 2100 struct devlink_dpipe_header *header = action->header; 2101 struct devlink_dpipe_field *field = &header->fields[action->field_id]; 2102 struct nlattr *action_attr; 2103 2104 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION); 2105 if (!action_attr) 2106 return -EMSGSIZE; 2107 2108 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) || 2109 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) || 2110 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 2111 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 2112 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 2113 goto nla_put_failure; 2114 2115 nla_nest_end(skb, action_attr); 2116 return 0; 2117 2118nla_put_failure: 2119 nla_nest_cancel(skb, action_attr); 2120 return -EMSGSIZE; 2121} 2122EXPORT_SYMBOL_GPL(devlink_dpipe_action_put); 2123 2124static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table, 2125 struct sk_buff *skb) 2126{ 2127 struct nlattr *actions_attr; 2128 2129 actions_attr = nla_nest_start_noflag(skb, 2130 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS); 2131 if (!actions_attr) 2132 return -EMSGSIZE; 2133 2134 if (table->table_ops->actions_dump(table->priv, skb)) 2135 goto nla_put_failure; 2136 2137 nla_nest_end(skb, actions_attr); 2138 return 0; 2139 2140nla_put_failure: 2141 nla_nest_cancel(skb, actions_attr); 2142 return -EMSGSIZE; 2143} 2144 2145static int devlink_dpipe_table_put(struct sk_buff *skb, 2146 struct devlink_dpipe_table *table) 2147{ 2148 struct nlattr *table_attr; 2149 u64 table_size; 2150 2151 table_size = table->table_ops->size_get(table->priv); 2152 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE); 2153 if (!table_attr) 2154 return -EMSGSIZE; 2155 2156 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) || 2157 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size, 2158 DEVLINK_ATTR_PAD)) 2159 goto nla_put_failure; 2160 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, 2161 table->counters_enabled)) 2162 goto nla_put_failure; 2163 2164 if (table->resource_valid) { 2165 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID, 2166 table->resource_id, DEVLINK_ATTR_PAD) || 2167 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS, 2168 table->resource_units, DEVLINK_ATTR_PAD)) 2169 goto nla_put_failure; 2170 } 2171 if (devlink_dpipe_matches_put(table, skb)) 2172 goto nla_put_failure; 2173 2174 if (devlink_dpipe_actions_put(table, skb)) 2175 goto nla_put_failure; 2176 2177 nla_nest_end(skb, table_attr); 2178 return 0; 2179 2180nla_put_failure: 2181 nla_nest_cancel(skb, table_attr); 2182 return -EMSGSIZE; 2183} 2184 2185static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb, 2186 struct genl_info *info) 2187{ 2188 int err; 2189 2190 if (*pskb) { 2191 err = genlmsg_reply(*pskb, info); 2192 if (err) 2193 return err; 2194 } 2195 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 2196 if (!*pskb) 2197 return -ENOMEM; 2198 return 0; 2199} 2200 2201static int devlink_dpipe_tables_fill(struct genl_info *info, 2202 enum devlink_command cmd, int flags, 2203 struct list_head *dpipe_tables, 2204 const char *table_name) 2205{ 2206 struct devlink *devlink = info->user_ptr[0]; 2207 struct devlink_dpipe_table *table; 2208 struct nlattr *tables_attr; 2209 struct sk_buff *skb = NULL; 2210 struct nlmsghdr *nlh; 2211 bool incomplete; 2212 void *hdr; 2213 int i; 2214 int err; 2215 2216 table = list_first_entry(dpipe_tables, 2217 struct devlink_dpipe_table, list); 2218start_again: 2219 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2220 if (err) 2221 return err; 2222 2223 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 2224 &devlink_nl_family, NLM_F_MULTI, cmd); 2225 if (!hdr) { 2226 nlmsg_free(skb); 2227 return -EMSGSIZE; 2228 } 2229 2230 if (devlink_nl_put_handle(skb, devlink)) 2231 goto nla_put_failure; 2232 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES); 2233 if (!tables_attr) 2234 goto nla_put_failure; 2235 2236 i = 0; 2237 incomplete = false; 2238 list_for_each_entry_from(table, dpipe_tables, list) { 2239 if (!table_name) { 2240 err = devlink_dpipe_table_put(skb, table); 2241 if (err) { 2242 if (!i) 2243 goto err_table_put; 2244 incomplete = true; 2245 break; 2246 } 2247 } else { 2248 if (!strcmp(table->name, table_name)) { 2249 err = devlink_dpipe_table_put(skb, table); 2250 if (err) 2251 break; 2252 } 2253 } 2254 i++; 2255 } 2256 2257 nla_nest_end(skb, tables_attr); 2258 genlmsg_end(skb, hdr); 2259 if (incomplete) 2260 goto start_again; 2261 2262send_done: 2263 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 2264 NLMSG_DONE, 0, flags | NLM_F_MULTI); 2265 if (!nlh) { 2266 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2267 if (err) 2268 return err; 2269 goto send_done; 2270 } 2271 2272 return genlmsg_reply(skb, info); 2273 2274nla_put_failure: 2275 err = -EMSGSIZE; 2276err_table_put: 2277 nlmsg_free(skb); 2278 return err; 2279} 2280 2281static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb, 2282 struct genl_info *info) 2283{ 2284 struct devlink *devlink = info->user_ptr[0]; 2285 const char *table_name = NULL; 2286 2287 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]) 2288 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 2289 2290 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0, 2291 &devlink->dpipe_table_list, 2292 table_name); 2293} 2294 2295static int devlink_dpipe_value_put(struct sk_buff *skb, 2296 struct devlink_dpipe_value *value) 2297{ 2298 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE, 2299 value->value_size, value->value)) 2300 return -EMSGSIZE; 2301 if (value->mask) 2302 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK, 2303 value->value_size, value->mask)) 2304 return -EMSGSIZE; 2305 if (value->mapping_valid) 2306 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING, 2307 value->mapping_value)) 2308 return -EMSGSIZE; 2309 return 0; 2310} 2311 2312static int devlink_dpipe_action_value_put(struct sk_buff *skb, 2313 struct devlink_dpipe_value *value) 2314{ 2315 if (!value->action) 2316 return -EINVAL; 2317 if (devlink_dpipe_action_put(skb, value->action)) 2318 return -EMSGSIZE; 2319 if (devlink_dpipe_value_put(skb, value)) 2320 return -EMSGSIZE; 2321 return 0; 2322} 2323 2324static int devlink_dpipe_action_values_put(struct sk_buff *skb, 2325 struct devlink_dpipe_value *values, 2326 unsigned int values_count) 2327{ 2328 struct nlattr *action_attr; 2329 int i; 2330 int err; 2331 2332 for (i = 0; i < values_count; i++) { 2333 action_attr = nla_nest_start_noflag(skb, 2334 DEVLINK_ATTR_DPIPE_ACTION_VALUE); 2335 if (!action_attr) 2336 return -EMSGSIZE; 2337 err = devlink_dpipe_action_value_put(skb, &values[i]); 2338 if (err) 2339 goto err_action_value_put; 2340 nla_nest_end(skb, action_attr); 2341 } 2342 return 0; 2343 2344err_action_value_put: 2345 nla_nest_cancel(skb, action_attr); 2346 return err; 2347} 2348 2349static int devlink_dpipe_match_value_put(struct sk_buff *skb, 2350 struct devlink_dpipe_value *value) 2351{ 2352 if (!value->match) 2353 return -EINVAL; 2354 if (devlink_dpipe_match_put(skb, value->match)) 2355 return -EMSGSIZE; 2356 if (devlink_dpipe_value_put(skb, value)) 2357 return -EMSGSIZE; 2358 return 0; 2359} 2360 2361static int devlink_dpipe_match_values_put(struct sk_buff *skb, 2362 struct devlink_dpipe_value *values, 2363 unsigned int values_count) 2364{ 2365 struct nlattr *match_attr; 2366 int i; 2367 int err; 2368 2369 for (i = 0; i < values_count; i++) { 2370 match_attr = nla_nest_start_noflag(skb, 2371 DEVLINK_ATTR_DPIPE_MATCH_VALUE); 2372 if (!match_attr) 2373 return -EMSGSIZE; 2374 err = devlink_dpipe_match_value_put(skb, &values[i]); 2375 if (err) 2376 goto err_match_value_put; 2377 nla_nest_end(skb, match_attr); 2378 } 2379 return 0; 2380 2381err_match_value_put: 2382 nla_nest_cancel(skb, match_attr); 2383 return err; 2384} 2385 2386static int devlink_dpipe_entry_put(struct sk_buff *skb, 2387 struct devlink_dpipe_entry *entry) 2388{ 2389 struct nlattr *entry_attr, *matches_attr, *actions_attr; 2390 int err; 2391 2392 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY); 2393 if (!entry_attr) 2394 return -EMSGSIZE; 2395 2396 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index, 2397 DEVLINK_ATTR_PAD)) 2398 goto nla_put_failure; 2399 if (entry->counter_valid) 2400 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER, 2401 entry->counter, DEVLINK_ATTR_PAD)) 2402 goto nla_put_failure; 2403 2404 matches_attr = nla_nest_start_noflag(skb, 2405 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES); 2406 if (!matches_attr) 2407 goto nla_put_failure; 2408 2409 err = devlink_dpipe_match_values_put(skb, entry->match_values, 2410 entry->match_values_count); 2411 if (err) { 2412 nla_nest_cancel(skb, matches_attr); 2413 goto err_match_values_put; 2414 } 2415 nla_nest_end(skb, matches_attr); 2416 2417 actions_attr = nla_nest_start_noflag(skb, 2418 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES); 2419 if (!actions_attr) 2420 goto nla_put_failure; 2421 2422 err = devlink_dpipe_action_values_put(skb, entry->action_values, 2423 entry->action_values_count); 2424 if (err) { 2425 nla_nest_cancel(skb, actions_attr); 2426 goto err_action_values_put; 2427 } 2428 nla_nest_end(skb, actions_attr); 2429 2430 nla_nest_end(skb, entry_attr); 2431 return 0; 2432 2433nla_put_failure: 2434 err = -EMSGSIZE; 2435err_match_values_put: 2436err_action_values_put: 2437 nla_nest_cancel(skb, entry_attr); 2438 return err; 2439} 2440 2441static struct devlink_dpipe_table * 2442devlink_dpipe_table_find(struct list_head *dpipe_tables, 2443 const char *table_name, struct devlink *devlink) 2444{ 2445 struct devlink_dpipe_table *table; 2446 list_for_each_entry_rcu(table, dpipe_tables, list, 2447 lockdep_is_held(&devlink->lock)) { 2448 if (!strcmp(table->name, table_name)) 2449 return table; 2450 } 2451 return NULL; 2452} 2453 2454int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx) 2455{ 2456 struct devlink *devlink; 2457 int err; 2458 2459 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb, 2460 dump_ctx->info); 2461 if (err) 2462 return err; 2463 2464 dump_ctx->hdr = genlmsg_put(dump_ctx->skb, 2465 dump_ctx->info->snd_portid, 2466 dump_ctx->info->snd_seq, 2467 &devlink_nl_family, NLM_F_MULTI, 2468 dump_ctx->cmd); 2469 if (!dump_ctx->hdr) 2470 goto nla_put_failure; 2471 2472 devlink = dump_ctx->info->user_ptr[0]; 2473 if (devlink_nl_put_handle(dump_ctx->skb, devlink)) 2474 goto nla_put_failure; 2475 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb, 2476 DEVLINK_ATTR_DPIPE_ENTRIES); 2477 if (!dump_ctx->nest) 2478 goto nla_put_failure; 2479 return 0; 2480 2481nla_put_failure: 2482 nlmsg_free(dump_ctx->skb); 2483 return -EMSGSIZE; 2484} 2485EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare); 2486 2487int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx, 2488 struct devlink_dpipe_entry *entry) 2489{ 2490 return devlink_dpipe_entry_put(dump_ctx->skb, entry); 2491} 2492EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append); 2493 2494int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx) 2495{ 2496 nla_nest_end(dump_ctx->skb, dump_ctx->nest); 2497 genlmsg_end(dump_ctx->skb, dump_ctx->hdr); 2498 return 0; 2499} 2500EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close); 2501 2502void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry) 2503 2504{ 2505 unsigned int value_count, value_index; 2506 struct devlink_dpipe_value *value; 2507 2508 value = entry->action_values; 2509 value_count = entry->action_values_count; 2510 for (value_index = 0; value_index < value_count; value_index++) { 2511 kfree(value[value_index].value); 2512 kfree(value[value_index].mask); 2513 } 2514 2515 value = entry->match_values; 2516 value_count = entry->match_values_count; 2517 for (value_index = 0; value_index < value_count; value_index++) { 2518 kfree(value[value_index].value); 2519 kfree(value[value_index].mask); 2520 } 2521} 2522EXPORT_SYMBOL(devlink_dpipe_entry_clear); 2523 2524static int devlink_dpipe_entries_fill(struct genl_info *info, 2525 enum devlink_command cmd, int flags, 2526 struct devlink_dpipe_table *table) 2527{ 2528 struct devlink_dpipe_dump_ctx dump_ctx; 2529 struct nlmsghdr *nlh; 2530 int err; 2531 2532 dump_ctx.skb = NULL; 2533 dump_ctx.cmd = cmd; 2534 dump_ctx.info = info; 2535 2536 err = table->table_ops->entries_dump(table->priv, 2537 table->counters_enabled, 2538 &dump_ctx); 2539 if (err) 2540 return err; 2541 2542send_done: 2543 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq, 2544 NLMSG_DONE, 0, flags | NLM_F_MULTI); 2545 if (!nlh) { 2546 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info); 2547 if (err) 2548 return err; 2549 goto send_done; 2550 } 2551 return genlmsg_reply(dump_ctx.skb, info); 2552} 2553 2554static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb, 2555 struct genl_info *info) 2556{ 2557 struct devlink *devlink = info->user_ptr[0]; 2558 struct devlink_dpipe_table *table; 2559 const char *table_name; 2560 2561 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]) 2562 return -EINVAL; 2563 2564 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 2565 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2566 table_name, devlink); 2567 if (!table) 2568 return -EINVAL; 2569 2570 if (!table->table_ops->entries_dump) 2571 return -EINVAL; 2572 2573 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET, 2574 0, table); 2575} 2576 2577static int devlink_dpipe_fields_put(struct sk_buff *skb, 2578 const struct devlink_dpipe_header *header) 2579{ 2580 struct devlink_dpipe_field *field; 2581 struct nlattr *field_attr; 2582 int i; 2583 2584 for (i = 0; i < header->fields_count; i++) { 2585 field = &header->fields[i]; 2586 field_attr = nla_nest_start_noflag(skb, 2587 DEVLINK_ATTR_DPIPE_FIELD); 2588 if (!field_attr) 2589 return -EMSGSIZE; 2590 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) || 2591 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 2592 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) || 2593 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type)) 2594 goto nla_put_failure; 2595 nla_nest_end(skb, field_attr); 2596 } 2597 return 0; 2598 2599nla_put_failure: 2600 nla_nest_cancel(skb, field_attr); 2601 return -EMSGSIZE; 2602} 2603 2604static int devlink_dpipe_header_put(struct sk_buff *skb, 2605 struct devlink_dpipe_header *header) 2606{ 2607 struct nlattr *fields_attr, *header_attr; 2608 int err; 2609 2610 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER); 2611 if (!header_attr) 2612 return -EMSGSIZE; 2613 2614 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) || 2615 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 2616 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 2617 goto nla_put_failure; 2618 2619 fields_attr = nla_nest_start_noflag(skb, 2620 DEVLINK_ATTR_DPIPE_HEADER_FIELDS); 2621 if (!fields_attr) 2622 goto nla_put_failure; 2623 2624 err = devlink_dpipe_fields_put(skb, header); 2625 if (err) { 2626 nla_nest_cancel(skb, fields_attr); 2627 goto nla_put_failure; 2628 } 2629 nla_nest_end(skb, fields_attr); 2630 nla_nest_end(skb, header_attr); 2631 return 0; 2632 2633nla_put_failure: 2634 err = -EMSGSIZE; 2635 nla_nest_cancel(skb, header_attr); 2636 return err; 2637} 2638 2639static int devlink_dpipe_headers_fill(struct genl_info *info, 2640 enum devlink_command cmd, int flags, 2641 struct devlink_dpipe_headers * 2642 dpipe_headers) 2643{ 2644 struct devlink *devlink = info->user_ptr[0]; 2645 struct nlattr *headers_attr; 2646 struct sk_buff *skb = NULL; 2647 struct nlmsghdr *nlh; 2648 void *hdr; 2649 int i, j; 2650 int err; 2651 2652 i = 0; 2653start_again: 2654 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2655 if (err) 2656 return err; 2657 2658 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 2659 &devlink_nl_family, NLM_F_MULTI, cmd); 2660 if (!hdr) { 2661 nlmsg_free(skb); 2662 return -EMSGSIZE; 2663 } 2664 2665 if (devlink_nl_put_handle(skb, devlink)) 2666 goto nla_put_failure; 2667 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS); 2668 if (!headers_attr) 2669 goto nla_put_failure; 2670 2671 j = 0; 2672 for (; i < dpipe_headers->headers_count; i++) { 2673 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]); 2674 if (err) { 2675 if (!j) 2676 goto err_table_put; 2677 break; 2678 } 2679 j++; 2680 } 2681 nla_nest_end(skb, headers_attr); 2682 genlmsg_end(skb, hdr); 2683 if (i != dpipe_headers->headers_count) 2684 goto start_again; 2685 2686send_done: 2687 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 2688 NLMSG_DONE, 0, flags | NLM_F_MULTI); 2689 if (!nlh) { 2690 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2691 if (err) 2692 return err; 2693 goto send_done; 2694 } 2695 return genlmsg_reply(skb, info); 2696 2697nla_put_failure: 2698 err = -EMSGSIZE; 2699err_table_put: 2700 nlmsg_free(skb); 2701 return err; 2702} 2703 2704static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb, 2705 struct genl_info *info) 2706{ 2707 struct devlink *devlink = info->user_ptr[0]; 2708 2709 if (!devlink->dpipe_headers) 2710 return -EOPNOTSUPP; 2711 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET, 2712 0, devlink->dpipe_headers); 2713} 2714 2715static int devlink_dpipe_table_counters_set(struct devlink *devlink, 2716 const char *table_name, 2717 bool enable) 2718{ 2719 struct devlink_dpipe_table *table; 2720 2721 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2722 table_name, devlink); 2723 if (!table) 2724 return -EINVAL; 2725 2726 if (table->counter_control_extern) 2727 return -EOPNOTSUPP; 2728 2729 if (!(table->counters_enabled ^ enable)) 2730 return 0; 2731 2732 table->counters_enabled = enable; 2733 if (table->table_ops->counters_set_update) 2734 table->table_ops->counters_set_update(table->priv, enable); 2735 return 0; 2736} 2737 2738static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb, 2739 struct genl_info *info) 2740{ 2741 struct devlink *devlink = info->user_ptr[0]; 2742 const char *table_name; 2743 bool counters_enable; 2744 2745 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] || 2746 !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]) 2747 return -EINVAL; 2748 2749 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 2750 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]); 2751 2752 return devlink_dpipe_table_counters_set(devlink, table_name, 2753 counters_enable); 2754} 2755 2756static struct devlink_resource * 2757devlink_resource_find(struct devlink *devlink, 2758 struct devlink_resource *resource, u64 resource_id) 2759{ 2760 struct list_head *resource_list; 2761 2762 if (resource) 2763 resource_list = &resource->resource_list; 2764 else 2765 resource_list = &devlink->resource_list; 2766 2767 list_for_each_entry(resource, resource_list, list) { 2768 struct devlink_resource *child_resource; 2769 2770 if (resource->id == resource_id) 2771 return resource; 2772 2773 child_resource = devlink_resource_find(devlink, resource, 2774 resource_id); 2775 if (child_resource) 2776 return child_resource; 2777 } 2778 return NULL; 2779} 2780 2781static void 2782devlink_resource_validate_children(struct devlink_resource *resource) 2783{ 2784 struct devlink_resource *child_resource; 2785 bool size_valid = true; 2786 u64 parts_size = 0; 2787 2788 if (list_empty(&resource->resource_list)) 2789 goto out; 2790 2791 list_for_each_entry(child_resource, &resource->resource_list, list) 2792 parts_size += child_resource->size_new; 2793 2794 if (parts_size > resource->size_new) 2795 size_valid = false; 2796out: 2797 resource->size_valid = size_valid; 2798} 2799 2800static int 2801devlink_resource_validate_size(struct devlink_resource *resource, u64 size, 2802 struct netlink_ext_ack *extack) 2803{ 2804 u64 reminder; 2805 int err = 0; 2806 2807 if (size > resource->size_params.size_max) { 2808 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum"); 2809 err = -EINVAL; 2810 } 2811 2812 if (size < resource->size_params.size_min) { 2813 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum"); 2814 err = -EINVAL; 2815 } 2816 2817 div64_u64_rem(size, resource->size_params.size_granularity, &reminder); 2818 if (reminder) { 2819 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity"); 2820 err = -EINVAL; 2821 } 2822 2823 return err; 2824} 2825 2826static int devlink_nl_cmd_resource_set(struct sk_buff *skb, 2827 struct genl_info *info) 2828{ 2829 struct devlink *devlink = info->user_ptr[0]; 2830 struct devlink_resource *resource; 2831 u64 resource_id; 2832 u64 size; 2833 int err; 2834 2835 if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] || 2836 !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]) 2837 return -EINVAL; 2838 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]); 2839 2840 resource = devlink_resource_find(devlink, NULL, resource_id); 2841 if (!resource) 2842 return -EINVAL; 2843 2844 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]); 2845 err = devlink_resource_validate_size(resource, size, info->extack); 2846 if (err) 2847 return err; 2848 2849 resource->size_new = size; 2850 devlink_resource_validate_children(resource); 2851 if (resource->parent) 2852 devlink_resource_validate_children(resource->parent); 2853 return 0; 2854} 2855 2856static int 2857devlink_resource_size_params_put(struct devlink_resource *resource, 2858 struct sk_buff *skb) 2859{ 2860 struct devlink_resource_size_params *size_params; 2861 2862 size_params = &resource->size_params; 2863 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN, 2864 size_params->size_granularity, DEVLINK_ATTR_PAD) || 2865 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX, 2866 size_params->size_max, DEVLINK_ATTR_PAD) || 2867 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN, 2868 size_params->size_min, DEVLINK_ATTR_PAD) || 2869 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit)) 2870 return -EMSGSIZE; 2871 return 0; 2872} 2873 2874static int devlink_resource_occ_put(struct devlink_resource *resource, 2875 struct sk_buff *skb) 2876{ 2877 if (!resource->occ_get) 2878 return 0; 2879 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC, 2880 resource->occ_get(resource->occ_get_priv), 2881 DEVLINK_ATTR_PAD); 2882} 2883 2884static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb, 2885 struct devlink_resource *resource) 2886{ 2887 struct devlink_resource *child_resource; 2888 struct nlattr *child_resource_attr; 2889 struct nlattr *resource_attr; 2890 2891 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE); 2892 if (!resource_attr) 2893 return -EMSGSIZE; 2894 2895 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) || 2896 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size, 2897 DEVLINK_ATTR_PAD) || 2898 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id, 2899 DEVLINK_ATTR_PAD)) 2900 goto nla_put_failure; 2901 if (resource->size != resource->size_new) 2902 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW, 2903 resource->size_new, DEVLINK_ATTR_PAD); 2904 if (devlink_resource_occ_put(resource, skb)) 2905 goto nla_put_failure; 2906 if (devlink_resource_size_params_put(resource, skb)) 2907 goto nla_put_failure; 2908 if (list_empty(&resource->resource_list)) 2909 goto out; 2910 2911 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID, 2912 resource->size_valid)) 2913 goto nla_put_failure; 2914 2915 child_resource_attr = nla_nest_start_noflag(skb, 2916 DEVLINK_ATTR_RESOURCE_LIST); 2917 if (!child_resource_attr) 2918 goto nla_put_failure; 2919 2920 list_for_each_entry(child_resource, &resource->resource_list, list) { 2921 if (devlink_resource_put(devlink, skb, child_resource)) 2922 goto resource_put_failure; 2923 } 2924 2925 nla_nest_end(skb, child_resource_attr); 2926out: 2927 nla_nest_end(skb, resource_attr); 2928 return 0; 2929 2930resource_put_failure: 2931 nla_nest_cancel(skb, child_resource_attr); 2932nla_put_failure: 2933 nla_nest_cancel(skb, resource_attr); 2934 return -EMSGSIZE; 2935} 2936 2937static int devlink_resource_fill(struct genl_info *info, 2938 enum devlink_command cmd, int flags) 2939{ 2940 struct devlink *devlink = info->user_ptr[0]; 2941 struct devlink_resource *resource; 2942 struct nlattr *resources_attr; 2943 struct sk_buff *skb = NULL; 2944 struct nlmsghdr *nlh; 2945 bool incomplete; 2946 void *hdr; 2947 int i; 2948 int err; 2949 2950 resource = list_first_entry(&devlink->resource_list, 2951 struct devlink_resource, list); 2952start_again: 2953 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2954 if (err) 2955 return err; 2956 2957 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 2958 &devlink_nl_family, NLM_F_MULTI, cmd); 2959 if (!hdr) { 2960 nlmsg_free(skb); 2961 return -EMSGSIZE; 2962 } 2963 2964 if (devlink_nl_put_handle(skb, devlink)) 2965 goto nla_put_failure; 2966 2967 resources_attr = nla_nest_start_noflag(skb, 2968 DEVLINK_ATTR_RESOURCE_LIST); 2969 if (!resources_attr) 2970 goto nla_put_failure; 2971 2972 incomplete = false; 2973 i = 0; 2974 list_for_each_entry_from(resource, &devlink->resource_list, list) { 2975 err = devlink_resource_put(devlink, skb, resource); 2976 if (err) { 2977 if (!i) 2978 goto err_resource_put; 2979 incomplete = true; 2980 break; 2981 } 2982 i++; 2983 } 2984 nla_nest_end(skb, resources_attr); 2985 genlmsg_end(skb, hdr); 2986 if (incomplete) 2987 goto start_again; 2988send_done: 2989 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 2990 NLMSG_DONE, 0, flags | NLM_F_MULTI); 2991 if (!nlh) { 2992 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2993 if (err) 2994 return err; 2995 goto send_done; 2996 } 2997 return genlmsg_reply(skb, info); 2998 2999nla_put_failure: 3000 err = -EMSGSIZE; 3001err_resource_put: 3002 nlmsg_free(skb); 3003 return err; 3004} 3005 3006static int devlink_nl_cmd_resource_dump(struct sk_buff *skb, 3007 struct genl_info *info) 3008{ 3009 struct devlink *devlink = info->user_ptr[0]; 3010 3011 if (list_empty(&devlink->resource_list)) 3012 return -EOPNOTSUPP; 3013 3014 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); 3015} 3016 3017static int 3018devlink_resources_validate(struct devlink *devlink, 3019 struct devlink_resource *resource, 3020 struct genl_info *info) 3021{ 3022 struct list_head *resource_list; 3023 int err = 0; 3024 3025 if (resource) 3026 resource_list = &resource->resource_list; 3027 else 3028 resource_list = &devlink->resource_list; 3029 3030 list_for_each_entry(resource, resource_list, list) { 3031 if (!resource->size_valid) 3032 return -EINVAL; 3033 err = devlink_resources_validate(devlink, resource, info); 3034 if (err) 3035 return err; 3036 } 3037 return err; 3038} 3039 3040static struct net *devlink_netns_get(struct sk_buff *skb, 3041 struct genl_info *info) 3042{ 3043 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID]; 3044 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD]; 3045 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID]; 3046 struct net *net; 3047 3048 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) { 3049 NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified"); 3050 return ERR_PTR(-EINVAL); 3051 } 3052 3053 if (netns_pid_attr) { 3054 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr)); 3055 } else if (netns_fd_attr) { 3056 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr)); 3057 } else if (netns_id_attr) { 3058 net = get_net_ns_by_id(sock_net(skb->sk), 3059 nla_get_u32(netns_id_attr)); 3060 if (!net) 3061 net = ERR_PTR(-EINVAL); 3062 } else { 3063 WARN_ON(1); 3064 net = ERR_PTR(-EINVAL); 3065 } 3066 if (IS_ERR(net)) { 3067 NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace"); 3068 return ERR_PTR(-EINVAL); 3069 } 3070 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { 3071 put_net(net); 3072 return ERR_PTR(-EPERM); 3073 } 3074 return net; 3075} 3076 3077static void devlink_param_notify(struct devlink *devlink, 3078 unsigned int port_index, 3079 struct devlink_param_item *param_item, 3080 enum devlink_command cmd); 3081 3082static void devlink_ns_change_notify(struct devlink *devlink, 3083 struct net *dest_net, struct net *curr_net, 3084 bool new) 3085{ 3086 struct devlink_param_item *param_item; 3087 enum devlink_command cmd; 3088 3089 /* Userspace needs to be notified about devlink objects 3090 * removed from original and entering new network namespace. 3091 * The rest of the devlink objects are re-created during 3092 * reload process so the notifications are generated separatelly. 3093 */ 3094 3095 if (!dest_net || net_eq(dest_net, curr_net)) 3096 return; 3097 3098 if (new) 3099 devlink_notify(devlink, DEVLINK_CMD_NEW); 3100 3101 cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL; 3102 list_for_each_entry(param_item, &devlink->param_list, list) 3103 devlink_param_notify(devlink, 0, param_item, cmd); 3104 3105 if (!new) 3106 devlink_notify(devlink, DEVLINK_CMD_DEL); 3107} 3108 3109static bool devlink_reload_supported(const struct devlink_ops *ops) 3110{ 3111 return ops->reload_down && ops->reload_up; 3112} 3113 3114static void devlink_reload_failed_set(struct devlink *devlink, 3115 bool reload_failed) 3116{ 3117 if (devlink->reload_failed == reload_failed) 3118 return; 3119 devlink->reload_failed = reload_failed; 3120 devlink_notify(devlink, DEVLINK_CMD_NEW); 3121} 3122 3123bool devlink_is_reload_failed(const struct devlink *devlink) 3124{ 3125 return devlink->reload_failed; 3126} 3127EXPORT_SYMBOL_GPL(devlink_is_reload_failed); 3128 3129static void 3130__devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats, 3131 enum devlink_reload_limit limit, u32 actions_performed) 3132{ 3133 unsigned long actions = actions_performed; 3134 int stat_idx; 3135 int action; 3136 3137 for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) { 3138 stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action; 3139 reload_stats[stat_idx]++; 3140 } 3141 devlink_notify(devlink, DEVLINK_CMD_NEW); 3142} 3143 3144static void 3145devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit, 3146 u32 actions_performed) 3147{ 3148 __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit, 3149 actions_performed); 3150} 3151 3152/** 3153 * devlink_remote_reload_actions_performed - Update devlink on reload actions 3154 * performed which are not a direct result of devlink reload call. 3155 * 3156 * This should be called by a driver after performing reload actions in case it was not 3157 * a result of devlink reload call. For example fw_activate was performed as a result 3158 * of devlink reload triggered fw_activate on another host. 3159 * The motivation for this function is to keep data on reload actions performed on this 3160 * function whether it was done due to direct devlink reload call or not. 3161 * 3162 * @devlink: devlink 3163 * @limit: reload limit 3164 * @actions_performed: bitmask of actions performed 3165 */ 3166void devlink_remote_reload_actions_performed(struct devlink *devlink, 3167 enum devlink_reload_limit limit, 3168 u32 actions_performed) 3169{ 3170 if (WARN_ON(!actions_performed || 3171 actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 3172 actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) || 3173 limit > DEVLINK_RELOAD_LIMIT_MAX)) 3174 return; 3175 3176 __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit, 3177 actions_performed); 3178} 3179EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed); 3180 3181static int devlink_reload(struct devlink *devlink, struct net *dest_net, 3182 enum devlink_reload_action action, enum devlink_reload_limit limit, 3183 u32 *actions_performed, struct netlink_ext_ack *extack) 3184{ 3185 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; 3186 struct net *curr_net; 3187 int err; 3188 3189 if (!devlink->reload_enabled) 3190 return -EOPNOTSUPP; 3191 3192 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats, 3193 sizeof(remote_reload_stats)); 3194 3195 curr_net = devlink_net(devlink); 3196 devlink_ns_change_notify(devlink, dest_net, curr_net, false); 3197 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack); 3198 if (err) 3199 return err; 3200 3201 if (dest_net && !net_eq(dest_net, curr_net)) 3202 __devlink_net_set(devlink, dest_net); 3203 3204 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack); 3205 devlink_reload_failed_set(devlink, !!err); 3206 if (err) 3207 return err; 3208 3209 devlink_ns_change_notify(devlink, dest_net, curr_net, true); 3210 WARN_ON(!(*actions_performed & BIT(action))); 3211 /* Catch driver on updating the remote action within devlink reload */ 3212 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats, 3213 sizeof(remote_reload_stats))); 3214 devlink_reload_stats_update(devlink, limit, *actions_performed); 3215 return 0; 3216} 3217 3218static int 3219devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed, 3220 enum devlink_command cmd, struct genl_info *info) 3221{ 3222 struct sk_buff *msg; 3223 void *hdr; 3224 3225 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3226 if (!msg) 3227 return -ENOMEM; 3228 3229 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd); 3230 if (!hdr) 3231 goto free_msg; 3232 3233 if (devlink_nl_put_handle(msg, devlink)) 3234 goto nla_put_failure; 3235 3236 if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed, 3237 actions_performed)) 3238 goto nla_put_failure; 3239 genlmsg_end(msg, hdr); 3240 3241 return genlmsg_reply(msg, info); 3242 3243nla_put_failure: 3244 genlmsg_cancel(msg, hdr); 3245free_msg: 3246 nlmsg_free(msg); 3247 return -EMSGSIZE; 3248} 3249 3250static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) 3251{ 3252 struct devlink *devlink = info->user_ptr[0]; 3253 enum devlink_reload_action action; 3254 enum devlink_reload_limit limit; 3255 struct net *dest_net = NULL; 3256 u32 actions_performed; 3257 int err; 3258 3259 if (!devlink_reload_supported(devlink->ops)) 3260 return -EOPNOTSUPP; 3261 3262 err = devlink_resources_validate(devlink, NULL, info); 3263 if (err) { 3264 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed"); 3265 return err; 3266 } 3267 3268 if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION]) 3269 action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]); 3270 else 3271 action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT; 3272 3273 if (!devlink_reload_action_is_supported(devlink, action)) { 3274 NL_SET_ERR_MSG_MOD(info->extack, 3275 "Requested reload action is not supported by the driver"); 3276 return -EOPNOTSUPP; 3277 } 3278 3279 limit = DEVLINK_RELOAD_LIMIT_UNSPEC; 3280 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) { 3281 struct nla_bitfield32 limits; 3282 u32 limits_selected; 3283 3284 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]); 3285 limits_selected = limits.value & limits.selector; 3286 if (!limits_selected) { 3287 NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected"); 3288 return -EINVAL; 3289 } 3290 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++) 3291 if (limits_selected & BIT(limit)) 3292 break; 3293 /* UAPI enables multiselection, but currently it is not used */ 3294 if (limits_selected != BIT(limit)) { 3295 NL_SET_ERR_MSG_MOD(info->extack, 3296 "Multiselection of limit is not supported"); 3297 return -EOPNOTSUPP; 3298 } 3299 if (!devlink_reload_limit_is_supported(devlink, limit)) { 3300 NL_SET_ERR_MSG_MOD(info->extack, 3301 "Requested limit is not supported by the driver"); 3302 return -EOPNOTSUPP; 3303 } 3304 if (devlink_reload_combination_is_invalid(action, limit)) { 3305 NL_SET_ERR_MSG_MOD(info->extack, 3306 "Requested limit is invalid for this action"); 3307 return -EINVAL; 3308 } 3309 } 3310 if (info->attrs[DEVLINK_ATTR_NETNS_PID] || 3311 info->attrs[DEVLINK_ATTR_NETNS_FD] || 3312 info->attrs[DEVLINK_ATTR_NETNS_ID]) { 3313 dest_net = devlink_netns_get(skb, info); 3314 if (IS_ERR(dest_net)) 3315 return PTR_ERR(dest_net); 3316 } 3317 3318 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); 3319 3320 if (dest_net) 3321 put_net(dest_net); 3322 3323 if (err) 3324 return err; 3325 /* For backward compatibility generate reply only if attributes used by user */ 3326 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) 3327 return 0; 3328 3329 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed, 3330 DEVLINK_CMD_RELOAD, info); 3331} 3332 3333static int devlink_nl_flash_update_fill(struct sk_buff *msg, 3334 struct devlink *devlink, 3335 enum devlink_command cmd, 3336 struct devlink_flash_notify *params) 3337{ 3338 void *hdr; 3339 3340 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd); 3341 if (!hdr) 3342 return -EMSGSIZE; 3343 3344 if (devlink_nl_put_handle(msg, devlink)) 3345 goto nla_put_failure; 3346 3347 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS) 3348 goto out; 3349 3350 if (params->status_msg && 3351 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG, 3352 params->status_msg)) 3353 goto nla_put_failure; 3354 if (params->component && 3355 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, 3356 params->component)) 3357 goto nla_put_failure; 3358 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, 3359 params->done, DEVLINK_ATTR_PAD)) 3360 goto nla_put_failure; 3361 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, 3362 params->total, DEVLINK_ATTR_PAD)) 3363 goto nla_put_failure; 3364 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, 3365 params->timeout, DEVLINK_ATTR_PAD)) 3366 goto nla_put_failure; 3367 3368out: 3369 genlmsg_end(msg, hdr); 3370 return 0; 3371 3372nla_put_failure: 3373 genlmsg_cancel(msg, hdr); 3374 return -EMSGSIZE; 3375} 3376 3377static void __devlink_flash_update_notify(struct devlink *devlink, 3378 enum devlink_command cmd, 3379 struct devlink_flash_notify *params) 3380{ 3381 struct sk_buff *msg; 3382 int err; 3383 3384 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE && 3385 cmd != DEVLINK_CMD_FLASH_UPDATE_END && 3386 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS); 3387 3388 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3389 if (!msg) 3390 return; 3391 3392 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params); 3393 if (err) 3394 goto out_free_msg; 3395 3396 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 3397 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 3398 return; 3399 3400out_free_msg: 3401 nlmsg_free(msg); 3402} 3403 3404void devlink_flash_update_begin_notify(struct devlink *devlink) 3405{ 3406 struct devlink_flash_notify params = {}; 3407 3408 __devlink_flash_update_notify(devlink, 3409 DEVLINK_CMD_FLASH_UPDATE, 3410 ¶ms); 3411} 3412EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify); 3413 3414void devlink_flash_update_end_notify(struct devlink *devlink) 3415{ 3416 struct devlink_flash_notify params = {}; 3417 3418 __devlink_flash_update_notify(devlink, 3419 DEVLINK_CMD_FLASH_UPDATE_END, 3420 ¶ms); 3421} 3422EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify); 3423 3424void devlink_flash_update_status_notify(struct devlink *devlink, 3425 const char *status_msg, 3426 const char *component, 3427 unsigned long done, 3428 unsigned long total) 3429{ 3430 struct devlink_flash_notify params = { 3431 .status_msg = status_msg, 3432 .component = component, 3433 .done = done, 3434 .total = total, 3435 }; 3436 3437 __devlink_flash_update_notify(devlink, 3438 DEVLINK_CMD_FLASH_UPDATE_STATUS, 3439 ¶ms); 3440} 3441EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); 3442 3443void devlink_flash_update_timeout_notify(struct devlink *devlink, 3444 const char *status_msg, 3445 const char *component, 3446 unsigned long timeout) 3447{ 3448 struct devlink_flash_notify params = { 3449 .status_msg = status_msg, 3450 .component = component, 3451 .timeout = timeout, 3452 }; 3453 3454 __devlink_flash_update_notify(devlink, 3455 DEVLINK_CMD_FLASH_UPDATE_STATUS, 3456 ¶ms); 3457} 3458EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); 3459 3460static int devlink_nl_cmd_flash_update(struct sk_buff *skb, 3461 struct genl_info *info) 3462{ 3463 struct nlattr *nla_component, *nla_overwrite_mask; 3464 struct devlink_flash_update_params params = {}; 3465 struct devlink *devlink = info->user_ptr[0]; 3466 u32 supported_params; 3467 3468 if (!devlink->ops->flash_update) 3469 return -EOPNOTSUPP; 3470 3471 if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]) 3472 return -EINVAL; 3473 3474 supported_params = devlink->ops->supported_flash_update_params; 3475 3476 params.file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]); 3477 3478 nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT]; 3479 if (nla_component) { 3480 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT)) { 3481 NL_SET_ERR_MSG_ATTR(info->extack, nla_component, 3482 "component update is not supported by this device"); 3483 return -EOPNOTSUPP; 3484 } 3485 params.component = nla_data(nla_component); 3486 } 3487 3488 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK]; 3489 if (nla_overwrite_mask) { 3490 struct nla_bitfield32 sections; 3491 3492 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) { 3493 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask, 3494 "overwrite settings are not supported by this device"); 3495 return -EOPNOTSUPP; 3496 } 3497 sections = nla_get_bitfield32(nla_overwrite_mask); 3498 params.overwrite_mask = sections.value & sections.selector; 3499 } 3500 3501 return devlink->ops->flash_update(devlink, ¶ms, info->extack); 3502} 3503 3504static const struct devlink_param devlink_param_generic[] = { 3505 { 3506 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET, 3507 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME, 3508 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE, 3509 }, 3510 { 3511 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS, 3512 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME, 3513 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE, 3514 }, 3515 { 3516 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, 3517 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME, 3518 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE, 3519 }, 3520 { 3521 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT, 3522 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME, 3523 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE, 3524 }, 3525 { 3526 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, 3527 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME, 3528 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE, 3529 }, 3530 { 3531 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX, 3532 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME, 3533 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE, 3534 }, 3535 { 3536 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN, 3537 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME, 3538 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE, 3539 }, 3540 { 3541 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY, 3542 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME, 3543 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE, 3544 }, 3545 { 3546 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE, 3547 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME, 3548 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE, 3549 }, 3550 { 3551 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, 3552 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME, 3553 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE, 3554 }, 3555 { 3556 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET, 3557 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME, 3558 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE, 3559 }, 3560}; 3561 3562static int devlink_param_generic_verify(const struct devlink_param *param) 3563{ 3564 /* verify it match generic parameter by id and name */ 3565 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX) 3566 return -EINVAL; 3567 if (strcmp(param->name, devlink_param_generic[param->id].name)) 3568 return -ENOENT; 3569 3570 WARN_ON(param->type != devlink_param_generic[param->id].type); 3571 3572 return 0; 3573} 3574 3575static int devlink_param_driver_verify(const struct devlink_param *param) 3576{ 3577 int i; 3578 3579 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX) 3580 return -EINVAL; 3581 /* verify no such name in generic params */ 3582 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++) 3583 if (!strcmp(param->name, devlink_param_generic[i].name)) 3584 return -EEXIST; 3585 3586 return 0; 3587} 3588 3589static struct devlink_param_item * 3590devlink_param_find_by_name(struct list_head *param_list, 3591 const char *param_name) 3592{ 3593 struct devlink_param_item *param_item; 3594 3595 list_for_each_entry(param_item, param_list, list) 3596 if (!strcmp(param_item->param->name, param_name)) 3597 return param_item; 3598 return NULL; 3599} 3600 3601static struct devlink_param_item * 3602devlink_param_find_by_id(struct list_head *param_list, u32 param_id) 3603{ 3604 struct devlink_param_item *param_item; 3605 3606 list_for_each_entry(param_item, param_list, list) 3607 if (param_item->param->id == param_id) 3608 return param_item; 3609 return NULL; 3610} 3611 3612static bool 3613devlink_param_cmode_is_supported(const struct devlink_param *param, 3614 enum devlink_param_cmode cmode) 3615{ 3616 return test_bit(cmode, ¶m->supported_cmodes); 3617} 3618 3619static int devlink_param_get(struct devlink *devlink, 3620 const struct devlink_param *param, 3621 struct devlink_param_gset_ctx *ctx) 3622{ 3623 if (!param->get) 3624 return -EOPNOTSUPP; 3625 return param->get(devlink, param->id, ctx); 3626} 3627 3628static int devlink_param_set(struct devlink *devlink, 3629 const struct devlink_param *param, 3630 struct devlink_param_gset_ctx *ctx) 3631{ 3632 if (!param->set) 3633 return -EOPNOTSUPP; 3634 return param->set(devlink, param->id, ctx); 3635} 3636 3637static int 3638devlink_param_type_to_nla_type(enum devlink_param_type param_type) 3639{ 3640 switch (param_type) { 3641 case DEVLINK_PARAM_TYPE_U8: 3642 return NLA_U8; 3643 case DEVLINK_PARAM_TYPE_U16: 3644 return NLA_U16; 3645 case DEVLINK_PARAM_TYPE_U32: 3646 return NLA_U32; 3647 case DEVLINK_PARAM_TYPE_STRING: 3648 return NLA_STRING; 3649 case DEVLINK_PARAM_TYPE_BOOL: 3650 return NLA_FLAG; 3651 default: 3652 return -EINVAL; 3653 } 3654} 3655 3656static int 3657devlink_nl_param_value_fill_one(struct sk_buff *msg, 3658 enum devlink_param_type type, 3659 enum devlink_param_cmode cmode, 3660 union devlink_param_value val) 3661{ 3662 struct nlattr *param_value_attr; 3663 3664 param_value_attr = nla_nest_start_noflag(msg, 3665 DEVLINK_ATTR_PARAM_VALUE); 3666 if (!param_value_attr) 3667 goto nla_put_failure; 3668 3669 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode)) 3670 goto value_nest_cancel; 3671 3672 switch (type) { 3673 case DEVLINK_PARAM_TYPE_U8: 3674 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8)) 3675 goto value_nest_cancel; 3676 break; 3677 case DEVLINK_PARAM_TYPE_U16: 3678 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16)) 3679 goto value_nest_cancel; 3680 break; 3681 case DEVLINK_PARAM_TYPE_U32: 3682 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32)) 3683 goto value_nest_cancel; 3684 break; 3685 case DEVLINK_PARAM_TYPE_STRING: 3686 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, 3687 val.vstr)) 3688 goto value_nest_cancel; 3689 break; 3690 case DEVLINK_PARAM_TYPE_BOOL: 3691 if (val.vbool && 3692 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA)) 3693 goto value_nest_cancel; 3694 break; 3695 } 3696 3697 nla_nest_end(msg, param_value_attr); 3698 return 0; 3699 3700value_nest_cancel: 3701 nla_nest_cancel(msg, param_value_attr); 3702nla_put_failure: 3703 return -EMSGSIZE; 3704} 3705 3706static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, 3707 unsigned int port_index, 3708 struct devlink_param_item *param_item, 3709 enum devlink_command cmd, 3710 u32 portid, u32 seq, int flags) 3711{ 3712 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1]; 3713 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; 3714 const struct devlink_param *param = param_item->param; 3715 struct devlink_param_gset_ctx ctx; 3716 struct nlattr *param_values_list; 3717 struct nlattr *param_attr; 3718 int nla_type; 3719 void *hdr; 3720 int err; 3721 int i; 3722 3723 /* Get value from driver part to driverinit configuration mode */ 3724 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 3725 if (!devlink_param_cmode_is_supported(param, i)) 3726 continue; 3727 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) { 3728 if (!param_item->driverinit_value_valid) 3729 return -EOPNOTSUPP; 3730 param_value[i] = param_item->driverinit_value; 3731 } else { 3732 if (!param_item->published) 3733 continue; 3734 ctx.cmode = i; 3735 err = devlink_param_get(devlink, param, &ctx); 3736 if (err) 3737 return err; 3738 param_value[i] = ctx.val; 3739 } 3740 param_value_set[i] = true; 3741 } 3742 3743 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 3744 if (!hdr) 3745 return -EMSGSIZE; 3746 3747 if (devlink_nl_put_handle(msg, devlink)) 3748 goto genlmsg_cancel; 3749 3750 if (cmd == DEVLINK_CMD_PORT_PARAM_GET || 3751 cmd == DEVLINK_CMD_PORT_PARAM_NEW || 3752 cmd == DEVLINK_CMD_PORT_PARAM_DEL) 3753 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index)) 3754 goto genlmsg_cancel; 3755 3756 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM); 3757 if (!param_attr) 3758 goto genlmsg_cancel; 3759 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name)) 3760 goto param_nest_cancel; 3761 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC)) 3762 goto param_nest_cancel; 3763 3764 nla_type = devlink_param_type_to_nla_type(param->type); 3765 if (nla_type < 0) 3766 goto param_nest_cancel; 3767 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type)) 3768 goto param_nest_cancel; 3769 3770 param_values_list = nla_nest_start_noflag(msg, 3771 DEVLINK_ATTR_PARAM_VALUES_LIST); 3772 if (!param_values_list) 3773 goto param_nest_cancel; 3774 3775 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 3776 if (!param_value_set[i]) 3777 continue; 3778 err = devlink_nl_param_value_fill_one(msg, param->type, 3779 i, param_value[i]); 3780 if (err) 3781 goto values_list_nest_cancel; 3782 } 3783 3784 nla_nest_end(msg, param_values_list); 3785 nla_nest_end(msg, param_attr); 3786 genlmsg_end(msg, hdr); 3787 return 0; 3788 3789values_list_nest_cancel: 3790 nla_nest_end(msg, param_values_list); 3791param_nest_cancel: 3792 nla_nest_cancel(msg, param_attr); 3793genlmsg_cancel: 3794 genlmsg_cancel(msg, hdr); 3795 return -EMSGSIZE; 3796} 3797 3798static void devlink_param_notify(struct devlink *devlink, 3799 unsigned int port_index, 3800 struct devlink_param_item *param_item, 3801 enum devlink_command cmd) 3802{ 3803 struct sk_buff *msg; 3804 int err; 3805 3806 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL && 3807 cmd != DEVLINK_CMD_PORT_PARAM_NEW && 3808 cmd != DEVLINK_CMD_PORT_PARAM_DEL); 3809 3810 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3811 if (!msg) 3812 return; 3813 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd, 3814 0, 0, 0); 3815 if (err) { 3816 nlmsg_free(msg); 3817 return; 3818 } 3819 3820 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 3821 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 3822} 3823 3824static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg, 3825 struct netlink_callback *cb) 3826{ 3827 struct devlink_param_item *param_item; 3828 struct devlink *devlink; 3829 int start = cb->args[0]; 3830 int idx = 0; 3831 int err = 0; 3832 3833 mutex_lock(&devlink_mutex); 3834 list_for_each_entry(devlink, &devlink_list, list) { 3835 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 3836 continue; 3837 mutex_lock(&devlink->lock); 3838 list_for_each_entry(param_item, &devlink->param_list, list) { 3839 if (idx < start) { 3840 idx++; 3841 continue; 3842 } 3843 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 3844 DEVLINK_CMD_PARAM_GET, 3845 NETLINK_CB(cb->skb).portid, 3846 cb->nlh->nlmsg_seq, 3847 NLM_F_MULTI); 3848 if (err == -EOPNOTSUPP) { 3849 err = 0; 3850 } else if (err) { 3851 mutex_unlock(&devlink->lock); 3852 goto out; 3853 } 3854 idx++; 3855 } 3856 mutex_unlock(&devlink->lock); 3857 } 3858out: 3859 mutex_unlock(&devlink_mutex); 3860 3861 if (err != -EMSGSIZE) 3862 return err; 3863 3864 cb->args[0] = idx; 3865 return msg->len; 3866} 3867 3868static int 3869devlink_param_type_get_from_info(struct genl_info *info, 3870 enum devlink_param_type *param_type) 3871{ 3872 if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE]) 3873 return -EINVAL; 3874 3875 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) { 3876 case NLA_U8: 3877 *param_type = DEVLINK_PARAM_TYPE_U8; 3878 break; 3879 case NLA_U16: 3880 *param_type = DEVLINK_PARAM_TYPE_U16; 3881 break; 3882 case NLA_U32: 3883 *param_type = DEVLINK_PARAM_TYPE_U32; 3884 break; 3885 case NLA_STRING: 3886 *param_type = DEVLINK_PARAM_TYPE_STRING; 3887 break; 3888 case NLA_FLAG: 3889 *param_type = DEVLINK_PARAM_TYPE_BOOL; 3890 break; 3891 default: 3892 return -EINVAL; 3893 } 3894 3895 return 0; 3896} 3897 3898static int 3899devlink_param_value_get_from_info(const struct devlink_param *param, 3900 struct genl_info *info, 3901 union devlink_param_value *value) 3902{ 3903 struct nlattr *param_data; 3904 int len; 3905 3906 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]; 3907 3908 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data) 3909 return -EINVAL; 3910 3911 switch (param->type) { 3912 case DEVLINK_PARAM_TYPE_U8: 3913 if (nla_len(param_data) != sizeof(u8)) 3914 return -EINVAL; 3915 value->vu8 = nla_get_u8(param_data); 3916 break; 3917 case DEVLINK_PARAM_TYPE_U16: 3918 if (nla_len(param_data) != sizeof(u16)) 3919 return -EINVAL; 3920 value->vu16 = nla_get_u16(param_data); 3921 break; 3922 case DEVLINK_PARAM_TYPE_U32: 3923 if (nla_len(param_data) != sizeof(u32)) 3924 return -EINVAL; 3925 value->vu32 = nla_get_u32(param_data); 3926 break; 3927 case DEVLINK_PARAM_TYPE_STRING: 3928 len = strnlen(nla_data(param_data), nla_len(param_data)); 3929 if (len == nla_len(param_data) || 3930 len >= __DEVLINK_PARAM_MAX_STRING_VALUE) 3931 return -EINVAL; 3932 strcpy(value->vstr, nla_data(param_data)); 3933 break; 3934 case DEVLINK_PARAM_TYPE_BOOL: 3935 if (param_data && nla_len(param_data)) 3936 return -EINVAL; 3937 value->vbool = nla_get_flag(param_data); 3938 break; 3939 } 3940 return 0; 3941} 3942 3943static struct devlink_param_item * 3944devlink_param_get_from_info(struct list_head *param_list, 3945 struct genl_info *info) 3946{ 3947 char *param_name; 3948 3949 if (!info->attrs[DEVLINK_ATTR_PARAM_NAME]) 3950 return NULL; 3951 3952 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]); 3953 return devlink_param_find_by_name(param_list, param_name); 3954} 3955 3956static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb, 3957 struct genl_info *info) 3958{ 3959 struct devlink *devlink = info->user_ptr[0]; 3960 struct devlink_param_item *param_item; 3961 struct sk_buff *msg; 3962 int err; 3963 3964 param_item = devlink_param_get_from_info(&devlink->param_list, info); 3965 if (!param_item) 3966 return -EINVAL; 3967 3968 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3969 if (!msg) 3970 return -ENOMEM; 3971 3972 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 3973 DEVLINK_CMD_PARAM_GET, 3974 info->snd_portid, info->snd_seq, 0); 3975 if (err) { 3976 nlmsg_free(msg); 3977 return err; 3978 } 3979 3980 return genlmsg_reply(msg, info); 3981} 3982 3983static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, 3984 unsigned int port_index, 3985 struct list_head *param_list, 3986 struct genl_info *info, 3987 enum devlink_command cmd) 3988{ 3989 enum devlink_param_type param_type; 3990 struct devlink_param_gset_ctx ctx; 3991 enum devlink_param_cmode cmode; 3992 struct devlink_param_item *param_item; 3993 const struct devlink_param *param; 3994 union devlink_param_value value; 3995 int err = 0; 3996 3997 param_item = devlink_param_get_from_info(param_list, info); 3998 if (!param_item) 3999 return -EINVAL; 4000 param = param_item->param; 4001 err = devlink_param_type_get_from_info(info, ¶m_type); 4002 if (err) 4003 return err; 4004 if (param_type != param->type) 4005 return -EINVAL; 4006 err = devlink_param_value_get_from_info(param, info, &value); 4007 if (err) 4008 return err; 4009 if (param->validate) { 4010 err = param->validate(devlink, param->id, value, info->extack); 4011 if (err) 4012 return err; 4013 } 4014 4015 if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]) 4016 return -EINVAL; 4017 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]); 4018 if (!devlink_param_cmode_is_supported(param, cmode)) 4019 return -EOPNOTSUPP; 4020 4021 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { 4022 if (param->type == DEVLINK_PARAM_TYPE_STRING) 4023 strcpy(param_item->driverinit_value.vstr, value.vstr); 4024 else 4025 param_item->driverinit_value = value; 4026 param_item->driverinit_value_valid = true; 4027 } else { 4028 if (!param->set) 4029 return -EOPNOTSUPP; 4030 ctx.val = value; 4031 ctx.cmode = cmode; 4032 err = devlink_param_set(devlink, param, &ctx); 4033 if (err) 4034 return err; 4035 } 4036 4037 devlink_param_notify(devlink, port_index, param_item, cmd); 4038 return 0; 4039} 4040 4041static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb, 4042 struct genl_info *info) 4043{ 4044 struct devlink *devlink = info->user_ptr[0]; 4045 4046 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list, 4047 info, DEVLINK_CMD_PARAM_NEW); 4048} 4049 4050static int devlink_param_register_one(struct devlink *devlink, 4051 unsigned int port_index, 4052 struct list_head *param_list, 4053 const struct devlink_param *param, 4054 enum devlink_command cmd) 4055{ 4056 struct devlink_param_item *param_item; 4057 4058 if (devlink_param_find_by_name(param_list, param->name)) 4059 return -EEXIST; 4060 4061 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT)) 4062 WARN_ON(param->get || param->set); 4063 else 4064 WARN_ON(!param->get || !param->set); 4065 4066 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL); 4067 if (!param_item) 4068 return -ENOMEM; 4069 param_item->param = param; 4070 4071 list_add_tail(¶m_item->list, param_list); 4072 devlink_param_notify(devlink, port_index, param_item, cmd); 4073 return 0; 4074} 4075 4076static void devlink_param_unregister_one(struct devlink *devlink, 4077 unsigned int port_index, 4078 struct list_head *param_list, 4079 const struct devlink_param *param, 4080 enum devlink_command cmd) 4081{ 4082 struct devlink_param_item *param_item; 4083 4084 param_item = devlink_param_find_by_name(param_list, param->name); 4085 WARN_ON(!param_item); 4086 devlink_param_notify(devlink, port_index, param_item, cmd); 4087 list_del(¶m_item->list); 4088 kfree(param_item); 4089} 4090 4091static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg, 4092 struct netlink_callback *cb) 4093{ 4094 struct devlink_param_item *param_item; 4095 struct devlink_port *devlink_port; 4096 struct devlink *devlink; 4097 int start = cb->args[0]; 4098 int idx = 0; 4099 int err = 0; 4100 4101 mutex_lock(&devlink_mutex); 4102 list_for_each_entry(devlink, &devlink_list, list) { 4103 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 4104 continue; 4105 mutex_lock(&devlink->lock); 4106 list_for_each_entry(devlink_port, &devlink->port_list, list) { 4107 list_for_each_entry(param_item, 4108 &devlink_port->param_list, list) { 4109 if (idx < start) { 4110 idx++; 4111 continue; 4112 } 4113 err = devlink_nl_param_fill(msg, 4114 devlink_port->devlink, 4115 devlink_port->index, param_item, 4116 DEVLINK_CMD_PORT_PARAM_GET, 4117 NETLINK_CB(cb->skb).portid, 4118 cb->nlh->nlmsg_seq, 4119 NLM_F_MULTI); 4120 if (err == -EOPNOTSUPP) { 4121 err = 0; 4122 } else if (err) { 4123 mutex_unlock(&devlink->lock); 4124 goto out; 4125 } 4126 idx++; 4127 } 4128 } 4129 mutex_unlock(&devlink->lock); 4130 } 4131out: 4132 mutex_unlock(&devlink_mutex); 4133 4134 if (err != -EMSGSIZE) 4135 return err; 4136 4137 cb->args[0] = idx; 4138 return msg->len; 4139} 4140 4141static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb, 4142 struct genl_info *info) 4143{ 4144 struct devlink_port *devlink_port = info->user_ptr[1]; 4145 struct devlink_param_item *param_item; 4146 struct sk_buff *msg; 4147 int err; 4148 4149 param_item = devlink_param_get_from_info(&devlink_port->param_list, 4150 info); 4151 if (!param_item) 4152 return -EINVAL; 4153 4154 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4155 if (!msg) 4156 return -ENOMEM; 4157 4158 err = devlink_nl_param_fill(msg, devlink_port->devlink, 4159 devlink_port->index, param_item, 4160 DEVLINK_CMD_PORT_PARAM_GET, 4161 info->snd_portid, info->snd_seq, 0); 4162 if (err) { 4163 nlmsg_free(msg); 4164 return err; 4165 } 4166 4167 return genlmsg_reply(msg, info); 4168} 4169 4170static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb, 4171 struct genl_info *info) 4172{ 4173 struct devlink_port *devlink_port = info->user_ptr[1]; 4174 4175 return __devlink_nl_cmd_param_set_doit(devlink_port->devlink, 4176 devlink_port->index, 4177 &devlink_port->param_list, info, 4178 DEVLINK_CMD_PORT_PARAM_NEW); 4179} 4180 4181static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg, 4182 struct devlink *devlink, 4183 struct devlink_snapshot *snapshot) 4184{ 4185 struct nlattr *snap_attr; 4186 int err; 4187 4188 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT); 4189 if (!snap_attr) 4190 return -EINVAL; 4191 4192 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id); 4193 if (err) 4194 goto nla_put_failure; 4195 4196 nla_nest_end(msg, snap_attr); 4197 return 0; 4198 4199nla_put_failure: 4200 nla_nest_cancel(msg, snap_attr); 4201 return err; 4202} 4203 4204static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg, 4205 struct devlink *devlink, 4206 struct devlink_region *region) 4207{ 4208 struct devlink_snapshot *snapshot; 4209 struct nlattr *snapshots_attr; 4210 int err; 4211 4212 snapshots_attr = nla_nest_start_noflag(msg, 4213 DEVLINK_ATTR_REGION_SNAPSHOTS); 4214 if (!snapshots_attr) 4215 return -EINVAL; 4216 4217 list_for_each_entry(snapshot, ®ion->snapshot_list, list) { 4218 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot); 4219 if (err) 4220 goto nla_put_failure; 4221 } 4222 4223 nla_nest_end(msg, snapshots_attr); 4224 return 0; 4225 4226nla_put_failure: 4227 nla_nest_cancel(msg, snapshots_attr); 4228 return err; 4229} 4230 4231static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink, 4232 enum devlink_command cmd, u32 portid, 4233 u32 seq, int flags, 4234 struct devlink_region *region) 4235{ 4236 void *hdr; 4237 int err; 4238 4239 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 4240 if (!hdr) 4241 return -EMSGSIZE; 4242 4243 err = devlink_nl_put_handle(msg, devlink); 4244 if (err) 4245 goto nla_put_failure; 4246 4247 if (region->port) { 4248 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 4249 region->port->index); 4250 if (err) 4251 goto nla_put_failure; 4252 } 4253 4254 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name); 4255 if (err) 4256 goto nla_put_failure; 4257 4258 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 4259 region->size, 4260 DEVLINK_ATTR_PAD); 4261 if (err) 4262 goto nla_put_failure; 4263 4264 err = devlink_nl_region_snapshots_id_put(msg, devlink, region); 4265 if (err) 4266 goto nla_put_failure; 4267 4268 genlmsg_end(msg, hdr); 4269 return 0; 4270 4271nla_put_failure: 4272 genlmsg_cancel(msg, hdr); 4273 return err; 4274} 4275 4276static struct sk_buff * 4277devlink_nl_region_notify_build(struct devlink_region *region, 4278 struct devlink_snapshot *snapshot, 4279 enum devlink_command cmd, u32 portid, u32 seq) 4280{ 4281 struct devlink *devlink = region->devlink; 4282 struct sk_buff *msg; 4283 void *hdr; 4284 int err; 4285 4286 4287 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4288 if (!msg) 4289 return ERR_PTR(-ENOMEM); 4290 4291 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd); 4292 if (!hdr) { 4293 err = -EMSGSIZE; 4294 goto out_free_msg; 4295 } 4296 4297 err = devlink_nl_put_handle(msg, devlink); 4298 if (err) 4299 goto out_cancel_msg; 4300 4301 if (region->port) { 4302 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 4303 region->port->index); 4304 if (err) 4305 goto out_cancel_msg; 4306 } 4307 4308 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, 4309 region->ops->name); 4310 if (err) 4311 goto out_cancel_msg; 4312 4313 if (snapshot) { 4314 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, 4315 snapshot->id); 4316 if (err) 4317 goto out_cancel_msg; 4318 } else { 4319 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 4320 region->size, DEVLINK_ATTR_PAD); 4321 if (err) 4322 goto out_cancel_msg; 4323 } 4324 genlmsg_end(msg, hdr); 4325 4326 return msg; 4327 4328out_cancel_msg: 4329 genlmsg_cancel(msg, hdr); 4330out_free_msg: 4331 nlmsg_free(msg); 4332 return ERR_PTR(err); 4333} 4334 4335static void devlink_nl_region_notify(struct devlink_region *region, 4336 struct devlink_snapshot *snapshot, 4337 enum devlink_command cmd) 4338{ 4339 struct devlink *devlink = region->devlink; 4340 struct sk_buff *msg; 4341 4342 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL); 4343 4344 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0); 4345 if (IS_ERR(msg)) 4346 return; 4347 4348 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 4349 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 4350} 4351 4352/** 4353 * __devlink_snapshot_id_increment - Increment number of snapshots using an id 4354 * @devlink: devlink instance 4355 * @id: the snapshot id 4356 * 4357 * Track when a new snapshot begins using an id. Load the count for the 4358 * given id from the snapshot xarray, increment it, and store it back. 4359 * 4360 * Called when a new snapshot is created with the given id. 4361 * 4362 * The id *must* have been previously allocated by 4363 * devlink_region_snapshot_id_get(). 4364 * 4365 * Returns 0 on success, or an error on failure. 4366 */ 4367static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id) 4368{ 4369 unsigned long count; 4370 void *p; 4371 4372 lockdep_assert_held(&devlink->lock); 4373 4374 p = xa_load(&devlink->snapshot_ids, id); 4375 if (WARN_ON(!p)) 4376 return -EINVAL; 4377 4378 if (WARN_ON(!xa_is_value(p))) 4379 return -EINVAL; 4380 4381 count = xa_to_value(p); 4382 count++; 4383 4384 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 4385 GFP_KERNEL)); 4386} 4387 4388/** 4389 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id 4390 * @devlink: devlink instance 4391 * @id: the snapshot id 4392 * 4393 * Track when a snapshot is deleted and stops using an id. Load the count 4394 * for the given id from the snapshot xarray, decrement it, and store it 4395 * back. 4396 * 4397 * If the count reaches zero, erase this id from the xarray, freeing it 4398 * up for future re-use by devlink_region_snapshot_id_get(). 4399 * 4400 * Called when a snapshot using the given id is deleted, and when the 4401 * initial allocator of the id is finished using it. 4402 */ 4403static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id) 4404{ 4405 unsigned long count; 4406 void *p; 4407 4408 lockdep_assert_held(&devlink->lock); 4409 4410 p = xa_load(&devlink->snapshot_ids, id); 4411 if (WARN_ON(!p)) 4412 return; 4413 4414 if (WARN_ON(!xa_is_value(p))) 4415 return; 4416 4417 count = xa_to_value(p); 4418 4419 if (count > 1) { 4420 count--; 4421 xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 4422 GFP_KERNEL); 4423 } else { 4424 /* If this was the last user, we can erase this id */ 4425 xa_erase(&devlink->snapshot_ids, id); 4426 } 4427} 4428 4429/** 4430 * __devlink_snapshot_id_insert - Insert a specific snapshot ID 4431 * @devlink: devlink instance 4432 * @id: the snapshot id 4433 * 4434 * Mark the given snapshot id as used by inserting a zero value into the 4435 * snapshot xarray. 4436 * 4437 * This must be called while holding the devlink instance lock. Unlike 4438 * devlink_snapshot_id_get, the initial reference count is zero, not one. 4439 * It is expected that the id will immediately be used before 4440 * releasing the devlink instance lock. 4441 * 4442 * Returns zero on success, or an error code if the snapshot id could not 4443 * be inserted. 4444 */ 4445static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id) 4446{ 4447 lockdep_assert_held(&devlink->lock); 4448 4449 if (xa_load(&devlink->snapshot_ids, id)) 4450 return -EEXIST; 4451 4452 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0), 4453 GFP_KERNEL)); 4454} 4455 4456/** 4457 * __devlink_region_snapshot_id_get - get snapshot ID 4458 * @devlink: devlink instance 4459 * @id: storage to return snapshot id 4460 * 4461 * Allocates a new snapshot id. Returns zero on success, or a negative 4462 * error on failure. Must be called while holding the devlink instance 4463 * lock. 4464 * 4465 * Snapshot IDs are tracked using an xarray which stores the number of 4466 * users of the snapshot id. 4467 * 4468 * Note that the caller of this function counts as a 'user', in order to 4469 * avoid race conditions. The caller must release its hold on the 4470 * snapshot by using devlink_region_snapshot_id_put. 4471 */ 4472static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 4473{ 4474 lockdep_assert_held(&devlink->lock); 4475 4476 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1), 4477 xa_limit_32b, GFP_KERNEL); 4478} 4479 4480/** 4481 * __devlink_region_snapshot_create - create a new snapshot 4482 * This will add a new snapshot of a region. The snapshot 4483 * will be stored on the region struct and can be accessed 4484 * from devlink. This is useful for future analyses of snapshots. 4485 * Multiple snapshots can be created on a region. 4486 * The @snapshot_id should be obtained using the getter function. 4487 * 4488 * Must be called only while holding the devlink instance lock. 4489 * 4490 * @region: devlink region of the snapshot 4491 * @data: snapshot data 4492 * @snapshot_id: snapshot id to be created 4493 */ 4494static int 4495__devlink_region_snapshot_create(struct devlink_region *region, 4496 u8 *data, u32 snapshot_id) 4497{ 4498 struct devlink *devlink = region->devlink; 4499 struct devlink_snapshot *snapshot; 4500 int err; 4501 4502 lockdep_assert_held(&devlink->lock); 4503 4504 /* check if region can hold one more snapshot */ 4505 if (region->cur_snapshots == region->max_snapshots) 4506 return -ENOSPC; 4507 4508 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) 4509 return -EEXIST; 4510 4511 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL); 4512 if (!snapshot) 4513 return -ENOMEM; 4514 4515 err = __devlink_snapshot_id_increment(devlink, snapshot_id); 4516 if (err) 4517 goto err_snapshot_id_increment; 4518 4519 snapshot->id = snapshot_id; 4520 snapshot->region = region; 4521 snapshot->data = data; 4522 4523 list_add_tail(&snapshot->list, ®ion->snapshot_list); 4524 4525 region->cur_snapshots++; 4526 4527 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW); 4528 return 0; 4529 4530err_snapshot_id_increment: 4531 kfree(snapshot); 4532 return err; 4533} 4534 4535static void devlink_region_snapshot_del(struct devlink_region *region, 4536 struct devlink_snapshot *snapshot) 4537{ 4538 struct devlink *devlink = region->devlink; 4539 4540 lockdep_assert_held(&devlink->lock); 4541 4542 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL); 4543 region->cur_snapshots--; 4544 list_del(&snapshot->list); 4545 region->ops->destructor(snapshot->data); 4546 __devlink_snapshot_id_decrement(devlink, snapshot->id); 4547 kfree(snapshot); 4548} 4549 4550static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb, 4551 struct genl_info *info) 4552{ 4553 struct devlink *devlink = info->user_ptr[0]; 4554 struct devlink_port *port = NULL; 4555 struct devlink_region *region; 4556 const char *region_name; 4557 struct sk_buff *msg; 4558 unsigned int index; 4559 int err; 4560 4561 if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) 4562 return -EINVAL; 4563 4564 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4565 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4566 4567 port = devlink_port_get_by_index(devlink, index); 4568 if (!port) 4569 return -ENODEV; 4570 } 4571 4572 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4573 if (port) 4574 region = devlink_port_region_get_by_name(port, region_name); 4575 else 4576 region = devlink_region_get_by_name(devlink, region_name); 4577 4578 if (!region) 4579 return -EINVAL; 4580 4581 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4582 if (!msg) 4583 return -ENOMEM; 4584 4585 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET, 4586 info->snd_portid, info->snd_seq, 0, 4587 region); 4588 if (err) { 4589 nlmsg_free(msg); 4590 return err; 4591 } 4592 4593 return genlmsg_reply(msg, info); 4594} 4595 4596static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg, 4597 struct netlink_callback *cb, 4598 struct devlink_port *port, 4599 int *idx, 4600 int start) 4601{ 4602 struct devlink_region *region; 4603 int err = 0; 4604 4605 list_for_each_entry(region, &port->region_list, list) { 4606 if (*idx < start) { 4607 (*idx)++; 4608 continue; 4609 } 4610 err = devlink_nl_region_fill(msg, port->devlink, 4611 DEVLINK_CMD_REGION_GET, 4612 NETLINK_CB(cb->skb).portid, 4613 cb->nlh->nlmsg_seq, 4614 NLM_F_MULTI, region); 4615 if (err) 4616 goto out; 4617 (*idx)++; 4618 } 4619 4620out: 4621 return err; 4622} 4623 4624static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg, 4625 struct netlink_callback *cb, 4626 struct devlink *devlink, 4627 int *idx, 4628 int start) 4629{ 4630 struct devlink_region *region; 4631 struct devlink_port *port; 4632 int err = 0; 4633 4634 mutex_lock(&devlink->lock); 4635 list_for_each_entry(region, &devlink->region_list, list) { 4636 if (*idx < start) { 4637 (*idx)++; 4638 continue; 4639 } 4640 err = devlink_nl_region_fill(msg, devlink, 4641 DEVLINK_CMD_REGION_GET, 4642 NETLINK_CB(cb->skb).portid, 4643 cb->nlh->nlmsg_seq, 4644 NLM_F_MULTI, region); 4645 if (err) 4646 goto out; 4647 (*idx)++; 4648 } 4649 4650 list_for_each_entry(port, &devlink->port_list, list) { 4651 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx, 4652 start); 4653 if (err) 4654 goto out; 4655 } 4656 4657out: 4658 mutex_unlock(&devlink->lock); 4659 return err; 4660} 4661 4662static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg, 4663 struct netlink_callback *cb) 4664{ 4665 struct devlink *devlink; 4666 int start = cb->args[0]; 4667 int idx = 0; 4668 int err; 4669 4670 mutex_lock(&devlink_mutex); 4671 list_for_each_entry(devlink, &devlink_list, list) { 4672 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 4673 continue; 4674 err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink, 4675 &idx, start); 4676 if (err) 4677 goto out; 4678 } 4679out: 4680 mutex_unlock(&devlink_mutex); 4681 cb->args[0] = idx; 4682 return msg->len; 4683} 4684 4685static int devlink_nl_cmd_region_del(struct sk_buff *skb, 4686 struct genl_info *info) 4687{ 4688 struct devlink *devlink = info->user_ptr[0]; 4689 struct devlink_snapshot *snapshot; 4690 struct devlink_port *port = NULL; 4691 struct devlink_region *region; 4692 const char *region_name; 4693 unsigned int index; 4694 u32 snapshot_id; 4695 4696 if (!info->attrs[DEVLINK_ATTR_REGION_NAME] || 4697 !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) 4698 return -EINVAL; 4699 4700 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4701 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); 4702 4703 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4704 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4705 4706 port = devlink_port_get_by_index(devlink, index); 4707 if (!port) 4708 return -ENODEV; 4709 } 4710 4711 if (port) 4712 region = devlink_port_region_get_by_name(port, region_name); 4713 else 4714 region = devlink_region_get_by_name(devlink, region_name); 4715 4716 if (!region) 4717 return -EINVAL; 4718 4719 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 4720 if (!snapshot) 4721 return -EINVAL; 4722 4723 devlink_region_snapshot_del(region, snapshot); 4724 return 0; 4725} 4726 4727static int 4728devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) 4729{ 4730 struct devlink *devlink = info->user_ptr[0]; 4731 struct devlink_snapshot *snapshot; 4732 struct devlink_port *port = NULL; 4733 struct nlattr *snapshot_id_attr; 4734 struct devlink_region *region; 4735 const char *region_name; 4736 unsigned int index; 4737 u32 snapshot_id; 4738 u8 *data; 4739 int err; 4740 4741 if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) { 4742 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided"); 4743 return -EINVAL; 4744 } 4745 4746 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4747 4748 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4749 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4750 4751 port = devlink_port_get_by_index(devlink, index); 4752 if (!port) 4753 return -ENODEV; 4754 } 4755 4756 if (port) 4757 region = devlink_port_region_get_by_name(port, region_name); 4758 else 4759 region = devlink_region_get_by_name(devlink, region_name); 4760 4761 if (!region) { 4762 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist"); 4763 return -EINVAL; 4764 } 4765 4766 if (!region->ops->snapshot) { 4767 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot"); 4768 return -EOPNOTSUPP; 4769 } 4770 4771 if (region->cur_snapshots == region->max_snapshots) { 4772 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots"); 4773 return -ENOSPC; 4774 } 4775 4776 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; 4777 if (snapshot_id_attr) { 4778 snapshot_id = nla_get_u32(snapshot_id_attr); 4779 4780 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { 4781 NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use"); 4782 return -EEXIST; 4783 } 4784 4785 err = __devlink_snapshot_id_insert(devlink, snapshot_id); 4786 if (err) 4787 return err; 4788 } else { 4789 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id); 4790 if (err) { 4791 NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id"); 4792 return err; 4793 } 4794 } 4795 4796 if (port) 4797 err = region->port_ops->snapshot(port, region->port_ops, 4798 info->extack, &data); 4799 else 4800 err = region->ops->snapshot(devlink, region->ops, 4801 info->extack, &data); 4802 if (err) 4803 goto err_snapshot_capture; 4804 4805 err = __devlink_region_snapshot_create(region, data, snapshot_id); 4806 if (err) 4807 goto err_snapshot_create; 4808 4809 if (!snapshot_id_attr) { 4810 struct sk_buff *msg; 4811 4812 snapshot = devlink_region_snapshot_get_by_id(region, 4813 snapshot_id); 4814 if (WARN_ON(!snapshot)) 4815 return -EINVAL; 4816 4817 msg = devlink_nl_region_notify_build(region, snapshot, 4818 DEVLINK_CMD_REGION_NEW, 4819 info->snd_portid, 4820 info->snd_seq); 4821 err = PTR_ERR_OR_ZERO(msg); 4822 if (err) 4823 goto err_notify; 4824 4825 err = genlmsg_reply(msg, info); 4826 if (err) 4827 goto err_notify; 4828 } 4829 4830 return 0; 4831 4832err_snapshot_create: 4833 region->ops->destructor(data); 4834err_snapshot_capture: 4835 __devlink_snapshot_id_decrement(devlink, snapshot_id); 4836 return err; 4837 4838err_notify: 4839 devlink_region_snapshot_del(region, snapshot); 4840 return err; 4841} 4842 4843static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg, 4844 struct devlink *devlink, 4845 u8 *chunk, u32 chunk_size, 4846 u64 addr) 4847{ 4848 struct nlattr *chunk_attr; 4849 int err; 4850 4851 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK); 4852 if (!chunk_attr) 4853 return -EINVAL; 4854 4855 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk); 4856 if (err) 4857 goto nla_put_failure; 4858 4859 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr, 4860 DEVLINK_ATTR_PAD); 4861 if (err) 4862 goto nla_put_failure; 4863 4864 nla_nest_end(msg, chunk_attr); 4865 return 0; 4866 4867nla_put_failure: 4868 nla_nest_cancel(msg, chunk_attr); 4869 return err; 4870} 4871 4872#define DEVLINK_REGION_READ_CHUNK_SIZE 256 4873 4874static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb, 4875 struct devlink *devlink, 4876 struct devlink_region *region, 4877 struct nlattr **attrs, 4878 u64 start_offset, 4879 u64 end_offset, 4880 u64 *new_offset) 4881{ 4882 struct devlink_snapshot *snapshot; 4883 u64 curr_offset = start_offset; 4884 u32 snapshot_id; 4885 int err = 0; 4886 4887 *new_offset = start_offset; 4888 4889 snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); 4890 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 4891 if (!snapshot) 4892 return -EINVAL; 4893 4894 while (curr_offset < end_offset) { 4895 u32 data_size; 4896 u8 *data; 4897 4898 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE) 4899 data_size = end_offset - curr_offset; 4900 else 4901 data_size = DEVLINK_REGION_READ_CHUNK_SIZE; 4902 4903 data = &snapshot->data[curr_offset]; 4904 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink, 4905 data, data_size, 4906 curr_offset); 4907 if (err) 4908 break; 4909 4910 curr_offset += data_size; 4911 } 4912 *new_offset = curr_offset; 4913 4914 return err; 4915} 4916 4917static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, 4918 struct netlink_callback *cb) 4919{ 4920 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 4921 u64 ret_offset, start_offset, end_offset = U64_MAX; 4922 struct nlattr **attrs = info->attrs; 4923 struct devlink_port *port = NULL; 4924 struct devlink_region *region; 4925 struct nlattr *chunks_attr; 4926 const char *region_name; 4927 struct devlink *devlink; 4928 unsigned int index; 4929 void *hdr; 4930 int err; 4931 4932 start_offset = *((u64 *)&cb->args[0]); 4933 4934 mutex_lock(&devlink_mutex); 4935 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); 4936 if (IS_ERR(devlink)) { 4937 err = PTR_ERR(devlink); 4938 goto out_dev; 4939 } 4940 4941 mutex_lock(&devlink->lock); 4942 4943 if (!attrs[DEVLINK_ATTR_REGION_NAME] || 4944 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) { 4945 err = -EINVAL; 4946 goto out_unlock; 4947 } 4948 4949 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4950 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4951 4952 port = devlink_port_get_by_index(devlink, index); 4953 if (!port) { 4954 err = -ENODEV; 4955 goto out_unlock; 4956 } 4957 } 4958 4959 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]); 4960 4961 if (port) 4962 region = devlink_port_region_get_by_name(port, region_name); 4963 else 4964 region = devlink_region_get_by_name(devlink, region_name); 4965 4966 if (!region) { 4967 err = -EINVAL; 4968 goto out_unlock; 4969 } 4970 4971 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] && 4972 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) { 4973 if (!start_offset) 4974 start_offset = 4975 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 4976 4977 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 4978 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); 4979 } 4980 4981 if (end_offset > region->size) 4982 end_offset = region->size; 4983 4984 /* return 0 if there is no further data to read */ 4985 if (start_offset == end_offset) { 4986 err = 0; 4987 goto out_unlock; 4988 } 4989 4990 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 4991 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, 4992 DEVLINK_CMD_REGION_READ); 4993 if (!hdr) { 4994 err = -EMSGSIZE; 4995 goto out_unlock; 4996 } 4997 4998 err = devlink_nl_put_handle(skb, devlink); 4999 if (err) 5000 goto nla_put_failure; 5001 5002 if (region->port) { 5003 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX, 5004 region->port->index); 5005 if (err) 5006 goto nla_put_failure; 5007 } 5008 5009 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name); 5010 if (err) 5011 goto nla_put_failure; 5012 5013 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS); 5014 if (!chunks_attr) { 5015 err = -EMSGSIZE; 5016 goto nla_put_failure; 5017 } 5018 5019 err = devlink_nl_region_read_snapshot_fill(skb, devlink, 5020 region, attrs, 5021 start_offset, 5022 end_offset, &ret_offset); 5023 5024 if (err && err != -EMSGSIZE) 5025 goto nla_put_failure; 5026 5027 /* Check if there was any progress done to prevent infinite loop */ 5028 if (ret_offset == start_offset) { 5029 err = -EINVAL; 5030 goto nla_put_failure; 5031 } 5032 5033 *((u64 *)&cb->args[0]) = ret_offset; 5034 5035 nla_nest_end(skb, chunks_attr); 5036 genlmsg_end(skb, hdr); 5037 mutex_unlock(&devlink->lock); 5038 mutex_unlock(&devlink_mutex); 5039 5040 return skb->len; 5041 5042nla_put_failure: 5043 genlmsg_cancel(skb, hdr); 5044out_unlock: 5045 mutex_unlock(&devlink->lock); 5046out_dev: 5047 mutex_unlock(&devlink_mutex); 5048 return err; 5049} 5050 5051struct devlink_info_req { 5052 struct sk_buff *msg; 5053}; 5054 5055int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name) 5056{ 5057 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name); 5058} 5059EXPORT_SYMBOL_GPL(devlink_info_driver_name_put); 5060 5061int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) 5062{ 5063 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); 5064} 5065EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); 5066 5067int devlink_info_board_serial_number_put(struct devlink_info_req *req, 5068 const char *bsn) 5069{ 5070 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, 5071 bsn); 5072} 5073EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); 5074 5075static int devlink_info_version_put(struct devlink_info_req *req, int attr, 5076 const char *version_name, 5077 const char *version_value) 5078{ 5079 struct nlattr *nest; 5080 int err; 5081 5082 nest = nla_nest_start_noflag(req->msg, attr); 5083 if (!nest) 5084 return -EMSGSIZE; 5085 5086 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, 5087 version_name); 5088 if (err) 5089 goto nla_put_failure; 5090 5091 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, 5092 version_value); 5093 if (err) 5094 goto nla_put_failure; 5095 5096 nla_nest_end(req->msg, nest); 5097 5098 return 0; 5099 5100nla_put_failure: 5101 nla_nest_cancel(req->msg, nest); 5102 return err; 5103} 5104 5105int devlink_info_version_fixed_put(struct devlink_info_req *req, 5106 const char *version_name, 5107 const char *version_value) 5108{ 5109 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, 5110 version_name, version_value); 5111} 5112EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); 5113 5114int devlink_info_version_stored_put(struct devlink_info_req *req, 5115 const char *version_name, 5116 const char *version_value) 5117{ 5118 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 5119 version_name, version_value); 5120} 5121EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); 5122 5123int devlink_info_version_running_put(struct devlink_info_req *req, 5124 const char *version_name, 5125 const char *version_value) 5126{ 5127 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 5128 version_name, version_value); 5129} 5130EXPORT_SYMBOL_GPL(devlink_info_version_running_put); 5131 5132static int 5133devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, 5134 enum devlink_command cmd, u32 portid, 5135 u32 seq, int flags, struct netlink_ext_ack *extack) 5136{ 5137 struct devlink_info_req req; 5138 void *hdr; 5139 int err; 5140 5141 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 5142 if (!hdr) 5143 return -EMSGSIZE; 5144 5145 err = -EMSGSIZE; 5146 if (devlink_nl_put_handle(msg, devlink)) 5147 goto err_cancel_msg; 5148 5149 req.msg = msg; 5150 err = devlink->ops->info_get(devlink, &req, extack); 5151 if (err) 5152 goto err_cancel_msg; 5153 5154 genlmsg_end(msg, hdr); 5155 return 0; 5156 5157err_cancel_msg: 5158 genlmsg_cancel(msg, hdr); 5159 return err; 5160} 5161 5162static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, 5163 struct genl_info *info) 5164{ 5165 struct devlink *devlink = info->user_ptr[0]; 5166 struct sk_buff *msg; 5167 int err; 5168 5169 if (!devlink->ops->info_get) 5170 return -EOPNOTSUPP; 5171 5172 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 5173 if (!msg) 5174 return -ENOMEM; 5175 5176 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 5177 info->snd_portid, info->snd_seq, 0, 5178 info->extack); 5179 if (err) { 5180 nlmsg_free(msg); 5181 return err; 5182 } 5183 5184 return genlmsg_reply(msg, info); 5185} 5186 5187static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg, 5188 struct netlink_callback *cb) 5189{ 5190 struct devlink *devlink; 5191 int start = cb->args[0]; 5192 int idx = 0; 5193 int err = 0; 5194 5195 mutex_lock(&devlink_mutex); 5196 list_for_each_entry(devlink, &devlink_list, list) { 5197 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 5198 continue; 5199 if (idx < start) { 5200 idx++; 5201 continue; 5202 } 5203 5204 if (!devlink->ops->info_get) { 5205 idx++; 5206 continue; 5207 } 5208 5209 mutex_lock(&devlink->lock); 5210 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 5211 NETLINK_CB(cb->skb).portid, 5212 cb->nlh->nlmsg_seq, NLM_F_MULTI, 5213 cb->extack); 5214 mutex_unlock(&devlink->lock); 5215 if (err == -EOPNOTSUPP) 5216 err = 0; 5217 else if (err) 5218 break; 5219 idx++; 5220 } 5221 mutex_unlock(&devlink_mutex); 5222 5223 if (err != -EMSGSIZE) 5224 return err; 5225 5226 cb->args[0] = idx; 5227 return msg->len; 5228} 5229 5230struct devlink_fmsg_item { 5231 struct list_head list; 5232 int attrtype; 5233 u8 nla_type; 5234 u16 len; 5235 int value[]; 5236}; 5237 5238struct devlink_fmsg { 5239 struct list_head item_list; 5240 bool putting_binary; /* This flag forces enclosing of binary data 5241 * in an array brackets. It forces using 5242 * of designated API: 5243 * devlink_fmsg_binary_pair_nest_start() 5244 * devlink_fmsg_binary_pair_nest_end() 5245 */ 5246}; 5247 5248static struct devlink_fmsg *devlink_fmsg_alloc(void) 5249{ 5250 struct devlink_fmsg *fmsg; 5251 5252 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL); 5253 if (!fmsg) 5254 return NULL; 5255 5256 INIT_LIST_HEAD(&fmsg->item_list); 5257 5258 return fmsg; 5259} 5260 5261static void devlink_fmsg_free(struct devlink_fmsg *fmsg) 5262{ 5263 struct devlink_fmsg_item *item, *tmp; 5264 5265 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) { 5266 list_del(&item->list); 5267 kfree(item); 5268 } 5269 kfree(fmsg); 5270} 5271 5272static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg, 5273 int attrtype) 5274{ 5275 struct devlink_fmsg_item *item; 5276 5277 item = kzalloc(sizeof(*item), GFP_KERNEL); 5278 if (!item) 5279 return -ENOMEM; 5280 5281 item->attrtype = attrtype; 5282 list_add_tail(&item->list, &fmsg->item_list); 5283 5284 return 0; 5285} 5286 5287int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg) 5288{ 5289 if (fmsg->putting_binary) 5290 return -EINVAL; 5291 5292 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START); 5293} 5294EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start); 5295 5296static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg) 5297{ 5298 if (fmsg->putting_binary) 5299 return -EINVAL; 5300 5301 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END); 5302} 5303 5304int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg) 5305{ 5306 if (fmsg->putting_binary) 5307 return -EINVAL; 5308 5309 return devlink_fmsg_nest_end(fmsg); 5310} 5311EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end); 5312 5313#define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN) 5314 5315static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name) 5316{ 5317 struct devlink_fmsg_item *item; 5318 5319 if (fmsg->putting_binary) 5320 return -EINVAL; 5321 5322 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE) 5323 return -EMSGSIZE; 5324 5325 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL); 5326 if (!item) 5327 return -ENOMEM; 5328 5329 item->nla_type = NLA_NUL_STRING; 5330 item->len = strlen(name) + 1; 5331 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME; 5332 memcpy(&item->value, name, item->len); 5333 list_add_tail(&item->list, &fmsg->item_list); 5334 5335 return 0; 5336} 5337 5338int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name) 5339{ 5340 int err; 5341 5342 if (fmsg->putting_binary) 5343 return -EINVAL; 5344 5345 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START); 5346 if (err) 5347 return err; 5348 5349 err = devlink_fmsg_put_name(fmsg, name); 5350 if (err) 5351 return err; 5352 5353 return 0; 5354} 5355EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start); 5356 5357int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg) 5358{ 5359 if (fmsg->putting_binary) 5360 return -EINVAL; 5361 5362 return devlink_fmsg_nest_end(fmsg); 5363} 5364EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end); 5365 5366int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg, 5367 const char *name) 5368{ 5369 int err; 5370 5371 if (fmsg->putting_binary) 5372 return -EINVAL; 5373 5374 err = devlink_fmsg_pair_nest_start(fmsg, name); 5375 if (err) 5376 return err; 5377 5378 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START); 5379 if (err) 5380 return err; 5381 5382 return 0; 5383} 5384EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start); 5385 5386int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg) 5387{ 5388 int err; 5389 5390 if (fmsg->putting_binary) 5391 return -EINVAL; 5392 5393 err = devlink_fmsg_nest_end(fmsg); 5394 if (err) 5395 return err; 5396 5397 err = devlink_fmsg_nest_end(fmsg); 5398 if (err) 5399 return err; 5400 5401 return 0; 5402} 5403EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end); 5404 5405int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg, 5406 const char *name) 5407{ 5408 int err; 5409 5410 err = devlink_fmsg_arr_pair_nest_start(fmsg, name); 5411 if (err) 5412 return err; 5413 5414 fmsg->putting_binary = true; 5415 return err; 5416} 5417EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start); 5418 5419int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg) 5420{ 5421 if (!fmsg->putting_binary) 5422 return -EINVAL; 5423 5424 fmsg->putting_binary = false; 5425 return devlink_fmsg_arr_pair_nest_end(fmsg); 5426} 5427EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end); 5428 5429static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg, 5430 const void *value, u16 value_len, 5431 u8 value_nla_type) 5432{ 5433 struct devlink_fmsg_item *item; 5434 5435 if (value_len > DEVLINK_FMSG_MAX_SIZE) 5436 return -EMSGSIZE; 5437 5438 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL); 5439 if (!item) 5440 return -ENOMEM; 5441 5442 item->nla_type = value_nla_type; 5443 item->len = value_len; 5444 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; 5445 memcpy(&item->value, value, item->len); 5446 list_add_tail(&item->list, &fmsg->item_list); 5447 5448 return 0; 5449} 5450 5451int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value) 5452{ 5453 if (fmsg->putting_binary) 5454 return -EINVAL; 5455 5456 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG); 5457} 5458EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put); 5459 5460int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value) 5461{ 5462 if (fmsg->putting_binary) 5463 return -EINVAL; 5464 5465 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8); 5466} 5467EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put); 5468 5469int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value) 5470{ 5471 if (fmsg->putting_binary) 5472 return -EINVAL; 5473 5474 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32); 5475} 5476EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put); 5477 5478int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value) 5479{ 5480 if (fmsg->putting_binary) 5481 return -EINVAL; 5482 5483 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64); 5484} 5485EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put); 5486 5487int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value) 5488{ 5489 if (fmsg->putting_binary) 5490 return -EINVAL; 5491 5492 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1, 5493 NLA_NUL_STRING); 5494} 5495EXPORT_SYMBOL_GPL(devlink_fmsg_string_put); 5496 5497int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value, 5498 u16 value_len) 5499{ 5500 if (!fmsg->putting_binary) 5501 return -EINVAL; 5502 5503 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY); 5504} 5505EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put); 5506 5507int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name, 5508 bool value) 5509{ 5510 int err; 5511 5512 err = devlink_fmsg_pair_nest_start(fmsg, name); 5513 if (err) 5514 return err; 5515 5516 err = devlink_fmsg_bool_put(fmsg, value); 5517 if (err) 5518 return err; 5519 5520 err = devlink_fmsg_pair_nest_end(fmsg); 5521 if (err) 5522 return err; 5523 5524 return 0; 5525} 5526EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put); 5527 5528int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name, 5529 u8 value) 5530{ 5531 int err; 5532 5533 err = devlink_fmsg_pair_nest_start(fmsg, name); 5534 if (err) 5535 return err; 5536 5537 err = devlink_fmsg_u8_put(fmsg, value); 5538 if (err) 5539 return err; 5540 5541 err = devlink_fmsg_pair_nest_end(fmsg); 5542 if (err) 5543 return err; 5544 5545 return 0; 5546} 5547EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put); 5548 5549int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name, 5550 u32 value) 5551{ 5552 int err; 5553 5554 err = devlink_fmsg_pair_nest_start(fmsg, name); 5555 if (err) 5556 return err; 5557 5558 err = devlink_fmsg_u32_put(fmsg, value); 5559 if (err) 5560 return err; 5561 5562 err = devlink_fmsg_pair_nest_end(fmsg); 5563 if (err) 5564 return err; 5565 5566 return 0; 5567} 5568EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put); 5569 5570int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name, 5571 u64 value) 5572{ 5573 int err; 5574 5575 err = devlink_fmsg_pair_nest_start(fmsg, name); 5576 if (err) 5577 return err; 5578 5579 err = devlink_fmsg_u64_put(fmsg, value); 5580 if (err) 5581 return err; 5582 5583 err = devlink_fmsg_pair_nest_end(fmsg); 5584 if (err) 5585 return err; 5586 5587 return 0; 5588} 5589EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put); 5590 5591int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name, 5592 const char *value) 5593{ 5594 int err; 5595 5596 err = devlink_fmsg_pair_nest_start(fmsg, name); 5597 if (err) 5598 return err; 5599 5600 err = devlink_fmsg_string_put(fmsg, value); 5601 if (err) 5602 return err; 5603 5604 err = devlink_fmsg_pair_nest_end(fmsg); 5605 if (err) 5606 return err; 5607 5608 return 0; 5609} 5610EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put); 5611 5612int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name, 5613 const void *value, u32 value_len) 5614{ 5615 u32 data_size; 5616 int end_err; 5617 u32 offset; 5618 int err; 5619 5620 err = devlink_fmsg_binary_pair_nest_start(fmsg, name); 5621 if (err) 5622 return err; 5623 5624 for (offset = 0; offset < value_len; offset += data_size) { 5625 data_size = value_len - offset; 5626 if (data_size > DEVLINK_FMSG_MAX_SIZE) 5627 data_size = DEVLINK_FMSG_MAX_SIZE; 5628 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size); 5629 if (err) 5630 break; 5631 /* Exit from loop with a break (instead of 5632 * return) to make sure putting_binary is turned off in 5633 * devlink_fmsg_binary_pair_nest_end 5634 */ 5635 } 5636 5637 end_err = devlink_fmsg_binary_pair_nest_end(fmsg); 5638 if (end_err) 5639 err = end_err; 5640 5641 return err; 5642} 5643EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put); 5644 5645static int 5646devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb) 5647{ 5648 switch (msg->nla_type) { 5649 case NLA_FLAG: 5650 case NLA_U8: 5651 case NLA_U32: 5652 case NLA_U64: 5653 case NLA_NUL_STRING: 5654 case NLA_BINARY: 5655 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, 5656 msg->nla_type); 5657 default: 5658 return -EINVAL; 5659 } 5660} 5661 5662static int 5663devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb) 5664{ 5665 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; 5666 u8 tmp; 5667 5668 switch (msg->nla_type) { 5669 case NLA_FLAG: 5670 /* Always provide flag data, regardless of its value */ 5671 tmp = *(bool *) msg->value; 5672 5673 return nla_put_u8(skb, attrtype, tmp); 5674 case NLA_U8: 5675 return nla_put_u8(skb, attrtype, *(u8 *) msg->value); 5676 case NLA_U32: 5677 return nla_put_u32(skb, attrtype, *(u32 *) msg->value); 5678 case NLA_U64: 5679 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value, 5680 DEVLINK_ATTR_PAD); 5681 case NLA_NUL_STRING: 5682 return nla_put_string(skb, attrtype, (char *) &msg->value); 5683 case NLA_BINARY: 5684 return nla_put(skb, attrtype, msg->len, (void *) &msg->value); 5685 default: 5686 return -EINVAL; 5687 } 5688} 5689 5690static int 5691devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb, 5692 int *start) 5693{ 5694 struct devlink_fmsg_item *item; 5695 struct nlattr *fmsg_nlattr; 5696 int i = 0; 5697 int err; 5698 5699 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG); 5700 if (!fmsg_nlattr) 5701 return -EMSGSIZE; 5702 5703 list_for_each_entry(item, &fmsg->item_list, list) { 5704 if (i < *start) { 5705 i++; 5706 continue; 5707 } 5708 5709 switch (item->attrtype) { 5710 case DEVLINK_ATTR_FMSG_OBJ_NEST_START: 5711 case DEVLINK_ATTR_FMSG_PAIR_NEST_START: 5712 case DEVLINK_ATTR_FMSG_ARR_NEST_START: 5713 case DEVLINK_ATTR_FMSG_NEST_END: 5714 err = nla_put_flag(skb, item->attrtype); 5715 break; 5716 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA: 5717 err = devlink_fmsg_item_fill_type(item, skb); 5718 if (err) 5719 break; 5720 err = devlink_fmsg_item_fill_data(item, skb); 5721 break; 5722 case DEVLINK_ATTR_FMSG_OBJ_NAME: 5723 err = nla_put_string(skb, item->attrtype, 5724 (char *) &item->value); 5725 break; 5726 default: 5727 err = -EINVAL; 5728 break; 5729 } 5730 if (!err) 5731 *start = ++i; 5732 else 5733 break; 5734 } 5735 5736 nla_nest_end(skb, fmsg_nlattr); 5737 return err; 5738} 5739 5740static int devlink_fmsg_snd(struct devlink_fmsg *fmsg, 5741 struct genl_info *info, 5742 enum devlink_command cmd, int flags) 5743{ 5744 struct nlmsghdr *nlh; 5745 struct sk_buff *skb; 5746 bool last = false; 5747 int index = 0; 5748 void *hdr; 5749 int err; 5750 5751 while (!last) { 5752 int tmp_index = index; 5753 5754 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 5755 if (!skb) 5756 return -ENOMEM; 5757 5758 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 5759 &devlink_nl_family, flags | NLM_F_MULTI, cmd); 5760 if (!hdr) { 5761 err = -EMSGSIZE; 5762 goto nla_put_failure; 5763 } 5764 5765 err = devlink_fmsg_prepare_skb(fmsg, skb, &index); 5766 if (!err) 5767 last = true; 5768 else if (err != -EMSGSIZE || tmp_index == index) 5769 goto nla_put_failure; 5770 5771 genlmsg_end(skb, hdr); 5772 err = genlmsg_reply(skb, info); 5773 if (err) 5774 return err; 5775 } 5776 5777 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 5778 if (!skb) 5779 return -ENOMEM; 5780 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 5781 NLMSG_DONE, 0, flags | NLM_F_MULTI); 5782 if (!nlh) { 5783 err = -EMSGSIZE; 5784 goto nla_put_failure; 5785 } 5786 5787 return genlmsg_reply(skb, info); 5788 5789nla_put_failure: 5790 nlmsg_free(skb); 5791 return err; 5792} 5793 5794static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb, 5795 struct netlink_callback *cb, 5796 enum devlink_command cmd) 5797{ 5798 int index = cb->args[0]; 5799 int tmp_index = index; 5800 void *hdr; 5801 int err; 5802 5803 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 5804 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd); 5805 if (!hdr) { 5806 err = -EMSGSIZE; 5807 goto nla_put_failure; 5808 } 5809 5810 err = devlink_fmsg_prepare_skb(fmsg, skb, &index); 5811 if ((err && err != -EMSGSIZE) || tmp_index == index) 5812 goto nla_put_failure; 5813 5814 cb->args[0] = index; 5815 genlmsg_end(skb, hdr); 5816 return skb->len; 5817 5818nla_put_failure: 5819 genlmsg_cancel(skb, hdr); 5820 return err; 5821} 5822 5823struct devlink_health_reporter { 5824 struct list_head list; 5825 void *priv; 5826 const struct devlink_health_reporter_ops *ops; 5827 struct devlink *devlink; 5828 struct devlink_port *devlink_port; 5829 struct devlink_fmsg *dump_fmsg; 5830 struct mutex dump_lock; /* lock parallel read/write from dump buffers */ 5831 u64 graceful_period; 5832 bool auto_recover; 5833 bool auto_dump; 5834 u8 health_state; 5835 u64 dump_ts; 5836 u64 dump_real_ts; 5837 u64 error_count; 5838 u64 recovery_count; 5839 u64 last_recovery_ts; 5840 refcount_t refcount; 5841}; 5842 5843void * 5844devlink_health_reporter_priv(struct devlink_health_reporter *reporter) 5845{ 5846 return reporter->priv; 5847} 5848EXPORT_SYMBOL_GPL(devlink_health_reporter_priv); 5849 5850static struct devlink_health_reporter * 5851__devlink_health_reporter_find_by_name(struct list_head *reporter_list, 5852 struct mutex *list_lock, 5853 const char *reporter_name) 5854{ 5855 struct devlink_health_reporter *reporter; 5856 5857 lockdep_assert_held(list_lock); 5858 list_for_each_entry(reporter, reporter_list, list) 5859 if (!strcmp(reporter->ops->name, reporter_name)) 5860 return reporter; 5861 return NULL; 5862} 5863 5864static struct devlink_health_reporter * 5865devlink_health_reporter_find_by_name(struct devlink *devlink, 5866 const char *reporter_name) 5867{ 5868 return __devlink_health_reporter_find_by_name(&devlink->reporter_list, 5869 &devlink->reporters_lock, 5870 reporter_name); 5871} 5872 5873static struct devlink_health_reporter * 5874devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port, 5875 const char *reporter_name) 5876{ 5877 return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list, 5878 &devlink_port->reporters_lock, 5879 reporter_name); 5880} 5881 5882static struct devlink_health_reporter * 5883__devlink_health_reporter_create(struct devlink *devlink, 5884 const struct devlink_health_reporter_ops *ops, 5885 u64 graceful_period, void *priv) 5886{ 5887 struct devlink_health_reporter *reporter; 5888 5889 if (WARN_ON(graceful_period && !ops->recover)) 5890 return ERR_PTR(-EINVAL); 5891 5892 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL); 5893 if (!reporter) 5894 return ERR_PTR(-ENOMEM); 5895 5896 reporter->priv = priv; 5897 reporter->ops = ops; 5898 reporter->devlink = devlink; 5899 reporter->graceful_period = graceful_period; 5900 reporter->auto_recover = !!ops->recover; 5901 reporter->auto_dump = !!ops->dump; 5902 mutex_init(&reporter->dump_lock); 5903 refcount_set(&reporter->refcount, 1); 5904 return reporter; 5905} 5906 5907/** 5908 * devlink_port_health_reporter_create - create devlink health reporter for 5909 * specified port instance 5910 * 5911 * @port: devlink_port which should contain the new reporter 5912 * @ops: ops 5913 * @graceful_period: to avoid recovery loops, in msecs 5914 * @priv: priv 5915 */ 5916struct devlink_health_reporter * 5917devlink_port_health_reporter_create(struct devlink_port *port, 5918 const struct devlink_health_reporter_ops *ops, 5919 u64 graceful_period, void *priv) 5920{ 5921 struct devlink_health_reporter *reporter; 5922 5923 mutex_lock(&port->reporters_lock); 5924 if (__devlink_health_reporter_find_by_name(&port->reporter_list, 5925 &port->reporters_lock, ops->name)) { 5926 reporter = ERR_PTR(-EEXIST); 5927 goto unlock; 5928 } 5929 5930 reporter = __devlink_health_reporter_create(port->devlink, ops, 5931 graceful_period, priv); 5932 if (IS_ERR(reporter)) 5933 goto unlock; 5934 5935 reporter->devlink_port = port; 5936 list_add_tail(&reporter->list, &port->reporter_list); 5937unlock: 5938 mutex_unlock(&port->reporters_lock); 5939 return reporter; 5940} 5941EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create); 5942 5943/** 5944 * devlink_health_reporter_create - create devlink health reporter 5945 * 5946 * @devlink: devlink 5947 * @ops: ops 5948 * @graceful_period: to avoid recovery loops, in msecs 5949 * @priv: priv 5950 */ 5951struct devlink_health_reporter * 5952devlink_health_reporter_create(struct devlink *devlink, 5953 const struct devlink_health_reporter_ops *ops, 5954 u64 graceful_period, void *priv) 5955{ 5956 struct devlink_health_reporter *reporter; 5957 5958 mutex_lock(&devlink->reporters_lock); 5959 if (devlink_health_reporter_find_by_name(devlink, ops->name)) { 5960 reporter = ERR_PTR(-EEXIST); 5961 goto unlock; 5962 } 5963 5964 reporter = __devlink_health_reporter_create(devlink, ops, 5965 graceful_period, priv); 5966 if (IS_ERR(reporter)) 5967 goto unlock; 5968 5969 list_add_tail(&reporter->list, &devlink->reporter_list); 5970unlock: 5971 mutex_unlock(&devlink->reporters_lock); 5972 return reporter; 5973} 5974EXPORT_SYMBOL_GPL(devlink_health_reporter_create); 5975 5976static void 5977devlink_health_reporter_free(struct devlink_health_reporter *reporter) 5978{ 5979 mutex_destroy(&reporter->dump_lock); 5980 if (reporter->dump_fmsg) 5981 devlink_fmsg_free(reporter->dump_fmsg); 5982 kfree(reporter); 5983} 5984 5985static void 5986devlink_health_reporter_put(struct devlink_health_reporter *reporter) 5987{ 5988 if (refcount_dec_and_test(&reporter->refcount)) 5989 devlink_health_reporter_free(reporter); 5990} 5991 5992static void 5993__devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) 5994{ 5995 list_del(&reporter->list); 5996 devlink_health_reporter_put(reporter); 5997} 5998 5999/** 6000 * devlink_health_reporter_destroy - destroy devlink health reporter 6001 * 6002 * @reporter: devlink health reporter to destroy 6003 */ 6004void 6005devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) 6006{ 6007 struct mutex *lock = &reporter->devlink->reporters_lock; 6008 6009 mutex_lock(lock); 6010 __devlink_health_reporter_destroy(reporter); 6011 mutex_unlock(lock); 6012} 6013EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy); 6014 6015/** 6016 * devlink_port_health_reporter_destroy - destroy devlink port health reporter 6017 * 6018 * @reporter: devlink health reporter to destroy 6019 */ 6020void 6021devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter) 6022{ 6023 struct mutex *lock = &reporter->devlink_port->reporters_lock; 6024 6025 mutex_lock(lock); 6026 __devlink_health_reporter_destroy(reporter); 6027 mutex_unlock(lock); 6028} 6029EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy); 6030 6031static int 6032devlink_nl_health_reporter_fill(struct sk_buff *msg, 6033 struct devlink *devlink, 6034 struct devlink_health_reporter *reporter, 6035 enum devlink_command cmd, u32 portid, 6036 u32 seq, int flags) 6037{ 6038 struct nlattr *reporter_attr; 6039 void *hdr; 6040 6041 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 6042 if (!hdr) 6043 return -EMSGSIZE; 6044 6045 if (devlink_nl_put_handle(msg, devlink)) 6046 goto genlmsg_cancel; 6047 6048 if (reporter->devlink_port) { 6049 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index)) 6050 goto genlmsg_cancel; 6051 } 6052 reporter_attr = nla_nest_start_noflag(msg, 6053 DEVLINK_ATTR_HEALTH_REPORTER); 6054 if (!reporter_attr) 6055 goto genlmsg_cancel; 6056 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME, 6057 reporter->ops->name)) 6058 goto reporter_nest_cancel; 6059 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE, 6060 reporter->health_state)) 6061 goto reporter_nest_cancel; 6062 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT, 6063 reporter->error_count, DEVLINK_ATTR_PAD)) 6064 goto reporter_nest_cancel; 6065 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT, 6066 reporter->recovery_count, DEVLINK_ATTR_PAD)) 6067 goto reporter_nest_cancel; 6068 if (reporter->ops->recover && 6069 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD, 6070 reporter->graceful_period, 6071 DEVLINK_ATTR_PAD)) 6072 goto reporter_nest_cancel; 6073 if (reporter->ops->recover && 6074 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER, 6075 reporter->auto_recover)) 6076 goto reporter_nest_cancel; 6077 if (reporter->dump_fmsg && 6078 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS, 6079 jiffies_to_msecs(reporter->dump_ts), 6080 DEVLINK_ATTR_PAD)) 6081 goto reporter_nest_cancel; 6082 if (reporter->dump_fmsg && 6083 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS, 6084 reporter->dump_real_ts, DEVLINK_ATTR_PAD)) 6085 goto reporter_nest_cancel; 6086 if (reporter->ops->dump && 6087 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, 6088 reporter->auto_dump)) 6089 goto reporter_nest_cancel; 6090 6091 nla_nest_end(msg, reporter_attr); 6092 genlmsg_end(msg, hdr); 6093 return 0; 6094 6095reporter_nest_cancel: 6096 nla_nest_end(msg, reporter_attr); 6097genlmsg_cancel: 6098 genlmsg_cancel(msg, hdr); 6099 return -EMSGSIZE; 6100} 6101 6102static void devlink_recover_notify(struct devlink_health_reporter *reporter, 6103 enum devlink_command cmd) 6104{ 6105 struct sk_buff *msg; 6106 int err; 6107 6108 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6109 6110 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6111 if (!msg) 6112 return; 6113 6114 err = devlink_nl_health_reporter_fill(msg, reporter->devlink, 6115 reporter, cmd, 0, 0, 0); 6116 if (err) { 6117 nlmsg_free(msg); 6118 return; 6119 } 6120 6121 genlmsg_multicast_netns(&devlink_nl_family, 6122 devlink_net(reporter->devlink), 6123 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 6124} 6125 6126void 6127devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter) 6128{ 6129 reporter->recovery_count++; 6130 reporter->last_recovery_ts = jiffies; 6131} 6132EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done); 6133 6134static int 6135devlink_health_reporter_recover(struct devlink_health_reporter *reporter, 6136 void *priv_ctx, struct netlink_ext_ack *extack) 6137{ 6138 int err; 6139 6140 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY) 6141 return 0; 6142 6143 if (!reporter->ops->recover) 6144 return -EOPNOTSUPP; 6145 6146 err = reporter->ops->recover(reporter, priv_ctx, extack); 6147 if (err) 6148 return err; 6149 6150 devlink_health_reporter_recovery_done(reporter); 6151 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY; 6152 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6153 6154 return 0; 6155} 6156 6157static void 6158devlink_health_dump_clear(struct devlink_health_reporter *reporter) 6159{ 6160 if (!reporter->dump_fmsg) 6161 return; 6162 devlink_fmsg_free(reporter->dump_fmsg); 6163 reporter->dump_fmsg = NULL; 6164} 6165 6166static int devlink_health_do_dump(struct devlink_health_reporter *reporter, 6167 void *priv_ctx, 6168 struct netlink_ext_ack *extack) 6169{ 6170 int err; 6171 6172 if (!reporter->ops->dump) 6173 return 0; 6174 6175 if (reporter->dump_fmsg) 6176 return 0; 6177 6178 reporter->dump_fmsg = devlink_fmsg_alloc(); 6179 if (!reporter->dump_fmsg) { 6180 err = -ENOMEM; 6181 return err; 6182 } 6183 6184 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg); 6185 if (err) 6186 goto dump_err; 6187 6188 err = reporter->ops->dump(reporter, reporter->dump_fmsg, 6189 priv_ctx, extack); 6190 if (err) 6191 goto dump_err; 6192 6193 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg); 6194 if (err) 6195 goto dump_err; 6196 6197 reporter->dump_ts = jiffies; 6198 reporter->dump_real_ts = ktime_get_real_ns(); 6199 6200 return 0; 6201 6202dump_err: 6203 devlink_health_dump_clear(reporter); 6204 return err; 6205} 6206 6207int devlink_health_report(struct devlink_health_reporter *reporter, 6208 const char *msg, void *priv_ctx) 6209{ 6210 enum devlink_health_reporter_state prev_health_state; 6211 struct devlink *devlink = reporter->devlink; 6212 unsigned long recover_ts_threshold; 6213 6214 /* write a log message of the current error */ 6215 WARN_ON(!msg); 6216 trace_devlink_health_report(devlink, reporter->ops->name, msg); 6217 reporter->error_count++; 6218 prev_health_state = reporter->health_state; 6219 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; 6220 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6221 6222 /* abort if the previous error wasn't recovered */ 6223 recover_ts_threshold = reporter->last_recovery_ts + 6224 msecs_to_jiffies(reporter->graceful_period); 6225 if (reporter->auto_recover && 6226 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY || 6227 (reporter->last_recovery_ts && reporter->recovery_count && 6228 time_is_after_jiffies(recover_ts_threshold)))) { 6229 trace_devlink_health_recover_aborted(devlink, 6230 reporter->ops->name, 6231 reporter->health_state, 6232 jiffies - 6233 reporter->last_recovery_ts); 6234 return -ECANCELED; 6235 } 6236 6237 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; 6238 6239 if (reporter->auto_dump) { 6240 mutex_lock(&reporter->dump_lock); 6241 /* store current dump of current error, for later analysis */ 6242 devlink_health_do_dump(reporter, priv_ctx, NULL); 6243 mutex_unlock(&reporter->dump_lock); 6244 } 6245 6246 if (reporter->auto_recover) 6247 return devlink_health_reporter_recover(reporter, 6248 priv_ctx, NULL); 6249 6250 return 0; 6251} 6252EXPORT_SYMBOL_GPL(devlink_health_report); 6253 6254static struct devlink_health_reporter * 6255devlink_health_reporter_get_from_attrs(struct devlink *devlink, 6256 struct nlattr **attrs) 6257{ 6258 struct devlink_health_reporter *reporter; 6259 struct devlink_port *devlink_port; 6260 char *reporter_name; 6261 6262 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]) 6263 return NULL; 6264 6265 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]); 6266 devlink_port = devlink_port_get_from_attrs(devlink, attrs); 6267 if (IS_ERR(devlink_port)) { 6268 mutex_lock(&devlink->reporters_lock); 6269 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name); 6270 if (reporter) 6271 refcount_inc(&reporter->refcount); 6272 mutex_unlock(&devlink->reporters_lock); 6273 } else { 6274 mutex_lock(&devlink_port->reporters_lock); 6275 reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name); 6276 if (reporter) 6277 refcount_inc(&reporter->refcount); 6278 mutex_unlock(&devlink_port->reporters_lock); 6279 } 6280 6281 return reporter; 6282} 6283 6284static struct devlink_health_reporter * 6285devlink_health_reporter_get_from_info(struct devlink *devlink, 6286 struct genl_info *info) 6287{ 6288 return devlink_health_reporter_get_from_attrs(devlink, info->attrs); 6289} 6290 6291static struct devlink_health_reporter * 6292devlink_health_reporter_get_from_cb(struct netlink_callback *cb) 6293{ 6294 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 6295 struct devlink_health_reporter *reporter; 6296 struct nlattr **attrs = info->attrs; 6297 struct devlink *devlink; 6298 6299 mutex_lock(&devlink_mutex); 6300 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); 6301 if (IS_ERR(devlink)) 6302 goto unlock; 6303 6304 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs); 6305 mutex_unlock(&devlink_mutex); 6306 return reporter; 6307unlock: 6308 mutex_unlock(&devlink_mutex); 6309 return NULL; 6310} 6311 6312void 6313devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, 6314 enum devlink_health_reporter_state state) 6315{ 6316 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY && 6317 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR)) 6318 return; 6319 6320 if (reporter->health_state == state) 6321 return; 6322 6323 reporter->health_state = state; 6324 trace_devlink_health_reporter_state_update(reporter->devlink, 6325 reporter->ops->name, state); 6326 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6327} 6328EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update); 6329 6330static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, 6331 struct genl_info *info) 6332{ 6333 struct devlink *devlink = info->user_ptr[0]; 6334 struct devlink_health_reporter *reporter; 6335 struct sk_buff *msg; 6336 int err; 6337 6338 reporter = devlink_health_reporter_get_from_info(devlink, info); 6339 if (!reporter) 6340 return -EINVAL; 6341 6342 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6343 if (!msg) { 6344 err = -ENOMEM; 6345 goto out; 6346 } 6347 6348 err = devlink_nl_health_reporter_fill(msg, devlink, reporter, 6349 DEVLINK_CMD_HEALTH_REPORTER_GET, 6350 info->snd_portid, info->snd_seq, 6351 0); 6352 if (err) { 6353 nlmsg_free(msg); 6354 goto out; 6355 } 6356 6357 err = genlmsg_reply(msg, info); 6358out: 6359 devlink_health_reporter_put(reporter); 6360 return err; 6361} 6362 6363static int 6364devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg, 6365 struct netlink_callback *cb) 6366{ 6367 struct devlink_health_reporter *reporter; 6368 struct devlink_port *port; 6369 struct devlink *devlink; 6370 int start = cb->args[0]; 6371 int idx = 0; 6372 int err; 6373 6374 mutex_lock(&devlink_mutex); 6375 list_for_each_entry(devlink, &devlink_list, list) { 6376 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 6377 continue; 6378 mutex_lock(&devlink->reporters_lock); 6379 list_for_each_entry(reporter, &devlink->reporter_list, 6380 list) { 6381 if (idx < start) { 6382 idx++; 6383 continue; 6384 } 6385 err = devlink_nl_health_reporter_fill(msg, devlink, 6386 reporter, 6387 DEVLINK_CMD_HEALTH_REPORTER_GET, 6388 NETLINK_CB(cb->skb).portid, 6389 cb->nlh->nlmsg_seq, 6390 NLM_F_MULTI); 6391 if (err) { 6392 mutex_unlock(&devlink->reporters_lock); 6393 goto out; 6394 } 6395 idx++; 6396 } 6397 mutex_unlock(&devlink->reporters_lock); 6398 } 6399 6400 list_for_each_entry(devlink, &devlink_list, list) { 6401 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 6402 continue; 6403 mutex_lock(&devlink->lock); 6404 list_for_each_entry(port, &devlink->port_list, list) { 6405 mutex_lock(&port->reporters_lock); 6406 list_for_each_entry(reporter, &port->reporter_list, list) { 6407 if (idx < start) { 6408 idx++; 6409 continue; 6410 } 6411 err = devlink_nl_health_reporter_fill(msg, devlink, reporter, 6412 DEVLINK_CMD_HEALTH_REPORTER_GET, 6413 NETLINK_CB(cb->skb).portid, 6414 cb->nlh->nlmsg_seq, 6415 NLM_F_MULTI); 6416 if (err) { 6417 mutex_unlock(&port->reporters_lock); 6418 mutex_unlock(&devlink->lock); 6419 goto out; 6420 } 6421 idx++; 6422 } 6423 mutex_unlock(&port->reporters_lock); 6424 } 6425 mutex_unlock(&devlink->lock); 6426 } 6427out: 6428 mutex_unlock(&devlink_mutex); 6429 6430 cb->args[0] = idx; 6431 return msg->len; 6432} 6433 6434static int 6435devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, 6436 struct genl_info *info) 6437{ 6438 struct devlink *devlink = info->user_ptr[0]; 6439 struct devlink_health_reporter *reporter; 6440 int err; 6441 6442 reporter = devlink_health_reporter_get_from_info(devlink, info); 6443 if (!reporter) 6444 return -EINVAL; 6445 6446 if (!reporter->ops->recover && 6447 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] || 6448 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) { 6449 err = -EOPNOTSUPP; 6450 goto out; 6451 } 6452 if (!reporter->ops->dump && 6453 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) { 6454 err = -EOPNOTSUPP; 6455 goto out; 6456 } 6457 6458 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]) 6459 reporter->graceful_period = 6460 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]); 6461 6462 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]) 6463 reporter->auto_recover = 6464 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]); 6465 6466 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) 6467 reporter->auto_dump = 6468 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]); 6469 6470 devlink_health_reporter_put(reporter); 6471 return 0; 6472out: 6473 devlink_health_reporter_put(reporter); 6474 return err; 6475} 6476 6477static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb, 6478 struct genl_info *info) 6479{ 6480 struct devlink *devlink = info->user_ptr[0]; 6481 struct devlink_health_reporter *reporter; 6482 int err; 6483 6484 reporter = devlink_health_reporter_get_from_info(devlink, info); 6485 if (!reporter) 6486 return -EINVAL; 6487 6488 err = devlink_health_reporter_recover(reporter, NULL, info->extack); 6489 6490 devlink_health_reporter_put(reporter); 6491 return err; 6492} 6493 6494static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, 6495 struct genl_info *info) 6496{ 6497 struct devlink *devlink = info->user_ptr[0]; 6498 struct devlink_health_reporter *reporter; 6499 struct devlink_fmsg *fmsg; 6500 int err; 6501 6502 reporter = devlink_health_reporter_get_from_info(devlink, info); 6503 if (!reporter) 6504 return -EINVAL; 6505 6506 if (!reporter->ops->diagnose) { 6507 devlink_health_reporter_put(reporter); 6508 return -EOPNOTSUPP; 6509 } 6510 6511 fmsg = devlink_fmsg_alloc(); 6512 if (!fmsg) { 6513 devlink_health_reporter_put(reporter); 6514 return -ENOMEM; 6515 } 6516 6517 err = devlink_fmsg_obj_nest_start(fmsg); 6518 if (err) 6519 goto out; 6520 6521 err = reporter->ops->diagnose(reporter, fmsg, info->extack); 6522 if (err) 6523 goto out; 6524 6525 err = devlink_fmsg_obj_nest_end(fmsg); 6526 if (err) 6527 goto out; 6528 6529 err = devlink_fmsg_snd(fmsg, info, 6530 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0); 6531 6532out: 6533 devlink_fmsg_free(fmsg); 6534 devlink_health_reporter_put(reporter); 6535 return err; 6536} 6537 6538static int 6539devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb, 6540 struct netlink_callback *cb) 6541{ 6542 struct devlink_health_reporter *reporter; 6543 u64 start = cb->args[0]; 6544 int err; 6545 6546 reporter = devlink_health_reporter_get_from_cb(cb); 6547 if (!reporter) 6548 return -EINVAL; 6549 6550 if (!reporter->ops->dump) { 6551 err = -EOPNOTSUPP; 6552 goto out; 6553 } 6554 mutex_lock(&reporter->dump_lock); 6555 if (!start) { 6556 err = devlink_health_do_dump(reporter, NULL, cb->extack); 6557 if (err) 6558 goto unlock; 6559 cb->args[1] = reporter->dump_ts; 6560 } 6561 if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) { 6562 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry"); 6563 err = -EAGAIN; 6564 goto unlock; 6565 } 6566 6567 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb, 6568 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET); 6569unlock: 6570 mutex_unlock(&reporter->dump_lock); 6571out: 6572 devlink_health_reporter_put(reporter); 6573 return err; 6574} 6575 6576static int 6577devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb, 6578 struct genl_info *info) 6579{ 6580 struct devlink *devlink = info->user_ptr[0]; 6581 struct devlink_health_reporter *reporter; 6582 6583 reporter = devlink_health_reporter_get_from_info(devlink, info); 6584 if (!reporter) 6585 return -EINVAL; 6586 6587 if (!reporter->ops->dump) { 6588 devlink_health_reporter_put(reporter); 6589 return -EOPNOTSUPP; 6590 } 6591 6592 mutex_lock(&reporter->dump_lock); 6593 devlink_health_dump_clear(reporter); 6594 mutex_unlock(&reporter->dump_lock); 6595 devlink_health_reporter_put(reporter); 6596 return 0; 6597} 6598 6599static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb, 6600 struct genl_info *info) 6601{ 6602 struct devlink *devlink = info->user_ptr[0]; 6603 struct devlink_health_reporter *reporter; 6604 int err; 6605 6606 reporter = devlink_health_reporter_get_from_info(devlink, info); 6607 if (!reporter) 6608 return -EINVAL; 6609 6610 if (!reporter->ops->test) { 6611 devlink_health_reporter_put(reporter); 6612 return -EOPNOTSUPP; 6613 } 6614 6615 err = reporter->ops->test(reporter, info->extack); 6616 6617 devlink_health_reporter_put(reporter); 6618 return err; 6619} 6620 6621struct devlink_stats { 6622 u64 rx_bytes; 6623 u64 rx_packets; 6624 struct u64_stats_sync syncp; 6625}; 6626 6627/** 6628 * struct devlink_trap_policer_item - Packet trap policer attributes. 6629 * @policer: Immutable packet trap policer attributes. 6630 * @rate: Rate in packets / sec. 6631 * @burst: Burst size in packets. 6632 * @list: trap_policer_list member. 6633 * 6634 * Describes packet trap policer attributes. Created by devlink during trap 6635 * policer registration. 6636 */ 6637struct devlink_trap_policer_item { 6638 const struct devlink_trap_policer *policer; 6639 u64 rate; 6640 u64 burst; 6641 struct list_head list; 6642}; 6643 6644/** 6645 * struct devlink_trap_group_item - Packet trap group attributes. 6646 * @group: Immutable packet trap group attributes. 6647 * @policer_item: Associated policer item. Can be NULL. 6648 * @list: trap_group_list member. 6649 * @stats: Trap group statistics. 6650 * 6651 * Describes packet trap group attributes. Created by devlink during trap 6652 * group registration. 6653 */ 6654struct devlink_trap_group_item { 6655 const struct devlink_trap_group *group; 6656 struct devlink_trap_policer_item *policer_item; 6657 struct list_head list; 6658 struct devlink_stats __percpu *stats; 6659}; 6660 6661/** 6662 * struct devlink_trap_item - Packet trap attributes. 6663 * @trap: Immutable packet trap attributes. 6664 * @group_item: Associated group item. 6665 * @list: trap_list member. 6666 * @action: Trap action. 6667 * @stats: Trap statistics. 6668 * @priv: Driver private information. 6669 * 6670 * Describes both mutable and immutable packet trap attributes. Created by 6671 * devlink during trap registration and used for all trap related operations. 6672 */ 6673struct devlink_trap_item { 6674 const struct devlink_trap *trap; 6675 struct devlink_trap_group_item *group_item; 6676 struct list_head list; 6677 enum devlink_trap_action action; 6678 struct devlink_stats __percpu *stats; 6679 void *priv; 6680}; 6681 6682static struct devlink_trap_policer_item * 6683devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id) 6684{ 6685 struct devlink_trap_policer_item *policer_item; 6686 6687 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) { 6688 if (policer_item->policer->id == id) 6689 return policer_item; 6690 } 6691 6692 return NULL; 6693} 6694 6695static struct devlink_trap_item * 6696devlink_trap_item_lookup(struct devlink *devlink, const char *name) 6697{ 6698 struct devlink_trap_item *trap_item; 6699 6700 list_for_each_entry(trap_item, &devlink->trap_list, list) { 6701 if (!strcmp(trap_item->trap->name, name)) 6702 return trap_item; 6703 } 6704 6705 return NULL; 6706} 6707 6708static struct devlink_trap_item * 6709devlink_trap_item_get_from_info(struct devlink *devlink, 6710 struct genl_info *info) 6711{ 6712 struct nlattr *attr; 6713 6714 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME]) 6715 return NULL; 6716 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME]; 6717 6718 return devlink_trap_item_lookup(devlink, nla_data(attr)); 6719} 6720 6721static int 6722devlink_trap_action_get_from_info(struct genl_info *info, 6723 enum devlink_trap_action *p_trap_action) 6724{ 6725 u8 val; 6726 6727 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]); 6728 switch (val) { 6729 case DEVLINK_TRAP_ACTION_DROP: 6730 case DEVLINK_TRAP_ACTION_TRAP: 6731 case DEVLINK_TRAP_ACTION_MIRROR: 6732 *p_trap_action = val; 6733 break; 6734 default: 6735 return -EINVAL; 6736 } 6737 6738 return 0; 6739} 6740 6741static int devlink_trap_metadata_put(struct sk_buff *msg, 6742 const struct devlink_trap *trap) 6743{ 6744 struct nlattr *attr; 6745 6746 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA); 6747 if (!attr) 6748 return -EMSGSIZE; 6749 6750 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) && 6751 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT)) 6752 goto nla_put_failure; 6753 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) && 6754 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE)) 6755 goto nla_put_failure; 6756 6757 nla_nest_end(msg, attr); 6758 6759 return 0; 6760 6761nla_put_failure: 6762 nla_nest_cancel(msg, attr); 6763 return -EMSGSIZE; 6764} 6765 6766static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats, 6767 struct devlink_stats *stats) 6768{ 6769 int i; 6770 6771 memset(stats, 0, sizeof(*stats)); 6772 for_each_possible_cpu(i) { 6773 struct devlink_stats *cpu_stats; 6774 u64 rx_packets, rx_bytes; 6775 unsigned int start; 6776 6777 cpu_stats = per_cpu_ptr(trap_stats, i); 6778 do { 6779 start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); 6780 rx_packets = cpu_stats->rx_packets; 6781 rx_bytes = cpu_stats->rx_bytes; 6782 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); 6783 6784 stats->rx_packets += rx_packets; 6785 stats->rx_bytes += rx_bytes; 6786 } 6787} 6788 6789static int devlink_trap_stats_put(struct sk_buff *msg, 6790 struct devlink_stats __percpu *trap_stats) 6791{ 6792 struct devlink_stats stats; 6793 struct nlattr *attr; 6794 6795 devlink_trap_stats_read(trap_stats, &stats); 6796 6797 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); 6798 if (!attr) 6799 return -EMSGSIZE; 6800 6801 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS, 6802 stats.rx_packets, DEVLINK_ATTR_PAD)) 6803 goto nla_put_failure; 6804 6805 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES, 6806 stats.rx_bytes, DEVLINK_ATTR_PAD)) 6807 goto nla_put_failure; 6808 6809 nla_nest_end(msg, attr); 6810 6811 return 0; 6812 6813nla_put_failure: 6814 nla_nest_cancel(msg, attr); 6815 return -EMSGSIZE; 6816} 6817 6818static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink, 6819 const struct devlink_trap_item *trap_item, 6820 enum devlink_command cmd, u32 portid, u32 seq, 6821 int flags) 6822{ 6823 struct devlink_trap_group_item *group_item = trap_item->group_item; 6824 void *hdr; 6825 int err; 6826 6827 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 6828 if (!hdr) 6829 return -EMSGSIZE; 6830 6831 if (devlink_nl_put_handle(msg, devlink)) 6832 goto nla_put_failure; 6833 6834 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, 6835 group_item->group->name)) 6836 goto nla_put_failure; 6837 6838 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name)) 6839 goto nla_put_failure; 6840 6841 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type)) 6842 goto nla_put_failure; 6843 6844 if (trap_item->trap->generic && 6845 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) 6846 goto nla_put_failure; 6847 6848 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action)) 6849 goto nla_put_failure; 6850 6851 err = devlink_trap_metadata_put(msg, trap_item->trap); 6852 if (err) 6853 goto nla_put_failure; 6854 6855 err = devlink_trap_stats_put(msg, trap_item->stats); 6856 if (err) 6857 goto nla_put_failure; 6858 6859 genlmsg_end(msg, hdr); 6860 6861 return 0; 6862 6863nla_put_failure: 6864 genlmsg_cancel(msg, hdr); 6865 return -EMSGSIZE; 6866} 6867 6868static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb, 6869 struct genl_info *info) 6870{ 6871 struct netlink_ext_ack *extack = info->extack; 6872 struct devlink *devlink = info->user_ptr[0]; 6873 struct devlink_trap_item *trap_item; 6874 struct sk_buff *msg; 6875 int err; 6876 6877 if (list_empty(&devlink->trap_list)) 6878 return -EOPNOTSUPP; 6879 6880 trap_item = devlink_trap_item_get_from_info(devlink, info); 6881 if (!trap_item) { 6882 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); 6883 return -ENOENT; 6884 } 6885 6886 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6887 if (!msg) 6888 return -ENOMEM; 6889 6890 err = devlink_nl_trap_fill(msg, devlink, trap_item, 6891 DEVLINK_CMD_TRAP_NEW, info->snd_portid, 6892 info->snd_seq, 0); 6893 if (err) 6894 goto err_trap_fill; 6895 6896 return genlmsg_reply(msg, info); 6897 6898err_trap_fill: 6899 nlmsg_free(msg); 6900 return err; 6901} 6902 6903static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg, 6904 struct netlink_callback *cb) 6905{ 6906 struct devlink_trap_item *trap_item; 6907 struct devlink *devlink; 6908 int start = cb->args[0]; 6909 int idx = 0; 6910 int err; 6911 6912 mutex_lock(&devlink_mutex); 6913 list_for_each_entry(devlink, &devlink_list, list) { 6914 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 6915 continue; 6916 mutex_lock(&devlink->lock); 6917 list_for_each_entry(trap_item, &devlink->trap_list, list) { 6918 if (idx < start) { 6919 idx++; 6920 continue; 6921 } 6922 err = devlink_nl_trap_fill(msg, devlink, trap_item, 6923 DEVLINK_CMD_TRAP_NEW, 6924 NETLINK_CB(cb->skb).portid, 6925 cb->nlh->nlmsg_seq, 6926 NLM_F_MULTI); 6927 if (err) { 6928 mutex_unlock(&devlink->lock); 6929 goto out; 6930 } 6931 idx++; 6932 } 6933 mutex_unlock(&devlink->lock); 6934 } 6935out: 6936 mutex_unlock(&devlink_mutex); 6937 6938 cb->args[0] = idx; 6939 return msg->len; 6940} 6941 6942static int __devlink_trap_action_set(struct devlink *devlink, 6943 struct devlink_trap_item *trap_item, 6944 enum devlink_trap_action trap_action, 6945 struct netlink_ext_ack *extack) 6946{ 6947 int err; 6948 6949 if (trap_item->action != trap_action && 6950 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) { 6951 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping"); 6952 return 0; 6953 } 6954 6955 err = devlink->ops->trap_action_set(devlink, trap_item->trap, 6956 trap_action, extack); 6957 if (err) 6958 return err; 6959 6960 trap_item->action = trap_action; 6961 6962 return 0; 6963} 6964 6965static int devlink_trap_action_set(struct devlink *devlink, 6966 struct devlink_trap_item *trap_item, 6967 struct genl_info *info) 6968{ 6969 enum devlink_trap_action trap_action; 6970 int err; 6971 6972 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) 6973 return 0; 6974 6975 err = devlink_trap_action_get_from_info(info, &trap_action); 6976 if (err) { 6977 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); 6978 return -EINVAL; 6979 } 6980 6981 return __devlink_trap_action_set(devlink, trap_item, trap_action, 6982 info->extack); 6983} 6984 6985static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb, 6986 struct genl_info *info) 6987{ 6988 struct netlink_ext_ack *extack = info->extack; 6989 struct devlink *devlink = info->user_ptr[0]; 6990 struct devlink_trap_item *trap_item; 6991 int err; 6992 6993 if (list_empty(&devlink->trap_list)) 6994 return -EOPNOTSUPP; 6995 6996 trap_item = devlink_trap_item_get_from_info(devlink, info); 6997 if (!trap_item) { 6998 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); 6999 return -ENOENT; 7000 } 7001 7002 err = devlink_trap_action_set(devlink, trap_item, info); 7003 if (err) 7004 return err; 7005 7006 return 0; 7007} 7008 7009static struct devlink_trap_group_item * 7010devlink_trap_group_item_lookup(struct devlink *devlink, const char *name) 7011{ 7012 struct devlink_trap_group_item *group_item; 7013 7014 list_for_each_entry(group_item, &devlink->trap_group_list, list) { 7015 if (!strcmp(group_item->group->name, name)) 7016 return group_item; 7017 } 7018 7019 return NULL; 7020} 7021 7022static struct devlink_trap_group_item * 7023devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id) 7024{ 7025 struct devlink_trap_group_item *group_item; 7026 7027 list_for_each_entry(group_item, &devlink->trap_group_list, list) { 7028 if (group_item->group->id == id) 7029 return group_item; 7030 } 7031 7032 return NULL; 7033} 7034 7035static struct devlink_trap_group_item * 7036devlink_trap_group_item_get_from_info(struct devlink *devlink, 7037 struct genl_info *info) 7038{ 7039 char *name; 7040 7041 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]) 7042 return NULL; 7043 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]); 7044 7045 return devlink_trap_group_item_lookup(devlink, name); 7046} 7047 7048static int 7049devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink, 7050 const struct devlink_trap_group_item *group_item, 7051 enum devlink_command cmd, u32 portid, u32 seq, 7052 int flags) 7053{ 7054 void *hdr; 7055 int err; 7056 7057 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 7058 if (!hdr) 7059 return -EMSGSIZE; 7060 7061 if (devlink_nl_put_handle(msg, devlink)) 7062 goto nla_put_failure; 7063 7064 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, 7065 group_item->group->name)) 7066 goto nla_put_failure; 7067 7068 if (group_item->group->generic && 7069 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) 7070 goto nla_put_failure; 7071 7072 if (group_item->policer_item && 7073 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, 7074 group_item->policer_item->policer->id)) 7075 goto nla_put_failure; 7076 7077 err = devlink_trap_stats_put(msg, group_item->stats); 7078 if (err) 7079 goto nla_put_failure; 7080 7081 genlmsg_end(msg, hdr); 7082 7083 return 0; 7084 7085nla_put_failure: 7086 genlmsg_cancel(msg, hdr); 7087 return -EMSGSIZE; 7088} 7089 7090static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb, 7091 struct genl_info *info) 7092{ 7093 struct netlink_ext_ack *extack = info->extack; 7094 struct devlink *devlink = info->user_ptr[0]; 7095 struct devlink_trap_group_item *group_item; 7096 struct sk_buff *msg; 7097 int err; 7098 7099 if (list_empty(&devlink->trap_group_list)) 7100 return -EOPNOTSUPP; 7101 7102 group_item = devlink_trap_group_item_get_from_info(devlink, info); 7103 if (!group_item) { 7104 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); 7105 return -ENOENT; 7106 } 7107 7108 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7109 if (!msg) 7110 return -ENOMEM; 7111 7112 err = devlink_nl_trap_group_fill(msg, devlink, group_item, 7113 DEVLINK_CMD_TRAP_GROUP_NEW, 7114 info->snd_portid, info->snd_seq, 0); 7115 if (err) 7116 goto err_trap_group_fill; 7117 7118 return genlmsg_reply(msg, info); 7119 7120err_trap_group_fill: 7121 nlmsg_free(msg); 7122 return err; 7123} 7124 7125static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg, 7126 struct netlink_callback *cb) 7127{ 7128 enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW; 7129 struct devlink_trap_group_item *group_item; 7130 u32 portid = NETLINK_CB(cb->skb).portid; 7131 struct devlink *devlink; 7132 int start = cb->args[0]; 7133 int idx = 0; 7134 int err; 7135 7136 mutex_lock(&devlink_mutex); 7137 list_for_each_entry(devlink, &devlink_list, list) { 7138 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 7139 continue; 7140 mutex_lock(&devlink->lock); 7141 list_for_each_entry(group_item, &devlink->trap_group_list, 7142 list) { 7143 if (idx < start) { 7144 idx++; 7145 continue; 7146 } 7147 err = devlink_nl_trap_group_fill(msg, devlink, 7148 group_item, cmd, 7149 portid, 7150 cb->nlh->nlmsg_seq, 7151 NLM_F_MULTI); 7152 if (err) { 7153 mutex_unlock(&devlink->lock); 7154 goto out; 7155 } 7156 idx++; 7157 } 7158 mutex_unlock(&devlink->lock); 7159 } 7160out: 7161 mutex_unlock(&devlink_mutex); 7162 7163 cb->args[0] = idx; 7164 return msg->len; 7165} 7166 7167static int 7168__devlink_trap_group_action_set(struct devlink *devlink, 7169 struct devlink_trap_group_item *group_item, 7170 enum devlink_trap_action trap_action, 7171 struct netlink_ext_ack *extack) 7172{ 7173 const char *group_name = group_item->group->name; 7174 struct devlink_trap_item *trap_item; 7175 int err; 7176 7177 if (devlink->ops->trap_group_action_set) { 7178 err = devlink->ops->trap_group_action_set(devlink, group_item->group, 7179 trap_action, extack); 7180 if (err) 7181 return err; 7182 7183 list_for_each_entry(trap_item, &devlink->trap_list, list) { 7184 if (strcmp(trap_item->group_item->group->name, group_name)) 7185 continue; 7186 if (trap_item->action != trap_action && 7187 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) 7188 continue; 7189 trap_item->action = trap_action; 7190 } 7191 7192 return 0; 7193 } 7194 7195 list_for_each_entry(trap_item, &devlink->trap_list, list) { 7196 if (strcmp(trap_item->group_item->group->name, group_name)) 7197 continue; 7198 err = __devlink_trap_action_set(devlink, trap_item, 7199 trap_action, extack); 7200 if (err) 7201 return err; 7202 } 7203 7204 return 0; 7205} 7206 7207static int 7208devlink_trap_group_action_set(struct devlink *devlink, 7209 struct devlink_trap_group_item *group_item, 7210 struct genl_info *info, bool *p_modified) 7211{ 7212 enum devlink_trap_action trap_action; 7213 int err; 7214 7215 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) 7216 return 0; 7217 7218 err = devlink_trap_action_get_from_info(info, &trap_action); 7219 if (err) { 7220 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); 7221 return -EINVAL; 7222 } 7223 7224 err = __devlink_trap_group_action_set(devlink, group_item, trap_action, 7225 info->extack); 7226 if (err) 7227 return err; 7228 7229 *p_modified = true; 7230 7231 return 0; 7232} 7233 7234static int devlink_trap_group_set(struct devlink *devlink, 7235 struct devlink_trap_group_item *group_item, 7236 struct genl_info *info) 7237{ 7238 struct devlink_trap_policer_item *policer_item; 7239 struct netlink_ext_ack *extack = info->extack; 7240 const struct devlink_trap_policer *policer; 7241 struct nlattr **attrs = info->attrs; 7242 int err; 7243 7244 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) 7245 return 0; 7246 7247 if (!devlink->ops->trap_group_set) 7248 return -EOPNOTSUPP; 7249 7250 policer_item = group_item->policer_item; 7251 if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) { 7252 u32 policer_id; 7253 7254 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); 7255 policer_item = devlink_trap_policer_item_lookup(devlink, 7256 policer_id); 7257 if (policer_id && !policer_item) { 7258 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); 7259 return -ENOENT; 7260 } 7261 } 7262 policer = policer_item ? policer_item->policer : NULL; 7263 7264 err = devlink->ops->trap_group_set(devlink, group_item->group, policer, 7265 extack); 7266 if (err) 7267 return err; 7268 7269 group_item->policer_item = policer_item; 7270 7271 return 0; 7272} 7273 7274static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb, 7275 struct genl_info *info) 7276{ 7277 struct netlink_ext_ack *extack = info->extack; 7278 struct devlink *devlink = info->user_ptr[0]; 7279 struct devlink_trap_group_item *group_item; 7280 bool modified = false; 7281 int err; 7282 7283 if (list_empty(&devlink->trap_group_list)) 7284 return -EOPNOTSUPP; 7285 7286 group_item = devlink_trap_group_item_get_from_info(devlink, info); 7287 if (!group_item) { 7288 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); 7289 return -ENOENT; 7290 } 7291 7292 err = devlink_trap_group_action_set(devlink, group_item, info, 7293 &modified); 7294 if (err) 7295 return err; 7296 7297 err = devlink_trap_group_set(devlink, group_item, info); 7298 if (err) 7299 goto err_trap_group_set; 7300 7301 return 0; 7302 7303err_trap_group_set: 7304 if (modified) 7305 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already"); 7306 return err; 7307} 7308 7309static struct devlink_trap_policer_item * 7310devlink_trap_policer_item_get_from_info(struct devlink *devlink, 7311 struct genl_info *info) 7312{ 7313 u32 id; 7314 7315 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) 7316 return NULL; 7317 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); 7318 7319 return devlink_trap_policer_item_lookup(devlink, id); 7320} 7321 7322static int 7323devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink, 7324 const struct devlink_trap_policer *policer) 7325{ 7326 struct nlattr *attr; 7327 u64 drops; 7328 int err; 7329 7330 if (!devlink->ops->trap_policer_counter_get) 7331 return 0; 7332 7333 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops); 7334 if (err) 7335 return err; 7336 7337 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); 7338 if (!attr) 7339 return -EMSGSIZE; 7340 7341 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops, 7342 DEVLINK_ATTR_PAD)) 7343 goto nla_put_failure; 7344 7345 nla_nest_end(msg, attr); 7346 7347 return 0; 7348 7349nla_put_failure: 7350 nla_nest_cancel(msg, attr); 7351 return -EMSGSIZE; 7352} 7353 7354static int 7355devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink, 7356 const struct devlink_trap_policer_item *policer_item, 7357 enum devlink_command cmd, u32 portid, u32 seq, 7358 int flags) 7359{ 7360 void *hdr; 7361 int err; 7362 7363 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 7364 if (!hdr) 7365 return -EMSGSIZE; 7366 7367 if (devlink_nl_put_handle(msg, devlink)) 7368 goto nla_put_failure; 7369 7370 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, 7371 policer_item->policer->id)) 7372 goto nla_put_failure; 7373 7374 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE, 7375 policer_item->rate, DEVLINK_ATTR_PAD)) 7376 goto nla_put_failure; 7377 7378 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST, 7379 policer_item->burst, DEVLINK_ATTR_PAD)) 7380 goto nla_put_failure; 7381 7382 err = devlink_trap_policer_stats_put(msg, devlink, 7383 policer_item->policer); 7384 if (err) 7385 goto nla_put_failure; 7386 7387 genlmsg_end(msg, hdr); 7388 7389 return 0; 7390 7391nla_put_failure: 7392 genlmsg_cancel(msg, hdr); 7393 return -EMSGSIZE; 7394} 7395 7396static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb, 7397 struct genl_info *info) 7398{ 7399 struct devlink_trap_policer_item *policer_item; 7400 struct netlink_ext_ack *extack = info->extack; 7401 struct devlink *devlink = info->user_ptr[0]; 7402 struct sk_buff *msg; 7403 int err; 7404 7405 if (list_empty(&devlink->trap_policer_list)) 7406 return -EOPNOTSUPP; 7407 7408 policer_item = devlink_trap_policer_item_get_from_info(devlink, info); 7409 if (!policer_item) { 7410 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); 7411 return -ENOENT; 7412 } 7413 7414 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7415 if (!msg) 7416 return -ENOMEM; 7417 7418 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, 7419 DEVLINK_CMD_TRAP_POLICER_NEW, 7420 info->snd_portid, info->snd_seq, 0); 7421 if (err) 7422 goto err_trap_policer_fill; 7423 7424 return genlmsg_reply(msg, info); 7425 7426err_trap_policer_fill: 7427 nlmsg_free(msg); 7428 return err; 7429} 7430 7431static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg, 7432 struct netlink_callback *cb) 7433{ 7434 enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW; 7435 struct devlink_trap_policer_item *policer_item; 7436 u32 portid = NETLINK_CB(cb->skb).portid; 7437 struct devlink *devlink; 7438 int start = cb->args[0]; 7439 int idx = 0; 7440 int err; 7441 7442 mutex_lock(&devlink_mutex); 7443 list_for_each_entry(devlink, &devlink_list, list) { 7444 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 7445 continue; 7446 mutex_lock(&devlink->lock); 7447 list_for_each_entry(policer_item, &devlink->trap_policer_list, 7448 list) { 7449 if (idx < start) { 7450 idx++; 7451 continue; 7452 } 7453 err = devlink_nl_trap_policer_fill(msg, devlink, 7454 policer_item, cmd, 7455 portid, 7456 cb->nlh->nlmsg_seq, 7457 NLM_F_MULTI); 7458 if (err) { 7459 mutex_unlock(&devlink->lock); 7460 goto out; 7461 } 7462 idx++; 7463 } 7464 mutex_unlock(&devlink->lock); 7465 } 7466out: 7467 mutex_unlock(&devlink_mutex); 7468 7469 cb->args[0] = idx; 7470 return msg->len; 7471} 7472 7473static int 7474devlink_trap_policer_set(struct devlink *devlink, 7475 struct devlink_trap_policer_item *policer_item, 7476 struct genl_info *info) 7477{ 7478 struct netlink_ext_ack *extack = info->extack; 7479 struct nlattr **attrs = info->attrs; 7480 u64 rate, burst; 7481 int err; 7482 7483 rate = policer_item->rate; 7484 burst = policer_item->burst; 7485 7486 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]) 7487 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]); 7488 7489 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]) 7490 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]); 7491 7492 if (rate < policer_item->policer->min_rate) { 7493 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit"); 7494 return -EINVAL; 7495 } 7496 7497 if (rate > policer_item->policer->max_rate) { 7498 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit"); 7499 return -EINVAL; 7500 } 7501 7502 if (burst < policer_item->policer->min_burst) { 7503 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit"); 7504 return -EINVAL; 7505 } 7506 7507 if (burst > policer_item->policer->max_burst) { 7508 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit"); 7509 return -EINVAL; 7510 } 7511 7512 err = devlink->ops->trap_policer_set(devlink, policer_item->policer, 7513 rate, burst, info->extack); 7514 if (err) 7515 return err; 7516 7517 policer_item->rate = rate; 7518 policer_item->burst = burst; 7519 7520 return 0; 7521} 7522 7523static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb, 7524 struct genl_info *info) 7525{ 7526 struct devlink_trap_policer_item *policer_item; 7527 struct netlink_ext_ack *extack = info->extack; 7528 struct devlink *devlink = info->user_ptr[0]; 7529 7530 if (list_empty(&devlink->trap_policer_list)) 7531 return -EOPNOTSUPP; 7532 7533 if (!devlink->ops->trap_policer_set) 7534 return -EOPNOTSUPP; 7535 7536 policer_item = devlink_trap_policer_item_get_from_info(devlink, info); 7537 if (!policer_item) { 7538 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); 7539 return -ENOENT; 7540 } 7541 7542 return devlink_trap_policer_set(devlink, policer_item, info); 7543} 7544 7545static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { 7546 [DEVLINK_ATTR_UNSPEC] = { .strict_start_type = 7547 DEVLINK_ATTR_TRAP_POLICER_ID }, 7548 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, 7549 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, 7550 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 }, 7551 [DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO, 7552 DEVLINK_PORT_TYPE_IB), 7553 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 }, 7554 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 }, 7555 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 }, 7556 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 }, 7557 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 }, 7558 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, 7559 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, 7560 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, 7561 [DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY, 7562 DEVLINK_ESWITCH_MODE_SWITCHDEV), 7563 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 }, 7564 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, 7565 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, 7566 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, 7567 [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64}, 7568 [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64}, 7569 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING }, 7570 [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 }, 7571 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 }, 7572 [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING }, 7573 [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 }, 7574 [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 }, 7575 [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 }, 7576 [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING }, 7577 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 }, 7578 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 }, 7579 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING }, 7580 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING }, 7581 [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] = 7582 NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS), 7583 [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING }, 7584 [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 }, 7585 [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING }, 7586 [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 }, 7587 [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 }, 7588 [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 }, 7589 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 }, 7590 [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 }, 7591 [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 }, 7592 [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 }, 7593 [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED }, 7594 [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 7595 DEVLINK_RELOAD_ACTION_MAX), 7596 [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK), 7597}; 7598 7599static const struct genl_small_ops devlink_nl_ops[] = { 7600 { 7601 .cmd = DEVLINK_CMD_GET, 7602 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7603 .doit = devlink_nl_cmd_get_doit, 7604 .dumpit = devlink_nl_cmd_get_dumpit, 7605 /* can be retrieved by unprivileged users */ 7606 }, 7607 { 7608 .cmd = DEVLINK_CMD_PORT_GET, 7609 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7610 .doit = devlink_nl_cmd_port_get_doit, 7611 .dumpit = devlink_nl_cmd_port_get_dumpit, 7612 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7613 /* can be retrieved by unprivileged users */ 7614 }, 7615 { 7616 .cmd = DEVLINK_CMD_PORT_SET, 7617 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7618 .doit = devlink_nl_cmd_port_set_doit, 7619 .flags = GENL_ADMIN_PERM, 7620 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7621 }, 7622 { 7623 .cmd = DEVLINK_CMD_PORT_SPLIT, 7624 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7625 .doit = devlink_nl_cmd_port_split_doit, 7626 .flags = GENL_ADMIN_PERM, 7627 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7628 }, 7629 { 7630 .cmd = DEVLINK_CMD_PORT_UNSPLIT, 7631 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7632 .doit = devlink_nl_cmd_port_unsplit_doit, 7633 .flags = GENL_ADMIN_PERM, 7634 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7635 }, 7636 { 7637 .cmd = DEVLINK_CMD_SB_GET, 7638 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7639 .doit = devlink_nl_cmd_sb_get_doit, 7640 .dumpit = devlink_nl_cmd_sb_get_dumpit, 7641 /* can be retrieved by unprivileged users */ 7642 }, 7643 { 7644 .cmd = DEVLINK_CMD_SB_POOL_GET, 7645 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7646 .doit = devlink_nl_cmd_sb_pool_get_doit, 7647 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit, 7648 /* can be retrieved by unprivileged users */ 7649 }, 7650 { 7651 .cmd = DEVLINK_CMD_SB_POOL_SET, 7652 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7653 .doit = devlink_nl_cmd_sb_pool_set_doit, 7654 .flags = GENL_ADMIN_PERM, 7655 }, 7656 { 7657 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET, 7658 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7659 .doit = devlink_nl_cmd_sb_port_pool_get_doit, 7660 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit, 7661 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7662 /* can be retrieved by unprivileged users */ 7663 }, 7664 { 7665 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, 7666 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7667 .doit = devlink_nl_cmd_sb_port_pool_set_doit, 7668 .flags = GENL_ADMIN_PERM, 7669 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7670 }, 7671 { 7672 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, 7673 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7674 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, 7675 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit, 7676 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7677 /* can be retrieved by unprivileged users */ 7678 }, 7679 { 7680 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, 7681 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7682 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit, 7683 .flags = GENL_ADMIN_PERM, 7684 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7685 }, 7686 { 7687 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT, 7688 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7689 .doit = devlink_nl_cmd_sb_occ_snapshot_doit, 7690 .flags = GENL_ADMIN_PERM, 7691 }, 7692 { 7693 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR, 7694 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7695 .doit = devlink_nl_cmd_sb_occ_max_clear_doit, 7696 .flags = GENL_ADMIN_PERM, 7697 }, 7698 { 7699 .cmd = DEVLINK_CMD_ESWITCH_GET, 7700 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7701 .doit = devlink_nl_cmd_eswitch_get_doit, 7702 .flags = GENL_ADMIN_PERM, 7703 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7704 }, 7705 { 7706 .cmd = DEVLINK_CMD_ESWITCH_SET, 7707 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7708 .doit = devlink_nl_cmd_eswitch_set_doit, 7709 .flags = GENL_ADMIN_PERM, 7710 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7711 }, 7712 { 7713 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, 7714 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7715 .doit = devlink_nl_cmd_dpipe_table_get, 7716 /* can be retrieved by unprivileged users */ 7717 }, 7718 { 7719 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, 7720 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7721 .doit = devlink_nl_cmd_dpipe_entries_get, 7722 /* can be retrieved by unprivileged users */ 7723 }, 7724 { 7725 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, 7726 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7727 .doit = devlink_nl_cmd_dpipe_headers_get, 7728 /* can be retrieved by unprivileged users */ 7729 }, 7730 { 7731 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, 7732 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7733 .doit = devlink_nl_cmd_dpipe_table_counters_set, 7734 .flags = GENL_ADMIN_PERM, 7735 }, 7736 { 7737 .cmd = DEVLINK_CMD_RESOURCE_SET, 7738 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7739 .doit = devlink_nl_cmd_resource_set, 7740 .flags = GENL_ADMIN_PERM, 7741 }, 7742 { 7743 .cmd = DEVLINK_CMD_RESOURCE_DUMP, 7744 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7745 .doit = devlink_nl_cmd_resource_dump, 7746 /* can be retrieved by unprivileged users */ 7747 }, 7748 { 7749 .cmd = DEVLINK_CMD_RELOAD, 7750 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7751 .doit = devlink_nl_cmd_reload, 7752 .flags = GENL_ADMIN_PERM, 7753 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7754 }, 7755 { 7756 .cmd = DEVLINK_CMD_PARAM_GET, 7757 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7758 .doit = devlink_nl_cmd_param_get_doit, 7759 .dumpit = devlink_nl_cmd_param_get_dumpit, 7760 /* can be retrieved by unprivileged users */ 7761 }, 7762 { 7763 .cmd = DEVLINK_CMD_PARAM_SET, 7764 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7765 .doit = devlink_nl_cmd_param_set_doit, 7766 .flags = GENL_ADMIN_PERM, 7767 }, 7768 { 7769 .cmd = DEVLINK_CMD_PORT_PARAM_GET, 7770 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7771 .doit = devlink_nl_cmd_port_param_get_doit, 7772 .dumpit = devlink_nl_cmd_port_param_get_dumpit, 7773 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7774 /* can be retrieved by unprivileged users */ 7775 }, 7776 { 7777 .cmd = DEVLINK_CMD_PORT_PARAM_SET, 7778 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7779 .doit = devlink_nl_cmd_port_param_set_doit, 7780 .flags = GENL_ADMIN_PERM, 7781 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7782 }, 7783 { 7784 .cmd = DEVLINK_CMD_REGION_GET, 7785 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7786 .doit = devlink_nl_cmd_region_get_doit, 7787 .dumpit = devlink_nl_cmd_region_get_dumpit, 7788 .flags = GENL_ADMIN_PERM, 7789 }, 7790 { 7791 .cmd = DEVLINK_CMD_REGION_NEW, 7792 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7793 .doit = devlink_nl_cmd_region_new, 7794 .flags = GENL_ADMIN_PERM, 7795 }, 7796 { 7797 .cmd = DEVLINK_CMD_REGION_DEL, 7798 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7799 .doit = devlink_nl_cmd_region_del, 7800 .flags = GENL_ADMIN_PERM, 7801 }, 7802 { 7803 .cmd = DEVLINK_CMD_REGION_READ, 7804 .validate = GENL_DONT_VALIDATE_STRICT | 7805 GENL_DONT_VALIDATE_DUMP_STRICT, 7806 .dumpit = devlink_nl_cmd_region_read_dumpit, 7807 .flags = GENL_ADMIN_PERM, 7808 }, 7809 { 7810 .cmd = DEVLINK_CMD_INFO_GET, 7811 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7812 .doit = devlink_nl_cmd_info_get_doit, 7813 .dumpit = devlink_nl_cmd_info_get_dumpit, 7814 /* can be retrieved by unprivileged users */ 7815 }, 7816 { 7817 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET, 7818 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7819 .doit = devlink_nl_cmd_health_reporter_get_doit, 7820 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit, 7821 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7822 DEVLINK_NL_FLAG_NO_LOCK, 7823 /* can be retrieved by unprivileged users */ 7824 }, 7825 { 7826 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET, 7827 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7828 .doit = devlink_nl_cmd_health_reporter_set_doit, 7829 .flags = GENL_ADMIN_PERM, 7830 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7831 DEVLINK_NL_FLAG_NO_LOCK, 7832 }, 7833 { 7834 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, 7835 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7836 .doit = devlink_nl_cmd_health_reporter_recover_doit, 7837 .flags = GENL_ADMIN_PERM, 7838 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7839 DEVLINK_NL_FLAG_NO_LOCK, 7840 }, 7841 { 7842 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 7843 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7844 .doit = devlink_nl_cmd_health_reporter_diagnose_doit, 7845 .flags = GENL_ADMIN_PERM, 7846 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7847 DEVLINK_NL_FLAG_NO_LOCK, 7848 }, 7849 { 7850 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, 7851 .validate = GENL_DONT_VALIDATE_STRICT | 7852 GENL_DONT_VALIDATE_DUMP_STRICT, 7853 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit, 7854 .flags = GENL_ADMIN_PERM, 7855 }, 7856 { 7857 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, 7858 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7859 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit, 7860 .flags = GENL_ADMIN_PERM, 7861 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7862 DEVLINK_NL_FLAG_NO_LOCK, 7863 }, 7864 { 7865 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST, 7866 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7867 .doit = devlink_nl_cmd_health_reporter_test_doit, 7868 .flags = GENL_ADMIN_PERM, 7869 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7870 DEVLINK_NL_FLAG_NO_LOCK, 7871 }, 7872 { 7873 .cmd = DEVLINK_CMD_FLASH_UPDATE, 7874 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7875 .doit = devlink_nl_cmd_flash_update, 7876 .flags = GENL_ADMIN_PERM, 7877 }, 7878 { 7879 .cmd = DEVLINK_CMD_TRAP_GET, 7880 .doit = devlink_nl_cmd_trap_get_doit, 7881 .dumpit = devlink_nl_cmd_trap_get_dumpit, 7882 /* can be retrieved by unprivileged users */ 7883 }, 7884 { 7885 .cmd = DEVLINK_CMD_TRAP_SET, 7886 .doit = devlink_nl_cmd_trap_set_doit, 7887 .flags = GENL_ADMIN_PERM, 7888 }, 7889 { 7890 .cmd = DEVLINK_CMD_TRAP_GROUP_GET, 7891 .doit = devlink_nl_cmd_trap_group_get_doit, 7892 .dumpit = devlink_nl_cmd_trap_group_get_dumpit, 7893 /* can be retrieved by unprivileged users */ 7894 }, 7895 { 7896 .cmd = DEVLINK_CMD_TRAP_GROUP_SET, 7897 .doit = devlink_nl_cmd_trap_group_set_doit, 7898 .flags = GENL_ADMIN_PERM, 7899 }, 7900 { 7901 .cmd = DEVLINK_CMD_TRAP_POLICER_GET, 7902 .doit = devlink_nl_cmd_trap_policer_get_doit, 7903 .dumpit = devlink_nl_cmd_trap_policer_get_dumpit, 7904 /* can be retrieved by unprivileged users */ 7905 }, 7906 { 7907 .cmd = DEVLINK_CMD_TRAP_POLICER_SET, 7908 .doit = devlink_nl_cmd_trap_policer_set_doit, 7909 .flags = GENL_ADMIN_PERM, 7910 }, 7911}; 7912 7913static struct genl_family devlink_nl_family __ro_after_init = { 7914 .name = DEVLINK_GENL_NAME, 7915 .version = DEVLINK_GENL_VERSION, 7916 .maxattr = DEVLINK_ATTR_MAX, 7917 .policy = devlink_nl_policy, 7918 .netnsok = true, 7919 .pre_doit = devlink_nl_pre_doit, 7920 .post_doit = devlink_nl_post_doit, 7921 .module = THIS_MODULE, 7922 .small_ops = devlink_nl_ops, 7923 .n_small_ops = ARRAY_SIZE(devlink_nl_ops), 7924 .mcgrps = devlink_nl_mcgrps, 7925 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), 7926}; 7927 7928static bool devlink_reload_actions_valid(const struct devlink_ops *ops) 7929{ 7930 const struct devlink_reload_combination *comb; 7931 int i; 7932 7933 if (!devlink_reload_supported(ops)) { 7934 if (WARN_ON(ops->reload_actions)) 7935 return false; 7936 return true; 7937 } 7938 7939 if (WARN_ON(!ops->reload_actions || 7940 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 7941 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) 7942 return false; 7943 7944 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || 7945 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) 7946 return false; 7947 7948 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { 7949 comb = &devlink_reload_invalid_combinations[i]; 7950 if (ops->reload_actions == BIT(comb->action) && 7951 ops->reload_limits == BIT(comb->limit)) 7952 return false; 7953 } 7954 return true; 7955} 7956 7957/** 7958 * devlink_alloc - Allocate new devlink instance resources 7959 * 7960 * @ops: ops 7961 * @priv_size: size of user private data 7962 * 7963 * Allocate new devlink instance resources, including devlink index 7964 * and name. 7965 */ 7966struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) 7967{ 7968 struct devlink *devlink; 7969 7970 if (WARN_ON(!ops)) 7971 return NULL; 7972 7973 if (!devlink_reload_actions_valid(ops)) 7974 return NULL; 7975 7976 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); 7977 if (!devlink) 7978 return NULL; 7979 devlink->ops = ops; 7980 xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC); 7981 __devlink_net_set(devlink, &init_net); 7982 INIT_LIST_HEAD(&devlink->port_list); 7983 INIT_LIST_HEAD(&devlink->sb_list); 7984 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list); 7985 INIT_LIST_HEAD(&devlink->resource_list); 7986 INIT_LIST_HEAD(&devlink->param_list); 7987 INIT_LIST_HEAD(&devlink->region_list); 7988 INIT_LIST_HEAD(&devlink->reporter_list); 7989 INIT_LIST_HEAD(&devlink->trap_list); 7990 INIT_LIST_HEAD(&devlink->trap_group_list); 7991 INIT_LIST_HEAD(&devlink->trap_policer_list); 7992 mutex_init(&devlink->lock); 7993 mutex_init(&devlink->reporters_lock); 7994 return devlink; 7995} 7996EXPORT_SYMBOL_GPL(devlink_alloc); 7997 7998/** 7999 * devlink_register - Register devlink instance 8000 * 8001 * @devlink: devlink 8002 * @dev: parent device 8003 */ 8004int devlink_register(struct devlink *devlink, struct device *dev) 8005{ 8006 devlink->dev = dev; 8007 devlink->registered = true; 8008 mutex_lock(&devlink_mutex); 8009 list_add_tail(&devlink->list, &devlink_list); 8010 devlink_notify(devlink, DEVLINK_CMD_NEW); 8011 mutex_unlock(&devlink_mutex); 8012 return 0; 8013} 8014EXPORT_SYMBOL_GPL(devlink_register); 8015 8016/** 8017 * devlink_unregister - Unregister devlink instance 8018 * 8019 * @devlink: devlink 8020 */ 8021void devlink_unregister(struct devlink *devlink) 8022{ 8023 mutex_lock(&devlink_mutex); 8024 WARN_ON(devlink_reload_supported(devlink->ops) && 8025 devlink->reload_enabled); 8026 devlink_notify(devlink, DEVLINK_CMD_DEL); 8027 list_del(&devlink->list); 8028 mutex_unlock(&devlink_mutex); 8029} 8030EXPORT_SYMBOL_GPL(devlink_unregister); 8031 8032/** 8033 * devlink_reload_enable - Enable reload of devlink instance 8034 * 8035 * @devlink: devlink 8036 * 8037 * Should be called at end of device initialization 8038 * process when reload operation is supported. 8039 */ 8040void devlink_reload_enable(struct devlink *devlink) 8041{ 8042 mutex_lock(&devlink_mutex); 8043 devlink->reload_enabled = true; 8044 mutex_unlock(&devlink_mutex); 8045} 8046EXPORT_SYMBOL_GPL(devlink_reload_enable); 8047 8048/** 8049 * devlink_reload_disable - Disable reload of devlink instance 8050 * 8051 * @devlink: devlink 8052 * 8053 * Should be called at the beginning of device cleanup 8054 * process when reload operation is supported. 8055 */ 8056void devlink_reload_disable(struct devlink *devlink) 8057{ 8058 mutex_lock(&devlink_mutex); 8059 /* Mutex is taken which ensures that no reload operation is in 8060 * progress while setting up forbidded flag. 8061 */ 8062 devlink->reload_enabled = false; 8063 mutex_unlock(&devlink_mutex); 8064} 8065EXPORT_SYMBOL_GPL(devlink_reload_disable); 8066 8067/** 8068 * devlink_free - Free devlink instance resources 8069 * 8070 * @devlink: devlink 8071 */ 8072void devlink_free(struct devlink *devlink) 8073{ 8074 mutex_destroy(&devlink->reporters_lock); 8075 mutex_destroy(&devlink->lock); 8076 WARN_ON(!list_empty(&devlink->trap_policer_list)); 8077 WARN_ON(!list_empty(&devlink->trap_group_list)); 8078 WARN_ON(!list_empty(&devlink->trap_list)); 8079 WARN_ON(!list_empty(&devlink->reporter_list)); 8080 WARN_ON(!list_empty(&devlink->region_list)); 8081 WARN_ON(!list_empty(&devlink->param_list)); 8082 WARN_ON(!list_empty(&devlink->resource_list)); 8083 WARN_ON(!list_empty(&devlink->dpipe_table_list)); 8084 WARN_ON(!list_empty(&devlink->sb_list)); 8085 WARN_ON(!list_empty(&devlink->port_list)); 8086 8087 xa_destroy(&devlink->snapshot_ids); 8088 8089 kfree(devlink); 8090} 8091EXPORT_SYMBOL_GPL(devlink_free); 8092 8093static void devlink_port_type_warn(struct work_struct *work) 8094{ 8095 struct devlink_port *port = container_of(to_delayed_work(work), 8096 struct devlink_port, 8097 type_warn_dw); 8098 dev_warn(port->devlink->dev, "Type was not set for devlink port."); 8099} 8100 8101static bool devlink_port_type_should_warn(struct devlink_port *devlink_port) 8102{ 8103 /* Ignore CPU and DSA flavours. */ 8104 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU && 8105 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA && 8106 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED; 8107} 8108 8109#define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600) 8110 8111static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port) 8112{ 8113 if (!devlink_port_type_should_warn(devlink_port)) 8114 return; 8115 /* Schedule a work to WARN in case driver does not set port 8116 * type within timeout. 8117 */ 8118 schedule_delayed_work(&devlink_port->type_warn_dw, 8119 DEVLINK_PORT_TYPE_WARN_TIMEOUT); 8120} 8121 8122static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port) 8123{ 8124 if (!devlink_port_type_should_warn(devlink_port)) 8125 return; 8126 cancel_delayed_work_sync(&devlink_port->type_warn_dw); 8127} 8128 8129/** 8130 * devlink_port_register - Register devlink port 8131 * 8132 * @devlink: devlink 8133 * @devlink_port: devlink port 8134 * @port_index: driver-specific numerical identifier of the port 8135 * 8136 * Register devlink port with provided port index. User can use 8137 * any indexing, even hw-related one. devlink_port structure 8138 * is convenient to be embedded inside user driver private structure. 8139 * Note that the caller should take care of zeroing the devlink_port 8140 * structure. 8141 */ 8142int devlink_port_register(struct devlink *devlink, 8143 struct devlink_port *devlink_port, 8144 unsigned int port_index) 8145{ 8146 mutex_lock(&devlink->lock); 8147 if (devlink_port_index_exists(devlink, port_index)) { 8148 mutex_unlock(&devlink->lock); 8149 return -EEXIST; 8150 } 8151 devlink_port->devlink = devlink; 8152 devlink_port->index = port_index; 8153 devlink_port->registered = true; 8154 spin_lock_init(&devlink_port->type_lock); 8155 INIT_LIST_HEAD(&devlink_port->reporter_list); 8156 mutex_init(&devlink_port->reporters_lock); 8157 list_add_tail(&devlink_port->list, &devlink->port_list); 8158 INIT_LIST_HEAD(&devlink_port->param_list); 8159 INIT_LIST_HEAD(&devlink_port->region_list); 8160 mutex_unlock(&devlink->lock); 8161 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn); 8162 devlink_port_type_warn_schedule(devlink_port); 8163 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 8164 return 0; 8165} 8166EXPORT_SYMBOL_GPL(devlink_port_register); 8167 8168/** 8169 * devlink_port_unregister - Unregister devlink port 8170 * 8171 * @devlink_port: devlink port 8172 */ 8173void devlink_port_unregister(struct devlink_port *devlink_port) 8174{ 8175 struct devlink *devlink = devlink_port->devlink; 8176 8177 devlink_port_type_warn_cancel(devlink_port); 8178 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); 8179 mutex_lock(&devlink->lock); 8180 list_del(&devlink_port->list); 8181 mutex_unlock(&devlink->lock); 8182 WARN_ON(!list_empty(&devlink_port->reporter_list)); 8183 WARN_ON(!list_empty(&devlink_port->region_list)); 8184 mutex_destroy(&devlink_port->reporters_lock); 8185} 8186EXPORT_SYMBOL_GPL(devlink_port_unregister); 8187 8188static void __devlink_port_type_set(struct devlink_port *devlink_port, 8189 enum devlink_port_type type, 8190 void *type_dev) 8191{ 8192 if (WARN_ON(!devlink_port->registered)) 8193 return; 8194 devlink_port_type_warn_cancel(devlink_port); 8195 spin_lock_bh(&devlink_port->type_lock); 8196 devlink_port->type = type; 8197 devlink_port->type_dev = type_dev; 8198 spin_unlock_bh(&devlink_port->type_lock); 8199 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 8200} 8201 8202static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port, 8203 struct net_device *netdev) 8204{ 8205 const struct net_device_ops *ops = netdev->netdev_ops; 8206 8207 /* If driver registers devlink port, it should set devlink port 8208 * attributes accordingly so the compat functions are called 8209 * and the original ops are not used. 8210 */ 8211 if (ops->ndo_get_phys_port_name) { 8212 /* Some drivers use the same set of ndos for netdevs 8213 * that have devlink_port registered and also for 8214 * those who don't. Make sure that ndo_get_phys_port_name 8215 * returns -EOPNOTSUPP here in case it is defined. 8216 * Warn if not. 8217 */ 8218 char name[IFNAMSIZ]; 8219 int err; 8220 8221 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name)); 8222 WARN_ON(err != -EOPNOTSUPP); 8223 } 8224 if (ops->ndo_get_port_parent_id) { 8225 /* Some drivers use the same set of ndos for netdevs 8226 * that have devlink_port registered and also for 8227 * those who don't. Make sure that ndo_get_port_parent_id 8228 * returns -EOPNOTSUPP here in case it is defined. 8229 * Warn if not. 8230 */ 8231 struct netdev_phys_item_id ppid; 8232 int err; 8233 8234 err = ops->ndo_get_port_parent_id(netdev, &ppid); 8235 WARN_ON(err != -EOPNOTSUPP); 8236 } 8237} 8238 8239/** 8240 * devlink_port_type_eth_set - Set port type to Ethernet 8241 * 8242 * @devlink_port: devlink port 8243 * @netdev: related netdevice 8244 */ 8245void devlink_port_type_eth_set(struct devlink_port *devlink_port, 8246 struct net_device *netdev) 8247{ 8248 if (netdev) 8249 devlink_port_type_netdev_checks(devlink_port, netdev); 8250 else 8251 dev_warn(devlink_port->devlink->dev, 8252 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n", 8253 devlink_port->index); 8254 8255 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev); 8256} 8257EXPORT_SYMBOL_GPL(devlink_port_type_eth_set); 8258 8259/** 8260 * devlink_port_type_ib_set - Set port type to InfiniBand 8261 * 8262 * @devlink_port: devlink port 8263 * @ibdev: related IB device 8264 */ 8265void devlink_port_type_ib_set(struct devlink_port *devlink_port, 8266 struct ib_device *ibdev) 8267{ 8268 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev); 8269} 8270EXPORT_SYMBOL_GPL(devlink_port_type_ib_set); 8271 8272/** 8273 * devlink_port_type_clear - Clear port type 8274 * 8275 * @devlink_port: devlink port 8276 */ 8277void devlink_port_type_clear(struct devlink_port *devlink_port) 8278{ 8279 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL); 8280 devlink_port_type_warn_schedule(devlink_port); 8281} 8282EXPORT_SYMBOL_GPL(devlink_port_type_clear); 8283 8284static int __devlink_port_attrs_set(struct devlink_port *devlink_port, 8285 enum devlink_port_flavour flavour) 8286{ 8287 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8288 8289 devlink_port->attrs_set = true; 8290 attrs->flavour = flavour; 8291 if (attrs->switch_id.id_len) { 8292 devlink_port->switch_port = true; 8293 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN)) 8294 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN; 8295 } else { 8296 devlink_port->switch_port = false; 8297 } 8298 return 0; 8299} 8300 8301/** 8302 * devlink_port_attrs_set - Set port attributes 8303 * 8304 * @devlink_port: devlink port 8305 * @attrs: devlink port attrs 8306 */ 8307void devlink_port_attrs_set(struct devlink_port *devlink_port, 8308 struct devlink_port_attrs *attrs) 8309{ 8310 int ret; 8311 8312 if (WARN_ON(devlink_port->registered)) 8313 return; 8314 devlink_port->attrs = *attrs; 8315 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour); 8316 if (ret) 8317 return; 8318 WARN_ON(attrs->splittable && attrs->split); 8319} 8320EXPORT_SYMBOL_GPL(devlink_port_attrs_set); 8321 8322/** 8323 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes 8324 * 8325 * @devlink_port: devlink port 8326 * @controller: associated controller number for the devlink port instance 8327 * @pf: associated PF for the devlink port instance 8328 * @external: indicates if the port is for an external controller 8329 */ 8330void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller, 8331 u16 pf, bool external) 8332{ 8333 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8334 int ret; 8335 8336 if (WARN_ON(devlink_port->registered)) 8337 return; 8338 ret = __devlink_port_attrs_set(devlink_port, 8339 DEVLINK_PORT_FLAVOUR_PCI_PF); 8340 if (ret) 8341 return; 8342 attrs->pci_pf.controller = controller; 8343 attrs->pci_pf.pf = pf; 8344 attrs->pci_pf.external = external; 8345} 8346EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set); 8347 8348/** 8349 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes 8350 * 8351 * @devlink_port: devlink port 8352 * @controller: associated controller number for the devlink port instance 8353 * @pf: associated PF for the devlink port instance 8354 * @vf: associated VF of a PF for the devlink port instance 8355 * @external: indicates if the port is for an external controller 8356 */ 8357void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller, 8358 u16 pf, u16 vf, bool external) 8359{ 8360 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8361 int ret; 8362 8363 if (WARN_ON(devlink_port->registered)) 8364 return; 8365 ret = __devlink_port_attrs_set(devlink_port, 8366 DEVLINK_PORT_FLAVOUR_PCI_VF); 8367 if (ret) 8368 return; 8369 attrs->pci_vf.controller = controller; 8370 attrs->pci_vf.pf = pf; 8371 attrs->pci_vf.vf = vf; 8372 attrs->pci_vf.external = external; 8373} 8374EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set); 8375 8376static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, 8377 char *name, size_t len) 8378{ 8379 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8380 int n = 0; 8381 8382 if (!devlink_port->attrs_set) 8383 return -EOPNOTSUPP; 8384 8385 switch (attrs->flavour) { 8386 case DEVLINK_PORT_FLAVOUR_PHYSICAL: 8387 if (!attrs->split) 8388 n = snprintf(name, len, "p%u", attrs->phys.port_number); 8389 else 8390 n = snprintf(name, len, "p%us%u", 8391 attrs->phys.port_number, 8392 attrs->phys.split_subport_number); 8393 break; 8394 case DEVLINK_PORT_FLAVOUR_CPU: 8395 case DEVLINK_PORT_FLAVOUR_DSA: 8396 case DEVLINK_PORT_FLAVOUR_UNUSED: 8397 /* As CPU and DSA ports do not have a netdevice associated 8398 * case should not ever happen. 8399 */ 8400 WARN_ON(1); 8401 return -EINVAL; 8402 case DEVLINK_PORT_FLAVOUR_PCI_PF: 8403 if (attrs->pci_pf.external) { 8404 n = snprintf(name, len, "c%u", attrs->pci_pf.controller); 8405 if (n >= len) 8406 return -EINVAL; 8407 len -= n; 8408 name += n; 8409 } 8410 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf); 8411 break; 8412 case DEVLINK_PORT_FLAVOUR_PCI_VF: 8413 if (attrs->pci_vf.external) { 8414 n = snprintf(name, len, "c%u", attrs->pci_vf.controller); 8415 if (n >= len) 8416 return -EINVAL; 8417 len -= n; 8418 name += n; 8419 } 8420 n = snprintf(name, len, "pf%uvf%u", 8421 attrs->pci_vf.pf, attrs->pci_vf.vf); 8422 break; 8423 case DEVLINK_PORT_FLAVOUR_VIRTUAL: 8424 return -EOPNOTSUPP; 8425 } 8426 8427 if (n >= len) 8428 return -EINVAL; 8429 8430 return 0; 8431} 8432 8433int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, 8434 u32 size, u16 ingress_pools_count, 8435 u16 egress_pools_count, u16 ingress_tc_count, 8436 u16 egress_tc_count) 8437{ 8438 struct devlink_sb *devlink_sb; 8439 int err = 0; 8440 8441 mutex_lock(&devlink->lock); 8442 if (devlink_sb_index_exists(devlink, sb_index)) { 8443 err = -EEXIST; 8444 goto unlock; 8445 } 8446 8447 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL); 8448 if (!devlink_sb) { 8449 err = -ENOMEM; 8450 goto unlock; 8451 } 8452 devlink_sb->index = sb_index; 8453 devlink_sb->size = size; 8454 devlink_sb->ingress_pools_count = ingress_pools_count; 8455 devlink_sb->egress_pools_count = egress_pools_count; 8456 devlink_sb->ingress_tc_count = ingress_tc_count; 8457 devlink_sb->egress_tc_count = egress_tc_count; 8458 list_add_tail(&devlink_sb->list, &devlink->sb_list); 8459unlock: 8460 mutex_unlock(&devlink->lock); 8461 return err; 8462} 8463EXPORT_SYMBOL_GPL(devlink_sb_register); 8464 8465void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index) 8466{ 8467 struct devlink_sb *devlink_sb; 8468 8469 mutex_lock(&devlink->lock); 8470 devlink_sb = devlink_sb_get_by_index(devlink, sb_index); 8471 WARN_ON(!devlink_sb); 8472 list_del(&devlink_sb->list); 8473 mutex_unlock(&devlink->lock); 8474 kfree(devlink_sb); 8475} 8476EXPORT_SYMBOL_GPL(devlink_sb_unregister); 8477 8478/** 8479 * devlink_dpipe_headers_register - register dpipe headers 8480 * 8481 * @devlink: devlink 8482 * @dpipe_headers: dpipe header array 8483 * 8484 * Register the headers supported by hardware. 8485 */ 8486int devlink_dpipe_headers_register(struct devlink *devlink, 8487 struct devlink_dpipe_headers *dpipe_headers) 8488{ 8489 mutex_lock(&devlink->lock); 8490 devlink->dpipe_headers = dpipe_headers; 8491 mutex_unlock(&devlink->lock); 8492 return 0; 8493} 8494EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register); 8495 8496/** 8497 * devlink_dpipe_headers_unregister - unregister dpipe headers 8498 * 8499 * @devlink: devlink 8500 * 8501 * Unregister the headers supported by hardware. 8502 */ 8503void devlink_dpipe_headers_unregister(struct devlink *devlink) 8504{ 8505 mutex_lock(&devlink->lock); 8506 devlink->dpipe_headers = NULL; 8507 mutex_unlock(&devlink->lock); 8508} 8509EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister); 8510 8511/** 8512 * devlink_dpipe_table_counter_enabled - check if counter allocation 8513 * required 8514 * @devlink: devlink 8515 * @table_name: tables name 8516 * 8517 * Used by driver to check if counter allocation is required. 8518 * After counter allocation is turned on the table entries 8519 * are updated to include counter statistics. 8520 * 8521 * After that point on the driver must respect the counter 8522 * state so that each entry added to the table is added 8523 * with a counter. 8524 */ 8525bool devlink_dpipe_table_counter_enabled(struct devlink *devlink, 8526 const char *table_name) 8527{ 8528 struct devlink_dpipe_table *table; 8529 bool enabled; 8530 8531 rcu_read_lock(); 8532 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8533 table_name, devlink); 8534 enabled = false; 8535 if (table) 8536 enabled = table->counters_enabled; 8537 rcu_read_unlock(); 8538 return enabled; 8539} 8540EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled); 8541 8542/** 8543 * devlink_dpipe_table_register - register dpipe table 8544 * 8545 * @devlink: devlink 8546 * @table_name: table name 8547 * @table_ops: table ops 8548 * @priv: priv 8549 * @counter_control_extern: external control for counters 8550 */ 8551int devlink_dpipe_table_register(struct devlink *devlink, 8552 const char *table_name, 8553 struct devlink_dpipe_table_ops *table_ops, 8554 void *priv, bool counter_control_extern) 8555{ 8556 struct devlink_dpipe_table *table; 8557 int err = 0; 8558 8559 if (WARN_ON(!table_ops->size_get)) 8560 return -EINVAL; 8561 8562 mutex_lock(&devlink->lock); 8563 8564 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name, 8565 devlink)) { 8566 err = -EEXIST; 8567 goto unlock; 8568 } 8569 8570 table = kzalloc(sizeof(*table), GFP_KERNEL); 8571 if (!table) { 8572 err = -ENOMEM; 8573 goto unlock; 8574 } 8575 8576 table->name = table_name; 8577 table->table_ops = table_ops; 8578 table->priv = priv; 8579 table->counter_control_extern = counter_control_extern; 8580 8581 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list); 8582unlock: 8583 mutex_unlock(&devlink->lock); 8584 return err; 8585} 8586EXPORT_SYMBOL_GPL(devlink_dpipe_table_register); 8587 8588/** 8589 * devlink_dpipe_table_unregister - unregister dpipe table 8590 * 8591 * @devlink: devlink 8592 * @table_name: table name 8593 */ 8594void devlink_dpipe_table_unregister(struct devlink *devlink, 8595 const char *table_name) 8596{ 8597 struct devlink_dpipe_table *table; 8598 8599 mutex_lock(&devlink->lock); 8600 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8601 table_name, devlink); 8602 if (!table) 8603 goto unlock; 8604 list_del_rcu(&table->list); 8605 mutex_unlock(&devlink->lock); 8606 kfree_rcu(table, rcu); 8607 return; 8608unlock: 8609 mutex_unlock(&devlink->lock); 8610} 8611EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister); 8612 8613/** 8614 * devlink_resource_register - devlink resource register 8615 * 8616 * @devlink: devlink 8617 * @resource_name: resource's name 8618 * @resource_size: resource's size 8619 * @resource_id: resource's id 8620 * @parent_resource_id: resource's parent id 8621 * @size_params: size parameters 8622 */ 8623int devlink_resource_register(struct devlink *devlink, 8624 const char *resource_name, 8625 u64 resource_size, 8626 u64 resource_id, 8627 u64 parent_resource_id, 8628 const struct devlink_resource_size_params *size_params) 8629{ 8630 struct devlink_resource *resource; 8631 struct list_head *resource_list; 8632 bool top_hierarchy; 8633 int err = 0; 8634 8635 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP; 8636 8637 mutex_lock(&devlink->lock); 8638 resource = devlink_resource_find(devlink, NULL, resource_id); 8639 if (resource) { 8640 err = -EINVAL; 8641 goto out; 8642 } 8643 8644 resource = kzalloc(sizeof(*resource), GFP_KERNEL); 8645 if (!resource) { 8646 err = -ENOMEM; 8647 goto out; 8648 } 8649 8650 if (top_hierarchy) { 8651 resource_list = &devlink->resource_list; 8652 } else { 8653 struct devlink_resource *parent_resource; 8654 8655 parent_resource = devlink_resource_find(devlink, NULL, 8656 parent_resource_id); 8657 if (parent_resource) { 8658 resource_list = &parent_resource->resource_list; 8659 resource->parent = parent_resource; 8660 } else { 8661 kfree(resource); 8662 err = -EINVAL; 8663 goto out; 8664 } 8665 } 8666 8667 resource->name = resource_name; 8668 resource->size = resource_size; 8669 resource->size_new = resource_size; 8670 resource->id = resource_id; 8671 resource->size_valid = true; 8672 memcpy(&resource->size_params, size_params, 8673 sizeof(resource->size_params)); 8674 INIT_LIST_HEAD(&resource->resource_list); 8675 list_add_tail(&resource->list, resource_list); 8676out: 8677 mutex_unlock(&devlink->lock); 8678 return err; 8679} 8680EXPORT_SYMBOL_GPL(devlink_resource_register); 8681 8682/** 8683 * devlink_resources_unregister - free all resources 8684 * 8685 * @devlink: devlink 8686 * @resource: resource 8687 */ 8688void devlink_resources_unregister(struct devlink *devlink, 8689 struct devlink_resource *resource) 8690{ 8691 struct devlink_resource *tmp, *child_resource; 8692 struct list_head *resource_list; 8693 8694 if (resource) 8695 resource_list = &resource->resource_list; 8696 else 8697 resource_list = &devlink->resource_list; 8698 8699 if (!resource) 8700 mutex_lock(&devlink->lock); 8701 8702 list_for_each_entry_safe(child_resource, tmp, resource_list, list) { 8703 devlink_resources_unregister(devlink, child_resource); 8704 list_del(&child_resource->list); 8705 kfree(child_resource); 8706 } 8707 8708 if (!resource) 8709 mutex_unlock(&devlink->lock); 8710} 8711EXPORT_SYMBOL_GPL(devlink_resources_unregister); 8712 8713/** 8714 * devlink_resource_size_get - get and update size 8715 * 8716 * @devlink: devlink 8717 * @resource_id: the requested resource id 8718 * @p_resource_size: ptr to update 8719 */ 8720int devlink_resource_size_get(struct devlink *devlink, 8721 u64 resource_id, 8722 u64 *p_resource_size) 8723{ 8724 struct devlink_resource *resource; 8725 int err = 0; 8726 8727 mutex_lock(&devlink->lock); 8728 resource = devlink_resource_find(devlink, NULL, resource_id); 8729 if (!resource) { 8730 err = -EINVAL; 8731 goto out; 8732 } 8733 *p_resource_size = resource->size_new; 8734 resource->size = resource->size_new; 8735out: 8736 mutex_unlock(&devlink->lock); 8737 return err; 8738} 8739EXPORT_SYMBOL_GPL(devlink_resource_size_get); 8740 8741/** 8742 * devlink_dpipe_table_resource_set - set the resource id 8743 * 8744 * @devlink: devlink 8745 * @table_name: table name 8746 * @resource_id: resource id 8747 * @resource_units: number of resource's units consumed per table's entry 8748 */ 8749int devlink_dpipe_table_resource_set(struct devlink *devlink, 8750 const char *table_name, u64 resource_id, 8751 u64 resource_units) 8752{ 8753 struct devlink_dpipe_table *table; 8754 int err = 0; 8755 8756 mutex_lock(&devlink->lock); 8757 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8758 table_name, devlink); 8759 if (!table) { 8760 err = -EINVAL; 8761 goto out; 8762 } 8763 table->resource_id = resource_id; 8764 table->resource_units = resource_units; 8765 table->resource_valid = true; 8766out: 8767 mutex_unlock(&devlink->lock); 8768 return err; 8769} 8770EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set); 8771 8772/** 8773 * devlink_resource_occ_get_register - register occupancy getter 8774 * 8775 * @devlink: devlink 8776 * @resource_id: resource id 8777 * @occ_get: occupancy getter callback 8778 * @occ_get_priv: occupancy getter callback priv 8779 */ 8780void devlink_resource_occ_get_register(struct devlink *devlink, 8781 u64 resource_id, 8782 devlink_resource_occ_get_t *occ_get, 8783 void *occ_get_priv) 8784{ 8785 struct devlink_resource *resource; 8786 8787 mutex_lock(&devlink->lock); 8788 resource = devlink_resource_find(devlink, NULL, resource_id); 8789 if (WARN_ON(!resource)) 8790 goto out; 8791 WARN_ON(resource->occ_get); 8792 8793 resource->occ_get = occ_get; 8794 resource->occ_get_priv = occ_get_priv; 8795out: 8796 mutex_unlock(&devlink->lock); 8797} 8798EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register); 8799 8800/** 8801 * devlink_resource_occ_get_unregister - unregister occupancy getter 8802 * 8803 * @devlink: devlink 8804 * @resource_id: resource id 8805 */ 8806void devlink_resource_occ_get_unregister(struct devlink *devlink, 8807 u64 resource_id) 8808{ 8809 struct devlink_resource *resource; 8810 8811 mutex_lock(&devlink->lock); 8812 resource = devlink_resource_find(devlink, NULL, resource_id); 8813 if (WARN_ON(!resource)) 8814 goto out; 8815 WARN_ON(!resource->occ_get); 8816 8817 resource->occ_get = NULL; 8818 resource->occ_get_priv = NULL; 8819out: 8820 mutex_unlock(&devlink->lock); 8821} 8822EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister); 8823 8824static int devlink_param_verify(const struct devlink_param *param) 8825{ 8826 if (!param || !param->name || !param->supported_cmodes) 8827 return -EINVAL; 8828 if (param->generic) 8829 return devlink_param_generic_verify(param); 8830 else 8831 return devlink_param_driver_verify(param); 8832} 8833 8834static int __devlink_params_register(struct devlink *devlink, 8835 unsigned int port_index, 8836 struct list_head *param_list, 8837 const struct devlink_param *params, 8838 size_t params_count, 8839 enum devlink_command reg_cmd, 8840 enum devlink_command unreg_cmd) 8841{ 8842 const struct devlink_param *param = params; 8843 int i; 8844 int err; 8845 8846 mutex_lock(&devlink->lock); 8847 for (i = 0; i < params_count; i++, param++) { 8848 err = devlink_param_verify(param); 8849 if (err) 8850 goto rollback; 8851 8852 err = devlink_param_register_one(devlink, port_index, 8853 param_list, param, reg_cmd); 8854 if (err) 8855 goto rollback; 8856 } 8857 8858 mutex_unlock(&devlink->lock); 8859 return 0; 8860 8861rollback: 8862 if (!i) 8863 goto unlock; 8864 for (param--; i > 0; i--, param--) 8865 devlink_param_unregister_one(devlink, port_index, param_list, 8866 param, unreg_cmd); 8867unlock: 8868 mutex_unlock(&devlink->lock); 8869 return err; 8870} 8871 8872static void __devlink_params_unregister(struct devlink *devlink, 8873 unsigned int port_index, 8874 struct list_head *param_list, 8875 const struct devlink_param *params, 8876 size_t params_count, 8877 enum devlink_command cmd) 8878{ 8879 const struct devlink_param *param = params; 8880 int i; 8881 8882 mutex_lock(&devlink->lock); 8883 for (i = 0; i < params_count; i++, param++) 8884 devlink_param_unregister_one(devlink, 0, param_list, param, 8885 cmd); 8886 mutex_unlock(&devlink->lock); 8887} 8888 8889/** 8890 * devlink_params_register - register configuration parameters 8891 * 8892 * @devlink: devlink 8893 * @params: configuration parameters array 8894 * @params_count: number of parameters provided 8895 * 8896 * Register the configuration parameters supported by the driver. 8897 */ 8898int devlink_params_register(struct devlink *devlink, 8899 const struct devlink_param *params, 8900 size_t params_count) 8901{ 8902 return __devlink_params_register(devlink, 0, &devlink->param_list, 8903 params, params_count, 8904 DEVLINK_CMD_PARAM_NEW, 8905 DEVLINK_CMD_PARAM_DEL); 8906} 8907EXPORT_SYMBOL_GPL(devlink_params_register); 8908 8909/** 8910 * devlink_params_unregister - unregister configuration parameters 8911 * @devlink: devlink 8912 * @params: configuration parameters to unregister 8913 * @params_count: number of parameters provided 8914 */ 8915void devlink_params_unregister(struct devlink *devlink, 8916 const struct devlink_param *params, 8917 size_t params_count) 8918{ 8919 return __devlink_params_unregister(devlink, 0, &devlink->param_list, 8920 params, params_count, 8921 DEVLINK_CMD_PARAM_DEL); 8922} 8923EXPORT_SYMBOL_GPL(devlink_params_unregister); 8924 8925/** 8926 * devlink_params_publish - publish configuration parameters 8927 * 8928 * @devlink: devlink 8929 * 8930 * Publish previously registered configuration parameters. 8931 */ 8932void devlink_params_publish(struct devlink *devlink) 8933{ 8934 struct devlink_param_item *param_item; 8935 8936 list_for_each_entry(param_item, &devlink->param_list, list) { 8937 if (param_item->published) 8938 continue; 8939 param_item->published = true; 8940 devlink_param_notify(devlink, 0, param_item, 8941 DEVLINK_CMD_PARAM_NEW); 8942 } 8943} 8944EXPORT_SYMBOL_GPL(devlink_params_publish); 8945 8946/** 8947 * devlink_params_unpublish - unpublish configuration parameters 8948 * 8949 * @devlink: devlink 8950 * 8951 * Unpublish previously registered configuration parameters. 8952 */ 8953void devlink_params_unpublish(struct devlink *devlink) 8954{ 8955 struct devlink_param_item *param_item; 8956 8957 list_for_each_entry(param_item, &devlink->param_list, list) { 8958 if (!param_item->published) 8959 continue; 8960 param_item->published = false; 8961 devlink_param_notify(devlink, 0, param_item, 8962 DEVLINK_CMD_PARAM_DEL); 8963 } 8964} 8965EXPORT_SYMBOL_GPL(devlink_params_unpublish); 8966 8967/** 8968 * devlink_port_params_register - register port configuration parameters 8969 * 8970 * @devlink_port: devlink port 8971 * @params: configuration parameters array 8972 * @params_count: number of parameters provided 8973 * 8974 * Register the configuration parameters supported by the port. 8975 */ 8976int devlink_port_params_register(struct devlink_port *devlink_port, 8977 const struct devlink_param *params, 8978 size_t params_count) 8979{ 8980 return __devlink_params_register(devlink_port->devlink, 8981 devlink_port->index, 8982 &devlink_port->param_list, params, 8983 params_count, 8984 DEVLINK_CMD_PORT_PARAM_NEW, 8985 DEVLINK_CMD_PORT_PARAM_DEL); 8986} 8987EXPORT_SYMBOL_GPL(devlink_port_params_register); 8988 8989/** 8990 * devlink_port_params_unregister - unregister port configuration 8991 * parameters 8992 * 8993 * @devlink_port: devlink port 8994 * @params: configuration parameters array 8995 * @params_count: number of parameters provided 8996 */ 8997void devlink_port_params_unregister(struct devlink_port *devlink_port, 8998 const struct devlink_param *params, 8999 size_t params_count) 9000{ 9001 return __devlink_params_unregister(devlink_port->devlink, 9002 devlink_port->index, 9003 &devlink_port->param_list, 9004 params, params_count, 9005 DEVLINK_CMD_PORT_PARAM_DEL); 9006} 9007EXPORT_SYMBOL_GPL(devlink_port_params_unregister); 9008 9009static int 9010__devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id, 9011 union devlink_param_value *init_val) 9012{ 9013 struct devlink_param_item *param_item; 9014 9015 param_item = devlink_param_find_by_id(param_list, param_id); 9016 if (!param_item) 9017 return -EINVAL; 9018 9019 if (!param_item->driverinit_value_valid || 9020 !devlink_param_cmode_is_supported(param_item->param, 9021 DEVLINK_PARAM_CMODE_DRIVERINIT)) 9022 return -EOPNOTSUPP; 9023 9024 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) 9025 strcpy(init_val->vstr, param_item->driverinit_value.vstr); 9026 else 9027 *init_val = param_item->driverinit_value; 9028 9029 return 0; 9030} 9031 9032static int 9033__devlink_param_driverinit_value_set(struct devlink *devlink, 9034 unsigned int port_index, 9035 struct list_head *param_list, u32 param_id, 9036 union devlink_param_value init_val, 9037 enum devlink_command cmd) 9038{ 9039 struct devlink_param_item *param_item; 9040 9041 param_item = devlink_param_find_by_id(param_list, param_id); 9042 if (!param_item) 9043 return -EINVAL; 9044 9045 if (!devlink_param_cmode_is_supported(param_item->param, 9046 DEVLINK_PARAM_CMODE_DRIVERINIT)) 9047 return -EOPNOTSUPP; 9048 9049 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) 9050 strcpy(param_item->driverinit_value.vstr, init_val.vstr); 9051 else 9052 param_item->driverinit_value = init_val; 9053 param_item->driverinit_value_valid = true; 9054 9055 devlink_param_notify(devlink, port_index, param_item, cmd); 9056 return 0; 9057} 9058 9059/** 9060 * devlink_param_driverinit_value_get - get configuration parameter 9061 * value for driver initializing 9062 * 9063 * @devlink: devlink 9064 * @param_id: parameter ID 9065 * @init_val: value of parameter in driverinit configuration mode 9066 * 9067 * This function should be used by the driver to get driverinit 9068 * configuration for initialization after reload command. 9069 */ 9070int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, 9071 union devlink_param_value *init_val) 9072{ 9073 if (!devlink_reload_supported(devlink->ops)) 9074 return -EOPNOTSUPP; 9075 9076 return __devlink_param_driverinit_value_get(&devlink->param_list, 9077 param_id, init_val); 9078} 9079EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get); 9080 9081/** 9082 * devlink_param_driverinit_value_set - set value of configuration 9083 * parameter for driverinit 9084 * configuration mode 9085 * 9086 * @devlink: devlink 9087 * @param_id: parameter ID 9088 * @init_val: value of parameter to set for driverinit configuration mode 9089 * 9090 * This function should be used by the driver to set driverinit 9091 * configuration mode default value. 9092 */ 9093int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, 9094 union devlink_param_value init_val) 9095{ 9096 return __devlink_param_driverinit_value_set(devlink, 0, 9097 &devlink->param_list, 9098 param_id, init_val, 9099 DEVLINK_CMD_PARAM_NEW); 9100} 9101EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set); 9102 9103/** 9104 * devlink_port_param_driverinit_value_get - get configuration parameter 9105 * value for driver initializing 9106 * 9107 * @devlink_port: devlink_port 9108 * @param_id: parameter ID 9109 * @init_val: value of parameter in driverinit configuration mode 9110 * 9111 * This function should be used by the driver to get driverinit 9112 * configuration for initialization after reload command. 9113 */ 9114int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port, 9115 u32 param_id, 9116 union devlink_param_value *init_val) 9117{ 9118 struct devlink *devlink = devlink_port->devlink; 9119 9120 if (!devlink_reload_supported(devlink->ops)) 9121 return -EOPNOTSUPP; 9122 9123 return __devlink_param_driverinit_value_get(&devlink_port->param_list, 9124 param_id, init_val); 9125} 9126EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get); 9127 9128/** 9129 * devlink_port_param_driverinit_value_set - set value of configuration 9130 * parameter for driverinit 9131 * configuration mode 9132 * 9133 * @devlink_port: devlink_port 9134 * @param_id: parameter ID 9135 * @init_val: value of parameter to set for driverinit configuration mode 9136 * 9137 * This function should be used by the driver to set driverinit 9138 * configuration mode default value. 9139 */ 9140int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port, 9141 u32 param_id, 9142 union devlink_param_value init_val) 9143{ 9144 return __devlink_param_driverinit_value_set(devlink_port->devlink, 9145 devlink_port->index, 9146 &devlink_port->param_list, 9147 param_id, init_val, 9148 DEVLINK_CMD_PORT_PARAM_NEW); 9149} 9150EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set); 9151 9152/** 9153 * devlink_param_value_changed - notify devlink on a parameter's value 9154 * change. Should be called by the driver 9155 * right after the change. 9156 * 9157 * @devlink: devlink 9158 * @param_id: parameter ID 9159 * 9160 * This function should be used by the driver to notify devlink on value 9161 * change, excluding driverinit configuration mode. 9162 * For driverinit configuration mode driver should use the function 9163 */ 9164void devlink_param_value_changed(struct devlink *devlink, u32 param_id) 9165{ 9166 struct devlink_param_item *param_item; 9167 9168 param_item = devlink_param_find_by_id(&devlink->param_list, param_id); 9169 WARN_ON(!param_item); 9170 9171 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 9172} 9173EXPORT_SYMBOL_GPL(devlink_param_value_changed); 9174 9175/** 9176 * devlink_port_param_value_changed - notify devlink on a parameter's value 9177 * change. Should be called by the driver 9178 * right after the change. 9179 * 9180 * @devlink_port: devlink_port 9181 * @param_id: parameter ID 9182 * 9183 * This function should be used by the driver to notify devlink on value 9184 * change, excluding driverinit configuration mode. 9185 * For driverinit configuration mode driver should use the function 9186 * devlink_port_param_driverinit_value_set() instead. 9187 */ 9188void devlink_port_param_value_changed(struct devlink_port *devlink_port, 9189 u32 param_id) 9190{ 9191 struct devlink_param_item *param_item; 9192 9193 param_item = devlink_param_find_by_id(&devlink_port->param_list, 9194 param_id); 9195 WARN_ON(!param_item); 9196 9197 devlink_param_notify(devlink_port->devlink, devlink_port->index, 9198 param_item, DEVLINK_CMD_PORT_PARAM_NEW); 9199} 9200EXPORT_SYMBOL_GPL(devlink_port_param_value_changed); 9201 9202/** 9203 * devlink_param_value_str_fill - Safely fill-up the string preventing 9204 * from overflow of the preallocated buffer 9205 * 9206 * @dst_val: destination devlink_param_value 9207 * @src: source buffer 9208 */ 9209void devlink_param_value_str_fill(union devlink_param_value *dst_val, 9210 const char *src) 9211{ 9212 size_t len; 9213 9214 len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE); 9215 WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE); 9216} 9217EXPORT_SYMBOL_GPL(devlink_param_value_str_fill); 9218 9219/** 9220 * devlink_region_create - create a new address region 9221 * 9222 * @devlink: devlink 9223 * @ops: region operations and name 9224 * @region_max_snapshots: Maximum supported number of snapshots for region 9225 * @region_size: size of region 9226 */ 9227struct devlink_region * 9228devlink_region_create(struct devlink *devlink, 9229 const struct devlink_region_ops *ops, 9230 u32 region_max_snapshots, u64 region_size) 9231{ 9232 struct devlink_region *region; 9233 int err = 0; 9234 9235 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 9236 return ERR_PTR(-EINVAL); 9237 9238 mutex_lock(&devlink->lock); 9239 9240 if (devlink_region_get_by_name(devlink, ops->name)) { 9241 err = -EEXIST; 9242 goto unlock; 9243 } 9244 9245 region = kzalloc(sizeof(*region), GFP_KERNEL); 9246 if (!region) { 9247 err = -ENOMEM; 9248 goto unlock; 9249 } 9250 9251 region->devlink = devlink; 9252 region->max_snapshots = region_max_snapshots; 9253 region->ops = ops; 9254 region->size = region_size; 9255 INIT_LIST_HEAD(®ion->snapshot_list); 9256 list_add_tail(®ion->list, &devlink->region_list); 9257 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 9258 9259 mutex_unlock(&devlink->lock); 9260 return region; 9261 9262unlock: 9263 mutex_unlock(&devlink->lock); 9264 return ERR_PTR(err); 9265} 9266EXPORT_SYMBOL_GPL(devlink_region_create); 9267 9268/** 9269 * devlink_port_region_create - create a new address region for a port 9270 * 9271 * @port: devlink port 9272 * @ops: region operations and name 9273 * @region_max_snapshots: Maximum supported number of snapshots for region 9274 * @region_size: size of region 9275 */ 9276struct devlink_region * 9277devlink_port_region_create(struct devlink_port *port, 9278 const struct devlink_port_region_ops *ops, 9279 u32 region_max_snapshots, u64 region_size) 9280{ 9281 struct devlink *devlink = port->devlink; 9282 struct devlink_region *region; 9283 int err = 0; 9284 9285 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 9286 return ERR_PTR(-EINVAL); 9287 9288 mutex_lock(&devlink->lock); 9289 9290 if (devlink_port_region_get_by_name(port, ops->name)) { 9291 err = -EEXIST; 9292 goto unlock; 9293 } 9294 9295 region = kzalloc(sizeof(*region), GFP_KERNEL); 9296 if (!region) { 9297 err = -ENOMEM; 9298 goto unlock; 9299 } 9300 9301 region->devlink = devlink; 9302 region->port = port; 9303 region->max_snapshots = region_max_snapshots; 9304 region->port_ops = ops; 9305 region->size = region_size; 9306 INIT_LIST_HEAD(®ion->snapshot_list); 9307 list_add_tail(®ion->list, &port->region_list); 9308 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 9309 9310 mutex_unlock(&devlink->lock); 9311 return region; 9312 9313unlock: 9314 mutex_unlock(&devlink->lock); 9315 return ERR_PTR(err); 9316} 9317EXPORT_SYMBOL_GPL(devlink_port_region_create); 9318 9319/** 9320 * devlink_region_destroy - destroy address region 9321 * 9322 * @region: devlink region to destroy 9323 */ 9324void devlink_region_destroy(struct devlink_region *region) 9325{ 9326 struct devlink *devlink = region->devlink; 9327 struct devlink_snapshot *snapshot, *ts; 9328 9329 mutex_lock(&devlink->lock); 9330 9331 /* Free all snapshots of region */ 9332 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list) 9333 devlink_region_snapshot_del(region, snapshot); 9334 9335 list_del(®ion->list); 9336 9337 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); 9338 mutex_unlock(&devlink->lock); 9339 kfree(region); 9340} 9341EXPORT_SYMBOL_GPL(devlink_region_destroy); 9342 9343/** 9344 * devlink_region_snapshot_id_get - get snapshot ID 9345 * 9346 * This callback should be called when adding a new snapshot, 9347 * Driver should use the same id for multiple snapshots taken 9348 * on multiple regions at the same time/by the same trigger. 9349 * 9350 * The caller of this function must use devlink_region_snapshot_id_put 9351 * when finished creating regions using this id. 9352 * 9353 * Returns zero on success, or a negative error code on failure. 9354 * 9355 * @devlink: devlink 9356 * @id: storage to return id 9357 */ 9358int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 9359{ 9360 int err; 9361 9362 mutex_lock(&devlink->lock); 9363 err = __devlink_region_snapshot_id_get(devlink, id); 9364 mutex_unlock(&devlink->lock); 9365 9366 return err; 9367} 9368EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); 9369 9370/** 9371 * devlink_region_snapshot_id_put - put snapshot ID reference 9372 * 9373 * This should be called by a driver after finishing creating snapshots 9374 * with an id. Doing so ensures that the ID can later be released in the 9375 * event that all snapshots using it have been destroyed. 9376 * 9377 * @devlink: devlink 9378 * @id: id to release reference on 9379 */ 9380void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) 9381{ 9382 mutex_lock(&devlink->lock); 9383 __devlink_snapshot_id_decrement(devlink, id); 9384 mutex_unlock(&devlink->lock); 9385} 9386EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); 9387 9388/** 9389 * devlink_region_snapshot_create - create a new snapshot 9390 * This will add a new snapshot of a region. The snapshot 9391 * will be stored on the region struct and can be accessed 9392 * from devlink. This is useful for future analyses of snapshots. 9393 * Multiple snapshots can be created on a region. 9394 * The @snapshot_id should be obtained using the getter function. 9395 * 9396 * @region: devlink region of the snapshot 9397 * @data: snapshot data 9398 * @snapshot_id: snapshot id to be created 9399 */ 9400int devlink_region_snapshot_create(struct devlink_region *region, 9401 u8 *data, u32 snapshot_id) 9402{ 9403 struct devlink *devlink = region->devlink; 9404 int err; 9405 9406 mutex_lock(&devlink->lock); 9407 err = __devlink_region_snapshot_create(region, data, snapshot_id); 9408 mutex_unlock(&devlink->lock); 9409 9410 return err; 9411} 9412EXPORT_SYMBOL_GPL(devlink_region_snapshot_create); 9413 9414#define DEVLINK_TRAP(_id, _type) \ 9415 { \ 9416 .type = DEVLINK_TRAP_TYPE_##_type, \ 9417 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \ 9418 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \ 9419 } 9420 9421static const struct devlink_trap devlink_trap_generic[] = { 9422 DEVLINK_TRAP(SMAC_MC, DROP), 9423 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP), 9424 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP), 9425 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP), 9426 DEVLINK_TRAP(EMPTY_TX_LIST, DROP), 9427 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP), 9428 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP), 9429 DEVLINK_TRAP(TTL_ERROR, EXCEPTION), 9430 DEVLINK_TRAP(TAIL_DROP, DROP), 9431 DEVLINK_TRAP(NON_IP_PACKET, DROP), 9432 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP), 9433 DEVLINK_TRAP(DIP_LB, DROP), 9434 DEVLINK_TRAP(SIP_MC, DROP), 9435 DEVLINK_TRAP(SIP_LB, DROP), 9436 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP), 9437 DEVLINK_TRAP(IPV4_SIP_BC, DROP), 9438 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP), 9439 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP), 9440 DEVLINK_TRAP(MTU_ERROR, EXCEPTION), 9441 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION), 9442 DEVLINK_TRAP(RPF, EXCEPTION), 9443 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION), 9444 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION), 9445 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION), 9446 DEVLINK_TRAP(NON_ROUTABLE, DROP), 9447 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION), 9448 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP), 9449 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP), 9450 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP), 9451 DEVLINK_TRAP(STP, CONTROL), 9452 DEVLINK_TRAP(LACP, CONTROL), 9453 DEVLINK_TRAP(LLDP, CONTROL), 9454 DEVLINK_TRAP(IGMP_QUERY, CONTROL), 9455 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL), 9456 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL), 9457 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL), 9458 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL), 9459 DEVLINK_TRAP(MLD_QUERY, CONTROL), 9460 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL), 9461 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL), 9462 DEVLINK_TRAP(MLD_V1_DONE, CONTROL), 9463 DEVLINK_TRAP(IPV4_DHCP, CONTROL), 9464 DEVLINK_TRAP(IPV6_DHCP, CONTROL), 9465 DEVLINK_TRAP(ARP_REQUEST, CONTROL), 9466 DEVLINK_TRAP(ARP_RESPONSE, CONTROL), 9467 DEVLINK_TRAP(ARP_OVERLAY, CONTROL), 9468 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL), 9469 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL), 9470 DEVLINK_TRAP(IPV4_BFD, CONTROL), 9471 DEVLINK_TRAP(IPV6_BFD, CONTROL), 9472 DEVLINK_TRAP(IPV4_OSPF, CONTROL), 9473 DEVLINK_TRAP(IPV6_OSPF, CONTROL), 9474 DEVLINK_TRAP(IPV4_BGP, CONTROL), 9475 DEVLINK_TRAP(IPV6_BGP, CONTROL), 9476 DEVLINK_TRAP(IPV4_VRRP, CONTROL), 9477 DEVLINK_TRAP(IPV6_VRRP, CONTROL), 9478 DEVLINK_TRAP(IPV4_PIM, CONTROL), 9479 DEVLINK_TRAP(IPV6_PIM, CONTROL), 9480 DEVLINK_TRAP(UC_LB, CONTROL), 9481 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL), 9482 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL), 9483 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL), 9484 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL), 9485 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL), 9486 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL), 9487 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL), 9488 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL), 9489 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL), 9490 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL), 9491 DEVLINK_TRAP(PTP_EVENT, CONTROL), 9492 DEVLINK_TRAP(PTP_GENERAL, CONTROL), 9493 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL), 9494 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL), 9495 DEVLINK_TRAP(EARLY_DROP, DROP), 9496 DEVLINK_TRAP(VXLAN_PARSING, DROP), 9497 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP), 9498 DEVLINK_TRAP(VLAN_PARSING, DROP), 9499 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP), 9500 DEVLINK_TRAP(MPLS_PARSING, DROP), 9501 DEVLINK_TRAP(ARP_PARSING, DROP), 9502 DEVLINK_TRAP(IP_1_PARSING, DROP), 9503 DEVLINK_TRAP(IP_N_PARSING, DROP), 9504 DEVLINK_TRAP(GRE_PARSING, DROP), 9505 DEVLINK_TRAP(UDP_PARSING, DROP), 9506 DEVLINK_TRAP(TCP_PARSING, DROP), 9507 DEVLINK_TRAP(IPSEC_PARSING, DROP), 9508 DEVLINK_TRAP(SCTP_PARSING, DROP), 9509 DEVLINK_TRAP(DCCP_PARSING, DROP), 9510 DEVLINK_TRAP(GTP_PARSING, DROP), 9511 DEVLINK_TRAP(ESP_PARSING, DROP), 9512}; 9513 9514#define DEVLINK_TRAP_GROUP(_id) \ 9515 { \ 9516 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \ 9517 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \ 9518 } 9519 9520static const struct devlink_trap_group devlink_trap_group_generic[] = { 9521 DEVLINK_TRAP_GROUP(L2_DROPS), 9522 DEVLINK_TRAP_GROUP(L3_DROPS), 9523 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS), 9524 DEVLINK_TRAP_GROUP(BUFFER_DROPS), 9525 DEVLINK_TRAP_GROUP(TUNNEL_DROPS), 9526 DEVLINK_TRAP_GROUP(ACL_DROPS), 9527 DEVLINK_TRAP_GROUP(STP), 9528 DEVLINK_TRAP_GROUP(LACP), 9529 DEVLINK_TRAP_GROUP(LLDP), 9530 DEVLINK_TRAP_GROUP(MC_SNOOPING), 9531 DEVLINK_TRAP_GROUP(DHCP), 9532 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY), 9533 DEVLINK_TRAP_GROUP(BFD), 9534 DEVLINK_TRAP_GROUP(OSPF), 9535 DEVLINK_TRAP_GROUP(BGP), 9536 DEVLINK_TRAP_GROUP(VRRP), 9537 DEVLINK_TRAP_GROUP(PIM), 9538 DEVLINK_TRAP_GROUP(UC_LB), 9539 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY), 9540 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY), 9541 DEVLINK_TRAP_GROUP(IPV6), 9542 DEVLINK_TRAP_GROUP(PTP_EVENT), 9543 DEVLINK_TRAP_GROUP(PTP_GENERAL), 9544 DEVLINK_TRAP_GROUP(ACL_SAMPLE), 9545 DEVLINK_TRAP_GROUP(ACL_TRAP), 9546 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS), 9547}; 9548 9549static int devlink_trap_generic_verify(const struct devlink_trap *trap) 9550{ 9551 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX) 9552 return -EINVAL; 9553 9554 if (strcmp(trap->name, devlink_trap_generic[trap->id].name)) 9555 return -EINVAL; 9556 9557 if (trap->type != devlink_trap_generic[trap->id].type) 9558 return -EINVAL; 9559 9560 return 0; 9561} 9562 9563static int devlink_trap_driver_verify(const struct devlink_trap *trap) 9564{ 9565 int i; 9566 9567 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX) 9568 return -EINVAL; 9569 9570 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) { 9571 if (!strcmp(trap->name, devlink_trap_generic[i].name)) 9572 return -EEXIST; 9573 } 9574 9575 return 0; 9576} 9577 9578static int devlink_trap_verify(const struct devlink_trap *trap) 9579{ 9580 if (!trap || !trap->name) 9581 return -EINVAL; 9582 9583 if (trap->generic) 9584 return devlink_trap_generic_verify(trap); 9585 else 9586 return devlink_trap_driver_verify(trap); 9587} 9588 9589static int 9590devlink_trap_group_generic_verify(const struct devlink_trap_group *group) 9591{ 9592 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) 9593 return -EINVAL; 9594 9595 if (strcmp(group->name, devlink_trap_group_generic[group->id].name)) 9596 return -EINVAL; 9597 9598 return 0; 9599} 9600 9601static int 9602devlink_trap_group_driver_verify(const struct devlink_trap_group *group) 9603{ 9604 int i; 9605 9606 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) 9607 return -EINVAL; 9608 9609 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) { 9610 if (!strcmp(group->name, devlink_trap_group_generic[i].name)) 9611 return -EEXIST; 9612 } 9613 9614 return 0; 9615} 9616 9617static int devlink_trap_group_verify(const struct devlink_trap_group *group) 9618{ 9619 if (group->generic) 9620 return devlink_trap_group_generic_verify(group); 9621 else 9622 return devlink_trap_group_driver_verify(group); 9623} 9624 9625static void 9626devlink_trap_group_notify(struct devlink *devlink, 9627 const struct devlink_trap_group_item *group_item, 9628 enum devlink_command cmd) 9629{ 9630 struct sk_buff *msg; 9631 int err; 9632 9633 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW && 9634 cmd != DEVLINK_CMD_TRAP_GROUP_DEL); 9635 9636 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 9637 if (!msg) 9638 return; 9639 9640 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0, 9641 0); 9642 if (err) { 9643 nlmsg_free(msg); 9644 return; 9645 } 9646 9647 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 9648 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 9649} 9650 9651static int 9652devlink_trap_item_group_link(struct devlink *devlink, 9653 struct devlink_trap_item *trap_item) 9654{ 9655 u16 group_id = trap_item->trap->init_group_id; 9656 struct devlink_trap_group_item *group_item; 9657 9658 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id); 9659 if (WARN_ON_ONCE(!group_item)) 9660 return -EINVAL; 9661 9662 trap_item->group_item = group_item; 9663 9664 return 0; 9665} 9666 9667static void devlink_trap_notify(struct devlink *devlink, 9668 const struct devlink_trap_item *trap_item, 9669 enum devlink_command cmd) 9670{ 9671 struct sk_buff *msg; 9672 int err; 9673 9674 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW && 9675 cmd != DEVLINK_CMD_TRAP_DEL); 9676 9677 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 9678 if (!msg) 9679 return; 9680 9681 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0); 9682 if (err) { 9683 nlmsg_free(msg); 9684 return; 9685 } 9686 9687 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 9688 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 9689} 9690 9691static int 9692devlink_trap_register(struct devlink *devlink, 9693 const struct devlink_trap *trap, void *priv) 9694{ 9695 struct devlink_trap_item *trap_item; 9696 int err; 9697 9698 if (devlink_trap_item_lookup(devlink, trap->name)) 9699 return -EEXIST; 9700 9701 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL); 9702 if (!trap_item) 9703 return -ENOMEM; 9704 9705 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); 9706 if (!trap_item->stats) { 9707 err = -ENOMEM; 9708 goto err_stats_alloc; 9709 } 9710 9711 trap_item->trap = trap; 9712 trap_item->action = trap->init_action; 9713 trap_item->priv = priv; 9714 9715 err = devlink_trap_item_group_link(devlink, trap_item); 9716 if (err) 9717 goto err_group_link; 9718 9719 err = devlink->ops->trap_init(devlink, trap, trap_item); 9720 if (err) 9721 goto err_trap_init; 9722 9723 list_add_tail(&trap_item->list, &devlink->trap_list); 9724 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW); 9725 9726 return 0; 9727 9728err_trap_init: 9729err_group_link: 9730 free_percpu(trap_item->stats); 9731err_stats_alloc: 9732 kfree(trap_item); 9733 return err; 9734} 9735 9736static void devlink_trap_unregister(struct devlink *devlink, 9737 const struct devlink_trap *trap) 9738{ 9739 struct devlink_trap_item *trap_item; 9740 9741 trap_item = devlink_trap_item_lookup(devlink, trap->name); 9742 if (WARN_ON_ONCE(!trap_item)) 9743 return; 9744 9745 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL); 9746 list_del(&trap_item->list); 9747 if (devlink->ops->trap_fini) 9748 devlink->ops->trap_fini(devlink, trap, trap_item); 9749 free_percpu(trap_item->stats); 9750 kfree(trap_item); 9751} 9752 9753static void devlink_trap_disable(struct devlink *devlink, 9754 const struct devlink_trap *trap) 9755{ 9756 struct devlink_trap_item *trap_item; 9757 9758 trap_item = devlink_trap_item_lookup(devlink, trap->name); 9759 if (WARN_ON_ONCE(!trap_item)) 9760 return; 9761 9762 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP, 9763 NULL); 9764 trap_item->action = DEVLINK_TRAP_ACTION_DROP; 9765} 9766 9767/** 9768 * devlink_traps_register - Register packet traps with devlink. 9769 * @devlink: devlink. 9770 * @traps: Packet traps. 9771 * @traps_count: Count of provided packet traps. 9772 * @priv: Driver private information. 9773 * 9774 * Return: Non-zero value on failure. 9775 */ 9776int devlink_traps_register(struct devlink *devlink, 9777 const struct devlink_trap *traps, 9778 size_t traps_count, void *priv) 9779{ 9780 int i, err; 9781 9782 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set) 9783 return -EINVAL; 9784 9785 mutex_lock(&devlink->lock); 9786 for (i = 0; i < traps_count; i++) { 9787 const struct devlink_trap *trap = &traps[i]; 9788 9789 err = devlink_trap_verify(trap); 9790 if (err) 9791 goto err_trap_verify; 9792 9793 err = devlink_trap_register(devlink, trap, priv); 9794 if (err) 9795 goto err_trap_register; 9796 } 9797 mutex_unlock(&devlink->lock); 9798 9799 return 0; 9800 9801err_trap_register: 9802err_trap_verify: 9803 for (i--; i >= 0; i--) 9804 devlink_trap_unregister(devlink, &traps[i]); 9805 mutex_unlock(&devlink->lock); 9806 return err; 9807} 9808EXPORT_SYMBOL_GPL(devlink_traps_register); 9809 9810/** 9811 * devlink_traps_unregister - Unregister packet traps from devlink. 9812 * @devlink: devlink. 9813 * @traps: Packet traps. 9814 * @traps_count: Count of provided packet traps. 9815 */ 9816void devlink_traps_unregister(struct devlink *devlink, 9817 const struct devlink_trap *traps, 9818 size_t traps_count) 9819{ 9820 int i; 9821 9822 mutex_lock(&devlink->lock); 9823 /* Make sure we do not have any packets in-flight while unregistering 9824 * traps by disabling all of them and waiting for a grace period. 9825 */ 9826 for (i = traps_count - 1; i >= 0; i--) 9827 devlink_trap_disable(devlink, &traps[i]); 9828 synchronize_rcu(); 9829 for (i = traps_count - 1; i >= 0; i--) 9830 devlink_trap_unregister(devlink, &traps[i]); 9831 mutex_unlock(&devlink->lock); 9832} 9833EXPORT_SYMBOL_GPL(devlink_traps_unregister); 9834 9835static void 9836devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats, 9837 size_t skb_len) 9838{ 9839 struct devlink_stats *stats; 9840 9841 stats = this_cpu_ptr(trap_stats); 9842 u64_stats_update_begin(&stats->syncp); 9843 stats->rx_bytes += skb_len; 9844 stats->rx_packets++; 9845 u64_stats_update_end(&stats->syncp); 9846} 9847 9848static void 9849devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata, 9850 const struct devlink_trap_item *trap_item, 9851 struct devlink_port *in_devlink_port, 9852 const struct flow_action_cookie *fa_cookie) 9853{ 9854 metadata->trap_name = trap_item->trap->name; 9855 metadata->trap_group_name = trap_item->group_item->group->name; 9856 metadata->fa_cookie = fa_cookie; 9857 metadata->trap_type = trap_item->trap->type; 9858 9859 spin_lock(&in_devlink_port->type_lock); 9860 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH) 9861 metadata->input_dev = in_devlink_port->type_dev; 9862 spin_unlock(&in_devlink_port->type_lock); 9863} 9864 9865/** 9866 * devlink_trap_report - Report trapped packet to drop monitor. 9867 * @devlink: devlink. 9868 * @skb: Trapped packet. 9869 * @trap_ctx: Trap context. 9870 * @in_devlink_port: Input devlink port. 9871 * @fa_cookie: Flow action cookie. Could be NULL. 9872 */ 9873void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb, 9874 void *trap_ctx, struct devlink_port *in_devlink_port, 9875 const struct flow_action_cookie *fa_cookie) 9876 9877{ 9878 struct devlink_trap_item *trap_item = trap_ctx; 9879 9880 devlink_trap_stats_update(trap_item->stats, skb->len); 9881 devlink_trap_stats_update(trap_item->group_item->stats, skb->len); 9882 9883 if (trace_devlink_trap_report_enabled()) { 9884 struct devlink_trap_metadata metadata = {}; 9885 9886 devlink_trap_report_metadata_set(&metadata, trap_item, 9887 in_devlink_port, fa_cookie); 9888 trace_devlink_trap_report(devlink, skb, &metadata); 9889 } 9890} 9891EXPORT_SYMBOL_GPL(devlink_trap_report); 9892 9893/** 9894 * devlink_trap_ctx_priv - Trap context to driver private information. 9895 * @trap_ctx: Trap context. 9896 * 9897 * Return: Driver private information passed during registration. 9898 */ 9899void *devlink_trap_ctx_priv(void *trap_ctx) 9900{ 9901 struct devlink_trap_item *trap_item = trap_ctx; 9902 9903 return trap_item->priv; 9904} 9905EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv); 9906 9907static int 9908devlink_trap_group_item_policer_link(struct devlink *devlink, 9909 struct devlink_trap_group_item *group_item) 9910{ 9911 u32 policer_id = group_item->group->init_policer_id; 9912 struct devlink_trap_policer_item *policer_item; 9913 9914 if (policer_id == 0) 9915 return 0; 9916 9917 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id); 9918 if (WARN_ON_ONCE(!policer_item)) 9919 return -EINVAL; 9920 9921 group_item->policer_item = policer_item; 9922 9923 return 0; 9924} 9925 9926static int 9927devlink_trap_group_register(struct devlink *devlink, 9928 const struct devlink_trap_group *group) 9929{ 9930 struct devlink_trap_group_item *group_item; 9931 int err; 9932 9933 if (devlink_trap_group_item_lookup(devlink, group->name)) 9934 return -EEXIST; 9935 9936 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL); 9937 if (!group_item) 9938 return -ENOMEM; 9939 9940 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); 9941 if (!group_item->stats) { 9942 err = -ENOMEM; 9943 goto err_stats_alloc; 9944 } 9945 9946 group_item->group = group; 9947 9948 err = devlink_trap_group_item_policer_link(devlink, group_item); 9949 if (err) 9950 goto err_policer_link; 9951 9952 if (devlink->ops->trap_group_init) { 9953 err = devlink->ops->trap_group_init(devlink, group); 9954 if (err) 9955 goto err_group_init; 9956 } 9957 9958 list_add_tail(&group_item->list, &devlink->trap_group_list); 9959 devlink_trap_group_notify(devlink, group_item, 9960 DEVLINK_CMD_TRAP_GROUP_NEW); 9961 9962 return 0; 9963 9964err_group_init: 9965err_policer_link: 9966 free_percpu(group_item->stats); 9967err_stats_alloc: 9968 kfree(group_item); 9969 return err; 9970} 9971 9972static void 9973devlink_trap_group_unregister(struct devlink *devlink, 9974 const struct devlink_trap_group *group) 9975{ 9976 struct devlink_trap_group_item *group_item; 9977 9978 group_item = devlink_trap_group_item_lookup(devlink, group->name); 9979 if (WARN_ON_ONCE(!group_item)) 9980 return; 9981 9982 devlink_trap_group_notify(devlink, group_item, 9983 DEVLINK_CMD_TRAP_GROUP_DEL); 9984 list_del(&group_item->list); 9985 free_percpu(group_item->stats); 9986 kfree(group_item); 9987} 9988 9989/** 9990 * devlink_trap_groups_register - Register packet trap groups with devlink. 9991 * @devlink: devlink. 9992 * @groups: Packet trap groups. 9993 * @groups_count: Count of provided packet trap groups. 9994 * 9995 * Return: Non-zero value on failure. 9996 */ 9997int devlink_trap_groups_register(struct devlink *devlink, 9998 const struct devlink_trap_group *groups, 9999 size_t groups_count) 10000{ 10001 int i, err; 10002 10003 mutex_lock(&devlink->lock); 10004 for (i = 0; i < groups_count; i++) { 10005 const struct devlink_trap_group *group = &groups[i]; 10006 10007 err = devlink_trap_group_verify(group); 10008 if (err) 10009 goto err_trap_group_verify; 10010 10011 err = devlink_trap_group_register(devlink, group); 10012 if (err) 10013 goto err_trap_group_register; 10014 } 10015 mutex_unlock(&devlink->lock); 10016 10017 return 0; 10018 10019err_trap_group_register: 10020err_trap_group_verify: 10021 for (i--; i >= 0; i--) 10022 devlink_trap_group_unregister(devlink, &groups[i]); 10023 mutex_unlock(&devlink->lock); 10024 return err; 10025} 10026EXPORT_SYMBOL_GPL(devlink_trap_groups_register); 10027 10028/** 10029 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink. 10030 * @devlink: devlink. 10031 * @groups: Packet trap groups. 10032 * @groups_count: Count of provided packet trap groups. 10033 */ 10034void devlink_trap_groups_unregister(struct devlink *devlink, 10035 const struct devlink_trap_group *groups, 10036 size_t groups_count) 10037{ 10038 int i; 10039 10040 mutex_lock(&devlink->lock); 10041 for (i = groups_count - 1; i >= 0; i--) 10042 devlink_trap_group_unregister(devlink, &groups[i]); 10043 mutex_unlock(&devlink->lock); 10044} 10045EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister); 10046 10047static void 10048devlink_trap_policer_notify(struct devlink *devlink, 10049 const struct devlink_trap_policer_item *policer_item, 10050 enum devlink_command cmd) 10051{ 10052 struct sk_buff *msg; 10053 int err; 10054 10055 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW && 10056 cmd != DEVLINK_CMD_TRAP_POLICER_DEL); 10057 10058 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 10059 if (!msg) 10060 return; 10061 10062 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0, 10063 0, 0); 10064 if (err) { 10065 nlmsg_free(msg); 10066 return; 10067 } 10068 10069 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 10070 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 10071} 10072 10073static int 10074devlink_trap_policer_register(struct devlink *devlink, 10075 const struct devlink_trap_policer *policer) 10076{ 10077 struct devlink_trap_policer_item *policer_item; 10078 int err; 10079 10080 if (devlink_trap_policer_item_lookup(devlink, policer->id)) 10081 return -EEXIST; 10082 10083 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL); 10084 if (!policer_item) 10085 return -ENOMEM; 10086 10087 policer_item->policer = policer; 10088 policer_item->rate = policer->init_rate; 10089 policer_item->burst = policer->init_burst; 10090 10091 if (devlink->ops->trap_policer_init) { 10092 err = devlink->ops->trap_policer_init(devlink, policer); 10093 if (err) 10094 goto err_policer_init; 10095 } 10096 10097 list_add_tail(&policer_item->list, &devlink->trap_policer_list); 10098 devlink_trap_policer_notify(devlink, policer_item, 10099 DEVLINK_CMD_TRAP_POLICER_NEW); 10100 10101 return 0; 10102 10103err_policer_init: 10104 kfree(policer_item); 10105 return err; 10106} 10107 10108static void 10109devlink_trap_policer_unregister(struct devlink *devlink, 10110 const struct devlink_trap_policer *policer) 10111{ 10112 struct devlink_trap_policer_item *policer_item; 10113 10114 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id); 10115 if (WARN_ON_ONCE(!policer_item)) 10116 return; 10117 10118 devlink_trap_policer_notify(devlink, policer_item, 10119 DEVLINK_CMD_TRAP_POLICER_DEL); 10120 list_del(&policer_item->list); 10121 if (devlink->ops->trap_policer_fini) 10122 devlink->ops->trap_policer_fini(devlink, policer); 10123 kfree(policer_item); 10124} 10125 10126/** 10127 * devlink_trap_policers_register - Register packet trap policers with devlink. 10128 * @devlink: devlink. 10129 * @policers: Packet trap policers. 10130 * @policers_count: Count of provided packet trap policers. 10131 * 10132 * Return: Non-zero value on failure. 10133 */ 10134int 10135devlink_trap_policers_register(struct devlink *devlink, 10136 const struct devlink_trap_policer *policers, 10137 size_t policers_count) 10138{ 10139 int i, err; 10140 10141 mutex_lock(&devlink->lock); 10142 for (i = 0; i < policers_count; i++) { 10143 const struct devlink_trap_policer *policer = &policers[i]; 10144 10145 if (WARN_ON(policer->id == 0 || 10146 policer->max_rate < policer->min_rate || 10147 policer->max_burst < policer->min_burst)) { 10148 err = -EINVAL; 10149 goto err_trap_policer_verify; 10150 } 10151 10152 err = devlink_trap_policer_register(devlink, policer); 10153 if (err) 10154 goto err_trap_policer_register; 10155 } 10156 mutex_unlock(&devlink->lock); 10157 10158 return 0; 10159 10160err_trap_policer_register: 10161err_trap_policer_verify: 10162 for (i--; i >= 0; i--) 10163 devlink_trap_policer_unregister(devlink, &policers[i]); 10164 mutex_unlock(&devlink->lock); 10165 return err; 10166} 10167EXPORT_SYMBOL_GPL(devlink_trap_policers_register); 10168 10169/** 10170 * devlink_trap_policers_unregister - Unregister packet trap policers from devlink. 10171 * @devlink: devlink. 10172 * @policers: Packet trap policers. 10173 * @policers_count: Count of provided packet trap policers. 10174 */ 10175void 10176devlink_trap_policers_unregister(struct devlink *devlink, 10177 const struct devlink_trap_policer *policers, 10178 size_t policers_count) 10179{ 10180 int i; 10181 10182 mutex_lock(&devlink->lock); 10183 for (i = policers_count - 1; i >= 0; i--) 10184 devlink_trap_policer_unregister(devlink, &policers[i]); 10185 mutex_unlock(&devlink->lock); 10186} 10187EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister); 10188 10189static void __devlink_compat_running_version(struct devlink *devlink, 10190 char *buf, size_t len) 10191{ 10192 const struct nlattr *nlattr; 10193 struct devlink_info_req req; 10194 struct sk_buff *msg; 10195 int rem, err; 10196 10197 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 10198 if (!msg) 10199 return; 10200 10201 req.msg = msg; 10202 err = devlink->ops->info_get(devlink, &req, NULL); 10203 if (err) 10204 goto free_msg; 10205 10206 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) { 10207 const struct nlattr *kv; 10208 int rem_kv; 10209 10210 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING) 10211 continue; 10212 10213 nla_for_each_nested(kv, nlattr, rem_kv) { 10214 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE) 10215 continue; 10216 10217 strlcat(buf, nla_data(kv), len); 10218 strlcat(buf, " ", len); 10219 } 10220 } 10221free_msg: 10222 nlmsg_free(msg); 10223} 10224 10225void devlink_compat_running_version(struct net_device *dev, 10226 char *buf, size_t len) 10227{ 10228 struct devlink *devlink; 10229 10230 dev_hold(dev); 10231 rtnl_unlock(); 10232 10233 devlink = netdev_to_devlink(dev); 10234 if (!devlink || !devlink->ops->info_get) 10235 goto out; 10236 10237 mutex_lock(&devlink->lock); 10238 __devlink_compat_running_version(devlink, buf, len); 10239 mutex_unlock(&devlink->lock); 10240 10241out: 10242 rtnl_lock(); 10243 dev_put(dev); 10244} 10245 10246int devlink_compat_flash_update(struct net_device *dev, const char *file_name) 10247{ 10248 struct devlink_flash_update_params params = {}; 10249 struct devlink *devlink; 10250 int ret; 10251 10252 dev_hold(dev); 10253 rtnl_unlock(); 10254 10255 devlink = netdev_to_devlink(dev); 10256 if (!devlink || !devlink->ops->flash_update) { 10257 ret = -EOPNOTSUPP; 10258 goto out; 10259 } 10260 10261 params.file_name = file_name; 10262 10263 mutex_lock(&devlink->lock); 10264 ret = devlink->ops->flash_update(devlink, ¶ms, NULL); 10265 mutex_unlock(&devlink->lock); 10266 10267out: 10268 rtnl_lock(); 10269 dev_put(dev); 10270 10271 return ret; 10272} 10273 10274int devlink_compat_phys_port_name_get(struct net_device *dev, 10275 char *name, size_t len) 10276{ 10277 struct devlink_port *devlink_port; 10278 10279 /* RTNL mutex is held here which ensures that devlink_port 10280 * instance cannot disappear in the middle. No need to take 10281 * any devlink lock as only permanent values are accessed. 10282 */ 10283 ASSERT_RTNL(); 10284 10285 devlink_port = netdev_to_devlink_port(dev); 10286 if (!devlink_port) 10287 return -EOPNOTSUPP; 10288 10289 return __devlink_port_phys_port_name_get(devlink_port, name, len); 10290} 10291 10292int devlink_compat_switch_id_get(struct net_device *dev, 10293 struct netdev_phys_item_id *ppid) 10294{ 10295 struct devlink_port *devlink_port; 10296 10297 /* Caller must hold RTNL mutex or reference to dev, which ensures that 10298 * devlink_port instance cannot disappear in the middle. No need to take 10299 * any devlink lock as only permanent values are accessed. 10300 */ 10301 devlink_port = netdev_to_devlink_port(dev); 10302 if (!devlink_port || !devlink_port->switch_port) 10303 return -EOPNOTSUPP; 10304 10305 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid)); 10306 10307 return 0; 10308} 10309 10310static void __net_exit devlink_pernet_pre_exit(struct net *net) 10311{ 10312 struct devlink *devlink; 10313 u32 actions_performed; 10314 int err; 10315 10316 /* In case network namespace is getting destroyed, reload 10317 * all devlink instances from this namespace into init_net. 10318 */ 10319 mutex_lock(&devlink_mutex); 10320 list_for_each_entry(devlink, &devlink_list, list) { 10321 if (net_eq(devlink_net(devlink), net)) { 10322 if (WARN_ON(!devlink_reload_supported(devlink->ops))) 10323 continue; 10324 err = devlink_reload(devlink, &init_net, 10325 DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 10326 DEVLINK_RELOAD_LIMIT_UNSPEC, 10327 &actions_performed, NULL); 10328 if (err && err != -EOPNOTSUPP) 10329 pr_warn("Failed to reload devlink instance into init_net\n"); 10330 } 10331 } 10332 mutex_unlock(&devlink_mutex); 10333} 10334 10335static struct pernet_operations devlink_pernet_ops __net_initdata = { 10336 .pre_exit = devlink_pernet_pre_exit, 10337}; 10338 10339static int __init devlink_init(void) 10340{ 10341 int err; 10342 10343 err = genl_register_family(&devlink_nl_family); 10344 if (err) 10345 goto out; 10346 err = register_pernet_subsys(&devlink_pernet_ops); 10347 10348out: 10349 WARN_ON(err); 10350 return err; 10351} 10352 10353subsys_initcall(devlink_init); 10354