aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@redhat.com>2007-10-23 23:19:37 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-24 00:27:50 -0400
commitbada339ba24dee9e143bfb42e1dc61f146619846 (patch)
tree69e14af15764a1b38d61cd1f0b55560e45779f23
parentc9927c2bf4f45bb85e8b502ab3fb79ad6483c244 (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.h2
-rw-r--r--net/core/dev.c14
-rw-r--r--net/ethernet/eth.c9
3 files changed, 20 insertions, 5 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c4de536cefa3..811024e311bd 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -669,6 +669,8 @@ struct net_device
669#define HAVE_SET_MAC_ADDR 669#define HAVE_SET_MAC_ADDR
670 int (*set_mac_address)(struct net_device *dev, 670 int (*set_mac_address)(struct net_device *dev,
671 void *addr); 671 void *addr);
672#define HAVE_VALIDATE_ADDR
673 int (*validate_addr)(struct net_device *dev);
672#define HAVE_PRIVATE_IOCTL 674#define HAVE_PRIVATE_IOCTL
673 int (*do_ioctl)(struct net_device *dev, 675 int (*do_ioctl)(struct net_device *dev,
674 struct ifreq *ifr, int cmd); 676 struct ifreq *ifr, int cmd);
diff --git a/net/core/dev.c b/net/core/dev.c
index 872658927e47..f861555cc525 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1007,17 +1007,20 @@ int dev_open(struct net_device *dev)
1007 * Call device private open method 1007 * Call device private open method
1008 */ 1008 */
1009 set_bit(__LINK_STATE_START, &dev->state); 1009 set_bit(__LINK_STATE_START, &dev->state);
1010 if (dev->open) { 1010
1011 if (dev->validate_addr)
1012 ret = dev->validate_addr(dev);
1013
1014 if (!ret && dev->open)
1011 ret = dev->open(dev); 1015 ret = dev->open(dev);
1012 if (ret)
1013 clear_bit(__LINK_STATE_START, &dev->state);
1014 }
1015 1016
1016 /* 1017 /*
1017 * If it went open OK then: 1018 * If it went open OK then:
1018 */ 1019 */
1019 1020
1020 if (!ret) { 1021 if (ret)
1022 clear_bit(__LINK_STATE_START, &dev->state);
1023 else {
1021 /* 1024 /*
1022 * Set the flags. 1025 * Set the flags.
1023 */ 1026 */
@@ -1038,6 +1041,7 @@ int dev_open(struct net_device *dev)
1038 */ 1041 */
1039 call_netdevice_notifiers(NETDEV_UP, dev); 1042 call_netdevice_notifiers(NETDEV_UP, dev);
1040 } 1043 }
1044
1041 return ret; 1045 return ret;
1042} 1046}
1043 1047
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index ed8a3d49487d..6b2e454ae313 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)
298 return 0; 298 return 0;
299} 299}
300 300
301static int eth_validate_addr(struct net_device *dev)
302{
303 if (!is_valid_ether_addr(dev->dev_addr))
304 return -EINVAL;
305
306 return 0;
307}
308
301const struct header_ops eth_header_ops ____cacheline_aligned = { 309const struct header_ops eth_header_ops ____cacheline_aligned = {
302 .create = eth_header, 310 .create = eth_header,
303 .parse = eth_header_parse, 311 .parse = eth_header_parse,
@@ -317,6 +325,7 @@ void ether_setup(struct net_device *dev)
317 325
318 dev->change_mtu = eth_change_mtu; 326 dev->change_mtu = eth_change_mtu;
319 dev->set_mac_address = eth_mac_addr; 327 dev->set_mac_address = eth_mac_addr;
328 dev->validate_addr = eth_validate_addr;
320 329
321 dev->type = ARPHRD_ETHER; 330 dev->type = ARPHRD_ETHER;
322 dev->hard_header_len = ETH_HLEN; 331 dev->hard_header_len = ETH_HLEN;