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