Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os 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>

authored by

Andrey Vagin and committed by
David S. Miller
c62cce2c 2a43ca0a

+19 -1
+1 -1
fs/nsfs.c
··· 118 118 return ret; 119 119 } 120 120 121 - static int open_related_ns(struct ns_common *ns, 121 + int open_related_ns(struct ns_common *ns, 122 122 struct ns_common *(*get_ns)(struct ns_common *ns)) 123 123 { 124 124 struct path path = {};
+4
include/linux/proc_fs.h
··· 82 82 return proc_mkdir_data(name, 0, parent, net); 83 83 } 84 84 85 + struct ns_common; 86 + int open_related_ns(struct ns_common *ns, 87 + struct ns_common *(*get_ns)(struct ns_common *ns)); 88 + 85 89 #endif /* _LINUX_PROC_FS_H */
+1
include/uapi/linux/sockios.h
··· 84 84 #define SIOCWANDEV 0x894A /* get/set netdev parameters */ 85 85 86 86 #define SIOCOUTQNSD 0x894B /* output queue size (not sent only) */ 87 + #define SIOCGSKNS 0x894C /* get socket network namespace */ 87 88 88 89 /* ARP cache control calls. */ 89 90 /* 0x8950 - 0x8952 * obsolete calls, don't re-use */
+13
net/socket.c
··· 877 877 * what to do with it - that's up to the protocol still. 878 878 */ 879 879 880 + static struct ns_common *get_net_ns(struct ns_common *ns) 881 + { 882 + return &get_net(container_of(ns, struct net, ns))->ns; 883 + } 884 + 880 885 static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) 881 886 { 882 887 struct socket *sock; ··· 949 944 if (dlci_ioctl_hook) 950 945 err = dlci_ioctl_hook(cmd, argp); 951 946 mutex_unlock(&dlci_ioctl_mutex); 947 + break; 948 + case SIOCGSKNS: 949 + err = -EPERM; 950 + if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 951 + break; 952 + 953 + err = open_related_ns(&net->ns, get_net_ns); 952 954 break; 953 955 default: 954 956 err = sock_do_ioctl(net, sock, cmd, arg); ··· 3105 3093 case SIOCSIFVLAN: 3106 3094 case SIOCADDDLCI: 3107 3095 case SIOCDELDLCI: 3096 + case SIOCGSKNS: 3108 3097 return sock_ioctl(file, cmd, arg); 3109 3098 3110 3099 case SIOCGIFFLAGS: