Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2018 Intel Corporation 3 : : */ 4 : : 5 : : #include <stdio.h> 6 : : #include <string.h> 7 : : #include <errno.h> 8 : : #include <stdint.h> 9 : : 10 : : #include <eal_export.h> 11 : : #include <rte_log.h> 12 : : #include <rte_errno.h> 13 : : 14 : : #include "bpf_impl.h" 15 : : 16 : : static struct rte_bpf * 17 : 48 : bpf_load(const struct rte_bpf_prm *prm) 18 : : { 19 : : uint8_t *buf; 20 : : struct rte_bpf *bpf; 21 : : size_t sz, bsz, insz, xsz; 22 : : 23 : 48 : xsz = prm->nb_xsym * sizeof(prm->xsym[0]); 24 : 48 : insz = prm->nb_ins * sizeof(prm->ins[0]); 25 : : bsz = sizeof(bpf[0]); 26 : 48 : sz = insz + xsz + bsz; 27 : : 28 : 48 : buf = mmap(NULL, sz, PROT_READ | PROT_WRITE, 29 : : MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 30 [ + - ]: 48 : if (buf == MAP_FAILED) 31 : : return NULL; 32 : : 33 : : bpf = (void *)buf; 34 : 48 : bpf->sz = sz; 35 : : 36 [ + + ]: 48 : memcpy(&bpf->prm, prm, sizeof(bpf->prm)); 37 : : 38 [ + + ]: 48 : if (xsz > 0) 39 : 5 : memcpy(buf + bsz, prm->xsym, xsz); 40 : 48 : memcpy(buf + bsz + xsz, prm->ins, insz); 41 : : 42 : 48 : bpf->prm.xsym = (void *)(buf + bsz); 43 : 48 : bpf->prm.ins = (void *)(buf + bsz + xsz); 44 : : 45 : 48 : return bpf; 46 : : } 47 : : 48 : : /* 49 : : * Check that user provided external symbol. 50 : : */ 51 : : static int 52 : 6 : bpf_check_xsym(const struct rte_bpf_xsym *xsym) 53 : : { 54 : : uint32_t i; 55 : : 56 [ + - ]: 6 : if (xsym->name == NULL) 57 : : return -EINVAL; 58 : : 59 [ - + ]: 6 : if (xsym->type == RTE_BPF_XTYPE_VAR) { 60 [ # # ]: 0 : if (xsym->var.desc.type == RTE_BPF_ARG_UNDEF) 61 : 0 : return -EINVAL; 62 [ + - ]: 6 : } else if (xsym->type == RTE_BPF_XTYPE_FUNC) { 63 : : 64 [ + - ]: 6 : if (xsym->func.nb_args > EBPF_FUNC_MAX_ARGS) 65 : : return -EINVAL; 66 : : 67 : : /* check function arguments */ 68 [ + + ]: 20 : for (i = 0; i != xsym->func.nb_args; i++) { 69 [ + - ]: 14 : if (xsym->func.args[i].type == RTE_BPF_ARG_UNDEF) 70 : : return -EINVAL; 71 : : } 72 : : 73 : : /* check return value info */ 74 [ + + ]: 6 : if (xsym->func.ret.type != RTE_BPF_ARG_UNDEF && 75 [ - + ]: 4 : xsym->func.ret.size == 0) 76 : 0 : return -EINVAL; 77 : : } else 78 : : return -EINVAL; 79 : : 80 : : return 0; 81 : : } 82 : : 83 : : RTE_EXPORT_SYMBOL(rte_bpf_load) 84 : : struct rte_bpf * 85 : 48 : rte_bpf_load(const struct rte_bpf_prm *prm) 86 : : { 87 : : struct rte_bpf *bpf; 88 : : int32_t rc; 89 : : uint32_t i; 90 : : 91 [ + - + - ]: 48 : if (prm == NULL || prm->ins == NULL || 92 [ + + + - ]: 48 : (prm->nb_xsym != 0 && prm->xsym == NULL)) { 93 : 0 : rte_errno = EINVAL; 94 : 0 : return NULL; 95 : : } 96 : : 97 : : rc = 0; 98 [ + + + - ]: 54 : for (i = 0; i != prm->nb_xsym && rc == 0; i++) 99 : 6 : rc = bpf_check_xsym(prm->xsym + i); 100 : : 101 [ - + ]: 48 : if (rc != 0) { 102 : 0 : rte_errno = -rc; 103 : 0 : RTE_BPF_LOG_LINE(ERR, "%s: %d-th xsym is invalid", __func__, i); 104 : 0 : return NULL; 105 : : } 106 : : 107 : 48 : bpf = bpf_load(prm); 108 [ - + ]: 48 : if (bpf == NULL) { 109 : 0 : rte_errno = ENOMEM; 110 : 0 : return NULL; 111 : : } 112 : : 113 : 48 : rc = __rte_bpf_validate(bpf); 114 [ + - ]: 48 : if (rc == 0) { 115 : 48 : __rte_bpf_jit(bpf); 116 [ + - ]: 48 : if (mprotect(bpf, bpf->sz, PROT_READ) != 0) 117 : : rc = -ENOMEM; 118 : : } 119 : : 120 [ - + ]: 48 : if (rc != 0) { 121 : 0 : rte_bpf_destroy(bpf); 122 : 0 : rte_errno = -rc; 123 : 0 : return NULL; 124 : : } 125 : : 126 : : return bpf; 127 : : }