Skip to content

A TCP/IP implementation in pure OCaml

License

Notifications You must be signed in to change notification settings

robur-coop/mnet

Repository files navigation

mnet, a pure OCaml TCP/IP stack for unikernels

mnet implements IPv4, IPv6, TCP, and UDP protocols for mkernel-based unikernels running on Solo5 and Unikraft. It replaces mirage-tcpip with a direct-style API powered by Miou and OCaml 5 effects.

The library also provides TLS (via ocaml-tls), DNS resolution (via ocaml-dns), and the Happy Eyeballs connection algorithm (via [happy-eyeballs][happy-eyeballs]).

Features

  • IPv4 with ARPv4, ICMPv4, and packet fragmentation/reassembly
  • IPv6 with Neighbor Discovery (NDPv6), router discovery, and PMTU
  • TCP via utcp with a Unix-socket-like API (connect, listen, accept, read, write, close)
  • UDP with sendto/recvfrom
  • TLS via ocaml-tls for encrypted connections
  • DNS resolver via ocaml-dns with TCP and UDP transports
  • Happy Eyeballs (RFC 8305) for fast dual-stack connections

Installation

mnet requires OCaml 5. It is also necessary to launch unikernels via virtualisation (KVM, BHyve, VMM). Your processor must therefore be configured to allow virtualisation (VT-x, AMD-V).

opam pin add mnet https://github.com/robur-coop/mnet.git
opam install mnet mnet-tls mnet-dns mnet-happy-eyeballs

Quick start

Initializing the stack

Every unikernel starts by creating a network stack via Mkernel.run. The stack needs a random number generator and an CIDRv4 (the IPv4 address of the unikernel). It is also possible to assign an IPv6 address to the unikernel. The DHCP protocol has not yet been implemented.

let ( let@ ) finally fn = Fun.protect ~finally fn
module RNG = Mirage_crypto_rng.Fortuna

let rng () = Mirage_crypto_rng_mkernel.initialize (module RNG)
let rng = Mkernel.map rng Mkernel.[]

let () =
  Mkernel.(run [ rng; Mnet.stack ~name:"service" ~gateway cidr ])
  @@ fun rng (stack, tcp, udp) () ->
  let@ () = fun () -> Mnet.kill stack in
  let@ () = fun () -> Mirage_crypto_rng_mkernel.kill rng in
  (* use [tcp] and [udp] here *)
  ()

The name parameter corresponds to the Solo5 network device. To launch the unikernel, you must allocate a virtual Ethernet interface (a tap interface) and you can launch the unikernel in this way:

$ sudo ip link add name br0 type bridge
$ sudo ip addr add 10.0.0.1/24 dev br0
$ sudo ip tuntap add name tap0 mode tap
$ sudo ip link set tap0 master br0 
$ solo5-hvt --net:service=tap0 -- unikernel.hvt --ipv4=10.0.0.2/24

Packages

Package Description
mnet Core TCP/IP stack (IPv4, IPv6, TCP, UDP)
mnet-tls TLS support via ocaml-tls
mnet-dns DNS client via ocaml-dns
mnet-happy-eyeballs Happy Eyeballs connection algorithm (RFC 8305)

End-to-end tests

mnet provides end-to-end tests that compile and run real unikernels. This requires:

  • sudo access (to create tap interfaces)
  • KVM access (membership in the kvm group on Linux)
  • The development version of mnet pinned in opam
git clone https://github.com/robur-coop/mnet
cd mnet
opam pin add -y .
sudo true
dune runtest --profile=unikernels

About

A TCP/IP implementation in pure OCaml

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors