(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)
{
}
}
+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])
{
(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);
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)
{
return i;
}
-__rte_experimental uint64_t
+uint64_t
rte_bpf_exec(const struct rte_bpf *bpf, void *ctx)
{
uint64_t rc;