From: Harry van Haaren <harry.van.haa...@intel.com> This commit introduces functions for basic mbuf rx and tx. This commit also contains a unit test that calls rte_gen_rx_burst and rte_gen_tx_burst to send bursts of 32 packets repeatedly in order to verify their functionality
Signed-off-by: Harry van Haaren <harry.van.haa...@intel.com> Signed-off-by: Ronan Randles <ronan.rand...@intel.com> --- app/test/test_gen.c | 46 ++++++++++++++++++++++++++++++++++++++++++ lib/gen/meson.build | 1 + lib/gen/rte_gen.c | 43 +++++++++++++++++++++++++++++++++++++++ lib/gen/rte_gen.h | 49 +++++++++++++++++++++++++++++++++++++++++++++ lib/gen/version.map | 2 ++ 5 files changed, 141 insertions(+) diff --git a/app/test/test_gen.c b/app/test/test_gen.c index f53f4a6608..ceacd8c7c4 100644 --- a/app/test/test_gen.c +++ b/app/test/test_gen.c @@ -8,6 +8,8 @@ #include "test.h" +#define BURST_MAX 32 + static struct rte_mempool *mp; static int @@ -36,12 +38,56 @@ test_gen_create(void) return 0; } +static int +test_gen_basic_rxtx(void) +{ + struct rte_gen *gen = rte_gen_create(mp); + TEST_ASSERT_FAIL(gen, "Expected valid pointer after create()"); + + struct rte_mbuf *bufs[BURST_MAX]; + uint16_t nb_rx = rte_gen_rx_burst(gen, bufs, BURST_MAX); + TEST_ASSERT_EQUAL(nb_rx, BURST_MAX, "Expected rx packet burst."); + + uint64_t latency[BURST_MAX]; + uint16_t nb_tx = rte_gen_tx_burst(gen, bufs, latency, BURST_MAX); + TEST_ASSERT_EQUAL(nb_tx, BURST_MAX, "Expected tx packet burst."); + + rte_gen_destroy(gen); + return 0; +} + +static int +test_gen_loop_rxtx(void) +{ + struct rte_gen *gen = rte_gen_create(mp); + TEST_ASSERT_FAIL(gen, "Expected valid pointer after create()"); + + uint32_t total_sent = 0; + + while (total_sent < 1000000) { + struct rte_mbuf *bufs[BURST_MAX]; + uint16_t nb_rx = rte_gen_rx_burst(gen, bufs, BURST_MAX); + TEST_ASSERT_EQUAL(nb_rx, BURST_MAX, "Expected rx packet burst."); + + uint64_t latency[BURST_MAX]; + uint16_t nb_tx = rte_gen_tx_burst(gen, bufs, latency, nb_rx); + TEST_ASSERT_EQUAL(nb_tx, BURST_MAX, "Expected tx packet burst."); + + total_sent += nb_tx; + } + + rte_gen_destroy(gen); + return 0; +} + static struct unit_test_suite gen_suite = { .suite_name = "gen: packet generator unit test suite", .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = { TEST_CASE_ST(NULL, NULL, test_gen_create), + TEST_CASE_ST(NULL, NULL, test_gen_basic_rxtx), + TEST_CASE_ST(NULL, NULL, test_gen_loop_rxtx), TEST_CASES_END() /**< NULL terminate unit test array */ } }; diff --git a/lib/gen/meson.build b/lib/gen/meson.build index 3c5d854645..753984cbba 100644 --- a/lib/gen/meson.build +++ b/lib/gen/meson.build @@ -3,3 +3,4 @@ sources = files('rte_gen.c') headers = files('rte_gen.h') +deps += ['mempool', 'mbuf'] diff --git a/lib/gen/rte_gen.c b/lib/gen/rte_gen.c index d993772422..f0ad57fa81 100644 --- a/lib/gen/rte_gen.c +++ b/lib/gen/rte_gen.c @@ -4,8 +4,11 @@ #include "rte_gen.h" +#include <rte_mbuf.h> #include <rte_malloc.h> +#define GEN_MAX_BURST 32 + /** Structure that represents a traffic generator. */ struct rte_gen { /* Mempool that buffers are retrieved from. */ @@ -31,3 +34,43 @@ rte_gen_destroy(struct rte_gen *gen) { rte_free(gen); } + +uint16_t +rte_gen_rx_burst(struct rte_gen *gen, + struct rte_mbuf **rx_pkts, + const uint16_t nb_pkts) +{ + /* Get a bulk of nb_pkts from the mempool. */ + int err = rte_mempool_get_bulk(gen->mp, (void **)rx_pkts, nb_pkts); + if (err) + return 0; + + const uint32_t pkt_len = 64; + + uint32_t i; + for (i = 0; i < nb_pkts; i++) { + struct rte_mbuf *m = rx_pkts[i]; + uint8_t *pkt_data = rte_pktmbuf_mtod(m, uint8_t *); + + memset(pkt_data, 0, pkt_len); + + m->pkt_len = pkt_len; + m->data_len = pkt_len; + } + + return nb_pkts; +} + +uint16_t +rte_gen_tx_burst(struct rte_gen *gen, + struct rte_mbuf **tx_pkts, + uint64_t *pkt_latencies, + const uint16_t nb_pkts) +{ + RTE_SET_USED(gen); + RTE_SET_USED(pkt_latencies); + + rte_pktmbuf_free_bulk(tx_pkts, nb_pkts); + + return nb_pkts; +} diff --git a/lib/gen/rte_gen.h b/lib/gen/rte_gen.h index 5b30430f9e..09ee1e8872 100644 --- a/lib/gen/rte_gen.h +++ b/lib/gen/rte_gen.h @@ -25,6 +25,7 @@ extern "C" { struct rte_gen; /* Forward declarations for DPDK componeents. */ +struct rte_mbuf; struct rte_mempool; /* Allocate and initialize a traffic generator instance. */ @@ -37,6 +38,54 @@ __rte_experimental void rte_gen_destroy(struct rte_gen *gen); +/** + * Call to receive a burst of generated packets + * + * @param gen + * Gen instance to be used. + * @param rx_pkts + * mbuf where packets will be generated. + * @param nb_pkts + * number of packets to be generated + * + * @retval nb_pkts + * On success the number of rx'ed packets will be returned + * @retval 0 + * Failure. + */ +__rte_experimental +uint16_t +rte_gen_rx_burst(struct rte_gen *gen, + struct rte_mbuf **rx_pkts, + const uint16_t nb_pkts); + +/** Call to transmit a burst of traffic back to the generator. + * This allows the generator to calculate stats/properties of the stream. + * + * If the pkt_latencies parameter is not NULL, it is expected to be a pointer + * to an array of uint64_t values that has nb_pkts in length. Each individual + * packet latency will be stored to the array. + * + * @param gen + * Gen instance to be used. + * @param tx_pkts + * mbuf to be used to tx packets + * @param pkt_latencies + * Array to store latencies of sent packets + * @param nb_pkts + * The number of packets to be tx'ed + * + * @retval nb_pkts + * On success the number of packets tx'ed is returned + */ +__rte_experimental +uint16_t +rte_gen_tx_burst(struct rte_gen *gen, + struct rte_mbuf **tx_pkts, + uint64_t *pkt_latencies, + const uint16_t nb_pkts); + + #ifdef __cplusplus } #endif diff --git a/lib/gen/version.map b/lib/gen/version.map index d8a26eb53a..bdd25add6f 100644 --- a/lib/gen/version.map +++ b/lib/gen/version.map @@ -3,4 +3,6 @@ EXPERIMENTAL { rte_gen_create; rte_gen_destroy; + rte_gen_rx_burst; + rte_gen_tx_burst; }; -- 2.25.1