libmemif: don't consume rx queue interrupt, if memif_rx_burst fails
[vpp.git] / extras / libmemif / docs / gettingstarted_doc.md
1 ## Getting started    {#libmemif_gettingstarted_doc}
2
3 #### Concept (Connecting to VPP)
4
5 For detailed information on api calls and structures please refer to @ref libmemif.h.
6
7 1. Initialize memif
8    - Declare callback function handling file descriptor event polling.
9 ```C
10 int
11 control_fd_update (int fd, uint8_t events)
12 {
13 ...
14 }
15 ```
16    - Call memif initialization function. memif\_init
17 ```C
18 err = memif_init (control_fd_update, APP_NAME, NULL, NULL);
19 ```
20    
21 > If event occurres on any file descriptor returned by this callback, call memif\_control\_fd\_handler function. Since version 2.0, last two optional arguments are used to specify custom memory allocation.
22 ```C
23 memif_err = memif_control_fd_handler (evt.data.fd, events);
24 ``` 
25 > If callback function parameter for memif\_init function is set to NULL, libmemif will handle file descriptor event polling.
26   Api call memif\_poll\_event will call epoll\_pwait with user defined timeout to poll event on file descriptors opened by libmemif.
27 ```C
28 /* main loop */
29     while (1)
30     {
31         if (memif_poll_event (-1) < 0)
32         {
33             DBG ("poll_event error!");
34         }
35     }
36 ```
37     
38 > Memif initialization function will initialize internal structures and create timer file descriptor, which will be used for sending periodic connection requests. Timer is disarmed if no memif interface is created.
39  
40 2. Creating interface
41    - Declare memif connction handle.
42 ```C
43 memif_conn_handle_t c;
44 ```
45 > example app uses struct that contains connection handle, rx/tx buffers and other connection specific information.
46
47    - Specify connection arguments.
48 ```C
49 memif_conn_args_t args;
50 memset (&args, 0, sizeof (args));
51 args.is_master = is_master;
52 args.log2_ring_size = 10;
53 args.buffer_size = 2048;
54 args.num_s2m_rings = 2;
55 args.num_m2s_rings = 2;
56 strncpy ((char *) args.interface_name, IF_NAME, strlen (IF_NAME));
57 args.mode = 0;
58 args.interface_id = 0;
59 ```
60    - Declare callback functions called on connected/disconnected/interrupted status changed.
61 ```C
62 int
63 on_connect (memif_conn_handle_t conn, void *private_ctx)
64 {
65 ...
66 }
67
68 int
69 on_disconnect (memif_conn_handle_t conn, void *private_ctx)
70 {
71     INFO ("memif connected!");
72     return 0;
73 }
74 ```
75    - Call memif interface create function. memif\_create
76 ```C
77 err = memif_create (&c->conn,
78         &args, on_connect, on_disconnect, on_interrupt, &ctx[index]);
79 ```
80 > If connection is in slave mode, arms timer file descriptor.
81 > If on interrupt callback is set to NULL, user will not be notified about interrupt. Use memif\_get\_queue\_efd call to get interrupt file descriptor for specific queue.
82 ```C
83 int fd = -1;
84 err = memif_get_queue_efd (c->conn, data->qid, &fd);
85 ```
86
87 3. Connection establishment
88     - User application will poll events on all file descriptors returned in memif\_control\_fd\_update\_t callback.
89     - On event call memif\_control\_fd\_handler.
90     - Everything else regarding connection establishment will be done internally.
91     - Once connection has been established, a callback will inform the user about connection status change.
92
93 4. Interrupt packet receive
94     - If event is polled on interrupt file descriptor, libmemif will call memif\_interrupt\_t callback specified for every connection instance.
95 ```C
96 int
97 on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
98 {
99 ...
100 }
101 ```
102
103 6. Memif buffers
104     - Packet data are stored in memif\_buffer\_t. Pointer _data_ points to shared memory buffer, and unsigned integer *_len* contains buffer length.
105     - flags: MEMIF\_BUFFER\_FLAG\_NEXT states that the buffer is not large enough to contain whole packet, so next buffer contains the rest of the packet. (chained buffers)
106 ```C
107 typedef struct
108 {
109     uint16_t desc_index;
110     uint32_t len;
111     uint8_t flags;
112     void *data;
113 } memif_buffer_t;
114 ```
115
116 5. Packet receive
117     - Api call memif\_rx\_burst will set all required fields in memif buffers provided by user application, dequeue received buffers and consume interrupt event on receive queue. The event is not consumed, if memif_rx_burst fails.
118 ```C
119 err = memif_rx_burst (c->conn, qid, c->bufs, MAX_MEMIF_BUFS, &rx);
120 ```
121     - User application can then process packets.
122     - Api call memif\_refill\_queue will enqueue rx buffers.
123 ```C
124 err = memif_refill_queue (c->conn, qid, rx);
125 ```
126
127 6. Packet transmit
128     - Api call memif\_buffer\_alloc will find free tx buffers and set all required fields in memif buffers provided by user application.
129 ```C
130 err = memif_buffer_alloc (c->conn, qid, c->tx_bufs, n, &r);
131 ```
132     - User application can populate shared memory buffers with packets.
133     - Api call memif\_tx\_burst will enqueue tx buffers
134 ```C
135 err = memif_tx_burst (c->conn, qid, c->tx_bufs, c->tx_buf_num, &r);
136 ```
137
138 7. Helper functions
139     - Memif version
140 ```C
141 uint16_t memif_ver = memif_get_version ();
142 ```
143     - Memif details
144       - Api call memif\_get\_details will return details about connection.
145 ```C
146 err = memif_get_details (c->conn, &md, buf, buflen);
147 ```
148     - Memif error messages
149       - Every api call returns error code (integer value) mapped to error string.
150       - Call memif\_strerror will return error message assigned to specific error code.
151 ```C
152 if (err != MEMIF_ERR_SUCCESS)
153     INFO ("memif_get_details: %s", memif_strerror (err));
154 ```
155         - Not all syscall errors are translated to memif error codes. If error code 1 (MEMIF\_ERR\_SYSCALL) is returned then libmemif needs to be compiled with -DMEMIF_DBG flag to print error message. Use _make -B_ to rebuild libmemif in debug mode.
156
157 #### Example app (libmemif fd event polling):
158
159 - @ref extras/libmemif/examples/icmp_responder
160
161 > Optional argument: transmit queue id.
162 ```
163 icmpr 1
164 ```
165 > Set transmit queue id to 1. Default is 0.
166 > Application will create memif interface in slave mode and try to connect to VPP. Exit using Ctrl+C. Application will handle SIGINT signal, free allocated memory and exit with EXIT_SUCCESS.
167
168 #### Example app:
169
170 ICMP Responder custom fd event polling.
171
172 - @ref extras/libmemif/examples/icmp_responder-epoll
173
174 #### Example app (multi-thread queue polling)
175
176 ICMP Responder multi-thread.
177 - @ref extras/libmemif/examples/icmp_responder-mt
178
179 > Simple example of libmemif multi-thread usage. Connection establishment is handled by main thread. There are two rx/tx queues in this example. One in polling mode and second in interrupt mode.
180
181 VPP config:
182 ```
183 # create memif id 0 master
184 # set int state memif0 up
185 # set int ip address memif0 192.168.1.1/24
186 # ping 192.168.1.2
187 ```
188 For multiple rings (queues) support run VPP with worker threads:
189 example startup.conf:
190 ```
191 unix {
192   interactive
193   nodaemon 
194   full-coredump
195 }
196
197 cpu {
198   workers 2
199 }
200 ```
201 VPP config:
202 ```
203 # create memif id 0 master
204 # set int state memif0 up
205 # set int ip address memif0 192.168.1.1/24
206 # ping 192.168.1.2
207 ```
208 > Master mode queue number is limited by worker threads. Slave mode interface needs to specify number of queues.
209 ```
210 # create memif id 0 slave rx-queues 2 tx-queues 2
211 ```
212 > Example applications use VPP default socket file for memif: /run/vpp/memif.sock
213 > For master mode, socket directory must exist prior to memif\_create call.
214
215 #### Unit tests
216
217 Unit tests use [Check](https://libcheck.github.io/check/index.html) framework. This framework must be installed in order to build *unit\_test* binary.
218 Ubuntu/Debian:
219 ```
220 sudo apt-get install check
221 ```
222 [More platforms](https://libcheck.github.io/check/web/install.html)
223