Commit 2c698bab authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Jakub Kicinski
Browse files

ipmr: Convert ipmr_rtm_dumproute() to RCU.



ipmr_rtm_dumproute() calls mr_table_dump() or mr_rtm_dumproute(),
and mr_rtm_dumproute() finally calls mr_table_dump().

mr_table_dump() calls the passed function, _ipmr_fill_mroute().

_ipmr_fill_mroute() is a wrapper of ipmr_fill_mroute() to cast
struct mr_mfc * to struct mfc_cache *.

ipmr_fill_mroute() can be already called safely under RCU.

Let's convert ipmr_rtm_dumproute() to RCU.

Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260228221800.1082070-7-kuniyu@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 295a17b3
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -2736,15 +2736,17 @@ static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct fib_dump_filter filter = {
		.rtnl_held = true,
		.rtnl_held = false,
	};
	int err;

	rcu_read_lock();

	if (cb->strict_check) {
		err = ip_valid_fib_dump_req(sock_net(skb->sk), cb->nlh,
					    &filter, cb);
		if (err < 0)
			return err;
			goto out;
	}

	if (filter.table_id) {
@@ -2752,19 +2754,28 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)

		mrt = __ipmr_get_table(sock_net(skb->sk), filter.table_id);
		if (!mrt) {
			if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IPMR)
				return skb->len;
			if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IPMR) {
				err = skb->len;
				goto out;
			}

			NL_SET_ERR_MSG(cb->extack, "ipv4: MR table does not exist");
			return -ENOENT;
			err = -ENOENT;
			goto out;
		}

		err = mr_table_dump(mrt, skb, cb, _ipmr_fill_mroute,
				    &mfc_unres_lock, &filter);
		return skb->len ? : err;
		err = skb->len ? : err;
		goto out;
	}

	return mr_rtm_dumproute(skb, cb, ipmr_mr_table_iter,
	err = mr_rtm_dumproute(skb, cb, ipmr_mr_table_iter,
			       _ipmr_fill_mroute, &mfc_unres_lock, &filter);
out:
	rcu_read_unlock();

	return err;
}

static const struct nla_policy rtm_ipmr_policy[RTA_MAX + 1] = {
@@ -3299,7 +3310,7 @@ static const struct rtnl_msg_handler ipmr_rtnl_msg_handlers[] __initconst = {
	 .doit = ipmr_rtm_route},
	{.protocol = RTNL_FAMILY_IPMR, .msgtype = RTM_GETROUTE,
	 .doit = ipmr_rtm_getroute, .dumpit = ipmr_rtm_dumproute,
	 .flags = RTNL_FLAG_DOIT_UNLOCKED},
	 .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED},
};

int __init ip_mr_init(void)