diff options
author | Johannes Berg <johannes.berg@intel.com> | 2021-06-12 11:20:54 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-06-12 23:16:45 +0300 |
commit | 8c713dc93ca9a423d6af8849c9254742a1070c37 (patch) | |
tree | 0e1fd314f469a3ddadf83411fc74df9ca35ff8b4 /net/core/rtnetlink.c | |
parent | 73214a690c50a134bd364e1a4430e0e7ac81a8d8 (diff) | |
download | linux-8c713dc93ca9a423d6af8849c9254742a1070c37.tar.xz |
rtnetlink: add alloc() method to rtnl_link_ops
In order to make rtnetlink ops that can create different
kinds of devices, like what we want to add to the WWAN
framework, the priv_size and setup parameters aren't quite
sufficient. Make this easier to manage by allowing ops to
allocate their own netdev via an @alloc method that gets
the tb netlink data.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r-- | net/core/rtnetlink.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index cd87c7661c72..92c3e43db812 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -376,12 +376,12 @@ int __rtnl_link_register(struct rtnl_link_ops *ops) if (rtnl_link_ops_get(ops->kind)) return -EEXIST; - /* The check for setup is here because if ops + /* The check for alloc/setup is here because if ops * does not have that filled up, it is not possible * to use the ops for creating device. So do not * fill up dellink as well. That disables rtnl_dellink. */ - if (ops->setup && !ops->dellink) + if ((ops->alloc || ops->setup) && !ops->dellink) ops->dellink = unregister_netdevice_queue; list_add_tail(&ops->list, &link_ops); @@ -3165,8 +3165,17 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname, return ERR_PTR(-EINVAL); } - dev = alloc_netdev_mqs(ops->priv_size, ifname, name_assign_type, - ops->setup, num_tx_queues, num_rx_queues); + if (ops->alloc) { + dev = ops->alloc(tb, ifname, name_assign_type, + num_tx_queues, num_rx_queues); + if (IS_ERR(dev)) + return dev; + } else { + dev = alloc_netdev_mqs(ops->priv_size, ifname, + name_assign_type, ops->setup, + num_tx_queues, num_rx_queues); + } + if (!dev) return ERR_PTR(-ENOMEM); @@ -3399,7 +3408,7 @@ replay: return -EOPNOTSUPP; } - if (!ops->setup) + if (!ops->alloc && !ops->setup) return -EOPNOTSUPP; if (!ifname[0]) { |