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