dpdk: remove vlan-strip offload code
[vpp.git] / extras / libmemif / docs / gettingstarted_doc.rst
1 .. _libmemif_gettingstarted_doc:
2
3 Getting started
4 ===============
5
6 For detailed information on api calls and structures please refer to
7 ``libmemif.h``.
8
9 Start by creating a memif socket. Memif socket represents UNIX domain
10 socket and interfaces assigned to use this socket. Memif uses UNIX domain
11 socket to communicate with other memif drivers.
12
13 First fill out the ``memif_socket_args`` struct. The minimum required
14 configuration is the UNIX socket path. > Use ``@`` or ``\0`` at the
15 beginning of the path to use abstract socket.
16
17 .. code:: c
18
19    memif_socket_args_t sargs;
20
21    strncpy(sargs.path, socket_path, sizeof(sargs.path));
22
23 .. code:: c
24
25    memif_socket_handle_t memif_socket;
26
27    memif_create_socket(&memif_socket, &sargs, &private_data);
28
29 Once you have created your socket, you can create memif interfaces on
30 this socket. Fill out the ``memif_conn_args`` struct. Then call
31 ``memif_create()``.
32
33 .. code:: c
34
35    memif_conn_args_t cargs;
36
37    /* Assign your socket handle */
38    cargs.socket = memif_socket;
39
40 .. code:: c
41
42    memif_conn_handle_t conn;
43
44    /* Assign callbacks */
45    memif_create (&conn, &cargs, on_connect_cb, on_disconnect_cb, on_interrupt_cb, &private_data);
46
47 Now start the polling events using libmemifs builtin polling.
48
49 .. code:: c
50
51    do {
52        err = memif_poll_event(memif_socket, /* timeout -1 = blocking */ -1);
53    } while (err == MEMIF_ERR_SUCCESS);
54
55 Polling can be canceled by calling ``memif_cancel_poll_event()``.
56
57 .. code:: c
58
59    memif_cancel_poll_event (memif_socket);
60
61 On link status change ``on_connect`` and ``on_disconnect`` callbacks are
62 called respectively. Before you can start transmitting data you, first
63 need to call ``memif_refill_queue()`` for each RX queue to initialize
64 this queue.
65
66 .. code:: c
67
68    int on_connect (memif_conn_handle_t conn, void *private_ctx)
69    {
70      my_private_data_t *data = (my_private_data_t *) private_ctx;
71
72      err = memif_refill_queue(conn, 0, -1, 0);
73      if (err != MEMIF_ERR_SUCCESS) {
74        INFO("memif_refill_queue: %s", memif_strerror(err));
75        return err;
76      }
77
78      /*
79       * Do stuff.
80       */
81
82      return 0;
83    }
84
85 Now you are ready to transmit packets. > Example implementation
86 ``examples/common/sender.c`` and ``examples/common/responder.c``
87
88 To transmit or receive data you will need to use ``memif_buffer``
89 struct. The important fields here are ``void *data``, ``uint32_t len``
90 and ``uint8_t flags``. The ``data`` pointer points directly to the
91 shared memory packet buffer. This is where you will find/insert your
92 packets. The ``len`` field is the length of the buffer. If the flag
93 ``MEMIF_BUFFER_FLAG_NEXT`` is present in ``flags`` field, this buffer is
94 chained so the rest of the data is located in the next buffer, and so
95 on.
96
97 First let’s receive data. To receive data call ``memif_rx_burst()``. The
98 function will fill out memif buffers passed to it. Then you would
99 process your data (e.g. copy to your stack). Last you must refill the
100 queue using ``memif_refill_queue()`` to notify peer that the buffers are
101 now free and can be overwritten.
102
103 .. code:: c
104
105    /* Fill out memif buffers and mark them as received */
106    err = memif_rx_burst(conn, qid, buffers, num_buffers, &num_received);
107    if (err != MEMIF_ERR_SUCCESS) {
108        INFO ("memif_rx_burst: %s", memif_strerror(err));
109        return err;
110    }
111    /*
112        Process the buffers.
113    */
114
115    /* Refill the queue, so that the peer interface can transmit more packets */
116    err = memif_refill_queue(conn, qid, num_received, 0);
117    if (err != MEMIF_ERR_SUCCESS) {
118        INFO("memif_refill_queue: %s", memif_strerror(err));
119        goto error;
120    }
121
122 In order to transmit data you first need to ‘allocate’ memif buffers
123 using ``memif_buffer_alloc()``. This function similar to
124 ``memif_rx_burst`` will fill out provided memif buffers. You will then
125 insert your packets directly into the shared memory (don’t forget to
126 update ``len`` filed if your packet is smaller that buffer length).
127 Finally call ``memif_tx_burst`` to transmit the buffers.
128
129 .. code:: c
130
131    /* Alocate memif buffers */
132    err = memif_buffer_alloc(conn, qid, buffers, num_pkts, &num_allocated, packet_size);
133    if (err != MEMIF_ERR_SUCCESS) {
134        INFO("memif_buffer_alloc: %s", memif_strerror(err));
135        goto error;
136    }
137
138    /*
139        Fill out the buffers.
140
141        tx_buffers[i].data field points to the shared memory.
142        update tx_buffers[i].len to your packet length, if the packet is smaller.
143    */
144
145    /* Transmit the buffers */
146    err = memif_tx_burst(conn, qid, buffers, num_allocated, &num_transmitted);
147    if (err != MEMIF_ERR_SUCCESS) {
148        INFO("memif_tx_burst: %s", memif_strerror(err));
149        goto error;
150    }
151
152 Zero-copy Slave
153 ---------------
154
155 Interface with slave role is the buffer producer, as such it can use
156 zero-copy mode.
157
158 After receiving buffers, process your packets in place. Then use
159 ``memif_buffer_enq_tx()`` to enqueue rx buffers to tx queue (by swapping
160 rx buffer with a free tx buffer).
161
162 .. code:: c
163
164    /* Fill out memif buffers and mark them as received */
165    err = memif_rx_burst(conn, qid, buffers, num_buffers, &num_received);
166    if (err != MEMIF_ERR_SUCCESS) {
167        INFO ("memif_rx_burst: %s", memif_strerror(err));
168        return err;
169    }
170
171    /*
172        Process the buffers in place.
173    */
174
175    /* Enqueue processed buffers to tx queue */
176    err = memif_buffer_enq_tx(conn, qid, buffers, num_buffers, &num_enqueued);
177    if (err != MEMIF_ERR_SUCCESS) {
178        INFO("memif_buffer_alloc: %s", memif_strerror(err));
179        goto error;
180    }
181
182    /* Refill the queue, so that the peer interface can transmit more packets */
183    err = memif_refill_queue(conn, qid, num_enqueued, 0);
184    if (err != MEMIF_ERR_SUCCESS) {
185        INFO("memif_refill_queue: %s", memif_strerror(err));
186        goto error;
187    }
188
189    /* Transmit the buffers. */
190    err = memif_tx_burst(conn, qid, buffers, num_enqueued, &num_transmitted);
191    if (err != MEMIF_ERR_SUCCESS) {
192        INFO("memif_tx_burst: %s", memif_strerror(err));
193        goto error;
194    }
195
196 Custom Event Polling
197 --------------------
198
199 Libmemif can be integrated into your applications fd event polling. You
200 will need to implement ``memif_control_fd_update_t`` callback and pass
201 it to ``memif_socket_args.on_control_fd_update``. Now each time any file
202 descriptor belonging to that socket updates, ``on_control_fd_update``
203 callback is called. The file descriptor and event type is passed in
204 ``memif_fd_event_t``. It also contains private context that is
205 associated with this fd. When event is polled on the fd you need to call
206 ``memif_control_fd_handler`` and pass the event type and private context
207 associated with the fd.
208
209 Multi Threading
210 ---------------
211
212 Connection establishment
213 ~~~~~~~~~~~~~~~~~~~~~~~~
214
215 Memif sockets should not be handled in parallel. Instead each thread
216 should have it’s own socket. However the UNIX socket can be the same. In
217 case of non-listener socket, it’s straight forward, just create the
218 socket using the same path. In case of listener socket, the polling
219 should be done by single thread. > The socket becomes listener once a
220 Master interface is assigned to it.
221
222 Packet handling
223 ~~~~~~~~~~~~~~~
224
225 Single queue must not be handled in parallel. Instead you can assign
226 queues to threads in such way that each queue is only assigned single
227 thread.
228
229 Shared Memory Layout
230 --------------------
231
232 Please refer to `DPDK MEMIF
233 documentation <http://doc.dpdk.org/guides/nics/memif.html>`__
234 ``'Shared memory'`` section.