Package: linux-image-3.2.0-2-amd64 Version: 3.2.16-1 Hi,
CLONE_NEWNET is still buggy (i found random reports with the same error message from 2010). uname: Linux * 3.2.0-2-amd64 #1 SMP Mon Apr 30 05:20:23 UTC 2012 x86_64 GNU/Linux See the attached example. I don't think it matters much how the socket is used: just create the socket before the unshare and use it somehow - listen() after unshare() triggered it too. The kernel starts spamming the message after the program is terminated. Also the port is not reachable from the outside - although i admit i couldn't find docs mentioning this is supported, but it really should be. (Given that struct net is part of struct sock(common) this shouldn't be hard) I could reproduce it in virtualbox with rescue mode from http://cdimage.debian.org/cdimage/wheezy_di_alpha1/amd64/iso-cd/debian-wheezy-DI-a1-amd64-netinst.iso - when i started it a second time the process would even hang for some time (not killable). logs look like this: [ 796.444219] unregister_netdevice: waiting for lo to become free. Usage count = 2 [ 806.684213] unregister_netdevice: waiting for lo to become free. Usage count = 2 [ 816.924212] unregister_netdevice: waiting for lo to become free. Usage count = 2 [ 827.164217] unregister_netdevice: waiting for lo to become free. Usage count = 2 [ 837.408237] unregister_netdevice: waiting for lo to become free. Usage count = 2 [ 847.648216] unregister_netdevice: waiting for lo to become free. Usage count = 2 [ 857.888219] unregister_netdevice: waiting for lo to become free. Usage count = 2 [ 868.128224] unregister_netdevice: waiting for lo to become free. Usage count = 2 [ 878.368221] unregister_netdevice: waiting for lo to become free. Usage count = 2 [ 888.608215] unregister_netdevice: waiting for lo to become free. Usage count = 2
#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netinet/ip.h> int main() { int listenfd, acceptfd, connectfd; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); puts("newnet + listen/connect test"); if (-1 == (listenfd = socket(AF_INET, SOCK_STREAM, 0))) { perror("socket failed"); abort(); } if (0 != listen(listenfd, 1)) { perror("listen failed"); abort(); } if (0 != unshare(CLONE_NEWNET)) { perror("unshare failed"); abort(); } if (0 != getsockname(listenfd, (struct sockaddr*) &addr, &addrlen)) { perror("getsockname failed"); } if (-1 == (connectfd = socket(AF_INET, SOCK_STREAM, 0))) { perror("socket failed"); abort(); } if (0 == connect(connectfd, (struct sockaddr*) &addr, addrlen)) { puts("successful connect - something is wrong here"); } else { perror("connect failed as expected"); } close(connectfd); printf("listening on 0.0.0.0:%i\n", (int) addr.sin_port); if (-1 == (acceptfd = accept(listenfd, NULL, NULL))) { perror("accept failed"); abort(); } { char buf[1024]; int len = read(acceptfd, buf, sizeof(buf)-1); if (len < 0) { perror("read failed"); abort(); } buf[len] = 0; printf("received: '%s'\n", buf); write(acceptfd, buf, len); close(acceptfd); } puts("done."); }