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