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.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 33b6d1b122fb..d7b81e4fdd56 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -213,7 +213,7 @@ static int check_filter(struct tap_filter *filter, const struct sk_buff *skb)
213 213
214/* Network device part of the driver */ 214/* Network device part of the driver */
215 215
216static unsigned int tun_net_id; 216static int tun_net_id;
217struct tun_net { 217struct tun_net {
218 struct list_head dev_list; 218 struct list_head dev_list;
219}; 219};
@@ -305,6 +305,23 @@ tun_net_change_mtu(struct net_device *dev, int new_mtu)
305 return 0; 305 return 0;
306} 306}
307 307
308static const struct net_device_ops tun_netdev_ops = {
309 .ndo_open = tun_net_open,
310 .ndo_stop = tun_net_close,
311 .ndo_start_xmit = tun_net_xmit,
312 .ndo_change_mtu = tun_net_change_mtu,
313};
314
315static const struct net_device_ops tap_netdev_ops = {
316 .ndo_open = tun_net_open,
317 .ndo_stop = tun_net_close,
318 .ndo_start_xmit = tun_net_xmit,
319 .ndo_change_mtu = tun_net_change_mtu,
320 .ndo_set_multicast_list = tun_net_mclist,
321 .ndo_set_mac_address = eth_mac_addr,
322 .ndo_validate_addr = eth_validate_addr,
323};
324
308/* Initialize net device. */ 325/* Initialize net device. */
309static void tun_net_init(struct net_device *dev) 326static void tun_net_init(struct net_device *dev)
310{ 327{
@@ -312,11 +329,12 @@ static void tun_net_init(struct net_device *dev)
312 329
313 switch (tun->flags & TUN_TYPE_MASK) { 330 switch (tun->flags & TUN_TYPE_MASK) {
314 case TUN_TUN_DEV: 331 case TUN_TUN_DEV:
332 dev->netdev_ops = &tun_netdev_ops;
333
315 /* Point-to-Point TUN Device */ 334 /* Point-to-Point TUN Device */
316 dev->hard_header_len = 0; 335 dev->hard_header_len = 0;
317 dev->addr_len = 0; 336 dev->addr_len = 0;
318 dev->mtu = 1500; 337 dev->mtu = 1500;
319 dev->change_mtu = tun_net_change_mtu;
320 338
321 /* Zero header length */ 339 /* Zero header length */
322 dev->type = ARPHRD_NONE; 340 dev->type = ARPHRD_NONE;
@@ -325,10 +343,9 @@ static void tun_net_init(struct net_device *dev)
325 break; 343 break;
326 344
327 case TUN_TAP_DEV: 345 case TUN_TAP_DEV:
346 dev->netdev_ops = &tap_netdev_ops;
328 /* Ethernet TAP Device */ 347 /* Ethernet TAP Device */
329 ether_setup(dev); 348 ether_setup(dev);
330 dev->change_mtu = tun_net_change_mtu;
331 dev->set_multicast_list = tun_net_mclist;
332 349
333 random_ether_addr(dev->dev_addr); 350 random_ether_addr(dev->dev_addr);
334 351
@@ -529,7 +546,6 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
529 } 546 }
530 547
531 netif_rx_ni(skb); 548 netif_rx_ni(skb);
532 tun->dev->last_rx = jiffies;
533 549
534 tun->dev->stats.rx_packets++; 550 tun->dev->stats.rx_packets++;
535 tun->dev->stats.rx_bytes += len; 551 tun->dev->stats.rx_bytes += len;
@@ -676,9 +692,6 @@ static void tun_setup(struct net_device *dev)
676 tun->owner = -1; 692 tun->owner = -1;
677 tun->group = -1; 693 tun->group = -1;
678 694
679 dev->open = tun_net_open;
680 dev->hard_start_xmit = tun_net_xmit;
681 dev->stop = tun_net_close;
682 dev->ethtool_ops = &tun_ethtool_ops; 695 dev->ethtool_ops = &tun_ethtool_ops;
683 dev->destructor = free_netdev; 696 dev->destructor = free_netdev;
684 dev->features |= NETIF_F_NETNS_LOCAL; 697 dev->features |= NETIF_F_NETNS_LOCAL;
@@ -702,6 +715,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
702 struct tun_net *tn; 715 struct tun_net *tn;
703 struct tun_struct *tun; 716 struct tun_struct *tun;
704 struct net_device *dev; 717 struct net_device *dev;
718 const struct cred *cred = current_cred();
705 int err; 719 int err;
706 720
707 tn = net_generic(net, tun_net_id); 721 tn = net_generic(net, tun_net_id);
@@ -712,11 +726,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
712 726
713 /* Check permissions */ 727 /* Check permissions */
714 if (((tun->owner != -1 && 728 if (((tun->owner != -1 &&
715 current->euid != tun->owner) || 729 cred->euid != tun->owner) ||
716 (tun->group != -1 && 730 (tun->group != -1 &&
717 current->egid != tun->group)) && 731 cred->egid != tun->group)) &&
718 !capable(CAP_NET_ADMIN)) 732 !capable(CAP_NET_ADMIN)) {
719 return -EPERM; 733 return -EPERM;
734 }
720 } 735 }
721 else if (__dev_get_by_name(net, ifr->ifr_name)) 736 else if (__dev_get_by_name(net, ifr->ifr_name))
722 return -EINVAL; 737 return -EINVAL;
@@ -750,6 +765,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
750 return -ENOMEM; 765 return -ENOMEM;
751 766
752 dev_net_set(dev, net); 767 dev_net_set(dev, net);
768
753 tun = netdev_priv(dev); 769 tun = netdev_priv(dev);
754 tun->dev = dev; 770 tun->dev = dev;
755 tun->flags = flags; 771 tun->flags = flags;
@@ -883,7 +899,6 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
883 void __user* argp = (void __user*)arg; 899 void __user* argp = (void __user*)arg;
884 struct ifreq ifr; 900 struct ifreq ifr;
885 int ret; 901 int ret;
886 DECLARE_MAC_BUF(mac);
887 902
888 if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) 903 if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
889 if (copy_from_user(&ifr, argp, sizeof ifr)) 904 if (copy_from_user(&ifr, argp, sizeof ifr))
@@ -1011,8 +1026,8 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
1011 1026
1012 case SIOCSIFHWADDR: 1027 case SIOCSIFHWADDR:
1013 /* Set hw address */ 1028 /* Set hw address */
1014 DBG(KERN_DEBUG "%s: set hw address: %s\n", 1029 DBG(KERN_DEBUG "%s: set hw address: %pM\n",
1015 tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data)); 1030 tun->dev->name, ifr.ifr_hwaddr.sa_data);
1016 1031
1017 rtnl_lock(); 1032 rtnl_lock();
1018 ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); 1033 ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);