[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <trinity-2a96550a-5664-4126-af2f-91ad7b8cc191-1553240417443@3c-app-gmx-bs55>
Date: Fri, 22 Mar 2019 08:40:17 +0100
From: "Harald Albrecht" <Harald.Albrecht@....net>
To: netdev@...r.kernel.org
Subject: [RFC 1/1] net/tun: fdinfo to relate TAP/TUN network interfaces
unambiguously with their serving processes
This is a first for me to appear on the Linux kernel netdev list, so please bear with me while killing me...
For diagnosing Linux virtual networking I need to relate TAP/TUN network interfacces to the user space processes they are served by. I'm aware of Kirill Tkhai's TUN SIOCGSKNS ioctl patches. My usecase is that my diagnosis software is a process different from a TAP/TUN serving process, so issuing the ioctl() is not really possible to outside processes (without resorting to gorilla tactics like attaching to the serving process, pausing it, and then injecting ioctl() calls). For my usecase, /proc/$PID/fdinfo/$FD is an easy-to-use source of the information I need for diagnosis.
At the moment, fdinfo for a TAP/TUN device unfortunately only returns the name of the TAP/TUN network interface the fd is connected to for serving. Unfortunately, this does not allow for unambiguous identification in such system configurations where there are multiple TAP/TUN network interfaces of the same ifname, but in different network namespaces. In addition to the ifname, a network namespace reference is necessary where the TAP/TUN network interface is currently living in. Together, these two nuggets of information allow to unambiguously relate TAP/TUN serving processes with the correct TAP/TUN network interfaces.
To achieve this, I would like you to give feedback on potential additional information in fdinfo for TAP/TUN, please see the following patch for discussion. I'm also providing a "test" script at https://gist.github.com/TheDiveO/d0834baacc92a7ab25300fd8c7468b61 that creates two identically named TAP/TUN network interfaces, but in different network namespaces, with a dummy serving process living in a third network namespace. This requires a dummy TAP serving process tapclient.c to also to be found here in the same GitHub gist: https://gist.github.com/TheDiveO/d0834baacc92a7ab25300fd8c7468b61.
About my potential patch:
- adds two new keys "iffnetns:" and "devnetns:".
- "iffnetns:" references the network namespace where the TAP/TUN network interface (if created) is located in. The format is the same as if readlink() a network namespace fd, such as in "$readlink /proc/self/ns/net". In particular, the textual representation is "net:[%u]", where %u is the inode number of the specific network namespace.
- "devnetns:" references the network namespace where the control fd would create new TAP/TUN network interfaces; please note that this can be different from the network namespace where the currently created TAP/TUN network interface is currently located in. Again, this reference is in the same textual format as for the "iffnetns:" key.
- at the moment I'm at a loss as to whether this additional information needs to be subjected to CAP_NET?
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 53f4f37b0ffd..1ddc22b35d0a 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -3440,22 +3440,37 @@ static int tun_chr_close(struct inode *inode, struct file *file)
#ifdef CONFIG_PROC_FS
static void tun_chr_show_fdinfo(struct seq_file *m, struct file *file)
{
- struct tun_file *tfile = file->private_data;
- struct tun_struct *tun;
- struct ifreq ifr;
-
- memset(&ifr, 0, sizeof(ifr));
-
- rtnl_lock();
- tun = tun_get(tfile);
- if (tun)
- tun_get_iff(current->nsproxy->net_ns, tun, &ifr);
- rtnl_unlock();
-
- if (tun)
- tun_put(tun);
-
- seq_printf(m, "iff:\t%s\n", ifr.ifr_name);
+ struct tun_file *tfile = file->private_data;
+ struct tun_struct *tun;
+ struct ifreq ifr;
+ unsigned int iffnetnsinum = 0; /* netns of TAP/TUN nif */
+ unsigned int tnetnsinum = 0; /* netns captured when opening /dev/net/tun */
+
+ memset(&ifr, 0, sizeof(ifr));
+
+ rtnl_lock();
+ tun = tun_get(tfile);
+ if (tun) {
+ tun_get_iff(current->nsproxy->net_ns, tun, &ifr);
+ /* network namespace where this /dev/net/tun char device fd reference
+ * will create new TAP/TUN network interfaces.
+ */
+ tnetnsinum = sock_net(&tfile->sk)->ns.inum;
+ /* network namespace where the TAP/TUN network interface
+ * currently is located in.
+ */
+ iffnetnsinum = dev_net(tun->dev)->ns.inum;
+ }
+ rtnl_unlock();
+
+ if (tun)
+ tun_put(tun);
+
+ seq_printf(m, "iff:\t%s\n", ifr.ifr_name);
+ if (iffnetnsinum)
+ seq_printf(m, "iffnetns:\tnet:[%u]\n", iffnetnsinum);
+ if (tnetnsinum)
+ seq_printf(m, "devnetns:\tnet:[%u]\n", tnetnsinum);
}
#endif
Harald
Powered by blists - more mailing lists