t_bpfjit.c revision 1.3 1 /* $NetBSD: t_bpfjit.c,v 1.3 2014/05/23 11:47:59 alnsn Exp $ */
2
3 /*-
4 * Copyright (c) 2011-2012 Alexander Nasonov.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: t_bpfjit.c,v 1.3 2014/05/23 11:47:59 alnsn Exp $");
34
35 #include <atf-c.h>
36 #include <stdint.h>
37 #include <string.h>
38
39 #define __BPF_PRIVATE
40 #include <net/bpf.h>
41 #include <net/bpfjit.h>
42
43 static uint8_t deadbeef_at_5[16] = {
44 0, 0xf1, 2, 0xf3, 4, 0xde, 0xad, 0xbe, 0xef, 0xff
45 };
46
47 static bpf_ctx_t bc_zeroed;
48 static bpf_ctx_t *bc = &bc_zeroed;
49
50 ATF_TC(bpfjit_empty);
51 ATF_TC_HEAD(bpfjit_empty, tc)
52 {
53 atf_tc_set_md_var(tc, "descr",
54 "Test that JIT compilation for an empty bpf program fails");
55 }
56
57 ATF_TC_BODY(bpfjit_empty, tc)
58 {
59 struct bpf_insn dummy;
60
61 ATF_CHECK(bpfjit_generate_code(bc, &dummy, 0) == NULL);
62 }
63
64 ATF_TC(bpfjit_alu_add_k);
65 ATF_TC_HEAD(bpfjit_alu_add_k, tc)
66 {
67 atf_tc_set_md_var(tc, "descr",
68 "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_K");
69 }
70
71 ATF_TC_BODY(bpfjit_alu_add_k, tc)
72 {
73 static struct bpf_insn insns[] = {
74 BPF_STMT(BPF_LD+BPF_IMM, 3),
75 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 2),
76 BPF_STMT(BPF_RET+BPF_A, 0)
77 };
78
79 bpfjit_func_t code;
80 uint8_t pkt[1]; /* the program doesn't read any data */
81
82 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
83
84 ATF_CHECK(bpf_validate(insns, insn_count));
85
86 code = bpfjit_generate_code(bc, insns, insn_count);
87 ATF_REQUIRE(code != NULL);
88
89 ATF_CHECK(code(pkt, 1, 1) == 5);
90
91 bpfjit_free_code(code);
92 }
93
94 ATF_TC(bpfjit_alu_sub_k);
95 ATF_TC_HEAD(bpfjit_alu_sub_k, tc)
96 {
97 atf_tc_set_md_var(tc, "descr",
98 "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_K");
99 }
100
101 ATF_TC_BODY(bpfjit_alu_sub_k, tc)
102 {
103 static struct bpf_insn insns[] = {
104 BPF_STMT(BPF_LD+BPF_IMM, 1),
105 BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 2),
106 BPF_STMT(BPF_RET+BPF_A, 0)
107 };
108
109 bpfjit_func_t code;
110 uint8_t pkt[1]; /* the program doesn't read any data */
111
112 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
113
114 ATF_CHECK(bpf_validate(insns, insn_count));
115
116 code = bpfjit_generate_code(bc, insns, insn_count);
117 ATF_REQUIRE(code != NULL);
118
119 ATF_CHECK(code(pkt, 1, 1) == UINT32_MAX);
120
121 bpfjit_free_code(code);
122 }
123
124 ATF_TC(bpfjit_alu_mul_k);
125 ATF_TC_HEAD(bpfjit_alu_mul_k, tc)
126 {
127 atf_tc_set_md_var(tc, "descr",
128 "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_K");
129 }
130
131 ATF_TC_BODY(bpfjit_alu_mul_k, tc)
132 {
133 static struct bpf_insn insns[] = {
134 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
135 BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, 3),
136 BPF_STMT(BPF_RET+BPF_A, 0)
137 };
138
139 bpfjit_func_t code;
140 uint8_t pkt[1]; /* the program doesn't read any data */
141
142 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
143
144 ATF_CHECK(bpf_validate(insns, insn_count));
145
146 code = bpfjit_generate_code(bc, insns, insn_count);
147 ATF_REQUIRE(code != NULL);
148
149 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(0xfffffffd));
150
151 bpfjit_free_code(code);
152 }
153
154 ATF_TC(bpfjit_alu_div0_k);
155 ATF_TC_HEAD(bpfjit_alu_div0_k, tc)
156 {
157 atf_tc_set_md_var(tc, "descr",
158 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0");
159 }
160
161 ATF_TC_BODY(bpfjit_alu_div0_k, tc)
162 {
163 static struct bpf_insn insns[] = {
164 BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 0),
165 BPF_STMT(BPF_RET+BPF_A, 0)
166 };
167
168 bpfjit_func_t code;
169 uint8_t pkt[1]; /* the program doesn't read any data */
170
171 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
172
173 //ATF_CHECK(bpf_validate(insns, insn_count));
174
175 code = bpfjit_generate_code(bc, insns, insn_count);
176 ATF_REQUIRE(code != NULL);
177
178 ATF_CHECK(code(pkt, 1, 1) == 0);
179
180 bpfjit_free_code(code);
181 }
182
183 ATF_TC(bpfjit_alu_div1_k);
184 ATF_TC_HEAD(bpfjit_alu_div1_k, tc)
185 {
186 atf_tc_set_md_var(tc, "descr",
187 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=1");
188 }
189
190 ATF_TC_BODY(bpfjit_alu_div1_k, tc)
191 {
192 static struct bpf_insn insns[] = {
193 BPF_STMT(BPF_LD+BPF_IMM, 7),
194 BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 1),
195 BPF_STMT(BPF_RET+BPF_A, 0)
196 };
197
198 bpfjit_func_t code;
199 uint8_t pkt[1]; /* the program doesn't read any data */
200
201 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
202
203 ATF_CHECK(bpf_validate(insns, insn_count));
204
205 code = bpfjit_generate_code(bc, insns, insn_count);
206 ATF_REQUIRE(code != NULL);
207
208 ATF_CHECK(code(pkt, 1, 1) == 7);
209
210 bpfjit_free_code(code);
211 }
212
213 ATF_TC(bpfjit_alu_div2_k);
214 ATF_TC_HEAD(bpfjit_alu_div2_k, tc)
215 {
216 atf_tc_set_md_var(tc, "descr",
217 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=2");
218 }
219
220 ATF_TC_BODY(bpfjit_alu_div2_k, tc)
221 {
222 static struct bpf_insn insns[] = {
223 BPF_STMT(BPF_LD+BPF_IMM, 7),
224 BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 2),
225 BPF_STMT(BPF_RET+BPF_A, 0)
226 };
227
228 bpfjit_func_t code;
229 uint8_t pkt[1]; /* the program doesn't read any data */
230
231 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
232
233 ATF_CHECK(bpf_validate(insns, insn_count));
234
235 code = bpfjit_generate_code(bc, insns, insn_count);
236 ATF_REQUIRE(code != NULL);
237
238 ATF_CHECK(code(pkt, 1, 1) == 3);
239
240 bpfjit_free_code(code);
241 }
242
243 ATF_TC(bpfjit_alu_div4_k);
244 ATF_TC_HEAD(bpfjit_alu_div4_k, tc)
245 {
246 atf_tc_set_md_var(tc, "descr",
247 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=4");
248 }
249
250 ATF_TC_BODY(bpfjit_alu_div4_k, tc)
251 {
252 static struct bpf_insn insns[] = {
253 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
254 BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4),
255 BPF_STMT(BPF_RET+BPF_A, 0)
256 };
257
258 bpfjit_func_t code;
259 uint8_t pkt[1]; /* the program doesn't read any data */
260
261 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
262
263 ATF_CHECK(bpf_validate(insns, insn_count));
264
265 code = bpfjit_generate_code(bc, insns, insn_count);
266 ATF_REQUIRE(code != NULL);
267
268 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(0x3fffffff));
269
270 bpfjit_free_code(code);
271 }
272
273 ATF_TC(bpfjit_alu_div10_k);
274 ATF_TC_HEAD(bpfjit_alu_div10_k, tc)
275 {
276 atf_tc_set_md_var(tc, "descr",
277 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10");
278 }
279
280 ATF_TC_BODY(bpfjit_alu_div10_k, tc)
281 {
282 static struct bpf_insn insns[] = {
283 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
284 BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10),
285 BPF_STMT(BPF_RET+BPF_A, 0)
286 };
287
288 bpfjit_func_t code;
289 uint8_t pkt[1]; /* the program doesn't read any data */
290
291 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
292
293 ATF_CHECK(bpf_validate(insns, insn_count));
294
295 code = bpfjit_generate_code(bc, insns, insn_count);
296 ATF_REQUIRE(code != NULL);
297
298 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(429484384));
299
300 bpfjit_free_code(code);
301 }
302
303 ATF_TC(bpfjit_alu_div10000_k);
304 ATF_TC_HEAD(bpfjit_alu_div10000_k, tc)
305 {
306 atf_tc_set_md_var(tc, "descr",
307 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10000");
308 }
309
310 ATF_TC_BODY(bpfjit_alu_div10000_k, tc)
311 {
312 static struct bpf_insn insns[] = {
313 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
314 BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10000),
315 BPF_STMT(BPF_RET+BPF_A, 0)
316 };
317
318 bpfjit_func_t code;
319 uint8_t pkt[1]; /* the program doesn't read any data */
320
321 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
322
323 ATF_CHECK(bpf_validate(insns, insn_count));
324
325 code = bpfjit_generate_code(bc, insns, insn_count);
326 ATF_REQUIRE(code != NULL);
327
328 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(429484));
329
330 bpfjit_free_code(code);
331 }
332
333 ATF_TC(bpfjit_alu_div7609801_k);
334 ATF_TC_HEAD(bpfjit_alu_div7609801_k, tc)
335 {
336 atf_tc_set_md_var(tc, "descr",
337 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=7609801");
338 }
339
340 ATF_TC_BODY(bpfjit_alu_div7609801_k, tc)
341 {
342 static struct bpf_insn insns[] = {
343 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)),
344 BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(7609801)),
345 BPF_STMT(BPF_RET+BPF_A, 0)
346 };
347
348 bpfjit_func_t code;
349 uint8_t pkt[1]; /* the program doesn't read any data */
350
351 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
352
353 ATF_CHECK(bpf_validate(insns, insn_count));
354
355 code = bpfjit_generate_code(bc, insns, insn_count);
356 ATF_REQUIRE(code != NULL);
357
358 ATF_CHECK(code(pkt, 1, 1) == 564);
359
360 bpfjit_free_code(code);
361 }
362
363 ATF_TC(bpfjit_alu_div80000000_k);
364 ATF_TC_HEAD(bpfjit_alu_div80000000_k, tc)
365 {
366 atf_tc_set_md_var(tc, "descr",
367 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0x80000000");
368 }
369
370 ATF_TC_BODY(bpfjit_alu_div80000000_k, tc)
371 {
372 static struct bpf_insn insns[] = {
373 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)),
374 BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0x80000000)),
375 BPF_STMT(BPF_RET+BPF_A, 0)
376 };
377
378 bpfjit_func_t code;
379 uint8_t pkt[1]; /* the program doesn't read any data */
380
381 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
382
383 ATF_CHECK(bpf_validate(insns, insn_count));
384
385 code = bpfjit_generate_code(bc, insns, insn_count);
386 ATF_REQUIRE(code != NULL);
387
388 ATF_CHECK(code(pkt, 1, 1) == 1);
389
390 bpfjit_free_code(code);
391 }
392
393 ATF_TC(bpfjit_alu_and_k);
394 ATF_TC_HEAD(bpfjit_alu_and_k, tc)
395 {
396 atf_tc_set_md_var(tc, "descr",
397 "Test JIT compilation of BPF_ALU+BPF_AND+BPF_K");
398 }
399
400 ATF_TC_BODY(bpfjit_alu_and_k, tc)
401 {
402 static struct bpf_insn insns[] = {
403 BPF_STMT(BPF_LD+BPF_IMM, 0xdead),
404 BPF_STMT(BPF_ALU+BPF_AND+BPF_K, 0xbeef),
405 BPF_STMT(BPF_RET+BPF_A, 0)
406 };
407
408 bpfjit_func_t code;
409 uint8_t pkt[1]; /* the program doesn't read any data */
410
411 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
412
413 ATF_CHECK(bpf_validate(insns, insn_count));
414
415 code = bpfjit_generate_code(bc, insns, insn_count);
416 ATF_REQUIRE(code != NULL);
417
418 ATF_CHECK(code(pkt, 1, 1) == (0xdead&0xbeef));
419
420 bpfjit_free_code(code);
421 }
422
423 ATF_TC(bpfjit_alu_or_k);
424 ATF_TC_HEAD(bpfjit_alu_or_k, tc)
425 {
426 atf_tc_set_md_var(tc, "descr",
427 "Test JIT compilation of BPF_ALU+BPF_OR+BPF_K");
428 }
429
430 ATF_TC_BODY(bpfjit_alu_or_k, tc)
431 {
432 static struct bpf_insn insns[] = {
433 BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000),
434 BPF_STMT(BPF_ALU+BPF_OR+BPF_K, 0x0000beef),
435 BPF_STMT(BPF_RET+BPF_A, 0)
436 };
437
438 bpfjit_func_t code;
439 uint8_t pkt[1]; /* the program doesn't read any data */
440
441 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
442
443 ATF_CHECK(bpf_validate(insns, insn_count));
444
445 code = bpfjit_generate_code(bc, insns, insn_count);
446 ATF_REQUIRE(code != NULL);
447
448 ATF_CHECK(code(pkt, 1, 1) == 0xdeadbeef);
449
450 bpfjit_free_code(code);
451 }
452
453 ATF_TC(bpfjit_alu_lsh_k);
454 ATF_TC_HEAD(bpfjit_alu_lsh_k, tc)
455 {
456 atf_tc_set_md_var(tc, "descr",
457 "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K");
458 }
459
460 ATF_TC_BODY(bpfjit_alu_lsh_k, tc)
461 {
462 static struct bpf_insn insns[] = {
463 BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
464 BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 16),
465 BPF_STMT(BPF_RET+BPF_A, 0)
466 };
467
468 bpfjit_func_t code;
469 uint8_t pkt[1]; /* the program doesn't read any data */
470
471 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
472
473 ATF_CHECK(bpf_validate(insns, insn_count));
474
475 code = bpfjit_generate_code(bc, insns, insn_count);
476 ATF_REQUIRE(code != NULL);
477
478 ATF_CHECK(code(pkt, 1, 1) == 0xbeef0000);
479
480 bpfjit_free_code(code);
481 }
482
483 ATF_TC(bpfjit_alu_lsh0_k);
484 ATF_TC_HEAD(bpfjit_alu_lsh0_k, tc)
485 {
486 atf_tc_set_md_var(tc, "descr",
487 "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K with k=0");
488 }
489
490 ATF_TC_BODY(bpfjit_alu_lsh0_k, tc)
491 {
492 static struct bpf_insn insns[] = {
493 BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
494 BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 0),
495 BPF_STMT(BPF_RET+BPF_A, 0)
496 };
497
498 bpfjit_func_t code;
499 uint8_t pkt[1]; /* the program doesn't read any data */
500
501 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
502
503 ATF_CHECK(bpf_validate(insns, insn_count));
504
505 code = bpfjit_generate_code(bc, insns, insn_count);
506 ATF_REQUIRE(code != NULL);
507
508 ATF_CHECK(code(pkt, 1, 1) == 0xdeadbeef);
509
510 bpfjit_free_code(code);
511 }
512
513 ATF_TC(bpfjit_alu_rsh_k);
514 ATF_TC_HEAD(bpfjit_alu_rsh_k, tc)
515 {
516 atf_tc_set_md_var(tc, "descr",
517 "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K");
518 }
519
520 ATF_TC_BODY(bpfjit_alu_rsh_k, tc)
521 {
522 static struct bpf_insn insns[] = {
523 BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
524 BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 16),
525 BPF_STMT(BPF_RET+BPF_A, 0)
526 };
527
528 bpfjit_func_t code;
529 uint8_t pkt[1]; /* the program doesn't read any data */
530
531 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
532
533 ATF_CHECK(bpf_validate(insns, insn_count));
534
535 code = bpfjit_generate_code(bc, insns, insn_count);
536 ATF_REQUIRE(code != NULL);
537
538 ATF_CHECK(code(pkt, 1, 1) == 0x0000dead);
539
540 bpfjit_free_code(code);
541 }
542
543 ATF_TC(bpfjit_alu_rsh0_k);
544 ATF_TC_HEAD(bpfjit_alu_rsh0_k, tc)
545 {
546 atf_tc_set_md_var(tc, "descr",
547 "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K with k=0");
548 }
549
550 ATF_TC_BODY(bpfjit_alu_rsh0_k, tc)
551 {
552 static struct bpf_insn insns[] = {
553 BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
554 BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 0),
555 BPF_STMT(BPF_RET+BPF_A, 0)
556 };
557
558 bpfjit_func_t code;
559 uint8_t pkt[1]; /* the program doesn't read any data */
560
561 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
562
563 ATF_CHECK(bpf_validate(insns, insn_count));
564
565 code = bpfjit_generate_code(bc, insns, insn_count);
566 ATF_REQUIRE(code != NULL);
567
568 ATF_CHECK(code(pkt, 1, 1) == 0xdeadbeef);
569
570 bpfjit_free_code(code);
571 }
572
573 ATF_TC(bpfjit_alu_modulo_k);
574 ATF_TC_HEAD(bpfjit_alu_modulo_k, tc)
575 {
576 atf_tc_set_md_var(tc, "descr",
577 "Test JIT compilation of modulo logic of BPF_ALU+BPF_K operations");
578 }
579
580 ATF_TC_BODY(bpfjit_alu_modulo_k, tc)
581 {
582 static struct bpf_insn insns[] = {
583 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
584
585 /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */
586 BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x0fffff77)),
587
588 /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */
589 BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 1),
590
591 /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */
592 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xdddddddd)),
593
594 /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */
595 BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, UINT32_C(0xffffffff)),
596
597 /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */
598 BPF_STMT(BPF_ALU+BPF_OR+BPF_K, UINT32_C(0x0000030c)),
599
600 /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */
601 BPF_STMT(BPF_ALU+BPF_NEG, 0),
602
603 /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */
604 BPF_STMT(BPF_ALU+BPF_AND+BPF_K, UINT32_C(0xffffff0f)),
605
606 /* F000009A,42218C74 >> 3 = 1E000013,48443180 */
607 /* 00000000,42218C74 >> 3 = 00000000,08443180 */
608 BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 3),
609
610 /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */
611 BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x7fffff77)),
612
613 /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */
614 /* 00000000,93818280 / DEAD = 00000000,0000A994 */
615 BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0xdead)),
616
617 BPF_STMT(BPF_RET+BPF_A, 0)
618 };
619
620 bpfjit_func_t code;
621 uint8_t pkt[1]; /* the program doesn't read any data */
622
623 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
624
625 ATF_CHECK(bpf_validate(insns, insn_count));
626
627 code = bpfjit_generate_code(bc, insns, insn_count);
628 ATF_REQUIRE(code != NULL);
629
630 ATF_CHECK(code(pkt, 1, 1) != UINT32_C(0x71cbbbc3));
631 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(0x0000a994));
632
633
634 bpfjit_free_code(code);
635 }
636
637 ATF_TC(bpfjit_alu_add_x);
638 ATF_TC_HEAD(bpfjit_alu_add_x, tc)
639 {
640 atf_tc_set_md_var(tc, "descr",
641 "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_X");
642 }
643
644 ATF_TC_BODY(bpfjit_alu_add_x, tc)
645 {
646 static struct bpf_insn insns[] = {
647 BPF_STMT(BPF_LD+BPF_IMM, 3),
648 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
649 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
650 BPF_STMT(BPF_RET+BPF_A, 0)
651 };
652
653 bpfjit_func_t code;
654 uint8_t pkt[1]; /* the program doesn't read any data */
655
656 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
657
658 ATF_CHECK(bpf_validate(insns, insn_count));
659
660 code = bpfjit_generate_code(bc, insns, insn_count);
661 ATF_REQUIRE(code != NULL);
662
663 ATF_CHECK(code(pkt, 1, 1) == 5);
664
665 bpfjit_free_code(code);
666 }
667
668 ATF_TC(bpfjit_alu_sub_x);
669 ATF_TC_HEAD(bpfjit_alu_sub_x, tc)
670 {
671 atf_tc_set_md_var(tc, "descr",
672 "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_X");
673 }
674
675 ATF_TC_BODY(bpfjit_alu_sub_x, tc)
676 {
677 static struct bpf_insn insns[] = {
678 BPF_STMT(BPF_LD+BPF_IMM, 1),
679 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
680 BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0),
681 BPF_STMT(BPF_RET+BPF_A, 0)
682 };
683
684 bpfjit_func_t code;
685 uint8_t pkt[1]; /* the program doesn't read any data */
686
687 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
688
689 ATF_CHECK(bpf_validate(insns, insn_count));
690
691 code = bpfjit_generate_code(bc, insns, insn_count);
692 ATF_REQUIRE(code != NULL);
693
694 ATF_CHECK(code(pkt, 1, 1) == UINT32_MAX);
695
696 bpfjit_free_code(code);
697 }
698
699 ATF_TC(bpfjit_alu_mul_x);
700 ATF_TC_HEAD(bpfjit_alu_mul_x, tc)
701 {
702 atf_tc_set_md_var(tc, "descr",
703 "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_X");
704 }
705
706 ATF_TC_BODY(bpfjit_alu_mul_x, tc)
707 {
708 static struct bpf_insn insns[] = {
709 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
710 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
711 BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0),
712 BPF_STMT(BPF_RET+BPF_A, 0)
713 };
714
715 bpfjit_func_t code;
716 uint8_t pkt[1]; /* the program doesn't read any data */
717
718 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
719
720 ATF_CHECK(bpf_validate(insns, insn_count));
721
722 code = bpfjit_generate_code(bc, insns, insn_count);
723 ATF_REQUIRE(code != NULL);
724
725 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(0xfffffffd));
726
727 bpfjit_free_code(code);
728 }
729
730 ATF_TC(bpfjit_alu_div0_x);
731 ATF_TC_HEAD(bpfjit_alu_div0_x, tc)
732 {
733 atf_tc_set_md_var(tc, "descr",
734 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0");
735 }
736
737 ATF_TC_BODY(bpfjit_alu_div0_x, tc)
738 {
739 static struct bpf_insn insns[] = {
740 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
741 BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
742 BPF_STMT(BPF_RET+BPF_A, 0)
743 };
744
745 bpfjit_func_t code;
746 uint8_t pkt[1]; /* the program doesn't read any data */
747
748 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
749
750 ATF_CHECK(bpf_validate(insns, insn_count));
751
752 code = bpfjit_generate_code(bc, insns, insn_count);
753 ATF_REQUIRE(code != NULL);
754
755 ATF_CHECK(code(pkt, 1, 1) == 0);
756
757 bpfjit_free_code(code);
758 }
759
760 ATF_TC(bpfjit_alu_div1_x);
761 ATF_TC_HEAD(bpfjit_alu_div1_x, tc)
762 {
763 atf_tc_set_md_var(tc, "descr",
764 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=1");
765 }
766
767 ATF_TC_BODY(bpfjit_alu_div1_x, tc)
768 {
769 static struct bpf_insn insns[] = {
770 BPF_STMT(BPF_LD+BPF_IMM, 7),
771 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
772 BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
773 BPF_STMT(BPF_RET+BPF_A, 0)
774 };
775
776 bpfjit_func_t code;
777 uint8_t pkt[1]; /* the program doesn't read any data */
778
779 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
780
781 ATF_CHECK(bpf_validate(insns, insn_count));
782
783 code = bpfjit_generate_code(bc, insns, insn_count);
784 ATF_REQUIRE(code != NULL);
785
786 ATF_CHECK(code(pkt, 1, 1) == 7);
787
788 bpfjit_free_code(code);
789 }
790
791 ATF_TC(bpfjit_alu_div2_x);
792 ATF_TC_HEAD(bpfjit_alu_div2_x, tc)
793 {
794 atf_tc_set_md_var(tc, "descr",
795 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=2");
796 }
797
798 ATF_TC_BODY(bpfjit_alu_div2_x, tc)
799 {
800 static struct bpf_insn insns[] = {
801 BPF_STMT(BPF_LD+BPF_IMM, 7),
802 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
803 BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
804 BPF_STMT(BPF_RET+BPF_A, 0)
805 };
806
807 bpfjit_func_t code;
808 uint8_t pkt[1]; /* the program doesn't read any data */
809
810 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
811
812 ATF_CHECK(bpf_validate(insns, insn_count));
813
814 code = bpfjit_generate_code(bc, insns, insn_count);
815 ATF_REQUIRE(code != NULL);
816
817 ATF_CHECK(code(pkt, 1, 1) == 3);
818
819 bpfjit_free_code(code);
820 }
821
822 ATF_TC(bpfjit_alu_div4_x);
823 ATF_TC_HEAD(bpfjit_alu_div4_x, tc)
824 {
825 atf_tc_set_md_var(tc, "descr",
826 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=4");
827 }
828
829 ATF_TC_BODY(bpfjit_alu_div4_x, tc)
830 {
831 static struct bpf_insn insns[] = {
832 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
833 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
834 BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
835 BPF_STMT(BPF_RET+BPF_A, 0)
836 };
837
838 bpfjit_func_t code;
839 uint8_t pkt[1]; /* the program doesn't read any data */
840
841 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
842
843 ATF_CHECK(bpf_validate(insns, insn_count));
844
845 code = bpfjit_generate_code(bc, insns, insn_count);
846 ATF_REQUIRE(code != NULL);
847
848 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(0x3fffffff));
849
850 bpfjit_free_code(code);
851 }
852
853 ATF_TC(bpfjit_alu_div10_x);
854 ATF_TC_HEAD(bpfjit_alu_div10_x, tc)
855 {
856 atf_tc_set_md_var(tc, "descr",
857 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10");
858 }
859
860 ATF_TC_BODY(bpfjit_alu_div10_x, tc)
861 {
862 static struct bpf_insn insns[] = {
863 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
864 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10),
865 BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
866 BPF_STMT(BPF_RET+BPF_A, 0)
867 };
868
869 bpfjit_func_t code;
870 uint8_t pkt[1]; /* the program doesn't read any data */
871
872 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
873
874 ATF_CHECK(bpf_validate(insns, insn_count));
875
876 code = bpfjit_generate_code(bc, insns, insn_count);
877 ATF_REQUIRE(code != NULL);
878
879 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(429484384));
880
881 bpfjit_free_code(code);
882 }
883
884 ATF_TC(bpfjit_alu_div10000_x);
885 ATF_TC_HEAD(bpfjit_alu_div10000_x, tc)
886 {
887 atf_tc_set_md_var(tc, "descr",
888 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10000");
889 }
890
891 ATF_TC_BODY(bpfjit_alu_div10000_x, tc)
892 {
893 static struct bpf_insn insns[] = {
894 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
895 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10000),
896 BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
897 BPF_STMT(BPF_RET+BPF_A, 0)
898 };
899
900 bpfjit_func_t code;
901 uint8_t pkt[1]; /* the program doesn't read any data */
902
903 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
904
905 ATF_CHECK(bpf_validate(insns, insn_count));
906
907 code = bpfjit_generate_code(bc, insns, insn_count);
908 ATF_REQUIRE(code != NULL);
909
910 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(429484));
911
912 bpfjit_free_code(code);
913 }
914
915 ATF_TC(bpfjit_alu_div7609801_x);
916 ATF_TC_HEAD(bpfjit_alu_div7609801_x, tc)
917 {
918 atf_tc_set_md_var(tc, "descr",
919 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=7609801");
920 }
921
922 ATF_TC_BODY(bpfjit_alu_div7609801_x, tc)
923 {
924 static struct bpf_insn insns[] = {
925 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)),
926 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(7609801)),
927 BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
928 BPF_STMT(BPF_RET+BPF_A, 0)
929 };
930
931 bpfjit_func_t code;
932 uint8_t pkt[1]; /* the program doesn't read any data */
933
934 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
935
936 ATF_CHECK(bpf_validate(insns, insn_count));
937
938 code = bpfjit_generate_code(bc, insns, insn_count);
939 ATF_REQUIRE(code != NULL);
940
941 ATF_CHECK(code(pkt, 1, 1) == 564);
942
943 bpfjit_free_code(code);
944 }
945
946 ATF_TC(bpfjit_alu_div80000000_x);
947 ATF_TC_HEAD(bpfjit_alu_div80000000_x, tc)
948 {
949 atf_tc_set_md_var(tc, "descr",
950 "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0x80000000");
951 }
952
953 ATF_TC_BODY(bpfjit_alu_div80000000_x, tc)
954 {
955 static struct bpf_insn insns[] = {
956 BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX - 33),
957 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)),
958 BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
959 BPF_STMT(BPF_RET+BPF_A, 0)
960 };
961
962 bpfjit_func_t code;
963 uint8_t pkt[1]; /* the program doesn't read any data */
964
965 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
966
967 ATF_CHECK(bpf_validate(insns, insn_count));
968
969 code = bpfjit_generate_code(bc, insns, insn_count);
970 ATF_REQUIRE(code != NULL);
971
972 ATF_CHECK(code(pkt, 1, 1) == 1);
973
974 bpfjit_free_code(code);
975 }
976
977 ATF_TC(bpfjit_alu_and_x);
978 ATF_TC_HEAD(bpfjit_alu_and_x, tc)
979 {
980 atf_tc_set_md_var(tc, "descr",
981 "Test JIT compilation of BPF_ALU+BPF_AND+BPF_X");
982 }
983
984 ATF_TC_BODY(bpfjit_alu_and_x, tc)
985 {
986 static struct bpf_insn insns[] = {
987 BPF_STMT(BPF_LD+BPF_IMM, 0xdead),
988 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0xbeef),
989 BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0),
990 BPF_STMT(BPF_RET+BPF_A, 0)
991 };
992
993 bpfjit_func_t code;
994 uint8_t pkt[1]; /* the program doesn't read any data */
995
996 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
997
998 ATF_CHECK(bpf_validate(insns, insn_count));
999
1000 code = bpfjit_generate_code(bc, insns, insn_count);
1001 ATF_REQUIRE(code != NULL);
1002
1003 ATF_CHECK(code(pkt, 1, 1) == (0xdead&0xbeef));
1004
1005 bpfjit_free_code(code);
1006 }
1007
1008 ATF_TC(bpfjit_alu_or_x);
1009 ATF_TC_HEAD(bpfjit_alu_or_x, tc)
1010 {
1011 atf_tc_set_md_var(tc, "descr",
1012 "Test JIT compilation of BPF_ALU+BPF_OR+BPF_X");
1013 }
1014
1015 ATF_TC_BODY(bpfjit_alu_or_x, tc)
1016 {
1017 static struct bpf_insn insns[] = {
1018 BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000),
1019 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0x0000beef),
1020 BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0),
1021 BPF_STMT(BPF_RET+BPF_A, 0)
1022 };
1023
1024 bpfjit_func_t code;
1025 uint8_t pkt[1]; /* the program doesn't read any data */
1026
1027 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1028
1029 ATF_CHECK(bpf_validate(insns, insn_count));
1030
1031 code = bpfjit_generate_code(bc, insns, insn_count);
1032 ATF_REQUIRE(code != NULL);
1033
1034 ATF_CHECK(code(pkt, 1, 1) == 0xdeadbeef);
1035
1036 bpfjit_free_code(code);
1037 }
1038
1039 ATF_TC(bpfjit_alu_lsh_x);
1040 ATF_TC_HEAD(bpfjit_alu_lsh_x, tc)
1041 {
1042 atf_tc_set_md_var(tc, "descr",
1043 "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X");
1044 }
1045
1046 ATF_TC_BODY(bpfjit_alu_lsh_x, tc)
1047 {
1048 static struct bpf_insn insns[] = {
1049 BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
1050 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16),
1051 BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0),
1052 BPF_STMT(BPF_RET+BPF_A, 0)
1053 };
1054
1055 bpfjit_func_t code;
1056 uint8_t pkt[1]; /* the program doesn't read any data */
1057
1058 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1059
1060 ATF_CHECK(bpf_validate(insns, insn_count));
1061
1062 code = bpfjit_generate_code(bc, insns, insn_count);
1063 ATF_REQUIRE(code != NULL);
1064
1065 ATF_CHECK(code(pkt, 1, 1) == 0xbeef0000);
1066
1067 bpfjit_free_code(code);
1068 }
1069
1070 ATF_TC(bpfjit_alu_lsh0_x);
1071 ATF_TC_HEAD(bpfjit_alu_lsh0_x, tc)
1072 {
1073 atf_tc_set_md_var(tc, "descr",
1074 "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X with k=0");
1075 }
1076
1077 ATF_TC_BODY(bpfjit_alu_lsh0_x, tc)
1078 {
1079 static struct bpf_insn insns[] = {
1080 BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
1081 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
1082 BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0),
1083 BPF_STMT(BPF_RET+BPF_A, 0)
1084 };
1085
1086 bpfjit_func_t code;
1087 uint8_t pkt[1]; /* the program doesn't read any data */
1088
1089 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1090
1091 ATF_CHECK(bpf_validate(insns, insn_count));
1092
1093 code = bpfjit_generate_code(bc, insns, insn_count);
1094 ATF_REQUIRE(code != NULL);
1095
1096 ATF_CHECK(code(pkt, 1, 1) == 0xdeadbeef);
1097
1098 bpfjit_free_code(code);
1099 }
1100
1101 ATF_TC(bpfjit_alu_rsh_x);
1102 ATF_TC_HEAD(bpfjit_alu_rsh_x, tc)
1103 {
1104 atf_tc_set_md_var(tc, "descr",
1105 "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X");
1106 }
1107
1108 ATF_TC_BODY(bpfjit_alu_rsh_x, tc)
1109 {
1110 static struct bpf_insn insns[] = {
1111 BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
1112 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16),
1113 BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0),
1114 BPF_STMT(BPF_RET+BPF_A, 0)
1115 };
1116
1117 bpfjit_func_t code;
1118 uint8_t pkt[1]; /* the program doesn't read any data */
1119
1120 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1121
1122 ATF_CHECK(bpf_validate(insns, insn_count));
1123
1124 code = bpfjit_generate_code(bc, insns, insn_count);
1125 ATF_REQUIRE(code != NULL);
1126
1127 ATF_CHECK(code(pkt, 1, 1) == 0x0000dead);
1128
1129 bpfjit_free_code(code);
1130 }
1131
1132 ATF_TC(bpfjit_alu_rsh0_x);
1133 ATF_TC_HEAD(bpfjit_alu_rsh0_x, tc)
1134 {
1135 atf_tc_set_md_var(tc, "descr",
1136 "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X with k=0");
1137 }
1138
1139 ATF_TC_BODY(bpfjit_alu_rsh0_x, tc)
1140 {
1141 static struct bpf_insn insns[] = {
1142 BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
1143 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
1144 BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0),
1145 BPF_STMT(BPF_RET+BPF_A, 0)
1146 };
1147
1148 bpfjit_func_t code;
1149 uint8_t pkt[1]; /* the program doesn't read any data */
1150
1151 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1152
1153 ATF_CHECK(bpf_validate(insns, insn_count));
1154
1155 code = bpfjit_generate_code(bc, insns, insn_count);
1156 ATF_REQUIRE(code != NULL);
1157
1158 ATF_CHECK(code(pkt, 1, 1) == 0xdeadbeef);
1159
1160 bpfjit_free_code(code);
1161 }
1162
1163 ATF_TC(bpfjit_alu_modulo_x);
1164 ATF_TC_HEAD(bpfjit_alu_modulo_x, tc)
1165 {
1166 atf_tc_set_md_var(tc, "descr",
1167 "Test JIT compilation of modulo logic of BPF_ALU+BPF_X operations");
1168 }
1169
1170 ATF_TC_BODY(bpfjit_alu_modulo_x, tc)
1171 {
1172 static struct bpf_insn insns[] = {
1173 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
1174
1175 /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */
1176 BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0fffff77)),
1177 BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0),
1178
1179 /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */
1180 BPF_STMT(BPF_LDX+BPF_W+BPF_K, 1),
1181 BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0),
1182
1183 /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */
1184 BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdddddddd)),
1185 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
1186
1187 /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */
1188 BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffffff)),
1189 BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0),
1190
1191 /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */
1192 BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0000030c)),
1193 BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0),
1194
1195 /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */
1196 BPF_STMT(BPF_ALU+BPF_NEG, 0),
1197
1198 /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */
1199 BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffff0f)),
1200 BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0),
1201
1202 /* F000009A,42218C74 >> 3 = 1E000013,48443180 */
1203 /* 00000000,42218C74 >> 3 = 00000000,08443180 */
1204 BPF_STMT(BPF_LDX+BPF_W+BPF_K, 3),
1205 BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0),
1206
1207 /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */
1208 BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x7fffff77)),
1209 BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0),
1210
1211 /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */
1212 /* 00000000,93818280 / DEAD = 00000000,0000A994 */
1213 BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdead)),
1214 BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
1215
1216 BPF_STMT(BPF_RET+BPF_A, 0)
1217 };
1218
1219 bpfjit_func_t code;
1220 uint8_t pkt[1]; /* the program doesn't read any data */
1221
1222 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1223
1224 ATF_CHECK(bpf_validate(insns, insn_count));
1225
1226 code = bpfjit_generate_code(bc, insns, insn_count);
1227 ATF_REQUIRE(code != NULL);
1228
1229 ATF_CHECK(code(pkt, 1, 1) != UINT32_C(0x71cbbbc3));
1230 ATF_CHECK(code(pkt, 1, 1) == UINT32_C(0x0000a994));
1231
1232
1233 bpfjit_free_code(code);
1234 }
1235
1236 ATF_TC(bpfjit_alu_neg);
1237 ATF_TC_HEAD(bpfjit_alu_neg, tc)
1238 {
1239 atf_tc_set_md_var(tc, "descr",
1240 "Test JIT compilation of BPF_ALU+BPF_NEG");
1241 }
1242
1243 ATF_TC_BODY(bpfjit_alu_neg, tc)
1244 {
1245 static struct bpf_insn insns[] = {
1246 BPF_STMT(BPF_LD+BPF_IMM, 777),
1247 BPF_STMT(BPF_ALU+BPF_NEG, 0),
1248 BPF_STMT(BPF_RET+BPF_A, 0)
1249 };
1250
1251 bpfjit_func_t code;
1252 uint8_t pkt[1]; /* the program doesn't read any data */
1253
1254 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1255
1256 ATF_CHECK(bpf_validate(insns, insn_count));
1257
1258 code = bpfjit_generate_code(bc, insns, insn_count);
1259 ATF_REQUIRE(code != NULL);
1260
1261 ATF_CHECK(code(pkt, 1, 1) == 0u-777u);
1262
1263 bpfjit_free_code(code);
1264 }
1265
1266 ATF_TC(bpfjit_jmp_ja);
1267 ATF_TC_HEAD(bpfjit_jmp_ja, tc)
1268 {
1269 atf_tc_set_md_var(tc, "descr",
1270 "Test JIT compilation of BPF_JMP+BPF_JA");
1271 }
1272
1273 ATF_TC_BODY(bpfjit_jmp_ja, tc)
1274 {
1275 static struct bpf_insn insns[] = {
1276 BPF_STMT(BPF_JMP+BPF_JA, 1),
1277 BPF_STMT(BPF_RET+BPF_K, 0),
1278 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
1279 BPF_STMT(BPF_RET+BPF_K, 1),
1280 BPF_STMT(BPF_RET+BPF_K, 2),
1281 BPF_STMT(BPF_RET+BPF_K, 3),
1282 };
1283
1284 bpfjit_func_t code;
1285 uint8_t pkt[1]; /* the program doesn't read any data */
1286
1287 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1288
1289 ATF_CHECK(bpf_validate(insns, insn_count));
1290
1291 code = bpfjit_generate_code(bc, insns, insn_count);
1292 ATF_REQUIRE(code != NULL);
1293
1294 ATF_CHECK(code(pkt, 1, 1) == UINT32_MAX);
1295
1296 bpfjit_free_code(code);
1297 }
1298
1299 ATF_TC(bpfjit_jmp_jgt_k);
1300 ATF_TC_HEAD(bpfjit_jmp_jgt_k, tc)
1301 {
1302 atf_tc_set_md_var(tc, "descr",
1303 "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_K");
1304 }
1305
1306 ATF_TC_BODY(bpfjit_jmp_jgt_k, tc)
1307 {
1308 static struct bpf_insn insns[] = {
1309 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1310 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 7, 0, 1),
1311 BPF_STMT(BPF_RET+BPF_K, 0),
1312 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 2, 2, 0),
1313 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 9, 0, 0),
1314 BPF_STMT(BPF_RET+BPF_K, 1),
1315 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 4, 1, 1),
1316 BPF_STMT(BPF_RET+BPF_K, 2),
1317 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 2, 3),
1318 BPF_STMT(BPF_RET+BPF_K, 3),
1319 BPF_STMT(BPF_RET+BPF_K, 4),
1320 BPF_STMT(BPF_RET+BPF_K, 5),
1321 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 5, 3, 1),
1322 BPF_STMT(BPF_RET+BPF_K, 6),
1323 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 0, 0, 0),
1324 BPF_STMT(BPF_RET+BPF_K, 7),
1325 BPF_STMT(BPF_RET+BPF_K, 8)
1326 };
1327
1328 bpfjit_func_t code;
1329 uint8_t pkt[8]; /* the program doesn't read any data */
1330
1331 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1332
1333 ATF_CHECK(bpf_validate(insns, insn_count));
1334
1335 code = bpfjit_generate_code(bc, insns, insn_count);
1336 ATF_REQUIRE(code != NULL);
1337
1338 ATF_CHECK(code(pkt, 1, 1) == 1);
1339 ATF_CHECK(code(pkt, 2, 2) == 1);
1340 ATF_CHECK(code(pkt, 3, 3) == 7);
1341 ATF_CHECK(code(pkt, 4, 4) == 7);
1342 ATF_CHECK(code(pkt, 5, 5) == 7);
1343 ATF_CHECK(code(pkt, 6, 6) == 8);
1344 ATF_CHECK(code(pkt, 7, 7) == 5);
1345 ATF_CHECK(code(pkt, 8, 8) == 0);
1346
1347 bpfjit_free_code(code);
1348 }
1349
1350 ATF_TC(bpfjit_jmp_jge_k);
1351 ATF_TC_HEAD(bpfjit_jmp_jge_k, tc)
1352 {
1353 atf_tc_set_md_var(tc, "descr",
1354 "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_K");
1355 }
1356
1357 ATF_TC_BODY(bpfjit_jmp_jge_k, tc)
1358 {
1359 static struct bpf_insn insns[] = {
1360 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1361 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 8, 0, 1),
1362 BPF_STMT(BPF_RET+BPF_K, 0),
1363 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 3, 2, 0),
1364 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 9, 0, 0),
1365 BPF_STMT(BPF_RET+BPF_K, 1),
1366 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 5, 1, 1),
1367 BPF_STMT(BPF_RET+BPF_K, 2),
1368 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 2, 3),
1369 BPF_STMT(BPF_RET+BPF_K, 3),
1370 BPF_STMT(BPF_RET+BPF_K, 4),
1371 BPF_STMT(BPF_RET+BPF_K, 5),
1372 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 6, 3, 1),
1373 BPF_STMT(BPF_RET+BPF_K, 6),
1374 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 1, 0, 0),
1375 BPF_STMT(BPF_RET+BPF_K, 7),
1376 BPF_STMT(BPF_RET+BPF_K, 8)
1377 };
1378
1379 bpfjit_func_t code;
1380 uint8_t pkt[8]; /* the program doesn't read any data */
1381
1382 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1383
1384 ATF_CHECK(bpf_validate(insns, insn_count));
1385
1386 code = bpfjit_generate_code(bc, insns, insn_count);
1387 ATF_REQUIRE(code != NULL);
1388
1389 ATF_CHECK(code(pkt, 1, 1) == 1);
1390 ATF_CHECK(code(pkt, 2, 2) == 1);
1391 ATF_CHECK(code(pkt, 3, 3) == 7);
1392 ATF_CHECK(code(pkt, 4, 4) == 7);
1393 ATF_CHECK(code(pkt, 5, 5) == 7);
1394 ATF_CHECK(code(pkt, 6, 6) == 8);
1395 ATF_CHECK(code(pkt, 7, 7) == 5);
1396 ATF_CHECK(code(pkt, 8, 8) == 0);
1397
1398 bpfjit_free_code(code);
1399 }
1400
1401 ATF_TC(bpfjit_jmp_jeq_k);
1402 ATF_TC_HEAD(bpfjit_jmp_jeq_k, tc)
1403 {
1404 atf_tc_set_md_var(tc, "descr",
1405 "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_K");
1406 }
1407
1408 ATF_TC_BODY(bpfjit_jmp_jeq_k, tc)
1409 {
1410 static struct bpf_insn insns[] = {
1411 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1412 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 1),
1413 BPF_STMT(BPF_RET+BPF_K, 0),
1414 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 1, 0),
1415 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 1, 1),
1416 BPF_STMT(BPF_RET+BPF_K, 1),
1417 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 5, 1, 1),
1418 BPF_STMT(BPF_RET+BPF_K, 2),
1419 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 7, 2, 3),
1420 BPF_STMT(BPF_RET+BPF_K, 3),
1421 BPF_STMT(BPF_RET+BPF_K, 4),
1422 BPF_STMT(BPF_RET+BPF_K, 5),
1423 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 3, 1),
1424 BPF_STMT(BPF_RET+BPF_K, 6),
1425 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 1, 0, 0),
1426 BPF_STMT(BPF_RET+BPF_K, 7),
1427 BPF_STMT(BPF_RET+BPF_K, 8)
1428 };
1429
1430 bpfjit_func_t code;
1431 uint8_t pkt[8]; /* the program doesn't read any data */
1432
1433 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1434
1435 ATF_CHECK(bpf_validate(insns, insn_count));
1436
1437 code = bpfjit_generate_code(bc, insns, insn_count);
1438 ATF_REQUIRE(code != NULL);
1439
1440 ATF_CHECK(code(pkt, 1, 1) == 7);
1441 ATF_CHECK(code(pkt, 2, 2) == 7);
1442 ATF_CHECK(code(pkt, 3, 3) == 1);
1443 ATF_CHECK(code(pkt, 4, 4) == 7);
1444 ATF_CHECK(code(pkt, 5, 5) == 7);
1445 ATF_CHECK(code(pkt, 6, 6) == 8);
1446 ATF_CHECK(code(pkt, 7, 7) == 5);
1447 ATF_CHECK(code(pkt, 8, 8) == 0);
1448
1449 bpfjit_free_code(code);
1450 }
1451
1452 ATF_TC(bpfjit_jmp_jset_k);
1453 ATF_TC_HEAD(bpfjit_jmp_jset_k, tc)
1454 {
1455 atf_tc_set_md_var(tc, "descr",
1456 "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_K");
1457 }
1458
1459 ATF_TC_BODY(bpfjit_jmp_jset_k, tc)
1460 {
1461 static struct bpf_insn insns[] = {
1462 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1463 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 8, 0, 1),
1464 BPF_STMT(BPF_RET+BPF_K, 0),
1465 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 4, 2, 0),
1466 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 3, 0, 0),
1467 BPF_STMT(BPF_RET+BPF_K, 1),
1468 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 1, 1),
1469 BPF_STMT(BPF_RET+BPF_K, 2),
1470 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 1, 2, 3),
1471 BPF_STMT(BPF_RET+BPF_K, 3),
1472 BPF_STMT(BPF_RET+BPF_K, 4),
1473 BPF_STMT(BPF_RET+BPF_K, 5),
1474 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 3, 1),
1475 BPF_STMT(BPF_RET+BPF_K, 6),
1476 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 7, 0, 0),
1477 BPF_STMT(BPF_RET+BPF_K, 7),
1478 BPF_STMT(BPF_RET+BPF_K, 8)
1479 };
1480
1481 bpfjit_func_t code;
1482 uint8_t pkt[8]; /* the program doesn't read any data */
1483
1484 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1485
1486 ATF_CHECK(bpf_validate(insns, insn_count));
1487
1488 code = bpfjit_generate_code(bc, insns, insn_count);
1489 ATF_REQUIRE(code != NULL);
1490
1491 ATF_CHECK(code(pkt, 1, 1) == 1);
1492 ATF_CHECK(code(pkt, 2, 2) == 1);
1493 ATF_CHECK(code(pkt, 3, 3) == 1);
1494 ATF_CHECK(code(pkt, 4, 4) == 7);
1495 ATF_CHECK(code(pkt, 5, 5) == 5);
1496 ATF_CHECK(code(pkt, 6, 6) == 8);
1497 ATF_CHECK(code(pkt, 7, 7) == 5);
1498 ATF_CHECK(code(pkt, 8, 8) == 0);
1499
1500 bpfjit_free_code(code);
1501 }
1502
1503 ATF_TC(bpfjit_jmp_modulo_k);
1504 ATF_TC_HEAD(bpfjit_jmp_modulo_k, tc)
1505 {
1506 atf_tc_set_md_var(tc, "descr",
1507 "Test JIT compilation of modulo logic of BPF_JMP+BPF_K operations");
1508 }
1509
1510 ATF_TC_BODY(bpfjit_jmp_modulo_k, tc)
1511 {
1512 static struct bpf_insn insns[] = {
1513 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
1514 BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4),
1515 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 1, 0),
1516 BPF_STMT(BPF_RET+BPF_K, 0),
1517 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 0, 1),
1518 BPF_STMT(BPF_RET+BPF_K, 1),
1519 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 0, 1),
1520 BPF_STMT(BPF_RET+BPF_K, 2),
1521 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 0, 3),
1522 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 2, 0),
1523 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 1, 0),
1524 BPF_STMT(BPF_JMP+BPF_JA, 1),
1525 BPF_STMT(BPF_RET+BPF_K, 3),
1526
1527 /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */
1528 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)),
1529
1530 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 1, 0),
1531 BPF_STMT(BPF_RET+BPF_K, 4),
1532 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 0, 1),
1533 BPF_STMT(BPF_RET+BPF_K, 5),
1534 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 0, 1),
1535 BPF_STMT(BPF_RET+BPF_K, 6),
1536 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 0, 3),
1537 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 2, 0),
1538 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 1, 0),
1539 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
1540 BPF_STMT(BPF_RET+BPF_K, 7)
1541 };
1542
1543 bpfjit_func_t code;
1544 uint8_t pkt[1]; /* the program doesn't read any data */
1545
1546 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1547
1548 ATF_CHECK(bpf_validate(insns, insn_count));
1549
1550 code = bpfjit_generate_code(bc, insns, insn_count);
1551 ATF_REQUIRE(code != NULL);
1552
1553 ATF_CHECK(code(pkt, 1, 1) == UINT32_MAX);
1554
1555 bpfjit_free_code(code);
1556 }
1557
1558 ATF_TC(bpfjit_jmp_jgt_x);
1559 ATF_TC_HEAD(bpfjit_jmp_jgt_x, tc)
1560 {
1561 atf_tc_set_md_var(tc, "descr",
1562 "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_X");
1563 }
1564
1565 ATF_TC_BODY(bpfjit_jmp_jgt_x, tc)
1566 {
1567 static struct bpf_insn insns[] = {
1568 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1569 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
1570 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
1571 BPF_STMT(BPF_RET+BPF_K, 0),
1572 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
1573 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
1574 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
1575 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0),
1576 BPF_STMT(BPF_RET+BPF_K, 1),
1577 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
1578 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 1, 1),
1579 BPF_STMT(BPF_RET+BPF_K, 2),
1580 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
1581 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 2, 3),
1582 BPF_STMT(BPF_RET+BPF_K, 3),
1583 BPF_STMT(BPF_RET+BPF_K, 4),
1584 BPF_STMT(BPF_RET+BPF_K, 5),
1585 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
1586 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 4, 1),
1587 BPF_STMT(BPF_RET+BPF_K, 6),
1588 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
1589 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0),
1590 BPF_STMT(BPF_RET+BPF_K, 7),
1591 BPF_STMT(BPF_RET+BPF_K, 8)
1592 };
1593
1594 bpfjit_func_t code;
1595 uint8_t pkt[8]; /* the program doesn't read any data */
1596
1597 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1598
1599 ATF_CHECK(bpf_validate(insns, insn_count));
1600
1601 code = bpfjit_generate_code(bc, insns, insn_count);
1602 ATF_REQUIRE(code != NULL);
1603
1604 ATF_CHECK(code(pkt, 1, 1) == 1);
1605 ATF_CHECK(code(pkt, 2, 2) == 1);
1606 ATF_CHECK(code(pkt, 3, 3) == 7);
1607 ATF_CHECK(code(pkt, 4, 4) == 7);
1608 ATF_CHECK(code(pkt, 5, 5) == 7);
1609 ATF_CHECK(code(pkt, 6, 6) == 8);
1610 ATF_CHECK(code(pkt, 7, 7) == 5);
1611 ATF_CHECK(code(pkt, 8, 8) == 0);
1612
1613 bpfjit_free_code(code);
1614 }
1615
1616 ATF_TC(bpfjit_jmp_jge_x);
1617 ATF_TC_HEAD(bpfjit_jmp_jge_x, tc)
1618 {
1619 atf_tc_set_md_var(tc, "descr",
1620 "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_X");
1621 }
1622
1623 ATF_TC_BODY(bpfjit_jmp_jge_x, tc)
1624 {
1625 static struct bpf_insn insns[] = {
1626 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1627 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
1628 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
1629 BPF_STMT(BPF_RET+BPF_K, 0),
1630 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
1631 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 3, 0),
1632 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
1633 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0),
1634 BPF_STMT(BPF_RET+BPF_K, 1),
1635 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
1636 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 1),
1637 BPF_STMT(BPF_RET+BPF_K, 2),
1638 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
1639 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 2, 3),
1640 BPF_STMT(BPF_RET+BPF_K, 3),
1641 BPF_STMT(BPF_RET+BPF_K, 4),
1642 BPF_STMT(BPF_RET+BPF_K, 5),
1643 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
1644 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 4, 1),
1645 BPF_STMT(BPF_RET+BPF_K, 6),
1646 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
1647 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0),
1648 BPF_STMT(BPF_RET+BPF_K, 7),
1649 BPF_STMT(BPF_RET+BPF_K, 8)
1650 };
1651
1652 bpfjit_func_t code;
1653 uint8_t pkt[8]; /* the program doesn't read any data */
1654
1655 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1656
1657 ATF_CHECK(bpf_validate(insns, insn_count));
1658
1659 code = bpfjit_generate_code(bc, insns, insn_count);
1660 ATF_REQUIRE(code != NULL);
1661
1662 ATF_CHECK(code(pkt, 1, 1) == 1);
1663 ATF_CHECK(code(pkt, 2, 2) == 1);
1664 ATF_CHECK(code(pkt, 3, 3) == 7);
1665 ATF_CHECK(code(pkt, 4, 4) == 7);
1666 ATF_CHECK(code(pkt, 5, 5) == 7);
1667 ATF_CHECK(code(pkt, 6, 6) == 8);
1668 ATF_CHECK(code(pkt, 7, 7) == 5);
1669 ATF_CHECK(code(pkt, 8, 8) == 0);
1670
1671 bpfjit_free_code(code);
1672 }
1673
1674 ATF_TC(bpfjit_jmp_jeq_x);
1675 ATF_TC_HEAD(bpfjit_jmp_jeq_x, tc)
1676 {
1677 atf_tc_set_md_var(tc, "descr",
1678 "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_X");
1679 }
1680
1681 ATF_TC_BODY(bpfjit_jmp_jeq_x, tc)
1682 {
1683 static struct bpf_insn insns[] = {
1684 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1685 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
1686 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
1687 BPF_STMT(BPF_RET+BPF_K, 0),
1688 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
1689 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 0),
1690 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
1691 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
1692 BPF_STMT(BPF_RET+BPF_K, 1),
1693 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
1694 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
1695 BPF_STMT(BPF_RET+BPF_K, 2),
1696 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
1697 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 3),
1698 BPF_STMT(BPF_RET+BPF_K, 3),
1699 BPF_STMT(BPF_RET+BPF_K, 4),
1700 BPF_STMT(BPF_RET+BPF_K, 5),
1701 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
1702 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 3, 1),
1703 BPF_STMT(BPF_RET+BPF_K, 6),
1704 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 1, 0, 0),
1705 BPF_STMT(BPF_RET+BPF_K, 7),
1706 BPF_STMT(BPF_RET+BPF_K, 8)
1707 };
1708
1709 bpfjit_func_t code;
1710 uint8_t pkt[8]; /* the program doesn't read any data */
1711
1712 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1713
1714 ATF_CHECK(bpf_validate(insns, insn_count));
1715
1716 code = bpfjit_generate_code(bc, insns, insn_count);
1717 ATF_REQUIRE(code != NULL);
1718
1719 ATF_CHECK(code(pkt, 1, 1) == 7);
1720 ATF_CHECK(code(pkt, 2, 2) == 7);
1721 ATF_CHECK(code(pkt, 3, 3) == 1);
1722 ATF_CHECK(code(pkt, 4, 4) == 7);
1723 ATF_CHECK(code(pkt, 5, 5) == 7);
1724 ATF_CHECK(code(pkt, 6, 6) == 8);
1725 ATF_CHECK(code(pkt, 7, 7) == 5);
1726 ATF_CHECK(code(pkt, 8, 8) == 0);
1727
1728 bpfjit_free_code(code);
1729 }
1730
1731 ATF_TC(bpfjit_jmp_jset_x);
1732 ATF_TC_HEAD(bpfjit_jmp_jset_x, tc)
1733 {
1734 atf_tc_set_md_var(tc, "descr",
1735 "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_X");
1736 }
1737
1738 ATF_TC_BODY(bpfjit_jmp_jset_x, tc)
1739 {
1740 static struct bpf_insn insns[] = {
1741 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1742 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
1743 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 1),
1744 BPF_STMT(BPF_RET+BPF_K, 0),
1745 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
1746 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 0),
1747 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 3, 0, 0),
1748 BPF_STMT(BPF_RET+BPF_K, 1),
1749 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
1750 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 1, 1),
1751 BPF_STMT(BPF_RET+BPF_K, 2),
1752 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
1753 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 3),
1754 BPF_STMT(BPF_RET+BPF_K, 3),
1755 BPF_STMT(BPF_RET+BPF_K, 4),
1756 BPF_STMT(BPF_RET+BPF_K, 5),
1757 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
1758 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 4, 1),
1759 BPF_STMT(BPF_RET+BPF_K, 6),
1760 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
1761 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 0),
1762 BPF_STMT(BPF_RET+BPF_K, 7),
1763 BPF_STMT(BPF_RET+BPF_K, 8)
1764 };
1765
1766 bpfjit_func_t code;
1767 uint8_t pkt[8]; /* the program doesn't read any data */
1768
1769 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1770
1771 ATF_CHECK(bpf_validate(insns, insn_count));
1772
1773 code = bpfjit_generate_code(bc, insns, insn_count);
1774 ATF_REQUIRE(code != NULL);
1775
1776 ATF_CHECK(code(pkt, 1, 1) == 1);
1777 ATF_CHECK(code(pkt, 2, 2) == 1);
1778 ATF_CHECK(code(pkt, 3, 3) == 1);
1779 ATF_CHECK(code(pkt, 4, 4) == 7);
1780 ATF_CHECK(code(pkt, 5, 5) == 5);
1781 ATF_CHECK(code(pkt, 6, 6) == 8);
1782 ATF_CHECK(code(pkt, 7, 7) == 5);
1783 ATF_CHECK(code(pkt, 8, 8) == 0);
1784
1785 bpfjit_free_code(code);
1786 }
1787
1788 ATF_TC(bpfjit_jmp_modulo_x);
1789 ATF_TC_HEAD(bpfjit_jmp_modulo_x, tc)
1790 {
1791 atf_tc_set_md_var(tc, "descr",
1792 "Test JIT compilation of modulo logic of BPF_JMP+BPF_X operations");
1793 }
1794
1795 ATF_TC_BODY(bpfjit_jmp_modulo_x, tc)
1796 {
1797 static struct bpf_insn insns[] = {
1798 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
1799 /* FFFFF770 << 4 = FFFFF770 */
1800 BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4),
1801
1802 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
1803 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
1804 BPF_STMT(BPF_RET+BPF_K, 0),
1805 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
1806 BPF_STMT(BPF_RET+BPF_K, 1),
1807 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
1808 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
1809 BPF_STMT(BPF_RET+BPF_K, 2),
1810 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
1811 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
1812 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
1813 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
1814 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
1815 BPF_STMT(BPF_JMP+BPF_JA, 1),
1816 BPF_STMT(BPF_RET+BPF_K, 3),
1817
1818 /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */
1819 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)),
1820
1821 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
1822 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
1823 BPF_STMT(BPF_RET+BPF_K, 4),
1824 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
1825 BPF_STMT(BPF_RET+BPF_K, 5),
1826 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
1827 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
1828 BPF_STMT(BPF_RET+BPF_K, 6),
1829 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
1830 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
1831 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
1832 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
1833 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
1834 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
1835 BPF_STMT(BPF_RET+BPF_K, 7)
1836 };
1837
1838 bpfjit_func_t code;
1839 uint8_t pkt[1]; /* the program doesn't read any data */
1840
1841 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1842
1843 ATF_CHECK(bpf_validate(insns, insn_count));
1844
1845 code = bpfjit_generate_code(bc, insns, insn_count);
1846 ATF_REQUIRE(code != NULL);
1847
1848 ATF_CHECK(code(pkt, 1, 1) == UINT32_MAX);
1849
1850 bpfjit_free_code(code);
1851 }
1852
1853 ATF_TC(bpfjit_ld_abs);
1854 ATF_TC_HEAD(bpfjit_ld_abs, tc)
1855 {
1856 atf_tc_set_md_var(tc, "descr",
1857 "Test JIT compilation of BPF_LD+BPF_ABS");
1858 }
1859
1860 ATF_TC_BODY(bpfjit_ld_abs, tc)
1861 {
1862 static struct bpf_insn insns[3][2] = {
1863 {
1864 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
1865 BPF_STMT(BPF_RET+BPF_A, 0)
1866 },
1867 {
1868 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 5),
1869 BPF_STMT(BPF_RET+BPF_A, 0)
1870 },
1871 {
1872 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 5),
1873 BPF_STMT(BPF_RET+BPF_A, 0)
1874 }
1875 };
1876
1877 static size_t lengths[3] = { 1, 2, 4 };
1878 static unsigned int expected[3] = { 0xde, 0xdead, 0xdeadbeef };
1879
1880 size_t i, l;
1881 uint8_t *pkt = deadbeef_at_5;
1882 size_t pktsize = sizeof(deadbeef_at_5);
1883
1884 size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
1885
1886 for (i = 0; i < 3; i++) {
1887 bpfjit_func_t code;
1888
1889 ATF_CHECK(bpf_validate(insns[i], insn_count));
1890
1891 code = bpfjit_generate_code(bc, insns[i], insn_count);
1892 ATF_REQUIRE(code != NULL);
1893
1894 for (l = 0; l < 5 + lengths[i]; l++) {
1895 ATF_CHECK(code(pkt, l, l) == 0);
1896 ATF_CHECK(code(pkt, pktsize, l) == 0);
1897 }
1898
1899 l = 5 + lengths[i];
1900 ATF_CHECK(code(pkt, l, l) == expected[i]);
1901 ATF_CHECK(code(pkt, pktsize, l) == expected[i]);
1902
1903 l = pktsize;
1904 ATF_CHECK(code(pkt, l, l) == expected[i]);
1905
1906 bpfjit_free_code(code);
1907 }
1908 }
1909
1910 ATF_TC(bpfjit_ld_abs_k_overflow);
1911 ATF_TC_HEAD(bpfjit_ld_abs_k_overflow, tc)
1912 {
1913 atf_tc_set_md_var(tc, "descr",
1914 "Test JIT compilation of BPF_LD+BPF_ABS with overflow in k+4");
1915 }
1916
1917 ATF_TC_BODY(bpfjit_ld_abs_k_overflow, tc)
1918 {
1919 static struct bpf_insn insns[12][3] = {
1920 {
1921 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
1922 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1923 BPF_STMT(BPF_RET+BPF_K, 1)
1924 },
1925 {
1926 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
1927 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1928 BPF_STMT(BPF_RET+BPF_K, 1)
1929 },
1930 {
1931 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
1932 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1933 BPF_STMT(BPF_RET+BPF_K, 1)
1934 },
1935 {
1936 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
1937 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1938 BPF_STMT(BPF_RET+BPF_K, 1)
1939 },
1940 {
1941 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
1942 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1943 BPF_STMT(BPF_RET+BPF_K, 1)
1944 },
1945 {
1946 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
1947 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1948 BPF_STMT(BPF_RET+BPF_K, 1)
1949 },
1950 {
1951 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1952 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
1953 BPF_STMT(BPF_RET+BPF_K, 1)
1954 },
1955 {
1956 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1957 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
1958 BPF_STMT(BPF_RET+BPF_K, 1)
1959 },
1960 {
1961 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1962 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
1963 BPF_STMT(BPF_RET+BPF_K, 1)
1964 },
1965 {
1966 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1967 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
1968 BPF_STMT(BPF_RET+BPF_K, 1)
1969 },
1970 {
1971 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1972 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
1973 BPF_STMT(BPF_RET+BPF_K, 1)
1974 },
1975 {
1976 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1977 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
1978 BPF_STMT(BPF_RET+BPF_K, 1)
1979 }
1980 };
1981
1982 int i;
1983 uint8_t pkt[8] = { 0 };
1984
1985 size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
1986
1987 for (i = 0; i < 3; i++) {
1988 bpfjit_func_t code;
1989
1990 ATF_CHECK(bpf_validate(insns[i], insn_count));
1991
1992 code = bpfjit_generate_code(bc, insns[i], insn_count);
1993 ATF_REQUIRE(code != NULL);
1994
1995 ATF_CHECK(code(pkt, 8, 8) == 0);
1996
1997 bpfjit_free_code(code);
1998 }
1999 }
2000
2001 ATF_TC(bpfjit_ld_ind);
2002 ATF_TC_HEAD(bpfjit_ld_ind, tc)
2003 {
2004 atf_tc_set_md_var(tc, "descr",
2005 "Test JIT compilation of BPF_LD+BPF_IND");
2006 }
2007
2008 ATF_TC_BODY(bpfjit_ld_ind, tc)
2009 {
2010 static struct bpf_insn insns[6][3] = {
2011 {
2012 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2013 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
2014 BPF_STMT(BPF_RET+BPF_A, 0)
2015 },
2016 {
2017 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2018 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2),
2019 BPF_STMT(BPF_RET+BPF_A, 0)
2020 },
2021 {
2022 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2023 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2),
2024 BPF_STMT(BPF_RET+BPF_A, 0)
2025 },
2026 {
2027 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2028 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2029 BPF_STMT(BPF_RET+BPF_A, 0)
2030 },
2031 {
2032 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2033 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
2034 BPF_STMT(BPF_RET+BPF_A, 0)
2035 },
2036 {
2037 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2038 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0),
2039 BPF_STMT(BPF_RET+BPF_A, 0)
2040 }
2041 };
2042
2043 static size_t lengths[6] = { 1, 2, 4, 1, 2, 4 };
2044
2045 static unsigned int expected[6] = {
2046 0xde, 0xdead, 0xdeadbeef,
2047 0xde, 0xdead, 0xdeadbeef
2048 };
2049
2050 size_t i, l;
2051 uint8_t *pkt = deadbeef_at_5;
2052 size_t pktsize = sizeof(deadbeef_at_5);
2053
2054 size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2055
2056 for (i = 0; i < 3; i++) {
2057 bpfjit_func_t code;
2058
2059 ATF_CHECK(bpf_validate(insns[i], insn_count));
2060
2061 code = bpfjit_generate_code(bc, insns[i], insn_count);
2062 ATF_REQUIRE(code != NULL);
2063
2064 for (l = 0; l < 5 + lengths[i]; l++) {
2065 ATF_CHECK(code(pkt, l, l) == 0);
2066 ATF_CHECK(code(pkt, pktsize, l) == 0);
2067 }
2068
2069 l = 5 + lengths[i];
2070 ATF_CHECK(code(pkt, l, l) == expected[i]);
2071 ATF_CHECK(code(pkt, pktsize, l) == expected[i]);
2072
2073 l = pktsize;
2074 ATF_CHECK(code(pkt, l, l) == expected[i]);
2075
2076 bpfjit_free_code(code);
2077 }
2078 }
2079
2080 ATF_TC(bpfjit_ld_ind_k_overflow);
2081 ATF_TC_HEAD(bpfjit_ld_ind_k_overflow, tc)
2082 {
2083 atf_tc_set_md_var(tc, "descr",
2084 "Test JIT compilation of BPF_LD+BPF_IND with overflow in k+4");
2085 }
2086
2087 ATF_TC_BODY(bpfjit_ld_ind_k_overflow, tc)
2088 {
2089 static struct bpf_insn insns[12][3] = {
2090 {
2091 BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
2092 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2093 BPF_STMT(BPF_RET+BPF_K, 1)
2094 },
2095 {
2096 BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
2097 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2098 BPF_STMT(BPF_RET+BPF_K, 1)
2099 },
2100 {
2101 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
2102 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2103 BPF_STMT(BPF_RET+BPF_K, 1)
2104 },
2105 {
2106 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
2107 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2108 BPF_STMT(BPF_RET+BPF_K, 1)
2109 },
2110 {
2111 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
2112 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2113 BPF_STMT(BPF_RET+BPF_K, 1)
2114 },
2115 {
2116 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
2117 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2118 BPF_STMT(BPF_RET+BPF_K, 1)
2119 },
2120 {
2121 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2122 BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
2123 BPF_STMT(BPF_RET+BPF_K, 1)
2124 },
2125 {
2126 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2127 BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
2128 BPF_STMT(BPF_RET+BPF_K, 1)
2129 },
2130 {
2131 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2132 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
2133 BPF_STMT(BPF_RET+BPF_K, 1)
2134 },
2135 {
2136 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2137 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
2138 BPF_STMT(BPF_RET+BPF_K, 1)
2139 },
2140 {
2141 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2142 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
2143 BPF_STMT(BPF_RET+BPF_K, 1)
2144 },
2145 {
2146 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2147 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
2148 BPF_STMT(BPF_RET+BPF_K, 1)
2149 }
2150 };
2151
2152 int i;
2153 uint8_t pkt[8] = { 0 };
2154
2155 size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2156
2157 for (i = 0; i < 3; i++) {
2158 bpfjit_func_t code;
2159
2160 ATF_CHECK(bpf_validate(insns[i], insn_count));
2161
2162 code = bpfjit_generate_code(bc, insns[i], insn_count);
2163 ATF_REQUIRE(code != NULL);
2164
2165 ATF_CHECK(code(pkt, 8, 8) == 0);
2166
2167 bpfjit_free_code(code);
2168 }
2169 }
2170
2171 ATF_TC(bpfjit_ld_ind_x_overflow1);
2172 ATF_TC_HEAD(bpfjit_ld_ind_x_overflow1, tc)
2173 {
2174 atf_tc_set_md_var(tc, "descr",
2175 "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
2176 }
2177
2178 ATF_TC_BODY(bpfjit_ld_ind_x_overflow1, tc)
2179 {
2180 static struct bpf_insn insns[] = {
2181 BPF_STMT(BPF_LD+BPF_LEN, 0),
2182 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
2183 BPF_STMT(BPF_MISC+BPF_TAX, 0),
2184 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2185 BPF_STMT(BPF_RET+BPF_A, 0)
2186 };
2187
2188 size_t i;
2189 bpfjit_func_t code;
2190 uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
2191
2192 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2193
2194 ATF_CHECK(bpf_validate(insns, insn_count));
2195
2196 code = bpfjit_generate_code(bc, insns, insn_count);
2197 ATF_REQUIRE(code != NULL);
2198
2199 for (i = 1; i <= sizeof(pkt); i++) {
2200 ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
2201 ATF_CHECK(code(pkt, i, i) == 10 * i);
2202 }
2203
2204 bpfjit_free_code(code);
2205 }
2206
2207 ATF_TC(bpfjit_ld_ind_x_overflow2);
2208 ATF_TC_HEAD(bpfjit_ld_ind_x_overflow2, tc)
2209 {
2210 atf_tc_set_md_var(tc, "descr",
2211 "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
2212 }
2213
2214 ATF_TC_BODY(bpfjit_ld_ind_x_overflow2, tc)
2215 {
2216 static struct bpf_insn insns[] = {
2217 BPF_STMT(BPF_LD+BPF_LEN, 0),
2218 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
2219 BPF_STMT(BPF_ST, 3),
2220 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
2221 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2222 BPF_STMT(BPF_RET+BPF_A, 0)
2223 };
2224
2225 size_t i;
2226 bpfjit_func_t code;
2227 uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
2228
2229 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2230
2231 ATF_CHECK(bpf_validate(insns, insn_count));
2232
2233 code = bpfjit_generate_code(bc, insns, insn_count);
2234 ATF_REQUIRE(code != NULL);
2235
2236 for (i = 1; i <= sizeof(pkt); i++) {
2237 ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
2238 ATF_CHECK(code(pkt, i, i) == 10 * i);
2239 }
2240
2241 bpfjit_free_code(code);
2242 }
2243
2244 ATF_TC(bpfjit_ld_len);
2245 ATF_TC_HEAD(bpfjit_ld_len, tc)
2246 {
2247 atf_tc_set_md_var(tc, "descr",
2248 "Test JIT compilation of BPF_LD+BPF_W+BPF_LEN");
2249 }
2250
2251 ATF_TC_BODY(bpfjit_ld_len, tc)
2252 {
2253 static struct bpf_insn insns[] = {
2254 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2255 BPF_STMT(BPF_RET+BPF_A, 0)
2256 };
2257
2258 size_t i;
2259 bpfjit_func_t code;
2260 uint8_t pkt[32]; /* the program doesn't read any data */
2261
2262 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2263
2264 ATF_CHECK(bpf_validate(insns, insn_count));
2265
2266 code = bpfjit_generate_code(bc, insns, insn_count);
2267 ATF_REQUIRE(code != NULL);
2268
2269 for (i = 0; i < sizeof(pkt); i++)
2270 ATF_CHECK(code(pkt, i, 1) == i);
2271
2272 bpfjit_free_code(code);
2273 }
2274
2275 ATF_TC(bpfjit_ld_imm);
2276 ATF_TC_HEAD(bpfjit_ld_imm, tc)
2277 {
2278 atf_tc_set_md_var(tc, "descr",
2279 "Test JIT compilation of BPF_LD+BPF_IMM");
2280 }
2281
2282 ATF_TC_BODY(bpfjit_ld_imm, tc)
2283 {
2284 static struct bpf_insn insns[] = {
2285 BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX),
2286 BPF_STMT(BPF_RET+BPF_A, 0)
2287 };
2288
2289 bpfjit_func_t code;
2290 uint8_t pkt[1]; /* the program doesn't read any data */
2291
2292 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2293
2294 ATF_CHECK(bpf_validate(insns, insn_count));
2295
2296 code = bpfjit_generate_code(bc, insns, insn_count);
2297 ATF_REQUIRE(code != NULL);
2298
2299 ATF_CHECK(code(pkt, 1, 1) == UINT32_MAX);
2300
2301 bpfjit_free_code(code);
2302 }
2303
2304 ATF_TC(bpfjit_ldx_imm1);
2305 ATF_TC_HEAD(bpfjit_ldx_imm1, tc)
2306 {
2307 atf_tc_set_md_var(tc, "descr",
2308 "Test JIT compilation of BPF_LDX+BPF_IMM");
2309 }
2310
2311 ATF_TC_BODY(bpfjit_ldx_imm1, tc)
2312 {
2313 static struct bpf_insn insns[] = {
2314 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX - 5),
2315 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2316 BPF_STMT(BPF_RET+BPF_A, 0)
2317 };
2318
2319 bpfjit_func_t code;
2320 uint8_t pkt[1]; /* the program doesn't read any data */
2321
2322 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2323
2324 ATF_CHECK(bpf_validate(insns, insn_count));
2325
2326 code = bpfjit_generate_code(bc, insns, insn_count);
2327 ATF_REQUIRE(code != NULL);
2328
2329 ATF_CHECK(code(pkt, 1, 1) == UINT32_MAX - 5);
2330
2331 bpfjit_free_code(code);
2332 }
2333
2334 ATF_TC(bpfjit_ldx_imm2);
2335 ATF_TC_HEAD(bpfjit_ldx_imm2, tc)
2336 {
2337 atf_tc_set_md_var(tc, "descr",
2338 "Test JIT compilation of BPF_LDX+BPF_IMM");
2339 }
2340
2341 ATF_TC_BODY(bpfjit_ldx_imm2, tc)
2342 {
2343 static struct bpf_insn insns[] = {
2344 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2345 BPF_STMT(BPF_LD+BPF_IMM, 5),
2346 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2347 BPF_STMT(BPF_RET+BPF_K, 7),
2348 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
2349 };
2350
2351 bpfjit_func_t code;
2352 uint8_t pkt[1]; /* the program doesn't read any data */
2353
2354 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2355
2356 ATF_CHECK(bpf_validate(insns, insn_count));
2357
2358 code = bpfjit_generate_code(bc, insns, insn_count);
2359 ATF_REQUIRE(code != NULL);
2360
2361 ATF_CHECK(code(pkt, 1, 1) == UINT32_MAX);
2362
2363 bpfjit_free_code(code);
2364 }
2365
2366 ATF_TC(bpfjit_ldx_len1);
2367 ATF_TC_HEAD(bpfjit_ldx_len1, tc)
2368 {
2369 atf_tc_set_md_var(tc, "descr",
2370 "Test JIT compilation of BPF_LDX+BPF_LEN");
2371 }
2372
2373 ATF_TC_BODY(bpfjit_ldx_len1, tc)
2374 {
2375 static struct bpf_insn insns[] = {
2376 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2377 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2378 BPF_STMT(BPF_RET+BPF_A, 0)
2379 };
2380
2381 size_t i;
2382 bpfjit_func_t code;
2383 uint8_t pkt[5]; /* the program doesn't read any data */
2384
2385 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2386
2387 ATF_CHECK(bpf_validate(insns, insn_count));
2388
2389 code = bpfjit_generate_code(bc, insns, insn_count);
2390 ATF_REQUIRE(code != NULL);
2391
2392 for (i = 1; i < sizeof(pkt); i++) {
2393 ATF_CHECK(code(pkt, i, 1) == i);
2394 ATF_CHECK(code(pkt, i + 1, i) == i + 1);
2395 }
2396
2397 bpfjit_free_code(code);
2398 }
2399
2400 ATF_TC(bpfjit_ldx_len2);
2401 ATF_TC_HEAD(bpfjit_ldx_len2, tc)
2402 {
2403 atf_tc_set_md_var(tc, "descr",
2404 "Test JIT compilation of BPF_LDX+BPF_LEN");
2405 }
2406
2407 ATF_TC_BODY(bpfjit_ldx_len2, tc)
2408 {
2409 static struct bpf_insn insns[] = {
2410 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2411 BPF_STMT(BPF_LD+BPF_IMM, 5),
2412 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2413 BPF_STMT(BPF_RET+BPF_K, 7),
2414 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
2415 };
2416
2417 bpfjit_func_t code;
2418 uint8_t pkt[5]; /* the program doesn't read any data */
2419
2420 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2421
2422 ATF_CHECK(bpf_validate(insns, insn_count));
2423
2424 code = bpfjit_generate_code(bc, insns, insn_count);
2425 ATF_REQUIRE(code != NULL);
2426
2427 ATF_CHECK(code(pkt, 5, 1) == UINT32_MAX);
2428 ATF_CHECK(code(pkt, 6, 5) == 7);
2429
2430 bpfjit_free_code(code);
2431 }
2432
2433 ATF_TC(bpfjit_ldx_msh);
2434 ATF_TC_HEAD(bpfjit_ldx_msh, tc)
2435 {
2436 atf_tc_set_md_var(tc, "descr",
2437 "Test JIT compilation of BPF_LDX+BPF_MSH");
2438 }
2439
2440 ATF_TC_BODY(bpfjit_ldx_msh, tc)
2441 {
2442 static struct bpf_insn insns[] = {
2443 BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1),
2444 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2445 BPF_STMT(BPF_RET+BPF_A, 0)
2446 };
2447
2448 bpfjit_func_t code;
2449 uint8_t pkt[2] = { 0, 0x7a };
2450
2451 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2452
2453 ATF_CHECK(bpf_validate(insns, insn_count));
2454
2455 code = bpfjit_generate_code(bc, insns, insn_count);
2456 ATF_REQUIRE(code != NULL);
2457
2458 ATF_CHECK(code(pkt, 2, 2) == 40);
2459
2460 bpfjit_free_code(code);
2461 }
2462
2463 ATF_TC(bpfjit_misc_tax);
2464 ATF_TC_HEAD(bpfjit_misc_tax, tc)
2465 {
2466 atf_tc_set_md_var(tc, "descr",
2467 "Test JIT compilation of BPF_MISC+BPF_TAX");
2468 }
2469
2470 ATF_TC_BODY(bpfjit_misc_tax, tc)
2471 {
2472 static struct bpf_insn insns[] = {
2473 BPF_STMT(BPF_LD+BPF_IMM, 3),
2474 BPF_STMT(BPF_MISC+BPF_TAX, 0),
2475 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
2476 BPF_STMT(BPF_RET+BPF_A, 0)
2477 };
2478
2479 bpfjit_func_t code;
2480 uint8_t pkt[] = { 0, 11, 22, 33, 44, 55 };
2481
2482 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2483
2484 ATF_CHECK(bpf_validate(insns, insn_count));
2485
2486 code = bpfjit_generate_code(bc, insns, insn_count);
2487 ATF_REQUIRE(code != NULL);
2488
2489 ATF_CHECK(code(pkt, sizeof(pkt), sizeof(pkt)) == 55);
2490
2491 bpfjit_free_code(code);
2492 }
2493
2494 ATF_TC(bpfjit_misc_txa);
2495 ATF_TC_HEAD(bpfjit_misc_txa, tc)
2496 {
2497 atf_tc_set_md_var(tc, "descr",
2498 "Test JIT compilation of BPF_MISC+BPF_TXA");
2499 }
2500
2501 ATF_TC_BODY(bpfjit_misc_txa, tc)
2502 {
2503 static struct bpf_insn insns[] = {
2504 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 391),
2505 BPF_STMT(BPF_MISC+BPF_TXA, 0),
2506 BPF_STMT(BPF_RET+BPF_A, 0)
2507 };
2508
2509 bpfjit_func_t code;
2510 uint8_t pkt[1]; /* the program doesn't read any data */
2511
2512 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2513
2514 ATF_CHECK(bpf_validate(insns, insn_count));
2515
2516 code = bpfjit_generate_code(bc, insns, insn_count);
2517 ATF_REQUIRE(code != NULL);
2518
2519 ATF_CHECK(code(pkt, 1, 1) == 391);
2520
2521 bpfjit_free_code(code);
2522 }
2523
2524 ATF_TC(bpfjit_st1);
2525 ATF_TC_HEAD(bpfjit_st1, tc)
2526 {
2527 atf_tc_set_md_var(tc, "descr",
2528 "Test JIT compilation of BPF_ST");
2529 }
2530
2531 ATF_TC_BODY(bpfjit_st1, tc)
2532 {
2533 static struct bpf_insn insns[] = {
2534 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2535 BPF_STMT(BPF_ST, 0),
2536 BPF_STMT(BPF_LD+BPF_MEM, 0),
2537 BPF_STMT(BPF_RET+BPF_A, 0)
2538 };
2539
2540 size_t i;
2541 bpfjit_func_t code;
2542 uint8_t pkt[16]; /* the program doesn't read any data */
2543
2544 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2545
2546 ATF_CHECK(bpf_validate(insns, insn_count));
2547
2548 code = bpfjit_generate_code(bc, insns, insn_count);
2549 ATF_REQUIRE(code != NULL);
2550
2551 for (i = 1; i <= sizeof(pkt); i++)
2552 ATF_CHECK(code(pkt, i, sizeof(pkt)) == i);
2553
2554 bpfjit_free_code(code);
2555 }
2556
2557 ATF_TC(bpfjit_st2);
2558 ATF_TC_HEAD(bpfjit_st2, tc)
2559 {
2560 atf_tc_set_md_var(tc, "descr",
2561 "Test JIT compilation of BPF_ST");
2562 }
2563
2564 ATF_TC_BODY(bpfjit_st2, tc)
2565 {
2566 static struct bpf_insn insns[] = {
2567 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2568 BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
2569 BPF_STMT(BPF_LD+BPF_MEM, 0),
2570 BPF_STMT(BPF_RET+BPF_A, 0)
2571 };
2572
2573 bpfjit_func_t code;
2574 uint8_t pkt[1]; /* the program doesn't read any data */
2575
2576 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2577
2578 ATF_CHECK(bpf_validate(insns, insn_count));
2579
2580 code = bpfjit_generate_code(bc, insns, insn_count);
2581 ATF_REQUIRE(code != NULL);
2582
2583 ATF_CHECK(code(pkt, 1, 1) == 0);
2584
2585 bpfjit_free_code(code);
2586 }
2587
2588 ATF_TC(bpfjit_st3);
2589 ATF_TC_HEAD(bpfjit_st3, tc)
2590 {
2591 atf_tc_set_md_var(tc, "descr",
2592 "Test JIT compilation of BPF_ST");
2593 }
2594
2595 ATF_TC_BODY(bpfjit_st3, tc)
2596 {
2597 static struct bpf_insn insns[] = {
2598 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2599 BPF_STMT(BPF_ST, 0),
2600 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
2601 BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
2602 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
2603 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
2604 BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
2605 BPF_STMT(BPF_RET+BPF_A, 0),
2606 BPF_STMT(BPF_LD+BPF_MEM, 0),
2607 BPF_STMT(BPF_RET+BPF_A, 0)
2608 };
2609
2610 bpfjit_func_t code;
2611 uint8_t pkt[2]; /* the program doesn't read any data */
2612
2613 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2614
2615 ATF_REQUIRE(BPF_MEMWORDS > 1);
2616
2617 ATF_CHECK(bpf_validate(insns, insn_count));
2618
2619 code = bpfjit_generate_code(bc, insns, insn_count);
2620 ATF_REQUIRE(code != NULL);
2621
2622 ATF_CHECK(code(pkt, 1, 1) == 1);
2623 ATF_CHECK(code(pkt, 2, 2) == 102);
2624
2625 bpfjit_free_code(code);
2626 }
2627
2628 ATF_TC(bpfjit_st4);
2629 ATF_TC_HEAD(bpfjit_st4, tc)
2630 {
2631 atf_tc_set_md_var(tc, "descr",
2632 "Test JIT compilation of BPF_ST");
2633 }
2634
2635 ATF_TC_BODY(bpfjit_st4, tc)
2636 {
2637 static struct bpf_insn insns[] = {
2638 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2639 BPF_STMT(BPF_ST, 5),
2640 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
2641 BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
2642 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
2643 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
2644 BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
2645 BPF_STMT(BPF_RET+BPF_A, 0),
2646 BPF_STMT(BPF_LD+BPF_MEM, 5),
2647 BPF_STMT(BPF_RET+BPF_A, 0)
2648 };
2649
2650 bpfjit_func_t code;
2651 uint8_t pkt[2]; /* the program doesn't read any data */
2652
2653 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2654
2655 ATF_REQUIRE(BPF_MEMWORDS > 6);
2656
2657 ATF_CHECK(bpf_validate(insns, insn_count));
2658
2659 code = bpfjit_generate_code(bc, insns, insn_count);
2660 ATF_REQUIRE(code != NULL);
2661
2662 ATF_CHECK(code(pkt, 1, 1) == 1);
2663 ATF_CHECK(code(pkt, 2, 2) == 102);
2664
2665 bpfjit_free_code(code);
2666 }
2667
2668 ATF_TC(bpfjit_st5);
2669 ATF_TC_HEAD(bpfjit_st5, tc)
2670 {
2671 atf_tc_set_md_var(tc, "descr",
2672 "Test JIT compilation of BPF_ST");
2673 }
2674
2675 ATF_TC_BODY(bpfjit_st5, tc)
2676 {
2677 struct bpf_insn insns[5*BPF_MEMWORDS+2];
2678 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2679
2680 size_t k;
2681 bpfjit_func_t code;
2682 uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
2683
2684 memset(insns, 0, sizeof(insns));
2685
2686 /* for each k do M[k] = k */
2687 for (k = 0; k < BPF_MEMWORDS; k++) {
2688 insns[2*k].code = BPF_LD+BPF_IMM;
2689 insns[2*k].k = 3*k;
2690 insns[2*k+1].code = BPF_ST;
2691 insns[2*k+1].k = k;
2692 }
2693
2694 /* load wirelen into A */
2695 insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
2696
2697 /* for each k, if (A == k + 1) return M[k] */
2698 for (k = 0; k < BPF_MEMWORDS; k++) {
2699 insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
2700 insns[2*BPF_MEMWORDS+3*k+1].k = k+1;
2701 insns[2*BPF_MEMWORDS+3*k+1].jt = 0;
2702 insns[2*BPF_MEMWORDS+3*k+1].jf = 2;
2703 insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
2704 insns[2*BPF_MEMWORDS+3*k+2].k = k;
2705 insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
2706 insns[2*BPF_MEMWORDS+3*k+3].k = 0;
2707 }
2708
2709 insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
2710 insns[5*BPF_MEMWORDS+1].k = UINT32_MAX;
2711
2712 ATF_CHECK(bpf_validate(insns, insn_count));
2713
2714 code = bpfjit_generate_code(bc, insns, insn_count);
2715 ATF_REQUIRE(code != NULL);
2716
2717 for (k = 1; k <= sizeof(pkt); k++)
2718 ATF_CHECK(code(pkt, k, k) == 3*(k-1));
2719
2720 bpfjit_free_code(code);
2721 }
2722
2723 ATF_TC(bpfjit_stx1);
2724 ATF_TC_HEAD(bpfjit_stx1, tc)
2725 {
2726 atf_tc_set_md_var(tc, "descr",
2727 "Test JIT compilation of BPF_STX");
2728 }
2729
2730 ATF_TC_BODY(bpfjit_stx1, tc)
2731 {
2732 static struct bpf_insn insns[] = {
2733 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2734 BPF_STMT(BPF_STX, 0),
2735 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
2736 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2737 BPF_STMT(BPF_RET+BPF_A, 0)
2738 };
2739
2740 size_t i;
2741 bpfjit_func_t code;
2742 uint8_t pkt[16]; /* the program doesn't read any data */
2743
2744 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2745
2746 ATF_CHECK(bpf_validate(insns, insn_count));
2747
2748 code = bpfjit_generate_code(bc, insns, insn_count);
2749 ATF_REQUIRE(code != NULL);
2750
2751 for (i = 1; i <= sizeof(pkt); i++)
2752 ATF_CHECK(code(pkt, i, sizeof(pkt)) == i);
2753
2754 bpfjit_free_code(code);
2755 }
2756
2757 ATF_TC(bpfjit_stx2);
2758 ATF_TC_HEAD(bpfjit_stx2, tc)
2759 {
2760 atf_tc_set_md_var(tc, "descr",
2761 "Test JIT compilation of BPF_STX");
2762 }
2763
2764 ATF_TC_BODY(bpfjit_stx2, tc)
2765 {
2766 static struct bpf_insn insns[] = {
2767 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2768 BPF_STMT(BPF_STX, BPF_MEMWORDS-1),
2769 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
2770 BPF_STMT(BPF_MISC+BPF_TXA, 0),
2771 BPF_STMT(BPF_RET+BPF_A, 0)
2772 };
2773
2774 bpfjit_func_t code;
2775 uint8_t pkt[1]; /* the program doesn't read any data */
2776
2777 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2778
2779 ATF_CHECK(bpf_validate(insns, insn_count));
2780
2781 code = bpfjit_generate_code(bc, insns, insn_count);
2782 ATF_REQUIRE(code != NULL);
2783
2784 ATF_CHECK(code(pkt, 1, 1) == 0);
2785
2786 bpfjit_free_code(code);
2787 }
2788
2789 ATF_TC(bpfjit_stx3);
2790 ATF_TC_HEAD(bpfjit_stx3, tc)
2791 {
2792 atf_tc_set_md_var(tc, "descr",
2793 "Test JIT compilation of BPF_STX");
2794 }
2795
2796 ATF_TC_BODY(bpfjit_stx3, tc)
2797 {
2798 static struct bpf_insn insns[] = {
2799 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2800 BPF_STMT(BPF_STX, 5),
2801 BPF_STMT(BPF_STX, 2),
2802 BPF_STMT(BPF_STX, 3),
2803 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 1),
2804 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2805 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 2),
2806 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2807 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
2808 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2809 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 5),
2810 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2811 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 6),
2812 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2813 BPF_STMT(BPF_RET+BPF_A, 0)
2814 };
2815
2816 size_t i;
2817 bpfjit_func_t code;
2818 uint8_t pkt[16]; /* the program doesn't read any data */
2819
2820 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2821
2822 ATF_CHECK(bpf_validate(insns, insn_count));
2823
2824 code = bpfjit_generate_code(bc, insns, insn_count);
2825 ATF_REQUIRE(code != NULL);
2826
2827 for (i = 1; i <= sizeof(pkt); i++)
2828 ATF_CHECK(code(pkt, i, sizeof(pkt)) == 3 * i);
2829
2830 bpfjit_free_code(code);
2831 }
2832
2833 ATF_TC(bpfjit_stx4);
2834 ATF_TC_HEAD(bpfjit_stx4, tc)
2835 {
2836 atf_tc_set_md_var(tc, "descr",
2837 "Test JIT compilation of BPF_STX");
2838 }
2839
2840 ATF_TC_BODY(bpfjit_stx4, tc)
2841 {
2842 struct bpf_insn insns[5*BPF_MEMWORDS+2];
2843 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2844
2845 size_t k;
2846 bpfjit_func_t code;
2847 uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
2848
2849 memset(insns, 0, sizeof(insns));
2850
2851 /* for each k do M[k] = k */
2852 for (k = 0; k < BPF_MEMWORDS; k++) {
2853 insns[2*k].code = BPF_LDX+BPF_W+BPF_IMM;
2854 insns[2*k].k = 3*k;
2855 insns[2*k+1].code = BPF_STX;
2856 insns[2*k+1].k = k;
2857 }
2858
2859 /* load wirelen into A */
2860 insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
2861
2862 /* for each k, if (A == k + 1) return M[k] */
2863 for (k = 0; k < BPF_MEMWORDS; k++) {
2864 insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
2865 insns[2*BPF_MEMWORDS+3*k+1].k = k+1;
2866 insns[2*BPF_MEMWORDS+3*k+1].jt = 0;
2867 insns[2*BPF_MEMWORDS+3*k+1].jf = 2;
2868 insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
2869 insns[2*BPF_MEMWORDS+3*k+2].k = k;
2870 insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
2871 insns[2*BPF_MEMWORDS+3*k+3].k = 0;
2872 }
2873
2874 insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
2875 insns[5*BPF_MEMWORDS+1].k = UINT32_MAX;
2876
2877 ATF_CHECK(bpf_validate(insns, insn_count));
2878
2879 code = bpfjit_generate_code(bc, insns, insn_count);
2880 ATF_REQUIRE(code != NULL);
2881
2882 for (k = 1; k <= sizeof(pkt); k++)
2883 ATF_CHECK(code(pkt, k, k) == 3*(k-1));
2884
2885 bpfjit_free_code(code);
2886 }
2887
2888 ATF_TC(bpfjit_opt_ld_abs_1);
2889 ATF_TC_HEAD(bpfjit_opt_ld_abs_1, tc)
2890 {
2891 atf_tc_set_md_var(tc, "descr",
2892 "Test JIT compilation with length optimization "
2893 "applied to BPF_LD+BPF_ABS");
2894 }
2895
2896 ATF_TC_BODY(bpfjit_opt_ld_abs_1, tc)
2897 {
2898 static struct bpf_insn insns[] = {
2899 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
2900 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
2901 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
2902 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
2903 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
2904 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
2905 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
2906 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
2907 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
2908 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
2909 BPF_STMT(BPF_RET+BPF_K, 0),
2910 };
2911
2912 size_t i, j;
2913 bpfjit_func_t code;
2914 uint8_t pkt[2][34] = {
2915 {
2916 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2917 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2918 0x80, 0x03, 0x70, 0x0f,
2919 0x80, 0x03, 0x70, 0x23
2920 },
2921 {
2922 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2923 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2924 0x80, 0x03, 0x70, 0x23,
2925 0x80, 0x03, 0x70, 0x0f
2926 }
2927 };
2928
2929 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2930
2931 ATF_CHECK(bpf_validate(insns, insn_count));
2932
2933 code = bpfjit_generate_code(bc, insns, insn_count);
2934 ATF_REQUIRE(code != NULL);
2935
2936 for (i = 0; i < 2; i++) {
2937 for (j = 1; j < sizeof(pkt[i]); j++)
2938 ATF_CHECK(code(pkt[i], j, j) == 0);
2939 ATF_CHECK(code(pkt[i], j, j) == UINT32_MAX);
2940 }
2941
2942 bpfjit_free_code(code);
2943 }
2944
2945 ATF_TC(bpfjit_opt_ld_abs_2);
2946 ATF_TC_HEAD(bpfjit_opt_ld_abs_2, tc)
2947 {
2948 atf_tc_set_md_var(tc, "descr",
2949 "Test JIT compilation with length optimization "
2950 "applied to BPF_LD+BPF_ABS");
2951 }
2952
2953 ATF_TC_BODY(bpfjit_opt_ld_abs_2, tc)
2954 {
2955 static struct bpf_insn insns[] = {
2956 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
2957 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
2958 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
2959 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
2960 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
2961 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
2962 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
2963 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
2964 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
2965 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
2966 BPF_STMT(BPF_RET+BPF_K, 0),
2967 };
2968
2969 size_t i, j;
2970 bpfjit_func_t code;
2971 uint8_t pkt[2][34] = {
2972 {
2973 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2974 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2975 0x80, 0x03, 0x70, 0x0f,
2976 0x80, 0x03, 0x70, 0x23
2977 },
2978 {
2979 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2980 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2981 0x80, 0x03, 0x70, 0x23,
2982 0x80, 0x03, 0x70, 0x0f
2983 }
2984 };
2985
2986 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2987
2988 ATF_CHECK(bpf_validate(insns, insn_count));
2989
2990 code = bpfjit_generate_code(bc, insns, insn_count);
2991 ATF_REQUIRE(code != NULL);
2992
2993 for (i = 0; i < 2; i++) {
2994 for (j = 1; j < sizeof(pkt[i]); j++)
2995 ATF_CHECK(code(pkt[i], j, j) == 0);
2996 ATF_CHECK(code(pkt[i], j, j) == UINT32_MAX);
2997 }
2998
2999 bpfjit_free_code(code);
3000 }
3001
3002 ATF_TC(bpfjit_opt_ld_abs_3);
3003 ATF_TC_HEAD(bpfjit_opt_ld_abs_3, tc)
3004 {
3005 atf_tc_set_md_var(tc, "descr",
3006 "Test JIT compilation with length optimization "
3007 "applied to BPF_LD+BPF_ABS");
3008 }
3009
3010 ATF_TC_BODY(bpfjit_opt_ld_abs_3, tc)
3011 {
3012 static struct bpf_insn insns[] = {
3013 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3014 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3015 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3016 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 6),
3017 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 5),
3018 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3019 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3020 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3021 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3022 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3023 BPF_STMT(BPF_RET+BPF_K, 0),
3024 };
3025
3026 size_t i, j;
3027 bpfjit_func_t code;
3028 uint8_t pkt[2][34] = {
3029 {
3030 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3031 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3032 0x80, 0x03, 0x70, 0x0f,
3033 0x80, 0x03, 0x70, 0x23
3034 },
3035 {
3036 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3037 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3038 0x80, 0x03, 0x70, 0x23,
3039 0x80, 0x03, 0x70, 0x0f
3040 }
3041 };
3042
3043 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3044
3045 ATF_CHECK(bpf_validate(insns, insn_count));
3046
3047 code = bpfjit_generate_code(bc, insns, insn_count);
3048 ATF_REQUIRE(code != NULL);
3049
3050 for (i = 0; i < 2; i++) {
3051 for (j = 1; j < sizeof(pkt[i]); j++)
3052 ATF_CHECK(code(pkt[i], j, j) == 0);
3053 ATF_CHECK(code(pkt[i], j, j) == UINT32_MAX);
3054 }
3055
3056 bpfjit_free_code(code);
3057 }
3058
3059 ATF_TC(bpfjit_opt_ld_ind_1);
3060 ATF_TC_HEAD(bpfjit_opt_ld_ind_1, tc)
3061 {
3062 atf_tc_set_md_var(tc, "descr",
3063 "Test JIT compilation with length optimization "
3064 "applied to BPF_LD+BPF_IND");
3065 }
3066
3067 ATF_TC_BODY(bpfjit_opt_ld_ind_1, tc)
3068 {
3069 static struct bpf_insn insns[] = {
3070 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 12),
3071 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
3072 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
3073 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 14),
3074 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3075 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
3076 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
3077 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3078 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
3079 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
3080 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3081 BPF_STMT(BPF_RET+BPF_K, 0),
3082 };
3083
3084 size_t i, j;
3085 bpfjit_func_t code;
3086 uint8_t pkt[2][34] = {
3087 {
3088 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3089 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3090 0x80, 0x03, 0x70, 0x0f,
3091 0x80, 0x03, 0x70, 0x23
3092 },
3093 {
3094 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3095 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3096 0x80, 0x03, 0x70, 0x23,
3097 0x80, 0x03, 0x70, 0x0f
3098 }
3099 };
3100
3101 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3102
3103 ATF_CHECK(bpf_validate(insns, insn_count));
3104
3105 code = bpfjit_generate_code(bc, insns, insn_count);
3106 ATF_REQUIRE(code != NULL);
3107
3108 for (i = 0; i < 2; i++) {
3109 for (j = 1; j < sizeof(pkt[i]); j++)
3110 ATF_CHECK(code(pkt[i], j, j) == 0);
3111 ATF_CHECK(code(pkt[i], j, j) == UINT32_MAX);
3112 }
3113
3114 bpfjit_free_code(code);
3115 }
3116
3117 ATF_TC(bpfjit_opt_ld_ind_2);
3118 ATF_TC_HEAD(bpfjit_opt_ld_ind_2, tc)
3119 {
3120 atf_tc_set_md_var(tc, "descr",
3121 "Test JIT compilation with length optimization "
3122 "applied to BPF_LD+BPF_IND");
3123 }
3124
3125 ATF_TC_BODY(bpfjit_opt_ld_ind_2, tc)
3126 {
3127 static struct bpf_insn insns[] = {
3128 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3129 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 26),
3130 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3131 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
3132 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
3133 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
3134 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
3135 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
3136 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3137 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3138 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3139 BPF_STMT(BPF_RET+BPF_K, 0),
3140 };
3141
3142 size_t i, j;
3143 bpfjit_func_t code;
3144 uint8_t pkt[2][34] = {
3145 {
3146 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3147 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3148 0x80, 0x03, 0x70, 0x0f,
3149 0x80, 0x03, 0x70, 0x23
3150 },
3151 {
3152 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3153 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3154 0x80, 0x03, 0x70, 0x23,
3155 0x80, 0x03, 0x70, 0x0f
3156 }
3157 };
3158
3159 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3160
3161 ATF_CHECK(bpf_validate(insns, insn_count));
3162
3163 code = bpfjit_generate_code(bc, insns, insn_count);
3164 ATF_REQUIRE(code != NULL);
3165
3166 for (i = 0; i < 2; i++) {
3167 for (j = 1; j < sizeof(pkt[i]); j++)
3168 ATF_CHECK(code(pkt[i], j, j) == 0);
3169 ATF_CHECK(code(pkt[i], j, j) == UINT32_MAX);
3170 }
3171
3172 bpfjit_free_code(code);
3173 }
3174
3175 ATF_TC(bpfjit_opt_ld_ind_3);
3176 ATF_TC_HEAD(bpfjit_opt_ld_ind_3, tc)
3177 {
3178 atf_tc_set_md_var(tc, "descr",
3179 "Test JIT compilation with length optimization "
3180 "applied to BPF_LD+BPF_IND");
3181 }
3182
3183 ATF_TC_BODY(bpfjit_opt_ld_ind_3, tc)
3184 {
3185 static struct bpf_insn insns[] = {
3186 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 15),
3187 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3188 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3189 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
3190 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
3191 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
3192 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
3193 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
3194 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3195 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3196 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3197 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3198 BPF_STMT(BPF_RET+BPF_K, 0),
3199 };
3200
3201 size_t i, j;
3202 bpfjit_func_t code;
3203 uint8_t pkt[2][34] = {
3204 {
3205 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3206 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3207 0x80, 0x03, 0x70, 0x0f,
3208 0x80, 0x03, 0x70, 0x23
3209 },
3210 {
3211 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3212 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3213 0x80, 0x03, 0x70, 0x23,
3214 0x80, 0x03, 0x70, 0x0f
3215 }
3216 };
3217
3218 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3219
3220 ATF_CHECK(bpf_validate(insns, insn_count));
3221
3222 code = bpfjit_generate_code(bc, insns, insn_count);
3223 ATF_REQUIRE(code != NULL);
3224
3225 for (i = 0; i < 2; i++) {
3226 for (j = 1; j < sizeof(pkt[i]); j++)
3227 ATF_CHECK(code(pkt[i], j, j) == 0);
3228 ATF_CHECK(code(pkt[i], j, j) == UINT32_MAX);
3229 }
3230
3231 bpfjit_free_code(code);
3232 }
3233
3234 ATF_TC(bpfjit_opt_ld_ind_4);
3235 ATF_TC_HEAD(bpfjit_opt_ld_ind_4, tc)
3236 {
3237 atf_tc_set_md_var(tc, "descr",
3238 "Test JIT compilation with length optimization "
3239 "applied to BPF_LD+BPF_IND");
3240 }
3241
3242 ATF_TC_BODY(bpfjit_opt_ld_ind_4, tc)
3243 {
3244 static struct bpf_insn insns[] = {
3245 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 11),
3246 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 19),
3247 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3248 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3249 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
3250 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
3251 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3252 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
3253 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3254 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3255 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3256 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3257 BPF_STMT(BPF_RET+BPF_K, 0),
3258 };
3259
3260 size_t i, j;
3261 bpfjit_func_t code;
3262 uint8_t pkt[2][34] = {
3263 {
3264 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3265 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3266 0x80, 0x03, 0x70, 0x0f,
3267 0x80, 0x03, 0x70, 0x23
3268 },
3269 {
3270 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3271 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3272 0x80, 0x03, 0x70, 0x23,
3273 0x80, 0x03, 0x70, 0x0f
3274 }
3275 };
3276
3277 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3278
3279 ATF_CHECK(bpf_validate(insns, insn_count));
3280
3281 code = bpfjit_generate_code(bc, insns, insn_count);
3282 ATF_REQUIRE(code != NULL);
3283
3284 for (i = 0; i < 2; i++) {
3285 for (j = 1; j < sizeof(pkt[i]); j++)
3286 ATF_CHECK(code(pkt[i], j, j) == 0);
3287 ATF_CHECK(code(pkt[i], j, j) == UINT32_MAX);
3288 }
3289
3290 bpfjit_free_code(code);
3291 }
3292
3293 ATF_TC(bpfjit_abc_ja);
3294 ATF_TC_HEAD(bpfjit_abc_ja, tc)
3295 {
3296 atf_tc_set_md_var(tc, "descr",
3297 "Test ABC optimization with a single BPF_JMP+BPF_JA");
3298 }
3299
3300 ATF_TC_BODY(bpfjit_abc_ja, tc)
3301 {
3302 static struct bpf_insn insns[] = {
3303 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
3304 BPF_STMT(BPF_JMP+BPF_JA, 2),
3305 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, UINT32_MAX - 1),
3306 BPF_STMT(BPF_RET+BPF_K, 0),
3307 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), /* min. length 6 */
3308 BPF_STMT(BPF_RET+BPF_A, 0),
3309 BPF_STMT(BPF_RET+BPF_K, 1),
3310 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
3311 BPF_STMT(BPF_RET+BPF_K, 2),
3312 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
3313 BPF_STMT(BPF_RET+BPF_K, 3),
3314 };
3315
3316 bpfjit_func_t code;
3317 uint8_t pkt[6] = {0, 0, /* UINT32_MAX: */ 255, 255, 255, 255};
3318
3319 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3320
3321 ATF_CHECK(bpf_validate(insns, insn_count));
3322
3323 code = bpfjit_generate_code(bc, insns, insn_count);
3324 ATF_REQUIRE(code != NULL);
3325
3326 ATF_CHECK(code(pkt, 0, 0) == 0);
3327 ATF_CHECK(code(pkt, 1, 1) == 0);
3328 ATF_CHECK(code(pkt, 2, 2) == 0);
3329 ATF_CHECK(code(pkt, 3, 3) == 0);
3330 ATF_CHECK(code(pkt, 4, 4) == 0);
3331 ATF_CHECK(code(pkt, 5, 5) == 0);
3332 ATF_CHECK(code(pkt, 6, 6) == UINT32_MAX);
3333
3334 bpfjit_free_code(code);
3335 }
3336
3337 ATF_TC(bpfjit_abc_ja_over);
3338 ATF_TC_HEAD(bpfjit_abc_ja_over, tc)
3339 {
3340 atf_tc_set_md_var(tc, "descr",
3341 "Test ABC optimization when BPF_JMP+BPF_JA jumps over all loads");
3342 }
3343
3344 ATF_TC_BODY(bpfjit_abc_ja_over, tc)
3345 {
3346 static struct bpf_insn insns[] = {
3347 BPF_STMT(BPF_JMP+BPF_JA, 2),
3348 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3),
3349 BPF_STMT(BPF_RET+BPF_K, 0),
3350 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3351 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4),
3352 BPF_STMT(BPF_RET+BPF_K, 1),
3353 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
3354 BPF_STMT(BPF_RET+BPF_K, 2),
3355 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
3356 BPF_STMT(BPF_RET+BPF_K, 3),
3357 };
3358
3359 bpfjit_func_t code;
3360 uint8_t pkt[1]; /* the program doesn't read any data */
3361
3362 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3363
3364 ATF_CHECK(bpf_validate(insns, insn_count));
3365
3366 code = bpfjit_generate_code(bc, insns, insn_count);
3367 ATF_REQUIRE(code != NULL);
3368
3369 ATF_CHECK(code(pkt, 1, 1) == UINT32_MAX);
3370
3371 bpfjit_free_code(code);
3372 }
3373
3374 ATF_TC(bpfjit_abc_ld_chain);
3375 ATF_TC_HEAD(bpfjit_abc_ld_chain, tc)
3376 {
3377 atf_tc_set_md_var(tc, "descr",
3378 "Test ABC optimization of a chain of BPF_LD instructions "
3379 "with exits leading to a single BPF_RET");
3380 }
3381
3382 ATF_TC_BODY(bpfjit_abc_ld_chain, tc)
3383 {
3384 static struct bpf_insn insns[] = {
3385 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
3386 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 4),
3387 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* min. length 6 */
3388 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 0, 2),
3389 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), /* min. length 10 */
3390 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 0, 1),
3391 BPF_STMT(BPF_RET+BPF_K, 123456789),
3392 BPF_STMT(BPF_RET+BPF_K, 987654321),
3393 };
3394
3395 bpfjit_func_t code;
3396 uint8_t pkt[10] = {};
3397
3398 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3399
3400 ATF_CHECK(bpf_validate(insns, insn_count));
3401
3402 code = bpfjit_generate_code(bc, insns, insn_count);
3403 ATF_REQUIRE(code != NULL);
3404
3405 /* Packet is too short. */
3406 ATF_CHECK(code(pkt, 1, 1) == 0);
3407 ATF_CHECK(code(pkt, 2, 2) == 0);
3408 ATF_CHECK(code(pkt, 3, 3) == 0);
3409
3410 /* !(pkt[3] == 8) => return 123456789 */
3411 ATF_CHECK(code(pkt, 4, 4) == 123456789);
3412 ATF_CHECK(code(pkt, 5, 5) == 123456789);
3413 ATF_CHECK(code(pkt, 6, 6) == 123456789);
3414 ATF_CHECK(code(pkt, 7, 7) == 123456789);
3415 ATF_CHECK(code(pkt, 8, 8) == 123456789);
3416 ATF_CHECK(code(pkt, 9, 9) == 123456789);
3417
3418 /* !(pkt[4:2] >= 7) => too short or return 123456789 */
3419 pkt[3] = 8;
3420 ATF_CHECK(code(pkt, 1, 1) == 0);
3421 ATF_CHECK(code(pkt, 2, 2) == 0);
3422 ATF_CHECK(code(pkt, 3, 3) == 0);
3423 ATF_CHECK(code(pkt, 4, 4) == 0);
3424 ATF_CHECK(code(pkt, 5, 5) == 0);
3425 ATF_CHECK(code(pkt, 6, 6) == 123456789);
3426 ATF_CHECK(code(pkt, 9, 9) == 123456789);
3427
3428 /* !(pkt[6:4] > 6) => too short or return 987654321 */
3429 pkt[4] = pkt[5] = 1;
3430 ATF_CHECK(code(pkt, 1, 1) == 0);
3431 ATF_CHECK(code(pkt, 2, 2) == 0);
3432 ATF_CHECK(code(pkt, 3, 3) == 0);
3433 ATF_CHECK(code(pkt, 4, 4) == 0);
3434 ATF_CHECK(code(pkt, 5, 5) == 0);
3435 ATF_CHECK(code(pkt, 6, 6) == 0);
3436 ATF_CHECK(code(pkt, 7, 7) == 0);
3437 ATF_CHECK(code(pkt, 8, 8) == 0);
3438 ATF_CHECK(code(pkt, 9, 9) == 0);
3439 ATF_CHECK(code(pkt, 10, 10) == 987654321);
3440
3441 /* (pkt[6:4] > 6) => too short or return 123456789 */
3442 pkt[6] = pkt[7] = pkt[8] = pkt[9] = 1;
3443 ATF_CHECK(code(pkt, 1, 1) == 0);
3444 ATF_CHECK(code(pkt, 2, 2) == 0);
3445 ATF_CHECK(code(pkt, 3, 3) == 0);
3446 ATF_CHECK(code(pkt, 4, 4) == 0);
3447 ATF_CHECK(code(pkt, 5, 5) == 0);
3448 ATF_CHECK(code(pkt, 6, 6) == 0);
3449 ATF_CHECK(code(pkt, 7, 7) == 0);
3450 ATF_CHECK(code(pkt, 8, 8) == 0);
3451 ATF_CHECK(code(pkt, 9, 9) == 0);
3452 ATF_CHECK(code(pkt, 10, 10) == 123456789);
3453
3454 bpfjit_free_code(code);
3455 }
3456
3457 ATF_TC(bpfjit_examples_1);
3458 ATF_TC_HEAD(bpfjit_examples_1, tc)
3459 {
3460 atf_tc_set_md_var(tc, "descr",
3461 "Test the first example from bpf(4) - "
3462 "accept Reverse ARP requests");
3463 }
3464
3465 ATF_TC_BODY(bpfjit_examples_1, tc)
3466 {
3467 /*
3468 * The following filter is taken from the Reverse ARP
3469 * Daemon. It accepts only Reverse ARP requests.
3470 */
3471 struct bpf_insn insns[] = {
3472 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3473 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8035, 0, 3),
3474 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
3475 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 1),
3476 BPF_STMT(BPF_RET+BPF_K, 42),
3477 BPF_STMT(BPF_RET+BPF_K, 0),
3478 };
3479
3480 bpfjit_func_t code;
3481 uint8_t pkt[22] = {};
3482
3483 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3484
3485 ATF_CHECK(bpf_validate(insns, insn_count));
3486
3487 code = bpfjit_generate_code(bc, insns, insn_count);
3488 ATF_REQUIRE(code != NULL);
3489
3490 /* Packet is too short. */
3491 ATF_CHECK(code(pkt, 1, 1) == 0);
3492 ATF_CHECK(code(pkt, 2, 2) == 0);
3493 ATF_CHECK(code(pkt, 3, 3) == 0);
3494 ATF_CHECK(code(pkt, 4, 4) == 0);
3495 ATF_CHECK(code(pkt, 5, 5) == 0);
3496 ATF_CHECK(code(pkt, 6, 6) == 0);
3497 ATF_CHECK(code(pkt, 7, 7) == 0);
3498 ATF_CHECK(code(pkt, 8, 8) == 0);
3499 ATF_CHECK(code(pkt, 9, 9) == 0);
3500 ATF_CHECK(code(pkt, 10, 10) == 0);
3501 ATF_CHECK(code(pkt, 11, 11) == 0);
3502 ATF_CHECK(code(pkt, 12, 12) == 0);
3503 ATF_CHECK(code(pkt, 13, 13) == 0);
3504 ATF_CHECK(code(pkt, 14, 14) == 0);
3505 ATF_CHECK(code(pkt, 15, 15) == 0);
3506 ATF_CHECK(code(pkt, 16, 16) == 0);
3507 ATF_CHECK(code(pkt, 17, 17) == 0);
3508 ATF_CHECK(code(pkt, 18, 18) == 0);
3509 ATF_CHECK(code(pkt, 19, 19) == 0);
3510 ATF_CHECK(code(pkt, 20, 20) == 0);
3511 ATF_CHECK(code(pkt, 21, 21) == 0);
3512
3513 /* The packet doesn't match. */
3514 ATF_CHECK(code(pkt, 22, 22) == 0);
3515
3516 /* Still no match after setting the protocol field. */
3517 pkt[12] = 0x80; pkt[13] = 0x35;
3518 ATF_CHECK(code(pkt, 22, 22) == 0);
3519
3520 /* Set RARP message type. */
3521 pkt[21] = 3;
3522 ATF_CHECK(code(pkt, 22, 22) == 42);
3523
3524 /* Packet is too short. */
3525 ATF_CHECK(code(pkt, 1, 1) == 0);
3526 ATF_CHECK(code(pkt, 2, 2) == 0);
3527 ATF_CHECK(code(pkt, 3, 3) == 0);
3528 ATF_CHECK(code(pkt, 4, 4) == 0);
3529 ATF_CHECK(code(pkt, 5, 5) == 0);
3530 ATF_CHECK(code(pkt, 6, 6) == 0);
3531 ATF_CHECK(code(pkt, 7, 7) == 0);
3532 ATF_CHECK(code(pkt, 8, 8) == 0);
3533 ATF_CHECK(code(pkt, 9, 9) == 0);
3534 ATF_CHECK(code(pkt, 10, 10) == 0);
3535 ATF_CHECK(code(pkt, 11, 11) == 0);
3536 ATF_CHECK(code(pkt, 12, 12) == 0);
3537 ATF_CHECK(code(pkt, 13, 13) == 0);
3538 ATF_CHECK(code(pkt, 14, 14) == 0);
3539 ATF_CHECK(code(pkt, 15, 15) == 0);
3540 ATF_CHECK(code(pkt, 16, 16) == 0);
3541 ATF_CHECK(code(pkt, 17, 17) == 0);
3542 ATF_CHECK(code(pkt, 18, 18) == 0);
3543 ATF_CHECK(code(pkt, 19, 19) == 0);
3544 ATF_CHECK(code(pkt, 20, 20) == 0);
3545 ATF_CHECK(code(pkt, 21, 21) == 0);
3546
3547 /* Change RARP message type. */
3548 pkt[20] = 3;
3549 ATF_CHECK(code(pkt, 22, 22) == 0);
3550
3551 bpfjit_free_code(code);
3552 }
3553
3554 ATF_TC(bpfjit_examples_2);
3555 ATF_TC_HEAD(bpfjit_examples_2, tc)
3556 {
3557 atf_tc_set_md_var(tc, "descr",
3558 "Test the second example from bpf(4) - "
3559 "accept IP packets between two specified hosts");
3560 }
3561
3562 ATF_TC_BODY(bpfjit_examples_2, tc)
3563 {
3564 /*
3565 * This filter accepts only IP packets between host 128.3.112.15
3566 * and 128.3.112.35.
3567 */
3568 static struct bpf_insn insns[] = {
3569 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3570 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 8),
3571 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3572 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3573 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3574 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
3575 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3576 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3577 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
3578 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3579 BPF_STMT(BPF_RET+BPF_K, 0),
3580 };
3581
3582 bpfjit_func_t code;
3583 uint8_t pkt[34] = {};
3584
3585 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3586
3587 ATF_CHECK(bpf_validate(insns, insn_count));
3588
3589 code = bpfjit_generate_code(bc, insns, insn_count);
3590 ATF_REQUIRE(code != NULL);
3591
3592 /* Packet is too short. */
3593 ATF_CHECK(code(pkt, 1, 1) == 0);
3594 ATF_CHECK(code(pkt, 2, 2) == 0);
3595 ATF_CHECK(code(pkt, 3, 3) == 0);
3596 ATF_CHECK(code(pkt, 4, 4) == 0);
3597 ATF_CHECK(code(pkt, 5, 5) == 0);
3598 ATF_CHECK(code(pkt, 6, 6) == 0);
3599 ATF_CHECK(code(pkt, 7, 7) == 0);
3600 ATF_CHECK(code(pkt, 8, 8) == 0);
3601 ATF_CHECK(code(pkt, 9, 9) == 0);
3602 ATF_CHECK(code(pkt, 10, 10) == 0);
3603 ATF_CHECK(code(pkt, 11, 11) == 0);
3604 ATF_CHECK(code(pkt, 12, 12) == 0);
3605 ATF_CHECK(code(pkt, 13, 13) == 0);
3606 ATF_CHECK(code(pkt, 14, 14) == 0);
3607 ATF_CHECK(code(pkt, 15, 15) == 0);
3608 ATF_CHECK(code(pkt, 16, 16) == 0);
3609 ATF_CHECK(code(pkt, 17, 17) == 0);
3610 ATF_CHECK(code(pkt, 18, 18) == 0);
3611 ATF_CHECK(code(pkt, 19, 19) == 0);
3612 ATF_CHECK(code(pkt, 20, 20) == 0);
3613 ATF_CHECK(code(pkt, 21, 21) == 0);
3614 ATF_CHECK(code(pkt, 22, 22) == 0);
3615 ATF_CHECK(code(pkt, 23, 23) == 0);
3616 ATF_CHECK(code(pkt, 24, 24) == 0);
3617 ATF_CHECK(code(pkt, 25, 25) == 0);
3618 ATF_CHECK(code(pkt, 26, 26) == 0);
3619 ATF_CHECK(code(pkt, 27, 27) == 0);
3620 ATF_CHECK(code(pkt, 28, 28) == 0);
3621 ATF_CHECK(code(pkt, 29, 29) == 0);
3622 ATF_CHECK(code(pkt, 30, 30) == 0);
3623 ATF_CHECK(code(pkt, 31, 31) == 0);
3624 ATF_CHECK(code(pkt, 32, 32) == 0);
3625 ATF_CHECK(code(pkt, 33, 33) == 0);
3626
3627 /* The packet doesn't match. */
3628 ATF_CHECK(code(pkt, 34, 34) == 0);
3629
3630 /* Still no match after setting the protocol field. */
3631 pkt[12] = 8;
3632 ATF_CHECK(code(pkt, 34, 34) == 0);
3633
3634 pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 15;
3635 ATF_CHECK(code(pkt, 34, 34) == 0);
3636
3637 pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 35;
3638 ATF_CHECK(code(pkt, 34, 34) == UINT32_MAX);
3639
3640 /* Swap the ip addresses. */
3641 pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 35;
3642 ATF_CHECK(code(pkt, 34, 34) == 0);
3643
3644 pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 15;
3645 ATF_CHECK(code(pkt, 34, 34) == UINT32_MAX);
3646
3647 /* Packet is too short. */
3648 ATF_CHECK(code(pkt, 1, 1) == 0);
3649 ATF_CHECK(code(pkt, 2, 2) == 0);
3650 ATF_CHECK(code(pkt, 3, 3) == 0);
3651 ATF_CHECK(code(pkt, 4, 4) == 0);
3652 ATF_CHECK(code(pkt, 5, 5) == 0);
3653 ATF_CHECK(code(pkt, 6, 6) == 0);
3654 ATF_CHECK(code(pkt, 7, 7) == 0);
3655 ATF_CHECK(code(pkt, 8, 8) == 0);
3656 ATF_CHECK(code(pkt, 9, 9) == 0);
3657 ATF_CHECK(code(pkt, 10, 10) == 0);
3658 ATF_CHECK(code(pkt, 11, 11) == 0);
3659 ATF_CHECK(code(pkt, 12, 12) == 0);
3660 ATF_CHECK(code(pkt, 13, 13) == 0);
3661 ATF_CHECK(code(pkt, 14, 14) == 0);
3662 ATF_CHECK(code(pkt, 15, 15) == 0);
3663 ATF_CHECK(code(pkt, 16, 16) == 0);
3664 ATF_CHECK(code(pkt, 17, 17) == 0);
3665 ATF_CHECK(code(pkt, 18, 18) == 0);
3666 ATF_CHECK(code(pkt, 19, 19) == 0);
3667 ATF_CHECK(code(pkt, 20, 20) == 0);
3668 ATF_CHECK(code(pkt, 21, 21) == 0);
3669 ATF_CHECK(code(pkt, 22, 22) == 0);
3670 ATF_CHECK(code(pkt, 23, 23) == 0);
3671 ATF_CHECK(code(pkt, 24, 24) == 0);
3672 ATF_CHECK(code(pkt, 25, 25) == 0);
3673 ATF_CHECK(code(pkt, 26, 26) == 0);
3674 ATF_CHECK(code(pkt, 27, 27) == 0);
3675 ATF_CHECK(code(pkt, 28, 28) == 0);
3676 ATF_CHECK(code(pkt, 29, 29) == 0);
3677 ATF_CHECK(code(pkt, 30, 30) == 0);
3678 ATF_CHECK(code(pkt, 31, 31) == 0);
3679 ATF_CHECK(code(pkt, 32, 32) == 0);
3680 ATF_CHECK(code(pkt, 33, 33) == 0);
3681
3682 /* Change the protocol field. */
3683 pkt[13] = 8;
3684 ATF_CHECK(code(pkt, 34, 34) == 0);
3685
3686 bpfjit_free_code(code);
3687 }
3688
3689 ATF_TC(bpfjit_examples_3);
3690 ATF_TC_HEAD(bpfjit_examples_3, tc)
3691 {
3692 atf_tc_set_md_var(tc, "descr",
3693 "Test the third example from bpf(4) - "
3694 "accept TCP finger packets");
3695 }
3696
3697 ATF_TC_BODY(bpfjit_examples_3, tc)
3698 {
3699 /*
3700 * This filter returns only TCP finger packets.
3701 */
3702 struct bpf_insn insns[] = {
3703 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3704 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 10),
3705 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
3706 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 8),
3707 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
3708 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
3709 BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
3710 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
3711 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0),
3712 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
3713 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
3714 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3715 BPF_STMT(BPF_RET+BPF_K, 0),
3716 };
3717
3718 bpfjit_func_t code;
3719 uint8_t pkt[30] = {};
3720
3721 /* Set IP fragment offset to non-zero. */
3722 pkt[20] = 1; pkt[21] = 1;
3723
3724 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3725
3726 ATF_CHECK(bpf_validate(insns, insn_count));
3727
3728 code = bpfjit_generate_code(bc, insns, insn_count);
3729 ATF_REQUIRE(code != NULL);
3730
3731 /* Packet is too short. */
3732 ATF_CHECK(code(pkt, 1, 1) == 0);
3733 ATF_CHECK(code(pkt, 2, 2) == 0);
3734 ATF_CHECK(code(pkt, 3, 3) == 0);
3735 ATF_CHECK(code(pkt, 4, 4) == 0);
3736 ATF_CHECK(code(pkt, 5, 5) == 0);
3737 ATF_CHECK(code(pkt, 6, 6) == 0);
3738 ATF_CHECK(code(pkt, 7, 7) == 0);
3739 ATF_CHECK(code(pkt, 8, 8) == 0);
3740 ATF_CHECK(code(pkt, 9, 9) == 0);
3741 ATF_CHECK(code(pkt, 10, 10) == 0);
3742 ATF_CHECK(code(pkt, 11, 11) == 0);
3743 ATF_CHECK(code(pkt, 12, 12) == 0);
3744 ATF_CHECK(code(pkt, 13, 13) == 0);
3745 ATF_CHECK(code(pkt, 14, 14) == 0);
3746 ATF_CHECK(code(pkt, 15, 15) == 0);
3747 ATF_CHECK(code(pkt, 16, 16) == 0);
3748 ATF_CHECK(code(pkt, 17, 17) == 0);
3749 ATF_CHECK(code(pkt, 18, 18) == 0);
3750 ATF_CHECK(code(pkt, 19, 19) == 0);
3751 ATF_CHECK(code(pkt, 20, 20) == 0);
3752 ATF_CHECK(code(pkt, 21, 21) == 0);
3753 ATF_CHECK(code(pkt, 22, 22) == 0);
3754 ATF_CHECK(code(pkt, 23, 23) == 0);
3755 ATF_CHECK(code(pkt, 24, 24) == 0);
3756 ATF_CHECK(code(pkt, 25, 25) == 0);
3757 ATF_CHECK(code(pkt, 26, 26) == 0);
3758 ATF_CHECK(code(pkt, 27, 27) == 0);
3759 ATF_CHECK(code(pkt, 28, 28) == 0);
3760 ATF_CHECK(code(pkt, 29, 29) == 0);
3761
3762 /* The packet doesn't match. */
3763 ATF_CHECK(code(pkt, 30, 30) == 0);
3764
3765 /* Still no match after setting the protocol field. */
3766 pkt[12] = 8;
3767 ATF_CHECK(code(pkt, 30, 30) == 0);
3768
3769 /* Get one step closer to the match. */
3770 pkt[23] = 6;
3771 ATF_CHECK(code(pkt, 30, 30) == 0);
3772
3773 /* Set IP fragment offset to zero. */
3774 pkt[20] = 0x20; pkt[21] = 0;
3775 ATF_CHECK(code(pkt, 30, 30) == 0);
3776
3777 /* Set IP header length to 12. */
3778 pkt[14] = 0xd3;
3779 ATF_CHECK(code(pkt, 30, 30) == 0);
3780
3781 /* Match one branch of the program. */
3782 pkt[27] = 79;
3783 ATF_CHECK(code(pkt, 30, 30) == UINT32_MAX);
3784
3785 /* Match the other branch of the program. */
3786 pkt[29] = 79; pkt[27] = 0;
3787 ATF_CHECK(code(pkt, 30, 30) == UINT32_MAX);
3788
3789 /* Packet is too short. */
3790 ATF_CHECK(code(pkt, 1, 1) == 0);
3791 ATF_CHECK(code(pkt, 2, 2) == 0);
3792 ATF_CHECK(code(pkt, 3, 3) == 0);
3793 ATF_CHECK(code(pkt, 4, 4) == 0);
3794 ATF_CHECK(code(pkt, 5, 5) == 0);
3795 ATF_CHECK(code(pkt, 6, 6) == 0);
3796 ATF_CHECK(code(pkt, 7, 7) == 0);
3797 ATF_CHECK(code(pkt, 8, 8) == 0);
3798 ATF_CHECK(code(pkt, 9, 9) == 0);
3799 ATF_CHECK(code(pkt, 10, 10) == 0);
3800 ATF_CHECK(code(pkt, 11, 11) == 0);
3801 ATF_CHECK(code(pkt, 12, 12) == 0);
3802 ATF_CHECK(code(pkt, 13, 13) == 0);
3803 ATF_CHECK(code(pkt, 14, 14) == 0);
3804 ATF_CHECK(code(pkt, 15, 15) == 0);
3805 ATF_CHECK(code(pkt, 16, 16) == 0);
3806 ATF_CHECK(code(pkt, 17, 17) == 0);
3807 ATF_CHECK(code(pkt, 18, 18) == 0);
3808 ATF_CHECK(code(pkt, 19, 19) == 0);
3809 ATF_CHECK(code(pkt, 20, 20) == 0);
3810 ATF_CHECK(code(pkt, 21, 21) == 0);
3811 ATF_CHECK(code(pkt, 22, 22) == 0);
3812 ATF_CHECK(code(pkt, 23, 23) == 0);
3813 ATF_CHECK(code(pkt, 24, 24) == 0);
3814 ATF_CHECK(code(pkt, 25, 25) == 0);
3815 ATF_CHECK(code(pkt, 26, 26) == 0);
3816 ATF_CHECK(code(pkt, 27, 27) == 0);
3817 ATF_CHECK(code(pkt, 28, 28) == 0);
3818 ATF_CHECK(code(pkt, 29, 29) == 0);
3819
3820 /* Set IP header length to 16. Packet is too short. */
3821 pkt[14] = 4;
3822 ATF_CHECK(code(pkt, 30, 30) == 0);
3823
3824 bpfjit_free_code(code);
3825 }
3826
3827 ATF_TP_ADD_TCS(tp)
3828 {
3829
3830 ATF_TP_ADD_TC(tp, bpfjit_empty);
3831 ATF_TP_ADD_TC(tp, bpfjit_alu_add_k);
3832 ATF_TP_ADD_TC(tp, bpfjit_alu_sub_k);
3833 ATF_TP_ADD_TC(tp, bpfjit_alu_mul_k);
3834 ATF_TP_ADD_TC(tp, bpfjit_alu_div0_k);
3835 ATF_TP_ADD_TC(tp, bpfjit_alu_div1_k);
3836 ATF_TP_ADD_TC(tp, bpfjit_alu_div2_k);
3837 ATF_TP_ADD_TC(tp, bpfjit_alu_div4_k);
3838 ATF_TP_ADD_TC(tp, bpfjit_alu_div10_k);
3839 ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_k);
3840 ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_k);
3841 ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_k);
3842 ATF_TP_ADD_TC(tp, bpfjit_alu_and_k);
3843 ATF_TP_ADD_TC(tp, bpfjit_alu_or_k);
3844 ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_k);
3845 ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_k);
3846 ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_k);
3847 ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_k);
3848 ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_k);
3849 ATF_TP_ADD_TC(tp, bpfjit_alu_add_x);
3850 ATF_TP_ADD_TC(tp, bpfjit_alu_sub_x);
3851 ATF_TP_ADD_TC(tp, bpfjit_alu_mul_x);
3852 ATF_TP_ADD_TC(tp, bpfjit_alu_div0_x);
3853 ATF_TP_ADD_TC(tp, bpfjit_alu_div1_x);
3854 ATF_TP_ADD_TC(tp, bpfjit_alu_div2_x);
3855 ATF_TP_ADD_TC(tp, bpfjit_alu_div4_x);
3856 ATF_TP_ADD_TC(tp, bpfjit_alu_div10_x);
3857 ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_x);
3858 ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_x);
3859 ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_x);
3860 ATF_TP_ADD_TC(tp, bpfjit_alu_and_x);
3861 ATF_TP_ADD_TC(tp, bpfjit_alu_or_x);
3862 ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_x);
3863 ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_x);
3864 ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_x);
3865 ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_x);
3866 ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_x);
3867 ATF_TP_ADD_TC(tp, bpfjit_alu_neg);
3868 ATF_TP_ADD_TC(tp, bpfjit_jmp_ja);
3869 ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_k);
3870 ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_k);
3871 ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_k);
3872 ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_k);
3873 ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_k);
3874 ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_x);
3875 ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_x);
3876 ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x);
3877 ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_x);
3878 ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_x);
3879 ATF_TP_ADD_TC(tp, bpfjit_ld_abs);
3880 ATF_TP_ADD_TC(tp, bpfjit_ld_abs_k_overflow);
3881 ATF_TP_ADD_TC(tp, bpfjit_ld_ind);
3882 ATF_TP_ADD_TC(tp, bpfjit_ld_ind_k_overflow);
3883 ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow1);
3884 ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow2);
3885 ATF_TP_ADD_TC(tp, bpfjit_ld_len);
3886 ATF_TP_ADD_TC(tp, bpfjit_ld_imm);
3887 ATF_TP_ADD_TC(tp, bpfjit_ldx_imm1);
3888 ATF_TP_ADD_TC(tp, bpfjit_ldx_imm2);
3889 ATF_TP_ADD_TC(tp, bpfjit_ldx_len1);
3890 ATF_TP_ADD_TC(tp, bpfjit_ldx_len2);
3891 ATF_TP_ADD_TC(tp, bpfjit_ldx_msh);
3892 ATF_TP_ADD_TC(tp, bpfjit_misc_tax);
3893 ATF_TP_ADD_TC(tp, bpfjit_misc_txa);
3894 ATF_TP_ADD_TC(tp, bpfjit_st1);
3895 ATF_TP_ADD_TC(tp, bpfjit_st2);
3896 ATF_TP_ADD_TC(tp, bpfjit_st3);
3897 ATF_TP_ADD_TC(tp, bpfjit_st4);
3898 ATF_TP_ADD_TC(tp, bpfjit_st5);
3899 ATF_TP_ADD_TC(tp, bpfjit_stx1);
3900 ATF_TP_ADD_TC(tp, bpfjit_stx2);
3901 ATF_TP_ADD_TC(tp, bpfjit_stx3);
3902 ATF_TP_ADD_TC(tp, bpfjit_stx4);
3903 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_1);
3904 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_2);
3905 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_3);
3906 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_1);
3907 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_2);
3908 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_3);
3909 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_4);
3910 ATF_TP_ADD_TC(tp, bpfjit_abc_ja);
3911 ATF_TP_ADD_TC(tp, bpfjit_abc_ja_over);
3912 ATF_TP_ADD_TC(tp, bpfjit_abc_ld_chain);
3913 ATF_TP_ADD_TC(tp, bpfjit_examples_1);
3914 ATF_TP_ADD_TC(tp, bpfjit_examples_2);
3915 ATF_TP_ADD_TC(tp, bpfjit_examples_3);
3916
3917 return atf_no_error();
3918 }
3919