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