This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] (linux) opensock: AF_NETLINK is a better choice than AF_UNIX
- From: Renzo Davoli <renzo at cs dot unibo dot it>
- To: libc-alpha at sourceware dot org
- Date: Tue, 22 Aug 2017 16:29:15 +0200
- Subject: [PATCH] (linux) opensock: AF_NETLINK is a better choice than AF_UNIX
- Authentication-results: sourceware.org; auth=none
In sysdeps/unix/sysv/linux/opensock.c the function __opensock
opens a "generic" socket.
This function tries to open sockets of different families and returns
as soon as it succeeds to open a socket. It remembers the kind of socket
which succeeded to avoid the scan in subsequent calls.
The sequence of families for the attempts are:
AF_UNIX, AF_INET, AF_INET6, etc.
This function is used in:
./sysdeps/unix/sysv/linux/if_index.c
./sysdeps/unix/sysv/linux/ifreq.c (for getifaddrs)
All the calling functions are related to the TCP-IP (v4 or v6) stack.
It is conceptually inconsistent to use AF_UNIX sockets (although
the Linux kernel accepts any kind of sockets).
AF_UNIX has nothing to do with networking: it is just an InterProcess
Communication means.
This choice makes harder to implement system call partial virtualization
https://sourceforge.net/projects/view-os/
User-space TCP-IP stacks as umnet modules virtualize the address families
AF_INET, AF_INET6 and AF_NETLINK (iproute for net configuration).
>From the practical point of view using (for example) a umnetlwipv6
stack, /bin/ip does not work while the busybox implementation of ip
succeeds (it uses a AF_INET socket for SIOCGIFINDEX).
$ ip addr add 10.0.0.1/24 dev vd0
Cannot find device "vd0"
$ busybox ip addr add 10.0.0.1/24 dev vd0
$
Partial virtualization using the current glibc code is harder:
all the ioctl requests should be captured and virtualized if the fd
is a socket and the request # is in a specific range.
It is not possible to decide whether a "socket(AF_UNIX..)" system call
returns a fd that needs virtualization or not.
If it gets connected to "/tmp/.X11-unix/X0" (for example) it is not
virtualized by the net module while if it is used in a
SIOCG* ioctl call it must be virtualized.
The patch here attached changes the sequence of socket for opensock's
attempts to:
AF_NETLINK, AF_INET, AF_INET6, AF_UNIX, etc.
Netlink is more appropriate for ioctl calls like "SIOGCIFINDEX".
I suppose AF_UNIX was chosen as its data structures are lighter than
those of AF_INET(6). AF_NETLINK should be as light as AF_UNIX
and it would make the life easier for partial virtualization.
A sequence like AF_NETLINK, AF_UNIX, AF_INET, AF_INET6,...
would fit anyway.
Looking around in other libC implementations
(paths are relative to their source trees):
* NetBSD uses AF_INET see:
http://bxr.su/DragonFly/lib/libc/net/if_nametoindex.c
* dietlibc uses AF_INET6 see: lib/if_nametoindex.c
* ulibc: uses AF_INET6 or AF_INET if AF_INET6 fails:
see: libc/inet/opensock.c
* newlibc: uses AF_INET in libc/sys/linux/net/ifname.c
and a __opensock similar to the one in glibc in
libc/sys/linux/net/ifreq.c
* eglibc seems to share the same opensock code of glibc.
Thank you
renzo
2018-08-20 Renzo Davoli <renzo@cs.unibo.it>
diff --git a/sysdeps/unix/sysv/linux/opensock.c b/sysdeps/unix/sysv/linux/opensock.c
index 21508cdc75..236c49a42f 100644
--- a/sysdeps/unix/sysv/linux/opensock.c
+++ b/sysdeps/unix/sysv/linux/opensock.c
@@ -35,9 +35,10 @@ __opensock (void)
const char procname[15];
} afs[] =
{
- { AF_UNIX, "net/unix" },
+ { AF_NETLINK, "net/netlink" },
{ AF_INET, "" },
{ AF_INET6, "net/if_inet6" },
+ { AF_UNIX, "net/unix" },
{ AF_AX25, "net/ax25" },
{ AF_NETROM, "net/nr" },
{ AF_ROSE, "net/rose" },