aboutsummaryrefslogtreecommitdiffstats
path: root/extras/libmemif/docs
diff options
context:
space:
mode:
Diffstat (limited to 'extras/libmemif/docs')
-rw-r--r--extras/libmemif/docs/buildinstructions_doc.md47
-rw-r--r--extras/libmemif/docs/buildinstructions_doc.rst61
-rw-r--r--extras/libmemif/docs/gettingstarted_doc.md164
-rw-r--r--extras/libmemif/docs/gettingstarted_doc.rst234
4 files changed, 295 insertions, 211 deletions
diff --git a/extras/libmemif/docs/buildinstructions_doc.md b/extras/libmemif/docs/buildinstructions_doc.md
deleted file mode 100644
index 3f7c8e8d66d..00000000000
--- a/extras/libmemif/docs/buildinstructions_doc.md
+++ /dev/null
@@ -1,47 +0,0 @@
-## Build Instructions {#libmemif_build_doc}
-
-#### Install dependencies
-```
-# sudo apt-get install -y git cmake autoconf pkg_config libtool
-```
-
-Libmemif is now part of VPP repository. Follow fd.io wiki to pull source code from VPP repository.
-[https://wiki.fd.io/view/VPP/Pulling,_Building,_Running,_Hacking_and_Pushing_VPP_Code#Pushing_Patches](https://wiki.fd.io/view/VPP/Pulling,_Building,_Running,_Hacking_and_Pushing_VPP_Code#Pushing_Patches)
-
-Libmemif is located under extras/libmemif. From extras/libmemif:
-```
-# mkdir build
-# cd build
-# cmake ..
-# make install
-```
-
-#### Verify installation:
-```
-build# ./examples/icmp_responder -?
-```
-Use `-?` flag to display help:
-```
-LIBMEMIF EXAMPLE APP: icmp_responder_example
-==============================
-libmemif version: 4.0, memif version: 2.0
-==============================
-In this example, memif endpoint connects to an external application.
-The example application can resolve ARP and reply to ICMPv4 packets.
-The program will exit once the interface is disconnected.
-==============================
-Usage: icmp_responder [OPTIONS]
-
-Options:
- -r Interface role <slave|master>. Default: slave
- -s Socket path. Supports abstract socket using @ before the path. Default: /run/vpp/memif.sock
- -i Interface id. Default: 0
- -a IPv4 address. Default: 192.168.1.1
- -h Mac address. Default: aa:aa:aa:aa:aa:aa
- -? Show help and exit.
- -v Show libmemif and memif version information and exit.
-```
-
-#### Examples
-
-Once the library is built/installed, refer to @ref libmemif_examples_doc and @ref libmemif_gettingstarted_doc for additional information on basic use cases and API usage.
diff --git a/extras/libmemif/docs/buildinstructions_doc.rst b/extras/libmemif/docs/buildinstructions_doc.rst
new file mode 100644
index 00000000000..090b9d6ff75
--- /dev/null
+++ b/extras/libmemif/docs/buildinstructions_doc.rst
@@ -0,0 +1,61 @@
+.. _libmemif_build_doc:
+
+Build Instructions
+==================
+
+Install dependencies
+--------------------
+
+::
+
+ # sudo apt-get install -y git cmake autoconf pkg_config libtool
+
+Libmemif is now part of VPP repository. Follow fd.io wiki to pull source
+code from VPP repository.
+https://wiki.fd.io/view/VPP/Pulling,_Building,_Running,_Hacking_and_Pushing_VPP_Code#Pushing_Patches
+
+Libmemif is located under extras/libmemif. From extras/libmemif:
+
+::
+
+ # mkdir build
+ # cd build
+ # cmake ..
+ # make install
+
+Verify installation:
+--------------------
+
+::
+
+ build# ./examples/icmp_responder -?
+
+Use ``-?`` flag to display help:
+
+::
+
+ LIBMEMIF EXAMPLE APP: icmp_responder_example
+ ==============================
+ libmemif version: 4.0, memif version: 2.0
+ ==============================
+ In this example, memif endpoint connects to an external application.
+ The example application can resolve ARP and reply to ICMPv4 packets.
+ The program will exit once the interface is disconnected.
+ ==============================
+ Usage: icmp_responder [OPTIONS]
+
+ Options:
+ -r Interface role <slave|master>. Default: slave
+ -s Socket path. Supports abstract socket using @ before the path. Default: /run/vpp/memif.sock
+ -i Interface id. Default: 0
+ -a IPv4 address. Default: 192.168.1.1
+ -h Mac address. Default: aa:aa:aa:aa:aa:aa
+ -? Show help and exit.
+ -v Show libmemif and memif version information and exit.
+
+Examples
+--------
+
+Once the library is built/installed, refer to :ref:`libmemif_examples_doc`
+and :ref:`libmemif_gettingstarted_doc` for additional information on basic
+use cases and API usage.
diff --git a/extras/libmemif/docs/gettingstarted_doc.md b/extras/libmemif/docs/gettingstarted_doc.md
deleted file mode 100644
index 6f2a99c8c69..00000000000
--- a/extras/libmemif/docs/gettingstarted_doc.md
+++ /dev/null
@@ -1,164 +0,0 @@
-## Getting started {#libmemif_gettingstarted_doc}
-
-For detailed information on api calls and structures please refer to @ref libmemif.h.
-
-Start by creating a memif socket. Memif socket represents UNIX domain socket and interfaces assigned to use this socket. Memif uses UNIX doman socket to communicate with other memif drivers.
-
-First fill out the `memif_socket_args` struct. The minimum required configuration is the UNIX socket path.
-> Use `@` or `\0` at the beginning of the path to use abstract socket.
-```c
-memif_socket_args_t sargs;
-
-strncpy(sargs.path, socket_path, sizeof(sargs.path));
-```
-```c
-memif_socket_handle_t memif_socket;
-
-memif_create_socket(&memif_socket, &sargs, &private_data);
-```
-Once you have created your socket, you can create memif interfaces on this socket. Fill out the `memif_conn_args` struct. Then call `memif_create()`.
-```c
-memif_conn_args_t cargs;
-
-/* Assign your socket handle */
-cargs.socket = memif_socket;
-```
-```c
-memif_conn_handle_t conn;
-
-/* Assign callbacks */
-memif_create (&conn, &cargs, on_connect_cb, on_disconnect_cb, on_interrupt_cb, &private_data);
-```
-Now start the polling events using libmemifs builtin polling.
-```c
-do {
- err = memif_poll_event(memif_socket, /* timeout -1 = blocking */ -1);
-} while (err == MEMIF_ERR_SUCCESS);
-```
-Polling can be canceled by calling `memif_cancel_poll_event()`.
-```c
-memif_cancel_poll_event (memif_socket);
-```
-On link status change `on_connect` and `on_disconnect` callbacks are called respectively. Before you can start transmitting data you, first need to call `memif_refill_queue()` for each RX queue to initialize this queue.
-```c
-int on_connect (memif_conn_handle_t conn, void *private_ctx)
-{
- my_private_data_t *data = (my_private_data_t *) private_ctx;
-
- err = memif_refill_queue(conn, 0, -1, 0);
- if (err != MEMIF_ERR_SUCCESS) {
- INFO("memif_refill_queue: %s", memif_strerror(err));
- return err;
- }
-
- /*
- * Do stuff.
- */
-
- return 0;
-}
-```
-Now you are ready to transmit packets.
-> Example implementation @ref examples/common/sender.c and @ref examples/common/responder.c
-
-To transmit or receive data you will need to use `memif_buffer` struct. The important fields here are `void *data`, `uint32_t len` and `uint8_t flags`. The `data` pointer points directly to the shared memory packet buffer. This is where you will find/insert your packets. The `len` field is the length of the buffer. If the flag `MEMIF_BUFFER_FLAG_NEXT` is present in `flags` field, this buffer is chained so the rest of the data is located in the next buffer, and so on.
-
-First let's receive data. To receive data call `memif_rx_burst()`. The function will fill out memif buffers passed to it. Then you would process your data (e.g. copy to your stack). Last you must refill the queue using `memif_refill_queue()` to notify peer that the buffers are now free and can be overwritten.
-```c
-/* Fill out memif buffers and mark them as received */
-err = memif_rx_burst(conn, qid, buffers, num_buffers, &num_received);
-if (err != MEMIF_ERR_SUCCESS) {
- INFO ("memif_rx_burst: %s", memif_strerror(err));
- return err;
-}
-/*
- Process the buffers.
-*/
-
-/* Refill the queue, so that the peer interface can transmit more packets */
-err = memif_refill_queue(conn, qid, num_received, 0);
-if (err != MEMIF_ERR_SUCCESS) {
- INFO("memif_refill_queue: %s", memif_strerror(err));
- goto error;
-}
-```
-In order to transmit data you first need to 'allocate' memif buffers using `memif_buffer_alloc()`. This function simmilar to `memif_rx_burst` will fill out provided memif buffers. You will then insert your packets directly into the shared memory (don't forget to update `len` filed if your packet is smaller that buffer length). Finaly call `memif_tx_burst` to transmit the buffers.
-```c
-/* Alocate memif buffers */
-err = memif_buffer_alloc(conn, qid, buffers, num_pkts, &num_allocated, packet_size);
-if (err != MEMIF_ERR_SUCCESS) {
- INFO("memif_buffer_alloc: %s", memif_strerror(err));
- goto error;
-}
-
-/*
- Fill out the buffers.
-
- tx_buffers[i].data field points to the shared memory.
- update tx_buffers[i].len to your packet length, if the packet is smaller.
-*/
-
-/* Transmit the buffers */
-err = memif_tx_burst(conn, qid, buffers, num_allocated, &num_transmitted);
-if (err != MEMIF_ERR_SUCCESS) {
- INFO("memif_tx_burst: %s", memif_strerror(err));
- goto error;
-}
-```
-### Zero-copy Slave
-
-Interface with slave role is the buffer producer, as such it can use zero-copy mode.
-
-After receiving buffers, process your packets in place. Then use `memif_buffer_enq_tx()` to enqueue rx buffers to tx queue (by swapping rx buffer with a free tx buffer).
-```c
-/* Fill out memif buffers and mark them as received */
-err = memif_rx_burst(conn, qid, buffers, num_buffers, &num_received);
-if (err != MEMIF_ERR_SUCCESS) {
- INFO ("memif_rx_burst: %s", memif_strerror(err));
- return err;
-}
-
-/*
- Process the buffers in place.
-*/
-
-/* Enqueue processed buffers to tx queue */
-err = memif_buffer_enq_tx(conn, qid, buffers, num_buffers, &num_enqueued);
-if (err != MEMIF_ERR_SUCCESS) {
- INFO("memif_buffer_alloc: %s", memif_strerror(err));
- goto error;
-}
-
-/* Refill the queue, so that the peer interface can transmit more packets */
-err = memif_refill_queue(conn, qid, num_enqueued, 0);
-if (err != MEMIF_ERR_SUCCESS) {
- INFO("memif_refill_queue: %s", memif_strerror(err));
- goto error;
-}
-
-/* Transmit the buffers. */
-err = memif_tx_burst(conn, qid, buffers, num_enqueued, &num_transmitted);
-if (err != MEMIF_ERR_SUCCESS) {
- INFO("memif_tx_burst: %s", memif_strerror(err));
- goto error;
-}
-```
-
-### Custom Event Polling
-
-Libmemif can be integrated into your applications fd event polling. You will need to implement `memif_control_fd_update_t` callback and pass it to `memif_socket_args.on_control_fd_update`. Now each time any file descriptor belonging to that socket updates, `on_control_fd_update` callback is called. The file descriptor and event type is passed in `memif_fd_event_t`. It also contains private context that is associated with this fd. When event is polled on the fd you need to call `memif_control_fd_handler` and pass the event type and private context associated with the fd.
-
-### Multi Threading
-
-#### Connection establishment
-
-Memif sockets should not be handled in paralell. Instead each thread should have it's own socket. However the UNIX socket can be the same. In case of non-listener socket, it's straight forward, just create the socket using the same path. In case of listener socket, the polling should be done by single thread.
-> The socket becomes listener once a Master interface is assigned to it.
-
-#### Packet handling
-
-Single queue must not be handled in paralel. Instead you can assign queues to threads in such way that each queue is only assigned single thread.
-
-### Shared Memory Layout
-
-Please refer to [DPDK MEMIF documentation](http://doc.dpdk.org/guides/nics/memif.html) `'Shared memory'` section. \ No newline at end of file
diff --git a/extras/libmemif/docs/gettingstarted_doc.rst b/extras/libmemif/docs/gettingstarted_doc.rst
new file mode 100644
index 00000000000..f576fe25145
--- /dev/null
+++ b/extras/libmemif/docs/gettingstarted_doc.rst
@@ -0,0 +1,234 @@
+.. _libmemif_gettingstarted_doc:
+
+Getting started
+===============
+
+For detailed information on api calls and structures please refer to
+``libmemif.h``.
+
+Start by creating a memif socket. Memif socket represents UNIX domain
+socket and interfaces assigned to use this socket. Memif uses UNIX domain
+socket to communicate with other memif drivers.
+
+First fill out the ``memif_socket_args`` struct. The minimum required
+configuration is the UNIX socket path. > Use ``@`` or ``\0`` at the
+beginning of the path to use abstract socket.
+
+.. code:: c
+
+ memif_socket_args_t sargs;
+
+ strncpy(sargs.path, socket_path, sizeof(sargs.path));
+
+.. code:: c
+
+ memif_socket_handle_t memif_socket;
+
+ memif_create_socket(&memif_socket, &sargs, &private_data);
+
+Once you have created your socket, you can create memif interfaces on
+this socket. Fill out the ``memif_conn_args`` struct. Then call
+``memif_create()``.
+
+.. code:: c
+
+ memif_conn_args_t cargs;
+
+ /* Assign your socket handle */
+ cargs.socket = memif_socket;
+
+.. code:: c
+
+ memif_conn_handle_t conn;
+
+ /* Assign callbacks */
+ memif_create (&conn, &cargs, on_connect_cb, on_disconnect_cb, on_interrupt_cb, &private_data);
+
+Now start the polling events using libmemifs builtin polling.
+
+.. code:: c
+
+ do {
+ err = memif_poll_event(memif_socket, /* timeout -1 = blocking */ -1);
+ } while (err == MEMIF_ERR_SUCCESS);
+
+Polling can be canceled by calling ``memif_cancel_poll_event()``.
+
+.. code:: c
+
+ memif_cancel_poll_event (memif_socket);
+
+On link status change ``on_connect`` and ``on_disconnect`` callbacks are
+called respectively. Before you can start transmitting data you, first
+need to call ``memif_refill_queue()`` for each RX queue to initialize
+this queue.
+
+.. code:: c
+
+ int on_connect (memif_conn_handle_t conn, void *private_ctx)
+ {
+ my_private_data_t *data = (my_private_data_t *) private_ctx;
+
+ err = memif_refill_queue(conn, 0, -1, 0);
+ if (err != MEMIF_ERR_SUCCESS) {
+ INFO("memif_refill_queue: %s", memif_strerror(err));
+ return err;
+ }
+
+ /*
+ * Do stuff.
+ */
+
+ return 0;
+ }
+
+Now you are ready to transmit packets. > Example implementation
+``examples/common/sender.c`` and ``examples/common/responder.c``
+
+To transmit or receive data you will need to use ``memif_buffer``
+struct. The important fields here are ``void *data``, ``uint32_t len``
+and ``uint8_t flags``. The ``data`` pointer points directly to the
+shared memory packet buffer. This is where you will find/insert your
+packets. The ``len`` field is the length of the buffer. If the flag
+``MEMIF_BUFFER_FLAG_NEXT`` is present in ``flags`` field, this buffer is
+chained so the rest of the data is located in the next buffer, and so
+on.
+
+First let’s receive data. To receive data call ``memif_rx_burst()``. The
+function will fill out memif buffers passed to it. Then you would
+process your data (e.g. copy to your stack). Last you must refill the
+queue using ``memif_refill_queue()`` to notify peer that the buffers are
+now free and can be overwritten.
+
+.. code:: c
+
+ /* Fill out memif buffers and mark them as received */
+ err = memif_rx_burst(conn, qid, buffers, num_buffers, &num_received);
+ if (err != MEMIF_ERR_SUCCESS) {
+ INFO ("memif_rx_burst: %s", memif_strerror(err));
+ return err;
+ }
+ /*
+ Process the buffers.
+ */
+
+ /* Refill the queue, so that the peer interface can transmit more packets */
+ err = memif_refill_queue(conn, qid, num_received, 0);
+ if (err != MEMIF_ERR_SUCCESS) {
+ INFO("memif_refill_queue: %s", memif_strerror(err));
+ goto error;
+ }
+
+In order to transmit data you first need to ‘allocate’ memif buffers
+using ``memif_buffer_alloc()``. This function similar to
+``memif_rx_burst`` will fill out provided memif buffers. You will then
+insert your packets directly into the shared memory (don’t forget to
+update ``len`` filed if your packet is smaller that buffer length).
+Finally call ``memif_tx_burst`` to transmit the buffers.
+
+.. code:: c
+
+ /* Alocate memif buffers */
+ err = memif_buffer_alloc(conn, qid, buffers, num_pkts, &num_allocated, packet_size);
+ if (err != MEMIF_ERR_SUCCESS) {
+ INFO("memif_buffer_alloc: %s", memif_strerror(err));
+ goto error;
+ }
+
+ /*
+ Fill out the buffers.
+
+ tx_buffers[i].data field points to the shared memory.
+ update tx_buffers[i].len to your packet length, if the packet is smaller.
+ */
+
+ /* Transmit the buffers */
+ err = memif_tx_burst(conn, qid, buffers, num_allocated, &num_transmitted);
+ if (err != MEMIF_ERR_SUCCESS) {
+ INFO("memif_tx_burst: %s", memif_strerror(err));
+ goto error;
+ }
+
+Zero-copy Slave
+---------------
+
+Interface with slave role is the buffer producer, as such it can use
+zero-copy mode.
+
+After receiving buffers, process your packets in place. Then use
+``memif_buffer_enq_tx()`` to enqueue rx buffers to tx queue (by swapping
+rx buffer with a free tx buffer).
+
+.. code:: c
+
+ /* Fill out memif buffers and mark them as received */
+ err = memif_rx_burst(conn, qid, buffers, num_buffers, &num_received);
+ if (err != MEMIF_ERR_SUCCESS) {
+ INFO ("memif_rx_burst: %s", memif_strerror(err));
+ return err;
+ }
+
+ /*
+ Process the buffers in place.
+ */
+
+ /* Enqueue processed buffers to tx queue */
+ err = memif_buffer_enq_tx(conn, qid, buffers, num_buffers, &num_enqueued);
+ if (err != MEMIF_ERR_SUCCESS) {
+ INFO("memif_buffer_alloc: %s", memif_strerror(err));
+ goto error;
+ }
+
+ /* Refill the queue, so that the peer interface can transmit more packets */
+ err = memif_refill_queue(conn, qid, num_enqueued, 0);
+ if (err != MEMIF_ERR_SUCCESS) {
+ INFO("memif_refill_queue: %s", memif_strerror(err));
+ goto error;
+ }
+
+ /* Transmit the buffers. */
+ err = memif_tx_burst(conn, qid, buffers, num_enqueued, &num_transmitted);
+ if (err != MEMIF_ERR_SUCCESS) {
+ INFO("memif_tx_burst: %s", memif_strerror(err));
+ goto error;
+ }
+
+Custom Event Polling
+--------------------
+
+Libmemif can be integrated into your applications fd event polling. You
+will need to implement ``memif_control_fd_update_t`` callback and pass
+it to ``memif_socket_args.on_control_fd_update``. Now each time any file
+descriptor belonging to that socket updates, ``on_control_fd_update``
+callback is called. The file descriptor and event type is passed in
+``memif_fd_event_t``. It also contains private context that is
+associated with this fd. When event is polled on the fd you need to call
+``memif_control_fd_handler`` and pass the event type and private context
+associated with the fd.
+
+Multi Threading
+---------------
+
+Connection establishment
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Memif sockets should not be handled in parallel. Instead each thread
+should have it’s own socket. However the UNIX socket can be the same. In
+case of non-listener socket, it’s straight forward, just create the
+socket using the same path. In case of listener socket, the polling
+should be done by single thread. > The socket becomes listener once a
+Master interface is assigned to it.
+
+Packet handling
+~~~~~~~~~~~~~~~
+
+Single queue must not be handled in parallel. Instead you can assign
+queues to threads in such way that each queue is only assigned single
+thread.
+
+Shared Memory Layout
+--------------------
+
+Please refer to `DPDK MEMIF
+documentation <http://doc.dpdk.org/guides/nics/memif.html>`__
+``'Shared memory'`` section.