This set of patches introduce 'direct packet access' from cls_bpf and act_bpf programs (which are root only).
Current bpf programs use LD_ABS, LD_INS instructions which have to do 'if (off < skb_headlen)' for every packet access. It's ok for socket filters, but too slow for XDP, since single LD_ABS insn consumes 3% of cpu. Therefore we have to amortize the cost of length check over multiple packet accesses via direct access to skb->data, data_end pointers. The existing packet parser typically look like: if (load_half(skb, offsetof(struct ethhdr, h_proto)) != ETH_P_IP) return 0; if (load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol)) != IPPROTO_UDP || load_byte(skb, ETH_HLEN) != 0x45) return 0; ... with 'direct packet access' the bpf program becomes: void *data = (void *)(long)skb->data; void *data_end = (void *)(long)skb->data_end; struct eth_hdr *eth = data; struct iphdr *iph = data + sizeof(*eth); if (data + sizeof(*eth) + sizeof(*iph) + sizeof(*udp) > data_end) return 0; if (eth->h_proto != htons(ETH_P_IP)) return 0; if (iph->protocol != IPPROTO_UDP || iph->ihl != 5) return 0; ... which is more natural to write and significantly faster. See patch 6 for performance tests: 21Mpps(old) vs 24Mpps(new) with just 5 loads. For more complex parsers the performance gain is higher. The other approach implemented in [1] was adding two new instructions to interpreter and JITs and was too hard to use from llvm side. The approach presented here doesn't need any instruction changes, but the verifier has to work harder to check safety of the packet access. Patch 1 prepares the code and Patch 2 adds new checks for direct packet access and all of them are gated with 'env->allow_ptr_leaks' which is true for root only. Patch 3 improves search pruning for large programs. Patch 4 wires in verifier's changes with net/core/filter side. Patch 5 updates docs Patches 6 and 7 add tests. [1] https://git.kernel.org/cgit/linux/kernel/git/ast/bpf.git/?h=ld_abs_dw Alexei Starovoitov (7): bpf: cleanup verifier code bpf: direct packet access bpf: improve verifier state equivalence bpf: wire in data and data_end for cls_act_bpf bpf: add documentation for 'direct packet access' samples/bpf: add 'pointer to packet' tests samples/bpf: add verifier tests Documentation/networking/filter.txt | 85 +++++- include/linux/filter.h | 16 + include/uapi/linux/bpf.h | 2 + kernel/bpf/core.c | 5 + kernel/bpf/verifier.c | 562 +++++++++++++++++++++++++++++++----- net/core/filter.c | 51 +++- net/sched/act_bpf.c | 2 + net/sched/cls_bpf.c | 2 + samples/bpf/Makefile | 2 + samples/bpf/parse_ldabs.c | 41 +++ samples/bpf/parse_simple.c | 48 +++ samples/bpf/parse_varlen.c | 153 ++++++++++ samples/bpf/test_cls_bpf.sh | 37 +++ samples/bpf/test_verifier.c | 80 +++++ 14 files changed, 1004 insertions(+), 82 deletions(-) create mode 100644 samples/bpf/parse_ldabs.c create mode 100644 samples/bpf/parse_simple.c create mode 100644 samples/bpf/parse_varlen.c create mode 100755 samples/bpf/test_cls_bpf.sh -- 2.8.0