forked from mirrors/linux
		
	tun: send netlink notification when the device is modified
I added dumping of link information about tun devices over netlink in commit1ec010e705("tun: export flags, uid, gid, queue information over netlink"), but didn't add the missing netlink notifications when the device's exported properties change. This patch adds notifications when owner/group or flags are modified, when queues are attached/detached, and when a tun fd is closed. Reported-by: Thomas Haller <thaller@redhat.com> Fixes:1ec010e705("tun: export flags, uid, gid, queue information over netlink") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									9fffc5c6dd
								
							
						
					
					
						commit
						83c1f36f98
					
				
					 1 changed files with 22 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -743,8 +743,15 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
 | 
			
		|||
 | 
			
		||||
static void tun_detach(struct tun_file *tfile, bool clean)
 | 
			
		||||
{
 | 
			
		||||
	struct tun_struct *tun;
 | 
			
		||||
	struct net_device *dev;
 | 
			
		||||
 | 
			
		||||
	rtnl_lock();
 | 
			
		||||
	tun = rtnl_dereference(tfile->tun);
 | 
			
		||||
	dev = tun ? tun->dev : NULL;
 | 
			
		||||
	__tun_detach(tfile, clean);
 | 
			
		||||
	if (dev)
 | 
			
		||||
		netdev_state_change(dev);
 | 
			
		||||
	rtnl_unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2562,13 +2569,15 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 | 
			
		|||
			/* One or more queue has already been attached, no need
 | 
			
		||||
			 * to initialize the device again.
 | 
			
		||||
			 */
 | 
			
		||||
			netdev_state_change(dev);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		tun->flags = (tun->flags & ~TUN_FEATURES) |
 | 
			
		||||
			      (ifr->ifr_flags & TUN_FEATURES);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
 | 
			
		||||
		netdev_state_change(dev);
 | 
			
		||||
	} else {
 | 
			
		||||
		char *name;
 | 
			
		||||
		unsigned long flags = 0;
 | 
			
		||||
		int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ?
 | 
			
		||||
| 
						 | 
				
			
			@ -2808,6 +2817,9 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
 | 
			
		|||
	} else
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
 | 
			
		||||
	if (ret >= 0)
 | 
			
		||||
		netdev_state_change(tun->dev);
 | 
			
		||||
 | 
			
		||||
unlock:
 | 
			
		||||
	rtnl_unlock();
 | 
			
		||||
	return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -2848,6 +2860,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 | 
			
		|||
	unsigned int ifindex;
 | 
			
		||||
	int le;
 | 
			
		||||
	int ret;
 | 
			
		||||
	bool do_notify = false;
 | 
			
		||||
 | 
			
		||||
	if (cmd == TUNSETIFF || cmd == TUNSETQUEUE ||
 | 
			
		||||
	    (_IOC_TYPE(cmd) == SOCK_IOC_TYPE && cmd != SIOCGSKNS)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2944,10 +2957,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 | 
			
		|||
		if (arg && !(tun->flags & IFF_PERSIST)) {
 | 
			
		||||
			tun->flags |= IFF_PERSIST;
 | 
			
		||||
			__module_get(THIS_MODULE);
 | 
			
		||||
			do_notify = true;
 | 
			
		||||
		}
 | 
			
		||||
		if (!arg && (tun->flags & IFF_PERSIST)) {
 | 
			
		||||
			tun->flags &= ~IFF_PERSIST;
 | 
			
		||||
			module_put(THIS_MODULE);
 | 
			
		||||
			do_notify = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		tun_debug(KERN_INFO, tun, "persist %s\n",
 | 
			
		||||
| 
						 | 
				
			
			@ -2962,6 +2977,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 | 
			
		|||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		tun->owner = owner;
 | 
			
		||||
		do_notify = true;
 | 
			
		||||
		tun_debug(KERN_INFO, tun, "owner set to %u\n",
 | 
			
		||||
			  from_kuid(&init_user_ns, tun->owner));
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -2974,6 +2990,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 | 
			
		|||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		tun->group = group;
 | 
			
		||||
		do_notify = true;
 | 
			
		||||
		tun_debug(KERN_INFO, tun, "group set to %u\n",
 | 
			
		||||
			  from_kgid(&init_user_ns, tun->group));
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -3133,6 +3150,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 | 
			
		|||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (do_notify)
 | 
			
		||||
		netdev_state_change(tun->dev);
 | 
			
		||||
 | 
			
		||||
unlock:
 | 
			
		||||
	rtnl_unlock();
 | 
			
		||||
	if (tun)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue