netdev.c (c3bdd5e65185f46150b3bac103b3854040487857) | netdev.c (1daf36c0dbc059cdef1a1c11e83599c972832d1d) |
---|---|
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" --- 11 unchanged lines hidden (view full) --- 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 | 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" --- 11 unchanged lines hidden (view full) --- 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 u32 nsim_dev_id; 29 |
|
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 | 30struct nsim_vf_config { 31 int link_state; 32 u16 min_tx_rate; 33 u16 max_tx_rate; 34 u16 vlan; 35 __be16 vlan_proto; 36 u16 qos; 37 u8 vf_mac[ETH_ALEN]; 38 bool spoofchk_enabled; 39 bool trusted; 40 bool rss_query_enabled; 41}; 42 |
41static u32 nsim_dev_id; 42 | |
43static struct dentry *nsim_ddir; | 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 --- 81 unchanged lines hidden (view full) --- 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); | 44 45static int nsim_num_vf(struct device *dev) 46{ 47 struct netdevsim *ns = to_nsim(dev); 48 49 return ns->num_vfs; 50} 51 --- 81 unchanged lines hidden (view full) --- 133 NULL, 134}; 135 136static void nsim_dev_release(struct device *dev) 137{ 138 struct netdevsim *ns = to_nsim(dev); 139 140 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{ | 141} 142 143static struct device_type nsim_dev_type = { 144 .groups = nsim_dev_attr_groups, 145 .release = nsim_dev_release, 146}; 147 148static int nsim_get_port_parent_id(struct net_device *dev, 149 struct netdev_phys_item_id *ppid) 150{ 151 struct netdevsim *ns = netdev_priv(dev); 152 153 ppid->id_len = sizeof(ns->sdev->switch_id); 154 memcpy(&ppid->id, &ns->sdev->switch_id, ppid->id_len); 155 return 0; 156} 157 158static int nsim_init(struct net_device *dev) 159{ |
162 char sdev_ddir_name[10], sdev_link_name[32]; | |
163 struct netdevsim *ns = netdev_priv(dev); | 160 struct netdevsim *ns = netdev_priv(dev); |
161 char sdev_link_name[32]; |
|
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 | 162 int err; 163 164 ns->netdev = dev; 165 ns->ddir = debugfs_create_dir(netdev_name(dev), nsim_ddir); 166 if (IS_ERR_OR_NULL(ns->ddir)) 167 return -ENOMEM; 168 |
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); | 169 sprintf(sdev_link_name, "../../" DRV_NAME "_sdev/%u", 170 ns->sdev->switch_id); |
192 debugfs_create_symlink("sdev", ns->ddir, sdev_link_name); 193 194 err = nsim_bpf_init(ns); 195 if (err) | 171 debugfs_create_symlink("sdev", ns->ddir, sdev_link_name); 172 173 err = nsim_bpf_init(ns); 174 if (err) |
196 goto err_sdev_destroy; | 175 goto err_debugfs_destroy; |
197 | 176 |
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); | 177 err = nsim_devlink_setup(ns); |
202 if (err) 203 goto err_bpf_uninit; 204 | 178 if (err) 179 goto err_bpf_uninit; 180 |
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 | 181 nsim_ipsec_init(ns); 182 183 return 0; 184 |
215err_unreg_dev: 216 device_unregister(&ns->dev); | |
217err_bpf_uninit: 218 nsim_bpf_uninit(ns); | 185err_bpf_uninit: 186 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); | 187err_debugfs_destroy: 188 debugfs_remove_recursive(ns->ddir); 189 return err; 190} 191 192static void nsim_uninit(struct net_device *dev) 193{ 194 struct netdevsim *ns = netdev_priv(dev); 195 196 nsim_ipsec_teardown(ns); 197 nsim_devlink_teardown(ns); 198 debugfs_remove_recursive(ns->ddir); 199 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() */ | 200} 201 202static void nsim_free(struct net_device *dev) 203{ 204 struct netdevsim *ns = netdev_priv(dev); 205 206 device_unregister(&ns->dev); 207 /* netdev and vf state will be freed out of device_release() */ |
208 nsim_sdev_put(ns->sdev); |
|
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; --- 227 unchanged lines hidden (view full) --- 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; | 209} 210 211static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev) 212{ 213 struct netdevsim *ns = netdev_priv(dev); 214 215 if (!nsim_ipsec_tx(ns, skb)) 216 goto out; --- 227 unchanged lines hidden (view full) --- 444}; 445 446static void nsim_setup(struct net_device *dev) 447{ 448 ether_setup(dev); 449 eth_hw_addr_random(dev); 450 451 dev->netdev_ops = &nsim_netdev_ops; |
452 dev->needs_free_netdev = true; |
|
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 | --- 17 unchanged lines hidden (view full) --- 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); | 453 dev->priv_destructor = nsim_free; 454 455 dev->tx_queue_len = 0; 456 dev->flags |= IFF_NOARP; 457 dev->flags &= ~IFF_MULTICAST; 458 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | 459 IFF_NO_QUEUE; 460 dev->features |= NETIF_F_HIGHDMA | --- 17 unchanged lines hidden (view full) --- 478 return 0; 479} 480 481static int nsim_newlink(struct net *src_net, struct net_device *dev, 482 struct nlattr *tb[], struct nlattr *data[], 483 struct netlink_ext_ack *extack) 484{ 485 struct netdevsim *ns = netdev_priv(dev); |
486 struct netdevsim *joinns = NULL; 487 int err; |
|
526 527 if (tb[IFLA_LINK]) { 528 struct net_device *joindev; | 488 489 if (tb[IFLA_LINK]) { 490 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); | 491 492 joindev = __dev_get_by_index(src_net, 493 nla_get_u32(tb[IFLA_LINK])); 494 if (!joindev) 495 return -ENODEV; 496 if (joindev->netdev_ops != &nsim_netdev_ops) 497 return -EINVAL; 498 499 joinns = netdev_priv(joindev); |
539 if (!joinns->sdev || !joinns->sdev->refcnt) 540 return -EINVAL; 541 ns->sdev = joinns->sdev; | |
542 } 543 | 500 } 501 |
544 return register_netdevice(dev); 545} | 502 ns->sdev = nsim_sdev_get(joinns); 503 if (IS_ERR(ns->sdev)) 504 return PTR_ERR(ns->sdev); |
546 | 505 |
547static void nsim_dellink(struct net_device *dev, struct list_head *head) 548{ 549 unregister_netdevice_queue(dev, head); | 506 ns->dev.id = nsim_dev_id++; 507 ns->dev.bus = &nsim_bus; 508 ns->dev.type = &nsim_dev_type; 509 err = device_register(&ns->dev); 510 if (err) 511 goto err_sdev_put; 512 513 SET_NETDEV_DEV(dev, &ns->dev); 514 515 err = register_netdevice(dev); 516 if (err) 517 goto err_unreg_dev; 518 return 0; 519 520err_unreg_dev: 521 device_unregister(&ns->dev); 522err_sdev_put: 523 nsim_sdev_put(ns->sdev); 524 return err; |
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, | 525} 526 527static struct rtnl_link_ops nsim_link_ops __read_mostly = { 528 .kind = DRV_NAME, 529 .priv_size = sizeof(struct netdevsim), 530 .setup = nsim_setup, 531 .validate = nsim_validate, 532 .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 | 533}; 534 535static int __init nsim_module_init(void) 536{ 537 int err; 538 539 nsim_ddir = debugfs_create_dir(DRV_NAME, NULL); 540 if (IS_ERR_OR_NULL(nsim_ddir)) 541 return -ENOMEM; 542 |
569 nsim_sdev_ddir = debugfs_create_dir(DRV_NAME "_sdev", NULL); 570 if (IS_ERR_OR_NULL(nsim_sdev_ddir)) { 571 err = -ENOMEM; | 543 err = nsim_sdev_init(); 544 if (err) |
572 goto err_debugfs_destroy; | 545 goto err_debugfs_destroy; |
573 } | |
574 575 err = bus_register(&nsim_bus); 576 if (err) | 546 547 err = bus_register(&nsim_bus); 548 if (err) |
577 goto err_sdir_destroy; | 549 goto err_sdev_exit; |
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); | 550 551 err = nsim_devlink_init(); 552 if (err) 553 goto err_unreg_bus; 554 555 err = rtnl_link_register(&nsim_link_ops); 556 if (err) 557 goto err_dl_fini; 558 559 return 0; 560 561err_dl_fini: 562 nsim_devlink_exit(); 563err_unreg_bus: 564 bus_unregister(&nsim_bus); |
593err_sdir_destroy: 594 debugfs_remove_recursive(nsim_sdev_ddir); | 565err_sdev_exit: 566 nsim_sdev_exit(); |
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); | 567err_debugfs_destroy: 568 debugfs_remove_recursive(nsim_ddir); 569 return err; 570} 571 572static void __exit nsim_module_exit(void) 573{ 574 rtnl_link_unregister(&nsim_link_ops); 575 nsim_devlink_exit(); 576 bus_unregister(&nsim_bus); |
605 debugfs_remove_recursive(nsim_sdev_ddir); | 577 nsim_sdev_exit(); |
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); | 578 debugfs_remove_recursive(nsim_ddir); 579} 580 581module_init(nsim_module_init); 582module_exit(nsim_module_exit); 583MODULE_LICENSE("GPL"); 584MODULE_ALIAS_RTNL_LINK(DRV_NAME); |