libmemif: add support for custom buffer-size and headroom in icmp example app
[vpp.git] / extras / libmemif / examples / common / responder.c
1 #include <common.h>
2
3 int
4 responder (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
5 {
6   memif_connection_t *c = (memif_connection_t *) private_ctx;
7   int err, i;
8   uint16_t tx;
9
10   /* receive packets from the shared memory */
11   err = memif_rx_burst (conn, qid, c->rx_bufs, MAX_MEMIF_BUFS, &c->rx_buf_num);
12   if (err != MEMIF_ERR_SUCCESS)
13     {
14       INFO ("memif_rx_burst: %s", memif_strerror (err));
15       return err;
16     }
17
18   do
19     {
20       /* allocate tx buffers */
21       err = memif_buffer_alloc (conn, qid, c->tx_bufs, c->rx_buf_num,
22                                 &c->tx_buf_num, c->buffer_size);
23       /* suppress full ring error MEMIF_ERR_NOBUF_RING */
24       if (err != MEMIF_ERR_SUCCESS && err != MEMIF_ERR_NOBUF_RING)
25         {
26           INFO ("memif_buffer_alloc: %s", memif_strerror (err));
27           goto error;
28         }
29
30       /* Process the packets */
31       if (c->packet_handler == NULL)
32         {
33           INFO ("Missing packet handler");
34           goto error;
35         }
36       err = c->packet_handler (c);
37       if (err != 0)
38         {
39           INFO ("packet handler error: %d", err);
40           goto error;
41         }
42       /* Done processing packets */
43
44       /* refill the queue */
45       err = memif_refill_queue (conn, qid, c->tx_buf_num, c->headroom_size);
46       if (err != MEMIF_ERR_SUCCESS)
47         {
48           INFO ("memif_refill_queue: %s", memif_strerror (err));
49           goto error;
50         }
51       c->rx_buf_num -= c->tx_buf_num;
52
53       err = memif_tx_burst (conn, qid, c->tx_bufs, c->tx_buf_num, &tx);
54       if (err != MEMIF_ERR_SUCCESS)
55         {
56           INFO ("memif_tx_burst: %s", memif_strerror (err));
57           goto error;
58         }
59       c->tx_buf_num -= tx;
60
61       /* This should never happen */
62       if (c->tx_buf_num != 0)
63         {
64           INFO ("memif_tx_burst failed to send all allocated buffers.");
65           goto error;
66         }
67     }
68   while (c->rx_buf_num > 0);
69
70   return 0;
71
72 error:
73   err = memif_refill_queue (conn, qid, c->rx_buf_num, c->headroom_size);
74   if (err != MEMIF_ERR_SUCCESS)
75     {
76       INFO ("memif_refill_queue: %s", memif_strerror (err));
77       return err;
78     }
79   c->rx_buf_num = 0;
80
81   return -1;
82 }
83
84 int
85 responder_zero_copy (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
86 {
87   memif_connection_t *c = (memif_connection_t *) private_ctx;
88   int err, i;
89   uint16_t tx, tx2;
90
91   /* receive packets from the shared memory */
92   err = memif_rx_burst (conn, qid, c->rx_bufs, MAX_MEMIF_BUFS, &c->rx_buf_num);
93   if (err != MEMIF_ERR_SUCCESS)
94     {
95       INFO ("memif_rx_burst: %s", memif_strerror (err));
96       return err;
97     }
98
99   do
100     {
101       /* Note that in zero copy memif_buffer_alloc is not part of respond
102       process,
103        * instead rx buffers are used directly using memif_buffer_enq_tx.
104        * /
105
106       /* Process the packets */
107       if (c->packet_handler == NULL)
108         {
109           INFO ("Missing packet handler");
110           goto error;
111         }
112       err = c->packet_handler (c);
113       if (err != 0)
114         {
115           INFO ("packet handler error: %d", err);
116           goto error;
117         }
118       /* Done processing packets */
119
120       /* Swap rx and tx buffers, swapped tx buffers are considered allocated
121        * and are ready to be transmitted. Notice that the buffers are swapped
122        * only in memif driver and locally remain in rx_bufs queue.
123        */
124       err = memif_buffer_enq_tx (conn, qid, c->rx_bufs, c->rx_buf_num, &tx);
125       /* suppress full ring error MEMIF_ERR_NOBUF_RING */
126       if (err != MEMIF_ERR_SUCCESS && err != MEMIF_ERR_NOBUF_RING)
127         {
128           INFO ("memif_buffer_alloc: %s", memif_strerror (err));
129           goto error;
130         }
131
132       /* refill the queue */
133       err = memif_refill_queue (conn, qid, tx, c->headroom_size);
134       if (err != MEMIF_ERR_SUCCESS)
135         {
136           INFO ("memif_refill_queue: %s", memif_strerror (err));
137           goto error;
138         }
139       c->rx_buf_num -= tx;
140
141       /* Notice that we send from rx_bufs as the buffers were only swapped
142        * internally in memif driver */
143       err = memif_tx_burst (conn, qid, c->rx_bufs, tx, &tx2);
144       if (err != MEMIF_ERR_SUCCESS)
145         {
146           INFO ("memif_tx_burst: %s", memif_strerror (err));
147           goto error;
148         }
149       tx -= tx2;
150
151       /* This should never happen */
152       if (tx != 0)
153         {
154           INFO ("memif_tx_burst failed to send all allocated buffers.");
155           goto error;
156         }
157     }
158   while (c->rx_buf_num > 0);
159
160   return 0;
161
162 error:
163   err = memif_refill_queue (conn, qid, c->rx_buf_num, c->headroom_size);
164   if (err != MEMIF_ERR_SUCCESS)
165     {
166       INFO ("memif_refill_queue: %s", memif_strerror (err));
167       return err;
168     }
169   c->rx_buf_num = 0;
170
171   return -1;
172 }