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