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