Commit bbcf9105 authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski

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: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20240227092411.2315725-3-edumazet@google.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 0598f8f3
...@@ -2205,21 +2205,20 @@ static int inet_netconf_get_devconf(struct sk_buff *in_skb, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment