{
struct mfc6_cache *c;
- /* The entries are added/deleted only under RTNL */
rcu_read_lock();
c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
&mfc->mf6cc_mcastgrp.sin6_addr, parent);
#endif
int err;
+ mutex_init(&net->ipv6.mfc_mutex);
+
err = ip6mr_notifier_init(net);
if (err)
return err;
ttls[i] = 1;
}
- /* The entries are added/deleted only under RTNL */
rcu_read_lock();
c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
&mfc->mf6cc_mcastgrp.sin6_addr, parent);
/* Wipe the cache */
if (flags & (MRT6_FLUSH_MFC | MRT6_FLUSH_MFC_STATIC)) {
+ mutex_lock(&net->ipv6.mfc_mutex);
+
list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
if (((c->mfc_flags & MFC_STATIC) && !(flags & MRT6_FLUSH_MFC_STATIC)) ||
(!(c->mfc_flags & MFC_STATIC) && !(flags & MRT6_FLUSH_MFC)))
mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
mr_cache_put(c);
}
+
+ mutex_unlock(&net->ipv6.mfc_mutex);
}
if (flags & MRT6_FLUSH_MFC) {
return -EFAULT;
if (parent == 0)
parent = mfc.mf6cc_parent;
- rtnl_lock();
+
+ mutex_lock(&net->ipv6.mfc_mutex);
+
if (optname == MRT6_DEL_MFC || optname == MRT6_DEL_MFC_PROXY)
ret = ip6mr_mfc_delete(mrt, &mfc, parent);
else
ret = ip6mr_mfc_add(net, mrt, &mfc,
sk ==
- rtnl_dereference(mrt->mroute_sk),
+ rcu_access_pointer(mrt->mroute_sk),
parent);
- rtnl_unlock();
+
+ mutex_unlock(&net->ipv6.mfc_mutex);
return ret;
case MRT6_FLUSH: