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