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 (vf >= nsim_bus_dev->num_vfs)
 117                return -EINVAL;
 118
 119        nsim_bus_dev->vfconfigs[vf].min_tx_rate = min;
 120        nsim_bus_dev->vfconfigs[vf].max_tx_rate = max;
 121
 122        return 0;
 123}
 124
 125static int nsim_set_vf_spoofchk(struct net_device *dev, int vf, bool val)
 126{
 127        struct netdevsim *ns = netdev_priv(dev);
 128        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 129
 130        if (vf >= nsim_bus_dev->num_vfs)
 131                return -EINVAL;
 132        nsim_bus_dev->vfconfigs[vf].spoofchk_enabled = val;
 133
 134        return 0;
 135}
 136
 137static int nsim_set_vf_rss_query_en(struct net_device *dev, int vf, bool val)
 138{
 139        struct netdevsim *ns = netdev_priv(dev);
 140        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 141
 142        if (vf >= nsim_bus_dev->num_vfs)
 143                return -EINVAL;
 144        nsim_bus_dev->vfconfigs[vf].rss_query_enabled = val;
 145
 146        return 0;
 147}
 148
 149static int nsim_set_vf_trust(struct net_device *dev, int vf, bool val)
 150{
 151        struct netdevsim *ns = netdev_priv(dev);
 152        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 153
 154        if (vf >= nsim_bus_dev->num_vfs)
 155                return -EINVAL;
 156        nsim_bus_dev->vfconfigs[vf].trusted = val;
 157
 158        return 0;
 159}
 160
 161static int
 162nsim_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivi)
 163{
 164        struct netdevsim *ns = netdev_priv(dev);
 165        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 166
 167        if (vf >= nsim_bus_dev->num_vfs)
 168                return -EINVAL;
 169
 170        ivi->vf = vf;
 171        ivi->linkstate = nsim_bus_dev->vfconfigs[vf].link_state;
 172        ivi->min_tx_rate = nsim_bus_dev->vfconfigs[vf].min_tx_rate;
 173        ivi->max_tx_rate = nsim_bus_dev->vfconfigs[vf].max_tx_rate;
 174        ivi->vlan = nsim_bus_dev->vfconfigs[vf].vlan;
 175        ivi->vlan_proto = nsim_bus_dev->vfconfigs[vf].vlan_proto;
 176        ivi->qos = nsim_bus_dev->vfconfigs[vf].qos;
 177        memcpy(&ivi->mac, nsim_bus_dev->vfconfigs[vf].vf_mac, ETH_ALEN);
 178        ivi->spoofchk = nsim_bus_dev->vfconfigs[vf].spoofchk_enabled;
 179        ivi->trusted = nsim_bus_dev->vfconfigs[vf].trusted;
 180        ivi->rss_query_en = nsim_bus_dev->vfconfigs[vf].rss_query_enabled;
 181
 182        return 0;
 183}
 184
 185static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state)
 186{
 187        struct netdevsim *ns = netdev_priv(dev);
 188        struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
 189
 190        if (vf >= nsim_bus_dev->num_vfs)
 191                return -EINVAL;
 192
 193        switch (state) {
 194        case IFLA_VF_LINK_STATE_AUTO:
 195        case IFLA_VF_LINK_STATE_ENABLE:
 196        case IFLA_VF_LINK_STATE_DISABLE:
 197                break;
 198        default:
 199                return -EINVAL;
 200        }
 201
 202        nsim_bus_dev->vfconfigs[vf].link_state = state;
 203
 204        return 0;
 205}
 206
 207static LIST_HEAD(nsim_block_cb_list);
 208
 209static int
 210nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
 211{
 212        struct netdevsim *ns = netdev_priv(dev);
 213
 214        switch (type) {
 215        case TC_SETUP_BLOCK:
 216                return flow_block_cb_setup_simple(type_data,
 217                                                  &nsim_block_cb_list,
 218                                                  nsim_setup_tc_block_cb,
 219                                                  ns, ns, true);
 220        default:
 221                return -EOPNOTSUPP;
 222        }
 223}
 224
 225static int
 226nsim_set_features(struct net_device *dev, netdev_features_t features)
 227{
 228        struct netdevsim *ns = netdev_priv(dev);
 229
 230        if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC))
 231                return nsim_bpf_disable_tc(ns);
 232
 233        return 0;
 234}
 235
 236static struct devlink_port *nsim_get_devlink_port(struct net_device *dev)
 237{
 238        struct netdevsim *ns = netdev_priv(dev);
 239
 240        return &ns->nsim_dev_port->devlink_port;
 241}
 242
 243static const struct net_device_ops nsim_netdev_ops = {
 244        .ndo_start_xmit         = nsim_start_xmit,
 245        .ndo_set_rx_mode        = nsim_set_rx_mode,
 246        .ndo_set_mac_address    = eth_mac_addr,
 247        .ndo_validate_addr      = eth_validate_addr,
 248        .ndo_change_mtu         = nsim_change_mtu,
 249        .ndo_get_stats64        = nsim_get_stats64,
 250        .ndo_set_vf_mac         = nsim_set_vf_mac,
 251        .ndo_set_vf_vlan        = nsim_set_vf_vlan,
 252        .ndo_set_vf_rate        = nsim_set_vf_rate,
 253        .ndo_set_vf_spoofchk    = nsim_set_vf_spoofchk,
 254        .ndo_set_vf_trust       = nsim_set_vf_trust,
 255        .ndo_get_vf_config      = nsim_get_vf_config,
 256        .ndo_set_vf_link_state  = nsim_set_vf_link_state,
 257        .ndo_set_vf_rss_query_en = nsim_set_vf_rss_query_en,
 258        .ndo_setup_tc           = nsim_setup_tc,
 259        .ndo_set_features       = nsim_set_features,
 260        .ndo_bpf                = nsim_bpf,
 261        .ndo_udp_tunnel_add     = udp_tunnel_nic_add_port,
 262        .ndo_udp_tunnel_del     = udp_tunnel_nic_del_port,
 263        .ndo_get_devlink_port   = nsim_get_devlink_port,
 264};
 265
 266static void nsim_setup(struct net_device *dev)
 267{
 268        ether_setup(dev);
 269        eth_hw_addr_random(dev);
 270
 271        dev->tx_queue_len = 0;
 272        dev->flags |= IFF_NOARP;
 273        dev->flags &= ~IFF_MULTICAST;
 274        dev->priv_flags |= IFF_LIVE_ADDR_CHANGE |
 275                           IFF_NO_QUEUE;
 276        dev->features |= NETIF_F_HIGHDMA |
 277                         NETIF_F_SG |
 278                         NETIF_F_FRAGLIST |
 279                         NETIF_F_HW_CSUM |
 280                         NETIF_F_TSO;
 281        dev->hw_features |= NETIF_F_HW_TC;
 282        dev->max_mtu = ETH_MAX_MTU;
 283}
 284
 285struct netdevsim *
 286nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
 287{
 288        struct net_device *dev;
 289        struct netdevsim *ns;
 290        int err;
 291
 292        dev = alloc_netdev(sizeof(*ns), "eth%d", NET_NAME_UNKNOWN, nsim_setup);
 293        if (!dev)
 294                return ERR_PTR(-ENOMEM);
 295
 296        dev_net_set(dev, nsim_dev_net(nsim_dev));
 297        ns = netdev_priv(dev);
 298        ns->netdev = dev;
 299        ns->nsim_dev = nsim_dev;
 300        ns->nsim_dev_port = nsim_dev_port;
 301        ns->nsim_bus_dev = nsim_dev->nsim_bus_dev;
 302        SET_NETDEV_DEV(dev, &ns->nsim_bus_dev->dev);
 303        dev->netdev_ops = &nsim_netdev_ops;
 304        nsim_ethtool_init(ns);
 305
 306        err = nsim_udp_tunnels_info_create(nsim_dev, dev);
 307        if (err)
 308                goto err_free_netdev;
 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(dev);
 318        if (err)
 319                goto err_ipsec_teardown;
 320        rtnl_unlock();
 321
 322        return ns;
 323
 324err_ipsec_teardown:
 325        nsim_ipsec_teardown(ns);
 326        nsim_bpf_uninit(ns);
 327err_utn_destroy:
 328        rtnl_unlock();
 329        nsim_udp_tunnels_info_destroy(dev);
 330err_free_netdev:
 331        free_netdev(dev);
 332        return ERR_PTR(err);
 333}
 334
 335void nsim_destroy(struct netdevsim *ns)
 336{
 337        struct net_device *dev = ns->netdev;
 338
 339        rtnl_lock();
 340        unregister_netdevice(dev);
 341        nsim_ipsec_teardown(ns);
 342        nsim_bpf_uninit(ns);
 343        rtnl_unlock();
 344        nsim_udp_tunnels_info_destroy(dev);
 345        free_netdev(dev);
 346}
 347
 348static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
 349                         struct netlink_ext_ack *extack)
 350{
 351        NL_SET_ERR_MSG_MOD(extack, "Please use: echo \"[ID] [PORT_COUNT]\" > /sys/bus/netdevsim/new_device");
 352        return -EOPNOTSUPP;
 353}
 354
 355static struct rtnl_link_ops nsim_link_ops __read_mostly = {
 356        .kind           = DRV_NAME,
 357        .validate       = nsim_validate,
 358};
 359
 360static int __init nsim_module_init(void)
 361{
 362        int err;
 363
 364        err = nsim_dev_init();
 365        if (err)
 366                return err;
 367
 368        err = nsim_bus_init();
 369        if (err)
 370                goto err_dev_exit;
 371
 372        err = rtnl_link_register(&nsim_link_ops);
 373        if (err)
 374                goto err_bus_exit;
 375
 376        return 0;
 377
 378err_bus_exit:
 379        nsim_bus_exit();
 380err_dev_exit:
 381        nsim_dev_exit();
 382        return err;
 383}
 384
 385static void __exit nsim_module_exit(void)
 386{
 387        rtnl_link_unregister(&nsim_link_ops);
 388        nsim_bus_exit();
 389        nsim_dev_exit();
 390}
 391
 392module_init(nsim_module_init);
 393module_exit(nsim_module_exit);
 394MODULE_LICENSE("GPL");
 395MODULE_ALIAS_RTNL_LINK(DRV_NAME);
 396