if (nla_put_u32(skb, IPMRA_TABLE_ID, mrt->id) ||
nla_put_u32(skb, IPMRA_TABLE_CACHE_RES_QUEUE_LEN, queue_len) ||
nla_put_s32(skb, IPMRA_TABLE_MROUTE_REG_VIF_NUM,
- mrt->mroute_reg_vif_num) ||
+ READ_ONCE(mrt->mroute_reg_vif_num)) ||
nla_put_u8(skb, IPMRA_TABLE_MROUTE_DO_ASSERT,
- mrt->mroute_do_assert) ||
- nla_put_u8(skb, IPMRA_TABLE_MROUTE_DO_PIM, mrt->mroute_do_pim) ||
+ READ_ONCE(mrt->mroute_do_assert)) ||
+ nla_put_u8(skb, IPMRA_TABLE_MROUTE_DO_PIM,
+ READ_ONCE(mrt->mroute_do_pim)) ||
nla_put_u8(skb, IPMRA_TABLE_MROUTE_DO_WRVIFWHOLE,
- mrt->mroute_do_wrvifwhole))
+ READ_ONCE(mrt->mroute_do_wrvifwhole)))
return false;
return true;
struct vif_device *vif;
vif = &mrt->vif_table[vifid];
- vif_dev = rtnl_dereference(vif->dev);
+ vif_dev = vif_dev_read(vif);
/* if the VIF doesn't exist just continue */
if (!vif_dev)
return true;
if (!vif_nest)
return false;
- if (nla_put_u32(skb, IPMRA_VIFA_IFINDEX, vif_dev->ifindex) ||
+ if (nla_put_u32(skb, IPMRA_VIFA_IFINDEX, READ_ONCE(vif_dev->ifindex)) ||
nla_put_u32(skb, IPMRA_VIFA_VIF_ID, vifid) ||
nla_put_u16(skb, IPMRA_VIFA_FLAGS, vif->flags) ||
- nla_put_u64_64bit(skb, IPMRA_VIFA_BYTES_IN, vif->bytes_in,
+ nla_put_u64_64bit(skb, IPMRA_VIFA_BYTES_IN, READ_ONCE(vif->bytes_in),
IPMRA_VIFA_PAD) ||
- nla_put_u64_64bit(skb, IPMRA_VIFA_BYTES_OUT, vif->bytes_out,
+ nla_put_u64_64bit(skb, IPMRA_VIFA_BYTES_OUT, READ_ONCE(vif->bytes_out),
IPMRA_VIFA_PAD) ||
- nla_put_u64_64bit(skb, IPMRA_VIFA_PACKETS_IN, vif->pkt_in,
+ nla_put_u64_64bit(skb, IPMRA_VIFA_PACKETS_IN, READ_ONCE(vif->pkt_in),
IPMRA_VIFA_PAD) ||
- nla_put_u64_64bit(skb, IPMRA_VIFA_PACKETS_OUT, vif->pkt_out,
+ nla_put_u64_64bit(skb, IPMRA_VIFA_PACKETS_OUT, READ_ONCE(vif->pkt_out),
IPMRA_VIFA_PAD) ||
nla_put_be32(skb, IPMRA_VIFA_LOCAL_ADDR, vif->local) ||
nla_put_be32(skb, IPMRA_VIFA_REMOTE_ADDR, vif->remote)) {
s_t = cb->args[0];
s_e = cb->args[1];
+ rcu_read_lock();
+
ipmr_for_each_table(mrt, net) {
struct nlattr *vifs, *af;
struct ifinfomsg *hdr;
nlmsg_end(skb, nlh);
goto out;
}
- for (i = 0; i < mrt->maxvif; i++) {
+ for (i = 0; i < READ_ONCE(mrt->maxvif); i++) {
if (e < s_e)
goto skip_entry;
if (!ipmr_fill_vif(mrt, i, skb)) {
}
out:
+ rcu_read_unlock();
+
cb->args[1] = e;
cb->args[0] = t;
static const struct rtnl_msg_handler ipmr_rtnl_msg_handlers[] __initconst = {
{.protocol = RTNL_FAMILY_IPMR, .msgtype = RTM_GETLINK,
- .dumpit = ipmr_rtm_dumplink},
+ .dumpit = ipmr_rtm_dumplink, .flags = RTNL_FLAG_DUMP_UNLOCKED},
{.protocol = RTNL_FAMILY_IPMR, .msgtype = RTM_NEWROUTE,
.doit = ipmr_rtm_route},
{.protocol = RTNL_FAMILY_IPMR, .msgtype = RTM_DELROUTE,