Commit e430f34e authored by Alexei Starovoitov's avatar Alexei Starovoitov Committed by David S. Miller

net: filter: cleanup A/X name usage

The macro 'A' used in internal BPF interpreter:
 #define A regs[insn->a_reg]
was easily confused with the name of classic BPF register 'A', since
'A' would mean two different things depending on context.

This patch is trying to clean up the naming and clarify its usage in the
following way:

- A and X are names of two classic BPF registers

- BPF_REG_A denotes internal BPF register R0 used to map classic register A
  in internal BPF programs generated from classic

- BPF_REG_X denotes internal BPF register R7 used to map classic register X
  in internal BPF programs generated from classic

- internal BPF instruction format:
struct sock_filter_int {
        __u8    code;           /* opcode */
        __u8    dst_reg:4;      /* dest register */
        __u8    src_reg:4;      /* source register */
        __s16   off;            /* signed offset */
        __s32   imm;            /* signed immediate constant */
};

- BPF_X/BPF_K is 1 bit used to encode source operand of instruction
In classic:
  BPF_X - means use register X as source operand
  BPF_K - means use 32-bit immediate as source operand
In internal:
  BPF_X - means use 'src_reg' register as source operand
  BPF_K - means use 32-bit immediate as source operand
Suggested-by: default avatarChema Gonzalez <chema@google.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@plumgrid.com>
Acked-by: default avatarDaniel Borkmann <dborkman@redhat.com>
Acked-by: default avatarChema Gonzalez <chema@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7b0dcbd8
...@@ -805,7 +805,7 @@ to seccomp_data, for converted BPF filters R1 points to a skb. ...@@ -805,7 +805,7 @@ to seccomp_data, for converted BPF filters R1 points to a skb.
A program, that is translated internally consists of the following elements: A program, that is translated internally consists of the following elements:
op:16, jt:8, jf:8, k:32 ==> op:8, a_reg:4, x_reg:4, off:16, imm:32 op:16, jt:8, jf:8, k:32 ==> op:8, dst_reg:4, src_reg:4, off:16, imm:32
So far 87 internal BPF instructions were implemented. 8-bit 'op' opcode field So far 87 internal BPF instructions were implemented. 8-bit 'op' opcode field
has room for new instructions. Some of them may use 16/24/32 byte encoding. New has room for new instructions. Some of them may use 16/24/32 byte encoding. New
......
This diff is collapsed.
...@@ -78,161 +78,173 @@ enum { ...@@ -78,161 +78,173 @@ enum {
/* Helper macros for filter block array initializers. */ /* Helper macros for filter block array initializers. */
/* ALU ops on registers, bpf_add|sub|...: A += X */ /* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
#define BPF_ALU64_REG(OP, A, X) \ #define BPF_ALU64_REG(OP, DST, SRC) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \ .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = 0, \ .off = 0, \
.imm = 0 }) .imm = 0 })
#define BPF_ALU32_REG(OP, A, X) \ #define BPF_ALU32_REG(OP, DST, SRC) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU | BPF_OP(OP) | BPF_X, \ .code = BPF_ALU | BPF_OP(OP) | BPF_X, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = 0, \ .off = 0, \
.imm = 0 }) .imm = 0 })
/* ALU ops on immediates, bpf_add|sub|...: A += IMM */ /* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
#define BPF_ALU64_IMM(OP, A, IMM) \ #define BPF_ALU64_IMM(OP, DST, IMM) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \ .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = 0, \ .src_reg = 0, \
.off = 0, \ .off = 0, \
.imm = IMM }) .imm = IMM })
#define BPF_ALU32_IMM(OP, A, IMM) \ #define BPF_ALU32_IMM(OP, DST, IMM) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU | BPF_OP(OP) | BPF_K, \ .code = BPF_ALU | BPF_OP(OP) | BPF_K, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = 0, \ .src_reg = 0, \
.off = 0, \ .off = 0, \
.imm = IMM }) .imm = IMM })
/* Endianess conversion, cpu_to_{l,b}e(), {l,b}e_to_cpu() */ /* Endianess conversion, cpu_to_{l,b}e(), {l,b}e_to_cpu() */
#define BPF_ENDIAN(TYPE, A, LEN) \ #define BPF_ENDIAN(TYPE, DST, LEN) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU | BPF_END | BPF_SRC(TYPE), \ .code = BPF_ALU | BPF_END | BPF_SRC(TYPE), \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = 0, \ .src_reg = 0, \
.off = 0, \ .off = 0, \
.imm = LEN }) .imm = LEN })
/* Short form of mov, A = X */ /* Short form of mov, dst_reg = src_reg */
#define BPF_MOV64_REG(A, X) \ #define BPF_MOV64_REG(DST, SRC) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU64 | BPF_MOV | BPF_X, \ .code = BPF_ALU64 | BPF_MOV | BPF_X, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = 0, \ .off = 0, \
.imm = 0 }) .imm = 0 })
#define BPF_MOV32_REG(A, X) \ #define BPF_MOV32_REG(DST, SRC) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU | BPF_MOV | BPF_X, \ .code = BPF_ALU | BPF_MOV | BPF_X, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = 0, \ .off = 0, \
.imm = 0 }) .imm = 0 })
/* Short form of mov, A = IMM */ /* Short form of mov, dst_reg = imm32 */
#define BPF_MOV64_IMM(A, IMM) \ #define BPF_MOV64_IMM(DST, IMM) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU64 | BPF_MOV | BPF_K, \ .code = BPF_ALU64 | BPF_MOV | BPF_K, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = 0, \ .src_reg = 0, \
.off = 0, \ .off = 0, \
.imm = IMM }) .imm = IMM })
#define BPF_MOV32_IMM(A, IMM) \ #define BPF_MOV32_IMM(DST, IMM) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU | BPF_MOV | BPF_K, \ .code = BPF_ALU | BPF_MOV | BPF_K, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = 0, \ .src_reg = 0, \
.off = 0, \ .off = 0, \
.imm = IMM }) .imm = IMM })
/* Short form of mov based on type, BPF_X: A = X, BPF_K: A = IMM */ /* Short form of mov based on type, BPF_X: dst_reg = src_reg, BPF_K: dst_reg = imm32 */
#define BPF_MOV64_RAW(TYPE, A, X, IMM) \ #define BPF_MOV64_RAW(TYPE, DST, SRC, IMM) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU64 | BPF_MOV | BPF_SRC(TYPE), \ .code = BPF_ALU64 | BPF_MOV | BPF_SRC(TYPE), \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = 0, \ .off = 0, \
.imm = IMM }) .imm = IMM })
#define BPF_MOV32_RAW(TYPE, A, X, IMM) \ #define BPF_MOV32_RAW(TYPE, DST, SRC, IMM) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_ALU | BPF_MOV | BPF_SRC(TYPE), \ .code = BPF_ALU | BPF_MOV | BPF_SRC(TYPE), \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = 0, \ .off = 0, \
.imm = IMM }) .imm = IMM })
/* Direct packet access, R0 = *(uint *) (skb->data + OFF) */ /* Direct packet access, R0 = *(uint *) (skb->data + imm32) */
#define BPF_LD_ABS(SIZE, OFF) \ #define BPF_LD_ABS(SIZE, IMM) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \ .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \
.a_reg = 0, \ .dst_reg = 0, \
.x_reg = 0, \ .src_reg = 0, \
.off = 0, \ .off = 0, \
.imm = OFF }) .imm = IMM })
/* Indirect packet access, R0 = *(uint *) (skb->data + X + OFF) */ /* Indirect packet access, R0 = *(uint *) (skb->data + src_reg + imm32) */
#define BPF_LD_IND(SIZE, X, OFF) \ #define BPF_LD_IND(SIZE, SRC, IMM) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_LD | BPF_SIZE(SIZE) | BPF_IND, \ .code = BPF_LD | BPF_SIZE(SIZE) | BPF_IND, \
.a_reg = 0, \ .dst_reg = 0, \
.x_reg = X, \ .src_reg = SRC, \
.off = 0, \ .off = 0, \
.imm = OFF }) .imm = IMM })
/* Memory store, A = *(uint *) (X + OFF), and vice versa */ /* Memory load, dst_reg = *(uint *) (src_reg + off16) */
#define BPF_LDX_MEM(SIZE, A, X, OFF) \ #define BPF_LDX_MEM(SIZE, DST, SRC, OFF) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \ .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = OFF, \ .off = OFF, \
.imm = 0 }) .imm = 0 })
#define BPF_STX_MEM(SIZE, A, X, OFF) \ /* Memory store, *(uint *) (dst_reg + off16) = src_reg */
#define BPF_STX_MEM(SIZE, DST, SRC, OFF) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \ .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = OFF, \ .off = OFF, \
.imm = 0 }) .imm = 0 })
/* Conditional jumps against registers, if (A 'op' X) goto pc + OFF */ /* Memory store, *(uint *) (dst_reg + off16) = imm32 */
#define BPF_ST_MEM(SIZE, DST, OFF, IMM) \
((struct sock_filter_int) { \
.code = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM, \
.dst_reg = DST, \
.src_reg = 0, \
.off = OFF, \
.imm = IMM })
/* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */
#define BPF_JMP_REG(OP, A, X, OFF) \ #define BPF_JMP_REG(OP, DST, SRC, OFF) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_JMP | BPF_OP(OP) | BPF_X, \ .code = BPF_JMP | BPF_OP(OP) | BPF_X, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = OFF, \ .off = OFF, \
.imm = 0 }) .imm = 0 })
/* Conditional jumps against immediates, if (A 'op' IMM) goto pc + OFF */ /* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */
#define BPF_JMP_IMM(OP, A, IMM, OFF) \ #define BPF_JMP_IMM(OP, DST, IMM, OFF) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_JMP | BPF_OP(OP) | BPF_K, \ .code = BPF_JMP | BPF_OP(OP) | BPF_K, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = 0, \ .src_reg = 0, \
.off = OFF, \ .off = OFF, \
.imm = IMM }) .imm = IMM })
...@@ -241,18 +253,18 @@ enum { ...@@ -241,18 +253,18 @@ enum {
#define BPF_EMIT_CALL(FUNC) \ #define BPF_EMIT_CALL(FUNC) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_JMP | BPF_CALL, \ .code = BPF_JMP | BPF_CALL, \
.a_reg = 0, \ .dst_reg = 0, \
.x_reg = 0, \ .src_reg = 0, \
.off = 0, \ .off = 0, \
.imm = ((FUNC) - __bpf_call_base) }) .imm = ((FUNC) - __bpf_call_base) })
/* Raw code statement block */ /* Raw code statement block */
#define BPF_RAW_INSN(CODE, A, X, OFF, IMM) \ #define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = CODE, \ .code = CODE, \
.a_reg = A, \ .dst_reg = DST, \
.x_reg = X, \ .src_reg = SRC, \
.off = OFF, \ .off = OFF, \
.imm = IMM }) .imm = IMM })
...@@ -261,8 +273,8 @@ enum { ...@@ -261,8 +273,8 @@ enum {
#define BPF_EXIT_INSN() \ #define BPF_EXIT_INSN() \
((struct sock_filter_int) { \ ((struct sock_filter_int) { \
.code = BPF_JMP | BPF_EXIT, \ .code = BPF_JMP | BPF_EXIT, \
.a_reg = 0, \ .dst_reg = 0, \
.x_reg = 0, \ .src_reg = 0, \
.off = 0, \ .off = 0, \
.imm = 0 }) .imm = 0 })
...@@ -287,8 +299,8 @@ enum { ...@@ -287,8 +299,8 @@ enum {
struct sock_filter_int { struct sock_filter_int {
__u8 code; /* opcode */ __u8 code; /* opcode */
__u8 a_reg:4; /* dest register */ __u8 dst_reg:4; /* dest register */
__u8 x_reg:4; /* source register */ __u8 src_reg:4; /* source register */
__s16 off; /* signed offset */ __s16 off; /* signed offset */
__s32 imm; /* signed immediate constant */ __s32 imm; /* signed immediate constant */
}; };
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment