mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
inet: do not use RTNL in inet_netconf_get_devconf()
"ip -4 netconf show dev XXXX" no longer acquires RTNL. Return -ENODEV instead of -EINVAL if no netdev or idev can be found. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Link: https://lore.kernel.org/r/20240227092411.2315725-3-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
0598f8f3bb
commit
bbcf91053b
|
|
@ -2205,21 +2205,20 @@ static int inet_netconf_get_devconf(struct sk_buff *in_skb,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct net *net = sock_net(in_skb->sk);
|
struct net *net = sock_net(in_skb->sk);
|
||||||
struct nlattr *tb[NETCONFA_MAX+1];
|
struct nlattr *tb[NETCONFA_MAX + 1];
|
||||||
|
const struct ipv4_devconf *devconf;
|
||||||
|
struct in_device *in_dev = NULL;
|
||||||
|
struct net_device *dev = NULL;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct ipv4_devconf *devconf;
|
|
||||||
struct in_device *in_dev;
|
|
||||||
struct net_device *dev;
|
|
||||||
int ifindex;
|
int ifindex;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = inet_netconf_valid_get_req(in_skb, nlh, tb, extack);
|
err = inet_netconf_valid_get_req(in_skb, nlh, tb, extack);
|
||||||
if (err)
|
if (err)
|
||||||
goto errout;
|
return err;
|
||||||
|
|
||||||
err = -EINVAL;
|
|
||||||
if (!tb[NETCONFA_IFINDEX])
|
if (!tb[NETCONFA_IFINDEX])
|
||||||
goto errout;
|
return -EINVAL;
|
||||||
|
|
||||||
ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]);
|
ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]);
|
||||||
switch (ifindex) {
|
switch (ifindex) {
|
||||||
|
|
@ -2230,10 +2229,10 @@ static int inet_netconf_get_devconf(struct sk_buff *in_skb,
|
||||||
devconf = net->ipv4.devconf_dflt;
|
devconf = net->ipv4.devconf_dflt;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev = __dev_get_by_index(net, ifindex);
|
err = -ENODEV;
|
||||||
if (!dev)
|
dev = dev_get_by_index(net, ifindex);
|
||||||
goto errout;
|
if (dev)
|
||||||
in_dev = __in_dev_get_rtnl(dev);
|
in_dev = in_dev_get(dev);
|
||||||
if (!in_dev)
|
if (!in_dev)
|
||||||
goto errout;
|
goto errout;
|
||||||
devconf = &in_dev->cnf;
|
devconf = &in_dev->cnf;
|
||||||
|
|
@ -2257,6 +2256,9 @@ static int inet_netconf_get_devconf(struct sk_buff *in_skb,
|
||||||
}
|
}
|
||||||
err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
|
err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
|
||||||
errout:
|
errout:
|
||||||
|
if (in_dev)
|
||||||
|
in_dev_put(in_dev);
|
||||||
|
dev_put(dev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2826,5 +2828,6 @@ void __init devinet_init(void)
|
||||||
rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, 0);
|
rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, 0);
|
||||||
rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, 0);
|
rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, 0);
|
||||||
rtnl_register(PF_INET, RTM_GETNETCONF, inet_netconf_get_devconf,
|
rtnl_register(PF_INET, RTM_GETNETCONF, inet_netconf_get_devconf,
|
||||||
inet_netconf_dump_devconf, 0);
|
inet_netconf_dump_devconf,
|
||||||
|
RTNL_FLAG_DOIT_UNLOCKED);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user