mctp: no longer rely on net->dev_index_head[]
[ Upstream commit 2d20773aec14996b6cc4db92d885028319be683d ] mctp_dump_addrinfo() is one of the last users of net->dev_index_head[] in the control path. Switch to for_each_netdev_dump() for better scalability. Use C99 for mctp_device_rtnl_msg_handlers[] to prepare future RTNL removal from mctp_dump_addrinfo() (mdev->addrs is not yet RCU protected) Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Matt Johnston <matt@codeconstruct.com.au> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Acked-by: Jeremy Kerr <jk@codeconstruct.com.au> Link: https://patch.msgid.link/20241206223811.1343076-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Stable-dep-of: f11cf946c0a9 ("net: mctp: Don't access ifa_index when missing") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
7777ca11a4
commit
2d45eeb7d5
@@ -20,8 +20,7 @@
|
|||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
|
|
||||||
struct mctp_dump_cb {
|
struct mctp_dump_cb {
|
||||||
int h;
|
unsigned long ifindex;
|
||||||
int idx;
|
|
||||||
size_t a_idx;
|
size_t a_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,43 +114,29 @@ static int mctp_dump_addrinfo(struct sk_buff *skb, struct netlink_callback *cb)
|
|||||||
{
|
{
|
||||||
struct mctp_dump_cb *mcb = (void *)cb->ctx;
|
struct mctp_dump_cb *mcb = (void *)cb->ctx;
|
||||||
struct net *net = sock_net(skb->sk);
|
struct net *net = sock_net(skb->sk);
|
||||||
struct hlist_head *head;
|
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct ifaddrmsg *hdr;
|
struct ifaddrmsg *hdr;
|
||||||
struct mctp_dev *mdev;
|
struct mctp_dev *mdev;
|
||||||
int ifindex;
|
int ifindex, rc;
|
||||||
int idx = 0, rc;
|
|
||||||
|
|
||||||
hdr = nlmsg_data(cb->nlh);
|
hdr = nlmsg_data(cb->nlh);
|
||||||
// filter by ifindex if requested
|
// filter by ifindex if requested
|
||||||
ifindex = hdr->ifa_index;
|
ifindex = hdr->ifa_index;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
for (; mcb->h < NETDEV_HASHENTRIES; mcb->h++, mcb->idx = 0) {
|
for_each_netdev_dump(net, dev, mcb->ifindex) {
|
||||||
idx = 0;
|
if (ifindex && ifindex != dev->ifindex)
|
||||||
head = &net->dev_index_head[mcb->h];
|
continue;
|
||||||
hlist_for_each_entry_rcu(dev, head, index_hlist) {
|
mdev = __mctp_dev_get(dev);
|
||||||
if (idx >= mcb->idx &&
|
if (!mdev)
|
||||||
(ifindex == 0 || ifindex == dev->ifindex)) {
|
continue;
|
||||||
mdev = __mctp_dev_get(dev);
|
rc = mctp_dump_dev_addrinfo(mdev, skb, cb);
|
||||||
if (mdev) {
|
mctp_dev_put(mdev);
|
||||||
rc = mctp_dump_dev_addrinfo(mdev,
|
if (rc < 0)
|
||||||
skb, cb);
|
break;
|
||||||
mctp_dev_put(mdev);
|
mcb->a_idx = 0;
|
||||||
// Error indicates full buffer, this
|
|
||||||
// callback will get retried.
|
|
||||||
if (rc < 0)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
idx++;
|
|
||||||
// reset for next iteration
|
|
||||||
mcb->a_idx = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
mcb->idx = idx;
|
|
||||||
|
|
||||||
return skb->len;
|
return skb->len;
|
||||||
}
|
}
|
||||||
@@ -525,9 +510,12 @@ static struct notifier_block mctp_dev_nb = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct rtnl_msg_handler mctp_device_rtnl_msg_handlers[] = {
|
static const struct rtnl_msg_handler mctp_device_rtnl_msg_handlers[] = {
|
||||||
{THIS_MODULE, PF_MCTP, RTM_NEWADDR, mctp_rtm_newaddr, NULL, 0},
|
{.owner = THIS_MODULE, .protocol = PF_MCTP, .msgtype = RTM_NEWADDR,
|
||||||
{THIS_MODULE, PF_MCTP, RTM_DELADDR, mctp_rtm_deladdr, NULL, 0},
|
.doit = mctp_rtm_newaddr},
|
||||||
{THIS_MODULE, PF_MCTP, RTM_GETADDR, NULL, mctp_dump_addrinfo, 0},
|
{.owner = THIS_MODULE, .protocol = PF_MCTP, .msgtype = RTM_DELADDR,
|
||||||
|
.doit = mctp_rtm_deladdr},
|
||||||
|
{.owner = THIS_MODULE, .protocol = PF_MCTP, .msgtype = RTM_GETADDR,
|
||||||
|
.dumpit = mctp_dump_addrinfo},
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init mctp_device_init(void)
|
int __init mctp_device_init(void)
|
||||||
|
Reference in New Issue
Block a user