ixy.ml is an OCaml rewrite of the ixy userspace network driver.
It is designed to be readable, idiomatic OCaml code.
It supports Intel 82599 10GbE NICs (
ixy.ml is still work-in-progress.
Quick start (on Debian)
sudo ./build.sh sudo ./setup-hugetlbfs.sh lspci | grep 'Ethernet controller.*\(82599ES\|X50\)' sudo ixy-pktgen <PCI address of the controller you want to use>
- multiple receive and transmit queues
- multiple memory pools
- simple API
- interactive development in
- Driver Internals
- OCaml Internals
- Intel 82599 Datasheet
- ixy in other languages
- FreeBSD ixgbe driver
- DPDK ixgbe driver
- Linux ixgbe driver
API documentation is built using
opam install odoc
Build the API documentation using:
The HTML documentation pages will be in
You can also just read the documentation comments (enclosed in
*)) in the
ixy.ml communicates with the network card using memory-mapped I/O and DMA.
The DMA interface is documented in
Help, I don't know OCaml!
There's a basic guide to OCaml in
It should help with reading the driver, though you won't be able to write your own OCaml programs after reading it.
You will need
opam install ppx_cstruct
Building and Installing
opam to install the library:
opam pin add ixy git://github.com/ixy-languages/ixy.ml.git
Alternatively build manually:
This will build the driver and the three example apps.
The app binaries will be located in
Build the test programs using:
The program binaries will be located in
You can also just build a specific test program, e.g. build
Three example apps are provided in the
In all examples a
<pci_addr> is a PCI address such as
ixy.ml has a tolerant PCI address parser that will automatically add punctuation, ignore wrong punctuation (
:) and possibly add the default
0000 domain, e.g.
0000:ab:cd.e can be written as
ixy-echo retransmits all packets it receives.
ixy-echo will create a single receive queue and a single transmit queue on the device specified by
<pci_addr> and forward all packets received on the receive queue onto the transmit queue.
ixy-fwd is a bidirectional layer 2 forwarder.
ixy-fwd <pci_addr> <pci_addr>
ixy-fwd will create a single receive queue and a single transmit queue on each device specified by the
<pci_addr>s and forward all packets received on on device's receive queue onto the other device's transmit queue.
Each packet's 49th byte will be incremented by 1 to simulate a somewhat realistic payload.
All packets that cannot be transmitted immediately will be dropped.
ixy-pktgen is a simple packet generator.
ixy-pktgen will create a single transmit queue on the device specified by
<pci_addr> and transmit the same 60 byte packet repeatedly as fast as possible.
The final 4 bytes of each packet are tagged with a 32-bit sequence number.
Writing your own apps
Read the API Documentation.
let () = (* parse a PCI address *) let pci_addr = match Ixy.PCI.of_string "0000:ab:cd.e" with | Some addr -> addr | None -> print_endline "couldn't parse address"; exit 1 in (* initialize a device *) let dev = Ixy.create ~pci_addr ~rxq:1 ~txq:1 in (* create a mempool *) let mempool = Ixy.Memory.allocate_mempool ~num_entries:2048 in (* allocate a packet *) let packet = match Ixy.Memory.pkt_buf_alloc mempool with | Some buf -> buf | None -> print_endline "couldn't allocate packet"; exit 1 in (* write some data to the packet *) Cstruct.memset packet.data 42; (* set the packet length *) packet.size <- 100; (* transmit the packet *) Ixy.tx_batch_busy_wait dev 0 [|packet|]
Make sure you have
findlib installed, otherwise
#require won't work.
(* load ixy.ml *) # #require "ixy";; (* play around with ixy.ml *) # Ixy.create;; - : pci_addr:Ixy.PCI.t -> rxq:int -> txq:int -> Ixy.t
Be careful when accessing registers via the
IXGBE module; the NIC has DMA access and can write basically anywhere in physical memory.
OCaml 4.06.0 or later
Other 64-bit architectures supported by OCaml may also work, but haven't been tested.
The driver will build on all operating systems supported by OCaml but requires Linux's
sysfs to work.
- Intel 82599ES/X520/X540/X550
All NICs supported by ixy should work with ixy.ml, though only 82599ES and X540 NICs have been tested.
On unsupported system configurations the driver will print an error message and exit at runtime.
The ixy.ml project is structured as follows:
lib/- the main ixy.ml driver
app/- example programs that use ixy.ml
test/- simple programs for debugging/testing internal functionality
build.sh- script to build and install ixy.ml on a clean Debian system
setup-hugetlbfs.sh- script to mount a
/mnt/hugeand allocate 512 huge pages
ixy.ml is not production-ready. Do not use in critical environments. DMA may corrupt memory.
ixy has also been written in other languages. Check out the other ixy implementations.