at v5.2-rc7 9.7 kB view raw
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 26#include "netdevsim.h" 27 28static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev) 29{ 30 struct netdevsim *ns = netdev_priv(dev); 31 32 if (!nsim_ipsec_tx(ns, skb)) 33 goto out; 34 35 u64_stats_update_begin(&ns->syncp); 36 ns->tx_packets++; 37 ns->tx_bytes += skb->len; 38 u64_stats_update_end(&ns->syncp); 39 40out: 41 dev_kfree_skb(skb); 42 43 return NETDEV_TX_OK; 44} 45 46static void nsim_set_rx_mode(struct net_device *dev) 47{ 48} 49 50static int nsim_change_mtu(struct net_device *dev, int new_mtu) 51{ 52 struct netdevsim *ns = netdev_priv(dev); 53 54 if (ns->xdp.prog && new_mtu > NSIM_XDP_MAX_MTU) 55 return -EBUSY; 56 57 dev->mtu = new_mtu; 58 59 return 0; 60} 61 62static void 63nsim_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) 64{ 65 struct netdevsim *ns = netdev_priv(dev); 66 unsigned int start; 67 68 do { 69 start = u64_stats_fetch_begin(&ns->syncp); 70 stats->tx_bytes = ns->tx_bytes; 71 stats->tx_packets = ns->tx_packets; 72 } while (u64_stats_fetch_retry(&ns->syncp, start)); 73} 74 75static int 76nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) 77{ 78 return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv); 79} 80 81static int 82nsim_setup_tc_block(struct net_device *dev, struct tc_block_offload *f) 83{ 84 struct netdevsim *ns = netdev_priv(dev); 85 86 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) 87 return -EOPNOTSUPP; 88 89 switch (f->command) { 90 case TC_BLOCK_BIND: 91 return tcf_block_cb_register(f->block, nsim_setup_tc_block_cb, 92 ns, ns, f->extack); 93 case TC_BLOCK_UNBIND: 94 tcf_block_cb_unregister(f->block, nsim_setup_tc_block_cb, ns); 95 return 0; 96 default: 97 return -EOPNOTSUPP; 98 } 99} 100 101static int nsim_set_vf_mac(struct net_device *dev, int vf, u8 *mac) 102{ 103 struct netdevsim *ns = netdev_priv(dev); 104 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev; 105 106 /* Only refuse multicast addresses, zero address can mean unset/any. */ 107 if (vf >= nsim_bus_dev->num_vfs || is_multicast_ether_addr(mac)) 108 return -EINVAL; 109 memcpy(nsim_bus_dev->vfconfigs[vf].vf_mac, mac, ETH_ALEN); 110 111 return 0; 112} 113 114static int nsim_set_vf_vlan(struct net_device *dev, int vf, 115 u16 vlan, u8 qos, __be16 vlan_proto) 116{ 117 struct netdevsim *ns = netdev_priv(dev); 118 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev; 119 120 if (vf >= nsim_bus_dev->num_vfs || vlan > 4095 || qos > 7) 121 return -EINVAL; 122 123 nsim_bus_dev->vfconfigs[vf].vlan = vlan; 124 nsim_bus_dev->vfconfigs[vf].qos = qos; 125 nsim_bus_dev->vfconfigs[vf].vlan_proto = vlan_proto; 126 127 return 0; 128} 129 130static int nsim_set_vf_rate(struct net_device *dev, int vf, int min, int max) 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 138 nsim_bus_dev->vfconfigs[vf].min_tx_rate = min; 139 nsim_bus_dev->vfconfigs[vf].max_tx_rate = max; 140 141 return 0; 142} 143 144static int nsim_set_vf_spoofchk(struct net_device *dev, int vf, bool val) 145{ 146 struct netdevsim *ns = netdev_priv(dev); 147 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev; 148 149 if (vf >= nsim_bus_dev->num_vfs) 150 return -EINVAL; 151 nsim_bus_dev->vfconfigs[vf].spoofchk_enabled = val; 152 153 return 0; 154} 155 156static int nsim_set_vf_rss_query_en(struct net_device *dev, int vf, bool val) 157{ 158 struct netdevsim *ns = netdev_priv(dev); 159 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev; 160 161 if (vf >= nsim_bus_dev->num_vfs) 162 return -EINVAL; 163 nsim_bus_dev->vfconfigs[vf].rss_query_enabled = val; 164 165 return 0; 166} 167 168static int nsim_set_vf_trust(struct net_device *dev, int vf, bool val) 169{ 170 struct netdevsim *ns = netdev_priv(dev); 171 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev; 172 173 if (vf >= nsim_bus_dev->num_vfs) 174 return -EINVAL; 175 nsim_bus_dev->vfconfigs[vf].trusted = val; 176 177 return 0; 178} 179 180static int 181nsim_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivi) 182{ 183 struct netdevsim *ns = netdev_priv(dev); 184 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev; 185 186 if (vf >= nsim_bus_dev->num_vfs) 187 return -EINVAL; 188 189 ivi->vf = vf; 190 ivi->linkstate = nsim_bus_dev->vfconfigs[vf].link_state; 191 ivi->min_tx_rate = nsim_bus_dev->vfconfigs[vf].min_tx_rate; 192 ivi->max_tx_rate = nsim_bus_dev->vfconfigs[vf].max_tx_rate; 193 ivi->vlan = nsim_bus_dev->vfconfigs[vf].vlan; 194 ivi->vlan_proto = nsim_bus_dev->vfconfigs[vf].vlan_proto; 195 ivi->qos = nsim_bus_dev->vfconfigs[vf].qos; 196 memcpy(&ivi->mac, nsim_bus_dev->vfconfigs[vf].vf_mac, ETH_ALEN); 197 ivi->spoofchk = nsim_bus_dev->vfconfigs[vf].spoofchk_enabled; 198 ivi->trusted = nsim_bus_dev->vfconfigs[vf].trusted; 199 ivi->rss_query_en = nsim_bus_dev->vfconfigs[vf].rss_query_enabled; 200 201 return 0; 202} 203 204static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state) 205{ 206 struct netdevsim *ns = netdev_priv(dev); 207 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev; 208 209 if (vf >= nsim_bus_dev->num_vfs) 210 return -EINVAL; 211 212 switch (state) { 213 case IFLA_VF_LINK_STATE_AUTO: 214 case IFLA_VF_LINK_STATE_ENABLE: 215 case IFLA_VF_LINK_STATE_DISABLE: 216 break; 217 default: 218 return -EINVAL; 219 } 220 221 nsim_bus_dev->vfconfigs[vf].link_state = state; 222 223 return 0; 224} 225 226static int 227nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) 228{ 229 switch (type) { 230 case TC_SETUP_BLOCK: 231 return nsim_setup_tc_block(dev, type_data); 232 default: 233 return -EOPNOTSUPP; 234 } 235} 236 237static int 238nsim_set_features(struct net_device *dev, netdev_features_t features) 239{ 240 struct netdevsim *ns = netdev_priv(dev); 241 242 if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC)) 243 return nsim_bpf_disable_tc(ns); 244 245 return 0; 246} 247 248static struct devlink_port *nsim_get_devlink_port(struct net_device *dev) 249{ 250 struct netdevsim *ns = netdev_priv(dev); 251 252 return &ns->nsim_dev_port->devlink_port; 253} 254 255static const struct net_device_ops nsim_netdev_ops = { 256 .ndo_start_xmit = nsim_start_xmit, 257 .ndo_set_rx_mode = nsim_set_rx_mode, 258 .ndo_set_mac_address = eth_mac_addr, 259 .ndo_validate_addr = eth_validate_addr, 260 .ndo_change_mtu = nsim_change_mtu, 261 .ndo_get_stats64 = nsim_get_stats64, 262 .ndo_set_vf_mac = nsim_set_vf_mac, 263 .ndo_set_vf_vlan = nsim_set_vf_vlan, 264 .ndo_set_vf_rate = nsim_set_vf_rate, 265 .ndo_set_vf_spoofchk = nsim_set_vf_spoofchk, 266 .ndo_set_vf_trust = nsim_set_vf_trust, 267 .ndo_get_vf_config = nsim_get_vf_config, 268 .ndo_set_vf_link_state = nsim_set_vf_link_state, 269 .ndo_set_vf_rss_query_en = nsim_set_vf_rss_query_en, 270 .ndo_setup_tc = nsim_setup_tc, 271 .ndo_set_features = nsim_set_features, 272 .ndo_bpf = nsim_bpf, 273 .ndo_get_devlink_port = nsim_get_devlink_port, 274}; 275 276static void nsim_setup(struct net_device *dev) 277{ 278 ether_setup(dev); 279 eth_hw_addr_random(dev); 280 281 dev->tx_queue_len = 0; 282 dev->flags |= IFF_NOARP; 283 dev->flags &= ~IFF_MULTICAST; 284 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | 285 IFF_NO_QUEUE; 286 dev->features |= NETIF_F_HIGHDMA | 287 NETIF_F_SG | 288 NETIF_F_FRAGLIST | 289 NETIF_F_HW_CSUM | 290 NETIF_F_TSO; 291 dev->hw_features |= NETIF_F_HW_TC; 292 dev->max_mtu = ETH_MAX_MTU; 293} 294 295struct netdevsim * 296nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port) 297{ 298 struct net_device *dev; 299 struct netdevsim *ns; 300 int err; 301 302 dev = alloc_netdev(sizeof(*ns), "eth%d", NET_NAME_UNKNOWN, nsim_setup); 303 if (!dev) 304 return ERR_PTR(-ENOMEM); 305 306 ns = netdev_priv(dev); 307 ns->netdev = dev; 308 ns->nsim_dev = nsim_dev; 309 ns->nsim_dev_port = nsim_dev_port; 310 ns->nsim_bus_dev = nsim_dev->nsim_bus_dev; 311 SET_NETDEV_DEV(dev, &ns->nsim_bus_dev->dev); 312 dev->netdev_ops = &nsim_netdev_ops; 313 314 rtnl_lock(); 315 err = nsim_bpf_init(ns); 316 if (err) 317 goto err_free_netdev; 318 319 nsim_ipsec_init(ns); 320 321 err = register_netdevice(dev); 322 if (err) 323 goto err_ipsec_teardown; 324 rtnl_unlock(); 325 326 return ns; 327 328err_ipsec_teardown: 329 nsim_ipsec_teardown(ns); 330 nsim_bpf_uninit(ns); 331 rtnl_unlock(); 332err_free_netdev: 333 free_netdev(dev); 334 return ERR_PTR(err); 335} 336 337void nsim_destroy(struct netdevsim *ns) 338{ 339 struct net_device *dev = ns->netdev; 340 341 rtnl_lock(); 342 unregister_netdevice(dev); 343 nsim_ipsec_teardown(ns); 344 nsim_bpf_uninit(ns); 345 rtnl_unlock(); 346 free_netdev(dev); 347} 348 349static int nsim_validate(struct nlattr *tb[], struct nlattr *data[], 350 struct netlink_ext_ack *extack) 351{ 352 NL_SET_ERR_MSG_MOD(extack, "Please use: echo \"[ID] [PORT_COUNT]\" > /sys/bus/netdevsim/new_device"); 353 return -EOPNOTSUPP; 354} 355 356static struct rtnl_link_ops nsim_link_ops __read_mostly = { 357 .kind = DRV_NAME, 358 .validate = nsim_validate, 359}; 360 361static int __init nsim_module_init(void) 362{ 363 int err; 364 365 err = nsim_dev_init(); 366 if (err) 367 return err; 368 369 err = nsim_bus_init(); 370 if (err) 371 goto err_dev_exit; 372 373 err = rtnl_link_register(&nsim_link_ops); 374 if (err) 375 goto err_bus_exit; 376 377 return 0; 378 379err_bus_exit: 380 nsim_bus_exit(); 381err_dev_exit: 382 nsim_dev_exit(); 383 return err; 384} 385 386static void __exit nsim_module_exit(void) 387{ 388 rtnl_link_unregister(&nsim_link_ops); 389 nsim_bus_exit(); 390 nsim_dev_exit(); 391} 392 393module_init(nsim_module_init); 394module_exit(nsim_module_exit); 395MODULE_LICENSE("GPL"); 396MODULE_ALIAS_RTNL_LINK(DRV_NAME);