When destroying vports we account for two types of synchronization
mechanisms: RTNL and RCU. However, it is possible to call into
network device methods with just a device reference without either
of these. These device methods can use the datapath data structures
but we don't wait for all of the references to go away before freeing
the datapath. The actual wait happens in rtnl_unlock(), so by moving
up that call we can avoid the possibility of use after free with
internal devices.
Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
list_del(&dp->list_node);
dp_detach_port(get_vport_protected(dp, ODPP_LOCAL));
+ /* rtnl_unlock() will wait until all the references to devices that
+ * are pending unregistration have been dropped. We do it here to
+ * ensure that any internal devices (which contain DP pointers) are
+ * fully destroyed before freeing the datapath.
+ */
+ rtnl_unlock();
+
call_rcu(&dp->rcu, destroy_dp_rcu);
module_put(THIS_MODULE);
genl_notify(reply, genl_info_net(info), info->snd_pid,
dp_datapath_multicast_group.id, info->nlhdr, GFP_KERNEL);
- err = 0;
+
+ return 0;
exit_unlock:
rtnl_unlock();