| 808 | |
| 809 | |
| 810 | static const char * |
| 811 | eval_load(struct bpf_verifier *bvf, const struct ebpf_insn *ins) |
| 812 | { |
| 813 | uint32_t opsz; |
| 814 | uint64_t msk; |
| 815 | const char *err; |
| 816 | struct bpf_eval_state *st; |
| 817 | struct bpf_reg_val *rd, rs; |
| 818 | const struct bpf_reg_val *sv; |
| 819 | |
| 820 | st = bvf->evst; |
| 821 | rd = st->rv + ins->dst_reg; |
| 822 | rs = st->rv[ins->src_reg]; |
| 823 | opsz = bpf_size(BPF_SIZE(ins->code)); |
| 824 | msk = RTE_LEN2MASK(opsz * CHAR_BIT, uint64_t); |
| 825 | |
| 826 | err = eval_ptr(bvf, &rs, opsz, 1, ins->off); |
| 827 | if (err != NULL) |
| 828 | return err; |
| 829 | |
| 830 | if (rs.v.type == BPF_ARG_PTR_STACK) { |
| 831 | |
| 832 | sv = st->sv + rs.u.max / sizeof(uint64_t); |
| 833 | if (sv->v.type == RTE_BPF_ARG_UNDEF || sv->mask < msk) |
| 834 | return "undefined value on the stack"; |
| 835 | |
| 836 | *rd = *sv; |
| 837 | |
| 838 | /* pointer to mbuf */ |
| 839 | } else if (rs.v.type == RTE_BPF_ARG_PTR_MBUF) { |
| 840 | |
| 841 | if (rs.u.max == offsetof(struct rte_mbuf, next)) { |
| 842 | eval_fill_imm(rd, msk, 0); |
| 843 | rd->v = rs.v; |
| 844 | } else if (rs.u.max == offsetof(struct rte_mbuf, buf_addr)) { |
| 845 | eval_fill_imm(rd, msk, 0); |
| 846 | rd->v.type = RTE_BPF_ARG_PTR; |
| 847 | rd->v.size = rs.v.buf_size; |
| 848 | } else if (rs.u.max == offsetof(struct rte_mbuf, data_off)) { |
| 849 | eval_fill_imm(rd, msk, RTE_PKTMBUF_HEADROOM); |
| 850 | rd->v.type = RTE_BPF_ARG_RAW; |
| 851 | } else { |
| 852 | eval_max_load(rd, msk); |
| 853 | rd->v.type = RTE_BPF_ARG_RAW; |
| 854 | } |
| 855 | |
| 856 | /* pointer to raw data */ |
| 857 | } else { |
| 858 | eval_max_load(rd, msk); |
| 859 | rd->v.type = RTE_BPF_ARG_RAW; |
| 860 | } |
| 861 | |
| 862 | return NULL; |
| 863 | } |
| 864 | |
| 865 | static const char * |
| 866 | eval_mbuf_store(const struct bpf_reg_val *rv, uint32_t opsz) |
nothing calls this directly
no test coverage detected