Introduce new ELF origin RTE_BPF_ORIGIN_ELF_MEMORY allowing one to
specify data area containing ELF image.

Signed-off-by: Marat Khalili <[email protected]>
---
 lib/bpf/bpf_impl.h     |  5 +++++
 lib/bpf/bpf_load.c     |  4 ++++
 lib/bpf/bpf_load_elf.c | 40 +++++++++++++++++++++++++++++++++++++++-
 lib/bpf/rte_bpf.h      |  6 ++++++
 4 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/lib/bpf/bpf_impl.h b/lib/bpf/bpf_impl.h
index 92d03583d977..14ad772d4beb 100644
--- a/lib/bpf/bpf_impl.h
+++ b/lib/bpf/bpf_impl.h
@@ -27,6 +27,7 @@ struct __rte_bpf_load {
        /* Loading ELF and applying relocations. */
        int elf_fd;  /* ELF fd, must be negative (not zero) by default. */
        void *elf;  /* Using void to avoid dependency on libelf. */
+       const char *elf_section;
 
        /* Value we are going to return, if any. */
        struct rte_bpf *bpf;
@@ -53,6 +54,10 @@ __rte_bpf_load_elf_cleanup(struct __rte_bpf_load *load);
 int
 __rte_bpf_load_elf_file(struct __rte_bpf_load *load);
 
+/* Open the ELF memory image. */
+int
+__rte_bpf_load_elf_memory(struct __rte_bpf_load *load);
+
 /* Get code from ELF and apply relocations to it. */
 int
 __rte_bpf_load_elf_code(struct __rte_bpf_load *load);
diff --git a/lib/bpf/bpf_load.c b/lib/bpf/bpf_load.c
index c3c49ac49b1b..b626f6c61645 100644
--- a/lib/bpf/bpf_load.c
+++ b/lib/bpf/bpf_load.c
@@ -237,6 +237,10 @@ load_try(struct __rte_bpf_load *load, const struct 
rte_bpf_prm_ex *app_prm)
                rc = rc < 0 ? rc : __rte_bpf_load_elf_file(load);
                rc = rc < 0 ? rc : __rte_bpf_load_elf_code(load);
                break;
+       case RTE_BPF_ORIGIN_ELF_MEMORY:
+               rc = rc < 0 ? rc : __rte_bpf_load_elf_memory(load);
+               rc = rc < 0 ? rc : __rte_bpf_load_elf_code(load);
+               break;
        default:
                rc = rc < 0 ? rc : -EINVAL;
        }
diff --git a/lib/bpf/bpf_load_elf.c b/lib/bpf/bpf_load_elf.c
index 4ae7492351ae..80443cb63a61 100644
--- a/lib/bpf/bpf_load_elf.c
+++ b/lib/bpf/bpf_load_elf.c
@@ -310,6 +310,36 @@ __rte_bpf_load_elf_file(struct __rte_bpf_load *load)
                return -EINVAL;
        }
 
+       load->elf_section = prm->elf_file.section;
+
+       return 0;
+}
+
+int
+__rte_bpf_load_elf_memory(struct __rte_bpf_load *load)
+{
+       const struct rte_bpf_prm_ex *const prm = &load->prm;
+
+       RTE_ASSERT(prm->origin == RTE_BPF_ORIGIN_ELF_MEMORY);
+
+       if (prm->elf_memory.data == NULL || prm->elf_memory.section == NULL)
+               return -EINVAL;
+
+       if (elf_version(EV_CURRENT) == EV_NONE)
+               return -ENOTSUP;
+
+       load->elf = elf_memory(
+               /* Cast away const, we are not going to modify the ELF image. */
+               (char *)(uintptr_t)prm->elf_memory.data, prm->elf_memory.size);
+       if (load->elf == NULL) {
+               const int rc = elf_errno();
+               RTE_BPF_LOG_FUNC_LINE(ERR, "error %d opening ELF image: %s",
+                       rc, elf_errmsg(rc));
+               return -EINVAL;
+       }
+
+       load->elf_section = prm->elf_memory.section;
+
        return 0;
 }
 
@@ -321,7 +351,7 @@ __rte_bpf_load_elf_code(struct __rte_bpf_load *load)
        size_t sidx;
        int rc;
 
-       rc = find_elf_code(load->elf, prm->elf_file.section, &sd, &sidx);
+       rc = find_elf_code(load->elf, load->elf_section, &sd, &sidx);
        if (rc < 0)
                return rc;
 
@@ -353,6 +383,14 @@ __rte_bpf_load_elf_file(struct __rte_bpf_load *load)
        return -ENOTSUP;
 }
 
+int
+__rte_bpf_load_elf_memory(struct __rte_bpf_load *load)
+{
+       RTE_SET_USED(load);
+       RTE_BPF_LOG_FUNC_LINE(ERR, "not supported, rebuild with libelf 
installed");
+       return -ENOTSUP;
+}
+
 int
 __rte_bpf_load_elf_code(struct __rte_bpf_load *load)
 {
diff --git a/lib/bpf/rte_bpf.h b/lib/bpf/rte_bpf.h
index dcb709352e17..3c3848925bdf 100644
--- a/lib/bpf/rte_bpf.h
+++ b/lib/bpf/rte_bpf.h
@@ -97,6 +97,7 @@ enum rte_bpf_origin {
        RTE_BPF_ORIGIN_RAW,             /**< code loaded from raw array */
        RTE_BPF_ORIGIN_CBPF,            /**< code converted from cbpf */
        RTE_BPF_ORIGIN_ELF_FILE,        /**< code loaded from elf_file */
+       RTE_BPF_ORIGIN_ELF_MEMORY,      /**< code loaded from elf_memory */
 };
 
 struct bpf_insn;
@@ -127,6 +128,11 @@ struct rte_bpf_prm_ex {
                        const char *path;  /**< path to the ELF file */
                        const char *section;  /**< ELF section with the code */
                } elf_file;
+               struct {
+                       const void *data;  /**< pointer to the ELF image */
+                       size_t size;  /**< size of the ELF image */
+                       const char *section;  /**< ELF section with the code */
+               } elf_memory;
        };
 
        const struct rte_bpf_xsym *xsym;
-- 
2.43.0

Reply via email to