at v5.10-rc1 10308 lines 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 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 4218 region->port->index)) 4219 goto nla_put_failure; 4220 4221 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name); 4222 if (err) 4223 goto nla_put_failure; 4224 4225 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 4226 region->size, 4227 DEVLINK_ATTR_PAD); 4228 if (err) 4229 goto nla_put_failure; 4230 4231 err = devlink_nl_region_snapshots_id_put(msg, devlink, region); 4232 if (err) 4233 goto nla_put_failure; 4234 4235 genlmsg_end(msg, hdr); 4236 return 0; 4237 4238nla_put_failure: 4239 genlmsg_cancel(msg, hdr); 4240 return err; 4241} 4242 4243static struct sk_buff * 4244devlink_nl_region_notify_build(struct devlink_region *region, 4245 struct devlink_snapshot *snapshot, 4246 enum devlink_command cmd, u32 portid, u32 seq) 4247{ 4248 struct devlink *devlink = region->devlink; 4249 struct sk_buff *msg; 4250 void *hdr; 4251 int err; 4252 4253 4254 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4255 if (!msg) 4256 return ERR_PTR(-ENOMEM); 4257 4258 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd); 4259 if (!hdr) { 4260 err = -EMSGSIZE; 4261 goto out_free_msg; 4262 } 4263 4264 err = devlink_nl_put_handle(msg, devlink); 4265 if (err) 4266 goto out_cancel_msg; 4267 4268 if (region->port) 4269 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 4270 region->port->index)) 4271 goto out_cancel_msg; 4272 4273 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, 4274 region->ops->name); 4275 if (err) 4276 goto out_cancel_msg; 4277 4278 if (snapshot) { 4279 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, 4280 snapshot->id); 4281 if (err) 4282 goto out_cancel_msg; 4283 } else { 4284 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 4285 region->size, DEVLINK_ATTR_PAD); 4286 if (err) 4287 goto out_cancel_msg; 4288 } 4289 genlmsg_end(msg, hdr); 4290 4291 return msg; 4292 4293out_cancel_msg: 4294 genlmsg_cancel(msg, hdr); 4295out_free_msg: 4296 nlmsg_free(msg); 4297 return ERR_PTR(err); 4298} 4299 4300static void devlink_nl_region_notify(struct devlink_region *region, 4301 struct devlink_snapshot *snapshot, 4302 enum devlink_command cmd) 4303{ 4304 struct devlink *devlink = region->devlink; 4305 struct sk_buff *msg; 4306 4307 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL); 4308 4309 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0); 4310 if (IS_ERR(msg)) 4311 return; 4312 4313 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 4314 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 4315} 4316 4317/** 4318 * __devlink_snapshot_id_increment - Increment number of snapshots using an id 4319 * @devlink: devlink instance 4320 * @id: the snapshot id 4321 * 4322 * Track when a new snapshot begins using an id. Load the count for the 4323 * given id from the snapshot xarray, increment it, and store it back. 4324 * 4325 * Called when a new snapshot is created with the given id. 4326 * 4327 * The id *must* have been previously allocated by 4328 * devlink_region_snapshot_id_get(). 4329 * 4330 * Returns 0 on success, or an error on failure. 4331 */ 4332static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id) 4333{ 4334 unsigned long count; 4335 void *p; 4336 4337 lockdep_assert_held(&devlink->lock); 4338 4339 p = xa_load(&devlink->snapshot_ids, id); 4340 if (WARN_ON(!p)) 4341 return -EINVAL; 4342 4343 if (WARN_ON(!xa_is_value(p))) 4344 return -EINVAL; 4345 4346 count = xa_to_value(p); 4347 count++; 4348 4349 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 4350 GFP_KERNEL)); 4351} 4352 4353/** 4354 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id 4355 * @devlink: devlink instance 4356 * @id: the snapshot id 4357 * 4358 * Track when a snapshot is deleted and stops using an id. Load the count 4359 * for the given id from the snapshot xarray, decrement it, and store it 4360 * back. 4361 * 4362 * If the count reaches zero, erase this id from the xarray, freeing it 4363 * up for future re-use by devlink_region_snapshot_id_get(). 4364 * 4365 * Called when a snapshot using the given id is deleted, and when the 4366 * initial allocator of the id is finished using it. 4367 */ 4368static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id) 4369{ 4370 unsigned long count; 4371 void *p; 4372 4373 lockdep_assert_held(&devlink->lock); 4374 4375 p = xa_load(&devlink->snapshot_ids, id); 4376 if (WARN_ON(!p)) 4377 return; 4378 4379 if (WARN_ON(!xa_is_value(p))) 4380 return; 4381 4382 count = xa_to_value(p); 4383 4384 if (count > 1) { 4385 count--; 4386 xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 4387 GFP_KERNEL); 4388 } else { 4389 /* If this was the last user, we can erase this id */ 4390 xa_erase(&devlink->snapshot_ids, id); 4391 } 4392} 4393 4394/** 4395 * __devlink_snapshot_id_insert - Insert a specific snapshot ID 4396 * @devlink: devlink instance 4397 * @id: the snapshot id 4398 * 4399 * Mark the given snapshot id as used by inserting a zero value into the 4400 * snapshot xarray. 4401 * 4402 * This must be called while holding the devlink instance lock. Unlike 4403 * devlink_snapshot_id_get, the initial reference count is zero, not one. 4404 * It is expected that the id will immediately be used before 4405 * releasing the devlink instance lock. 4406 * 4407 * Returns zero on success, or an error code if the snapshot id could not 4408 * be inserted. 4409 */ 4410static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id) 4411{ 4412 lockdep_assert_held(&devlink->lock); 4413 4414 if (xa_load(&devlink->snapshot_ids, id)) 4415 return -EEXIST; 4416 4417 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0), 4418 GFP_KERNEL)); 4419} 4420 4421/** 4422 * __devlink_region_snapshot_id_get - get snapshot ID 4423 * @devlink: devlink instance 4424 * @id: storage to return snapshot id 4425 * 4426 * Allocates a new snapshot id. Returns zero on success, or a negative 4427 * error on failure. Must be called while holding the devlink instance 4428 * lock. 4429 * 4430 * Snapshot IDs are tracked using an xarray which stores the number of 4431 * users of the snapshot id. 4432 * 4433 * Note that the caller of this function counts as a 'user', in order to 4434 * avoid race conditions. The caller must release its hold on the 4435 * snapshot by using devlink_region_snapshot_id_put. 4436 */ 4437static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 4438{ 4439 lockdep_assert_held(&devlink->lock); 4440 4441 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1), 4442 xa_limit_32b, GFP_KERNEL); 4443} 4444 4445/** 4446 * __devlink_region_snapshot_create - create a new snapshot 4447 * This will add a new snapshot of a region. The snapshot 4448 * will be stored on the region struct and can be accessed 4449 * from devlink. This is useful for future analyses of snapshots. 4450 * Multiple snapshots can be created on a region. 4451 * The @snapshot_id should be obtained using the getter function. 4452 * 4453 * Must be called only while holding the devlink instance lock. 4454 * 4455 * @region: devlink region of the snapshot 4456 * @data: snapshot data 4457 * @snapshot_id: snapshot id to be created 4458 */ 4459static int 4460__devlink_region_snapshot_create(struct devlink_region *region, 4461 u8 *data, u32 snapshot_id) 4462{ 4463 struct devlink *devlink = region->devlink; 4464 struct devlink_snapshot *snapshot; 4465 int err; 4466 4467 lockdep_assert_held(&devlink->lock); 4468 4469 /* check if region can hold one more snapshot */ 4470 if (region->cur_snapshots == region->max_snapshots) 4471 return -ENOSPC; 4472 4473 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) 4474 return -EEXIST; 4475 4476 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL); 4477 if (!snapshot) 4478 return -ENOMEM; 4479 4480 err = __devlink_snapshot_id_increment(devlink, snapshot_id); 4481 if (err) 4482 goto err_snapshot_id_increment; 4483 4484 snapshot->id = snapshot_id; 4485 snapshot->region = region; 4486 snapshot->data = data; 4487 4488 list_add_tail(&snapshot->list, &region->snapshot_list); 4489 4490 region->cur_snapshots++; 4491 4492 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW); 4493 return 0; 4494 4495err_snapshot_id_increment: 4496 kfree(snapshot); 4497 return err; 4498} 4499 4500static void devlink_region_snapshot_del(struct devlink_region *region, 4501 struct devlink_snapshot *snapshot) 4502{ 4503 struct devlink *devlink = region->devlink; 4504 4505 lockdep_assert_held(&devlink->lock); 4506 4507 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL); 4508 region->cur_snapshots--; 4509 list_del(&snapshot->list); 4510 region->ops->destructor(snapshot->data); 4511 __devlink_snapshot_id_decrement(devlink, snapshot->id); 4512 kfree(snapshot); 4513} 4514 4515static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb, 4516 struct genl_info *info) 4517{ 4518 struct devlink *devlink = info->user_ptr[0]; 4519 struct devlink_port *port = NULL; 4520 struct devlink_region *region; 4521 const char *region_name; 4522 struct sk_buff *msg; 4523 unsigned int index; 4524 int err; 4525 4526 if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) 4527 return -EINVAL; 4528 4529 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4530 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4531 4532 port = devlink_port_get_by_index(devlink, index); 4533 if (!port) 4534 return -ENODEV; 4535 } 4536 4537 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4538 if (port) 4539 region = devlink_port_region_get_by_name(port, region_name); 4540 else 4541 region = devlink_region_get_by_name(devlink, region_name); 4542 4543 if (!region) 4544 return -EINVAL; 4545 4546 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4547 if (!msg) 4548 return -ENOMEM; 4549 4550 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET, 4551 info->snd_portid, info->snd_seq, 0, 4552 region); 4553 if (err) { 4554 nlmsg_free(msg); 4555 return err; 4556 } 4557 4558 return genlmsg_reply(msg, info); 4559} 4560 4561static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg, 4562 struct netlink_callback *cb, 4563 struct devlink_port *port, 4564 int *idx, 4565 int start) 4566{ 4567 struct devlink_region *region; 4568 int err = 0; 4569 4570 list_for_each_entry(region, &port->region_list, list) { 4571 if (*idx < start) { 4572 (*idx)++; 4573 continue; 4574 } 4575 err = devlink_nl_region_fill(msg, port->devlink, 4576 DEVLINK_CMD_REGION_GET, 4577 NETLINK_CB(cb->skb).portid, 4578 cb->nlh->nlmsg_seq, 4579 NLM_F_MULTI, region); 4580 if (err) 4581 goto out; 4582 (*idx)++; 4583 } 4584 4585out: 4586 return err; 4587} 4588 4589static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg, 4590 struct netlink_callback *cb, 4591 struct devlink *devlink, 4592 int *idx, 4593 int start) 4594{ 4595 struct devlink_region *region; 4596 struct devlink_port *port; 4597 int err = 0; 4598 4599 mutex_lock(&devlink->lock); 4600 list_for_each_entry(region, &devlink->region_list, list) { 4601 if (*idx < start) { 4602 (*idx)++; 4603 continue; 4604 } 4605 err = devlink_nl_region_fill(msg, devlink, 4606 DEVLINK_CMD_REGION_GET, 4607 NETLINK_CB(cb->skb).portid, 4608 cb->nlh->nlmsg_seq, 4609 NLM_F_MULTI, region); 4610 if (err) 4611 goto out; 4612 (*idx)++; 4613 } 4614 4615 list_for_each_entry(port, &devlink->port_list, list) { 4616 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx, 4617 start); 4618 if (err) 4619 goto out; 4620 } 4621 4622out: 4623 mutex_unlock(&devlink->lock); 4624 return err; 4625} 4626 4627static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg, 4628 struct netlink_callback *cb) 4629{ 4630 struct devlink *devlink; 4631 int start = cb->args[0]; 4632 int idx = 0; 4633 int err; 4634 4635 mutex_lock(&devlink_mutex); 4636 list_for_each_entry(devlink, &devlink_list, list) { 4637 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 4638 continue; 4639 err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink, 4640 &idx, start); 4641 if (err) 4642 goto out; 4643 } 4644out: 4645 mutex_unlock(&devlink_mutex); 4646 cb->args[0] = idx; 4647 return msg->len; 4648} 4649 4650static int devlink_nl_cmd_region_del(struct sk_buff *skb, 4651 struct genl_info *info) 4652{ 4653 struct devlink *devlink = info->user_ptr[0]; 4654 struct devlink_snapshot *snapshot; 4655 struct devlink_port *port = NULL; 4656 struct devlink_region *region; 4657 const char *region_name; 4658 unsigned int index; 4659 u32 snapshot_id; 4660 4661 if (!info->attrs[DEVLINK_ATTR_REGION_NAME] || 4662 !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) 4663 return -EINVAL; 4664 4665 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4666 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); 4667 4668 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4669 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4670 4671 port = devlink_port_get_by_index(devlink, index); 4672 if (!port) 4673 return -ENODEV; 4674 } 4675 4676 if (port) 4677 region = devlink_port_region_get_by_name(port, region_name); 4678 else 4679 region = devlink_region_get_by_name(devlink, region_name); 4680 4681 if (!region) 4682 return -EINVAL; 4683 4684 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 4685 if (!snapshot) 4686 return -EINVAL; 4687 4688 devlink_region_snapshot_del(region, snapshot); 4689 return 0; 4690} 4691 4692static int 4693devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) 4694{ 4695 struct devlink *devlink = info->user_ptr[0]; 4696 struct devlink_snapshot *snapshot; 4697 struct devlink_port *port = NULL; 4698 struct nlattr *snapshot_id_attr; 4699 struct devlink_region *region; 4700 const char *region_name; 4701 unsigned int index; 4702 u32 snapshot_id; 4703 u8 *data; 4704 int err; 4705 4706 if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) { 4707 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided"); 4708 return -EINVAL; 4709 } 4710 4711 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 4712 4713 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4714 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4715 4716 port = devlink_port_get_by_index(devlink, index); 4717 if (!port) 4718 return -ENODEV; 4719 } 4720 4721 if (port) 4722 region = devlink_port_region_get_by_name(port, region_name); 4723 else 4724 region = devlink_region_get_by_name(devlink, region_name); 4725 4726 if (!region) { 4727 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist"); 4728 return -EINVAL; 4729 } 4730 4731 if (!region->ops->snapshot) { 4732 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot"); 4733 return -EOPNOTSUPP; 4734 } 4735 4736 if (region->cur_snapshots == region->max_snapshots) { 4737 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots"); 4738 return -ENOSPC; 4739 } 4740 4741 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; 4742 if (snapshot_id_attr) { 4743 snapshot_id = nla_get_u32(snapshot_id_attr); 4744 4745 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { 4746 NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use"); 4747 return -EEXIST; 4748 } 4749 4750 err = __devlink_snapshot_id_insert(devlink, snapshot_id); 4751 if (err) 4752 return err; 4753 } else { 4754 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id); 4755 if (err) { 4756 NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id"); 4757 return err; 4758 } 4759 } 4760 4761 if (port) 4762 err = region->port_ops->snapshot(port, region->port_ops, 4763 info->extack, &data); 4764 else 4765 err = region->ops->snapshot(devlink, region->ops, 4766 info->extack, &data); 4767 if (err) 4768 goto err_snapshot_capture; 4769 4770 err = __devlink_region_snapshot_create(region, data, snapshot_id); 4771 if (err) 4772 goto err_snapshot_create; 4773 4774 if (!snapshot_id_attr) { 4775 struct sk_buff *msg; 4776 4777 snapshot = devlink_region_snapshot_get_by_id(region, 4778 snapshot_id); 4779 if (WARN_ON(!snapshot)) 4780 return -EINVAL; 4781 4782 msg = devlink_nl_region_notify_build(region, snapshot, 4783 DEVLINK_CMD_REGION_NEW, 4784 info->snd_portid, 4785 info->snd_seq); 4786 err = PTR_ERR_OR_ZERO(msg); 4787 if (err) 4788 goto err_notify; 4789 4790 err = genlmsg_reply(msg, info); 4791 if (err) 4792 goto err_notify; 4793 } 4794 4795 return 0; 4796 4797err_snapshot_create: 4798 region->ops->destructor(data); 4799err_snapshot_capture: 4800 __devlink_snapshot_id_decrement(devlink, snapshot_id); 4801 return err; 4802 4803err_notify: 4804 devlink_region_snapshot_del(region, snapshot); 4805 return err; 4806} 4807 4808static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg, 4809 struct devlink *devlink, 4810 u8 *chunk, u32 chunk_size, 4811 u64 addr) 4812{ 4813 struct nlattr *chunk_attr; 4814 int err; 4815 4816 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK); 4817 if (!chunk_attr) 4818 return -EINVAL; 4819 4820 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk); 4821 if (err) 4822 goto nla_put_failure; 4823 4824 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr, 4825 DEVLINK_ATTR_PAD); 4826 if (err) 4827 goto nla_put_failure; 4828 4829 nla_nest_end(msg, chunk_attr); 4830 return 0; 4831 4832nla_put_failure: 4833 nla_nest_cancel(msg, chunk_attr); 4834 return err; 4835} 4836 4837#define DEVLINK_REGION_READ_CHUNK_SIZE 256 4838 4839static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb, 4840 struct devlink *devlink, 4841 struct devlink_region *region, 4842 struct nlattr **attrs, 4843 u64 start_offset, 4844 u64 end_offset, 4845 u64 *new_offset) 4846{ 4847 struct devlink_snapshot *snapshot; 4848 u64 curr_offset = start_offset; 4849 u32 snapshot_id; 4850 int err = 0; 4851 4852 *new_offset = start_offset; 4853 4854 snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); 4855 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 4856 if (!snapshot) 4857 return -EINVAL; 4858 4859 while (curr_offset < end_offset) { 4860 u32 data_size; 4861 u8 *data; 4862 4863 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE) 4864 data_size = end_offset - curr_offset; 4865 else 4866 data_size = DEVLINK_REGION_READ_CHUNK_SIZE; 4867 4868 data = &snapshot->data[curr_offset]; 4869 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink, 4870 data, data_size, 4871 curr_offset); 4872 if (err) 4873 break; 4874 4875 curr_offset += data_size; 4876 } 4877 *new_offset = curr_offset; 4878 4879 return err; 4880} 4881 4882static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, 4883 struct netlink_callback *cb) 4884{ 4885 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 4886 u64 ret_offset, start_offset, end_offset = U64_MAX; 4887 struct nlattr **attrs = info->attrs; 4888 struct devlink_port *port = NULL; 4889 struct devlink_region *region; 4890 struct nlattr *chunks_attr; 4891 const char *region_name; 4892 struct devlink *devlink; 4893 unsigned int index; 4894 void *hdr; 4895 int err; 4896 4897 start_offset = *((u64 *)&cb->args[0]); 4898 4899 mutex_lock(&devlink_mutex); 4900 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); 4901 if (IS_ERR(devlink)) { 4902 err = PTR_ERR(devlink); 4903 goto out_dev; 4904 } 4905 4906 mutex_lock(&devlink->lock); 4907 4908 if (!attrs[DEVLINK_ATTR_REGION_NAME] || 4909 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) { 4910 err = -EINVAL; 4911 goto out_unlock; 4912 } 4913 4914 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 4915 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 4916 4917 port = devlink_port_get_by_index(devlink, index); 4918 if (!port) 4919 return -ENODEV; 4920 } 4921 4922 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]); 4923 4924 if (port) 4925 region = devlink_port_region_get_by_name(port, region_name); 4926 else 4927 region = devlink_region_get_by_name(devlink, region_name); 4928 4929 if (!region) { 4930 err = -EINVAL; 4931 goto out_unlock; 4932 } 4933 4934 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] && 4935 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) { 4936 if (!start_offset) 4937 start_offset = 4938 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 4939 4940 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 4941 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); 4942 } 4943 4944 if (end_offset > region->size) 4945 end_offset = region->size; 4946 4947 /* return 0 if there is no further data to read */ 4948 if (start_offset == end_offset) { 4949 err = 0; 4950 goto out_unlock; 4951 } 4952 4953 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 4954 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, 4955 DEVLINK_CMD_REGION_READ); 4956 if (!hdr) { 4957 err = -EMSGSIZE; 4958 goto out_unlock; 4959 } 4960 4961 err = devlink_nl_put_handle(skb, devlink); 4962 if (err) 4963 goto nla_put_failure; 4964 4965 if (region->port) 4966 if (nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX, 4967 region->port->index)) 4968 goto nla_put_failure; 4969 4970 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name); 4971 if (err) 4972 goto nla_put_failure; 4973 4974 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS); 4975 if (!chunks_attr) { 4976 err = -EMSGSIZE; 4977 goto nla_put_failure; 4978 } 4979 4980 err = devlink_nl_region_read_snapshot_fill(skb, devlink, 4981 region, attrs, 4982 start_offset, 4983 end_offset, &ret_offset); 4984 4985 if (err && err != -EMSGSIZE) 4986 goto nla_put_failure; 4987 4988 /* Check if there was any progress done to prevent infinite loop */ 4989 if (ret_offset == start_offset) { 4990 err = -EINVAL; 4991 goto nla_put_failure; 4992 } 4993 4994 *((u64 *)&cb->args[0]) = ret_offset; 4995 4996 nla_nest_end(skb, chunks_attr); 4997 genlmsg_end(skb, hdr); 4998 mutex_unlock(&devlink->lock); 4999 mutex_unlock(&devlink_mutex); 5000 5001 return skb->len; 5002 5003nla_put_failure: 5004 genlmsg_cancel(skb, hdr); 5005out_unlock: 5006 mutex_unlock(&devlink->lock); 5007out_dev: 5008 mutex_unlock(&devlink_mutex); 5009 return err; 5010} 5011 5012struct devlink_info_req { 5013 struct sk_buff *msg; 5014}; 5015 5016int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name) 5017{ 5018 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name); 5019} 5020EXPORT_SYMBOL_GPL(devlink_info_driver_name_put); 5021 5022int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) 5023{ 5024 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); 5025} 5026EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); 5027 5028int devlink_info_board_serial_number_put(struct devlink_info_req *req, 5029 const char *bsn) 5030{ 5031 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, 5032 bsn); 5033} 5034EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); 5035 5036static int devlink_info_version_put(struct devlink_info_req *req, int attr, 5037 const char *version_name, 5038 const char *version_value) 5039{ 5040 struct nlattr *nest; 5041 int err; 5042 5043 nest = nla_nest_start_noflag(req->msg, attr); 5044 if (!nest) 5045 return -EMSGSIZE; 5046 5047 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, 5048 version_name); 5049 if (err) 5050 goto nla_put_failure; 5051 5052 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, 5053 version_value); 5054 if (err) 5055 goto nla_put_failure; 5056 5057 nla_nest_end(req->msg, nest); 5058 5059 return 0; 5060 5061nla_put_failure: 5062 nla_nest_cancel(req->msg, nest); 5063 return err; 5064} 5065 5066int devlink_info_version_fixed_put(struct devlink_info_req *req, 5067 const char *version_name, 5068 const char *version_value) 5069{ 5070 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, 5071 version_name, version_value); 5072} 5073EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); 5074 5075int devlink_info_version_stored_put(struct devlink_info_req *req, 5076 const char *version_name, 5077 const char *version_value) 5078{ 5079 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 5080 version_name, version_value); 5081} 5082EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); 5083 5084int devlink_info_version_running_put(struct devlink_info_req *req, 5085 const char *version_name, 5086 const char *version_value) 5087{ 5088 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 5089 version_name, version_value); 5090} 5091EXPORT_SYMBOL_GPL(devlink_info_version_running_put); 5092 5093static int 5094devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, 5095 enum devlink_command cmd, u32 portid, 5096 u32 seq, int flags, struct netlink_ext_ack *extack) 5097{ 5098 struct devlink_info_req req; 5099 void *hdr; 5100 int err; 5101 5102 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 5103 if (!hdr) 5104 return -EMSGSIZE; 5105 5106 err = -EMSGSIZE; 5107 if (devlink_nl_put_handle(msg, devlink)) 5108 goto err_cancel_msg; 5109 5110 req.msg = msg; 5111 err = devlink->ops->info_get(devlink, &req, extack); 5112 if (err) 5113 goto err_cancel_msg; 5114 5115 genlmsg_end(msg, hdr); 5116 return 0; 5117 5118err_cancel_msg: 5119 genlmsg_cancel(msg, hdr); 5120 return err; 5121} 5122 5123static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, 5124 struct genl_info *info) 5125{ 5126 struct devlink *devlink = info->user_ptr[0]; 5127 struct sk_buff *msg; 5128 int err; 5129 5130 if (!devlink->ops->info_get) 5131 return -EOPNOTSUPP; 5132 5133 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 5134 if (!msg) 5135 return -ENOMEM; 5136 5137 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 5138 info->snd_portid, info->snd_seq, 0, 5139 info->extack); 5140 if (err) { 5141 nlmsg_free(msg); 5142 return err; 5143 } 5144 5145 return genlmsg_reply(msg, info); 5146} 5147 5148static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg, 5149 struct netlink_callback *cb) 5150{ 5151 struct devlink *devlink; 5152 int start = cb->args[0]; 5153 int idx = 0; 5154 int err = 0; 5155 5156 mutex_lock(&devlink_mutex); 5157 list_for_each_entry(devlink, &devlink_list, list) { 5158 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 5159 continue; 5160 if (idx < start) { 5161 idx++; 5162 continue; 5163 } 5164 5165 if (!devlink->ops->info_get) { 5166 idx++; 5167 continue; 5168 } 5169 5170 mutex_lock(&devlink->lock); 5171 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 5172 NETLINK_CB(cb->skb).portid, 5173 cb->nlh->nlmsg_seq, NLM_F_MULTI, 5174 cb->extack); 5175 mutex_unlock(&devlink->lock); 5176 if (err == -EOPNOTSUPP) 5177 err = 0; 5178 else if (err) 5179 break; 5180 idx++; 5181 } 5182 mutex_unlock(&devlink_mutex); 5183 5184 if (err != -EMSGSIZE) 5185 return err; 5186 5187 cb->args[0] = idx; 5188 return msg->len; 5189} 5190 5191struct devlink_fmsg_item { 5192 struct list_head list; 5193 int attrtype; 5194 u8 nla_type; 5195 u16 len; 5196 int value[]; 5197}; 5198 5199struct devlink_fmsg { 5200 struct list_head item_list; 5201 bool putting_binary; /* This flag forces enclosing of binary data 5202 * in an array brackets. It forces using 5203 * of designated API: 5204 * devlink_fmsg_binary_pair_nest_start() 5205 * devlink_fmsg_binary_pair_nest_end() 5206 */ 5207}; 5208 5209static struct devlink_fmsg *devlink_fmsg_alloc(void) 5210{ 5211 struct devlink_fmsg *fmsg; 5212 5213 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL); 5214 if (!fmsg) 5215 return NULL; 5216 5217 INIT_LIST_HEAD(&fmsg->item_list); 5218 5219 return fmsg; 5220} 5221 5222static void devlink_fmsg_free(struct devlink_fmsg *fmsg) 5223{ 5224 struct devlink_fmsg_item *item, *tmp; 5225 5226 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) { 5227 list_del(&item->list); 5228 kfree(item); 5229 } 5230 kfree(fmsg); 5231} 5232 5233static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg, 5234 int attrtype) 5235{ 5236 struct devlink_fmsg_item *item; 5237 5238 item = kzalloc(sizeof(*item), GFP_KERNEL); 5239 if (!item) 5240 return -ENOMEM; 5241 5242 item->attrtype = attrtype; 5243 list_add_tail(&item->list, &fmsg->item_list); 5244 5245 return 0; 5246} 5247 5248int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg) 5249{ 5250 if (fmsg->putting_binary) 5251 return -EINVAL; 5252 5253 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START); 5254} 5255EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start); 5256 5257static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg) 5258{ 5259 if (fmsg->putting_binary) 5260 return -EINVAL; 5261 5262 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END); 5263} 5264 5265int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg) 5266{ 5267 if (fmsg->putting_binary) 5268 return -EINVAL; 5269 5270 return devlink_fmsg_nest_end(fmsg); 5271} 5272EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end); 5273 5274#define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN) 5275 5276static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name) 5277{ 5278 struct devlink_fmsg_item *item; 5279 5280 if (fmsg->putting_binary) 5281 return -EINVAL; 5282 5283 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE) 5284 return -EMSGSIZE; 5285 5286 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL); 5287 if (!item) 5288 return -ENOMEM; 5289 5290 item->nla_type = NLA_NUL_STRING; 5291 item->len = strlen(name) + 1; 5292 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME; 5293 memcpy(&item->value, name, item->len); 5294 list_add_tail(&item->list, &fmsg->item_list); 5295 5296 return 0; 5297} 5298 5299int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name) 5300{ 5301 int err; 5302 5303 if (fmsg->putting_binary) 5304 return -EINVAL; 5305 5306 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START); 5307 if (err) 5308 return err; 5309 5310 err = devlink_fmsg_put_name(fmsg, name); 5311 if (err) 5312 return err; 5313 5314 return 0; 5315} 5316EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start); 5317 5318int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg) 5319{ 5320 if (fmsg->putting_binary) 5321 return -EINVAL; 5322 5323 return devlink_fmsg_nest_end(fmsg); 5324} 5325EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end); 5326 5327int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg, 5328 const char *name) 5329{ 5330 int err; 5331 5332 if (fmsg->putting_binary) 5333 return -EINVAL; 5334 5335 err = devlink_fmsg_pair_nest_start(fmsg, name); 5336 if (err) 5337 return err; 5338 5339 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START); 5340 if (err) 5341 return err; 5342 5343 return 0; 5344} 5345EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start); 5346 5347int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg) 5348{ 5349 int err; 5350 5351 if (fmsg->putting_binary) 5352 return -EINVAL; 5353 5354 err = devlink_fmsg_nest_end(fmsg); 5355 if (err) 5356 return err; 5357 5358 err = devlink_fmsg_nest_end(fmsg); 5359 if (err) 5360 return err; 5361 5362 return 0; 5363} 5364EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end); 5365 5366int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg, 5367 const char *name) 5368{ 5369 int err; 5370 5371 err = devlink_fmsg_arr_pair_nest_start(fmsg, name); 5372 if (err) 5373 return err; 5374 5375 fmsg->putting_binary = true; 5376 return err; 5377} 5378EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start); 5379 5380int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg) 5381{ 5382 if (!fmsg->putting_binary) 5383 return -EINVAL; 5384 5385 fmsg->putting_binary = false; 5386 return devlink_fmsg_arr_pair_nest_end(fmsg); 5387} 5388EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end); 5389 5390static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg, 5391 const void *value, u16 value_len, 5392 u8 value_nla_type) 5393{ 5394 struct devlink_fmsg_item *item; 5395 5396 if (value_len > DEVLINK_FMSG_MAX_SIZE) 5397 return -EMSGSIZE; 5398 5399 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL); 5400 if (!item) 5401 return -ENOMEM; 5402 5403 item->nla_type = value_nla_type; 5404 item->len = value_len; 5405 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; 5406 memcpy(&item->value, value, item->len); 5407 list_add_tail(&item->list, &fmsg->item_list); 5408 5409 return 0; 5410} 5411 5412int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value) 5413{ 5414 if (fmsg->putting_binary) 5415 return -EINVAL; 5416 5417 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG); 5418} 5419EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put); 5420 5421int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value) 5422{ 5423 if (fmsg->putting_binary) 5424 return -EINVAL; 5425 5426 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8); 5427} 5428EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put); 5429 5430int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value) 5431{ 5432 if (fmsg->putting_binary) 5433 return -EINVAL; 5434 5435 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32); 5436} 5437EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put); 5438 5439int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value) 5440{ 5441 if (fmsg->putting_binary) 5442 return -EINVAL; 5443 5444 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64); 5445} 5446EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put); 5447 5448int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value) 5449{ 5450 if (fmsg->putting_binary) 5451 return -EINVAL; 5452 5453 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1, 5454 NLA_NUL_STRING); 5455} 5456EXPORT_SYMBOL_GPL(devlink_fmsg_string_put); 5457 5458int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value, 5459 u16 value_len) 5460{ 5461 if (!fmsg->putting_binary) 5462 return -EINVAL; 5463 5464 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY); 5465} 5466EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put); 5467 5468int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name, 5469 bool value) 5470{ 5471 int err; 5472 5473 err = devlink_fmsg_pair_nest_start(fmsg, name); 5474 if (err) 5475 return err; 5476 5477 err = devlink_fmsg_bool_put(fmsg, value); 5478 if (err) 5479 return err; 5480 5481 err = devlink_fmsg_pair_nest_end(fmsg); 5482 if (err) 5483 return err; 5484 5485 return 0; 5486} 5487EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put); 5488 5489int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name, 5490 u8 value) 5491{ 5492 int err; 5493 5494 err = devlink_fmsg_pair_nest_start(fmsg, name); 5495 if (err) 5496 return err; 5497 5498 err = devlink_fmsg_u8_put(fmsg, value); 5499 if (err) 5500 return err; 5501 5502 err = devlink_fmsg_pair_nest_end(fmsg); 5503 if (err) 5504 return err; 5505 5506 return 0; 5507} 5508EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put); 5509 5510int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name, 5511 u32 value) 5512{ 5513 int err; 5514 5515 err = devlink_fmsg_pair_nest_start(fmsg, name); 5516 if (err) 5517 return err; 5518 5519 err = devlink_fmsg_u32_put(fmsg, value); 5520 if (err) 5521 return err; 5522 5523 err = devlink_fmsg_pair_nest_end(fmsg); 5524 if (err) 5525 return err; 5526 5527 return 0; 5528} 5529EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put); 5530 5531int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name, 5532 u64 value) 5533{ 5534 int err; 5535 5536 err = devlink_fmsg_pair_nest_start(fmsg, name); 5537 if (err) 5538 return err; 5539 5540 err = devlink_fmsg_u64_put(fmsg, value); 5541 if (err) 5542 return err; 5543 5544 err = devlink_fmsg_pair_nest_end(fmsg); 5545 if (err) 5546 return err; 5547 5548 return 0; 5549} 5550EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put); 5551 5552int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name, 5553 const char *value) 5554{ 5555 int err; 5556 5557 err = devlink_fmsg_pair_nest_start(fmsg, name); 5558 if (err) 5559 return err; 5560 5561 err = devlink_fmsg_string_put(fmsg, value); 5562 if (err) 5563 return err; 5564 5565 err = devlink_fmsg_pair_nest_end(fmsg); 5566 if (err) 5567 return err; 5568 5569 return 0; 5570} 5571EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put); 5572 5573int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name, 5574 const void *value, u32 value_len) 5575{ 5576 u32 data_size; 5577 int end_err; 5578 u32 offset; 5579 int err; 5580 5581 err = devlink_fmsg_binary_pair_nest_start(fmsg, name); 5582 if (err) 5583 return err; 5584 5585 for (offset = 0; offset < value_len; offset += data_size) { 5586 data_size = value_len - offset; 5587 if (data_size > DEVLINK_FMSG_MAX_SIZE) 5588 data_size = DEVLINK_FMSG_MAX_SIZE; 5589 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size); 5590 if (err) 5591 break; 5592 /* Exit from loop with a break (instead of 5593 * return) to make sure putting_binary is turned off in 5594 * devlink_fmsg_binary_pair_nest_end 5595 */ 5596 } 5597 5598 end_err = devlink_fmsg_binary_pair_nest_end(fmsg); 5599 if (end_err) 5600 err = end_err; 5601 5602 return err; 5603} 5604EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put); 5605 5606static int 5607devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb) 5608{ 5609 switch (msg->nla_type) { 5610 case NLA_FLAG: 5611 case NLA_U8: 5612 case NLA_U32: 5613 case NLA_U64: 5614 case NLA_NUL_STRING: 5615 case NLA_BINARY: 5616 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, 5617 msg->nla_type); 5618 default: 5619 return -EINVAL; 5620 } 5621} 5622 5623static int 5624devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb) 5625{ 5626 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; 5627 u8 tmp; 5628 5629 switch (msg->nla_type) { 5630 case NLA_FLAG: 5631 /* Always provide flag data, regardless of its value */ 5632 tmp = *(bool *) msg->value; 5633 5634 return nla_put_u8(skb, attrtype, tmp); 5635 case NLA_U8: 5636 return nla_put_u8(skb, attrtype, *(u8 *) msg->value); 5637 case NLA_U32: 5638 return nla_put_u32(skb, attrtype, *(u32 *) msg->value); 5639 case NLA_U64: 5640 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value, 5641 DEVLINK_ATTR_PAD); 5642 case NLA_NUL_STRING: 5643 return nla_put_string(skb, attrtype, (char *) &msg->value); 5644 case NLA_BINARY: 5645 return nla_put(skb, attrtype, msg->len, (void *) &msg->value); 5646 default: 5647 return -EINVAL; 5648 } 5649} 5650 5651static int 5652devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb, 5653 int *start) 5654{ 5655 struct devlink_fmsg_item *item; 5656 struct nlattr *fmsg_nlattr; 5657 int i = 0; 5658 int err; 5659 5660 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG); 5661 if (!fmsg_nlattr) 5662 return -EMSGSIZE; 5663 5664 list_for_each_entry(item, &fmsg->item_list, list) { 5665 if (i < *start) { 5666 i++; 5667 continue; 5668 } 5669 5670 switch (item->attrtype) { 5671 case DEVLINK_ATTR_FMSG_OBJ_NEST_START: 5672 case DEVLINK_ATTR_FMSG_PAIR_NEST_START: 5673 case DEVLINK_ATTR_FMSG_ARR_NEST_START: 5674 case DEVLINK_ATTR_FMSG_NEST_END: 5675 err = nla_put_flag(skb, item->attrtype); 5676 break; 5677 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA: 5678 err = devlink_fmsg_item_fill_type(item, skb); 5679 if (err) 5680 break; 5681 err = devlink_fmsg_item_fill_data(item, skb); 5682 break; 5683 case DEVLINK_ATTR_FMSG_OBJ_NAME: 5684 err = nla_put_string(skb, item->attrtype, 5685 (char *) &item->value); 5686 break; 5687 default: 5688 err = -EINVAL; 5689 break; 5690 } 5691 if (!err) 5692 *start = ++i; 5693 else 5694 break; 5695 } 5696 5697 nla_nest_end(skb, fmsg_nlattr); 5698 return err; 5699} 5700 5701static int devlink_fmsg_snd(struct devlink_fmsg *fmsg, 5702 struct genl_info *info, 5703 enum devlink_command cmd, int flags) 5704{ 5705 struct nlmsghdr *nlh; 5706 struct sk_buff *skb; 5707 bool last = false; 5708 int index = 0; 5709 void *hdr; 5710 int err; 5711 5712 while (!last) { 5713 int tmp_index = index; 5714 5715 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 5716 if (!skb) 5717 return -ENOMEM; 5718 5719 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 5720 &devlink_nl_family, flags | NLM_F_MULTI, cmd); 5721 if (!hdr) { 5722 err = -EMSGSIZE; 5723 goto nla_put_failure; 5724 } 5725 5726 err = devlink_fmsg_prepare_skb(fmsg, skb, &index); 5727 if (!err) 5728 last = true; 5729 else if (err != -EMSGSIZE || tmp_index == index) 5730 goto nla_put_failure; 5731 5732 genlmsg_end(skb, hdr); 5733 err = genlmsg_reply(skb, info); 5734 if (err) 5735 return err; 5736 } 5737 5738 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 5739 if (!skb) 5740 return -ENOMEM; 5741 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 5742 NLMSG_DONE, 0, flags | NLM_F_MULTI); 5743 if (!nlh) { 5744 err = -EMSGSIZE; 5745 goto nla_put_failure; 5746 } 5747 5748 return genlmsg_reply(skb, info); 5749 5750nla_put_failure: 5751 nlmsg_free(skb); 5752 return err; 5753} 5754 5755static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb, 5756 struct netlink_callback *cb, 5757 enum devlink_command cmd) 5758{ 5759 int index = cb->args[0]; 5760 int tmp_index = index; 5761 void *hdr; 5762 int err; 5763 5764 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 5765 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd); 5766 if (!hdr) { 5767 err = -EMSGSIZE; 5768 goto nla_put_failure; 5769 } 5770 5771 err = devlink_fmsg_prepare_skb(fmsg, skb, &index); 5772 if ((err && err != -EMSGSIZE) || tmp_index == index) 5773 goto nla_put_failure; 5774 5775 cb->args[0] = index; 5776 genlmsg_end(skb, hdr); 5777 return skb->len; 5778 5779nla_put_failure: 5780 genlmsg_cancel(skb, hdr); 5781 return err; 5782} 5783 5784struct devlink_health_reporter { 5785 struct list_head list; 5786 void *priv; 5787 const struct devlink_health_reporter_ops *ops; 5788 struct devlink *devlink; 5789 struct devlink_port *devlink_port; 5790 struct devlink_fmsg *dump_fmsg; 5791 struct mutex dump_lock; /* lock parallel read/write from dump buffers */ 5792 u64 graceful_period; 5793 bool auto_recover; 5794 bool auto_dump; 5795 u8 health_state; 5796 u64 dump_ts; 5797 u64 dump_real_ts; 5798 u64 error_count; 5799 u64 recovery_count; 5800 u64 last_recovery_ts; 5801 refcount_t refcount; 5802}; 5803 5804void * 5805devlink_health_reporter_priv(struct devlink_health_reporter *reporter) 5806{ 5807 return reporter->priv; 5808} 5809EXPORT_SYMBOL_GPL(devlink_health_reporter_priv); 5810 5811static struct devlink_health_reporter * 5812__devlink_health_reporter_find_by_name(struct list_head *reporter_list, 5813 struct mutex *list_lock, 5814 const char *reporter_name) 5815{ 5816 struct devlink_health_reporter *reporter; 5817 5818 lockdep_assert_held(list_lock); 5819 list_for_each_entry(reporter, reporter_list, list) 5820 if (!strcmp(reporter->ops->name, reporter_name)) 5821 return reporter; 5822 return NULL; 5823} 5824 5825static struct devlink_health_reporter * 5826devlink_health_reporter_find_by_name(struct devlink *devlink, 5827 const char *reporter_name) 5828{ 5829 return __devlink_health_reporter_find_by_name(&devlink->reporter_list, 5830 &devlink->reporters_lock, 5831 reporter_name); 5832} 5833 5834static struct devlink_health_reporter * 5835devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port, 5836 const char *reporter_name) 5837{ 5838 return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list, 5839 &devlink_port->reporters_lock, 5840 reporter_name); 5841} 5842 5843static struct devlink_health_reporter * 5844__devlink_health_reporter_create(struct devlink *devlink, 5845 const struct devlink_health_reporter_ops *ops, 5846 u64 graceful_period, void *priv) 5847{ 5848 struct devlink_health_reporter *reporter; 5849 5850 if (WARN_ON(graceful_period && !ops->recover)) 5851 return ERR_PTR(-EINVAL); 5852 5853 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL); 5854 if (!reporter) 5855 return ERR_PTR(-ENOMEM); 5856 5857 reporter->priv = priv; 5858 reporter->ops = ops; 5859 reporter->devlink = devlink; 5860 reporter->graceful_period = graceful_period; 5861 reporter->auto_recover = !!ops->recover; 5862 reporter->auto_dump = !!ops->dump; 5863 mutex_init(&reporter->dump_lock); 5864 refcount_set(&reporter->refcount, 1); 5865 return reporter; 5866} 5867 5868/** 5869 * devlink_port_health_reporter_create - create devlink health reporter for 5870 * specified port instance 5871 * 5872 * @port: devlink_port which should contain the new reporter 5873 * @ops: ops 5874 * @graceful_period: to avoid recovery loops, in msecs 5875 * @priv: priv 5876 */ 5877struct devlink_health_reporter * 5878devlink_port_health_reporter_create(struct devlink_port *port, 5879 const struct devlink_health_reporter_ops *ops, 5880 u64 graceful_period, void *priv) 5881{ 5882 struct devlink_health_reporter *reporter; 5883 5884 mutex_lock(&port->reporters_lock); 5885 if (__devlink_health_reporter_find_by_name(&port->reporter_list, 5886 &port->reporters_lock, ops->name)) { 5887 reporter = ERR_PTR(-EEXIST); 5888 goto unlock; 5889 } 5890 5891 reporter = __devlink_health_reporter_create(port->devlink, ops, 5892 graceful_period, priv); 5893 if (IS_ERR(reporter)) 5894 goto unlock; 5895 5896 reporter->devlink_port = port; 5897 list_add_tail(&reporter->list, &port->reporter_list); 5898unlock: 5899 mutex_unlock(&port->reporters_lock); 5900 return reporter; 5901} 5902EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create); 5903 5904/** 5905 * devlink_health_reporter_create - create devlink health reporter 5906 * 5907 * @devlink: devlink 5908 * @ops: ops 5909 * @graceful_period: to avoid recovery loops, in msecs 5910 * @priv: priv 5911 */ 5912struct devlink_health_reporter * 5913devlink_health_reporter_create(struct devlink *devlink, 5914 const struct devlink_health_reporter_ops *ops, 5915 u64 graceful_period, void *priv) 5916{ 5917 struct devlink_health_reporter *reporter; 5918 5919 mutex_lock(&devlink->reporters_lock); 5920 if (devlink_health_reporter_find_by_name(devlink, ops->name)) { 5921 reporter = ERR_PTR(-EEXIST); 5922 goto unlock; 5923 } 5924 5925 reporter = __devlink_health_reporter_create(devlink, ops, 5926 graceful_period, priv); 5927 if (IS_ERR(reporter)) 5928 goto unlock; 5929 5930 list_add_tail(&reporter->list, &devlink->reporter_list); 5931unlock: 5932 mutex_unlock(&devlink->reporters_lock); 5933 return reporter; 5934} 5935EXPORT_SYMBOL_GPL(devlink_health_reporter_create); 5936 5937static void 5938devlink_health_reporter_free(struct devlink_health_reporter *reporter) 5939{ 5940 mutex_destroy(&reporter->dump_lock); 5941 if (reporter->dump_fmsg) 5942 devlink_fmsg_free(reporter->dump_fmsg); 5943 kfree(reporter); 5944} 5945 5946static void 5947devlink_health_reporter_put(struct devlink_health_reporter *reporter) 5948{ 5949 if (refcount_dec_and_test(&reporter->refcount)) 5950 devlink_health_reporter_free(reporter); 5951} 5952 5953static void 5954__devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) 5955{ 5956 list_del(&reporter->list); 5957 devlink_health_reporter_put(reporter); 5958} 5959 5960/** 5961 * devlink_health_reporter_destroy - destroy devlink health reporter 5962 * 5963 * @reporter: devlink health reporter to destroy 5964 */ 5965void 5966devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) 5967{ 5968 struct mutex *lock = &reporter->devlink->reporters_lock; 5969 5970 mutex_lock(lock); 5971 __devlink_health_reporter_destroy(reporter); 5972 mutex_unlock(lock); 5973} 5974EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy); 5975 5976/** 5977 * devlink_port_health_reporter_destroy - destroy devlink port health reporter 5978 * 5979 * @reporter: devlink health reporter to destroy 5980 */ 5981void 5982devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter) 5983{ 5984 struct mutex *lock = &reporter->devlink_port->reporters_lock; 5985 5986 mutex_lock(lock); 5987 __devlink_health_reporter_destroy(reporter); 5988 mutex_unlock(lock); 5989} 5990EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy); 5991 5992static int 5993devlink_nl_health_reporter_fill(struct sk_buff *msg, 5994 struct devlink *devlink, 5995 struct devlink_health_reporter *reporter, 5996 enum devlink_command cmd, u32 portid, 5997 u32 seq, int flags) 5998{ 5999 struct nlattr *reporter_attr; 6000 void *hdr; 6001 6002 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 6003 if (!hdr) 6004 return -EMSGSIZE; 6005 6006 if (devlink_nl_put_handle(msg, devlink)) 6007 goto genlmsg_cancel; 6008 6009 if (reporter->devlink_port) { 6010 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index)) 6011 goto genlmsg_cancel; 6012 } 6013 reporter_attr = nla_nest_start_noflag(msg, 6014 DEVLINK_ATTR_HEALTH_REPORTER); 6015 if (!reporter_attr) 6016 goto genlmsg_cancel; 6017 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME, 6018 reporter->ops->name)) 6019 goto reporter_nest_cancel; 6020 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE, 6021 reporter->health_state)) 6022 goto reporter_nest_cancel; 6023 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT, 6024 reporter->error_count, DEVLINK_ATTR_PAD)) 6025 goto reporter_nest_cancel; 6026 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT, 6027 reporter->recovery_count, DEVLINK_ATTR_PAD)) 6028 goto reporter_nest_cancel; 6029 if (reporter->ops->recover && 6030 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD, 6031 reporter->graceful_period, 6032 DEVLINK_ATTR_PAD)) 6033 goto reporter_nest_cancel; 6034 if (reporter->ops->recover && 6035 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER, 6036 reporter->auto_recover)) 6037 goto reporter_nest_cancel; 6038 if (reporter->dump_fmsg && 6039 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS, 6040 jiffies_to_msecs(reporter->dump_ts), 6041 DEVLINK_ATTR_PAD)) 6042 goto reporter_nest_cancel; 6043 if (reporter->dump_fmsg && 6044 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS, 6045 reporter->dump_real_ts, DEVLINK_ATTR_PAD)) 6046 goto reporter_nest_cancel; 6047 if (reporter->ops->dump && 6048 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, 6049 reporter->auto_dump)) 6050 goto reporter_nest_cancel; 6051 6052 nla_nest_end(msg, reporter_attr); 6053 genlmsg_end(msg, hdr); 6054 return 0; 6055 6056reporter_nest_cancel: 6057 nla_nest_end(msg, reporter_attr); 6058genlmsg_cancel: 6059 genlmsg_cancel(msg, hdr); 6060 return -EMSGSIZE; 6061} 6062 6063static void devlink_recover_notify(struct devlink_health_reporter *reporter, 6064 enum devlink_command cmd) 6065{ 6066 struct sk_buff *msg; 6067 int err; 6068 6069 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6070 6071 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6072 if (!msg) 6073 return; 6074 6075 err = devlink_nl_health_reporter_fill(msg, reporter->devlink, 6076 reporter, cmd, 0, 0, 0); 6077 if (err) { 6078 nlmsg_free(msg); 6079 return; 6080 } 6081 6082 genlmsg_multicast_netns(&devlink_nl_family, 6083 devlink_net(reporter->devlink), 6084 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 6085} 6086 6087void 6088devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter) 6089{ 6090 reporter->recovery_count++; 6091 reporter->last_recovery_ts = jiffies; 6092} 6093EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done); 6094 6095static int 6096devlink_health_reporter_recover(struct devlink_health_reporter *reporter, 6097 void *priv_ctx, struct netlink_ext_ack *extack) 6098{ 6099 int err; 6100 6101 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY) 6102 return 0; 6103 6104 if (!reporter->ops->recover) 6105 return -EOPNOTSUPP; 6106 6107 err = reporter->ops->recover(reporter, priv_ctx, extack); 6108 if (err) 6109 return err; 6110 6111 devlink_health_reporter_recovery_done(reporter); 6112 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY; 6113 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6114 6115 return 0; 6116} 6117 6118static void 6119devlink_health_dump_clear(struct devlink_health_reporter *reporter) 6120{ 6121 if (!reporter->dump_fmsg) 6122 return; 6123 devlink_fmsg_free(reporter->dump_fmsg); 6124 reporter->dump_fmsg = NULL; 6125} 6126 6127static int devlink_health_do_dump(struct devlink_health_reporter *reporter, 6128 void *priv_ctx, 6129 struct netlink_ext_ack *extack) 6130{ 6131 int err; 6132 6133 if (!reporter->ops->dump) 6134 return 0; 6135 6136 if (reporter->dump_fmsg) 6137 return 0; 6138 6139 reporter->dump_fmsg = devlink_fmsg_alloc(); 6140 if (!reporter->dump_fmsg) { 6141 err = -ENOMEM; 6142 return err; 6143 } 6144 6145 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg); 6146 if (err) 6147 goto dump_err; 6148 6149 err = reporter->ops->dump(reporter, reporter->dump_fmsg, 6150 priv_ctx, extack); 6151 if (err) 6152 goto dump_err; 6153 6154 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg); 6155 if (err) 6156 goto dump_err; 6157 6158 reporter->dump_ts = jiffies; 6159 reporter->dump_real_ts = ktime_get_real_ns(); 6160 6161 return 0; 6162 6163dump_err: 6164 devlink_health_dump_clear(reporter); 6165 return err; 6166} 6167 6168int devlink_health_report(struct devlink_health_reporter *reporter, 6169 const char *msg, void *priv_ctx) 6170{ 6171 enum devlink_health_reporter_state prev_health_state; 6172 struct devlink *devlink = reporter->devlink; 6173 unsigned long recover_ts_threshold; 6174 6175 /* write a log message of the current error */ 6176 WARN_ON(!msg); 6177 trace_devlink_health_report(devlink, reporter->ops->name, msg); 6178 reporter->error_count++; 6179 prev_health_state = reporter->health_state; 6180 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; 6181 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6182 6183 /* abort if the previous error wasn't recovered */ 6184 recover_ts_threshold = reporter->last_recovery_ts + 6185 msecs_to_jiffies(reporter->graceful_period); 6186 if (reporter->auto_recover && 6187 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY || 6188 (reporter->last_recovery_ts && reporter->recovery_count && 6189 time_is_after_jiffies(recover_ts_threshold)))) { 6190 trace_devlink_health_recover_aborted(devlink, 6191 reporter->ops->name, 6192 reporter->health_state, 6193 jiffies - 6194 reporter->last_recovery_ts); 6195 return -ECANCELED; 6196 } 6197 6198 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; 6199 6200 if (reporter->auto_dump) { 6201 mutex_lock(&reporter->dump_lock); 6202 /* store current dump of current error, for later analysis */ 6203 devlink_health_do_dump(reporter, priv_ctx, NULL); 6204 mutex_unlock(&reporter->dump_lock); 6205 } 6206 6207 if (reporter->auto_recover) 6208 return devlink_health_reporter_recover(reporter, 6209 priv_ctx, NULL); 6210 6211 return 0; 6212} 6213EXPORT_SYMBOL_GPL(devlink_health_report); 6214 6215static struct devlink_health_reporter * 6216devlink_health_reporter_get_from_attrs(struct devlink *devlink, 6217 struct nlattr **attrs) 6218{ 6219 struct devlink_health_reporter *reporter; 6220 struct devlink_port *devlink_port; 6221 char *reporter_name; 6222 6223 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]) 6224 return NULL; 6225 6226 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]); 6227 devlink_port = devlink_port_get_from_attrs(devlink, attrs); 6228 if (IS_ERR(devlink_port)) { 6229 mutex_lock(&devlink->reporters_lock); 6230 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name); 6231 if (reporter) 6232 refcount_inc(&reporter->refcount); 6233 mutex_unlock(&devlink->reporters_lock); 6234 } else { 6235 mutex_lock(&devlink_port->reporters_lock); 6236 reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name); 6237 if (reporter) 6238 refcount_inc(&reporter->refcount); 6239 mutex_unlock(&devlink_port->reporters_lock); 6240 } 6241 6242 return reporter; 6243} 6244 6245static struct devlink_health_reporter * 6246devlink_health_reporter_get_from_info(struct devlink *devlink, 6247 struct genl_info *info) 6248{ 6249 return devlink_health_reporter_get_from_attrs(devlink, info->attrs); 6250} 6251 6252static struct devlink_health_reporter * 6253devlink_health_reporter_get_from_cb(struct netlink_callback *cb) 6254{ 6255 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 6256 struct devlink_health_reporter *reporter; 6257 struct nlattr **attrs = info->attrs; 6258 struct devlink *devlink; 6259 6260 mutex_lock(&devlink_mutex); 6261 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); 6262 if (IS_ERR(devlink)) 6263 goto unlock; 6264 6265 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs); 6266 mutex_unlock(&devlink_mutex); 6267 return reporter; 6268unlock: 6269 mutex_unlock(&devlink_mutex); 6270 return NULL; 6271} 6272 6273void 6274devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, 6275 enum devlink_health_reporter_state state) 6276{ 6277 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY && 6278 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR)) 6279 return; 6280 6281 if (reporter->health_state == state) 6282 return; 6283 6284 reporter->health_state = state; 6285 trace_devlink_health_reporter_state_update(reporter->devlink, 6286 reporter->ops->name, state); 6287 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 6288} 6289EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update); 6290 6291static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, 6292 struct genl_info *info) 6293{ 6294 struct devlink *devlink = info->user_ptr[0]; 6295 struct devlink_health_reporter *reporter; 6296 struct sk_buff *msg; 6297 int err; 6298 6299 reporter = devlink_health_reporter_get_from_info(devlink, info); 6300 if (!reporter) 6301 return -EINVAL; 6302 6303 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6304 if (!msg) { 6305 err = -ENOMEM; 6306 goto out; 6307 } 6308 6309 err = devlink_nl_health_reporter_fill(msg, devlink, reporter, 6310 DEVLINK_CMD_HEALTH_REPORTER_GET, 6311 info->snd_portid, info->snd_seq, 6312 0); 6313 if (err) { 6314 nlmsg_free(msg); 6315 goto out; 6316 } 6317 6318 err = genlmsg_reply(msg, info); 6319out: 6320 devlink_health_reporter_put(reporter); 6321 return err; 6322} 6323 6324static int 6325devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg, 6326 struct netlink_callback *cb) 6327{ 6328 struct devlink_health_reporter *reporter; 6329 struct devlink_port *port; 6330 struct devlink *devlink; 6331 int start = cb->args[0]; 6332 int idx = 0; 6333 int err; 6334 6335 mutex_lock(&devlink_mutex); 6336 list_for_each_entry(devlink, &devlink_list, list) { 6337 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 6338 continue; 6339 mutex_lock(&devlink->reporters_lock); 6340 list_for_each_entry(reporter, &devlink->reporter_list, 6341 list) { 6342 if (idx < start) { 6343 idx++; 6344 continue; 6345 } 6346 err = devlink_nl_health_reporter_fill(msg, devlink, 6347 reporter, 6348 DEVLINK_CMD_HEALTH_REPORTER_GET, 6349 NETLINK_CB(cb->skb).portid, 6350 cb->nlh->nlmsg_seq, 6351 NLM_F_MULTI); 6352 if (err) { 6353 mutex_unlock(&devlink->reporters_lock); 6354 goto out; 6355 } 6356 idx++; 6357 } 6358 mutex_unlock(&devlink->reporters_lock); 6359 } 6360 6361 list_for_each_entry(devlink, &devlink_list, list) { 6362 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 6363 continue; 6364 mutex_lock(&devlink->lock); 6365 list_for_each_entry(port, &devlink->port_list, list) { 6366 mutex_lock(&port->reporters_lock); 6367 list_for_each_entry(reporter, &port->reporter_list, list) { 6368 if (idx < start) { 6369 idx++; 6370 continue; 6371 } 6372 err = devlink_nl_health_reporter_fill(msg, devlink, reporter, 6373 DEVLINK_CMD_HEALTH_REPORTER_GET, 6374 NETLINK_CB(cb->skb).portid, 6375 cb->nlh->nlmsg_seq, 6376 NLM_F_MULTI); 6377 if (err) { 6378 mutex_unlock(&port->reporters_lock); 6379 mutex_unlock(&devlink->lock); 6380 goto out; 6381 } 6382 idx++; 6383 } 6384 mutex_unlock(&port->reporters_lock); 6385 } 6386 mutex_unlock(&devlink->lock); 6387 } 6388out: 6389 mutex_unlock(&devlink_mutex); 6390 6391 cb->args[0] = idx; 6392 return msg->len; 6393} 6394 6395static int 6396devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, 6397 struct genl_info *info) 6398{ 6399 struct devlink *devlink = info->user_ptr[0]; 6400 struct devlink_health_reporter *reporter; 6401 int err; 6402 6403 reporter = devlink_health_reporter_get_from_info(devlink, info); 6404 if (!reporter) 6405 return -EINVAL; 6406 6407 if (!reporter->ops->recover && 6408 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] || 6409 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) { 6410 err = -EOPNOTSUPP; 6411 goto out; 6412 } 6413 if (!reporter->ops->dump && 6414 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) { 6415 err = -EOPNOTSUPP; 6416 goto out; 6417 } 6418 6419 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]) 6420 reporter->graceful_period = 6421 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]); 6422 6423 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]) 6424 reporter->auto_recover = 6425 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]); 6426 6427 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) 6428 reporter->auto_dump = 6429 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]); 6430 6431 devlink_health_reporter_put(reporter); 6432 return 0; 6433out: 6434 devlink_health_reporter_put(reporter); 6435 return err; 6436} 6437 6438static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb, 6439 struct genl_info *info) 6440{ 6441 struct devlink *devlink = info->user_ptr[0]; 6442 struct devlink_health_reporter *reporter; 6443 int err; 6444 6445 reporter = devlink_health_reporter_get_from_info(devlink, info); 6446 if (!reporter) 6447 return -EINVAL; 6448 6449 err = devlink_health_reporter_recover(reporter, NULL, info->extack); 6450 6451 devlink_health_reporter_put(reporter); 6452 return err; 6453} 6454 6455static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, 6456 struct genl_info *info) 6457{ 6458 struct devlink *devlink = info->user_ptr[0]; 6459 struct devlink_health_reporter *reporter; 6460 struct devlink_fmsg *fmsg; 6461 int err; 6462 6463 reporter = devlink_health_reporter_get_from_info(devlink, info); 6464 if (!reporter) 6465 return -EINVAL; 6466 6467 if (!reporter->ops->diagnose) { 6468 devlink_health_reporter_put(reporter); 6469 return -EOPNOTSUPP; 6470 } 6471 6472 fmsg = devlink_fmsg_alloc(); 6473 if (!fmsg) { 6474 devlink_health_reporter_put(reporter); 6475 return -ENOMEM; 6476 } 6477 6478 err = devlink_fmsg_obj_nest_start(fmsg); 6479 if (err) 6480 goto out; 6481 6482 err = reporter->ops->diagnose(reporter, fmsg, info->extack); 6483 if (err) 6484 goto out; 6485 6486 err = devlink_fmsg_obj_nest_end(fmsg); 6487 if (err) 6488 goto out; 6489 6490 err = devlink_fmsg_snd(fmsg, info, 6491 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0); 6492 6493out: 6494 devlink_fmsg_free(fmsg); 6495 devlink_health_reporter_put(reporter); 6496 return err; 6497} 6498 6499static int 6500devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb, 6501 struct netlink_callback *cb) 6502{ 6503 struct devlink_health_reporter *reporter; 6504 u64 start = cb->args[0]; 6505 int err; 6506 6507 reporter = devlink_health_reporter_get_from_cb(cb); 6508 if (!reporter) 6509 return -EINVAL; 6510 6511 if (!reporter->ops->dump) { 6512 err = -EOPNOTSUPP; 6513 goto out; 6514 } 6515 mutex_lock(&reporter->dump_lock); 6516 if (!start) { 6517 err = devlink_health_do_dump(reporter, NULL, cb->extack); 6518 if (err) 6519 goto unlock; 6520 cb->args[1] = reporter->dump_ts; 6521 } 6522 if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) { 6523 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry"); 6524 err = -EAGAIN; 6525 goto unlock; 6526 } 6527 6528 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb, 6529 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET); 6530unlock: 6531 mutex_unlock(&reporter->dump_lock); 6532out: 6533 devlink_health_reporter_put(reporter); 6534 return err; 6535} 6536 6537static int 6538devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb, 6539 struct genl_info *info) 6540{ 6541 struct devlink *devlink = info->user_ptr[0]; 6542 struct devlink_health_reporter *reporter; 6543 6544 reporter = devlink_health_reporter_get_from_info(devlink, info); 6545 if (!reporter) 6546 return -EINVAL; 6547 6548 if (!reporter->ops->dump) { 6549 devlink_health_reporter_put(reporter); 6550 return -EOPNOTSUPP; 6551 } 6552 6553 mutex_lock(&reporter->dump_lock); 6554 devlink_health_dump_clear(reporter); 6555 mutex_unlock(&reporter->dump_lock); 6556 devlink_health_reporter_put(reporter); 6557 return 0; 6558} 6559 6560static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb, 6561 struct genl_info *info) 6562{ 6563 struct devlink *devlink = info->user_ptr[0]; 6564 struct devlink_health_reporter *reporter; 6565 int err; 6566 6567 reporter = devlink_health_reporter_get_from_info(devlink, info); 6568 if (!reporter) 6569 return -EINVAL; 6570 6571 if (!reporter->ops->test) { 6572 devlink_health_reporter_put(reporter); 6573 return -EOPNOTSUPP; 6574 } 6575 6576 err = reporter->ops->test(reporter, info->extack); 6577 6578 devlink_health_reporter_put(reporter); 6579 return err; 6580} 6581 6582struct devlink_stats { 6583 u64 rx_bytes; 6584 u64 rx_packets; 6585 struct u64_stats_sync syncp; 6586}; 6587 6588/** 6589 * struct devlink_trap_policer_item - Packet trap policer attributes. 6590 * @policer: Immutable packet trap policer attributes. 6591 * @rate: Rate in packets / sec. 6592 * @burst: Burst size in packets. 6593 * @list: trap_policer_list member. 6594 * 6595 * Describes packet trap policer attributes. Created by devlink during trap 6596 * policer registration. 6597 */ 6598struct devlink_trap_policer_item { 6599 const struct devlink_trap_policer *policer; 6600 u64 rate; 6601 u64 burst; 6602 struct list_head list; 6603}; 6604 6605/** 6606 * struct devlink_trap_group_item - Packet trap group attributes. 6607 * @group: Immutable packet trap group attributes. 6608 * @policer_item: Associated policer item. Can be NULL. 6609 * @list: trap_group_list member. 6610 * @stats: Trap group statistics. 6611 * 6612 * Describes packet trap group attributes. Created by devlink during trap 6613 * group registration. 6614 */ 6615struct devlink_trap_group_item { 6616 const struct devlink_trap_group *group; 6617 struct devlink_trap_policer_item *policer_item; 6618 struct list_head list; 6619 struct devlink_stats __percpu *stats; 6620}; 6621 6622/** 6623 * struct devlink_trap_item - Packet trap attributes. 6624 * @trap: Immutable packet trap attributes. 6625 * @group_item: Associated group item. 6626 * @list: trap_list member. 6627 * @action: Trap action. 6628 * @stats: Trap statistics. 6629 * @priv: Driver private information. 6630 * 6631 * Describes both mutable and immutable packet trap attributes. Created by 6632 * devlink during trap registration and used for all trap related operations. 6633 */ 6634struct devlink_trap_item { 6635 const struct devlink_trap *trap; 6636 struct devlink_trap_group_item *group_item; 6637 struct list_head list; 6638 enum devlink_trap_action action; 6639 struct devlink_stats __percpu *stats; 6640 void *priv; 6641}; 6642 6643static struct devlink_trap_policer_item * 6644devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id) 6645{ 6646 struct devlink_trap_policer_item *policer_item; 6647 6648 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) { 6649 if (policer_item->policer->id == id) 6650 return policer_item; 6651 } 6652 6653 return NULL; 6654} 6655 6656static struct devlink_trap_item * 6657devlink_trap_item_lookup(struct devlink *devlink, const char *name) 6658{ 6659 struct devlink_trap_item *trap_item; 6660 6661 list_for_each_entry(trap_item, &devlink->trap_list, list) { 6662 if (!strcmp(trap_item->trap->name, name)) 6663 return trap_item; 6664 } 6665 6666 return NULL; 6667} 6668 6669static struct devlink_trap_item * 6670devlink_trap_item_get_from_info(struct devlink *devlink, 6671 struct genl_info *info) 6672{ 6673 struct nlattr *attr; 6674 6675 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME]) 6676 return NULL; 6677 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME]; 6678 6679 return devlink_trap_item_lookup(devlink, nla_data(attr)); 6680} 6681 6682static int 6683devlink_trap_action_get_from_info(struct genl_info *info, 6684 enum devlink_trap_action *p_trap_action) 6685{ 6686 u8 val; 6687 6688 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]); 6689 switch (val) { 6690 case DEVLINK_TRAP_ACTION_DROP: 6691 case DEVLINK_TRAP_ACTION_TRAP: 6692 case DEVLINK_TRAP_ACTION_MIRROR: 6693 *p_trap_action = val; 6694 break; 6695 default: 6696 return -EINVAL; 6697 } 6698 6699 return 0; 6700} 6701 6702static int devlink_trap_metadata_put(struct sk_buff *msg, 6703 const struct devlink_trap *trap) 6704{ 6705 struct nlattr *attr; 6706 6707 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA); 6708 if (!attr) 6709 return -EMSGSIZE; 6710 6711 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) && 6712 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT)) 6713 goto nla_put_failure; 6714 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) && 6715 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE)) 6716 goto nla_put_failure; 6717 6718 nla_nest_end(msg, attr); 6719 6720 return 0; 6721 6722nla_put_failure: 6723 nla_nest_cancel(msg, attr); 6724 return -EMSGSIZE; 6725} 6726 6727static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats, 6728 struct devlink_stats *stats) 6729{ 6730 int i; 6731 6732 memset(stats, 0, sizeof(*stats)); 6733 for_each_possible_cpu(i) { 6734 struct devlink_stats *cpu_stats; 6735 u64 rx_packets, rx_bytes; 6736 unsigned int start; 6737 6738 cpu_stats = per_cpu_ptr(trap_stats, i); 6739 do { 6740 start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); 6741 rx_packets = cpu_stats->rx_packets; 6742 rx_bytes = cpu_stats->rx_bytes; 6743 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); 6744 6745 stats->rx_packets += rx_packets; 6746 stats->rx_bytes += rx_bytes; 6747 } 6748} 6749 6750static int devlink_trap_stats_put(struct sk_buff *msg, 6751 struct devlink_stats __percpu *trap_stats) 6752{ 6753 struct devlink_stats stats; 6754 struct nlattr *attr; 6755 6756 devlink_trap_stats_read(trap_stats, &stats); 6757 6758 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); 6759 if (!attr) 6760 return -EMSGSIZE; 6761 6762 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS, 6763 stats.rx_packets, DEVLINK_ATTR_PAD)) 6764 goto nla_put_failure; 6765 6766 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES, 6767 stats.rx_bytes, DEVLINK_ATTR_PAD)) 6768 goto nla_put_failure; 6769 6770 nla_nest_end(msg, attr); 6771 6772 return 0; 6773 6774nla_put_failure: 6775 nla_nest_cancel(msg, attr); 6776 return -EMSGSIZE; 6777} 6778 6779static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink, 6780 const struct devlink_trap_item *trap_item, 6781 enum devlink_command cmd, u32 portid, u32 seq, 6782 int flags) 6783{ 6784 struct devlink_trap_group_item *group_item = trap_item->group_item; 6785 void *hdr; 6786 int err; 6787 6788 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 6789 if (!hdr) 6790 return -EMSGSIZE; 6791 6792 if (devlink_nl_put_handle(msg, devlink)) 6793 goto nla_put_failure; 6794 6795 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, 6796 group_item->group->name)) 6797 goto nla_put_failure; 6798 6799 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name)) 6800 goto nla_put_failure; 6801 6802 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type)) 6803 goto nla_put_failure; 6804 6805 if (trap_item->trap->generic && 6806 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) 6807 goto nla_put_failure; 6808 6809 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action)) 6810 goto nla_put_failure; 6811 6812 err = devlink_trap_metadata_put(msg, trap_item->trap); 6813 if (err) 6814 goto nla_put_failure; 6815 6816 err = devlink_trap_stats_put(msg, trap_item->stats); 6817 if (err) 6818 goto nla_put_failure; 6819 6820 genlmsg_end(msg, hdr); 6821 6822 return 0; 6823 6824nla_put_failure: 6825 genlmsg_cancel(msg, hdr); 6826 return -EMSGSIZE; 6827} 6828 6829static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb, 6830 struct genl_info *info) 6831{ 6832 struct netlink_ext_ack *extack = info->extack; 6833 struct devlink *devlink = info->user_ptr[0]; 6834 struct devlink_trap_item *trap_item; 6835 struct sk_buff *msg; 6836 int err; 6837 6838 if (list_empty(&devlink->trap_list)) 6839 return -EOPNOTSUPP; 6840 6841 trap_item = devlink_trap_item_get_from_info(devlink, info); 6842 if (!trap_item) { 6843 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); 6844 return -ENOENT; 6845 } 6846 6847 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6848 if (!msg) 6849 return -ENOMEM; 6850 6851 err = devlink_nl_trap_fill(msg, devlink, trap_item, 6852 DEVLINK_CMD_TRAP_NEW, info->snd_portid, 6853 info->snd_seq, 0); 6854 if (err) 6855 goto err_trap_fill; 6856 6857 return genlmsg_reply(msg, info); 6858 6859err_trap_fill: 6860 nlmsg_free(msg); 6861 return err; 6862} 6863 6864static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg, 6865 struct netlink_callback *cb) 6866{ 6867 struct devlink_trap_item *trap_item; 6868 struct devlink *devlink; 6869 int start = cb->args[0]; 6870 int idx = 0; 6871 int err; 6872 6873 mutex_lock(&devlink_mutex); 6874 list_for_each_entry(devlink, &devlink_list, list) { 6875 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 6876 continue; 6877 mutex_lock(&devlink->lock); 6878 list_for_each_entry(trap_item, &devlink->trap_list, list) { 6879 if (idx < start) { 6880 idx++; 6881 continue; 6882 } 6883 err = devlink_nl_trap_fill(msg, devlink, trap_item, 6884 DEVLINK_CMD_TRAP_NEW, 6885 NETLINK_CB(cb->skb).portid, 6886 cb->nlh->nlmsg_seq, 6887 NLM_F_MULTI); 6888 if (err) { 6889 mutex_unlock(&devlink->lock); 6890 goto out; 6891 } 6892 idx++; 6893 } 6894 mutex_unlock(&devlink->lock); 6895 } 6896out: 6897 mutex_unlock(&devlink_mutex); 6898 6899 cb->args[0] = idx; 6900 return msg->len; 6901} 6902 6903static int __devlink_trap_action_set(struct devlink *devlink, 6904 struct devlink_trap_item *trap_item, 6905 enum devlink_trap_action trap_action, 6906 struct netlink_ext_ack *extack) 6907{ 6908 int err; 6909 6910 if (trap_item->action != trap_action && 6911 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) { 6912 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping"); 6913 return 0; 6914 } 6915 6916 err = devlink->ops->trap_action_set(devlink, trap_item->trap, 6917 trap_action, extack); 6918 if (err) 6919 return err; 6920 6921 trap_item->action = trap_action; 6922 6923 return 0; 6924} 6925 6926static int devlink_trap_action_set(struct devlink *devlink, 6927 struct devlink_trap_item *trap_item, 6928 struct genl_info *info) 6929{ 6930 enum devlink_trap_action trap_action; 6931 int err; 6932 6933 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) 6934 return 0; 6935 6936 err = devlink_trap_action_get_from_info(info, &trap_action); 6937 if (err) { 6938 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); 6939 return -EINVAL; 6940 } 6941 6942 return __devlink_trap_action_set(devlink, trap_item, trap_action, 6943 info->extack); 6944} 6945 6946static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb, 6947 struct genl_info *info) 6948{ 6949 struct netlink_ext_ack *extack = info->extack; 6950 struct devlink *devlink = info->user_ptr[0]; 6951 struct devlink_trap_item *trap_item; 6952 int err; 6953 6954 if (list_empty(&devlink->trap_list)) 6955 return -EOPNOTSUPP; 6956 6957 trap_item = devlink_trap_item_get_from_info(devlink, info); 6958 if (!trap_item) { 6959 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); 6960 return -ENOENT; 6961 } 6962 6963 err = devlink_trap_action_set(devlink, trap_item, info); 6964 if (err) 6965 return err; 6966 6967 return 0; 6968} 6969 6970static struct devlink_trap_group_item * 6971devlink_trap_group_item_lookup(struct devlink *devlink, const char *name) 6972{ 6973 struct devlink_trap_group_item *group_item; 6974 6975 list_for_each_entry(group_item, &devlink->trap_group_list, list) { 6976 if (!strcmp(group_item->group->name, name)) 6977 return group_item; 6978 } 6979 6980 return NULL; 6981} 6982 6983static struct devlink_trap_group_item * 6984devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id) 6985{ 6986 struct devlink_trap_group_item *group_item; 6987 6988 list_for_each_entry(group_item, &devlink->trap_group_list, list) { 6989 if (group_item->group->id == id) 6990 return group_item; 6991 } 6992 6993 return NULL; 6994} 6995 6996static struct devlink_trap_group_item * 6997devlink_trap_group_item_get_from_info(struct devlink *devlink, 6998 struct genl_info *info) 6999{ 7000 char *name; 7001 7002 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]) 7003 return NULL; 7004 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]); 7005 7006 return devlink_trap_group_item_lookup(devlink, name); 7007} 7008 7009static int 7010devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink, 7011 const struct devlink_trap_group_item *group_item, 7012 enum devlink_command cmd, u32 portid, u32 seq, 7013 int flags) 7014{ 7015 void *hdr; 7016 int err; 7017 7018 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 7019 if (!hdr) 7020 return -EMSGSIZE; 7021 7022 if (devlink_nl_put_handle(msg, devlink)) 7023 goto nla_put_failure; 7024 7025 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, 7026 group_item->group->name)) 7027 goto nla_put_failure; 7028 7029 if (group_item->group->generic && 7030 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) 7031 goto nla_put_failure; 7032 7033 if (group_item->policer_item && 7034 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, 7035 group_item->policer_item->policer->id)) 7036 goto nla_put_failure; 7037 7038 err = devlink_trap_stats_put(msg, group_item->stats); 7039 if (err) 7040 goto nla_put_failure; 7041 7042 genlmsg_end(msg, hdr); 7043 7044 return 0; 7045 7046nla_put_failure: 7047 genlmsg_cancel(msg, hdr); 7048 return -EMSGSIZE; 7049} 7050 7051static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb, 7052 struct genl_info *info) 7053{ 7054 struct netlink_ext_ack *extack = info->extack; 7055 struct devlink *devlink = info->user_ptr[0]; 7056 struct devlink_trap_group_item *group_item; 7057 struct sk_buff *msg; 7058 int err; 7059 7060 if (list_empty(&devlink->trap_group_list)) 7061 return -EOPNOTSUPP; 7062 7063 group_item = devlink_trap_group_item_get_from_info(devlink, info); 7064 if (!group_item) { 7065 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); 7066 return -ENOENT; 7067 } 7068 7069 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7070 if (!msg) 7071 return -ENOMEM; 7072 7073 err = devlink_nl_trap_group_fill(msg, devlink, group_item, 7074 DEVLINK_CMD_TRAP_GROUP_NEW, 7075 info->snd_portid, info->snd_seq, 0); 7076 if (err) 7077 goto err_trap_group_fill; 7078 7079 return genlmsg_reply(msg, info); 7080 7081err_trap_group_fill: 7082 nlmsg_free(msg); 7083 return err; 7084} 7085 7086static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg, 7087 struct netlink_callback *cb) 7088{ 7089 enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW; 7090 struct devlink_trap_group_item *group_item; 7091 u32 portid = NETLINK_CB(cb->skb).portid; 7092 struct devlink *devlink; 7093 int start = cb->args[0]; 7094 int idx = 0; 7095 int err; 7096 7097 mutex_lock(&devlink_mutex); 7098 list_for_each_entry(devlink, &devlink_list, list) { 7099 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 7100 continue; 7101 mutex_lock(&devlink->lock); 7102 list_for_each_entry(group_item, &devlink->trap_group_list, 7103 list) { 7104 if (idx < start) { 7105 idx++; 7106 continue; 7107 } 7108 err = devlink_nl_trap_group_fill(msg, devlink, 7109 group_item, cmd, 7110 portid, 7111 cb->nlh->nlmsg_seq, 7112 NLM_F_MULTI); 7113 if (err) { 7114 mutex_unlock(&devlink->lock); 7115 goto out; 7116 } 7117 idx++; 7118 } 7119 mutex_unlock(&devlink->lock); 7120 } 7121out: 7122 mutex_unlock(&devlink_mutex); 7123 7124 cb->args[0] = idx; 7125 return msg->len; 7126} 7127 7128static int 7129__devlink_trap_group_action_set(struct devlink *devlink, 7130 struct devlink_trap_group_item *group_item, 7131 enum devlink_trap_action trap_action, 7132 struct netlink_ext_ack *extack) 7133{ 7134 const char *group_name = group_item->group->name; 7135 struct devlink_trap_item *trap_item; 7136 int err; 7137 7138 if (devlink->ops->trap_group_action_set) { 7139 err = devlink->ops->trap_group_action_set(devlink, group_item->group, 7140 trap_action, extack); 7141 if (err) 7142 return err; 7143 7144 list_for_each_entry(trap_item, &devlink->trap_list, list) { 7145 if (strcmp(trap_item->group_item->group->name, group_name)) 7146 continue; 7147 if (trap_item->action != trap_action && 7148 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) 7149 continue; 7150 trap_item->action = trap_action; 7151 } 7152 7153 return 0; 7154 } 7155 7156 list_for_each_entry(trap_item, &devlink->trap_list, list) { 7157 if (strcmp(trap_item->group_item->group->name, group_name)) 7158 continue; 7159 err = __devlink_trap_action_set(devlink, trap_item, 7160 trap_action, extack); 7161 if (err) 7162 return err; 7163 } 7164 7165 return 0; 7166} 7167 7168static int 7169devlink_trap_group_action_set(struct devlink *devlink, 7170 struct devlink_trap_group_item *group_item, 7171 struct genl_info *info, bool *p_modified) 7172{ 7173 enum devlink_trap_action trap_action; 7174 int err; 7175 7176 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) 7177 return 0; 7178 7179 err = devlink_trap_action_get_from_info(info, &trap_action); 7180 if (err) { 7181 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); 7182 return -EINVAL; 7183 } 7184 7185 err = __devlink_trap_group_action_set(devlink, group_item, trap_action, 7186 info->extack); 7187 if (err) 7188 return err; 7189 7190 *p_modified = true; 7191 7192 return 0; 7193} 7194 7195static int devlink_trap_group_set(struct devlink *devlink, 7196 struct devlink_trap_group_item *group_item, 7197 struct genl_info *info) 7198{ 7199 struct devlink_trap_policer_item *policer_item; 7200 struct netlink_ext_ack *extack = info->extack; 7201 const struct devlink_trap_policer *policer; 7202 struct nlattr **attrs = info->attrs; 7203 int err; 7204 7205 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) 7206 return 0; 7207 7208 if (!devlink->ops->trap_group_set) 7209 return -EOPNOTSUPP; 7210 7211 policer_item = group_item->policer_item; 7212 if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) { 7213 u32 policer_id; 7214 7215 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); 7216 policer_item = devlink_trap_policer_item_lookup(devlink, 7217 policer_id); 7218 if (policer_id && !policer_item) { 7219 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); 7220 return -ENOENT; 7221 } 7222 } 7223 policer = policer_item ? policer_item->policer : NULL; 7224 7225 err = devlink->ops->trap_group_set(devlink, group_item->group, policer, 7226 extack); 7227 if (err) 7228 return err; 7229 7230 group_item->policer_item = policer_item; 7231 7232 return 0; 7233} 7234 7235static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb, 7236 struct genl_info *info) 7237{ 7238 struct netlink_ext_ack *extack = info->extack; 7239 struct devlink *devlink = info->user_ptr[0]; 7240 struct devlink_trap_group_item *group_item; 7241 bool modified = false; 7242 int err; 7243 7244 if (list_empty(&devlink->trap_group_list)) 7245 return -EOPNOTSUPP; 7246 7247 group_item = devlink_trap_group_item_get_from_info(devlink, info); 7248 if (!group_item) { 7249 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); 7250 return -ENOENT; 7251 } 7252 7253 err = devlink_trap_group_action_set(devlink, group_item, info, 7254 &modified); 7255 if (err) 7256 return err; 7257 7258 err = devlink_trap_group_set(devlink, group_item, info); 7259 if (err) 7260 goto err_trap_group_set; 7261 7262 return 0; 7263 7264err_trap_group_set: 7265 if (modified) 7266 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already"); 7267 return err; 7268} 7269 7270static struct devlink_trap_policer_item * 7271devlink_trap_policer_item_get_from_info(struct devlink *devlink, 7272 struct genl_info *info) 7273{ 7274 u32 id; 7275 7276 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) 7277 return NULL; 7278 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); 7279 7280 return devlink_trap_policer_item_lookup(devlink, id); 7281} 7282 7283static int 7284devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink, 7285 const struct devlink_trap_policer *policer) 7286{ 7287 struct nlattr *attr; 7288 u64 drops; 7289 int err; 7290 7291 if (!devlink->ops->trap_policer_counter_get) 7292 return 0; 7293 7294 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops); 7295 if (err) 7296 return err; 7297 7298 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); 7299 if (!attr) 7300 return -EMSGSIZE; 7301 7302 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops, 7303 DEVLINK_ATTR_PAD)) 7304 goto nla_put_failure; 7305 7306 nla_nest_end(msg, attr); 7307 7308 return 0; 7309 7310nla_put_failure: 7311 nla_nest_cancel(msg, attr); 7312 return -EMSGSIZE; 7313} 7314 7315static int 7316devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink, 7317 const struct devlink_trap_policer_item *policer_item, 7318 enum devlink_command cmd, u32 portid, u32 seq, 7319 int flags) 7320{ 7321 void *hdr; 7322 int err; 7323 7324 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 7325 if (!hdr) 7326 return -EMSGSIZE; 7327 7328 if (devlink_nl_put_handle(msg, devlink)) 7329 goto nla_put_failure; 7330 7331 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, 7332 policer_item->policer->id)) 7333 goto nla_put_failure; 7334 7335 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE, 7336 policer_item->rate, DEVLINK_ATTR_PAD)) 7337 goto nla_put_failure; 7338 7339 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST, 7340 policer_item->burst, DEVLINK_ATTR_PAD)) 7341 goto nla_put_failure; 7342 7343 err = devlink_trap_policer_stats_put(msg, devlink, 7344 policer_item->policer); 7345 if (err) 7346 goto nla_put_failure; 7347 7348 genlmsg_end(msg, hdr); 7349 7350 return 0; 7351 7352nla_put_failure: 7353 genlmsg_cancel(msg, hdr); 7354 return -EMSGSIZE; 7355} 7356 7357static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb, 7358 struct genl_info *info) 7359{ 7360 struct devlink_trap_policer_item *policer_item; 7361 struct netlink_ext_ack *extack = info->extack; 7362 struct devlink *devlink = info->user_ptr[0]; 7363 struct sk_buff *msg; 7364 int err; 7365 7366 if (list_empty(&devlink->trap_policer_list)) 7367 return -EOPNOTSUPP; 7368 7369 policer_item = devlink_trap_policer_item_get_from_info(devlink, info); 7370 if (!policer_item) { 7371 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); 7372 return -ENOENT; 7373 } 7374 7375 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7376 if (!msg) 7377 return -ENOMEM; 7378 7379 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, 7380 DEVLINK_CMD_TRAP_POLICER_NEW, 7381 info->snd_portid, info->snd_seq, 0); 7382 if (err) 7383 goto err_trap_policer_fill; 7384 7385 return genlmsg_reply(msg, info); 7386 7387err_trap_policer_fill: 7388 nlmsg_free(msg); 7389 return err; 7390} 7391 7392static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg, 7393 struct netlink_callback *cb) 7394{ 7395 enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW; 7396 struct devlink_trap_policer_item *policer_item; 7397 u32 portid = NETLINK_CB(cb->skb).portid; 7398 struct devlink *devlink; 7399 int start = cb->args[0]; 7400 int idx = 0; 7401 int err; 7402 7403 mutex_lock(&devlink_mutex); 7404 list_for_each_entry(devlink, &devlink_list, list) { 7405 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 7406 continue; 7407 mutex_lock(&devlink->lock); 7408 list_for_each_entry(policer_item, &devlink->trap_policer_list, 7409 list) { 7410 if (idx < start) { 7411 idx++; 7412 continue; 7413 } 7414 err = devlink_nl_trap_policer_fill(msg, devlink, 7415 policer_item, cmd, 7416 portid, 7417 cb->nlh->nlmsg_seq, 7418 NLM_F_MULTI); 7419 if (err) { 7420 mutex_unlock(&devlink->lock); 7421 goto out; 7422 } 7423 idx++; 7424 } 7425 mutex_unlock(&devlink->lock); 7426 } 7427out: 7428 mutex_unlock(&devlink_mutex); 7429 7430 cb->args[0] = idx; 7431 return msg->len; 7432} 7433 7434static int 7435devlink_trap_policer_set(struct devlink *devlink, 7436 struct devlink_trap_policer_item *policer_item, 7437 struct genl_info *info) 7438{ 7439 struct netlink_ext_ack *extack = info->extack; 7440 struct nlattr **attrs = info->attrs; 7441 u64 rate, burst; 7442 int err; 7443 7444 rate = policer_item->rate; 7445 burst = policer_item->burst; 7446 7447 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]) 7448 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]); 7449 7450 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]) 7451 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]); 7452 7453 if (rate < policer_item->policer->min_rate) { 7454 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit"); 7455 return -EINVAL; 7456 } 7457 7458 if (rate > policer_item->policer->max_rate) { 7459 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit"); 7460 return -EINVAL; 7461 } 7462 7463 if (burst < policer_item->policer->min_burst) { 7464 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit"); 7465 return -EINVAL; 7466 } 7467 7468 if (burst > policer_item->policer->max_burst) { 7469 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit"); 7470 return -EINVAL; 7471 } 7472 7473 err = devlink->ops->trap_policer_set(devlink, policer_item->policer, 7474 rate, burst, info->extack); 7475 if (err) 7476 return err; 7477 7478 policer_item->rate = rate; 7479 policer_item->burst = burst; 7480 7481 return 0; 7482} 7483 7484static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb, 7485 struct genl_info *info) 7486{ 7487 struct devlink_trap_policer_item *policer_item; 7488 struct netlink_ext_ack *extack = info->extack; 7489 struct devlink *devlink = info->user_ptr[0]; 7490 7491 if (list_empty(&devlink->trap_policer_list)) 7492 return -EOPNOTSUPP; 7493 7494 if (!devlink->ops->trap_policer_set) 7495 return -EOPNOTSUPP; 7496 7497 policer_item = devlink_trap_policer_item_get_from_info(devlink, info); 7498 if (!policer_item) { 7499 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); 7500 return -ENOENT; 7501 } 7502 7503 return devlink_trap_policer_set(devlink, policer_item, info); 7504} 7505 7506static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { 7507 [DEVLINK_ATTR_UNSPEC] = { .strict_start_type = 7508 DEVLINK_ATTR_TRAP_POLICER_ID }, 7509 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, 7510 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, 7511 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 }, 7512 [DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO, 7513 DEVLINK_PORT_TYPE_IB), 7514 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 }, 7515 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 }, 7516 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 }, 7517 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 }, 7518 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 }, 7519 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, 7520 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, 7521 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, 7522 [DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY, 7523 DEVLINK_ESWITCH_MODE_SWITCHDEV), 7524 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 }, 7525 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, 7526 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, 7527 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, 7528 [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64}, 7529 [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64}, 7530 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING }, 7531 [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 }, 7532 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 }, 7533 [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING }, 7534 [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 }, 7535 [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 }, 7536 [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 }, 7537 [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING }, 7538 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 }, 7539 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 }, 7540 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING }, 7541 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING }, 7542 [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] = 7543 NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS), 7544 [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING }, 7545 [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 }, 7546 [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING }, 7547 [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 }, 7548 [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 }, 7549 [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 }, 7550 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 }, 7551 [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 }, 7552 [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 }, 7553 [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 }, 7554 [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED }, 7555 [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 7556 DEVLINK_RELOAD_ACTION_MAX), 7557 [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK), 7558}; 7559 7560static const struct genl_small_ops devlink_nl_ops[] = { 7561 { 7562 .cmd = DEVLINK_CMD_GET, 7563 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7564 .doit = devlink_nl_cmd_get_doit, 7565 .dumpit = devlink_nl_cmd_get_dumpit, 7566 /* can be retrieved by unprivileged users */ 7567 }, 7568 { 7569 .cmd = DEVLINK_CMD_PORT_GET, 7570 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7571 .doit = devlink_nl_cmd_port_get_doit, 7572 .dumpit = devlink_nl_cmd_port_get_dumpit, 7573 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7574 /* can be retrieved by unprivileged users */ 7575 }, 7576 { 7577 .cmd = DEVLINK_CMD_PORT_SET, 7578 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7579 .doit = devlink_nl_cmd_port_set_doit, 7580 .flags = GENL_ADMIN_PERM, 7581 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7582 }, 7583 { 7584 .cmd = DEVLINK_CMD_PORT_SPLIT, 7585 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7586 .doit = devlink_nl_cmd_port_split_doit, 7587 .flags = GENL_ADMIN_PERM, 7588 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7589 }, 7590 { 7591 .cmd = DEVLINK_CMD_PORT_UNSPLIT, 7592 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7593 .doit = devlink_nl_cmd_port_unsplit_doit, 7594 .flags = GENL_ADMIN_PERM, 7595 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7596 }, 7597 { 7598 .cmd = DEVLINK_CMD_SB_GET, 7599 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7600 .doit = devlink_nl_cmd_sb_get_doit, 7601 .dumpit = devlink_nl_cmd_sb_get_dumpit, 7602 /* can be retrieved by unprivileged users */ 7603 }, 7604 { 7605 .cmd = DEVLINK_CMD_SB_POOL_GET, 7606 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7607 .doit = devlink_nl_cmd_sb_pool_get_doit, 7608 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit, 7609 /* can be retrieved by unprivileged users */ 7610 }, 7611 { 7612 .cmd = DEVLINK_CMD_SB_POOL_SET, 7613 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7614 .doit = devlink_nl_cmd_sb_pool_set_doit, 7615 .flags = GENL_ADMIN_PERM, 7616 }, 7617 { 7618 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET, 7619 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7620 .doit = devlink_nl_cmd_sb_port_pool_get_doit, 7621 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit, 7622 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7623 /* can be retrieved by unprivileged users */ 7624 }, 7625 { 7626 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, 7627 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7628 .doit = devlink_nl_cmd_sb_port_pool_set_doit, 7629 .flags = GENL_ADMIN_PERM, 7630 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7631 }, 7632 { 7633 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, 7634 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7635 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, 7636 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit, 7637 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7638 /* can be retrieved by unprivileged users */ 7639 }, 7640 { 7641 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, 7642 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7643 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit, 7644 .flags = GENL_ADMIN_PERM, 7645 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7646 }, 7647 { 7648 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT, 7649 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7650 .doit = devlink_nl_cmd_sb_occ_snapshot_doit, 7651 .flags = GENL_ADMIN_PERM, 7652 }, 7653 { 7654 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR, 7655 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7656 .doit = devlink_nl_cmd_sb_occ_max_clear_doit, 7657 .flags = GENL_ADMIN_PERM, 7658 }, 7659 { 7660 .cmd = DEVLINK_CMD_ESWITCH_GET, 7661 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7662 .doit = devlink_nl_cmd_eswitch_get_doit, 7663 .flags = GENL_ADMIN_PERM, 7664 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7665 }, 7666 { 7667 .cmd = DEVLINK_CMD_ESWITCH_SET, 7668 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7669 .doit = devlink_nl_cmd_eswitch_set_doit, 7670 .flags = GENL_ADMIN_PERM, 7671 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7672 }, 7673 { 7674 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, 7675 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7676 .doit = devlink_nl_cmd_dpipe_table_get, 7677 /* can be retrieved by unprivileged users */ 7678 }, 7679 { 7680 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, 7681 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7682 .doit = devlink_nl_cmd_dpipe_entries_get, 7683 /* can be retrieved by unprivileged users */ 7684 }, 7685 { 7686 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, 7687 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7688 .doit = devlink_nl_cmd_dpipe_headers_get, 7689 /* can be retrieved by unprivileged users */ 7690 }, 7691 { 7692 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, 7693 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7694 .doit = devlink_nl_cmd_dpipe_table_counters_set, 7695 .flags = GENL_ADMIN_PERM, 7696 }, 7697 { 7698 .cmd = DEVLINK_CMD_RESOURCE_SET, 7699 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7700 .doit = devlink_nl_cmd_resource_set, 7701 .flags = GENL_ADMIN_PERM, 7702 }, 7703 { 7704 .cmd = DEVLINK_CMD_RESOURCE_DUMP, 7705 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7706 .doit = devlink_nl_cmd_resource_dump, 7707 /* can be retrieved by unprivileged users */ 7708 }, 7709 { 7710 .cmd = DEVLINK_CMD_RELOAD, 7711 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7712 .doit = devlink_nl_cmd_reload, 7713 .flags = GENL_ADMIN_PERM, 7714 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK, 7715 }, 7716 { 7717 .cmd = DEVLINK_CMD_PARAM_GET, 7718 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7719 .doit = devlink_nl_cmd_param_get_doit, 7720 .dumpit = devlink_nl_cmd_param_get_dumpit, 7721 /* can be retrieved by unprivileged users */ 7722 }, 7723 { 7724 .cmd = DEVLINK_CMD_PARAM_SET, 7725 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7726 .doit = devlink_nl_cmd_param_set_doit, 7727 .flags = GENL_ADMIN_PERM, 7728 }, 7729 { 7730 .cmd = DEVLINK_CMD_PORT_PARAM_GET, 7731 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7732 .doit = devlink_nl_cmd_port_param_get_doit, 7733 .dumpit = devlink_nl_cmd_port_param_get_dumpit, 7734 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7735 /* can be retrieved by unprivileged users */ 7736 }, 7737 { 7738 .cmd = DEVLINK_CMD_PORT_PARAM_SET, 7739 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7740 .doit = devlink_nl_cmd_port_param_set_doit, 7741 .flags = GENL_ADMIN_PERM, 7742 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 7743 }, 7744 { 7745 .cmd = DEVLINK_CMD_REGION_GET, 7746 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7747 .doit = devlink_nl_cmd_region_get_doit, 7748 .dumpit = devlink_nl_cmd_region_get_dumpit, 7749 .flags = GENL_ADMIN_PERM, 7750 }, 7751 { 7752 .cmd = DEVLINK_CMD_REGION_NEW, 7753 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7754 .doit = devlink_nl_cmd_region_new, 7755 .flags = GENL_ADMIN_PERM, 7756 }, 7757 { 7758 .cmd = DEVLINK_CMD_REGION_DEL, 7759 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7760 .doit = devlink_nl_cmd_region_del, 7761 .flags = GENL_ADMIN_PERM, 7762 }, 7763 { 7764 .cmd = DEVLINK_CMD_REGION_READ, 7765 .validate = GENL_DONT_VALIDATE_STRICT | 7766 GENL_DONT_VALIDATE_DUMP_STRICT, 7767 .dumpit = devlink_nl_cmd_region_read_dumpit, 7768 .flags = GENL_ADMIN_PERM, 7769 }, 7770 { 7771 .cmd = DEVLINK_CMD_INFO_GET, 7772 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7773 .doit = devlink_nl_cmd_info_get_doit, 7774 .dumpit = devlink_nl_cmd_info_get_dumpit, 7775 /* can be retrieved by unprivileged users */ 7776 }, 7777 { 7778 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET, 7779 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7780 .doit = devlink_nl_cmd_health_reporter_get_doit, 7781 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit, 7782 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7783 DEVLINK_NL_FLAG_NO_LOCK, 7784 /* can be retrieved by unprivileged users */ 7785 }, 7786 { 7787 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET, 7788 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7789 .doit = devlink_nl_cmd_health_reporter_set_doit, 7790 .flags = GENL_ADMIN_PERM, 7791 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7792 DEVLINK_NL_FLAG_NO_LOCK, 7793 }, 7794 { 7795 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, 7796 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7797 .doit = devlink_nl_cmd_health_reporter_recover_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_DIAGNOSE, 7804 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7805 .doit = devlink_nl_cmd_health_reporter_diagnose_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_DUMP_GET, 7812 .validate = GENL_DONT_VALIDATE_STRICT | 7813 GENL_DONT_VALIDATE_DUMP_STRICT, 7814 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit, 7815 .flags = GENL_ADMIN_PERM, 7816 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | 7817 DEVLINK_NL_FLAG_NO_LOCK, 7818 }, 7819 { 7820 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, 7821 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7822 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit, 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_TEST, 7829 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7830 .doit = devlink_nl_cmd_health_reporter_test_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_FLASH_UPDATE, 7837 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 7838 .doit = devlink_nl_cmd_flash_update, 7839 .flags = GENL_ADMIN_PERM, 7840 }, 7841 { 7842 .cmd = DEVLINK_CMD_TRAP_GET, 7843 .doit = devlink_nl_cmd_trap_get_doit, 7844 .dumpit = devlink_nl_cmd_trap_get_dumpit, 7845 /* can be retrieved by unprivileged users */ 7846 }, 7847 { 7848 .cmd = DEVLINK_CMD_TRAP_SET, 7849 .doit = devlink_nl_cmd_trap_set_doit, 7850 .flags = GENL_ADMIN_PERM, 7851 }, 7852 { 7853 .cmd = DEVLINK_CMD_TRAP_GROUP_GET, 7854 .doit = devlink_nl_cmd_trap_group_get_doit, 7855 .dumpit = devlink_nl_cmd_trap_group_get_dumpit, 7856 /* can be retrieved by unprivileged users */ 7857 }, 7858 { 7859 .cmd = DEVLINK_CMD_TRAP_GROUP_SET, 7860 .doit = devlink_nl_cmd_trap_group_set_doit, 7861 .flags = GENL_ADMIN_PERM, 7862 }, 7863 { 7864 .cmd = DEVLINK_CMD_TRAP_POLICER_GET, 7865 .doit = devlink_nl_cmd_trap_policer_get_doit, 7866 .dumpit = devlink_nl_cmd_trap_policer_get_dumpit, 7867 /* can be retrieved by unprivileged users */ 7868 }, 7869 { 7870 .cmd = DEVLINK_CMD_TRAP_POLICER_SET, 7871 .doit = devlink_nl_cmd_trap_policer_set_doit, 7872 .flags = GENL_ADMIN_PERM, 7873 }, 7874}; 7875 7876static struct genl_family devlink_nl_family __ro_after_init = { 7877 .name = DEVLINK_GENL_NAME, 7878 .version = DEVLINK_GENL_VERSION, 7879 .maxattr = DEVLINK_ATTR_MAX, 7880 .policy = devlink_nl_policy, 7881 .netnsok = true, 7882 .pre_doit = devlink_nl_pre_doit, 7883 .post_doit = devlink_nl_post_doit, 7884 .module = THIS_MODULE, 7885 .small_ops = devlink_nl_ops, 7886 .n_small_ops = ARRAY_SIZE(devlink_nl_ops), 7887 .mcgrps = devlink_nl_mcgrps, 7888 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), 7889}; 7890 7891static bool devlink_reload_actions_valid(const struct devlink_ops *ops) 7892{ 7893 const struct devlink_reload_combination *comb; 7894 int i; 7895 7896 if (!devlink_reload_supported(ops)) { 7897 if (WARN_ON(ops->reload_actions)) 7898 return false; 7899 return true; 7900 } 7901 7902 if (WARN_ON(!ops->reload_actions || 7903 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 7904 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) 7905 return false; 7906 7907 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || 7908 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) 7909 return false; 7910 7911 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { 7912 comb = &devlink_reload_invalid_combinations[i]; 7913 if (ops->reload_actions == BIT(comb->action) && 7914 ops->reload_limits == BIT(comb->limit)) 7915 return false; 7916 } 7917 return true; 7918} 7919 7920/** 7921 * devlink_alloc - Allocate new devlink instance resources 7922 * 7923 * @ops: ops 7924 * @priv_size: size of user private data 7925 * 7926 * Allocate new devlink instance resources, including devlink index 7927 * and name. 7928 */ 7929struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) 7930{ 7931 struct devlink *devlink; 7932 7933 if (WARN_ON(!ops)) 7934 return NULL; 7935 7936 if (!devlink_reload_actions_valid(ops)) 7937 return NULL; 7938 7939 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); 7940 if (!devlink) 7941 return NULL; 7942 devlink->ops = ops; 7943 xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC); 7944 __devlink_net_set(devlink, &init_net); 7945 INIT_LIST_HEAD(&devlink->port_list); 7946 INIT_LIST_HEAD(&devlink->sb_list); 7947 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list); 7948 INIT_LIST_HEAD(&devlink->resource_list); 7949 INIT_LIST_HEAD(&devlink->param_list); 7950 INIT_LIST_HEAD(&devlink->region_list); 7951 INIT_LIST_HEAD(&devlink->reporter_list); 7952 INIT_LIST_HEAD(&devlink->trap_list); 7953 INIT_LIST_HEAD(&devlink->trap_group_list); 7954 INIT_LIST_HEAD(&devlink->trap_policer_list); 7955 mutex_init(&devlink->lock); 7956 mutex_init(&devlink->reporters_lock); 7957 return devlink; 7958} 7959EXPORT_SYMBOL_GPL(devlink_alloc); 7960 7961/** 7962 * devlink_register - Register devlink instance 7963 * 7964 * @devlink: devlink 7965 * @dev: parent device 7966 */ 7967int devlink_register(struct devlink *devlink, struct device *dev) 7968{ 7969 devlink->dev = dev; 7970 devlink->registered = true; 7971 mutex_lock(&devlink_mutex); 7972 list_add_tail(&devlink->list, &devlink_list); 7973 devlink_notify(devlink, DEVLINK_CMD_NEW); 7974 mutex_unlock(&devlink_mutex); 7975 return 0; 7976} 7977EXPORT_SYMBOL_GPL(devlink_register); 7978 7979/** 7980 * devlink_unregister - Unregister devlink instance 7981 * 7982 * @devlink: devlink 7983 */ 7984void devlink_unregister(struct devlink *devlink) 7985{ 7986 mutex_lock(&devlink_mutex); 7987 WARN_ON(devlink_reload_supported(devlink->ops) && 7988 devlink->reload_enabled); 7989 devlink_notify(devlink, DEVLINK_CMD_DEL); 7990 list_del(&devlink->list); 7991 mutex_unlock(&devlink_mutex); 7992} 7993EXPORT_SYMBOL_GPL(devlink_unregister); 7994 7995/** 7996 * devlink_reload_enable - Enable reload of devlink instance 7997 * 7998 * @devlink: devlink 7999 * 8000 * Should be called at end of device initialization 8001 * process when reload operation is supported. 8002 */ 8003void devlink_reload_enable(struct devlink *devlink) 8004{ 8005 mutex_lock(&devlink_mutex); 8006 devlink->reload_enabled = true; 8007 mutex_unlock(&devlink_mutex); 8008} 8009EXPORT_SYMBOL_GPL(devlink_reload_enable); 8010 8011/** 8012 * devlink_reload_disable - Disable reload of devlink instance 8013 * 8014 * @devlink: devlink 8015 * 8016 * Should be called at the beginning of device cleanup 8017 * process when reload operation is supported. 8018 */ 8019void devlink_reload_disable(struct devlink *devlink) 8020{ 8021 mutex_lock(&devlink_mutex); 8022 /* Mutex is taken which ensures that no reload operation is in 8023 * progress while setting up forbidded flag. 8024 */ 8025 devlink->reload_enabled = false; 8026 mutex_unlock(&devlink_mutex); 8027} 8028EXPORT_SYMBOL_GPL(devlink_reload_disable); 8029 8030/** 8031 * devlink_free - Free devlink instance resources 8032 * 8033 * @devlink: devlink 8034 */ 8035void devlink_free(struct devlink *devlink) 8036{ 8037 mutex_destroy(&devlink->reporters_lock); 8038 mutex_destroy(&devlink->lock); 8039 WARN_ON(!list_empty(&devlink->trap_policer_list)); 8040 WARN_ON(!list_empty(&devlink->trap_group_list)); 8041 WARN_ON(!list_empty(&devlink->trap_list)); 8042 WARN_ON(!list_empty(&devlink->reporter_list)); 8043 WARN_ON(!list_empty(&devlink->region_list)); 8044 WARN_ON(!list_empty(&devlink->param_list)); 8045 WARN_ON(!list_empty(&devlink->resource_list)); 8046 WARN_ON(!list_empty(&devlink->dpipe_table_list)); 8047 WARN_ON(!list_empty(&devlink->sb_list)); 8048 WARN_ON(!list_empty(&devlink->port_list)); 8049 8050 xa_destroy(&devlink->snapshot_ids); 8051 8052 kfree(devlink); 8053} 8054EXPORT_SYMBOL_GPL(devlink_free); 8055 8056static void devlink_port_type_warn(struct work_struct *work) 8057{ 8058 WARN(true, "Type was not set for devlink port."); 8059} 8060 8061static bool devlink_port_type_should_warn(struct devlink_port *devlink_port) 8062{ 8063 /* Ignore CPU and DSA flavours. */ 8064 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU && 8065 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA && 8066 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED; 8067} 8068 8069#define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600) 8070 8071static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port) 8072{ 8073 if (!devlink_port_type_should_warn(devlink_port)) 8074 return; 8075 /* Schedule a work to WARN in case driver does not set port 8076 * type within timeout. 8077 */ 8078 schedule_delayed_work(&devlink_port->type_warn_dw, 8079 DEVLINK_PORT_TYPE_WARN_TIMEOUT); 8080} 8081 8082static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port) 8083{ 8084 if (!devlink_port_type_should_warn(devlink_port)) 8085 return; 8086 cancel_delayed_work_sync(&devlink_port->type_warn_dw); 8087} 8088 8089/** 8090 * devlink_port_register - Register devlink port 8091 * 8092 * @devlink: devlink 8093 * @devlink_port: devlink port 8094 * @port_index: driver-specific numerical identifier of the port 8095 * 8096 * Register devlink port with provided port index. User can use 8097 * any indexing, even hw-related one. devlink_port structure 8098 * is convenient to be embedded inside user driver private structure. 8099 * Note that the caller should take care of zeroing the devlink_port 8100 * structure. 8101 */ 8102int devlink_port_register(struct devlink *devlink, 8103 struct devlink_port *devlink_port, 8104 unsigned int port_index) 8105{ 8106 mutex_lock(&devlink->lock); 8107 if (devlink_port_index_exists(devlink, port_index)) { 8108 mutex_unlock(&devlink->lock); 8109 return -EEXIST; 8110 } 8111 devlink_port->devlink = devlink; 8112 devlink_port->index = port_index; 8113 devlink_port->registered = true; 8114 spin_lock_init(&devlink_port->type_lock); 8115 INIT_LIST_HEAD(&devlink_port->reporter_list); 8116 mutex_init(&devlink_port->reporters_lock); 8117 list_add_tail(&devlink_port->list, &devlink->port_list); 8118 INIT_LIST_HEAD(&devlink_port->param_list); 8119 INIT_LIST_HEAD(&devlink_port->region_list); 8120 mutex_unlock(&devlink->lock); 8121 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn); 8122 devlink_port_type_warn_schedule(devlink_port); 8123 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 8124 return 0; 8125} 8126EXPORT_SYMBOL_GPL(devlink_port_register); 8127 8128/** 8129 * devlink_port_unregister - Unregister devlink port 8130 * 8131 * @devlink_port: devlink port 8132 */ 8133void devlink_port_unregister(struct devlink_port *devlink_port) 8134{ 8135 struct devlink *devlink = devlink_port->devlink; 8136 8137 devlink_port_type_warn_cancel(devlink_port); 8138 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); 8139 mutex_lock(&devlink->lock); 8140 list_del(&devlink_port->list); 8141 mutex_unlock(&devlink->lock); 8142 WARN_ON(!list_empty(&devlink_port->reporter_list)); 8143 WARN_ON(!list_empty(&devlink_port->region_list)); 8144 mutex_destroy(&devlink_port->reporters_lock); 8145} 8146EXPORT_SYMBOL_GPL(devlink_port_unregister); 8147 8148static void __devlink_port_type_set(struct devlink_port *devlink_port, 8149 enum devlink_port_type type, 8150 void *type_dev) 8151{ 8152 if (WARN_ON(!devlink_port->registered)) 8153 return; 8154 devlink_port_type_warn_cancel(devlink_port); 8155 spin_lock_bh(&devlink_port->type_lock); 8156 devlink_port->type = type; 8157 devlink_port->type_dev = type_dev; 8158 spin_unlock_bh(&devlink_port->type_lock); 8159 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 8160} 8161 8162static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port, 8163 struct net_device *netdev) 8164{ 8165 const struct net_device_ops *ops = netdev->netdev_ops; 8166 8167 /* If driver registers devlink port, it should set devlink port 8168 * attributes accordingly so the compat functions are called 8169 * and the original ops are not used. 8170 */ 8171 if (ops->ndo_get_phys_port_name) { 8172 /* Some drivers use the same set of ndos for netdevs 8173 * that have devlink_port registered and also for 8174 * those who don't. Make sure that ndo_get_phys_port_name 8175 * returns -EOPNOTSUPP here in case it is defined. 8176 * Warn if not. 8177 */ 8178 char name[IFNAMSIZ]; 8179 int err; 8180 8181 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name)); 8182 WARN_ON(err != -EOPNOTSUPP); 8183 } 8184 if (ops->ndo_get_port_parent_id) { 8185 /* Some drivers use the same set of ndos for netdevs 8186 * that have devlink_port registered and also for 8187 * those who don't. Make sure that ndo_get_port_parent_id 8188 * returns -EOPNOTSUPP here in case it is defined. 8189 * Warn if not. 8190 */ 8191 struct netdev_phys_item_id ppid; 8192 int err; 8193 8194 err = ops->ndo_get_port_parent_id(netdev, &ppid); 8195 WARN_ON(err != -EOPNOTSUPP); 8196 } 8197} 8198 8199/** 8200 * devlink_port_type_eth_set - Set port type to Ethernet 8201 * 8202 * @devlink_port: devlink port 8203 * @netdev: related netdevice 8204 */ 8205void devlink_port_type_eth_set(struct devlink_port *devlink_port, 8206 struct net_device *netdev) 8207{ 8208 if (netdev) 8209 devlink_port_type_netdev_checks(devlink_port, netdev); 8210 else 8211 dev_warn(devlink_port->devlink->dev, 8212 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n", 8213 devlink_port->index); 8214 8215 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev); 8216} 8217EXPORT_SYMBOL_GPL(devlink_port_type_eth_set); 8218 8219/** 8220 * devlink_port_type_ib_set - Set port type to InfiniBand 8221 * 8222 * @devlink_port: devlink port 8223 * @ibdev: related IB device 8224 */ 8225void devlink_port_type_ib_set(struct devlink_port *devlink_port, 8226 struct ib_device *ibdev) 8227{ 8228 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev); 8229} 8230EXPORT_SYMBOL_GPL(devlink_port_type_ib_set); 8231 8232/** 8233 * devlink_port_type_clear - Clear port type 8234 * 8235 * @devlink_port: devlink port 8236 */ 8237void devlink_port_type_clear(struct devlink_port *devlink_port) 8238{ 8239 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL); 8240 devlink_port_type_warn_schedule(devlink_port); 8241} 8242EXPORT_SYMBOL_GPL(devlink_port_type_clear); 8243 8244static int __devlink_port_attrs_set(struct devlink_port *devlink_port, 8245 enum devlink_port_flavour flavour) 8246{ 8247 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8248 8249 if (WARN_ON(devlink_port->registered)) 8250 return -EEXIST; 8251 devlink_port->attrs_set = true; 8252 attrs->flavour = flavour; 8253 if (attrs->switch_id.id_len) { 8254 devlink_port->switch_port = true; 8255 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN)) 8256 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN; 8257 } else { 8258 devlink_port->switch_port = false; 8259 } 8260 return 0; 8261} 8262 8263/** 8264 * devlink_port_attrs_set - Set port attributes 8265 * 8266 * @devlink_port: devlink port 8267 * @attrs: devlink port attrs 8268 */ 8269void devlink_port_attrs_set(struct devlink_port *devlink_port, 8270 struct devlink_port_attrs *attrs) 8271{ 8272 int ret; 8273 8274 devlink_port->attrs = *attrs; 8275 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour); 8276 if (ret) 8277 return; 8278 WARN_ON(attrs->splittable && attrs->split); 8279} 8280EXPORT_SYMBOL_GPL(devlink_port_attrs_set); 8281 8282/** 8283 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes 8284 * 8285 * @devlink_port: devlink port 8286 * @controller: associated controller number for the devlink port instance 8287 * @pf: associated PF for the devlink port instance 8288 * @external: indicates if the port is for an external controller 8289 */ 8290void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller, 8291 u16 pf, bool external) 8292{ 8293 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8294 int ret; 8295 8296 ret = __devlink_port_attrs_set(devlink_port, 8297 DEVLINK_PORT_FLAVOUR_PCI_PF); 8298 if (ret) 8299 return; 8300 attrs->pci_pf.controller = controller; 8301 attrs->pci_pf.pf = pf; 8302 attrs->pci_pf.external = external; 8303} 8304EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set); 8305 8306/** 8307 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes 8308 * 8309 * @devlink_port: devlink port 8310 * @controller: associated controller number for the devlink port instance 8311 * @pf: associated PF for the devlink port instance 8312 * @vf: associated VF of a PF for the devlink port instance 8313 * @external: indicates if the port is for an external controller 8314 */ 8315void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller, 8316 u16 pf, u16 vf, bool external) 8317{ 8318 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8319 int ret; 8320 8321 ret = __devlink_port_attrs_set(devlink_port, 8322 DEVLINK_PORT_FLAVOUR_PCI_VF); 8323 if (ret) 8324 return; 8325 attrs->pci_vf.controller = controller; 8326 attrs->pci_vf.pf = pf; 8327 attrs->pci_vf.vf = vf; 8328 attrs->pci_vf.external = external; 8329} 8330EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set); 8331 8332static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, 8333 char *name, size_t len) 8334{ 8335 struct devlink_port_attrs *attrs = &devlink_port->attrs; 8336 int n = 0; 8337 8338 if (!devlink_port->attrs_set) 8339 return -EOPNOTSUPP; 8340 8341 switch (attrs->flavour) { 8342 case DEVLINK_PORT_FLAVOUR_PHYSICAL: 8343 case DEVLINK_PORT_FLAVOUR_VIRTUAL: 8344 if (!attrs->split) 8345 n = snprintf(name, len, "p%u", attrs->phys.port_number); 8346 else 8347 n = snprintf(name, len, "p%us%u", 8348 attrs->phys.port_number, 8349 attrs->phys.split_subport_number); 8350 break; 8351 case DEVLINK_PORT_FLAVOUR_CPU: 8352 case DEVLINK_PORT_FLAVOUR_DSA: 8353 case DEVLINK_PORT_FLAVOUR_UNUSED: 8354 /* As CPU and DSA ports do not have a netdevice associated 8355 * case should not ever happen. 8356 */ 8357 WARN_ON(1); 8358 return -EINVAL; 8359 case DEVLINK_PORT_FLAVOUR_PCI_PF: 8360 if (attrs->pci_pf.external) { 8361 n = snprintf(name, len, "c%u", attrs->pci_pf.controller); 8362 if (n >= len) 8363 return -EINVAL; 8364 len -= n; 8365 name += n; 8366 } 8367 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf); 8368 break; 8369 case DEVLINK_PORT_FLAVOUR_PCI_VF: 8370 if (attrs->pci_vf.external) { 8371 n = snprintf(name, len, "c%u", attrs->pci_vf.controller); 8372 if (n >= len) 8373 return -EINVAL; 8374 len -= n; 8375 name += n; 8376 } 8377 n = snprintf(name, len, "pf%uvf%u", 8378 attrs->pci_vf.pf, attrs->pci_vf.vf); 8379 break; 8380 } 8381 8382 if (n >= len) 8383 return -EINVAL; 8384 8385 return 0; 8386} 8387 8388int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, 8389 u32 size, u16 ingress_pools_count, 8390 u16 egress_pools_count, u16 ingress_tc_count, 8391 u16 egress_tc_count) 8392{ 8393 struct devlink_sb *devlink_sb; 8394 int err = 0; 8395 8396 mutex_lock(&devlink->lock); 8397 if (devlink_sb_index_exists(devlink, sb_index)) { 8398 err = -EEXIST; 8399 goto unlock; 8400 } 8401 8402 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL); 8403 if (!devlink_sb) { 8404 err = -ENOMEM; 8405 goto unlock; 8406 } 8407 devlink_sb->index = sb_index; 8408 devlink_sb->size = size; 8409 devlink_sb->ingress_pools_count = ingress_pools_count; 8410 devlink_sb->egress_pools_count = egress_pools_count; 8411 devlink_sb->ingress_tc_count = ingress_tc_count; 8412 devlink_sb->egress_tc_count = egress_tc_count; 8413 list_add_tail(&devlink_sb->list, &devlink->sb_list); 8414unlock: 8415 mutex_unlock(&devlink->lock); 8416 return err; 8417} 8418EXPORT_SYMBOL_GPL(devlink_sb_register); 8419 8420void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index) 8421{ 8422 struct devlink_sb *devlink_sb; 8423 8424 mutex_lock(&devlink->lock); 8425 devlink_sb = devlink_sb_get_by_index(devlink, sb_index); 8426 WARN_ON(!devlink_sb); 8427 list_del(&devlink_sb->list); 8428 mutex_unlock(&devlink->lock); 8429 kfree(devlink_sb); 8430} 8431EXPORT_SYMBOL_GPL(devlink_sb_unregister); 8432 8433/** 8434 * devlink_dpipe_headers_register - register dpipe headers 8435 * 8436 * @devlink: devlink 8437 * @dpipe_headers: dpipe header array 8438 * 8439 * Register the headers supported by hardware. 8440 */ 8441int devlink_dpipe_headers_register(struct devlink *devlink, 8442 struct devlink_dpipe_headers *dpipe_headers) 8443{ 8444 mutex_lock(&devlink->lock); 8445 devlink->dpipe_headers = dpipe_headers; 8446 mutex_unlock(&devlink->lock); 8447 return 0; 8448} 8449EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register); 8450 8451/** 8452 * devlink_dpipe_headers_unregister - unregister dpipe headers 8453 * 8454 * @devlink: devlink 8455 * 8456 * Unregister the headers supported by hardware. 8457 */ 8458void devlink_dpipe_headers_unregister(struct devlink *devlink) 8459{ 8460 mutex_lock(&devlink->lock); 8461 devlink->dpipe_headers = NULL; 8462 mutex_unlock(&devlink->lock); 8463} 8464EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister); 8465 8466/** 8467 * devlink_dpipe_table_counter_enabled - check if counter allocation 8468 * required 8469 * @devlink: devlink 8470 * @table_name: tables name 8471 * 8472 * Used by driver to check if counter allocation is required. 8473 * After counter allocation is turned on the table entries 8474 * are updated to include counter statistics. 8475 * 8476 * After that point on the driver must respect the counter 8477 * state so that each entry added to the table is added 8478 * with a counter. 8479 */ 8480bool devlink_dpipe_table_counter_enabled(struct devlink *devlink, 8481 const char *table_name) 8482{ 8483 struct devlink_dpipe_table *table; 8484 bool enabled; 8485 8486 rcu_read_lock(); 8487 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8488 table_name, devlink); 8489 enabled = false; 8490 if (table) 8491 enabled = table->counters_enabled; 8492 rcu_read_unlock(); 8493 return enabled; 8494} 8495EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled); 8496 8497/** 8498 * devlink_dpipe_table_register - register dpipe table 8499 * 8500 * @devlink: devlink 8501 * @table_name: table name 8502 * @table_ops: table ops 8503 * @priv: priv 8504 * @counter_control_extern: external control for counters 8505 */ 8506int devlink_dpipe_table_register(struct devlink *devlink, 8507 const char *table_name, 8508 struct devlink_dpipe_table_ops *table_ops, 8509 void *priv, bool counter_control_extern) 8510{ 8511 struct devlink_dpipe_table *table; 8512 int err = 0; 8513 8514 if (WARN_ON(!table_ops->size_get)) 8515 return -EINVAL; 8516 8517 mutex_lock(&devlink->lock); 8518 8519 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name, 8520 devlink)) { 8521 err = -EEXIST; 8522 goto unlock; 8523 } 8524 8525 table = kzalloc(sizeof(*table), GFP_KERNEL); 8526 if (!table) { 8527 err = -ENOMEM; 8528 goto unlock; 8529 } 8530 8531 table->name = table_name; 8532 table->table_ops = table_ops; 8533 table->priv = priv; 8534 table->counter_control_extern = counter_control_extern; 8535 8536 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list); 8537unlock: 8538 mutex_unlock(&devlink->lock); 8539 return err; 8540} 8541EXPORT_SYMBOL_GPL(devlink_dpipe_table_register); 8542 8543/** 8544 * devlink_dpipe_table_unregister - unregister dpipe table 8545 * 8546 * @devlink: devlink 8547 * @table_name: table name 8548 */ 8549void devlink_dpipe_table_unregister(struct devlink *devlink, 8550 const char *table_name) 8551{ 8552 struct devlink_dpipe_table *table; 8553 8554 mutex_lock(&devlink->lock); 8555 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8556 table_name, devlink); 8557 if (!table) 8558 goto unlock; 8559 list_del_rcu(&table->list); 8560 mutex_unlock(&devlink->lock); 8561 kfree_rcu(table, rcu); 8562 return; 8563unlock: 8564 mutex_unlock(&devlink->lock); 8565} 8566EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister); 8567 8568/** 8569 * devlink_resource_register - devlink resource register 8570 * 8571 * @devlink: devlink 8572 * @resource_name: resource's name 8573 * @resource_size: resource's size 8574 * @resource_id: resource's id 8575 * @parent_resource_id: resource's parent id 8576 * @size_params: size parameters 8577 */ 8578int devlink_resource_register(struct devlink *devlink, 8579 const char *resource_name, 8580 u64 resource_size, 8581 u64 resource_id, 8582 u64 parent_resource_id, 8583 const struct devlink_resource_size_params *size_params) 8584{ 8585 struct devlink_resource *resource; 8586 struct list_head *resource_list; 8587 bool top_hierarchy; 8588 int err = 0; 8589 8590 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP; 8591 8592 mutex_lock(&devlink->lock); 8593 resource = devlink_resource_find(devlink, NULL, resource_id); 8594 if (resource) { 8595 err = -EINVAL; 8596 goto out; 8597 } 8598 8599 resource = kzalloc(sizeof(*resource), GFP_KERNEL); 8600 if (!resource) { 8601 err = -ENOMEM; 8602 goto out; 8603 } 8604 8605 if (top_hierarchy) { 8606 resource_list = &devlink->resource_list; 8607 } else { 8608 struct devlink_resource *parent_resource; 8609 8610 parent_resource = devlink_resource_find(devlink, NULL, 8611 parent_resource_id); 8612 if (parent_resource) { 8613 resource_list = &parent_resource->resource_list; 8614 resource->parent = parent_resource; 8615 } else { 8616 kfree(resource); 8617 err = -EINVAL; 8618 goto out; 8619 } 8620 } 8621 8622 resource->name = resource_name; 8623 resource->size = resource_size; 8624 resource->size_new = resource_size; 8625 resource->id = resource_id; 8626 resource->size_valid = true; 8627 memcpy(&resource->size_params, size_params, 8628 sizeof(resource->size_params)); 8629 INIT_LIST_HEAD(&resource->resource_list); 8630 list_add_tail(&resource->list, resource_list); 8631out: 8632 mutex_unlock(&devlink->lock); 8633 return err; 8634} 8635EXPORT_SYMBOL_GPL(devlink_resource_register); 8636 8637/** 8638 * devlink_resources_unregister - free all resources 8639 * 8640 * @devlink: devlink 8641 * @resource: resource 8642 */ 8643void devlink_resources_unregister(struct devlink *devlink, 8644 struct devlink_resource *resource) 8645{ 8646 struct devlink_resource *tmp, *child_resource; 8647 struct list_head *resource_list; 8648 8649 if (resource) 8650 resource_list = &resource->resource_list; 8651 else 8652 resource_list = &devlink->resource_list; 8653 8654 if (!resource) 8655 mutex_lock(&devlink->lock); 8656 8657 list_for_each_entry_safe(child_resource, tmp, resource_list, list) { 8658 devlink_resources_unregister(devlink, child_resource); 8659 list_del(&child_resource->list); 8660 kfree(child_resource); 8661 } 8662 8663 if (!resource) 8664 mutex_unlock(&devlink->lock); 8665} 8666EXPORT_SYMBOL_GPL(devlink_resources_unregister); 8667 8668/** 8669 * devlink_resource_size_get - get and update size 8670 * 8671 * @devlink: devlink 8672 * @resource_id: the requested resource id 8673 * @p_resource_size: ptr to update 8674 */ 8675int devlink_resource_size_get(struct devlink *devlink, 8676 u64 resource_id, 8677 u64 *p_resource_size) 8678{ 8679 struct devlink_resource *resource; 8680 int err = 0; 8681 8682 mutex_lock(&devlink->lock); 8683 resource = devlink_resource_find(devlink, NULL, resource_id); 8684 if (!resource) { 8685 err = -EINVAL; 8686 goto out; 8687 } 8688 *p_resource_size = resource->size_new; 8689 resource->size = resource->size_new; 8690out: 8691 mutex_unlock(&devlink->lock); 8692 return err; 8693} 8694EXPORT_SYMBOL_GPL(devlink_resource_size_get); 8695 8696/** 8697 * devlink_dpipe_table_resource_set - set the resource id 8698 * 8699 * @devlink: devlink 8700 * @table_name: table name 8701 * @resource_id: resource id 8702 * @resource_units: number of resource's units consumed per table's entry 8703 */ 8704int devlink_dpipe_table_resource_set(struct devlink *devlink, 8705 const char *table_name, u64 resource_id, 8706 u64 resource_units) 8707{ 8708 struct devlink_dpipe_table *table; 8709 int err = 0; 8710 8711 mutex_lock(&devlink->lock); 8712 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 8713 table_name, devlink); 8714 if (!table) { 8715 err = -EINVAL; 8716 goto out; 8717 } 8718 table->resource_id = resource_id; 8719 table->resource_units = resource_units; 8720 table->resource_valid = true; 8721out: 8722 mutex_unlock(&devlink->lock); 8723 return err; 8724} 8725EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set); 8726 8727/** 8728 * devlink_resource_occ_get_register - register occupancy getter 8729 * 8730 * @devlink: devlink 8731 * @resource_id: resource id 8732 * @occ_get: occupancy getter callback 8733 * @occ_get_priv: occupancy getter callback priv 8734 */ 8735void devlink_resource_occ_get_register(struct devlink *devlink, 8736 u64 resource_id, 8737 devlink_resource_occ_get_t *occ_get, 8738 void *occ_get_priv) 8739{ 8740 struct devlink_resource *resource; 8741 8742 mutex_lock(&devlink->lock); 8743 resource = devlink_resource_find(devlink, NULL, resource_id); 8744 if (WARN_ON(!resource)) 8745 goto out; 8746 WARN_ON(resource->occ_get); 8747 8748 resource->occ_get = occ_get; 8749 resource->occ_get_priv = occ_get_priv; 8750out: 8751 mutex_unlock(&devlink->lock); 8752} 8753EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register); 8754 8755/** 8756 * devlink_resource_occ_get_unregister - unregister occupancy getter 8757 * 8758 * @devlink: devlink 8759 * @resource_id: resource id 8760 */ 8761void devlink_resource_occ_get_unregister(struct devlink *devlink, 8762 u64 resource_id) 8763{ 8764 struct devlink_resource *resource; 8765 8766 mutex_lock(&devlink->lock); 8767 resource = devlink_resource_find(devlink, NULL, resource_id); 8768 if (WARN_ON(!resource)) 8769 goto out; 8770 WARN_ON(!resource->occ_get); 8771 8772 resource->occ_get = NULL; 8773 resource->occ_get_priv = NULL; 8774out: 8775 mutex_unlock(&devlink->lock); 8776} 8777EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister); 8778 8779static int devlink_param_verify(const struct devlink_param *param) 8780{ 8781 if (!param || !param->name || !param->supported_cmodes) 8782 return -EINVAL; 8783 if (param->generic) 8784 return devlink_param_generic_verify(param); 8785 else 8786 return devlink_param_driver_verify(param); 8787} 8788 8789static int __devlink_params_register(struct devlink *devlink, 8790 unsigned int port_index, 8791 struct list_head *param_list, 8792 const struct devlink_param *params, 8793 size_t params_count, 8794 enum devlink_command reg_cmd, 8795 enum devlink_command unreg_cmd) 8796{ 8797 const struct devlink_param *param = params; 8798 int i; 8799 int err; 8800 8801 mutex_lock(&devlink->lock); 8802 for (i = 0; i < params_count; i++, param++) { 8803 err = devlink_param_verify(param); 8804 if (err) 8805 goto rollback; 8806 8807 err = devlink_param_register_one(devlink, port_index, 8808 param_list, param, reg_cmd); 8809 if (err) 8810 goto rollback; 8811 } 8812 8813 mutex_unlock(&devlink->lock); 8814 return 0; 8815 8816rollback: 8817 if (!i) 8818 goto unlock; 8819 for (param--; i > 0; i--, param--) 8820 devlink_param_unregister_one(devlink, port_index, param_list, 8821 param, unreg_cmd); 8822unlock: 8823 mutex_unlock(&devlink->lock); 8824 return err; 8825} 8826 8827static void __devlink_params_unregister(struct devlink *devlink, 8828 unsigned int port_index, 8829 struct list_head *param_list, 8830 const struct devlink_param *params, 8831 size_t params_count, 8832 enum devlink_command cmd) 8833{ 8834 const struct devlink_param *param = params; 8835 int i; 8836 8837 mutex_lock(&devlink->lock); 8838 for (i = 0; i < params_count; i++, param++) 8839 devlink_param_unregister_one(devlink, 0, param_list, param, 8840 cmd); 8841 mutex_unlock(&devlink->lock); 8842} 8843 8844/** 8845 * devlink_params_register - register configuration parameters 8846 * 8847 * @devlink: devlink 8848 * @params: configuration parameters array 8849 * @params_count: number of parameters provided 8850 * 8851 * Register the configuration parameters supported by the driver. 8852 */ 8853int devlink_params_register(struct devlink *devlink, 8854 const struct devlink_param *params, 8855 size_t params_count) 8856{ 8857 return __devlink_params_register(devlink, 0, &devlink->param_list, 8858 params, params_count, 8859 DEVLINK_CMD_PARAM_NEW, 8860 DEVLINK_CMD_PARAM_DEL); 8861} 8862EXPORT_SYMBOL_GPL(devlink_params_register); 8863 8864/** 8865 * devlink_params_unregister - unregister configuration parameters 8866 * @devlink: devlink 8867 * @params: configuration parameters to unregister 8868 * @params_count: number of parameters provided 8869 */ 8870void devlink_params_unregister(struct devlink *devlink, 8871 const struct devlink_param *params, 8872 size_t params_count) 8873{ 8874 return __devlink_params_unregister(devlink, 0, &devlink->param_list, 8875 params, params_count, 8876 DEVLINK_CMD_PARAM_DEL); 8877} 8878EXPORT_SYMBOL_GPL(devlink_params_unregister); 8879 8880/** 8881 * devlink_params_publish - publish configuration parameters 8882 * 8883 * @devlink: devlink 8884 * 8885 * Publish previously registered configuration parameters. 8886 */ 8887void devlink_params_publish(struct devlink *devlink) 8888{ 8889 struct devlink_param_item *param_item; 8890 8891 list_for_each_entry(param_item, &devlink->param_list, list) { 8892 if (param_item->published) 8893 continue; 8894 param_item->published = true; 8895 devlink_param_notify(devlink, 0, param_item, 8896 DEVLINK_CMD_PARAM_NEW); 8897 } 8898} 8899EXPORT_SYMBOL_GPL(devlink_params_publish); 8900 8901/** 8902 * devlink_params_unpublish - unpublish configuration parameters 8903 * 8904 * @devlink: devlink 8905 * 8906 * Unpublish previously registered configuration parameters. 8907 */ 8908void devlink_params_unpublish(struct devlink *devlink) 8909{ 8910 struct devlink_param_item *param_item; 8911 8912 list_for_each_entry(param_item, &devlink->param_list, list) { 8913 if (!param_item->published) 8914 continue; 8915 param_item->published = false; 8916 devlink_param_notify(devlink, 0, param_item, 8917 DEVLINK_CMD_PARAM_DEL); 8918 } 8919} 8920EXPORT_SYMBOL_GPL(devlink_params_unpublish); 8921 8922/** 8923 * devlink_port_params_register - register port configuration parameters 8924 * 8925 * @devlink_port: devlink port 8926 * @params: configuration parameters array 8927 * @params_count: number of parameters provided 8928 * 8929 * Register the configuration parameters supported by the port. 8930 */ 8931int devlink_port_params_register(struct devlink_port *devlink_port, 8932 const struct devlink_param *params, 8933 size_t params_count) 8934{ 8935 return __devlink_params_register(devlink_port->devlink, 8936 devlink_port->index, 8937 &devlink_port->param_list, params, 8938 params_count, 8939 DEVLINK_CMD_PORT_PARAM_NEW, 8940 DEVLINK_CMD_PORT_PARAM_DEL); 8941} 8942EXPORT_SYMBOL_GPL(devlink_port_params_register); 8943 8944/** 8945 * devlink_port_params_unregister - unregister port configuration 8946 * parameters 8947 * 8948 * @devlink_port: devlink port 8949 * @params: configuration parameters array 8950 * @params_count: number of parameters provided 8951 */ 8952void devlink_port_params_unregister(struct devlink_port *devlink_port, 8953 const struct devlink_param *params, 8954 size_t params_count) 8955{ 8956 return __devlink_params_unregister(devlink_port->devlink, 8957 devlink_port->index, 8958 &devlink_port->param_list, 8959 params, params_count, 8960 DEVLINK_CMD_PORT_PARAM_DEL); 8961} 8962EXPORT_SYMBOL_GPL(devlink_port_params_unregister); 8963 8964static int 8965__devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id, 8966 union devlink_param_value *init_val) 8967{ 8968 struct devlink_param_item *param_item; 8969 8970 param_item = devlink_param_find_by_id(param_list, param_id); 8971 if (!param_item) 8972 return -EINVAL; 8973 8974 if (!param_item->driverinit_value_valid || 8975 !devlink_param_cmode_is_supported(param_item->param, 8976 DEVLINK_PARAM_CMODE_DRIVERINIT)) 8977 return -EOPNOTSUPP; 8978 8979 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) 8980 strcpy(init_val->vstr, param_item->driverinit_value.vstr); 8981 else 8982 *init_val = param_item->driverinit_value; 8983 8984 return 0; 8985} 8986 8987static int 8988__devlink_param_driverinit_value_set(struct devlink *devlink, 8989 unsigned int port_index, 8990 struct list_head *param_list, u32 param_id, 8991 union devlink_param_value init_val, 8992 enum devlink_command cmd) 8993{ 8994 struct devlink_param_item *param_item; 8995 8996 param_item = devlink_param_find_by_id(param_list, param_id); 8997 if (!param_item) 8998 return -EINVAL; 8999 9000 if (!devlink_param_cmode_is_supported(param_item->param, 9001 DEVLINK_PARAM_CMODE_DRIVERINIT)) 9002 return -EOPNOTSUPP; 9003 9004 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) 9005 strcpy(param_item->driverinit_value.vstr, init_val.vstr); 9006 else 9007 param_item->driverinit_value = init_val; 9008 param_item->driverinit_value_valid = true; 9009 9010 devlink_param_notify(devlink, port_index, param_item, cmd); 9011 return 0; 9012} 9013 9014/** 9015 * devlink_param_driverinit_value_get - get configuration parameter 9016 * value for driver initializing 9017 * 9018 * @devlink: devlink 9019 * @param_id: parameter ID 9020 * @init_val: value of parameter in driverinit configuration mode 9021 * 9022 * This function should be used by the driver to get driverinit 9023 * configuration for initialization after reload command. 9024 */ 9025int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, 9026 union devlink_param_value *init_val) 9027{ 9028 if (!devlink_reload_supported(devlink->ops)) 9029 return -EOPNOTSUPP; 9030 9031 return __devlink_param_driverinit_value_get(&devlink->param_list, 9032 param_id, init_val); 9033} 9034EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get); 9035 9036/** 9037 * devlink_param_driverinit_value_set - set value of configuration 9038 * parameter for driverinit 9039 * configuration mode 9040 * 9041 * @devlink: devlink 9042 * @param_id: parameter ID 9043 * @init_val: value of parameter to set for driverinit configuration mode 9044 * 9045 * This function should be used by the driver to set driverinit 9046 * configuration mode default value. 9047 */ 9048int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, 9049 union devlink_param_value init_val) 9050{ 9051 return __devlink_param_driverinit_value_set(devlink, 0, 9052 &devlink->param_list, 9053 param_id, init_val, 9054 DEVLINK_CMD_PARAM_NEW); 9055} 9056EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set); 9057 9058/** 9059 * devlink_port_param_driverinit_value_get - get configuration parameter 9060 * value for driver initializing 9061 * 9062 * @devlink_port: devlink_port 9063 * @param_id: parameter ID 9064 * @init_val: value of parameter in driverinit configuration mode 9065 * 9066 * This function should be used by the driver to get driverinit 9067 * configuration for initialization after reload command. 9068 */ 9069int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port, 9070 u32 param_id, 9071 union devlink_param_value *init_val) 9072{ 9073 struct devlink *devlink = devlink_port->devlink; 9074 9075 if (!devlink_reload_supported(devlink->ops)) 9076 return -EOPNOTSUPP; 9077 9078 return __devlink_param_driverinit_value_get(&devlink_port->param_list, 9079 param_id, init_val); 9080} 9081EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get); 9082 9083/** 9084 * devlink_port_param_driverinit_value_set - set value of configuration 9085 * parameter for driverinit 9086 * configuration mode 9087 * 9088 * @devlink_port: devlink_port 9089 * @param_id: parameter ID 9090 * @init_val: value of parameter to set for driverinit configuration mode 9091 * 9092 * This function should be used by the driver to set driverinit 9093 * configuration mode default value. 9094 */ 9095int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port, 9096 u32 param_id, 9097 union devlink_param_value init_val) 9098{ 9099 return __devlink_param_driverinit_value_set(devlink_port->devlink, 9100 devlink_port->index, 9101 &devlink_port->param_list, 9102 param_id, init_val, 9103 DEVLINK_CMD_PORT_PARAM_NEW); 9104} 9105EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set); 9106 9107/** 9108 * devlink_param_value_changed - notify devlink on a parameter's value 9109 * change. Should be called by the driver 9110 * right after the change. 9111 * 9112 * @devlink: devlink 9113 * @param_id: parameter ID 9114 * 9115 * This function should be used by the driver to notify devlink on value 9116 * change, excluding driverinit configuration mode. 9117 * For driverinit configuration mode driver should use the function 9118 */ 9119void devlink_param_value_changed(struct devlink *devlink, u32 param_id) 9120{ 9121 struct devlink_param_item *param_item; 9122 9123 param_item = devlink_param_find_by_id(&devlink->param_list, param_id); 9124 WARN_ON(!param_item); 9125 9126 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 9127} 9128EXPORT_SYMBOL_GPL(devlink_param_value_changed); 9129 9130/** 9131 * devlink_port_param_value_changed - notify devlink on a parameter's value 9132 * change. Should be called by the driver 9133 * right after the change. 9134 * 9135 * @devlink_port: devlink_port 9136 * @param_id: parameter ID 9137 * 9138 * This function should be used by the driver to notify devlink on value 9139 * change, excluding driverinit configuration mode. 9140 * For driverinit configuration mode driver should use the function 9141 * devlink_port_param_driverinit_value_set() instead. 9142 */ 9143void devlink_port_param_value_changed(struct devlink_port *devlink_port, 9144 u32 param_id) 9145{ 9146 struct devlink_param_item *param_item; 9147 9148 param_item = devlink_param_find_by_id(&devlink_port->param_list, 9149 param_id); 9150 WARN_ON(!param_item); 9151 9152 devlink_param_notify(devlink_port->devlink, devlink_port->index, 9153 param_item, DEVLINK_CMD_PORT_PARAM_NEW); 9154} 9155EXPORT_SYMBOL_GPL(devlink_port_param_value_changed); 9156 9157/** 9158 * devlink_param_value_str_fill - Safely fill-up the string preventing 9159 * from overflow of the preallocated buffer 9160 * 9161 * @dst_val: destination devlink_param_value 9162 * @src: source buffer 9163 */ 9164void devlink_param_value_str_fill(union devlink_param_value *dst_val, 9165 const char *src) 9166{ 9167 size_t len; 9168 9169 len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE); 9170 WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE); 9171} 9172EXPORT_SYMBOL_GPL(devlink_param_value_str_fill); 9173 9174/** 9175 * devlink_region_create - create a new address region 9176 * 9177 * @devlink: devlink 9178 * @ops: region operations and name 9179 * @region_max_snapshots: Maximum supported number of snapshots for region 9180 * @region_size: size of region 9181 */ 9182struct devlink_region * 9183devlink_region_create(struct devlink *devlink, 9184 const struct devlink_region_ops *ops, 9185 u32 region_max_snapshots, u64 region_size) 9186{ 9187 struct devlink_region *region; 9188 int err = 0; 9189 9190 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 9191 return ERR_PTR(-EINVAL); 9192 9193 mutex_lock(&devlink->lock); 9194 9195 if (devlink_region_get_by_name(devlink, ops->name)) { 9196 err = -EEXIST; 9197 goto unlock; 9198 } 9199 9200 region = kzalloc(sizeof(*region), GFP_KERNEL); 9201 if (!region) { 9202 err = -ENOMEM; 9203 goto unlock; 9204 } 9205 9206 region->devlink = devlink; 9207 region->max_snapshots = region_max_snapshots; 9208 region->ops = ops; 9209 region->size = region_size; 9210 INIT_LIST_HEAD(&region->snapshot_list); 9211 list_add_tail(&region->list, &devlink->region_list); 9212 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 9213 9214 mutex_unlock(&devlink->lock); 9215 return region; 9216 9217unlock: 9218 mutex_unlock(&devlink->lock); 9219 return ERR_PTR(err); 9220} 9221EXPORT_SYMBOL_GPL(devlink_region_create); 9222 9223/** 9224 * devlink_port_region_create - create a new address region for a port 9225 * 9226 * @port: devlink port 9227 * @ops: region operations and name 9228 * @region_max_snapshots: Maximum supported number of snapshots for region 9229 * @region_size: size of region 9230 */ 9231struct devlink_region * 9232devlink_port_region_create(struct devlink_port *port, 9233 const struct devlink_port_region_ops *ops, 9234 u32 region_max_snapshots, u64 region_size) 9235{ 9236 struct devlink *devlink = port->devlink; 9237 struct devlink_region *region; 9238 int err = 0; 9239 9240 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 9241 return ERR_PTR(-EINVAL); 9242 9243 mutex_lock(&devlink->lock); 9244 9245 if (devlink_port_region_get_by_name(port, ops->name)) { 9246 err = -EEXIST; 9247 goto unlock; 9248 } 9249 9250 region = kzalloc(sizeof(*region), GFP_KERNEL); 9251 if (!region) { 9252 err = -ENOMEM; 9253 goto unlock; 9254 } 9255 9256 region->devlink = devlink; 9257 region->port = port; 9258 region->max_snapshots = region_max_snapshots; 9259 region->port_ops = ops; 9260 region->size = region_size; 9261 INIT_LIST_HEAD(&region->snapshot_list); 9262 list_add_tail(&region->list, &port->region_list); 9263 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 9264 9265 mutex_unlock(&devlink->lock); 9266 return region; 9267 9268unlock: 9269 mutex_unlock(&devlink->lock); 9270 return ERR_PTR(err); 9271} 9272EXPORT_SYMBOL_GPL(devlink_port_region_create); 9273 9274/** 9275 * devlink_region_destroy - destroy address region 9276 * 9277 * @region: devlink region to destroy 9278 */ 9279void devlink_region_destroy(struct devlink_region *region) 9280{ 9281 struct devlink *devlink = region->devlink; 9282 struct devlink_snapshot *snapshot, *ts; 9283 9284 mutex_lock(&devlink->lock); 9285 9286 /* Free all snapshots of region */ 9287 list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list) 9288 devlink_region_snapshot_del(region, snapshot); 9289 9290 list_del(&region->list); 9291 9292 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); 9293 mutex_unlock(&devlink->lock); 9294 kfree(region); 9295} 9296EXPORT_SYMBOL_GPL(devlink_region_destroy); 9297 9298/** 9299 * devlink_region_snapshot_id_get - get snapshot ID 9300 * 9301 * This callback should be called when adding a new snapshot, 9302 * Driver should use the same id for multiple snapshots taken 9303 * on multiple regions at the same time/by the same trigger. 9304 * 9305 * The caller of this function must use devlink_region_snapshot_id_put 9306 * when finished creating regions using this id. 9307 * 9308 * Returns zero on success, or a negative error code on failure. 9309 * 9310 * @devlink: devlink 9311 * @id: storage to return id 9312 */ 9313int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 9314{ 9315 int err; 9316 9317 mutex_lock(&devlink->lock); 9318 err = __devlink_region_snapshot_id_get(devlink, id); 9319 mutex_unlock(&devlink->lock); 9320 9321 return err; 9322} 9323EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); 9324 9325/** 9326 * devlink_region_snapshot_id_put - put snapshot ID reference 9327 * 9328 * This should be called by a driver after finishing creating snapshots 9329 * with an id. Doing so ensures that the ID can later be released in the 9330 * event that all snapshots using it have been destroyed. 9331 * 9332 * @devlink: devlink 9333 * @id: id to release reference on 9334 */ 9335void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) 9336{ 9337 mutex_lock(&devlink->lock); 9338 __devlink_snapshot_id_decrement(devlink, id); 9339 mutex_unlock(&devlink->lock); 9340} 9341EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); 9342 9343/** 9344 * devlink_region_snapshot_create - create a new snapshot 9345 * This will add a new snapshot of a region. The snapshot 9346 * will be stored on the region struct and can be accessed 9347 * from devlink. This is useful for future analyses of snapshots. 9348 * Multiple snapshots can be created on a region. 9349 * The @snapshot_id should be obtained using the getter function. 9350 * 9351 * @region: devlink region of the snapshot 9352 * @data: snapshot data 9353 * @snapshot_id: snapshot id to be created 9354 */ 9355int devlink_region_snapshot_create(struct devlink_region *region, 9356 u8 *data, u32 snapshot_id) 9357{ 9358 struct devlink *devlink = region->devlink; 9359 int err; 9360 9361 mutex_lock(&devlink->lock); 9362 err = __devlink_region_snapshot_create(region, data, snapshot_id); 9363 mutex_unlock(&devlink->lock); 9364 9365 return err; 9366} 9367EXPORT_SYMBOL_GPL(devlink_region_snapshot_create); 9368 9369#define DEVLINK_TRAP(_id, _type) \ 9370 { \ 9371 .type = DEVLINK_TRAP_TYPE_##_type, \ 9372 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \ 9373 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \ 9374 } 9375 9376static const struct devlink_trap devlink_trap_generic[] = { 9377 DEVLINK_TRAP(SMAC_MC, DROP), 9378 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP), 9379 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP), 9380 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP), 9381 DEVLINK_TRAP(EMPTY_TX_LIST, DROP), 9382 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP), 9383 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP), 9384 DEVLINK_TRAP(TTL_ERROR, EXCEPTION), 9385 DEVLINK_TRAP(TAIL_DROP, DROP), 9386 DEVLINK_TRAP(NON_IP_PACKET, DROP), 9387 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP), 9388 DEVLINK_TRAP(DIP_LB, DROP), 9389 DEVLINK_TRAP(SIP_MC, DROP), 9390 DEVLINK_TRAP(SIP_LB, DROP), 9391 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP), 9392 DEVLINK_TRAP(IPV4_SIP_BC, DROP), 9393 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP), 9394 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP), 9395 DEVLINK_TRAP(MTU_ERROR, EXCEPTION), 9396 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION), 9397 DEVLINK_TRAP(RPF, EXCEPTION), 9398 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION), 9399 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION), 9400 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION), 9401 DEVLINK_TRAP(NON_ROUTABLE, DROP), 9402 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION), 9403 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP), 9404 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP), 9405 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP), 9406 DEVLINK_TRAP(STP, CONTROL), 9407 DEVLINK_TRAP(LACP, CONTROL), 9408 DEVLINK_TRAP(LLDP, CONTROL), 9409 DEVLINK_TRAP(IGMP_QUERY, CONTROL), 9410 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL), 9411 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL), 9412 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL), 9413 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL), 9414 DEVLINK_TRAP(MLD_QUERY, CONTROL), 9415 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL), 9416 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL), 9417 DEVLINK_TRAP(MLD_V1_DONE, CONTROL), 9418 DEVLINK_TRAP(IPV4_DHCP, CONTROL), 9419 DEVLINK_TRAP(IPV6_DHCP, CONTROL), 9420 DEVLINK_TRAP(ARP_REQUEST, CONTROL), 9421 DEVLINK_TRAP(ARP_RESPONSE, CONTROL), 9422 DEVLINK_TRAP(ARP_OVERLAY, CONTROL), 9423 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL), 9424 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL), 9425 DEVLINK_TRAP(IPV4_BFD, CONTROL), 9426 DEVLINK_TRAP(IPV6_BFD, CONTROL), 9427 DEVLINK_TRAP(IPV4_OSPF, CONTROL), 9428 DEVLINK_TRAP(IPV6_OSPF, CONTROL), 9429 DEVLINK_TRAP(IPV4_BGP, CONTROL), 9430 DEVLINK_TRAP(IPV6_BGP, CONTROL), 9431 DEVLINK_TRAP(IPV4_VRRP, CONTROL), 9432 DEVLINK_TRAP(IPV6_VRRP, CONTROL), 9433 DEVLINK_TRAP(IPV4_PIM, CONTROL), 9434 DEVLINK_TRAP(IPV6_PIM, CONTROL), 9435 DEVLINK_TRAP(UC_LB, CONTROL), 9436 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL), 9437 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL), 9438 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL), 9439 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL), 9440 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL), 9441 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL), 9442 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL), 9443 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL), 9444 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL), 9445 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL), 9446 DEVLINK_TRAP(PTP_EVENT, CONTROL), 9447 DEVLINK_TRAP(PTP_GENERAL, CONTROL), 9448 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL), 9449 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL), 9450 DEVLINK_TRAP(EARLY_DROP, DROP), 9451 DEVLINK_TRAP(VXLAN_PARSING, DROP), 9452 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP), 9453 DEVLINK_TRAP(VLAN_PARSING, DROP), 9454 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP), 9455 DEVLINK_TRAP(MPLS_PARSING, DROP), 9456 DEVLINK_TRAP(ARP_PARSING, DROP), 9457 DEVLINK_TRAP(IP_1_PARSING, DROP), 9458 DEVLINK_TRAP(IP_N_PARSING, DROP), 9459 DEVLINK_TRAP(GRE_PARSING, DROP), 9460 DEVLINK_TRAP(UDP_PARSING, DROP), 9461 DEVLINK_TRAP(TCP_PARSING, DROP), 9462 DEVLINK_TRAP(IPSEC_PARSING, DROP), 9463 DEVLINK_TRAP(SCTP_PARSING, DROP), 9464 DEVLINK_TRAP(DCCP_PARSING, DROP), 9465 DEVLINK_TRAP(GTP_PARSING, DROP), 9466 DEVLINK_TRAP(ESP_PARSING, DROP), 9467}; 9468 9469#define DEVLINK_TRAP_GROUP(_id) \ 9470 { \ 9471 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \ 9472 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \ 9473 } 9474 9475static const struct devlink_trap_group devlink_trap_group_generic[] = { 9476 DEVLINK_TRAP_GROUP(L2_DROPS), 9477 DEVLINK_TRAP_GROUP(L3_DROPS), 9478 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS), 9479 DEVLINK_TRAP_GROUP(BUFFER_DROPS), 9480 DEVLINK_TRAP_GROUP(TUNNEL_DROPS), 9481 DEVLINK_TRAP_GROUP(ACL_DROPS), 9482 DEVLINK_TRAP_GROUP(STP), 9483 DEVLINK_TRAP_GROUP(LACP), 9484 DEVLINK_TRAP_GROUP(LLDP), 9485 DEVLINK_TRAP_GROUP(MC_SNOOPING), 9486 DEVLINK_TRAP_GROUP(DHCP), 9487 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY), 9488 DEVLINK_TRAP_GROUP(BFD), 9489 DEVLINK_TRAP_GROUP(OSPF), 9490 DEVLINK_TRAP_GROUP(BGP), 9491 DEVLINK_TRAP_GROUP(VRRP), 9492 DEVLINK_TRAP_GROUP(PIM), 9493 DEVLINK_TRAP_GROUP(UC_LB), 9494 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY), 9495 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY), 9496 DEVLINK_TRAP_GROUP(IPV6), 9497 DEVLINK_TRAP_GROUP(PTP_EVENT), 9498 DEVLINK_TRAP_GROUP(PTP_GENERAL), 9499 DEVLINK_TRAP_GROUP(ACL_SAMPLE), 9500 DEVLINK_TRAP_GROUP(ACL_TRAP), 9501 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS), 9502}; 9503 9504static int devlink_trap_generic_verify(const struct devlink_trap *trap) 9505{ 9506 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX) 9507 return -EINVAL; 9508 9509 if (strcmp(trap->name, devlink_trap_generic[trap->id].name)) 9510 return -EINVAL; 9511 9512 if (trap->type != devlink_trap_generic[trap->id].type) 9513 return -EINVAL; 9514 9515 return 0; 9516} 9517 9518static int devlink_trap_driver_verify(const struct devlink_trap *trap) 9519{ 9520 int i; 9521 9522 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX) 9523 return -EINVAL; 9524 9525 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) { 9526 if (!strcmp(trap->name, devlink_trap_generic[i].name)) 9527 return -EEXIST; 9528 } 9529 9530 return 0; 9531} 9532 9533static int devlink_trap_verify(const struct devlink_trap *trap) 9534{ 9535 if (!trap || !trap->name) 9536 return -EINVAL; 9537 9538 if (trap->generic) 9539 return devlink_trap_generic_verify(trap); 9540 else 9541 return devlink_trap_driver_verify(trap); 9542} 9543 9544static int 9545devlink_trap_group_generic_verify(const struct devlink_trap_group *group) 9546{ 9547 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) 9548 return -EINVAL; 9549 9550 if (strcmp(group->name, devlink_trap_group_generic[group->id].name)) 9551 return -EINVAL; 9552 9553 return 0; 9554} 9555 9556static int 9557devlink_trap_group_driver_verify(const struct devlink_trap_group *group) 9558{ 9559 int i; 9560 9561 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) 9562 return -EINVAL; 9563 9564 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) { 9565 if (!strcmp(group->name, devlink_trap_group_generic[i].name)) 9566 return -EEXIST; 9567 } 9568 9569 return 0; 9570} 9571 9572static int devlink_trap_group_verify(const struct devlink_trap_group *group) 9573{ 9574 if (group->generic) 9575 return devlink_trap_group_generic_verify(group); 9576 else 9577 return devlink_trap_group_driver_verify(group); 9578} 9579 9580static void 9581devlink_trap_group_notify(struct devlink *devlink, 9582 const struct devlink_trap_group_item *group_item, 9583 enum devlink_command cmd) 9584{ 9585 struct sk_buff *msg; 9586 int err; 9587 9588 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW && 9589 cmd != DEVLINK_CMD_TRAP_GROUP_DEL); 9590 9591 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 9592 if (!msg) 9593 return; 9594 9595 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0, 9596 0); 9597 if (err) { 9598 nlmsg_free(msg); 9599 return; 9600 } 9601 9602 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 9603 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 9604} 9605 9606static int 9607devlink_trap_item_group_link(struct devlink *devlink, 9608 struct devlink_trap_item *trap_item) 9609{ 9610 u16 group_id = trap_item->trap->init_group_id; 9611 struct devlink_trap_group_item *group_item; 9612 9613 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id); 9614 if (WARN_ON_ONCE(!group_item)) 9615 return -EINVAL; 9616 9617 trap_item->group_item = group_item; 9618 9619 return 0; 9620} 9621 9622static void devlink_trap_notify(struct devlink *devlink, 9623 const struct devlink_trap_item *trap_item, 9624 enum devlink_command cmd) 9625{ 9626 struct sk_buff *msg; 9627 int err; 9628 9629 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW && 9630 cmd != DEVLINK_CMD_TRAP_DEL); 9631 9632 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 9633 if (!msg) 9634 return; 9635 9636 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0); 9637 if (err) { 9638 nlmsg_free(msg); 9639 return; 9640 } 9641 9642 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 9643 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 9644} 9645 9646static int 9647devlink_trap_register(struct devlink *devlink, 9648 const struct devlink_trap *trap, void *priv) 9649{ 9650 struct devlink_trap_item *trap_item; 9651 int err; 9652 9653 if (devlink_trap_item_lookup(devlink, trap->name)) 9654 return -EEXIST; 9655 9656 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL); 9657 if (!trap_item) 9658 return -ENOMEM; 9659 9660 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); 9661 if (!trap_item->stats) { 9662 err = -ENOMEM; 9663 goto err_stats_alloc; 9664 } 9665 9666 trap_item->trap = trap; 9667 trap_item->action = trap->init_action; 9668 trap_item->priv = priv; 9669 9670 err = devlink_trap_item_group_link(devlink, trap_item); 9671 if (err) 9672 goto err_group_link; 9673 9674 err = devlink->ops->trap_init(devlink, trap, trap_item); 9675 if (err) 9676 goto err_trap_init; 9677 9678 list_add_tail(&trap_item->list, &devlink->trap_list); 9679 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW); 9680 9681 return 0; 9682 9683err_trap_init: 9684err_group_link: 9685 free_percpu(trap_item->stats); 9686err_stats_alloc: 9687 kfree(trap_item); 9688 return err; 9689} 9690 9691static void devlink_trap_unregister(struct devlink *devlink, 9692 const struct devlink_trap *trap) 9693{ 9694 struct devlink_trap_item *trap_item; 9695 9696 trap_item = devlink_trap_item_lookup(devlink, trap->name); 9697 if (WARN_ON_ONCE(!trap_item)) 9698 return; 9699 9700 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL); 9701 list_del(&trap_item->list); 9702 if (devlink->ops->trap_fini) 9703 devlink->ops->trap_fini(devlink, trap, trap_item); 9704 free_percpu(trap_item->stats); 9705 kfree(trap_item); 9706} 9707 9708static void devlink_trap_disable(struct devlink *devlink, 9709 const struct devlink_trap *trap) 9710{ 9711 struct devlink_trap_item *trap_item; 9712 9713 trap_item = devlink_trap_item_lookup(devlink, trap->name); 9714 if (WARN_ON_ONCE(!trap_item)) 9715 return; 9716 9717 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP, 9718 NULL); 9719 trap_item->action = DEVLINK_TRAP_ACTION_DROP; 9720} 9721 9722/** 9723 * devlink_traps_register - Register packet traps with devlink. 9724 * @devlink: devlink. 9725 * @traps: Packet traps. 9726 * @traps_count: Count of provided packet traps. 9727 * @priv: Driver private information. 9728 * 9729 * Return: Non-zero value on failure. 9730 */ 9731int devlink_traps_register(struct devlink *devlink, 9732 const struct devlink_trap *traps, 9733 size_t traps_count, void *priv) 9734{ 9735 int i, err; 9736 9737 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set) 9738 return -EINVAL; 9739 9740 mutex_lock(&devlink->lock); 9741 for (i = 0; i < traps_count; i++) { 9742 const struct devlink_trap *trap = &traps[i]; 9743 9744 err = devlink_trap_verify(trap); 9745 if (err) 9746 goto err_trap_verify; 9747 9748 err = devlink_trap_register(devlink, trap, priv); 9749 if (err) 9750 goto err_trap_register; 9751 } 9752 mutex_unlock(&devlink->lock); 9753 9754 return 0; 9755 9756err_trap_register: 9757err_trap_verify: 9758 for (i--; i >= 0; i--) 9759 devlink_trap_unregister(devlink, &traps[i]); 9760 mutex_unlock(&devlink->lock); 9761 return err; 9762} 9763EXPORT_SYMBOL_GPL(devlink_traps_register); 9764 9765/** 9766 * devlink_traps_unregister - Unregister packet traps from devlink. 9767 * @devlink: devlink. 9768 * @traps: Packet traps. 9769 * @traps_count: Count of provided packet traps. 9770 */ 9771void devlink_traps_unregister(struct devlink *devlink, 9772 const struct devlink_trap *traps, 9773 size_t traps_count) 9774{ 9775 int i; 9776 9777 mutex_lock(&devlink->lock); 9778 /* Make sure we do not have any packets in-flight while unregistering 9779 * traps by disabling all of them and waiting for a grace period. 9780 */ 9781 for (i = traps_count - 1; i >= 0; i--) 9782 devlink_trap_disable(devlink, &traps[i]); 9783 synchronize_rcu(); 9784 for (i = traps_count - 1; i >= 0; i--) 9785 devlink_trap_unregister(devlink, &traps[i]); 9786 mutex_unlock(&devlink->lock); 9787} 9788EXPORT_SYMBOL_GPL(devlink_traps_unregister); 9789 9790static void 9791devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats, 9792 size_t skb_len) 9793{ 9794 struct devlink_stats *stats; 9795 9796 stats = this_cpu_ptr(trap_stats); 9797 u64_stats_update_begin(&stats->syncp); 9798 stats->rx_bytes += skb_len; 9799 stats->rx_packets++; 9800 u64_stats_update_end(&stats->syncp); 9801} 9802 9803static void 9804devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata, 9805 const struct devlink_trap_item *trap_item, 9806 struct devlink_port *in_devlink_port, 9807 const struct flow_action_cookie *fa_cookie) 9808{ 9809 metadata->trap_name = trap_item->trap->name; 9810 metadata->trap_group_name = trap_item->group_item->group->name; 9811 metadata->fa_cookie = fa_cookie; 9812 metadata->trap_type = trap_item->trap->type; 9813 9814 spin_lock(&in_devlink_port->type_lock); 9815 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH) 9816 metadata->input_dev = in_devlink_port->type_dev; 9817 spin_unlock(&in_devlink_port->type_lock); 9818} 9819 9820/** 9821 * devlink_trap_report - Report trapped packet to drop monitor. 9822 * @devlink: devlink. 9823 * @skb: Trapped packet. 9824 * @trap_ctx: Trap context. 9825 * @in_devlink_port: Input devlink port. 9826 * @fa_cookie: Flow action cookie. Could be NULL. 9827 */ 9828void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb, 9829 void *trap_ctx, struct devlink_port *in_devlink_port, 9830 const struct flow_action_cookie *fa_cookie) 9831 9832{ 9833 struct devlink_trap_item *trap_item = trap_ctx; 9834 9835 devlink_trap_stats_update(trap_item->stats, skb->len); 9836 devlink_trap_stats_update(trap_item->group_item->stats, skb->len); 9837 9838 if (trace_devlink_trap_report_enabled()) { 9839 struct devlink_trap_metadata metadata = {}; 9840 9841 devlink_trap_report_metadata_set(&metadata, trap_item, 9842 in_devlink_port, fa_cookie); 9843 trace_devlink_trap_report(devlink, skb, &metadata); 9844 } 9845} 9846EXPORT_SYMBOL_GPL(devlink_trap_report); 9847 9848/** 9849 * devlink_trap_ctx_priv - Trap context to driver private information. 9850 * @trap_ctx: Trap context. 9851 * 9852 * Return: Driver private information passed during registration. 9853 */ 9854void *devlink_trap_ctx_priv(void *trap_ctx) 9855{ 9856 struct devlink_trap_item *trap_item = trap_ctx; 9857 9858 return trap_item->priv; 9859} 9860EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv); 9861 9862static int 9863devlink_trap_group_item_policer_link(struct devlink *devlink, 9864 struct devlink_trap_group_item *group_item) 9865{ 9866 u32 policer_id = group_item->group->init_policer_id; 9867 struct devlink_trap_policer_item *policer_item; 9868 9869 if (policer_id == 0) 9870 return 0; 9871 9872 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id); 9873 if (WARN_ON_ONCE(!policer_item)) 9874 return -EINVAL; 9875 9876 group_item->policer_item = policer_item; 9877 9878 return 0; 9879} 9880 9881static int 9882devlink_trap_group_register(struct devlink *devlink, 9883 const struct devlink_trap_group *group) 9884{ 9885 struct devlink_trap_group_item *group_item; 9886 int err; 9887 9888 if (devlink_trap_group_item_lookup(devlink, group->name)) 9889 return -EEXIST; 9890 9891 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL); 9892 if (!group_item) 9893 return -ENOMEM; 9894 9895 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); 9896 if (!group_item->stats) { 9897 err = -ENOMEM; 9898 goto err_stats_alloc; 9899 } 9900 9901 group_item->group = group; 9902 9903 err = devlink_trap_group_item_policer_link(devlink, group_item); 9904 if (err) 9905 goto err_policer_link; 9906 9907 if (devlink->ops->trap_group_init) { 9908 err = devlink->ops->trap_group_init(devlink, group); 9909 if (err) 9910 goto err_group_init; 9911 } 9912 9913 list_add_tail(&group_item->list, &devlink->trap_group_list); 9914 devlink_trap_group_notify(devlink, group_item, 9915 DEVLINK_CMD_TRAP_GROUP_NEW); 9916 9917 return 0; 9918 9919err_group_init: 9920err_policer_link: 9921 free_percpu(group_item->stats); 9922err_stats_alloc: 9923 kfree(group_item); 9924 return err; 9925} 9926 9927static void 9928devlink_trap_group_unregister(struct devlink *devlink, 9929 const struct devlink_trap_group *group) 9930{ 9931 struct devlink_trap_group_item *group_item; 9932 9933 group_item = devlink_trap_group_item_lookup(devlink, group->name); 9934 if (WARN_ON_ONCE(!group_item)) 9935 return; 9936 9937 devlink_trap_group_notify(devlink, group_item, 9938 DEVLINK_CMD_TRAP_GROUP_DEL); 9939 list_del(&group_item->list); 9940 free_percpu(group_item->stats); 9941 kfree(group_item); 9942} 9943 9944/** 9945 * devlink_trap_groups_register - Register packet trap groups with devlink. 9946 * @devlink: devlink. 9947 * @groups: Packet trap groups. 9948 * @groups_count: Count of provided packet trap groups. 9949 * 9950 * Return: Non-zero value on failure. 9951 */ 9952int devlink_trap_groups_register(struct devlink *devlink, 9953 const struct devlink_trap_group *groups, 9954 size_t groups_count) 9955{ 9956 int i, err; 9957 9958 mutex_lock(&devlink->lock); 9959 for (i = 0; i < groups_count; i++) { 9960 const struct devlink_trap_group *group = &groups[i]; 9961 9962 err = devlink_trap_group_verify(group); 9963 if (err) 9964 goto err_trap_group_verify; 9965 9966 err = devlink_trap_group_register(devlink, group); 9967 if (err) 9968 goto err_trap_group_register; 9969 } 9970 mutex_unlock(&devlink->lock); 9971 9972 return 0; 9973 9974err_trap_group_register: 9975err_trap_group_verify: 9976 for (i--; i >= 0; i--) 9977 devlink_trap_group_unregister(devlink, &groups[i]); 9978 mutex_unlock(&devlink->lock); 9979 return err; 9980} 9981EXPORT_SYMBOL_GPL(devlink_trap_groups_register); 9982 9983/** 9984 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink. 9985 * @devlink: devlink. 9986 * @groups: Packet trap groups. 9987 * @groups_count: Count of provided packet trap groups. 9988 */ 9989void devlink_trap_groups_unregister(struct devlink *devlink, 9990 const struct devlink_trap_group *groups, 9991 size_t groups_count) 9992{ 9993 int i; 9994 9995 mutex_lock(&devlink->lock); 9996 for (i = groups_count - 1; i >= 0; i--) 9997 devlink_trap_group_unregister(devlink, &groups[i]); 9998 mutex_unlock(&devlink->lock); 9999} 10000EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister); 10001 10002static void 10003devlink_trap_policer_notify(struct devlink *devlink, 10004 const struct devlink_trap_policer_item *policer_item, 10005 enum devlink_command cmd) 10006{ 10007 struct sk_buff *msg; 10008 int err; 10009 10010 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW && 10011 cmd != DEVLINK_CMD_TRAP_POLICER_DEL); 10012 10013 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 10014 if (!msg) 10015 return; 10016 10017 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0, 10018 0, 0); 10019 if (err) { 10020 nlmsg_free(msg); 10021 return; 10022 } 10023 10024 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 10025 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 10026} 10027 10028static int 10029devlink_trap_policer_register(struct devlink *devlink, 10030 const struct devlink_trap_policer *policer) 10031{ 10032 struct devlink_trap_policer_item *policer_item; 10033 int err; 10034 10035 if (devlink_trap_policer_item_lookup(devlink, policer->id)) 10036 return -EEXIST; 10037 10038 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL); 10039 if (!policer_item) 10040 return -ENOMEM; 10041 10042 policer_item->policer = policer; 10043 policer_item->rate = policer->init_rate; 10044 policer_item->burst = policer->init_burst; 10045 10046 if (devlink->ops->trap_policer_init) { 10047 err = devlink->ops->trap_policer_init(devlink, policer); 10048 if (err) 10049 goto err_policer_init; 10050 } 10051 10052 list_add_tail(&policer_item->list, &devlink->trap_policer_list); 10053 devlink_trap_policer_notify(devlink, policer_item, 10054 DEVLINK_CMD_TRAP_POLICER_NEW); 10055 10056 return 0; 10057 10058err_policer_init: 10059 kfree(policer_item); 10060 return err; 10061} 10062 10063static void 10064devlink_trap_policer_unregister(struct devlink *devlink, 10065 const struct devlink_trap_policer *policer) 10066{ 10067 struct devlink_trap_policer_item *policer_item; 10068 10069 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id); 10070 if (WARN_ON_ONCE(!policer_item)) 10071 return; 10072 10073 devlink_trap_policer_notify(devlink, policer_item, 10074 DEVLINK_CMD_TRAP_POLICER_DEL); 10075 list_del(&policer_item->list); 10076 if (devlink->ops->trap_policer_fini) 10077 devlink->ops->trap_policer_fini(devlink, policer); 10078 kfree(policer_item); 10079} 10080 10081/** 10082 * devlink_trap_policers_register - Register packet trap policers with devlink. 10083 * @devlink: devlink. 10084 * @policers: Packet trap policers. 10085 * @policers_count: Count of provided packet trap policers. 10086 * 10087 * Return: Non-zero value on failure. 10088 */ 10089int 10090devlink_trap_policers_register(struct devlink *devlink, 10091 const struct devlink_trap_policer *policers, 10092 size_t policers_count) 10093{ 10094 int i, err; 10095 10096 mutex_lock(&devlink->lock); 10097 for (i = 0; i < policers_count; i++) { 10098 const struct devlink_trap_policer *policer = &policers[i]; 10099 10100 if (WARN_ON(policer->id == 0 || 10101 policer->max_rate < policer->min_rate || 10102 policer->max_burst < policer->min_burst)) { 10103 err = -EINVAL; 10104 goto err_trap_policer_verify; 10105 } 10106 10107 err = devlink_trap_policer_register(devlink, policer); 10108 if (err) 10109 goto err_trap_policer_register; 10110 } 10111 mutex_unlock(&devlink->lock); 10112 10113 return 0; 10114 10115err_trap_policer_register: 10116err_trap_policer_verify: 10117 for (i--; i >= 0; i--) 10118 devlink_trap_policer_unregister(devlink, &policers[i]); 10119 mutex_unlock(&devlink->lock); 10120 return err; 10121} 10122EXPORT_SYMBOL_GPL(devlink_trap_policers_register); 10123 10124/** 10125 * devlink_trap_policers_unregister - Unregister packet trap policers from devlink. 10126 * @devlink: devlink. 10127 * @policers: Packet trap policers. 10128 * @policers_count: Count of provided packet trap policers. 10129 */ 10130void 10131devlink_trap_policers_unregister(struct devlink *devlink, 10132 const struct devlink_trap_policer *policers, 10133 size_t policers_count) 10134{ 10135 int i; 10136 10137 mutex_lock(&devlink->lock); 10138 for (i = policers_count - 1; i >= 0; i--) 10139 devlink_trap_policer_unregister(devlink, &policers[i]); 10140 mutex_unlock(&devlink->lock); 10141} 10142EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister); 10143 10144static void __devlink_compat_running_version(struct devlink *devlink, 10145 char *buf, size_t len) 10146{ 10147 const struct nlattr *nlattr; 10148 struct devlink_info_req req; 10149 struct sk_buff *msg; 10150 int rem, err; 10151 10152 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 10153 if (!msg) 10154 return; 10155 10156 req.msg = msg; 10157 err = devlink->ops->info_get(devlink, &req, NULL); 10158 if (err) 10159 goto free_msg; 10160 10161 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) { 10162 const struct nlattr *kv; 10163 int rem_kv; 10164 10165 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING) 10166 continue; 10167 10168 nla_for_each_nested(kv, nlattr, rem_kv) { 10169 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE) 10170 continue; 10171 10172 strlcat(buf, nla_data(kv), len); 10173 strlcat(buf, " ", len); 10174 } 10175 } 10176free_msg: 10177 nlmsg_free(msg); 10178} 10179 10180void devlink_compat_running_version(struct net_device *dev, 10181 char *buf, size_t len) 10182{ 10183 struct devlink *devlink; 10184 10185 dev_hold(dev); 10186 rtnl_unlock(); 10187 10188 devlink = netdev_to_devlink(dev); 10189 if (!devlink || !devlink->ops->info_get) 10190 goto out; 10191 10192 mutex_lock(&devlink->lock); 10193 __devlink_compat_running_version(devlink, buf, len); 10194 mutex_unlock(&devlink->lock); 10195 10196out: 10197 rtnl_lock(); 10198 dev_put(dev); 10199} 10200 10201int devlink_compat_flash_update(struct net_device *dev, const char *file_name) 10202{ 10203 struct devlink_flash_update_params params = {}; 10204 struct devlink *devlink; 10205 int ret; 10206 10207 dev_hold(dev); 10208 rtnl_unlock(); 10209 10210 devlink = netdev_to_devlink(dev); 10211 if (!devlink || !devlink->ops->flash_update) { 10212 ret = -EOPNOTSUPP; 10213 goto out; 10214 } 10215 10216 params.file_name = file_name; 10217 10218 mutex_lock(&devlink->lock); 10219 ret = devlink->ops->flash_update(devlink, &params, NULL); 10220 mutex_unlock(&devlink->lock); 10221 10222out: 10223 rtnl_lock(); 10224 dev_put(dev); 10225 10226 return ret; 10227} 10228 10229int devlink_compat_phys_port_name_get(struct net_device *dev, 10230 char *name, size_t len) 10231{ 10232 struct devlink_port *devlink_port; 10233 10234 /* RTNL mutex is held here which ensures that devlink_port 10235 * instance cannot disappear in the middle. No need to take 10236 * any devlink lock as only permanent values are accessed. 10237 */ 10238 ASSERT_RTNL(); 10239 10240 devlink_port = netdev_to_devlink_port(dev); 10241 if (!devlink_port) 10242 return -EOPNOTSUPP; 10243 10244 return __devlink_port_phys_port_name_get(devlink_port, name, len); 10245} 10246 10247int devlink_compat_switch_id_get(struct net_device *dev, 10248 struct netdev_phys_item_id *ppid) 10249{ 10250 struct devlink_port *devlink_port; 10251 10252 /* Caller must hold RTNL mutex or reference to dev, which ensures that 10253 * devlink_port instance cannot disappear in the middle. No need to take 10254 * any devlink lock as only permanent values are accessed. 10255 */ 10256 devlink_port = netdev_to_devlink_port(dev); 10257 if (!devlink_port || !devlink_port->switch_port) 10258 return -EOPNOTSUPP; 10259 10260 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid)); 10261 10262 return 0; 10263} 10264 10265static void __net_exit devlink_pernet_pre_exit(struct net *net) 10266{ 10267 struct devlink *devlink; 10268 u32 actions_performed; 10269 int err; 10270 10271 /* In case network namespace is getting destroyed, reload 10272 * all devlink instances from this namespace into init_net. 10273 */ 10274 mutex_lock(&devlink_mutex); 10275 list_for_each_entry(devlink, &devlink_list, list) { 10276 if (net_eq(devlink_net(devlink), net)) { 10277 if (WARN_ON(!devlink_reload_supported(devlink->ops))) 10278 continue; 10279 err = devlink_reload(devlink, &init_net, 10280 DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 10281 DEVLINK_RELOAD_LIMIT_UNSPEC, 10282 &actions_performed, NULL); 10283 if (err && err != -EOPNOTSUPP) 10284 pr_warn("Failed to reload devlink instance into init_net\n"); 10285 } 10286 } 10287 mutex_unlock(&devlink_mutex); 10288} 10289 10290static struct pernet_operations devlink_pernet_ops __net_initdata = { 10291 .pre_exit = devlink_pernet_pre_exit, 10292}; 10293 10294static int __init devlink_init(void) 10295{ 10296 int err; 10297 10298 err = genl_register_family(&devlink_nl_family); 10299 if (err) 10300 goto out; 10301 err = register_pernet_subsys(&devlink_pernet_ops); 10302 10303out: 10304 WARN_ON(err); 10305 return err; 10306} 10307 10308subsys_initcall(devlink_init);