Commit 36226a8d authored by Brian Braunstein's avatar Brian Braunstein Committed by David S. Miller

[NET] tun/tap: fixed hw address handling

Fixed tun/tap driver's handling of hw addresses.  The hw address is stored
in both the net_device.dev_addr and tun.dev_addr fields.  These fields were
not kept synchronized, and in fact weren't even initialized to the same
value.  Now during both init and when performing SIOCSIFHWADDR on the tun
device these values are both updated.  However, if SIOCSIFHWADDR is
performed on the net device directly (for instance, setting the hw address
using ifconfig), the tun device does not get updated.  Perhaps the
tun.dev_addr field should be removed completely at some point, as it is
redundant and net_device.dev_addr can be used anywhere it is used.
Signed-off-by: default avatarBrian Braunstein <linuxkernel@bristyle.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 48491e6b
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
/* /*
* Changes: * Changes:
* *
* Brian Braunstein <linuxkernel@bristyle.com> 2007/03/23
* Fixed hw address handling. Now net_device.dev_addr is kept consistent
* with tun.dev_addr when the address is set by this module.
*
* Mike Kershaw <dragorn@kismetwireless.net> 2005/08/14 * Mike Kershaw <dragorn@kismetwireless.net> 2005/08/14
* Add TUNSETLINK ioctl to set the link encapsulation * Add TUNSETLINK ioctl to set the link encapsulation
* *
...@@ -196,7 +200,10 @@ static void tun_net_init(struct net_device *dev) ...@@ -196,7 +200,10 @@ static void tun_net_init(struct net_device *dev)
dev->set_multicast_list = tun_net_mclist; dev->set_multicast_list = tun_net_mclist;
ether_setup(dev); ether_setup(dev);
random_ether_addr(dev->dev_addr);
/* random address already created for us by tun_set_iff, use it */
memcpy(dev->dev_addr, tun->dev_addr, min(sizeof(tun->dev_addr), sizeof(dev->dev_addr)) );
dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */ dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */
break; break;
} }
...@@ -636,6 +643,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, ...@@ -636,6 +643,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
return 0; return 0;
case SIOCGIFHWADDR: case SIOCGIFHWADDR:
/* Note: the actual net device's address may be different */
memcpy(ifr.ifr_hwaddr.sa_data, tun->dev_addr, memcpy(ifr.ifr_hwaddr.sa_data, tun->dev_addr,
min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr)); min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
if (copy_to_user( argp, &ifr, sizeof ifr)) if (copy_to_user( argp, &ifr, sizeof ifr))
...@@ -643,16 +651,24 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, ...@@ -643,16 +651,24 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
return 0; return 0;
case SIOCSIFHWADDR: case SIOCSIFHWADDR:
/** Set the character device's hardware address. This is used when {
* filtering packets being sent from the network device to the character /* try to set the actual net device's hw address */
* device. */ int ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
memcpy(tun->dev_addr, ifr.ifr_hwaddr.sa_data,
min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr)); if (ret == 0) {
DBG(KERN_DEBUG "%s: set hardware address: %x:%x:%x:%x:%x:%x\n", /** Set the character device's hardware address. This is used when
tun->dev->name, * filtering packets being sent from the network device to the character
tun->dev_addr[0], tun->dev_addr[1], tun->dev_addr[2], * device. */
tun->dev_addr[3], tun->dev_addr[4], tun->dev_addr[5]); memcpy(tun->dev_addr, ifr.ifr_hwaddr.sa_data,
return 0; min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
DBG(KERN_DEBUG "%s: set hardware address: %x:%x:%x:%x:%x:%x\n",
tun->dev->name,
tun->dev_addr[0], tun->dev_addr[1], tun->dev_addr[2],
tun->dev_addr[3], tun->dev_addr[4], tun->dev_addr[5]);
}
return ret;
}
case SIOCADDMULTI: case SIOCADDMULTI:
/** Add the specified group to the character device's multicast filter /** Add the specified group to the character device's multicast filter
......
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