cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

netdev.c (10692B)


      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_dev *nsim_dev = ns->nsim_dev;
     86
     87	/* Only refuse multicast addresses, zero address can mean unset/any. */
     88	if (vf >= nsim_dev_get_vfs(nsim_dev) || is_multicast_ether_addr(mac))
     89		return -EINVAL;
     90	memcpy(nsim_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_dev *nsim_dev = ns->nsim_dev;
    100
    101	if (vf >= nsim_dev_get_vfs(nsim_dev) || vlan > 4095 || qos > 7)
    102		return -EINVAL;
    103
    104	nsim_dev->vfconfigs[vf].vlan = vlan;
    105	nsim_dev->vfconfigs[vf].qos = qos;
    106	nsim_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_dev *nsim_dev = ns->nsim_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_dev_get_vfs(nsim_dev))
    122		return -EINVAL;
    123
    124	nsim_dev->vfconfigs[vf].min_tx_rate = min;
    125	nsim_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_dev *nsim_dev = ns->nsim_dev;
    134
    135	if (vf >= nsim_dev_get_vfs(nsim_dev))
    136		return -EINVAL;
    137	nsim_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_dev *nsim_dev = ns->nsim_dev;
    146
    147	if (vf >= nsim_dev_get_vfs(nsim_dev))
    148		return -EINVAL;
    149	nsim_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_dev *nsim_dev = ns->nsim_dev;
    158
    159	if (vf >= nsim_dev_get_vfs(nsim_dev))
    160		return -EINVAL;
    161	nsim_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_dev *nsim_dev = ns->nsim_dev;
    171
    172	if (vf >= nsim_dev_get_vfs(nsim_dev))
    173		return -EINVAL;
    174
    175	ivi->vf = vf;
    176	ivi->linkstate = nsim_dev->vfconfigs[vf].link_state;
    177	ivi->min_tx_rate = nsim_dev->vfconfigs[vf].min_tx_rate;
    178	ivi->max_tx_rate = nsim_dev->vfconfigs[vf].max_tx_rate;
    179	ivi->vlan = nsim_dev->vfconfigs[vf].vlan;
    180	ivi->vlan_proto = nsim_dev->vfconfigs[vf].vlan_proto;
    181	ivi->qos = nsim_dev->vfconfigs[vf].qos;
    182	memcpy(&ivi->mac, nsim_dev->vfconfigs[vf].vf_mac, ETH_ALEN);
    183	ivi->spoofchk = nsim_dev->vfconfigs[vf].spoofchk_enabled;
    184	ivi->trusted = nsim_dev->vfconfigs[vf].trusted;
    185	ivi->rss_query_en = nsim_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_dev *nsim_dev = ns->nsim_dev;
    194
    195	if (vf >= nsim_dev_get_vfs(nsim_dev))
    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_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);