Skip to content
This repository was archived by the owner on Oct 31, 2024. It is now read-only.

Commit ff7abcc

Browse files
Eric Dumazetgregkh
Eric Dumazet
authored andcommittedOct 17, 2024
mpls: no longer hold RTNL in mpls_netconf_dump_devconf()
[ Upstream commit e0f89d2 ] - Use for_each_netdev_dump() to no longer rely on net->dev_index_head hash table. - No longer care of net->dev_base_seq - Fix return value at the end of a dump, so that NLMSG_DONE can be appended to current skb, saving one recvmsg() system call. - No longer grab RTNL, RCU protection is enough, afer adding one READ_ONCE(mdev->input_enabled) in mpls_netconf_fill_devconf() Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://lore.kernel.org/r/20240410111951.2673193-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Stable-dep-of: 5be2062 ("mpls: Handle error of rtnl_register_module().") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent ba5366b commit ff7abcc

File tree

1 file changed

+22
-37
lines changed

1 file changed

+22
-37
lines changed
 

‎net/mpls/af_mpls.c

+22-37
Original file line numberDiff line numberDiff line change
@@ -1154,7 +1154,7 @@ static int mpls_netconf_fill_devconf(struct sk_buff *skb, struct mpls_dev *mdev,
11541154

11551155
if ((all || type == NETCONFA_INPUT) &&
11561156
nla_put_s32(skb, NETCONFA_INPUT,
1157-
mdev->input_enabled) < 0)
1157+
READ_ONCE(mdev->input_enabled)) < 0)
11581158
goto nla_put_failure;
11591159

11601160
nlmsg_end(skb, nlh);
@@ -1303,11 +1303,12 @@ static int mpls_netconf_dump_devconf(struct sk_buff *skb,
13031303
{
13041304
const struct nlmsghdr *nlh = cb->nlh;
13051305
struct net *net = sock_net(skb->sk);
1306-
struct hlist_head *head;
1306+
struct {
1307+
unsigned long ifindex;
1308+
} *ctx = (void *)cb->ctx;
13071309
struct net_device *dev;
13081310
struct mpls_dev *mdev;
1309-
int idx, s_idx;
1310-
int h, s_h;
1311+
int err = 0;
13111312

13121313
if (cb->strict_check) {
13131314
struct netlink_ext_ack *extack = cb->extack;
@@ -1324,40 +1325,23 @@ static int mpls_netconf_dump_devconf(struct sk_buff *skb,
13241325
}
13251326
}
13261327

1327-
s_h = cb->args[0];
1328-
s_idx = idx = cb->args[1];
1329-
1330-
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
1331-
idx = 0;
1332-
head = &net->dev_index_head[h];
1333-
rcu_read_lock();
1334-
cb->seq = net->dev_base_seq;
1335-
hlist_for_each_entry_rcu(dev, head, index_hlist) {
1336-
if (idx < s_idx)
1337-
goto cont;
1338-
mdev = mpls_dev_get(dev);
1339-
if (!mdev)
1340-
goto cont;
1341-
if (mpls_netconf_fill_devconf(skb, mdev,
1342-
NETLINK_CB(cb->skb).portid,
1343-
nlh->nlmsg_seq,
1344-
RTM_NEWNETCONF,
1345-
NLM_F_MULTI,
1346-
NETCONFA_ALL) < 0) {
1347-
rcu_read_unlock();
1348-
goto done;
1349-
}
1350-
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1351-
cont:
1352-
idx++;
1353-
}
1354-
rcu_read_unlock();
1328+
rcu_read_lock();
1329+
for_each_netdev_dump(net, dev, ctx->ifindex) {
1330+
mdev = mpls_dev_get(dev);
1331+
if (!mdev)
1332+
continue;
1333+
err = mpls_netconf_fill_devconf(skb, mdev,
1334+
NETLINK_CB(cb->skb).portid,
1335+
nlh->nlmsg_seq,
1336+
RTM_NEWNETCONF,
1337+
NLM_F_MULTI,
1338+
NETCONFA_ALL);
1339+
if (err < 0)
1340+
break;
13551341
}
1356-
done:
1357-
cb->args[0] = h;
1358-
cb->args[1] = idx;
1342+
rcu_read_unlock();
13591343

1360-
return skb->len;
1344+
return err;
13611345
}
13621346

13631347
#define MPLS_PERDEV_SYSCTL_OFFSET(field) \
@@ -2771,7 +2755,8 @@ static int __init mpls_init(void)
27712755
mpls_getroute, mpls_dump_routes, 0);
27722756
rtnl_register_module(THIS_MODULE, PF_MPLS, RTM_GETNETCONF,
27732757
mpls_netconf_get_devconf,
2774-
mpls_netconf_dump_devconf, 0);
2758+
mpls_netconf_dump_devconf,
2759+
RTNL_FLAG_DUMP_UNLOCKED);
27752760
err = ipgre_tunnel_encap_add_mpls_ops();
27762761
if (err)
27772762
pr_err("Can't add mpls over gre tunnel ops\n");

0 commit comments

Comments
 (0)
This repository has been archived.