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