linux/drivers/net/netdevsim/netdev.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2017 Netronome Systems, Inc.
   3 *
   4 * This software is licensed under the GNU General License Version 2,
   5 * June 1991 as shown in the file COPYING in the top-level directory of this
   6 * source tree.
   7 *
   8 * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
   9 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
  10 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  11 * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
  12 * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
  13 * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  14 */
  15
  16#include <linux/debugfs.h>
  17#include <linux/etherdevice.h>
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/netdevice.h>
  21#include <linux/slab.h>
  22#include <net/netlink.h>
  23#include <net/pkt_cls.h>
  24#include <net/rtnetlink.h>
  25#include <net/udp_tunnel.h>
  26
  27#include "netdevsim.h"
  28
  29static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
  30{
  31        struct netdevsim *ns = netdev_priv(dev);
  32
  33        if (!nsim_ipsec_tx(ns, skb))
  34                goto out;
  35
  36        u64_stats_update_begin(&ns->syncp);
  37        ns->tx_packets++;
  38        ns->tx_bytes += skb->len;
  39        u64_stats_update_end(&ns->syncp);
  40
  41out:
  42        dev_kfree_skb(skb);
  43
  44        return NETDEV_TX_OK;
  45}
  46
  47static void nsim_set_rx_mode(struct net_device *dev)
  48{
  49}
  50
  51static int nsim_change_mtu(struct net_device *dev, int new_mtu)
  52{
  53        struct netdevsim *ns = netdev_priv(dev);
  54
  55        if (ns->xdp.prog && new_mtu > NSIM_XDP_MAX_MTU)
  56                return -EBUSY;
  57
  58        dev->mtu = new_mtu;
  59
  60        return 0;
  61}
  62
  63static void
  64nsim_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
  65{
  66        struct netdevsim *ns = netdev_priv(dev);
  67        unsigned int start;
  68
  69        do {
  70                start = u64_stats_fetch_begin(&ns->syncp);
  71                stats->tx_bytes = ns->tx_bytes;
  72                stats->tx_packets = ns->tx_packets;
  73        } while (u64_stats_fetch_retry(&ns->syncp, start));
  74}
  75
  76static int
  77nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
  78{
  79        return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv);
  80}
  81
  82static int nsim_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
  83{
  84        struct netdevsim *ns = netdev_priv(dev);
  85        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
  86
  87        /* Only refuse multicast addresses, zero address can mean unset/any. */
  88        if (vf >= nsim_bus_dev->num_vfs || is_multicast_ether_addr(mac))
  89                return -EINVAL;
  90        memcpy(nsim_bus_dev->vfconfigs[vf].vf_mac, mac, ETH_ALEN);
  91
  92        return 0;
  93}
  94
  95static int nsim_set_vf_vlan(struct net_device *dev, int vf,
  96                            u16 vlan, u8 qos, __be16 vlan_proto)
  97{
  98        struct netdevsim *ns = netdev_priv(dev);
  99        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 100
 101        if (vf >= nsim_bus_dev->num_vfs || vlan > 4095 || qos > 7)
 102                return -EINVAL;
 103
 104        nsim_bus_dev->vfconfigs[vf].vlan = vlan;
 105        nsim_bus_dev->vfconfigs[vf].qos = qos;
 106        nsim_bus_dev->vfconfigs[vf].vlan_proto = vlan_proto;
 107
 108        return 0;
 109}
 110
 111static int nsim_set_vf_rate(struct net_device *dev, int vf, int min, int max)
 112{
 113        struct netdevsim *ns = netdev_priv(dev);
 114        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 115
 116        if (nsim_esw_mode_is_switchdev(ns->nsim_dev)) {
 117                pr_err("Not supported in switchdev mode. Please use devlink API.\n");
 118                return -EOPNOTSUPP;
 119        }
 120
 121        if (vf >= nsim_bus_dev->num_vfs)
 122                return -EINVAL;
 123
 124        nsim_bus_dev->vfconfigs[vf].min_tx_rate = min;
 125        nsim_bus_dev->vfconfigs[vf].max_tx_rate = max;
 126
 127        return 0;
 128}
 129
 130static int nsim_set_vf_spoofchk(struct net_device *dev, int vf, bool val)
 131{
 132        struct netdevsim *ns = netdev_priv(dev);
 133        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 134
 135        if (vf >= nsim_bus_dev->num_vfs)
 136                return -EINVAL;
 137        nsim_bus_dev->vfconfigs[vf].spoofchk_enabled = val;
 138
 139        return 0;
 140}
 141
 142static int nsim_set_vf_rss_query_en(struct net_device *dev, int vf, bool val)
 143{
 144        struct netdevsim *ns = netdev_priv(dev);
 145        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 146
 147        if (vf >= nsim_bus_dev->num_vfs)
 148                return -EINVAL;
 149        nsim_bus_dev->vfconfigs[vf].rss_query_enabled = val;
 150
 151        return 0;
 152}
 153
 154static int nsim_set_vf_trust(struct net_device *dev, int vf, bool val)
 155{
 156        struct netdevsim *ns = netdev_priv(dev);
 157        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 158
 159        if (vf >= nsim_bus_dev->num_vfs)
 160                return -EINVAL;
 161        nsim_bus_dev->vfconfigs[vf].trusted = val;
 162
 163        return 0;
 164}
 165
 166static int
 167nsim_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivi)
 168{
 169        struct netdevsim *ns = netdev_priv(dev);
 170        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 171
 172        if (vf >= nsim_bus_dev->num_vfs)
 173                return -EINVAL;
 174
 175        ivi->vf = vf;
 176        ivi->linkstate = nsim_bus_dev->vfconfigs[vf].link_state;
 177        ivi->min_tx_rate = nsim_bus_dev->vfconfigs[vf].min_tx_rate;
 178        ivi->max_tx_rate = nsim_bus_dev->vfconfigs[vf].max_tx_rate;
 179        ivi->vlan = nsim_bus_dev->vfconfigs[vf].vlan;
 180        ivi->vlan_proto = nsim_bus_dev->vfconfigs[vf].vlan_proto;
 181        ivi->qos = nsim_bus_dev->vfconfigs[vf].qos;
 182        memcpy(&ivi->mac, nsim_bus_dev->vfconfigs[vf].vf_mac, ETH_ALEN);
 183        ivi->spoofchk = nsim_bus_dev->vfconfigs[vf].spoofchk_enabled;
 184        ivi->trusted = nsim_bus_dev->vfconfigs[vf].trusted;
 185        ivi->rss_query_en = nsim_bus_dev->vfconfigs[vf].rss_query_enabled;
 186
 187        return 0;
 188}
 189
 190static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state)
 191{
 192        struct netdevsim *ns = netdev_priv(dev);
 193        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 194
 195        if (vf >= nsim_bus_dev->num_vfs)
 196                return -EINVAL;
 197
 198        switch (state) {
 199        case IFLA_VF_LINK_STATE_AUTO:
 200        case IFLA_VF_LINK_STATE_ENABLE:
 201        case IFLA_VF_LINK_STATE_DISABLE:
 202                break;
 203        default:
 204                return -EINVAL;
 205        }
 206
 207        nsim_bus_dev->vfconfigs[vf].link_state = state;
 208
 209        return 0;
 210}
 211
 212static LIST_HEAD(nsim_block_cb_list);
 213
 214static int
 215nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
 216{
 217        struct netdevsim *ns = netdev_priv(dev);
 218
 219        switch (type) {
 220        case TC_SETUP_BLOCK:
 221                return flow_block_cb_setup_simple(type_data,
 222                                                  &nsim_block_cb_list,
 223                                                  nsim_setup_tc_block_cb,
 224                                                  ns, ns, true);
 225        default:
 226                return -EOPNOTSUPP;
 227        }
 228}
 229
 230static int
 231nsim_set_features(struct net_device *dev, netdev_features_t features)
 232{
 233        struct netdevsim *ns = netdev_priv(dev);
 234
 235        if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC))
 236                return nsim_bpf_disable_tc(ns);
 237
 238        return 0;
 239}
 240
 241static struct devlink_port *nsim_get_devlink_port(struct net_device *dev)
 242{
 243        struct netdevsim *ns = netdev_priv(dev);
 244
 245        return &ns->nsim_dev_port->devlink_port;
 246}
 247
 248static const struct net_device_ops nsim_netdev_ops = {
 249        .ndo_start_xmit         = nsim_start_xmit,
 250        .ndo_set_rx_mode        = nsim_set_rx_mode,
 251        .ndo_set_mac_address    = eth_mac_addr,
 252        .ndo_validate_addr      = eth_validate_addr,
 253        .ndo_change_mtu         = nsim_change_mtu,
 254        .ndo_get_stats64        = nsim_get_stats64,
 255        .ndo_set_vf_mac         = nsim_set_vf_mac,
 256        .ndo_set_vf_vlan        = nsim_set_vf_vlan,
 257        .ndo_set_vf_rate        = nsim_set_vf_rate,
 258        .ndo_set_vf_spoofchk    = nsim_set_vf_spoofchk,
 259        .ndo_set_vf_trust       = nsim_set_vf_trust,
 260        .ndo_get_vf_config      = nsim_get_vf_config,
 261        .ndo_set_vf_link_state  = nsim_set_vf_link_state,
 262        .ndo_set_vf_rss_query_en = nsim_set_vf_rss_query_en,
 263        .ndo_setup_tc           = nsim_setup_tc,
 264        .ndo_set_features       = nsim_set_features,
 265        .ndo_bpf                = nsim_bpf,
 266        .ndo_get_devlink_port   = nsim_get_devlink_port,
 267};
 268
 269static const struct net_device_ops nsim_vf_netdev_ops = {
 270        .ndo_start_xmit         = nsim_start_xmit,
 271        .ndo_set_rx_mode        = nsim_set_rx_mode,
 272        .ndo_set_mac_address    = eth_mac_addr,
 273        .ndo_validate_addr      = eth_validate_addr,
 274        .ndo_change_mtu         = nsim_change_mtu,
 275        .ndo_get_stats64        = nsim_get_stats64,
 276        .ndo_setup_tc           = nsim_setup_tc,
 277        .ndo_set_features       = nsim_set_features,
 278        .ndo_get_devlink_port   = nsim_get_devlink_port,
 279};
 280
 281static void nsim_setup(struct net_device *dev)
 282{
 283        ether_setup(dev);
 284        eth_hw_addr_random(dev);
 285
 286        dev->tx_queue_len = 0;
 287        dev->flags |= IFF_NOARP;
 288        dev->flags &= ~IFF_MULTICAST;
 289        dev->priv_flags |= IFF_LIVE_ADDR_CHANGE |
 290                           IFF_NO_QUEUE;
 291        dev->features |= NETIF_F_HIGHDMA |
 292                         NETIF_F_SG |
 293                         NETIF_F_FRAGLIST |
 294                         NETIF_F_HW_CSUM |
 295                         NETIF_F_TSO;
 296        dev->hw_features |= NETIF_F_HW_TC;
 297        dev->max_mtu = ETH_MAX_MTU;
 298}
 299
 300static int nsim_init_netdevsim(struct netdevsim *ns)
 301{
 302        int err;
 303
 304        ns->netdev->netdev_ops = &nsim_netdev_ops;
 305
 306        err = nsim_udp_tunnels_info_create(ns->nsim_dev, ns->netdev);
 307        if (err)
 308                return err;
 309
 310        rtnl_lock();
 311        err = nsim_bpf_init(ns);
 312        if (err)
 313                goto err_utn_destroy;
 314
 315        nsim_ipsec_init(ns);
 316
 317        err = register_netdevice(ns->netdev);
 318        if (err)
 319                goto err_ipsec_teardown;
 320        rtnl_unlock();
 321        return 0;
 322
 323err_ipsec_teardown:
 324        nsim_ipsec_teardown(ns);
 325        nsim_bpf_uninit(ns);
 326err_utn_destroy:
 327        rtnl_unlock();
 328        nsim_udp_tunnels_info_destroy(ns->netdev);
 329        return err;
 330}
 331
 332static int nsim_init_netdevsim_vf(struct netdevsim *ns)
 333{
 334        int err;
 335
 336        ns->netdev->netdev_ops = &nsim_vf_netdev_ops;
 337        rtnl_lock();
 338        err = register_netdevice(ns->netdev);
 339        rtnl_unlock();
 340        return err;
 341}
 342
 343struct netdevsim *
 344nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
 345{
 346        struct net_device *dev;
 347        struct netdevsim *ns;
 348        int err;
 349
 350        dev = alloc_netdev_mq(sizeof(*ns), "eth%d", NET_NAME_UNKNOWN, nsim_setup,
 351                              nsim_dev->nsim_bus_dev->num_queues);
 352        if (!dev)
 353                return ERR_PTR(-ENOMEM);
 354
 355        dev_net_set(dev, nsim_dev_net(nsim_dev));
 356        ns = netdev_priv(dev);
 357        ns->netdev = dev;
 358        u64_stats_init(&ns->syncp);
 359        ns->nsim_dev = nsim_dev;
 360        ns->nsim_dev_port = nsim_dev_port;
 361        ns->nsim_bus_dev = nsim_dev->nsim_bus_dev;
 362        SET_NETDEV_DEV(dev, &ns->nsim_bus_dev->dev);
 363        nsim_ethtool_init(ns);
 364        if (nsim_dev_port_is_pf(nsim_dev_port))
 365                err = nsim_init_netdevsim(ns);
 366        else
 367                err = nsim_init_netdevsim_vf(ns);
 368        if (err)
 369                goto err_free_netdev;
 370        return ns;
 371
 372err_free_netdev:
 373        free_netdev(dev);
 374        return ERR_PTR(err);
 375}
 376
 377void nsim_destroy(struct netdevsim *ns)
 378{
 379        struct net_device *dev = ns->netdev;
 380
 381        rtnl_lock();
 382        unregister_netdevice(dev);
 383        if (nsim_dev_port_is_pf(ns->nsim_dev_port)) {
 384                nsim_ipsec_teardown(ns);
 385                nsim_bpf_uninit(ns);
 386        }
 387        rtnl_unlock();
 388        if (nsim_dev_port_is_pf(ns->nsim_dev_port))
 389                nsim_udp_tunnels_info_destroy(dev);
 390        free_netdev(dev);
 391}
 392
 393static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
 394                         struct netlink_ext_ack *extack)
 395{
 396        NL_SET_ERR_MSG_MOD(extack,
 397                           "Please use: echo \"[ID] [PORT_COUNT] [NUM_QUEUES]\" > /sys/bus/netdevsim/new_device");
 398        return -EOPNOTSUPP;
 399}
 400
 401static struct rtnl_link_ops nsim_link_ops __read_mostly = {
 402        .kind           = DRV_NAME,
 403        .validate       = nsim_validate,
 404};
 405
 406static int __init nsim_module_init(void)
 407{
 408        int err;
 409
 410        err = nsim_dev_init();
 411        if (err)
 412                return err;
 413
 414        err = nsim_bus_init();
 415        if (err)
 416                goto err_dev_exit;
 417
 418        err = rtnl_link_register(&nsim_link_ops);
 419        if (err)
 420                goto err_bus_exit;
 421
 422        return 0;
 423
 424err_bus_exit:
 425        nsim_bus_exit();
 426err_dev_exit:
 427        nsim_dev_exit();
 428        return err;
 429}
 430
 431static void __exit nsim_module_exit(void)
 432{
 433        rtnl_link_unregister(&nsim_link_ops);
 434        nsim_bus_exit();
 435        nsim_dev_exit();
 436}
 437
 438module_init(nsim_module_init);
 439module_exit(nsim_module_exit);
 440MODULE_LICENSE("GPL");
 441MODULE_ALIAS_RTNL_LINK(DRV_NAME);
 442