
- icmp_responder: responds to ICMPv4 and ARP requests - loopback: connects two interfaces and sends a verification packet from master memif to slave memif where it is looped back - loopback (reverse path): reverses direction of packet in loopback application (slave memif to master memif) Type: refactor Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com> Change-Id: Ie90aaa3367269408efb6c5d538ad5aa827432238 Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
172 lines
4.2 KiB
C
172 lines
4.2 KiB
C
#include <common.h>
|
|
|
|
int
|
|
responder (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
|
|
{
|
|
memif_connection_t *c = (memif_connection_t *) private_ctx;
|
|
int err, i;
|
|
uint16_t tx;
|
|
|
|
/* receive packets from the shared memory */
|
|
err = memif_rx_burst (conn, qid, c->rx_bufs, MAX_MEMIF_BUFS, &c->rx_buf_num);
|
|
if (err != MEMIF_ERR_SUCCESS)
|
|
{
|
|
INFO ("memif_rx_burst: %s", memif_strerror (err));
|
|
return err;
|
|
}
|
|
|
|
do
|
|
{
|
|
/* allocate tx buffers */
|
|
err = memif_buffer_alloc (conn, qid, c->tx_bufs, c->rx_buf_num,
|
|
&c->tx_buf_num, 2048);
|
|
/* suppress full ring error MEMIF_ERR_NOBUF_RING */
|
|
if (err != MEMIF_ERR_SUCCESS && err != MEMIF_ERR_NOBUF_RING)
|
|
{
|
|
INFO ("memif_buffer_alloc: %s", memif_strerror (err));
|
|
goto error;
|
|
}
|
|
|
|
/* Process the packets */
|
|
if (c->packet_handler == NULL)
|
|
{
|
|
INFO ("Missing packet handler");
|
|
goto error;
|
|
}
|
|
err = c->packet_handler (c);
|
|
if (err != 0)
|
|
{
|
|
INFO ("packet handler error: %d", err);
|
|
goto error;
|
|
}
|
|
/* Done processing packets */
|
|
|
|
/* refill the queue */
|
|
err = memif_refill_queue (conn, qid, c->tx_buf_num, 0);
|
|
if (err != MEMIF_ERR_SUCCESS)
|
|
{
|
|
INFO ("memif_refill_queue: %s", memif_strerror (err));
|
|
goto error;
|
|
}
|
|
c->rx_buf_num -= c->tx_buf_num;
|
|
|
|
err = memif_tx_burst (conn, qid, c->tx_bufs, c->tx_buf_num, &tx);
|
|
if (err != MEMIF_ERR_SUCCESS)
|
|
{
|
|
INFO ("memif_tx_burst: %s", memif_strerror (err));
|
|
goto error;
|
|
}
|
|
c->tx_buf_num -= tx;
|
|
|
|
/* This should never happen */
|
|
if (c->tx_buf_num != 0)
|
|
{
|
|
INFO ("memif_tx_burst failed to send all allocated buffers.");
|
|
goto error;
|
|
}
|
|
}
|
|
while (c->rx_buf_num > 0);
|
|
|
|
return 0;
|
|
|
|
error:
|
|
err = memif_refill_queue (conn, qid, c->rx_buf_num, 0);
|
|
if (err != MEMIF_ERR_SUCCESS)
|
|
{
|
|
INFO ("memif_refill_queue: %s", memif_strerror (err));
|
|
return err;
|
|
}
|
|
c->rx_buf_num = 0;
|
|
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
responder_zero_copy (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
|
|
{
|
|
memif_connection_t *c = (memif_connection_t *) private_ctx;
|
|
int err, i;
|
|
uint16_t tx, tx2;
|
|
|
|
/* receive packets from the shared memory */
|
|
err = memif_rx_burst (conn, qid, c->rx_bufs, MAX_MEMIF_BUFS, &c->rx_buf_num);
|
|
if (err != MEMIF_ERR_SUCCESS)
|
|
{
|
|
INFO ("memif_rx_burst: %s", memif_strerror (err));
|
|
return err;
|
|
}
|
|
|
|
do
|
|
{
|
|
/* Note that in zero copy memif_buffer_alloc is not part of respond
|
|
process,
|
|
* instead rx buffers are used directly using memif_buffer_enq_tx.
|
|
* /
|
|
|
|
/* Process the packets */
|
|
if (c->packet_handler == NULL)
|
|
{
|
|
INFO ("Missing packet handler");
|
|
goto error;
|
|
}
|
|
err = c->packet_handler (c);
|
|
if (err != 0)
|
|
{
|
|
INFO ("packet handler error: %d", err);
|
|
goto error;
|
|
}
|
|
/* Done processing packets */
|
|
|
|
/* Swap rx and tx buffers, swapped tx buffers are considered allocated
|
|
* and are ready to be transmitted. Notice that the buffers are swapped
|
|
* only in memif driver and locally remain in rx_bufs queue.
|
|
*/
|
|
err = memif_buffer_enq_tx (conn, qid, c->rx_bufs, c->rx_buf_num, &tx);
|
|
/* suppress full ring error MEMIF_ERR_NOBUF_RING */
|
|
if (err != MEMIF_ERR_SUCCESS && err != MEMIF_ERR_NOBUF_RING)
|
|
{
|
|
INFO ("memif_buffer_alloc: %s", memif_strerror (err));
|
|
goto error;
|
|
}
|
|
|
|
/* refill the queue */
|
|
err = memif_refill_queue (conn, qid, tx, 0);
|
|
if (err != MEMIF_ERR_SUCCESS)
|
|
{
|
|
INFO ("memif_refill_queue: %s", memif_strerror (err));
|
|
goto error;
|
|
}
|
|
c->rx_buf_num -= tx;
|
|
|
|
/* Notice that we send from rx_bufs as the buffers were only swapped
|
|
* internally in memif driver */
|
|
err = memif_tx_burst (conn, qid, c->rx_bufs, tx, &tx2);
|
|
if (err != MEMIF_ERR_SUCCESS)
|
|
{
|
|
INFO ("memif_tx_burst: %s", memif_strerror (err));
|
|
goto error;
|
|
}
|
|
tx -= tx2;
|
|
|
|
/* This should never happen */
|
|
if (tx != 0)
|
|
{
|
|
INFO ("memif_tx_burst failed to send all allocated buffers.");
|
|
goto error;
|
|
}
|
|
}
|
|
while (c->rx_buf_num > 0);
|
|
|
|
return 0;
|
|
|
|
error:
|
|
err = memif_refill_queue (conn, qid, c->rx_buf_num, 0);
|
|
if (err != MEMIF_ERR_SUCCESS)
|
|
{
|
|
INFO ("memif_refill_queue: %s", memif_strerror (err));
|
|
return err;
|
|
}
|
|
c->rx_buf_num = 0;
|
|
|
|
return -1;
|
|
} |