a couple of weekends ago I’ve played with libslirp and put together slirp-forwarder.

SliRP emulates in userspace a TCP/IP stack. It can be used to circumvent the limitation of creating TAP/TUN devices in the host namespace for an unprivileged user. The program could run in the host namespace, receive messages from the network namespace where a TAP device is configured, and forward them to the outside world using unprivileged operations such as opening another connection to the destination host. Privileged operations are still not possible outside of the emulated network, as the helper program doesn’t gain any additional privilege that running as an unprivileged user.

Once the PoC was ready, I discovered there was already another tool by Akihiro Suda (@AkihiroSuda), slirp4netns that was doing exactly the same thing, and it was already using the better slirp implementation in QEMU, that is used for configuring unprivileged virtual machines.

slirp4netns was added to the rootlesscontainers github organization, and its repo can be found here: https://github.com/rootless-containers/slirp4netns

With some small changes to slirp4netns, it was possible to integrate slirp4netns into Podman for the configuration of an unprivileged network namespace. For example, we needed a way to terminate the slirp4netns program once the container exits, allow to configure the interface and notify Podman back once the configuration is done.

$ l t o a p p o 0 d m a n r u L i i U R T c R L i i U R T c R n i n n P X X o X i n n P X X o X n e e l n e e l k t t L p p l b k t t B p p l b - 6 O a a i y 6 R a a i y r e a O c c s t e a O c c s t m n d a P k k i e n d a A k k i e c d d B e e o s c d d D e e o s a a r d A t t n : a r d C t t n : l p : r C s s s 0 p : r A s s s 0 p : 1 : K : : : : 1 : S : : : i L 2 0 0 0 ( E 0 T 0 1 0 ( n o 7 : R 0 t . f 0 e c . : U e e t . h 0 e R e e t . a 0 1 N r r x 0 e . 8 U r r x 0 i l . / N r r q r 2 0 N r r q f 0 1 I o o u B n . : N o o u B c L . 2 N r r e ) e 1 : I r r e ) o o 1 8 G s s u t 0 c N s s u n o : : e 0 c G : : e f p S 0 0 l T c 0 0 l T i b M c M e X H e e X g a a o T d d n W B : M d d n c s p U r r : b a c e T r r : b - k k e : o o 1 y d a 1 U o o 1 y a : : 6 p p 0 t d s f : p p 0 t 2 H 5 p p 0 e r t f 1 p p 0 e 5 o 5 e e 0 s : : 5 e e 0 s 5 s 3 d d : C 1 f 0 d d : . t 6 : : 0 E 0 e 0 : : 9 0 0 0 : . 0 0 0 0 . ( C 0 a 0 M 0 E . : M ( . e v v . : 2 4 e v v 9 0 t e e 0 E . b t e e 0 r r r 1 2 f r r r . i r r B : 5 9 i r r 0 c u u ) 0 5 / c u u : n n A 6 : n n B 1 s s : 4 1 s s ) : : 4 M : : 0 0 B a S 0 0 : s c f c F k o f c r a 9 : p r a a r 2 e a r m r 5 : m r e i 5 L e i : e . i : e 0 r 2 n 0 r : 5 k : 0 5 0 . 2 5 5 . 0

This is how it looks from the host, the arguments to slirp4netns in addition to some fd used for the synchronization, are the PID of a process in the network namespace to configure and the device name.

$ [ $ 1 1 0 b ] p 4 i g 6 n 1 r 0 / 0 e p 3 p / o 6 u d 0 - s m f r a a / n b s i r l n u i / n r s p l i - r r p m 4 n a e l t p n i s n e - c s l - e e e p 3 1 - 0 r & 4 1 0 4 4 7 t a p 0