Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=36226a8ded46b89a94f9de5976f554bb5e02d84c
Commit:     36226a8ded46b89a94f9de5976f554bb5e02d84c
Parent:     48491e6bdb8fa73751cc95f740175ec799db5d55
Author:     Brian Braunstein <[EMAIL PROTECTED]>
AuthorDate: Thu Apr 26 01:00:55 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Thu Apr 26 01:00:55 2007 -0700

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 drivers/net/tun.c |   38 +++++++++++++++++++++++++++-----------
 1 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 4d46159..a2c6caa 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -18,6 +18,10 @@
 /*
  *  Changes:
  *
+ *  Brian Braunstein <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 2005/08/14
  *    Add TUNSETLINK ioctl to set the link encapsulation
  *
@@ -196,7 +200,10 @@ static void tun_net_init(struct net_device *dev)
                dev->set_multicast_list = tun_net_mclist;
 
                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 */
                break;
        }
@@ -636,6 +643,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file 
*file,
                return 0;
 
        case SIOCGIFHWADDR:
+               /* Note: the actual net device's address may be different */
                memcpy(ifr.ifr_hwaddr.sa_data, tun->dev_addr,
                                min(sizeof ifr.ifr_hwaddr.sa_data, sizeof 
tun->dev_addr));
                if (copy_to_user( argp, &ifr, sizeof ifr))
@@ -643,16 +651,24 @@ static int tun_chr_ioctl(struct inode *inode, struct file 
*file,
                return 0;
 
        case SIOCSIFHWADDR:
-               /** Set the character device's hardware address. This is used 
when
-                * filtering packets being sent from the network device to the 
character
-                * device. */
-               memcpy(tun->dev_addr, ifr.ifr_hwaddr.sa_data,
-                               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 0;
+       {
+               /* try to set the actual net device's hw address */
+               int ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
+
+               if (ret == 0) {
+                       /** Set the character device's hardware address. This 
is used when
+                        * filtering packets being sent from the network device 
to the character
+                        * device. */
+                       memcpy(tun->dev_addr, ifr.ifr_hwaddr.sa_data,
+                                       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:
                /** Add the specified group to the character device's multicast 
filter
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to