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