[PATCH RFC v2 net-next 01/16] net: filter: split filter.c into two files
BPF is used in several kernel components. This split creates logical boundary between generic eBPF core and the rest kernel/bpf/core.c: eBPF interpreter net/core/filter.c: classic->eBPF converter, classic verifiers, socket filters This patch only moves functions. Signed-off-by: Alexei Starovoitov --- kernel/Makefile |1 + kernel/bpf/Makefile |1 + kernel/bpf/core.c | 536 +++ net/core/filter.c | 511 4 files changed, 538 insertions(+), 511 deletions(-) create mode 100644 kernel/bpf/Makefile create mode 100644 kernel/bpf/core.c diff --git a/kernel/Makefile b/kernel/Makefile index f2a8b6246ce9..e7360b7c2c0e 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -87,6 +87,7 @@ obj-$(CONFIG_RING_BUFFER) += trace/ obj-$(CONFIG_TRACEPOINTS) += trace/ obj-$(CONFIG_IRQ_WORK) += irq_work.o obj-$(CONFIG_CPU_PM) += cpu_pm.o +obj-$(CONFIG_NET) += bpf/ obj-$(CONFIG_PERF_EVENTS) += events/ diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile new file mode 100644 index ..6a71145e2769 --- /dev/null +++ b/kernel/bpf/Makefile @@ -0,0 +1 @@ +obj-y := core.o diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c new file mode 100644 index ..77a240a1ce11 --- /dev/null +++ b/kernel/bpf/core.c @@ -0,0 +1,536 @@ +/* + * Linux Socket Filter - Kernel level socket filtering + * + * Based on the design of the Berkeley Packet Filter. The new + * internal format has been designed by PLUMgrid: + * + * Copyright (c) 2011 - 2014 PLUMgrid, http://plumgrid.com + * + * Authors: + * + * Jay Schulist + * Alexei Starovoitov + * Daniel Borkmann + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Andi Kleen - Fix a few bad bugs and races. + * Kris Katterjohn - Added many additional checks in sk_chk_filter() + */ +#include +#include +#include + +/* Registers */ +#define BPF_R0 regs[BPF_REG_0] +#define BPF_R1 regs[BPF_REG_1] +#define BPF_R2 regs[BPF_REG_2] +#define BPF_R3 regs[BPF_REG_3] +#define BPF_R4 regs[BPF_REG_4] +#define BPF_R5 regs[BPF_REG_5] +#define BPF_R6 regs[BPF_REG_6] +#define BPF_R7 regs[BPF_REG_7] +#define BPF_R8 regs[BPF_REG_8] +#define BPF_R9 regs[BPF_REG_9] +#define BPF_R10regs[BPF_REG_10] + +/* Named registers */ +#define DSTregs[insn->dst_reg] +#define SRCregs[insn->src_reg] +#define FP regs[BPF_REG_FP] +#define ARG1 regs[BPF_REG_ARG1] +#define CTXregs[BPF_REG_CTX] +#define IMMinsn->imm + +/* No hurry in this branch + * + * Exported for the bpf jit load helper. + */ +void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, unsigned int size) +{ + u8 *ptr = NULL; + + if (k >= SKF_NET_OFF) + ptr = skb_network_header(skb) + k - SKF_NET_OFF; + else if (k >= SKF_LL_OFF) + ptr = skb_mac_header(skb) + k - SKF_LL_OFF; + if (ptr >= skb->head && ptr + size <= skb_tail_pointer(skb)) + return ptr; + + return NULL; +} + +/* Base function for offset calculation. Needs to go into .text section, + * therefore keeping it non-static as well; will also be used by JITs + * anyway later on, so do not let the compiler omit it. + */ +noinline u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) +{ + return 0; +} + +/** + * __sk_run_filter - run a filter on a given context + * @ctx: buffer to run the filter on + * @insn: filter to apply + * + * Decode and apply filter instructions to the skb->data. Return length to + * keep, 0 for none. @ctx is the data we are operating on, @insn is the + * array of filter instructions. + */ +static unsigned int __sk_run_filter(void *ctx, const struct sock_filter_int *insn) +{ + u64 stack[MAX_BPF_STACK / sizeof(u64)]; + u64 regs[MAX_BPF_REG], tmp; + static const void *jumptable[256] = { + [0 ... 255] = &_label, + /* Now overwrite non-defaults ... */ + /* 32 bit ALU operations */ + [BPF_ALU | BPF_ADD | BPF_X] = &_ADD_X, + [BPF_ALU | BPF_ADD | BPF_K] = &_ADD_K, + [BPF_ALU | BPF_SUB | BPF_X] = &_SUB_X, + [BPF_ALU | BPF_SUB | BPF_K] = &_SUB_K, + [BPF_ALU | BPF_AND | BPF_X] = &_AND_X, + [BPF_ALU | BPF_AND | BPF_K] = &_AND_K, + [BPF_ALU | BPF_OR | BPF_X] = &_OR_X, + [BPF_ALU | BPF_OR | BPF_K] = &_OR_K, + [BPF_ALU | BPF_LSH | BPF_X] = &_LSH_X, + [BPF_ALU | BPF_LSH | BPF_K] = &_LSH_K, + [BPF_ALU | BPF_RSH | BPF_X] = &_RSH_X, + [BPF_ALU | BPF_RSH | BPF_K] = &_RSH_K, + [BPF_ALU | BPF_XOR | BPF_X] = &_XOR_X, + [BPF_ALU | BPF_XOR | BPF_K] =
[PATCH RFC v2 net-next 01/16] net: filter: split filter.c into two files
BPF is used in several kernel components. This split creates logical boundary between generic eBPF core and the rest kernel/bpf/core.c: eBPF interpreter net/core/filter.c: classic-eBPF converter, classic verifiers, socket filters This patch only moves functions. Signed-off-by: Alexei Starovoitov a...@plumgrid.com --- kernel/Makefile |1 + kernel/bpf/Makefile |1 + kernel/bpf/core.c | 536 +++ net/core/filter.c | 511 4 files changed, 538 insertions(+), 511 deletions(-) create mode 100644 kernel/bpf/Makefile create mode 100644 kernel/bpf/core.c diff --git a/kernel/Makefile b/kernel/Makefile index f2a8b6246ce9..e7360b7c2c0e 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -87,6 +87,7 @@ obj-$(CONFIG_RING_BUFFER) += trace/ obj-$(CONFIG_TRACEPOINTS) += trace/ obj-$(CONFIG_IRQ_WORK) += irq_work.o obj-$(CONFIG_CPU_PM) += cpu_pm.o +obj-$(CONFIG_NET) += bpf/ obj-$(CONFIG_PERF_EVENTS) += events/ diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile new file mode 100644 index ..6a71145e2769 --- /dev/null +++ b/kernel/bpf/Makefile @@ -0,0 +1 @@ +obj-y := core.o diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c new file mode 100644 index ..77a240a1ce11 --- /dev/null +++ b/kernel/bpf/core.c @@ -0,0 +1,536 @@ +/* + * Linux Socket Filter - Kernel level socket filtering + * + * Based on the design of the Berkeley Packet Filter. The new + * internal format has been designed by PLUMgrid: + * + * Copyright (c) 2011 - 2014 PLUMgrid, http://plumgrid.com + * + * Authors: + * + * Jay Schulist jsch...@samba.org + * Alexei Starovoitov a...@plumgrid.com + * Daniel Borkmann dbork...@redhat.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Andi Kleen - Fix a few bad bugs and races. + * Kris Katterjohn - Added many additional checks in sk_chk_filter() + */ +#include linux/filter.h +#include linux/skbuff.h +#include asm/unaligned.h + +/* Registers */ +#define BPF_R0 regs[BPF_REG_0] +#define BPF_R1 regs[BPF_REG_1] +#define BPF_R2 regs[BPF_REG_2] +#define BPF_R3 regs[BPF_REG_3] +#define BPF_R4 regs[BPF_REG_4] +#define BPF_R5 regs[BPF_REG_5] +#define BPF_R6 regs[BPF_REG_6] +#define BPF_R7 regs[BPF_REG_7] +#define BPF_R8 regs[BPF_REG_8] +#define BPF_R9 regs[BPF_REG_9] +#define BPF_R10regs[BPF_REG_10] + +/* Named registers */ +#define DSTregs[insn-dst_reg] +#define SRCregs[insn-src_reg] +#define FP regs[BPF_REG_FP] +#define ARG1 regs[BPF_REG_ARG1] +#define CTXregs[BPF_REG_CTX] +#define IMMinsn-imm + +/* No hurry in this branch + * + * Exported for the bpf jit load helper. + */ +void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, unsigned int size) +{ + u8 *ptr = NULL; + + if (k = SKF_NET_OFF) + ptr = skb_network_header(skb) + k - SKF_NET_OFF; + else if (k = SKF_LL_OFF) + ptr = skb_mac_header(skb) + k - SKF_LL_OFF; + if (ptr = skb-head ptr + size = skb_tail_pointer(skb)) + return ptr; + + return NULL; +} + +/* Base function for offset calculation. Needs to go into .text section, + * therefore keeping it non-static as well; will also be used by JITs + * anyway later on, so do not let the compiler omit it. + */ +noinline u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) +{ + return 0; +} + +/** + * __sk_run_filter - run a filter on a given context + * @ctx: buffer to run the filter on + * @insn: filter to apply + * + * Decode and apply filter instructions to the skb-data. Return length to + * keep, 0 for none. @ctx is the data we are operating on, @insn is the + * array of filter instructions. + */ +static unsigned int __sk_run_filter(void *ctx, const struct sock_filter_int *insn) +{ + u64 stack[MAX_BPF_STACK / sizeof(u64)]; + u64 regs[MAX_BPF_REG], tmp; + static const void *jumptable[256] = { + [0 ... 255] = default_label, + /* Now overwrite non-defaults ... */ + /* 32 bit ALU operations */ + [BPF_ALU | BPF_ADD | BPF_X] = ALU_ADD_X, + [BPF_ALU | BPF_ADD | BPF_K] = ALU_ADD_K, + [BPF_ALU | BPF_SUB | BPF_X] = ALU_SUB_X, + [BPF_ALU | BPF_SUB | BPF_K] = ALU_SUB_K, + [BPF_ALU | BPF_AND | BPF_X] = ALU_AND_X, + [BPF_ALU | BPF_AND | BPF_K] = ALU_AND_K, + [BPF_ALU | BPF_OR | BPF_X] = ALU_OR_X, + [BPF_ALU | BPF_OR | BPF_K] = ALU_OR_K, + [BPF_ALU | BPF_LSH | BPF_X] = ALU_LSH_X, + [BPF_ALU | BPF_LSH | BPF_K] = ALU_LSH_K, + [BPF_ALU | BPF_RSH | BPF_X] = ALU_RSH_X, + [BPF_ALU |