at v5.1 14 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 28struct nsim_vf_config { 29 int link_state; 30 u16 min_tx_rate; 31 u16 max_tx_rate; 32 u16 vlan; 33 __be16 vlan_proto; 34 u16 qos; 35 u8 vf_mac[ETH_ALEN]; 36 bool spoofchk_enabled; 37 bool trusted; 38 bool rss_query_enabled; 39}; 40 41static u32 nsim_dev_id; 42 43static struct dentry *nsim_ddir; 44static struct dentry *nsim_sdev_ddir; 45 46static int nsim_num_vf(struct device *dev) 47{ 48 struct netdevsim *ns = to_nsim(dev); 49 50 return ns->num_vfs; 51} 52 53static struct bus_type nsim_bus = { 54 .name = DRV_NAME, 55 .dev_name = DRV_NAME, 56 .num_vf = nsim_num_vf, 57}; 58 59static int nsim_vfs_enable(struct netdevsim *ns, unsigned int num_vfs) 60{ 61 ns->vfconfigs = kcalloc(num_vfs, sizeof(struct nsim_vf_config), 62 GFP_KERNEL); 63 if (!ns->vfconfigs) 64 return -ENOMEM; 65 ns->num_vfs = num_vfs; 66 67 return 0; 68} 69 70static void nsim_vfs_disable(struct netdevsim *ns) 71{ 72 kfree(ns->vfconfigs); 73 ns->vfconfigs = NULL; 74 ns->num_vfs = 0; 75} 76 77static ssize_t 78nsim_numvfs_store(struct device *dev, struct device_attribute *attr, 79 const char *buf, size_t count) 80{ 81 struct netdevsim *ns = to_nsim(dev); 82 unsigned int num_vfs; 83 int ret; 84 85 ret = kstrtouint(buf, 0, &num_vfs); 86 if (ret) 87 return ret; 88 89 rtnl_lock(); 90 if (ns->num_vfs == num_vfs) 91 goto exit_good; 92 if (ns->num_vfs && num_vfs) { 93 ret = -EBUSY; 94 goto exit_unlock; 95 } 96 97 if (num_vfs) { 98 ret = nsim_vfs_enable(ns, num_vfs); 99 if (ret) 100 goto exit_unlock; 101 } else { 102 nsim_vfs_disable(ns); 103 } 104exit_good: 105 ret = count; 106exit_unlock: 107 rtnl_unlock(); 108 109 return ret; 110} 111 112static ssize_t 113nsim_numvfs_show(struct device *dev, struct device_attribute *attr, char *buf) 114{ 115 struct netdevsim *ns = to_nsim(dev); 116 117 return sprintf(buf, "%u\n", ns->num_vfs); 118} 119 120static struct device_attribute nsim_numvfs_attr = 121 __ATTR(sriov_numvfs, 0664, nsim_numvfs_show, nsim_numvfs_store); 122 123static struct attribute *nsim_dev_attrs[] = { 124 &nsim_numvfs_attr.attr, 125 NULL, 126}; 127 128static const struct attribute_group nsim_dev_attr_group = { 129 .attrs = nsim_dev_attrs, 130}; 131 132static const struct attribute_group *nsim_dev_attr_groups[] = { 133 &nsim_dev_attr_group, 134 NULL, 135}; 136 137static void nsim_dev_release(struct device *dev) 138{ 139 struct netdevsim *ns = to_nsim(dev); 140 141 nsim_vfs_disable(ns); 142 free_netdev(ns->netdev); 143} 144 145static struct device_type nsim_dev_type = { 146 .groups = nsim_dev_attr_groups, 147 .release = nsim_dev_release, 148}; 149 150static int nsim_get_port_parent_id(struct net_device *dev, 151 struct netdev_phys_item_id *ppid) 152{ 153 struct netdevsim *ns = netdev_priv(dev); 154 155 ppid->id_len = sizeof(ns->sdev->switch_id); 156 memcpy(&ppid->id, &ns->sdev->switch_id, ppid->id_len); 157 return 0; 158} 159 160static int nsim_init(struct net_device *dev) 161{ 162 char sdev_ddir_name[10], sdev_link_name[32]; 163 struct netdevsim *ns = netdev_priv(dev); 164 int err; 165 166 ns->netdev = dev; 167 ns->ddir = debugfs_create_dir(netdev_name(dev), nsim_ddir); 168 if (IS_ERR_OR_NULL(ns->ddir)) 169 return -ENOMEM; 170 171 if (!ns->sdev) { 172 ns->sdev = kzalloc(sizeof(*ns->sdev), GFP_KERNEL); 173 if (!ns->sdev) { 174 err = -ENOMEM; 175 goto err_debugfs_destroy; 176 } 177 ns->sdev->refcnt = 1; 178 ns->sdev->switch_id = nsim_dev_id; 179 sprintf(sdev_ddir_name, "%u", ns->sdev->switch_id); 180 ns->sdev->ddir = debugfs_create_dir(sdev_ddir_name, 181 nsim_sdev_ddir); 182 if (IS_ERR_OR_NULL(ns->sdev->ddir)) { 183 err = PTR_ERR_OR_ZERO(ns->sdev->ddir) ?: -EINVAL; 184 goto err_sdev_free; 185 } 186 } else { 187 sprintf(sdev_ddir_name, "%u", ns->sdev->switch_id); 188 ns->sdev->refcnt++; 189 } 190 191 sprintf(sdev_link_name, "../../" DRV_NAME "_sdev/%s", sdev_ddir_name); 192 debugfs_create_symlink("sdev", ns->ddir, sdev_link_name); 193 194 err = nsim_bpf_init(ns); 195 if (err) 196 goto err_sdev_destroy; 197 198 ns->dev.id = nsim_dev_id++; 199 ns->dev.bus = &nsim_bus; 200 ns->dev.type = &nsim_dev_type; 201 err = device_register(&ns->dev); 202 if (err) 203 goto err_bpf_uninit; 204 205 SET_NETDEV_DEV(dev, &ns->dev); 206 207 err = nsim_devlink_setup(ns); 208 if (err) 209 goto err_unreg_dev; 210 211 nsim_ipsec_init(ns); 212 213 return 0; 214 215err_unreg_dev: 216 device_unregister(&ns->dev); 217err_bpf_uninit: 218 nsim_bpf_uninit(ns); 219err_sdev_destroy: 220 if (!--ns->sdev->refcnt) { 221 debugfs_remove_recursive(ns->sdev->ddir); 222err_sdev_free: 223 kfree(ns->sdev); 224 } 225err_debugfs_destroy: 226 debugfs_remove_recursive(ns->ddir); 227 return err; 228} 229 230static void nsim_uninit(struct net_device *dev) 231{ 232 struct netdevsim *ns = netdev_priv(dev); 233 234 nsim_ipsec_teardown(ns); 235 nsim_devlink_teardown(ns); 236 debugfs_remove_recursive(ns->ddir); 237 nsim_bpf_uninit(ns); 238 if (!--ns->sdev->refcnt) { 239 debugfs_remove_recursive(ns->sdev->ddir); 240 kfree(ns->sdev); 241 } 242} 243 244static void nsim_free(struct net_device *dev) 245{ 246 struct netdevsim *ns = netdev_priv(dev); 247 248 device_unregister(&ns->dev); 249 /* netdev and vf state will be freed out of device_release() */ 250} 251 252static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev) 253{ 254 struct netdevsim *ns = netdev_priv(dev); 255 256 if (!nsim_ipsec_tx(ns, skb)) 257 goto out; 258 259 u64_stats_update_begin(&ns->syncp); 260 ns->tx_packets++; 261 ns->tx_bytes += skb->len; 262 u64_stats_update_end(&ns->syncp); 263 264out: 265 dev_kfree_skb(skb); 266 267 return NETDEV_TX_OK; 268} 269 270static void nsim_set_rx_mode(struct net_device *dev) 271{ 272} 273 274static int nsim_change_mtu(struct net_device *dev, int new_mtu) 275{ 276 struct netdevsim *ns = netdev_priv(dev); 277 278 if (ns->xdp.prog && new_mtu > NSIM_XDP_MAX_MTU) 279 return -EBUSY; 280 281 dev->mtu = new_mtu; 282 283 return 0; 284} 285 286static void 287nsim_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) 288{ 289 struct netdevsim *ns = netdev_priv(dev); 290 unsigned int start; 291 292 do { 293 start = u64_stats_fetch_begin(&ns->syncp); 294 stats->tx_bytes = ns->tx_bytes; 295 stats->tx_packets = ns->tx_packets; 296 } while (u64_stats_fetch_retry(&ns->syncp, start)); 297} 298 299static int 300nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) 301{ 302 return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv); 303} 304 305static int 306nsim_setup_tc_block(struct net_device *dev, struct tc_block_offload *f) 307{ 308 struct netdevsim *ns = netdev_priv(dev); 309 310 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) 311 return -EOPNOTSUPP; 312 313 switch (f->command) { 314 case TC_BLOCK_BIND: 315 return tcf_block_cb_register(f->block, nsim_setup_tc_block_cb, 316 ns, ns, f->extack); 317 case TC_BLOCK_UNBIND: 318 tcf_block_cb_unregister(f->block, nsim_setup_tc_block_cb, ns); 319 return 0; 320 default: 321 return -EOPNOTSUPP; 322 } 323} 324 325static int nsim_set_vf_mac(struct net_device *dev, int vf, u8 *mac) 326{ 327 struct netdevsim *ns = netdev_priv(dev); 328 329 /* Only refuse multicast addresses, zero address can mean unset/any. */ 330 if (vf >= ns->num_vfs || is_multicast_ether_addr(mac)) 331 return -EINVAL; 332 memcpy(ns->vfconfigs[vf].vf_mac, mac, ETH_ALEN); 333 334 return 0; 335} 336 337static int nsim_set_vf_vlan(struct net_device *dev, int vf, 338 u16 vlan, u8 qos, __be16 vlan_proto) 339{ 340 struct netdevsim *ns = netdev_priv(dev); 341 342 if (vf >= ns->num_vfs || vlan > 4095 || qos > 7) 343 return -EINVAL; 344 345 ns->vfconfigs[vf].vlan = vlan; 346 ns->vfconfigs[vf].qos = qos; 347 ns->vfconfigs[vf].vlan_proto = vlan_proto; 348 349 return 0; 350} 351 352static int nsim_set_vf_rate(struct net_device *dev, int vf, int min, int max) 353{ 354 struct netdevsim *ns = netdev_priv(dev); 355 356 if (vf >= ns->num_vfs) 357 return -EINVAL; 358 359 ns->vfconfigs[vf].min_tx_rate = min; 360 ns->vfconfigs[vf].max_tx_rate = max; 361 362 return 0; 363} 364 365static int nsim_set_vf_spoofchk(struct net_device *dev, int vf, bool val) 366{ 367 struct netdevsim *ns = netdev_priv(dev); 368 369 if (vf >= ns->num_vfs) 370 return -EINVAL; 371 ns->vfconfigs[vf].spoofchk_enabled = val; 372 373 return 0; 374} 375 376static int nsim_set_vf_rss_query_en(struct net_device *dev, int vf, bool val) 377{ 378 struct netdevsim *ns = netdev_priv(dev); 379 380 if (vf >= ns->num_vfs) 381 return -EINVAL; 382 ns->vfconfigs[vf].rss_query_enabled = val; 383 384 return 0; 385} 386 387static int nsim_set_vf_trust(struct net_device *dev, int vf, bool val) 388{ 389 struct netdevsim *ns = netdev_priv(dev); 390 391 if (vf >= ns->num_vfs) 392 return -EINVAL; 393 ns->vfconfigs[vf].trusted = val; 394 395 return 0; 396} 397 398static int 399nsim_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivi) 400{ 401 struct netdevsim *ns = netdev_priv(dev); 402 403 if (vf >= ns->num_vfs) 404 return -EINVAL; 405 406 ivi->vf = vf; 407 ivi->linkstate = ns->vfconfigs[vf].link_state; 408 ivi->min_tx_rate = ns->vfconfigs[vf].min_tx_rate; 409 ivi->max_tx_rate = ns->vfconfigs[vf].max_tx_rate; 410 ivi->vlan = ns->vfconfigs[vf].vlan; 411 ivi->vlan_proto = ns->vfconfigs[vf].vlan_proto; 412 ivi->qos = ns->vfconfigs[vf].qos; 413 memcpy(&ivi->mac, ns->vfconfigs[vf].vf_mac, ETH_ALEN); 414 ivi->spoofchk = ns->vfconfigs[vf].spoofchk_enabled; 415 ivi->trusted = ns->vfconfigs[vf].trusted; 416 ivi->rss_query_en = ns->vfconfigs[vf].rss_query_enabled; 417 418 return 0; 419} 420 421static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state) 422{ 423 struct netdevsim *ns = netdev_priv(dev); 424 425 if (vf >= ns->num_vfs) 426 return -EINVAL; 427 428 switch (state) { 429 case IFLA_VF_LINK_STATE_AUTO: 430 case IFLA_VF_LINK_STATE_ENABLE: 431 case IFLA_VF_LINK_STATE_DISABLE: 432 break; 433 default: 434 return -EINVAL; 435 } 436 437 ns->vfconfigs[vf].link_state = state; 438 439 return 0; 440} 441 442static int 443nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) 444{ 445 switch (type) { 446 case TC_SETUP_BLOCK: 447 return nsim_setup_tc_block(dev, type_data); 448 default: 449 return -EOPNOTSUPP; 450 } 451} 452 453static int 454nsim_set_features(struct net_device *dev, netdev_features_t features) 455{ 456 struct netdevsim *ns = netdev_priv(dev); 457 458 if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC)) 459 return nsim_bpf_disable_tc(ns); 460 461 return 0; 462} 463 464static const struct net_device_ops nsim_netdev_ops = { 465 .ndo_init = nsim_init, 466 .ndo_uninit = nsim_uninit, 467 .ndo_start_xmit = nsim_start_xmit, 468 .ndo_set_rx_mode = nsim_set_rx_mode, 469 .ndo_set_mac_address = eth_mac_addr, 470 .ndo_validate_addr = eth_validate_addr, 471 .ndo_change_mtu = nsim_change_mtu, 472 .ndo_get_stats64 = nsim_get_stats64, 473 .ndo_set_vf_mac = nsim_set_vf_mac, 474 .ndo_set_vf_vlan = nsim_set_vf_vlan, 475 .ndo_set_vf_rate = nsim_set_vf_rate, 476 .ndo_set_vf_spoofchk = nsim_set_vf_spoofchk, 477 .ndo_set_vf_trust = nsim_set_vf_trust, 478 .ndo_get_vf_config = nsim_get_vf_config, 479 .ndo_set_vf_link_state = nsim_set_vf_link_state, 480 .ndo_set_vf_rss_query_en = nsim_set_vf_rss_query_en, 481 .ndo_setup_tc = nsim_setup_tc, 482 .ndo_set_features = nsim_set_features, 483 .ndo_bpf = nsim_bpf, 484 .ndo_get_port_parent_id = nsim_get_port_parent_id, 485}; 486 487static void nsim_setup(struct net_device *dev) 488{ 489 ether_setup(dev); 490 eth_hw_addr_random(dev); 491 492 dev->netdev_ops = &nsim_netdev_ops; 493 dev->priv_destructor = nsim_free; 494 495 dev->tx_queue_len = 0; 496 dev->flags |= IFF_NOARP; 497 dev->flags &= ~IFF_MULTICAST; 498 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | 499 IFF_NO_QUEUE; 500 dev->features |= NETIF_F_HIGHDMA | 501 NETIF_F_SG | 502 NETIF_F_FRAGLIST | 503 NETIF_F_HW_CSUM | 504 NETIF_F_TSO; 505 dev->hw_features |= NETIF_F_HW_TC; 506 dev->max_mtu = ETH_MAX_MTU; 507} 508 509static int nsim_validate(struct nlattr *tb[], struct nlattr *data[], 510 struct netlink_ext_ack *extack) 511{ 512 if (tb[IFLA_ADDRESS]) { 513 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) 514 return -EINVAL; 515 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) 516 return -EADDRNOTAVAIL; 517 } 518 return 0; 519} 520 521static int nsim_newlink(struct net *src_net, struct net_device *dev, 522 struct nlattr *tb[], struct nlattr *data[], 523 struct netlink_ext_ack *extack) 524{ 525 struct netdevsim *ns = netdev_priv(dev); 526 527 if (tb[IFLA_LINK]) { 528 struct net_device *joindev; 529 struct netdevsim *joinns; 530 531 joindev = __dev_get_by_index(src_net, 532 nla_get_u32(tb[IFLA_LINK])); 533 if (!joindev) 534 return -ENODEV; 535 if (joindev->netdev_ops != &nsim_netdev_ops) 536 return -EINVAL; 537 538 joinns = netdev_priv(joindev); 539 if (!joinns->sdev || !joinns->sdev->refcnt) 540 return -EINVAL; 541 ns->sdev = joinns->sdev; 542 } 543 544 return register_netdevice(dev); 545} 546 547static void nsim_dellink(struct net_device *dev, struct list_head *head) 548{ 549 unregister_netdevice_queue(dev, head); 550} 551 552static struct rtnl_link_ops nsim_link_ops __read_mostly = { 553 .kind = DRV_NAME, 554 .priv_size = sizeof(struct netdevsim), 555 .setup = nsim_setup, 556 .validate = nsim_validate, 557 .newlink = nsim_newlink, 558 .dellink = nsim_dellink, 559}; 560 561static int __init nsim_module_init(void) 562{ 563 int err; 564 565 nsim_ddir = debugfs_create_dir(DRV_NAME, NULL); 566 if (IS_ERR_OR_NULL(nsim_ddir)) 567 return -ENOMEM; 568 569 nsim_sdev_ddir = debugfs_create_dir(DRV_NAME "_sdev", NULL); 570 if (IS_ERR_OR_NULL(nsim_sdev_ddir)) { 571 err = -ENOMEM; 572 goto err_debugfs_destroy; 573 } 574 575 err = bus_register(&nsim_bus); 576 if (err) 577 goto err_sdir_destroy; 578 579 err = nsim_devlink_init(); 580 if (err) 581 goto err_unreg_bus; 582 583 err = rtnl_link_register(&nsim_link_ops); 584 if (err) 585 goto err_dl_fini; 586 587 return 0; 588 589err_dl_fini: 590 nsim_devlink_exit(); 591err_unreg_bus: 592 bus_unregister(&nsim_bus); 593err_sdir_destroy: 594 debugfs_remove_recursive(nsim_sdev_ddir); 595err_debugfs_destroy: 596 debugfs_remove_recursive(nsim_ddir); 597 return err; 598} 599 600static void __exit nsim_module_exit(void) 601{ 602 rtnl_link_unregister(&nsim_link_ops); 603 nsim_devlink_exit(); 604 bus_unregister(&nsim_bus); 605 debugfs_remove_recursive(nsim_sdev_ddir); 606 debugfs_remove_recursive(nsim_ddir); 607} 608 609module_init(nsim_module_init); 610module_exit(nsim_module_exit); 611MODULE_LICENSE("GPL"); 612MODULE_ALIAS_RTNL_LINK(DRV_NAME);