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