at v5.10 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 3397void 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} 3405EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify); 3406 3407void devlink_flash_update_end_notify(struct devlink *devlink) 3408{ 3409 struct devlink_flash_notify params = { 0 }; 3410 3411 __devlink_flash_update_notify(devlink, 3412 DEVLINK_CMD_FLASH_UPDATE_END, 3413 &params); 3414} 3415EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify); 3416 3417void devlink_flash_update_status_notify(struct devlink *devlink, 3418 const char *status_msg, 3419 const char *component, 3420 unsigned long done, 3421 unsigned long total) 3422{ 3423 struct devlink_flash_notify params = { 3424 .status_msg = status_msg, 3425 .component = component, 3426 .done = done, 3427 .total = total, 3428 }; 3429 3430 __devlink_flash_update_notify(devlink, 3431 DEVLINK_CMD_FLASH_UPDATE_STATUS, 3432 &params); 3433} 3434EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); 3435 3436void devlink_flash_update_timeout_notify(struct devlink *devlink, 3437 const char *status_msg, 3438 const char *component, 3439 unsigned long timeout) 3440{ 3441 struct devlink_flash_notify params = { 3442 .status_msg = status_msg, 3443 .component = component, 3444 .timeout = timeout, 3445 }; 3446 3447 __devlink_flash_update_notify(devlink, 3448 DEVLINK_CMD_FLASH_UPDATE_STATUS, 3449 &params); 3450} 3451EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); 3452 3453static int devlink_nl_cmd_flash_update(struct sk_buff *skb, 3454 struct genl_info *info) 3455{ 3456 struct nlattr *nla_component, *nla_overwrite_mask; 3457 struct devlink_flash_update_params params = {}; 3458 struct devlink *devlink = info->user_ptr[0]; 3459 u32 supported_params; 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 params.file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]); 3470 3471 nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT]; 3472 if (nla_component) { 3473 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT)) { 3474 NL_SET_ERR_MSG_ATTR(info->extack, nla_component, 3475 "component update is not supported by this device"); 3476 return -EOPNOTSUPP; 3477 } 3478 params.component = nla_data(nla_component); 3479 } 3480 3481 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK]; 3482 if (nla_overwrite_mask) { 3483 struct nla_bitfield32 sections; 3484 3485 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) { 3486 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask, 3487 "overwrite settings are not supported by this device"); 3488 return -EOPNOTSUPP; 3489 } 3490 sections = nla_get_bitfield32(nla_overwrite_mask); 3491 params.overwrite_mask = sections.value & sections.selector; 3492 } 3493 3494 return devlink->ops->flash_update(devlink, &params, info->extack); 3495} 3496 3497static const struct devlink_param devlink_param_generic[] = { 3498 { 3499 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET, 3500 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME, 3501 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE, 3502 }, 3503 { 3504 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS, 3505 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME, 3506 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE, 3507 }, 3508 { 3509 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, 3510 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME, 3511 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE, 3512 }, 3513 { 3514 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT, 3515 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME, 3516 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE, 3517 }, 3518 { 3519 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, 3520 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME, 3521 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE, 3522 }, 3523 { 3524 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX, 3525 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME, 3526 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE, 3527 }, 3528 { 3529 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN, 3530 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME, 3531 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE, 3532 }, 3533 { 3534 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY, 3535 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME, 3536 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE, 3537 }, 3538 { 3539 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE, 3540 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME, 3541 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE, 3542 }, 3543 { 3544 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, 3545 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME, 3546 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE, 3547 }, 3548 { 3549 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET, 3550 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME, 3551 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE, 3552 }, 3553}; 3554 3555static int devlink_param_generic_verify(const struct devlink_param *param) 3556{ 3557 /* verify it match generic parameter by id and name */ 3558 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX) 3559 return -EINVAL; 3560 if (strcmp(param->name, devlink_param_generic[param->id].name)) 3561 return -ENOENT; 3562 3563 WARN_ON(param->type != devlink_param_generic[param->id].type); 3564 3565 return 0; 3566} 3567 3568static int devlink_param_driver_verify(const struct devlink_param *param) 3569{ 3570 int i; 3571 3572 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX) 3573 return -EINVAL; 3574 /* verify no such name in generic params */ 3575 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++) 3576 if (!strcmp(param->name, devlink_param_generic[i].name)) 3577 return -EEXIST; 3578 3579 return 0; 3580} 3581 3582static struct devlink_param_item * 3583devlink_param_find_by_name(struct list_head *param_list, 3584 const char *param_name) 3585{ 3586 struct devlink_param_item *param_item; 3587 3588 list_for_each_entry(param_item, param_list, list) 3589 if (!strcmp(param_item->param->name, param_name)) 3590 return param_item; 3591 return NULL; 3592} 3593 3594static struct devlink_param_item * 3595devlink_param_find_by_id(struct list_head *param_list, u32 param_id) 3596{ 3597 struct devlink_param_item *param_item; 3598 3599 list_for_each_entry(param_item, param_list, list) 3600 if (param_item->param->id == param_id) 3601 return param_item; 3602 return NULL; 3603} 3604 3605static bool 3606devlink_param_cmode_is_supported(const struct devlink_param *param, 3607 enum devlink_param_cmode cmode) 3608{ 3609 return test_bit(cmode, &param->supported_cmodes); 3610} 3611 3612static int devlink_param_get(struct devlink *devlink, 3613 const struct devlink_param *param, 3614 struct devlink_param_gset_ctx *ctx) 3615{ 3616 if (!param->get) 3617 return -EOPNOTSUPP; 3618 return param->get(devlink, param->id, ctx); 3619} 3620 3621static int devlink_param_set(struct devlink *devlink, 3622 const struct devlink_param *param, 3623 struct devlink_param_gset_ctx *ctx) 3624{ 3625 if (!param->set) 3626 return -EOPNOTSUPP; 3627 return param->set(devlink, param->id, ctx); 3628} 3629 3630static int 3631devlink_param_type_to_nla_type(enum devlink_param_type param_type) 3632{ 3633 switch (param_type) { 3634 case DEVLINK_PARAM_TYPE_U8: 3635 return NLA_U8; 3636 case DEVLINK_PARAM_TYPE_U16: 3637 return NLA_U16; 3638 case DEVLINK_PARAM_TYPE_U32: 3639 return NLA_U32; 3640 case DEVLINK_PARAM_TYPE_STRING: 3641 return NLA_STRING; 3642 case DEVLINK_PARAM_TYPE_BOOL: 3643 return NLA_FLAG; 3644 default: 3645 return -EINVAL; 3646 } 3647} 3648 3649static int 3650devlink_nl_param_value_fill_one(struct sk_buff *msg, 3651 enum devlink_param_type type, 3652 enum devlink_param_cmode cmode, 3653 union devlink_param_value val) 3654{ 3655 struct nlattr *param_value_attr; 3656 3657 param_value_attr = nla_nest_start_noflag(msg, 3658 DEVLINK_ATTR_PARAM_VALUE); 3659 if (!param_value_attr) 3660 goto nla_put_failure; 3661 3662 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode)) 3663 goto value_nest_cancel; 3664 3665 switch (type) { 3666 case DEVLINK_PARAM_TYPE_U8: 3667 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8)) 3668 goto value_nest_cancel; 3669 break; 3670 case DEVLINK_PARAM_TYPE_U16: 3671 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16)) 3672 goto value_nest_cancel; 3673 break; 3674 case DEVLINK_PARAM_TYPE_U32: 3675 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32)) 3676 goto value_nest_cancel; 3677 break; 3678 case DEVLINK_PARAM_TYPE_STRING: 3679 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, 3680 val.vstr)) 3681 goto value_nest_cancel; 3682 break; 3683 case DEVLINK_PARAM_TYPE_BOOL: 3684 if (val.vbool && 3685 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA)) 3686 goto value_nest_cancel; 3687 break; 3688 } 3689 3690 nla_nest_end(msg, param_value_attr); 3691 return 0; 3692 3693value_nest_cancel: 3694 nla_nest_cancel(msg, param_value_attr); 3695nla_put_failure: 3696 return -EMSGSIZE; 3697} 3698 3699static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, 3700 unsigned int port_index, 3701 struct devlink_param_item *param_item, 3702 enum devlink_command cmd, 3703 u32 portid, u32 seq, int flags) 3704{ 3705 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1]; 3706 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; 3707 const struct devlink_param *param = param_item->param; 3708 struct devlink_param_gset_ctx ctx; 3709 struct nlattr *param_values_list; 3710 struct nlattr *param_attr; 3711 int nla_type; 3712 void *hdr; 3713 int err; 3714 int i; 3715 3716 /* Get value from driver part to driverinit configuration mode */ 3717 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 3718 if (!devlink_param_cmode_is_supported(param, i)) 3719 continue; 3720 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) { 3721 if (!param_item->driverinit_value_valid) 3722 return -EOPNOTSUPP; 3723 param_value[i] = param_item->driverinit_value; 3724 } else { 3725 if (!param_item->published) 3726 continue; 3727 ctx.cmode = i; 3728 err = devlink_param_get(devlink, param, &ctx); 3729 if (err) 3730 return err; 3731 param_value[i] = ctx.val; 3732 } 3733 param_value_set[i] = true; 3734 } 3735 3736 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 3737 if (!hdr) 3738 return -EMSGSIZE; 3739 3740 if (devlink_nl_put_handle(msg, devlink)) 3741 goto genlmsg_cancel; 3742 3743 if (cmd == DEVLINK_CMD_PORT_PARAM_GET || 3744 cmd == DEVLINK_CMD_PORT_PARAM_NEW || 3745 cmd == DEVLINK_CMD_PORT_PARAM_DEL) 3746 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index)) 3747 goto genlmsg_cancel; 3748 3749 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM); 3750 if (!param_attr) 3751 goto genlmsg_cancel; 3752 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name)) 3753 goto param_nest_cancel; 3754 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC)) 3755 goto param_nest_cancel; 3756 3757 nla_type = devlink_param_type_to_nla_type(param->type); 3758 if (nla_type < 0) 3759 goto param_nest_cancel; 3760 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type)) 3761 goto param_nest_cancel; 3762 3763 param_values_list = nla_nest_start_noflag(msg, 3764 DEVLINK_ATTR_PARAM_VALUES_LIST); 3765 if (!param_values_list) 3766 goto param_nest_cancel; 3767 3768 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 3769 if (!param_value_set[i]) 3770 continue; 3771 err = devlink_nl_param_value_fill_one(msg, param->type, 3772 i, param_value[i]); 3773 if (err) 3774 goto values_list_nest_cancel; 3775 } 3776 3777 nla_nest_end(msg, param_values_list); 3778 nla_nest_end(msg, param_attr); 3779 genlmsg_end(msg, hdr); 3780 return 0; 3781 3782values_list_nest_cancel: 3783 nla_nest_end(msg, param_values_list); 3784param_nest_cancel: 3785 nla_nest_cancel(msg, param_attr); 3786genlmsg_cancel: 3787 genlmsg_cancel(msg, hdr); 3788 return -EMSGSIZE; 3789} 3790 3791static void devlink_param_notify(struct devlink *devlink, 3792 unsigned int port_index, 3793 struct devlink_param_item *param_item, 3794 enum devlink_command cmd) 3795{ 3796 struct sk_buff *msg; 3797 int err; 3798 3799 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL && 3800 cmd != DEVLINK_CMD_PORT_PARAM_NEW && 3801 cmd != DEVLINK_CMD_PORT_PARAM_DEL); 3802 3803 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3804 if (!msg) 3805 return; 3806 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd, 3807 0, 0, 0); 3808 if (err) { 3809 nlmsg_free(msg); 3810 return; 3811 } 3812 3813 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 3814 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 3815} 3816 3817static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg, 3818 struct netlink_callback *cb) 3819{ 3820 struct devlink_param_item *param_item; 3821 struct devlink *devlink; 3822 int start = cb->args[0]; 3823 int idx = 0; 3824 int err = 0; 3825 3826 mutex_lock(&devlink_mutex); 3827 list_for_each_entry(devlink, &devlink_list, list) { 3828 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 3829 continue; 3830 mutex_lock(&devlink->lock); 3831 list_for_each_entry(param_item, &devlink->param_list, list) { 3832 if (idx < start) { 3833 idx++; 3834 continue; 3835 } 3836 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 3837 DEVLINK_CMD_PARAM_GET, 3838 NETLINK_CB(cb->skb).portid, 3839 cb->nlh->nlmsg_seq, 3840 NLM_F_MULTI); 3841 if (err == -EOPNOTSUPP) { 3842 err = 0; 3843 } else if (err) { 3844 mutex_unlock(&devlink->lock); 3845 goto out; 3846 } 3847 idx++; 3848 } 3849 mutex_unlock(&devlink->lock); 3850 } 3851out: 3852 mutex_unlock(&devlink_mutex); 3853 3854 if (err != -EMSGSIZE) 3855 return err; 3856 3857 cb->args[0] = idx; 3858 return msg->len; 3859} 3860 3861static int 3862devlink_param_type_get_from_info(struct genl_info *info, 3863 enum devlink_param_type *param_type) 3864{ 3865 if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE]) 3866 return -EINVAL; 3867 3868 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) { 3869 case NLA_U8: 3870 *param_type = DEVLINK_PARAM_TYPE_U8; 3871 break; 3872 case NLA_U16: 3873 *param_type = DEVLINK_PARAM_TYPE_U16; 3874 break; 3875 case NLA_U32: 3876 *param_type = DEVLINK_PARAM_TYPE_U32; 3877 break; 3878 case NLA_STRING: 3879 *param_type = DEVLINK_PARAM_TYPE_STRING; 3880 break; 3881 case NLA_FLAG: 3882 *param_type = DEVLINK_PARAM_TYPE_BOOL; 3883 break; 3884 default: 3885 return -EINVAL; 3886 } 3887 3888 return 0; 3889} 3890 3891static int 3892devlink_param_value_get_from_info(const struct devlink_param *param, 3893 struct genl_info *info, 3894 union devlink_param_value *value) 3895{ 3896 struct nlattr *param_data; 3897 int len; 3898 3899 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]; 3900 3901 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data) 3902 return -EINVAL; 3903 3904 switch (param->type) { 3905 case DEVLINK_PARAM_TYPE_U8: 3906 if (nla_len(param_data) != sizeof(u8)) 3907 return -EINVAL; 3908 value->vu8 = nla_get_u8(param_data); 3909 break; 3910 case DEVLINK_PARAM_TYPE_U16: 3911 if (nla_len(param_data) != sizeof(u16)) 3912 return -EINVAL; 3913 value->vu16 = nla_get_u16(param_data); 3914 break; 3915 case DEVLINK_PARAM_TYPE_U32: 3916 if (nla_len(param_data) != sizeof(u32)) 3917 return -EINVAL; 3918 value->vu32 = nla_get_u32(param_data); 3919 break; 3920 case DEVLINK_PARAM_TYPE_STRING: 3921 len = strnlen(nla_data(param_data), nla_len(param_data)); 3922 if (len == nla_len(param_data) || 3923 len >= __DEVLINK_PARAM_MAX_STRING_VALUE) 3924 return -EINVAL; 3925 strcpy(value->vstr, nla_data(param_data)); 3926 break; 3927 case DEVLINK_PARAM_TYPE_BOOL: 3928 if (param_data && nla_len(param_data)) 3929 return -EINVAL; 3930 value->vbool = nla_get_flag(param_data); 3931 break; 3932 } 3933 return 0; 3934} 3935 3936static struct devlink_param_item * 3937devlink_param_get_from_info(struct list_head *param_list, 3938 struct genl_info *info) 3939{ 3940 char *param_name; 3941 3942 if (!info->attrs[DEVLINK_ATTR_PARAM_NAME]) 3943 return NULL; 3944 3945 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]); 3946 return devlink_param_find_by_name(param_list, param_name); 3947} 3948 3949static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb, 3950 struct genl_info *info) 3951{ 3952 struct devlink *devlink = info->user_ptr[0]; 3953 struct devlink_param_item *param_item; 3954 struct sk_buff *msg; 3955 int err; 3956 3957 param_item = devlink_param_get_from_info(&devlink->param_list, info); 3958 if (!param_item) 3959 return -EINVAL; 3960 3961 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3962 if (!msg) 3963 return -ENOMEM; 3964 3965 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 3966 DEVLINK_CMD_PARAM_GET, 3967 info->snd_portid, info->snd_seq, 0); 3968 if (err) { 3969 nlmsg_free(msg); 3970 return err; 3971 } 3972 3973 return genlmsg_reply(msg, info); 3974} 3975 3976static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, 3977 unsigned int port_index, 3978 struct list_head *param_list, 3979 struct genl_info *info, 3980 enum devlink_command cmd) 3981{ 3982 enum devlink_param_type param_type; 3983 struct devlink_param_gset_ctx ctx; 3984 enum devlink_param_cmode cmode; 3985 struct devlink_param_item *param_item; 3986 const struct devlink_param *param; 3987 union devlink_param_value value; 3988 int err = 0; 3989 3990 param_item = devlink_param_get_from_info(param_list, info); 3991 if (!param_item) 3992 return -EINVAL; 3993 param = param_item->param; 3994 err = devlink_param_type_get_from_info(info, &param_type); 3995 if (err) 3996 return err; 3997 if (param_type != param->type) 3998 return -EINVAL; 3999 err = devlink_param_value_get_from_info(param, info, &value); 4000 if (err) 4001 return err; 4002 if (param->validate) { 4003 err = param->validate(devlink, param->id, value, info->extack); 4004 if (err) 4005 return err; 4006 } 4007 4008 if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]) 4009 return -EINVAL; 4010 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]); 4011 if (!devlink_param_cmode_is_supported(param, cmode)) 4012 return -EOPNOTSUPP; 4013 4014 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { 4015 if (param->type == DEVLINK_PARAM_TYPE_STRING) 4016 strcpy(param_item->driverinit_value.vstr, value.vstr); 4017 else 4018 param_item->driverinit_value = value; 4019 param_item->driverinit_value_valid = true; 4020 } else { 4021 if (!param->set) 4022 return -EOPNOTSUPP; 4023 ctx.val = value; 4024 ctx.cmode = cmode; 4025 err = devlink_param_set(devlink, param, &ctx); 4026 if (err) 4027 return err; 4028 } 4029 4030 devlink_param_notify(devlink, port_index, param_item, cmd); 4031 return 0; 4032} 4033 4034static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb, 4035 struct genl_info *info) 4036{ 4037 struct devlink *devlink = info->user_ptr[0]; 4038 4039 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list, 4040 info, DEVLINK_CMD_PARAM_NEW); 4041} 4042 4043static int devlink_param_register_one(struct devlink *devlink, 4044 unsigned int port_index, 4045 struct list_head *param_list, 4046 const struct devlink_param *param, 4047 enum devlink_command cmd) 4048{ 4049 struct devlink_param_item *param_item; 4050 4051 if (devlink_param_find_by_name(param_list, param->name)) 4052 return -EEXIST; 4053 4054 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT)) 4055 WARN_ON(param->get || param->set); 4056 else 4057 WARN_ON(!param->get || !param->set); 4058 4059 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL); 4060 if (!param_item) 4061 return -ENOMEM; 4062 param_item->param = param; 4063 4064 list_add_tail(&param_item->list, param_list); 4065 devlink_param_notify(devlink, port_index, param_item, cmd); 4066 return 0; 4067} 4068 4069static void devlink_param_unregister_one(struct devlink *devlink, 4070 unsigned int port_index, 4071 struct list_head *param_list, 4072 const struct devlink_param *param, 4073 enum devlink_command cmd) 4074{ 4075 struct devlink_param_item *param_item; 4076 4077 param_item = devlink_param_find_by_name(param_list, param->name); 4078 WARN_ON(!param_item); 4079 devlink_param_notify(devlink, port_index, param_item, cmd); 4080 list_del(&param_item->list); 4081 kfree(param_item); 4082} 4083 4084static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg, 4085 struct netlink_callback *cb) 4086{ 4087 struct devlink_param_item *param_item; 4088 struct devlink_port *devlink_port; 4089 struct devlink *devlink; 4090 int start = cb->args[0]; 4091 int idx = 0; 4092 int err = 0; 4093 4094 mutex_lock(&devlink_mutex); 4095 list_for_each_entry(devlink, &devlink_list, list) { 4096 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 4097 continue; 4098 mutex_lock(&devlink->lock); 4099 list_for_each_entry(devlink_port, &devlink->port_list, list) { 4100 list_for_each_entry(param_item, 4101 &devlink_port->param_list, list) { 4102 if (idx < start) { 4103 idx++; 4104 continue; 4105 } 4106 err = devlink_nl_param_fill(msg, 4107 devlink_port->devlink, 4108 devlink_port->index, param_item, 4109 DEVLINK_CMD_PORT_PARAM_GET, 4110 NETLINK_CB(cb->skb).portid, 4111 cb->nlh->nlmsg_seq, 4112 NLM_F_MULTI); 4113 if (err == -EOPNOTSUPP) { 4114 err = 0; 4115 } else if (err) { 4116 mutex_unlock(&devlink->lock); 4117 goto out; 4118 } 4119 idx++; 4120 } 4121 } 4122 mutex_unlock(&devlink->lock); 4123 } 4124out: 4125 mutex_unlock(&devlink_mutex); 4126 4127 if (err != -EMSGSIZE) 4128 return err; 4129 4130 cb->args[0] = idx; 4131 return msg->len; 4132} 4133 4134static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb, 4135 struct genl_info *info) 4136{ 4137 struct devlink_port *devlink_port = info->user_ptr[0]; 4138 struct devlink_param_item *param_item; 4139 struct sk_buff *msg; 4140 int err; 4141 4142 param_item = devlink_param_get_from_info(&devlink_port->param_list, 4143 info); 4144 if (!param_item) 4145 return -EINVAL; 4146 4147 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4148 if (!msg) 4149 return -ENOMEM; 4150 4151 err = devlink_nl_param_fill(msg, devlink_port->devlink, 4152 devlink_port->index, param_item, 4153 DEVLINK_CMD_PORT_PARAM_GET, 4154 info->snd_portid, info->snd_seq, 0); 4155 if (err) { 4156 nlmsg_free(msg); 4157 return err; 4158 } 4159 4160 return genlmsg_reply(msg, info); 4161} 4162 4163static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb, 4164 struct genl_info *info) 4165{ 4166 struct devlink_port *devlink_port = info->user_ptr[0]; 4167 4168 return __devlink_nl_cmd_param_set_doit(devlink_port->devlink, 4169 devlink_port->index, 4170 &devlink_port->param_list, info, 4171 DEVLINK_CMD_PORT_PARAM_NEW); 4172} 4173 4174static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg, 4175 struct devlink *devlink, 4176 struct devlink_snapshot *snapshot) 4177{ 4178 struct nlattr *snap_attr; 4179 int err; 4180 4181 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT); 4182 if (!snap_attr) 4183 return -EINVAL; 4184 4185 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id); 4186 if (err) 4187 goto nla_put_failure; 4188 4189 nla_nest_end(msg, snap_attr); 4190 return 0; 4191 4192nla_put_failure: 4193 nla_nest_cancel(msg, snap_attr); 4194 return err; 4195} 4196 4197static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg, 4198 struct devlink *devlink, 4199 struct devlink_region *region) 4200{ 4201 struct devlink_snapshot *snapshot; 4202 struct nlattr *snapshots_attr; 4203 int err; 4204 4205 snapshots_attr = nla_nest_start_noflag(msg, 4206 DEVLINK_ATTR_REGION_SNAPSHOTS); 4207 if (!snapshots_attr) 4208 return -EINVAL; 4209 4210 list_for_each_entry(snapshot, &region->snapshot_list, list) { 4211 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot); 4212 if (err) 4213 goto nla_put_failure; 4214 } 4215 4216 nla_nest_end(msg, snapshots_attr); 4217 return 0; 4218 4219nla_put_failure: 4220 nla_nest_cancel(msg, snapshots_attr); 4221 return err; 4222} 4223 4224static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink, 4225 enum devlink_command cmd, u32 portid, 4226 u32 seq, int flags, 4227 struct devlink_region *region) 4228{ 4229 void *hdr; 4230 int err; 4231 4232 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 4233 if (!hdr) 4234 return -EMSGSIZE; 4235 4236 err = devlink_nl_put_handle(msg, devlink); 4237 if (err) 4238 goto nla_put_failure; 4239 4240 if (region->port) { 4241 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 4242 region->port->index); 4243 if (err) 4244 goto nla_put_failure; 4245 } 4246 4247 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name); 4248 if (err) 4249 goto nla_put_failure; 4250 4251 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 4252 region->size, 4253 DEVLINK_ATTR_PAD); 4254 if (err) 4255 goto nla_put_failure; 4256 4257 err = devlink_nl_region_snapshots_id_put(msg, devlink, region); 4258 if (err) 4259 goto nla_put_failure; 4260 4261 genlmsg_end(msg, hdr); 4262 return 0; 4263 4264nla_put_failure: 4265 genlmsg_cancel(msg, hdr); 4266 return err; 4267} 4268 4269static struct sk_buff * 4270devlink_nl_region_notify_build(struct devlink_region *region, 4271 struct devlink_snapshot *snapshot, 4272 enum devlink_command cmd, u32 portid, u32 seq) 4273{ 4274 struct devlink *devlink = region->devlink; 4275 struct sk_buff *msg; 4276 void *hdr; 4277 int err; 4278 4279 4280 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4281 if (!msg) 4282 return ERR_PTR(-ENOMEM); 4283 4284 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd); 4285 if (!hdr) { 4286 err = -EMSGSIZE; 4287 goto out_free_msg; 4288 } 4289 4290 err = devlink_nl_put_handle(msg, devlink); 4291 if (err) 4292 goto out_cancel_msg; 4293 4294 if (region->port) { 4295 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 4296 region->port->index); 4297 if (err) 4298 goto out_cancel_msg; 4299 } 4300 4301 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, 4302 region->ops->name); 4303 if (err) 4304 goto out_cancel_msg; 4305 4306 if (snapshot) { 4307 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, 4308 snapshot->id); 4309 if (err) 4310 goto out_cancel_msg; 4311 } else { 4312 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 4313 region->size, DEVLINK_ATTR_PAD); 4314 if (err) 4315 goto out_cancel_msg; 4316 } 4317 genlmsg_end(msg, hdr); 4318 4319 return msg; 4320 4321out_cancel_msg: 4322 genlmsg_cancel(msg, hdr); 4323out_free_msg: 4324 nlmsg_free(msg); 4325 return ERR_PTR(err); 4326} 4327 4328static void devlink_nl_region_notify(struct devlink_region *region, 4329 struct devlink_snapshot *snapshot, 4330 enum devlink_command cmd) 4331{ 4332 struct devlink *devlink = region->devlink; 4333 struct sk_buff *msg; 4334 4335 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL); 4336 4337 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0); 4338 if (IS_ERR(msg)) 4339 return; 4340 4341 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 4342 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 4343} 4344 4345/** 4346 * __devlink_snapshot_id_increment - Increment number of snapshots using an id 4347 * @devlink: devlink instance 4348 * @id: the snapshot id 4349 * 4350 * Track when a new snapshot begins using an id. Load the count for the 4351 * given id from the snapshot xarray, increment it, and store it back. 4352 * 4353 * Called when a new snapshot is created with the given id. 4354 * 4355 * The id *must* have been previously allocated by 4356 * devlink_region_snapshot_id_get(). 4357 * 4358 * Returns 0 on success, or an error on failure. 4359 */ 4360static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id) 4361{ 4362 unsigned long count; 4363 void *p; 4364 4365 lockdep_assert_held(&devlink->lock); 4366 4367 p = xa_load(&devlink->snapshot_ids, id); 4368 if (WARN_ON(!p)) 4369 return -EINVAL; 4370 4371 if (WARN_ON(!xa_is_value(p))) 4372 return -EINVAL; 4373 4374 count = xa_to_value(p); 4375 count++; 4376 4377 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 4378 GFP_KERNEL)); 4379} 4380 4381/** 4382 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id 4383 * @devlink: devlink instance 4384 * @id: the snapshot id 4385 * 4386 * Track when a snapshot is deleted and stops using an id. Load the count 4387 * for the given id from the snapshot xarray, decrement it, and store it 4388 * back. 4389 * 4390 * If the count reaches zero, erase this id from the xarray, freeing it 4391 * up for future re-use by devlink_region_snapshot_id_get(). 4392 * 4393 * Called when a snapshot using the given id is deleted, and when the 4394 * initial allocator of the id is finished using it. 4395 */ 4396static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id) 4397{ 4398 unsigned long count; 4399 void *p; 4400 4401 lockdep_assert_held(&devlink->lock); 4402 4403 p = xa_load(&devlink->snapshot_ids, id); 4404 if (WARN_ON(!p)) 4405 return; 4406 4407 if (WARN_ON(!xa_is_value(p))) 4408 return; 4409 4410 count = xa_to_value(p); 4411 4412 if (count > 1) { 4413 count--; 4414 xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 4415 GFP_KERNEL); 4416 } else { 4417 /* If this was the last user, we can erase this id */ 4418 xa_erase(&devlink->snapshot_ids, id); 4419 } 4420} 4421 4422/** 4423 * __devlink_snapshot_id_insert - Insert a specific snapshot ID 4424 * @devlink: devlink instance 4425 * @id: the snapshot id 4426 * 4427 * Mark the given snapshot id as used by inserting a zero value into the 4428 * snapshot xarray. 4429 * 4430 * This must be called while holding the devlink instance lock. Unlike 4431 * devlink_snapshot_id_get, the initial reference count is zero, not one. 4432 * It is expected that the id will immediately be used before 4433 * releasing the devlink instance lock. 4434 * 4435 * Returns zero on success, or an error code if the snapshot id could not 4436 * be inserted. 4437 */ 4438static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id) 4439{ 4440 lockdep_assert_held(&devlink->lock); 4441 4442 if (xa_load(&devlink->snapshot_ids, id)) 4443 return -EEXIST; 4444 4445 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0), 4446 GFP_KERNEL)); 4447} 4448 4449/** 4450 * __devlink_region_snapshot_id_get - get snapshot ID 4451 * @devlink: devlink instance 4452 * @id: storage to return snapshot id 4453 * 4454 * Allocates a new snapshot id. Returns zero on success, or a negative 4455 * error on failure. Must be called while holding the devlink instance 4456 * lock. 4457 * 4458 * Snapshot IDs are tracked using an xarray which stores the number of 4459 * users of the snapshot id. 4460 * 4461 * Note that the caller of this function counts as a 'user', in order to 4462 * avoid race conditions. The caller must release its hold on the 4463 * snapshot by using devlink_region_snapshot_id_put. 4464 */ 4465static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 4466{ 4467 lockdep_assert_held(&devlink->lock); 4468 4469 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1), 4470 xa_limit_32b, GFP_KERNEL); 4471} 4472 4473/** 4474 * __devlink_region_snapshot_create - create a new snapshot 4475 * This will add a new snapshot of a region. The snapshot 4476 * will be stored on the region struct and can be accessed 4477 * from devlink. This is useful for future analyses of snapshots. 4478 * Multiple snapshots can be created on a region. 4479 * The @snapshot_id should be obtained using the getter function. 4480 * 4481 * Must be called only while holding the devlink instance lock. 4482 * 4483 * @region: devlink region of the snapshot 4484 * @data: snapshot data 4485 * @snapshot_id: snapshot id to be created 4486 */ 4487static int 4488__devlink_region_snapshot_create(struct devlink_region *region, 4489 u8 *data, u32 snapshot_id) 4490{ 4491 struct devlink *devlink = region->devlink; 4492 struct devlink_snapshot *snapshot; 4493 int err; 4494 4495 lockdep_assert_held(&devlink->lock); 4496 4497 /* check if region can hold one more snapshot */ 4498 if (region->cur_snapshots == region->max_snapshots) 4499 return -ENOSPC; 4500 4501 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) 4502 return -EEXIST; 4503 4504 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL); 4505 if (!snapshot) 4506 return -ENOMEM; 4507 4508 err = __devlink_snapshot_id_increment(devlink, snapshot_id); 4509 if (err) 4510 goto err_snapshot_id_increment; 4511 4512 snapshot->id = snapshot_id; 4513 snapshot->region = region; 4514 snapshot->data = data; 4515 4516 list_add_tail(&snapshot->list, &region->snapshot_list); 4517 4518 region->cur_snapshots++; 4519 4520 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW); 4521 return 0; 4522 4523err_snapshot_id_increment: 4524 kfree(snapshot); 4525 return err; 4526} 4527 4528static void devlink_region_snapshot_del(struct devlink_region *region, 4529 struct devlink_snapshot *snapshot) 4530{ 4531 struct devlink *devlink = region->devlink; 4532 4533 lockdep_assert_held(&devlink->lock); 4534 4535 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL); 4536 region->cur_snapshots--; 4537 list_del(&snapshot->list); 4538 region->ops->destructor(snapshot->data); 4539 __devlink_snapshot_id_decrement(devlink, snapshot->id); 4540 kfree(snapshot); 4541} 4542 4543static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb, 4544 struct genl_info *info) 4545{ 4546 struct devlink *devlink = info->user_ptr[0]; 4547 struct devlink_port *port = NULL; 4548 struct devlink_region *region; 4549 const char *region_name; 4550 struct sk_buff *msg; 4551 unsigned int index; 4552 int err; 4553 4554 if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) 4555 return -EINVAL; 4556 4557 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4558 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4559 4560 port = devlink_port_get_by_index(devlink, index); 4561 if (!port) 4562 return -ENODEV; 4563 } 4564 4565 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4566 if (port) 4567 region = devlink_port_region_get_by_name(port, region_name); 4568 else 4569 region = devlink_region_get_by_name(devlink, region_name); 4570 4571 if (!region) 4572 return -EINVAL; 4573 4574 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4575 if (!msg) 4576 return -ENOMEM; 4577 4578 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET, 4579 info->snd_portid, info->snd_seq, 0, 4580 region); 4581 if (err) { 4582 nlmsg_free(msg); 4583 return err; 4584 } 4585 4586 return genlmsg_reply(msg, info); 4587} 4588 4589static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg, 4590 struct netlink_callback *cb, 4591 struct devlink_port *port, 4592 int *idx, 4593 int start) 4594{ 4595 struct devlink_region *region; 4596 int err = 0; 4597 4598 list_for_each_entry(region, &port->region_list, list) { 4599 if (*idx < start) { 4600 (*idx)++; 4601 continue; 4602 } 4603 err = devlink_nl_region_fill(msg, port->devlink, 4604 DEVLINK_CMD_REGION_GET, 4605 NETLINK_CB(cb->skb).portid, 4606 cb->nlh->nlmsg_seq, 4607 NLM_F_MULTI, region); 4608 if (err) 4609 goto out; 4610 (*idx)++; 4611 } 4612 4613out: 4614 return err; 4615} 4616 4617static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg, 4618 struct netlink_callback *cb, 4619 struct devlink *devlink, 4620 int *idx, 4621 int start) 4622{ 4623 struct devlink_region *region; 4624 struct devlink_port *port; 4625 int err = 0; 4626 4627 mutex_lock(&devlink->lock); 4628 list_for_each_entry(region, &devlink->region_list, list) { 4629 if (*idx < start) { 4630 (*idx)++; 4631 continue; 4632 } 4633 err = devlink_nl_region_fill(msg, devlink, 4634 DEVLINK_CMD_REGION_GET, 4635 NETLINK_CB(cb->skb).portid, 4636 cb->nlh->nlmsg_seq, 4637 NLM_F_MULTI, region); 4638 if (err) 4639 goto out; 4640 (*idx)++; 4641 } 4642 4643 list_for_each_entry(port, &devlink->port_list, list) { 4644 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx, 4645 start); 4646 if (err) 4647 goto out; 4648 } 4649 4650out: 4651 mutex_unlock(&devlink->lock); 4652 return err; 4653} 4654 4655static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg, 4656 struct netlink_callback *cb) 4657{ 4658 struct devlink *devlink; 4659 int start = cb->args[0]; 4660 int idx = 0; 4661 int err; 4662 4663 mutex_lock(&devlink_mutex); 4664 list_for_each_entry(devlink, &devlink_list, list) { 4665 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 4666 continue; 4667 err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink, 4668 &idx, start); 4669 if (err) 4670 goto out; 4671 } 4672out: 4673 mutex_unlock(&devlink_mutex); 4674 cb->args[0] = idx; 4675 return msg->len; 4676} 4677 4678static int devlink_nl_cmd_region_del(struct sk_buff *skb, 4679 struct genl_info *info) 4680{ 4681 struct devlink *devlink = info->user_ptr[0]; 4682 struct devlink_snapshot *snapshot; 4683 struct devlink_port *port = NULL; 4684 struct devlink_region *region; 4685 const char *region_name; 4686 unsigned int index; 4687 u32 snapshot_id; 4688 4689 if (!info->attrs[DEVLINK_ATTR_REGION_NAME] || 4690 !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) 4691 return -EINVAL; 4692 4693 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4694 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); 4695 4696 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4697 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4698 4699 port = devlink_port_get_by_index(devlink, index); 4700 if (!port) 4701 return -ENODEV; 4702 } 4703 4704 if (port) 4705 region = devlink_port_region_get_by_name(port, region_name); 4706 else 4707 region = devlink_region_get_by_name(devlink, region_name); 4708 4709 if (!region) 4710 return -EINVAL; 4711 4712 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 4713 if (!snapshot) 4714 return -EINVAL; 4715 4716 devlink_region_snapshot_del(region, snapshot); 4717 return 0; 4718} 4719 4720static int 4721devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) 4722{ 4723 struct devlink *devlink = info->user_ptr[0]; 4724 struct devlink_snapshot *snapshot; 4725 struct devlink_port *port = NULL; 4726 struct nlattr *snapshot_id_attr; 4727 struct devlink_region *region; 4728 const char *region_name; 4729 unsigned int index; 4730 u32 snapshot_id; 4731 u8 *data; 4732 int err; 4733 4734 if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) { 4735 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided"); 4736 return -EINVAL; 4737 } 4738 4739 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4740 4741 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4742 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4743 4744 port = devlink_port_get_by_index(devlink, index); 4745 if (!port) 4746 return -ENODEV; 4747 } 4748 4749 if (port) 4750 region = devlink_port_region_get_by_name(port, region_name); 4751 else 4752 region = devlink_region_get_by_name(devlink, region_name); 4753 4754 if (!region) { 4755 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist"); 4756 return -EINVAL; 4757 } 4758 4759 if (!region->ops->snapshot) { 4760 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot"); 4761 return -EOPNOTSUPP; 4762 } 4763 4764 if (region->cur_snapshots == region->max_snapshots) { 4765 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots"); 4766 return -ENOSPC; 4767 } 4768 4769 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; 4770 if (snapshot_id_attr) { 4771 snapshot_id = nla_get_u32(snapshot_id_attr); 4772 4773 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { 4774 NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use"); 4775 return -EEXIST; 4776 } 4777 4778 err = __devlink_snapshot_id_insert(devlink, snapshot_id); 4779 if (err) 4780 return err; 4781 } else { 4782 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id); 4783 if (err) { 4784 NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id"); 4785 return err; 4786 } 4787 } 4788 4789 if (port) 4790 err = region->port_ops->snapshot(port, region->port_ops, 4791 info->extack, &data); 4792 else 4793 err = region->ops->snapshot(devlink, region->ops, 4794 info->extack, &data); 4795 if (err) 4796 goto err_snapshot_capture; 4797 4798 err = __devlink_region_snapshot_create(region, data, snapshot_id); 4799 if (err) 4800 goto err_snapshot_create; 4801 4802 if (!snapshot_id_attr) { 4803 struct sk_buff *msg; 4804 4805 snapshot = devlink_region_snapshot_get_by_id(region, 4806 snapshot_id); 4807 if (WARN_ON(!snapshot)) 4808 return -EINVAL; 4809 4810 msg = devlink_nl_region_notify_build(region, snapshot, 4811 DEVLINK_CMD_REGION_NEW, 4812 info->snd_portid, 4813 info->snd_seq); 4814 err = PTR_ERR_OR_ZERO(msg); 4815 if (err) 4816 goto err_notify; 4817 4818 err = genlmsg_reply(msg, info); 4819 if (err) 4820 goto err_notify; 4821 } 4822 4823 return 0; 4824 4825err_snapshot_create: 4826 region->ops->destructor(data); 4827err_snapshot_capture: 4828 __devlink_snapshot_id_decrement(devlink, snapshot_id); 4829 return err; 4830 4831err_notify: 4832 devlink_region_snapshot_del(region, snapshot); 4833 return err; 4834} 4835 4836static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg, 4837 struct devlink *devlink, 4838 u8 *chunk, u32 chunk_size, 4839 u64 addr) 4840{ 4841 struct nlattr *chunk_attr; 4842 int err; 4843 4844 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK); 4845 if (!chunk_attr) 4846 return -EINVAL; 4847 4848 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk); 4849 if (err) 4850 goto nla_put_failure; 4851 4852 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr, 4853 DEVLINK_ATTR_PAD); 4854 if (err) 4855 goto nla_put_failure; 4856 4857 nla_nest_end(msg, chunk_attr); 4858 return 0; 4859 4860nla_put_failure: 4861 nla_nest_cancel(msg, chunk_attr); 4862 return err; 4863} 4864 4865#define DEVLINK_REGION_READ_CHUNK_SIZE 256 4866 4867static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb, 4868 struct devlink *devlink, 4869 struct devlink_region *region, 4870 struct nlattr **attrs, 4871 u64 start_offset, 4872 u64 end_offset, 4873 u64 *new_offset) 4874{ 4875 struct devlink_snapshot *snapshot; 4876 u64 curr_offset = start_offset; 4877 u32 snapshot_id; 4878 int err = 0; 4879 4880 *new_offset = start_offset; 4881 4882 snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); 4883 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 4884 if (!snapshot) 4885 return -EINVAL; 4886 4887 while (curr_offset < end_offset) { 4888 u32 data_size; 4889 u8 *data; 4890 4891 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE) 4892 data_size = end_offset - curr_offset; 4893 else 4894 data_size = DEVLINK_REGION_READ_CHUNK_SIZE; 4895 4896 data = &snapshot->data[curr_offset]; 4897 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink, 4898 data, data_size, 4899 curr_offset); 4900 if (err) 4901 break; 4902 4903 curr_offset += data_size; 4904 } 4905 *new_offset = curr_offset; 4906 4907 return err; 4908} 4909 4910static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, 4911 struct netlink_callback *cb) 4912{ 4913 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 4914 u64 ret_offset, start_offset, end_offset = U64_MAX; 4915 struct nlattr **attrs = info->attrs; 4916 struct devlink_port *port = NULL; 4917 struct devlink_region *region; 4918 struct nlattr *chunks_attr; 4919 const char *region_name; 4920 struct devlink *devlink; 4921 unsigned int index; 4922 void *hdr; 4923 int err; 4924 4925 start_offset = *((u64 *)&cb->args[0]); 4926 4927 mutex_lock(&devlink_mutex); 4928 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); 4929 if (IS_ERR(devlink)) { 4930 err = PTR_ERR(devlink); 4931 goto out_dev; 4932 } 4933 4934 mutex_lock(&devlink->lock); 4935 4936 if (!attrs[DEVLINK_ATTR_REGION_NAME] || 4937 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) { 4938 err = -EINVAL; 4939 goto out_unlock; 4940 } 4941 4942 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4943 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4944 4945 port = devlink_port_get_by_index(devlink, index); 4946 if (!port) { 4947 err = -ENODEV; 4948 goto out_unlock; 4949 } 4950 } 4951 4952 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]); 4953 4954 if (port) 4955 region = devlink_port_region_get_by_name(port, region_name); 4956 else 4957 region = devlink_region_get_by_name(devlink, region_name); 4958 4959 if (!region) { 4960 err = -EINVAL; 4961 goto out_unlock; 4962 } 4963 4964 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] && 4965 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) { 4966 if (!start_offset) 4967 start_offset = 4968 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 4969 4970 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 4971 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); 4972 } 4973 4974 if (end_offset > region->size) 4975 end_offset = region->size; 4976 4977 /* return 0 if there is no further data to read */ 4978 if (start_offset == end_offset) { 4979 err = 0; 4980 goto out_unlock; 4981 } 4982 4983 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 4984 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, 4985 DEVLINK_CMD_REGION_READ); 4986 if (!hdr) { 4987 err = -EMSGSIZE; 4988 goto out_unlock; 4989 } 4990 4991 err = devlink_nl_put_handle(skb, devlink); 4992 if (err) 4993 goto nla_put_failure; 4994 4995 if (region->port) { 4996 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX, 4997 region->port->index); 4998 if (err) 4999 goto nla_put_failure; 5000 } 5001 5002 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name); 5003 if (err) 5004 goto nla_put_failure; 5005 5006 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS); 5007 if (!chunks_attr) { 5008 err = -EMSGSIZE; 5009 goto nla_put_failure; 5010 } 5011 5012 err = devlink_nl_region_read_snapshot_fill(skb, devlink, 5013 region, attrs, 5014 start_offset, 5015 end_offset, &ret_offset); 5016 5017 if (err && err != -EMSGSIZE) 5018 goto nla_put_failure; 5019 5020 /* Check if there was any progress done to prevent infinite loop */ 5021 if (ret_offset == start_offset) { 5022 err = -EINVAL; 5023 goto nla_put_failure; 5024 } 5025 5026 *((u64 *)&cb->args[0]) = ret_offset; 5027 5028 nla_nest_end(skb, chunks_attr); 5029 genlmsg_end(skb, hdr); 5030 mutex_unlock(&devlink->lock); 5031 mutex_unlock(&devlink_mutex); 5032 5033 return skb->len; 5034 5035nla_put_failure: 5036 genlmsg_cancel(skb, hdr); 5037out_unlock: 5038 mutex_unlock(&devlink->lock); 5039out_dev: 5040 mutex_unlock(&devlink_mutex); 5041 return err; 5042} 5043 5044struct devlink_info_req { 5045 struct sk_buff *msg; 5046}; 5047 5048int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name) 5049{ 5050 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name); 5051} 5052EXPORT_SYMBOL_GPL(devlink_info_driver_name_put); 5053 5054int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) 5055{ 5056 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); 5057} 5058EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); 5059 5060int devlink_info_board_serial_number_put(struct devlink_info_req *req, 5061 const char *bsn) 5062{ 5063 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, 5064 bsn); 5065} 5066EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); 5067 5068static int devlink_info_version_put(struct devlink_info_req *req, int attr, 5069 const char *version_name, 5070 const char *version_value) 5071{ 5072 struct nlattr *nest; 5073 int err; 5074 5075 nest = nla_nest_start_noflag(req->msg, attr); 5076 if (!nest) 5077 return -EMSGSIZE; 5078 5079 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, 5080 version_name); 5081 if (err) 5082 goto nla_put_failure; 5083 5084 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, 5085 version_value); 5086 if (err) 5087 goto nla_put_failure; 5088 5089 nla_nest_end(req->msg, nest); 5090 5091 return 0; 5092 5093nla_put_failure: 5094 nla_nest_cancel(req->msg, nest); 5095 return err; 5096} 5097 5098int devlink_info_version_fixed_put(struct devlink_info_req *req, 5099 const char *version_name, 5100 const char *version_value) 5101{ 5102 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, 5103 version_name, version_value); 5104} 5105EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); 5106 5107int devlink_info_version_stored_put(struct devlink_info_req *req, 5108 const char *version_name, 5109 const char *version_value) 5110{ 5111 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 5112 version_name, version_value); 5113} 5114EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); 5115 5116int devlink_info_version_running_put(struct devlink_info_req *req, 5117 const char *version_name, 5118 const char *version_value) 5119{ 5120 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 5121 version_name, version_value); 5122} 5123EXPORT_SYMBOL_GPL(devlink_info_version_running_put); 5124 5125static int 5126devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, 5127 enum devlink_command cmd, u32 portid, 5128 u32 seq, int flags, struct netlink_ext_ack *extack) 5129{ 5130 struct devlink_info_req req; 5131 void *hdr; 5132 int err; 5133 5134 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 5135 if (!hdr) 5136 return -EMSGSIZE; 5137 5138 err = -EMSGSIZE; 5139 if (devlink_nl_put_handle(msg, devlink)) 5140 goto err_cancel_msg; 5141 5142 req.msg = msg; 5143 err = devlink->ops->info_get(devlink, &req, extack); 5144 if (err) 5145 goto err_cancel_msg; 5146 5147 genlmsg_end(msg, hdr); 5148 return 0; 5149 5150err_cancel_msg: 5151 genlmsg_cancel(msg, hdr); 5152 return err; 5153} 5154 5155static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, 5156 struct genl_info *info) 5157{ 5158 struct devlink *devlink = info->user_ptr[0]; 5159 struct sk_buff *msg; 5160 int err; 5161 5162 if (!devlink->ops->info_get) 5163 return -EOPNOTSUPP; 5164 5165 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 5166 if (!msg) 5167 return -ENOMEM; 5168 5169 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 5170 info->snd_portid, info->snd_seq, 0, 5171 info->extack); 5172 if (err) { 5173 nlmsg_free(msg); 5174 return err; 5175 } 5176 5177 return genlmsg_reply(msg, info); 5178} 5179 5180static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg, 5181 struct netlink_callback *cb) 5182{ 5183 struct devlink *devlink; 5184 int start = cb->args[0]; 5185 int idx = 0; 5186 int err = 0; 5187 5188 mutex_lock(&devlink_mutex); 5189 list_for_each_entry(devlink, &devlink_list, list) { 5190 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 5191 continue; 5192 if (idx < start) { 5193 idx++; 5194 continue; 5195 } 5196 5197 if (!devlink->ops->info_get) { 5198 idx++; 5199 continue; 5200 } 5201 5202 mutex_lock(&devlink->lock); 5203 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 5204 NETLINK_CB(cb->skb).portid, 5205 cb->nlh->nlmsg_seq, NLM_F_MULTI, 5206 cb->extack); 5207 mutex_unlock(&devlink->lock); 5208 if (err == -EOPNOTSUPP) 5209 err = 0; 5210 else if (err) 5211 break; 5212 idx++; 5213 } 5214 mutex_unlock(&devlink_mutex); 5215 5216 if (err != -EMSGSIZE) 5217 return err; 5218 5219 cb->args[0] = idx; 5220 return msg->len; 5221} 5222 5223struct devlink_fmsg_item { 5224 struct list_head list; 5225 int attrtype; 5226 u8 nla_type; 5227 u16 len; 5228 int value[]; 5229}; 5230 5231struct devlink_fmsg { 5232 struct list_head item_list; 5233 bool putting_binary; /* This flag forces enclosing of binary data 5234 * in an array brackets. It forces using 5235 * of designated API: 5236 * devlink_fmsg_binary_pair_nest_start() 5237 * devlink_fmsg_binary_pair_nest_end() 5238 */ 5239}; 5240 5241static struct devlink_fmsg *devlink_fmsg_alloc(void) 5242{ 5243 struct devlink_fmsg *fmsg; 5244 5245 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL); 5246 if (!fmsg) 5247 return NULL; 5248 5249 INIT_LIST_HEAD(&fmsg->item_list); 5250 5251 return fmsg; 5252} 5253 5254static void devlink_fmsg_free(struct devlink_fmsg *fmsg) 5255{ 5256 struct devlink_fmsg_item *item, *tmp; 5257 5258 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) { 5259 list_del(&item->list); 5260 kfree(item); 5261 } 5262 kfree(fmsg); 5263} 5264 5265static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg, 5266 int attrtype) 5267{ 5268 struct devlink_fmsg_item *item; 5269 5270 item = kzalloc(sizeof(*item), GFP_KERNEL); 5271 if (!item) 5272 return -ENOMEM; 5273 5274 item->attrtype = attrtype; 5275 list_add_tail(&item->list, &fmsg->item_list); 5276 5277 return 0; 5278} 5279 5280int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg) 5281{ 5282 if (fmsg->putting_binary) 5283 return -EINVAL; 5284 5285 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START); 5286} 5287EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start); 5288 5289static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg) 5290{ 5291 if (fmsg->putting_binary) 5292 return -EINVAL; 5293 5294 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END); 5295} 5296 5297int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg) 5298{ 5299 if (fmsg->putting_binary) 5300 return -EINVAL; 5301 5302 return devlink_fmsg_nest_end(fmsg); 5303} 5304EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end); 5305 5306#define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN) 5307 5308static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name) 5309{ 5310 struct devlink_fmsg_item *item; 5311 5312 if (fmsg->putting_binary) 5313 return -EINVAL; 5314 5315 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE) 5316 return -EMSGSIZE; 5317 5318 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL); 5319 if (!item) 5320 return -ENOMEM; 5321 5322 item->nla_type = NLA_NUL_STRING; 5323 item->len = strlen(name) + 1; 5324 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME; 5325 memcpy(&item->value, name, item->len); 5326 list_add_tail(&item->list, &fmsg->item_list); 5327 5328 return 0; 5329} 5330 5331int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name) 5332{ 5333 int err; 5334 5335 if (fmsg->putting_binary) 5336 return -EINVAL; 5337 5338 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START); 5339 if (err) 5340 return err; 5341 5342 err = devlink_fmsg_put_name(fmsg, name); 5343 if (err) 5344 return err; 5345 5346 return 0; 5347} 5348EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start); 5349 5350int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg) 5351{ 5352 if (fmsg->putting_binary) 5353 return -EINVAL; 5354 5355 return devlink_fmsg_nest_end(fmsg); 5356} 5357EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end); 5358 5359int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg, 5360 const char *name) 5361{ 5362 int err; 5363 5364 if (fmsg->putting_binary) 5365 return -EINVAL; 5366 5367 err = devlink_fmsg_pair_nest_start(fmsg, name); 5368 if (err) 5369 return err; 5370 5371 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START); 5372 if (err) 5373 return err; 5374 5375 return 0; 5376} 5377EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start); 5378 5379int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg) 5380{ 5381 int err; 5382 5383 if (fmsg->putting_binary) 5384 return -EINVAL; 5385 5386 err = devlink_fmsg_nest_end(fmsg); 5387 if (err) 5388 return err; 5389 5390 err = devlink_fmsg_nest_end(fmsg); 5391 if (err) 5392 return err; 5393 5394 return 0; 5395} 5396EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end); 5397 5398int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg, 5399 const char *name) 5400{ 5401 int err; 5402 5403 err = devlink_fmsg_arr_pair_nest_start(fmsg, name); 5404 if (err) 5405 return err; 5406 5407 fmsg->putting_binary = true; 5408 return err; 5409} 5410EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start); 5411 5412int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg) 5413{ 5414 if (!fmsg->putting_binary) 5415 return -EINVAL; 5416 5417 fmsg->putting_binary = false; 5418 return devlink_fmsg_arr_pair_nest_end(fmsg); 5419} 5420EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end); 5421 5422static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg, 5423 const void *value, u16 value_len, 5424 u8 value_nla_type) 5425{ 5426 struct devlink_fmsg_item *item; 5427 5428 if (value_len > DEVLINK_FMSG_MAX_SIZE) 5429 return -EMSGSIZE; 5430 5431 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL); 5432 if (!item) 5433 return -ENOMEM; 5434 5435 item->nla_type = value_nla_type; 5436 item->len = value_len; 5437 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; 5438 memcpy(&item->value, value, item->len); 5439 list_add_tail(&item->list, &fmsg->item_list); 5440 5441 return 0; 5442} 5443 5444int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value) 5445{ 5446 if (fmsg->putting_binary) 5447 return -EINVAL; 5448 5449 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG); 5450} 5451EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put); 5452 5453int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value) 5454{ 5455 if (fmsg->putting_binary) 5456 return -EINVAL; 5457 5458 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8); 5459} 5460EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put); 5461 5462int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value) 5463{ 5464 if (fmsg->putting_binary) 5465 return -EINVAL; 5466 5467 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32); 5468} 5469EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put); 5470 5471int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value) 5472{ 5473 if (fmsg->putting_binary) 5474 return -EINVAL; 5475 5476 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64); 5477} 5478EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put); 5479 5480int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value) 5481{ 5482 if (fmsg->putting_binary) 5483 return -EINVAL; 5484 5485 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1, 5486 NLA_NUL_STRING); 5487} 5488EXPORT_SYMBOL_GPL(devlink_fmsg_string_put); 5489 5490int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value, 5491 u16 value_len) 5492{ 5493 if (!fmsg->putting_binary) 5494 return -EINVAL; 5495 5496 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY); 5497} 5498EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put); 5499 5500int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name, 5501 bool value) 5502{ 5503 int err; 5504 5505 err = devlink_fmsg_pair_nest_start(fmsg, name); 5506 if (err) 5507 return err; 5508 5509 err = devlink_fmsg_bool_put(fmsg, value); 5510 if (err) 5511 return err; 5512 5513 err = devlink_fmsg_pair_nest_end(fmsg); 5514 if (err) 5515 return err; 5516 5517 return 0; 5518} 5519EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put); 5520 5521int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name, 5522 u8 value) 5523{ 5524 int err; 5525 5526 err = devlink_fmsg_pair_nest_start(fmsg, name); 5527 if (err) 5528 return err; 5529 5530 err = devlink_fmsg_u8_put(fmsg, value); 5531 if (err) 5532 return err; 5533 5534 err = devlink_fmsg_pair_nest_end(fmsg); 5535 if (err) 5536 return err; 5537 5538 return 0; 5539} 5540EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put); 5541 5542int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name, 5543 u32 value) 5544{ 5545 int err; 5546 5547 err = devlink_fmsg_pair_nest_start(fmsg, name); 5548 if (err) 5549 return err; 5550 5551 err = devlink_fmsg_u32_put(fmsg, value); 5552 if (err) 5553 return err; 5554 5555 err = devlink_fmsg_pair_nest_end(fmsg); 5556 if (err) 5557 return err; 5558 5559 return 0; 5560} 5561EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put); 5562 5563int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name, 5564 u64 value) 5565{ 5566 int err; 5567 5568 err = devlink_fmsg_pair_nest_start(fmsg, name); 5569 if (err) 5570 return err; 5571 5572 err = devlink_fmsg_u64_put(fmsg, value); 5573 if (err) 5574 return err; 5575 5576 err = devlink_fmsg_pair_nest_end(fmsg); 5577 if (err) 5578 return err; 5579 5580 return 0; 5581} 5582EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put); 5583 5584int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name, 5585 const char *value) 5586{ 5587 int err; 5588 5589 err = devlink_fmsg_pair_nest_start(fmsg, name); 5590 if (err) 5591 return err; 5592 5593 err = devlink_fmsg_string_put(fmsg, value); 5594 if (err) 5595 return err; 5596 5597 err = devlink_fmsg_pair_nest_end(fmsg); 5598 if (err) 5599 return err; 5600 5601 return 0; 5602} 5603EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put); 5604 5605int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name, 5606 const void *value, u32 value_len) 5607{ 5608 u32 data_size; 5609 int end_err; 5610 u32 offset; 5611 int err; 5612 5613 err = devlink_fmsg_binary_pair_nest_start(fmsg, name); 5614 if (err) 5615 return err; 5616 5617 for (offset = 0; offset < value_len; offset += data_size) { 5618 data_size = value_len - offset; 5619 if (data_size > DEVLINK_FMSG_MAX_SIZE) 5620 data_size = DEVLINK_FMSG_MAX_SIZE; 5621 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size); 5622 if (err) 5623 break; 5624 /* Exit from loop with a break (instead of 5625 * return) to make sure putting_binary is turned off in 5626 * devlink_fmsg_binary_pair_nest_end 5627 */ 5628 } 5629 5630 end_err = devlink_fmsg_binary_pair_nest_end(fmsg); 5631 if (end_err) 5632 err = end_err; 5633 5634 return err; 5635} 5636EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put); 5637 5638static int 5639devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb) 5640{ 5641 switch (msg->nla_type) { 5642 case NLA_FLAG: 5643 case NLA_U8: 5644 case NLA_U32: 5645 case NLA_U64: 5646 case NLA_NUL_STRING: 5647 case NLA_BINARY: 5648 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, 5649 msg->nla_type); 5650 default: 5651 return -EINVAL; 5652 } 5653} 5654 5655static int 5656devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb) 5657{ 5658 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; 5659 u8 tmp; 5660 5661 switch (msg->nla_type) { 5662 case NLA_FLAG: 5663 /* Always provide flag data, regardless of its value */ 5664 tmp = *(bool *) msg->value; 5665 5666 return nla_put_u8(skb, attrtype, tmp); 5667 case NLA_U8: 5668 return nla_put_u8(skb, attrtype, *(u8 *) msg->value); 5669 case NLA_U32: 5670 return nla_put_u32(skb, attrtype, *(u32 *) msg->value); 5671 case NLA_U64: 5672 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value, 5673 DEVLINK_ATTR_PAD); 5674 case NLA_NUL_STRING: 5675 return nla_put_string(skb, attrtype, (char *) &msg->value); 5676 case NLA_BINARY: 5677 return nla_put(skb, attrtype, msg->len, (void *) &msg->value); 5678 default: 5679 return -EINVAL; 5680 } 5681} 5682 5683static int 5684devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb, 5685 int *start) 5686{ 5687 struct devlink_fmsg_item *item; 5688 struct nlattr *fmsg_nlattr; 5689 int i = 0; 5690 int err; 5691 5692 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG); 5693 if (!fmsg_nlattr) 5694 return -EMSGSIZE; 5695 5696 list_for_each_entry(item, &fmsg->item_list, list) { 5697 if (i < *start) { 5698 i++; 5699 continue; 5700 } 5701 5702 switch (item->attrtype) { 5703 case DEVLINK_ATTR_FMSG_OBJ_NEST_START: 5704 case DEVLINK_ATTR_FMSG_PAIR_NEST_START: 5705 case DEVLINK_ATTR_FMSG_ARR_NEST_START: 5706 case DEVLINK_ATTR_FMSG_NEST_END: 5707 err = nla_put_flag(skb, item->attrtype); 5708 break; 5709 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA: 5710 err = devlink_fmsg_item_fill_type(item, skb); 5711 if (err) 5712 break; 5713 err = devlink_fmsg_item_fill_data(item, skb); 5714 break; 5715 case DEVLINK_ATTR_FMSG_OBJ_NAME: 5716 err = nla_put_string(skb, item->attrtype, 5717 (char *) &item->value); 5718 break; 5719 default: 5720 err = -EINVAL; 5721 break; 5722 } 5723 if (!err) 5724 *start = ++i; 5725 else 5726 break; 5727 } 5728 5729 nla_nest_end(skb, fmsg_nlattr); 5730 return err; 5731} 5732 5733static int devlink_fmsg_snd(struct devlink_fmsg *fmsg, 5734 struct genl_info *info, 5735 enum devlink_command cmd, int flags) 5736{ 5737 struct nlmsghdr *nlh; 5738 struct sk_buff *skb; 5739 bool last = false; 5740 int index = 0; 5741 void *hdr; 5742 int err; 5743 5744 while (!last) { 5745 int tmp_index = index; 5746 5747 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 5748 if (!skb) 5749 return -ENOMEM; 5750 5751 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 5752 &devlink_nl_family, flags | NLM_F_MULTI, cmd); 5753 if (!hdr) { 5754 err = -EMSGSIZE; 5755 goto nla_put_failure; 5756 } 5757 5758 err = devlink_fmsg_prepare_skb(fmsg, skb, &index); 5759 if (!err) 5760 last = true; 5761 else if (err != -EMSGSIZE || tmp_index == index) 5762 goto nla_put_failure; 5763 5764 genlmsg_end(skb, hdr); 5765 err = genlmsg_reply(skb, info); 5766 if (err) 5767 return err; 5768 } 5769 5770 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 5771 if (!skb) 5772 return -ENOMEM; 5773 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 5774 NLMSG_DONE, 0, flags | NLM_F_MULTI); 5775 if (!nlh) { 5776 err = -EMSGSIZE; 5777 goto nla_put_failure; 5778 } 5779 5780 return genlmsg_reply(skb, info); 5781 5782nla_put_failure: 5783 nlmsg_free(skb); 5784 return err; 5785} 5786 5787static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb, 5788 struct netlink_callback *cb, 5789 enum devlink_command cmd) 5790{ 5791 int index = cb->args[0]; 5792 int tmp_index = index; 5793 void *hdr; 5794 int err; 5795 5796 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 5797 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd); 5798 if (!hdr) { 5799 err = -EMSGSIZE; 5800 goto nla_put_failure; 5801 } 5802 5803 err = devlink_fmsg_prepare_skb(fmsg, skb, &index); 5804 if ((err && err != -EMSGSIZE) || tmp_index == index) 5805 goto nla_put_failure; 5806 5807 cb->args[0] = index; 5808 genlmsg_end(skb, hdr); 5809 return skb->len; 5810 5811nla_put_failure: 5812 genlmsg_cancel(skb, hdr); 5813 return err; 5814} 5815 5816struct devlink_health_reporter { 5817 struct list_head list; 5818 void *priv; 5819 const struct devlink_health_reporter_ops *ops; 5820 struct devlink *devlink; 5821 struct devlink_port *devlink_port; 5822 struct devlink_fmsg *dump_fmsg; 5823 struct mutex dump_lock; /* lock parallel read/write from dump buffers */ 5824 u64 graceful_period; 5825 bool auto_recover; 5826 bool auto_dump; 5827 u8 health_state; 5828 u64 dump_ts; 5829 u64 dump_real_ts; 5830 u64 error_count; 5831 u64 recovery_count; 5832 u64 last_recovery_ts; 5833 refcount_t refcount; 5834}; 5835 5836void * 5837devlink_health_reporter_priv(struct devlink_health_reporter *reporter) 5838{ 5839 return reporter->priv; 5840} 5841EXPORT_SYMBOL_GPL(devlink_health_reporter_priv); 5842 5843static struct devlink_health_reporter * 5844__devlink_health_reporter_find_by_name(struct list_head *reporter_list, 5845 struct mutex *list_lock, 5846 const char *reporter_name) 5847{ 5848 struct devlink_health_reporter *reporter; 5849 5850 lockdep_assert_held(list_lock); 5851 list_for_each_entry(reporter, reporter_list, list) 5852 if (!strcmp(reporter->ops->name, reporter_name)) 5853 return reporter; 5854 return NULL; 5855} 5856 5857static struct devlink_health_reporter * 5858devlink_health_reporter_find_by_name(struct devlink *devlink, 5859 const char *reporter_name) 5860{ 5861 return __devlink_health_reporter_find_by_name(&devlink->reporter_list, 5862 &devlink->reporters_lock, 5863 reporter_name); 5864} 5865 5866static struct devlink_health_reporter * 5867devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port, 5868 const char *reporter_name) 5869{ 5870 return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list, 5871 &devlink_port->reporters_lock, 5872 reporter_name); 5873} 5874 5875static struct devlink_health_reporter * 5876__devlink_health_reporter_create(struct devlink *devlink, 5877 const struct devlink_health_reporter_ops *ops, 5878 u64 graceful_period, void *priv) 5879{ 5880 struct devlink_health_reporter *reporter; 5881 5882 if (WARN_ON(graceful_period && !ops->recover)) 5883 return ERR_PTR(-EINVAL); 5884 5885 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL); 5886 if (!reporter) 5887 return ERR_PTR(-ENOMEM); 5888 5889 reporter->priv = priv; 5890 reporter->ops = ops; 5891 reporter->devlink = devlink; 5892 reporter->graceful_period = graceful_period; 5893 reporter->auto_recover = !!ops->recover; 5894 reporter->auto_dump = !!ops->dump; 5895 mutex_init(&reporter->dump_lock); 5896 refcount_set(&reporter->refcount, 1); 5897 return reporter; 5898} 5899 5900/** 5901 * devlink_port_health_reporter_create - create devlink health reporter for 5902 * specified port instance 5903 * 5904 * @port: devlink_port which should contain the new reporter 5905 * @ops: ops 5906 * @graceful_period: to avoid recovery loops, in msecs 5907 * @priv: priv 5908 */ 5909struct devlink_health_reporter * 5910devlink_port_health_reporter_create(struct devlink_port *port, 5911 const struct devlink_health_reporter_ops *ops, 5912 u64 graceful_period, void *priv) 5913{ 5914 struct devlink_health_reporter *reporter; 5915 5916 mutex_lock(&port->reporters_lock); 5917 if (__devlink_health_reporter_find_by_name(&port->reporter_list, 5918 &port->reporters_lock, ops->name)) { 5919 reporter = ERR_PTR(-EEXIST); 5920 goto unlock; 5921 } 5922 5923 reporter = __devlink_health_reporter_create(port->devlink, ops, 5924 graceful_period, priv); 5925 if (IS_ERR(reporter)) 5926 goto unlock; 5927 5928 reporter->devlink_port = port; 5929 list_add_tail(&reporter->list, &port->reporter_list); 5930unlock: 5931 mutex_unlock(&port->reporters_lock); 5932 return reporter; 5933} 5934EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create); 5935 5936/** 5937 * devlink_health_reporter_create - create devlink health reporter 5938 * 5939 * @devlink: devlink 5940 * @ops: ops 5941 * @graceful_period: to avoid recovery loops, in msecs 5942 * @priv: priv 5943 */ 5944struct devlink_health_reporter * 5945devlink_health_reporter_create(struct devlink *devlink, 5946 const struct devlink_health_reporter_ops *ops, 5947 u64 graceful_period, void *priv) 5948{ 5949 struct devlink_health_reporter *reporter; 5950 5951 mutex_lock(&devlink->reporters_lock); 5952 if (devlink_health_reporter_find_by_name(devlink, ops->name)) { 5953 reporter = ERR_PTR(-EEXIST); 5954 goto unlock; 5955 } 5956 5957 reporter = __devlink_health_reporter_create(devlink, ops, 5958 graceful_period, priv); 5959 if (IS_ERR(reporter)) 5960 goto unlock; 5961 5962 list_add_tail(&reporter->list, &devlink->reporter_list); 5963unlock: 5964 mutex_unlock(&devlink->reporters_lock); 5965 return reporter; 5966} 5967EXPORT_SYMBOL_GPL(devlink_health_reporter_create); 5968 5969static void 5970devlink_health_reporter_free(struct devlink_health_reporter *reporter) 5971{ 5972 mutex_destroy(&reporter->dump_lock); 5973 if (reporter->dump_fmsg) 5974 devlink_fmsg_free(reporter->dump_fmsg); 5975 kfree(reporter); 5976} 5977 5978static void 5979devlink_health_reporter_put(struct devlink_health_reporter *reporter) 5980{ 5981 if (refcount_dec_and_test(&reporter->refcount)) 5982 devlink_health_reporter_free(reporter); 5983} 5984 5985static void 5986__devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) 5987{ 5988 list_del(&reporter->list); 5989 devlink_health_reporter_put(reporter); 5990} 5991 5992/** 5993 * devlink_health_reporter_destroy - destroy devlink health reporter 5994 * 5995 * @reporter: devlink health reporter to destroy 5996 */ 5997void 5998devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) 5999{ 6000 struct mutex *lock = &reporter->devlink->reporters_lock; 6001 6002 mutex_lock(lock); 6003 __devlink_health_reporter_destroy(reporter); 6004 mutex_unlock(lock); 6005} 6006EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy); 6007 6008/** 6009 * devlink_port_health_reporter_destroy - destroy devlink port health reporter 6010 * 6011 * @reporter: devlink health reporter to destroy 6012 */ 6013void 6014devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter) 6015{ 6016 struct mutex *lock = &reporter->devlink_port->reporters_lock; 6017 6018 mutex_lock(lock); 6019 __devlink_health_reporter_destroy(reporter); 6020 mutex_unlock(lock); 6021} 6022EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy); 6023 6024static int 6025devlink_nl_health_reporter_fill(struct sk_buff *msg, 6026 struct devlink *devlink, 6027 struct devlink_health_reporter *reporter, 6028 enum devlink_command cmd, u32 portid, 6029 u32 seq, int flags) 6030{ 6031 struct nlattr *reporter_attr; 6032 void *hdr; 6033 6034 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 6035 if (!hdr) 6036 return -EMSGSIZE; 6037 6038 if (devlink_nl_put_handle(msg, devlink)) 6039 goto genlmsg_cancel; 6040 6041 if (reporter->devlink_port) { 6042 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index)) 6043 goto genlmsg_cancel; 6044 } 6045 reporter_attr = nla_nest_start_noflag(msg, 6046 DEVLINK_ATTR_HEALTH_REPORTER); 6047 if (!reporter_attr) 6048 goto genlmsg_cancel; 6049 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME, 6050 reporter->ops->name)) 6051 goto reporter_nest_cancel; 6052 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE, 6053 reporter->health_state)) 6054 goto reporter_nest_cancel; 6055 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT, 6056 reporter->error_count, DEVLINK_ATTR_PAD)) 6057 goto reporter_nest_cancel; 6058 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT, 6059 reporter->recovery_count, DEVLINK_ATTR_PAD)) 6060 goto reporter_nest_cancel; 6061 if (reporter->ops->recover && 6062 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD, 6063 reporter->graceful_period, 6064 DEVLINK_ATTR_PAD)) 6065 goto reporter_nest_cancel; 6066 if (reporter->ops->recover && 6067 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER, 6068 reporter->auto_recover)) 6069 goto reporter_nest_cancel; 6070 if (reporter->dump_fmsg && 6071 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS, 6072 jiffies_to_msecs(reporter->dump_ts), 6073 DEVLINK_ATTR_PAD)) 6074 goto reporter_nest_cancel; 6075 if (reporter->dump_fmsg && 6076 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS, 6077 reporter->dump_real_ts, DEVLINK_ATTR_PAD)) 6078 goto reporter_nest_cancel; 6079 if (reporter->ops->dump && 6080 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, 6081 reporter->auto_dump)) 6082 goto reporter_nest_cancel; 6083 6084 nla_nest_end(msg, reporter_attr); 6085 genlmsg_end(msg, hdr); 6086 return 0; 6087 6088reporter_nest_cancel: 6089 nla_nest_end(msg, reporter_attr); 6090genlmsg_cancel: 6091 genlmsg_cancel(msg, hdr); 6092 return -EMSGSIZE; 6093} 6094 6095static void devlink_recover_notify(struct devlink_health_reporter *reporter, 6096 enum devlink_command cmd) 6097{ 6098 struct sk_buff *msg; 6099 int err; 6100 6101 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6102 6103 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6104 if (!msg) 6105 return; 6106 6107 err = devlink_nl_health_reporter_fill(msg, reporter->devlink, 6108 reporter, cmd, 0, 0, 0); 6109 if (err) { 6110 nlmsg_free(msg); 6111 return; 6112 } 6113 6114 genlmsg_multicast_netns(&devlink_nl_family, 6115 devlink_net(reporter->devlink), 6116 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 6117} 6118 6119void 6120devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter) 6121{ 6122 reporter->recovery_count++; 6123 reporter->last_recovery_ts = jiffies; 6124} 6125EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done); 6126 6127static int 6128devlink_health_reporter_recover(struct devlink_health_reporter *reporter, 6129 void *priv_ctx, struct netlink_ext_ack *extack) 6130{ 6131 int err; 6132 6133 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY) 6134 return 0; 6135 6136 if (!reporter->ops->recover) 6137 return -EOPNOTSUPP; 6138 6139 err = reporter->ops->recover(reporter, priv_ctx, extack); 6140 if (err) 6141 return err; 6142 6143 devlink_health_reporter_recovery_done(reporter); 6144 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY; 6145 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6146 6147 return 0; 6148} 6149 6150static void 6151devlink_health_dump_clear(struct devlink_health_reporter *reporter) 6152{ 6153 if (!reporter->dump_fmsg) 6154 return; 6155 devlink_fmsg_free(reporter->dump_fmsg); 6156 reporter->dump_fmsg = NULL; 6157} 6158 6159static int devlink_health_do_dump(struct devlink_health_reporter *reporter, 6160 void *priv_ctx, 6161 struct netlink_ext_ack *extack) 6162{ 6163 int err; 6164 6165 if (!reporter->ops->dump) 6166 return 0; 6167 6168 if (reporter->dump_fmsg) 6169 return 0; 6170 6171 reporter->dump_fmsg = devlink_fmsg_alloc(); 6172 if (!reporter->dump_fmsg) { 6173 err = -ENOMEM; 6174 return err; 6175 } 6176 6177 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg); 6178 if (err) 6179 goto dump_err; 6180 6181 err = reporter->ops->dump(reporter, reporter->dump_fmsg, 6182 priv_ctx, extack); 6183 if (err) 6184 goto dump_err; 6185 6186 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg); 6187 if (err) 6188 goto dump_err; 6189 6190 reporter->dump_ts = jiffies; 6191 reporter->dump_real_ts = ktime_get_real_ns(); 6192 6193 return 0; 6194 6195dump_err: 6196 devlink_health_dump_clear(reporter); 6197 return err; 6198} 6199 6200int devlink_health_report(struct devlink_health_reporter *reporter, 6201 const char *msg, void *priv_ctx) 6202{ 6203 enum devlink_health_reporter_state prev_health_state; 6204 struct devlink *devlink = reporter->devlink; 6205 unsigned long recover_ts_threshold; 6206 6207 /* write a log message of the current error */ 6208 WARN_ON(!msg); 6209 trace_devlink_health_report(devlink, reporter->ops->name, msg); 6210 reporter->error_count++; 6211 prev_health_state = reporter->health_state; 6212 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; 6213 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6214 6215 /* abort if the previous error wasn't recovered */ 6216 recover_ts_threshold = reporter->last_recovery_ts + 6217 msecs_to_jiffies(reporter->graceful_period); 6218 if (reporter->auto_recover && 6219 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY || 6220 (reporter->last_recovery_ts && reporter->recovery_count && 6221 time_is_after_jiffies(recover_ts_threshold)))) { 6222 trace_devlink_health_recover_aborted(devlink, 6223 reporter->ops->name, 6224 reporter->health_state, 6225 jiffies - 6226 reporter->last_recovery_ts); 6227 return -ECANCELED; 6228 } 6229 6230 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; 6231 6232 if (reporter->auto_dump) { 6233 mutex_lock(&reporter->dump_lock); 6234 /* store current dump of current error, for later analysis */ 6235 devlink_health_do_dump(reporter, priv_ctx, NULL); 6236 mutex_unlock(&reporter->dump_lock); 6237 } 6238 6239 if (reporter->auto_recover) 6240 return devlink_health_reporter_recover(reporter, 6241 priv_ctx, NULL); 6242 6243 return 0; 6244} 6245EXPORT_SYMBOL_GPL(devlink_health_report); 6246 6247static struct devlink_health_reporter * 6248devlink_health_reporter_get_from_attrs(struct devlink *devlink, 6249 struct nlattr **attrs) 6250{ 6251 struct devlink_health_reporter *reporter; 6252 struct devlink_port *devlink_port; 6253 char *reporter_name; 6254 6255 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]) 6256 return NULL; 6257 6258 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]); 6259 devlink_port = devlink_port_get_from_attrs(devlink, attrs); 6260 if (IS_ERR(devlink_port)) { 6261 mutex_lock(&devlink->reporters_lock); 6262 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name); 6263 if (reporter) 6264 refcount_inc(&reporter->refcount); 6265 mutex_unlock(&devlink->reporters_lock); 6266 } else { 6267 mutex_lock(&devlink_port->reporters_lock); 6268 reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name); 6269 if (reporter) 6270 refcount_inc(&reporter->refcount); 6271 mutex_unlock(&devlink_port->reporters_lock); 6272 } 6273 6274 return reporter; 6275} 6276 6277static struct devlink_health_reporter * 6278devlink_health_reporter_get_from_info(struct devlink *devlink, 6279 struct genl_info *info) 6280{ 6281 return devlink_health_reporter_get_from_attrs(devlink, info->attrs); 6282} 6283 6284static struct devlink_health_reporter * 6285devlink_health_reporter_get_from_cb(struct netlink_callback *cb) 6286{ 6287 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 6288 struct devlink_health_reporter *reporter; 6289 struct nlattr **attrs = info->attrs; 6290 struct devlink *devlink; 6291 6292 mutex_lock(&devlink_mutex); 6293 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); 6294 if (IS_ERR(devlink)) 6295 goto unlock; 6296 6297 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs); 6298 mutex_unlock(&devlink_mutex); 6299 return reporter; 6300unlock: 6301 mutex_unlock(&devlink_mutex); 6302 return NULL; 6303} 6304 6305void 6306devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, 6307 enum devlink_health_reporter_state state) 6308{ 6309 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY && 6310 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR)) 6311 return; 6312 6313 if (reporter->health_state == state) 6314 return; 6315 6316 reporter->health_state = state; 6317 trace_devlink_health_reporter_state_update(reporter->devlink, 6318 reporter->ops->name, state); 6319 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6320} 6321EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update); 6322 6323static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, 6324 struct genl_info *info) 6325{ 6326 struct devlink *devlink = info->user_ptr[0]; 6327 struct devlink_health_reporter *reporter; 6328 struct sk_buff *msg; 6329 int err; 6330 6331 reporter = devlink_health_reporter_get_from_info(devlink, info); 6332 if (!reporter) 6333 return -EINVAL; 6334 6335 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6336 if (!msg) { 6337 err = -ENOMEM; 6338 goto out; 6339 } 6340 6341 err = devlink_nl_health_reporter_fill(msg, devlink, reporter, 6342 DEVLINK_CMD_HEALTH_REPORTER_GET, 6343 info->snd_portid, info->snd_seq, 6344 0); 6345 if (err) { 6346 nlmsg_free(msg); 6347 goto out; 6348 } 6349 6350 err = genlmsg_reply(msg, info); 6351out: 6352 devlink_health_reporter_put(reporter); 6353 return err; 6354} 6355 6356static int 6357devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg, 6358 struct netlink_callback *cb) 6359{ 6360 struct devlink_health_reporter *reporter; 6361 struct devlink_port *port; 6362 struct devlink *devlink; 6363 int start = cb->args[0]; 6364 int idx = 0; 6365 int err; 6366 6367 mutex_lock(&devlink_mutex); 6368 list_for_each_entry(devlink, &devlink_list, list) { 6369 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 6370 continue; 6371 mutex_lock(&devlink->reporters_lock); 6372 list_for_each_entry(reporter, &devlink->reporter_list, 6373 list) { 6374 if (idx < start) { 6375 idx++; 6376 continue; 6377 } 6378 err = devlink_nl_health_reporter_fill(msg, devlink, 6379 reporter, 6380 DEVLINK_CMD_HEALTH_REPORTER_GET, 6381 NETLINK_CB(cb->skb).portid, 6382 cb->nlh->nlmsg_seq, 6383 NLM_F_MULTI); 6384 if (err) { 6385 mutex_unlock(&devlink->reporters_lock); 6386 goto out; 6387 } 6388 idx++; 6389 } 6390 mutex_unlock(&devlink->reporters_lock); 6391 } 6392 6393 list_for_each_entry(devlink, &devlink_list, list) { 6394 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 6395 continue; 6396 mutex_lock(&devlink->lock); 6397 list_for_each_entry(port, &devlink->port_list, list) { 6398 mutex_lock(&port->reporters_lock); 6399 list_for_each_entry(reporter, &port->reporter_list, list) { 6400 if (idx < start) { 6401 idx++; 6402 continue; 6403 } 6404 err = devlink_nl_health_reporter_fill(msg, devlink, reporter, 6405 DEVLINK_CMD_HEALTH_REPORTER_GET, 6406 NETLINK_CB(cb->skb).portid, 6407 cb->nlh->nlmsg_seq, 6408 NLM_F_MULTI); 6409 if (err) { 6410 mutex_unlock(&port->reporters_lock); 6411 mutex_unlock(&devlink->lock); 6412 goto out; 6413 } 6414 idx++; 6415 } 6416 mutex_unlock(&port->reporters_lock); 6417 } 6418 mutex_unlock(&devlink->lock); 6419 } 6420out: 6421 mutex_unlock(&devlink_mutex); 6422 6423 cb->args[0] = idx; 6424 return msg->len; 6425} 6426 6427static int 6428devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, 6429 struct genl_info *info) 6430{ 6431 struct devlink *devlink = info->user_ptr[0]; 6432 struct devlink_health_reporter *reporter; 6433 int err; 6434 6435 reporter = devlink_health_reporter_get_from_info(devlink, info); 6436 if (!reporter) 6437 return -EINVAL; 6438 6439 if (!reporter->ops->recover && 6440 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] || 6441 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) { 6442 err = -EOPNOTSUPP; 6443 goto out; 6444 } 6445 if (!reporter->ops->dump && 6446 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) { 6447 err = -EOPNOTSUPP; 6448 goto out; 6449 } 6450 6451 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]) 6452 reporter->graceful_period = 6453 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]); 6454 6455 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]) 6456 reporter->auto_recover = 6457 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]); 6458 6459 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) 6460 reporter->auto_dump = 6461 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]); 6462 6463 devlink_health_reporter_put(reporter); 6464 return 0; 6465out: 6466 devlink_health_reporter_put(reporter); 6467 return err; 6468} 6469 6470static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb, 6471 struct genl_info *info) 6472{ 6473 struct devlink *devlink = info->user_ptr[0]; 6474 struct devlink_health_reporter *reporter; 6475 int err; 6476 6477 reporter = devlink_health_reporter_get_from_info(devlink, info); 6478 if (!reporter) 6479 return -EINVAL; 6480 6481 err = devlink_health_reporter_recover(reporter, NULL, info->extack); 6482 6483 devlink_health_reporter_put(reporter); 6484 return err; 6485} 6486 6487static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, 6488 struct genl_info *info) 6489{ 6490 struct devlink *devlink = info->user_ptr[0]; 6491 struct devlink_health_reporter *reporter; 6492 struct devlink_fmsg *fmsg; 6493 int err; 6494 6495 reporter = devlink_health_reporter_get_from_info(devlink, info); 6496 if (!reporter) 6497 return -EINVAL; 6498 6499 if (!reporter->ops->diagnose) { 6500 devlink_health_reporter_put(reporter); 6501 return -EOPNOTSUPP; 6502 } 6503 6504 fmsg = devlink_fmsg_alloc(); 6505 if (!fmsg) { 6506 devlink_health_reporter_put(reporter); 6507 return -ENOMEM; 6508 } 6509 6510 err = devlink_fmsg_obj_nest_start(fmsg); 6511 if (err) 6512 goto out; 6513 6514 err = reporter->ops->diagnose(reporter, fmsg, info->extack); 6515 if (err) 6516 goto out; 6517 6518 err = devlink_fmsg_obj_nest_end(fmsg); 6519 if (err) 6520 goto out; 6521 6522 err = devlink_fmsg_snd(fmsg, info, 6523 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0); 6524 6525out: 6526 devlink_fmsg_free(fmsg); 6527 devlink_health_reporter_put(reporter); 6528 return err; 6529} 6530 6531static int 6532devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb, 6533 struct netlink_callback *cb) 6534{ 6535 struct devlink_health_reporter *reporter; 6536 u64 start = cb->args[0]; 6537 int err; 6538 6539 reporter = devlink_health_reporter_get_from_cb(cb); 6540 if (!reporter) 6541 return -EINVAL; 6542 6543 if (!reporter->ops->dump) { 6544 err = -EOPNOTSUPP; 6545 goto out; 6546 } 6547 mutex_lock(&reporter->dump_lock); 6548 if (!start) { 6549 err = devlink_health_do_dump(reporter, NULL, cb->extack); 6550 if (err) 6551 goto unlock; 6552 cb->args[1] = reporter->dump_ts; 6553 } 6554 if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) { 6555 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry"); 6556 err = -EAGAIN; 6557 goto unlock; 6558 } 6559 6560 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb, 6561 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET); 6562unlock: 6563 mutex_unlock(&reporter->dump_lock); 6564out: 6565 devlink_health_reporter_put(reporter); 6566 return err; 6567} 6568 6569static int 6570devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb, 6571 struct genl_info *info) 6572{ 6573 struct devlink *devlink = info->user_ptr[0]; 6574 struct devlink_health_reporter *reporter; 6575 6576 reporter = devlink_health_reporter_get_from_info(devlink, info); 6577 if (!reporter) 6578 return -EINVAL; 6579 6580 if (!reporter->ops->dump) { 6581 devlink_health_reporter_put(reporter); 6582 return -EOPNOTSUPP; 6583 } 6584 6585 mutex_lock(&reporter->dump_lock); 6586 devlink_health_dump_clear(reporter); 6587 mutex_unlock(&reporter->dump_lock); 6588 devlink_health_reporter_put(reporter); 6589 return 0; 6590} 6591 6592static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb, 6593 struct genl_info *info) 6594{ 6595 struct devlink *devlink = info->user_ptr[0]; 6596 struct devlink_health_reporter *reporter; 6597 int err; 6598 6599 reporter = devlink_health_reporter_get_from_info(devlink, info); 6600 if (!reporter) 6601 return -EINVAL; 6602 6603 if (!reporter->ops->test) { 6604 devlink_health_reporter_put(reporter); 6605 return -EOPNOTSUPP; 6606 } 6607 6608 err = reporter->ops->test(reporter, info->extack); 6609 6610 devlink_health_reporter_put(reporter); 6611 return err; 6612} 6613 6614struct devlink_stats { 6615 u64 rx_bytes; 6616 u64 rx_packets; 6617 struct u64_stats_sync syncp; 6618}; 6619 6620/** 6621 * struct devlink_trap_policer_item - Packet trap policer attributes. 6622 * @policer: Immutable packet trap policer attributes. 6623 * @rate: Rate in packets / sec. 6624 * @burst: Burst size in packets. 6625 * @list: trap_policer_list member. 6626 * 6627 * Describes packet trap policer attributes. Created by devlink during trap 6628 * policer registration. 6629 */ 6630struct devlink_trap_policer_item { 6631 const struct devlink_trap_policer *policer; 6632 u64 rate; 6633 u64 burst; 6634 struct list_head list; 6635}; 6636 6637/** 6638 * struct devlink_trap_group_item - Packet trap group attributes. 6639 * @group: Immutable packet trap group attributes. 6640 * @policer_item: Associated policer item. Can be NULL. 6641 * @list: trap_group_list member. 6642 * @stats: Trap group statistics. 6643 * 6644 * Describes packet trap group attributes. Created by devlink during trap 6645 * group registration. 6646 */ 6647struct devlink_trap_group_item { 6648 const struct devlink_trap_group *group; 6649 struct devlink_trap_policer_item *policer_item; 6650 struct list_head list; 6651 struct devlink_stats __percpu *stats; 6652}; 6653 6654/** 6655 * struct devlink_trap_item - Packet trap attributes. 6656 * @trap: Immutable packet trap attributes. 6657 * @group_item: Associated group item. 6658 * @list: trap_list member. 6659 * @action: Trap action. 6660 * @stats: Trap statistics. 6661 * @priv: Driver private information. 6662 * 6663 * Describes both mutable and immutable packet trap attributes. Created by 6664 * devlink during trap registration and used for all trap related operations. 6665 */ 6666struct devlink_trap_item { 6667 const struct devlink_trap *trap; 6668 struct devlink_trap_group_item *group_item; 6669 struct list_head list; 6670 enum devlink_trap_action action; 6671 struct devlink_stats __percpu *stats; 6672 void *priv; 6673}; 6674 6675static struct devlink_trap_policer_item * 6676devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id) 6677{ 6678 struct devlink_trap_policer_item *policer_item; 6679 6680 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) { 6681 if (policer_item->policer->id == id) 6682 return policer_item; 6683 } 6684 6685 return NULL; 6686} 6687 6688static struct devlink_trap_item * 6689devlink_trap_item_lookup(struct devlink *devlink, const char *name) 6690{ 6691 struct devlink_trap_item *trap_item; 6692 6693 list_for_each_entry(trap_item, &devlink->trap_list, list) { 6694 if (!strcmp(trap_item->trap->name, name)) 6695 return trap_item; 6696 } 6697 6698 return NULL; 6699} 6700 6701static struct devlink_trap_item * 6702devlink_trap_item_get_from_info(struct devlink *devlink, 6703 struct genl_info *info) 6704{ 6705 struct nlattr *attr; 6706 6707 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME]) 6708 return NULL; 6709 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME]; 6710 6711 return devlink_trap_item_lookup(devlink, nla_data(attr)); 6712} 6713 6714static int 6715devlink_trap_action_get_from_info(struct genl_info *info, 6716 enum devlink_trap_action *p_trap_action) 6717{ 6718 u8 val; 6719 6720 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]); 6721 switch (val) { 6722 case DEVLINK_TRAP_ACTION_DROP: 6723 case DEVLINK_TRAP_ACTION_TRAP: 6724 case DEVLINK_TRAP_ACTION_MIRROR: 6725 *p_trap_action = val; 6726 break; 6727 default: 6728 return -EINVAL; 6729 } 6730 6731 return 0; 6732} 6733 6734static int devlink_trap_metadata_put(struct sk_buff *msg, 6735 const struct devlink_trap *trap) 6736{ 6737 struct nlattr *attr; 6738 6739 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA); 6740 if (!attr) 6741 return -EMSGSIZE; 6742 6743 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) && 6744 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT)) 6745 goto nla_put_failure; 6746 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) && 6747 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE)) 6748 goto nla_put_failure; 6749 6750 nla_nest_end(msg, attr); 6751 6752 return 0; 6753 6754nla_put_failure: 6755 nla_nest_cancel(msg, attr); 6756 return -EMSGSIZE; 6757} 6758 6759static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats, 6760 struct devlink_stats *stats) 6761{ 6762 int i; 6763 6764 memset(stats, 0, sizeof(*stats)); 6765 for_each_possible_cpu(i) { 6766 struct devlink_stats *cpu_stats; 6767 u64 rx_packets, rx_bytes; 6768 unsigned int start; 6769 6770 cpu_stats = per_cpu_ptr(trap_stats, i); 6771 do { 6772 start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); 6773 rx_packets = cpu_stats->rx_packets; 6774 rx_bytes = cpu_stats->rx_bytes; 6775 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); 6776 6777 stats->rx_packets += rx_packets; 6778 stats->rx_bytes += rx_bytes; 6779 } 6780} 6781 6782static int devlink_trap_stats_put(struct sk_buff *msg, 6783 struct devlink_stats __percpu *trap_stats) 6784{ 6785 struct devlink_stats stats; 6786 struct nlattr *attr; 6787 6788 devlink_trap_stats_read(trap_stats, &stats); 6789 6790 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); 6791 if (!attr) 6792 return -EMSGSIZE; 6793 6794 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS, 6795 stats.rx_packets, DEVLINK_ATTR_PAD)) 6796 goto nla_put_failure; 6797 6798 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES, 6799 stats.rx_bytes, DEVLINK_ATTR_PAD)) 6800 goto nla_put_failure; 6801 6802 nla_nest_end(msg, attr); 6803 6804 return 0; 6805 6806nla_put_failure: 6807 nla_nest_cancel(msg, attr); 6808 return -EMSGSIZE; 6809} 6810 6811static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink, 6812 const struct devlink_trap_item *trap_item, 6813 enum devlink_command cmd, u32 portid, u32 seq, 6814 int flags) 6815{ 6816 struct devlink_trap_group_item *group_item = trap_item->group_item; 6817 void *hdr; 6818 int err; 6819 6820 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 6821 if (!hdr) 6822 return -EMSGSIZE; 6823 6824 if (devlink_nl_put_handle(msg, devlink)) 6825 goto nla_put_failure; 6826 6827 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, 6828 group_item->group->name)) 6829 goto nla_put_failure; 6830 6831 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name)) 6832 goto nla_put_failure; 6833 6834 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type)) 6835 goto nla_put_failure; 6836 6837 if (trap_item->trap->generic && 6838 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) 6839 goto nla_put_failure; 6840 6841 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action)) 6842 goto nla_put_failure; 6843 6844 err = devlink_trap_metadata_put(msg, trap_item->trap); 6845 if (err) 6846 goto nla_put_failure; 6847 6848 err = devlink_trap_stats_put(msg, trap_item->stats); 6849 if (err) 6850 goto nla_put_failure; 6851 6852 genlmsg_end(msg, hdr); 6853 6854 return 0; 6855 6856nla_put_failure: 6857 genlmsg_cancel(msg, hdr); 6858 return -EMSGSIZE; 6859} 6860 6861static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb, 6862 struct genl_info *info) 6863{ 6864 struct netlink_ext_ack *extack = info->extack; 6865 struct devlink *devlink = info->user_ptr[0]; 6866 struct devlink_trap_item *trap_item; 6867 struct sk_buff *msg; 6868 int err; 6869 6870 if (list_empty(&devlink->trap_list)) 6871 return -EOPNOTSUPP; 6872 6873 trap_item = devlink_trap_item_get_from_info(devlink, info); 6874 if (!trap_item) { 6875 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); 6876 return -ENOENT; 6877 } 6878 6879 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6880 if (!msg) 6881 return -ENOMEM; 6882 6883 err = devlink_nl_trap_fill(msg, devlink, trap_item, 6884 DEVLINK_CMD_TRAP_NEW, info->snd_portid, 6885 info->snd_seq, 0); 6886 if (err) 6887 goto err_trap_fill; 6888 6889 return genlmsg_reply(msg, info); 6890 6891err_trap_fill: 6892 nlmsg_free(msg); 6893 return err; 6894} 6895 6896static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg, 6897 struct netlink_callback *cb) 6898{ 6899 struct devlink_trap_item *trap_item; 6900 struct devlink *devlink; 6901 int start = cb->args[0]; 6902 int idx = 0; 6903 int err; 6904 6905 mutex_lock(&devlink_mutex); 6906 list_for_each_entry(devlink, &devlink_list, list) { 6907 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 6908 continue; 6909 mutex_lock(&devlink->lock); 6910 list_for_each_entry(trap_item, &devlink->trap_list, list) { 6911 if (idx < start) { 6912 idx++; 6913 continue; 6914 } 6915 err = devlink_nl_trap_fill(msg, devlink, trap_item, 6916 DEVLINK_CMD_TRAP_NEW, 6917 NETLINK_CB(cb->skb).portid, 6918 cb->nlh->nlmsg_seq, 6919 NLM_F_MULTI); 6920 if (err) { 6921 mutex_unlock(&devlink->lock); 6922 goto out; 6923 } 6924 idx++; 6925 } 6926 mutex_unlock(&devlink->lock); 6927 } 6928out: 6929 mutex_unlock(&devlink_mutex); 6930 6931 cb->args[0] = idx; 6932 return msg->len; 6933} 6934 6935static int __devlink_trap_action_set(struct devlink *devlink, 6936 struct devlink_trap_item *trap_item, 6937 enum devlink_trap_action trap_action, 6938 struct netlink_ext_ack *extack) 6939{ 6940 int err; 6941 6942 if (trap_item->action != trap_action && 6943 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) { 6944 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping"); 6945 return 0; 6946 } 6947 6948 err = devlink->ops->trap_action_set(devlink, trap_item->trap, 6949 trap_action, extack); 6950 if (err) 6951 return err; 6952 6953 trap_item->action = trap_action; 6954 6955 return 0; 6956} 6957 6958static int devlink_trap_action_set(struct devlink *devlink, 6959 struct devlink_trap_item *trap_item, 6960 struct genl_info *info) 6961{ 6962 enum devlink_trap_action trap_action; 6963 int err; 6964 6965 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) 6966 return 0; 6967 6968 err = devlink_trap_action_get_from_info(info, &trap_action); 6969 if (err) { 6970 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); 6971 return -EINVAL; 6972 } 6973 6974 return __devlink_trap_action_set(devlink, trap_item, trap_action, 6975 info->extack); 6976} 6977 6978static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb, 6979 struct genl_info *info) 6980{ 6981 struct netlink_ext_ack *extack = info->extack; 6982 struct devlink *devlink = info->user_ptr[0]; 6983 struct devlink_trap_item *trap_item; 6984 int err; 6985 6986 if (list_empty(&devlink->trap_list)) 6987 return -EOPNOTSUPP; 6988 6989 trap_item = devlink_trap_item_get_from_info(devlink, info); 6990 if (!trap_item) { 6991 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); 6992 return -ENOENT; 6993 } 6994 6995 err = devlink_trap_action_set(devlink, trap_item, info); 6996 if (err) 6997 return err; 6998 6999 return 0; 7000} 7001 7002static struct devlink_trap_group_item * 7003devlink_trap_group_item_lookup(struct devlink *devlink, const char *name) 7004{ 7005 struct devlink_trap_group_item *group_item; 7006 7007 list_for_each_entry(group_item, &devlink->trap_group_list, list) { 7008 if (!strcmp(group_item->group->name, name)) 7009 return group_item; 7010 } 7011 7012 return NULL; 7013} 7014 7015static struct devlink_trap_group_item * 7016devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id) 7017{ 7018 struct devlink_trap_group_item *group_item; 7019 7020 list_for_each_entry(group_item, &devlink->trap_group_list, list) { 7021 if (group_item->group->id == id) 7022 return group_item; 7023 } 7024 7025 return NULL; 7026} 7027 7028static struct devlink_trap_group_item * 7029devlink_trap_group_item_get_from_info(struct devlink *devlink, 7030 struct genl_info *info) 7031{ 7032 char *name; 7033 7034 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]) 7035 return NULL; 7036 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]); 7037 7038 return devlink_trap_group_item_lookup(devlink, name); 7039} 7040 7041static int 7042devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink, 7043 const struct devlink_trap_group_item *group_item, 7044 enum devlink_command cmd, u32 portid, u32 seq, 7045 int flags) 7046{ 7047 void *hdr; 7048 int err; 7049 7050 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 7051 if (!hdr) 7052 return -EMSGSIZE; 7053 7054 if (devlink_nl_put_handle(msg, devlink)) 7055 goto nla_put_failure; 7056 7057 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, 7058 group_item->group->name)) 7059 goto nla_put_failure; 7060 7061 if (group_item->group->generic && 7062 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) 7063 goto nla_put_failure; 7064 7065 if (group_item->policer_item && 7066 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, 7067 group_item->policer_item->policer->id)) 7068 goto nla_put_failure; 7069 7070 err = devlink_trap_stats_put(msg, group_item->stats); 7071 if (err) 7072 goto nla_put_failure; 7073 7074 genlmsg_end(msg, hdr); 7075 7076 return 0; 7077 7078nla_put_failure: 7079 genlmsg_cancel(msg, hdr); 7080 return -EMSGSIZE; 7081} 7082 7083static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb, 7084 struct genl_info *info) 7085{ 7086 struct netlink_ext_ack *extack = info->extack; 7087 struct devlink *devlink = info->user_ptr[0]; 7088 struct devlink_trap_group_item *group_item; 7089 struct sk_buff *msg; 7090 int err; 7091 7092 if (list_empty(&devlink->trap_group_list)) 7093 return -EOPNOTSUPP; 7094 7095 group_item = devlink_trap_group_item_get_from_info(devlink, info); 7096 if (!group_item) { 7097 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); 7098 return -ENOENT; 7099 } 7100 7101 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7102 if (!msg) 7103 return -ENOMEM; 7104 7105 err = devlink_nl_trap_group_fill(msg, devlink, group_item, 7106 DEVLINK_CMD_TRAP_GROUP_NEW, 7107 info->snd_portid, info->snd_seq, 0); 7108 if (err) 7109 goto err_trap_group_fill; 7110 7111 return genlmsg_reply(msg, info); 7112 7113err_trap_group_fill: 7114 nlmsg_free(msg); 7115 return err; 7116} 7117 7118static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg, 7119 struct netlink_callback *cb) 7120{ 7121 enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW; 7122 struct devlink_trap_group_item *group_item; 7123 u32 portid = NETLINK_CB(cb->skb).portid; 7124 struct devlink *devlink; 7125 int start = cb->args[0]; 7126 int idx = 0; 7127 int err; 7128 7129 mutex_lock(&devlink_mutex); 7130 list_for_each_entry(devlink, &devlink_list, list) { 7131 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 7132 continue; 7133 mutex_lock(&devlink->lock); 7134 list_for_each_entry(group_item, &devlink->trap_group_list, 7135 list) { 7136 if (idx < start) { 7137 idx++; 7138 continue; 7139 } 7140 err = devlink_nl_trap_group_fill(msg, devlink, 7141 group_item, cmd, 7142 portid, 7143 cb->nlh->nlmsg_seq, 7144 NLM_F_MULTI); 7145 if (err) { 7146 mutex_unlock(&devlink->lock); 7147 goto out; 7148 } 7149 idx++; 7150 } 7151 mutex_unlock(&devlink->lock); 7152 } 7153out: 7154 mutex_unlock(&devlink_mutex); 7155 7156 cb->args[0] = idx; 7157 return msg->len; 7158} 7159 7160static int 7161__devlink_trap_group_action_set(struct devlink *devlink, 7162 struct devlink_trap_group_item *group_item, 7163 enum devlink_trap_action trap_action, 7164 struct netlink_ext_ack *extack) 7165{ 7166 const char *group_name = group_item->group->name; 7167 struct devlink_trap_item *trap_item; 7168 int err; 7169 7170 if (devlink->ops->trap_group_action_set) { 7171 err = devlink->ops->trap_group_action_set(devlink, group_item->group, 7172 trap_action, extack); 7173 if (err) 7174 return err; 7175 7176 list_for_each_entry(trap_item, &devlink->trap_list, list) { 7177 if (strcmp(trap_item->group_item->group->name, group_name)) 7178 continue; 7179 if (trap_item->action != trap_action && 7180 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) 7181 continue; 7182 trap_item->action = trap_action; 7183 } 7184 7185 return 0; 7186 } 7187 7188 list_for_each_entry(trap_item, &devlink->trap_list, list) { 7189 if (strcmp(trap_item->group_item->group->name, group_name)) 7190 continue; 7191 err = __devlink_trap_action_set(devlink, trap_item, 7192 trap_action, extack); 7193 if (err) 7194 return err; 7195 } 7196 7197 return 0; 7198} 7199 7200static int 7201devlink_trap_group_action_set(struct devlink *devlink, 7202 struct devlink_trap_group_item *group_item, 7203 struct genl_info *info, bool *p_modified) 7204{ 7205 enum devlink_trap_action trap_action; 7206 int err; 7207 7208 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) 7209 return 0; 7210 7211 err = devlink_trap_action_get_from_info(info, &trap_action); 7212 if (err) { 7213 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); 7214 return -EINVAL; 7215 } 7216 7217 err = __devlink_trap_group_action_set(devlink, group_item, trap_action, 7218 info->extack); 7219 if (err) 7220 return err; 7221 7222 *p_modified = true; 7223 7224 return 0; 7225} 7226 7227static int devlink_trap_group_set(struct devlink *devlink, 7228 struct devlink_trap_group_item *group_item, 7229 struct genl_info *info) 7230{ 7231 struct devlink_trap_policer_item *policer_item; 7232 struct netlink_ext_ack *extack = info->extack; 7233 const struct devlink_trap_policer *policer; 7234 struct nlattr **attrs = info->attrs; 7235 int err; 7236 7237 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) 7238 return 0; 7239 7240 if (!devlink->ops->trap_group_set) 7241 return -EOPNOTSUPP; 7242 7243 policer_item = group_item->policer_item; 7244 if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) { 7245 u32 policer_id; 7246 7247 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); 7248 policer_item = devlink_trap_policer_item_lookup(devlink, 7249 policer_id); 7250 if (policer_id && !policer_item) { 7251 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); 7252 return -ENOENT; 7253 } 7254 } 7255 policer = policer_item ? policer_item->policer : NULL; 7256 7257 err = devlink->ops->trap_group_set(devlink, group_item->group, policer, 7258 extack); 7259 if (err) 7260 return err; 7261 7262 group_item->policer_item = policer_item; 7263 7264 return 0; 7265} 7266 7267static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb, 7268 struct genl_info *info) 7269{ 7270 struct netlink_ext_ack *extack = info->extack; 7271 struct devlink *devlink = info->user_ptr[0]; 7272 struct devlink_trap_group_item *group_item; 7273 bool modified = false; 7274 int err; 7275 7276 if (list_empty(&devlink->trap_group_list)) 7277 return -EOPNOTSUPP; 7278 7279 group_item = devlink_trap_group_item_get_from_info(devlink, info); 7280 if (!group_item) { 7281 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); 7282 return -ENOENT; 7283 } 7284 7285 err = devlink_trap_group_action_set(devlink, group_item, info, 7286 &modified); 7287 if (err) 7288 return err; 7289 7290 err = devlink_trap_group_set(devlink, group_item, info); 7291 if (err) 7292 goto err_trap_group_set; 7293 7294 return 0; 7295 7296err_trap_group_set: 7297 if (modified) 7298 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already"); 7299 return err; 7300} 7301 7302static struct devlink_trap_policer_item * 7303devlink_trap_policer_item_get_from_info(struct devlink *devlink, 7304 struct genl_info *info) 7305{ 7306 u32 id; 7307 7308 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) 7309 return NULL; 7310 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); 7311 7312 return devlink_trap_policer_item_lookup(devlink, id); 7313} 7314 7315static int 7316devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink, 7317 const struct devlink_trap_policer *policer) 7318{ 7319 struct nlattr *attr; 7320 u64 drops; 7321 int err; 7322 7323 if (!devlink->ops->trap_policer_counter_get) 7324 return 0; 7325 7326 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops); 7327 if (err) 7328 return err; 7329 7330 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); 7331 if (!attr) 7332 return -EMSGSIZE; 7333 7334 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops, 7335 DEVLINK_ATTR_PAD)) 7336 goto nla_put_failure; 7337 7338 nla_nest_end(msg, attr); 7339 7340 return 0; 7341 7342nla_put_failure: 7343 nla_nest_cancel(msg, attr); 7344 return -EMSGSIZE; 7345} 7346 7347static int 7348devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink, 7349 const struct devlink_trap_policer_item *policer_item, 7350 enum devlink_command cmd, u32 portid, u32 seq, 7351 int flags) 7352{ 7353 void *hdr; 7354 int err; 7355 7356 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 7357 if (!hdr) 7358 return -EMSGSIZE; 7359 7360 if (devlink_nl_put_handle(msg, devlink)) 7361 goto nla_put_failure; 7362 7363 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, 7364 policer_item->policer->id)) 7365 goto nla_put_failure; 7366 7367 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE, 7368 policer_item->rate, DEVLINK_ATTR_PAD)) 7369 goto nla_put_failure; 7370 7371 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST, 7372 policer_item->burst, DEVLINK_ATTR_PAD)) 7373 goto nla_put_failure; 7374 7375 err = devlink_trap_policer_stats_put(msg, devlink, 7376 policer_item->policer); 7377 if (err) 7378 goto nla_put_failure; 7379 7380 genlmsg_end(msg, hdr); 7381 7382 return 0; 7383 7384nla_put_failure: 7385 genlmsg_cancel(msg, hdr); 7386 return -EMSGSIZE; 7387} 7388 7389static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb, 7390 struct genl_info *info) 7391{ 7392 struct devlink_trap_policer_item *policer_item; 7393 struct netlink_ext_ack *extack = info->extack; 7394 struct devlink *devlink = info->user_ptr[0]; 7395 struct sk_buff *msg; 7396 int err; 7397 7398 if (list_empty(&devlink->trap_policer_list)) 7399 return -EOPNOTSUPP; 7400 7401 policer_item = devlink_trap_policer_item_get_from_info(devlink, info); 7402 if (!policer_item) { 7403 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); 7404 return -ENOENT; 7405 } 7406 7407 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7408 if (!msg) 7409 return -ENOMEM; 7410 7411 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, 7412 DEVLINK_CMD_TRAP_POLICER_NEW, 7413 info->snd_portid, info->snd_seq, 0); 7414 if (err) 7415 goto err_trap_policer_fill; 7416 7417 return genlmsg_reply(msg, info); 7418 7419err_trap_policer_fill: 7420 nlmsg_free(msg); 7421 return err; 7422} 7423 7424static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg, 7425 struct netlink_callback *cb) 7426{ 7427 enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW; 7428 struct devlink_trap_policer_item *policer_item; 7429 u32 portid = NETLINK_CB(cb->skb).portid; 7430 struct devlink *devlink; 7431 int start = cb->args[0]; 7432 int idx = 0; 7433 int err; 7434 7435 mutex_lock(&devlink_mutex); 7436 list_for_each_entry(devlink, &devlink_list, list) { 7437 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 7438 continue; 7439 mutex_lock(&devlink->lock); 7440 list_for_each_entry(policer_item, &devlink->trap_policer_list, 7441 list) { 7442 if (idx < start) { 7443 idx++; 7444 continue; 7445 } 7446 err = devlink_nl_trap_policer_fill(msg, devlink, 7447 policer_item, cmd, 7448 portid, 7449 cb->nlh->nlmsg_seq, 7450 NLM_F_MULTI); 7451 if (err) { 7452 mutex_unlock(&devlink->lock); 7453 goto out; 7454 } 7455 idx++; 7456 } 7457 mutex_unlock(&devlink->lock); 7458 } 7459out: 7460 mutex_unlock(&devlink_mutex); 7461 7462 cb->args[0] = idx; 7463 return msg->len; 7464} 7465 7466static int 7467devlink_trap_policer_set(struct devlink *devlink, 7468 struct devlink_trap_policer_item *policer_item, 7469 struct genl_info *info) 7470{ 7471 struct netlink_ext_ack *extack = info->extack; 7472 struct nlattr **attrs = info->attrs; 7473 u64 rate, burst; 7474 int err; 7475 7476 rate = policer_item->rate; 7477 burst = policer_item->burst; 7478 7479 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]) 7480 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]); 7481 7482 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]) 7483 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]); 7484 7485 if (rate < policer_item->policer->min_rate) { 7486 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit"); 7487 return -EINVAL; 7488 } 7489 7490 if (rate > policer_item->policer->max_rate) { 7491 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit"); 7492 return -EINVAL; 7493 } 7494 7495 if (burst < policer_item->policer->min_burst) { 7496 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit"); 7497 return -EINVAL; 7498 } 7499 7500 if (burst > policer_item->policer->max_burst) { 7501 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit"); 7502 return -EINVAL; 7503 } 7504 7505 err = devlink->ops->trap_policer_set(devlink, policer_item->policer, 7506 rate, burst, info->extack); 7507 if (err) 7508 return err; 7509 7510 policer_item->rate = rate; 7511 policer_item->burst = burst; 7512 7513 return 0; 7514} 7515 7516static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb, 7517 struct genl_info *info) 7518{ 7519 struct devlink_trap_policer_item *policer_item; 7520 struct netlink_ext_ack *extack = info->extack; 7521 struct devlink *devlink = info->user_ptr[0]; 7522 7523 if (list_empty(&devlink->trap_policer_list)) 7524 return -EOPNOTSUPP; 7525 7526 if (!devlink->ops->trap_policer_set) 7527 return -EOPNOTSUPP; 7528 7529 policer_item = devlink_trap_policer_item_get_from_info(devlink, info); 7530 if (!policer_item) { 7531 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); 7532 return -ENOENT; 7533 } 7534 7535 return devlink_trap_policer_set(devlink, policer_item, info); 7536} 7537 7538static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { 7539 [DEVLINK_ATTR_UNSPEC] = { .strict_start_type = 7540 DEVLINK_ATTR_TRAP_POLICER_ID }, 7541 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, 7542 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, 7543 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 }, 7544 [DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO, 7545 DEVLINK_PORT_TYPE_IB), 7546 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 }, 7547 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 }, 7548 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 }, 7549 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 }, 7550 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 }, 7551 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, 7552 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, 7553 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, 7554 [DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY, 7555 DEVLINK_ESWITCH_MODE_SWITCHDEV), 7556 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 }, 7557 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, 7558 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, 7559 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, 7560 [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64}, 7561 [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64}, 7562 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING }, 7563 [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 }, 7564 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 }, 7565 [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING }, 7566 [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 }, 7567 [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 }, 7568 [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 }, 7569 [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING }, 7570 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 }, 7571 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 }, 7572 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING }, 7573 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING }, 7574 [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] = 7575 NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS), 7576 [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING }, 7577 [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 }, 7578 [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING }, 7579 [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 }, 7580 [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 }, 7581 [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 }, 7582 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 }, 7583 [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 }, 7584 [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 }, 7585 [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 }, 7586 [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED }, 7587 [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 7588 DEVLINK_RELOAD_ACTION_MAX), 7589 [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK), 7590}; 7591 7592static const struct genl_small_ops devlink_nl_ops[] = { 7593 { 7594 .cmd = DEVLINK_CMD_GET, 7595 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7596 .doit = devlink_nl_cmd_get_doit, 7597 .dumpit = devlink_nl_cmd_get_dumpit, 7598 /* can be retrieved by unprivileged users */ 7599 }, 7600 { 7601 .cmd = DEVLINK_CMD_PORT_GET, 7602 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7603 .doit = devlink_nl_cmd_port_get_doit, 7604 .dumpit = devlink_nl_cmd_port_get_dumpit, 7605 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7606 /* can be retrieved by unprivileged users */ 7607 }, 7608 { 7609 .cmd = DEVLINK_CMD_PORT_SET, 7610 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7611 .doit = devlink_nl_cmd_port_set_doit, 7612 .flags = GENL_ADMIN_PERM, 7613 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7614 }, 7615 { 7616 .cmd = DEVLINK_CMD_PORT_SPLIT, 7617 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7618 .doit = devlink_nl_cmd_port_split_doit, 7619 .flags = GENL_ADMIN_PERM, 7620 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7621 }, 7622 { 7623 .cmd = DEVLINK_CMD_PORT_UNSPLIT, 7624 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7625 .doit = devlink_nl_cmd_port_unsplit_doit, 7626 .flags = GENL_ADMIN_PERM, 7627 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7628 }, 7629 { 7630 .cmd = DEVLINK_CMD_SB_GET, 7631 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7632 .doit = devlink_nl_cmd_sb_get_doit, 7633 .dumpit = devlink_nl_cmd_sb_get_dumpit, 7634 /* can be retrieved by unprivileged users */ 7635 }, 7636 { 7637 .cmd = DEVLINK_CMD_SB_POOL_GET, 7638 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7639 .doit = devlink_nl_cmd_sb_pool_get_doit, 7640 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit, 7641 /* can be retrieved by unprivileged users */ 7642 }, 7643 { 7644 .cmd = DEVLINK_CMD_SB_POOL_SET, 7645 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7646 .doit = devlink_nl_cmd_sb_pool_set_doit, 7647 .flags = GENL_ADMIN_PERM, 7648 }, 7649 { 7650 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET, 7651 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7652 .doit = devlink_nl_cmd_sb_port_pool_get_doit, 7653 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit, 7654 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7655 /* can be retrieved by unprivileged users */ 7656 }, 7657 { 7658 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, 7659 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7660 .doit = devlink_nl_cmd_sb_port_pool_set_doit, 7661 .flags = GENL_ADMIN_PERM, 7662 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7663 }, 7664 { 7665 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, 7666 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7667 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, 7668 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit, 7669 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7670 /* can be retrieved by unprivileged users */ 7671 }, 7672 { 7673 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, 7674 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7675 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit, 7676 .flags = GENL_ADMIN_PERM, 7677 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7678 }, 7679 { 7680 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT, 7681 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7682 .doit = devlink_nl_cmd_sb_occ_snapshot_doit, 7683 .flags = GENL_ADMIN_PERM, 7684 }, 7685 { 7686 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR, 7687 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7688 .doit = devlink_nl_cmd_sb_occ_max_clear_doit, 7689 .flags = GENL_ADMIN_PERM, 7690 }, 7691 { 7692 .cmd = DEVLINK_CMD_ESWITCH_GET, 7693 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7694 .doit = devlink_nl_cmd_eswitch_get_doit, 7695 .flags = GENL_ADMIN_PERM, 7696 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7697 }, 7698 { 7699 .cmd = DEVLINK_CMD_ESWITCH_SET, 7700 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7701 .doit = devlink_nl_cmd_eswitch_set_doit, 7702 .flags = GENL_ADMIN_PERM, 7703 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7704 }, 7705 { 7706 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, 7707 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7708 .doit = devlink_nl_cmd_dpipe_table_get, 7709 /* can be retrieved by unprivileged users */ 7710 }, 7711 { 7712 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, 7713 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7714 .doit = devlink_nl_cmd_dpipe_entries_get, 7715 /* can be retrieved by unprivileged users */ 7716 }, 7717 { 7718 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, 7719 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7720 .doit = devlink_nl_cmd_dpipe_headers_get, 7721 /* can be retrieved by unprivileged users */ 7722 }, 7723 { 7724 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, 7725 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7726 .doit = devlink_nl_cmd_dpipe_table_counters_set, 7727 .flags = GENL_ADMIN_PERM, 7728 }, 7729 { 7730 .cmd = DEVLINK_CMD_RESOURCE_SET, 7731 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7732 .doit = devlink_nl_cmd_resource_set, 7733 .flags = GENL_ADMIN_PERM, 7734 }, 7735 { 7736 .cmd = DEVLINK_CMD_RESOURCE_DUMP, 7737 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7738 .doit = devlink_nl_cmd_resource_dump, 7739 /* can be retrieved by unprivileged users */ 7740 }, 7741 { 7742 .cmd = DEVLINK_CMD_RELOAD, 7743 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7744 .doit = devlink_nl_cmd_reload, 7745 .flags = GENL_ADMIN_PERM, 7746 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7747 }, 7748 { 7749 .cmd = DEVLINK_CMD_PARAM_GET, 7750 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7751 .doit = devlink_nl_cmd_param_get_doit, 7752 .dumpit = devlink_nl_cmd_param_get_dumpit, 7753 /* can be retrieved by unprivileged users */ 7754 }, 7755 { 7756 .cmd = DEVLINK_CMD_PARAM_SET, 7757 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7758 .doit = devlink_nl_cmd_param_set_doit, 7759 .flags = GENL_ADMIN_PERM, 7760 }, 7761 { 7762 .cmd = DEVLINK_CMD_PORT_PARAM_GET, 7763 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7764 .doit = devlink_nl_cmd_port_param_get_doit, 7765 .dumpit = devlink_nl_cmd_port_param_get_dumpit, 7766 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7767 /* can be retrieved by unprivileged users */ 7768 }, 7769 { 7770 .cmd = DEVLINK_CMD_PORT_PARAM_SET, 7771 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7772 .doit = devlink_nl_cmd_port_param_set_doit, 7773 .flags = GENL_ADMIN_PERM, 7774 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7775 }, 7776 { 7777 .cmd = DEVLINK_CMD_REGION_GET, 7778 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7779 .doit = devlink_nl_cmd_region_get_doit, 7780 .dumpit = devlink_nl_cmd_region_get_dumpit, 7781 .flags = GENL_ADMIN_PERM, 7782 }, 7783 { 7784 .cmd = DEVLINK_CMD_REGION_NEW, 7785 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7786 .doit = devlink_nl_cmd_region_new, 7787 .flags = GENL_ADMIN_PERM, 7788 }, 7789 { 7790 .cmd = DEVLINK_CMD_REGION_DEL, 7791 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7792 .doit = devlink_nl_cmd_region_del, 7793 .flags = GENL_ADMIN_PERM, 7794 }, 7795 { 7796 .cmd = DEVLINK_CMD_REGION_READ, 7797 .validate = GENL_DONT_VALIDATE_STRICT | 7798 GENL_DONT_VALIDATE_DUMP_STRICT, 7799 .dumpit = devlink_nl_cmd_region_read_dumpit, 7800 .flags = GENL_ADMIN_PERM, 7801 }, 7802 { 7803 .cmd = DEVLINK_CMD_INFO_GET, 7804 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7805 .doit = devlink_nl_cmd_info_get_doit, 7806 .dumpit = devlink_nl_cmd_info_get_dumpit, 7807 /* can be retrieved by unprivileged users */ 7808 }, 7809 { 7810 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET, 7811 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7812 .doit = devlink_nl_cmd_health_reporter_get_doit, 7813 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit, 7814 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7815 DEVLINK_NL_FLAG_NO_LOCK, 7816 /* can be retrieved by unprivileged users */ 7817 }, 7818 { 7819 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET, 7820 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7821 .doit = devlink_nl_cmd_health_reporter_set_doit, 7822 .flags = GENL_ADMIN_PERM, 7823 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7824 DEVLINK_NL_FLAG_NO_LOCK, 7825 }, 7826 { 7827 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, 7828 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7829 .doit = devlink_nl_cmd_health_reporter_recover_doit, 7830 .flags = GENL_ADMIN_PERM, 7831 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7832 DEVLINK_NL_FLAG_NO_LOCK, 7833 }, 7834 { 7835 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 7836 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7837 .doit = devlink_nl_cmd_health_reporter_diagnose_doit, 7838 .flags = GENL_ADMIN_PERM, 7839 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7840 DEVLINK_NL_FLAG_NO_LOCK, 7841 }, 7842 { 7843 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, 7844 .validate = GENL_DONT_VALIDATE_STRICT | 7845 GENL_DONT_VALIDATE_DUMP_STRICT, 7846 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit, 7847 .flags = GENL_ADMIN_PERM, 7848 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7849 DEVLINK_NL_FLAG_NO_LOCK, 7850 }, 7851 { 7852 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, 7853 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7854 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit, 7855 .flags = GENL_ADMIN_PERM, 7856 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7857 DEVLINK_NL_FLAG_NO_LOCK, 7858 }, 7859 { 7860 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST, 7861 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7862 .doit = devlink_nl_cmd_health_reporter_test_doit, 7863 .flags = GENL_ADMIN_PERM, 7864 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7865 DEVLINK_NL_FLAG_NO_LOCK, 7866 }, 7867 { 7868 .cmd = DEVLINK_CMD_FLASH_UPDATE, 7869 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7870 .doit = devlink_nl_cmd_flash_update, 7871 .flags = GENL_ADMIN_PERM, 7872 }, 7873 { 7874 .cmd = DEVLINK_CMD_TRAP_GET, 7875 .doit = devlink_nl_cmd_trap_get_doit, 7876 .dumpit = devlink_nl_cmd_trap_get_dumpit, 7877 /* can be retrieved by unprivileged users */ 7878 }, 7879 { 7880 .cmd = DEVLINK_CMD_TRAP_SET, 7881 .doit = devlink_nl_cmd_trap_set_doit, 7882 .flags = GENL_ADMIN_PERM, 7883 }, 7884 { 7885 .cmd = DEVLINK_CMD_TRAP_GROUP_GET, 7886 .doit = devlink_nl_cmd_trap_group_get_doit, 7887 .dumpit = devlink_nl_cmd_trap_group_get_dumpit, 7888 /* can be retrieved by unprivileged users */ 7889 }, 7890 { 7891 .cmd = DEVLINK_CMD_TRAP_GROUP_SET, 7892 .doit = devlink_nl_cmd_trap_group_set_doit, 7893 .flags = GENL_ADMIN_PERM, 7894 }, 7895 { 7896 .cmd = DEVLINK_CMD_TRAP_POLICER_GET, 7897 .doit = devlink_nl_cmd_trap_policer_get_doit, 7898 .dumpit = devlink_nl_cmd_trap_policer_get_dumpit, 7899 /* can be retrieved by unprivileged users */ 7900 }, 7901 { 7902 .cmd = DEVLINK_CMD_TRAP_POLICER_SET, 7903 .doit = devlink_nl_cmd_trap_policer_set_doit, 7904 .flags = GENL_ADMIN_PERM, 7905 }, 7906}; 7907 7908static struct genl_family devlink_nl_family __ro_after_init = { 7909 .name = DEVLINK_GENL_NAME, 7910 .version = DEVLINK_GENL_VERSION, 7911 .maxattr = DEVLINK_ATTR_MAX, 7912 .policy = devlink_nl_policy, 7913 .netnsok = true, 7914 .pre_doit = devlink_nl_pre_doit, 7915 .post_doit = devlink_nl_post_doit, 7916 .module = THIS_MODULE, 7917 .small_ops = devlink_nl_ops, 7918 .n_small_ops = ARRAY_SIZE(devlink_nl_ops), 7919 .mcgrps = devlink_nl_mcgrps, 7920 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), 7921}; 7922 7923static bool devlink_reload_actions_valid(const struct devlink_ops *ops) 7924{ 7925 const struct devlink_reload_combination *comb; 7926 int i; 7927 7928 if (!devlink_reload_supported(ops)) { 7929 if (WARN_ON(ops->reload_actions)) 7930 return false; 7931 return true; 7932 } 7933 7934 if (WARN_ON(!ops->reload_actions || 7935 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 7936 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) 7937 return false; 7938 7939 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || 7940 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) 7941 return false; 7942 7943 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { 7944 comb = &devlink_reload_invalid_combinations[i]; 7945 if (ops->reload_actions == BIT(comb->action) && 7946 ops->reload_limits == BIT(comb->limit)) 7947 return false; 7948 } 7949 return true; 7950} 7951 7952/** 7953 * devlink_alloc - Allocate new devlink instance resources 7954 * 7955 * @ops: ops 7956 * @priv_size: size of user private data 7957 * 7958 * Allocate new devlink instance resources, including devlink index 7959 * and name. 7960 */ 7961struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) 7962{ 7963 struct devlink *devlink; 7964 7965 if (WARN_ON(!ops)) 7966 return NULL; 7967 7968 if (!devlink_reload_actions_valid(ops)) 7969 return NULL; 7970 7971 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); 7972 if (!devlink) 7973 return NULL; 7974 devlink->ops = ops; 7975 xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC); 7976 __devlink_net_set(devlink, &init_net); 7977 INIT_LIST_HEAD(&devlink->port_list); 7978 INIT_LIST_HEAD(&devlink->sb_list); 7979 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list); 7980 INIT_LIST_HEAD(&devlink->resource_list); 7981 INIT_LIST_HEAD(&devlink->param_list); 7982 INIT_LIST_HEAD(&devlink->region_list); 7983 INIT_LIST_HEAD(&devlink->reporter_list); 7984 INIT_LIST_HEAD(&devlink->trap_list); 7985 INIT_LIST_HEAD(&devlink->trap_group_list); 7986 INIT_LIST_HEAD(&devlink->trap_policer_list); 7987 mutex_init(&devlink->lock); 7988 mutex_init(&devlink->reporters_lock); 7989 return devlink; 7990} 7991EXPORT_SYMBOL_GPL(devlink_alloc); 7992 7993/** 7994 * devlink_register - Register devlink instance 7995 * 7996 * @devlink: devlink 7997 * @dev: parent device 7998 */ 7999int devlink_register(struct devlink *devlink, struct device *dev) 8000{ 8001 devlink->dev = dev; 8002 devlink->registered = true; 8003 mutex_lock(&devlink_mutex); 8004 list_add_tail(&devlink->list, &devlink_list); 8005 devlink_notify(devlink, DEVLINK_CMD_NEW); 8006 mutex_unlock(&devlink_mutex); 8007 return 0; 8008} 8009EXPORT_SYMBOL_GPL(devlink_register); 8010 8011/** 8012 * devlink_unregister - Unregister devlink instance 8013 * 8014 * @devlink: devlink 8015 */ 8016void devlink_unregister(struct devlink *devlink) 8017{ 8018 mutex_lock(&devlink_mutex); 8019 WARN_ON(devlink_reload_supported(devlink->ops) && 8020 devlink->reload_enabled); 8021 devlink_notify(devlink, DEVLINK_CMD_DEL); 8022 list_del(&devlink->list); 8023 mutex_unlock(&devlink_mutex); 8024} 8025EXPORT_SYMBOL_GPL(devlink_unregister); 8026 8027/** 8028 * devlink_reload_enable - Enable reload of devlink instance 8029 * 8030 * @devlink: devlink 8031 * 8032 * Should be called at end of device initialization 8033 * process when reload operation is supported. 8034 */ 8035void devlink_reload_enable(struct devlink *devlink) 8036{ 8037 mutex_lock(&devlink_mutex); 8038 devlink->reload_enabled = true; 8039 mutex_unlock(&devlink_mutex); 8040} 8041EXPORT_SYMBOL_GPL(devlink_reload_enable); 8042 8043/** 8044 * devlink_reload_disable - Disable reload of devlink instance 8045 * 8046 * @devlink: devlink 8047 * 8048 * Should be called at the beginning of device cleanup 8049 * process when reload operation is supported. 8050 */ 8051void devlink_reload_disable(struct devlink *devlink) 8052{ 8053 mutex_lock(&devlink_mutex); 8054 /* Mutex is taken which ensures that no reload operation is in 8055 * progress while setting up forbidded flag. 8056 */ 8057 devlink->reload_enabled = false; 8058 mutex_unlock(&devlink_mutex); 8059} 8060EXPORT_SYMBOL_GPL(devlink_reload_disable); 8061 8062/** 8063 * devlink_free - Free devlink instance resources 8064 * 8065 * @devlink: devlink 8066 */ 8067void devlink_free(struct devlink *devlink) 8068{ 8069 mutex_destroy(&devlink->reporters_lock); 8070 mutex_destroy(&devlink->lock); 8071 WARN_ON(!list_empty(&devlink->trap_policer_list)); 8072 WARN_ON(!list_empty(&devlink->trap_group_list)); 8073 WARN_ON(!list_empty(&devlink->trap_list)); 8074 WARN_ON(!list_empty(&devlink->reporter_list)); 8075 WARN_ON(!list_empty(&devlink->region_list)); 8076 WARN_ON(!list_empty(&devlink->param_list)); 8077 WARN_ON(!list_empty(&devlink->resource_list)); 8078 WARN_ON(!list_empty(&devlink->dpipe_table_list)); 8079 WARN_ON(!list_empty(&devlink->sb_list)); 8080 WARN_ON(!list_empty(&devlink->port_list)); 8081 8082 xa_destroy(&devlink->snapshot_ids); 8083 8084 kfree(devlink); 8085} 8086EXPORT_SYMBOL_GPL(devlink_free); 8087 8088static void devlink_port_type_warn(struct work_struct *work) 8089{ 8090 WARN(true, "Type was not set for devlink port."); 8091} 8092 8093static bool devlink_port_type_should_warn(struct devlink_port *devlink_port) 8094{ 8095 /* Ignore CPU and DSA flavours. */ 8096 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU && 8097 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA && 8098 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED; 8099} 8100 8101#define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600) 8102 8103static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port) 8104{ 8105 if (!devlink_port_type_should_warn(devlink_port)) 8106 return; 8107 /* Schedule a work to WARN in case driver does not set port 8108 * type within timeout. 8109 */ 8110 schedule_delayed_work(&devlink_port->type_warn_dw, 8111 DEVLINK_PORT_TYPE_WARN_TIMEOUT); 8112} 8113 8114static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port) 8115{ 8116 if (!devlink_port_type_should_warn(devlink_port)) 8117 return; 8118 cancel_delayed_work_sync(&devlink_port->type_warn_dw); 8119} 8120 8121/** 8122 * devlink_port_register - Register devlink port 8123 * 8124 * @devlink: devlink 8125 * @devlink_port: devlink port 8126 * @port_index: driver-specific numerical identifier of the port 8127 * 8128 * Register devlink port with provided port index. User can use 8129 * any indexing, even hw-related one. devlink_port structure 8130 * is convenient to be embedded inside user driver private structure. 8131 * Note that the caller should take care of zeroing the devlink_port 8132 * structure. 8133 */ 8134int devlink_port_register(struct devlink *devlink, 8135 struct devlink_port *devlink_port, 8136 unsigned int port_index) 8137{ 8138 mutex_lock(&devlink->lock); 8139 if (devlink_port_index_exists(devlink, port_index)) { 8140 mutex_unlock(&devlink->lock); 8141 return -EEXIST; 8142 } 8143 devlink_port->devlink = devlink; 8144 devlink_port->index = port_index; 8145 devlink_port->registered = true; 8146 spin_lock_init(&devlink_port->type_lock); 8147 INIT_LIST_HEAD(&devlink_port->reporter_list); 8148 mutex_init(&devlink_port->reporters_lock); 8149 list_add_tail(&devlink_port->list, &devlink->port_list); 8150 INIT_LIST_HEAD(&devlink_port->param_list); 8151 INIT_LIST_HEAD(&devlink_port->region_list); 8152 mutex_unlock(&devlink->lock); 8153 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn); 8154 devlink_port_type_warn_schedule(devlink_port); 8155 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 8156 return 0; 8157} 8158EXPORT_SYMBOL_GPL(devlink_port_register); 8159 8160/** 8161 * devlink_port_unregister - Unregister devlink port 8162 * 8163 * @devlink_port: devlink port 8164 */ 8165void devlink_port_unregister(struct devlink_port *devlink_port) 8166{ 8167 struct devlink *devlink = devlink_port->devlink; 8168 8169 devlink_port_type_warn_cancel(devlink_port); 8170 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); 8171 mutex_lock(&devlink->lock); 8172 list_del(&devlink_port->list); 8173 mutex_unlock(&devlink->lock); 8174 WARN_ON(!list_empty(&devlink_port->reporter_list)); 8175 WARN_ON(!list_empty(&devlink_port->region_list)); 8176 mutex_destroy(&devlink_port->reporters_lock); 8177} 8178EXPORT_SYMBOL_GPL(devlink_port_unregister); 8179 8180static void __devlink_port_type_set(struct devlink_port *devlink_port, 8181 enum devlink_port_type type, 8182 void *type_dev) 8183{ 8184 if (WARN_ON(!devlink_port->registered)) 8185 return; 8186 devlink_port_type_warn_cancel(devlink_port); 8187 spin_lock_bh(&devlink_port->type_lock); 8188 devlink_port->type = type; 8189 devlink_port->type_dev = type_dev; 8190 spin_unlock_bh(&devlink_port->type_lock); 8191 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 8192} 8193 8194static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port, 8195 struct net_device *netdev) 8196{ 8197 const struct net_device_ops *ops = netdev->netdev_ops; 8198 8199 /* If driver registers devlink port, it should set devlink port 8200 * attributes accordingly so the compat functions are called 8201 * and the original ops are not used. 8202 */ 8203 if (ops->ndo_get_phys_port_name) { 8204 /* Some drivers use the same set of ndos for netdevs 8205 * that have devlink_port registered and also for 8206 * those who don't. Make sure that ndo_get_phys_port_name 8207 * returns -EOPNOTSUPP here in case it is defined. 8208 * Warn if not. 8209 */ 8210 char name[IFNAMSIZ]; 8211 int err; 8212 8213 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name)); 8214 WARN_ON(err != -EOPNOTSUPP); 8215 } 8216 if (ops->ndo_get_port_parent_id) { 8217 /* Some drivers use the same set of ndos for netdevs 8218 * that have devlink_port registered and also for 8219 * those who don't. Make sure that ndo_get_port_parent_id 8220 * returns -EOPNOTSUPP here in case it is defined. 8221 * Warn if not. 8222 */ 8223 struct netdev_phys_item_id ppid; 8224 int err; 8225 8226 err = ops->ndo_get_port_parent_id(netdev, &ppid); 8227 WARN_ON(err != -EOPNOTSUPP); 8228 } 8229} 8230 8231/** 8232 * devlink_port_type_eth_set - Set port type to Ethernet 8233 * 8234 * @devlink_port: devlink port 8235 * @netdev: related netdevice 8236 */ 8237void devlink_port_type_eth_set(struct devlink_port *devlink_port, 8238 struct net_device *netdev) 8239{ 8240 if (netdev) 8241 devlink_port_type_netdev_checks(devlink_port, netdev); 8242 else 8243 dev_warn(devlink_port->devlink->dev, 8244 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n", 8245 devlink_port->index); 8246 8247 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev); 8248} 8249EXPORT_SYMBOL_GPL(devlink_port_type_eth_set); 8250 8251/** 8252 * devlink_port_type_ib_set - Set port type to InfiniBand 8253 * 8254 * @devlink_port: devlink port 8255 * @ibdev: related IB device 8256 */ 8257void devlink_port_type_ib_set(struct devlink_port *devlink_port, 8258 struct ib_device *ibdev) 8259{ 8260 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev); 8261} 8262EXPORT_SYMBOL_GPL(devlink_port_type_ib_set); 8263 8264/** 8265 * devlink_port_type_clear - Clear port type 8266 * 8267 * @devlink_port: devlink port 8268 */ 8269void devlink_port_type_clear(struct devlink_port *devlink_port) 8270{ 8271 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL); 8272 devlink_port_type_warn_schedule(devlink_port); 8273} 8274EXPORT_SYMBOL_GPL(devlink_port_type_clear); 8275 8276static int __devlink_port_attrs_set(struct devlink_port *devlink_port, 8277 enum devlink_port_flavour flavour) 8278{ 8279 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8280 8281 devlink_port->attrs_set = true; 8282 attrs->flavour = flavour; 8283 if (attrs->switch_id.id_len) { 8284 devlink_port->switch_port = true; 8285 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN)) 8286 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN; 8287 } else { 8288 devlink_port->switch_port = false; 8289 } 8290 return 0; 8291} 8292 8293/** 8294 * devlink_port_attrs_set - Set port attributes 8295 * 8296 * @devlink_port: devlink port 8297 * @attrs: devlink port attrs 8298 */ 8299void devlink_port_attrs_set(struct devlink_port *devlink_port, 8300 struct devlink_port_attrs *attrs) 8301{ 8302 int ret; 8303 8304 if (WARN_ON(devlink_port->registered)) 8305 return; 8306 devlink_port->attrs = *attrs; 8307 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour); 8308 if (ret) 8309 return; 8310 WARN_ON(attrs->splittable && attrs->split); 8311} 8312EXPORT_SYMBOL_GPL(devlink_port_attrs_set); 8313 8314/** 8315 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes 8316 * 8317 * @devlink_port: devlink port 8318 * @controller: associated controller number for the devlink port instance 8319 * @pf: associated PF for the devlink port instance 8320 * @external: indicates if the port is for an external controller 8321 */ 8322void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller, 8323 u16 pf, bool external) 8324{ 8325 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8326 int ret; 8327 8328 if (WARN_ON(devlink_port->registered)) 8329 return; 8330 ret = __devlink_port_attrs_set(devlink_port, 8331 DEVLINK_PORT_FLAVOUR_PCI_PF); 8332 if (ret) 8333 return; 8334 attrs->pci_pf.controller = controller; 8335 attrs->pci_pf.pf = pf; 8336 attrs->pci_pf.external = external; 8337} 8338EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set); 8339 8340/** 8341 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes 8342 * 8343 * @devlink_port: devlink port 8344 * @controller: associated controller number for the devlink port instance 8345 * @pf: associated PF for the devlink port instance 8346 * @vf: associated VF of a PF for the devlink port instance 8347 * @external: indicates if the port is for an external controller 8348 */ 8349void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller, 8350 u16 pf, u16 vf, bool external) 8351{ 8352 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8353 int ret; 8354 8355 if (WARN_ON(devlink_port->registered)) 8356 return; 8357 ret = __devlink_port_attrs_set(devlink_port, 8358 DEVLINK_PORT_FLAVOUR_PCI_VF); 8359 if (ret) 8360 return; 8361 attrs->pci_vf.controller = controller; 8362 attrs->pci_vf.pf = pf; 8363 attrs->pci_vf.vf = vf; 8364 attrs->pci_vf.external = external; 8365} 8366EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set); 8367 8368static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, 8369 char *name, size_t len) 8370{ 8371 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8372 int n = 0; 8373 8374 if (!devlink_port->attrs_set) 8375 return -EOPNOTSUPP; 8376 8377 switch (attrs->flavour) { 8378 case DEVLINK_PORT_FLAVOUR_PHYSICAL: 8379 case DEVLINK_PORT_FLAVOUR_VIRTUAL: 8380 if (!attrs->split) 8381 n = snprintf(name, len, "p%u", attrs->phys.port_number); 8382 else 8383 n = snprintf(name, len, "p%us%u", 8384 attrs->phys.port_number, 8385 attrs->phys.split_subport_number); 8386 break; 8387 case DEVLINK_PORT_FLAVOUR_CPU: 8388 case DEVLINK_PORT_FLAVOUR_DSA: 8389 case DEVLINK_PORT_FLAVOUR_UNUSED: 8390 /* As CPU and DSA ports do not have a netdevice associated 8391 * case should not ever happen. 8392 */ 8393 WARN_ON(1); 8394 return -EINVAL; 8395 case DEVLINK_PORT_FLAVOUR_PCI_PF: 8396 if (attrs->pci_pf.external) { 8397 n = snprintf(name, len, "c%u", attrs->pci_pf.controller); 8398 if (n >= len) 8399 return -EINVAL; 8400 len -= n; 8401 name += n; 8402 } 8403 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf); 8404 break; 8405 case DEVLINK_PORT_FLAVOUR_PCI_VF: 8406 if (attrs->pci_vf.external) { 8407 n = snprintf(name, len, "c%u", attrs->pci_vf.controller); 8408 if (n >= len) 8409 return -EINVAL; 8410 len -= n; 8411 name += n; 8412 } 8413 n = snprintf(name, len, "pf%uvf%u", 8414 attrs->pci_vf.pf, attrs->pci_vf.vf); 8415 break; 8416 } 8417 8418 if (n >= len) 8419 return -EINVAL; 8420 8421 return 0; 8422} 8423 8424int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, 8425 u32 size, u16 ingress_pools_count, 8426 u16 egress_pools_count, u16 ingress_tc_count, 8427 u16 egress_tc_count) 8428{ 8429 struct devlink_sb *devlink_sb; 8430 int err = 0; 8431 8432 mutex_lock(&devlink->lock); 8433 if (devlink_sb_index_exists(devlink, sb_index)) { 8434 err = -EEXIST; 8435 goto unlock; 8436 } 8437 8438 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL); 8439 if (!devlink_sb) { 8440 err = -ENOMEM; 8441 goto unlock; 8442 } 8443 devlink_sb->index = sb_index; 8444 devlink_sb->size = size; 8445 devlink_sb->ingress_pools_count = ingress_pools_count; 8446 devlink_sb->egress_pools_count = egress_pools_count; 8447 devlink_sb->ingress_tc_count = ingress_tc_count; 8448 devlink_sb->egress_tc_count = egress_tc_count; 8449 list_add_tail(&devlink_sb->list, &devlink->sb_list); 8450unlock: 8451 mutex_unlock(&devlink->lock); 8452 return err; 8453} 8454EXPORT_SYMBOL_GPL(devlink_sb_register); 8455 8456void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index) 8457{ 8458 struct devlink_sb *devlink_sb; 8459 8460 mutex_lock(&devlink->lock); 8461 devlink_sb = devlink_sb_get_by_index(devlink, sb_index); 8462 WARN_ON(!devlink_sb); 8463 list_del(&devlink_sb->list); 8464 mutex_unlock(&devlink->lock); 8465 kfree(devlink_sb); 8466} 8467EXPORT_SYMBOL_GPL(devlink_sb_unregister); 8468 8469/** 8470 * devlink_dpipe_headers_register - register dpipe headers 8471 * 8472 * @devlink: devlink 8473 * @dpipe_headers: dpipe header array 8474 * 8475 * Register the headers supported by hardware. 8476 */ 8477int devlink_dpipe_headers_register(struct devlink *devlink, 8478 struct devlink_dpipe_headers *dpipe_headers) 8479{ 8480 mutex_lock(&devlink->lock); 8481 devlink->dpipe_headers = dpipe_headers; 8482 mutex_unlock(&devlink->lock); 8483 return 0; 8484} 8485EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register); 8486 8487/** 8488 * devlink_dpipe_headers_unregister - unregister dpipe headers 8489 * 8490 * @devlink: devlink 8491 * 8492 * Unregister the headers supported by hardware. 8493 */ 8494void devlink_dpipe_headers_unregister(struct devlink *devlink) 8495{ 8496 mutex_lock(&devlink->lock); 8497 devlink->dpipe_headers = NULL; 8498 mutex_unlock(&devlink->lock); 8499} 8500EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister); 8501 8502/** 8503 * devlink_dpipe_table_counter_enabled - check if counter allocation 8504 * required 8505 * @devlink: devlink 8506 * @table_name: tables name 8507 * 8508 * Used by driver to check if counter allocation is required. 8509 * After counter allocation is turned on the table entries 8510 * are updated to include counter statistics. 8511 * 8512 * After that point on the driver must respect the counter 8513 * state so that each entry added to the table is added 8514 * with a counter. 8515 */ 8516bool devlink_dpipe_table_counter_enabled(struct devlink *devlink, 8517 const char *table_name) 8518{ 8519 struct devlink_dpipe_table *table; 8520 bool enabled; 8521 8522 rcu_read_lock(); 8523 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8524 table_name, devlink); 8525 enabled = false; 8526 if (table) 8527 enabled = table->counters_enabled; 8528 rcu_read_unlock(); 8529 return enabled; 8530} 8531EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled); 8532 8533/** 8534 * devlink_dpipe_table_register - register dpipe table 8535 * 8536 * @devlink: devlink 8537 * @table_name: table name 8538 * @table_ops: table ops 8539 * @priv: priv 8540 * @counter_control_extern: external control for counters 8541 */ 8542int devlink_dpipe_table_register(struct devlink *devlink, 8543 const char *table_name, 8544 struct devlink_dpipe_table_ops *table_ops, 8545 void *priv, bool counter_control_extern) 8546{ 8547 struct devlink_dpipe_table *table; 8548 int err = 0; 8549 8550 if (WARN_ON(!table_ops->size_get)) 8551 return -EINVAL; 8552 8553 mutex_lock(&devlink->lock); 8554 8555 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name, 8556 devlink)) { 8557 err = -EEXIST; 8558 goto unlock; 8559 } 8560 8561 table = kzalloc(sizeof(*table), GFP_KERNEL); 8562 if (!table) { 8563 err = -ENOMEM; 8564 goto unlock; 8565 } 8566 8567 table->name = table_name; 8568 table->table_ops = table_ops; 8569 table->priv = priv; 8570 table->counter_control_extern = counter_control_extern; 8571 8572 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list); 8573unlock: 8574 mutex_unlock(&devlink->lock); 8575 return err; 8576} 8577EXPORT_SYMBOL_GPL(devlink_dpipe_table_register); 8578 8579/** 8580 * devlink_dpipe_table_unregister - unregister dpipe table 8581 * 8582 * @devlink: devlink 8583 * @table_name: table name 8584 */ 8585void devlink_dpipe_table_unregister(struct devlink *devlink, 8586 const char *table_name) 8587{ 8588 struct devlink_dpipe_table *table; 8589 8590 mutex_lock(&devlink->lock); 8591 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8592 table_name, devlink); 8593 if (!table) 8594 goto unlock; 8595 list_del_rcu(&table->list); 8596 mutex_unlock(&devlink->lock); 8597 kfree_rcu(table, rcu); 8598 return; 8599unlock: 8600 mutex_unlock(&devlink->lock); 8601} 8602EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister); 8603 8604/** 8605 * devlink_resource_register - devlink resource register 8606 * 8607 * @devlink: devlink 8608 * @resource_name: resource's name 8609 * @resource_size: resource's size 8610 * @resource_id: resource's id 8611 * @parent_resource_id: resource's parent id 8612 * @size_params: size parameters 8613 */ 8614int devlink_resource_register(struct devlink *devlink, 8615 const char *resource_name, 8616 u64 resource_size, 8617 u64 resource_id, 8618 u64 parent_resource_id, 8619 const struct devlink_resource_size_params *size_params) 8620{ 8621 struct devlink_resource *resource; 8622 struct list_head *resource_list; 8623 bool top_hierarchy; 8624 int err = 0; 8625 8626 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP; 8627 8628 mutex_lock(&devlink->lock); 8629 resource = devlink_resource_find(devlink, NULL, resource_id); 8630 if (resource) { 8631 err = -EINVAL; 8632 goto out; 8633 } 8634 8635 resource = kzalloc(sizeof(*resource), GFP_KERNEL); 8636 if (!resource) { 8637 err = -ENOMEM; 8638 goto out; 8639 } 8640 8641 if (top_hierarchy) { 8642 resource_list = &devlink->resource_list; 8643 } else { 8644 struct devlink_resource *parent_resource; 8645 8646 parent_resource = devlink_resource_find(devlink, NULL, 8647 parent_resource_id); 8648 if (parent_resource) { 8649 resource_list = &parent_resource->resource_list; 8650 resource->parent = parent_resource; 8651 } else { 8652 kfree(resource); 8653 err = -EINVAL; 8654 goto out; 8655 } 8656 } 8657 8658 resource->name = resource_name; 8659 resource->size = resource_size; 8660 resource->size_new = resource_size; 8661 resource->id = resource_id; 8662 resource->size_valid = true; 8663 memcpy(&resource->size_params, size_params, 8664 sizeof(resource->size_params)); 8665 INIT_LIST_HEAD(&resource->resource_list); 8666 list_add_tail(&resource->list, resource_list); 8667out: 8668 mutex_unlock(&devlink->lock); 8669 return err; 8670} 8671EXPORT_SYMBOL_GPL(devlink_resource_register); 8672 8673/** 8674 * devlink_resources_unregister - free all resources 8675 * 8676 * @devlink: devlink 8677 * @resource: resource 8678 */ 8679void devlink_resources_unregister(struct devlink *devlink, 8680 struct devlink_resource *resource) 8681{ 8682 struct devlink_resource *tmp, *child_resource; 8683 struct list_head *resource_list; 8684 8685 if (resource) 8686 resource_list = &resource->resource_list; 8687 else 8688 resource_list = &devlink->resource_list; 8689 8690 if (!resource) 8691 mutex_lock(&devlink->lock); 8692 8693 list_for_each_entry_safe(child_resource, tmp, resource_list, list) { 8694 devlink_resources_unregister(devlink, child_resource); 8695 list_del(&child_resource->list); 8696 kfree(child_resource); 8697 } 8698 8699 if (!resource) 8700 mutex_unlock(&devlink->lock); 8701} 8702EXPORT_SYMBOL_GPL(devlink_resources_unregister); 8703 8704/** 8705 * devlink_resource_size_get - get and update size 8706 * 8707 * @devlink: devlink 8708 * @resource_id: the requested resource id 8709 * @p_resource_size: ptr to update 8710 */ 8711int devlink_resource_size_get(struct devlink *devlink, 8712 u64 resource_id, 8713 u64 *p_resource_size) 8714{ 8715 struct devlink_resource *resource; 8716 int err = 0; 8717 8718 mutex_lock(&devlink->lock); 8719 resource = devlink_resource_find(devlink, NULL, resource_id); 8720 if (!resource) { 8721 err = -EINVAL; 8722 goto out; 8723 } 8724 *p_resource_size = resource->size_new; 8725 resource->size = resource->size_new; 8726out: 8727 mutex_unlock(&devlink->lock); 8728 return err; 8729} 8730EXPORT_SYMBOL_GPL(devlink_resource_size_get); 8731 8732/** 8733 * devlink_dpipe_table_resource_set - set the resource id 8734 * 8735 * @devlink: devlink 8736 * @table_name: table name 8737 * @resource_id: resource id 8738 * @resource_units: number of resource's units consumed per table's entry 8739 */ 8740int devlink_dpipe_table_resource_set(struct devlink *devlink, 8741 const char *table_name, u64 resource_id, 8742 u64 resource_units) 8743{ 8744 struct devlink_dpipe_table *table; 8745 int err = 0; 8746 8747 mutex_lock(&devlink->lock); 8748 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8749 table_name, devlink); 8750 if (!table) { 8751 err = -EINVAL; 8752 goto out; 8753 } 8754 table->resource_id = resource_id; 8755 table->resource_units = resource_units; 8756 table->resource_valid = true; 8757out: 8758 mutex_unlock(&devlink->lock); 8759 return err; 8760} 8761EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set); 8762 8763/** 8764 * devlink_resource_occ_get_register - register occupancy getter 8765 * 8766 * @devlink: devlink 8767 * @resource_id: resource id 8768 * @occ_get: occupancy getter callback 8769 * @occ_get_priv: occupancy getter callback priv 8770 */ 8771void devlink_resource_occ_get_register(struct devlink *devlink, 8772 u64 resource_id, 8773 devlink_resource_occ_get_t *occ_get, 8774 void *occ_get_priv) 8775{ 8776 struct devlink_resource *resource; 8777 8778 mutex_lock(&devlink->lock); 8779 resource = devlink_resource_find(devlink, NULL, resource_id); 8780 if (WARN_ON(!resource)) 8781 goto out; 8782 WARN_ON(resource->occ_get); 8783 8784 resource->occ_get = occ_get; 8785 resource->occ_get_priv = occ_get_priv; 8786out: 8787 mutex_unlock(&devlink->lock); 8788} 8789EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register); 8790 8791/** 8792 * devlink_resource_occ_get_unregister - unregister occupancy getter 8793 * 8794 * @devlink: devlink 8795 * @resource_id: resource id 8796 */ 8797void devlink_resource_occ_get_unregister(struct devlink *devlink, 8798 u64 resource_id) 8799{ 8800 struct devlink_resource *resource; 8801 8802 mutex_lock(&devlink->lock); 8803 resource = devlink_resource_find(devlink, NULL, resource_id); 8804 if (WARN_ON(!resource)) 8805 goto out; 8806 WARN_ON(!resource->occ_get); 8807 8808 resource->occ_get = NULL; 8809 resource->occ_get_priv = NULL; 8810out: 8811 mutex_unlock(&devlink->lock); 8812} 8813EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister); 8814 8815static int devlink_param_verify(const struct devlink_param *param) 8816{ 8817 if (!param || !param->name || !param->supported_cmodes) 8818 return -EINVAL; 8819 if (param->generic) 8820 return devlink_param_generic_verify(param); 8821 else 8822 return devlink_param_driver_verify(param); 8823} 8824 8825static int __devlink_params_register(struct devlink *devlink, 8826 unsigned int port_index, 8827 struct list_head *param_list, 8828 const struct devlink_param *params, 8829 size_t params_count, 8830 enum devlink_command reg_cmd, 8831 enum devlink_command unreg_cmd) 8832{ 8833 const struct devlink_param *param = params; 8834 int i; 8835 int err; 8836 8837 mutex_lock(&devlink->lock); 8838 for (i = 0; i < params_count; i++, param++) { 8839 err = devlink_param_verify(param); 8840 if (err) 8841 goto rollback; 8842 8843 err = devlink_param_register_one(devlink, port_index, 8844 param_list, param, reg_cmd); 8845 if (err) 8846 goto rollback; 8847 } 8848 8849 mutex_unlock(&devlink->lock); 8850 return 0; 8851 8852rollback: 8853 if (!i) 8854 goto unlock; 8855 for (param--; i > 0; i--, param--) 8856 devlink_param_unregister_one(devlink, port_index, param_list, 8857 param, unreg_cmd); 8858unlock: 8859 mutex_unlock(&devlink->lock); 8860 return err; 8861} 8862 8863static void __devlink_params_unregister(struct devlink *devlink, 8864 unsigned int port_index, 8865 struct list_head *param_list, 8866 const struct devlink_param *params, 8867 size_t params_count, 8868 enum devlink_command cmd) 8869{ 8870 const struct devlink_param *param = params; 8871 int i; 8872 8873 mutex_lock(&devlink->lock); 8874 for (i = 0; i < params_count; i++, param++) 8875 devlink_param_unregister_one(devlink, 0, param_list, param, 8876 cmd); 8877 mutex_unlock(&devlink->lock); 8878} 8879 8880/** 8881 * devlink_params_register - register configuration parameters 8882 * 8883 * @devlink: devlink 8884 * @params: configuration parameters array 8885 * @params_count: number of parameters provided 8886 * 8887 * Register the configuration parameters supported by the driver. 8888 */ 8889int devlink_params_register(struct devlink *devlink, 8890 const struct devlink_param *params, 8891 size_t params_count) 8892{ 8893 return __devlink_params_register(devlink, 0, &devlink->param_list, 8894 params, params_count, 8895 DEVLINK_CMD_PARAM_NEW, 8896 DEVLINK_CMD_PARAM_DEL); 8897} 8898EXPORT_SYMBOL_GPL(devlink_params_register); 8899 8900/** 8901 * devlink_params_unregister - unregister configuration parameters 8902 * @devlink: devlink 8903 * @params: configuration parameters to unregister 8904 * @params_count: number of parameters provided 8905 */ 8906void devlink_params_unregister(struct devlink *devlink, 8907 const struct devlink_param *params, 8908 size_t params_count) 8909{ 8910 return __devlink_params_unregister(devlink, 0, &devlink->param_list, 8911 params, params_count, 8912 DEVLINK_CMD_PARAM_DEL); 8913} 8914EXPORT_SYMBOL_GPL(devlink_params_unregister); 8915 8916/** 8917 * devlink_params_publish - publish configuration parameters 8918 * 8919 * @devlink: devlink 8920 * 8921 * Publish previously registered configuration parameters. 8922 */ 8923void devlink_params_publish(struct devlink *devlink) 8924{ 8925 struct devlink_param_item *param_item; 8926 8927 list_for_each_entry(param_item, &devlink->param_list, list) { 8928 if (param_item->published) 8929 continue; 8930 param_item->published = true; 8931 devlink_param_notify(devlink, 0, param_item, 8932 DEVLINK_CMD_PARAM_NEW); 8933 } 8934} 8935EXPORT_SYMBOL_GPL(devlink_params_publish); 8936 8937/** 8938 * devlink_params_unpublish - unpublish configuration parameters 8939 * 8940 * @devlink: devlink 8941 * 8942 * Unpublish previously registered configuration parameters. 8943 */ 8944void devlink_params_unpublish(struct devlink *devlink) 8945{ 8946 struct devlink_param_item *param_item; 8947 8948 list_for_each_entry(param_item, &devlink->param_list, list) { 8949 if (!param_item->published) 8950 continue; 8951 param_item->published = false; 8952 devlink_param_notify(devlink, 0, param_item, 8953 DEVLINK_CMD_PARAM_DEL); 8954 } 8955} 8956EXPORT_SYMBOL_GPL(devlink_params_unpublish); 8957 8958/** 8959 * devlink_port_params_register - register port configuration parameters 8960 * 8961 * @devlink_port: devlink port 8962 * @params: configuration parameters array 8963 * @params_count: number of parameters provided 8964 * 8965 * Register the configuration parameters supported by the port. 8966 */ 8967int devlink_port_params_register(struct devlink_port *devlink_port, 8968 const struct devlink_param *params, 8969 size_t params_count) 8970{ 8971 return __devlink_params_register(devlink_port->devlink, 8972 devlink_port->index, 8973 &devlink_port->param_list, params, 8974 params_count, 8975 DEVLINK_CMD_PORT_PARAM_NEW, 8976 DEVLINK_CMD_PORT_PARAM_DEL); 8977} 8978EXPORT_SYMBOL_GPL(devlink_port_params_register); 8979 8980/** 8981 * devlink_port_params_unregister - unregister port configuration 8982 * parameters 8983 * 8984 * @devlink_port: devlink port 8985 * @params: configuration parameters array 8986 * @params_count: number of parameters provided 8987 */ 8988void devlink_port_params_unregister(struct devlink_port *devlink_port, 8989 const struct devlink_param *params, 8990 size_t params_count) 8991{ 8992 return __devlink_params_unregister(devlink_port->devlink, 8993 devlink_port->index, 8994 &devlink_port->param_list, 8995 params, params_count, 8996 DEVLINK_CMD_PORT_PARAM_DEL); 8997} 8998EXPORT_SYMBOL_GPL(devlink_port_params_unregister); 8999 9000static int 9001__devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id, 9002 union devlink_param_value *init_val) 9003{ 9004 struct devlink_param_item *param_item; 9005 9006 param_item = devlink_param_find_by_id(param_list, param_id); 9007 if (!param_item) 9008 return -EINVAL; 9009 9010 if (!param_item->driverinit_value_valid || 9011 !devlink_param_cmode_is_supported(param_item->param, 9012 DEVLINK_PARAM_CMODE_DRIVERINIT)) 9013 return -EOPNOTSUPP; 9014 9015 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) 9016 strcpy(init_val->vstr, param_item->driverinit_value.vstr); 9017 else 9018 *init_val = param_item->driverinit_value; 9019 9020 return 0; 9021} 9022 9023static int 9024__devlink_param_driverinit_value_set(struct devlink *devlink, 9025 unsigned int port_index, 9026 struct list_head *param_list, u32 param_id, 9027 union devlink_param_value init_val, 9028 enum devlink_command cmd) 9029{ 9030 struct devlink_param_item *param_item; 9031 9032 param_item = devlink_param_find_by_id(param_list, param_id); 9033 if (!param_item) 9034 return -EINVAL; 9035 9036 if (!devlink_param_cmode_is_supported(param_item->param, 9037 DEVLINK_PARAM_CMODE_DRIVERINIT)) 9038 return -EOPNOTSUPP; 9039 9040 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) 9041 strcpy(param_item->driverinit_value.vstr, init_val.vstr); 9042 else 9043 param_item->driverinit_value = init_val; 9044 param_item->driverinit_value_valid = true; 9045 9046 devlink_param_notify(devlink, port_index, param_item, cmd); 9047 return 0; 9048} 9049 9050/** 9051 * devlink_param_driverinit_value_get - get configuration parameter 9052 * value for driver initializing 9053 * 9054 * @devlink: devlink 9055 * @param_id: parameter ID 9056 * @init_val: value of parameter in driverinit configuration mode 9057 * 9058 * This function should be used by the driver to get driverinit 9059 * configuration for initialization after reload command. 9060 */ 9061int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, 9062 union devlink_param_value *init_val) 9063{ 9064 if (!devlink_reload_supported(devlink->ops)) 9065 return -EOPNOTSUPP; 9066 9067 return __devlink_param_driverinit_value_get(&devlink->param_list, 9068 param_id, init_val); 9069} 9070EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get); 9071 9072/** 9073 * devlink_param_driverinit_value_set - set value of configuration 9074 * parameter for driverinit 9075 * configuration mode 9076 * 9077 * @devlink: devlink 9078 * @param_id: parameter ID 9079 * @init_val: value of parameter to set for driverinit configuration mode 9080 * 9081 * This function should be used by the driver to set driverinit 9082 * configuration mode default value. 9083 */ 9084int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, 9085 union devlink_param_value init_val) 9086{ 9087 return __devlink_param_driverinit_value_set(devlink, 0, 9088 &devlink->param_list, 9089 param_id, init_val, 9090 DEVLINK_CMD_PARAM_NEW); 9091} 9092EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set); 9093 9094/** 9095 * devlink_port_param_driverinit_value_get - get configuration parameter 9096 * value for driver initializing 9097 * 9098 * @devlink_port: devlink_port 9099 * @param_id: parameter ID 9100 * @init_val: value of parameter in driverinit configuration mode 9101 * 9102 * This function should be used by the driver to get driverinit 9103 * configuration for initialization after reload command. 9104 */ 9105int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port, 9106 u32 param_id, 9107 union devlink_param_value *init_val) 9108{ 9109 struct devlink *devlink = devlink_port->devlink; 9110 9111 if (!devlink_reload_supported(devlink->ops)) 9112 return -EOPNOTSUPP; 9113 9114 return __devlink_param_driverinit_value_get(&devlink_port->param_list, 9115 param_id, init_val); 9116} 9117EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get); 9118 9119/** 9120 * devlink_port_param_driverinit_value_set - set value of configuration 9121 * parameter for driverinit 9122 * configuration mode 9123 * 9124 * @devlink_port: devlink_port 9125 * @param_id: parameter ID 9126 * @init_val: value of parameter to set for driverinit configuration mode 9127 * 9128 * This function should be used by the driver to set driverinit 9129 * configuration mode default value. 9130 */ 9131int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port, 9132 u32 param_id, 9133 union devlink_param_value init_val) 9134{ 9135 return __devlink_param_driverinit_value_set(devlink_port->devlink, 9136 devlink_port->index, 9137 &devlink_port->param_list, 9138 param_id, init_val, 9139 DEVLINK_CMD_PORT_PARAM_NEW); 9140} 9141EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set); 9142 9143/** 9144 * devlink_param_value_changed - notify devlink on a parameter's value 9145 * change. Should be called by the driver 9146 * right after the change. 9147 * 9148 * @devlink: devlink 9149 * @param_id: parameter ID 9150 * 9151 * This function should be used by the driver to notify devlink on value 9152 * change, excluding driverinit configuration mode. 9153 * For driverinit configuration mode driver should use the function 9154 */ 9155void devlink_param_value_changed(struct devlink *devlink, u32 param_id) 9156{ 9157 struct devlink_param_item *param_item; 9158 9159 param_item = devlink_param_find_by_id(&devlink->param_list, param_id); 9160 WARN_ON(!param_item); 9161 9162 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 9163} 9164EXPORT_SYMBOL_GPL(devlink_param_value_changed); 9165 9166/** 9167 * devlink_port_param_value_changed - notify devlink on a parameter's value 9168 * change. Should be called by the driver 9169 * right after the change. 9170 * 9171 * @devlink_port: devlink_port 9172 * @param_id: parameter ID 9173 * 9174 * This function should be used by the driver to notify devlink on value 9175 * change, excluding driverinit configuration mode. 9176 * For driverinit configuration mode driver should use the function 9177 * devlink_port_param_driverinit_value_set() instead. 9178 */ 9179void devlink_port_param_value_changed(struct devlink_port *devlink_port, 9180 u32 param_id) 9181{ 9182 struct devlink_param_item *param_item; 9183 9184 param_item = devlink_param_find_by_id(&devlink_port->param_list, 9185 param_id); 9186 WARN_ON(!param_item); 9187 9188 devlink_param_notify(devlink_port->devlink, devlink_port->index, 9189 param_item, DEVLINK_CMD_PORT_PARAM_NEW); 9190} 9191EXPORT_SYMBOL_GPL(devlink_port_param_value_changed); 9192 9193/** 9194 * devlink_param_value_str_fill - Safely fill-up the string preventing 9195 * from overflow of the preallocated buffer 9196 * 9197 * @dst_val: destination devlink_param_value 9198 * @src: source buffer 9199 */ 9200void devlink_param_value_str_fill(union devlink_param_value *dst_val, 9201 const char *src) 9202{ 9203 size_t len; 9204 9205 len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE); 9206 WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE); 9207} 9208EXPORT_SYMBOL_GPL(devlink_param_value_str_fill); 9209 9210/** 9211 * devlink_region_create - create a new address region 9212 * 9213 * @devlink: devlink 9214 * @ops: region operations and name 9215 * @region_max_snapshots: Maximum supported number of snapshots for region 9216 * @region_size: size of region 9217 */ 9218struct devlink_region * 9219devlink_region_create(struct devlink *devlink, 9220 const struct devlink_region_ops *ops, 9221 u32 region_max_snapshots, u64 region_size) 9222{ 9223 struct devlink_region *region; 9224 int err = 0; 9225 9226 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 9227 return ERR_PTR(-EINVAL); 9228 9229 mutex_lock(&devlink->lock); 9230 9231 if (devlink_region_get_by_name(devlink, ops->name)) { 9232 err = -EEXIST; 9233 goto unlock; 9234 } 9235 9236 region = kzalloc(sizeof(*region), GFP_KERNEL); 9237 if (!region) { 9238 err = -ENOMEM; 9239 goto unlock; 9240 } 9241 9242 region->devlink = devlink; 9243 region->max_snapshots = region_max_snapshots; 9244 region->ops = ops; 9245 region->size = region_size; 9246 INIT_LIST_HEAD(&region->snapshot_list); 9247 list_add_tail(&region->list, &devlink->region_list); 9248 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 9249 9250 mutex_unlock(&devlink->lock); 9251 return region; 9252 9253unlock: 9254 mutex_unlock(&devlink->lock); 9255 return ERR_PTR(err); 9256} 9257EXPORT_SYMBOL_GPL(devlink_region_create); 9258 9259/** 9260 * devlink_port_region_create - create a new address region for a port 9261 * 9262 * @port: devlink port 9263 * @ops: region operations and name 9264 * @region_max_snapshots: Maximum supported number of snapshots for region 9265 * @region_size: size of region 9266 */ 9267struct devlink_region * 9268devlink_port_region_create(struct devlink_port *port, 9269 const struct devlink_port_region_ops *ops, 9270 u32 region_max_snapshots, u64 region_size) 9271{ 9272 struct devlink *devlink = port->devlink; 9273 struct devlink_region *region; 9274 int err = 0; 9275 9276 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 9277 return ERR_PTR(-EINVAL); 9278 9279 mutex_lock(&devlink->lock); 9280 9281 if (devlink_port_region_get_by_name(port, ops->name)) { 9282 err = -EEXIST; 9283 goto unlock; 9284 } 9285 9286 region = kzalloc(sizeof(*region), GFP_KERNEL); 9287 if (!region) { 9288 err = -ENOMEM; 9289 goto unlock; 9290 } 9291 9292 region->devlink = devlink; 9293 region->port = port; 9294 region->max_snapshots = region_max_snapshots; 9295 region->port_ops = ops; 9296 region->size = region_size; 9297 INIT_LIST_HEAD(&region->snapshot_list); 9298 list_add_tail(&region->list, &port->region_list); 9299 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 9300 9301 mutex_unlock(&devlink->lock); 9302 return region; 9303 9304unlock: 9305 mutex_unlock(&devlink->lock); 9306 return ERR_PTR(err); 9307} 9308EXPORT_SYMBOL_GPL(devlink_port_region_create); 9309 9310/** 9311 * devlink_region_destroy - destroy address region 9312 * 9313 * @region: devlink region to destroy 9314 */ 9315void devlink_region_destroy(struct devlink_region *region) 9316{ 9317 struct devlink *devlink = region->devlink; 9318 struct devlink_snapshot *snapshot, *ts; 9319 9320 mutex_lock(&devlink->lock); 9321 9322 /* Free all snapshots of region */ 9323 list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list) 9324 devlink_region_snapshot_del(region, snapshot); 9325 9326 list_del(&region->list); 9327 9328 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); 9329 mutex_unlock(&devlink->lock); 9330 kfree(region); 9331} 9332EXPORT_SYMBOL_GPL(devlink_region_destroy); 9333 9334/** 9335 * devlink_region_snapshot_id_get - get snapshot ID 9336 * 9337 * This callback should be called when adding a new snapshot, 9338 * Driver should use the same id for multiple snapshots taken 9339 * on multiple regions at the same time/by the same trigger. 9340 * 9341 * The caller of this function must use devlink_region_snapshot_id_put 9342 * when finished creating regions using this id. 9343 * 9344 * Returns zero on success, or a negative error code on failure. 9345 * 9346 * @devlink: devlink 9347 * @id: storage to return id 9348 */ 9349int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 9350{ 9351 int err; 9352 9353 mutex_lock(&devlink->lock); 9354 err = __devlink_region_snapshot_id_get(devlink, id); 9355 mutex_unlock(&devlink->lock); 9356 9357 return err; 9358} 9359EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); 9360 9361/** 9362 * devlink_region_snapshot_id_put - put snapshot ID reference 9363 * 9364 * This should be called by a driver after finishing creating snapshots 9365 * with an id. Doing so ensures that the ID can later be released in the 9366 * event that all snapshots using it have been destroyed. 9367 * 9368 * @devlink: devlink 9369 * @id: id to release reference on 9370 */ 9371void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) 9372{ 9373 mutex_lock(&devlink->lock); 9374 __devlink_snapshot_id_decrement(devlink, id); 9375 mutex_unlock(&devlink->lock); 9376} 9377EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); 9378 9379/** 9380 * devlink_region_snapshot_create - create a new snapshot 9381 * This will add a new snapshot of a region. The snapshot 9382 * will be stored on the region struct and can be accessed 9383 * from devlink. This is useful for future analyses of snapshots. 9384 * Multiple snapshots can be created on a region. 9385 * The @snapshot_id should be obtained using the getter function. 9386 * 9387 * @region: devlink region of the snapshot 9388 * @data: snapshot data 9389 * @snapshot_id: snapshot id to be created 9390 */ 9391int devlink_region_snapshot_create(struct devlink_region *region, 9392 u8 *data, u32 snapshot_id) 9393{ 9394 struct devlink *devlink = region->devlink; 9395 int err; 9396 9397 mutex_lock(&devlink->lock); 9398 err = __devlink_region_snapshot_create(region, data, snapshot_id); 9399 mutex_unlock(&devlink->lock); 9400 9401 return err; 9402} 9403EXPORT_SYMBOL_GPL(devlink_region_snapshot_create); 9404 9405#define DEVLINK_TRAP(_id, _type) \ 9406 { \ 9407 .type = DEVLINK_TRAP_TYPE_##_type, \ 9408 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \ 9409 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \ 9410 } 9411 9412static const struct devlink_trap devlink_trap_generic[] = { 9413 DEVLINK_TRAP(SMAC_MC, DROP), 9414 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP), 9415 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP), 9416 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP), 9417 DEVLINK_TRAP(EMPTY_TX_LIST, DROP), 9418 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP), 9419 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP), 9420 DEVLINK_TRAP(TTL_ERROR, EXCEPTION), 9421 DEVLINK_TRAP(TAIL_DROP, DROP), 9422 DEVLINK_TRAP(NON_IP_PACKET, DROP), 9423 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP), 9424 DEVLINK_TRAP(DIP_LB, DROP), 9425 DEVLINK_TRAP(SIP_MC, DROP), 9426 DEVLINK_TRAP(SIP_LB, DROP), 9427 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP), 9428 DEVLINK_TRAP(IPV4_SIP_BC, DROP), 9429 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP), 9430 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP), 9431 DEVLINK_TRAP(MTU_ERROR, EXCEPTION), 9432 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION), 9433 DEVLINK_TRAP(RPF, EXCEPTION), 9434 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION), 9435 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION), 9436 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION), 9437 DEVLINK_TRAP(NON_ROUTABLE, DROP), 9438 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION), 9439 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP), 9440 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP), 9441 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP), 9442 DEVLINK_TRAP(STP, CONTROL), 9443 DEVLINK_TRAP(LACP, CONTROL), 9444 DEVLINK_TRAP(LLDP, CONTROL), 9445 DEVLINK_TRAP(IGMP_QUERY, CONTROL), 9446 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL), 9447 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL), 9448 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL), 9449 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL), 9450 DEVLINK_TRAP(MLD_QUERY, CONTROL), 9451 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL), 9452 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL), 9453 DEVLINK_TRAP(MLD_V1_DONE, CONTROL), 9454 DEVLINK_TRAP(IPV4_DHCP, CONTROL), 9455 DEVLINK_TRAP(IPV6_DHCP, CONTROL), 9456 DEVLINK_TRAP(ARP_REQUEST, CONTROL), 9457 DEVLINK_TRAP(ARP_RESPONSE, CONTROL), 9458 DEVLINK_TRAP(ARP_OVERLAY, CONTROL), 9459 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL), 9460 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL), 9461 DEVLINK_TRAP(IPV4_BFD, CONTROL), 9462 DEVLINK_TRAP(IPV6_BFD, CONTROL), 9463 DEVLINK_TRAP(IPV4_OSPF, CONTROL), 9464 DEVLINK_TRAP(IPV6_OSPF, CONTROL), 9465 DEVLINK_TRAP(IPV4_BGP, CONTROL), 9466 DEVLINK_TRAP(IPV6_BGP, CONTROL), 9467 DEVLINK_TRAP(IPV4_VRRP, CONTROL), 9468 DEVLINK_TRAP(IPV6_VRRP, CONTROL), 9469 DEVLINK_TRAP(IPV4_PIM, CONTROL), 9470 DEVLINK_TRAP(IPV6_PIM, CONTROL), 9471 DEVLINK_TRAP(UC_LB, CONTROL), 9472 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL), 9473 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL), 9474 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL), 9475 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL), 9476 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL), 9477 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL), 9478 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL), 9479 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL), 9480 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL), 9481 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL), 9482 DEVLINK_TRAP(PTP_EVENT, CONTROL), 9483 DEVLINK_TRAP(PTP_GENERAL, CONTROL), 9484 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL), 9485 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL), 9486 DEVLINK_TRAP(EARLY_DROP, DROP), 9487 DEVLINK_TRAP(VXLAN_PARSING, DROP), 9488 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP), 9489 DEVLINK_TRAP(VLAN_PARSING, DROP), 9490 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP), 9491 DEVLINK_TRAP(MPLS_PARSING, DROP), 9492 DEVLINK_TRAP(ARP_PARSING, DROP), 9493 DEVLINK_TRAP(IP_1_PARSING, DROP), 9494 DEVLINK_TRAP(IP_N_PARSING, DROP), 9495 DEVLINK_TRAP(GRE_PARSING, DROP), 9496 DEVLINK_TRAP(UDP_PARSING, DROP), 9497 DEVLINK_TRAP(TCP_PARSING, DROP), 9498 DEVLINK_TRAP(IPSEC_PARSING, DROP), 9499 DEVLINK_TRAP(SCTP_PARSING, DROP), 9500 DEVLINK_TRAP(DCCP_PARSING, DROP), 9501 DEVLINK_TRAP(GTP_PARSING, DROP), 9502 DEVLINK_TRAP(ESP_PARSING, DROP), 9503}; 9504 9505#define DEVLINK_TRAP_GROUP(_id) \ 9506 { \ 9507 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \ 9508 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \ 9509 } 9510 9511static const struct devlink_trap_group devlink_trap_group_generic[] = { 9512 DEVLINK_TRAP_GROUP(L2_DROPS), 9513 DEVLINK_TRAP_GROUP(L3_DROPS), 9514 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS), 9515 DEVLINK_TRAP_GROUP(BUFFER_DROPS), 9516 DEVLINK_TRAP_GROUP(TUNNEL_DROPS), 9517 DEVLINK_TRAP_GROUP(ACL_DROPS), 9518 DEVLINK_TRAP_GROUP(STP), 9519 DEVLINK_TRAP_GROUP(LACP), 9520 DEVLINK_TRAP_GROUP(LLDP), 9521 DEVLINK_TRAP_GROUP(MC_SNOOPING), 9522 DEVLINK_TRAP_GROUP(DHCP), 9523 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY), 9524 DEVLINK_TRAP_GROUP(BFD), 9525 DEVLINK_TRAP_GROUP(OSPF), 9526 DEVLINK_TRAP_GROUP(BGP), 9527 DEVLINK_TRAP_GROUP(VRRP), 9528 DEVLINK_TRAP_GROUP(PIM), 9529 DEVLINK_TRAP_GROUP(UC_LB), 9530 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY), 9531 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY), 9532 DEVLINK_TRAP_GROUP(IPV6), 9533 DEVLINK_TRAP_GROUP(PTP_EVENT), 9534 DEVLINK_TRAP_GROUP(PTP_GENERAL), 9535 DEVLINK_TRAP_GROUP(ACL_SAMPLE), 9536 DEVLINK_TRAP_GROUP(ACL_TRAP), 9537 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS), 9538}; 9539 9540static int devlink_trap_generic_verify(const struct devlink_trap *trap) 9541{ 9542 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX) 9543 return -EINVAL; 9544 9545 if (strcmp(trap->name, devlink_trap_generic[trap->id].name)) 9546 return -EINVAL; 9547 9548 if (trap->type != devlink_trap_generic[trap->id].type) 9549 return -EINVAL; 9550 9551 return 0; 9552} 9553 9554static int devlink_trap_driver_verify(const struct devlink_trap *trap) 9555{ 9556 int i; 9557 9558 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX) 9559 return -EINVAL; 9560 9561 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) { 9562 if (!strcmp(trap->name, devlink_trap_generic[i].name)) 9563 return -EEXIST; 9564 } 9565 9566 return 0; 9567} 9568 9569static int devlink_trap_verify(const struct devlink_trap *trap) 9570{ 9571 if (!trap || !trap->name) 9572 return -EINVAL; 9573 9574 if (trap->generic) 9575 return devlink_trap_generic_verify(trap); 9576 else 9577 return devlink_trap_driver_verify(trap); 9578} 9579 9580static int 9581devlink_trap_group_generic_verify(const struct devlink_trap_group *group) 9582{ 9583 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) 9584 return -EINVAL; 9585 9586 if (strcmp(group->name, devlink_trap_group_generic[group->id].name)) 9587 return -EINVAL; 9588 9589 return 0; 9590} 9591 9592static int 9593devlink_trap_group_driver_verify(const struct devlink_trap_group *group) 9594{ 9595 int i; 9596 9597 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) 9598 return -EINVAL; 9599 9600 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) { 9601 if (!strcmp(group->name, devlink_trap_group_generic[i].name)) 9602 return -EEXIST; 9603 } 9604 9605 return 0; 9606} 9607 9608static int devlink_trap_group_verify(const struct devlink_trap_group *group) 9609{ 9610 if (group->generic) 9611 return devlink_trap_group_generic_verify(group); 9612 else 9613 return devlink_trap_group_driver_verify(group); 9614} 9615 9616static void 9617devlink_trap_group_notify(struct devlink *devlink, 9618 const struct devlink_trap_group_item *group_item, 9619 enum devlink_command cmd) 9620{ 9621 struct sk_buff *msg; 9622 int err; 9623 9624 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW && 9625 cmd != DEVLINK_CMD_TRAP_GROUP_DEL); 9626 9627 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 9628 if (!msg) 9629 return; 9630 9631 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0, 9632 0); 9633 if (err) { 9634 nlmsg_free(msg); 9635 return; 9636 } 9637 9638 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 9639 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 9640} 9641 9642static int 9643devlink_trap_item_group_link(struct devlink *devlink, 9644 struct devlink_trap_item *trap_item) 9645{ 9646 u16 group_id = trap_item->trap->init_group_id; 9647 struct devlink_trap_group_item *group_item; 9648 9649 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id); 9650 if (WARN_ON_ONCE(!group_item)) 9651 return -EINVAL; 9652 9653 trap_item->group_item = group_item; 9654 9655 return 0; 9656} 9657 9658static void devlink_trap_notify(struct devlink *devlink, 9659 const struct devlink_trap_item *trap_item, 9660 enum devlink_command cmd) 9661{ 9662 struct sk_buff *msg; 9663 int err; 9664 9665 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW && 9666 cmd != DEVLINK_CMD_TRAP_DEL); 9667 9668 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 9669 if (!msg) 9670 return; 9671 9672 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0); 9673 if (err) { 9674 nlmsg_free(msg); 9675 return; 9676 } 9677 9678 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 9679 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 9680} 9681 9682static int 9683devlink_trap_register(struct devlink *devlink, 9684 const struct devlink_trap *trap, void *priv) 9685{ 9686 struct devlink_trap_item *trap_item; 9687 int err; 9688 9689 if (devlink_trap_item_lookup(devlink, trap->name)) 9690 return -EEXIST; 9691 9692 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL); 9693 if (!trap_item) 9694 return -ENOMEM; 9695 9696 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); 9697 if (!trap_item->stats) { 9698 err = -ENOMEM; 9699 goto err_stats_alloc; 9700 } 9701 9702 trap_item->trap = trap; 9703 trap_item->action = trap->init_action; 9704 trap_item->priv = priv; 9705 9706 err = devlink_trap_item_group_link(devlink, trap_item); 9707 if (err) 9708 goto err_group_link; 9709 9710 err = devlink->ops->trap_init(devlink, trap, trap_item); 9711 if (err) 9712 goto err_trap_init; 9713 9714 list_add_tail(&trap_item->list, &devlink->trap_list); 9715 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW); 9716 9717 return 0; 9718 9719err_trap_init: 9720err_group_link: 9721 free_percpu(trap_item->stats); 9722err_stats_alloc: 9723 kfree(trap_item); 9724 return err; 9725} 9726 9727static void devlink_trap_unregister(struct devlink *devlink, 9728 const struct devlink_trap *trap) 9729{ 9730 struct devlink_trap_item *trap_item; 9731 9732 trap_item = devlink_trap_item_lookup(devlink, trap->name); 9733 if (WARN_ON_ONCE(!trap_item)) 9734 return; 9735 9736 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL); 9737 list_del(&trap_item->list); 9738 if (devlink->ops->trap_fini) 9739 devlink->ops->trap_fini(devlink, trap, trap_item); 9740 free_percpu(trap_item->stats); 9741 kfree(trap_item); 9742} 9743 9744static void devlink_trap_disable(struct devlink *devlink, 9745 const struct devlink_trap *trap) 9746{ 9747 struct devlink_trap_item *trap_item; 9748 9749 trap_item = devlink_trap_item_lookup(devlink, trap->name); 9750 if (WARN_ON_ONCE(!trap_item)) 9751 return; 9752 9753 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP, 9754 NULL); 9755 trap_item->action = DEVLINK_TRAP_ACTION_DROP; 9756} 9757 9758/** 9759 * devlink_traps_register - Register packet traps with devlink. 9760 * @devlink: devlink. 9761 * @traps: Packet traps. 9762 * @traps_count: Count of provided packet traps. 9763 * @priv: Driver private information. 9764 * 9765 * Return: Non-zero value on failure. 9766 */ 9767int devlink_traps_register(struct devlink *devlink, 9768 const struct devlink_trap *traps, 9769 size_t traps_count, void *priv) 9770{ 9771 int i, err; 9772 9773 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set) 9774 return -EINVAL; 9775 9776 mutex_lock(&devlink->lock); 9777 for (i = 0; i < traps_count; i++) { 9778 const struct devlink_trap *trap = &traps[i]; 9779 9780 err = devlink_trap_verify(trap); 9781 if (err) 9782 goto err_trap_verify; 9783 9784 err = devlink_trap_register(devlink, trap, priv); 9785 if (err) 9786 goto err_trap_register; 9787 } 9788 mutex_unlock(&devlink->lock); 9789 9790 return 0; 9791 9792err_trap_register: 9793err_trap_verify: 9794 for (i--; i >= 0; i--) 9795 devlink_trap_unregister(devlink, &traps[i]); 9796 mutex_unlock(&devlink->lock); 9797 return err; 9798} 9799EXPORT_SYMBOL_GPL(devlink_traps_register); 9800 9801/** 9802 * devlink_traps_unregister - Unregister packet traps from devlink. 9803 * @devlink: devlink. 9804 * @traps: Packet traps. 9805 * @traps_count: Count of provided packet traps. 9806 */ 9807void devlink_traps_unregister(struct devlink *devlink, 9808 const struct devlink_trap *traps, 9809 size_t traps_count) 9810{ 9811 int i; 9812 9813 mutex_lock(&devlink->lock); 9814 /* Make sure we do not have any packets in-flight while unregistering 9815 * traps by disabling all of them and waiting for a grace period. 9816 */ 9817 for (i = traps_count - 1; i >= 0; i--) 9818 devlink_trap_disable(devlink, &traps[i]); 9819 synchronize_rcu(); 9820 for (i = traps_count - 1; i >= 0; i--) 9821 devlink_trap_unregister(devlink, &traps[i]); 9822 mutex_unlock(&devlink->lock); 9823} 9824EXPORT_SYMBOL_GPL(devlink_traps_unregister); 9825 9826static void 9827devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats, 9828 size_t skb_len) 9829{ 9830 struct devlink_stats *stats; 9831 9832 stats = this_cpu_ptr(trap_stats); 9833 u64_stats_update_begin(&stats->syncp); 9834 stats->rx_bytes += skb_len; 9835 stats->rx_packets++; 9836 u64_stats_update_end(&stats->syncp); 9837} 9838 9839static void 9840devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata, 9841 const struct devlink_trap_item *trap_item, 9842 struct devlink_port *in_devlink_port, 9843 const struct flow_action_cookie *fa_cookie) 9844{ 9845 metadata->trap_name = trap_item->trap->name; 9846 metadata->trap_group_name = trap_item->group_item->group->name; 9847 metadata->fa_cookie = fa_cookie; 9848 metadata->trap_type = trap_item->trap->type; 9849 9850 spin_lock(&in_devlink_port->type_lock); 9851 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH) 9852 metadata->input_dev = in_devlink_port->type_dev; 9853 spin_unlock(&in_devlink_port->type_lock); 9854} 9855 9856/** 9857 * devlink_trap_report - Report trapped packet to drop monitor. 9858 * @devlink: devlink. 9859 * @skb: Trapped packet. 9860 * @trap_ctx: Trap context. 9861 * @in_devlink_port: Input devlink port. 9862 * @fa_cookie: Flow action cookie. Could be NULL. 9863 */ 9864void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb, 9865 void *trap_ctx, struct devlink_port *in_devlink_port, 9866 const struct flow_action_cookie *fa_cookie) 9867 9868{ 9869 struct devlink_trap_item *trap_item = trap_ctx; 9870 9871 devlink_trap_stats_update(trap_item->stats, skb->len); 9872 devlink_trap_stats_update(trap_item->group_item->stats, skb->len); 9873 9874 if (trace_devlink_trap_report_enabled()) { 9875 struct devlink_trap_metadata metadata = {}; 9876 9877 devlink_trap_report_metadata_set(&metadata, trap_item, 9878 in_devlink_port, fa_cookie); 9879 trace_devlink_trap_report(devlink, skb, &metadata); 9880 } 9881} 9882EXPORT_SYMBOL_GPL(devlink_trap_report); 9883 9884/** 9885 * devlink_trap_ctx_priv - Trap context to driver private information. 9886 * @trap_ctx: Trap context. 9887 * 9888 * Return: Driver private information passed during registration. 9889 */ 9890void *devlink_trap_ctx_priv(void *trap_ctx) 9891{ 9892 struct devlink_trap_item *trap_item = trap_ctx; 9893 9894 return trap_item->priv; 9895} 9896EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv); 9897 9898static int 9899devlink_trap_group_item_policer_link(struct devlink *devlink, 9900 struct devlink_trap_group_item *group_item) 9901{ 9902 u32 policer_id = group_item->group->init_policer_id; 9903 struct devlink_trap_policer_item *policer_item; 9904 9905 if (policer_id == 0) 9906 return 0; 9907 9908 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id); 9909 if (WARN_ON_ONCE(!policer_item)) 9910 return -EINVAL; 9911 9912 group_item->policer_item = policer_item; 9913 9914 return 0; 9915} 9916 9917static int 9918devlink_trap_group_register(struct devlink *devlink, 9919 const struct devlink_trap_group *group) 9920{ 9921 struct devlink_trap_group_item *group_item; 9922 int err; 9923 9924 if (devlink_trap_group_item_lookup(devlink, group->name)) 9925 return -EEXIST; 9926 9927 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL); 9928 if (!group_item) 9929 return -ENOMEM; 9930 9931 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); 9932 if (!group_item->stats) { 9933 err = -ENOMEM; 9934 goto err_stats_alloc; 9935 } 9936 9937 group_item->group = group; 9938 9939 err = devlink_trap_group_item_policer_link(devlink, group_item); 9940 if (err) 9941 goto err_policer_link; 9942 9943 if (devlink->ops->trap_group_init) { 9944 err = devlink->ops->trap_group_init(devlink, group); 9945 if (err) 9946 goto err_group_init; 9947 } 9948 9949 list_add_tail(&group_item->list, &devlink->trap_group_list); 9950 devlink_trap_group_notify(devlink, group_item, 9951 DEVLINK_CMD_TRAP_GROUP_NEW); 9952 9953 return 0; 9954 9955err_group_init: 9956err_policer_link: 9957 free_percpu(group_item->stats); 9958err_stats_alloc: 9959 kfree(group_item); 9960 return err; 9961} 9962 9963static void 9964devlink_trap_group_unregister(struct devlink *devlink, 9965 const struct devlink_trap_group *group) 9966{ 9967 struct devlink_trap_group_item *group_item; 9968 9969 group_item = devlink_trap_group_item_lookup(devlink, group->name); 9970 if (WARN_ON_ONCE(!group_item)) 9971 return; 9972 9973 devlink_trap_group_notify(devlink, group_item, 9974 DEVLINK_CMD_TRAP_GROUP_DEL); 9975 list_del(&group_item->list); 9976 free_percpu(group_item->stats); 9977 kfree(group_item); 9978} 9979 9980/** 9981 * devlink_trap_groups_register - Register packet trap groups with devlink. 9982 * @devlink: devlink. 9983 * @groups: Packet trap groups. 9984 * @groups_count: Count of provided packet trap groups. 9985 * 9986 * Return: Non-zero value on failure. 9987 */ 9988int devlink_trap_groups_register(struct devlink *devlink, 9989 const struct devlink_trap_group *groups, 9990 size_t groups_count) 9991{ 9992 int i, err; 9993 9994 mutex_lock(&devlink->lock); 9995 for (i = 0; i < groups_count; i++) { 9996 const struct devlink_trap_group *group = &groups[i]; 9997 9998 err = devlink_trap_group_verify(group); 9999 if (err) 10000 goto err_trap_group_verify; 10001 10002 err = devlink_trap_group_register(devlink, group); 10003 if (err) 10004 goto err_trap_group_register; 10005 } 10006 mutex_unlock(&devlink->lock); 10007 10008 return 0; 10009 10010err_trap_group_register: 10011err_trap_group_verify: 10012 for (i--; i >= 0; i--) 10013 devlink_trap_group_unregister(devlink, &groups[i]); 10014 mutex_unlock(&devlink->lock); 10015 return err; 10016} 10017EXPORT_SYMBOL_GPL(devlink_trap_groups_register); 10018 10019/** 10020 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink. 10021 * @devlink: devlink. 10022 * @groups: Packet trap groups. 10023 * @groups_count: Count of provided packet trap groups. 10024 */ 10025void devlink_trap_groups_unregister(struct devlink *devlink, 10026 const struct devlink_trap_group *groups, 10027 size_t groups_count) 10028{ 10029 int i; 10030 10031 mutex_lock(&devlink->lock); 10032 for (i = groups_count - 1; i >= 0; i--) 10033 devlink_trap_group_unregister(devlink, &groups[i]); 10034 mutex_unlock(&devlink->lock); 10035} 10036EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister); 10037 10038static void 10039devlink_trap_policer_notify(struct devlink *devlink, 10040 const struct devlink_trap_policer_item *policer_item, 10041 enum devlink_command cmd) 10042{ 10043 struct sk_buff *msg; 10044 int err; 10045 10046 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW && 10047 cmd != DEVLINK_CMD_TRAP_POLICER_DEL); 10048 10049 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 10050 if (!msg) 10051 return; 10052 10053 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0, 10054 0, 0); 10055 if (err) { 10056 nlmsg_free(msg); 10057 return; 10058 } 10059 10060 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 10061 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 10062} 10063 10064static int 10065devlink_trap_policer_register(struct devlink *devlink, 10066 const struct devlink_trap_policer *policer) 10067{ 10068 struct devlink_trap_policer_item *policer_item; 10069 int err; 10070 10071 if (devlink_trap_policer_item_lookup(devlink, policer->id)) 10072 return -EEXIST; 10073 10074 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL); 10075 if (!policer_item) 10076 return -ENOMEM; 10077 10078 policer_item->policer = policer; 10079 policer_item->rate = policer->init_rate; 10080 policer_item->burst = policer->init_burst; 10081 10082 if (devlink->ops->trap_policer_init) { 10083 err = devlink->ops->trap_policer_init(devlink, policer); 10084 if (err) 10085 goto err_policer_init; 10086 } 10087 10088 list_add_tail(&policer_item->list, &devlink->trap_policer_list); 10089 devlink_trap_policer_notify(devlink, policer_item, 10090 DEVLINK_CMD_TRAP_POLICER_NEW); 10091 10092 return 0; 10093 10094err_policer_init: 10095 kfree(policer_item); 10096 return err; 10097} 10098 10099static void 10100devlink_trap_policer_unregister(struct devlink *devlink, 10101 const struct devlink_trap_policer *policer) 10102{ 10103 struct devlink_trap_policer_item *policer_item; 10104 10105 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id); 10106 if (WARN_ON_ONCE(!policer_item)) 10107 return; 10108 10109 devlink_trap_policer_notify(devlink, policer_item, 10110 DEVLINK_CMD_TRAP_POLICER_DEL); 10111 list_del(&policer_item->list); 10112 if (devlink->ops->trap_policer_fini) 10113 devlink->ops->trap_policer_fini(devlink, policer); 10114 kfree(policer_item); 10115} 10116 10117/** 10118 * devlink_trap_policers_register - Register packet trap policers with devlink. 10119 * @devlink: devlink. 10120 * @policers: Packet trap policers. 10121 * @policers_count: Count of provided packet trap policers. 10122 * 10123 * Return: Non-zero value on failure. 10124 */ 10125int 10126devlink_trap_policers_register(struct devlink *devlink, 10127 const struct devlink_trap_policer *policers, 10128 size_t policers_count) 10129{ 10130 int i, err; 10131 10132 mutex_lock(&devlink->lock); 10133 for (i = 0; i < policers_count; i++) { 10134 const struct devlink_trap_policer *policer = &policers[i]; 10135 10136 if (WARN_ON(policer->id == 0 || 10137 policer->max_rate < policer->min_rate || 10138 policer->max_burst < policer->min_burst)) { 10139 err = -EINVAL; 10140 goto err_trap_policer_verify; 10141 } 10142 10143 err = devlink_trap_policer_register(devlink, policer); 10144 if (err) 10145 goto err_trap_policer_register; 10146 } 10147 mutex_unlock(&devlink->lock); 10148 10149 return 0; 10150 10151err_trap_policer_register: 10152err_trap_policer_verify: 10153 for (i--; i >= 0; i--) 10154 devlink_trap_policer_unregister(devlink, &policers[i]); 10155 mutex_unlock(&devlink->lock); 10156 return err; 10157} 10158EXPORT_SYMBOL_GPL(devlink_trap_policers_register); 10159 10160/** 10161 * devlink_trap_policers_unregister - Unregister packet trap policers from devlink. 10162 * @devlink: devlink. 10163 * @policers: Packet trap policers. 10164 * @policers_count: Count of provided packet trap policers. 10165 */ 10166void 10167devlink_trap_policers_unregister(struct devlink *devlink, 10168 const struct devlink_trap_policer *policers, 10169 size_t policers_count) 10170{ 10171 int i; 10172 10173 mutex_lock(&devlink->lock); 10174 for (i = policers_count - 1; i >= 0; i--) 10175 devlink_trap_policer_unregister(devlink, &policers[i]); 10176 mutex_unlock(&devlink->lock); 10177} 10178EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister); 10179 10180static void __devlink_compat_running_version(struct devlink *devlink, 10181 char *buf, size_t len) 10182{ 10183 const struct nlattr *nlattr; 10184 struct devlink_info_req req; 10185 struct sk_buff *msg; 10186 int rem, err; 10187 10188 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 10189 if (!msg) 10190 return; 10191 10192 req.msg = msg; 10193 err = devlink->ops->info_get(devlink, &req, NULL); 10194 if (err) 10195 goto free_msg; 10196 10197 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) { 10198 const struct nlattr *kv; 10199 int rem_kv; 10200 10201 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING) 10202 continue; 10203 10204 nla_for_each_nested(kv, nlattr, rem_kv) { 10205 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE) 10206 continue; 10207 10208 strlcat(buf, nla_data(kv), len); 10209 strlcat(buf, " ", len); 10210 } 10211 } 10212free_msg: 10213 nlmsg_free(msg); 10214} 10215 10216void devlink_compat_running_version(struct net_device *dev, 10217 char *buf, size_t len) 10218{ 10219 struct devlink *devlink; 10220 10221 dev_hold(dev); 10222 rtnl_unlock(); 10223 10224 devlink = netdev_to_devlink(dev); 10225 if (!devlink || !devlink->ops->info_get) 10226 goto out; 10227 10228 mutex_lock(&devlink->lock); 10229 __devlink_compat_running_version(devlink, buf, len); 10230 mutex_unlock(&devlink->lock); 10231 10232out: 10233 rtnl_lock(); 10234 dev_put(dev); 10235} 10236 10237int devlink_compat_flash_update(struct net_device *dev, const char *file_name) 10238{ 10239 struct devlink_flash_update_params params = {}; 10240 struct devlink *devlink; 10241 int ret; 10242 10243 dev_hold(dev); 10244 rtnl_unlock(); 10245 10246 devlink = netdev_to_devlink(dev); 10247 if (!devlink || !devlink->ops->flash_update) { 10248 ret = -EOPNOTSUPP; 10249 goto out; 10250 } 10251 10252 params.file_name = file_name; 10253 10254 mutex_lock(&devlink->lock); 10255 ret = devlink->ops->flash_update(devlink, &params, NULL); 10256 mutex_unlock(&devlink->lock); 10257 10258out: 10259 rtnl_lock(); 10260 dev_put(dev); 10261 10262 return ret; 10263} 10264 10265int devlink_compat_phys_port_name_get(struct net_device *dev, 10266 char *name, size_t len) 10267{ 10268 struct devlink_port *devlink_port; 10269 10270 /* RTNL mutex is held here which ensures that devlink_port 10271 * instance cannot disappear in the middle. No need to take 10272 * any devlink lock as only permanent values are accessed. 10273 */ 10274 ASSERT_RTNL(); 10275 10276 devlink_port = netdev_to_devlink_port(dev); 10277 if (!devlink_port) 10278 return -EOPNOTSUPP; 10279 10280 return __devlink_port_phys_port_name_get(devlink_port, name, len); 10281} 10282 10283int devlink_compat_switch_id_get(struct net_device *dev, 10284 struct netdev_phys_item_id *ppid) 10285{ 10286 struct devlink_port *devlink_port; 10287 10288 /* Caller must hold RTNL mutex or reference to dev, which ensures that 10289 * devlink_port instance cannot disappear in the middle. No need to take 10290 * any devlink lock as only permanent values are accessed. 10291 */ 10292 devlink_port = netdev_to_devlink_port(dev); 10293 if (!devlink_port || !devlink_port->switch_port) 10294 return -EOPNOTSUPP; 10295 10296 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid)); 10297 10298 return 0; 10299} 10300 10301static void __net_exit devlink_pernet_pre_exit(struct net *net) 10302{ 10303 struct devlink *devlink; 10304 u32 actions_performed; 10305 int err; 10306 10307 /* In case network namespace is getting destroyed, reload 10308 * all devlink instances from this namespace into init_net. 10309 */ 10310 mutex_lock(&devlink_mutex); 10311 list_for_each_entry(devlink, &devlink_list, list) { 10312 if (net_eq(devlink_net(devlink), net)) { 10313 if (WARN_ON(!devlink_reload_supported(devlink->ops))) 10314 continue; 10315 err = devlink_reload(devlink, &init_net, 10316 DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 10317 DEVLINK_RELOAD_LIMIT_UNSPEC, 10318 &actions_performed, NULL); 10319 if (err && err != -EOPNOTSUPP) 10320 pr_warn("Failed to reload devlink instance into init_net\n"); 10321 } 10322 } 10323 mutex_unlock(&devlink_mutex); 10324} 10325 10326static struct pernet_operations devlink_pernet_ops __net_initdata = { 10327 .pre_exit = devlink_pernet_pre_exit, 10328}; 10329 10330static int __init devlink_init(void) 10331{ 10332 int err; 10333 10334 err = genl_register_family(&devlink_nl_family); 10335 if (err) 10336 goto out; 10337 err = register_pernet_subsys(&devlink_pernet_ops); 10338 10339out: 10340 WARN_ON(err); 10341 return err; 10342} 10343 10344subsys_initcall(devlink_init);