Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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);