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