X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_bpf%2Fbpf_exec.c;h=b921112feb3a700f580e3cf6f8c51d44fdab61ed;hb=d354c5e77666f443dfdb1dadc7b8abe0c9fe258d;hp=6a79139c0d07fbc7030159c985e38d71572c18be;hpb=60702e8c7cbbadd4d5e6ffe4d7f470db339b0a04;p=dpdk.git diff --git a/lib/librte_bpf/bpf_exec.c b/lib/librte_bpf/bpf_exec.c index 6a79139c0d..b921112feb 100644 --- a/lib/librte_bpf/bpf_exec.c +++ b/lib/librte_bpf/bpf_exec.c @@ -74,6 +74,26 @@ (uintptr_t)((reg)[(ins)->dst_reg] + (ins)->off), \ reg[ins->src_reg])) +/* BPF_LD | BPF_ABS/BPF_IND */ + +#define NOP(x) (x) + +#define BPF_LD_ABS(bpf, reg, ins, type, op) do { \ + const type *p = bpf_ld_mbuf(bpf, reg, ins, (ins)->imm, sizeof(type)); \ + if (p == NULL) \ + return 0; \ + reg[EBPF_REG_0] = op(p[0]); \ +} while (0) + +#define BPF_LD_IND(bpf, reg, ins, type, op) do { \ + uint32_t ofs = reg[ins->src_reg] + (ins)->imm; \ + const type *p = bpf_ld_mbuf(bpf, reg, ins, ofs, sizeof(type)); \ + if (p == NULL) \ + return 0; \ + reg[EBPF_REG_0] = op(p[0]); \ +} while (0) + + static inline void bpf_alu_be(uint64_t reg[EBPF_REG_NUM], const struct ebpf_insn *ins) { @@ -112,6 +132,23 @@ bpf_alu_le(uint64_t reg[EBPF_REG_NUM], const struct ebpf_insn *ins) } } +static inline const void * +bpf_ld_mbuf(const struct rte_bpf *bpf, uint64_t reg[EBPF_REG_NUM], + const struct ebpf_insn *ins, uint32_t off, uint32_t len) +{ + const struct rte_mbuf *mb; + const void *p; + + mb = (const struct rte_mbuf *)(uintptr_t)reg[EBPF_REG_6]; + p = rte_pktmbuf_read(mb, off, len, reg + EBPF_REG_0); + if (p == NULL) + RTE_BPF_LOG(DEBUG, "%s(bpf=%p, mbuf=%p, ofs=%u, len=%u): " + "load beyond packet boundary at pc: %#zx;\n", + __func__, bpf, mb, off, len, + (uintptr_t)(ins) - (uintptr_t)(bpf)->prm.ins); + return p; +} + static inline uint64_t bpf_exec(const struct rte_bpf *bpf, uint64_t reg[EBPF_REG_NUM]) { @@ -296,6 +333,26 @@ bpf_exec(const struct rte_bpf *bpf, uint64_t reg[EBPF_REG_NUM]) (uint64_t)(uint32_t)ins[1].imm << 32; ins++; break; + /* load absolute instructions */ + case (BPF_LD | BPF_ABS | BPF_B): + BPF_LD_ABS(bpf, reg, ins, uint8_t, NOP); + break; + case (BPF_LD | BPF_ABS | BPF_H): + BPF_LD_ABS(bpf, reg, ins, uint16_t, rte_be_to_cpu_16); + break; + case (BPF_LD | BPF_ABS | BPF_W): + BPF_LD_ABS(bpf, reg, ins, uint32_t, rte_be_to_cpu_32); + break; + /* load indirect instructions */ + case (BPF_LD | BPF_IND | BPF_B): + BPF_LD_IND(bpf, reg, ins, uint8_t, NOP); + break; + case (BPF_LD | BPF_IND | BPF_H): + BPF_LD_IND(bpf, reg, ins, uint16_t, rte_be_to_cpu_16); + break; + case (BPF_LD | BPF_IND | BPF_W): + BPF_LD_IND(bpf, reg, ins, uint32_t, rte_be_to_cpu_32); + break; /* store instructions */ case (BPF_STX | BPF_MEM | BPF_B): BPF_ST_REG(reg, ins, uint8_t); @@ -424,7 +481,7 @@ bpf_exec(const struct rte_bpf *bpf, uint64_t reg[EBPF_REG_NUM]) return 0; } -__rte_experimental uint32_t +uint32_t rte_bpf_exec_burst(const struct rte_bpf *bpf, void *ctx[], uint64_t rc[], uint32_t num) { @@ -443,7 +500,7 @@ rte_bpf_exec_burst(const struct rte_bpf *bpf, void *ctx[], uint64_t rc[], return i; } -__rte_experimental uint64_t +uint64_t rte_bpf_exec(const struct rte_bpf *bpf, void *ctx) { uint64_t rc;