aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorBrian Braunstein <linuxkernel@bristyle.com>2007-04-26 04:00:55 -0400
committerDavid S. Miller <davem@davemloft.net>2007-04-26 04:00:55 -0400
commit36226a8ded46b89a94f9de5976f554bb5e02d84c (patch)
tree44fcfa54c6300dc2a843537cafb4a6f0d7075566 /drivers/net/tun.c
parent48491e6bdb8fa73751cc95f740175ec799db5d55 (diff)
[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: Brian Braunstein <linuxkernel@bristyle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 4d461595406d..a2c6caaaae93 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -18,6 +18,10 @@
18/* 18/*
19 * Changes: 19 * Changes:
20 * 20 *
21 * Brian Braunstein <linuxkernel@bristyle.com> 2007/03/23
22 * Fixed hw address handling. Now net_device.dev_addr is kept consistent
23 * with tun.dev_addr when the address is set by this module.
24 *
21 * Mike Kershaw <dragorn@kismetwireless.net> 2005/08/14 25 * Mike Kershaw <dragorn@kismetwireless.net> 2005/08/14
22 * Add TUNSETLINK ioctl to set the link encapsulation 26 * Add TUNSETLINK ioctl to set the link encapsulation
23 * 27 *
@@ -196,7 +200,10 @@ static void tun_net_init(struct net_device *dev)
196 dev->set_multicast_list = tun_net_mclist; 200 dev->set_multicast_list = tun_net_mclist;
197 201
198 ether_setup(dev); 202 ether_setup(dev);
199 random_ether_addr(dev->dev_addr); 203
204 /* random address already created for us by tun_set_iff, use it */
205 memcpy(dev->dev_addr, tun->dev_addr, min(sizeof(tun->dev_addr), sizeof(dev->dev_addr)) );
206
200 dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */ 207 dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */
201 break; 208 break;
202 } 209 }
@@ -636,6 +643,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
636 return 0; 643 return 0;
637 644
638 case SIOCGIFHWADDR: 645 case SIOCGIFHWADDR:
646 /* Note: the actual net device's address may be different */
639 memcpy(ifr.ifr_hwaddr.sa_data, tun->dev_addr, 647 memcpy(ifr.ifr_hwaddr.sa_data, tun->dev_addr,
640 min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr)); 648 min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
641 if (copy_to_user( argp, &ifr, sizeof ifr)) 649 if (copy_to_user( argp, &ifr, sizeof ifr))
@@ -643,16 +651,24 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
643 return 0; 651 return 0;
644 652
645 case SIOCSIFHWADDR: 653 case SIOCSIFHWADDR:
646 /** Set the character device's hardware address. This is used when 654 {
647 * filtering packets being sent from the network device to the character 655 /* try to set the actual net device's hw address */
648 * device. */ 656 int ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
649 memcpy(tun->dev_addr, ifr.ifr_hwaddr.sa_data, 657
650 min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr)); 658 if (ret == 0) {
651 DBG(KERN_DEBUG "%s: set hardware address: %x:%x:%x:%x:%x:%x\n", 659 /** Set the character device's hardware address. This is used when
652 tun->dev->name, 660 * filtering packets being sent from the network device to the character
653 tun->dev_addr[0], tun->dev_addr[1], tun->dev_addr[2], 661 * device. */
654 tun->dev_addr[3], tun->dev_addr[4], tun->dev_addr[5]); 662 memcpy(tun->dev_addr, ifr.ifr_hwaddr.sa_data,
655 return 0; 663 min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
664 DBG(KERN_DEBUG "%s: set hardware address: %x:%x:%x:%x:%x:%x\n",
665 tun->dev->name,
666 tun->dev_addr[0], tun->dev_addr[1], tun->dev_addr[2],
667 tun->dev_addr[3], tun->dev_addr[4], tun->dev_addr[5]);
668 }
669
670 return ret;
671 }
656 672
657 case SIOCADDMULTI: 673 case SIOCADDMULTI:
658 /** Add the specified group to the character device's multicast filter 674 /** Add the specified group to the character device's multicast filter