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