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