Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp3268328pxj; Tue, 1 Jun 2021 01:06:24 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxTKTVWPgsPX342e3dda8V79oPsC05Z0m7faXlCTBU5WE687f7RTJKljQSWAMOKhFt6rMGK X-Received: by 2002:a05:6402:1601:: with SMTP id f1mr30542721edv.383.1622534783995; Tue, 01 Jun 2021 01:06:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622534783; cv=none; d=google.com; s=arc-20160816; b=eX85fSI70j7AKv21OdHwd4oc+phvyTFaZHgY13kJ81+Po67/iPRR4njVArOCGYCdn7 4Z7l7gmO0plyMdf+7WDu1sfbS5sPJmgq7OSmTgUfbXMwLktZyHoJ3IkRXnnxrxn8tvHd XnLxRCdpqzS9vcnoHSvWeXv19zJhRcjA5Esv8vXnu/hk8vA68qJndoea2U/z2WNSmqBh dyC4INqAkRm+NKrL3atH+IypbUcdkrifrn4qAxcjusH5IPNney1s2D9JzFZ682VQ026t CC26ULdreW/rmPgYBDkbpGBR7/rSlCCTCZ1M02LEqGuaXWWPqequLh4rmeW6dpVAvkZw aH3Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=qnULA4C7FAMVLQzdZ81PwjLgezBF+uVOWbzDZExvI50=; b=inlR7oO3FD5Xz8tHAsJ+J83pUfEyWPM2J0FgUez5BTls241uZGkr2CJk/gEbolO+M+ nIcDfPZZ3VZstWcpful4ly0djcZcDjJJKws0hrLKV4qmDTiPc43EaoFGG3FztyH6aVx3 MMKpBcKlWrPq/O1yOvVpfyshcUS/YmyAM8yOV/WYDp2sNrcHo+LVPT6LmCLwBlFU6n5s 6fIy/MCWuCQrtYDaODRb04IL0TAVEsOQuxPTjRXbGpDiq8LPoGP5r848MowvFIISHnM+ jymr6OSPdkEgA8D7Vibz0PZgkq2ao+l5drtJM0Cz5O8kcQtobLPZXqU8WXm0852jMYKS yirg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z27si15439872ejc.287.2021.06.01.01.06.01; Tue, 01 Jun 2021 01:06:23 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233308AbhFAIHb (ORCPT + 99 others); Tue, 1 Jun 2021 04:07:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51186 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233194AbhFAIH1 (ORCPT ); Tue, 1 Jun 2021 04:07:27 -0400 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:191:4433::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C09C7C061756; Tue, 1 Jun 2021 01:05:45 -0700 (PDT) Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94.2) (envelope-from ) id 1lnzPD-000V6C-SC; Tue, 01 Jun 2021 10:05:44 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org Cc: m.chetan.kumar@intel.com, loic.poulain@linaro.org, Johannes Berg Subject: [RFC 2/4] rtnetlink: add alloc() method to rtnl_link_ops Date: Tue, 1 Jun 2021 10:05:36 +0200 Message-Id: <20210601100320.d72771182b79.Iadd04d389e9e8500e7de5e02081ab212c673d143@changeid> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210601080538.71036-1-johannes@sipsolutions.net> References: <20210601080538.71036-1-johannes@sipsolutions.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg 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 --- 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