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