[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <174265435050.356712.1842575186842459886.stgit@pro.pro>
Date: Sat, 22 Mar 2025 17:39:10 +0300
From: Kirill Tkhai <tkhai@...ru>
To: netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: tkhai@...ru
Subject: [PATCH NET-PREV 10/51] net: Underline newlink and changelink dependencies
This is to get rtnetlink code knowledge about devices
touching by newlink and changelink to bring them to the same
lock group.
Signed-off-by: Kirill Tkhai <tkhai@...ru>
---
drivers/infiniband/ulp/ipoib/ipoib_netlink.c | 1 +
drivers/net/amt.c | 5 +++++
drivers/net/bonding/bond_netlink.c | 5 +++++
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 1 +
drivers/net/ipvlan/ipvlan_main.c | 1 +
drivers/net/ipvlan/ipvtap.c | 1 +
drivers/net/macsec.c | 1 +
drivers/net/macvlan.c | 1 +
drivers/net/macvtap.c | 1 +
drivers/net/vxlan/vxlan_core.c | 6 ++++++
drivers/net/wireless/virtual/virt_wifi.c | 1 +
include/net/rtnetlink.h | 16 ++++++++++++++++
net/8021q/vlan_netlink.c | 1 +
net/core/rtnetlink.c | 5 +++++
net/dsa/netlink.c | 5 +++++
net/hsr/hsr_netlink.c | 6 ++++++
net/ieee802154/6lowpan/core.c | 1 +
17 files changed, 58 insertions(+)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
index 9ad8d9856275..2dd3231df36c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
@@ -172,6 +172,7 @@ static struct rtnl_link_ops ipoib_link_ops __read_mostly = {
.policy = ipoib_policy,
.priv_size = sizeof(struct ipoib_dev_priv),
.setup = ipoib_setup_common,
+ .newlink_deps = &generic_newlink_deps,
.newlink = ipoib_new_child_link,
.dellink = ipoib_del_child_link,
.changelink = ipoib_changelink,
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 6d15ab3bfbbc..2288f4bf649c 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -3330,6 +3330,10 @@ static int amt_fill_info(struct sk_buff *skb, const struct net_device *dev)
return -EMSGSIZE;
}
+struct link_deps amt_newlink_deps = {
+ .mandatory.data = { IFLA_AMT_LINK, },
+};
+
static struct rtnl_link_ops amt_link_ops __read_mostly = {
.kind = "amt",
.maxtype = IFLA_AMT_MAX,
@@ -3337,6 +3341,7 @@ static struct rtnl_link_ops amt_link_ops __read_mostly = {
.priv_size = sizeof(struct amt_dev),
.setup = amt_link_setup,
.validate = amt_validate,
+ .newlink_deps = &amt_newlink_deps,
.newlink = amt_newlink,
.dellink = amt_dellink,
.get_size = amt_get_size,
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
index 2a6a424806aa..5fcab77d616f 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -906,6 +906,10 @@ static int bond_fill_linkxstats(struct sk_buff *skb,
return 0;
}
+struct link_deps bond_changelink_deps = {
+ .optional.data = { IFLA_BOND_ACTIVE_SLAVE, IFLA_BOND_PRIMARY, },
+};
+
struct rtnl_link_ops bond_link_ops __read_mostly = {
.kind = "bond",
.priv_size = sizeof(struct bonding),
@@ -914,6 +918,7 @@ struct rtnl_link_ops bond_link_ops __read_mostly = {
.policy = bond_policy,
.validate = bond_validate,
.newlink = bond_newlink,
+ .changelink_deps = &bond_changelink_deps,
.changelink = bond_changelink,
.get_size = bond_get_size,
.fill_info = bond_fill_info,
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
index f3bea196a8f9..495368cbef34 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
@@ -400,6 +400,7 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = {
.priv_size = sizeof(struct rmnet_priv),
.setup = rmnet_vnd_setup,
.validate = rmnet_rtnl_validate,
+ .newlink_deps = &generic_newlink_deps,
.newlink = rmnet_newlink,
.dellink = rmnet_dellink,
.get_size = rmnet_get_size,
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 094f44dac5c8..aafaf9d1d822 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -700,6 +700,7 @@ static struct rtnl_link_ops ipvlan_link_ops = {
.priv_size = sizeof(struct ipvl_dev),
.setup = ipvlan_link_setup,
+ .newlink_deps = &generic_newlink_deps,
.newlink = ipvlan_link_new,
.dellink = ipvlan_link_delete,
.get_link_net = ipvlan_get_link_net,
diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c
index 1afc4c47be73..df1d22092b21 100644
--- a/drivers/net/ipvlan/ipvtap.c
+++ b/drivers/net/ipvlan/ipvtap.c
@@ -128,6 +128,7 @@ static void ipvtap_setup(struct net_device *dev)
static struct rtnl_link_ops ipvtap_link_ops __read_mostly = {
.kind = "ipvtap",
.setup = ipvtap_setup,
+ .newlink_deps = &generic_newlink_deps,
.newlink = ipvtap_newlink,
.dellink = ipvtap_dellink,
.priv_size = sizeof(struct ipvtap_dev),
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 2da70bc3dd86..246cf09a0ebc 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -4430,6 +4430,7 @@ static struct rtnl_link_ops macsec_link_ops __read_mostly = {
.policy = macsec_rtnl_policy,
.setup = macsec_setup,
.validate = macsec_validate_attr,
+ .newlink_deps = &generic_newlink_deps,
.newlink = macsec_newlink,
.changelink = macsec_changelink,
.dellink = macsec_dellink,
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 24298a33e0e9..b51e2e21dead 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1754,6 +1754,7 @@ static struct net *macvlan_get_link_net(const struct net_device *dev)
static struct rtnl_link_ops macvlan_link_ops = {
.kind = "macvlan",
.setup = macvlan_setup,
+ .newlink_deps = &generic_newlink_deps,
.newlink = macvlan_newlink,
.dellink = macvlan_dellink,
.get_link_net = macvlan_get_link_net,
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 29a5929d48e5..f24168080e04 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -140,6 +140,7 @@ static struct net *macvtap_link_net(const struct net_device *dev)
static struct rtnl_link_ops macvtap_link_ops __read_mostly = {
.kind = "macvtap",
.setup = macvtap_setup,
+ .newlink_deps = &generic_newlink_deps,
.newlink = macvtap_newlink,
.dellink = macvtap_dellink,
.get_link_net = macvtap_link_net,
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 8983e75e9881..b041ddc2ab34 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -4579,6 +4579,10 @@ static struct net *vxlan_get_link_net(const struct net_device *dev)
return READ_ONCE(vxlan->net);
}
+struct link_deps vxlan_newlink_deps = {
+ .mandatory.data = { IFLA_VXLAN_LINK, },
+};
+
static struct rtnl_link_ops vxlan_link_ops __read_mostly = {
.kind = "vxlan",
.maxtype = IFLA_VXLAN_MAX,
@@ -4586,7 +4590,9 @@ static struct rtnl_link_ops vxlan_link_ops __read_mostly = {
.priv_size = sizeof(struct vxlan_dev),
.setup = vxlan_setup,
.validate = vxlan_validate,
+ .newlink_deps = &vxlan_newlink_deps,
.newlink = vxlan_newlink,
+ .changelink_deps= &vxlan_newlink_deps,
.changelink = vxlan_changelink,
.dellink = vxlan_dellink,
.get_size = vxlan_get_size,
diff --git a/drivers/net/wireless/virtual/virt_wifi.c b/drivers/net/wireless/virtual/virt_wifi.c
index 4ee374080466..c80ae0e0df53 100644
--- a/drivers/net/wireless/virtual/virt_wifi.c
+++ b/drivers/net/wireless/virtual/virt_wifi.c
@@ -622,6 +622,7 @@ static void virt_wifi_dellink(struct net_device *dev,
static struct rtnl_link_ops virt_wifi_link_ops = {
.kind = "virt_wifi",
.setup = virt_wifi_setup,
+ .newlink_deps = &generic_newlink_deps,
.newlink = virt_wifi_newlink,
.dellink = virt_wifi_dellink,
.priv_size = sizeof(struct virt_wifi_netdev_priv),
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index b45d57b5968a..f1702e8872cf 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -29,6 +29,18 @@ static inline enum rtnl_kinds rtnl_msgtype_kind(int msgtype)
return msgtype & RTNL_KIND_MASK;
}
+#define MAX_LINK_DEPS 5
+struct link_deps_table {
+ int tb[MAX_LINK_DEPS + 1];
+ int data[MAX_LINK_DEPS + 1];
+};
+
+struct link_deps {
+ struct link_deps_table mandatory;
+ struct link_deps_table optional;
+};
+extern struct link_deps generic_newlink_deps;
+
void rtnl_register(int protocol, int msgtype,
rtnl_doit_func, rtnl_dumpit_func, unsigned int flags);
int rtnl_register_module(struct module *owner, int protocol, int msgtype,
@@ -58,7 +70,9 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
* and @setup are unused. Returns a netdev or ERR_PTR().
* @priv_size: sizeof net_device private space
* @setup: net_device setup function
+ * @newlink_deps: Indexes of real devices that newlink depends on.
* @newlink: Function for configuring and registering a new device
+ * @changelink_deps: Indexes of real devices that changelink depends on.
* @changelink: Function for changing parameters of an existing device
* @dellink: Function to remove a device
* @get_size: Function to calculate required room for dumping device
@@ -96,11 +110,13 @@ struct rtnl_link_ops {
struct nlattr *data[],
struct netlink_ext_ack *extack);
+ struct link_deps *newlink_deps;
int (*newlink)(struct net *src_net,
struct net_device *dev,
struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack);
+ struct link_deps *changelink_deps;
int (*changelink)(struct net_device *dev,
struct nlattr *tb[],
struct nlattr *data[],
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index cf5219df7903..c71180ba0746 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -293,6 +293,7 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = {
.priv_size = sizeof(struct vlan_dev_priv),
.setup = vlan_setup,
.validate = vlan_validate,
+ .newlink_deps = &generic_newlink_deps,
.newlink = vlan_newlink,
.changelink = vlan_changelink,
.dellink = unregister_vlan_dev,
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 046736091b4f..cf060ba4cd1d 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3490,6 +3490,11 @@ static int rtnl_group_changelink(const struct sk_buff *skb,
return err;
}
+struct link_deps generic_newlink_deps = {
+ .mandatory.tb = { IFLA_LINK, }
+};
+EXPORT_SYMBOL_GPL(generic_newlink_deps);
+
static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
const struct rtnl_link_ops *ops,
const struct nlmsghdr *nlh,
diff --git a/net/dsa/netlink.c b/net/dsa/netlink.c
index 1332e56349e5..835d935814fb 100644
--- a/net/dsa/netlink.c
+++ b/net/dsa/netlink.c
@@ -11,6 +11,10 @@ static const struct nla_policy dsa_policy[IFLA_DSA_MAX + 1] = {
[IFLA_DSA_CONDUIT] = { .type = NLA_U32 },
};
+struct link_deps dsa_changelink_deps = {
+ .optional.data = { IFLA_DSA_CONDUIT, },
+};
+
static int dsa_changelink(struct net_device *dev, struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
@@ -57,6 +61,7 @@ struct rtnl_link_ops dsa_link_ops __read_mostly = {
.priv_size = sizeof(struct dsa_port),
.maxtype = IFLA_DSA_MAX,
.policy = dsa_policy,
+ .changelink_deps = &dsa_changelink_deps,
.changelink = dsa_changelink,
.get_size = dsa_get_size,
.fill_info = dsa_fill_info,
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index f6ff0b61e08a..6ec883739415 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -176,12 +176,18 @@ static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev)
return -EMSGSIZE;
}
+static struct link_deps hsr_newlink_deps = {
+ .mandatory.data = { IFLA_HSR_SLAVE1, IFLA_HSR_SLAVE2, },
+ .optional.data = { IFLA_HSR_INTERLINK, },
+};
+
static struct rtnl_link_ops hsr_link_ops __read_mostly = {
.kind = "hsr",
.maxtype = IFLA_HSR_MAX,
.policy = hsr_policy,
.priv_size = sizeof(struct hsr_priv),
.setup = hsr_dev_setup,
+ .newlink_deps = &hsr_newlink_deps,
.newlink = hsr_newlink,
.dellink = hsr_dellink,
.fill_info = hsr_fill_info,
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
index 77b4e92027c5..4236aafd448f 100644
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -196,6 +196,7 @@ static struct rtnl_link_ops lowpan_link_ops __read_mostly = {
.kind = "lowpan",
.priv_size = LOWPAN_PRIV_SIZE(sizeof(struct lowpan_802154_dev)),
.setup = lowpan_setup,
+ .newlink_deps = &generic_newlink_deps,
.newlink = lowpan_newlink,
.dellink = lowpan_dellink,
.validate = lowpan_validate,
Powered by blists - more mailing lists