Commit 573c7ba0 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

net: introduce pre-change upper device notifier

This newly introduced netdevice notifier is called before actual change
upper happens. That provides a possibility for notifier handlers to
know upper change will happen and react to it, including possibility to
forbid the change. That is valuable for drivers which can check if the
upper device linkage is supported and forbid that in case it is not.
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 125ecf4b
...@@ -2106,6 +2106,7 @@ struct pcpu_sw_netstats { ...@@ -2106,6 +2106,7 @@ struct pcpu_sw_netstats {
#define NETDEV_PRECHANGEMTU 0x0017 /* notify before mtu change happened */ #define NETDEV_PRECHANGEMTU 0x0017 /* notify before mtu change happened */
#define NETDEV_CHANGEINFODATA 0x0018 #define NETDEV_CHANGEINFODATA 0x0018
#define NETDEV_BONDING_INFO 0x0019 #define NETDEV_BONDING_INFO 0x0019
#define NETDEV_PRECHANGEUPPER 0x001A
int register_netdevice_notifier(struct notifier_block *nb); int register_netdevice_notifier(struct notifier_block *nb);
int unregister_netdevice_notifier(struct notifier_block *nb); int unregister_netdevice_notifier(struct notifier_block *nb);
......
...@@ -5346,6 +5346,12 @@ static int __netdev_upper_dev_link(struct net_device *dev, ...@@ -5346,6 +5346,12 @@ static int __netdev_upper_dev_link(struct net_device *dev,
changeupper_info.master = master; changeupper_info.master = master;
changeupper_info.linking = true; changeupper_info.linking = true;
ret = call_netdevice_notifiers_info(NETDEV_PRECHANGEUPPER, dev,
&changeupper_info.info);
ret = notifier_to_errno(ret);
if (ret)
return ret;
ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, private, ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, private,
master); master);
if (ret) if (ret)
...@@ -5488,6 +5494,9 @@ void netdev_upper_dev_unlink(struct net_device *dev, ...@@ -5488,6 +5494,9 @@ void netdev_upper_dev_unlink(struct net_device *dev,
changeupper_info.master = netdev_master_upper_dev_get(dev) == upper_dev; changeupper_info.master = netdev_master_upper_dev_get(dev) == upper_dev;
changeupper_info.linking = false; changeupper_info.linking = false;
call_netdevice_notifiers_info(NETDEV_PRECHANGEUPPER, dev,
&changeupper_info.info);
__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev); __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
/* Here is the tricky part. We must remove all dev's lower /* Here is the tricky part. We must remove all dev's lower
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment