All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org
Cc: m.chetan.kumar@intel.com, loic.poulain@linaro.org,
	Johannes Berg <johannes.berg@intel.com>
Subject: [RFC 2/4] rtnetlink: add alloc() method to rtnl_link_ops
Date: Tue,  1 Jun 2021 10:05:36 +0200	[thread overview]
Message-ID: <20210601100320.d72771182b79.Iadd04d389e9e8500e7de5e02081ab212c673d143@changeid> (raw)
In-Reply-To: <20210601080538.71036-1-johannes@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

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
both the tb and data.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/bareudp.c   |  2 +-
 drivers/net/can/vxcan.c |  2 +-
 drivers/net/geneve.c    |  2 +-
 drivers/net/veth.c      |  2 +-
 drivers/net/vxlan.c     |  2 +-
 include/net/rtnetlink.h | 10 ++++++++++
 net/core/rtnetlink.c    | 17 ++++++++++++++---
 net/ipv4/ip_gre.c       |  2 +-
 8 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c
index edfad93e7b68..a694f6d8eb21 100644
--- a/drivers/net/bareudp.c
+++ b/drivers/net/bareudp.c
@@ -727,7 +727,7 @@ struct net_device *bareudp_dev_create(struct net *net, const char *name,
 
 	memset(tb, 0, sizeof(tb));
 	dev = rtnl_create_link(net, name, name_assign_type,
-			       &bareudp_link_ops, tb, NULL);
+			       &bareudp_link_ops, tb, NULL, NULL);
 	if (IS_ERR(dev))
 		return dev;
 
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 8861a7d875e7..f904c78b4c23 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -204,7 +204,7 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
 		return PTR_ERR(peer_net);
 
 	peer = rtnl_create_link(peer_net, ifname, name_assign_type,
-				&vxcan_link_ops, tbp, extack);
+				&vxcan_link_ops, tbp, NULL, extack);
 	if (IS_ERR(peer)) {
 		put_net(peer_net);
 		return PTR_ERR(peer);
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 1ab94b5f9bbf..130397110623 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1840,7 +1840,7 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
 
 	memset(tb, 0, sizeof(tb));
 	dev = rtnl_create_link(net, name, name_assign_type,
-			       &geneve_link_ops, tb, NULL);
+			       &geneve_link_ops, tb, NULL, NULL);
 	if (IS_ERR(dev))
 		return dev;
 
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index bdb7ce3cb054..788faa8faa98 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1498,7 +1498,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
 		return PTR_ERR(net);
 
 	peer = rtnl_create_link(net, ifname, name_assign_type,
-				&veth_link_ops, tbp, extack);
+				&veth_link_ops, tbp, NULL, extack);
 	if (IS_ERR(peer)) {
 		put_net(net);
 		return PTR_ERR(peer);
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 02a14f1b938a..b8a63a8bcb73 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -4483,7 +4483,7 @@ struct net_device *vxlan_dev_create(struct net *net, const char *name,
 	memset(&tb, 0, sizeof(tb));
 
 	dev = rtnl_create_link(net, name, name_assign_type,
-			       &vxlan_link_ops, tb, NULL);
+			       &vxlan_link_ops, tb, NULL, NULL);
 	if (IS_ERR(dev))
 		return dev;
 
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 479f60ef54c0..75426ad5a05b 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -37,6 +37,9 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
  *	@maxtype: Highest device specific netlink attribute number
  *	@policy: Netlink policy for device specific attribute validation
  *	@validate: Optional validation function for netlink/changelink parameters
+ *	@alloc: netdev allocation function, can be %NULL and is then used
+ *		in place of alloc_netdev_mqs(), in this case @priv_size
+ *		and @setup are unused. Returns a netdev or ERR_PTR().
  *	@priv_size: sizeof net_device private space
  *	@setup: net_device setup function
  *	@newlink: Function for configuring and registering a new device
@@ -63,6 +66,12 @@ struct rtnl_link_ops {
 	const char		*kind;
 
 	size_t			priv_size;
+	struct net_device	*(*alloc)(struct nlattr *tb[],
+					  struct nlattr *data[],
+					  const char *ifname,
+					  unsigned char name_assign_type,
+					  unsigned int num_tx_queues,
+					  unsigned int num_rx_queues);
 	void			(*setup)(struct net_device *dev);
 
 	bool			netns_refund;
@@ -162,6 +171,7 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
 				    unsigned char name_assign_type,
 				    const struct rtnl_link_ops *ops,
 				    struct nlattr *tb[],
+				    struct nlattr *data[],
 				    struct netlink_ext_ack *extack);
 int rtnl_delete_link(struct net_device *dev);
 int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 714d5fa38546..9da38639f088 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3151,6 +3151,7 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
 				    unsigned char name_assign_type,
 				    const struct rtnl_link_ops *ops,
 				    struct nlattr *tb[],
+				    struct nlattr *data[],
 				    struct netlink_ext_ack *extack)
 {
 	struct net_device *dev;
@@ -3177,8 +3178,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, data, 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);
 
@@ -3440,7 +3450,8 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 	}
 
 	dev = rtnl_create_link(link_net ? : dest_net, ifname,
-			       name_assign_type, ops, tb, extack);
+			       name_assign_type, ops, tb, data,
+			       extack);
 	if (IS_ERR(dev)) {
 		err = PTR_ERR(dev);
 		goto out;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index a68bf4c6fe9b..7680f5b87f61 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1637,7 +1637,7 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
 	memset(&tb, 0, sizeof(tb));
 
 	dev = rtnl_create_link(net, name, name_assign_type,
-			       &ipgre_tap_ops, tb, NULL);
+			       &ipgre_tap_ops, tb, NULL, NULL);
 	if (IS_ERR(dev))
 		return dev;
 
-- 
2.31.1


  parent reply	other threads:[~2021-06-01  8:05 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-01  8:05 [RFC 0/4] wwan framework netdev creation Johannes Berg
2021-06-01  8:05 ` [RFC 1/4] iosm: fix stats and RCU bugs in RX Johannes Berg
2021-06-01  8:05 ` Johannes Berg [this message]
2021-06-01  8:05 ` [RFC 3/4] wwan: add interface creation support Johannes Berg
2021-06-01  9:37   ` Loic Poulain
2021-06-01 10:35     ` Johannes Berg
2021-06-02  6:52       ` Loic Poulain
2021-06-02  8:29         ` Johannes Berg
2021-06-03  7:00           ` Loic Poulain
2021-06-03  7:02             ` Kumar, M Chetan
2021-06-02  1:42   ` Sergey Ryazanov
2021-06-02  7:38     ` Johannes Berg
2021-06-02 12:45       ` Sergey Ryazanov
2021-06-02 12:56         ` Johannes Berg
2021-06-02 15:38           ` Sergey Ryazanov
2021-06-01  8:05 ` [RFC 4/4] iosm: convert to generic wwan ops Johannes Berg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210601100320.d72771182b79.Iadd04d389e9e8500e7de5e02081ab212c673d143@changeid \
    --to=johannes@sipsolutions.net \
    --cc=johannes.berg@intel.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=loic.poulain@linaro.org \
    --cc=m.chetan.kumar@intel.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.