aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-05-29 04:22:51 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-02 01:16:58 -0400
commitf8f6d679aaa78b989d9aee8d2935066fbdca2a30 (patch)
tree3468a865cc28d7c6bf743879a72751c9adfb6e7e /include/linux
parent3480593131e0b781287dae0139bf7ccee7cba7ff (diff)
net: filter: improve filter block macros
Commit 9739eef13c92 ("net: filter: make BPF conversion more readable") started to introduce helper macros similar to BPF_STMT()/BPF_JUMP() macros from classic BPF. However, quite some statements in the filter conversion functions remained in the old style which gives a mixture of block macros and non block macros in the code. This patch makes the block macros itself more readable by using explicit member initialization, and converts the remaining ones where possible to remain in a more consistent state. Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Acked-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/filter.h255
1 files changed, 205 insertions, 50 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 49ef7a298c92..f0c2ad43b4af 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -76,56 +76,211 @@ enum {
76/* BPF program can access up to 512 bytes of stack space. */ 76/* BPF program can access up to 512 bytes of stack space. */
77#define MAX_BPF_STACK 512 77#define MAX_BPF_STACK 512
78 78
79/* bpf_add|sub|...: a += x, bpf_mov: a = x */ 79/* Helper macros for filter block array initializers. */
80#define BPF_ALU64_REG(op, a, x) \ 80
81 ((struct sock_filter_int) {BPF_ALU64|BPF_OP(op)|BPF_X, a, x, 0, 0}) 81/* ALU ops on registers, bpf_add|sub|...: A += X */
82#define BPF_ALU32_REG(op, a, x) \ 82
83 ((struct sock_filter_int) {BPF_ALU|BPF_OP(op)|BPF_X, a, x, 0, 0}) 83#define BPF_ALU64_REG(OP, A, X) \
84 84 ((struct sock_filter_int) { \
85/* bpf_add|sub|...: a += imm, bpf_mov: a = imm */ 85 .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \
86#define BPF_ALU64_IMM(op, a, imm) \ 86 .a_reg = A, \
87 ((struct sock_filter_int) {BPF_ALU64|BPF_OP(op)|BPF_K, a, 0, 0, imm}) 87 .x_reg = X, \
88#define BPF_ALU32_IMM(op, a, imm) \ 88 .off = 0, \
89 ((struct sock_filter_int) {BPF_ALU|BPF_OP(op)|BPF_K, a, 0, 0, imm}) 89 .imm = 0 })
90 90
91/* R0 = *(uint *) (skb->data + off) */ 91#define BPF_ALU32_REG(OP, A, X) \
92#define BPF_LD_ABS(size, off) \ 92 ((struct sock_filter_int) { \
93 ((struct sock_filter_int) {BPF_LD|BPF_SIZE(size)|BPF_ABS, 0, 0, 0, off}) 93 .code = BPF_ALU | BPF_OP(OP) | BPF_X, \
94 94 .a_reg = A, \
95/* R0 = *(uint *) (skb->data + x + off) */ 95 .x_reg = X, \
96#define BPF_LD_IND(size, x, off) \ 96 .off = 0, \
97 ((struct sock_filter_int) {BPF_LD|BPF_SIZE(size)|BPF_IND, 0, x, 0, off}) 97 .imm = 0 })
98 98
99/* a = *(uint *) (x + off) */ 99/* ALU ops on immediates, bpf_add|sub|...: A += IMM */
100#define BPF_LDX_MEM(sz, a, x, off) \ 100
101 ((struct sock_filter_int) {BPF_LDX|BPF_SIZE(sz)|BPF_MEM, a, x, off, 0}) 101#define BPF_ALU64_IMM(OP, A, IMM) \
102 102 ((struct sock_filter_int) { \
103/* if (a 'op' x) goto pc+off */ 103 .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
104#define BPF_JMP_REG(op, a, x, off) \ 104 .a_reg = A, \
105 ((struct sock_filter_int) {BPF_JMP|BPF_OP(op)|BPF_X, a, x, off, 0}) 105 .x_reg = 0, \
106 106 .off = 0, \
107/* if (a 'op' imm) goto pc+off */ 107 .imm = IMM })
108#define BPF_JMP_IMM(op, a, imm, off) \ 108
109 ((struct sock_filter_int) {BPF_JMP|BPF_OP(op)|BPF_K, a, 0, off, imm}) 109#define BPF_ALU32_IMM(OP, A, IMM) \
110 110 ((struct sock_filter_int) { \
111#define BPF_EXIT_INSN() \ 111 .code = BPF_ALU | BPF_OP(OP) | BPF_K, \
112 ((struct sock_filter_int) {BPF_JMP|BPF_EXIT, 0, 0, 0, 0}) 112 .a_reg = A, \
113 113 .x_reg = 0, \
114static inline int size_to_bpf(int size) 114 .off = 0, \
115{ 115 .imm = IMM })
116 switch (size) { 116
117 case 1: 117/* Endianess conversion, cpu_to_{l,b}e(), {l,b}e_to_cpu() */
118 return BPF_B; 118
119 case 2: 119#define BPF_ENDIAN(TYPE, A, LEN) \
120 return BPF_H; 120 ((struct sock_filter_int) { \
121 case 4: 121 .code = BPF_ALU | BPF_END | BPF_SRC(TYPE), \
122 return BPF_W; 122 .a_reg = A, \
123 case 8: 123 .x_reg = 0, \
124 return BPF_DW; 124 .off = 0, \
125 default: 125 .imm = LEN })
126 return -EINVAL; 126
127 } 127/* Short form of mov, A = X */
128} 128
129#define BPF_MOV64_REG(A, X) \
130 ((struct sock_filter_int) { \
131 .code = BPF_ALU64 | BPF_MOV | BPF_X, \
132 .a_reg = A, \
133 .x_reg = X, \
134 .off = 0, \
135 .imm = 0 })
136
137#define BPF_MOV32_REG(A, X) \
138 ((struct sock_filter_int) { \
139 .code = BPF_ALU | BPF_MOV | BPF_X, \
140 .a_reg = A, \
141 .x_reg = X, \
142 .off = 0, \
143 .imm = 0 })
144
145/* Short form of mov, A = IMM */
146
147#define BPF_MOV64_IMM(A, IMM) \
148 ((struct sock_filter_int) { \
149 .code = BPF_ALU64 | BPF_MOV | BPF_K, \
150 .a_reg = A, \
151 .x_reg = 0, \
152 .off = 0, \
153 .imm = IMM })
154
155#define BPF_MOV32_IMM(A, IMM) \
156 ((struct sock_filter_int) { \
157 .code = BPF_ALU | BPF_MOV | BPF_K, \
158 .a_reg = A, \
159 .x_reg = 0, \
160 .off = 0, \
161 .imm = IMM })
162
163/* Short form of mov based on type, BPF_X: A = X, BPF_K: A = IMM */
164
165#define BPF_MOV64_RAW(TYPE, A, X, IMM) \
166 ((struct sock_filter_int) { \
167 .code = BPF_ALU64 | BPF_MOV | BPF_SRC(TYPE), \
168 .a_reg = A, \
169 .x_reg = X, \
170 .off = 0, \
171 .imm = IMM })
172
173#define BPF_MOV32_RAW(TYPE, A, X, IMM) \
174 ((struct sock_filter_int) { \
175 .code = BPF_ALU | BPF_MOV | BPF_SRC(TYPE), \
176 .a_reg = A, \
177 .x_reg = X, \
178 .off = 0, \
179 .imm = IMM })
180
181/* Direct packet access, R0 = *(uint *) (skb->data + OFF) */
182
183#define BPF_LD_ABS(SIZE, OFF) \
184 ((struct sock_filter_int) { \
185 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \
186 .a_reg = 0, \
187 .x_reg = 0, \
188 .off = 0, \
189 .imm = OFF })
190
191/* Indirect packet access, R0 = *(uint *) (skb->data + X + OFF) */
192
193#define BPF_LD_IND(SIZE, X, OFF) \
194 ((struct sock_filter_int) { \
195 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_IND, \
196 .a_reg = 0, \
197 .x_reg = X, \
198 .off = 0, \
199 .imm = OFF })
200
201/* Memory store, A = *(uint *) (X + OFF), and vice versa */
202
203#define BPF_LDX_MEM(SIZE, A, X, OFF) \
204 ((struct sock_filter_int) { \
205 .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \
206 .a_reg = A, \
207 .x_reg = X, \
208 .off = OFF, \
209 .imm = 0 })
210
211#define BPF_STX_MEM(SIZE, A, X, OFF) \
212 ((struct sock_filter_int) { \
213 .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \
214 .a_reg = A, \
215 .x_reg = X, \
216 .off = OFF, \
217 .imm = 0 })
218
219/* Conditional jumps against registers, if (A 'op' X) goto pc + OFF */
220
221#define BPF_JMP_REG(OP, A, X, OFF) \
222 ((struct sock_filter_int) { \
223 .code = BPF_JMP | BPF_OP(OP) | BPF_X, \
224 .a_reg = A, \
225 .x_reg = X, \
226 .off = OFF, \
227 .imm = 0 })
228
229/* Conditional jumps against immediates, if (A 'op' IMM) goto pc + OFF */
230
231#define BPF_JMP_IMM(OP, A, IMM, OFF) \
232 ((struct sock_filter_int) { \
233 .code = BPF_JMP | BPF_OP(OP) | BPF_K, \
234 .a_reg = A, \
235 .x_reg = 0, \
236 .off = OFF, \
237 .imm = IMM })
238
239/* Function call */
240