diff options
author | Jeff Garzik <jgarzik@redhat.com> | 2007-10-23 20:19:37 -0700 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-23 21:27:50 -0700 |
commit | bada339ba24dee9e143bfb42e1dc61f146619846 (patch) | |
tree | 69e14af15764a1b38d61cd1f0b55560e45779f23 | |
parent | c9927c2bf4f45bb85e8b502ab3fb79ad6483c244 (diff) |
[NET]: Validate device addr prior to interface-up
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netdevice.h | 2 | ||||
-rw-r--r-- | net/core/dev.c | 14 | ||||
-rw-r--r-- | net/ethernet/eth.c | 9 |
3 files changed, 20 insertions, 5 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c4de536cefa..811024e311b 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -669,6 +669,8 @@ struct net_device #define HAVE_SET_MAC_ADDR int (*set_mac_address)(struct net_device *dev, void *addr); +#define HAVE_VALIDATE_ADDR + int (*validate_addr)(struct net_device *dev); #define HAVE_PRIVATE_IOCTL int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); diff --git a/net/core/dev.c b/net/core/dev.c index 872658927e4..f861555cc52 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1007,17 +1007,20 @@ int dev_open(struct net_device *dev) * Call device private open method */ set_bit(__LINK_STATE_START, &dev->state); - if (dev->open) { + + if (dev->validate_addr) + ret = dev->validate_addr(dev); + + if (!ret && dev->open) ret = dev->open(dev); - if (ret) - clear_bit(__LINK_STATE_START, &dev->state); - } /* * If it went open OK then: */ - if (!ret) { + if (ret) + clear_bit(__LINK_STATE_START, &dev->state); + else { /* * Set the flags. */ @@ -1038,6 +1041,7 @@ int dev_open(struct net_device *dev) */ call_netdevice_notifiers(NETDEV_UP, dev); } + return ret; } diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index ed8a3d49487..6b2e454ae31 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -298,6 +298,14 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu) return 0; } +static int eth_validate_addr(struct net_device *dev) +{ + if (!is_valid_ether_addr(dev->dev_addr)) + return -EINVAL; + + return 0; +} + const struct header_ops eth_header_ops ____cacheline_aligned = { .create = eth_header, .parse = eth_header_parse, @@ -317,6 +325,7 @@ void ether_setup(struct net_device *dev) dev->change_mtu = eth_change_mtu; dev->set_mac_address = eth_mac_addr; + dev->validate_addr = eth_validate_addr; dev->type = ARPHRD_ETHER; dev->hard_header_len = ETH_HLEN; |