mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
ip6mr: Annotate access to mrt->mroute_do_{pim,assert,wrvifwhole}.
These fields in struct mr_table are updated in ip6_mroute_setsockopt() under RTNL: * mroute_do_pim * mroute_do_assert (MRT6_PIM is under RTNL while MRT6_ASSERT is lockless) * mroute_do_wrvifwhole However, ip6_mroute_getsockopt() does not hold RTNL and read the first two fields locklessly, and ip6_mr_forward() reads all the three under RCU. Let's use WRITE_ONCE() and READ_ONCE() for them. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260604224712.3209821-3-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
e02bf5e7aa
commit
364568de4e
|
|
@ -1778,7 +1778,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval,
|
|||
return -EINVAL;
|
||||
if (copy_from_sockptr(&v, optval, sizeof(v)))
|
||||
return -EFAULT;
|
||||
mrt->mroute_do_assert = v;
|
||||
WRITE_ONCE(mrt->mroute_do_assert, v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1798,9 +1798,9 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval,
|
|||
rtnl_lock();
|
||||
ret = 0;
|
||||
if (v != mrt->mroute_do_pim) {
|
||||
mrt->mroute_do_pim = v;
|
||||
mrt->mroute_do_assert = v;
|
||||
mrt->mroute_do_wrvifwhole = do_wrmifwhole;
|
||||
WRITE_ONCE(mrt->mroute_do_pim, v);
|
||||
WRITE_ONCE(mrt->mroute_do_assert, v);
|
||||
WRITE_ONCE(mrt->mroute_do_wrvifwhole, do_wrmifwhole);
|
||||
}
|
||||
rtnl_unlock();
|
||||
return ret;
|
||||
|
|
@ -1868,11 +1868,11 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval,
|
|||
break;
|
||||
#ifdef CONFIG_IPV6_PIMSM_V2
|
||||
case MRT6_PIM:
|
||||
val = mrt->mroute_do_pim;
|
||||
val = READ_ONCE(mrt->mroute_do_pim);
|
||||
break;
|
||||
#endif
|
||||
case MRT6_ASSERT:
|
||||
val = mrt->mroute_do_assert;
|
||||
val = READ_ONCE(mrt->mroute_do_assert);
|
||||
break;
|
||||
default:
|
||||
return -ENOPROTOOPT;
|
||||
|
|
@ -2175,20 +2175,20 @@ static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
|
|||
if (rcu_access_pointer(mrt->vif_table[vif].dev) != dev) {
|
||||
atomic_long_inc(&c->_c.mfc_un.res.wrong_if);
|
||||
|
||||
if (true_vifi >= 0 && mrt->mroute_do_assert &&
|
||||
if (true_vifi >= 0 && READ_ONCE(mrt->mroute_do_assert) &&
|
||||
/* pimsm uses asserts, when switching from RPT to SPT,
|
||||
so that we cannot check that packet arrived on an oif.
|
||||
It is bad, but otherwise we would need to move pretty
|
||||
large chunk of pimd to kernel. Ough... --ANK
|
||||
*/
|
||||
(mrt->mroute_do_pim ||
|
||||
(READ_ONCE(mrt->mroute_do_pim) ||
|
||||
c->_c.mfc_un.res.ttls[true_vifi] < 255) &&
|
||||
time_after(jiffies,
|
||||
c->_c.mfc_un.res.last_assert +
|
||||
MFC_ASSERT_THRESH)) {
|
||||
c->_c.mfc_un.res.last_assert = jiffies;
|
||||
ip6mr_cache_report(mrt, skb, true_vifi, MRT6MSG_WRONGMIF);
|
||||
if (mrt->mroute_do_wrvifwhole)
|
||||
if (READ_ONCE(mrt->mroute_do_wrvifwhole))
|
||||
ip6mr_cache_report(mrt, skb, true_vifi,
|
||||
MRT6MSG_WRMIFWHOLE);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user