aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@plumgrid.com>2014-06-06 17:46:06 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-11 03:13:16 -0400
commite430f34ee5192c84bcabd3c79ab7e2388b5eec74 (patch)
tree4b4086b0ecf0c4d67c4ae28d493b5987430da143 /include/linux
parent7b0dcbd879101e829755d1288c1b440ba1f59460 (diff)
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: Chema Gonzalez <chema@google.com> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Acked-by: Daniel Borkmann <dborkman@redhat.com> Acked-by: Chema Gonzalez <chema@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/filter.h156
1 files changed, 84 insertions, 72 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h
index f0c2ad43b4af..a7e3c48d73a7 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -78,161 +78,173 @@ enum {
78 78
79/* Helper macros for filter block array initializers. */ 79/* Helper macros for filter block array initializers. */
80 80
81/* ALU ops on registers, bpf_add|sub|...: A += X */ 81/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
82 82
83#define BPF_ALU64_REG(OP, A, X) \ 83#define BPF_ALU64_REG(OP, DST, SRC) \
84 ((struct sock_filter_int) { \ 84 ((struct sock_filter_int) { \
85 .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \ 85 .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \
86 .a_reg = A, \ 86 .dst_reg = DST, \
87 .x_reg = X, \ 87 .src_reg = SRC, \
88 .off = 0, \ 88 .off = 0, \
89 .imm = 0 }) 89 .imm = 0 })
90 90
91#define BPF_ALU32_REG(OP, A, X) \ 91#define BPF_ALU32_REG(OP, DST, SRC) \
92 ((struct sock_filter_int) { \ 92 ((struct sock_filter_int) { \
93 .code = BPF_ALU | BPF_OP(OP) | BPF_X, \ 93 .code = BPF_ALU | BPF_OP(OP) | BPF_X, \
94 .a_reg = A, \ 94 .dst_reg = DST, \
95 .x_reg = X, \ 95 .src_reg = SRC, \
96 .off = 0, \ 96 .off = 0, \
97 .imm = 0 }) 97 .imm = 0 })
98 98
99/* ALU ops on immediates, bpf_add|sub|...: A += IMM */ 99/* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
100 100
101#define BPF_ALU64_IMM(OP, A, IMM) \ 101#define BPF_ALU64_IMM(OP, DST, IMM) \
102 ((struct sock_filter_int) { \ 102 ((struct sock_filter_int) { \
103 .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \ 103 .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
104 .a_reg = A, \ 104 .dst_reg = DST, \
105 .x_reg = 0, \ 105 .src_reg = 0, \
106 .off = 0, \ 106 .off = 0, \
107 .imm = IMM }) 107 .imm = IMM })
108 108
109#define BPF_ALU32_IMM(OP, A, IMM) \ 109#define BPF_ALU32_IMM(OP, DST, IMM) \
110 ((struct sock_filter_int) { \ 110 ((struct sock_filter_int) { \
111 .code = BPF_ALU | BPF_OP(OP) | BPF_K, \ 111 .code = BPF_ALU | BPF_OP(OP) | BPF_K, \
112 .a_reg = A, \ 112 .dst_reg = DST, \
113 .x_reg = 0, \ 113 .src_reg = 0, \
114 .off = 0, \ 114 .off = 0, \
115 .imm = IMM }) 115 .imm = IMM })
116 116
117/* Endianess conversion, cpu_to_{l,b}e(), {l,b}e_to_cpu() */ 117/* Endianess conversion, cpu_to_{l,b}e(), {l,b}e_to_cpu() */
118 118
119#define BPF_ENDIAN(TYPE, A, LEN) \ 119#define BPF_ENDIAN(TYPE, DST, LEN) \
120 ((struct sock_filter_int) { \ 120 ((struct sock_filter_int) { \
121 .code = BPF_ALU | BPF_END | BPF_SRC(TYPE), \ 121 .code = BPF_ALU | BPF_END | BPF_SRC(TYPE), \
122 .a_reg = A, \ 122 .dst_reg = DST, \
123 .x_reg = 0, \ 123 .src_reg = 0, \
124 .off = 0, \ 124 .off = 0, \
125 .imm = LEN }) 125 .imm = LEN })
126 126
127/* Short form of mov, A = X */ 127/* Short form of mov, dst_reg = src_reg */
128 128
129#define BPF_MOV64_REG(A, X) \ 129#define BPF_MOV64_REG(DST, SRC) \
130 ((struct sock_filter_int) { \ 130 ((struct sock_filter_int) { \
131 .code = BPF_ALU64 | BPF_MOV | BPF_X, \ 131 .code = BPF_ALU64 | BPF_MOV | BPF_X, \
132 .a_reg = A, \ 132 .dst_reg = DST, \
133 .x_reg = X, \ 133 .src_reg = SRC, \
134 .off = 0, \ 134 .off = 0, \
135 .imm = 0 }) 135 .imm = 0 })
136 136
137#define BPF_MOV32_REG(A, X) \ 137#define BPF_MOV32_REG(DST, SRC) \
138 ((struct sock_filter_int) { \ 138 ((struct sock_filter_int) { \
139 .code = BPF_ALU | BPF_MOV | BPF_X, \ 139 .code = BPF_ALU | BPF_MOV | BPF_X, \
140 .a_reg = A, \ 140 .dst_reg = DST, \
141 .x_reg = X, \ 141 .src_reg = SRC, \
142 .off = 0, \ 142 .off = 0, \
143 .imm = 0 }) 143 .imm = 0 })
144 144
145/* Short form of mov, A = IMM */ 145/* Short form of mov, dst_reg = imm32 */
146 146
147#define BPF_MOV64_IMM(A, IMM) \ 147#define BPF_MOV64_IMM(DST, IMM) \
148 ((struct sock_filter_int) { \ 148 ((struct sock_filter_int) { \
149 .code = BPF_ALU64 | BPF_MOV | BPF_K, \ 149 .code = BPF_ALU64 | BPF_MOV | BPF_K, \
150 .a_reg = A, \ 150 .dst_reg = DST, \
151 .x_reg = 0, \ 151 .src_reg = 0, \
152 .off = 0, \ 152 .off = 0, \
153 .imm = IMM }) 153 .imm = IMM })
154 154
155#define BPF_MOV32_IMM(A, IMM) \ 155#define BPF_MOV32_IMM(DST, IMM) \
156 ((struct sock_filter_int) { \ 156 ((struct sock_filter_int) { \
157 .code = BPF_ALU | BPF_MOV | BPF_K, \ 157 .code = BPF_ALU | BPF_MOV | BPF_K, \
158 .a_reg = A, \ 158 .dst_reg = DST, \
159 .x_reg = 0, \ 159 .src_reg = 0, \
160 .off = 0, \ 160 .off = 0, \
161 .imm = IMM }) 161 .imm = IMM })
162 162
163/* Short form of mov based on type, BPF_X: A = X, BPF_K: A = IMM */ 163/* Short form of mov based on type, BPF_X: dst_reg = src_reg, BPF_K: dst_reg = imm32 */
164 164
165#define BPF_MOV64_RAW(TYPE, A, X, IMM) \ 165#define BPF_MOV64_RAW(TYPE, DST, SRC, IMM) \
166 ((struct sock_filter_int) { \ 166 ((struct sock_filter_int) { \
167 .code = BPF_ALU64 | BPF_MOV | BPF_SRC(TYPE), \ 167 .code = BPF_ALU64 | BPF_MOV | BPF_SRC(TYPE), \
168 .a_reg = A, \ 168 .dst_reg = DST, \
169 .x_reg = X, \ 169 .src_reg = SRC, \
170 .off = 0, \ 170 .off = 0, \
171 .imm = IMM }) 171 .imm = IMM })
172 172
173#define BPF_MOV32_RAW(TYPE, A, X, IMM) \ 173#define BPF_MOV32_RAW(TYPE, DST, SRC, IMM) \
174 ((struct sock_filter_int) { \ 174 ((struct sock_filter_int) { \
175 .code = BPF_ALU | BPF_MOV | BPF_SRC(TYPE), \ 175 .code = BPF_ALU | BPF_MOV | BPF_SRC(TYPE), \
176 .a_reg = A, \ 176 .dst_reg = DST, \
177 .x_reg = X, \ 177 .src_reg = SRC, \
178 .off = 0, \ 178 .off = 0, \
179 .imm = IMM }) 179 .imm = IMM })
180 180
181/* Direct packet access, R0 = *(uint *) (skb->data + OFF) */ 181/* Direct packet access, R0 = *(uint *) (skb->data + imm32) */
182 182
183#define BPF_LD_ABS(SIZE, OFF) \ 183#define BPF_LD_ABS(SIZE, IMM) \
184 ((struct sock_filter_int) { \ 184 ((struct sock_filter_int) { \
185 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \ 185 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \
186 .a_reg = 0, \ 186 .dst_reg = 0, \
187 .x_reg = 0, \ 187 .src_reg = 0, \
188 .off = 0, \ 188 .off = 0, \
189 .imm = OFF }) 189 .imm = IMM })
190 190
191/* Indirect packet access, R0 = *(uint *) (skb->data + X + OFF) */ 191/* Indirect packet access, R0 = *(uint *) (skb->data + src_reg + imm32) */
192 192
193#define BPF_LD_IND(SIZE, X, OFF) \ 193#define BPF_LD_IND(SIZE, SRC, IMM) \
194 ((struct sock_filter_int) { \ 194 ((struct sock_filter_int) { \
195 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_IND, \ 195 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_IND, \
196 .a_reg = 0, \ 196 .dst_reg = 0, \
197 .x_reg = X, \ 197 .src_reg = SRC, \
198 .off = 0, \ 198 .off = 0, \
199 .imm = OFF }) 199 .imm = IMM })
200 200
201/* Memory store, A = *(uint *) (X + OFF), and vice versa */ 201/* Memory load, dst_reg = *(uint *) (src_reg + off16) */
202 202
203#define BPF_LDX_MEM(SIZE, A, X, OFF) \ 203#define BPF_LDX_MEM(SIZE, DST, SRC, OFF) \
204 ((struct sock_filter_int) { \ 204 ((struct sock_filter_int) { \
205 .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \ 205 .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \
206 .a_reg = A, \ 206 .dst_reg = DST, \
207 .x_reg = X, \ 207 .src_reg = SRC, \
208 .off = OFF, \ 208 .off = OFF, \
209 .imm = 0 }) 209 .imm = 0 })
210 210
211#define BPF_STX_MEM(SIZE, A, X, OFF) \ 211/* Memory store, *(uint *) (dst_reg + off16) = src_reg */
212
213#define BPF_STX_MEM(SIZE, DST, SRC, OFF) \
212 ((struct sock_filter_int) { \ 214 ((struct sock_filter_int) { \
213 .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \ 215 .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \
214 .a_reg = A, \ 216 .dst_reg = DST, \
215 .x_reg = X, \ 217 .src_reg = SRC, \
216 .off = OFF, \ 218 .off = OFF, \
217 .imm = 0 }) 219 .imm = 0 })
218 220
219/* Conditional jumps against registers, if (A 'op' X) goto pc + OFF */ 221/* Memory store, *(uint *) (dst_reg + off16) = imm32 */
222
223#define BPF_ST_MEM(SIZE, DST, OFF, IMM) \
224 ((struct sock_filter_int) { \
225 .code = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM, \
226 .dst_reg = DST, \
227 .src_reg = 0, \
228 .off = OFF, \
229 .imm = IMM })
230
231/* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */
220 232
221#define BPF_JMP_REG(OP, A, X, OFF) \ 233#define BPF_JMP_REG(OP, DST, SRC, OFF) \
222 ((struct sock_filter_int) { \ 234 ((struct sock_filter_int) { \
223 .code = BPF_JMP | BPF_OP(OP) | BPF_X, \ 235 .code = BPF_JMP | BPF_OP(OP) | BPF_X, \
224 .a_reg = A, \ 236 .dst_reg = DST, \
225 .x_reg = X, \ 237 .src_reg = SRC, \
226 .off = OFF, \ 238 .off = OFF, \
227 .imm = 0 }) 239 .imm = 0 })
228 240
229/* Conditional jumps against immediates, if (A 'op' IMM) goto pc + OFF */ 241/* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */
230 242
231#define BPF_JMP_IMM(OP, A, IMM, OFF) \ 243#define BPF_JMP_IMM(OP, DST, IMM, OFF) \
232 ((struct sock_filter_int) { \ 244 ((struct sock_filter_int) { \
233 .code = BPF_JMP | BPF_OP(OP) | BPF_K, \ 245 .code = BPF_JMP | BPF_OP(OP) | BPF_K, \
234 .a_reg = A, \ 246 .dst_reg = DST, \
235 .x_reg = 0, \ 247 .src_reg = 0, \
236 .off = OFF, \ 248 .off = OFF, \
237 .imm = IMM }) 249 .imm = IMM })
238 250
@@ -241,18 +253,18 @@ enum {
241#define BPF_EMIT_CALL(FUNC) \ 253#define BPF_EMIT_CALL(FUNC) \
242 ((struct sock_filter_int) { \ 254 ((struct sock_filter_int) { \
243 .code = BPF_JMP | BPF_CALL, \ 255 .code = BPF_JMP | BPF_CALL, \
244 .a_reg = 0, \ 256 .dst_reg = 0, \
245 .x_reg = 0, \ 257 .src_reg = 0, \
246 .off = 0, \ 258 .off = 0, \
247 .imm = ((FUNC) - __bpf_call_base) }) 259 .imm = ((FUNC) - __bpf_call_base) })
248 260
249/* Raw code statement block */ 261/* Raw code statement block */
250 262
251#define BPF_RAW_INSN(CODE, A, X, OFF, IMM) \ 263#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \
252 ((struct sock_filter_int) { \ 264 ((struct sock_filter_int) { \
253 .code = CODE, \ 265 .code = CODE, \
254 .a_reg = A, \ 266 .dst_reg = DST, \
255 .x_reg = X, \ 267 .src_reg = SRC, \
256 .off = OFF, \ 268 .off = OFF, \
257 .imm = IMM }) 269 .imm = IMM })
258 270
@@ -261,8 +273,8 @@ enum {
261#define BPF_EXIT_INSN() \ 273#define BPF_EXIT_INSN() \
262 ((struct sock_filter_int) { \ 274 ((struct sock_filter_int) { \
263 .code = BPF_JMP | BPF_EXIT, \ 275 .code = BPF_JMP | BPF_EXIT, \
264 .a_reg = 0, \ 276 .dst_reg = 0, \
265 .x_reg = 0, \ 277 .src_reg = 0, \
266 .off = 0, \ 278 .off = 0, \
267 .imm = 0 }) 279 .imm = 0 })
268 280
@@ -287,8 +299,8 @@ enum {
287 299
288struct sock_filter_int { 300struct sock_filter_int {
289 __u8 code; /* opcode */ 301 __u8 code; /* opcode */
290 __u8 a_reg:4; /* dest register */ 302 __u8 dst_reg:4; /* dest register */
291 __u8 x_reg:4; /* source register */ 303 __u8 src_reg:4; /* source register */
292 __s16 off; /* signed offset */ 304 __s16 off; /* signed offset */
293 __s32 imm; /* signed immediate constant */ 305 __s32 imm; /* signed immediate constant */
294}; 306};