aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
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