Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mpls: Convert RTM_GETNETCONF to RCU.

mpls_netconf_get_devconf() calls __dev_get_by_index(),
and this only depends on RTNL.

Let's convert mpls_netconf_get_devconf() to RCU and use
dev_get_by_index_rcu().

Note that nlmsg_new() is moved ahead to use GFP_KERNEL.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Guillaume Nault <gnault@redhat.com>
Link: https://patch.msgid.link/20251029173344.2934622-12-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kuniyuki Iwashima and committed by
Jakub Kicinski
fb2b77b9 dde1b38e

+30 -14
+30 -14
net/mpls/af_mpls.c
··· 1282 1282 if (err < 0) 1283 1283 goto errout; 1284 1284 1285 - err = -EINVAL; 1286 - if (!tb[NETCONFA_IFINDEX]) 1285 + if (!tb[NETCONFA_IFINDEX]) { 1286 + err = -EINVAL; 1287 1287 goto errout; 1288 + } 1288 1289 1289 1290 ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]); 1290 - dev = __dev_get_by_index(net, ifindex); 1291 - if (!dev) 1292 - goto errout; 1293 1291 1294 - mdev = mpls_dev_get(net, dev); 1295 - if (!mdev) 1296 - goto errout; 1297 - 1298 - err = -ENOBUFS; 1299 1292 skb = nlmsg_new(mpls_netconf_msgsize_devconf(NETCONFA_ALL), GFP_KERNEL); 1300 - if (!skb) 1293 + if (!skb) { 1294 + err = -ENOBUFS; 1301 1295 goto errout; 1296 + } 1297 + 1298 + rcu_read_lock(); 1299 + 1300 + dev = dev_get_by_index_rcu(net, ifindex); 1301 + if (!dev) { 1302 + err = -EINVAL; 1303 + goto errout_unlock; 1304 + } 1305 + 1306 + mdev = mpls_dev_rcu(dev); 1307 + if (!mdev) { 1308 + err = -EINVAL; 1309 + goto errout_unlock; 1310 + } 1302 1311 1303 1312 err = mpls_netconf_fill_devconf(skb, mdev, 1304 1313 NETLINK_CB(in_skb).portid, ··· 1316 1307 if (err < 0) { 1317 1308 /* -EMSGSIZE implies BUG in mpls_netconf_msgsize_devconf() */ 1318 1309 WARN_ON(err == -EMSGSIZE); 1319 - kfree_skb(skb); 1320 - goto errout; 1310 + goto errout_unlock; 1321 1311 } 1312 + 1322 1313 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid); 1314 + 1315 + rcu_read_unlock(); 1323 1316 errout: 1324 1317 return err; 1318 + 1319 + errout_unlock: 1320 + rcu_read_unlock(); 1321 + kfree_skb(skb); 1322 + goto errout; 1325 1323 } 1326 1324 1327 1325 static int mpls_netconf_dump_devconf(struct sk_buff *skb, ··· 2792 2776 RTNL_FLAG_DUMP_UNLOCKED}, 2793 2777 {THIS_MODULE, PF_MPLS, RTM_GETNETCONF, 2794 2778 mpls_netconf_get_devconf, mpls_netconf_dump_devconf, 2795 - RTNL_FLAG_DUMP_UNLOCKED}, 2779 + RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED}, 2796 2780 }; 2797 2781 2798 2782 static int __init mpls_init(void)