diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 00:04:25 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 00:04:25 +0200 |
commit | 9a76aba02a37718242d7cdc294f0a3901928aa57 (patch) | |
tree | 2040d038f85d2120f21af83b0793efd5af1864e3 /drivers/net/netdevsim/netdev.c | |
parent | x86: i8259: Add missing include file (diff) | |
parent | bpf: test: fix spelling mistake "REUSEEPORT" -> "REUSEPORT" (diff) | |
download | linux-9a76aba02a37718242d7cdc294f0a3901928aa57.tar.xz linux-9a76aba02a37718242d7cdc294f0a3901928aa57.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller:
"Highlights:
- Gustavo A. R. Silva keeps working on the implicit switch fallthru
changes.
- Support 802.11ax High-Efficiency wireless in cfg80211 et al, From
Luca Coelho.
- Re-enable ASPM in r8169, from Kai-Heng Feng.
- Add virtual XFRM interfaces, which avoids all of the limitations of
existing IPSEC tunnels. From Steffen Klassert.
- Convert GRO over to use a hash table, so that when we have many
flows active we don't traverse a long list during accumluation.
- Many new self tests for routing, TC, tunnels, etc. Too many
contributors to mention them all, but I'm really happy to keep
seeing this stuff.
- Hardware timestamping support for dpaa_eth/fsl-fman from Yangbo Lu.
- Lots of cleanups and fixes in L2TP code from Guillaume Nault.
- Add IPSEC offload support to netdevsim, from Shannon Nelson.
- Add support for slotting with non-uniform distribution to netem
packet scheduler, from Yousuk Seung.
- Add UDP GSO support to mlx5e, from Boris Pismenny.
- Support offloading of Team LAG in NFP, from John Hurley.
- Allow to configure TX queue selection based upon RX queue, from
Amritha Nambiar.
- Support ethtool ring size configuration in aquantia, from Anton
Mikaev.
- Support DSCP and flowlabel per-transport in SCTP, from Xin Long.
- Support list based batching and stack traversal of SKBs, this is
very exciting work. From Edward Cree.
- Busyloop optimizations in vhost_net, from Toshiaki Makita.
- Introduce the ETF qdisc, which allows time based transmissions. IGB
can offload this in hardware. From Vinicius Costa Gomes.
- Add parameter support to devlink, from Moshe Shemesh.
- Several multiplication and division optimizations for BPF JIT in
nfp driver, from Jiong Wang.
- Lots of prepatory work to make more of the packet scheduler layer
lockless, when possible, from Vlad Buslov.
- Add ACK filter and NAT awareness to sch_cake packet scheduler, from
Toke Høiland-Jørgensen.
- Support regions and region snapshots in devlink, from Alex Vesker.
- Allow to attach XDP programs to both HW and SW at the same time on
a given device, with initial support in nfp. From Jakub Kicinski.
- Add TLS RX offload and support in mlx5, from Ilya Lesokhin.
- Use PHYLIB in r8169 driver, from Heiner Kallweit.
- All sorts of changes to support Spectrum 2 in mlxsw driver, from
Ido Schimmel.
- PTP support in mv88e6xxx DSA driver, from Andrew Lunn.
- Make TCP_USER_TIMEOUT socket option more accurate, from Jon
Maxwell.
- Support for templates in packet scheduler classifier, from Jiri
Pirko.
- IPV6 support in RDS, from Ka-Cheong Poon.
- Native tproxy support in nf_tables, from Máté Eckl.
- Maintain IP fragment queue in an rbtree, but optimize properly for
in-order frags. From Peter Oskolkov.
- Improvde handling of ACKs on hole repairs, from Yuchung Cheng"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1996 commits)
bpf: test: fix spelling mistake "REUSEEPORT" -> "REUSEPORT"
hv/netvsc: Fix NULL dereference at single queue mode fallback
net: filter: mark expected switch fall-through
xen-netfront: fix warn message as irq device name has '/'
cxgb4: Add new T5 PCI device ids 0x50af and 0x50b0
net: dsa: mv88e6xxx: missing unlock on error path
rds: fix building with IPV6=m
inet/connection_sock: prefer _THIS_IP_ to current_text_addr
net: dsa: mv88e6xxx: bitwise vs logical bug
net: sock_diag: Fix spectre v1 gadget in __sock_diag_cmd()
ieee802154: hwsim: using right kind of iteration
net: hns3: Add vlan filter setting by ethtool command -K
net: hns3: Set tx ring' tc info when netdev is up
net: hns3: Remove tx ring BD len register in hns3_enet
net: hns3: Fix desc num set to default when setting channel
net: hns3: Fix for phy link issue when using marvell phy driver
net: hns3: Fix for information of phydev lost problem when down/up
net: hns3: Fix for command format parsing error in hclge_is_all_function_id_zero
net: hns3: Add support for serdes loopback selftest
bnxt_en: take coredump_record structure off stack
...
Diffstat (limited to 'drivers/net/netdevsim/netdev.c')
-rw-r--r-- | drivers/net/netdevsim/netdev.c | 119 |
1 files changed, 112 insertions, 7 deletions
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index ec68f38213d9..8d8e2b3f263e 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -22,6 +22,7 @@ #include <net/netlink.h> #include <net/pkt_cls.h> #include <net/rtnetlink.h> +#include <net/switchdev.h> #include "netdevsim.h" @@ -40,6 +41,9 @@ struct nsim_vf_config { static u32 nsim_dev_id; +static struct dentry *nsim_ddir; +static struct dentry *nsim_sdev_ddir; + static int nsim_num_vf(struct device *dev) { struct netdevsim *ns = to_nsim(dev); @@ -144,8 +148,29 @@ static struct device_type nsim_dev_type = { .release = nsim_dev_release, }; +static int +nsim_port_attr_get(struct net_device *dev, struct switchdev_attr *attr) +{ + struct netdevsim *ns = netdev_priv(dev); + + switch (attr->id) { + case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: + attr->u.ppid.id_len = sizeof(ns->sdev->switch_id); + memcpy(&attr->u.ppid.id, &ns->sdev->switch_id, + attr->u.ppid.id_len); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static const struct switchdev_ops nsim_switchdev_ops = { + .switchdev_port_attr_get = nsim_port_attr_get, +}; + static int nsim_init(struct net_device *dev) { + char sdev_ddir_name[10], sdev_link_name[32]; struct netdevsim *ns = netdev_priv(dev); int err; @@ -154,9 +179,32 @@ static int nsim_init(struct net_device *dev) if (IS_ERR_OR_NULL(ns->ddir)) return -ENOMEM; + if (!ns->sdev) { + ns->sdev = kzalloc(sizeof(*ns->sdev), GFP_KERNEL); + if (!ns->sdev) { + err = -ENOMEM; + goto err_debugfs_destroy; + } + ns->sdev->refcnt = 1; + ns->sdev->switch_id = nsim_dev_id; + sprintf(sdev_ddir_name, "%u", ns->sdev->switch_id); + ns->sdev->ddir = debugfs_create_dir(sdev_ddir_name, + nsim_sdev_ddir); + if (IS_ERR_OR_NULL(ns->sdev->ddir)) { + err = PTR_ERR_OR_ZERO(ns->sdev->ddir) ?: -EINVAL; + goto err_sdev_free; + } + } else { + sprintf(sdev_ddir_name, "%u", ns->sdev->switch_id); + ns->sdev->refcnt++; + } + + sprintf(sdev_link_name, "../../" DRV_NAME "_sdev/%s", sdev_ddir_name); + debugfs_create_symlink("sdev", ns->ddir, sdev_link_name); + err = nsim_bpf_init(ns); if (err) - goto err_debugfs_destroy; + goto err_sdev_destroy; ns->dev.id = nsim_dev_id++; ns->dev.bus = &nsim_bus; @@ -166,17 +214,26 @@ static int nsim_init(struct net_device *dev) goto err_bpf_uninit; SET_NETDEV_DEV(dev, &ns->dev); + SWITCHDEV_SET_OPS(dev, &nsim_switchdev_ops); err = nsim_devlink_setup(ns); if (err) goto err_unreg_dev; + nsim_ipsec_init(ns); + return 0; err_unreg_dev: device_unregister(&ns->dev); err_bpf_uninit: nsim_bpf_uninit(ns); +err_sdev_destroy: + if (!--ns->sdev->refcnt) { + debugfs_remove_recursive(ns->sdev->ddir); +err_sdev_free: + kfree(ns->sdev); + } err_debugfs_destroy: debugfs_remove_recursive(ns->ddir); return err; @@ -186,9 +243,14 @@ static void nsim_uninit(struct net_device *dev) { struct netdevsim *ns = netdev_priv(dev); + nsim_ipsec_teardown(ns); nsim_devlink_teardown(ns); debugfs_remove_recursive(ns->ddir); nsim_bpf_uninit(ns); + if (!--ns->sdev->refcnt) { + debugfs_remove_recursive(ns->sdev->ddir); + kfree(ns->sdev); + } } static void nsim_free(struct net_device *dev) @@ -203,11 +265,15 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct netdevsim *ns = netdev_priv(dev); + if (!nsim_ipsec_tx(ns, skb)) + goto out; + u64_stats_update_begin(&ns->syncp); ns->tx_packets++; ns->tx_bytes += skb->len; u64_stats_update_end(&ns->syncp); +out: dev_kfree_skb(skb); return NETDEV_TX_OK; @@ -221,8 +287,7 @@ static int nsim_change_mtu(struct net_device *dev, int new_mtu) { struct netdevsim *ns = netdev_priv(dev); - if (ns->xdp_prog_mode == XDP_ATTACHED_DRV && - new_mtu > NSIM_XDP_MAX_MTU) + if (ns->xdp.prog && new_mtu > NSIM_XDP_MAX_MTU) return -EBUSY; dev->mtu = new_mtu; @@ -260,7 +325,7 @@ nsim_setup_tc_block(struct net_device *dev, struct tc_block_offload *f) switch (f->command) { case TC_BLOCK_BIND: return tcf_block_cb_register(f->block, nsim_setup_tc_block_cb, - ns, ns); + ns, ns, f->extack); case TC_BLOCK_UNBIND: tcf_block_cb_unregister(f->block, nsim_setup_tc_block_cb, ns); return 0; @@ -464,15 +529,46 @@ static int nsim_validate(struct nlattr *tb[], struct nlattr *data[], return 0; } +static int nsim_newlink(struct net *src_net, struct net_device *dev, + struct nlattr *tb[], struct nlattr *data[], + struct netlink_ext_ack *extack) +{ + struct netdevsim *ns = netdev_priv(dev); + + if (tb[IFLA_LINK]) { + struct net_device *joindev; + struct netdevsim *joinns; + + joindev = __dev_get_by_index(src_net, + nla_get_u32(tb[IFLA_LINK])); + if (!joindev) + return -ENODEV; + if (joindev->netdev_ops != &nsim_netdev_ops) + return -EINVAL; + + joinns = netdev_priv(joindev); + if (!joinns->sdev || !joinns->sdev->refcnt) + return -EINVAL; + ns->sdev = joinns->sdev; + } + + return register_netdevice(dev); +} + +static void nsim_dellink(struct net_device *dev, struct list_head *head) +{ + unregister_netdevice_queue(dev, head); +} + static struct rtnl_link_ops nsim_link_ops __read_mostly = { .kind = DRV_NAME, .priv_size = sizeof(struct netdevsim), .setup = nsim_setup, .validate = nsim_validate, + .newlink = nsim_newlink, + .dellink = nsim_dellink, }; -struct dentry *nsim_ddir; - static int __init nsim_module_init(void) { int err; @@ -481,9 +577,15 @@ static int __init nsim_module_init(void) if (IS_ERR_OR_NULL(nsim_ddir)) return -ENOMEM; + nsim_sdev_ddir = debugfs_create_dir(DRV_NAME "_sdev", NULL); + if (IS_ERR_OR_NULL(nsim_sdev_ddir)) { + err = -ENOMEM; + goto err_debugfs_destroy; + } + err = bus_register(&nsim_bus); if (err) - goto err_debugfs_destroy; + goto err_sdir_destroy; err = nsim_devlink_init(); if (err) @@ -499,6 +601,8 @@ err_dl_fini: nsim_devlink_exit(); err_unreg_bus: bus_unregister(&nsim_bus); +err_sdir_destroy: + debugfs_remove_recursive(nsim_sdev_ddir); err_debugfs_destroy: debugfs_remove_recursive(nsim_ddir); return err; @@ -509,6 +613,7 @@ static void __exit nsim_module_exit(void) rtnl_link_unregister(&nsim_link_ops); nsim_devlink_exit(); bus_unregister(&nsim_bus); + debugfs_remove_recursive(nsim_sdev_ddir); debugfs_remove_recursive(nsim_ddir); } |