.notifier_call = br_device_event
};
+/* called with RTNL */
static int br_netdev_switch_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
struct netdev_switch_notifier_fdb_info *fdb_info;
int err = NOTIFY_DONE;
- rtnl_lock();
p = br_port_get_rtnl(dev);
if (!p)
goto out;
}
out:
- rtnl_unlock();
return err;
}
#include <linux/mutex.h>
#include <linux/notifier.h>
#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
#include <net/ip_fib.h>
#include <net/switchdev.h>
}
EXPORT_SYMBOL_GPL(netdev_switch_port_stp_update);
-static DEFINE_MUTEX(netdev_switch_mutex);
static RAW_NOTIFIER_HEAD(netdev_switch_notif_chain);
/**
{
int err;
- mutex_lock(&netdev_switch_mutex);
+ rtnl_lock();
err = raw_notifier_chain_register(&netdev_switch_notif_chain, nb);
- mutex_unlock(&netdev_switch_mutex);
+ rtnl_unlock();
return err;
}
EXPORT_SYMBOL_GPL(register_netdev_switch_notifier);
{
int err;
- mutex_lock(&netdev_switch_mutex);
+ rtnl_lock();
err = raw_notifier_chain_unregister(&netdev_switch_notif_chain, nb);
- mutex_unlock(&netdev_switch_mutex);
+ rtnl_unlock();
return err;
}
EXPORT_SYMBOL_GPL(unregister_netdev_switch_notifier);
* Call all network notifier blocks. This should be called by driver
* when it needs to propagate hardware event.
* Return values are same as for atomic_notifier_call_chain().
+ * rtnl_lock must be held.
*/
int call_netdev_switch_notifiers(unsigned long val, struct net_device *dev,
struct netdev_switch_notifier_info *info)
{
int err;
+ ASSERT_RTNL();
+
info->dev = dev;
- mutex_lock(&netdev_switch_mutex);
err = raw_notifier_call_chain(&netdev_switch_notif_chain, val, info);
- mutex_unlock(&netdev_switch_mutex);
return err;
}
EXPORT_SYMBOL_GPL(call_netdev_switch_notifiers);