Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260228221800.1082070-7-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kuniyuki Iwashima and committed by
Jakub Kicinski
2c698bab 295a17b3

+20 -9
+20 -9
net/ipv4/ipmr.c
··· 2736 2736 static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) 2737 2737 { 2738 2738 struct fib_dump_filter filter = { 2739 - .rtnl_held = true, 2739 + .rtnl_held = false, 2740 2740 }; 2741 2741 int err; 2742 + 2743 + rcu_read_lock(); 2742 2744 2743 2745 if (cb->strict_check) { 2744 2746 err = ip_valid_fib_dump_req(sock_net(skb->sk), cb->nlh, 2745 2747 &filter, cb); 2746 2748 if (err < 0) 2747 - return err; 2749 + goto out; 2748 2750 } 2749 2751 2750 2752 if (filter.table_id) { ··· 2754 2752 2755 2753 mrt = __ipmr_get_table(sock_net(skb->sk), filter.table_id); 2756 2754 if (!mrt) { 2757 - if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IPMR) 2758 - return skb->len; 2755 + if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IPMR) { 2756 + err = skb->len; 2757 + goto out; 2758 + } 2759 2759 2760 2760 NL_SET_ERR_MSG(cb->extack, "ipv4: MR table does not exist"); 2761 - return -ENOENT; 2761 + err = -ENOENT; 2762 + goto out; 2762 2763 } 2764 + 2763 2765 err = mr_table_dump(mrt, skb, cb, _ipmr_fill_mroute, 2764 2766 &mfc_unres_lock, &filter); 2765 - return skb->len ? : err; 2767 + err = skb->len ? : err; 2768 + goto out; 2766 2769 } 2767 2770 2768 - return mr_rtm_dumproute(skb, cb, ipmr_mr_table_iter, 2769 - _ipmr_fill_mroute, &mfc_unres_lock, &filter); 2771 + err = mr_rtm_dumproute(skb, cb, ipmr_mr_table_iter, 2772 + _ipmr_fill_mroute, &mfc_unres_lock, &filter); 2773 + out: 2774 + rcu_read_unlock(); 2775 + 2776 + return err; 2770 2777 } 2771 2778 2772 2779 static const struct nla_policy rtm_ipmr_policy[RTA_MAX + 1] = { ··· 3310 3299 .doit = ipmr_rtm_route}, 3311 3300 {.protocol = RTNL_FAMILY_IPMR, .msgtype = RTM_GETROUTE, 3312 3301 .doit = ipmr_rtm_getroute, .dumpit = ipmr_rtm_dumproute, 3313 - .flags = RTNL_FLAG_DOIT_UNLOCKED}, 3302 + .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED}, 3314 3303 }; 3315 3304 3316 3305 int __init ip_mr_init(void)