tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kernel networking stack in userspace


Recently I added support for the NFS client as a rump file system.  Since
NFS uses in-kernel networking, as a side effect kernel TCP/IP networking
is now provided in a userspace library.  Apart from being able to use
multiple TCP/IP stacks within a single system (a.k.a. virtualization,
one being the kernel networking stack and the rest running in userspace),
it does not have any real applications I can immediately see.  However,
since it is useful for playing, development, writing regression tests, and
generally learning about BSD networking, I'm writing this short tutorial.

There are two choices for operation mode:
  1) virtual networking using host sockets (similar to e.g. MMlite)
     (librumpnet, librumpnet_sockin)
  2) full TCP/IP networking stack
     (librumpnet, librumpnet_net, librumpnet_netinet, librumpnet_virtif)

Switching between these two is currently done when the application
is linked.  I hope to eventually make this run-time configurable.

Since the caller accesses the networking stack through the sockets
layer, it cannot tell the difference between the two.  It is therefore
up to the user/operator to decide which mode is desired.

Option 1 defines a networking domain with the SOCK_DGRAM and
SOCK_STREAM protocols and interfaces with the host kernel via
the kernel's socket syscall interface.  This has three implications:

  * only the socket code is run in userspace
  * all communication happens using the host IP address
  * no system administration priviledges are required

On the contrary, option 2 runs the entire kernel networking stack in
userspace.  This means that it must have raw ethernet access and
accomplishes this through the use of tap(4) (similar to e.g. qemu).
Contrasting the other option, this brings:

  * full networking stack in userspace
  * the interface and routing table must be configured before use
  * /dev/tap and interface configuration priviledges are required

To configure the interface from your code, you must emulate what
ifconfig(8) and route(8) do on a normal system.  There is an
example in src/sys/rump/net/rumptest/rumptest_net.c on how to do
this.  I'll probably move that stuff to a library lateron.

Currently, tap must be configured manually as tap0.  To do this, execute
(with appropriate priviledges):
golem> ifconfig tap0 create
golem> ifconfig tap0 up

Optionally, if wanting to bridge to a real network, execute:
golem> ifconfig bridge0 create
golem> brconfig bridge0 add tap0 add yourrealif0
golem> brconfig bridge0 up
(yes, the first command really is ifconfig, not brconfig)

Apart from that, both options require threading, which can be enabled by
setting the RUMP_THREADS environment variable to 1.  Then it's just a
matter of running the application.  If all goes well, running
rumptest_net should dump out the html on the main page

Enjoy (if you're into this sort of stuff ;)
  - antti

pie-in-the-sky: barring interfacing with tap(4), the userspace kernel
networking stack is likely to be highly portable.  So if you don't like
networking on $OS, by all means use the NetBSD TCP/IP stack linked
against your application ;)

Home | Main Index | Thread Index | Old Index