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