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