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