Commit bada339ba24dee9e143bfb42e1dc61f146619846

Authored by Jeff Garzik
Committed by David S. Miller
1 parent c9927c2bf4

[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>

Showing 3 changed files with 20 additions and 5 deletions Side-by-side Diff

include/linux/netdevice.h
... ... @@ -669,6 +669,8 @@
669 669 #define HAVE_SET_MAC_ADDR
670 670 int (*set_mac_address)(struct net_device *dev,
671 671 void *addr);
  672 +#define HAVE_VALIDATE_ADDR
  673 + int (*validate_addr)(struct net_device *dev);
672 674 #define HAVE_PRIVATE_IOCTL
673 675 int (*do_ioctl)(struct net_device *dev,
674 676 struct ifreq *ifr, int cmd);
... ... @@ -1007,17 +1007,20 @@
1007 1007 * Call device private open method
1008 1008 */
1009 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 1015 ret = dev->open(dev);
1012   - if (ret)
1013   - clear_bit(__LINK_STATE_START, &dev->state);
1014   - }
1015 1016  
1016 1017 /*
1017 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 1025 * Set the flags.
1023 1026 */
... ... @@ -1038,6 +1041,7 @@
1038 1041 */
1039 1042 call_netdevice_notifiers(NETDEV_UP, dev);
1040 1043 }
  1044 +
1041 1045 return ret;
1042 1046 }
1043 1047  
... ... @@ -298,6 +298,14 @@
298 298 return 0;
299 299 }
300 300  
  301 +static 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 +
301 309 const struct header_ops eth_header_ops ____cacheline_aligned = {
302 310 .create = eth_header,
303 311 .parse = eth_header_parse,
... ... @@ -317,6 +325,7 @@
317 325  
318 326 dev->change_mtu = eth_change_mtu;
319 327 dev->set_mac_address = eth_mac_addr;
  328 + dev->validate_addr = eth_validate_addr;
320 329  
321 330 dev->type = ARPHRD_ETHER;
322 331 dev->hard_header_len = ETH_HLEN;