Run each subtest in test_bpf_elf twice: the old way loading ELF images
via temporary file, and using the new rte_bpf_load_ex API to load them
directly from memory.

In tests loading port/queue filters use new rte_bpf_eth_(rx|tx)_install
API to install an already loaded (via one of the ways) BPF program.

Signed-off-by: Marat Khalili <[email protected]>
---
 app/test/test_bpf.c | 193 ++++++++++++++++++++++++++------------------
 1 file changed, 113 insertions(+), 80 deletions(-)

diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c
index c8a4ee755097..69e84f0cab56 100644
--- a/app/test/test_bpf.c
+++ b/app/test/test_bpf.c
@@ -3977,12 +3977,61 @@ create_temp_bpf_file(const uint8_t *data, size_t size, 
const char *name)
 
 #include "test_bpf_load.h"
 
+/* Function loading BPF program from ELF image in memory. */
+typedef struct rte_bpf *
+(*load_elf_image_t)(const void *data, size_t size, const char *section,
+       const struct rte_bpf_xsym *xsym, uint32_t nb_xsym, const struct 
rte_bpf_arg *prog_arg);
+
+/* Load BPF program by writing ELF image to temporary file and opening this 
file. */
+static struct rte_bpf *
+load_elf_image_temp_file(const void *data, size_t size, const char *section,
+       const struct rte_bpf_xsym *xsym, uint32_t nb_xsym, const struct 
rte_bpf_arg *prog_arg)
+{
+       /* Create temp file from embedded BPF object */
+       char *tmpfile = create_temp_bpf_file(data, size, "test");
+       if (tmpfile == NULL) {
+               rte_errno = EIO;
+               return NULL;
+       }
+
+       /* Try to load BPF program from temp file */
+       const struct rte_bpf_prm prm = {
+               .xsym = xsym,
+               .nb_xsym = nb_xsym,
+               .prog_arg = *prog_arg,
+       };
+
+       struct rte_bpf *bpf = rte_bpf_elf_load(&prm, tmpfile, section);
+       unlink(tmpfile);
+       free(tmpfile);
+
+       return bpf;
+}
+
+/* Load BPF program by calling rte_bpf_load_ex and specifying image as the 
origin. */
+static struct rte_bpf *
+load_elf_image_direct(const void *data, size_t size, const char *section,
+       const struct rte_bpf_xsym *xsym, uint32_t nb_xsym, const struct 
rte_bpf_arg *prog_arg)
+{
+       return rte_bpf_load_ex(&(struct rte_bpf_prm_ex){
+               .sz = sizeof(struct rte_bpf_prm_ex),
+               .origin = RTE_BPF_ORIGIN_ELF_MEMORY,
+               .elf_memory.data = data,
+               .elf_memory.size = size,
+               .elf_memory.section = section,
+               .xsym = xsym,
+               .nb_xsym = nb_xsym,
+               .prog_arg[0] = *prog_arg,
+               .nb_prog_arg = 1,
+       });
+}
+
 /*
  * Test loading BPF program from an object file.
  * This test uses same arguments as previous test_call1 example.
  */
 static int
-test_bpf_elf_load(void)
+test_bpf_elf_load(load_elf_image_t load_elf_image)
 {
        static const char test_section[] = "call1";
        uint8_t tbuf[sizeof(struct dummy_vect8)];
@@ -4010,28 +4059,15 @@ test_bpf_elf_load(void)
                        },
                },
        };
-       int ret;
-
-       /* Create temp file from embedded BPF object */
-       char *tmpfile = create_temp_bpf_file(app_test_bpf_load_o,
-                                            app_test_bpf_load_o_len,
-                                            "load");
-       if (tmpfile == NULL)
-               return -1;
-
-       /* Try to load BPF program from temp file */
-       const struct rte_bpf_prm prm = {
-               .xsym = xsym,
-               .nb_xsym = RTE_DIM(xsym),
-               .prog_arg = {
-                       .type = RTE_BPF_ARG_PTR,
-                       .size = sizeof(tbuf),
-               },
+       static const struct rte_bpf_arg prog_arg = {
+               .type = RTE_BPF_ARG_PTR,
+               .size = sizeof(tbuf),
        };
+       struct rte_bpf *bpf;
+       int ret;
 
-       struct rte_bpf *bpf = rte_bpf_elf_load(&prm, tmpfile, test_section);
-       unlink(tmpfile);
-       free(tmpfile);
+       bpf = load_elf_image(app_test_bpf_load_o, app_test_bpf_load_o_len, 
test_section,
+               xsym, RTE_DIM(xsym), &prog_arg);
 
        /* If libelf support is not available */
        if (bpf == NULL && rte_errno == ENOTSUP)
@@ -4174,22 +4210,28 @@ setup_mbufs(struct rte_mbuf *burst[], unsigned int n)
        return tcp_count;
 }
 
-static int bpf_tx_test(uint16_t port, const char *tmpfile, struct rte_mempool 
*pool,
-                      const char *section, uint32_t flags)
+static int bpf_tx_test(uint16_t port, struct rte_mempool *pool, 
load_elf_image_t load_elf_image,
+       const char *section, uint32_t flags)
 {
-       const struct rte_bpf_prm prm = {
-               .prog_arg = {
-                       .type = RTE_BPF_ARG_PTR,
-                       .size = sizeof(struct dummy_net),
-               },
+       static const struct rte_bpf_arg prog_arg = {
+               .type = RTE_BPF_ARG_PTR,
+               .size = sizeof(struct dummy_net),
        };
+       struct rte_bpf *bpf;
        int ret;
 
-       /* Try to load BPF TX program from temp file */
-       ret = rte_bpf_eth_tx_elf_load(port, 0, &prm, tmpfile, section, flags);
+       /* Try to load BPF program from image */
+       bpf = load_elf_image(app_test_bpf_filter_o, app_test_bpf_filter_o_len, 
section,
+               NULL, 0, &prog_arg);
+       TEST_ASSERT_NOT_NULL(bpf, "failed to load BPF filter from image, 
error=%d:(%s)\n",
+                      rte_errno, rte_strerror(rte_errno));
+
+       /* Try to install loaded BPF program */
+       ret = rte_bpf_eth_tx_install(port, 0, bpf, flags);
        if (ret != 0) {
-               printf("%s@%d: failed to load BPF filter from file=%s 
error=%d:(%s)\n",
-                      __func__, __LINE__, tmpfile, rte_errno, 
rte_strerror(rte_errno));
+               printf("%s@%d: failed to install BPF filter, error=%d:(%s)\n",
+                      __func__, __LINE__, rte_errno, rte_strerror(rte_errno));
+               rte_bpf_destroy(bpf);
                return ret;
        }
 
@@ -4217,10 +4259,9 @@ static int bpf_tx_test(uint16_t port, const char 
*tmpfile, struct rte_mempool *p
 
 /* Test loading a transmit filter which only allows IPv4 packets */
 static int
-test_bpf_elf_tx_load(void)
+test_bpf_elf_tx_load(load_elf_image_t load_elf_image)
 {
        static const char null_dev[] = "net_null_bpf0";
-       char *tmpfile = NULL;
        struct rte_mempool *mb_pool = NULL;
        uint16_t port = UINT16_MAX;
        int ret;
@@ -4237,27 +4278,17 @@ test_bpf_elf_tx_load(void)
        if (ret != 0)
                goto fail;
 
-       /* Create temp file from embedded BPF object */
-       tmpfile = create_temp_bpf_file(app_test_bpf_filter_o, 
app_test_bpf_filter_o_len, "tx");
-       if (tmpfile == NULL)
-               goto fail;
-
        /* Do test with VM */
-       ret = bpf_tx_test(port, tmpfile, mb_pool, "filter", 0);
+       ret = bpf_tx_test(port, mb_pool, load_elf_image, "filter", 0);
        if (ret != 0)
                goto fail;
 
        /* Repeat with JIT */
-       ret = bpf_tx_test(port, tmpfile, mb_pool, "filter", RTE_BPF_ETH_F_JIT);
+       ret = bpf_tx_test(port, mb_pool, load_elf_image, "filter", 
RTE_BPF_ETH_F_JIT);
        if (ret == 0)
                printf("%s: TX ELF load test passed\n", __func__);
 
 fail:
-       if (tmpfile) {
-               unlink(tmpfile);
-               free(tmpfile);
-       }
-
        if (port != UINT16_MAX)
                rte_vdev_uninit(null_dev);
 
@@ -4272,23 +4303,28 @@ test_bpf_elf_tx_load(void)
 }
 
 /* Test loading a receive filter */
-static int bpf_rx_test(uint16_t port, const char *tmpfile, struct rte_mempool 
*pool,
-                      const char *section, uint32_t flags, uint16_t expected)
+static int bpf_rx_test(uint16_t port, struct rte_mempool *pool, 
load_elf_image_t load_elf_image,
+       const char *section, uint32_t flags, uint16_t expected)
 {
-       struct rte_mbuf *pkts[BPF_TEST_BURST];
-       const struct rte_bpf_prm prm = {
-               .prog_arg = {
-                       .type = RTE_BPF_ARG_PTR,
-                       .size = sizeof(struct dummy_net),
-               },
+       static const struct rte_bpf_arg prog_arg = {
+               .type = RTE_BPF_ARG_PTR,
+               .size = sizeof(struct dummy_net),
        };
+       struct rte_mbuf *pkts[BPF_TEST_BURST];
+       struct rte_bpf *bpf;
        int ret;
 
-       /* Load BPF program to drop all packets */
-       ret = rte_bpf_eth_rx_elf_load(port, 0, &prm, tmpfile, section, flags);
+       /* Try to load BPF program from image */
+       bpf = load_elf_image(app_test_bpf_filter_o, app_test_bpf_filter_o_len, 
section,
+               NULL, 0, &prog_arg);
+       TEST_ASSERT_NOT_NULL(bpf, "failed to load BPF filter from image, 
error=%d:(%s)\n",
+                      rte_errno, rte_strerror(rte_errno));
+
+       /* Try to install loaded BPF program */
+       ret = rte_bpf_eth_rx_install(port, 0, bpf, flags);
        if (ret != 0) {
-               printf("%s@%d: failed to load BPF filter from file=%s 
error=%d:(%s)\n",
-                      __func__, __LINE__, tmpfile, rte_errno, 
rte_strerror(rte_errno));
+               printf("%s@%d: failed to install BPF filter, error=%d:(%s)\n",
+                      __func__, __LINE__, rte_errno, rte_strerror(rte_errno));
                return ret;
        }
 
@@ -4311,11 +4347,10 @@ static int bpf_rx_test(uint16_t port, const char 
*tmpfile, struct rte_mempool *p
 
 /* Test loading a receive filters, first with drop all and then with allow all 
packets */
 static int
-test_bpf_elf_rx_load(void)
+test_bpf_elf_rx_load(load_elf_image_t load_elf_image)
 {
        static const char null_dev[] = "net_null_bpf0";
        struct rte_mempool *pool = NULL;
-       char *tmpfile = NULL;
        uint16_t port = UINT16_MAX;
        int ret;
 
@@ -4331,28 +4366,23 @@ test_bpf_elf_rx_load(void)
        if (ret != 0)
                goto fail;
 
-       /* Create temp file from embedded BPF object */
-       tmpfile = create_temp_bpf_file(app_test_bpf_filter_o, 
app_test_bpf_filter_o_len, "rx");
-       if (tmpfile == NULL)
-               goto fail;
-
        /* Do test with VM */
-       ret = bpf_rx_test(port, tmpfile, pool, "drop", 0, 0);
+       ret = bpf_rx_test(port, pool, load_elf_image, "drop", 0, 0);
        if (ret != 0)
                goto fail;
 
        /* Repeat with JIT */
-       ret = bpf_rx_test(port, tmpfile, pool, "drop", RTE_BPF_ETH_F_JIT, 0);
+       ret = bpf_rx_test(port, pool, load_elf_image, "drop", 
RTE_BPF_ETH_F_JIT, 0);
        if (ret != 0)
                goto fail;
 
        /* Repeat with allow all */
-       ret = bpf_rx_test(port, tmpfile, pool, "allow", 0, BPF_TEST_BURST);
+       ret = bpf_rx_test(port, pool, load_elf_image, "allow", 0, 
BPF_TEST_BURST);
        if (ret != 0)
                goto fail;
 
        /* Repeat with JIT */
-       ret = bpf_rx_test(port, tmpfile, pool, "allow", RTE_BPF_ETH_F_JIT, 
BPF_TEST_BURST);
+       ret = bpf_rx_test(port, pool, load_elf_image, "allow", 
RTE_BPF_ETH_F_JIT, BPF_TEST_BURST);
        if (ret != 0)
                goto fail;
 
@@ -4364,11 +4394,6 @@ test_bpf_elf_rx_load(void)
                          "Mempool available %u != %u leaks?", avail, 
BPF_TEST_POOLSIZE);
 
 fail:
-       if (tmpfile) {
-               unlink(tmpfile);
-               free(tmpfile);
-       }
-
        if (port != UINT16_MAX)
                rte_vdev_uninit(null_dev);
 
@@ -4381,13 +4406,21 @@ test_bpf_elf_rx_load(void)
 static int
 test_bpf_elf(void)
 {
-       int ret;
+       static const load_elf_image_t elf_image_loaders[] = {
+               load_elf_image_temp_file,
+               load_elf_image_direct,
+       };
 
-       ret = test_bpf_elf_load();
-       if (ret == TEST_SUCCESS)
-               ret = test_bpf_elf_tx_load();
-       if (ret == TEST_SUCCESS)
-               ret = test_bpf_elf_rx_load();
+       int ret = TEST_SUCCESS;
+
+       for (int li = 0; li != RTE_DIM(elf_image_loaders); ++li) {
+               if (ret == TEST_SUCCESS)
+                       ret = test_bpf_elf_load(elf_image_loaders[li]);
+               if (ret == TEST_SUCCESS)
+                       ret = test_bpf_elf_tx_load(elf_image_loaders[li]);
+               if (ret == TEST_SUCCESS)
+                       ret = test_bpf_elf_rx_load(elf_image_loaders[li]);
+       }
 
        return ret;
 }
-- 
2.43.0

Reply via email to