Commit b7d2fc9a authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Paolo Abeni
Browse files

phonet: Don't hold RTNL for getaddr_dumpit().



getaddr_dumpit() already relies on RCU and does not need RTNL.

Let's use READ_ONCE() for ifindex and register getaddr_dumpit()
with RTNL_FLAG_DUMP_UNLOCKED.

While at it, the retval of getaddr_dumpit() is changed to combine
NLMSG_DONE and save recvmsg() as done in 58a4ff5d ("phonet: no
longer hold RTNL in route_dumpit()").

Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 8786e98d
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -127,14 +127,17 @@ static int fill_addr(struct sk_buff *skb, u32 ifindex, u8 addr,

static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{
	int addr_idx = 0, addr_start_idx = cb->args[1];
	int dev_idx = 0, dev_start_idx = cb->args[0];
	struct phonet_device_list *pndevs;
	struct phonet_device *pnd;
	int dev_idx = 0, dev_start_idx = cb->args[0];
	int addr_idx = 0, addr_start_idx = cb->args[1];
	int err = 0;

	pndevs = phonet_device_list(sock_net(skb->sk));

	rcu_read_lock();
	list_for_each_entry_rcu(pnd, &pndevs->list, list) {
		DECLARE_BITMAP(addrs, 64);
		u8 addr;

		if (dev_idx > dev_start_idx)
@@ -143,23 +146,26 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
			continue;

		addr_idx = 0;
		for_each_set_bit(addr, pnd->addrs, 64) {
		memcpy(addrs, pnd->addrs, sizeof(pnd->addrs));

		for_each_set_bit(addr, addrs, 64) {
			if (addr_idx++ < addr_start_idx)
				continue;

			if (fill_addr(skb, pnd->netdev->ifindex, addr << 2,
					 NETLINK_CB(cb->skb).portid,
					cb->nlh->nlmsg_seq, RTM_NEWADDR) < 0)
			err = fill_addr(skb, READ_ONCE(pnd->netdev->ifindex),
					addr << 2, NETLINK_CB(cb->skb).portid,
					cb->nlh->nlmsg_seq, RTM_NEWADDR);
			if (err < 0)
				goto out;
		}
	}

out:
	rcu_read_unlock();

	cb->args[0] = dev_idx;
	cb->args[1] = addr_idx;

	return skb->len;
	return err;
}

/* Routes handling */
@@ -298,7 +304,7 @@ static const struct rtnl_msg_handler phonet_rtnl_msg_handlers[] __initdata_or_mo
	{.owner = THIS_MODULE, .protocol = PF_PHONET, .msgtype = RTM_DELADDR,
	 .doit = addr_doit, .flags = RTNL_FLAG_DOIT_UNLOCKED},
	{.owner = THIS_MODULE, .protocol = PF_PHONET, .msgtype = RTM_GETADDR,
	 .dumpit = getaddr_dumpit},
	 .dumpit = getaddr_dumpit, .flags = RTNL_FLAG_DUMP_UNLOCKED},
	{.owner = THIS_MODULE, .protocol = PF_PHONET, .msgtype = RTM_NEWROUTE,
	 .doit = route_doit},
	{.owner = THIS_MODULE, .protocol = PF_PHONET, .msgtype = RTM_DELROUTE,