diff options
Diffstat (limited to 'drivers/net/tun.c')
| -rw-r--r-- | drivers/net/tun.c | 43 |
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 | ||
| 216 | static unsigned int tun_net_id; | 216 | static int tun_net_id; |
| 217 | struct tun_net { | 217 | struct 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 | ||
| 308 | static 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 | |||
| 315 | static 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. */ |
| 309 | static void tun_net_init(struct net_device *dev) | 326 | static 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); |
