static int tun_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct tun_struct *tun = (struct tun_struct *)file->private_data; DBG(KERN_INFO "%s: tun_chr_ioctl\n", tun->name); switch (cmd) { case TUNSETIFF: return tun_set_iff(tun, arg); case TUNSETNOCSUM: /* Disable/Enable checksum on net iface */ if (arg) tun->flags |= TUN_NOCHECKSUM; else tun->flags &= ~TUN_NOCHECKSUM; DBG(KERN_INFO "%s: checksum %s\n", tun->name, arg ? "disabled" : "enabled"); break; #ifdef TUN_DEBUG case TUNSETDEBUG: tun->debug = arg; break; #endif default: return -EINVAL; }; return 0; }
static int tun_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct tun_struct *tun = (struct tun_struct *)file->private_data; if (cmd == TUNSETIFF && !tun) { struct ifreq ifr; int err; if (copy_from_user(&ifr, (void *)arg, sizeof(ifr))) return -EFAULT; ifr.ifr_name[IFNAMSIZ-1] = '\0'; rtnl_lock(); err = tun_set_iff(file, &ifr); rtnl_unlock(); if (err) return err; copy_to_user((void *)arg, &ifr, sizeof(ifr)); return 0; } if (!tun) return -EBADFD; DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->name, cmd); switch (cmd) { case TUNSETNOCSUM: /* Disable/Enable checksum */ if (arg) tun->flags |= TUN_NOCHECKSUM; else tun->flags &= ~TUN_NOCHECKSUM; DBG(KERN_INFO "%s: checksum %s\n", tun->name, arg ? "disabled" : "enabled"); break; case TUNSETPERSIST: /* Disable/Enable persist mode */ if (arg) tun->flags |= TUN_PERSIST; else tun->flags &= ~TUN_PERSIST; DBG(KERN_INFO "%s: persist %s\n", tun->name, arg ? "disabled" : "enabled"); break; case TUNSETOWNER: /* Set owner of the device */ tun->owner = (uid_t) arg; DBG(KERN_INFO "%s: owner set to %d\n", tun->owner); break; #ifdef TUN_DEBUG case TUNSETDEBUG: tun->debug = arg; break; #endif default: return -EINVAL; }; return 0; }