at v6.3 256 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#include "devl_internal.h" 35 36struct devlink_linecard { 37 struct list_head list; 38 struct devlink *devlink; 39 unsigned int index; 40 const struct devlink_linecard_ops *ops; 41 void *priv; 42 enum devlink_linecard_state state; 43 struct mutex state_lock; /* Protects state */ 44 const char *type; 45 struct devlink_linecard_type *types; 46 unsigned int types_count; 47 struct devlink *nested_devlink; 48}; 49 50/** 51 * struct devlink_resource - devlink resource 52 * @name: name of the resource 53 * @id: id, per devlink instance 54 * @size: size of the resource 55 * @size_new: updated size of the resource, reload is needed 56 * @size_valid: valid in case the total size of the resource is valid 57 * including its children 58 * @parent: parent resource 59 * @size_params: size parameters 60 * @list: parent list 61 * @resource_list: list of child resources 62 * @occ_get: occupancy getter callback 63 * @occ_get_priv: occupancy getter callback priv 64 */ 65struct devlink_resource { 66 const char *name; 67 u64 id; 68 u64 size; 69 u64 size_new; 70 bool size_valid; 71 struct devlink_resource *parent; 72 struct devlink_resource_size_params size_params; 73 struct list_head list; 74 struct list_head resource_list; 75 devlink_resource_occ_get_t *occ_get; 76 void *occ_get_priv; 77}; 78 79static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = { 80 { 81 .name = "destination mac", 82 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC, 83 .bitwidth = 48, 84 }, 85}; 86 87struct devlink_dpipe_header devlink_dpipe_header_ethernet = { 88 .name = "ethernet", 89 .id = DEVLINK_DPIPE_HEADER_ETHERNET, 90 .fields = devlink_dpipe_fields_ethernet, 91 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet), 92 .global = true, 93}; 94EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet); 95 96static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = { 97 { 98 .name = "destination ip", 99 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP, 100 .bitwidth = 32, 101 }, 102}; 103 104struct devlink_dpipe_header devlink_dpipe_header_ipv4 = { 105 .name = "ipv4", 106 .id = DEVLINK_DPIPE_HEADER_IPV4, 107 .fields = devlink_dpipe_fields_ipv4, 108 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4), 109 .global = true, 110}; 111EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4); 112 113static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = { 114 { 115 .name = "destination ip", 116 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP, 117 .bitwidth = 128, 118 }, 119}; 120 121struct devlink_dpipe_header devlink_dpipe_header_ipv6 = { 122 .name = "ipv6", 123 .id = DEVLINK_DPIPE_HEADER_IPV6, 124 .fields = devlink_dpipe_fields_ipv6, 125 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6), 126 .global = true, 127}; 128EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6); 129 130EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg); 131EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr); 132EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report); 133 134#define DEVLINK_PORT_FN_CAPS_VALID_MASK \ 135 (_BITUL(__DEVLINK_PORT_FN_ATTR_CAPS_MAX) - 1) 136 137static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = { 138 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY }, 139 [DEVLINK_PORT_FN_ATTR_STATE] = 140 NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE, 141 DEVLINK_PORT_FN_STATE_ACTIVE), 142 [DEVLINK_PORT_FN_ATTR_CAPS] = 143 NLA_POLICY_BITFIELD32(DEVLINK_PORT_FN_CAPS_VALID_MASK), 144}; 145 146#define ASSERT_DEVLINK_PORT_REGISTERED(devlink_port) \ 147 WARN_ON_ONCE(!(devlink_port)->registered) 148#define ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port) \ 149 WARN_ON_ONCE((devlink_port)->registered) 150#define ASSERT_DEVLINK_PORT_INITIALIZED(devlink_port) \ 151 WARN_ON_ONCE(!(devlink_port)->initialized) 152 153static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink, 154 unsigned int port_index) 155{ 156 return xa_load(&devlink->ports, port_index); 157} 158 159struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink, 160 struct nlattr **attrs) 161{ 162 if (attrs[DEVLINK_ATTR_PORT_INDEX]) { 163 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]); 164 struct devlink_port *devlink_port; 165 166 devlink_port = devlink_port_get_by_index(devlink, port_index); 167 if (!devlink_port) 168 return ERR_PTR(-ENODEV); 169 return devlink_port; 170 } 171 return ERR_PTR(-EINVAL); 172} 173 174struct devlink_port *devlink_port_get_from_info(struct devlink *devlink, 175 struct genl_info *info) 176{ 177 return devlink_port_get_from_attrs(devlink, info->attrs); 178} 179 180static inline bool 181devlink_rate_is_leaf(struct devlink_rate *devlink_rate) 182{ 183 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF; 184} 185 186static inline bool 187devlink_rate_is_node(struct devlink_rate *devlink_rate) 188{ 189 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE; 190} 191 192static struct devlink_rate * 193devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info) 194{ 195 struct devlink_rate *devlink_rate; 196 struct devlink_port *devlink_port; 197 198 devlink_port = devlink_port_get_from_attrs(devlink, info->attrs); 199 if (IS_ERR(devlink_port)) 200 return ERR_CAST(devlink_port); 201 devlink_rate = devlink_port->devlink_rate; 202 return devlink_rate ?: ERR_PTR(-ENODEV); 203} 204 205static struct devlink_rate * 206devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name) 207{ 208 static struct devlink_rate *devlink_rate; 209 210 list_for_each_entry(devlink_rate, &devlink->rate_list, list) { 211 if (devlink_rate_is_node(devlink_rate) && 212 !strcmp(node_name, devlink_rate->name)) 213 return devlink_rate; 214 } 215 return ERR_PTR(-ENODEV); 216} 217 218static struct devlink_rate * 219devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs) 220{ 221 const char *rate_node_name; 222 size_t len; 223 224 if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME]) 225 return ERR_PTR(-EINVAL); 226 rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]); 227 len = strlen(rate_node_name); 228 /* Name cannot be empty or decimal number */ 229 if (!len || strspn(rate_node_name, "0123456789") == len) 230 return ERR_PTR(-EINVAL); 231 232 return devlink_rate_node_get_by_name(devlink, rate_node_name); 233} 234 235struct devlink_rate * 236devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info) 237{ 238 return devlink_rate_node_get_from_attrs(devlink, info->attrs); 239} 240 241struct devlink_rate * 242devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info) 243{ 244 struct nlattr **attrs = info->attrs; 245 246 if (attrs[DEVLINK_ATTR_PORT_INDEX]) 247 return devlink_rate_leaf_get_from_info(devlink, info); 248 else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME]) 249 return devlink_rate_node_get_from_info(devlink, info); 250 else 251 return ERR_PTR(-EINVAL); 252} 253 254static struct devlink_linecard * 255devlink_linecard_get_by_index(struct devlink *devlink, 256 unsigned int linecard_index) 257{ 258 struct devlink_linecard *devlink_linecard; 259 260 list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) { 261 if (devlink_linecard->index == linecard_index) 262 return devlink_linecard; 263 } 264 return NULL; 265} 266 267static bool devlink_linecard_index_exists(struct devlink *devlink, 268 unsigned int linecard_index) 269{ 270 return devlink_linecard_get_by_index(devlink, linecard_index); 271} 272 273static struct devlink_linecard * 274devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs) 275{ 276 if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) { 277 u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]); 278 struct devlink_linecard *linecard; 279 280 linecard = devlink_linecard_get_by_index(devlink, linecard_index); 281 if (!linecard) 282 return ERR_PTR(-ENODEV); 283 return linecard; 284 } 285 return ERR_PTR(-EINVAL); 286} 287 288struct devlink_linecard * 289devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info) 290{ 291 return devlink_linecard_get_from_attrs(devlink, info->attrs); 292} 293 294struct devlink_sb { 295 struct list_head list; 296 unsigned int index; 297 u32 size; 298 u16 ingress_pools_count; 299 u16 egress_pools_count; 300 u16 ingress_tc_count; 301 u16 egress_tc_count; 302}; 303 304static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb) 305{ 306 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count; 307} 308 309static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink, 310 unsigned int sb_index) 311{ 312 struct devlink_sb *devlink_sb; 313 314 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 315 if (devlink_sb->index == sb_index) 316 return devlink_sb; 317 } 318 return NULL; 319} 320 321static bool devlink_sb_index_exists(struct devlink *devlink, 322 unsigned int sb_index) 323{ 324 return devlink_sb_get_by_index(devlink, sb_index); 325} 326 327static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink, 328 struct nlattr **attrs) 329{ 330 if (attrs[DEVLINK_ATTR_SB_INDEX]) { 331 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]); 332 struct devlink_sb *devlink_sb; 333 334 devlink_sb = devlink_sb_get_by_index(devlink, sb_index); 335 if (!devlink_sb) 336 return ERR_PTR(-ENODEV); 337 return devlink_sb; 338 } 339 return ERR_PTR(-EINVAL); 340} 341 342static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink, 343 struct genl_info *info) 344{ 345 return devlink_sb_get_from_attrs(devlink, info->attrs); 346} 347 348static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb, 349 struct nlattr **attrs, 350 u16 *p_pool_index) 351{ 352 u16 val; 353 354 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX]) 355 return -EINVAL; 356 357 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]); 358 if (val >= devlink_sb_pool_count(devlink_sb)) 359 return -EINVAL; 360 *p_pool_index = val; 361 return 0; 362} 363 364static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb, 365 struct genl_info *info, 366 u16 *p_pool_index) 367{ 368 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs, 369 p_pool_index); 370} 371 372static int 373devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs, 374 enum devlink_sb_pool_type *p_pool_type) 375{ 376 u8 val; 377 378 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE]) 379 return -EINVAL; 380 381 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]); 382 if (val != DEVLINK_SB_POOL_TYPE_INGRESS && 383 val != DEVLINK_SB_POOL_TYPE_EGRESS) 384 return -EINVAL; 385 *p_pool_type = val; 386 return 0; 387} 388 389static int 390devlink_sb_pool_type_get_from_info(struct genl_info *info, 391 enum devlink_sb_pool_type *p_pool_type) 392{ 393 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type); 394} 395 396static int 397devlink_sb_th_type_get_from_attrs(struct nlattr **attrs, 398 enum devlink_sb_threshold_type *p_th_type) 399{ 400 u8 val; 401 402 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]) 403 return -EINVAL; 404 405 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]); 406 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC && 407 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC) 408 return -EINVAL; 409 *p_th_type = val; 410 return 0; 411} 412 413static int 414devlink_sb_th_type_get_from_info(struct genl_info *info, 415 enum devlink_sb_threshold_type *p_th_type) 416{ 417 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type); 418} 419 420static int 421devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb, 422 struct nlattr **attrs, 423 enum devlink_sb_pool_type pool_type, 424 u16 *p_tc_index) 425{ 426 u16 val; 427 428 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX]) 429 return -EINVAL; 430 431 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]); 432 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS && 433 val >= devlink_sb->ingress_tc_count) 434 return -EINVAL; 435 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS && 436 val >= devlink_sb->egress_tc_count) 437 return -EINVAL; 438 *p_tc_index = val; 439 return 0; 440} 441 442static void devlink_port_fn_cap_fill(struct nla_bitfield32 *caps, 443 u32 cap, bool is_enable) 444{ 445 caps->selector |= cap; 446 if (is_enable) 447 caps->value |= cap; 448} 449 450static int devlink_port_fn_roce_fill(const struct devlink_ops *ops, 451 struct devlink_port *devlink_port, 452 struct nla_bitfield32 *caps, 453 struct netlink_ext_ack *extack) 454{ 455 bool is_enable; 456 int err; 457 458 if (!ops->port_fn_roce_get) 459 return 0; 460 461 err = ops->port_fn_roce_get(devlink_port, &is_enable, extack); 462 if (err) { 463 if (err == -EOPNOTSUPP) 464 return 0; 465 return err; 466 } 467 468 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_ROCE, is_enable); 469 return 0; 470} 471 472static int devlink_port_fn_migratable_fill(const struct devlink_ops *ops, 473 struct devlink_port *devlink_port, 474 struct nla_bitfield32 *caps, 475 struct netlink_ext_ack *extack) 476{ 477 bool is_enable; 478 int err; 479 480 if (!ops->port_fn_migratable_get || 481 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) 482 return 0; 483 484 err = ops->port_fn_migratable_get(devlink_port, &is_enable, extack); 485 if (err) { 486 if (err == -EOPNOTSUPP) 487 return 0; 488 return err; 489 } 490 491 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_MIGRATABLE, is_enable); 492 return 0; 493} 494 495static int devlink_port_fn_caps_fill(const struct devlink_ops *ops, 496 struct devlink_port *devlink_port, 497 struct sk_buff *msg, 498 struct netlink_ext_ack *extack, 499 bool *msg_updated) 500{ 501 struct nla_bitfield32 caps = {}; 502 int err; 503 504 err = devlink_port_fn_roce_fill(ops, devlink_port, &caps, extack); 505 if (err) 506 return err; 507 508 err = devlink_port_fn_migratable_fill(ops, devlink_port, &caps, extack); 509 if (err) 510 return err; 511 512 if (!caps.selector) 513 return 0; 514 err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value, 515 caps.selector); 516 if (err) 517 return err; 518 519 *msg_updated = true; 520 return 0; 521} 522 523static int 524devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb, 525 struct genl_info *info, 526 enum devlink_sb_pool_type pool_type, 527 u16 *p_tc_index) 528{ 529 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs, 530 pool_type, p_tc_index); 531} 532 533struct devlink_region { 534 struct devlink *devlink; 535 struct devlink_port *port; 536 struct list_head list; 537 union { 538 const struct devlink_region_ops *ops; 539 const struct devlink_port_region_ops *port_ops; 540 }; 541 struct mutex snapshot_lock; /* protects snapshot_list, 542 * max_snapshots and cur_snapshots 543 * consistency. 544 */ 545 struct list_head snapshot_list; 546 u32 max_snapshots; 547 u32 cur_snapshots; 548 u64 size; 549}; 550 551struct devlink_snapshot { 552 struct list_head list; 553 struct devlink_region *region; 554 u8 *data; 555 u32 id; 556}; 557 558static struct devlink_region * 559devlink_region_get_by_name(struct devlink *devlink, const char *region_name) 560{ 561 struct devlink_region *region; 562 563 list_for_each_entry(region, &devlink->region_list, list) 564 if (!strcmp(region->ops->name, region_name)) 565 return region; 566 567 return NULL; 568} 569 570static struct devlink_region * 571devlink_port_region_get_by_name(struct devlink_port *port, 572 const char *region_name) 573{ 574 struct devlink_region *region; 575 576 list_for_each_entry(region, &port->region_list, list) 577 if (!strcmp(region->ops->name, region_name)) 578 return region; 579 580 return NULL; 581} 582 583static struct devlink_snapshot * 584devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id) 585{ 586 struct devlink_snapshot *snapshot; 587 588 list_for_each_entry(snapshot, &region->snapshot_list, list) 589 if (snapshot->id == id) 590 return snapshot; 591 592 return NULL; 593} 594 595static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink) 596{ 597 struct nlattr *nested_attr; 598 599 nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK); 600 if (!nested_attr) 601 return -EMSGSIZE; 602 if (devlink_nl_put_handle(msg, devlink)) 603 goto nla_put_failure; 604 605 nla_nest_end(msg, nested_attr); 606 return 0; 607 608nla_put_failure: 609 nla_nest_cancel(msg, nested_attr); 610 return -EMSGSIZE; 611} 612 613int devlink_nl_port_handle_fill(struct sk_buff *msg, struct devlink_port *devlink_port) 614{ 615 if (devlink_nl_put_handle(msg, devlink_port->devlink)) 616 return -EMSGSIZE; 617 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 618 return -EMSGSIZE; 619 return 0; 620} 621 622size_t devlink_nl_port_handle_size(struct devlink_port *devlink_port) 623{ 624 struct devlink *devlink = devlink_port->devlink; 625 626 return nla_total_size(strlen(devlink->dev->bus->name) + 1) /* DEVLINK_ATTR_BUS_NAME */ 627 + nla_total_size(strlen(dev_name(devlink->dev)) + 1) /* DEVLINK_ATTR_DEV_NAME */ 628 + nla_total_size(4); /* DEVLINK_ATTR_PORT_INDEX */ 629} 630 631static int devlink_nl_port_attrs_put(struct sk_buff *msg, 632 struct devlink_port *devlink_port) 633{ 634 struct devlink_port_attrs *attrs = &devlink_port->attrs; 635 636 if (!devlink_port->attrs_set) 637 return 0; 638 if (attrs->lanes) { 639 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes)) 640 return -EMSGSIZE; 641 } 642 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable)) 643 return -EMSGSIZE; 644 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour)) 645 return -EMSGSIZE; 646 switch (devlink_port->attrs.flavour) { 647 case DEVLINK_PORT_FLAVOUR_PCI_PF: 648 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, 649 attrs->pci_pf.controller) || 650 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf)) 651 return -EMSGSIZE; 652 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external)) 653 return -EMSGSIZE; 654 break; 655 case DEVLINK_PORT_FLAVOUR_PCI_VF: 656 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, 657 attrs->pci_vf.controller) || 658 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) || 659 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf)) 660 return -EMSGSIZE; 661 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external)) 662 return -EMSGSIZE; 663 break; 664 case DEVLINK_PORT_FLAVOUR_PCI_SF: 665 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, 666 attrs->pci_sf.controller) || 667 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, 668 attrs->pci_sf.pf) || 669 nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER, 670 attrs->pci_sf.sf)) 671 return -EMSGSIZE; 672 break; 673 case DEVLINK_PORT_FLAVOUR_PHYSICAL: 674 case DEVLINK_PORT_FLAVOUR_CPU: 675 case DEVLINK_PORT_FLAVOUR_DSA: 676 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, 677 attrs->phys.port_number)) 678 return -EMSGSIZE; 679 if (!attrs->split) 680 return 0; 681 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, 682 attrs->phys.port_number)) 683 return -EMSGSIZE; 684 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER, 685 attrs->phys.split_subport_number)) 686 return -EMSGSIZE; 687 break; 688 default: 689 break; 690 } 691 return 0; 692} 693 694static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops, 695 struct devlink_port *port, 696 struct sk_buff *msg, 697 struct netlink_ext_ack *extack, 698 bool *msg_updated) 699{ 700 u8 hw_addr[MAX_ADDR_LEN]; 701 int hw_addr_len; 702 int err; 703 704 if (!ops->port_function_hw_addr_get) 705 return 0; 706 707 err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len, 708 extack); 709 if (err) { 710 if (err == -EOPNOTSUPP) 711 return 0; 712 return err; 713 } 714 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr); 715 if (err) 716 return err; 717 *msg_updated = true; 718 return 0; 719} 720 721static int devlink_nl_rate_fill(struct sk_buff *msg, 722 struct devlink_rate *devlink_rate, 723 enum devlink_command cmd, u32 portid, u32 seq, 724 int flags, struct netlink_ext_ack *extack) 725{ 726 struct devlink *devlink = devlink_rate->devlink; 727 void *hdr; 728 729 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 730 if (!hdr) 731 return -EMSGSIZE; 732 733 if (devlink_nl_put_handle(msg, devlink)) 734 goto nla_put_failure; 735 736 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type)) 737 goto nla_put_failure; 738 739 if (devlink_rate_is_leaf(devlink_rate)) { 740 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 741 devlink_rate->devlink_port->index)) 742 goto nla_put_failure; 743 } else if (devlink_rate_is_node(devlink_rate)) { 744 if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME, 745 devlink_rate->name)) 746 goto nla_put_failure; 747 } 748 749 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE, 750 devlink_rate->tx_share, DEVLINK_ATTR_PAD)) 751 goto nla_put_failure; 752 753 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX, 754 devlink_rate->tx_max, DEVLINK_ATTR_PAD)) 755 goto nla_put_failure; 756 757 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY, 758 devlink_rate->tx_priority)) 759 goto nla_put_failure; 760 761 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT, 762 devlink_rate->tx_weight)) 763 goto nla_put_failure; 764 765 if (devlink_rate->parent) 766 if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME, 767 devlink_rate->parent->name)) 768 goto nla_put_failure; 769 770 genlmsg_end(msg, hdr); 771 return 0; 772 773nla_put_failure: 774 genlmsg_cancel(msg, hdr); 775 return -EMSGSIZE; 776} 777 778static bool 779devlink_port_fn_state_valid(enum devlink_port_fn_state state) 780{ 781 return state == DEVLINK_PORT_FN_STATE_INACTIVE || 782 state == DEVLINK_PORT_FN_STATE_ACTIVE; 783} 784 785static bool 786devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate) 787{ 788 return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED || 789 opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED; 790} 791 792static int devlink_port_fn_state_fill(const struct devlink_ops *ops, 793 struct devlink_port *port, 794 struct sk_buff *msg, 795 struct netlink_ext_ack *extack, 796 bool *msg_updated) 797{ 798 enum devlink_port_fn_opstate opstate; 799 enum devlink_port_fn_state state; 800 int err; 801 802 if (!ops->port_fn_state_get) 803 return 0; 804 805 err = ops->port_fn_state_get(port, &state, &opstate, extack); 806 if (err) { 807 if (err == -EOPNOTSUPP) 808 return 0; 809 return err; 810 } 811 if (!devlink_port_fn_state_valid(state)) { 812 WARN_ON_ONCE(1); 813 NL_SET_ERR_MSG(extack, "Invalid state read from driver"); 814 return -EINVAL; 815 } 816 if (!devlink_port_fn_opstate_valid(opstate)) { 817 WARN_ON_ONCE(1); 818 NL_SET_ERR_MSG(extack, "Invalid operational state read from driver"); 819 return -EINVAL; 820 } 821 if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) || 822 nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate)) 823 return -EMSGSIZE; 824 *msg_updated = true; 825 return 0; 826} 827 828static int 829devlink_port_fn_mig_set(struct devlink_port *devlink_port, bool enable, 830 struct netlink_ext_ack *extack) 831{ 832 const struct devlink_ops *ops = devlink_port->devlink->ops; 833 834 return ops->port_fn_migratable_set(devlink_port, enable, extack); 835} 836 837static int 838devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable, 839 struct netlink_ext_ack *extack) 840{ 841 const struct devlink_ops *ops = devlink_port->devlink->ops; 842 843 return ops->port_fn_roce_set(devlink_port, enable, extack); 844} 845 846static int devlink_port_fn_caps_set(struct devlink_port *devlink_port, 847 const struct nlattr *attr, 848 struct netlink_ext_ack *extack) 849{ 850 struct nla_bitfield32 caps; 851 u32 caps_value; 852 int err; 853 854 caps = nla_get_bitfield32(attr); 855 caps_value = caps.value & caps.selector; 856 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE) { 857 err = devlink_port_fn_roce_set(devlink_port, 858 caps_value & DEVLINK_PORT_FN_CAP_ROCE, 859 extack); 860 if (err) 861 return err; 862 } 863 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) { 864 err = devlink_port_fn_mig_set(devlink_port, caps_value & 865 DEVLINK_PORT_FN_CAP_MIGRATABLE, 866 extack); 867 if (err) 868 return err; 869 } 870 return 0; 871} 872 873static int 874devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port, 875 struct netlink_ext_ack *extack) 876{ 877 const struct devlink_ops *ops; 878 struct nlattr *function_attr; 879 bool msg_updated = false; 880 int err; 881 882 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION); 883 if (!function_attr) 884 return -EMSGSIZE; 885 886 ops = port->devlink->ops; 887 err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack, 888 &msg_updated); 889 if (err) 890 goto out; 891 err = devlink_port_fn_caps_fill(ops, port, msg, extack, 892 &msg_updated); 893 if (err) 894 goto out; 895 err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated); 896out: 897 if (err || !msg_updated) 898 nla_nest_cancel(msg, function_attr); 899 else 900 nla_nest_end(msg, function_attr); 901 return err; 902} 903 904static int devlink_nl_port_fill(struct sk_buff *msg, 905 struct devlink_port *devlink_port, 906 enum devlink_command cmd, u32 portid, u32 seq, 907 int flags, struct netlink_ext_ack *extack) 908{ 909 struct devlink *devlink = devlink_port->devlink; 910 void *hdr; 911 912 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 913 if (!hdr) 914 return -EMSGSIZE; 915 916 if (devlink_nl_put_handle(msg, devlink)) 917 goto nla_put_failure; 918 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 919 goto nla_put_failure; 920 921 spin_lock_bh(&devlink_port->type_lock); 922 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type)) 923 goto nla_put_failure_type_locked; 924 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET && 925 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE, 926 devlink_port->desired_type)) 927 goto nla_put_failure_type_locked; 928 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) { 929 if (devlink_port->type_eth.netdev && 930 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX, 931 devlink_port->type_eth.ifindex) || 932 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME, 933 devlink_port->type_eth.ifname))) 934 goto nla_put_failure_type_locked; 935 } 936 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) { 937 struct ib_device *ibdev = devlink_port->type_ib.ibdev; 938 939 if (ibdev && 940 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME, 941 ibdev->name)) 942 goto nla_put_failure_type_locked; 943 } 944 spin_unlock_bh(&devlink_port->type_lock); 945 if (devlink_nl_port_attrs_put(msg, devlink_port)) 946 goto nla_put_failure; 947 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack)) 948 goto nla_put_failure; 949 if (devlink_port->linecard && 950 nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, 951 devlink_port->linecard->index)) 952 goto nla_put_failure; 953 954 genlmsg_end(msg, hdr); 955 return 0; 956 957nla_put_failure_type_locked: 958 spin_unlock_bh(&devlink_port->type_lock); 959nla_put_failure: 960 genlmsg_cancel(msg, hdr); 961 return -EMSGSIZE; 962} 963 964static void devlink_port_notify(struct devlink_port *devlink_port, 965 enum devlink_command cmd) 966{ 967 struct devlink *devlink = devlink_port->devlink; 968 struct sk_buff *msg; 969 int err; 970 971 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL); 972 973 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 974 return; 975 976 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 977 if (!msg) 978 return; 979 980 err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL); 981 if (err) { 982 nlmsg_free(msg); 983 return; 984 } 985 986 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, 987 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 988} 989 990static void devlink_rate_notify(struct devlink_rate *devlink_rate, 991 enum devlink_command cmd) 992{ 993 struct devlink *devlink = devlink_rate->devlink; 994 struct sk_buff *msg; 995 int err; 996 997 WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL); 998 999 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 1000 return; 1001 1002 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1003 if (!msg) 1004 return; 1005 1006 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL); 1007 if (err) { 1008 nlmsg_free(msg); 1009 return; 1010 } 1011 1012 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, 1013 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 1014} 1015 1016static int 1017devlink_nl_cmd_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 1018 struct netlink_callback *cb) 1019{ 1020 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 1021 struct devlink_rate *devlink_rate; 1022 int idx = 0; 1023 int err = 0; 1024 1025 list_for_each_entry(devlink_rate, &devlink->rate_list, list) { 1026 enum devlink_command cmd = DEVLINK_CMD_RATE_NEW; 1027 u32 id = NETLINK_CB(cb->skb).portid; 1028 1029 if (idx < state->idx) { 1030 idx++; 1031 continue; 1032 } 1033 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id, 1034 cb->nlh->nlmsg_seq, 1035 NLM_F_MULTI, NULL); 1036 if (err) { 1037 state->idx = idx; 1038 break; 1039 } 1040 idx++; 1041 } 1042 1043 return err; 1044} 1045 1046const struct devlink_cmd devl_cmd_rate_get = { 1047 .dump_one = devlink_nl_cmd_rate_get_dump_one, 1048}; 1049 1050static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb, 1051 struct genl_info *info) 1052{ 1053 struct devlink_rate *devlink_rate = info->user_ptr[1]; 1054 struct sk_buff *msg; 1055 int err; 1056 1057 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1058 if (!msg) 1059 return -ENOMEM; 1060 1061 err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW, 1062 info->snd_portid, info->snd_seq, 0, 1063 info->extack); 1064 if (err) { 1065 nlmsg_free(msg); 1066 return err; 1067 } 1068 1069 return genlmsg_reply(msg, info); 1070} 1071 1072static bool 1073devlink_rate_is_parent_node(struct devlink_rate *devlink_rate, 1074 struct devlink_rate *parent) 1075{ 1076 while (parent) { 1077 if (parent == devlink_rate) 1078 return true; 1079 parent = parent->parent; 1080 } 1081 return false; 1082} 1083 1084static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb, 1085 struct genl_info *info) 1086{ 1087 struct devlink_port *devlink_port = info->user_ptr[1]; 1088 struct sk_buff *msg; 1089 int err; 1090 1091 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1092 if (!msg) 1093 return -ENOMEM; 1094 1095 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW, 1096 info->snd_portid, info->snd_seq, 0, 1097 info->extack); 1098 if (err) { 1099 nlmsg_free(msg); 1100 return err; 1101 } 1102 1103 return genlmsg_reply(msg, info); 1104} 1105 1106static int 1107devlink_nl_cmd_port_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 1108 struct netlink_callback *cb) 1109{ 1110 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 1111 struct devlink_port *devlink_port; 1112 unsigned long port_index; 1113 int err = 0; 1114 1115 xa_for_each_start(&devlink->ports, port_index, devlink_port, state->idx) { 1116 err = devlink_nl_port_fill(msg, devlink_port, 1117 DEVLINK_CMD_NEW, 1118 NETLINK_CB(cb->skb).portid, 1119 cb->nlh->nlmsg_seq, 1120 NLM_F_MULTI, cb->extack); 1121 if (err) { 1122 state->idx = port_index; 1123 break; 1124 } 1125 } 1126 1127 return err; 1128} 1129 1130const struct devlink_cmd devl_cmd_port_get = { 1131 .dump_one = devlink_nl_cmd_port_get_dump_one, 1132}; 1133 1134static int devlink_port_type_set(struct devlink_port *devlink_port, 1135 enum devlink_port_type port_type) 1136 1137{ 1138 int err; 1139 1140 if (!devlink_port->devlink->ops->port_type_set) 1141 return -EOPNOTSUPP; 1142 1143 if (port_type == devlink_port->type) 1144 return 0; 1145 1146 err = devlink_port->devlink->ops->port_type_set(devlink_port, 1147 port_type); 1148 if (err) 1149 return err; 1150 1151 devlink_port->desired_type = port_type; 1152 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 1153 return 0; 1154} 1155 1156static int devlink_port_function_hw_addr_set(struct devlink_port *port, 1157 const struct nlattr *attr, 1158 struct netlink_ext_ack *extack) 1159{ 1160 const struct devlink_ops *ops = port->devlink->ops; 1161 const u8 *hw_addr; 1162 int hw_addr_len; 1163 1164 hw_addr = nla_data(attr); 1165 hw_addr_len = nla_len(attr); 1166 if (hw_addr_len > MAX_ADDR_LEN) { 1167 NL_SET_ERR_MSG(extack, "Port function hardware address too long"); 1168 return -EINVAL; 1169 } 1170 if (port->type == DEVLINK_PORT_TYPE_ETH) { 1171 if (hw_addr_len != ETH_ALEN) { 1172 NL_SET_ERR_MSG(extack, "Address must be 6 bytes for Ethernet device"); 1173 return -EINVAL; 1174 } 1175 if (!is_unicast_ether_addr(hw_addr)) { 1176 NL_SET_ERR_MSG(extack, "Non-unicast hardware address unsupported"); 1177 return -EINVAL; 1178 } 1179 } 1180 1181 return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len, 1182 extack); 1183} 1184 1185static int devlink_port_fn_state_set(struct devlink_port *port, 1186 const struct nlattr *attr, 1187 struct netlink_ext_ack *extack) 1188{ 1189 enum devlink_port_fn_state state; 1190 const struct devlink_ops *ops; 1191 1192 state = nla_get_u8(attr); 1193 ops = port->devlink->ops; 1194 return ops->port_fn_state_set(port, state, extack); 1195} 1196 1197static int devlink_port_function_validate(struct devlink_port *devlink_port, 1198 struct nlattr **tb, 1199 struct netlink_ext_ack *extack) 1200{ 1201 const struct devlink_ops *ops = devlink_port->devlink->ops; 1202 struct nlattr *attr; 1203 1204 if (tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] && 1205 !ops->port_function_hw_addr_set) { 1206 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR], 1207 "Port doesn't support function attributes"); 1208 return -EOPNOTSUPP; 1209 } 1210 if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) { 1211 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR], 1212 "Function does not support state setting"); 1213 return -EOPNOTSUPP; 1214 } 1215 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS]; 1216 if (attr) { 1217 struct nla_bitfield32 caps; 1218 1219 caps = nla_get_bitfield32(attr); 1220 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE && 1221 !ops->port_fn_roce_set) { 1222 NL_SET_ERR_MSG_ATTR(extack, attr, 1223 "Port doesn't support RoCE function attribute"); 1224 return -EOPNOTSUPP; 1225 } 1226 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) { 1227 if (!ops->port_fn_migratable_set) { 1228 NL_SET_ERR_MSG_ATTR(extack, attr, 1229 "Port doesn't support migratable function attribute"); 1230 return -EOPNOTSUPP; 1231 } 1232 if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) { 1233 NL_SET_ERR_MSG_ATTR(extack, attr, 1234 "migratable function attribute supported for VFs only"); 1235 return -EOPNOTSUPP; 1236 } 1237 } 1238 } 1239 return 0; 1240} 1241 1242static int devlink_port_function_set(struct devlink_port *port, 1243 const struct nlattr *attr, 1244 struct netlink_ext_ack *extack) 1245{ 1246 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1]; 1247 int err; 1248 1249 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr, 1250 devlink_function_nl_policy, extack); 1251 if (err < 0) { 1252 NL_SET_ERR_MSG(extack, "Fail to parse port function attributes"); 1253 return err; 1254 } 1255 1256 err = devlink_port_function_validate(port, tb, extack); 1257 if (err) 1258 return err; 1259 1260 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR]; 1261 if (attr) { 1262 err = devlink_port_function_hw_addr_set(port, attr, extack); 1263 if (err) 1264 return err; 1265 } 1266 1267 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS]; 1268 if (attr) { 1269 err = devlink_port_fn_caps_set(port, attr, extack); 1270 if (err) 1271 return err; 1272 } 1273 1274 /* Keep this as the last function attribute set, so that when 1275 * multiple port function attributes are set along with state, 1276 * Those can be applied first before activating the state. 1277 */ 1278 attr = tb[DEVLINK_PORT_FN_ATTR_STATE]; 1279 if (attr) 1280 err = devlink_port_fn_state_set(port, attr, extack); 1281 1282 if (!err) 1283 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW); 1284 return err; 1285} 1286 1287static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb, 1288 struct genl_info *info) 1289{ 1290 struct devlink_port *devlink_port = info->user_ptr[1]; 1291 int err; 1292 1293 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) { 1294 enum devlink_port_type port_type; 1295 1296 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]); 1297 err = devlink_port_type_set(devlink_port, port_type); 1298 if (err) 1299 return err; 1300 } 1301 1302 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) { 1303 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION]; 1304 struct netlink_ext_ack *extack = info->extack; 1305 1306 err = devlink_port_function_set(devlink_port, attr, extack); 1307 if (err) 1308 return err; 1309 } 1310 1311 return 0; 1312} 1313 1314static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, 1315 struct genl_info *info) 1316{ 1317 struct devlink_port *devlink_port = info->user_ptr[1]; 1318 struct devlink *devlink = info->user_ptr[0]; 1319 u32 count; 1320 1321 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT)) 1322 return -EINVAL; 1323 if (!devlink->ops->port_split) 1324 return -EOPNOTSUPP; 1325 1326 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]); 1327 1328 if (!devlink_port->attrs.splittable) { 1329 /* Split ports cannot be split. */ 1330 if (devlink_port->attrs.split) 1331 NL_SET_ERR_MSG(info->extack, "Port cannot be split further"); 1332 else 1333 NL_SET_ERR_MSG(info->extack, "Port cannot be split"); 1334 return -EINVAL; 1335 } 1336 1337 if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) { 1338 NL_SET_ERR_MSG(info->extack, "Invalid split count"); 1339 return -EINVAL; 1340 } 1341 1342 return devlink->ops->port_split(devlink, devlink_port, count, 1343 info->extack); 1344} 1345 1346static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb, 1347 struct genl_info *info) 1348{ 1349 struct devlink_port *devlink_port = info->user_ptr[1]; 1350 struct devlink *devlink = info->user_ptr[0]; 1351 1352 if (!devlink->ops->port_unsplit) 1353 return -EOPNOTSUPP; 1354 return devlink->ops->port_unsplit(devlink, devlink_port, info->extack); 1355} 1356 1357static int devlink_port_new_notify(struct devlink *devlink, 1358 unsigned int port_index, 1359 struct genl_info *info) 1360{ 1361 struct devlink_port *devlink_port; 1362 struct sk_buff *msg; 1363 int err; 1364 1365 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1366 if (!msg) 1367 return -ENOMEM; 1368 1369 lockdep_assert_held(&devlink->lock); 1370 devlink_port = devlink_port_get_by_index(devlink, port_index); 1371 if (!devlink_port) { 1372 err = -ENODEV; 1373 goto out; 1374 } 1375 1376 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW, 1377 info->snd_portid, info->snd_seq, 0, NULL); 1378 if (err) 1379 goto out; 1380 1381 return genlmsg_reply(msg, info); 1382 1383out: 1384 nlmsg_free(msg); 1385 return err; 1386} 1387 1388static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb, 1389 struct genl_info *info) 1390{ 1391 struct netlink_ext_ack *extack = info->extack; 1392 struct devlink_port_new_attrs new_attrs = {}; 1393 struct devlink *devlink = info->user_ptr[0]; 1394 unsigned int new_port_index; 1395 int err; 1396 1397 if (!devlink->ops->port_new || !devlink->ops->port_del) 1398 return -EOPNOTSUPP; 1399 1400 if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] || 1401 !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) { 1402 NL_SET_ERR_MSG(extack, "Port flavour or PCI PF are not specified"); 1403 return -EINVAL; 1404 } 1405 new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]); 1406 new_attrs.pfnum = 1407 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]); 1408 1409 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 1410 /* Port index of the new port being created by driver. */ 1411 new_attrs.port_index = 1412 nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 1413 new_attrs.port_index_valid = true; 1414 } 1415 if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) { 1416 new_attrs.controller = 1417 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]); 1418 new_attrs.controller_valid = true; 1419 } 1420 if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF && 1421 info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) { 1422 new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]); 1423 new_attrs.sfnum_valid = true; 1424 } 1425 1426 err = devlink->ops->port_new(devlink, &new_attrs, extack, 1427 &new_port_index); 1428 if (err) 1429 return err; 1430 1431 err = devlink_port_new_notify(devlink, new_port_index, info); 1432 if (err && err != -ENODEV) { 1433 /* Fail to send the response; destroy newly created port. */ 1434 devlink->ops->port_del(devlink, new_port_index, extack); 1435 } 1436 return err; 1437} 1438 1439static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb, 1440 struct genl_info *info) 1441{ 1442 struct netlink_ext_ack *extack = info->extack; 1443 struct devlink *devlink = info->user_ptr[0]; 1444 unsigned int port_index; 1445 1446 if (!devlink->ops->port_del) 1447 return -EOPNOTSUPP; 1448 1449 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_INDEX)) { 1450 NL_SET_ERR_MSG(extack, "Port index is not specified"); 1451 return -EINVAL; 1452 } 1453 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 1454 1455 return devlink->ops->port_del(devlink, port_index, extack); 1456} 1457 1458static int 1459devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate, 1460 struct genl_info *info, 1461 struct nlattr *nla_parent) 1462{ 1463 struct devlink *devlink = devlink_rate->devlink; 1464 const char *parent_name = nla_data(nla_parent); 1465 const struct devlink_ops *ops = devlink->ops; 1466 size_t len = strlen(parent_name); 1467 struct devlink_rate *parent; 1468 int err = -EOPNOTSUPP; 1469 1470 parent = devlink_rate->parent; 1471 1472 if (parent && !len) { 1473 if (devlink_rate_is_leaf(devlink_rate)) 1474 err = ops->rate_leaf_parent_set(devlink_rate, NULL, 1475 devlink_rate->priv, NULL, 1476 info->extack); 1477 else if (devlink_rate_is_node(devlink_rate)) 1478 err = ops->rate_node_parent_set(devlink_rate, NULL, 1479 devlink_rate->priv, NULL, 1480 info->extack); 1481 if (err) 1482 return err; 1483 1484 refcount_dec(&parent->refcnt); 1485 devlink_rate->parent = NULL; 1486 } else if (len) { 1487 parent = devlink_rate_node_get_by_name(devlink, parent_name); 1488 if (IS_ERR(parent)) 1489 return -ENODEV; 1490 1491 if (parent == devlink_rate) { 1492 NL_SET_ERR_MSG(info->extack, "Parent to self is not allowed"); 1493 return -EINVAL; 1494 } 1495 1496 if (devlink_rate_is_node(devlink_rate) && 1497 devlink_rate_is_parent_node(devlink_rate, parent->parent)) { 1498 NL_SET_ERR_MSG(info->extack, "Node is already a parent of parent node."); 1499 return -EEXIST; 1500 } 1501 1502 if (devlink_rate_is_leaf(devlink_rate)) 1503 err = ops->rate_leaf_parent_set(devlink_rate, parent, 1504 devlink_rate->priv, parent->priv, 1505 info->extack); 1506 else if (devlink_rate_is_node(devlink_rate)) 1507 err = ops->rate_node_parent_set(devlink_rate, parent, 1508 devlink_rate->priv, parent->priv, 1509 info->extack); 1510 if (err) 1511 return err; 1512 1513 if (devlink_rate->parent) 1514 /* we're reassigning to other parent in this case */ 1515 refcount_dec(&devlink_rate->parent->refcnt); 1516 1517 refcount_inc(&parent->refcnt); 1518 devlink_rate->parent = parent; 1519 } 1520 1521 return 0; 1522} 1523 1524static int devlink_nl_rate_set(struct devlink_rate *devlink_rate, 1525 const struct devlink_ops *ops, 1526 struct genl_info *info) 1527{ 1528 struct nlattr *nla_parent, **attrs = info->attrs; 1529 int err = -EOPNOTSUPP; 1530 u32 priority; 1531 u32 weight; 1532 u64 rate; 1533 1534 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) { 1535 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]); 1536 if (devlink_rate_is_leaf(devlink_rate)) 1537 err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv, 1538 rate, info->extack); 1539 else if (devlink_rate_is_node(devlink_rate)) 1540 err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv, 1541 rate, info->extack); 1542 if (err) 1543 return err; 1544 devlink_rate->tx_share = rate; 1545 } 1546 1547 if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) { 1548 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]); 1549 if (devlink_rate_is_leaf(devlink_rate)) 1550 err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv, 1551 rate, info->extack); 1552 else if (devlink_rate_is_node(devlink_rate)) 1553 err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv, 1554 rate, info->extack); 1555 if (err) 1556 return err; 1557 devlink_rate->tx_max = rate; 1558 } 1559 1560 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]) { 1561 priority = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]); 1562 if (devlink_rate_is_leaf(devlink_rate)) 1563 err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv, 1564 priority, info->extack); 1565 else if (devlink_rate_is_node(devlink_rate)) 1566 err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv, 1567 priority, info->extack); 1568 1569 if (err) 1570 return err; 1571 devlink_rate->tx_priority = priority; 1572 } 1573 1574 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]) { 1575 weight = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]); 1576 if (devlink_rate_is_leaf(devlink_rate)) 1577 err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv, 1578 weight, info->extack); 1579 else if (devlink_rate_is_node(devlink_rate)) 1580 err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv, 1581 weight, info->extack); 1582 1583 if (err) 1584 return err; 1585 devlink_rate->tx_weight = weight; 1586 } 1587 1588 nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME]; 1589 if (nla_parent) { 1590 err = devlink_nl_rate_parent_node_set(devlink_rate, info, 1591 nla_parent); 1592 if (err) 1593 return err; 1594 } 1595 1596 return 0; 1597} 1598 1599static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops, 1600 struct genl_info *info, 1601 enum devlink_rate_type type) 1602{ 1603 struct nlattr **attrs = info->attrs; 1604 1605 if (type == DEVLINK_RATE_TYPE_LEAF) { 1606 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) { 1607 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the leafs"); 1608 return false; 1609 } 1610 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) { 1611 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the leafs"); 1612 return false; 1613 } 1614 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] && 1615 !ops->rate_leaf_parent_set) { 1616 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the leafs"); 1617 return false; 1618 } 1619 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) { 1620 NL_SET_ERR_MSG_ATTR(info->extack, 1621 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY], 1622 "TX priority set isn't supported for the leafs"); 1623 return false; 1624 } 1625 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) { 1626 NL_SET_ERR_MSG_ATTR(info->extack, 1627 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT], 1628 "TX weight set isn't supported for the leafs"); 1629 return false; 1630 } 1631 } else if (type == DEVLINK_RATE_TYPE_NODE) { 1632 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) { 1633 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the nodes"); 1634 return false; 1635 } 1636 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) { 1637 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the nodes"); 1638 return false; 1639 } 1640 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] && 1641 !ops->rate_node_parent_set) { 1642 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the nodes"); 1643 return false; 1644 } 1645 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_tx_priority_set) { 1646 NL_SET_ERR_MSG_ATTR(info->extack, 1647 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY], 1648 "TX priority set isn't supported for the nodes"); 1649 return false; 1650 } 1651 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_tx_weight_set) { 1652 NL_SET_ERR_MSG_ATTR(info->extack, 1653 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT], 1654 "TX weight set isn't supported for the nodes"); 1655 return false; 1656 } 1657 } else { 1658 WARN(1, "Unknown type of rate object"); 1659 return false; 1660 } 1661 1662 return true; 1663} 1664 1665static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb, 1666 struct genl_info *info) 1667{ 1668 struct devlink_rate *devlink_rate = info->user_ptr[1]; 1669 struct devlink *devlink = devlink_rate->devlink; 1670 const struct devlink_ops *ops = devlink->ops; 1671 int err; 1672 1673 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type)) 1674 return -EOPNOTSUPP; 1675 1676 err = devlink_nl_rate_set(devlink_rate, ops, info); 1677 1678 if (!err) 1679 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); 1680 return err; 1681} 1682 1683static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb, 1684 struct genl_info *info) 1685{ 1686 struct devlink *devlink = info->user_ptr[0]; 1687 struct devlink_rate *rate_node; 1688 const struct devlink_ops *ops; 1689 int err; 1690 1691 ops = devlink->ops; 1692 if (!ops || !ops->rate_node_new || !ops->rate_node_del) { 1693 NL_SET_ERR_MSG(info->extack, "Rate nodes aren't supported"); 1694 return -EOPNOTSUPP; 1695 } 1696 1697 if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE)) 1698 return -EOPNOTSUPP; 1699 1700 rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs); 1701 if (!IS_ERR(rate_node)) 1702 return -EEXIST; 1703 else if (rate_node == ERR_PTR(-EINVAL)) 1704 return -EINVAL; 1705 1706 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL); 1707 if (!rate_node) 1708 return -ENOMEM; 1709 1710 rate_node->devlink = devlink; 1711 rate_node->type = DEVLINK_RATE_TYPE_NODE; 1712 rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL); 1713 if (!rate_node->name) { 1714 err = -ENOMEM; 1715 goto err_strdup; 1716 } 1717 1718 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack); 1719 if (err) 1720 goto err_node_new; 1721 1722 err = devlink_nl_rate_set(rate_node, ops, info); 1723 if (err) 1724 goto err_rate_set; 1725 1726 refcount_set(&rate_node->refcnt, 1); 1727 list_add(&rate_node->list, &devlink->rate_list); 1728 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); 1729 return 0; 1730 1731err_rate_set: 1732 ops->rate_node_del(rate_node, rate_node->priv, info->extack); 1733err_node_new: 1734 kfree(rate_node->name); 1735err_strdup: 1736 kfree(rate_node); 1737 return err; 1738} 1739 1740static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb, 1741 struct genl_info *info) 1742{ 1743 struct devlink_rate *rate_node = info->user_ptr[1]; 1744 struct devlink *devlink = rate_node->devlink; 1745 const struct devlink_ops *ops = devlink->ops; 1746 int err; 1747 1748 if (refcount_read(&rate_node->refcnt) > 1) { 1749 NL_SET_ERR_MSG(info->extack, "Node has children. Cannot delete node."); 1750 return -EBUSY; 1751 } 1752 1753 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); 1754 err = ops->rate_node_del(rate_node, rate_node->priv, info->extack); 1755 if (rate_node->parent) 1756 refcount_dec(&rate_node->parent->refcnt); 1757 list_del(&rate_node->list); 1758 kfree(rate_node->name); 1759 kfree(rate_node); 1760 return err; 1761} 1762 1763struct devlink_linecard_type { 1764 const char *type; 1765 const void *priv; 1766}; 1767 1768static int devlink_nl_linecard_fill(struct sk_buff *msg, 1769 struct devlink *devlink, 1770 struct devlink_linecard *linecard, 1771 enum devlink_command cmd, u32 portid, 1772 u32 seq, int flags, 1773 struct netlink_ext_ack *extack) 1774{ 1775 struct devlink_linecard_type *linecard_type; 1776 struct nlattr *attr; 1777 void *hdr; 1778 int i; 1779 1780 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 1781 if (!hdr) 1782 return -EMSGSIZE; 1783 1784 if (devlink_nl_put_handle(msg, devlink)) 1785 goto nla_put_failure; 1786 if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index)) 1787 goto nla_put_failure; 1788 if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state)) 1789 goto nla_put_failure; 1790 if (linecard->type && 1791 nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type)) 1792 goto nla_put_failure; 1793 1794 if (linecard->types_count) { 1795 attr = nla_nest_start(msg, 1796 DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES); 1797 if (!attr) 1798 goto nla_put_failure; 1799 for (i = 0; i < linecard->types_count; i++) { 1800 linecard_type = &linecard->types[i]; 1801 if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, 1802 linecard_type->type)) { 1803 nla_nest_cancel(msg, attr); 1804 goto nla_put_failure; 1805 } 1806 } 1807 nla_nest_end(msg, attr); 1808 } 1809 1810 if (linecard->nested_devlink && 1811 devlink_nl_put_nested_handle(msg, linecard->nested_devlink)) 1812 goto nla_put_failure; 1813 1814 genlmsg_end(msg, hdr); 1815 return 0; 1816 1817nla_put_failure: 1818 genlmsg_cancel(msg, hdr); 1819 return -EMSGSIZE; 1820} 1821 1822static void devlink_linecard_notify(struct devlink_linecard *linecard, 1823 enum devlink_command cmd) 1824{ 1825 struct devlink *devlink = linecard->devlink; 1826 struct sk_buff *msg; 1827 int err; 1828 1829 WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW && 1830 cmd != DEVLINK_CMD_LINECARD_DEL); 1831 1832 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 1833 return; 1834 1835 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1836 if (!msg) 1837 return; 1838 1839 err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0, 1840 NULL); 1841 if (err) { 1842 nlmsg_free(msg); 1843 return; 1844 } 1845 1846 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 1847 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 1848} 1849 1850static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb, 1851 struct genl_info *info) 1852{ 1853 struct devlink_linecard *linecard = info->user_ptr[1]; 1854 struct devlink *devlink = linecard->devlink; 1855 struct sk_buff *msg; 1856 int err; 1857 1858 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1859 if (!msg) 1860 return -ENOMEM; 1861 1862 mutex_lock(&linecard->state_lock); 1863 err = devlink_nl_linecard_fill(msg, devlink, linecard, 1864 DEVLINK_CMD_LINECARD_NEW, 1865 info->snd_portid, info->snd_seq, 0, 1866 info->extack); 1867 mutex_unlock(&linecard->state_lock); 1868 if (err) { 1869 nlmsg_free(msg); 1870 return err; 1871 } 1872 1873 return genlmsg_reply(msg, info); 1874} 1875 1876static int devlink_nl_cmd_linecard_get_dump_one(struct sk_buff *msg, 1877 struct devlink *devlink, 1878 struct netlink_callback *cb) 1879{ 1880 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 1881 struct devlink_linecard *linecard; 1882 int idx = 0; 1883 int err = 0; 1884 1885 list_for_each_entry(linecard, &devlink->linecard_list, list) { 1886 if (idx < state->idx) { 1887 idx++; 1888 continue; 1889 } 1890 mutex_lock(&linecard->state_lock); 1891 err = devlink_nl_linecard_fill(msg, devlink, linecard, 1892 DEVLINK_CMD_LINECARD_NEW, 1893 NETLINK_CB(cb->skb).portid, 1894 cb->nlh->nlmsg_seq, 1895 NLM_F_MULTI, 1896 cb->extack); 1897 mutex_unlock(&linecard->state_lock); 1898 if (err) { 1899 state->idx = idx; 1900 break; 1901 } 1902 idx++; 1903 } 1904 1905 return err; 1906} 1907 1908const struct devlink_cmd devl_cmd_linecard_get = { 1909 .dump_one = devlink_nl_cmd_linecard_get_dump_one, 1910}; 1911 1912static struct devlink_linecard_type * 1913devlink_linecard_type_lookup(struct devlink_linecard *linecard, 1914 const char *type) 1915{ 1916 struct devlink_linecard_type *linecard_type; 1917 int i; 1918 1919 for (i = 0; i < linecard->types_count; i++) { 1920 linecard_type = &linecard->types[i]; 1921 if (!strcmp(type, linecard_type->type)) 1922 return linecard_type; 1923 } 1924 return NULL; 1925} 1926 1927static int devlink_linecard_type_set(struct devlink_linecard *linecard, 1928 const char *type, 1929 struct netlink_ext_ack *extack) 1930{ 1931 const struct devlink_linecard_ops *ops = linecard->ops; 1932 struct devlink_linecard_type *linecard_type; 1933 int err; 1934 1935 mutex_lock(&linecard->state_lock); 1936 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) { 1937 NL_SET_ERR_MSG(extack, "Line card is currently being provisioned"); 1938 err = -EBUSY; 1939 goto out; 1940 } 1941 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) { 1942 NL_SET_ERR_MSG(extack, "Line card is currently being unprovisioned"); 1943 err = -EBUSY; 1944 goto out; 1945 } 1946 1947 linecard_type = devlink_linecard_type_lookup(linecard, type); 1948 if (!linecard_type) { 1949 NL_SET_ERR_MSG(extack, "Unsupported line card type provided"); 1950 err = -EINVAL; 1951 goto out; 1952 } 1953 1954 if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED && 1955 linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) { 1956 NL_SET_ERR_MSG(extack, "Line card already provisioned"); 1957 err = -EBUSY; 1958 /* Check if the line card is provisioned in the same 1959 * way the user asks. In case it is, make the operation 1960 * to return success. 1961 */ 1962 if (ops->same_provision && 1963 ops->same_provision(linecard, linecard->priv, 1964 linecard_type->type, 1965 linecard_type->priv)) 1966 err = 0; 1967 goto out; 1968 } 1969 1970 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING; 1971 linecard->type = linecard_type->type; 1972 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 1973 mutex_unlock(&linecard->state_lock); 1974 err = ops->provision(linecard, linecard->priv, linecard_type->type, 1975 linecard_type->priv, extack); 1976 if (err) { 1977 /* Provisioning failed. Assume the linecard is unprovisioned 1978 * for future operations. 1979 */ 1980 mutex_lock(&linecard->state_lock); 1981 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; 1982 linecard->type = NULL; 1983 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 1984 mutex_unlock(&linecard->state_lock); 1985 } 1986 return err; 1987 1988out: 1989 mutex_unlock(&linecard->state_lock); 1990 return err; 1991} 1992 1993static int devlink_linecard_type_unset(struct devlink_linecard *linecard, 1994 struct netlink_ext_ack *extack) 1995{ 1996 int err; 1997 1998 mutex_lock(&linecard->state_lock); 1999 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) { 2000 NL_SET_ERR_MSG(extack, "Line card is currently being provisioned"); 2001 err = -EBUSY; 2002 goto out; 2003 } 2004 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) { 2005 NL_SET_ERR_MSG(extack, "Line card is currently being unprovisioned"); 2006 err = -EBUSY; 2007 goto out; 2008 } 2009 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) { 2010 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; 2011 linecard->type = NULL; 2012 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 2013 err = 0; 2014 goto out; 2015 } 2016 2017 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) { 2018 NL_SET_ERR_MSG(extack, "Line card is not provisioned"); 2019 err = 0; 2020 goto out; 2021 } 2022 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING; 2023 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 2024 mutex_unlock(&linecard->state_lock); 2025 err = linecard->ops->unprovision(linecard, linecard->priv, 2026 extack); 2027 if (err) { 2028 /* Unprovisioning failed. Assume the linecard is unprovisioned 2029 * for future operations. 2030 */ 2031 mutex_lock(&linecard->state_lock); 2032 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; 2033 linecard->type = NULL; 2034 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 2035 mutex_unlock(&linecard->state_lock); 2036 } 2037 return err; 2038 2039out: 2040 mutex_unlock(&linecard->state_lock); 2041 return err; 2042} 2043 2044static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb, 2045 struct genl_info *info) 2046{ 2047 struct devlink_linecard *linecard = info->user_ptr[1]; 2048 struct netlink_ext_ack *extack = info->extack; 2049 int err; 2050 2051 if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) { 2052 const char *type; 2053 2054 type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]); 2055 if (strcmp(type, "")) { 2056 err = devlink_linecard_type_set(linecard, type, extack); 2057 if (err) 2058 return err; 2059 } else { 2060 err = devlink_linecard_type_unset(linecard, extack); 2061 if (err) 2062 return err; 2063 } 2064 } 2065 2066 return 0; 2067} 2068 2069static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink, 2070 struct devlink_sb *devlink_sb, 2071 enum devlink_command cmd, u32 portid, 2072 u32 seq, int flags) 2073{ 2074 void *hdr; 2075 2076 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 2077 if (!hdr) 2078 return -EMSGSIZE; 2079 2080 if (devlink_nl_put_handle(msg, devlink)) 2081 goto nla_put_failure; 2082 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 2083 goto nla_put_failure; 2084 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size)) 2085 goto nla_put_failure; 2086 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT, 2087 devlink_sb->ingress_pools_count)) 2088 goto nla_put_failure; 2089 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT, 2090 devlink_sb->egress_pools_count)) 2091 goto nla_put_failure; 2092 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT, 2093 devlink_sb->ingress_tc_count)) 2094 goto nla_put_failure; 2095 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT, 2096 devlink_sb->egress_tc_count)) 2097 goto nla_put_failure; 2098 2099 genlmsg_end(msg, hdr); 2100 return 0; 2101 2102nla_put_failure: 2103 genlmsg_cancel(msg, hdr); 2104 return -EMSGSIZE; 2105} 2106 2107static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb, 2108 struct genl_info *info) 2109{ 2110 struct devlink *devlink = info->user_ptr[0]; 2111 struct devlink_sb *devlink_sb; 2112 struct sk_buff *msg; 2113 int err; 2114 2115 devlink_sb = devlink_sb_get_from_info(devlink, info); 2116 if (IS_ERR(devlink_sb)) 2117 return PTR_ERR(devlink_sb); 2118 2119 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2120 if (!msg) 2121 return -ENOMEM; 2122 2123 err = devlink_nl_sb_fill(msg, devlink, devlink_sb, 2124 DEVLINK_CMD_SB_NEW, 2125 info->snd_portid, info->snd_seq, 0); 2126 if (err) { 2127 nlmsg_free(msg); 2128 return err; 2129 } 2130 2131 return genlmsg_reply(msg, info); 2132} 2133 2134static int 2135devlink_nl_cmd_sb_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 2136 struct netlink_callback *cb) 2137{ 2138 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 2139 struct devlink_sb *devlink_sb; 2140 int idx = 0; 2141 int err = 0; 2142 2143 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 2144 if (idx < state->idx) { 2145 idx++; 2146 continue; 2147 } 2148 err = devlink_nl_sb_fill(msg, devlink, devlink_sb, 2149 DEVLINK_CMD_SB_NEW, 2150 NETLINK_CB(cb->skb).portid, 2151 cb->nlh->nlmsg_seq, 2152 NLM_F_MULTI); 2153 if (err) { 2154 state->idx = idx; 2155 break; 2156 } 2157 idx++; 2158 } 2159 2160 return err; 2161} 2162 2163const struct devlink_cmd devl_cmd_sb_get = { 2164 .dump_one = devlink_nl_cmd_sb_get_dump_one, 2165}; 2166 2167static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink, 2168 struct devlink_sb *devlink_sb, 2169 u16 pool_index, enum devlink_command cmd, 2170 u32 portid, u32 seq, int flags) 2171{ 2172 struct devlink_sb_pool_info pool_info; 2173 void *hdr; 2174 int err; 2175 2176 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index, 2177 pool_index, &pool_info); 2178 if (err) 2179 return err; 2180 2181 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 2182 if (!hdr) 2183 return -EMSGSIZE; 2184 2185 if (devlink_nl_put_handle(msg, devlink)) 2186 goto nla_put_failure; 2187 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 2188 goto nla_put_failure; 2189 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) 2190 goto nla_put_failure; 2191 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type)) 2192 goto nla_put_failure; 2193 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size)) 2194 goto nla_put_failure; 2195 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE, 2196 pool_info.threshold_type)) 2197 goto nla_put_failure; 2198 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE, 2199 pool_info.cell_size)) 2200 goto nla_put_failure; 2201 2202 genlmsg_end(msg, hdr); 2203 return 0; 2204 2205nla_put_failure: 2206 genlmsg_cancel(msg, hdr); 2207 return -EMSGSIZE; 2208} 2209 2210static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb, 2211 struct genl_info *info) 2212{ 2213 struct devlink *devlink = info->user_ptr[0]; 2214 struct devlink_sb *devlink_sb; 2215 struct sk_buff *msg; 2216 u16 pool_index; 2217 int err; 2218 2219 devlink_sb = devlink_sb_get_from_info(devlink, info); 2220 if (IS_ERR(devlink_sb)) 2221 return PTR_ERR(devlink_sb); 2222 2223 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 2224 &pool_index); 2225 if (err) 2226 return err; 2227 2228 if (!devlink->ops->sb_pool_get) 2229 return -EOPNOTSUPP; 2230 2231 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2232 if (!msg) 2233 return -ENOMEM; 2234 2235 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index, 2236 DEVLINK_CMD_SB_POOL_NEW, 2237 info->snd_portid, info->snd_seq, 0); 2238 if (err) { 2239 nlmsg_free(msg); 2240 return err; 2241 } 2242 2243 return genlmsg_reply(msg, info); 2244} 2245 2246static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, 2247 struct devlink *devlink, 2248 struct devlink_sb *devlink_sb, 2249 u32 portid, u32 seq) 2250{ 2251 u16 pool_count = devlink_sb_pool_count(devlink_sb); 2252 u16 pool_index; 2253 int err; 2254 2255 for (pool_index = 0; pool_index < pool_count; pool_index++) { 2256 if (*p_idx < start) { 2257 (*p_idx)++; 2258 continue; 2259 } 2260 err = devlink_nl_sb_pool_fill(msg, devlink, 2261 devlink_sb, 2262 pool_index, 2263 DEVLINK_CMD_SB_POOL_NEW, 2264 portid, seq, NLM_F_MULTI); 2265 if (err) 2266 return err; 2267 (*p_idx)++; 2268 } 2269 return 0; 2270} 2271 2272static int 2273devlink_nl_cmd_sb_pool_get_dump_one(struct sk_buff *msg, 2274 struct devlink *devlink, 2275 struct netlink_callback *cb) 2276{ 2277 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 2278 struct devlink_sb *devlink_sb; 2279 int err = 0; 2280 int idx = 0; 2281 2282 if (!devlink->ops->sb_pool_get) 2283 return 0; 2284 2285 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 2286 err = __sb_pool_get_dumpit(msg, state->idx, &idx, 2287 devlink, devlink_sb, 2288 NETLINK_CB(cb->skb).portid, 2289 cb->nlh->nlmsg_seq); 2290 if (err == -EOPNOTSUPP) { 2291 err = 0; 2292 } else if (err) { 2293 state->idx = idx; 2294 break; 2295 } 2296 } 2297 2298 return err; 2299} 2300 2301const struct devlink_cmd devl_cmd_sb_pool_get = { 2302 .dump_one = devlink_nl_cmd_sb_pool_get_dump_one, 2303}; 2304 2305static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index, 2306 u16 pool_index, u32 size, 2307 enum devlink_sb_threshold_type threshold_type, 2308 struct netlink_ext_ack *extack) 2309 2310{ 2311 const struct devlink_ops *ops = devlink->ops; 2312 2313 if (ops->sb_pool_set) 2314 return ops->sb_pool_set(devlink, sb_index, pool_index, 2315 size, threshold_type, extack); 2316 return -EOPNOTSUPP; 2317} 2318 2319static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb, 2320 struct genl_info *info) 2321{ 2322 struct devlink *devlink = info->user_ptr[0]; 2323 enum devlink_sb_threshold_type threshold_type; 2324 struct devlink_sb *devlink_sb; 2325 u16 pool_index; 2326 u32 size; 2327 int err; 2328 2329 devlink_sb = devlink_sb_get_from_info(devlink, info); 2330 if (IS_ERR(devlink_sb)) 2331 return PTR_ERR(devlink_sb); 2332 2333 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 2334 &pool_index); 2335 if (err) 2336 return err; 2337 2338 err = devlink_sb_th_type_get_from_info(info, &threshold_type); 2339 if (err) 2340 return err; 2341 2342 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE)) 2343 return -EINVAL; 2344 2345 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]); 2346 return devlink_sb_pool_set(devlink, devlink_sb->index, 2347 pool_index, size, threshold_type, 2348 info->extack); 2349} 2350 2351static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg, 2352 struct devlink *devlink, 2353 struct devlink_port *devlink_port, 2354 struct devlink_sb *devlink_sb, 2355 u16 pool_index, 2356 enum devlink_command cmd, 2357 u32 portid, u32 seq, int flags) 2358{ 2359 const struct devlink_ops *ops = devlink->ops; 2360 u32 threshold; 2361 void *hdr; 2362 int err; 2363 2364 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index, 2365 pool_index, &threshold); 2366 if (err) 2367 return err; 2368 2369 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 2370 if (!hdr) 2371 return -EMSGSIZE; 2372 2373 if (devlink_nl_put_handle(msg, devlink)) 2374 goto nla_put_failure; 2375 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 2376 goto nla_put_failure; 2377 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 2378 goto nla_put_failure; 2379 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) 2380 goto nla_put_failure; 2381 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) 2382 goto nla_put_failure; 2383 2384 if (ops->sb_occ_port_pool_get) { 2385 u32 cur; 2386 u32 max; 2387 2388 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index, 2389 pool_index, &cur, &max); 2390 if (err && err != -EOPNOTSUPP) 2391 goto sb_occ_get_failure; 2392 if (!err) { 2393 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) 2394 goto nla_put_failure; 2395 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) 2396 goto nla_put_failure; 2397 } 2398 } 2399 2400 genlmsg_end(msg, hdr); 2401 return 0; 2402 2403nla_put_failure: 2404 err = -EMSGSIZE; 2405sb_occ_get_failure: 2406 genlmsg_cancel(msg, hdr); 2407 return err; 2408} 2409 2410static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb, 2411 struct genl_info *info) 2412{ 2413 struct devlink_port *devlink_port = info->user_ptr[1]; 2414 struct devlink *devlink = devlink_port->devlink; 2415 struct devlink_sb *devlink_sb; 2416 struct sk_buff *msg; 2417 u16 pool_index; 2418 int err; 2419 2420 devlink_sb = devlink_sb_get_from_info(devlink, info); 2421 if (IS_ERR(devlink_sb)) 2422 return PTR_ERR(devlink_sb); 2423 2424 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 2425 &pool_index); 2426 if (err) 2427 return err; 2428 2429 if (!devlink->ops->sb_port_pool_get) 2430 return -EOPNOTSUPP; 2431 2432 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2433 if (!msg) 2434 return -ENOMEM; 2435 2436 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port, 2437 devlink_sb, pool_index, 2438 DEVLINK_CMD_SB_PORT_POOL_NEW, 2439 info->snd_portid, info->snd_seq, 0); 2440 if (err) { 2441 nlmsg_free(msg); 2442 return err; 2443 } 2444 2445 return genlmsg_reply(msg, info); 2446} 2447 2448static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, 2449 struct devlink *devlink, 2450 struct devlink_sb *devlink_sb, 2451 u32 portid, u32 seq) 2452{ 2453 struct devlink_port *devlink_port; 2454 u16 pool_count = devlink_sb_pool_count(devlink_sb); 2455 unsigned long port_index; 2456 u16 pool_index; 2457 int err; 2458 2459 xa_for_each(&devlink->ports, port_index, devlink_port) { 2460 for (pool_index = 0; pool_index < pool_count; pool_index++) { 2461 if (*p_idx < start) { 2462 (*p_idx)++; 2463 continue; 2464 } 2465 err = devlink_nl_sb_port_pool_fill(msg, devlink, 2466 devlink_port, 2467 devlink_sb, 2468 pool_index, 2469 DEVLINK_CMD_SB_PORT_POOL_NEW, 2470 portid, seq, 2471 NLM_F_MULTI); 2472 if (err) 2473 return err; 2474 (*p_idx)++; 2475 } 2476 } 2477 return 0; 2478} 2479 2480static int 2481devlink_nl_cmd_sb_port_pool_get_dump_one(struct sk_buff *msg, 2482 struct devlink *devlink, 2483 struct netlink_callback *cb) 2484{ 2485 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 2486 struct devlink_sb *devlink_sb; 2487 int idx = 0; 2488 int err = 0; 2489 2490 if (!devlink->ops->sb_port_pool_get) 2491 return 0; 2492 2493 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 2494 err = __sb_port_pool_get_dumpit(msg, state->idx, &idx, 2495 devlink, devlink_sb, 2496 NETLINK_CB(cb->skb).portid, 2497 cb->nlh->nlmsg_seq); 2498 if (err == -EOPNOTSUPP) { 2499 err = 0; 2500 } else if (err) { 2501 state->idx = idx; 2502 break; 2503 } 2504 } 2505 2506 return err; 2507} 2508 2509const struct devlink_cmd devl_cmd_sb_port_pool_get = { 2510 .dump_one = devlink_nl_cmd_sb_port_pool_get_dump_one, 2511}; 2512 2513static int devlink_sb_port_pool_set(struct devlink_port *devlink_port, 2514 unsigned int sb_index, u16 pool_index, 2515 u32 threshold, 2516 struct netlink_ext_ack *extack) 2517 2518{ 2519 const struct devlink_ops *ops = devlink_port->devlink->ops; 2520 2521 if (ops->sb_port_pool_set) 2522 return ops->sb_port_pool_set(devlink_port, sb_index, 2523 pool_index, threshold, extack); 2524 return -EOPNOTSUPP; 2525} 2526 2527static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb, 2528 struct genl_info *info) 2529{ 2530 struct devlink_port *devlink_port = info->user_ptr[1]; 2531 struct devlink *devlink = info->user_ptr[0]; 2532 struct devlink_sb *devlink_sb; 2533 u16 pool_index; 2534 u32 threshold; 2535 int err; 2536 2537 devlink_sb = devlink_sb_get_from_info(devlink, info); 2538 if (IS_ERR(devlink_sb)) 2539 return PTR_ERR(devlink_sb); 2540 2541 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 2542 &pool_index); 2543 if (err) 2544 return err; 2545 2546 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD)) 2547 return -EINVAL; 2548 2549 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); 2550 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index, 2551 pool_index, threshold, info->extack); 2552} 2553 2554static int 2555devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink, 2556 struct devlink_port *devlink_port, 2557 struct devlink_sb *devlink_sb, u16 tc_index, 2558 enum devlink_sb_pool_type pool_type, 2559 enum devlink_command cmd, 2560 u32 portid, u32 seq, int flags) 2561{ 2562 const struct devlink_ops *ops = devlink->ops; 2563 u16 pool_index; 2564 u32 threshold; 2565 void *hdr; 2566 int err; 2567 2568 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index, 2569 tc_index, pool_type, 2570 &pool_index, &threshold); 2571 if (err) 2572 return err; 2573 2574 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 2575 if (!hdr) 2576 return -EMSGSIZE; 2577 2578 if (devlink_nl_put_handle(msg, devlink)) 2579 goto nla_put_failure; 2580 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 2581 goto nla_put_failure; 2582 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 2583 goto nla_put_failure; 2584 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index)) 2585 goto nla_put_failure; 2586 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type)) 2587 goto nla_put_failure; 2588 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) 2589 goto nla_put_failure; 2590 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) 2591 goto nla_put_failure; 2592 2593 if (ops->sb_occ_tc_port_bind_get) { 2594 u32 cur; 2595 u32 max; 2596 2597 err = ops->sb_occ_tc_port_bind_get(devlink_port, 2598 devlink_sb->index, 2599 tc_index, pool_type, 2600 &cur, &max); 2601 if (err && err != -EOPNOTSUPP) 2602 return err; 2603 if (!err) { 2604 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) 2605 goto nla_put_failure; 2606 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) 2607 goto nla_put_failure; 2608 } 2609 } 2610 2611 genlmsg_end(msg, hdr); 2612 return 0; 2613 2614nla_put_failure: 2615 genlmsg_cancel(msg, hdr); 2616 return -EMSGSIZE; 2617} 2618 2619static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb, 2620 struct genl_info *info) 2621{ 2622 struct devlink_port *devlink_port = info->user_ptr[1]; 2623 struct devlink *devlink = devlink_port->devlink; 2624 struct devlink_sb *devlink_sb; 2625 struct sk_buff *msg; 2626 enum devlink_sb_pool_type pool_type; 2627 u16 tc_index; 2628 int err; 2629 2630 devlink_sb = devlink_sb_get_from_info(devlink, info); 2631 if (IS_ERR(devlink_sb)) 2632 return PTR_ERR(devlink_sb); 2633 2634 err = devlink_sb_pool_type_get_from_info(info, &pool_type); 2635 if (err) 2636 return err; 2637 2638 err = devlink_sb_tc_index_get_from_info(devlink_sb, info, 2639 pool_type, &tc_index); 2640 if (err) 2641 return err; 2642 2643 if (!devlink->ops->sb_tc_pool_bind_get) 2644 return -EOPNOTSUPP; 2645 2646 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2647 if (!msg) 2648 return -ENOMEM; 2649 2650 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port, 2651 devlink_sb, tc_index, pool_type, 2652 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 2653 info->snd_portid, 2654 info->snd_seq, 0); 2655 if (err) { 2656 nlmsg_free(msg); 2657 return err; 2658 } 2659 2660 return genlmsg_reply(msg, info); 2661} 2662 2663static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, 2664 int start, int *p_idx, 2665 struct devlink *devlink, 2666 struct devlink_sb *devlink_sb, 2667 u32 portid, u32 seq) 2668{ 2669 struct devlink_port *devlink_port; 2670 unsigned long port_index; 2671 u16 tc_index; 2672 int err; 2673 2674 xa_for_each(&devlink->ports, port_index, devlink_port) { 2675 for (tc_index = 0; 2676 tc_index < devlink_sb->ingress_tc_count; tc_index++) { 2677 if (*p_idx < start) { 2678 (*p_idx)++; 2679 continue; 2680 } 2681 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, 2682 devlink_port, 2683 devlink_sb, 2684 tc_index, 2685 DEVLINK_SB_POOL_TYPE_INGRESS, 2686 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 2687 portid, seq, 2688 NLM_F_MULTI); 2689 if (err) 2690 return err; 2691 (*p_idx)++; 2692 } 2693 for (tc_index = 0; 2694 tc_index < devlink_sb->egress_tc_count; tc_index++) { 2695 if (*p_idx < start) { 2696 (*p_idx)++; 2697 continue; 2698 } 2699 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, 2700 devlink_port, 2701 devlink_sb, 2702 tc_index, 2703 DEVLINK_SB_POOL_TYPE_EGRESS, 2704 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 2705 portid, seq, 2706 NLM_F_MULTI); 2707 if (err) 2708 return err; 2709 (*p_idx)++; 2710 } 2711 } 2712 return 0; 2713} 2714 2715static int 2716devlink_nl_cmd_sb_tc_pool_bind_get_dump_one(struct sk_buff *msg, 2717 struct devlink *devlink, 2718 struct netlink_callback *cb) 2719{ 2720 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 2721 struct devlink_sb *devlink_sb; 2722 int idx = 0; 2723 int err = 0; 2724 2725 if (!devlink->ops->sb_tc_pool_bind_get) 2726 return 0; 2727 2728 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 2729 err = __sb_tc_pool_bind_get_dumpit(msg, state->idx, &idx, 2730 devlink, devlink_sb, 2731 NETLINK_CB(cb->skb).portid, 2732 cb->nlh->nlmsg_seq); 2733 if (err == -EOPNOTSUPP) { 2734 err = 0; 2735 } else if (err) { 2736 state->idx = idx; 2737 break; 2738 } 2739 } 2740 2741 return err; 2742} 2743 2744const struct devlink_cmd devl_cmd_sb_tc_pool_bind_get = { 2745 .dump_one = devlink_nl_cmd_sb_tc_pool_bind_get_dump_one, 2746}; 2747 2748static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port, 2749 unsigned int sb_index, u16 tc_index, 2750 enum devlink_sb_pool_type pool_type, 2751 u16 pool_index, u32 threshold, 2752 struct netlink_ext_ack *extack) 2753 2754{ 2755 const struct devlink_ops *ops = devlink_port->devlink->ops; 2756 2757 if (ops->sb_tc_pool_bind_set) 2758 return ops->sb_tc_pool_bind_set(devlink_port, sb_index, 2759 tc_index, pool_type, 2760 pool_index, threshold, extack); 2761 return -EOPNOTSUPP; 2762} 2763 2764static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb, 2765 struct genl_info *info) 2766{ 2767 struct devlink_port *devlink_port = info->user_ptr[1]; 2768 struct devlink *devlink = info->user_ptr[0]; 2769 enum devlink_sb_pool_type pool_type; 2770 struct devlink_sb *devlink_sb; 2771 u16 tc_index; 2772 u16 pool_index; 2773 u32 threshold; 2774 int err; 2775 2776 devlink_sb = devlink_sb_get_from_info(devlink, info); 2777 if (IS_ERR(devlink_sb)) 2778 return PTR_ERR(devlink_sb); 2779 2780 err = devlink_sb_pool_type_get_from_info(info, &pool_type); 2781 if (err) 2782 return err; 2783 2784 err = devlink_sb_tc_index_get_from_info(devlink_sb, info, 2785 pool_type, &tc_index); 2786 if (err) 2787 return err; 2788 2789 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 2790 &pool_index); 2791 if (err) 2792 return err; 2793 2794 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD)) 2795 return -EINVAL; 2796 2797 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); 2798 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index, 2799 tc_index, pool_type, 2800 pool_index, threshold, info->extack); 2801} 2802 2803static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb, 2804 struct genl_info *info) 2805{ 2806 struct devlink *devlink = info->user_ptr[0]; 2807 const struct devlink_ops *ops = devlink->ops; 2808 struct devlink_sb *devlink_sb; 2809 2810 devlink_sb = devlink_sb_get_from_info(devlink, info); 2811 if (IS_ERR(devlink_sb)) 2812 return PTR_ERR(devlink_sb); 2813 2814 if (ops->sb_occ_snapshot) 2815 return ops->sb_occ_snapshot(devlink, devlink_sb->index); 2816 return -EOPNOTSUPP; 2817} 2818 2819static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb, 2820 struct genl_info *info) 2821{ 2822 struct devlink *devlink = info->user_ptr[0]; 2823 const struct devlink_ops *ops = devlink->ops; 2824 struct devlink_sb *devlink_sb; 2825 2826 devlink_sb = devlink_sb_get_from_info(devlink, info); 2827 if (IS_ERR(devlink_sb)) 2828 return PTR_ERR(devlink_sb); 2829 2830 if (ops->sb_occ_max_clear) 2831 return ops->sb_occ_max_clear(devlink, devlink_sb->index); 2832 return -EOPNOTSUPP; 2833} 2834 2835int devlink_rate_nodes_check(struct devlink *devlink, u16 mode, 2836 struct netlink_ext_ack *extack) 2837{ 2838 struct devlink_rate *devlink_rate; 2839 2840 list_for_each_entry(devlink_rate, &devlink->rate_list, list) 2841 if (devlink_rate_is_node(devlink_rate)) { 2842 NL_SET_ERR_MSG(extack, "Rate node(s) exists."); 2843 return -EBUSY; 2844 } 2845 return 0; 2846} 2847 2848int devlink_dpipe_match_put(struct sk_buff *skb, 2849 struct devlink_dpipe_match *match) 2850{ 2851 struct devlink_dpipe_header *header = match->header; 2852 struct devlink_dpipe_field *field = &header->fields[match->field_id]; 2853 struct nlattr *match_attr; 2854 2855 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH); 2856 if (!match_attr) 2857 return -EMSGSIZE; 2858 2859 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) || 2860 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) || 2861 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 2862 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 2863 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 2864 goto nla_put_failure; 2865 2866 nla_nest_end(skb, match_attr); 2867 return 0; 2868 2869nla_put_failure: 2870 nla_nest_cancel(skb, match_attr); 2871 return -EMSGSIZE; 2872} 2873EXPORT_SYMBOL_GPL(devlink_dpipe_match_put); 2874 2875static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table, 2876 struct sk_buff *skb) 2877{ 2878 struct nlattr *matches_attr; 2879 2880 matches_attr = nla_nest_start_noflag(skb, 2881 DEVLINK_ATTR_DPIPE_TABLE_MATCHES); 2882 if (!matches_attr) 2883 return -EMSGSIZE; 2884 2885 if (table->table_ops->matches_dump(table->priv, skb)) 2886 goto nla_put_failure; 2887 2888 nla_nest_end(skb, matches_attr); 2889 return 0; 2890 2891nla_put_failure: 2892 nla_nest_cancel(skb, matches_attr); 2893 return -EMSGSIZE; 2894} 2895 2896int devlink_dpipe_action_put(struct sk_buff *skb, 2897 struct devlink_dpipe_action *action) 2898{ 2899 struct devlink_dpipe_header *header = action->header; 2900 struct devlink_dpipe_field *field = &header->fields[action->field_id]; 2901 struct nlattr *action_attr; 2902 2903 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION); 2904 if (!action_attr) 2905 return -EMSGSIZE; 2906 2907 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) || 2908 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) || 2909 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 2910 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 2911 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 2912 goto nla_put_failure; 2913 2914 nla_nest_end(skb, action_attr); 2915 return 0; 2916 2917nla_put_failure: 2918 nla_nest_cancel(skb, action_attr); 2919 return -EMSGSIZE; 2920} 2921EXPORT_SYMBOL_GPL(devlink_dpipe_action_put); 2922 2923static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table, 2924 struct sk_buff *skb) 2925{ 2926 struct nlattr *actions_attr; 2927 2928 actions_attr = nla_nest_start_noflag(skb, 2929 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS); 2930 if (!actions_attr) 2931 return -EMSGSIZE; 2932 2933 if (table->table_ops->actions_dump(table->priv, skb)) 2934 goto nla_put_failure; 2935 2936 nla_nest_end(skb, actions_attr); 2937 return 0; 2938 2939nla_put_failure: 2940 nla_nest_cancel(skb, actions_attr); 2941 return -EMSGSIZE; 2942} 2943 2944static int devlink_dpipe_table_put(struct sk_buff *skb, 2945 struct devlink_dpipe_table *table) 2946{ 2947 struct nlattr *table_attr; 2948 u64 table_size; 2949 2950 table_size = table->table_ops->size_get(table->priv); 2951 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE); 2952 if (!table_attr) 2953 return -EMSGSIZE; 2954 2955 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) || 2956 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size, 2957 DEVLINK_ATTR_PAD)) 2958 goto nla_put_failure; 2959 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, 2960 table->counters_enabled)) 2961 goto nla_put_failure; 2962 2963 if (table->resource_valid) { 2964 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID, 2965 table->resource_id, DEVLINK_ATTR_PAD) || 2966 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS, 2967 table->resource_units, DEVLINK_ATTR_PAD)) 2968 goto nla_put_failure; 2969 } 2970 if (devlink_dpipe_matches_put(table, skb)) 2971 goto nla_put_failure; 2972 2973 if (devlink_dpipe_actions_put(table, skb)) 2974 goto nla_put_failure; 2975 2976 nla_nest_end(skb, table_attr); 2977 return 0; 2978 2979nla_put_failure: 2980 nla_nest_cancel(skb, table_attr); 2981 return -EMSGSIZE; 2982} 2983 2984static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb, 2985 struct genl_info *info) 2986{ 2987 int err; 2988 2989 if (*pskb) { 2990 err = genlmsg_reply(*pskb, info); 2991 if (err) 2992 return err; 2993 } 2994 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 2995 if (!*pskb) 2996 return -ENOMEM; 2997 return 0; 2998} 2999 3000static int devlink_dpipe_tables_fill(struct genl_info *info, 3001 enum devlink_command cmd, int flags, 3002 struct list_head *dpipe_tables, 3003 const char *table_name) 3004{ 3005 struct devlink *devlink = info->user_ptr[0]; 3006 struct devlink_dpipe_table *table; 3007 struct nlattr *tables_attr; 3008 struct sk_buff *skb = NULL; 3009 struct nlmsghdr *nlh; 3010 bool incomplete; 3011 void *hdr; 3012 int i; 3013 int err; 3014 3015 table = list_first_entry(dpipe_tables, 3016 struct devlink_dpipe_table, list); 3017start_again: 3018 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 3019 if (err) 3020 return err; 3021 3022 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 3023 &devlink_nl_family, NLM_F_MULTI, cmd); 3024 if (!hdr) { 3025 nlmsg_free(skb); 3026 return -EMSGSIZE; 3027 } 3028 3029 if (devlink_nl_put_handle(skb, devlink)) 3030 goto nla_put_failure; 3031 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES); 3032 if (!tables_attr) 3033 goto nla_put_failure; 3034 3035 i = 0; 3036 incomplete = false; 3037 list_for_each_entry_from(table, dpipe_tables, list) { 3038 if (!table_name) { 3039 err = devlink_dpipe_table_put(skb, table); 3040 if (err) { 3041 if (!i) 3042 goto err_table_put; 3043 incomplete = true; 3044 break; 3045 } 3046 } else { 3047 if (!strcmp(table->name, table_name)) { 3048 err = devlink_dpipe_table_put(skb, table); 3049 if (err) 3050 break; 3051 } 3052 } 3053 i++; 3054 } 3055 3056 nla_nest_end(skb, tables_attr); 3057 genlmsg_end(skb, hdr); 3058 if (incomplete) 3059 goto start_again; 3060 3061send_done: 3062 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 3063 NLMSG_DONE, 0, flags | NLM_F_MULTI); 3064 if (!nlh) { 3065 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 3066 if (err) 3067 return err; 3068 goto send_done; 3069 } 3070 3071 return genlmsg_reply(skb, info); 3072 3073nla_put_failure: 3074 err = -EMSGSIZE; 3075err_table_put: 3076 nlmsg_free(skb); 3077 return err; 3078} 3079 3080static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb, 3081 struct genl_info *info) 3082{ 3083 struct devlink *devlink = info->user_ptr[0]; 3084 const char *table_name = NULL; 3085 3086 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]) 3087 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 3088 3089 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0, 3090 &devlink->dpipe_table_list, 3091 table_name); 3092} 3093 3094static int devlink_dpipe_value_put(struct sk_buff *skb, 3095 struct devlink_dpipe_value *value) 3096{ 3097 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE, 3098 value->value_size, value->value)) 3099 return -EMSGSIZE; 3100 if (value->mask) 3101 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK, 3102 value->value_size, value->mask)) 3103 return -EMSGSIZE; 3104 if (value->mapping_valid) 3105 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING, 3106 value->mapping_value)) 3107 return -EMSGSIZE; 3108 return 0; 3109} 3110 3111static int devlink_dpipe_action_value_put(struct sk_buff *skb, 3112 struct devlink_dpipe_value *value) 3113{ 3114 if (!value->action) 3115 return -EINVAL; 3116 if (devlink_dpipe_action_put(skb, value->action)) 3117 return -EMSGSIZE; 3118 if (devlink_dpipe_value_put(skb, value)) 3119 return -EMSGSIZE; 3120 return 0; 3121} 3122 3123static int devlink_dpipe_action_values_put(struct sk_buff *skb, 3124 struct devlink_dpipe_value *values, 3125 unsigned int values_count) 3126{ 3127 struct nlattr *action_attr; 3128 int i; 3129 int err; 3130 3131 for (i = 0; i < values_count; i++) { 3132 action_attr = nla_nest_start_noflag(skb, 3133 DEVLINK_ATTR_DPIPE_ACTION_VALUE); 3134 if (!action_attr) 3135 return -EMSGSIZE; 3136 err = devlink_dpipe_action_value_put(skb, &values[i]); 3137 if (err) 3138 goto err_action_value_put; 3139 nla_nest_end(skb, action_attr); 3140 } 3141 return 0; 3142 3143err_action_value_put: 3144 nla_nest_cancel(skb, action_attr); 3145 return err; 3146} 3147 3148static int devlink_dpipe_match_value_put(struct sk_buff *skb, 3149 struct devlink_dpipe_value *value) 3150{ 3151 if (!value->match) 3152 return -EINVAL; 3153 if (devlink_dpipe_match_put(skb, value->match)) 3154 return -EMSGSIZE; 3155 if (devlink_dpipe_value_put(skb, value)) 3156 return -EMSGSIZE; 3157 return 0; 3158} 3159 3160static int devlink_dpipe_match_values_put(struct sk_buff *skb, 3161 struct devlink_dpipe_value *values, 3162 unsigned int values_count) 3163{ 3164 struct nlattr *match_attr; 3165 int i; 3166 int err; 3167 3168 for (i = 0; i < values_count; i++) { 3169 match_attr = nla_nest_start_noflag(skb, 3170 DEVLINK_ATTR_DPIPE_MATCH_VALUE); 3171 if (!match_attr) 3172 return -EMSGSIZE; 3173 err = devlink_dpipe_match_value_put(skb, &values[i]); 3174 if (err) 3175 goto err_match_value_put; 3176 nla_nest_end(skb, match_attr); 3177 } 3178 return 0; 3179 3180err_match_value_put: 3181 nla_nest_cancel(skb, match_attr); 3182 return err; 3183} 3184 3185static int devlink_dpipe_entry_put(struct sk_buff *skb, 3186 struct devlink_dpipe_entry *entry) 3187{ 3188 struct nlattr *entry_attr, *matches_attr, *actions_attr; 3189 int err; 3190 3191 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY); 3192 if (!entry_attr) 3193 return -EMSGSIZE; 3194 3195 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index, 3196 DEVLINK_ATTR_PAD)) 3197 goto nla_put_failure; 3198 if (entry->counter_valid) 3199 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER, 3200 entry->counter, DEVLINK_ATTR_PAD)) 3201 goto nla_put_failure; 3202 3203 matches_attr = nla_nest_start_noflag(skb, 3204 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES); 3205 if (!matches_attr) 3206 goto nla_put_failure; 3207 3208 err = devlink_dpipe_match_values_put(skb, entry->match_values, 3209 entry->match_values_count); 3210 if (err) { 3211 nla_nest_cancel(skb, matches_attr); 3212 goto err_match_values_put; 3213 } 3214 nla_nest_end(skb, matches_attr); 3215 3216 actions_attr = nla_nest_start_noflag(skb, 3217 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES); 3218 if (!actions_attr) 3219 goto nla_put_failure; 3220 3221 err = devlink_dpipe_action_values_put(skb, entry->action_values, 3222 entry->action_values_count); 3223 if (err) { 3224 nla_nest_cancel(skb, actions_attr); 3225 goto err_action_values_put; 3226 } 3227 nla_nest_end(skb, actions_attr); 3228 3229 nla_nest_end(skb, entry_attr); 3230 return 0; 3231 3232nla_put_failure: 3233 err = -EMSGSIZE; 3234err_match_values_put: 3235err_action_values_put: 3236 nla_nest_cancel(skb, entry_attr); 3237 return err; 3238} 3239 3240static struct devlink_dpipe_table * 3241devlink_dpipe_table_find(struct list_head *dpipe_tables, 3242 const char *table_name, struct devlink *devlink) 3243{ 3244 struct devlink_dpipe_table *table; 3245 list_for_each_entry_rcu(table, dpipe_tables, list, 3246 lockdep_is_held(&devlink->lock)) { 3247 if (!strcmp(table->name, table_name)) 3248 return table; 3249 } 3250 return NULL; 3251} 3252 3253int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx) 3254{ 3255 struct devlink *devlink; 3256 int err; 3257 3258 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb, 3259 dump_ctx->info); 3260 if (err) 3261 return err; 3262 3263 dump_ctx->hdr = genlmsg_put(dump_ctx->skb, 3264 dump_ctx->info->snd_portid, 3265 dump_ctx->info->snd_seq, 3266 &devlink_nl_family, NLM_F_MULTI, 3267 dump_ctx->cmd); 3268 if (!dump_ctx->hdr) 3269 goto nla_put_failure; 3270 3271 devlink = dump_ctx->info->user_ptr[0]; 3272 if (devlink_nl_put_handle(dump_ctx->skb, devlink)) 3273 goto nla_put_failure; 3274 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb, 3275 DEVLINK_ATTR_DPIPE_ENTRIES); 3276 if (!dump_ctx->nest) 3277 goto nla_put_failure; 3278 return 0; 3279 3280nla_put_failure: 3281 nlmsg_free(dump_ctx->skb); 3282 return -EMSGSIZE; 3283} 3284EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare); 3285 3286int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx, 3287 struct devlink_dpipe_entry *entry) 3288{ 3289 return devlink_dpipe_entry_put(dump_ctx->skb, entry); 3290} 3291EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append); 3292 3293int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx) 3294{ 3295 nla_nest_end(dump_ctx->skb, dump_ctx->nest); 3296 genlmsg_end(dump_ctx->skb, dump_ctx->hdr); 3297 return 0; 3298} 3299EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close); 3300 3301void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry) 3302 3303{ 3304 unsigned int value_count, value_index; 3305 struct devlink_dpipe_value *value; 3306 3307 value = entry->action_values; 3308 value_count = entry->action_values_count; 3309 for (value_index = 0; value_index < value_count; value_index++) { 3310 kfree(value[value_index].value); 3311 kfree(value[value_index].mask); 3312 } 3313 3314 value = entry->match_values; 3315 value_count = entry->match_values_count; 3316 for (value_index = 0; value_index < value_count; value_index++) { 3317 kfree(value[value_index].value); 3318 kfree(value[value_index].mask); 3319 } 3320} 3321EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear); 3322 3323static int devlink_dpipe_entries_fill(struct genl_info *info, 3324 enum devlink_command cmd, int flags, 3325 struct devlink_dpipe_table *table) 3326{ 3327 struct devlink_dpipe_dump_ctx dump_ctx; 3328 struct nlmsghdr *nlh; 3329 int err; 3330 3331 dump_ctx.skb = NULL; 3332 dump_ctx.cmd = cmd; 3333 dump_ctx.info = info; 3334 3335 err = table->table_ops->entries_dump(table->priv, 3336 table->counters_enabled, 3337 &dump_ctx); 3338 if (err) 3339 return err; 3340 3341send_done: 3342 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq, 3343 NLMSG_DONE, 0, flags | NLM_F_MULTI); 3344 if (!nlh) { 3345 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info); 3346 if (err) 3347 return err; 3348 goto send_done; 3349 } 3350 return genlmsg_reply(dump_ctx.skb, info); 3351} 3352 3353static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb, 3354 struct genl_info *info) 3355{ 3356 struct devlink *devlink = info->user_ptr[0]; 3357 struct devlink_dpipe_table *table; 3358 const char *table_name; 3359 3360 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME)) 3361 return -EINVAL; 3362 3363 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 3364 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 3365 table_name, devlink); 3366 if (!table) 3367 return -EINVAL; 3368 3369 if (!table->table_ops->entries_dump) 3370 return -EINVAL; 3371 3372 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET, 3373 0, table); 3374} 3375 3376static int devlink_dpipe_fields_put(struct sk_buff *skb, 3377 const struct devlink_dpipe_header *header) 3378{ 3379 struct devlink_dpipe_field *field; 3380 struct nlattr *field_attr; 3381 int i; 3382 3383 for (i = 0; i < header->fields_count; i++) { 3384 field = &header->fields[i]; 3385 field_attr = nla_nest_start_noflag(skb, 3386 DEVLINK_ATTR_DPIPE_FIELD); 3387 if (!field_attr) 3388 return -EMSGSIZE; 3389 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) || 3390 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 3391 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) || 3392 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type)) 3393 goto nla_put_failure; 3394 nla_nest_end(skb, field_attr); 3395 } 3396 return 0; 3397 3398nla_put_failure: 3399 nla_nest_cancel(skb, field_attr); 3400 return -EMSGSIZE; 3401} 3402 3403static int devlink_dpipe_header_put(struct sk_buff *skb, 3404 struct devlink_dpipe_header *header) 3405{ 3406 struct nlattr *fields_attr, *header_attr; 3407 int err; 3408 3409 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER); 3410 if (!header_attr) 3411 return -EMSGSIZE; 3412 3413 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) || 3414 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 3415 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 3416 goto nla_put_failure; 3417 3418 fields_attr = nla_nest_start_noflag(skb, 3419 DEVLINK_ATTR_DPIPE_HEADER_FIELDS); 3420 if (!fields_attr) 3421 goto nla_put_failure; 3422 3423 err = devlink_dpipe_fields_put(skb, header); 3424 if (err) { 3425 nla_nest_cancel(skb, fields_attr); 3426 goto nla_put_failure; 3427 } 3428 nla_nest_end(skb, fields_attr); 3429 nla_nest_end(skb, header_attr); 3430 return 0; 3431 3432nla_put_failure: 3433 err = -EMSGSIZE; 3434 nla_nest_cancel(skb, header_attr); 3435 return err; 3436} 3437 3438static int devlink_dpipe_headers_fill(struct genl_info *info, 3439 enum devlink_command cmd, int flags, 3440 struct devlink_dpipe_headers * 3441 dpipe_headers) 3442{ 3443 struct devlink *devlink = info->user_ptr[0]; 3444 struct nlattr *headers_attr; 3445 struct sk_buff *skb = NULL; 3446 struct nlmsghdr *nlh; 3447 void *hdr; 3448 int i, j; 3449 int err; 3450 3451 i = 0; 3452start_again: 3453 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 3454 if (err) 3455 return err; 3456 3457 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 3458 &devlink_nl_family, NLM_F_MULTI, cmd); 3459 if (!hdr) { 3460 nlmsg_free(skb); 3461 return -EMSGSIZE; 3462 } 3463 3464 if (devlink_nl_put_handle(skb, devlink)) 3465 goto nla_put_failure; 3466 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS); 3467 if (!headers_attr) 3468 goto nla_put_failure; 3469 3470 j = 0; 3471 for (; i < dpipe_headers->headers_count; i++) { 3472 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]); 3473 if (err) { 3474 if (!j) 3475 goto err_table_put; 3476 break; 3477 } 3478 j++; 3479 } 3480 nla_nest_end(skb, headers_attr); 3481 genlmsg_end(skb, hdr); 3482 if (i != dpipe_headers->headers_count) 3483 goto start_again; 3484 3485send_done: 3486 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 3487 NLMSG_DONE, 0, flags | NLM_F_MULTI); 3488 if (!nlh) { 3489 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 3490 if (err) 3491 return err; 3492 goto send_done; 3493 } 3494 return genlmsg_reply(skb, info); 3495 3496nla_put_failure: 3497 err = -EMSGSIZE; 3498err_table_put: 3499 nlmsg_free(skb); 3500 return err; 3501} 3502 3503static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb, 3504 struct genl_info *info) 3505{ 3506 struct devlink *devlink = info->user_ptr[0]; 3507 3508 if (!devlink->dpipe_headers) 3509 return -EOPNOTSUPP; 3510 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET, 3511 0, devlink->dpipe_headers); 3512} 3513 3514static int devlink_dpipe_table_counters_set(struct devlink *devlink, 3515 const char *table_name, 3516 bool enable) 3517{ 3518 struct devlink_dpipe_table *table; 3519 3520 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 3521 table_name, devlink); 3522 if (!table) 3523 return -EINVAL; 3524 3525 if (table->counter_control_extern) 3526 return -EOPNOTSUPP; 3527 3528 if (!(table->counters_enabled ^ enable)) 3529 return 0; 3530 3531 table->counters_enabled = enable; 3532 if (table->table_ops->counters_set_update) 3533 table->table_ops->counters_set_update(table->priv, enable); 3534 return 0; 3535} 3536 3537static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb, 3538 struct genl_info *info) 3539{ 3540 struct devlink *devlink = info->user_ptr[0]; 3541 const char *table_name; 3542 bool counters_enable; 3543 3544 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) || 3545 GENL_REQ_ATTR_CHECK(info, 3546 DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED)) 3547 return -EINVAL; 3548 3549 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 3550 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]); 3551 3552 return devlink_dpipe_table_counters_set(devlink, table_name, 3553 counters_enable); 3554} 3555 3556static struct devlink_resource * 3557devlink_resource_find(struct devlink *devlink, 3558 struct devlink_resource *resource, u64 resource_id) 3559{ 3560 struct list_head *resource_list; 3561 3562 if (resource) 3563 resource_list = &resource->resource_list; 3564 else 3565 resource_list = &devlink->resource_list; 3566 3567 list_for_each_entry(resource, resource_list, list) { 3568 struct devlink_resource *child_resource; 3569 3570 if (resource->id == resource_id) 3571 return resource; 3572 3573 child_resource = devlink_resource_find(devlink, resource, 3574 resource_id); 3575 if (child_resource) 3576 return child_resource; 3577 } 3578 return NULL; 3579} 3580 3581static void 3582devlink_resource_validate_children(struct devlink_resource *resource) 3583{ 3584 struct devlink_resource *child_resource; 3585 bool size_valid = true; 3586 u64 parts_size = 0; 3587 3588 if (list_empty(&resource->resource_list)) 3589 goto out; 3590 3591 list_for_each_entry(child_resource, &resource->resource_list, list) 3592 parts_size += child_resource->size_new; 3593 3594 if (parts_size > resource->size_new) 3595 size_valid = false; 3596out: 3597 resource->size_valid = size_valid; 3598} 3599 3600static int 3601devlink_resource_validate_size(struct devlink_resource *resource, u64 size, 3602 struct netlink_ext_ack *extack) 3603{ 3604 u64 reminder; 3605 int err = 0; 3606 3607 if (size > resource->size_params.size_max) { 3608 NL_SET_ERR_MSG(extack, "Size larger than maximum"); 3609 err = -EINVAL; 3610 } 3611 3612 if (size < resource->size_params.size_min) { 3613 NL_SET_ERR_MSG(extack, "Size smaller than minimum"); 3614 err = -EINVAL; 3615 } 3616 3617 div64_u64_rem(size, resource->size_params.size_granularity, &reminder); 3618 if (reminder) { 3619 NL_SET_ERR_MSG(extack, "Wrong granularity"); 3620 err = -EINVAL; 3621 } 3622 3623 return err; 3624} 3625 3626static int devlink_nl_cmd_resource_set(struct sk_buff *skb, 3627 struct genl_info *info) 3628{ 3629 struct devlink *devlink = info->user_ptr[0]; 3630 struct devlink_resource *resource; 3631 u64 resource_id; 3632 u64 size; 3633 int err; 3634 3635 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) || 3636 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE)) 3637 return -EINVAL; 3638 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]); 3639 3640 resource = devlink_resource_find(devlink, NULL, resource_id); 3641 if (!resource) 3642 return -EINVAL; 3643 3644 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]); 3645 err = devlink_resource_validate_size(resource, size, info->extack); 3646 if (err) 3647 return err; 3648 3649 resource->size_new = size; 3650 devlink_resource_validate_children(resource); 3651 if (resource->parent) 3652 devlink_resource_validate_children(resource->parent); 3653 return 0; 3654} 3655 3656static int 3657devlink_resource_size_params_put(struct devlink_resource *resource, 3658 struct sk_buff *skb) 3659{ 3660 struct devlink_resource_size_params *size_params; 3661 3662 size_params = &resource->size_params; 3663 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN, 3664 size_params->size_granularity, DEVLINK_ATTR_PAD) || 3665 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX, 3666 size_params->size_max, DEVLINK_ATTR_PAD) || 3667 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN, 3668 size_params->size_min, DEVLINK_ATTR_PAD) || 3669 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit)) 3670 return -EMSGSIZE; 3671 return 0; 3672} 3673 3674static int devlink_resource_occ_put(struct devlink_resource *resource, 3675 struct sk_buff *skb) 3676{ 3677 if (!resource->occ_get) 3678 return 0; 3679 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC, 3680 resource->occ_get(resource->occ_get_priv), 3681 DEVLINK_ATTR_PAD); 3682} 3683 3684static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb, 3685 struct devlink_resource *resource) 3686{ 3687 struct devlink_resource *child_resource; 3688 struct nlattr *child_resource_attr; 3689 struct nlattr *resource_attr; 3690 3691 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE); 3692 if (!resource_attr) 3693 return -EMSGSIZE; 3694 3695 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) || 3696 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size, 3697 DEVLINK_ATTR_PAD) || 3698 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id, 3699 DEVLINK_ATTR_PAD)) 3700 goto nla_put_failure; 3701 if (resource->size != resource->size_new && 3702 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW, 3703 resource->size_new, DEVLINK_ATTR_PAD)) 3704 goto nla_put_failure; 3705 if (devlink_resource_occ_put(resource, skb)) 3706 goto nla_put_failure; 3707 if (devlink_resource_size_params_put(resource, skb)) 3708 goto nla_put_failure; 3709 if (list_empty(&resource->resource_list)) 3710 goto out; 3711 3712 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID, 3713 resource->size_valid)) 3714 goto nla_put_failure; 3715 3716 child_resource_attr = nla_nest_start_noflag(skb, 3717 DEVLINK_ATTR_RESOURCE_LIST); 3718 if (!child_resource_attr) 3719 goto nla_put_failure; 3720 3721 list_for_each_entry(child_resource, &resource->resource_list, list) { 3722 if (devlink_resource_put(devlink, skb, child_resource)) 3723 goto resource_put_failure; 3724 } 3725 3726 nla_nest_end(skb, child_resource_attr); 3727out: 3728 nla_nest_end(skb, resource_attr); 3729 return 0; 3730 3731resource_put_failure: 3732 nla_nest_cancel(skb, child_resource_attr); 3733nla_put_failure: 3734 nla_nest_cancel(skb, resource_attr); 3735 return -EMSGSIZE; 3736} 3737 3738static int devlink_resource_fill(struct genl_info *info, 3739 enum devlink_command cmd, int flags) 3740{ 3741 struct devlink *devlink = info->user_ptr[0]; 3742 struct devlink_resource *resource; 3743 struct nlattr *resources_attr; 3744 struct sk_buff *skb = NULL; 3745 struct nlmsghdr *nlh; 3746 bool incomplete; 3747 void *hdr; 3748 int i; 3749 int err; 3750 3751 resource = list_first_entry(&devlink->resource_list, 3752 struct devlink_resource, list); 3753start_again: 3754 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 3755 if (err) 3756 return err; 3757 3758 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 3759 &devlink_nl_family, NLM_F_MULTI, cmd); 3760 if (!hdr) { 3761 nlmsg_free(skb); 3762 return -EMSGSIZE; 3763 } 3764 3765 if (devlink_nl_put_handle(skb, devlink)) 3766 goto nla_put_failure; 3767 3768 resources_attr = nla_nest_start_noflag(skb, 3769 DEVLINK_ATTR_RESOURCE_LIST); 3770 if (!resources_attr) 3771 goto nla_put_failure; 3772 3773 incomplete = false; 3774 i = 0; 3775 list_for_each_entry_from(resource, &devlink->resource_list, list) { 3776 err = devlink_resource_put(devlink, skb, resource); 3777 if (err) { 3778 if (!i) 3779 goto err_resource_put; 3780 incomplete = true; 3781 break; 3782 } 3783 i++; 3784 } 3785 nla_nest_end(skb, resources_attr); 3786 genlmsg_end(skb, hdr); 3787 if (incomplete) 3788 goto start_again; 3789send_done: 3790 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 3791 NLMSG_DONE, 0, flags | NLM_F_MULTI); 3792 if (!nlh) { 3793 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 3794 if (err) 3795 return err; 3796 goto send_done; 3797 } 3798 return genlmsg_reply(skb, info); 3799 3800nla_put_failure: 3801 err = -EMSGSIZE; 3802err_resource_put: 3803 nlmsg_free(skb); 3804 return err; 3805} 3806 3807static int devlink_nl_cmd_resource_dump(struct sk_buff *skb, 3808 struct genl_info *info) 3809{ 3810 struct devlink *devlink = info->user_ptr[0]; 3811 3812 if (list_empty(&devlink->resource_list)) 3813 return -EOPNOTSUPP; 3814 3815 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); 3816} 3817 3818int devlink_resources_validate(struct devlink *devlink, 3819 struct devlink_resource *resource, 3820 struct genl_info *info) 3821{ 3822 struct list_head *resource_list; 3823 int err = 0; 3824 3825 if (resource) 3826 resource_list = &resource->resource_list; 3827 else 3828 resource_list = &devlink->resource_list; 3829 3830 list_for_each_entry(resource, resource_list, list) { 3831 if (!resource->size_valid) 3832 return -EINVAL; 3833 err = devlink_resources_validate(devlink, resource, info); 3834 if (err) 3835 return err; 3836 } 3837 return err; 3838} 3839 3840static const struct devlink_param devlink_param_generic[] = { 3841 { 3842 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET, 3843 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME, 3844 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE, 3845 }, 3846 { 3847 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS, 3848 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME, 3849 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE, 3850 }, 3851 { 3852 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, 3853 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME, 3854 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE, 3855 }, 3856 { 3857 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT, 3858 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME, 3859 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE, 3860 }, 3861 { 3862 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, 3863 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME, 3864 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE, 3865 }, 3866 { 3867 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX, 3868 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME, 3869 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE, 3870 }, 3871 { 3872 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN, 3873 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME, 3874 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE, 3875 }, 3876 { 3877 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY, 3878 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME, 3879 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE, 3880 }, 3881 { 3882 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE, 3883 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME, 3884 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE, 3885 }, 3886 { 3887 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, 3888 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME, 3889 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE, 3890 }, 3891 { 3892 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET, 3893 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME, 3894 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE, 3895 }, 3896 { 3897 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH, 3898 .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME, 3899 .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE, 3900 }, 3901 { 3902 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA, 3903 .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME, 3904 .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE, 3905 }, 3906 { 3907 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET, 3908 .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME, 3909 .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE, 3910 }, 3911 { 3912 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP, 3913 .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME, 3914 .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE, 3915 }, 3916 { 3917 .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE, 3918 .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME, 3919 .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE, 3920 }, 3921 { 3922 .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE, 3923 .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME, 3924 .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE, 3925 }, 3926}; 3927 3928static int devlink_param_generic_verify(const struct devlink_param *param) 3929{ 3930 /* verify it match generic parameter by id and name */ 3931 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX) 3932 return -EINVAL; 3933 if (strcmp(param->name, devlink_param_generic[param->id].name)) 3934 return -ENOENT; 3935 3936 WARN_ON(param->type != devlink_param_generic[param->id].type); 3937 3938 return 0; 3939} 3940 3941static int devlink_param_driver_verify(const struct devlink_param *param) 3942{ 3943 int i; 3944 3945 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX) 3946 return -EINVAL; 3947 /* verify no such name in generic params */ 3948 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++) 3949 if (!strcmp(param->name, devlink_param_generic[i].name)) 3950 return -EEXIST; 3951 3952 return 0; 3953} 3954 3955static struct devlink_param_item * 3956devlink_param_find_by_name(struct xarray *params, const char *param_name) 3957{ 3958 struct devlink_param_item *param_item; 3959 unsigned long param_id; 3960 3961 xa_for_each(params, param_id, param_item) { 3962 if (!strcmp(param_item->param->name, param_name)) 3963 return param_item; 3964 } 3965 return NULL; 3966} 3967 3968static struct devlink_param_item * 3969devlink_param_find_by_id(struct xarray *params, u32 param_id) 3970{ 3971 return xa_load(params, param_id); 3972} 3973 3974static bool 3975devlink_param_cmode_is_supported(const struct devlink_param *param, 3976 enum devlink_param_cmode cmode) 3977{ 3978 return test_bit(cmode, &param->supported_cmodes); 3979} 3980 3981static int devlink_param_get(struct devlink *devlink, 3982 const struct devlink_param *param, 3983 struct devlink_param_gset_ctx *ctx) 3984{ 3985 if (!param->get || devlink->reload_failed) 3986 return -EOPNOTSUPP; 3987 return param->get(devlink, param->id, ctx); 3988} 3989 3990static int devlink_param_set(struct devlink *devlink, 3991 const struct devlink_param *param, 3992 struct devlink_param_gset_ctx *ctx) 3993{ 3994 if (!param->set || devlink->reload_failed) 3995 return -EOPNOTSUPP; 3996 return param->set(devlink, param->id, ctx); 3997} 3998 3999static int 4000devlink_param_type_to_nla_type(enum devlink_param_type param_type) 4001{ 4002 switch (param_type) { 4003 case DEVLINK_PARAM_TYPE_U8: 4004 return NLA_U8; 4005 case DEVLINK_PARAM_TYPE_U16: 4006 return NLA_U16; 4007 case DEVLINK_PARAM_TYPE_U32: 4008 return NLA_U32; 4009 case DEVLINK_PARAM_TYPE_STRING: 4010 return NLA_STRING; 4011 case DEVLINK_PARAM_TYPE_BOOL: 4012 return NLA_FLAG; 4013 default: 4014 return -EINVAL; 4015 } 4016} 4017 4018static int 4019devlink_nl_param_value_fill_one(struct sk_buff *msg, 4020 enum devlink_param_type type, 4021 enum devlink_param_cmode cmode, 4022 union devlink_param_value val) 4023{ 4024 struct nlattr *param_value_attr; 4025 4026 param_value_attr = nla_nest_start_noflag(msg, 4027 DEVLINK_ATTR_PARAM_VALUE); 4028 if (!param_value_attr) 4029 goto nla_put_failure; 4030 4031 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode)) 4032 goto value_nest_cancel; 4033 4034 switch (type) { 4035 case DEVLINK_PARAM_TYPE_U8: 4036 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8)) 4037 goto value_nest_cancel; 4038 break; 4039 case DEVLINK_PARAM_TYPE_U16: 4040 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16)) 4041 goto value_nest_cancel; 4042 break; 4043 case DEVLINK_PARAM_TYPE_U32: 4044 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32)) 4045 goto value_nest_cancel; 4046 break; 4047 case DEVLINK_PARAM_TYPE_STRING: 4048 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, 4049 val.vstr)) 4050 goto value_nest_cancel; 4051 break; 4052 case DEVLINK_PARAM_TYPE_BOOL: 4053 if (val.vbool && 4054 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA)) 4055 goto value_nest_cancel; 4056 break; 4057 } 4058 4059 nla_nest_end(msg, param_value_attr); 4060 return 0; 4061 4062value_nest_cancel: 4063 nla_nest_cancel(msg, param_value_attr); 4064nla_put_failure: 4065 return -EMSGSIZE; 4066} 4067 4068static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, 4069 unsigned int port_index, 4070 struct devlink_param_item *param_item, 4071 enum devlink_command cmd, 4072 u32 portid, u32 seq, int flags) 4073{ 4074 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1]; 4075 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; 4076 const struct devlink_param *param = param_item->param; 4077 struct devlink_param_gset_ctx ctx; 4078 struct nlattr *param_values_list; 4079 struct nlattr *param_attr; 4080 int nla_type; 4081 void *hdr; 4082 int err; 4083 int i; 4084 4085 /* Get value from driver part to driverinit configuration mode */ 4086 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 4087 if (!devlink_param_cmode_is_supported(param, i)) 4088 continue; 4089 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) { 4090 if (param_item->driverinit_value_new_valid) 4091 param_value[i] = param_item->driverinit_value_new; 4092 else if (param_item->driverinit_value_valid) 4093 param_value[i] = param_item->driverinit_value; 4094 else 4095 return -EOPNOTSUPP; 4096 } else { 4097 ctx.cmode = i; 4098 err = devlink_param_get(devlink, param, &ctx); 4099 if (err) 4100 return err; 4101 param_value[i] = ctx.val; 4102 } 4103 param_value_set[i] = true; 4104 } 4105 4106 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 4107 if (!hdr) 4108 return -EMSGSIZE; 4109 4110 if (devlink_nl_put_handle(msg, devlink)) 4111 goto genlmsg_cancel; 4112 4113 if (cmd == DEVLINK_CMD_PORT_PARAM_GET || 4114 cmd == DEVLINK_CMD_PORT_PARAM_NEW || 4115 cmd == DEVLINK_CMD_PORT_PARAM_DEL) 4116 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index)) 4117 goto genlmsg_cancel; 4118 4119 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM); 4120 if (!param_attr) 4121 goto genlmsg_cancel; 4122 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name)) 4123 goto param_nest_cancel; 4124 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC)) 4125 goto param_nest_cancel; 4126 4127 nla_type = devlink_param_type_to_nla_type(param->type); 4128 if (nla_type < 0) 4129 goto param_nest_cancel; 4130 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type)) 4131 goto param_nest_cancel; 4132 4133 param_values_list = nla_nest_start_noflag(msg, 4134 DEVLINK_ATTR_PARAM_VALUES_LIST); 4135 if (!param_values_list) 4136 goto param_nest_cancel; 4137 4138 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 4139 if (!param_value_set[i]) 4140 continue; 4141 err = devlink_nl_param_value_fill_one(msg, param->type, 4142 i, param_value[i]); 4143 if (err) 4144 goto values_list_nest_cancel; 4145 } 4146 4147 nla_nest_end(msg, param_values_list); 4148 nla_nest_end(msg, param_attr); 4149 genlmsg_end(msg, hdr); 4150 return 0; 4151 4152values_list_nest_cancel: 4153 nla_nest_end(msg, param_values_list); 4154param_nest_cancel: 4155 nla_nest_cancel(msg, param_attr); 4156genlmsg_cancel: 4157 genlmsg_cancel(msg, hdr); 4158 return -EMSGSIZE; 4159} 4160 4161static void devlink_param_notify(struct devlink *devlink, 4162 unsigned int port_index, 4163 struct devlink_param_item *param_item, 4164 enum devlink_command cmd) 4165{ 4166 struct sk_buff *msg; 4167 int err; 4168 4169 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL && 4170 cmd != DEVLINK_CMD_PORT_PARAM_NEW && 4171 cmd != DEVLINK_CMD_PORT_PARAM_DEL); 4172 4173 /* devlink_notify_register() / devlink_notify_unregister() 4174 * will replay the notifications if the params are added/removed 4175 * outside of the lifetime of the instance. 4176 */ 4177 if (!devl_is_registered(devlink)) 4178 return; 4179 4180 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4181 if (!msg) 4182 return; 4183 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd, 4184 0, 0, 0); 4185 if (err) { 4186 nlmsg_free(msg); 4187 return; 4188 } 4189 4190 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 4191 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 4192} 4193 4194static int 4195devlink_nl_cmd_param_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 4196 struct netlink_callback *cb) 4197{ 4198 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 4199 struct devlink_param_item *param_item; 4200 unsigned long param_id; 4201 int err = 0; 4202 4203 xa_for_each_start(&devlink->params, param_id, param_item, state->idx) { 4204 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 4205 DEVLINK_CMD_PARAM_GET, 4206 NETLINK_CB(cb->skb).portid, 4207 cb->nlh->nlmsg_seq, 4208 NLM_F_MULTI); 4209 if (err == -EOPNOTSUPP) { 4210 err = 0; 4211 } else if (err) { 4212 state->idx = param_id; 4213 break; 4214 } 4215 } 4216 4217 return err; 4218} 4219 4220const struct devlink_cmd devl_cmd_param_get = { 4221 .dump_one = devlink_nl_cmd_param_get_dump_one, 4222}; 4223 4224static int 4225devlink_param_type_get_from_info(struct genl_info *info, 4226 enum devlink_param_type *param_type) 4227{ 4228 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE)) 4229 return -EINVAL; 4230 4231 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) { 4232 case NLA_U8: 4233 *param_type = DEVLINK_PARAM_TYPE_U8; 4234 break; 4235 case NLA_U16: 4236 *param_type = DEVLINK_PARAM_TYPE_U16; 4237 break; 4238 case NLA_U32: 4239 *param_type = DEVLINK_PARAM_TYPE_U32; 4240 break; 4241 case NLA_STRING: 4242 *param_type = DEVLINK_PARAM_TYPE_STRING; 4243 break; 4244 case NLA_FLAG: 4245 *param_type = DEVLINK_PARAM_TYPE_BOOL; 4246 break; 4247 default: 4248 return -EINVAL; 4249 } 4250 4251 return 0; 4252} 4253 4254static int 4255devlink_param_value_get_from_info(const struct devlink_param *param, 4256 struct genl_info *info, 4257 union devlink_param_value *value) 4258{ 4259 struct nlattr *param_data; 4260 int len; 4261 4262 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]; 4263 4264 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data) 4265 return -EINVAL; 4266 4267 switch (param->type) { 4268 case DEVLINK_PARAM_TYPE_U8: 4269 if (nla_len(param_data) != sizeof(u8)) 4270 return -EINVAL; 4271 value->vu8 = nla_get_u8(param_data); 4272 break; 4273 case DEVLINK_PARAM_TYPE_U16: 4274 if (nla_len(param_data) != sizeof(u16)) 4275 return -EINVAL; 4276 value->vu16 = nla_get_u16(param_data); 4277 break; 4278 case DEVLINK_PARAM_TYPE_U32: 4279 if (nla_len(param_data) != sizeof(u32)) 4280 return -EINVAL; 4281 value->vu32 = nla_get_u32(param_data); 4282 break; 4283 case DEVLINK_PARAM_TYPE_STRING: 4284 len = strnlen(nla_data(param_data), nla_len(param_data)); 4285 if (len == nla_len(param_data) || 4286 len >= __DEVLINK_PARAM_MAX_STRING_VALUE) 4287 return -EINVAL; 4288 strcpy(value->vstr, nla_data(param_data)); 4289 break; 4290 case DEVLINK_PARAM_TYPE_BOOL: 4291 if (param_data && nla_len(param_data)) 4292 return -EINVAL; 4293 value->vbool = nla_get_flag(param_data); 4294 break; 4295 } 4296 return 0; 4297} 4298 4299static struct devlink_param_item * 4300devlink_param_get_from_info(struct xarray *params, struct genl_info *info) 4301{ 4302 char *param_name; 4303 4304 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME)) 4305 return NULL; 4306 4307 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]); 4308 return devlink_param_find_by_name(params, param_name); 4309} 4310 4311static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb, 4312 struct genl_info *info) 4313{ 4314 struct devlink *devlink = info->user_ptr[0]; 4315 struct devlink_param_item *param_item; 4316 struct sk_buff *msg; 4317 int err; 4318 4319 param_item = devlink_param_get_from_info(&devlink->params, info); 4320 if (!param_item) 4321 return -EINVAL; 4322 4323 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4324 if (!msg) 4325 return -ENOMEM; 4326 4327 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 4328 DEVLINK_CMD_PARAM_GET, 4329 info->snd_portid, info->snd_seq, 0); 4330 if (err) { 4331 nlmsg_free(msg); 4332 return err; 4333 } 4334 4335 return genlmsg_reply(msg, info); 4336} 4337 4338static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, 4339 unsigned int port_index, 4340 struct xarray *params, 4341 struct genl_info *info, 4342 enum devlink_command cmd) 4343{ 4344 enum devlink_param_type param_type; 4345 struct devlink_param_gset_ctx ctx; 4346 enum devlink_param_cmode cmode; 4347 struct devlink_param_item *param_item; 4348 const struct devlink_param *param; 4349 union devlink_param_value value; 4350 int err = 0; 4351 4352 param_item = devlink_param_get_from_info(params, info); 4353 if (!param_item) 4354 return -EINVAL; 4355 param = param_item->param; 4356 err = devlink_param_type_get_from_info(info, &param_type); 4357 if (err) 4358 return err; 4359 if (param_type != param->type) 4360 return -EINVAL; 4361 err = devlink_param_value_get_from_info(param, info, &value); 4362 if (err) 4363 return err; 4364 if (param->validate) { 4365 err = param->validate(devlink, param->id, value, info->extack); 4366 if (err) 4367 return err; 4368 } 4369 4370 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE)) 4371 return -EINVAL; 4372 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]); 4373 if (!devlink_param_cmode_is_supported(param, cmode)) 4374 return -EOPNOTSUPP; 4375 4376 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { 4377 param_item->driverinit_value_new = value; 4378 param_item->driverinit_value_new_valid = true; 4379 } else { 4380 if (!param->set) 4381 return -EOPNOTSUPP; 4382 ctx.val = value; 4383 ctx.cmode = cmode; 4384 err = devlink_param_set(devlink, param, &ctx); 4385 if (err) 4386 return err; 4387 } 4388 4389 devlink_param_notify(devlink, port_index, param_item, cmd); 4390 return 0; 4391} 4392 4393static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb, 4394 struct genl_info *info) 4395{ 4396 struct devlink *devlink = info->user_ptr[0]; 4397 4398 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->params, 4399 info, DEVLINK_CMD_PARAM_NEW); 4400} 4401 4402static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg, 4403 struct netlink_callback *cb) 4404{ 4405 NL_SET_ERR_MSG(cb->extack, "Port params are not supported"); 4406 return msg->len; 4407} 4408 4409static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb, 4410 struct genl_info *info) 4411{ 4412 NL_SET_ERR_MSG(info->extack, "Port params are not supported"); 4413 return -EINVAL; 4414} 4415 4416static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb, 4417 struct genl_info *info) 4418{ 4419 NL_SET_ERR_MSG(info->extack, "Port params are not supported"); 4420 return -EINVAL; 4421} 4422 4423static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg, 4424 struct devlink *devlink, 4425 struct devlink_snapshot *snapshot) 4426{ 4427 struct nlattr *snap_attr; 4428 int err; 4429 4430 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT); 4431 if (!snap_attr) 4432 return -EINVAL; 4433 4434 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id); 4435 if (err) 4436 goto nla_put_failure; 4437 4438 nla_nest_end(msg, snap_attr); 4439 return 0; 4440 4441nla_put_failure: 4442 nla_nest_cancel(msg, snap_attr); 4443 return err; 4444} 4445 4446static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg, 4447 struct devlink *devlink, 4448 struct devlink_region *region) 4449{ 4450 struct devlink_snapshot *snapshot; 4451 struct nlattr *snapshots_attr; 4452 int err; 4453 4454 snapshots_attr = nla_nest_start_noflag(msg, 4455 DEVLINK_ATTR_REGION_SNAPSHOTS); 4456 if (!snapshots_attr) 4457 return -EINVAL; 4458 4459 list_for_each_entry(snapshot, &region->snapshot_list, list) { 4460 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot); 4461 if (err) 4462 goto nla_put_failure; 4463 } 4464 4465 nla_nest_end(msg, snapshots_attr); 4466 return 0; 4467 4468nla_put_failure: 4469 nla_nest_cancel(msg, snapshots_attr); 4470 return err; 4471} 4472 4473static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink, 4474 enum devlink_command cmd, u32 portid, 4475 u32 seq, int flags, 4476 struct devlink_region *region) 4477{ 4478 void *hdr; 4479 int err; 4480 4481 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 4482 if (!hdr) 4483 return -EMSGSIZE; 4484 4485 err = devlink_nl_put_handle(msg, devlink); 4486 if (err) 4487 goto nla_put_failure; 4488 4489 if (region->port) { 4490 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 4491 region->port->index); 4492 if (err) 4493 goto nla_put_failure; 4494 } 4495 4496 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name); 4497 if (err) 4498 goto nla_put_failure; 4499 4500 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 4501 region->size, 4502 DEVLINK_ATTR_PAD); 4503 if (err) 4504 goto nla_put_failure; 4505 4506 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS, 4507 region->max_snapshots); 4508 if (err) 4509 goto nla_put_failure; 4510 4511 err = devlink_nl_region_snapshots_id_put(msg, devlink, region); 4512 if (err) 4513 goto nla_put_failure; 4514 4515 genlmsg_end(msg, hdr); 4516 return 0; 4517 4518nla_put_failure: 4519 genlmsg_cancel(msg, hdr); 4520 return err; 4521} 4522 4523static struct sk_buff * 4524devlink_nl_region_notify_build(struct devlink_region *region, 4525 struct devlink_snapshot *snapshot, 4526 enum devlink_command cmd, u32 portid, u32 seq) 4527{ 4528 struct devlink *devlink = region->devlink; 4529 struct sk_buff *msg; 4530 void *hdr; 4531 int err; 4532 4533 4534 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4535 if (!msg) 4536 return ERR_PTR(-ENOMEM); 4537 4538 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd); 4539 if (!hdr) { 4540 err = -EMSGSIZE; 4541 goto out_free_msg; 4542 } 4543 4544 err = devlink_nl_put_handle(msg, devlink); 4545 if (err) 4546 goto out_cancel_msg; 4547 4548 if (region->port) { 4549 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 4550 region->port->index); 4551 if (err) 4552 goto out_cancel_msg; 4553 } 4554 4555 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, 4556 region->ops->name); 4557 if (err) 4558 goto out_cancel_msg; 4559 4560 if (snapshot) { 4561 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, 4562 snapshot->id); 4563 if (err) 4564 goto out_cancel_msg; 4565 } else { 4566 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 4567 region->size, DEVLINK_ATTR_PAD); 4568 if (err) 4569 goto out_cancel_msg; 4570 } 4571 genlmsg_end(msg, hdr); 4572 4573 return msg; 4574 4575out_cancel_msg: 4576 genlmsg_cancel(msg, hdr); 4577out_free_msg: 4578 nlmsg_free(msg); 4579 return ERR_PTR(err); 4580} 4581 4582static void devlink_nl_region_notify(struct devlink_region *region, 4583 struct devlink_snapshot *snapshot, 4584 enum devlink_command cmd) 4585{ 4586 struct devlink *devlink = region->devlink; 4587 struct sk_buff *msg; 4588 4589 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL); 4590 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 4591 return; 4592 4593 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0); 4594 if (IS_ERR(msg)) 4595 return; 4596 4597 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, 4598 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 4599} 4600 4601/** 4602 * __devlink_snapshot_id_increment - Increment number of snapshots using an id 4603 * @devlink: devlink instance 4604 * @id: the snapshot id 4605 * 4606 * Track when a new snapshot begins using an id. Load the count for the 4607 * given id from the snapshot xarray, increment it, and store it back. 4608 * 4609 * Called when a new snapshot is created with the given id. 4610 * 4611 * The id *must* have been previously allocated by 4612 * devlink_region_snapshot_id_get(). 4613 * 4614 * Returns 0 on success, or an error on failure. 4615 */ 4616static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id) 4617{ 4618 unsigned long count; 4619 void *p; 4620 int err; 4621 4622 xa_lock(&devlink->snapshot_ids); 4623 p = xa_load(&devlink->snapshot_ids, id); 4624 if (WARN_ON(!p)) { 4625 err = -EINVAL; 4626 goto unlock; 4627 } 4628 4629 if (WARN_ON(!xa_is_value(p))) { 4630 err = -EINVAL; 4631 goto unlock; 4632 } 4633 4634 count = xa_to_value(p); 4635 count++; 4636 4637 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 4638 GFP_ATOMIC)); 4639unlock: 4640 xa_unlock(&devlink->snapshot_ids); 4641 return err; 4642} 4643 4644/** 4645 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id 4646 * @devlink: devlink instance 4647 * @id: the snapshot id 4648 * 4649 * Track when a snapshot is deleted and stops using an id. Load the count 4650 * for the given id from the snapshot xarray, decrement it, and store it 4651 * back. 4652 * 4653 * If the count reaches zero, erase this id from the xarray, freeing it 4654 * up for future re-use by devlink_region_snapshot_id_get(). 4655 * 4656 * Called when a snapshot using the given id is deleted, and when the 4657 * initial allocator of the id is finished using it. 4658 */ 4659static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id) 4660{ 4661 unsigned long count; 4662 void *p; 4663 4664 xa_lock(&devlink->snapshot_ids); 4665 p = xa_load(&devlink->snapshot_ids, id); 4666 if (WARN_ON(!p)) 4667 goto unlock; 4668 4669 if (WARN_ON(!xa_is_value(p))) 4670 goto unlock; 4671 4672 count = xa_to_value(p); 4673 4674 if (count > 1) { 4675 count--; 4676 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 4677 GFP_ATOMIC); 4678 } else { 4679 /* If this was the last user, we can erase this id */ 4680 __xa_erase(&devlink->snapshot_ids, id); 4681 } 4682unlock: 4683 xa_unlock(&devlink->snapshot_ids); 4684} 4685 4686/** 4687 * __devlink_snapshot_id_insert - Insert a specific snapshot ID 4688 * @devlink: devlink instance 4689 * @id: the snapshot id 4690 * 4691 * Mark the given snapshot id as used by inserting a zero value into the 4692 * snapshot xarray. 4693 * 4694 * This must be called while holding the devlink instance lock. Unlike 4695 * devlink_snapshot_id_get, the initial reference count is zero, not one. 4696 * It is expected that the id will immediately be used before 4697 * releasing the devlink instance lock. 4698 * 4699 * Returns zero on success, or an error code if the snapshot id could not 4700 * be inserted. 4701 */ 4702static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id) 4703{ 4704 int err; 4705 4706 xa_lock(&devlink->snapshot_ids); 4707 if (xa_load(&devlink->snapshot_ids, id)) { 4708 xa_unlock(&devlink->snapshot_ids); 4709 return -EEXIST; 4710 } 4711 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0), 4712 GFP_ATOMIC)); 4713 xa_unlock(&devlink->snapshot_ids); 4714 return err; 4715} 4716 4717/** 4718 * __devlink_region_snapshot_id_get - get snapshot ID 4719 * @devlink: devlink instance 4720 * @id: storage to return snapshot id 4721 * 4722 * Allocates a new snapshot id. Returns zero on success, or a negative 4723 * error on failure. Must be called while holding the devlink instance 4724 * lock. 4725 * 4726 * Snapshot IDs are tracked using an xarray which stores the number of 4727 * users of the snapshot id. 4728 * 4729 * Note that the caller of this function counts as a 'user', in order to 4730 * avoid race conditions. The caller must release its hold on the 4731 * snapshot by using devlink_region_snapshot_id_put. 4732 */ 4733static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 4734{ 4735 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1), 4736 xa_limit_32b, GFP_KERNEL); 4737} 4738 4739/** 4740 * __devlink_region_snapshot_create - create a new snapshot 4741 * This will add a new snapshot of a region. The snapshot 4742 * will be stored on the region struct and can be accessed 4743 * from devlink. This is useful for future analyses of snapshots. 4744 * Multiple snapshots can be created on a region. 4745 * The @snapshot_id should be obtained using the getter function. 4746 * 4747 * Must be called only while holding the region snapshot lock. 4748 * 4749 * @region: devlink region of the snapshot 4750 * @data: snapshot data 4751 * @snapshot_id: snapshot id to be created 4752 */ 4753static int 4754__devlink_region_snapshot_create(struct devlink_region *region, 4755 u8 *data, u32 snapshot_id) 4756{ 4757 struct devlink *devlink = region->devlink; 4758 struct devlink_snapshot *snapshot; 4759 int err; 4760 4761 lockdep_assert_held(&region->snapshot_lock); 4762 4763 /* check if region can hold one more snapshot */ 4764 if (region->cur_snapshots == region->max_snapshots) 4765 return -ENOSPC; 4766 4767 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) 4768 return -EEXIST; 4769 4770 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL); 4771 if (!snapshot) 4772 return -ENOMEM; 4773 4774 err = __devlink_snapshot_id_increment(devlink, snapshot_id); 4775 if (err) 4776 goto err_snapshot_id_increment; 4777 4778 snapshot->id = snapshot_id; 4779 snapshot->region = region; 4780 snapshot->data = data; 4781 4782 list_add_tail(&snapshot->list, &region->snapshot_list); 4783 4784 region->cur_snapshots++; 4785 4786 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW); 4787 return 0; 4788 4789err_snapshot_id_increment: 4790 kfree(snapshot); 4791 return err; 4792} 4793 4794static void devlink_region_snapshot_del(struct devlink_region *region, 4795 struct devlink_snapshot *snapshot) 4796{ 4797 struct devlink *devlink = region->devlink; 4798 4799 lockdep_assert_held(&region->snapshot_lock); 4800 4801 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL); 4802 region->cur_snapshots--; 4803 list_del(&snapshot->list); 4804 region->ops->destructor(snapshot->data); 4805 __devlink_snapshot_id_decrement(devlink, snapshot->id); 4806 kfree(snapshot); 4807} 4808 4809static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb, 4810 struct genl_info *info) 4811{ 4812 struct devlink *devlink = info->user_ptr[0]; 4813 struct devlink_port *port = NULL; 4814 struct devlink_region *region; 4815 const char *region_name; 4816 struct sk_buff *msg; 4817 unsigned int index; 4818 int err; 4819 4820 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) 4821 return -EINVAL; 4822 4823 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4824 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4825 4826 port = devlink_port_get_by_index(devlink, index); 4827 if (!port) 4828 return -ENODEV; 4829 } 4830 4831 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4832 if (port) 4833 region = devlink_port_region_get_by_name(port, region_name); 4834 else 4835 region = devlink_region_get_by_name(devlink, region_name); 4836 4837 if (!region) 4838 return -EINVAL; 4839 4840 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4841 if (!msg) 4842 return -ENOMEM; 4843 4844 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET, 4845 info->snd_portid, info->snd_seq, 0, 4846 region); 4847 if (err) { 4848 nlmsg_free(msg); 4849 return err; 4850 } 4851 4852 return genlmsg_reply(msg, info); 4853} 4854 4855static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg, 4856 struct netlink_callback *cb, 4857 struct devlink_port *port, 4858 int *idx, 4859 int start) 4860{ 4861 struct devlink_region *region; 4862 int err = 0; 4863 4864 list_for_each_entry(region, &port->region_list, list) { 4865 if (*idx < start) { 4866 (*idx)++; 4867 continue; 4868 } 4869 err = devlink_nl_region_fill(msg, port->devlink, 4870 DEVLINK_CMD_REGION_GET, 4871 NETLINK_CB(cb->skb).portid, 4872 cb->nlh->nlmsg_seq, 4873 NLM_F_MULTI, region); 4874 if (err) 4875 goto out; 4876 (*idx)++; 4877 } 4878 4879out: 4880 return err; 4881} 4882 4883static int 4884devlink_nl_cmd_region_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 4885 struct netlink_callback *cb) 4886{ 4887 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 4888 struct devlink_region *region; 4889 struct devlink_port *port; 4890 unsigned long port_index; 4891 int idx = 0; 4892 int err; 4893 4894 list_for_each_entry(region, &devlink->region_list, list) { 4895 if (idx < state->idx) { 4896 idx++; 4897 continue; 4898 } 4899 err = devlink_nl_region_fill(msg, devlink, 4900 DEVLINK_CMD_REGION_GET, 4901 NETLINK_CB(cb->skb).portid, 4902 cb->nlh->nlmsg_seq, 4903 NLM_F_MULTI, region); 4904 if (err) { 4905 state->idx = idx; 4906 return err; 4907 } 4908 idx++; 4909 } 4910 4911 xa_for_each(&devlink->ports, port_index, port) { 4912 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx, 4913 state->idx); 4914 if (err) { 4915 state->idx = idx; 4916 return err; 4917 } 4918 } 4919 4920 return 0; 4921} 4922 4923const struct devlink_cmd devl_cmd_region_get = { 4924 .dump_one = devlink_nl_cmd_region_get_dump_one, 4925}; 4926 4927static int devlink_nl_cmd_region_del(struct sk_buff *skb, 4928 struct genl_info *info) 4929{ 4930 struct devlink *devlink = info->user_ptr[0]; 4931 struct devlink_snapshot *snapshot; 4932 struct devlink_port *port = NULL; 4933 struct devlink_region *region; 4934 const char *region_name; 4935 unsigned int index; 4936 u32 snapshot_id; 4937 4938 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) || 4939 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID)) 4940 return -EINVAL; 4941 4942 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4943 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); 4944 4945 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4946 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4947 4948 port = devlink_port_get_by_index(devlink, index); 4949 if (!port) 4950 return -ENODEV; 4951 } 4952 4953 if (port) 4954 region = devlink_port_region_get_by_name(port, region_name); 4955 else 4956 region = devlink_region_get_by_name(devlink, region_name); 4957 4958 if (!region) 4959 return -EINVAL; 4960 4961 mutex_lock(&region->snapshot_lock); 4962 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 4963 if (!snapshot) { 4964 mutex_unlock(&region->snapshot_lock); 4965 return -EINVAL; 4966 } 4967 4968 devlink_region_snapshot_del(region, snapshot); 4969 mutex_unlock(&region->snapshot_lock); 4970 return 0; 4971} 4972 4973static int 4974devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) 4975{ 4976 struct devlink *devlink = info->user_ptr[0]; 4977 struct devlink_snapshot *snapshot; 4978 struct devlink_port *port = NULL; 4979 struct nlattr *snapshot_id_attr; 4980 struct devlink_region *region; 4981 const char *region_name; 4982 unsigned int index; 4983 u32 snapshot_id; 4984 u8 *data; 4985 int err; 4986 4987 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) { 4988 NL_SET_ERR_MSG(info->extack, "No region name provided"); 4989 return -EINVAL; 4990 } 4991 4992 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4993 4994 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4995 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4996 4997 port = devlink_port_get_by_index(devlink, index); 4998 if (!port) 4999 return -ENODEV; 5000 } 5001 5002 if (port) 5003 region = devlink_port_region_get_by_name(port, region_name); 5004 else 5005 region = devlink_region_get_by_name(devlink, region_name); 5006 5007 if (!region) { 5008 NL_SET_ERR_MSG(info->extack, "The requested region does not exist"); 5009 return -EINVAL; 5010 } 5011 5012 if (!region->ops->snapshot) { 5013 NL_SET_ERR_MSG(info->extack, "The requested region does not support taking an immediate snapshot"); 5014 return -EOPNOTSUPP; 5015 } 5016 5017 mutex_lock(&region->snapshot_lock); 5018 5019 if (region->cur_snapshots == region->max_snapshots) { 5020 NL_SET_ERR_MSG(info->extack, "The region has reached the maximum number of stored snapshots"); 5021 err = -ENOSPC; 5022 goto unlock; 5023 } 5024 5025 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; 5026 if (snapshot_id_attr) { 5027 snapshot_id = nla_get_u32(snapshot_id_attr); 5028 5029 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { 5030 NL_SET_ERR_MSG(info->extack, "The requested snapshot id is already in use"); 5031 err = -EEXIST; 5032 goto unlock; 5033 } 5034 5035 err = __devlink_snapshot_id_insert(devlink, snapshot_id); 5036 if (err) 5037 goto unlock; 5038 } else { 5039 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id); 5040 if (err) { 5041 NL_SET_ERR_MSG(info->extack, "Failed to allocate a new snapshot id"); 5042 goto unlock; 5043 } 5044 } 5045 5046 if (port) 5047 err = region->port_ops->snapshot(port, region->port_ops, 5048 info->extack, &data); 5049 else 5050 err = region->ops->snapshot(devlink, region->ops, 5051 info->extack, &data); 5052 if (err) 5053 goto err_snapshot_capture; 5054 5055 err = __devlink_region_snapshot_create(region, data, snapshot_id); 5056 if (err) 5057 goto err_snapshot_create; 5058 5059 if (!snapshot_id_attr) { 5060 struct sk_buff *msg; 5061 5062 snapshot = devlink_region_snapshot_get_by_id(region, 5063 snapshot_id); 5064 if (WARN_ON(!snapshot)) { 5065 err = -EINVAL; 5066 goto unlock; 5067 } 5068 5069 msg = devlink_nl_region_notify_build(region, snapshot, 5070 DEVLINK_CMD_REGION_NEW, 5071 info->snd_portid, 5072 info->snd_seq); 5073 err = PTR_ERR_OR_ZERO(msg); 5074 if (err) 5075 goto err_notify; 5076 5077 err = genlmsg_reply(msg, info); 5078 if (err) 5079 goto err_notify; 5080 } 5081 5082 mutex_unlock(&region->snapshot_lock); 5083 return 0; 5084 5085err_snapshot_create: 5086 region->ops->destructor(data); 5087err_snapshot_capture: 5088 __devlink_snapshot_id_decrement(devlink, snapshot_id); 5089 mutex_unlock(&region->snapshot_lock); 5090 return err; 5091 5092err_notify: 5093 devlink_region_snapshot_del(region, snapshot); 5094unlock: 5095 mutex_unlock(&region->snapshot_lock); 5096 return err; 5097} 5098 5099static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg, 5100 u8 *chunk, u32 chunk_size, 5101 u64 addr) 5102{ 5103 struct nlattr *chunk_attr; 5104 int err; 5105 5106 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK); 5107 if (!chunk_attr) 5108 return -EINVAL; 5109 5110 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk); 5111 if (err) 5112 goto nla_put_failure; 5113 5114 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr, 5115 DEVLINK_ATTR_PAD); 5116 if (err) 5117 goto nla_put_failure; 5118 5119 nla_nest_end(msg, chunk_attr); 5120 return 0; 5121 5122nla_put_failure: 5123 nla_nest_cancel(msg, chunk_attr); 5124 return err; 5125} 5126 5127#define DEVLINK_REGION_READ_CHUNK_SIZE 256 5128 5129typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size, 5130 u64 curr_offset, 5131 struct netlink_ext_ack *extack); 5132 5133static int 5134devlink_nl_region_read_fill(struct sk_buff *skb, devlink_chunk_fill_t *cb, 5135 void *cb_priv, u64 start_offset, u64 end_offset, 5136 u64 *new_offset, struct netlink_ext_ack *extack) 5137{ 5138 u64 curr_offset = start_offset; 5139 int err = 0; 5140 u8 *data; 5141 5142 /* Allocate and re-use a single buffer */ 5143 data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL); 5144 if (!data) 5145 return -ENOMEM; 5146 5147 *new_offset = start_offset; 5148 5149 while (curr_offset < end_offset) { 5150 u32 data_size; 5151 5152 data_size = min_t(u32, end_offset - curr_offset, 5153 DEVLINK_REGION_READ_CHUNK_SIZE); 5154 5155 err = cb(cb_priv, data, data_size, curr_offset, extack); 5156 if (err) 5157 break; 5158 5159 err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset); 5160 if (err) 5161 break; 5162 5163 curr_offset += data_size; 5164 } 5165 *new_offset = curr_offset; 5166 5167 kfree(data); 5168 5169 return err; 5170} 5171 5172static int 5173devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size, 5174 u64 curr_offset, 5175 struct netlink_ext_ack __always_unused *extack) 5176{ 5177 struct devlink_snapshot *snapshot = cb_priv; 5178 5179 memcpy(chunk, &snapshot->data[curr_offset], chunk_size); 5180 5181 return 0; 5182} 5183 5184static int 5185devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size, 5186 u64 curr_offset, struct netlink_ext_ack *extack) 5187{ 5188 struct devlink_region *region = cb_priv; 5189 5190 return region->port_ops->read(region->port, region->port_ops, extack, 5191 curr_offset, chunk_size, chunk); 5192} 5193 5194static int 5195devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size, 5196 u64 curr_offset, struct netlink_ext_ack *extack) 5197{ 5198 struct devlink_region *region = cb_priv; 5199 5200 return region->ops->read(region->devlink, region->ops, extack, 5201 curr_offset, chunk_size, chunk); 5202} 5203 5204static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, 5205 struct netlink_callback *cb) 5206{ 5207 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 5208 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 5209 struct nlattr *chunks_attr, *region_attr, *snapshot_attr; 5210 u64 ret_offset, start_offset, end_offset = U64_MAX; 5211 struct nlattr **attrs = info->attrs; 5212 struct devlink_port *port = NULL; 5213 devlink_chunk_fill_t *region_cb; 5214 struct devlink_region *region; 5215 const char *region_name; 5216 struct devlink *devlink; 5217 unsigned int index; 5218 void *region_cb_priv; 5219 void *hdr; 5220 int err; 5221 5222 start_offset = state->start_offset; 5223 5224 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs); 5225 if (IS_ERR(devlink)) 5226 return PTR_ERR(devlink); 5227 5228 if (!attrs[DEVLINK_ATTR_REGION_NAME]) { 5229 NL_SET_ERR_MSG(cb->extack, "No region name provided"); 5230 err = -EINVAL; 5231 goto out_unlock; 5232 } 5233 5234 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 5235 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 5236 5237 port = devlink_port_get_by_index(devlink, index); 5238 if (!port) { 5239 err = -ENODEV; 5240 goto out_unlock; 5241 } 5242 } 5243 5244 region_attr = attrs[DEVLINK_ATTR_REGION_NAME]; 5245 region_name = nla_data(region_attr); 5246 5247 if (port) 5248 region = devlink_port_region_get_by_name(port, region_name); 5249 else 5250 region = devlink_region_get_by_name(devlink, region_name); 5251 5252 if (!region) { 5253 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist"); 5254 err = -EINVAL; 5255 goto out_unlock; 5256 } 5257 5258 snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; 5259 if (!snapshot_attr) { 5260 if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) { 5261 NL_SET_ERR_MSG(cb->extack, "No snapshot id provided"); 5262 err = -EINVAL; 5263 goto out_unlock; 5264 } 5265 5266 if (!region->ops->read) { 5267 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read"); 5268 err = -EOPNOTSUPP; 5269 goto out_unlock; 5270 } 5271 5272 if (port) 5273 region_cb = &devlink_region_port_direct_fill; 5274 else 5275 region_cb = &devlink_region_direct_fill; 5276 region_cb_priv = region; 5277 } else { 5278 struct devlink_snapshot *snapshot; 5279 u32 snapshot_id; 5280 5281 if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) { 5282 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot"); 5283 err = -EINVAL; 5284 goto out_unlock; 5285 } 5286 5287 snapshot_id = nla_get_u32(snapshot_attr); 5288 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 5289 if (!snapshot) { 5290 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist"); 5291 err = -EINVAL; 5292 goto out_unlock; 5293 } 5294 region_cb = &devlink_region_snapshot_fill; 5295 region_cb_priv = snapshot; 5296 } 5297 5298 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] && 5299 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) { 5300 if (!start_offset) 5301 start_offset = 5302 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 5303 5304 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 5305 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); 5306 } 5307 5308 if (end_offset > region->size) 5309 end_offset = region->size; 5310 5311 /* return 0 if there is no further data to read */ 5312 if (start_offset == end_offset) { 5313 err = 0; 5314 goto out_unlock; 5315 } 5316 5317 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 5318 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, 5319 DEVLINK_CMD_REGION_READ); 5320 if (!hdr) { 5321 err = -EMSGSIZE; 5322 goto out_unlock; 5323 } 5324 5325 err = devlink_nl_put_handle(skb, devlink); 5326 if (err) 5327 goto nla_put_failure; 5328 5329 if (region->port) { 5330 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX, 5331 region->port->index); 5332 if (err) 5333 goto nla_put_failure; 5334 } 5335 5336 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name); 5337 if (err) 5338 goto nla_put_failure; 5339 5340 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS); 5341 if (!chunks_attr) { 5342 err = -EMSGSIZE; 5343 goto nla_put_failure; 5344 } 5345 5346 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv, 5347 start_offset, end_offset, &ret_offset, 5348 cb->extack); 5349 5350 if (err && err != -EMSGSIZE) 5351 goto nla_put_failure; 5352 5353 /* Check if there was any progress done to prevent infinite loop */ 5354 if (ret_offset == start_offset) { 5355 err = -EINVAL; 5356 goto nla_put_failure; 5357 } 5358 5359 state->start_offset = ret_offset; 5360 5361 nla_nest_end(skb, chunks_attr); 5362 genlmsg_end(skb, hdr); 5363 devl_unlock(devlink); 5364 devlink_put(devlink); 5365 return skb->len; 5366 5367nla_put_failure: 5368 genlmsg_cancel(skb, hdr); 5369out_unlock: 5370 devl_unlock(devlink); 5371 devlink_put(devlink); 5372 return err; 5373} 5374 5375struct devlink_stats { 5376 u64_stats_t rx_bytes; 5377 u64_stats_t rx_packets; 5378 struct u64_stats_sync syncp; 5379}; 5380 5381/** 5382 * struct devlink_trap_policer_item - Packet trap policer attributes. 5383 * @policer: Immutable packet trap policer attributes. 5384 * @rate: Rate in packets / sec. 5385 * @burst: Burst size in packets. 5386 * @list: trap_policer_list member. 5387 * 5388 * Describes packet trap policer attributes. Created by devlink during trap 5389 * policer registration. 5390 */ 5391struct devlink_trap_policer_item { 5392 const struct devlink_trap_policer *policer; 5393 u64 rate; 5394 u64 burst; 5395 struct list_head list; 5396}; 5397 5398/** 5399 * struct devlink_trap_group_item - Packet trap group attributes. 5400 * @group: Immutable packet trap group attributes. 5401 * @policer_item: Associated policer item. Can be NULL. 5402 * @list: trap_group_list member. 5403 * @stats: Trap group statistics. 5404 * 5405 * Describes packet trap group attributes. Created by devlink during trap 5406 * group registration. 5407 */ 5408struct devlink_trap_group_item { 5409 const struct devlink_trap_group *group; 5410 struct devlink_trap_policer_item *policer_item; 5411 struct list_head list; 5412 struct devlink_stats __percpu *stats; 5413}; 5414 5415/** 5416 * struct devlink_trap_item - Packet trap attributes. 5417 * @trap: Immutable packet trap attributes. 5418 * @group_item: Associated group item. 5419 * @list: trap_list member. 5420 * @action: Trap action. 5421 * @stats: Trap statistics. 5422 * @priv: Driver private information. 5423 * 5424 * Describes both mutable and immutable packet trap attributes. Created by 5425 * devlink during trap registration and used for all trap related operations. 5426 */ 5427struct devlink_trap_item { 5428 const struct devlink_trap *trap; 5429 struct devlink_trap_group_item *group_item; 5430 struct list_head list; 5431 enum devlink_trap_action action; 5432 struct devlink_stats __percpu *stats; 5433 void *priv; 5434}; 5435 5436static struct devlink_trap_policer_item * 5437devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id) 5438{ 5439 struct devlink_trap_policer_item *policer_item; 5440 5441 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) { 5442 if (policer_item->policer->id == id) 5443 return policer_item; 5444 } 5445 5446 return NULL; 5447} 5448 5449static struct devlink_trap_item * 5450devlink_trap_item_lookup(struct devlink *devlink, const char *name) 5451{ 5452 struct devlink_trap_item *trap_item; 5453 5454 list_for_each_entry(trap_item, &devlink->trap_list, list) { 5455 if (!strcmp(trap_item->trap->name, name)) 5456 return trap_item; 5457 } 5458 5459 return NULL; 5460} 5461 5462static struct devlink_trap_item * 5463devlink_trap_item_get_from_info(struct devlink *devlink, 5464 struct genl_info *info) 5465{ 5466 struct nlattr *attr; 5467 5468 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME]) 5469 return NULL; 5470 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME]; 5471 5472 return devlink_trap_item_lookup(devlink, nla_data(attr)); 5473} 5474 5475static int 5476devlink_trap_action_get_from_info(struct genl_info *info, 5477 enum devlink_trap_action *p_trap_action) 5478{ 5479 u8 val; 5480 5481 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]); 5482 switch (val) { 5483 case DEVLINK_TRAP_ACTION_DROP: 5484 case DEVLINK_TRAP_ACTION_TRAP: 5485 case DEVLINK_TRAP_ACTION_MIRROR: 5486 *p_trap_action = val; 5487 break; 5488 default: 5489 return -EINVAL; 5490 } 5491 5492 return 0; 5493} 5494 5495static int devlink_trap_metadata_put(struct sk_buff *msg, 5496 const struct devlink_trap *trap) 5497{ 5498 struct nlattr *attr; 5499 5500 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA); 5501 if (!attr) 5502 return -EMSGSIZE; 5503 5504 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) && 5505 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT)) 5506 goto nla_put_failure; 5507 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) && 5508 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE)) 5509 goto nla_put_failure; 5510 5511 nla_nest_end(msg, attr); 5512 5513 return 0; 5514 5515nla_put_failure: 5516 nla_nest_cancel(msg, attr); 5517 return -EMSGSIZE; 5518} 5519 5520static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats, 5521 struct devlink_stats *stats) 5522{ 5523 int i; 5524 5525 memset(stats, 0, sizeof(*stats)); 5526 for_each_possible_cpu(i) { 5527 struct devlink_stats *cpu_stats; 5528 u64 rx_packets, rx_bytes; 5529 unsigned int start; 5530 5531 cpu_stats = per_cpu_ptr(trap_stats, i); 5532 do { 5533 start = u64_stats_fetch_begin(&cpu_stats->syncp); 5534 rx_packets = u64_stats_read(&cpu_stats->rx_packets); 5535 rx_bytes = u64_stats_read(&cpu_stats->rx_bytes); 5536 } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); 5537 5538 u64_stats_add(&stats->rx_packets, rx_packets); 5539 u64_stats_add(&stats->rx_bytes, rx_bytes); 5540 } 5541} 5542 5543static int 5544devlink_trap_group_stats_put(struct sk_buff *msg, 5545 struct devlink_stats __percpu *trap_stats) 5546{ 5547 struct devlink_stats stats; 5548 struct nlattr *attr; 5549 5550 devlink_trap_stats_read(trap_stats, &stats); 5551 5552 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); 5553 if (!attr) 5554 return -EMSGSIZE; 5555 5556 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS, 5557 u64_stats_read(&stats.rx_packets), 5558 DEVLINK_ATTR_PAD)) 5559 goto nla_put_failure; 5560 5561 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES, 5562 u64_stats_read(&stats.rx_bytes), 5563 DEVLINK_ATTR_PAD)) 5564 goto nla_put_failure; 5565 5566 nla_nest_end(msg, attr); 5567 5568 return 0; 5569 5570nla_put_failure: 5571 nla_nest_cancel(msg, attr); 5572 return -EMSGSIZE; 5573} 5574 5575static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink, 5576 const struct devlink_trap_item *trap_item) 5577{ 5578 struct devlink_stats stats; 5579 struct nlattr *attr; 5580 u64 drops = 0; 5581 int err; 5582 5583 if (devlink->ops->trap_drop_counter_get) { 5584 err = devlink->ops->trap_drop_counter_get(devlink, 5585 trap_item->trap, 5586 &drops); 5587 if (err) 5588 return err; 5589 } 5590 5591 devlink_trap_stats_read(trap_item->stats, &stats); 5592 5593 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); 5594 if (!attr) 5595 return -EMSGSIZE; 5596 5597 if (devlink->ops->trap_drop_counter_get && 5598 nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops, 5599 DEVLINK_ATTR_PAD)) 5600 goto nla_put_failure; 5601 5602 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS, 5603 u64_stats_read(&stats.rx_packets), 5604 DEVLINK_ATTR_PAD)) 5605 goto nla_put_failure; 5606 5607 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES, 5608 u64_stats_read(&stats.rx_bytes), 5609 DEVLINK_ATTR_PAD)) 5610 goto nla_put_failure; 5611 5612 nla_nest_end(msg, attr); 5613 5614 return 0; 5615 5616nla_put_failure: 5617 nla_nest_cancel(msg, attr); 5618 return -EMSGSIZE; 5619} 5620 5621static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink, 5622 const struct devlink_trap_item *trap_item, 5623 enum devlink_command cmd, u32 portid, u32 seq, 5624 int flags) 5625{ 5626 struct devlink_trap_group_item *group_item = trap_item->group_item; 5627 void *hdr; 5628 int err; 5629 5630 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 5631 if (!hdr) 5632 return -EMSGSIZE; 5633 5634 if (devlink_nl_put_handle(msg, devlink)) 5635 goto nla_put_failure; 5636 5637 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, 5638 group_item->group->name)) 5639 goto nla_put_failure; 5640 5641 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name)) 5642 goto nla_put_failure; 5643 5644 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type)) 5645 goto nla_put_failure; 5646 5647 if (trap_item->trap->generic && 5648 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) 5649 goto nla_put_failure; 5650 5651 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action)) 5652 goto nla_put_failure; 5653 5654 err = devlink_trap_metadata_put(msg, trap_item->trap); 5655 if (err) 5656 goto nla_put_failure; 5657 5658 err = devlink_trap_stats_put(msg, devlink, trap_item); 5659 if (err) 5660 goto nla_put_failure; 5661 5662 genlmsg_end(msg, hdr); 5663 5664 return 0; 5665 5666nla_put_failure: 5667 genlmsg_cancel(msg, hdr); 5668 return -EMSGSIZE; 5669} 5670 5671static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb, 5672 struct genl_info *info) 5673{ 5674 struct netlink_ext_ack *extack = info->extack; 5675 struct devlink *devlink = info->user_ptr[0]; 5676 struct devlink_trap_item *trap_item; 5677 struct sk_buff *msg; 5678 int err; 5679 5680 if (list_empty(&devlink->trap_list)) 5681 return -EOPNOTSUPP; 5682 5683 trap_item = devlink_trap_item_get_from_info(devlink, info); 5684 if (!trap_item) { 5685 NL_SET_ERR_MSG(extack, "Device did not register this trap"); 5686 return -ENOENT; 5687 } 5688 5689 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 5690 if (!msg) 5691 return -ENOMEM; 5692 5693 err = devlink_nl_trap_fill(msg, devlink, trap_item, 5694 DEVLINK_CMD_TRAP_NEW, info->snd_portid, 5695 info->snd_seq, 0); 5696 if (err) 5697 goto err_trap_fill; 5698 5699 return genlmsg_reply(msg, info); 5700 5701err_trap_fill: 5702 nlmsg_free(msg); 5703 return err; 5704} 5705 5706static int 5707devlink_nl_cmd_trap_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 5708 struct netlink_callback *cb) 5709{ 5710 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 5711 struct devlink_trap_item *trap_item; 5712 int idx = 0; 5713 int err = 0; 5714 5715 list_for_each_entry(trap_item, &devlink->trap_list, list) { 5716 if (idx < state->idx) { 5717 idx++; 5718 continue; 5719 } 5720 err = devlink_nl_trap_fill(msg, devlink, trap_item, 5721 DEVLINK_CMD_TRAP_NEW, 5722 NETLINK_CB(cb->skb).portid, 5723 cb->nlh->nlmsg_seq, 5724 NLM_F_MULTI); 5725 if (err) { 5726 state->idx = idx; 5727 break; 5728 } 5729 idx++; 5730 } 5731 5732 return err; 5733} 5734 5735const struct devlink_cmd devl_cmd_trap_get = { 5736 .dump_one = devlink_nl_cmd_trap_get_dump_one, 5737}; 5738 5739static int __devlink_trap_action_set(struct devlink *devlink, 5740 struct devlink_trap_item *trap_item, 5741 enum devlink_trap_action trap_action, 5742 struct netlink_ext_ack *extack) 5743{ 5744 int err; 5745 5746 if (trap_item->action != trap_action && 5747 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) { 5748 NL_SET_ERR_MSG(extack, "Cannot change action of non-drop traps. Skipping"); 5749 return 0; 5750 } 5751 5752 err = devlink->ops->trap_action_set(devlink, trap_item->trap, 5753 trap_action, extack); 5754 if (err) 5755 return err; 5756 5757 trap_item->action = trap_action; 5758 5759 return 0; 5760} 5761 5762static int devlink_trap_action_set(struct devlink *devlink, 5763 struct devlink_trap_item *trap_item, 5764 struct genl_info *info) 5765{ 5766 enum devlink_trap_action trap_action; 5767 int err; 5768 5769 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) 5770 return 0; 5771 5772 err = devlink_trap_action_get_from_info(info, &trap_action); 5773 if (err) { 5774 NL_SET_ERR_MSG(info->extack, "Invalid trap action"); 5775 return -EINVAL; 5776 } 5777 5778 return __devlink_trap_action_set(devlink, trap_item, trap_action, 5779 info->extack); 5780} 5781 5782static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb, 5783 struct genl_info *info) 5784{ 5785 struct netlink_ext_ack *extack = info->extack; 5786 struct devlink *devlink = info->user_ptr[0]; 5787 struct devlink_trap_item *trap_item; 5788 5789 if (list_empty(&devlink->trap_list)) 5790 return -EOPNOTSUPP; 5791 5792 trap_item = devlink_trap_item_get_from_info(devlink, info); 5793 if (!trap_item) { 5794 NL_SET_ERR_MSG(extack, "Device did not register this trap"); 5795 return -ENOENT; 5796 } 5797 5798 return devlink_trap_action_set(devlink, trap_item, info); 5799} 5800 5801static struct devlink_trap_group_item * 5802devlink_trap_group_item_lookup(struct devlink *devlink, const char *name) 5803{ 5804 struct devlink_trap_group_item *group_item; 5805 5806 list_for_each_entry(group_item, &devlink->trap_group_list, list) { 5807 if (!strcmp(group_item->group->name, name)) 5808 return group_item; 5809 } 5810 5811 return NULL; 5812} 5813 5814static struct devlink_trap_group_item * 5815devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id) 5816{ 5817 struct devlink_trap_group_item *group_item; 5818 5819 list_for_each_entry(group_item, &devlink->trap_group_list, list) { 5820 if (group_item->group->id == id) 5821 return group_item; 5822 } 5823 5824 return NULL; 5825} 5826 5827static struct devlink_trap_group_item * 5828devlink_trap_group_item_get_from_info(struct devlink *devlink, 5829 struct genl_info *info) 5830{ 5831 char *name; 5832 5833 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]) 5834 return NULL; 5835 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]); 5836 5837 return devlink_trap_group_item_lookup(devlink, name); 5838} 5839 5840static int 5841devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink, 5842 const struct devlink_trap_group_item *group_item, 5843 enum devlink_command cmd, u32 portid, u32 seq, 5844 int flags) 5845{ 5846 void *hdr; 5847 int err; 5848 5849 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 5850 if (!hdr) 5851 return -EMSGSIZE; 5852 5853 if (devlink_nl_put_handle(msg, devlink)) 5854 goto nla_put_failure; 5855 5856 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, 5857 group_item->group->name)) 5858 goto nla_put_failure; 5859 5860 if (group_item->group->generic && 5861 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) 5862 goto nla_put_failure; 5863 5864 if (group_item->policer_item && 5865 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, 5866 group_item->policer_item->policer->id)) 5867 goto nla_put_failure; 5868 5869 err = devlink_trap_group_stats_put(msg, group_item->stats); 5870 if (err) 5871 goto nla_put_failure; 5872 5873 genlmsg_end(msg, hdr); 5874 5875 return 0; 5876 5877nla_put_failure: 5878 genlmsg_cancel(msg, hdr); 5879 return -EMSGSIZE; 5880} 5881 5882static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb, 5883 struct genl_info *info) 5884{ 5885 struct netlink_ext_ack *extack = info->extack; 5886 struct devlink *devlink = info->user_ptr[0]; 5887 struct devlink_trap_group_item *group_item; 5888 struct sk_buff *msg; 5889 int err; 5890 5891 if (list_empty(&devlink->trap_group_list)) 5892 return -EOPNOTSUPP; 5893 5894 group_item = devlink_trap_group_item_get_from_info(devlink, info); 5895 if (!group_item) { 5896 NL_SET_ERR_MSG(extack, "Device did not register this trap group"); 5897 return -ENOENT; 5898 } 5899 5900 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 5901 if (!msg) 5902 return -ENOMEM; 5903 5904 err = devlink_nl_trap_group_fill(msg, devlink, group_item, 5905 DEVLINK_CMD_TRAP_GROUP_NEW, 5906 info->snd_portid, info->snd_seq, 0); 5907 if (err) 5908 goto err_trap_group_fill; 5909 5910 return genlmsg_reply(msg, info); 5911 5912err_trap_group_fill: 5913 nlmsg_free(msg); 5914 return err; 5915} 5916 5917static int 5918devlink_nl_cmd_trap_group_get_dump_one(struct sk_buff *msg, 5919 struct devlink *devlink, 5920 struct netlink_callback *cb) 5921{ 5922 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 5923 struct devlink_trap_group_item *group_item; 5924 int idx = 0; 5925 int err = 0; 5926 5927 5928 list_for_each_entry(group_item, &devlink->trap_group_list, list) { 5929 if (idx < state->idx) { 5930 idx++; 5931 continue; 5932 } 5933 err = devlink_nl_trap_group_fill(msg, devlink, group_item, 5934 DEVLINK_CMD_TRAP_GROUP_NEW, 5935 NETLINK_CB(cb->skb).portid, 5936 cb->nlh->nlmsg_seq, 5937 NLM_F_MULTI); 5938 if (err) { 5939 state->idx = idx; 5940 break; 5941 } 5942 idx++; 5943 } 5944 5945 return err; 5946} 5947 5948const struct devlink_cmd devl_cmd_trap_group_get = { 5949 .dump_one = devlink_nl_cmd_trap_group_get_dump_one, 5950}; 5951 5952static int 5953__devlink_trap_group_action_set(struct devlink *devlink, 5954 struct devlink_trap_group_item *group_item, 5955 enum devlink_trap_action trap_action, 5956 struct netlink_ext_ack *extack) 5957{ 5958 const char *group_name = group_item->group->name; 5959 struct devlink_trap_item *trap_item; 5960 int err; 5961 5962 if (devlink->ops->trap_group_action_set) { 5963 err = devlink->ops->trap_group_action_set(devlink, group_item->group, 5964 trap_action, extack); 5965 if (err) 5966 return err; 5967 5968 list_for_each_entry(trap_item, &devlink->trap_list, list) { 5969 if (strcmp(trap_item->group_item->group->name, group_name)) 5970 continue; 5971 if (trap_item->action != trap_action && 5972 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) 5973 continue; 5974 trap_item->action = trap_action; 5975 } 5976 5977 return 0; 5978 } 5979 5980 list_for_each_entry(trap_item, &devlink->trap_list, list) { 5981 if (strcmp(trap_item->group_item->group->name, group_name)) 5982 continue; 5983 err = __devlink_trap_action_set(devlink, trap_item, 5984 trap_action, extack); 5985 if (err) 5986 return err; 5987 } 5988 5989 return 0; 5990} 5991 5992static int 5993devlink_trap_group_action_set(struct devlink *devlink, 5994 struct devlink_trap_group_item *group_item, 5995 struct genl_info *info, bool *p_modified) 5996{ 5997 enum devlink_trap_action trap_action; 5998 int err; 5999 6000 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) 6001 return 0; 6002 6003 err = devlink_trap_action_get_from_info(info, &trap_action); 6004 if (err) { 6005 NL_SET_ERR_MSG(info->extack, "Invalid trap action"); 6006 return -EINVAL; 6007 } 6008 6009 err = __devlink_trap_group_action_set(devlink, group_item, trap_action, 6010 info->extack); 6011 if (err) 6012 return err; 6013 6014 *p_modified = true; 6015 6016 return 0; 6017} 6018 6019static int devlink_trap_group_set(struct devlink *devlink, 6020 struct devlink_trap_group_item *group_item, 6021 struct genl_info *info) 6022{ 6023 struct devlink_trap_policer_item *policer_item; 6024 struct netlink_ext_ack *extack = info->extack; 6025 const struct devlink_trap_policer *policer; 6026 struct nlattr **attrs = info->attrs; 6027 u32 policer_id; 6028 int err; 6029 6030 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) 6031 return 0; 6032 6033 if (!devlink->ops->trap_group_set) 6034 return -EOPNOTSUPP; 6035 6036 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); 6037 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id); 6038 if (policer_id && !policer_item) { 6039 NL_SET_ERR_MSG(extack, "Device did not register this trap policer"); 6040 return -ENOENT; 6041 } 6042 policer = policer_item ? policer_item->policer : NULL; 6043 6044 err = devlink->ops->trap_group_set(devlink, group_item->group, policer, 6045 extack); 6046 if (err) 6047 return err; 6048 6049 group_item->policer_item = policer_item; 6050 6051 return 0; 6052} 6053 6054static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb, 6055 struct genl_info *info) 6056{ 6057 struct netlink_ext_ack *extack = info->extack; 6058 struct devlink *devlink = info->user_ptr[0]; 6059 struct devlink_trap_group_item *group_item; 6060 bool modified = false; 6061 int err; 6062 6063 if (list_empty(&devlink->trap_group_list)) 6064 return -EOPNOTSUPP; 6065 6066 group_item = devlink_trap_group_item_get_from_info(devlink, info); 6067 if (!group_item) { 6068 NL_SET_ERR_MSG(extack, "Device did not register this trap group"); 6069 return -ENOENT; 6070 } 6071 6072 err = devlink_trap_group_action_set(devlink, group_item, info, 6073 &modified); 6074 if (err) 6075 return err; 6076 6077 err = devlink_trap_group_set(devlink, group_item, info); 6078 if (err) 6079 goto err_trap_group_set; 6080 6081 return 0; 6082 6083err_trap_group_set: 6084 if (modified) 6085 NL_SET_ERR_MSG(extack, "Trap group set failed, but some changes were committed already"); 6086 return err; 6087} 6088 6089static struct devlink_trap_policer_item * 6090devlink_trap_policer_item_get_from_info(struct devlink *devlink, 6091 struct genl_info *info) 6092{ 6093 u32 id; 6094 6095 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) 6096 return NULL; 6097 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); 6098 6099 return devlink_trap_policer_item_lookup(devlink, id); 6100} 6101 6102static int 6103devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink, 6104 const struct devlink_trap_policer *policer) 6105{ 6106 struct nlattr *attr; 6107 u64 drops; 6108 int err; 6109 6110 if (!devlink->ops->trap_policer_counter_get) 6111 return 0; 6112 6113 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops); 6114 if (err) 6115 return err; 6116 6117 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); 6118 if (!attr) 6119 return -EMSGSIZE; 6120 6121 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops, 6122 DEVLINK_ATTR_PAD)) 6123 goto nla_put_failure; 6124 6125 nla_nest_end(msg, attr); 6126 6127 return 0; 6128 6129nla_put_failure: 6130 nla_nest_cancel(msg, attr); 6131 return -EMSGSIZE; 6132} 6133 6134static int 6135devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink, 6136 const struct devlink_trap_policer_item *policer_item, 6137 enum devlink_command cmd, u32 portid, u32 seq, 6138 int flags) 6139{ 6140 void *hdr; 6141 int err; 6142 6143 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 6144 if (!hdr) 6145 return -EMSGSIZE; 6146 6147 if (devlink_nl_put_handle(msg, devlink)) 6148 goto nla_put_failure; 6149 6150 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, 6151 policer_item->policer->id)) 6152 goto nla_put_failure; 6153 6154 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE, 6155 policer_item->rate, DEVLINK_ATTR_PAD)) 6156 goto nla_put_failure; 6157 6158 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST, 6159 policer_item->burst, DEVLINK_ATTR_PAD)) 6160 goto nla_put_failure; 6161 6162 err = devlink_trap_policer_stats_put(msg, devlink, 6163 policer_item->policer); 6164 if (err) 6165 goto nla_put_failure; 6166 6167 genlmsg_end(msg, hdr); 6168 6169 return 0; 6170 6171nla_put_failure: 6172 genlmsg_cancel(msg, hdr); 6173 return -EMSGSIZE; 6174} 6175 6176static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb, 6177 struct genl_info *info) 6178{ 6179 struct devlink_trap_policer_item *policer_item; 6180 struct netlink_ext_ack *extack = info->extack; 6181 struct devlink *devlink = info->user_ptr[0]; 6182 struct sk_buff *msg; 6183 int err; 6184 6185 if (list_empty(&devlink->trap_policer_list)) 6186 return -EOPNOTSUPP; 6187 6188 policer_item = devlink_trap_policer_item_get_from_info(devlink, info); 6189 if (!policer_item) { 6190 NL_SET_ERR_MSG(extack, "Device did not register this trap policer"); 6191 return -ENOENT; 6192 } 6193 6194 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6195 if (!msg) 6196 return -ENOMEM; 6197 6198 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, 6199 DEVLINK_CMD_TRAP_POLICER_NEW, 6200 info->snd_portid, info->snd_seq, 0); 6201 if (err) 6202 goto err_trap_policer_fill; 6203 6204 return genlmsg_reply(msg, info); 6205 6206err_trap_policer_fill: 6207 nlmsg_free(msg); 6208 return err; 6209} 6210 6211static int 6212devlink_nl_cmd_trap_policer_get_dump_one(struct sk_buff *msg, 6213 struct devlink *devlink, 6214 struct netlink_callback *cb) 6215{ 6216 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 6217 struct devlink_trap_policer_item *policer_item; 6218 int idx = 0; 6219 int err = 0; 6220 6221 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) { 6222 if (idx < state->idx) { 6223 idx++; 6224 continue; 6225 } 6226 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, 6227 DEVLINK_CMD_TRAP_POLICER_NEW, 6228 NETLINK_CB(cb->skb).portid, 6229 cb->nlh->nlmsg_seq, 6230 NLM_F_MULTI); 6231 if (err) { 6232 state->idx = idx; 6233 break; 6234 } 6235 idx++; 6236 } 6237 6238 return err; 6239} 6240 6241const struct devlink_cmd devl_cmd_trap_policer_get = { 6242 .dump_one = devlink_nl_cmd_trap_policer_get_dump_one, 6243}; 6244 6245static int 6246devlink_trap_policer_set(struct devlink *devlink, 6247 struct devlink_trap_policer_item *policer_item, 6248 struct genl_info *info) 6249{ 6250 struct netlink_ext_ack *extack = info->extack; 6251 struct nlattr **attrs = info->attrs; 6252 u64 rate, burst; 6253 int err; 6254 6255 rate = policer_item->rate; 6256 burst = policer_item->burst; 6257 6258 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]) 6259 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]); 6260 6261 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]) 6262 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]); 6263 6264 if (rate < policer_item->policer->min_rate) { 6265 NL_SET_ERR_MSG(extack, "Policer rate lower than limit"); 6266 return -EINVAL; 6267 } 6268 6269 if (rate > policer_item->policer->max_rate) { 6270 NL_SET_ERR_MSG(extack, "Policer rate higher than limit"); 6271 return -EINVAL; 6272 } 6273 6274 if (burst < policer_item->policer->min_burst) { 6275 NL_SET_ERR_MSG(extack, "Policer burst size lower than limit"); 6276 return -EINVAL; 6277 } 6278 6279 if (burst > policer_item->policer->max_burst) { 6280 NL_SET_ERR_MSG(extack, "Policer burst size higher than limit"); 6281 return -EINVAL; 6282 } 6283 6284 err = devlink->ops->trap_policer_set(devlink, policer_item->policer, 6285 rate, burst, info->extack); 6286 if (err) 6287 return err; 6288 6289 policer_item->rate = rate; 6290 policer_item->burst = burst; 6291 6292 return 0; 6293} 6294 6295static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb, 6296 struct genl_info *info) 6297{ 6298 struct devlink_trap_policer_item *policer_item; 6299 struct netlink_ext_ack *extack = info->extack; 6300 struct devlink *devlink = info->user_ptr[0]; 6301 6302 if (list_empty(&devlink->trap_policer_list)) 6303 return -EOPNOTSUPP; 6304 6305 if (!devlink->ops->trap_policer_set) 6306 return -EOPNOTSUPP; 6307 6308 policer_item = devlink_trap_policer_item_get_from_info(devlink, info); 6309 if (!policer_item) { 6310 NL_SET_ERR_MSG(extack, "Device did not register this trap policer"); 6311 return -ENOENT; 6312 } 6313 6314 return devlink_trap_policer_set(devlink, policer_item, info); 6315} 6316 6317const struct genl_small_ops devlink_nl_ops[56] = { 6318 { 6319 .cmd = DEVLINK_CMD_GET, 6320 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6321 .doit = devlink_nl_cmd_get_doit, 6322 .dumpit = devlink_nl_instance_iter_dumpit, 6323 /* can be retrieved by unprivileged users */ 6324 }, 6325 { 6326 .cmd = DEVLINK_CMD_PORT_GET, 6327 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6328 .doit = devlink_nl_cmd_port_get_doit, 6329 .dumpit = devlink_nl_instance_iter_dumpit, 6330 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6331 /* can be retrieved by unprivileged users */ 6332 }, 6333 { 6334 .cmd = DEVLINK_CMD_PORT_SET, 6335 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6336 .doit = devlink_nl_cmd_port_set_doit, 6337 .flags = GENL_ADMIN_PERM, 6338 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6339 }, 6340 { 6341 .cmd = DEVLINK_CMD_RATE_GET, 6342 .doit = devlink_nl_cmd_rate_get_doit, 6343 .dumpit = devlink_nl_instance_iter_dumpit, 6344 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE, 6345 /* can be retrieved by unprivileged users */ 6346 }, 6347 { 6348 .cmd = DEVLINK_CMD_RATE_SET, 6349 .doit = devlink_nl_cmd_rate_set_doit, 6350 .flags = GENL_ADMIN_PERM, 6351 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE, 6352 }, 6353 { 6354 .cmd = DEVLINK_CMD_RATE_NEW, 6355 .doit = devlink_nl_cmd_rate_new_doit, 6356 .flags = GENL_ADMIN_PERM, 6357 }, 6358 { 6359 .cmd = DEVLINK_CMD_RATE_DEL, 6360 .doit = devlink_nl_cmd_rate_del_doit, 6361 .flags = GENL_ADMIN_PERM, 6362 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE, 6363 }, 6364 { 6365 .cmd = DEVLINK_CMD_PORT_SPLIT, 6366 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6367 .doit = devlink_nl_cmd_port_split_doit, 6368 .flags = GENL_ADMIN_PERM, 6369 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6370 }, 6371 { 6372 .cmd = DEVLINK_CMD_PORT_UNSPLIT, 6373 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6374 .doit = devlink_nl_cmd_port_unsplit_doit, 6375 .flags = GENL_ADMIN_PERM, 6376 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6377 }, 6378 { 6379 .cmd = DEVLINK_CMD_PORT_NEW, 6380 .doit = devlink_nl_cmd_port_new_doit, 6381 .flags = GENL_ADMIN_PERM, 6382 }, 6383 { 6384 .cmd = DEVLINK_CMD_PORT_DEL, 6385 .doit = devlink_nl_cmd_port_del_doit, 6386 .flags = GENL_ADMIN_PERM, 6387 }, 6388 { 6389 .cmd = DEVLINK_CMD_LINECARD_GET, 6390 .doit = devlink_nl_cmd_linecard_get_doit, 6391 .dumpit = devlink_nl_instance_iter_dumpit, 6392 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD, 6393 /* can be retrieved by unprivileged users */ 6394 }, 6395 { 6396 .cmd = DEVLINK_CMD_LINECARD_SET, 6397 .doit = devlink_nl_cmd_linecard_set_doit, 6398 .flags = GENL_ADMIN_PERM, 6399 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD, 6400 }, 6401 { 6402 .cmd = DEVLINK_CMD_SB_GET, 6403 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6404 .doit = devlink_nl_cmd_sb_get_doit, 6405 .dumpit = devlink_nl_instance_iter_dumpit, 6406 /* can be retrieved by unprivileged users */ 6407 }, 6408 { 6409 .cmd = DEVLINK_CMD_SB_POOL_GET, 6410 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6411 .doit = devlink_nl_cmd_sb_pool_get_doit, 6412 .dumpit = devlink_nl_instance_iter_dumpit, 6413 /* can be retrieved by unprivileged users */ 6414 }, 6415 { 6416 .cmd = DEVLINK_CMD_SB_POOL_SET, 6417 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6418 .doit = devlink_nl_cmd_sb_pool_set_doit, 6419 .flags = GENL_ADMIN_PERM, 6420 }, 6421 { 6422 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET, 6423 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6424 .doit = devlink_nl_cmd_sb_port_pool_get_doit, 6425 .dumpit = devlink_nl_instance_iter_dumpit, 6426 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6427 /* can be retrieved by unprivileged users */ 6428 }, 6429 { 6430 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, 6431 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6432 .doit = devlink_nl_cmd_sb_port_pool_set_doit, 6433 .flags = GENL_ADMIN_PERM, 6434 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6435 }, 6436 { 6437 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, 6438 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6439 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, 6440 .dumpit = devlink_nl_instance_iter_dumpit, 6441 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6442 /* can be retrieved by unprivileged users */ 6443 }, 6444 { 6445 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, 6446 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6447 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit, 6448 .flags = GENL_ADMIN_PERM, 6449 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6450 }, 6451 { 6452 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT, 6453 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6454 .doit = devlink_nl_cmd_sb_occ_snapshot_doit, 6455 .flags = GENL_ADMIN_PERM, 6456 }, 6457 { 6458 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR, 6459 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6460 .doit = devlink_nl_cmd_sb_occ_max_clear_doit, 6461 .flags = GENL_ADMIN_PERM, 6462 }, 6463 { 6464 .cmd = DEVLINK_CMD_ESWITCH_GET, 6465 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6466 .doit = devlink_nl_cmd_eswitch_get_doit, 6467 .flags = GENL_ADMIN_PERM, 6468 }, 6469 { 6470 .cmd = DEVLINK_CMD_ESWITCH_SET, 6471 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6472 .doit = devlink_nl_cmd_eswitch_set_doit, 6473 .flags = GENL_ADMIN_PERM, 6474 }, 6475 { 6476 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, 6477 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6478 .doit = devlink_nl_cmd_dpipe_table_get, 6479 /* can be retrieved by unprivileged users */ 6480 }, 6481 { 6482 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, 6483 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6484 .doit = devlink_nl_cmd_dpipe_entries_get, 6485 /* can be retrieved by unprivileged users */ 6486 }, 6487 { 6488 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, 6489 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6490 .doit = devlink_nl_cmd_dpipe_headers_get, 6491 /* can be retrieved by unprivileged users */ 6492 }, 6493 { 6494 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, 6495 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6496 .doit = devlink_nl_cmd_dpipe_table_counters_set, 6497 .flags = GENL_ADMIN_PERM, 6498 }, 6499 { 6500 .cmd = DEVLINK_CMD_RESOURCE_SET, 6501 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6502 .doit = devlink_nl_cmd_resource_set, 6503 .flags = GENL_ADMIN_PERM, 6504 }, 6505 { 6506 .cmd = DEVLINK_CMD_RESOURCE_DUMP, 6507 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6508 .doit = devlink_nl_cmd_resource_dump, 6509 /* can be retrieved by unprivileged users */ 6510 }, 6511 { 6512 .cmd = DEVLINK_CMD_RELOAD, 6513 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6514 .doit = devlink_nl_cmd_reload, 6515 .flags = GENL_ADMIN_PERM, 6516 }, 6517 { 6518 .cmd = DEVLINK_CMD_PARAM_GET, 6519 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6520 .doit = devlink_nl_cmd_param_get_doit, 6521 .dumpit = devlink_nl_instance_iter_dumpit, 6522 /* can be retrieved by unprivileged users */ 6523 }, 6524 { 6525 .cmd = DEVLINK_CMD_PARAM_SET, 6526 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6527 .doit = devlink_nl_cmd_param_set_doit, 6528 .flags = GENL_ADMIN_PERM, 6529 }, 6530 { 6531 .cmd = DEVLINK_CMD_PORT_PARAM_GET, 6532 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6533 .doit = devlink_nl_cmd_port_param_get_doit, 6534 .dumpit = devlink_nl_cmd_port_param_get_dumpit, 6535 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6536 /* can be retrieved by unprivileged users */ 6537 }, 6538 { 6539 .cmd = DEVLINK_CMD_PORT_PARAM_SET, 6540 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6541 .doit = devlink_nl_cmd_port_param_set_doit, 6542 .flags = GENL_ADMIN_PERM, 6543 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6544 }, 6545 { 6546 .cmd = DEVLINK_CMD_REGION_GET, 6547 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6548 .doit = devlink_nl_cmd_region_get_doit, 6549 .dumpit = devlink_nl_instance_iter_dumpit, 6550 .flags = GENL_ADMIN_PERM, 6551 }, 6552 { 6553 .cmd = DEVLINK_CMD_REGION_NEW, 6554 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6555 .doit = devlink_nl_cmd_region_new, 6556 .flags = GENL_ADMIN_PERM, 6557 }, 6558 { 6559 .cmd = DEVLINK_CMD_REGION_DEL, 6560 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6561 .doit = devlink_nl_cmd_region_del, 6562 .flags = GENL_ADMIN_PERM, 6563 }, 6564 { 6565 .cmd = DEVLINK_CMD_REGION_READ, 6566 .validate = GENL_DONT_VALIDATE_STRICT | 6567 GENL_DONT_VALIDATE_DUMP_STRICT, 6568 .dumpit = devlink_nl_cmd_region_read_dumpit, 6569 .flags = GENL_ADMIN_PERM, 6570 }, 6571 { 6572 .cmd = DEVLINK_CMD_INFO_GET, 6573 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6574 .doit = devlink_nl_cmd_info_get_doit, 6575 .dumpit = devlink_nl_instance_iter_dumpit, 6576 /* can be retrieved by unprivileged users */ 6577 }, 6578 { 6579 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET, 6580 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6581 .doit = devlink_nl_cmd_health_reporter_get_doit, 6582 .dumpit = devlink_nl_instance_iter_dumpit, 6583 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 6584 /* can be retrieved by unprivileged users */ 6585 }, 6586 { 6587 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET, 6588 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6589 .doit = devlink_nl_cmd_health_reporter_set_doit, 6590 .flags = GENL_ADMIN_PERM, 6591 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 6592 }, 6593 { 6594 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, 6595 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6596 .doit = devlink_nl_cmd_health_reporter_recover_doit, 6597 .flags = GENL_ADMIN_PERM, 6598 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 6599 }, 6600 { 6601 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 6602 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6603 .doit = devlink_nl_cmd_health_reporter_diagnose_doit, 6604 .flags = GENL_ADMIN_PERM, 6605 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 6606 }, 6607 { 6608 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, 6609 .validate = GENL_DONT_VALIDATE_STRICT | 6610 GENL_DONT_VALIDATE_DUMP_STRICT, 6611 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit, 6612 .flags = GENL_ADMIN_PERM, 6613 }, 6614 { 6615 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, 6616 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6617 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit, 6618 .flags = GENL_ADMIN_PERM, 6619 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 6620 }, 6621 { 6622 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST, 6623 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6624 .doit = devlink_nl_cmd_health_reporter_test_doit, 6625 .flags = GENL_ADMIN_PERM, 6626 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 6627 }, 6628 { 6629 .cmd = DEVLINK_CMD_FLASH_UPDATE, 6630 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6631 .doit = devlink_nl_cmd_flash_update, 6632 .flags = GENL_ADMIN_PERM, 6633 }, 6634 { 6635 .cmd = DEVLINK_CMD_TRAP_GET, 6636 .doit = devlink_nl_cmd_trap_get_doit, 6637 .dumpit = devlink_nl_instance_iter_dumpit, 6638 /* can be retrieved by unprivileged users */ 6639 }, 6640 { 6641 .cmd = DEVLINK_CMD_TRAP_SET, 6642 .doit = devlink_nl_cmd_trap_set_doit, 6643 .flags = GENL_ADMIN_PERM, 6644 }, 6645 { 6646 .cmd = DEVLINK_CMD_TRAP_GROUP_GET, 6647 .doit = devlink_nl_cmd_trap_group_get_doit, 6648 .dumpit = devlink_nl_instance_iter_dumpit, 6649 /* can be retrieved by unprivileged users */ 6650 }, 6651 { 6652 .cmd = DEVLINK_CMD_TRAP_GROUP_SET, 6653 .doit = devlink_nl_cmd_trap_group_set_doit, 6654 .flags = GENL_ADMIN_PERM, 6655 }, 6656 { 6657 .cmd = DEVLINK_CMD_TRAP_POLICER_GET, 6658 .doit = devlink_nl_cmd_trap_policer_get_doit, 6659 .dumpit = devlink_nl_instance_iter_dumpit, 6660 /* can be retrieved by unprivileged users */ 6661 }, 6662 { 6663 .cmd = DEVLINK_CMD_TRAP_POLICER_SET, 6664 .doit = devlink_nl_cmd_trap_policer_set_doit, 6665 .flags = GENL_ADMIN_PERM, 6666 }, 6667 { 6668 .cmd = DEVLINK_CMD_SELFTESTS_GET, 6669 .doit = devlink_nl_cmd_selftests_get_doit, 6670 .dumpit = devlink_nl_instance_iter_dumpit, 6671 /* can be retrieved by unprivileged users */ 6672 }, 6673 { 6674 .cmd = DEVLINK_CMD_SELFTESTS_RUN, 6675 .doit = devlink_nl_cmd_selftests_run, 6676 .flags = GENL_ADMIN_PERM, 6677 }, 6678 /* -- No new ops here! Use split ops going forward! -- */ 6679}; 6680 6681static void 6682devlink_trap_policer_notify(struct devlink *devlink, 6683 const struct devlink_trap_policer_item *policer_item, 6684 enum devlink_command cmd); 6685static void 6686devlink_trap_group_notify(struct devlink *devlink, 6687 const struct devlink_trap_group_item *group_item, 6688 enum devlink_command cmd); 6689static void devlink_trap_notify(struct devlink *devlink, 6690 const struct devlink_trap_item *trap_item, 6691 enum devlink_command cmd); 6692 6693void devlink_notify_register(struct devlink *devlink) 6694{ 6695 struct devlink_trap_policer_item *policer_item; 6696 struct devlink_trap_group_item *group_item; 6697 struct devlink_param_item *param_item; 6698 struct devlink_trap_item *trap_item; 6699 struct devlink_port *devlink_port; 6700 struct devlink_linecard *linecard; 6701 struct devlink_rate *rate_node; 6702 struct devlink_region *region; 6703 unsigned long port_index; 6704 unsigned long param_id; 6705 6706 devlink_notify(devlink, DEVLINK_CMD_NEW); 6707 list_for_each_entry(linecard, &devlink->linecard_list, list) 6708 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 6709 6710 xa_for_each(&devlink->ports, port_index, devlink_port) 6711 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 6712 6713 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) 6714 devlink_trap_policer_notify(devlink, policer_item, 6715 DEVLINK_CMD_TRAP_POLICER_NEW); 6716 6717 list_for_each_entry(group_item, &devlink->trap_group_list, list) 6718 devlink_trap_group_notify(devlink, group_item, 6719 DEVLINK_CMD_TRAP_GROUP_NEW); 6720 6721 list_for_each_entry(trap_item, &devlink->trap_list, list) 6722 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW); 6723 6724 list_for_each_entry(rate_node, &devlink->rate_list, list) 6725 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); 6726 6727 list_for_each_entry(region, &devlink->region_list, list) 6728 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 6729 6730 xa_for_each(&devlink->params, param_id, param_item) 6731 devlink_param_notify(devlink, 0, param_item, 6732 DEVLINK_CMD_PARAM_NEW); 6733} 6734 6735void devlink_notify_unregister(struct devlink *devlink) 6736{ 6737 struct devlink_trap_policer_item *policer_item; 6738 struct devlink_trap_group_item *group_item; 6739 struct devlink_param_item *param_item; 6740 struct devlink_trap_item *trap_item; 6741 struct devlink_port *devlink_port; 6742 struct devlink_rate *rate_node; 6743 struct devlink_region *region; 6744 unsigned long port_index; 6745 unsigned long param_id; 6746 6747 xa_for_each(&devlink->params, param_id, param_item) 6748 devlink_param_notify(devlink, 0, param_item, 6749 DEVLINK_CMD_PARAM_DEL); 6750 6751 list_for_each_entry_reverse(region, &devlink->region_list, list) 6752 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); 6753 6754 list_for_each_entry_reverse(rate_node, &devlink->rate_list, list) 6755 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); 6756 6757 list_for_each_entry_reverse(trap_item, &devlink->trap_list, list) 6758 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL); 6759 6760 list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list) 6761 devlink_trap_group_notify(devlink, group_item, 6762 DEVLINK_CMD_TRAP_GROUP_DEL); 6763 list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list, 6764 list) 6765 devlink_trap_policer_notify(devlink, policer_item, 6766 DEVLINK_CMD_TRAP_POLICER_DEL); 6767 6768 xa_for_each(&devlink->ports, port_index, devlink_port) 6769 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); 6770 devlink_notify(devlink, DEVLINK_CMD_DEL); 6771} 6772 6773static void devlink_port_type_warn(struct work_struct *work) 6774{ 6775 WARN(true, "Type was not set for devlink port."); 6776} 6777 6778static bool devlink_port_type_should_warn(struct devlink_port *devlink_port) 6779{ 6780 /* Ignore CPU and DSA flavours. */ 6781 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU && 6782 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA && 6783 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED; 6784} 6785 6786#define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600) 6787 6788static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port) 6789{ 6790 if (!devlink_port_type_should_warn(devlink_port)) 6791 return; 6792 /* Schedule a work to WARN in case driver does not set port 6793 * type within timeout. 6794 */ 6795 schedule_delayed_work(&devlink_port->type_warn_dw, 6796 DEVLINK_PORT_TYPE_WARN_TIMEOUT); 6797} 6798 6799static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port) 6800{ 6801 if (!devlink_port_type_should_warn(devlink_port)) 6802 return; 6803 cancel_delayed_work_sync(&devlink_port->type_warn_dw); 6804} 6805 6806/** 6807 * devlink_port_init() - Init devlink port 6808 * 6809 * @devlink: devlink 6810 * @devlink_port: devlink port 6811 * 6812 * Initialize essencial stuff that is needed for functions 6813 * that may be called before devlink port registration. 6814 * Call to this function is optional and not needed 6815 * in case the driver does not use such functions. 6816 */ 6817void devlink_port_init(struct devlink *devlink, 6818 struct devlink_port *devlink_port) 6819{ 6820 if (devlink_port->initialized) 6821 return; 6822 devlink_port->devlink = devlink; 6823 INIT_LIST_HEAD(&devlink_port->region_list); 6824 devlink_port->initialized = true; 6825} 6826EXPORT_SYMBOL_GPL(devlink_port_init); 6827 6828/** 6829 * devlink_port_fini() - Deinitialize devlink port 6830 * 6831 * @devlink_port: devlink port 6832 * 6833 * Deinitialize essencial stuff that is in use for functions 6834 * that may be called after devlink port unregistration. 6835 * Call to this function is optional and not needed 6836 * in case the driver does not use such functions. 6837 */ 6838void devlink_port_fini(struct devlink_port *devlink_port) 6839{ 6840 WARN_ON(!list_empty(&devlink_port->region_list)); 6841} 6842EXPORT_SYMBOL_GPL(devlink_port_fini); 6843 6844/** 6845 * devl_port_register() - Register devlink port 6846 * 6847 * @devlink: devlink 6848 * @devlink_port: devlink port 6849 * @port_index: driver-specific numerical identifier of the port 6850 * 6851 * Register devlink port with provided port index. User can use 6852 * any indexing, even hw-related one. devlink_port structure 6853 * is convenient to be embedded inside user driver private structure. 6854 * Note that the caller should take care of zeroing the devlink_port 6855 * structure. 6856 */ 6857int devl_port_register(struct devlink *devlink, 6858 struct devlink_port *devlink_port, 6859 unsigned int port_index) 6860{ 6861 int err; 6862 6863 devl_assert_locked(devlink); 6864 6865 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); 6866 6867 devlink_port_init(devlink, devlink_port); 6868 devlink_port->registered = true; 6869 devlink_port->index = port_index; 6870 spin_lock_init(&devlink_port->type_lock); 6871 INIT_LIST_HEAD(&devlink_port->reporter_list); 6872 err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL); 6873 if (err) 6874 return err; 6875 6876 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn); 6877 devlink_port_type_warn_schedule(devlink_port); 6878 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 6879 return 0; 6880} 6881EXPORT_SYMBOL_GPL(devl_port_register); 6882 6883/** 6884 * devlink_port_register - Register devlink port 6885 * 6886 * @devlink: devlink 6887 * @devlink_port: devlink port 6888 * @port_index: driver-specific numerical identifier of the port 6889 * 6890 * Register devlink port with provided port index. User can use 6891 * any indexing, even hw-related one. devlink_port structure 6892 * is convenient to be embedded inside user driver private structure. 6893 * Note that the caller should take care of zeroing the devlink_port 6894 * structure. 6895 * 6896 * Context: Takes and release devlink->lock <mutex>. 6897 */ 6898int devlink_port_register(struct devlink *devlink, 6899 struct devlink_port *devlink_port, 6900 unsigned int port_index) 6901{ 6902 int err; 6903 6904 devl_lock(devlink); 6905 err = devl_port_register(devlink, devlink_port, port_index); 6906 devl_unlock(devlink); 6907 return err; 6908} 6909EXPORT_SYMBOL_GPL(devlink_port_register); 6910 6911/** 6912 * devl_port_unregister() - Unregister devlink port 6913 * 6914 * @devlink_port: devlink port 6915 */ 6916void devl_port_unregister(struct devlink_port *devlink_port) 6917{ 6918 lockdep_assert_held(&devlink_port->devlink->lock); 6919 WARN_ON(devlink_port->type != DEVLINK_PORT_TYPE_NOTSET); 6920 6921 devlink_port_type_warn_cancel(devlink_port); 6922 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); 6923 xa_erase(&devlink_port->devlink->ports, devlink_port->index); 6924 WARN_ON(!list_empty(&devlink_port->reporter_list)); 6925 devlink_port->registered = false; 6926} 6927EXPORT_SYMBOL_GPL(devl_port_unregister); 6928 6929/** 6930 * devlink_port_unregister - Unregister devlink port 6931 * 6932 * @devlink_port: devlink port 6933 * 6934 * Context: Takes and release devlink->lock <mutex>. 6935 */ 6936void devlink_port_unregister(struct devlink_port *devlink_port) 6937{ 6938 struct devlink *devlink = devlink_port->devlink; 6939 6940 devl_lock(devlink); 6941 devl_port_unregister(devlink_port); 6942 devl_unlock(devlink); 6943} 6944EXPORT_SYMBOL_GPL(devlink_port_unregister); 6945 6946static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port, 6947 struct net_device *netdev) 6948{ 6949 const struct net_device_ops *ops = netdev->netdev_ops; 6950 6951 /* If driver registers devlink port, it should set devlink port 6952 * attributes accordingly so the compat functions are called 6953 * and the original ops are not used. 6954 */ 6955 if (ops->ndo_get_phys_port_name) { 6956 /* Some drivers use the same set of ndos for netdevs 6957 * that have devlink_port registered and also for 6958 * those who don't. Make sure that ndo_get_phys_port_name 6959 * returns -EOPNOTSUPP here in case it is defined. 6960 * Warn if not. 6961 */ 6962 char name[IFNAMSIZ]; 6963 int err; 6964 6965 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name)); 6966 WARN_ON(err != -EOPNOTSUPP); 6967 } 6968 if (ops->ndo_get_port_parent_id) { 6969 /* Some drivers use the same set of ndos for netdevs 6970 * that have devlink_port registered and also for 6971 * those who don't. Make sure that ndo_get_port_parent_id 6972 * returns -EOPNOTSUPP here in case it is defined. 6973 * Warn if not. 6974 */ 6975 struct netdev_phys_item_id ppid; 6976 int err; 6977 6978 err = ops->ndo_get_port_parent_id(netdev, &ppid); 6979 WARN_ON(err != -EOPNOTSUPP); 6980 } 6981} 6982 6983static void __devlink_port_type_set(struct devlink_port *devlink_port, 6984 enum devlink_port_type type, 6985 void *type_dev) 6986{ 6987 struct net_device *netdev = type_dev; 6988 6989 ASSERT_DEVLINK_PORT_REGISTERED(devlink_port); 6990 6991 if (type == DEVLINK_PORT_TYPE_NOTSET) { 6992 devlink_port_type_warn_schedule(devlink_port); 6993 } else { 6994 devlink_port_type_warn_cancel(devlink_port); 6995 if (type == DEVLINK_PORT_TYPE_ETH && netdev) 6996 devlink_port_type_netdev_checks(devlink_port, netdev); 6997 } 6998 6999 spin_lock_bh(&devlink_port->type_lock); 7000 devlink_port->type = type; 7001 switch (type) { 7002 case DEVLINK_PORT_TYPE_ETH: 7003 devlink_port->type_eth.netdev = netdev; 7004 if (netdev) { 7005 ASSERT_RTNL(); 7006 devlink_port->type_eth.ifindex = netdev->ifindex; 7007 BUILD_BUG_ON(sizeof(devlink_port->type_eth.ifname) != 7008 sizeof(netdev->name)); 7009 strcpy(devlink_port->type_eth.ifname, netdev->name); 7010 } 7011 break; 7012 case DEVLINK_PORT_TYPE_IB: 7013 devlink_port->type_ib.ibdev = type_dev; 7014 break; 7015 default: 7016 break; 7017 } 7018 spin_unlock_bh(&devlink_port->type_lock); 7019 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 7020} 7021 7022/** 7023 * devlink_port_type_eth_set - Set port type to Ethernet 7024 * 7025 * @devlink_port: devlink port 7026 * 7027 * If driver is calling this, most likely it is doing something wrong. 7028 */ 7029void devlink_port_type_eth_set(struct devlink_port *devlink_port) 7030{ 7031 dev_warn(devlink_port->devlink->dev, 7032 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n", 7033 devlink_port->index); 7034 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL); 7035} 7036EXPORT_SYMBOL_GPL(devlink_port_type_eth_set); 7037 7038/** 7039 * devlink_port_type_ib_set - Set port type to InfiniBand 7040 * 7041 * @devlink_port: devlink port 7042 * @ibdev: related IB device 7043 */ 7044void devlink_port_type_ib_set(struct devlink_port *devlink_port, 7045 struct ib_device *ibdev) 7046{ 7047 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev); 7048} 7049EXPORT_SYMBOL_GPL(devlink_port_type_ib_set); 7050 7051/** 7052 * devlink_port_type_clear - Clear port type 7053 * 7054 * @devlink_port: devlink port 7055 * 7056 * If driver is calling this for clearing Ethernet type, most likely 7057 * it is doing something wrong. 7058 */ 7059void devlink_port_type_clear(struct devlink_port *devlink_port) 7060{ 7061 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) 7062 dev_warn(devlink_port->devlink->dev, 7063 "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n", 7064 devlink_port->index); 7065 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL); 7066} 7067EXPORT_SYMBOL_GPL(devlink_port_type_clear); 7068 7069int devlink_port_netdevice_event(struct notifier_block *nb, 7070 unsigned long event, void *ptr) 7071{ 7072 struct net_device *netdev = netdev_notifier_info_to_dev(ptr); 7073 struct devlink_port *devlink_port = netdev->devlink_port; 7074 struct devlink *devlink; 7075 7076 devlink = container_of(nb, struct devlink, netdevice_nb); 7077 7078 if (!devlink_port || devlink_port->devlink != devlink) 7079 return NOTIFY_OK; 7080 7081 switch (event) { 7082 case NETDEV_POST_INIT: 7083 /* Set the type but not netdev pointer. It is going to be set 7084 * later on by NETDEV_REGISTER event. Happens once during 7085 * netdevice register 7086 */ 7087 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, 7088 NULL); 7089 break; 7090 case NETDEV_REGISTER: 7091 case NETDEV_CHANGENAME: 7092 if (devlink_net(devlink) != dev_net(netdev)) 7093 return NOTIFY_OK; 7094 /* Set the netdev on top of previously set type. Note this 7095 * event happens also during net namespace change so here 7096 * we take into account netdev pointer appearing in this 7097 * namespace. 7098 */ 7099 __devlink_port_type_set(devlink_port, devlink_port->type, 7100 netdev); 7101 break; 7102 case NETDEV_UNREGISTER: 7103 if (devlink_net(devlink) != dev_net(netdev)) 7104 return NOTIFY_OK; 7105 /* Clear netdev pointer, but not the type. This event happens 7106 * also during net namespace change so we need to clear 7107 * pointer to netdev that is going to another net namespace. 7108 */ 7109 __devlink_port_type_set(devlink_port, devlink_port->type, 7110 NULL); 7111 break; 7112 case NETDEV_PRE_UNINIT: 7113 /* Clear the type and the netdev pointer. Happens one during 7114 * netdevice unregister. 7115 */ 7116 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, 7117 NULL); 7118 break; 7119 } 7120 7121 return NOTIFY_OK; 7122} 7123 7124static int __devlink_port_attrs_set(struct devlink_port *devlink_port, 7125 enum devlink_port_flavour flavour) 7126{ 7127 struct devlink_port_attrs *attrs = &devlink_port->attrs; 7128 7129 devlink_port->attrs_set = true; 7130 attrs->flavour = flavour; 7131 if (attrs->switch_id.id_len) { 7132 devlink_port->switch_port = true; 7133 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN)) 7134 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN; 7135 } else { 7136 devlink_port->switch_port = false; 7137 } 7138 return 0; 7139} 7140 7141/** 7142 * devlink_port_attrs_set - Set port attributes 7143 * 7144 * @devlink_port: devlink port 7145 * @attrs: devlink port attrs 7146 */ 7147void devlink_port_attrs_set(struct devlink_port *devlink_port, 7148 struct devlink_port_attrs *attrs) 7149{ 7150 int ret; 7151 7152 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); 7153 7154 devlink_port->attrs = *attrs; 7155 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour); 7156 if (ret) 7157 return; 7158 WARN_ON(attrs->splittable && attrs->split); 7159} 7160EXPORT_SYMBOL_GPL(devlink_port_attrs_set); 7161 7162/** 7163 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes 7164 * 7165 * @devlink_port: devlink port 7166 * @controller: associated controller number for the devlink port instance 7167 * @pf: associated PF for the devlink port instance 7168 * @external: indicates if the port is for an external controller 7169 */ 7170void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller, 7171 u16 pf, bool external) 7172{ 7173 struct devlink_port_attrs *attrs = &devlink_port->attrs; 7174 int ret; 7175 7176 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); 7177 7178 ret = __devlink_port_attrs_set(devlink_port, 7179 DEVLINK_PORT_FLAVOUR_PCI_PF); 7180 if (ret) 7181 return; 7182 attrs->pci_pf.controller = controller; 7183 attrs->pci_pf.pf = pf; 7184 attrs->pci_pf.external = external; 7185} 7186EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set); 7187 7188/** 7189 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes 7190 * 7191 * @devlink_port: devlink port 7192 * @controller: associated controller number for the devlink port instance 7193 * @pf: associated PF for the devlink port instance 7194 * @vf: associated VF of a PF for the devlink port instance 7195 * @external: indicates if the port is for an external controller 7196 */ 7197void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller, 7198 u16 pf, u16 vf, bool external) 7199{ 7200 struct devlink_port_attrs *attrs = &devlink_port->attrs; 7201 int ret; 7202 7203 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); 7204 7205 ret = __devlink_port_attrs_set(devlink_port, 7206 DEVLINK_PORT_FLAVOUR_PCI_VF); 7207 if (ret) 7208 return; 7209 attrs->pci_vf.controller = controller; 7210 attrs->pci_vf.pf = pf; 7211 attrs->pci_vf.vf = vf; 7212 attrs->pci_vf.external = external; 7213} 7214EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set); 7215 7216/** 7217 * devlink_port_attrs_pci_sf_set - Set PCI SF port attributes 7218 * 7219 * @devlink_port: devlink port 7220 * @controller: associated controller number for the devlink port instance 7221 * @pf: associated PF for the devlink port instance 7222 * @sf: associated SF of a PF for the devlink port instance 7223 * @external: indicates if the port is for an external controller 7224 */ 7225void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller, 7226 u16 pf, u32 sf, bool external) 7227{ 7228 struct devlink_port_attrs *attrs = &devlink_port->attrs; 7229 int ret; 7230 7231 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); 7232 7233 ret = __devlink_port_attrs_set(devlink_port, 7234 DEVLINK_PORT_FLAVOUR_PCI_SF); 7235 if (ret) 7236 return; 7237 attrs->pci_sf.controller = controller; 7238 attrs->pci_sf.pf = pf; 7239 attrs->pci_sf.sf = sf; 7240 attrs->pci_sf.external = external; 7241} 7242EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set); 7243 7244/** 7245 * devl_rate_node_create - create devlink rate node 7246 * @devlink: devlink instance 7247 * @priv: driver private data 7248 * @node_name: name of the resulting node 7249 * @parent: parent devlink_rate struct 7250 * 7251 * Create devlink rate object of type node 7252 */ 7253struct devlink_rate * 7254devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name, 7255 struct devlink_rate *parent) 7256{ 7257 struct devlink_rate *rate_node; 7258 7259 rate_node = devlink_rate_node_get_by_name(devlink, node_name); 7260 if (!IS_ERR(rate_node)) 7261 return ERR_PTR(-EEXIST); 7262 7263 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL); 7264 if (!rate_node) 7265 return ERR_PTR(-ENOMEM); 7266 7267 if (parent) { 7268 rate_node->parent = parent; 7269 refcount_inc(&rate_node->parent->refcnt); 7270 } 7271 7272 rate_node->type = DEVLINK_RATE_TYPE_NODE; 7273 rate_node->devlink = devlink; 7274 rate_node->priv = priv; 7275 7276 rate_node->name = kstrdup(node_name, GFP_KERNEL); 7277 if (!rate_node->name) { 7278 kfree(rate_node); 7279 return ERR_PTR(-ENOMEM); 7280 } 7281 7282 refcount_set(&rate_node->refcnt, 1); 7283 list_add(&rate_node->list, &devlink->rate_list); 7284 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); 7285 return rate_node; 7286} 7287EXPORT_SYMBOL_GPL(devl_rate_node_create); 7288 7289/** 7290 * devl_rate_leaf_create - create devlink rate leaf 7291 * @devlink_port: devlink port object to create rate object on 7292 * @priv: driver private data 7293 * @parent: parent devlink_rate struct 7294 * 7295 * Create devlink rate object of type leaf on provided @devlink_port. 7296 */ 7297int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv, 7298 struct devlink_rate *parent) 7299{ 7300 struct devlink *devlink = devlink_port->devlink; 7301 struct devlink_rate *devlink_rate; 7302 7303 devl_assert_locked(devlink_port->devlink); 7304 7305 if (WARN_ON(devlink_port->devlink_rate)) 7306 return -EBUSY; 7307 7308 devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL); 7309 if (!devlink_rate) 7310 return -ENOMEM; 7311 7312 if (parent) { 7313 devlink_rate->parent = parent; 7314 refcount_inc(&devlink_rate->parent->refcnt); 7315 } 7316 7317 devlink_rate->type = DEVLINK_RATE_TYPE_LEAF; 7318 devlink_rate->devlink = devlink; 7319 devlink_rate->devlink_port = devlink_port; 7320 devlink_rate->priv = priv; 7321 list_add_tail(&devlink_rate->list, &devlink->rate_list); 7322 devlink_port->devlink_rate = devlink_rate; 7323 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); 7324 7325 return 0; 7326} 7327EXPORT_SYMBOL_GPL(devl_rate_leaf_create); 7328 7329/** 7330 * devl_rate_leaf_destroy - destroy devlink rate leaf 7331 * 7332 * @devlink_port: devlink port linked to the rate object 7333 * 7334 * Destroy the devlink rate object of type leaf on provided @devlink_port. 7335 */ 7336void devl_rate_leaf_destroy(struct devlink_port *devlink_port) 7337{ 7338 struct devlink_rate *devlink_rate = devlink_port->devlink_rate; 7339 7340 devl_assert_locked(devlink_port->devlink); 7341 if (!devlink_rate) 7342 return; 7343 7344 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL); 7345 if (devlink_rate->parent) 7346 refcount_dec(&devlink_rate->parent->refcnt); 7347 list_del(&devlink_rate->list); 7348 devlink_port->devlink_rate = NULL; 7349 kfree(devlink_rate); 7350} 7351EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy); 7352 7353/** 7354 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device 7355 * @devlink: devlink instance 7356 * 7357 * Unset parent for all rate objects and destroy all rate nodes 7358 * on specified device. 7359 */ 7360void devl_rate_nodes_destroy(struct devlink *devlink) 7361{ 7362 static struct devlink_rate *devlink_rate, *tmp; 7363 const struct devlink_ops *ops = devlink->ops; 7364 7365 devl_assert_locked(devlink); 7366 7367 list_for_each_entry(devlink_rate, &devlink->rate_list, list) { 7368 if (!devlink_rate->parent) 7369 continue; 7370 7371 refcount_dec(&devlink_rate->parent->refcnt); 7372 if (devlink_rate_is_leaf(devlink_rate)) 7373 ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv, 7374 NULL, NULL); 7375 else if (devlink_rate_is_node(devlink_rate)) 7376 ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv, 7377 NULL, NULL); 7378 } 7379 list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) { 7380 if (devlink_rate_is_node(devlink_rate)) { 7381 ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL); 7382 list_del(&devlink_rate->list); 7383 kfree(devlink_rate->name); 7384 kfree(devlink_rate); 7385 } 7386 } 7387} 7388EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy); 7389 7390/** 7391 * devlink_port_linecard_set - Link port with a linecard 7392 * 7393 * @devlink_port: devlink port 7394 * @linecard: devlink linecard 7395 */ 7396void devlink_port_linecard_set(struct devlink_port *devlink_port, 7397 struct devlink_linecard *linecard) 7398{ 7399 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); 7400 7401 devlink_port->linecard = linecard; 7402} 7403EXPORT_SYMBOL_GPL(devlink_port_linecard_set); 7404 7405static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, 7406 char *name, size_t len) 7407{ 7408 struct devlink_port_attrs *attrs = &devlink_port->attrs; 7409 int n = 0; 7410 7411 if (!devlink_port->attrs_set) 7412 return -EOPNOTSUPP; 7413 7414 switch (attrs->flavour) { 7415 case DEVLINK_PORT_FLAVOUR_PHYSICAL: 7416 if (devlink_port->linecard) 7417 n = snprintf(name, len, "l%u", 7418 devlink_port->linecard->index); 7419 if (n < len) 7420 n += snprintf(name + n, len - n, "p%u", 7421 attrs->phys.port_number); 7422 if (n < len && attrs->split) 7423 n += snprintf(name + n, len - n, "s%u", 7424 attrs->phys.split_subport_number); 7425 break; 7426 case DEVLINK_PORT_FLAVOUR_CPU: 7427 case DEVLINK_PORT_FLAVOUR_DSA: 7428 case DEVLINK_PORT_FLAVOUR_UNUSED: 7429 /* As CPU and DSA ports do not have a netdevice associated 7430 * case should not ever happen. 7431 */ 7432 WARN_ON(1); 7433 return -EINVAL; 7434 case DEVLINK_PORT_FLAVOUR_PCI_PF: 7435 if (attrs->pci_pf.external) { 7436 n = snprintf(name, len, "c%u", attrs->pci_pf.controller); 7437 if (n >= len) 7438 return -EINVAL; 7439 len -= n; 7440 name += n; 7441 } 7442 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf); 7443 break; 7444 case DEVLINK_PORT_FLAVOUR_PCI_VF: 7445 if (attrs->pci_vf.external) { 7446 n = snprintf(name, len, "c%u", attrs->pci_vf.controller); 7447 if (n >= len) 7448 return -EINVAL; 7449 len -= n; 7450 name += n; 7451 } 7452 n = snprintf(name, len, "pf%uvf%u", 7453 attrs->pci_vf.pf, attrs->pci_vf.vf); 7454 break; 7455 case DEVLINK_PORT_FLAVOUR_PCI_SF: 7456 if (attrs->pci_sf.external) { 7457 n = snprintf(name, len, "c%u", attrs->pci_sf.controller); 7458 if (n >= len) 7459 return -EINVAL; 7460 len -= n; 7461 name += n; 7462 } 7463 n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf, 7464 attrs->pci_sf.sf); 7465 break; 7466 case DEVLINK_PORT_FLAVOUR_VIRTUAL: 7467 return -EOPNOTSUPP; 7468 } 7469 7470 if (n >= len) 7471 return -EINVAL; 7472 7473 return 0; 7474} 7475 7476static int devlink_linecard_types_init(struct devlink_linecard *linecard) 7477{ 7478 struct devlink_linecard_type *linecard_type; 7479 unsigned int count; 7480 int i; 7481 7482 count = linecard->ops->types_count(linecard, linecard->priv); 7483 linecard->types = kmalloc_array(count, sizeof(*linecard_type), 7484 GFP_KERNEL); 7485 if (!linecard->types) 7486 return -ENOMEM; 7487 linecard->types_count = count; 7488 7489 for (i = 0; i < count; i++) { 7490 linecard_type = &linecard->types[i]; 7491 linecard->ops->types_get(linecard, linecard->priv, i, 7492 &linecard_type->type, 7493 &linecard_type->priv); 7494 } 7495 return 0; 7496} 7497 7498static void devlink_linecard_types_fini(struct devlink_linecard *linecard) 7499{ 7500 kfree(linecard->types); 7501} 7502 7503/** 7504 * devl_linecard_create - Create devlink linecard 7505 * 7506 * @devlink: devlink 7507 * @linecard_index: driver-specific numerical identifier of the linecard 7508 * @ops: linecards ops 7509 * @priv: user priv pointer 7510 * 7511 * Create devlink linecard instance with provided linecard index. 7512 * Caller can use any indexing, even hw-related one. 7513 * 7514 * Return: Line card structure or an ERR_PTR() encoded error code. 7515 */ 7516struct devlink_linecard * 7517devl_linecard_create(struct devlink *devlink, unsigned int linecard_index, 7518 const struct devlink_linecard_ops *ops, void *priv) 7519{ 7520 struct devlink_linecard *linecard; 7521 int err; 7522 7523 if (WARN_ON(!ops || !ops->provision || !ops->unprovision || 7524 !ops->types_count || !ops->types_get)) 7525 return ERR_PTR(-EINVAL); 7526 7527 if (devlink_linecard_index_exists(devlink, linecard_index)) 7528 return ERR_PTR(-EEXIST); 7529 7530 linecard = kzalloc(sizeof(*linecard), GFP_KERNEL); 7531 if (!linecard) 7532 return ERR_PTR(-ENOMEM); 7533 7534 linecard->devlink = devlink; 7535 linecard->index = linecard_index; 7536 linecard->ops = ops; 7537 linecard->priv = priv; 7538 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; 7539 mutex_init(&linecard->state_lock); 7540 7541 err = devlink_linecard_types_init(linecard); 7542 if (err) { 7543 mutex_destroy(&linecard->state_lock); 7544 kfree(linecard); 7545 return ERR_PTR(err); 7546 } 7547 7548 list_add_tail(&linecard->list, &devlink->linecard_list); 7549 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 7550 return linecard; 7551} 7552EXPORT_SYMBOL_GPL(devl_linecard_create); 7553 7554/** 7555 * devl_linecard_destroy - Destroy devlink linecard 7556 * 7557 * @linecard: devlink linecard 7558 */ 7559void devl_linecard_destroy(struct devlink_linecard *linecard) 7560{ 7561 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL); 7562 list_del(&linecard->list); 7563 devlink_linecard_types_fini(linecard); 7564 mutex_destroy(&linecard->state_lock); 7565 kfree(linecard); 7566} 7567EXPORT_SYMBOL_GPL(devl_linecard_destroy); 7568 7569/** 7570 * devlink_linecard_provision_set - Set provisioning on linecard 7571 * 7572 * @linecard: devlink linecard 7573 * @type: linecard type 7574 * 7575 * This is either called directly from the provision() op call or 7576 * as a result of the provision() op call asynchronously. 7577 */ 7578void devlink_linecard_provision_set(struct devlink_linecard *linecard, 7579 const char *type) 7580{ 7581 mutex_lock(&linecard->state_lock); 7582 WARN_ON(linecard->type && strcmp(linecard->type, type)); 7583 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED; 7584 linecard->type = type; 7585 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 7586 mutex_unlock(&linecard->state_lock); 7587} 7588EXPORT_SYMBOL_GPL(devlink_linecard_provision_set); 7589 7590/** 7591 * devlink_linecard_provision_clear - Clear provisioning on linecard 7592 * 7593 * @linecard: devlink linecard 7594 * 7595 * This is either called directly from the unprovision() op call or 7596 * as a result of the unprovision() op call asynchronously. 7597 */ 7598void devlink_linecard_provision_clear(struct devlink_linecard *linecard) 7599{ 7600 mutex_lock(&linecard->state_lock); 7601 WARN_ON(linecard->nested_devlink); 7602 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; 7603 linecard->type = NULL; 7604 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 7605 mutex_unlock(&linecard->state_lock); 7606} 7607EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear); 7608 7609/** 7610 * devlink_linecard_provision_fail - Fail provisioning on linecard 7611 * 7612 * @linecard: devlink linecard 7613 * 7614 * This is either called directly from the provision() op call or 7615 * as a result of the provision() op call asynchronously. 7616 */ 7617void devlink_linecard_provision_fail(struct devlink_linecard *linecard) 7618{ 7619 mutex_lock(&linecard->state_lock); 7620 WARN_ON(linecard->nested_devlink); 7621 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED; 7622 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 7623 mutex_unlock(&linecard->state_lock); 7624} 7625EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail); 7626 7627/** 7628 * devlink_linecard_activate - Set linecard active 7629 * 7630 * @linecard: devlink linecard 7631 */ 7632void devlink_linecard_activate(struct devlink_linecard *linecard) 7633{ 7634 mutex_lock(&linecard->state_lock); 7635 WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED); 7636 linecard->state = DEVLINK_LINECARD_STATE_ACTIVE; 7637 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 7638 mutex_unlock(&linecard->state_lock); 7639} 7640EXPORT_SYMBOL_GPL(devlink_linecard_activate); 7641 7642/** 7643 * devlink_linecard_deactivate - Set linecard inactive 7644 * 7645 * @linecard: devlink linecard 7646 */ 7647void devlink_linecard_deactivate(struct devlink_linecard *linecard) 7648{ 7649 mutex_lock(&linecard->state_lock); 7650 switch (linecard->state) { 7651 case DEVLINK_LINECARD_STATE_ACTIVE: 7652 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED; 7653 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 7654 break; 7655 case DEVLINK_LINECARD_STATE_UNPROVISIONING: 7656 /* Line card is being deactivated as part 7657 * of unprovisioning flow. 7658 */ 7659 break; 7660 default: 7661 WARN_ON(1); 7662 break; 7663 } 7664 mutex_unlock(&linecard->state_lock); 7665} 7666EXPORT_SYMBOL_GPL(devlink_linecard_deactivate); 7667 7668/** 7669 * devlink_linecard_nested_dl_set - Attach/detach nested devlink 7670 * instance to linecard. 7671 * 7672 * @linecard: devlink linecard 7673 * @nested_devlink: devlink instance to attach or NULL to detach 7674 */ 7675void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard, 7676 struct devlink *nested_devlink) 7677{ 7678 mutex_lock(&linecard->state_lock); 7679 linecard->nested_devlink = nested_devlink; 7680 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); 7681 mutex_unlock(&linecard->state_lock); 7682} 7683EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set); 7684 7685int devl_sb_register(struct devlink *devlink, unsigned int sb_index, 7686 u32 size, u16 ingress_pools_count, 7687 u16 egress_pools_count, u16 ingress_tc_count, 7688 u16 egress_tc_count) 7689{ 7690 struct devlink_sb *devlink_sb; 7691 7692 lockdep_assert_held(&devlink->lock); 7693 7694 if (devlink_sb_index_exists(devlink, sb_index)) 7695 return -EEXIST; 7696 7697 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL); 7698 if (!devlink_sb) 7699 return -ENOMEM; 7700 devlink_sb->index = sb_index; 7701 devlink_sb->size = size; 7702 devlink_sb->ingress_pools_count = ingress_pools_count; 7703 devlink_sb->egress_pools_count = egress_pools_count; 7704 devlink_sb->ingress_tc_count = ingress_tc_count; 7705 devlink_sb->egress_tc_count = egress_tc_count; 7706 list_add_tail(&devlink_sb->list, &devlink->sb_list); 7707 return 0; 7708} 7709EXPORT_SYMBOL_GPL(devl_sb_register); 7710 7711int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, 7712 u32 size, u16 ingress_pools_count, 7713 u16 egress_pools_count, u16 ingress_tc_count, 7714 u16 egress_tc_count) 7715{ 7716 int err; 7717 7718 devl_lock(devlink); 7719 err = devl_sb_register(devlink, sb_index, size, ingress_pools_count, 7720 egress_pools_count, ingress_tc_count, 7721 egress_tc_count); 7722 devl_unlock(devlink); 7723 return err; 7724} 7725EXPORT_SYMBOL_GPL(devlink_sb_register); 7726 7727void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index) 7728{ 7729 struct devlink_sb *devlink_sb; 7730 7731 lockdep_assert_held(&devlink->lock); 7732 7733 devlink_sb = devlink_sb_get_by_index(devlink, sb_index); 7734 WARN_ON(!devlink_sb); 7735 list_del(&devlink_sb->list); 7736 kfree(devlink_sb); 7737} 7738EXPORT_SYMBOL_GPL(devl_sb_unregister); 7739 7740void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index) 7741{ 7742 devl_lock(devlink); 7743 devl_sb_unregister(devlink, sb_index); 7744 devl_unlock(devlink); 7745} 7746EXPORT_SYMBOL_GPL(devlink_sb_unregister); 7747 7748/** 7749 * devl_dpipe_headers_register - register dpipe headers 7750 * 7751 * @devlink: devlink 7752 * @dpipe_headers: dpipe header array 7753 * 7754 * Register the headers supported by hardware. 7755 */ 7756void devl_dpipe_headers_register(struct devlink *devlink, 7757 struct devlink_dpipe_headers *dpipe_headers) 7758{ 7759 lockdep_assert_held(&devlink->lock); 7760 7761 devlink->dpipe_headers = dpipe_headers; 7762} 7763EXPORT_SYMBOL_GPL(devl_dpipe_headers_register); 7764 7765/** 7766 * devl_dpipe_headers_unregister - unregister dpipe headers 7767 * 7768 * @devlink: devlink 7769 * 7770 * Unregister the headers supported by hardware. 7771 */ 7772void devl_dpipe_headers_unregister(struct devlink *devlink) 7773{ 7774 lockdep_assert_held(&devlink->lock); 7775 7776 devlink->dpipe_headers = NULL; 7777} 7778EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister); 7779 7780/** 7781 * devlink_dpipe_table_counter_enabled - check if counter allocation 7782 * required 7783 * @devlink: devlink 7784 * @table_name: tables name 7785 * 7786 * Used by driver to check if counter allocation is required. 7787 * After counter allocation is turned on the table entries 7788 * are updated to include counter statistics. 7789 * 7790 * After that point on the driver must respect the counter 7791 * state so that each entry added to the table is added 7792 * with a counter. 7793 */ 7794bool devlink_dpipe_table_counter_enabled(struct devlink *devlink, 7795 const char *table_name) 7796{ 7797 struct devlink_dpipe_table *table; 7798 bool enabled; 7799 7800 rcu_read_lock(); 7801 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 7802 table_name, devlink); 7803 enabled = false; 7804 if (table) 7805 enabled = table->counters_enabled; 7806 rcu_read_unlock(); 7807 return enabled; 7808} 7809EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled); 7810 7811/** 7812 * devl_dpipe_table_register - register dpipe table 7813 * 7814 * @devlink: devlink 7815 * @table_name: table name 7816 * @table_ops: table ops 7817 * @priv: priv 7818 * @counter_control_extern: external control for counters 7819 */ 7820int devl_dpipe_table_register(struct devlink *devlink, 7821 const char *table_name, 7822 struct devlink_dpipe_table_ops *table_ops, 7823 void *priv, bool counter_control_extern) 7824{ 7825 struct devlink_dpipe_table *table; 7826 7827 lockdep_assert_held(&devlink->lock); 7828 7829 if (WARN_ON(!table_ops->size_get)) 7830 return -EINVAL; 7831 7832 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name, 7833 devlink)) 7834 return -EEXIST; 7835 7836 table = kzalloc(sizeof(*table), GFP_KERNEL); 7837 if (!table) 7838 return -ENOMEM; 7839 7840 table->name = table_name; 7841 table->table_ops = table_ops; 7842 table->priv = priv; 7843 table->counter_control_extern = counter_control_extern; 7844 7845 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list); 7846 7847 return 0; 7848} 7849EXPORT_SYMBOL_GPL(devl_dpipe_table_register); 7850 7851/** 7852 * devl_dpipe_table_unregister - unregister dpipe table 7853 * 7854 * @devlink: devlink 7855 * @table_name: table name 7856 */ 7857void devl_dpipe_table_unregister(struct devlink *devlink, 7858 const char *table_name) 7859{ 7860 struct devlink_dpipe_table *table; 7861 7862 lockdep_assert_held(&devlink->lock); 7863 7864 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 7865 table_name, devlink); 7866 if (!table) 7867 return; 7868 list_del_rcu(&table->list); 7869 kfree_rcu(table, rcu); 7870} 7871EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister); 7872 7873/** 7874 * devl_resource_register - devlink resource register 7875 * 7876 * @devlink: devlink 7877 * @resource_name: resource's name 7878 * @resource_size: resource's size 7879 * @resource_id: resource's id 7880 * @parent_resource_id: resource's parent id 7881 * @size_params: size parameters 7882 * 7883 * Generic resources should reuse the same names across drivers. 7884 * Please see the generic resources list at: 7885 * Documentation/networking/devlink/devlink-resource.rst 7886 */ 7887int devl_resource_register(struct devlink *devlink, 7888 const char *resource_name, 7889 u64 resource_size, 7890 u64 resource_id, 7891 u64 parent_resource_id, 7892 const struct devlink_resource_size_params *size_params) 7893{ 7894 struct devlink_resource *resource; 7895 struct list_head *resource_list; 7896 bool top_hierarchy; 7897 7898 lockdep_assert_held(&devlink->lock); 7899 7900 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP; 7901 7902 resource = devlink_resource_find(devlink, NULL, resource_id); 7903 if (resource) 7904 return -EINVAL; 7905 7906 resource = kzalloc(sizeof(*resource), GFP_KERNEL); 7907 if (!resource) 7908 return -ENOMEM; 7909 7910 if (top_hierarchy) { 7911 resource_list = &devlink->resource_list; 7912 } else { 7913 struct devlink_resource *parent_resource; 7914 7915 parent_resource = devlink_resource_find(devlink, NULL, 7916 parent_resource_id); 7917 if (parent_resource) { 7918 resource_list = &parent_resource->resource_list; 7919 resource->parent = parent_resource; 7920 } else { 7921 kfree(resource); 7922 return -EINVAL; 7923 } 7924 } 7925 7926 resource->name = resource_name; 7927 resource->size = resource_size; 7928 resource->size_new = resource_size; 7929 resource->id = resource_id; 7930 resource->size_valid = true; 7931 memcpy(&resource->size_params, size_params, 7932 sizeof(resource->size_params)); 7933 INIT_LIST_HEAD(&resource->resource_list); 7934 list_add_tail(&resource->list, resource_list); 7935 7936 return 0; 7937} 7938EXPORT_SYMBOL_GPL(devl_resource_register); 7939 7940/** 7941 * devlink_resource_register - devlink resource register 7942 * 7943 * @devlink: devlink 7944 * @resource_name: resource's name 7945 * @resource_size: resource's size 7946 * @resource_id: resource's id 7947 * @parent_resource_id: resource's parent id 7948 * @size_params: size parameters 7949 * 7950 * Generic resources should reuse the same names across drivers. 7951 * Please see the generic resources list at: 7952 * Documentation/networking/devlink/devlink-resource.rst 7953 * 7954 * Context: Takes and release devlink->lock <mutex>. 7955 */ 7956int devlink_resource_register(struct devlink *devlink, 7957 const char *resource_name, 7958 u64 resource_size, 7959 u64 resource_id, 7960 u64 parent_resource_id, 7961 const struct devlink_resource_size_params *size_params) 7962{ 7963 int err; 7964 7965 devl_lock(devlink); 7966 err = devl_resource_register(devlink, resource_name, resource_size, 7967 resource_id, parent_resource_id, size_params); 7968 devl_unlock(devlink); 7969 return err; 7970} 7971EXPORT_SYMBOL_GPL(devlink_resource_register); 7972 7973static void devlink_resource_unregister(struct devlink *devlink, 7974 struct devlink_resource *resource) 7975{ 7976 struct devlink_resource *tmp, *child_resource; 7977 7978 list_for_each_entry_safe(child_resource, tmp, &resource->resource_list, 7979 list) { 7980 devlink_resource_unregister(devlink, child_resource); 7981 list_del(&child_resource->list); 7982 kfree(child_resource); 7983 } 7984} 7985 7986/** 7987 * devl_resources_unregister - free all resources 7988 * 7989 * @devlink: devlink 7990 */ 7991void devl_resources_unregister(struct devlink *devlink) 7992{ 7993 struct devlink_resource *tmp, *child_resource; 7994 7995 lockdep_assert_held(&devlink->lock); 7996 7997 list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list, 7998 list) { 7999 devlink_resource_unregister(devlink, child_resource); 8000 list_del(&child_resource->list); 8001 kfree(child_resource); 8002 } 8003} 8004EXPORT_SYMBOL_GPL(devl_resources_unregister); 8005 8006/** 8007 * devlink_resources_unregister - free all resources 8008 * 8009 * @devlink: devlink 8010 * 8011 * Context: Takes and release devlink->lock <mutex>. 8012 */ 8013void devlink_resources_unregister(struct devlink *devlink) 8014{ 8015 devl_lock(devlink); 8016 devl_resources_unregister(devlink); 8017 devl_unlock(devlink); 8018} 8019EXPORT_SYMBOL_GPL(devlink_resources_unregister); 8020 8021/** 8022 * devl_resource_size_get - get and update size 8023 * 8024 * @devlink: devlink 8025 * @resource_id: the requested resource id 8026 * @p_resource_size: ptr to update 8027 */ 8028int devl_resource_size_get(struct devlink *devlink, 8029 u64 resource_id, 8030 u64 *p_resource_size) 8031{ 8032 struct devlink_resource *resource; 8033 8034 lockdep_assert_held(&devlink->lock); 8035 8036 resource = devlink_resource_find(devlink, NULL, resource_id); 8037 if (!resource) 8038 return -EINVAL; 8039 *p_resource_size = resource->size_new; 8040 resource->size = resource->size_new; 8041 return 0; 8042} 8043EXPORT_SYMBOL_GPL(devl_resource_size_get); 8044 8045/** 8046 * devl_dpipe_table_resource_set - set the resource id 8047 * 8048 * @devlink: devlink 8049 * @table_name: table name 8050 * @resource_id: resource id 8051 * @resource_units: number of resource's units consumed per table's entry 8052 */ 8053int devl_dpipe_table_resource_set(struct devlink *devlink, 8054 const char *table_name, u64 resource_id, 8055 u64 resource_units) 8056{ 8057 struct devlink_dpipe_table *table; 8058 8059 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8060 table_name, devlink); 8061 if (!table) 8062 return -EINVAL; 8063 8064 table->resource_id = resource_id; 8065 table->resource_units = resource_units; 8066 table->resource_valid = true; 8067 return 0; 8068} 8069EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set); 8070 8071/** 8072 * devl_resource_occ_get_register - register occupancy getter 8073 * 8074 * @devlink: devlink 8075 * @resource_id: resource id 8076 * @occ_get: occupancy getter callback 8077 * @occ_get_priv: occupancy getter callback priv 8078 */ 8079void devl_resource_occ_get_register(struct devlink *devlink, 8080 u64 resource_id, 8081 devlink_resource_occ_get_t *occ_get, 8082 void *occ_get_priv) 8083{ 8084 struct devlink_resource *resource; 8085 8086 lockdep_assert_held(&devlink->lock); 8087 8088 resource = devlink_resource_find(devlink, NULL, resource_id); 8089 if (WARN_ON(!resource)) 8090 return; 8091 WARN_ON(resource->occ_get); 8092 8093 resource->occ_get = occ_get; 8094 resource->occ_get_priv = occ_get_priv; 8095} 8096EXPORT_SYMBOL_GPL(devl_resource_occ_get_register); 8097 8098/** 8099 * devlink_resource_occ_get_register - register occupancy getter 8100 * 8101 * @devlink: devlink 8102 * @resource_id: resource id 8103 * @occ_get: occupancy getter callback 8104 * @occ_get_priv: occupancy getter callback priv 8105 * 8106 * Context: Takes and release devlink->lock <mutex>. 8107 */ 8108void devlink_resource_occ_get_register(struct devlink *devlink, 8109 u64 resource_id, 8110 devlink_resource_occ_get_t *occ_get, 8111 void *occ_get_priv) 8112{ 8113 devl_lock(devlink); 8114 devl_resource_occ_get_register(devlink, resource_id, 8115 occ_get, occ_get_priv); 8116 devl_unlock(devlink); 8117} 8118EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register); 8119 8120/** 8121 * devl_resource_occ_get_unregister - unregister occupancy getter 8122 * 8123 * @devlink: devlink 8124 * @resource_id: resource id 8125 */ 8126void devl_resource_occ_get_unregister(struct devlink *devlink, 8127 u64 resource_id) 8128{ 8129 struct devlink_resource *resource; 8130 8131 lockdep_assert_held(&devlink->lock); 8132 8133 resource = devlink_resource_find(devlink, NULL, resource_id); 8134 if (WARN_ON(!resource)) 8135 return; 8136 WARN_ON(!resource->occ_get); 8137 8138 resource->occ_get = NULL; 8139 resource->occ_get_priv = NULL; 8140} 8141EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister); 8142 8143/** 8144 * devlink_resource_occ_get_unregister - unregister occupancy getter 8145 * 8146 * @devlink: devlink 8147 * @resource_id: resource id 8148 * 8149 * Context: Takes and release devlink->lock <mutex>. 8150 */ 8151void devlink_resource_occ_get_unregister(struct devlink *devlink, 8152 u64 resource_id) 8153{ 8154 devl_lock(devlink); 8155 devl_resource_occ_get_unregister(devlink, resource_id); 8156 devl_unlock(devlink); 8157} 8158EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister); 8159 8160static int devlink_param_verify(const struct devlink_param *param) 8161{ 8162 if (!param || !param->name || !param->supported_cmodes) 8163 return -EINVAL; 8164 if (param->generic) 8165 return devlink_param_generic_verify(param); 8166 else 8167 return devlink_param_driver_verify(param); 8168} 8169 8170static int devlink_param_register(struct devlink *devlink, 8171 const struct devlink_param *param) 8172{ 8173 struct devlink_param_item *param_item; 8174 int err; 8175 8176 WARN_ON(devlink_param_verify(param)); 8177 WARN_ON(devlink_param_find_by_name(&devlink->params, param->name)); 8178 8179 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT)) 8180 WARN_ON(param->get || param->set); 8181 else 8182 WARN_ON(!param->get || !param->set); 8183 8184 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL); 8185 if (!param_item) 8186 return -ENOMEM; 8187 8188 param_item->param = param; 8189 8190 err = xa_insert(&devlink->params, param->id, param_item, GFP_KERNEL); 8191 if (err) 8192 goto err_xa_insert; 8193 8194 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 8195 return 0; 8196 8197err_xa_insert: 8198 kfree(param_item); 8199 return err; 8200} 8201 8202static void devlink_param_unregister(struct devlink *devlink, 8203 const struct devlink_param *param) 8204{ 8205 struct devlink_param_item *param_item; 8206 8207 param_item = devlink_param_find_by_id(&devlink->params, param->id); 8208 if (WARN_ON(!param_item)) 8209 return; 8210 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL); 8211 xa_erase(&devlink->params, param->id); 8212 kfree(param_item); 8213} 8214 8215/** 8216 * devl_params_register - register configuration parameters 8217 * 8218 * @devlink: devlink 8219 * @params: configuration parameters array 8220 * @params_count: number of parameters provided 8221 * 8222 * Register the configuration parameters supported by the driver. 8223 */ 8224int devl_params_register(struct devlink *devlink, 8225 const struct devlink_param *params, 8226 size_t params_count) 8227{ 8228 const struct devlink_param *param = params; 8229 int i, err; 8230 8231 lockdep_assert_held(&devlink->lock); 8232 8233 for (i = 0; i < params_count; i++, param++) { 8234 err = devlink_param_register(devlink, param); 8235 if (err) 8236 goto rollback; 8237 } 8238 return 0; 8239 8240rollback: 8241 if (!i) 8242 return err; 8243 8244 for (param--; i > 0; i--, param--) 8245 devlink_param_unregister(devlink, param); 8246 return err; 8247} 8248EXPORT_SYMBOL_GPL(devl_params_register); 8249 8250int devlink_params_register(struct devlink *devlink, 8251 const struct devlink_param *params, 8252 size_t params_count) 8253{ 8254 int err; 8255 8256 devl_lock(devlink); 8257 err = devl_params_register(devlink, params, params_count); 8258 devl_unlock(devlink); 8259 return err; 8260} 8261EXPORT_SYMBOL_GPL(devlink_params_register); 8262 8263/** 8264 * devl_params_unregister - unregister configuration parameters 8265 * @devlink: devlink 8266 * @params: configuration parameters to unregister 8267 * @params_count: number of parameters provided 8268 */ 8269void devl_params_unregister(struct devlink *devlink, 8270 const struct devlink_param *params, 8271 size_t params_count) 8272{ 8273 const struct devlink_param *param = params; 8274 int i; 8275 8276 lockdep_assert_held(&devlink->lock); 8277 8278 for (i = 0; i < params_count; i++, param++) 8279 devlink_param_unregister(devlink, param); 8280} 8281EXPORT_SYMBOL_GPL(devl_params_unregister); 8282 8283void devlink_params_unregister(struct devlink *devlink, 8284 const struct devlink_param *params, 8285 size_t params_count) 8286{ 8287 devl_lock(devlink); 8288 devl_params_unregister(devlink, params, params_count); 8289 devl_unlock(devlink); 8290} 8291EXPORT_SYMBOL_GPL(devlink_params_unregister); 8292 8293/** 8294 * devl_param_driverinit_value_get - get configuration parameter 8295 * value for driver initializing 8296 * 8297 * @devlink: devlink 8298 * @param_id: parameter ID 8299 * @val: pointer to store the value of parameter in driverinit 8300 * configuration mode 8301 * 8302 * This function should be used by the driver to get driverinit 8303 * configuration for initialization after reload command. 8304 * 8305 * Note that lockless call of this function relies on the 8306 * driver to maintain following basic sane behavior: 8307 * 1) Driver ensures a call to this function cannot race with 8308 * registering/unregistering the parameter with the same parameter ID. 8309 * 2) Driver ensures a call to this function cannot race with 8310 * devl_param_driverinit_value_set() call with the same parameter ID. 8311 * 3) Driver ensures a call to this function cannot race with 8312 * reload operation. 8313 * If the driver is not able to comply, it has to take the devlink->lock 8314 * while calling this. 8315 */ 8316int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id, 8317 union devlink_param_value *val) 8318{ 8319 struct devlink_param_item *param_item; 8320 8321 if (WARN_ON(!devlink_reload_supported(devlink->ops))) 8322 return -EOPNOTSUPP; 8323 8324 param_item = devlink_param_find_by_id(&devlink->params, param_id); 8325 if (!param_item) 8326 return -EINVAL; 8327 8328 if (!param_item->driverinit_value_valid) 8329 return -EOPNOTSUPP; 8330 8331 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param, 8332 DEVLINK_PARAM_CMODE_DRIVERINIT))) 8333 return -EOPNOTSUPP; 8334 8335 *val = param_item->driverinit_value; 8336 8337 return 0; 8338} 8339EXPORT_SYMBOL_GPL(devl_param_driverinit_value_get); 8340 8341/** 8342 * devl_param_driverinit_value_set - set value of configuration 8343 * parameter for driverinit 8344 * configuration mode 8345 * 8346 * @devlink: devlink 8347 * @param_id: parameter ID 8348 * @init_val: value of parameter to set for driverinit configuration mode 8349 * 8350 * This function should be used by the driver to set driverinit 8351 * configuration mode default value. 8352 */ 8353void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id, 8354 union devlink_param_value init_val) 8355{ 8356 struct devlink_param_item *param_item; 8357 8358 devl_assert_locked(devlink); 8359 8360 param_item = devlink_param_find_by_id(&devlink->params, param_id); 8361 if (WARN_ON(!param_item)) 8362 return; 8363 8364 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param, 8365 DEVLINK_PARAM_CMODE_DRIVERINIT))) 8366 return; 8367 8368 param_item->driverinit_value = init_val; 8369 param_item->driverinit_value_valid = true; 8370 8371 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 8372} 8373EXPORT_SYMBOL_GPL(devl_param_driverinit_value_set); 8374 8375void devlink_params_driverinit_load_new(struct devlink *devlink) 8376{ 8377 struct devlink_param_item *param_item; 8378 unsigned long param_id; 8379 8380 xa_for_each(&devlink->params, param_id, param_item) { 8381 if (!devlink_param_cmode_is_supported(param_item->param, 8382 DEVLINK_PARAM_CMODE_DRIVERINIT) || 8383 !param_item->driverinit_value_new_valid) 8384 continue; 8385 param_item->driverinit_value = param_item->driverinit_value_new; 8386 param_item->driverinit_value_valid = true; 8387 param_item->driverinit_value_new_valid = false; 8388 } 8389} 8390 8391/** 8392 * devl_param_value_changed - notify devlink on a parameter's value 8393 * change. Should be called by the driver 8394 * right after the change. 8395 * 8396 * @devlink: devlink 8397 * @param_id: parameter ID 8398 * 8399 * This function should be used by the driver to notify devlink on value 8400 * change, excluding driverinit configuration mode. 8401 * For driverinit configuration mode driver should use the function 8402 */ 8403void devl_param_value_changed(struct devlink *devlink, u32 param_id) 8404{ 8405 struct devlink_param_item *param_item; 8406 8407 param_item = devlink_param_find_by_id(&devlink->params, param_id); 8408 WARN_ON(!param_item); 8409 8410 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 8411} 8412EXPORT_SYMBOL_GPL(devl_param_value_changed); 8413 8414/** 8415 * devl_region_create - create a new address region 8416 * 8417 * @devlink: devlink 8418 * @ops: region operations and name 8419 * @region_max_snapshots: Maximum supported number of snapshots for region 8420 * @region_size: size of region 8421 */ 8422struct devlink_region *devl_region_create(struct devlink *devlink, 8423 const struct devlink_region_ops *ops, 8424 u32 region_max_snapshots, 8425 u64 region_size) 8426{ 8427 struct devlink_region *region; 8428 8429 devl_assert_locked(devlink); 8430 8431 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 8432 return ERR_PTR(-EINVAL); 8433 8434 if (devlink_region_get_by_name(devlink, ops->name)) 8435 return ERR_PTR(-EEXIST); 8436 8437 region = kzalloc(sizeof(*region), GFP_KERNEL); 8438 if (!region) 8439 return ERR_PTR(-ENOMEM); 8440 8441 region->devlink = devlink; 8442 region->max_snapshots = region_max_snapshots; 8443 region->ops = ops; 8444 region->size = region_size; 8445 INIT_LIST_HEAD(&region->snapshot_list); 8446 mutex_init(&region->snapshot_lock); 8447 list_add_tail(&region->list, &devlink->region_list); 8448 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 8449 8450 return region; 8451} 8452EXPORT_SYMBOL_GPL(devl_region_create); 8453 8454/** 8455 * devlink_region_create - create a new address region 8456 * 8457 * @devlink: devlink 8458 * @ops: region operations and name 8459 * @region_max_snapshots: Maximum supported number of snapshots for region 8460 * @region_size: size of region 8461 * 8462 * Context: Takes and release devlink->lock <mutex>. 8463 */ 8464struct devlink_region * 8465devlink_region_create(struct devlink *devlink, 8466 const struct devlink_region_ops *ops, 8467 u32 region_max_snapshots, u64 region_size) 8468{ 8469 struct devlink_region *region; 8470 8471 devl_lock(devlink); 8472 region = devl_region_create(devlink, ops, region_max_snapshots, 8473 region_size); 8474 devl_unlock(devlink); 8475 return region; 8476} 8477EXPORT_SYMBOL_GPL(devlink_region_create); 8478 8479/** 8480 * devlink_port_region_create - create a new address region for a port 8481 * 8482 * @port: devlink port 8483 * @ops: region operations and name 8484 * @region_max_snapshots: Maximum supported number of snapshots for region 8485 * @region_size: size of region 8486 * 8487 * Context: Takes and release devlink->lock <mutex>. 8488 */ 8489struct devlink_region * 8490devlink_port_region_create(struct devlink_port *port, 8491 const struct devlink_port_region_ops *ops, 8492 u32 region_max_snapshots, u64 region_size) 8493{ 8494 struct devlink *devlink = port->devlink; 8495 struct devlink_region *region; 8496 int err = 0; 8497 8498 ASSERT_DEVLINK_PORT_INITIALIZED(port); 8499 8500 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 8501 return ERR_PTR(-EINVAL); 8502 8503 devl_lock(devlink); 8504 8505 if (devlink_port_region_get_by_name(port, ops->name)) { 8506 err = -EEXIST; 8507 goto unlock; 8508 } 8509 8510 region = kzalloc(sizeof(*region), GFP_KERNEL); 8511 if (!region) { 8512 err = -ENOMEM; 8513 goto unlock; 8514 } 8515 8516 region->devlink = devlink; 8517 region->port = port; 8518 region->max_snapshots = region_max_snapshots; 8519 region->port_ops = ops; 8520 region->size = region_size; 8521 INIT_LIST_HEAD(&region->snapshot_list); 8522 mutex_init(&region->snapshot_lock); 8523 list_add_tail(&region->list, &port->region_list); 8524 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 8525 8526 devl_unlock(devlink); 8527 return region; 8528 8529unlock: 8530 devl_unlock(devlink); 8531 return ERR_PTR(err); 8532} 8533EXPORT_SYMBOL_GPL(devlink_port_region_create); 8534 8535/** 8536 * devl_region_destroy - destroy address region 8537 * 8538 * @region: devlink region to destroy 8539 */ 8540void devl_region_destroy(struct devlink_region *region) 8541{ 8542 struct devlink *devlink = region->devlink; 8543 struct devlink_snapshot *snapshot, *ts; 8544 8545 devl_assert_locked(devlink); 8546 8547 /* Free all snapshots of region */ 8548 mutex_lock(&region->snapshot_lock); 8549 list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list) 8550 devlink_region_snapshot_del(region, snapshot); 8551 mutex_unlock(&region->snapshot_lock); 8552 8553 list_del(&region->list); 8554 mutex_destroy(&region->snapshot_lock); 8555 8556 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); 8557 kfree(region); 8558} 8559EXPORT_SYMBOL_GPL(devl_region_destroy); 8560 8561/** 8562 * devlink_region_destroy - destroy address region 8563 * 8564 * @region: devlink region to destroy 8565 * 8566 * Context: Takes and release devlink->lock <mutex>. 8567 */ 8568void devlink_region_destroy(struct devlink_region *region) 8569{ 8570 struct devlink *devlink = region->devlink; 8571 8572 devl_lock(devlink); 8573 devl_region_destroy(region); 8574 devl_unlock(devlink); 8575} 8576EXPORT_SYMBOL_GPL(devlink_region_destroy); 8577 8578/** 8579 * devlink_region_snapshot_id_get - get snapshot ID 8580 * 8581 * This callback should be called when adding a new snapshot, 8582 * Driver should use the same id for multiple snapshots taken 8583 * on multiple regions at the same time/by the same trigger. 8584 * 8585 * The caller of this function must use devlink_region_snapshot_id_put 8586 * when finished creating regions using this id. 8587 * 8588 * Returns zero on success, or a negative error code on failure. 8589 * 8590 * @devlink: devlink 8591 * @id: storage to return id 8592 */ 8593int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 8594{ 8595 return __devlink_region_snapshot_id_get(devlink, id); 8596} 8597EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); 8598 8599/** 8600 * devlink_region_snapshot_id_put - put snapshot ID reference 8601 * 8602 * This should be called by a driver after finishing creating snapshots 8603 * with an id. Doing so ensures that the ID can later be released in the 8604 * event that all snapshots using it have been destroyed. 8605 * 8606 * @devlink: devlink 8607 * @id: id to release reference on 8608 */ 8609void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) 8610{ 8611 __devlink_snapshot_id_decrement(devlink, id); 8612} 8613EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); 8614 8615/** 8616 * devlink_region_snapshot_create - create a new snapshot 8617 * This will add a new snapshot of a region. The snapshot 8618 * will be stored on the region struct and can be accessed 8619 * from devlink. This is useful for future analyses of snapshots. 8620 * Multiple snapshots can be created on a region. 8621 * The @snapshot_id should be obtained using the getter function. 8622 * 8623 * @region: devlink region of the snapshot 8624 * @data: snapshot data 8625 * @snapshot_id: snapshot id to be created 8626 */ 8627int devlink_region_snapshot_create(struct devlink_region *region, 8628 u8 *data, u32 snapshot_id) 8629{ 8630 int err; 8631 8632 mutex_lock(&region->snapshot_lock); 8633 err = __devlink_region_snapshot_create(region, data, snapshot_id); 8634 mutex_unlock(&region->snapshot_lock); 8635 return err; 8636} 8637EXPORT_SYMBOL_GPL(devlink_region_snapshot_create); 8638 8639#define DEVLINK_TRAP(_id, _type) \ 8640 { \ 8641 .type = DEVLINK_TRAP_TYPE_##_type, \ 8642 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \ 8643 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \ 8644 } 8645 8646static const struct devlink_trap devlink_trap_generic[] = { 8647 DEVLINK_TRAP(SMAC_MC, DROP), 8648 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP), 8649 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP), 8650 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP), 8651 DEVLINK_TRAP(EMPTY_TX_LIST, DROP), 8652 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP), 8653 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP), 8654 DEVLINK_TRAP(TTL_ERROR, EXCEPTION), 8655 DEVLINK_TRAP(TAIL_DROP, DROP), 8656 DEVLINK_TRAP(NON_IP_PACKET, DROP), 8657 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP), 8658 DEVLINK_TRAP(DIP_LB, DROP), 8659 DEVLINK_TRAP(SIP_MC, DROP), 8660 DEVLINK_TRAP(SIP_LB, DROP), 8661 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP), 8662 DEVLINK_TRAP(IPV4_SIP_BC, DROP), 8663 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP), 8664 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP), 8665 DEVLINK_TRAP(MTU_ERROR, EXCEPTION), 8666 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION), 8667 DEVLINK_TRAP(RPF, EXCEPTION), 8668 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION), 8669 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION), 8670 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION), 8671 DEVLINK_TRAP(NON_ROUTABLE, DROP), 8672 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION), 8673 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP), 8674 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP), 8675 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP), 8676 DEVLINK_TRAP(STP, CONTROL), 8677 DEVLINK_TRAP(LACP, CONTROL), 8678 DEVLINK_TRAP(LLDP, CONTROL), 8679 DEVLINK_TRAP(IGMP_QUERY, CONTROL), 8680 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL), 8681 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL), 8682 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL), 8683 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL), 8684 DEVLINK_TRAP(MLD_QUERY, CONTROL), 8685 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL), 8686 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL), 8687 DEVLINK_TRAP(MLD_V1_DONE, CONTROL), 8688 DEVLINK_TRAP(IPV4_DHCP, CONTROL), 8689 DEVLINK_TRAP(IPV6_DHCP, CONTROL), 8690 DEVLINK_TRAP(ARP_REQUEST, CONTROL), 8691 DEVLINK_TRAP(ARP_RESPONSE, CONTROL), 8692 DEVLINK_TRAP(ARP_OVERLAY, CONTROL), 8693 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL), 8694 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL), 8695 DEVLINK_TRAP(IPV4_BFD, CONTROL), 8696 DEVLINK_TRAP(IPV6_BFD, CONTROL), 8697 DEVLINK_TRAP(IPV4_OSPF, CONTROL), 8698 DEVLINK_TRAP(IPV6_OSPF, CONTROL), 8699 DEVLINK_TRAP(IPV4_BGP, CONTROL), 8700 DEVLINK_TRAP(IPV6_BGP, CONTROL), 8701 DEVLINK_TRAP(IPV4_VRRP, CONTROL), 8702 DEVLINK_TRAP(IPV6_VRRP, CONTROL), 8703 DEVLINK_TRAP(IPV4_PIM, CONTROL), 8704 DEVLINK_TRAP(IPV6_PIM, CONTROL), 8705 DEVLINK_TRAP(UC_LB, CONTROL), 8706 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL), 8707 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL), 8708 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL), 8709 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL), 8710 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL), 8711 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL), 8712 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL), 8713 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL), 8714 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL), 8715 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL), 8716 DEVLINK_TRAP(PTP_EVENT, CONTROL), 8717 DEVLINK_TRAP(PTP_GENERAL, CONTROL), 8718 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL), 8719 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL), 8720 DEVLINK_TRAP(EARLY_DROP, DROP), 8721 DEVLINK_TRAP(VXLAN_PARSING, DROP), 8722 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP), 8723 DEVLINK_TRAP(VLAN_PARSING, DROP), 8724 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP), 8725 DEVLINK_TRAP(MPLS_PARSING, DROP), 8726 DEVLINK_TRAP(ARP_PARSING, DROP), 8727 DEVLINK_TRAP(IP_1_PARSING, DROP), 8728 DEVLINK_TRAP(IP_N_PARSING, DROP), 8729 DEVLINK_TRAP(GRE_PARSING, DROP), 8730 DEVLINK_TRAP(UDP_PARSING, DROP), 8731 DEVLINK_TRAP(TCP_PARSING, DROP), 8732 DEVLINK_TRAP(IPSEC_PARSING, DROP), 8733 DEVLINK_TRAP(SCTP_PARSING, DROP), 8734 DEVLINK_TRAP(DCCP_PARSING, DROP), 8735 DEVLINK_TRAP(GTP_PARSING, DROP), 8736 DEVLINK_TRAP(ESP_PARSING, DROP), 8737 DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP), 8738 DEVLINK_TRAP(DMAC_FILTER, DROP), 8739 DEVLINK_TRAP(EAPOL, CONTROL), 8740 DEVLINK_TRAP(LOCKED_PORT, DROP), 8741}; 8742 8743#define DEVLINK_TRAP_GROUP(_id) \ 8744 { \ 8745 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \ 8746 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \ 8747 } 8748 8749static const struct devlink_trap_group devlink_trap_group_generic[] = { 8750 DEVLINK_TRAP_GROUP(L2_DROPS), 8751 DEVLINK_TRAP_GROUP(L3_DROPS), 8752 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS), 8753 DEVLINK_TRAP_GROUP(BUFFER_DROPS), 8754 DEVLINK_TRAP_GROUP(TUNNEL_DROPS), 8755 DEVLINK_TRAP_GROUP(ACL_DROPS), 8756 DEVLINK_TRAP_GROUP(STP), 8757 DEVLINK_TRAP_GROUP(LACP), 8758 DEVLINK_TRAP_GROUP(LLDP), 8759 DEVLINK_TRAP_GROUP(MC_SNOOPING), 8760 DEVLINK_TRAP_GROUP(DHCP), 8761 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY), 8762 DEVLINK_TRAP_GROUP(BFD), 8763 DEVLINK_TRAP_GROUP(OSPF), 8764 DEVLINK_TRAP_GROUP(BGP), 8765 DEVLINK_TRAP_GROUP(VRRP), 8766 DEVLINK_TRAP_GROUP(PIM), 8767 DEVLINK_TRAP_GROUP(UC_LB), 8768 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY), 8769 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY), 8770 DEVLINK_TRAP_GROUP(IPV6), 8771 DEVLINK_TRAP_GROUP(PTP_EVENT), 8772 DEVLINK_TRAP_GROUP(PTP_GENERAL), 8773 DEVLINK_TRAP_GROUP(ACL_SAMPLE), 8774 DEVLINK_TRAP_GROUP(ACL_TRAP), 8775 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS), 8776 DEVLINK_TRAP_GROUP(EAPOL), 8777}; 8778 8779static int devlink_trap_generic_verify(const struct devlink_trap *trap) 8780{ 8781 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX) 8782 return -EINVAL; 8783 8784 if (strcmp(trap->name, devlink_trap_generic[trap->id].name)) 8785 return -EINVAL; 8786 8787 if (trap->type != devlink_trap_generic[trap->id].type) 8788 return -EINVAL; 8789 8790 return 0; 8791} 8792 8793static int devlink_trap_driver_verify(const struct devlink_trap *trap) 8794{ 8795 int i; 8796 8797 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX) 8798 return -EINVAL; 8799 8800 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) { 8801 if (!strcmp(trap->name, devlink_trap_generic[i].name)) 8802 return -EEXIST; 8803 } 8804 8805 return 0; 8806} 8807 8808static int devlink_trap_verify(const struct devlink_trap *trap) 8809{ 8810 if (!trap || !trap->name) 8811 return -EINVAL; 8812 8813 if (trap->generic) 8814 return devlink_trap_generic_verify(trap); 8815 else 8816 return devlink_trap_driver_verify(trap); 8817} 8818 8819static int 8820devlink_trap_group_generic_verify(const struct devlink_trap_group *group) 8821{ 8822 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) 8823 return -EINVAL; 8824 8825 if (strcmp(group->name, devlink_trap_group_generic[group->id].name)) 8826 return -EINVAL; 8827 8828 return 0; 8829} 8830 8831static int 8832devlink_trap_group_driver_verify(const struct devlink_trap_group *group) 8833{ 8834 int i; 8835 8836 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) 8837 return -EINVAL; 8838 8839 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) { 8840 if (!strcmp(group->name, devlink_trap_group_generic[i].name)) 8841 return -EEXIST; 8842 } 8843 8844 return 0; 8845} 8846 8847static int devlink_trap_group_verify(const struct devlink_trap_group *group) 8848{ 8849 if (group->generic) 8850 return devlink_trap_group_generic_verify(group); 8851 else 8852 return devlink_trap_group_driver_verify(group); 8853} 8854 8855static void 8856devlink_trap_group_notify(struct devlink *devlink, 8857 const struct devlink_trap_group_item *group_item, 8858 enum devlink_command cmd) 8859{ 8860 struct sk_buff *msg; 8861 int err; 8862 8863 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW && 8864 cmd != DEVLINK_CMD_TRAP_GROUP_DEL); 8865 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 8866 return; 8867 8868 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 8869 if (!msg) 8870 return; 8871 8872 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0, 8873 0); 8874 if (err) { 8875 nlmsg_free(msg); 8876 return; 8877 } 8878 8879 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 8880 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 8881} 8882 8883static int 8884devlink_trap_item_group_link(struct devlink *devlink, 8885 struct devlink_trap_item *trap_item) 8886{ 8887 u16 group_id = trap_item->trap->init_group_id; 8888 struct devlink_trap_group_item *group_item; 8889 8890 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id); 8891 if (WARN_ON_ONCE(!group_item)) 8892 return -EINVAL; 8893 8894 trap_item->group_item = group_item; 8895 8896 return 0; 8897} 8898 8899static void devlink_trap_notify(struct devlink *devlink, 8900 const struct devlink_trap_item *trap_item, 8901 enum devlink_command cmd) 8902{ 8903 struct sk_buff *msg; 8904 int err; 8905 8906 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW && 8907 cmd != DEVLINK_CMD_TRAP_DEL); 8908 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 8909 return; 8910 8911 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 8912 if (!msg) 8913 return; 8914 8915 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0); 8916 if (err) { 8917 nlmsg_free(msg); 8918 return; 8919 } 8920 8921 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 8922 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 8923} 8924 8925static int 8926devlink_trap_register(struct devlink *devlink, 8927 const struct devlink_trap *trap, void *priv) 8928{ 8929 struct devlink_trap_item *trap_item; 8930 int err; 8931 8932 if (devlink_trap_item_lookup(devlink, trap->name)) 8933 return -EEXIST; 8934 8935 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL); 8936 if (!trap_item) 8937 return -ENOMEM; 8938 8939 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); 8940 if (!trap_item->stats) { 8941 err = -ENOMEM; 8942 goto err_stats_alloc; 8943 } 8944 8945 trap_item->trap = trap; 8946 trap_item->action = trap->init_action; 8947 trap_item->priv = priv; 8948 8949 err = devlink_trap_item_group_link(devlink, trap_item); 8950 if (err) 8951 goto err_group_link; 8952 8953 err = devlink->ops->trap_init(devlink, trap, trap_item); 8954 if (err) 8955 goto err_trap_init; 8956 8957 list_add_tail(&trap_item->list, &devlink->trap_list); 8958 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW); 8959 8960 return 0; 8961 8962err_trap_init: 8963err_group_link: 8964 free_percpu(trap_item->stats); 8965err_stats_alloc: 8966 kfree(trap_item); 8967 return err; 8968} 8969 8970static void devlink_trap_unregister(struct devlink *devlink, 8971 const struct devlink_trap *trap) 8972{ 8973 struct devlink_trap_item *trap_item; 8974 8975 trap_item = devlink_trap_item_lookup(devlink, trap->name); 8976 if (WARN_ON_ONCE(!trap_item)) 8977 return; 8978 8979 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL); 8980 list_del(&trap_item->list); 8981 if (devlink->ops->trap_fini) 8982 devlink->ops->trap_fini(devlink, trap, trap_item); 8983 free_percpu(trap_item->stats); 8984 kfree(trap_item); 8985} 8986 8987static void devlink_trap_disable(struct devlink *devlink, 8988 const struct devlink_trap *trap) 8989{ 8990 struct devlink_trap_item *trap_item; 8991 8992 trap_item = devlink_trap_item_lookup(devlink, trap->name); 8993 if (WARN_ON_ONCE(!trap_item)) 8994 return; 8995 8996 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP, 8997 NULL); 8998 trap_item->action = DEVLINK_TRAP_ACTION_DROP; 8999} 9000 9001/** 9002 * devl_traps_register - Register packet traps with devlink. 9003 * @devlink: devlink. 9004 * @traps: Packet traps. 9005 * @traps_count: Count of provided packet traps. 9006 * @priv: Driver private information. 9007 * 9008 * Return: Non-zero value on failure. 9009 */ 9010int devl_traps_register(struct devlink *devlink, 9011 const struct devlink_trap *traps, 9012 size_t traps_count, void *priv) 9013{ 9014 int i, err; 9015 9016 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set) 9017 return -EINVAL; 9018 9019 devl_assert_locked(devlink); 9020 for (i = 0; i < traps_count; i++) { 9021 const struct devlink_trap *trap = &traps[i]; 9022 9023 err = devlink_trap_verify(trap); 9024 if (err) 9025 goto err_trap_verify; 9026 9027 err = devlink_trap_register(devlink, trap, priv); 9028 if (err) 9029 goto err_trap_register; 9030 } 9031 9032 return 0; 9033 9034err_trap_register: 9035err_trap_verify: 9036 for (i--; i >= 0; i--) 9037 devlink_trap_unregister(devlink, &traps[i]); 9038 return err; 9039} 9040EXPORT_SYMBOL_GPL(devl_traps_register); 9041 9042/** 9043 * devlink_traps_register - Register packet traps with devlink. 9044 * @devlink: devlink. 9045 * @traps: Packet traps. 9046 * @traps_count: Count of provided packet traps. 9047 * @priv: Driver private information. 9048 * 9049 * Context: Takes and release devlink->lock <mutex>. 9050 * 9051 * Return: Non-zero value on failure. 9052 */ 9053int devlink_traps_register(struct devlink *devlink, 9054 const struct devlink_trap *traps, 9055 size_t traps_count, void *priv) 9056{ 9057 int err; 9058 9059 devl_lock(devlink); 9060 err = devl_traps_register(devlink, traps, traps_count, priv); 9061 devl_unlock(devlink); 9062 return err; 9063} 9064EXPORT_SYMBOL_GPL(devlink_traps_register); 9065 9066/** 9067 * devl_traps_unregister - Unregister packet traps from devlink. 9068 * @devlink: devlink. 9069 * @traps: Packet traps. 9070 * @traps_count: Count of provided packet traps. 9071 */ 9072void devl_traps_unregister(struct devlink *devlink, 9073 const struct devlink_trap *traps, 9074 size_t traps_count) 9075{ 9076 int i; 9077 9078 devl_assert_locked(devlink); 9079 /* Make sure we do not have any packets in-flight while unregistering 9080 * traps by disabling all of them and waiting for a grace period. 9081 */ 9082 for (i = traps_count - 1; i >= 0; i--) 9083 devlink_trap_disable(devlink, &traps[i]); 9084 synchronize_rcu(); 9085 for (i = traps_count - 1; i >= 0; i--) 9086 devlink_trap_unregister(devlink, &traps[i]); 9087} 9088EXPORT_SYMBOL_GPL(devl_traps_unregister); 9089 9090/** 9091 * devlink_traps_unregister - Unregister packet traps from devlink. 9092 * @devlink: devlink. 9093 * @traps: Packet traps. 9094 * @traps_count: Count of provided packet traps. 9095 * 9096 * Context: Takes and release devlink->lock <mutex>. 9097 */ 9098void devlink_traps_unregister(struct devlink *devlink, 9099 const struct devlink_trap *traps, 9100 size_t traps_count) 9101{ 9102 devl_lock(devlink); 9103 devl_traps_unregister(devlink, traps, traps_count); 9104 devl_unlock(devlink); 9105} 9106EXPORT_SYMBOL_GPL(devlink_traps_unregister); 9107 9108static void 9109devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats, 9110 size_t skb_len) 9111{ 9112 struct devlink_stats *stats; 9113 9114 stats = this_cpu_ptr(trap_stats); 9115 u64_stats_update_begin(&stats->syncp); 9116 u64_stats_add(&stats->rx_bytes, skb_len); 9117 u64_stats_inc(&stats->rx_packets); 9118 u64_stats_update_end(&stats->syncp); 9119} 9120 9121static void 9122devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata, 9123 const struct devlink_trap_item *trap_item, 9124 struct devlink_port *in_devlink_port, 9125 const struct flow_action_cookie *fa_cookie) 9126{ 9127 metadata->trap_name = trap_item->trap->name; 9128 metadata->trap_group_name = trap_item->group_item->group->name; 9129 metadata->fa_cookie = fa_cookie; 9130 metadata->trap_type = trap_item->trap->type; 9131 9132 spin_lock(&in_devlink_port->type_lock); 9133 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH) 9134 metadata->input_dev = in_devlink_port->type_eth.netdev; 9135 spin_unlock(&in_devlink_port->type_lock); 9136} 9137 9138/** 9139 * devlink_trap_report - Report trapped packet to drop monitor. 9140 * @devlink: devlink. 9141 * @skb: Trapped packet. 9142 * @trap_ctx: Trap context. 9143 * @in_devlink_port: Input devlink port. 9144 * @fa_cookie: Flow action cookie. Could be NULL. 9145 */ 9146void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb, 9147 void *trap_ctx, struct devlink_port *in_devlink_port, 9148 const struct flow_action_cookie *fa_cookie) 9149 9150{ 9151 struct devlink_trap_item *trap_item = trap_ctx; 9152 9153 devlink_trap_stats_update(trap_item->stats, skb->len); 9154 devlink_trap_stats_update(trap_item->group_item->stats, skb->len); 9155 9156 if (trace_devlink_trap_report_enabled()) { 9157 struct devlink_trap_metadata metadata = {}; 9158 9159 devlink_trap_report_metadata_set(&metadata, trap_item, 9160 in_devlink_port, fa_cookie); 9161 trace_devlink_trap_report(devlink, skb, &metadata); 9162 } 9163} 9164EXPORT_SYMBOL_GPL(devlink_trap_report); 9165 9166/** 9167 * devlink_trap_ctx_priv - Trap context to driver private information. 9168 * @trap_ctx: Trap context. 9169 * 9170 * Return: Driver private information passed during registration. 9171 */ 9172void *devlink_trap_ctx_priv(void *trap_ctx) 9173{ 9174 struct devlink_trap_item *trap_item = trap_ctx; 9175 9176 return trap_item->priv; 9177} 9178EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv); 9179 9180static int 9181devlink_trap_group_item_policer_link(struct devlink *devlink, 9182 struct devlink_trap_group_item *group_item) 9183{ 9184 u32 policer_id = group_item->group->init_policer_id; 9185 struct devlink_trap_policer_item *policer_item; 9186 9187 if (policer_id == 0) 9188 return 0; 9189 9190 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id); 9191 if (WARN_ON_ONCE(!policer_item)) 9192 return -EINVAL; 9193 9194 group_item->policer_item = policer_item; 9195 9196 return 0; 9197} 9198 9199static int 9200devlink_trap_group_register(struct devlink *devlink, 9201 const struct devlink_trap_group *group) 9202{ 9203 struct devlink_trap_group_item *group_item; 9204 int err; 9205 9206 if (devlink_trap_group_item_lookup(devlink, group->name)) 9207 return -EEXIST; 9208 9209 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL); 9210 if (!group_item) 9211 return -ENOMEM; 9212 9213 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); 9214 if (!group_item->stats) { 9215 err = -ENOMEM; 9216 goto err_stats_alloc; 9217 } 9218 9219 group_item->group = group; 9220 9221 err = devlink_trap_group_item_policer_link(devlink, group_item); 9222 if (err) 9223 goto err_policer_link; 9224 9225 if (devlink->ops->trap_group_init) { 9226 err = devlink->ops->trap_group_init(devlink, group); 9227 if (err) 9228 goto err_group_init; 9229 } 9230 9231 list_add_tail(&group_item->list, &devlink->trap_group_list); 9232 devlink_trap_group_notify(devlink, group_item, 9233 DEVLINK_CMD_TRAP_GROUP_NEW); 9234 9235 return 0; 9236 9237err_group_init: 9238err_policer_link: 9239 free_percpu(group_item->stats); 9240err_stats_alloc: 9241 kfree(group_item); 9242 return err; 9243} 9244 9245static void 9246devlink_trap_group_unregister(struct devlink *devlink, 9247 const struct devlink_trap_group *group) 9248{ 9249 struct devlink_trap_group_item *group_item; 9250 9251 group_item = devlink_trap_group_item_lookup(devlink, group->name); 9252 if (WARN_ON_ONCE(!group_item)) 9253 return; 9254 9255 devlink_trap_group_notify(devlink, group_item, 9256 DEVLINK_CMD_TRAP_GROUP_DEL); 9257 list_del(&group_item->list); 9258 free_percpu(group_item->stats); 9259 kfree(group_item); 9260} 9261 9262/** 9263 * devl_trap_groups_register - Register packet trap groups with devlink. 9264 * @devlink: devlink. 9265 * @groups: Packet trap groups. 9266 * @groups_count: Count of provided packet trap groups. 9267 * 9268 * Return: Non-zero value on failure. 9269 */ 9270int devl_trap_groups_register(struct devlink *devlink, 9271 const struct devlink_trap_group *groups, 9272 size_t groups_count) 9273{ 9274 int i, err; 9275 9276 devl_assert_locked(devlink); 9277 for (i = 0; i < groups_count; i++) { 9278 const struct devlink_trap_group *group = &groups[i]; 9279 9280 err = devlink_trap_group_verify(group); 9281 if (err) 9282 goto err_trap_group_verify; 9283 9284 err = devlink_trap_group_register(devlink, group); 9285 if (err) 9286 goto err_trap_group_register; 9287 } 9288 9289 return 0; 9290 9291err_trap_group_register: 9292err_trap_group_verify: 9293 for (i--; i >= 0; i--) 9294 devlink_trap_group_unregister(devlink, &groups[i]); 9295 return err; 9296} 9297EXPORT_SYMBOL_GPL(devl_trap_groups_register); 9298 9299/** 9300 * devlink_trap_groups_register - Register packet trap groups with devlink. 9301 * @devlink: devlink. 9302 * @groups: Packet trap groups. 9303 * @groups_count: Count of provided packet trap groups. 9304 * 9305 * Context: Takes and release devlink->lock <mutex>. 9306 * 9307 * Return: Non-zero value on failure. 9308 */ 9309int devlink_trap_groups_register(struct devlink *devlink, 9310 const struct devlink_trap_group *groups, 9311 size_t groups_count) 9312{ 9313 int err; 9314 9315 devl_lock(devlink); 9316 err = devl_trap_groups_register(devlink, groups, groups_count); 9317 devl_unlock(devlink); 9318 return err; 9319} 9320EXPORT_SYMBOL_GPL(devlink_trap_groups_register); 9321 9322/** 9323 * devl_trap_groups_unregister - Unregister packet trap groups from devlink. 9324 * @devlink: devlink. 9325 * @groups: Packet trap groups. 9326 * @groups_count: Count of provided packet trap groups. 9327 */ 9328void devl_trap_groups_unregister(struct devlink *devlink, 9329 const struct devlink_trap_group *groups, 9330 size_t groups_count) 9331{ 9332 int i; 9333 9334 devl_assert_locked(devlink); 9335 for (i = groups_count - 1; i >= 0; i--) 9336 devlink_trap_group_unregister(devlink, &groups[i]); 9337} 9338EXPORT_SYMBOL_GPL(devl_trap_groups_unregister); 9339 9340/** 9341 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink. 9342 * @devlink: devlink. 9343 * @groups: Packet trap groups. 9344 * @groups_count: Count of provided packet trap groups. 9345 * 9346 * Context: Takes and release devlink->lock <mutex>. 9347 */ 9348void devlink_trap_groups_unregister(struct devlink *devlink, 9349 const struct devlink_trap_group *groups, 9350 size_t groups_count) 9351{ 9352 devl_lock(devlink); 9353 devl_trap_groups_unregister(devlink, groups, groups_count); 9354 devl_unlock(devlink); 9355} 9356EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister); 9357 9358static void 9359devlink_trap_policer_notify(struct devlink *devlink, 9360 const struct devlink_trap_policer_item *policer_item, 9361 enum devlink_command cmd) 9362{ 9363 struct sk_buff *msg; 9364 int err; 9365 9366 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW && 9367 cmd != DEVLINK_CMD_TRAP_POLICER_DEL); 9368 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 9369 return; 9370 9371 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 9372 if (!msg) 9373 return; 9374 9375 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0, 9376 0, 0); 9377 if (err) { 9378 nlmsg_free(msg); 9379 return; 9380 } 9381 9382 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 9383 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 9384} 9385 9386static int 9387devlink_trap_policer_register(struct devlink *devlink, 9388 const struct devlink_trap_policer *policer) 9389{ 9390 struct devlink_trap_policer_item *policer_item; 9391 int err; 9392 9393 if (devlink_trap_policer_item_lookup(devlink, policer->id)) 9394 return -EEXIST; 9395 9396 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL); 9397 if (!policer_item) 9398 return -ENOMEM; 9399 9400 policer_item->policer = policer; 9401 policer_item->rate = policer->init_rate; 9402 policer_item->burst = policer->init_burst; 9403 9404 if (devlink->ops->trap_policer_init) { 9405 err = devlink->ops->trap_policer_init(devlink, policer); 9406 if (err) 9407 goto err_policer_init; 9408 } 9409 9410 list_add_tail(&policer_item->list, &devlink->trap_policer_list); 9411 devlink_trap_policer_notify(devlink, policer_item, 9412 DEVLINK_CMD_TRAP_POLICER_NEW); 9413 9414 return 0; 9415 9416err_policer_init: 9417 kfree(policer_item); 9418 return err; 9419} 9420 9421static void 9422devlink_trap_policer_unregister(struct devlink *devlink, 9423 const struct devlink_trap_policer *policer) 9424{ 9425 struct devlink_trap_policer_item *policer_item; 9426 9427 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id); 9428 if (WARN_ON_ONCE(!policer_item)) 9429 return; 9430 9431 devlink_trap_policer_notify(devlink, policer_item, 9432 DEVLINK_CMD_TRAP_POLICER_DEL); 9433 list_del(&policer_item->list); 9434 if (devlink->ops->trap_policer_fini) 9435 devlink->ops->trap_policer_fini(devlink, policer); 9436 kfree(policer_item); 9437} 9438 9439/** 9440 * devl_trap_policers_register - Register packet trap policers with devlink. 9441 * @devlink: devlink. 9442 * @policers: Packet trap policers. 9443 * @policers_count: Count of provided packet trap policers. 9444 * 9445 * Return: Non-zero value on failure. 9446 */ 9447int 9448devl_trap_policers_register(struct devlink *devlink, 9449 const struct devlink_trap_policer *policers, 9450 size_t policers_count) 9451{ 9452 int i, err; 9453 9454 devl_assert_locked(devlink); 9455 for (i = 0; i < policers_count; i++) { 9456 const struct devlink_trap_policer *policer = &policers[i]; 9457 9458 if (WARN_ON(policer->id == 0 || 9459 policer->max_rate < policer->min_rate || 9460 policer->max_burst < policer->min_burst)) { 9461 err = -EINVAL; 9462 goto err_trap_policer_verify; 9463 } 9464 9465 err = devlink_trap_policer_register(devlink, policer); 9466 if (err) 9467 goto err_trap_policer_register; 9468 } 9469 return 0; 9470 9471err_trap_policer_register: 9472err_trap_policer_verify: 9473 for (i--; i >= 0; i--) 9474 devlink_trap_policer_unregister(devlink, &policers[i]); 9475 return err; 9476} 9477EXPORT_SYMBOL_GPL(devl_trap_policers_register); 9478 9479/** 9480 * devl_trap_policers_unregister - Unregister packet trap policers from devlink. 9481 * @devlink: devlink. 9482 * @policers: Packet trap policers. 9483 * @policers_count: Count of provided packet trap policers. 9484 */ 9485void 9486devl_trap_policers_unregister(struct devlink *devlink, 9487 const struct devlink_trap_policer *policers, 9488 size_t policers_count) 9489{ 9490 int i; 9491 9492 devl_assert_locked(devlink); 9493 for (i = policers_count - 1; i >= 0; i--) 9494 devlink_trap_policer_unregister(devlink, &policers[i]); 9495} 9496EXPORT_SYMBOL_GPL(devl_trap_policers_unregister); 9497 9498int devlink_compat_phys_port_name_get(struct net_device *dev, 9499 char *name, size_t len) 9500{ 9501 struct devlink_port *devlink_port; 9502 9503 /* RTNL mutex is held here which ensures that devlink_port 9504 * instance cannot disappear in the middle. No need to take 9505 * any devlink lock as only permanent values are accessed. 9506 */ 9507 ASSERT_RTNL(); 9508 9509 devlink_port = dev->devlink_port; 9510 if (!devlink_port) 9511 return -EOPNOTSUPP; 9512 9513 return __devlink_port_phys_port_name_get(devlink_port, name, len); 9514} 9515 9516int devlink_compat_switch_id_get(struct net_device *dev, 9517 struct netdev_phys_item_id *ppid) 9518{ 9519 struct devlink_port *devlink_port; 9520 9521 /* Caller must hold RTNL mutex or reference to dev, which ensures that 9522 * devlink_port instance cannot disappear in the middle. No need to take 9523 * any devlink lock as only permanent values are accessed. 9524 */ 9525 devlink_port = dev->devlink_port; 9526 if (!devlink_port || !devlink_port->switch_port) 9527 return -EOPNOTSUPP; 9528 9529 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid)); 9530 9531 return 0; 9532}