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);