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