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