linux/drivers/net/netdevsim/dev.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2018 Cumulus Networks. All rights reserved.
   3 * Copyright (c) 2018 David Ahern <dsa@cumulusnetworks.com>
   4 * Copyright (c) 2019 Mellanox Technologies. All rights reserved.
   5 *
   6 * This software is licensed under the GNU General License Version 2,
   7 * June 1991 as shown in the file COPYING in the top-level directory of this
   8 * source tree.
   9 *
  10 * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
  11 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
  12 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13 * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
  14 * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
  15 * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  16 */
  17
  18#include <linux/debugfs.h>
  19#include <linux/device.h>
  20#include <linux/etherdevice.h>
  21#include <linux/inet.h>
  22#include <linux/jiffies.h>
  23#include <linux/kernel.h>
  24#include <linux/list.h>
  25#include <linux/mutex.h>
  26#include <linux/random.h>
  27#include <linux/rtnetlink.h>
  28#include <linux/workqueue.h>
  29#include <net/devlink.h>
  30#include <net/ip.h>
  31#include <net/flow_offload.h>
  32#include <uapi/linux/devlink.h>
  33#include <uapi/linux/ip.h>
  34#include <uapi/linux/udp.h>
  35
  36#include "netdevsim.h"
  37
  38static unsigned int
  39nsim_dev_port_index(enum nsim_dev_port_type type, unsigned int port_index)
  40{
  41        switch (type) {
  42        case NSIM_DEV_PORT_TYPE_VF:
  43                port_index = NSIM_DEV_VF_PORT_INDEX_BASE + port_index;
  44                break;
  45        case NSIM_DEV_PORT_TYPE_PF:
  46                break;
  47        }
  48
  49        return port_index;
  50}
  51
  52static inline unsigned int nsim_dev_port_index_to_vf_index(unsigned int port_index)
  53{
  54        return port_index - NSIM_DEV_VF_PORT_INDEX_BASE;
  55}
  56
  57static struct dentry *nsim_dev_ddir;
  58
  59#define NSIM_DEV_DUMMY_REGION_SIZE (1024 * 32)
  60
  61static int
  62nsim_dev_take_snapshot(struct devlink *devlink,
  63                       const struct devlink_region_ops *ops,
  64                       struct netlink_ext_ack *extack,
  65                       u8 **data)
  66{
  67        void *dummy_data;
  68
  69        dummy_data = kmalloc(NSIM_DEV_DUMMY_REGION_SIZE, GFP_KERNEL);
  70        if (!dummy_data)
  71                return -ENOMEM;
  72
  73        get_random_bytes(dummy_data, NSIM_DEV_DUMMY_REGION_SIZE);
  74
  75        *data = dummy_data;
  76
  77        return 0;
  78}
  79
  80static ssize_t nsim_dev_take_snapshot_write(struct file *file,
  81                                            const char __user *data,
  82                                            size_t count, loff_t *ppos)
  83{
  84        struct nsim_dev *nsim_dev = file->private_data;
  85        struct devlink *devlink;
  86        u8 *dummy_data;
  87        int err;
  88        u32 id;
  89
  90        devlink = priv_to_devlink(nsim_dev);
  91
  92        err = nsim_dev_take_snapshot(devlink, NULL, NULL, &dummy_data);
  93        if (err)
  94                return err;
  95
  96        err = devlink_region_snapshot_id_get(devlink, &id);
  97        if (err) {
  98                pr_err("Failed to get snapshot id\n");
  99                kfree(dummy_data);
 100                return err;
 101        }
 102        err = devlink_region_snapshot_create(nsim_dev->dummy_region,
 103                                             dummy_data, id);
 104        devlink_region_snapshot_id_put(devlink, id);
 105        if (err) {
 106                pr_err("Failed to create region snapshot\n");
 107                kfree(dummy_data);
 108                return err;
 109        }
 110
 111        return count;
 112}
 113
 114static const struct file_operations nsim_dev_take_snapshot_fops = {
 115        .open = simple_open,
 116        .write = nsim_dev_take_snapshot_write,
 117        .llseek = generic_file_llseek,
 118        .owner = THIS_MODULE,
 119};
 120
 121static ssize_t nsim_dev_trap_fa_cookie_read(struct file *file,
 122                                            char __user *data,
 123                                            size_t count, loff_t *ppos)
 124{
 125        struct nsim_dev *nsim_dev = file->private_data;
 126        struct flow_action_cookie *fa_cookie;
 127        unsigned int buf_len;
 128        ssize_t ret;
 129        char *buf;
 130
 131        spin_lock(&nsim_dev->fa_cookie_lock);
 132        fa_cookie = nsim_dev->fa_cookie;
 133        if (!fa_cookie) {
 134                ret = -EINVAL;
 135                goto errout;
 136        }
 137        buf_len = fa_cookie->cookie_len * 2;
 138        buf = kmalloc(buf_len, GFP_ATOMIC);
 139        if (!buf) {
 140                ret = -ENOMEM;
 141                goto errout;
 142        }
 143        bin2hex(buf, fa_cookie->cookie, fa_cookie->cookie_len);
 144        spin_unlock(&nsim_dev->fa_cookie_lock);
 145
 146        ret = simple_read_from_buffer(data, count, ppos, buf, buf_len);
 147
 148        kfree(buf);
 149        return ret;
 150
 151errout:
 152        spin_unlock(&nsim_dev->fa_cookie_lock);
 153        return ret;
 154}
 155
 156static ssize_t nsim_dev_trap_fa_cookie_write(struct file *file,
 157                                             const char __user *data,
 158                                             size_t count, loff_t *ppos)
 159{
 160        struct nsim_dev *nsim_dev = file->private_data;
 161        struct flow_action_cookie *fa_cookie;
 162        size_t cookie_len;
 163        ssize_t ret;
 164        char *buf;
 165
 166        if (*ppos != 0)
 167                return -EINVAL;
 168        cookie_len = (count - 1) / 2;
 169        if ((count - 1) % 2)
 170                return -EINVAL;
 171        buf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN);
 172        if (!buf)
 173                return -ENOMEM;
 174
 175        ret = simple_write_to_buffer(buf, count, ppos, data, count);
 176        if (ret < 0)
 177                goto free_buf;
 178
 179        fa_cookie = kmalloc(sizeof(*fa_cookie) + cookie_len,
 180                            GFP_KERNEL | __GFP_NOWARN);
 181        if (!fa_cookie) {
 182                ret = -ENOMEM;
 183                goto free_buf;
 184        }
 185
 186        fa_cookie->cookie_len = cookie_len;
 187        ret = hex2bin(fa_cookie->cookie, buf, cookie_len);
 188        if (ret)
 189                goto free_fa_cookie;
 190        kfree(buf);
 191
 192        spin_lock(&nsim_dev->fa_cookie_lock);
 193        kfree(nsim_dev->fa_cookie);
 194        nsim_dev->fa_cookie = fa_cookie;
 195        spin_unlock(&nsim_dev->fa_cookie_lock);
 196
 197        return count;
 198
 199free_fa_cookie:
 200        kfree(fa_cookie);
 201free_buf:
 202        kfree(buf);
 203        return ret;
 204}
 205
 206static const struct file_operations nsim_dev_trap_fa_cookie_fops = {
 207        .open = simple_open,
 208        .read = nsim_dev_trap_fa_cookie_read,
 209        .write = nsim_dev_trap_fa_cookie_write,
 210        .llseek = generic_file_llseek,
 211        .owner = THIS_MODULE,
 212};
 213
 214static const struct file_operations nsim_dev_max_vfs_fops = {
 215        .open = simple_open,
 216        .read = nsim_bus_dev_max_vfs_read,
 217        .write = nsim_bus_dev_max_vfs_write,
 218        .llseek = generic_file_llseek,
 219        .owner = THIS_MODULE,
 220};
 221
 222static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
 223{
 224        char dev_ddir_name[sizeof(DRV_NAME) + 10];
 225        int err;
 226
 227        sprintf(dev_ddir_name, DRV_NAME "%u", nsim_dev->nsim_bus_dev->dev.id);
 228        nsim_dev->ddir = debugfs_create_dir(dev_ddir_name, nsim_dev_ddir);
 229        if (IS_ERR(nsim_dev->ddir))
 230                return PTR_ERR(nsim_dev->ddir);
 231        nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir);
 232        if (IS_ERR(nsim_dev->ports_ddir))
 233                return PTR_ERR(nsim_dev->ports_ddir);
 234        debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
 235                            &nsim_dev->fw_update_status);
 236        debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir,
 237                            &nsim_dev->fw_update_overwrite_mask);
 238        debugfs_create_u32("max_macs", 0600, nsim_dev->ddir,
 239                           &nsim_dev->max_macs);
 240        debugfs_create_bool("test1", 0600, nsim_dev->ddir,
 241                            &nsim_dev->test1);
 242        nsim_dev->take_snapshot = debugfs_create_file("take_snapshot",
 243                                                      0200,
 244                                                      nsim_dev->ddir,
 245                                                      nsim_dev,
 246                                                &nsim_dev_take_snapshot_fops);
 247        debugfs_create_bool("dont_allow_reload", 0600, nsim_dev->ddir,
 248                            &nsim_dev->dont_allow_reload);
 249        debugfs_create_bool("fail_reload", 0600, nsim_dev->ddir,
 250                            &nsim_dev->fail_reload);
 251        debugfs_create_file("trap_flow_action_cookie", 0600, nsim_dev->ddir,
 252                            nsim_dev, &nsim_dev_trap_fa_cookie_fops);
 253        debugfs_create_bool("fail_trap_group_set", 0600,
 254                            nsim_dev->ddir,
 255                            &nsim_dev->fail_trap_group_set);
 256        debugfs_create_bool("fail_trap_policer_set", 0600,
 257                            nsim_dev->ddir,
 258                            &nsim_dev->fail_trap_policer_set);
 259        debugfs_create_bool("fail_trap_policer_counter_get", 0600,
 260                            nsim_dev->ddir,
 261                            &nsim_dev->fail_trap_policer_counter_get);
 262        nsim_dev->max_vfs = debugfs_create_file("max_vfs",
 263                                                0600,
 264                                                nsim_dev->ddir,
 265                                                nsim_dev->nsim_bus_dev,
 266                                                &nsim_dev_max_vfs_fops);
 267        nsim_dev->nodes_ddir = debugfs_create_dir("rate_nodes", nsim_dev->ddir);
 268        if (IS_ERR(nsim_dev->nodes_ddir)) {
 269                err = PTR_ERR(nsim_dev->nodes_ddir);
 270                goto err_out;
 271        }
 272        debugfs_create_bool("fail_trap_drop_counter_get", 0600,
 273                            nsim_dev->ddir,
 274                            &nsim_dev->fail_trap_drop_counter_get);
 275        nsim_udp_tunnels_debugfs_create(nsim_dev);
 276        return 0;
 277
 278err_out:
 279        debugfs_remove_recursive(nsim_dev->ports_ddir);
 280        debugfs_remove_recursive(nsim_dev->ddir);
 281        return err;
 282}
 283
 284static void nsim_dev_debugfs_exit(struct nsim_dev *nsim_dev)
 285{
 286        debugfs_remove_recursive(nsim_dev->nodes_ddir);
 287        debugfs_remove_recursive(nsim_dev->ports_ddir);
 288        debugfs_remove_recursive(nsim_dev->ddir);
 289}
 290
 291static ssize_t nsim_dev_rate_parent_read(struct file *file,
 292                                         char __user *data,
 293                                         size_t count, loff_t *ppos)
 294{
 295        char **name_ptr = file->private_data;
 296        size_t len;
 297
 298        if (!*name_ptr)
 299                return 0;
 300
 301        len = strlen(*name_ptr);
 302        return simple_read_from_buffer(data, count, ppos, *name_ptr, len);
 303}
 304
 305static const struct file_operations nsim_dev_rate_parent_fops = {
 306        .open = simple_open,
 307        .read = nsim_dev_rate_parent_read,
 308        .llseek = generic_file_llseek,
 309        .owner = THIS_MODULE,
 310};
 311
 312static int nsim_dev_port_debugfs_init(struct nsim_dev *nsim_dev,
 313                                      struct nsim_dev_port *nsim_dev_port)
 314{
 315        struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
 316        unsigned int port_index = nsim_dev_port->port_index;
 317        char port_ddir_name[16];
 318        char dev_link_name[32];
 319
 320        sprintf(port_ddir_name, "%u", port_index);
 321        nsim_dev_port->ddir = debugfs_create_dir(port_ddir_name,
 322                                                 nsim_dev->ports_ddir);
 323        if (IS_ERR(nsim_dev_port->ddir))
 324                return PTR_ERR(nsim_dev_port->ddir);
 325
 326        sprintf(dev_link_name, "../../../" DRV_NAME "%u", nsim_bus_dev->dev.id);
 327        if (nsim_dev_port_is_vf(nsim_dev_port)) {
 328                unsigned int vf_id = nsim_dev_port_index_to_vf_index(port_index);
 329
 330                debugfs_create_u16("tx_share", 0400, nsim_dev_port->ddir,
 331                                   &nsim_bus_dev->vfconfigs[vf_id].min_tx_rate);
 332                debugfs_create_u16("tx_max", 0400, nsim_dev_port->ddir,
 333                                   &nsim_bus_dev->vfconfigs[vf_id].max_tx_rate);
 334                nsim_dev_port->rate_parent = debugfs_create_file("rate_parent",
 335                                                                 0400,
 336                                                                 nsim_dev_port->ddir,
 337                                                                 &nsim_dev_port->parent_name,
 338                                                                 &nsim_dev_rate_parent_fops);
 339        }
 340        debugfs_create_symlink("dev", nsim_dev_port->ddir, dev_link_name);
 341
 342        return 0;
 343}
 344
 345static void nsim_dev_port_debugfs_exit(struct nsim_dev_port *nsim_dev_port)
 346{
 347        debugfs_remove_recursive(nsim_dev_port->ddir);
 348}
 349
 350static int nsim_dev_resources_register(struct devlink *devlink)
 351{
 352        struct devlink_resource_size_params params = {
 353                .size_max = (u64)-1,
 354                .size_granularity = 1,
 355                .unit = DEVLINK_RESOURCE_UNIT_ENTRY
 356        };
 357        int err;
 358
 359        /* Resources for IPv4 */
 360        err = devlink_resource_register(devlink, "IPv4", (u64)-1,
 361                                        NSIM_RESOURCE_IPV4,
 362                                        DEVLINK_RESOURCE_ID_PARENT_TOP,
 363                                        &params);
 364        if (err) {
 365                pr_err("Failed to register IPv4 top resource\n");
 366                goto out;
 367        }
 368
 369        err = devlink_resource_register(devlink, "fib", (u64)-1,
 370                                        NSIM_RESOURCE_IPV4_FIB,
 371                                        NSIM_RESOURCE_IPV4, &params);
 372        if (err) {
 373                pr_err("Failed to register IPv4 FIB resource\n");
 374                return err;
 375        }
 376
 377        err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
 378                                        NSIM_RESOURCE_IPV4_FIB_RULES,
 379                                        NSIM_RESOURCE_IPV4, &params);
 380        if (err) {
 381                pr_err("Failed to register IPv4 FIB rules resource\n");
 382                return err;
 383        }
 384
 385        /* Resources for IPv6 */
 386        err = devlink_resource_register(devlink, "IPv6", (u64)-1,
 387                                        NSIM_RESOURCE_IPV6,
 388                                        DEVLINK_RESOURCE_ID_PARENT_TOP,
 389                                        &params);
 390        if (err) {
 391                pr_err("Failed to register IPv6 top resource\n");
 392                goto out;
 393        }
 394
 395        err = devlink_resource_register(devlink, "fib", (u64)-1,
 396                                        NSIM_RESOURCE_IPV6_FIB,
 397                                        NSIM_RESOURCE_IPV6, &params);
 398        if (err) {
 399                pr_err("Failed to register IPv6 FIB resource\n");
 400                return err;
 401        }
 402
 403        err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
 404                                        NSIM_RESOURCE_IPV6_FIB_RULES,
 405                                        NSIM_RESOURCE_IPV6, &params);
 406        if (err) {
 407                pr_err("Failed to register IPv6 FIB rules resource\n");
 408                return err;
 409        }
 410
 411        /* Resources for nexthops */
 412        err = devlink_resource_register(devlink, "nexthops", (u64)-1,
 413                                        NSIM_RESOURCE_NEXTHOPS,
 414                                        DEVLINK_RESOURCE_ID_PARENT_TOP,
 415                                        &params);
 416
 417out:
 418        return err;
 419}
 420
 421enum nsim_devlink_param_id {
 422        NSIM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
 423        NSIM_DEVLINK_PARAM_ID_TEST1,
 424};
 425
 426static const struct devlink_param nsim_devlink_params[] = {
 427        DEVLINK_PARAM_GENERIC(MAX_MACS,
 428                              BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 429                              NULL, NULL, NULL),
 430        DEVLINK_PARAM_DRIVER(NSIM_DEVLINK_PARAM_ID_TEST1,
 431                             "test1", DEVLINK_PARAM_TYPE_BOOL,
 432                             BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 433                             NULL, NULL, NULL),
 434};
 435
 436static void nsim_devlink_set_params_init_values(struct nsim_dev *nsim_dev,
 437                                                struct devlink *devlink)
 438{
 439        union devlink_param_value value;
 440
 441        value.vu32 = nsim_dev->max_macs;
 442        devlink_param_driverinit_value_set(devlink,
 443                                           DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
 444                                           value);
 445        value.vbool = nsim_dev->test1;
 446        devlink_param_driverinit_value_set(devlink,
 447                                           NSIM_DEVLINK_PARAM_ID_TEST1,
 448                                           value);
 449}
 450
 451static void nsim_devlink_param_load_driverinit_values(struct devlink *devlink)
 452{
 453        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 454        union devlink_param_value saved_value;
 455        int err;
 456
 457        err = devlink_param_driverinit_value_get(devlink,
 458                                                 DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
 459                                                 &saved_value);
 460        if (!err)
 461                nsim_dev->max_macs = saved_value.vu32;
 462        err = devlink_param_driverinit_value_get(devlink,
 463                                                 NSIM_DEVLINK_PARAM_ID_TEST1,
 464                                                 &saved_value);
 465        if (!err)
 466                nsim_dev->test1 = saved_value.vbool;
 467}
 468
 469#define NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX 16
 470
 471static const struct devlink_region_ops dummy_region_ops = {
 472        .name = "dummy",
 473        .destructor = &kfree,
 474        .snapshot = nsim_dev_take_snapshot,
 475};
 476
 477static int nsim_dev_dummy_region_init(struct nsim_dev *nsim_dev,
 478                                      struct devlink *devlink)
 479{
 480        nsim_dev->dummy_region =
 481                devlink_region_create(devlink, &dummy_region_ops,
 482                                      NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX,
 483                                      NSIM_DEV_DUMMY_REGION_SIZE);
 484        return PTR_ERR_OR_ZERO(nsim_dev->dummy_region);
 485}
 486
 487static void nsim_dev_dummy_region_exit(struct nsim_dev *nsim_dev)
 488{
 489        devlink_region_destroy(nsim_dev->dummy_region);
 490}
 491
 492static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port);
 493int nsim_esw_legacy_enable(struct nsim_dev *nsim_dev, struct netlink_ext_ack *extack)
 494{
 495        struct devlink *devlink = priv_to_devlink(nsim_dev);
 496        struct nsim_dev_port *nsim_dev_port, *tmp;
 497
 498        devlink_rate_nodes_destroy(devlink);
 499        mutex_lock(&nsim_dev->port_list_lock);
 500        list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list)
 501                if (nsim_dev_port_is_vf(nsim_dev_port))
 502                        __nsim_dev_port_del(nsim_dev_port);
 503        mutex_unlock(&nsim_dev->port_list_lock);
 504        nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY;
 505        return 0;
 506}
 507
 508int nsim_esw_switchdev_enable(struct nsim_dev *nsim_dev, struct netlink_ext_ack *extack)
 509{
 510        struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
 511        int i, err;
 512
 513        for (i = 0; i < nsim_bus_dev->num_vfs; i++) {
 514                err = nsim_dev_port_add(nsim_bus_dev, NSIM_DEV_PORT_TYPE_VF, i);
 515                if (err) {
 516                        NL_SET_ERR_MSG_MOD(extack, "Failed to initialize VFs' netdevsim ports");
 517                        pr_err("Failed to initialize VF id=%d. %d.\n", i, err);
 518                        goto err_port_add_vfs;
 519                }
 520        }
 521        nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_SWITCHDEV;
 522        return 0;
 523
 524err_port_add_vfs:
 525        for (i--; i >= 0; i--)
 526                nsim_dev_port_del(nsim_bus_dev, NSIM_DEV_PORT_TYPE_VF, i);
 527        return err;
 528}
 529
 530static int nsim_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
 531                                         struct netlink_ext_ack *extack)
 532{
 533        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 534        int err = 0;
 535
 536        mutex_lock(&nsim_dev->nsim_bus_dev->vfs_lock);
 537        if (mode == nsim_dev->esw_mode)
 538                goto unlock;
 539
 540        if (mode == DEVLINK_ESWITCH_MODE_LEGACY)
 541                err = nsim_esw_legacy_enable(nsim_dev, extack);
 542        else if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV)
 543                err = nsim_esw_switchdev_enable(nsim_dev, extack);
 544        else
 545                err = -EINVAL;
 546
 547unlock:
 548        mutex_unlock(&nsim_dev->nsim_bus_dev->vfs_lock);
 549        return err;
 550}
 551
 552static int nsim_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
 553{
 554        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 555
 556        *mode = nsim_dev->esw_mode;
 557        return 0;
 558}
 559
 560struct nsim_trap_item {
 561        void *trap_ctx;
 562        enum devlink_trap_action action;
 563};
 564
 565struct nsim_trap_data {
 566        struct delayed_work trap_report_dw;
 567        struct nsim_trap_item *trap_items_arr;
 568        u64 *trap_policers_cnt_arr;
 569        u64 trap_pkt_cnt;
 570        struct nsim_dev *nsim_dev;
 571        spinlock_t trap_lock;   /* Protects trap_items_arr */
 572};
 573
 574/* All driver-specific traps must be documented in
 575 * Documentation/networking/devlink/netdevsim.rst
 576 */
 577enum {
 578        NSIM_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,
 579        NSIM_TRAP_ID_FID_MISS,
 580};
 581
 582#define NSIM_TRAP_NAME_FID_MISS "fid_miss"
 583
 584#define NSIM_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
 585
 586#define NSIM_TRAP_DROP(_id, _group_id)                                        \
 587        DEVLINK_TRAP_GENERIC(DROP, DROP, _id,                                 \
 588                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
 589                             NSIM_TRAP_METADATA)
 590#define NSIM_TRAP_DROP_EXT(_id, _group_id, _metadata)                         \
 591        DEVLINK_TRAP_GENERIC(DROP, DROP, _id,                                 \
 592                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
 593                             NSIM_TRAP_METADATA | (_metadata))
 594#define NSIM_TRAP_EXCEPTION(_id, _group_id)                                   \
 595        DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id,                            \
 596                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
 597                             NSIM_TRAP_METADATA)
 598#define NSIM_TRAP_CONTROL(_id, _group_id, _action)                            \
 599        DEVLINK_TRAP_GENERIC(CONTROL, _action, _id,                           \
 600                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
 601                             NSIM_TRAP_METADATA)
 602#define NSIM_TRAP_DRIVER_EXCEPTION(_id, _group_id)                            \
 603        DEVLINK_TRAP_DRIVER(EXCEPTION, TRAP, NSIM_TRAP_ID_##_id,              \
 604                            NSIM_TRAP_NAME_##_id,                             \
 605                            DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,        \
 606                            NSIM_TRAP_METADATA)
 607
 608#define NSIM_DEV_TRAP_POLICER_MIN_RATE  1
 609#define NSIM_DEV_TRAP_POLICER_MAX_RATE  8000
 610#define NSIM_DEV_TRAP_POLICER_MIN_BURST 8
 611#define NSIM_DEV_TRAP_POLICER_MAX_BURST 65536
 612
 613#define NSIM_TRAP_POLICER(_id, _rate, _burst)                                 \
 614        DEVLINK_TRAP_POLICER(_id, _rate, _burst,                              \
 615                             NSIM_DEV_TRAP_POLICER_MAX_RATE,                  \
 616                             NSIM_DEV_TRAP_POLICER_MIN_RATE,                  \
 617                             NSIM_DEV_TRAP_POLICER_MAX_BURST,                 \
 618                             NSIM_DEV_TRAP_POLICER_MIN_BURST)
 619
 620static const struct devlink_trap_policer nsim_trap_policers_arr[] = {
 621        NSIM_TRAP_POLICER(1, 1000, 128),
 622        NSIM_TRAP_POLICER(2, 2000, 256),
 623        NSIM_TRAP_POLICER(3, 3000, 512),
 624};
 625
 626static const struct devlink_trap_group nsim_trap_groups_arr[] = {
 627        DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
 628        DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 1),
 629        DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 1),
 630        DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 2),
 631        DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 3),
 632        DEVLINK_TRAP_GROUP_GENERIC(MC_SNOOPING, 3),
 633};
 634
 635static const struct devlink_trap nsim_traps_arr[] = {
 636        NSIM_TRAP_DROP(SMAC_MC, L2_DROPS),
 637        NSIM_TRAP_DROP(VLAN_TAG_MISMATCH, L2_DROPS),
 638        NSIM_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
 639        NSIM_TRAP_DROP(INGRESS_STP_FILTER, L2_DROPS),
 640        NSIM_TRAP_DROP(EMPTY_TX_LIST, L2_DROPS),
 641        NSIM_TRAP_DROP(PORT_LOOPBACK_FILTER, L2_DROPS),
 642        NSIM_TRAP_DRIVER_EXCEPTION(FID_MISS, L2_DROPS),
 643        NSIM_TRAP_DROP(BLACKHOLE_ROUTE, L3_DROPS),
 644        NSIM_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS),
 645        NSIM_TRAP_DROP(TAIL_DROP, BUFFER_DROPS),
 646        NSIM_TRAP_DROP_EXT(INGRESS_FLOW_ACTION_DROP, ACL_DROPS,
 647                           DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
 648        NSIM_TRAP_DROP_EXT(EGRESS_FLOW_ACTION_DROP, ACL_DROPS,
 649                           DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
 650        NSIM_TRAP_CONTROL(IGMP_QUERY, MC_SNOOPING, MIRROR),
 651        NSIM_TRAP_CONTROL(IGMP_V1_REPORT, MC_SNOOPING, TRAP),
 652};
 653
 654#define NSIM_TRAP_L4_DATA_LEN 100
 655
 656static struct sk_buff *nsim_dev_trap_skb_build(void)
 657{
 658        int tot_len, data_len = NSIM_TRAP_L4_DATA_LEN;
 659        struct sk_buff *skb;
 660        struct udphdr *udph;
 661        struct ethhdr *eth;
 662        struct iphdr *iph;
 663
 664        skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
 665        if (!skb)
 666                return NULL;
 667        tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + data_len;
 668
 669        skb_reset_mac_header(skb);
 670        eth = skb_put(skb, sizeof(struct ethhdr));
 671        eth_random_addr(eth->h_dest);
 672        eth_random_addr(eth->h_source);
 673        eth->h_proto = htons(ETH_P_IP);
 674        skb->protocol = htons(ETH_P_IP);
 675
 676        skb_set_network_header(skb, skb->len);
 677        iph = skb_put(skb, sizeof(struct iphdr));
 678        iph->protocol = IPPROTO_UDP;
 679        iph->saddr = in_aton("192.0.2.1");
 680        iph->daddr = in_aton("198.51.100.1");
 681        iph->version = 0x4;
 682        iph->frag_off = 0;
 683        iph->ihl = 0x5;
 684        iph->tot_len = htons(tot_len);
 685        iph->ttl = 100;
 686        iph->check = 0;
 687        iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
 688
 689        skb_set_transport_header(skb, skb->len);
 690        udph = skb_put_zero(skb, sizeof(struct udphdr) + data_len);
 691        get_random_bytes(&udph->source, sizeof(u16));
 692        get_random_bytes(&udph->dest, sizeof(u16));
 693        udph->len = htons(sizeof(struct udphdr) + data_len);
 694
 695        return skb;
 696}
 697
 698static void nsim_dev_trap_report(struct nsim_dev_port *nsim_dev_port)
 699{
 700        struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev;
 701        struct devlink *devlink = priv_to_devlink(nsim_dev);
 702        struct nsim_trap_data *nsim_trap_data;
 703        int i;
 704
 705        nsim_trap_data = nsim_dev->trap_data;
 706
 707        spin_lock(&nsim_trap_data->trap_lock);
 708        for (i = 0; i < ARRAY_SIZE(nsim_traps_arr); i++) {
 709                struct flow_action_cookie *fa_cookie = NULL;
 710                struct nsim_trap_item *nsim_trap_item;
 711                struct sk_buff *skb;
 712                bool has_fa_cookie;
 713
 714                has_fa_cookie = nsim_traps_arr[i].metadata_cap &
 715                                DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE;
 716
 717                nsim_trap_item = &nsim_trap_data->trap_items_arr[i];
 718                if (nsim_trap_item->action == DEVLINK_TRAP_ACTION_DROP)
 719                        continue;
 720
 721                skb = nsim_dev_trap_skb_build();
 722                if (!skb)
 723                        continue;
 724                skb->dev = nsim_dev_port->ns->netdev;
 725
 726                /* Trapped packets are usually passed to devlink in softIRQ,
 727                 * but in this case they are generated in a workqueue. Disable
 728                 * softIRQs to prevent lockdep from complaining about
 729                 * "incosistent lock state".
 730                 */
 731
 732                spin_lock_bh(&nsim_dev->fa_cookie_lock);
 733                fa_cookie = has_fa_cookie ? nsim_dev->fa_cookie : NULL;
 734                devlink_trap_report(devlink, skb, nsim_trap_item->trap_ctx,
 735                                    &nsim_dev_port->devlink_port, fa_cookie);
 736                spin_unlock_bh(&nsim_dev->fa_cookie_lock);
 737                consume_skb(skb);
 738        }
 739        spin_unlock(&nsim_trap_data->trap_lock);
 740}
 741
 742#define NSIM_TRAP_REPORT_INTERVAL_MS    100
 743
 744static void nsim_dev_trap_report_work(struct work_struct *work)
 745{
 746        struct nsim_trap_data *nsim_trap_data;
 747        struct nsim_dev_port *nsim_dev_port;
 748        struct nsim_dev *nsim_dev;
 749
 750        nsim_trap_data = container_of(work, struct nsim_trap_data,
 751                                      trap_report_dw.work);
 752        nsim_dev = nsim_trap_data->nsim_dev;
 753
 754        /* For each running port and enabled packet trap, generate a UDP
 755         * packet with a random 5-tuple and report it.
 756         */
 757        mutex_lock(&nsim_dev->port_list_lock);
 758        list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) {
 759                if (!netif_running(nsim_dev_port->ns->netdev))
 760                        continue;
 761
 762                nsim_dev_trap_report(nsim_dev_port);
 763        }
 764        mutex_unlock(&nsim_dev->port_list_lock);
 765
 766        schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
 767                              msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
 768}
 769
 770static int nsim_dev_traps_init(struct devlink *devlink)
 771{
 772        size_t policers_count = ARRAY_SIZE(nsim_trap_policers_arr);
 773        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 774        struct nsim_trap_data *nsim_trap_data;
 775        int err;
 776
 777        nsim_trap_data = kzalloc(sizeof(*nsim_trap_data), GFP_KERNEL);
 778        if (!nsim_trap_data)
 779                return -ENOMEM;
 780
 781        nsim_trap_data->trap_items_arr = kcalloc(ARRAY_SIZE(nsim_traps_arr),
 782                                                 sizeof(struct nsim_trap_item),
 783                                                 GFP_KERNEL);
 784        if (!nsim_trap_data->trap_items_arr) {
 785                err = -ENOMEM;
 786                goto err_trap_data_free;
 787        }
 788
 789        nsim_trap_data->trap_policers_cnt_arr = kcalloc(policers_count,
 790                                                        sizeof(u64),
 791                                                        GFP_KERNEL);
 792        if (!nsim_trap_data->trap_policers_cnt_arr) {
 793                err = -ENOMEM;
 794                goto err_trap_items_free;
 795        }
 796
 797        /* The lock is used to protect the action state of the registered
 798         * traps. The value is written by user and read in delayed work when
 799         * iterating over all the traps.
 800         */
 801        spin_lock_init(&nsim_trap_data->trap_lock);
 802        nsim_trap_data->nsim_dev = nsim_dev;
 803        nsim_dev->trap_data = nsim_trap_data;
 804
 805        err = devlink_trap_policers_register(devlink, nsim_trap_policers_arr,
 806                                             policers_count);
 807        if (err)
 808                goto err_trap_policers_cnt_free;
 809
 810        err = devlink_trap_groups_register(devlink, nsim_trap_groups_arr,
 811                                           ARRAY_SIZE(nsim_trap_groups_arr));
 812        if (err)
 813                goto err_trap_policers_unregister;
 814
 815        err = devlink_traps_register(devlink, nsim_traps_arr,
 816                                     ARRAY_SIZE(nsim_traps_arr), NULL);
 817        if (err)
 818                goto err_trap_groups_unregister;
 819
 820        INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw,
 821                          nsim_dev_trap_report_work);
 822        schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
 823                              msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
 824
 825        return 0;
 826
 827err_trap_groups_unregister:
 828        devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr,
 829                                       ARRAY_SIZE(nsim_trap_groups_arr));
 830err_trap_policers_unregister:
 831        devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr,
 832                                         ARRAY_SIZE(nsim_trap_policers_arr));
 833err_trap_policers_cnt_free:
 834        kfree(nsim_trap_data->trap_policers_cnt_arr);
 835err_trap_items_free:
 836        kfree(nsim_trap_data->trap_items_arr);
 837err_trap_data_free:
 838        kfree(nsim_trap_data);
 839        return err;
 840}
 841
 842static void nsim_dev_traps_exit(struct devlink *devlink)
 843{
 844        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 845
 846        cancel_delayed_work_sync(&nsim_dev->trap_data->trap_report_dw);
 847        devlink_traps_unregister(devlink, nsim_traps_arr,
 848                                 ARRAY_SIZE(nsim_traps_arr));
 849        devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr,
 850                                       ARRAY_SIZE(nsim_trap_groups_arr));
 851        devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr,
 852                                         ARRAY_SIZE(nsim_trap_policers_arr));
 853        kfree(nsim_dev->trap_data->trap_policers_cnt_arr);
 854        kfree(nsim_dev->trap_data->trap_items_arr);
 855        kfree(nsim_dev->trap_data);
 856}
 857
 858static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
 859                                  struct netlink_ext_ack *extack);
 860static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev);
 861
 862static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change,
 863                                enum devlink_reload_action action, enum devlink_reload_limit limit,
 864                                struct netlink_ext_ack *extack)
 865{
 866        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 867        struct nsim_bus_dev *nsim_bus_dev;
 868
 869        nsim_bus_dev = nsim_dev->nsim_bus_dev;
 870        if (!mutex_trylock(&nsim_bus_dev->nsim_bus_reload_lock))
 871                return -EOPNOTSUPP;
 872
 873        if (nsim_dev->dont_allow_reload) {
 874                /* For testing purposes, user set debugfs dont_allow_reload
 875                 * value to true. So forbid it.
 876                 */
 877                NL_SET_ERR_MSG_MOD(extack, "User forbid the reload for testing purposes");
 878                mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
 879                return -EOPNOTSUPP;
 880        }
 881        nsim_bus_dev->in_reload = true;
 882
 883        nsim_dev_reload_destroy(nsim_dev);
 884        mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
 885        return 0;
 886}
 887
 888static int nsim_dev_reload_up(struct devlink *devlink, enum devlink_reload_action action,
 889                              enum devlink_reload_limit limit, u32 *actions_performed,
 890                              struct netlink_ext_ack *extack)
 891{
 892        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 893        struct nsim_bus_dev *nsim_bus_dev;
 894        int ret;
 895
 896        nsim_bus_dev = nsim_dev->nsim_bus_dev;
 897        mutex_lock(&nsim_bus_dev->nsim_bus_reload_lock);
 898        nsim_bus_dev->in_reload = false;
 899
 900        if (nsim_dev->fail_reload) {
 901                /* For testing purposes, user set debugfs fail_reload
 902                 * value to true. Fail right away.
 903                 */
 904                NL_SET_ERR_MSG_MOD(extack, "User setup the reload to fail for testing purposes");
 905                mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
 906                return -EINVAL;
 907        }
 908
 909        *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
 910        ret = nsim_dev_reload_create(nsim_dev, extack);
 911        mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
 912        return ret;
 913}
 914
 915static int nsim_dev_info_get(struct devlink *devlink,
 916                             struct devlink_info_req *req,
 917                             struct netlink_ext_ack *extack)
 918{
 919        return devlink_info_driver_name_put(req, DRV_NAME);
 920}
 921
 922#define NSIM_DEV_FLASH_SIZE 500000
 923#define NSIM_DEV_FLASH_CHUNK_SIZE 1000
 924#define NSIM_DEV_FLASH_CHUNK_TIME_MS 10
 925
 926static int nsim_dev_flash_update(struct devlink *devlink,
 927                                 struct devlink_flash_update_params *params,
 928                                 struct netlink_ext_ack *extack)
 929{
 930        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 931        int i;
 932
 933        if ((params->overwrite_mask & ~nsim_dev->fw_update_overwrite_mask) != 0)
 934                return -EOPNOTSUPP;
 935
 936        if (nsim_dev->fw_update_status) {
 937                devlink_flash_update_status_notify(devlink,
 938                                                   "Preparing to flash",
 939                                                   params->component, 0, 0);
 940        }
 941
 942        for (i = 0; i < NSIM_DEV_FLASH_SIZE / NSIM_DEV_FLASH_CHUNK_SIZE; i++) {
 943                if (nsim_dev->fw_update_status)
 944                        devlink_flash_update_status_notify(devlink, "Flashing",
 945                                                           params->component,
 946                                                           i * NSIM_DEV_FLASH_CHUNK_SIZE,
 947                                                           NSIM_DEV_FLASH_SIZE);
 948                msleep(NSIM_DEV_FLASH_CHUNK_TIME_MS);
 949        }
 950
 951        if (nsim_dev->fw_update_status) {
 952                devlink_flash_update_status_notify(devlink, "Flashing",
 953                                                   params->component,
 954                                                   NSIM_DEV_FLASH_SIZE,
 955                                                   NSIM_DEV_FLASH_SIZE);
 956                devlink_flash_update_timeout_notify(devlink, "Flash select",
 957                                                    params->component, 81);
 958                devlink_flash_update_status_notify(devlink, "Flashing done",
 959                                                   params->component, 0, 0);
 960        }
 961
 962        return 0;
 963}
 964
 965static struct nsim_trap_item *
 966nsim_dev_trap_item_lookup(struct nsim_dev *nsim_dev, u16 trap_id)
 967{
 968        struct nsim_trap_data *nsim_trap_data = nsim_dev->trap_data;
 969        int i;
 970
 971        for (i = 0; i < ARRAY_SIZE(nsim_traps_arr); i++) {
 972                if (nsim_traps_arr[i].id == trap_id)
 973                        return &nsim_trap_data->trap_items_arr[i];
 974        }
 975
 976        return NULL;
 977}
 978
 979static int nsim_dev_devlink_trap_init(struct devlink *devlink,
 980                                      const struct devlink_trap *trap,
 981                                      void *trap_ctx)
 982{
 983        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 984        struct nsim_trap_item *nsim_trap_item;
 985
 986        nsim_trap_item = nsim_dev_trap_item_lookup(nsim_dev, trap->id);
 987        if (WARN_ON(!nsim_trap_item))
 988                return -ENOENT;
 989
 990        nsim_trap_item->trap_ctx = trap_ctx;
 991        nsim_trap_item->action = trap->init_action;
 992
 993        return 0;
 994}
 995
 996static int
 997nsim_dev_devlink_trap_action_set(struct devlink *devlink,
 998                                 const struct devlink_trap *trap,
 999                                 enum devlink_trap_action action,
1000                                 struct netlink_ext_ack *extack)
1001{
1002        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1003        struct nsim_trap_item *nsim_trap_item;
1004
1005        nsim_trap_item = nsim_dev_trap_item_lookup(nsim_dev, trap->id);
1006        if (WARN_ON(!nsim_trap_item))
1007                return -ENOENT;
1008
1009        spin_lock(&nsim_dev->trap_data->trap_lock);
1010        nsim_trap_item->action = action;
1011        spin_unlock(&nsim_dev->trap_data->trap_lock);
1012
1013        return 0;
1014}
1015
1016static int
1017nsim_dev_devlink_trap_group_set(struct devlink *devlink,
1018                                const struct devlink_trap_group *group,
1019                                const struct devlink_trap_policer *policer,
1020                                struct netlink_ext_ack *extack)
1021{
1022        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1023
1024        if (nsim_dev->fail_trap_group_set)
1025                return -EINVAL;
1026
1027        return 0;
1028}
1029
1030static int
1031nsim_dev_devlink_trap_policer_set(struct devlink *devlink,
1032                                  const struct devlink_trap_policer *policer,
1033                                  u64 rate, u64 burst,
1034                                  struct netlink_ext_ack *extack)
1035{
1036        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1037
1038        if (nsim_dev->fail_trap_policer_set) {
1039                NL_SET_ERR_MSG_MOD(extack, "User setup the operation to fail for testing purposes");
1040                return -EINVAL;
1041        }
1042
1043        return 0;
1044}
1045
1046static int
1047nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink,
1048                                          const struct devlink_trap_policer *policer,
1049                                          u64 *p_drops)
1050{
1051        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1052        u64 *cnt;
1053
1054        if (nsim_dev->fail_trap_policer_counter_get)
1055                return -EINVAL;
1056
1057        cnt = &nsim_dev->trap_data->trap_policers_cnt_arr[policer->id - 1];
1058        *p_drops = (*cnt)++;
1059
1060        return 0;
1061}
1062
1063#define NSIM_LINK_SPEED_MAX     5000 /* Mbps */
1064#define NSIM_LINK_SPEED_UNIT    125000 /* 1 Mbps given in bytes/sec to avoid
1065                                        * u64 overflow during conversion from
1066                                        * bytes to bits.
1067                                        */
1068
1069static int nsim_rate_bytes_to_units(char *name, u64 *rate, struct netlink_ext_ack *extack)
1070{
1071        u64 val;
1072        u32 rem;
1073
1074        val = div_u64_rem(*rate, NSIM_LINK_SPEED_UNIT, &rem);
1075        if (rem) {
1076                pr_err("%s rate value %lluBps not in link speed units of 1Mbps.\n",
1077                       name, *rate);
1078                NL_SET_ERR_MSG_MOD(extack, "TX rate value not in link speed units of 1Mbps.");
1079                return -EINVAL;
1080        }
1081
1082        if (val > NSIM_LINK_SPEED_MAX) {
1083                pr_err("%s rate value %lluMbps exceed link maximum speed 5000Mbps.\n",
1084                       name, val);
1085                NL_SET_ERR_MSG_MOD(extack, "TX rate value exceed link maximum speed 5000Mbps.");
1086                return -EINVAL;
1087        }
1088        *rate = val;
1089        return 0;
1090}
1091
1092static int nsim_leaf_tx_share_set(struct devlink_rate *devlink_rate, void *priv,
1093                                  u64 tx_share, struct netlink_ext_ack *extack)
1094{
1095        struct nsim_dev_port *nsim_dev_port = priv;
1096        struct nsim_bus_dev *nsim_bus_dev = nsim_dev_port->ns->nsim_bus_dev;
1097        int vf_id = nsim_dev_port_index_to_vf_index(nsim_dev_port->port_index);
1098        int err;
1099
1100        err = nsim_rate_bytes_to_units("tx_share", &tx_share, extack);
1101        if (err)
1102                return err;
1103
1104        nsim_bus_dev->vfconfigs[vf_id].min_tx_rate = tx_share;
1105        return 0;
1106}
1107
1108static int nsim_leaf_tx_max_set(struct devlink_rate *devlink_rate, void *priv,
1109                                u64 tx_max, struct netlink_ext_ack *extack)
1110{
1111        struct nsim_dev_port *nsim_dev_port = priv;
1112        struct nsim_bus_dev *nsim_bus_dev = nsim_dev_port->ns->nsim_bus_dev;
1113        int vf_id = nsim_dev_port_index_to_vf_index(nsim_dev_port->port_index);
1114        int err;
1115
1116        err = nsim_rate_bytes_to_units("tx_max", &tx_max, extack);
1117        if (err)
1118                return err;
1119
1120        nsim_bus_dev->vfconfigs[vf_id].max_tx_rate = tx_max;
1121        return 0;
1122}
1123
1124struct nsim_rate_node {
1125        struct dentry *ddir;
1126        struct dentry *rate_parent;
1127        char *parent_name;
1128        u16 tx_share;
1129        u16 tx_max;
1130};
1131
1132static int nsim_node_tx_share_set(struct devlink_rate *devlink_rate, void *priv,
1133                                  u64 tx_share, struct netlink_ext_ack *extack)
1134{
1135        struct nsim_rate_node *nsim_node = priv;
1136        int err;
1137
1138        err = nsim_rate_bytes_to_units("tx_share", &tx_share, extack);
1139        if (err)
1140                return err;
1141
1142        nsim_node->tx_share = tx_share;
1143        return 0;
1144}
1145
1146static int nsim_node_tx_max_set(struct devlink_rate *devlink_rate, void *priv,
1147                                u64 tx_max, struct netlink_ext_ack *extack)
1148{
1149        struct nsim_rate_node *nsim_node = priv;
1150        int err;
1151
1152        err = nsim_rate_bytes_to_units("tx_max", &tx_max, extack);
1153        if (err)
1154                return err;
1155
1156        nsim_node->tx_max = tx_max;
1157        return 0;
1158}
1159
1160static int nsim_rate_node_new(struct devlink_rate *node, void **priv,
1161                              struct netlink_ext_ack *extack)
1162{
1163        struct nsim_dev *nsim_dev = devlink_priv(node->devlink);
1164        struct nsim_rate_node *nsim_node;
1165
1166        if (!nsim_esw_mode_is_switchdev(nsim_dev)) {
1167                NL_SET_ERR_MSG_MOD(extack, "Node creation allowed only in switchdev mode.");
1168                return -EOPNOTSUPP;
1169        }
1170
1171        nsim_node = kzalloc(sizeof(*nsim_node), GFP_KERNEL);
1172        if (!nsim_node)
1173                return -ENOMEM;
1174
1175        nsim_node->ddir = debugfs_create_dir(node->name, nsim_dev->nodes_ddir);
1176
1177        debugfs_create_u16("tx_share", 0400, nsim_node->ddir, &nsim_node->tx_share);
1178        debugfs_create_u16("tx_max", 0400, nsim_node->ddir, &nsim_node->tx_max);
1179        nsim_node->rate_parent = debugfs_create_file("rate_parent", 0400,
1180                                                     nsim_node->ddir,
1181                                                     &nsim_node->parent_name,
1182                                                     &nsim_dev_rate_parent_fops);
1183
1184        *priv = nsim_node;
1185        return 0;
1186}
1187
1188static int nsim_rate_node_del(struct devlink_rate *node, void *priv,
1189                              struct netlink_ext_ack *extack)
1190{
1191        struct nsim_rate_node *nsim_node = priv;
1192
1193        debugfs_remove(nsim_node->rate_parent);
1194        debugfs_remove_recursive(nsim_node->ddir);
1195        kfree(nsim_node);
1196        return 0;
1197}
1198
1199static int nsim_rate_leaf_parent_set(struct devlink_rate *child,
1200                                     struct devlink_rate *parent,
1201                                     void *priv_child, void *priv_parent,
1202                                     struct netlink_ext_ack *extack)
1203{
1204        struct nsim_dev_port *nsim_dev_port = priv_child;
1205
1206        if (parent)
1207                nsim_dev_port->parent_name = parent->name;
1208        else
1209                nsim_dev_port->parent_name = NULL;
1210        return 0;
1211}
1212
1213static int nsim_rate_node_parent_set(struct devlink_rate *child,
1214                                     struct devlink_rate *parent,
1215                                     void *priv_child, void *priv_parent,
1216                                     struct netlink_ext_ack *extack)
1217{
1218        struct nsim_rate_node *nsim_node = priv_child;
1219
1220        if (parent)
1221                nsim_node->parent_name = parent->name;
1222        else
1223                nsim_node->parent_name = NULL;
1224        return 0;
1225}
1226
1227static int
1228nsim_dev_devlink_trap_drop_counter_get(struct devlink *devlink,
1229                                       const struct devlink_trap *trap,
1230                                       u64 *p_drops)
1231{
1232        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1233        u64 *cnt;
1234
1235        if (nsim_dev->fail_trap_drop_counter_get)
1236                return -EINVAL;
1237
1238        cnt = &nsim_dev->trap_data->trap_pkt_cnt;
1239        *p_drops = (*cnt)++;
1240
1241        return 0;
1242}
1243
1244static const struct devlink_ops nsim_dev_devlink_ops = {
1245        .eswitch_mode_set = nsim_devlink_eswitch_mode_set,
1246        .eswitch_mode_get = nsim_devlink_eswitch_mode_get,
1247        .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
1248                                         DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
1249        .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
1250        .reload_down = nsim_dev_reload_down,
1251        .reload_up = nsim_dev_reload_up,
1252        .info_get = nsim_dev_info_get,
1253        .flash_update = nsim_dev_flash_update,
1254        .trap_init = nsim_dev_devlink_trap_init,
1255        .trap_action_set = nsim_dev_devlink_trap_action_set,
1256        .trap_group_set = nsim_dev_devlink_trap_group_set,
1257        .trap_policer_set = nsim_dev_devlink_trap_policer_set,
1258        .trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
1259        .rate_leaf_tx_share_set = nsim_leaf_tx_share_set,
1260        .rate_leaf_tx_max_set = nsim_leaf_tx_max_set,
1261        .rate_node_tx_share_set = nsim_node_tx_share_set,
1262        .rate_node_tx_max_set = nsim_node_tx_max_set,
1263        .rate_node_new = nsim_rate_node_new,
1264        .rate_node_del = nsim_rate_node_del,
1265        .rate_leaf_parent_set = nsim_rate_leaf_parent_set,
1266        .rate_node_parent_set = nsim_rate_node_parent_set,
1267        .trap_drop_counter_get = nsim_dev_devlink_trap_drop_counter_get,
1268};
1269
1270#define NSIM_DEV_MAX_MACS_DEFAULT 32
1271#define NSIM_DEV_TEST1_DEFAULT true
1272
1273static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type,
1274                               unsigned int port_index)
1275{
1276        struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
1277        struct devlink_port_attrs attrs = {};
1278        struct nsim_dev_port *nsim_dev_port;
1279        struct devlink_port *devlink_port;
1280        int err;
1281
1282        if (type == NSIM_DEV_PORT_TYPE_VF && !nsim_bus_dev->num_vfs)
1283                return -EINVAL;
1284
1285        nsim_dev_port = kzalloc(sizeof(*nsim_dev_port), GFP_KERNEL);
1286        if (!nsim_dev_port)
1287                return -ENOMEM;
1288        nsim_dev_port->port_index = nsim_dev_port_index(type, port_index);
1289        nsim_dev_port->port_type = type;
1290
1291        devlink_port = &nsim_dev_port->devlink_port;
1292        if (nsim_dev_port_is_pf(nsim_dev_port)) {
1293                attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
1294                attrs.phys.port_number = port_index + 1;
1295        } else {
1296                attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF;
1297                attrs.pci_vf.pf = 0;
1298                attrs.pci_vf.vf = port_index;
1299        }
1300        memcpy(attrs.switch_id.id, nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
1301        attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
1302        devlink_port_attrs_set(devlink_port, &attrs);
1303        err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port,
1304                                    nsim_dev_port->port_index);
1305        if (err)
1306                goto err_port_free;
1307
1308        err = nsim_dev_port_debugfs_init(nsim_dev, nsim_dev_port);
1309        if (err)
1310                goto err_dl_port_unregister;
1311
1312        nsim_dev_port->ns = nsim_create(nsim_dev, nsim_dev_port);
1313        if (IS_ERR(nsim_dev_port->ns)) {
1314                err = PTR_ERR(nsim_dev_port->ns);
1315                goto err_port_debugfs_exit;
1316        }
1317
1318        if (nsim_dev_port_is_vf(nsim_dev_port)) {
1319                err = devlink_rate_leaf_create(&nsim_dev_port->devlink_port,
1320                                               nsim_dev_port);
1321                if (err)
1322                        goto err_nsim_destroy;
1323        }
1324
1325        devlink_port_type_eth_set(devlink_port, nsim_dev_port->ns->netdev);
1326        list_add(&nsim_dev_port->list, &nsim_dev->port_list);
1327
1328        return 0;
1329
1330err_nsim_destroy:
1331        nsim_destroy(nsim_dev_port->ns);
1332err_port_debugfs_exit:
1333        nsim_dev_port_debugfs_exit(nsim_dev_port);
1334err_dl_port_unregister:
1335        devlink_port_unregister(devlink_port);
1336err_port_free:
1337        kfree(nsim_dev_port);
1338        return err;
1339}
1340
1341static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
1342{
1343        struct devlink_port *devlink_port = &nsim_dev_port->devlink_port;
1344
1345        list_del(&nsim_dev_port->list);
1346        if (nsim_dev_port_is_vf(nsim_dev_port))
1347                devlink_rate_leaf_destroy(&nsim_dev_port->devlink_port);
1348        devlink_port_type_clear(devlink_port);
1349        nsim_destroy(nsim_dev_port->ns);
1350        nsim_dev_port_debugfs_exit(nsim_dev_port);
1351        devlink_port_unregister(devlink_port);
1352        kfree(nsim_dev_port);
1353}
1354
1355static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev)
1356{
1357        struct nsim_dev_port *nsim_dev_port, *tmp;
1358
1359        mutex_lock(&nsim_dev->port_list_lock);
1360        list_for_each_entry_safe(nsim_dev_port, tmp,
1361                                 &nsim_dev->port_list, list)
1362                __nsim_dev_port_del(nsim_dev_port);
1363        mutex_unlock(&nsim_dev->port_list_lock);
1364}
1365
1366static int nsim_dev_port_add_all(struct nsim_dev *nsim_dev,
1367                                 unsigned int port_count)
1368{
1369        int i, err;
1370
1371        for (i = 0; i < port_count; i++) {
1372                err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_PF, i);
1373                if (err)
1374                        goto err_port_del_all;
1375        }
1376        return 0;
1377
1378err_port_del_all:
1379        nsim_dev_port_del_all(nsim_dev);
1380        return err;
1381}
1382
1383static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
1384                                  struct netlink_ext_ack *extack)
1385{
1386        struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
1387        struct devlink *devlink;
1388        int err;
1389
1390        devlink = priv_to_devlink(nsim_dev);
1391        nsim_dev = devlink_priv(devlink);
1392        INIT_LIST_HEAD(&nsim_dev->port_list);
1393        mutex_init(&nsim_dev->port_list_lock);
1394        nsim_dev->fw_update_status = true;
1395        nsim_dev->fw_update_overwrite_mask = 0;
1396
1397        nsim_devlink_param_load_driverinit_values(devlink);
1398
1399        err = nsim_dev_dummy_region_init(nsim_dev, devlink);
1400        if (err)
1401                return err;
1402
1403        err = nsim_dev_traps_init(devlink);
1404        if (err)
1405                goto err_dummy_region_exit;
1406
1407        nsim_dev->fib_data = nsim_fib_create(devlink, extack);
1408        if (IS_ERR(nsim_dev->fib_data)) {
1409                err = PTR_ERR(nsim_dev->fib_data);
1410                goto err_traps_exit;
1411        }
1412
1413        err = nsim_dev_health_init(nsim_dev, devlink);
1414        if (err)
1415                goto err_fib_destroy;
1416
1417        err = nsim_dev_psample_init(nsim_dev);
1418        if (err)
1419                goto err_health_exit;
1420
1421        err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count);
1422        if (err)
1423                goto err_psample_exit;
1424
1425        nsim_dev->take_snapshot = debugfs_create_file("take_snapshot",
1426                                                      0200,
1427                                                      nsim_dev->ddir,
1428                                                      nsim_dev,
1429                                                &nsim_dev_take_snapshot_fops);
1430        return 0;
1431
1432err_psample_exit:
1433        nsim_dev_psample_exit(nsim_dev);
1434err_health_exit:
1435        nsim_dev_health_exit(nsim_dev);
1436err_fib_destroy:
1437        nsim_fib_destroy(devlink, nsim_dev->fib_data);
1438err_traps_exit:
1439        nsim_dev_traps_exit(devlink);
1440err_dummy_region_exit:
1441        nsim_dev_dummy_region_exit(nsim_dev);
1442        return err;
1443}
1444
1445int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
1446{
1447        struct nsim_dev *nsim_dev;
1448        struct devlink *devlink;
1449        int err;
1450
1451        devlink = devlink_alloc_ns(&nsim_dev_devlink_ops, sizeof(*nsim_dev),
1452                                 nsim_bus_dev->initial_net, &nsim_bus_dev->dev);
1453        if (!devlink)
1454                return -ENOMEM;
1455        nsim_dev = devlink_priv(devlink);
1456        nsim_dev->nsim_bus_dev = nsim_bus_dev;
1457        nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id);
1458        get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
1459        INIT_LIST_HEAD(&nsim_dev->port_list);
1460        mutex_init(&nsim_dev->port_list_lock);
1461        nsim_dev->fw_update_status = true;
1462        nsim_dev->fw_update_overwrite_mask = 0;
1463        nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
1464        nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
1465        spin_lock_init(&nsim_dev->fa_cookie_lock);
1466
1467        dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
1468
1469        err = nsim_dev_resources_register(devlink);
1470        if (err)
1471                goto err_devlink_free;
1472
1473        err = devlink_register(devlink);
1474        if (err)
1475                goto err_resources_unregister;
1476
1477        err = devlink_params_register(devlink, nsim_devlink_params,
1478                                      ARRAY_SIZE(nsim_devlink_params));
1479        if (err)
1480                goto err_dl_unregister;
1481        nsim_devlink_set_params_init_values(nsim_dev, devlink);
1482
1483        err = nsim_dev_dummy_region_init(nsim_dev, devlink);
1484        if (err)
1485                goto err_params_unregister;
1486
1487        err = nsim_dev_traps_init(devlink);
1488        if (err)
1489                goto err_dummy_region_exit;
1490
1491        err = nsim_dev_debugfs_init(nsim_dev);
1492        if (err)
1493                goto err_traps_exit;
1494
1495        nsim_dev->fib_data = nsim_fib_create(devlink, NULL);
1496        if (IS_ERR(nsim_dev->fib_data)) {
1497                err = PTR_ERR(nsim_dev->fib_data);
1498                goto err_debugfs_exit;
1499        }
1500
1501        err = nsim_dev_health_init(nsim_dev, devlink);
1502        if (err)
1503                goto err_fib_destroy;
1504
1505        err = nsim_bpf_dev_init(nsim_dev);
1506        if (err)
1507                goto err_health_exit;
1508
1509        err = nsim_dev_psample_init(nsim_dev);
1510        if (err)
1511                goto err_bpf_dev_exit;
1512
1513        err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count);
1514        if (err)
1515                goto err_psample_exit;
1516
1517        devlink_params_publish(devlink);
1518        devlink_reload_enable(devlink);
1519        nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY;
1520        return 0;
1521
1522err_psample_exit:
1523        nsim_dev_psample_exit(nsim_dev);
1524err_bpf_dev_exit:
1525        nsim_bpf_dev_exit(nsim_dev);
1526err_health_exit:
1527        nsim_dev_health_exit(nsim_dev);
1528err_fib_destroy:
1529        nsim_fib_destroy(devlink, nsim_dev->fib_data);
1530err_debugfs_exit:
1531        nsim_dev_debugfs_exit(nsim_dev);
1532err_traps_exit:
1533        nsim_dev_traps_exit(devlink);
1534err_dummy_region_exit:
1535        nsim_dev_dummy_region_exit(nsim_dev);
1536err_params_unregister:
1537        devlink_params_unregister(devlink, nsim_devlink_params,
1538                                  ARRAY_SIZE(nsim_devlink_params));
1539err_dl_unregister:
1540        devlink_unregister(devlink);
1541err_resources_unregister:
1542        devlink_resources_unregister(devlink, NULL);
1543err_devlink_free:
1544        devlink_free(devlink);
1545        return err;
1546}
1547
1548static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev)
1549{
1550        struct devlink *devlink = priv_to_devlink(nsim_dev);
1551
1552        if (devlink_is_reload_failed(devlink))
1553                return;
1554        debugfs_remove(nsim_dev->take_snapshot);
1555
1556        mutex_lock(&nsim_dev->nsim_bus_dev->vfs_lock);
1557        if (nsim_dev->nsim_bus_dev->num_vfs)
1558                nsim_bus_dev_vfs_disable(nsim_dev->nsim_bus_dev);
1559        mutex_unlock(&nsim_dev->nsim_bus_dev->vfs_lock);
1560
1561        nsim_dev_port_del_all(nsim_dev);
1562        nsim_dev_psample_exit(nsim_dev);
1563        nsim_dev_health_exit(nsim_dev);
1564        nsim_fib_destroy(devlink, nsim_dev->fib_data);
1565        nsim_dev_traps_exit(devlink);
1566        nsim_dev_dummy_region_exit(nsim_dev);
1567        mutex_destroy(&nsim_dev->port_list_lock);
1568}
1569
1570void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
1571{
1572        struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1573        struct devlink *devlink = priv_to_devlink(nsim_dev);
1574
1575        devlink_reload_disable(devlink);
1576
1577        nsim_dev_reload_destroy(nsim_dev);
1578
1579        nsim_bpf_dev_exit(nsim_dev);
1580        nsim_dev_debugfs_exit(nsim_dev);
1581        devlink_params_unregister(devlink, nsim_devlink_params,
1582                                  ARRAY_SIZE(nsim_devlink_params));
1583        devlink_unregister(devlink);
1584        devlink_resources_unregister(devlink, NULL);
1585        devlink_free(devlink);
1586}
1587
1588static struct nsim_dev_port *
1589__nsim_dev_port_lookup(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type,
1590                       unsigned int port_index)
1591{
1592        struct nsim_dev_port *nsim_dev_port;
1593
1594        port_index = nsim_dev_port_index(type, port_index);
1595        list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list)
1596                if (nsim_dev_port->port_index == port_index)
1597                        return nsim_dev_port;
1598        return NULL;
1599}
1600
1601int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type,
1602                      unsigned int port_index)
1603{
1604        struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1605        int err;
1606
1607        mutex_lock(&nsim_dev->port_list_lock);
1608        if (__nsim_dev_port_lookup(nsim_dev, type, port_index))
1609                err = -EEXIST;
1610        else
1611                err = __nsim_dev_port_add(nsim_dev, type, port_index);
1612        mutex_unlock(&nsim_dev->port_list_lock);
1613        return err;
1614}
1615
1616int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type,
1617                      unsigned int port_index)
1618{
1619        struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1620        struct nsim_dev_port *nsim_dev_port;
1621        int err = 0;
1622
1623        mutex_lock(&nsim_dev->port_list_lock);
1624        nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, type, port_index);
1625        if (!nsim_dev_port)
1626                err = -ENOENT;
1627        else
1628                __nsim_dev_port_del(nsim_dev_port);
1629        mutex_unlock(&nsim_dev->port_list_lock);
1630        return err;
1631}
1632
1633int nsim_dev_init(void)
1634{
1635        nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL);
1636        return PTR_ERR_OR_ZERO(nsim_dev_ddir);
1637}
1638
1639void nsim_dev_exit(void)
1640{
1641        debugfs_remove_recursive(nsim_dev_ddir);
1642}
1643