aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Machata <petrm@mellanox.com>2018-12-13 06:54:35 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-13 21:41:38 -0500
commitd59cdf9475ad84d1f57cab1d162cf289702cfb15 (patch)
tree192e3f68684228dda9a057f8ff49caf6974892f3
parent1570415f0810fce085066fb39827397452c3965a (diff)
net: dev: Issue NETDEV_PRE_CHANGEADDR
When a device address is about to be changed, or an address added to the list of device HW addresses, it is necessary to ensure that all interested parties can support the address. Therefore, send the NETDEV_PRE_CHANGEADDR notification, and if anyone bails on it, do not change the address. Signed-off-by: Petr Machata <petrm@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--net/core/dev.c24
-rw-r--r--net/core/dev_addr_lists.c3
3 files changed, 29 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 1d5ad053ccf7..811632d4d8b1 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3634,6 +3634,8 @@ int dev_set_mtu_ext(struct net_device *dev, int mtu,
3634int dev_set_mtu(struct net_device *, int); 3634int dev_set_mtu(struct net_device *, int);
3635int dev_change_tx_queue_len(struct net_device *, unsigned long); 3635int dev_change_tx_queue_len(struct net_device *, unsigned long);
3636void dev_set_group(struct net_device *, int); 3636void dev_set_group(struct net_device *, int);
3637int dev_pre_changeaddr_notify(struct net_device *dev, const char *addr,
3638 struct netlink_ext_ack *extack);
3637int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa, 3639int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
3638 struct netlink_ext_ack *extack); 3640 struct netlink_ext_ack *extack);
3639int dev_change_carrier(struct net_device *, bool new_carrier); 3641int dev_change_carrier(struct net_device *, bool new_carrier);
diff --git a/net/core/dev.c b/net/core/dev.c
index 01497b7d1bdf..ed9aa4a91f1f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7757,6 +7757,27 @@ void dev_set_group(struct net_device *dev, int new_group)
7757EXPORT_SYMBOL(dev_set_group); 7757EXPORT_SYMBOL(dev_set_group);
7758 7758
7759/** 7759/**
7760 * dev_pre_changeaddr_notify - Call NETDEV_PRE_CHANGEADDR.
7761 * @dev: device
7762 * @addr: new address
7763 * @extack: netlink extended ack
7764 */
7765int dev_pre_changeaddr_notify(struct net_device *dev, const char *addr,
7766 struct netlink_ext_ack *extack)
7767{
7768 struct netdev_notifier_pre_changeaddr_info info = {
7769 .info.dev = dev,
7770 .info.extack = extack,
7771 .dev_addr = addr,
7772 };
7773 int rc;
7774
7775 rc = call_netdevice_notifiers_info(NETDEV_PRE_CHANGEADDR, &info.info);
7776 return notifier_to_errno(rc);
7777}
7778EXPORT_SYMBOL(dev_pre_changeaddr_notify);
7779
7780/**
7760 * dev_set_mac_address - Change Media Access Control Address 7781 * dev_set_mac_address - Change Media Access Control Address
7761 * @dev: device 7782 * @dev: device
7762 * @sa: new address 7783 * @sa: new address
@@ -7776,6 +7797,9 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
7776 return -EINVAL; 7797 return -EINVAL;
7777 if (!netif_device_present(dev)) 7798 if (!netif_device_present(dev))
7778 return -ENODEV; 7799 return -ENODEV;
7800 err = dev_pre_changeaddr_notify(dev, sa->sa_data, extack);
7801 if (err)
7802 return err;
7779 err = ops->ndo_set_mac_address(dev, sa); 7803 err = ops->ndo_set_mac_address(dev, sa);
7780 if (err) 7804 if (err)
7781 return err; 7805 return err;
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 81a8cd4ea3bd..a6723b306717 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -498,6 +498,9 @@ int dev_addr_add(struct net_device *dev, const unsigned char *addr,
498 498
499 ASSERT_RTNL(); 499 ASSERT_RTNL();
500 500
501 err = dev_pre_changeaddr_notify(dev, addr, NULL);
502 if (err)
503 return err;
501 err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type); 504 err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type);
502 if (!err) 505 if (!err)
503 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); 506 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);