forked from mirrors/linux
		
	net: add an ioctl to get a socket network namespace
Each socket operates in a network namespace where it has been created, so if we want to dump and restore a socket, we have to know its network namespace. We have a socket_diag to get information about sockets, it doesn't report sockets which are not bound or connected. This patch introduces a new socket ioctl, which is called SIOCGSKNS and used to get a file descriptor for a socket network namespace. A task must have CAP_NET_ADMIN in a target network namespace to use this ioctl. Cc: "David S. Miller" <davem@davemloft.net> Cc: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andrei Vagin <avagin@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									2a43ca0aa9
								
							
						
					
					
						commit
						c62cce2cae
					
				
					 4 changed files with 19 additions and 1 deletions
				
			
		|  | @ -118,7 +118,7 @@ void *ns_get_path(struct path *path, struct task_struct *task, | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int open_related_ns(struct ns_common *ns, | ||||
| int open_related_ns(struct ns_common *ns, | ||||
| 		   struct ns_common *(*get_ns)(struct ns_common *ns)) | ||||
| { | ||||
| 	struct path path = {}; | ||||
|  |  | |||
|  | @ -82,4 +82,8 @@ static inline struct proc_dir_entry *proc_net_mkdir( | |||
| 	return proc_mkdir_data(name, 0, parent, net); | ||||
| } | ||||
| 
 | ||||
| struct ns_common; | ||||
| int open_related_ns(struct ns_common *ns, | ||||
| 		   struct ns_common *(*get_ns)(struct ns_common *ns)); | ||||
| 
 | ||||
| #endif /* _LINUX_PROC_FS_H */ | ||||
|  |  | |||
|  | @ -84,6 +84,7 @@ | |||
| #define SIOCWANDEV	0x894A		/* get/set netdev parameters	*/ | ||||
| 
 | ||||
| #define SIOCOUTQNSD	0x894B		/* output queue size (not sent only) */ | ||||
| #define SIOCGSKNS	0x894C		/* get socket network namespace */ | ||||
| 
 | ||||
| /* ARP cache control calls. */ | ||||
| 		    /*  0x8950 - 0x8952  * obsolete calls, don't re-use */ | ||||
|  |  | |||
							
								
								
									
										13
									
								
								net/socket.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								net/socket.c
									
									
									
									
									
								
							|  | @ -877,6 +877,11 @@ static long sock_do_ioctl(struct net *net, struct socket *sock, | |||
|  *	what to do with it - that's up to the protocol still. | ||||
|  */ | ||||
| 
 | ||||
| static struct ns_common *get_net_ns(struct ns_common *ns) | ||||
| { | ||||
| 	return &get_net(container_of(ns, struct net, ns))->ns; | ||||
| } | ||||
| 
 | ||||
| static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) | ||||
| { | ||||
| 	struct socket *sock; | ||||
|  | @ -945,6 +950,13 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
| 				err = dlci_ioctl_hook(cmd, argp); | ||||
| 			mutex_unlock(&dlci_ioctl_mutex); | ||||
| 			break; | ||||
| 		case SIOCGSKNS: | ||||
| 			err = -EPERM; | ||||
| 			if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | ||||
| 				break; | ||||
| 
 | ||||
| 			err = open_related_ns(&net->ns, get_net_ns); | ||||
| 			break; | ||||
| 		default: | ||||
| 			err = sock_do_ioctl(net, sock, cmd, arg); | ||||
| 			break; | ||||
|  | @ -3093,6 +3105,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, | |||
| 	case SIOCSIFVLAN: | ||||
| 	case SIOCADDDLCI: | ||||
| 	case SIOCDELDLCI: | ||||
| 	case SIOCGSKNS: | ||||
| 		return sock_ioctl(file, cmd, arg); | ||||
| 
 | ||||
| 	case SIOCGIFFLAGS: | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Andrey Vagin
						Andrey Vagin