From 4c13eb6657fe9ef7b4dc8f1a405c902e9e5234e0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 25 Apr 2007 17:40:23 -0700 Subject: [ETH]: Make eth_type_trans set skb->dev like the other *_type_trans One less thing for drivers writers to worry about. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 5643d1e84ed6..a57aa010cb25 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -254,11 +254,11 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, return -EFAULT; } - skb->dev = tun->dev; switch (tun->flags & TUN_TYPE_MASK) { case TUN_TUN_DEV: skb->mac.raw = skb->data; skb->protocol = pi.proto; + skb->dev = tun->dev; break; case TUN_TAP_DEV: skb->protocol = eth_type_trans(skb, tun->dev); -- cgit v1.2.1 From 459a98ed881802dee55897441bc7f77af614368e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Mar 2007 15:30:44 -0700 Subject: [SK_BUFF]: Introduce skb_reset_mac_header(skb) For the common, open coded 'skb->mac.raw = skb->data' operation, so that we can later turn skb->mac.raw into a offset, reducing the size of struct sk_buff in 64bit land while possibly keeping it as a pointer on 32bit. This one touches just the most simple case, next will handle the slightly more "complex" cases. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a57aa010cb25..288d8559f8c5 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -256,7 +256,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, switch (tun->flags & TUN_TYPE_MASK) { case TUN_TUN_DEV: - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); skb->protocol = pi.proto; skb->dev = tun->dev; break; -- cgit v1.2.1 From d626f62b11e00c16e81e4308ab93d3f13551812a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 27 Mar 2007 18:55:52 -0300 Subject: [SK_BUFF]: Introduce skb_copy_from_linear_data{_offset} To clearly state the intent of copying from linear sk_buffs, _offset being a overly long variant but interesting for the sake of saving some bytes. Signed-off-by: Arnaldo Carvalho de Melo --- drivers/net/tun.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 288d8559f8c5..4d461595406d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -386,8 +386,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, * - we are multicast promiscous. * - we belong to the multicast group. */ - memcpy(addr, skb->data, - min_t(size_t, sizeof addr, skb->len)); + skb_copy_from_linear_data(skb, addr, min_t(size_t, sizeof addr, + skb->len)); bit_nr = ether_crc(sizeof addr, addr) >> 26; if ((tun->if_flags & IFF_PROMISC) || memcmp(addr, tun->dev_addr, sizeof addr) == 0 || -- cgit v1.2.1 From 36226a8ded46b89a94f9de5976f554bb5e02d84c Mon Sep 17 00:00:00 2001 From: Brian Braunstein Date: Thu, 26 Apr 2007 01:00:55 -0700 Subject: [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 Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/tun.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'drivers/net/tun.c') 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 @@ /* * Changes: * + * Brian Braunstein 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 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 -- cgit v1.2.1