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