]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/netbsd-tests/net/bpfjit/t_bpfjit.c
MFC r314450,r313439:
[FreeBSD/stable/10.git] / contrib / netbsd-tests / net / bpfjit / t_bpfjit.c
1 /*      $NetBSD: t_bpfjit.c,v 1.12 2017/01/13 21:30:42 christos Exp $ */
2
3 /*-
4  * Copyright (c) 2011-2012, 2014-2015 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.12 2017/01/13 21:30:42 christos 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_ja_overflow);
1704 ATF_TC_HEAD(bpfjit_jmp_ja_overflow, tc)
1705 {
1706         atf_tc_set_md_var(tc, "descr",
1707             "Test BPF_JMP+BPF_JA with negative offset");
1708 }
1709
1710 ATF_TC_BODY(bpfjit_jmp_ja_overflow, tc)
1711 {
1712         static struct bpf_insn insns[] = {
1713                 BPF_STMT(BPF_JMP+BPF_JA, 1),
1714                 BPF_STMT(BPF_RET+BPF_K, 777),
1715                 BPF_STMT(BPF_JMP+BPF_JA, UINT32_MAX - 1), // -2
1716                 BPF_STMT(BPF_RET+BPF_K, 0)
1717         };
1718
1719         bpfjit_func_t code;
1720         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1721
1722         RZ(rump_init());
1723
1724         /* Jumps with negative offsets work only in userspace. */
1725         ATF_CHECK(!prog_validate(insns, insn_count));
1726
1727         rump_schedule();
1728         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1729         rump_unschedule();
1730         ATF_CHECK(code == NULL);
1731 }
1732
1733 ATF_TC(bpfjit_jmp_jgt_k);
1734 ATF_TC_HEAD(bpfjit_jmp_jgt_k, tc)
1735 {
1736         atf_tc_set_md_var(tc, "descr",
1737             "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_K");
1738 }
1739
1740 ATF_TC_BODY(bpfjit_jmp_jgt_k, tc)
1741 {
1742         static struct bpf_insn insns[] = {
1743                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1744                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 7, 0, 1),
1745                 BPF_STMT(BPF_RET+BPF_K, 0),
1746                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 2, 2, 0),
1747                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 9, 0, 0),
1748                 BPF_STMT(BPF_RET+BPF_K, 1),
1749                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 4, 1, 1),
1750                 BPF_STMT(BPF_RET+BPF_K, 2),
1751                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 2, 3),
1752                 BPF_STMT(BPF_RET+BPF_K, 3),
1753                 BPF_STMT(BPF_RET+BPF_K, 4),
1754                 BPF_STMT(BPF_RET+BPF_K, 5),
1755                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 5, 3, 1),
1756                 BPF_STMT(BPF_RET+BPF_K, 6),
1757                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 0, 0, 0),
1758                 BPF_STMT(BPF_RET+BPF_K, 7),
1759                 BPF_STMT(BPF_RET+BPF_K, 8)
1760         };
1761
1762         bpfjit_func_t code;
1763         uint8_t pkt[8]; /* the program doesn't read any data */
1764
1765         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1766
1767         RZ(rump_init());
1768
1769         ATF_CHECK(prog_validate(insns, insn_count));
1770
1771         rump_schedule();
1772         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1773         rump_unschedule();
1774         ATF_REQUIRE(code != NULL);
1775
1776         ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
1777         ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
1778         ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
1779         ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1780         ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
1781         ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1782         ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1783         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1784
1785         rump_schedule();
1786         rumpns_bpfjit_free_code(code);
1787         rump_unschedule();
1788 }
1789
1790 ATF_TC(bpfjit_jmp_jge_k);
1791 ATF_TC_HEAD(bpfjit_jmp_jge_k, tc)
1792 {
1793         atf_tc_set_md_var(tc, "descr",
1794             "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_K");
1795 }
1796
1797 ATF_TC_BODY(bpfjit_jmp_jge_k, tc)
1798 {
1799         static struct bpf_insn insns[] = {
1800                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1801                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 8, 0, 1),
1802                 BPF_STMT(BPF_RET+BPF_K, 0),
1803                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 3, 2, 0),
1804                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 9, 0, 0),
1805                 BPF_STMT(BPF_RET+BPF_K, 1),
1806                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 5, 1, 1),
1807                 BPF_STMT(BPF_RET+BPF_K, 2),
1808                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 2, 3),
1809                 BPF_STMT(BPF_RET+BPF_K, 3),
1810                 BPF_STMT(BPF_RET+BPF_K, 4),
1811                 BPF_STMT(BPF_RET+BPF_K, 5),
1812                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 6, 3, 1),
1813                 BPF_STMT(BPF_RET+BPF_K, 6),
1814                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 1, 0, 0),
1815                 BPF_STMT(BPF_RET+BPF_K, 7),
1816                 BPF_STMT(BPF_RET+BPF_K, 8)
1817         };
1818
1819         bpfjit_func_t code;
1820         uint8_t pkt[8]; /* the program doesn't read any data */
1821
1822         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1823
1824         RZ(rump_init());
1825
1826         ATF_CHECK(prog_validate(insns, insn_count));
1827
1828         rump_schedule();
1829         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1830         rump_unschedule();
1831         ATF_REQUIRE(code != NULL);
1832
1833         ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
1834         ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
1835         ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
1836         ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1837         ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
1838         ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1839         ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1840         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1841
1842         rump_schedule();
1843         rumpns_bpfjit_free_code(code);
1844         rump_unschedule();
1845 }
1846
1847 ATF_TC(bpfjit_jmp_jeq_k);
1848 ATF_TC_HEAD(bpfjit_jmp_jeq_k, tc)
1849 {
1850         atf_tc_set_md_var(tc, "descr",
1851             "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_K");
1852 }
1853
1854 ATF_TC_BODY(bpfjit_jmp_jeq_k, tc)
1855 {
1856         static struct bpf_insn insns[] = {
1857                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1858                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 1),
1859                 BPF_STMT(BPF_RET+BPF_K, 0),
1860                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 1, 0),
1861                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 1, 1),
1862                 BPF_STMT(BPF_RET+BPF_K, 1),
1863                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 5, 1, 1),
1864                 BPF_STMT(BPF_RET+BPF_K, 2),
1865                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 7, 2, 3),
1866                 BPF_STMT(BPF_RET+BPF_K, 3),
1867                 BPF_STMT(BPF_RET+BPF_K, 4),
1868                 BPF_STMT(BPF_RET+BPF_K, 5),
1869                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 3, 1),
1870                 BPF_STMT(BPF_RET+BPF_K, 6),
1871                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 1, 0, 0),
1872                 BPF_STMT(BPF_RET+BPF_K, 7),
1873                 BPF_STMT(BPF_RET+BPF_K, 8)
1874         };
1875
1876         bpfjit_func_t code;
1877         uint8_t pkt[8]; /* the program doesn't read any data */
1878
1879         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1880
1881         RZ(rump_init());
1882
1883         ATF_CHECK(prog_validate(insns, insn_count));
1884
1885         rump_schedule();
1886         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1887         rump_unschedule();
1888         ATF_REQUIRE(code != NULL);
1889
1890         ATF_CHECK(jitcall(code, pkt, 1, 1) == 7);
1891         ATF_CHECK(jitcall(code, pkt, 2, 2) == 7);
1892         ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
1893         ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1894         ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
1895         ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1896         ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1897         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1898
1899         rump_schedule();
1900         rumpns_bpfjit_free_code(code);
1901         rump_unschedule();
1902 }
1903
1904 ATF_TC(bpfjit_jmp_jset_k);
1905 ATF_TC_HEAD(bpfjit_jmp_jset_k, tc)
1906 {
1907         atf_tc_set_md_var(tc, "descr",
1908             "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_K");
1909 }
1910
1911 ATF_TC_BODY(bpfjit_jmp_jset_k, tc)
1912 {
1913         static struct bpf_insn insns[] = {
1914                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1915                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 8, 0, 1),
1916                 BPF_STMT(BPF_RET+BPF_K, 0),
1917                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 4, 2, 0),
1918                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 3, 0, 0),
1919                 BPF_STMT(BPF_RET+BPF_K, 1),
1920                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 1, 1),
1921                 BPF_STMT(BPF_RET+BPF_K, 2),
1922                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 1, 2, 3),
1923                 BPF_STMT(BPF_RET+BPF_K, 3),
1924                 BPF_STMT(BPF_RET+BPF_K, 4),
1925                 BPF_STMT(BPF_RET+BPF_K, 5),
1926                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 3, 1),
1927                 BPF_STMT(BPF_RET+BPF_K, 6),
1928                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 7, 0, 0),
1929                 BPF_STMT(BPF_RET+BPF_K, 7),
1930                 BPF_STMT(BPF_RET+BPF_K, 8)
1931         };
1932
1933         bpfjit_func_t code;
1934         uint8_t pkt[8]; /* the program doesn't read any data */
1935
1936         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1937
1938         RZ(rump_init());
1939
1940         ATF_CHECK(prog_validate(insns, insn_count));
1941
1942         rump_schedule();
1943         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1944         rump_unschedule();
1945         ATF_REQUIRE(code != NULL);
1946
1947         ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
1948         ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
1949         ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
1950         ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1951         ATF_CHECK(jitcall(code, pkt, 5, 5) == 5);
1952         ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1953         ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1954         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1955
1956         rump_schedule();
1957         rumpns_bpfjit_free_code(code);
1958         rump_unschedule();
1959 }
1960
1961 ATF_TC(bpfjit_jmp_modulo_k);
1962 ATF_TC_HEAD(bpfjit_jmp_modulo_k, tc)
1963 {
1964         atf_tc_set_md_var(tc, "descr",
1965             "Test JIT compilation of modulo logic of BPF_JMP+BPF_K operations");
1966 }
1967
1968 ATF_TC_BODY(bpfjit_jmp_modulo_k, tc)
1969 {
1970         static struct bpf_insn insns[] = {
1971                 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
1972                 BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4),
1973                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 1, 0),
1974                 BPF_STMT(BPF_RET+BPF_K, 0),
1975                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 0, 1),
1976                 BPF_STMT(BPF_RET+BPF_K, 1),
1977                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 0, 1),
1978                 BPF_STMT(BPF_RET+BPF_K, 2),
1979                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 0, 3),
1980                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 2, 0),
1981                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 1, 0),
1982                 BPF_STMT(BPF_JMP+BPF_JA, 1),
1983                 BPF_STMT(BPF_RET+BPF_K, 3),
1984
1985                 /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */
1986                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)),
1987
1988                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 1, 0),
1989                 BPF_STMT(BPF_RET+BPF_K, 4),
1990                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 0, 1),
1991                 BPF_STMT(BPF_RET+BPF_K, 5),
1992                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 0, 1),
1993                 BPF_STMT(BPF_RET+BPF_K, 6),
1994                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 0, 3),
1995                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 2, 0),
1996                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 1, 0),
1997                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
1998                 BPF_STMT(BPF_RET+BPF_K, 7)
1999         };
2000
2001         uint8_t pkt[1]; /* the program doesn't read any data */
2002
2003         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2004
2005         RZ(rump_init());
2006
2007         ATF_CHECK(prog_validate(insns, insn_count));
2008         ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
2009 }
2010
2011 ATF_TC(bpfjit_jmp_jgt_x);
2012 ATF_TC_HEAD(bpfjit_jmp_jgt_x, tc)
2013 {
2014         atf_tc_set_md_var(tc, "descr",
2015             "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_X");
2016 }
2017
2018 ATF_TC_BODY(bpfjit_jmp_jgt_x, tc)
2019 {
2020         static struct bpf_insn insns[] = {
2021                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2022                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
2023                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
2024                 BPF_STMT(BPF_RET+BPF_K, 0),
2025                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
2026                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
2027                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
2028                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0),
2029                 BPF_STMT(BPF_RET+BPF_K, 1),
2030                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
2031                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 1, 1),
2032                 BPF_STMT(BPF_RET+BPF_K, 2),
2033                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
2034                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 2, 3),
2035                 BPF_STMT(BPF_RET+BPF_K, 3),
2036                 BPF_STMT(BPF_RET+BPF_K, 4),
2037                 BPF_STMT(BPF_RET+BPF_K, 5),
2038                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2039                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 4, 1),
2040                 BPF_STMT(BPF_RET+BPF_K, 6),
2041                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
2042                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0),
2043                 BPF_STMT(BPF_RET+BPF_K, 7),
2044                 BPF_STMT(BPF_RET+BPF_K, 8)
2045         };
2046
2047         bpfjit_func_t code;
2048         uint8_t pkt[8]; /* the program doesn't read any data */
2049
2050         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2051
2052         RZ(rump_init());
2053
2054         ATF_CHECK(prog_validate(insns, insn_count));
2055
2056         rump_schedule();
2057         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2058         rump_unschedule();
2059         ATF_REQUIRE(code != NULL);
2060
2061         ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
2062         ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
2063         ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
2064         ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
2065         ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
2066         ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
2067         ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
2068         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
2069
2070         rump_schedule();
2071         rumpns_bpfjit_free_code(code);
2072         rump_unschedule();
2073 }
2074
2075 ATF_TC(bpfjit_jmp_jge_x);
2076 ATF_TC_HEAD(bpfjit_jmp_jge_x, tc)
2077 {
2078         atf_tc_set_md_var(tc, "descr",
2079             "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_X");
2080 }
2081
2082 ATF_TC_BODY(bpfjit_jmp_jge_x, tc)
2083 {
2084         static struct bpf_insn insns[] = {
2085                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2086                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
2087                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
2088                 BPF_STMT(BPF_RET+BPF_K, 0),
2089                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2090                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 3, 0),
2091                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
2092                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0),
2093                 BPF_STMT(BPF_RET+BPF_K, 1),
2094                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2095                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 1),
2096                 BPF_STMT(BPF_RET+BPF_K, 2),
2097                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
2098                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 2, 3),
2099                 BPF_STMT(BPF_RET+BPF_K, 3),
2100                 BPF_STMT(BPF_RET+BPF_K, 4),
2101                 BPF_STMT(BPF_RET+BPF_K, 5),
2102                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
2103                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 4, 1),
2104                 BPF_STMT(BPF_RET+BPF_K, 6),
2105                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
2106                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0),
2107                 BPF_STMT(BPF_RET+BPF_K, 7),
2108                 BPF_STMT(BPF_RET+BPF_K, 8)
2109         };
2110
2111         bpfjit_func_t code;
2112         uint8_t pkt[8]; /* the program doesn't read any data */
2113
2114         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2115
2116         RZ(rump_init());
2117
2118         ATF_CHECK(prog_validate(insns, insn_count));
2119
2120         rump_schedule();
2121         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2122         rump_unschedule();
2123         ATF_REQUIRE(code != NULL);
2124
2125         ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
2126         ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
2127         ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
2128         ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
2129         ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
2130         ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
2131         ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
2132         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
2133
2134         rump_schedule();
2135         rumpns_bpfjit_free_code(code);
2136         rump_unschedule();
2137 }
2138
2139 ATF_TC(bpfjit_jmp_jeq_x);
2140 ATF_TC_HEAD(bpfjit_jmp_jeq_x, tc)
2141 {
2142         atf_tc_set_md_var(tc, "descr",
2143             "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_X");
2144 }
2145
2146 ATF_TC_BODY(bpfjit_jmp_jeq_x, tc)
2147 {
2148         static struct bpf_insn insns[] = {
2149                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2150                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
2151                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
2152                 BPF_STMT(BPF_RET+BPF_K, 1),
2153                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2154                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 0),
2155                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
2156                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
2157                 BPF_STMT(BPF_RET+BPF_K, 2),
2158                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2159                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
2160                 BPF_STMT(BPF_RET+BPF_K, 3),
2161                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
2162                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 3),
2163                 BPF_STMT(BPF_RET+BPF_K, 4),
2164                 BPF_STMT(BPF_RET+BPF_K, 5),
2165                 BPF_STMT(BPF_RET+BPF_K, 6),
2166                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
2167                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 3, 1),
2168                 BPF_STMT(BPF_RET+BPF_K, 7),
2169                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2170                 BPF_STMT(BPF_RET+BPF_K, 8),
2171                 BPF_STMT(BPF_RET+BPF_K, 9)
2172         };
2173
2174         bpfjit_func_t code;
2175         uint8_t pkt[8]; /* the program doesn't read any data */
2176
2177         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2178
2179         RZ(rump_init());
2180
2181         ATF_CHECK(prog_validate(insns, insn_count));
2182
2183         rump_schedule();
2184         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2185         rump_unschedule();
2186         ATF_REQUIRE(code != NULL);
2187
2188         ATF_CHECK(jitcall(code, pkt, 1, 1) == 8);
2189         ATF_CHECK(jitcall(code, pkt, 2, 2) == 8);
2190         ATF_CHECK(jitcall(code, pkt, 3, 3) == 2);
2191         ATF_CHECK(jitcall(code, pkt, 4, 4) == 8);
2192         ATF_CHECK(jitcall(code, pkt, 5, 5) == 3);
2193         ATF_CHECK(jitcall(code, pkt, 6, 6) == 9);
2194         ATF_CHECK(jitcall(code, pkt, 7, 7) == 6);
2195         ATF_CHECK(jitcall(code, pkt, 8, 8) == 1);
2196
2197         rump_schedule();
2198         rumpns_bpfjit_free_code(code);
2199         rump_unschedule();
2200 }
2201
2202 ATF_TC(bpfjit_jmp_jset_x);
2203 ATF_TC_HEAD(bpfjit_jmp_jset_x, tc)
2204 {
2205         atf_tc_set_md_var(tc, "descr",
2206             "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_X");
2207 }
2208
2209 ATF_TC_BODY(bpfjit_jmp_jset_x, tc)
2210 {
2211         static struct bpf_insn insns[] = {
2212                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2213                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
2214                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 1),
2215                 BPF_STMT(BPF_RET+BPF_K, 0),
2216                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
2217                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 0),
2218                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 3, 0, 0),
2219                 BPF_STMT(BPF_RET+BPF_K, 1),
2220                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
2221                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 1, 1),
2222                 BPF_STMT(BPF_RET+BPF_K, 2),
2223                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
2224                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 3),
2225                 BPF_STMT(BPF_RET+BPF_K, 3),
2226                 BPF_STMT(BPF_RET+BPF_K, 4),
2227                 BPF_STMT(BPF_RET+BPF_K, 5),
2228                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
2229                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 4, 1),
2230                 BPF_STMT(BPF_RET+BPF_K, 6),
2231                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
2232                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 0),
2233                 BPF_STMT(BPF_RET+BPF_K, 7),
2234                 BPF_STMT(BPF_RET+BPF_K, 8)
2235         };
2236
2237         bpfjit_func_t code;
2238         uint8_t pkt[8]; /* the program doesn't read any data */
2239
2240         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2241
2242         RZ(rump_init());
2243
2244         ATF_CHECK(prog_validate(insns, insn_count));
2245
2246         rump_schedule();
2247         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2248         rump_unschedule();
2249         ATF_REQUIRE(code != NULL);
2250
2251         ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
2252         ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
2253         ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
2254         ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
2255         ATF_CHECK(jitcall(code, pkt, 5, 5) == 5);
2256         ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
2257         ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
2258         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
2259
2260         rump_schedule();
2261         rumpns_bpfjit_free_code(code);
2262         rump_unschedule();
2263 }
2264
2265 ATF_TC(bpfjit_jmp_jeq_x_noinit_ax);
2266 ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_ax, tc)
2267 {
2268         atf_tc_set_md_var(tc, "descr", "Test JIT compilation "
2269             "of BPF_JMP+BPF_EQ+BPF_X with uninitialised A and X");
2270 }
2271
2272 ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_ax, tc)
2273 {
2274         static struct bpf_insn insns[] = {
2275                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
2276                 BPF_STMT(BPF_RET+BPF_K, 10),
2277                 BPF_STMT(BPF_RET+BPF_K, 11)
2278         };
2279
2280         bpfjit_func_t code;
2281         uint8_t pkt[8]; /* the program doesn't read any data */
2282
2283         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2284
2285         RZ(rump_init());
2286
2287         ATF_CHECK(prog_validate(insns, insn_count));
2288
2289         rump_schedule();
2290         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2291         rump_unschedule();
2292         ATF_REQUIRE(code != NULL);
2293
2294         ATF_CHECK(jitcall(code, pkt, 1, 1) == 10);
2295
2296         rump_schedule();
2297         rumpns_bpfjit_free_code(code);
2298         rump_unschedule();
2299 }
2300
2301 ATF_TC(bpfjit_jmp_jeq_x_noinit_a);
2302 ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_a, tc)
2303 {
2304         atf_tc_set_md_var(tc, "descr", "Test JIT compilation "
2305             "of BPF_JMP+BPF_EQ+BPF_X with uninitialised A");
2306 }
2307
2308 ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_a, tc)
2309 {
2310         static struct bpf_insn insns[] = {
2311                 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), /* X > 0 */
2312                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
2313                 BPF_STMT(BPF_RET+BPF_K, 10),
2314                 BPF_STMT(BPF_RET+BPF_K, 11)
2315         };
2316
2317         bpfjit_func_t code;
2318         uint8_t pkt[8]; /* the program doesn't read any data */
2319
2320         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2321
2322         RZ(rump_init());
2323
2324         ATF_CHECK(prog_validate(insns, insn_count));
2325
2326         rump_schedule();
2327         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2328         rump_unschedule();
2329         ATF_REQUIRE(code != NULL);
2330
2331         ATF_CHECK(jitcall(code, pkt, 1, 1) == 11);
2332
2333         rump_schedule();
2334         rumpns_bpfjit_free_code(code);
2335         rump_unschedule();
2336 }
2337
2338 ATF_TC(bpfjit_jmp_jeq_x_noinit_x);
2339 ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_x, tc)
2340 {
2341         atf_tc_set_md_var(tc, "descr", "Test JIT compilation "
2342             "of BPF_JMP+BPF_EQ+BPF_X with uninitialised X");
2343 }
2344
2345 ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_x, tc)
2346 {
2347         static struct bpf_insn insns[] = {
2348                 BPF_STMT(BPF_LD+BPF_LEN, 0), /* A > 0 */
2349                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
2350                 BPF_STMT(BPF_RET+BPF_K, 10),
2351                 BPF_STMT(BPF_RET+BPF_K, 11)
2352         };
2353
2354         bpfjit_func_t code;
2355         uint8_t pkt[8]; /* the program doesn't read any data */
2356
2357         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2358
2359         RZ(rump_init());
2360
2361         ATF_CHECK(prog_validate(insns, insn_count));
2362
2363         rump_schedule();
2364         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2365         rump_unschedule();
2366         ATF_REQUIRE(code != NULL);
2367
2368         ATF_CHECK(jitcall(code, pkt, 1, 1) == 11);
2369
2370         rump_schedule();
2371         rumpns_bpfjit_free_code(code);
2372         rump_unschedule();
2373 }
2374
2375 ATF_TC(bpfjit_jmp_modulo_x);
2376 ATF_TC_HEAD(bpfjit_jmp_modulo_x, tc)
2377 {
2378         atf_tc_set_md_var(tc, "descr",
2379             "Test JIT compilation of modulo logic of BPF_JMP+BPF_X operations");
2380 }
2381
2382 ATF_TC_BODY(bpfjit_jmp_modulo_x, tc)
2383 {
2384         static struct bpf_insn insns[] = {
2385                 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
2386                 /* FFFFF770 << 4 = FFFFF770 */
2387                 BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4),
2388
2389                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
2390                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2391                 BPF_STMT(BPF_RET+BPF_K, 0),
2392                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
2393                 BPF_STMT(BPF_RET+BPF_K, 1),
2394                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
2395                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
2396                 BPF_STMT(BPF_RET+BPF_K, 2),
2397                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
2398                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
2399                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
2400                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
2401                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
2402                 BPF_STMT(BPF_JMP+BPF_JA, 1),
2403                 BPF_STMT(BPF_RET+BPF_K, 3),
2404
2405                 /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */
2406                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)),
2407
2408                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
2409                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2410                 BPF_STMT(BPF_RET+BPF_K, 4),
2411                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
2412                 BPF_STMT(BPF_RET+BPF_K, 5),
2413                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
2414                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
2415                 BPF_STMT(BPF_RET+BPF_K, 6),
2416                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
2417                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
2418                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
2419                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
2420                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
2421                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
2422                 BPF_STMT(BPF_RET+BPF_K, 7)
2423         };
2424
2425         uint8_t pkt[1]; /* the program doesn't read any data */
2426
2427         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2428
2429         RZ(rump_init());
2430
2431         ATF_CHECK(prog_validate(insns, insn_count));
2432         ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
2433 }
2434
2435 ATF_TC(bpfjit_ld_abs);
2436 ATF_TC_HEAD(bpfjit_ld_abs, tc)
2437 {
2438         atf_tc_set_md_var(tc, "descr",
2439             "Test JIT compilation of BPF_LD+BPF_ABS");
2440 }
2441
2442 ATF_TC_BODY(bpfjit_ld_abs, tc)
2443 {
2444         static struct bpf_insn insns[3][2] = {
2445                 {
2446                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
2447                         BPF_STMT(BPF_RET+BPF_A, 0)
2448                 },
2449                 {
2450                         BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 5),
2451                         BPF_STMT(BPF_RET+BPF_A, 0)
2452                 },
2453                 {
2454                         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 5),
2455                         BPF_STMT(BPF_RET+BPF_A, 0)
2456                 }
2457         };
2458
2459         static size_t lengths[3] = { 1, 2, 4 };
2460         static unsigned int expected[3] = { 0xde, 0xdead, 0xdeadbeef };
2461
2462         size_t i, l;
2463         uint8_t *pkt = deadbeef_at_5;
2464         size_t pktsize = sizeof(deadbeef_at_5);
2465
2466         size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2467
2468         RZ(rump_init());
2469
2470         for (i = 0; i < 3; i++) {
2471                 bpfjit_func_t code;
2472
2473                 ATF_CHECK(prog_validate(insns[i], insn_count));
2474
2475                 rump_schedule();
2476                 code = rumpns_bpfjit_generate_code(NULL, insns[i], insn_count);
2477                 rump_unschedule();
2478                 ATF_REQUIRE(code != NULL);
2479
2480                 for (l = 1; l < 5 + lengths[i]; l++) {
2481                         ATF_CHECK(jitcall(code, pkt, l, l) == 0);
2482                         ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0);
2483                 }
2484
2485                 l = 5 + lengths[i];
2486                 ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
2487                 ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]);
2488
2489                 l = pktsize;
2490                 ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
2491
2492                 rump_schedule();
2493                 rumpns_bpfjit_free_code(code);
2494                 rump_unschedule();
2495         }
2496 }
2497
2498 ATF_TC(bpfjit_ld_abs_k_overflow);
2499 ATF_TC_HEAD(bpfjit_ld_abs_k_overflow, tc)
2500 {
2501         atf_tc_set_md_var(tc, "descr",
2502             "Test JIT compilation of BPF_LD+BPF_ABS with overflow in k+4");
2503 }
2504
2505 ATF_TC_BODY(bpfjit_ld_abs_k_overflow, tc)
2506 {
2507         static struct bpf_insn insns[12][3] = {
2508                 {
2509                         BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
2510                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2511                         BPF_STMT(BPF_RET+BPF_K, 1)
2512                 },
2513                 {
2514                         BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
2515                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2516                         BPF_STMT(BPF_RET+BPF_K, 1)
2517                 },
2518                 {
2519                         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
2520                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2521                         BPF_STMT(BPF_RET+BPF_K, 1)
2522                 },
2523                 {
2524                         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
2525                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2526                         BPF_STMT(BPF_RET+BPF_K, 1)
2527                 },
2528                 {
2529                         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
2530                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2531                         BPF_STMT(BPF_RET+BPF_K, 1)
2532                 },
2533                 {
2534                         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
2535                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2536                         BPF_STMT(BPF_RET+BPF_K, 1)
2537                 },
2538                 {
2539                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2540                         BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
2541                         BPF_STMT(BPF_RET+BPF_K, 1)
2542                 },
2543                 {
2544                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2545                         BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
2546                         BPF_STMT(BPF_RET+BPF_K, 1)
2547                 },
2548                 {
2549                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2550                         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
2551                         BPF_STMT(BPF_RET+BPF_K, 1)
2552                 },
2553                 {
2554                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2555                         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
2556                         BPF_STMT(BPF_RET+BPF_K, 1)
2557                 },
2558                 {
2559                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2560                         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
2561                         BPF_STMT(BPF_RET+BPF_K, 1)
2562                 },
2563                 {
2564                         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2565                         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
2566                         BPF_STMT(BPF_RET+BPF_K, 1)
2567                 }
2568         };
2569
2570         int i;
2571         uint8_t pkt[8] = { 0 };
2572
2573         size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2574
2575         RZ(rump_init());
2576
2577         for (i = 0; i < 3; i++) {
2578                 ATF_CHECK(prog_validate(insns[i], insn_count));
2579                 ATF_CHECK(exec_prog(insns[i], insn_count, pkt, 8) == 0);
2580         }
2581 }
2582
2583 ATF_TC(bpfjit_ld_ind);
2584 ATF_TC_HEAD(bpfjit_ld_ind, tc)
2585 {
2586         atf_tc_set_md_var(tc, "descr",
2587             "Test JIT compilation of BPF_LD+BPF_IND");
2588 }
2589
2590 ATF_TC_BODY(bpfjit_ld_ind, tc)
2591 {
2592         static struct bpf_insn insns[6][3] = {
2593                 {
2594                         BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2595                         BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
2596                         BPF_STMT(BPF_RET+BPF_A, 0)
2597                 },
2598                 {
2599                         BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2600                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2),
2601                         BPF_STMT(BPF_RET+BPF_A, 0)
2602                 },
2603                 {
2604                         BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2605                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2),
2606                         BPF_STMT(BPF_RET+BPF_A, 0)
2607                 },
2608                 {
2609                         BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2610                         BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2611                         BPF_STMT(BPF_RET+BPF_A, 0)
2612                 },
2613                 {
2614                         BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2615                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
2616                         BPF_STMT(BPF_RET+BPF_A, 0)
2617                 },
2618                 {
2619                         BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2620                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0),
2621                         BPF_STMT(BPF_RET+BPF_A, 0)
2622                 }
2623         };
2624
2625         static size_t lengths[6] = { 1, 2, 4, 1, 2, 4 };
2626
2627         static unsigned int expected[6] = {
2628                 0xde, 0xdead, 0xdeadbeef,
2629                 0xde, 0xdead, 0xdeadbeef
2630         };
2631
2632         size_t i, l;
2633         uint8_t *pkt = deadbeef_at_5;
2634         size_t pktsize = sizeof(deadbeef_at_5);
2635
2636         size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2637
2638         RZ(rump_init());
2639
2640         for (i = 0; i < 3; i++) {
2641                 bpfjit_func_t code;
2642
2643                 ATF_CHECK(prog_validate(insns[i], insn_count));
2644
2645                 rump_schedule();
2646                 code = rumpns_bpfjit_generate_code(NULL, insns[i], insn_count);
2647                 rump_unschedule();
2648                 ATF_REQUIRE(code != NULL);
2649
2650                 for (l = 1; l < 5 + lengths[i]; l++) {
2651                         ATF_CHECK(jitcall(code, pkt, l, l) == 0);
2652                         ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0);
2653                 }
2654
2655                 l = 5 + lengths[i];
2656                 ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
2657                 ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]);
2658
2659                 l = pktsize;
2660                 ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
2661
2662                 rump_schedule();
2663                 rumpns_bpfjit_free_code(code);
2664                 rump_unschedule();
2665         }
2666 }
2667
2668 ATF_TC(bpfjit_ld_ind_k_overflow);
2669 ATF_TC_HEAD(bpfjit_ld_ind_k_overflow, tc)
2670 {
2671         atf_tc_set_md_var(tc, "descr",
2672             "Test JIT compilation of BPF_LD+BPF_IND with overflow in k+4");
2673 }
2674
2675 ATF_TC_BODY(bpfjit_ld_ind_k_overflow, tc)
2676 {
2677         static struct bpf_insn insns[12][3] = {
2678                 {
2679                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
2680                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2681                         BPF_STMT(BPF_RET+BPF_K, 1)
2682                 },
2683                 {
2684                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
2685                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2686                         BPF_STMT(BPF_RET+BPF_K, 1)
2687                 },
2688                 {
2689                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
2690                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2691                         BPF_STMT(BPF_RET+BPF_K, 1)
2692                 },
2693                 {
2694                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
2695                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2696                         BPF_STMT(BPF_RET+BPF_K, 1)
2697                 },
2698                 {
2699                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
2700                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2701                         BPF_STMT(BPF_RET+BPF_K, 1)
2702                 },
2703                 {
2704                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
2705                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2706                         BPF_STMT(BPF_RET+BPF_K, 1)
2707                 },
2708                 {
2709                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2710                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
2711                         BPF_STMT(BPF_RET+BPF_K, 1)
2712                 },
2713                 {
2714                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2715                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
2716                         BPF_STMT(BPF_RET+BPF_K, 1)
2717                 },
2718                 {
2719                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2720                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
2721                         BPF_STMT(BPF_RET+BPF_K, 1)
2722                 },
2723                 {
2724                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2725                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
2726                         BPF_STMT(BPF_RET+BPF_K, 1)
2727                 },
2728                 {
2729                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2730                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
2731                         BPF_STMT(BPF_RET+BPF_K, 1)
2732                 },
2733                 {
2734                         BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2735                         BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
2736                         BPF_STMT(BPF_RET+BPF_K, 1)
2737                 }
2738         };
2739
2740         int i;
2741         uint8_t pkt[8] = { 0 };
2742
2743         size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2744
2745         RZ(rump_init());
2746
2747         for (i = 0; i < 3; i++) {
2748
2749                 ATF_CHECK(prog_validate(insns[i], insn_count));
2750                 ATF_CHECK(exec_prog(insns[i], insn_count, pkt, 8) == 0);
2751         }
2752 }
2753
2754 ATF_TC(bpfjit_ld_ind_x_overflow1);
2755 ATF_TC_HEAD(bpfjit_ld_ind_x_overflow1, tc)
2756 {
2757         atf_tc_set_md_var(tc, "descr",
2758             "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
2759 }
2760
2761 ATF_TC_BODY(bpfjit_ld_ind_x_overflow1, tc)
2762 {
2763         static struct bpf_insn insns[] = {
2764                 BPF_STMT(BPF_LD+BPF_LEN, 0),
2765                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
2766                 BPF_STMT(BPF_MISC+BPF_TAX, 0),
2767                 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2768                 BPF_STMT(BPF_RET+BPF_A, 0)
2769         };
2770
2771         size_t i;
2772         bpfjit_func_t code;
2773         uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
2774
2775         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2776
2777         RZ(rump_init());
2778
2779         ATF_CHECK(prog_validate(insns, insn_count));
2780
2781         rump_schedule();
2782         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2783         rump_unschedule();
2784         ATF_REQUIRE(code != NULL);
2785
2786         for (i = 1; i <= sizeof(pkt); i++) {
2787                 //ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
2788                 ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i);
2789         }
2790
2791         rump_schedule();
2792         rumpns_bpfjit_free_code(code);
2793         rump_unschedule();
2794 }
2795
2796 ATF_TC(bpfjit_ld_ind_x_overflow2);
2797 ATF_TC_HEAD(bpfjit_ld_ind_x_overflow2, tc)
2798 {
2799         atf_tc_set_md_var(tc, "descr",
2800             "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
2801 }
2802
2803 ATF_TC_BODY(bpfjit_ld_ind_x_overflow2, tc)
2804 {
2805         static struct bpf_insn insns[] = {
2806                 BPF_STMT(BPF_LD+BPF_LEN, 0),
2807                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
2808                 BPF_STMT(BPF_ST, 3),
2809                 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
2810                 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2811                 BPF_STMT(BPF_RET+BPF_A, 0)
2812         };
2813
2814         size_t i;
2815         bpfjit_func_t code;
2816         uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
2817
2818         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2819
2820         RZ(rump_init());
2821
2822         ATF_CHECK(prog_validate(insns, insn_count));
2823
2824         rump_schedule();
2825         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2826         rump_unschedule();
2827         ATF_REQUIRE(code != NULL);
2828
2829         for (i = 1; i <= sizeof(pkt); i++) {
2830                 //ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
2831                 ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i);
2832         }
2833
2834         rump_schedule();
2835         rumpns_bpfjit_free_code(code);
2836         rump_unschedule();
2837 }
2838
2839 ATF_TC(bpfjit_ld_len);
2840 ATF_TC_HEAD(bpfjit_ld_len, tc)
2841 {
2842         atf_tc_set_md_var(tc, "descr",
2843             "Test JIT compilation of BPF_LD+BPF_W+BPF_LEN");
2844 }
2845
2846 ATF_TC_BODY(bpfjit_ld_len, tc)
2847 {
2848         static struct bpf_insn insns[] = {
2849                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2850                 BPF_STMT(BPF_RET+BPF_A, 0)
2851         };
2852
2853         size_t i;
2854         bpfjit_func_t code;
2855         uint8_t pkt[32]; /* the program doesn't read any data */
2856
2857         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2858
2859         RZ(rump_init());
2860
2861         ATF_CHECK(prog_validate(insns, insn_count));
2862
2863         rump_schedule();
2864         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2865         rump_unschedule();
2866         ATF_REQUIRE(code != NULL);
2867
2868         for (i = 0; i < sizeof(pkt); i++)
2869                 ATF_CHECK(jitcall(code, pkt, i, 1) == i);
2870
2871         rump_schedule();
2872         rumpns_bpfjit_free_code(code);
2873         rump_unschedule();
2874 }
2875
2876 ATF_TC(bpfjit_ld_imm);
2877 ATF_TC_HEAD(bpfjit_ld_imm, tc)
2878 {
2879         atf_tc_set_md_var(tc, "descr",
2880             "Test JIT compilation of BPF_LD+BPF_IMM");
2881 }
2882
2883 ATF_TC_BODY(bpfjit_ld_imm, tc)
2884 {
2885         static struct bpf_insn insns[] = {
2886                 BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX),
2887                 BPF_STMT(BPF_RET+BPF_A, 0)
2888         };
2889
2890         uint8_t pkt[1]; /* the program doesn't read any data */
2891
2892         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2893
2894         RZ(rump_init());
2895
2896         ATF_CHECK(prog_validate(insns, insn_count));
2897         ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
2898 }
2899
2900 ATF_TC(bpfjit_ldx_imm1);
2901 ATF_TC_HEAD(bpfjit_ldx_imm1, tc)
2902 {
2903         atf_tc_set_md_var(tc, "descr",
2904             "Test JIT compilation of BPF_LDX+BPF_IMM");
2905 }
2906
2907 ATF_TC_BODY(bpfjit_ldx_imm1, tc)
2908 {
2909         static struct bpf_insn insns[] = {
2910                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX - 5),
2911                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2912                 BPF_STMT(BPF_RET+BPF_A, 0)
2913         };
2914
2915         uint8_t pkt[1]; /* the program doesn't read any data */
2916
2917         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2918
2919         RZ(rump_init());
2920
2921         ATF_CHECK(prog_validate(insns, insn_count));
2922         ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX - 5);
2923 }
2924
2925 ATF_TC(bpfjit_ldx_imm2);
2926 ATF_TC_HEAD(bpfjit_ldx_imm2, tc)
2927 {
2928         atf_tc_set_md_var(tc, "descr",
2929             "Test JIT compilation of BPF_LDX+BPF_IMM");
2930 }
2931
2932 ATF_TC_BODY(bpfjit_ldx_imm2, tc)
2933 {
2934         static struct bpf_insn insns[] = {
2935                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2936                 BPF_STMT(BPF_LD+BPF_IMM, 5),
2937                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2938                 BPF_STMT(BPF_RET+BPF_K, 7),
2939                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
2940         };
2941
2942         uint8_t pkt[1]; /* the program doesn't read any data */
2943
2944         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2945
2946         RZ(rump_init());
2947
2948         ATF_CHECK(prog_validate(insns, insn_count));
2949         ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
2950 }
2951
2952 ATF_TC(bpfjit_ldx_len1);
2953 ATF_TC_HEAD(bpfjit_ldx_len1, tc)
2954 {
2955         atf_tc_set_md_var(tc, "descr",
2956             "Test JIT compilation of BPF_LDX+BPF_LEN");
2957 }
2958
2959 ATF_TC_BODY(bpfjit_ldx_len1, tc)
2960 {
2961         static struct bpf_insn insns[] = {
2962                 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2963                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2964                 BPF_STMT(BPF_RET+BPF_A, 0)
2965         };
2966
2967         size_t i;
2968         bpfjit_func_t code;
2969         uint8_t pkt[5]; /* the program doesn't read any data */
2970
2971         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2972
2973         RZ(rump_init());
2974
2975         ATF_CHECK(prog_validate(insns, insn_count));
2976
2977         rump_schedule();
2978         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2979         rump_unschedule();
2980         ATF_REQUIRE(code != NULL);
2981
2982         for (i = 1; i < sizeof(pkt); i++) {
2983                 ATF_CHECK(jitcall(code, pkt, i, 1) == i);
2984                 ATF_CHECK(jitcall(code, pkt, i + 1, i) == i + 1);
2985         }
2986
2987         rump_schedule();
2988         rumpns_bpfjit_free_code(code);
2989         rump_unschedule();
2990 }
2991
2992 ATF_TC(bpfjit_ldx_len2);
2993 ATF_TC_HEAD(bpfjit_ldx_len2, tc)
2994 {
2995         atf_tc_set_md_var(tc, "descr",
2996             "Test JIT compilation of BPF_LDX+BPF_LEN");
2997 }
2998
2999 ATF_TC_BODY(bpfjit_ldx_len2, tc)
3000 {
3001         static struct bpf_insn insns[] = {
3002                 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
3003                 BPF_STMT(BPF_LD+BPF_IMM, 5),
3004                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
3005                 BPF_STMT(BPF_RET+BPF_K, 7),
3006                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
3007         };
3008
3009         bpfjit_func_t code;
3010         uint8_t pkt[5]; /* the program doesn't read any data */
3011
3012         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3013
3014         RZ(rump_init());
3015
3016         ATF_CHECK(prog_validate(insns, insn_count));
3017
3018         rump_schedule();
3019         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3020         rump_unschedule();
3021         ATF_REQUIRE(code != NULL);
3022
3023         ATF_CHECK(jitcall(code, pkt, 5, 1) == UINT32_MAX);
3024         ATF_CHECK(jitcall(code, pkt, 6, 5) == 7);
3025
3026         rump_schedule();
3027         rumpns_bpfjit_free_code(code);
3028         rump_unschedule();
3029 }
3030
3031 ATF_TC(bpfjit_ldx_msh);
3032 ATF_TC_HEAD(bpfjit_ldx_msh, tc)
3033 {
3034         atf_tc_set_md_var(tc, "descr",
3035             "Test JIT compilation of BPF_LDX+BPF_MSH");
3036 }
3037
3038 ATF_TC_BODY(bpfjit_ldx_msh, tc)
3039 {
3040         static struct bpf_insn insns[] = {
3041                 BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1),
3042                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3043                 BPF_STMT(BPF_RET+BPF_A, 0)
3044         };
3045
3046         uint8_t pkt[2] = { 0, 0x7a };
3047
3048         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3049
3050         RZ(rump_init());
3051
3052         ATF_CHECK(prog_validate(insns, insn_count));
3053         ATF_CHECK(exec_prog(insns, insn_count, pkt, 2) == 40);
3054 }
3055
3056 ATF_TC(bpfjit_misc_tax);
3057 ATF_TC_HEAD(bpfjit_misc_tax, tc)
3058 {
3059         atf_tc_set_md_var(tc, "descr",
3060             "Test JIT compilation of BPF_MISC+BPF_TAX");
3061 }
3062
3063 ATF_TC_BODY(bpfjit_misc_tax, tc)
3064 {
3065         static struct bpf_insn insns[] = {
3066                 BPF_STMT(BPF_LD+BPF_IMM, 3),
3067                 BPF_STMT(BPF_MISC+BPF_TAX, 0),
3068                 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
3069                 BPF_STMT(BPF_RET+BPF_A, 0)
3070         };
3071
3072         uint8_t pkt[6] = { 0, 11, 22, 33, 44, 55 };
3073
3074         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3075
3076         RZ(rump_init());
3077
3078         ATF_CHECK(prog_validate(insns, insn_count));
3079         ATF_CHECK(exec_prog(insns, insn_count, pkt, 6) == 55);
3080 }
3081
3082 ATF_TC(bpfjit_misc_txa);
3083 ATF_TC_HEAD(bpfjit_misc_txa, tc)
3084 {
3085         atf_tc_set_md_var(tc, "descr",
3086             "Test JIT compilation of BPF_MISC+BPF_TXA");
3087 }
3088
3089 ATF_TC_BODY(bpfjit_misc_txa, tc)
3090 {
3091         static struct bpf_insn insns[] = {
3092                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 391),
3093                 BPF_STMT(BPF_MISC+BPF_TXA, 0),
3094                 BPF_STMT(BPF_RET+BPF_A, 0)
3095         };
3096
3097         uint8_t pkt[1]; /* the program doesn't read any data */
3098
3099         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3100
3101         RZ(rump_init());
3102
3103         ATF_CHECK(prog_validate(insns, insn_count));
3104         ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 391);
3105 }
3106
3107 ATF_TC(bpfjit_st1);
3108 ATF_TC_HEAD(bpfjit_st1, tc)
3109 {
3110         atf_tc_set_md_var(tc, "descr",
3111             "Test JIT compilation of BPF_ST");
3112 }
3113
3114 ATF_TC_BODY(bpfjit_st1, tc)
3115 {
3116         static struct bpf_insn insns[] = {
3117                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
3118                 BPF_STMT(BPF_ST, 0),
3119                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
3120                 BPF_STMT(BPF_LD+BPF_MEM, 0),
3121                 BPF_STMT(BPF_RET+BPF_A, 0)
3122         };
3123
3124         size_t i;
3125         bpfjit_func_t code;
3126         uint8_t pkt[16]; /* the program doesn't read any data */
3127
3128         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3129
3130         RZ(rump_init());
3131
3132         ATF_CHECK(prog_validate(insns, insn_count));
3133
3134         rump_schedule();
3135         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3136         rump_unschedule();
3137         ATF_REQUIRE(code != NULL);
3138
3139         for (i = 1; i <= sizeof(pkt); i++)
3140                 ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i);
3141
3142         rump_schedule();
3143         rumpns_bpfjit_free_code(code);
3144         rump_unschedule();
3145 }
3146
3147 ATF_TC(bpfjit_st2);
3148 ATF_TC_HEAD(bpfjit_st2, tc)
3149 {
3150         atf_tc_set_md_var(tc, "descr",
3151             "Test JIT compilation of BPF_ST");
3152 }
3153
3154 ATF_TC_BODY(bpfjit_st2, tc)
3155 {
3156         static struct bpf_insn insns[] = {
3157                 BPF_STMT(BPF_ST, 0),
3158                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
3159                 BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
3160                 BPF_STMT(BPF_LD+BPF_MEM, 0),
3161                 BPF_STMT(BPF_RET+BPF_A, 0)
3162         };
3163
3164         uint8_t pkt[1]; /* the program doesn't read any data */
3165
3166         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3167
3168         RZ(rump_init());
3169
3170         ATF_CHECK(prog_validate(insns, insn_count));
3171         ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
3172 }
3173
3174 ATF_TC(bpfjit_st3);
3175 ATF_TC_HEAD(bpfjit_st3, tc)
3176 {
3177         atf_tc_set_md_var(tc, "descr",
3178             "Test JIT compilation of BPF_ST");
3179 }
3180
3181 ATF_TC_BODY(bpfjit_st3, tc)
3182 {
3183         static struct bpf_insn insns[] = {
3184                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
3185                 BPF_STMT(BPF_ST, 0),
3186                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
3187                 BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
3188                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
3189                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
3190                 BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
3191                 BPF_STMT(BPF_RET+BPF_A, 0),
3192                 BPF_STMT(BPF_LD+BPF_MEM, 0),
3193                 BPF_STMT(BPF_RET+BPF_A, 0)
3194         };
3195
3196         bpfjit_func_t code;
3197         uint8_t pkt[2]; /* the program doesn't read any data */
3198
3199         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3200
3201         ATF_REQUIRE(BPF_MEMWORDS > 1);
3202
3203         RZ(rump_init());
3204
3205         ATF_CHECK(prog_validate(insns, insn_count));
3206
3207         rump_schedule();
3208         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3209         rump_unschedule();
3210         ATF_REQUIRE(code != NULL);
3211
3212         ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
3213         ATF_CHECK(jitcall(code, pkt, 2, 2) == 102);
3214
3215         rump_schedule();
3216         rumpns_bpfjit_free_code(code);
3217         rump_unschedule();
3218 }
3219
3220 ATF_TC(bpfjit_st4);
3221 ATF_TC_HEAD(bpfjit_st4, tc)
3222 {
3223         atf_tc_set_md_var(tc, "descr",
3224             "Test JIT compilation of BPF_ST");
3225 }
3226
3227 ATF_TC_BODY(bpfjit_st4, tc)
3228 {
3229         static struct bpf_insn insns[] = {
3230                 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
3231                 BPF_STMT(BPF_ST, 5),
3232                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
3233                 BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
3234                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
3235                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
3236                 BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
3237                 BPF_STMT(BPF_RET+BPF_A, 0),
3238                 BPF_STMT(BPF_LD+BPF_MEM, 5),
3239                 BPF_STMT(BPF_RET+BPF_A, 0)
3240         };
3241
3242         bpfjit_func_t code;
3243         uint8_t pkt[2]; /* the program doesn't read any data */
3244
3245         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3246
3247         ATF_REQUIRE(BPF_MEMWORDS > 6);
3248
3249         RZ(rump_init());
3250
3251         ATF_CHECK(prog_validate(insns, insn_count));
3252
3253         rump_schedule();
3254         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3255         rump_unschedule();
3256         ATF_REQUIRE(code != NULL);
3257
3258         ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
3259         ATF_CHECK(jitcall(code, pkt, 2, 2) == 102);
3260
3261         rump_schedule();
3262         rumpns_bpfjit_free_code(code);
3263         rump_unschedule();
3264 }
3265
3266 ATF_TC(bpfjit_st5);
3267 ATF_TC_HEAD(bpfjit_st5, tc)
3268 {
3269         atf_tc_set_md_var(tc, "descr",
3270             "Test JIT compilation of BPF_ST");
3271 }
3272
3273 ATF_TC_BODY(bpfjit_st5, tc)
3274 {
3275         struct bpf_insn insns[5*BPF_MEMWORDS+2];
3276         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3277
3278         size_t k;
3279         bpfjit_func_t code;
3280         uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
3281
3282         memset(insns, 0, sizeof(insns));
3283
3284         /* for each k do M[k] = k */
3285         for (k = 0; k < BPF_MEMWORDS; k++) {
3286                 insns[2*k].code   = BPF_LD+BPF_IMM;
3287                 insns[2*k].k      = 3*k;
3288                 insns[2*k+1].code = BPF_ST;
3289                 insns[2*k+1].k    = k;
3290         }
3291
3292         /* load wirelen into A */
3293         insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
3294
3295         /* for each k, if (A == k + 1) return M[k] */
3296         for (k = 0; k < BPF_MEMWORDS; k++) {
3297                 insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
3298                 insns[2*BPF_MEMWORDS+3*k+1].k    = k+1;
3299                 insns[2*BPF_MEMWORDS+3*k+1].jt   = 0;
3300                 insns[2*BPF_MEMWORDS+3*k+1].jf   = 2;
3301                 insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
3302                 insns[2*BPF_MEMWORDS+3*k+2].k    = k;
3303                 insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
3304                 insns[2*BPF_MEMWORDS+3*k+3].k    = 0;
3305         }
3306
3307         insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
3308         insns[5*BPF_MEMWORDS+1].k    = UINT32_MAX;
3309
3310         RZ(rump_init());
3311
3312         ATF_CHECK(prog_validate(insns, insn_count));
3313
3314         rump_schedule();
3315         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3316         rump_unschedule();
3317         ATF_REQUIRE(code != NULL);
3318
3319         for (k = 1; k <= sizeof(pkt); k++)
3320                 ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1));
3321
3322         rump_schedule();
3323         rumpns_bpfjit_free_code(code);
3324         rump_unschedule();
3325 }
3326
3327 ATF_TC(bpfjit_stx1);
3328 ATF_TC_HEAD(bpfjit_stx1, tc)
3329 {
3330         atf_tc_set_md_var(tc, "descr",
3331             "Test JIT compilation of BPF_STX");
3332 }
3333
3334 ATF_TC_BODY(bpfjit_stx1, tc)
3335 {
3336         static struct bpf_insn insns[] = {
3337                 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
3338                 BPF_STMT(BPF_STX, 0),
3339                 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
3340                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3341                 BPF_STMT(BPF_RET+BPF_A, 0)
3342         };
3343
3344         size_t i;
3345         bpfjit_func_t code;
3346         uint8_t pkt[16]; /* the program doesn't read any data */
3347
3348         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3349
3350         RZ(rump_init());
3351
3352         ATF_CHECK(prog_validate(insns, insn_count));
3353
3354         rump_schedule();
3355         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3356         rump_unschedule();
3357         ATF_REQUIRE(code != NULL);
3358
3359         for (i = 1; i <= sizeof(pkt); i++)
3360                 ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i);
3361
3362         rump_schedule();
3363         rumpns_bpfjit_free_code(code);
3364         rump_unschedule();
3365 }
3366
3367 ATF_TC(bpfjit_stx2);
3368 ATF_TC_HEAD(bpfjit_stx2, tc)
3369 {
3370         atf_tc_set_md_var(tc, "descr",
3371             "Test JIT compilation of BPF_STX");
3372 }
3373
3374 ATF_TC_BODY(bpfjit_stx2, tc)
3375 {
3376         static struct bpf_insn insns[] = {
3377                 BPF_STMT(BPF_ST, 0),
3378                 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
3379                 BPF_STMT(BPF_STX, BPF_MEMWORDS-1),
3380                 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
3381                 BPF_STMT(BPF_MISC+BPF_TXA, 0),
3382                 BPF_STMT(BPF_RET+BPF_A, 0)
3383         };
3384
3385         uint8_t pkt[1]; /* the program doesn't read any data */
3386
3387         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3388
3389         RZ(rump_init());
3390
3391         ATF_CHECK(prog_validate(insns, insn_count));
3392         ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
3393 }
3394
3395 ATF_TC(bpfjit_stx3);
3396 ATF_TC_HEAD(bpfjit_stx3, tc)
3397 {
3398         atf_tc_set_md_var(tc, "descr",
3399             "Test JIT compilation of BPF_STX");
3400 }
3401
3402 ATF_TC_BODY(bpfjit_stx3, tc)
3403 {
3404         static struct bpf_insn insns[] = {
3405                 BPF_STMT(BPF_STX, 6),
3406                 BPF_STMT(BPF_ST, 1),
3407                 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
3408                 BPF_STMT(BPF_STX, 5),
3409                 BPF_STMT(BPF_STX, 2),
3410                 BPF_STMT(BPF_STX, 3),
3411                 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 1),
3412                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3413                 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 2),
3414                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3415                 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
3416                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3417                 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 5),
3418                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3419                 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 6),
3420                 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3421                 BPF_STMT(BPF_RET+BPF_A, 0)
3422         };
3423
3424         size_t i;
3425         bpfjit_func_t code;
3426         uint8_t pkt[16]; /* the program doesn't read any data */
3427
3428         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3429
3430         RZ(rump_init());
3431
3432         ATF_CHECK(prog_validate(insns, insn_count));
3433
3434         rump_schedule();
3435         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3436         rump_unschedule();
3437         ATF_REQUIRE(code != NULL);
3438
3439         for (i = 1; i <= sizeof(pkt); i++)
3440                 ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == 3 * i);
3441
3442         rump_schedule();
3443         rumpns_bpfjit_free_code(code);
3444         rump_unschedule();
3445 }
3446
3447 ATF_TC(bpfjit_stx4);
3448 ATF_TC_HEAD(bpfjit_stx4, tc)
3449 {
3450         atf_tc_set_md_var(tc, "descr",
3451             "Test JIT compilation of BPF_STX");
3452 }
3453
3454 ATF_TC_BODY(bpfjit_stx4, tc)
3455 {
3456         struct bpf_insn insns[5*BPF_MEMWORDS+2];
3457         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3458
3459         size_t k;
3460         bpfjit_func_t code;
3461         uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
3462
3463         memset(insns, 0, sizeof(insns));
3464
3465         /* for each k do M[k] = k */
3466         for (k = 0; k < BPF_MEMWORDS; k++) {
3467                 insns[2*k].code   = BPF_LDX+BPF_W+BPF_IMM;
3468                 insns[2*k].k      = 3*k;
3469                 insns[2*k+1].code = BPF_STX;
3470                 insns[2*k+1].k    = k;
3471         }
3472
3473         /* load wirelen into A */
3474         insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
3475
3476         /* for each k, if (A == k + 1) return M[k] */
3477         for (k = 0; k < BPF_MEMWORDS; k++) {
3478                 insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
3479                 insns[2*BPF_MEMWORDS+3*k+1].k    = k+1;
3480                 insns[2*BPF_MEMWORDS+3*k+1].jt   = 0;
3481                 insns[2*BPF_MEMWORDS+3*k+1].jf   = 2;
3482                 insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
3483                 insns[2*BPF_MEMWORDS+3*k+2].k    = k;
3484                 insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
3485                 insns[2*BPF_MEMWORDS+3*k+3].k    = 0;
3486         }
3487
3488         insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
3489         insns[5*BPF_MEMWORDS+1].k    = UINT32_MAX;
3490
3491         RZ(rump_init());
3492
3493         ATF_CHECK(prog_validate(insns, insn_count));
3494
3495         rump_schedule();
3496         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3497         rump_unschedule();
3498         ATF_REQUIRE(code != NULL);
3499
3500         for (k = 1; k <= sizeof(pkt); k++)
3501                 ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1));
3502
3503         rump_schedule();
3504         rumpns_bpfjit_free_code(code);
3505         rump_unschedule();
3506 }
3507
3508 ATF_TC(bpfjit_opt_ld_abs_1);
3509 ATF_TC_HEAD(bpfjit_opt_ld_abs_1, tc)
3510 {
3511         atf_tc_set_md_var(tc, "descr",
3512             "Test JIT compilation with length optimization "
3513             "applied to BPF_LD+BPF_ABS");
3514 }
3515
3516 ATF_TC_BODY(bpfjit_opt_ld_abs_1, tc)
3517 {
3518         static struct bpf_insn insns[] = {
3519                 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3520                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
3521                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3522                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3523                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3524                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
3525                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3526                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3527                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
3528                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3529                 BPF_STMT(BPF_RET+BPF_K, 0),
3530         };
3531
3532         size_t i, j;
3533         bpfjit_func_t code;
3534         uint8_t pkt[2][34] = {
3535                 {
3536                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3537                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3538                         0x80, 0x03, 0x70, 0x0f,
3539                         0x80, 0x03, 0x70, 0x23
3540                 },
3541                 {
3542                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3543                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3544                         0x80, 0x03, 0x70, 0x23,
3545                         0x80, 0x03, 0x70, 0x0f
3546                 }
3547         };
3548
3549         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3550
3551         RZ(rump_init());
3552
3553         ATF_CHECK(prog_validate(insns, insn_count));
3554
3555         rump_schedule();
3556         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3557         rump_unschedule();
3558         ATF_REQUIRE(code != NULL);
3559
3560         for (i = 0; i < 2; i++) {
3561                 for (j = 1; j < sizeof(pkt[i]); j++)
3562                         ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3563                 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3564         }
3565
3566         rump_schedule();
3567         rumpns_bpfjit_free_code(code);
3568         rump_unschedule();
3569 }
3570
3571 ATF_TC(bpfjit_opt_ld_abs_2);
3572 ATF_TC_HEAD(bpfjit_opt_ld_abs_2, tc)
3573 {
3574         atf_tc_set_md_var(tc, "descr",
3575             "Test JIT compilation with length optimization "
3576             "applied to BPF_LD+BPF_ABS");
3577 }
3578
3579 ATF_TC_BODY(bpfjit_opt_ld_abs_2, tc)
3580 {
3581         static struct bpf_insn insns[] = {
3582                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3583                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3584                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3585                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
3586                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
3587                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3588                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
3589                 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3590                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3591                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3592                 BPF_STMT(BPF_RET+BPF_K, 0),
3593         };
3594
3595         size_t i, j;
3596         bpfjit_func_t code;
3597         uint8_t pkt[2][34] = {
3598                 {
3599                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3600                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3601                         0x80, 0x03, 0x70, 0x0f,
3602                         0x80, 0x03, 0x70, 0x23
3603                 },
3604                 {
3605                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3606                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3607                         0x80, 0x03, 0x70, 0x23,
3608                         0x80, 0x03, 0x70, 0x0f
3609                 }
3610         };
3611
3612         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3613
3614         RZ(rump_init());
3615
3616         ATF_CHECK(prog_validate(insns, insn_count));
3617
3618         rump_schedule();
3619         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3620         rump_unschedule();
3621         ATF_REQUIRE(code != NULL);
3622
3623         for (i = 0; i < 2; i++) {
3624                 for (j = 1; j < sizeof(pkt[i]); j++)
3625                         ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3626                 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3627         }
3628
3629         rump_schedule();
3630         rumpns_bpfjit_free_code(code);
3631         rump_unschedule();
3632 }
3633
3634 ATF_TC(bpfjit_opt_ld_abs_3);
3635 ATF_TC_HEAD(bpfjit_opt_ld_abs_3, tc)
3636 {
3637         atf_tc_set_md_var(tc, "descr",
3638             "Test JIT compilation with length optimization "
3639             "applied to BPF_LD+BPF_ABS");
3640 }
3641
3642 ATF_TC_BODY(bpfjit_opt_ld_abs_3, tc)
3643 {
3644         static struct bpf_insn insns[] = {
3645                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3646                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3647                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3648                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 6),
3649                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 5),
3650                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3651                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3652                 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3653                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3654                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3655                 BPF_STMT(BPF_RET+BPF_K, 0),
3656         };
3657
3658         size_t i, j;
3659         bpfjit_func_t code;
3660         uint8_t pkt[2][34] = {
3661                 {
3662                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3663                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3664                         0x80, 0x03, 0x70, 0x0f,
3665                         0x80, 0x03, 0x70, 0x23
3666                 },
3667                 {
3668                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3669                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3670                         0x80, 0x03, 0x70, 0x23,
3671                         0x80, 0x03, 0x70, 0x0f
3672                 }
3673         };
3674
3675         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3676
3677         RZ(rump_init());
3678
3679         ATF_CHECK(prog_validate(insns, insn_count));
3680
3681         rump_schedule();
3682         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3683         rump_unschedule();
3684         ATF_REQUIRE(code != NULL);
3685
3686         for (i = 0; i < 2; i++) {
3687                 for (j = 1; j < sizeof(pkt[i]); j++)
3688                         ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3689                 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3690         }
3691
3692         rump_schedule();
3693         rumpns_bpfjit_free_code(code);
3694         rump_unschedule();
3695 }
3696
3697 ATF_TC(bpfjit_opt_ld_ind_1);
3698 ATF_TC_HEAD(bpfjit_opt_ld_ind_1, tc)
3699 {
3700         atf_tc_set_md_var(tc, "descr",
3701             "Test JIT compilation with length optimization "
3702             "applied to BPF_LD+BPF_IND");
3703 }
3704
3705 ATF_TC_BODY(bpfjit_opt_ld_ind_1, tc)
3706 {
3707         static struct bpf_insn insns[] = {
3708                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 12),
3709                 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
3710                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
3711                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 14),
3712                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3713                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
3714                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
3715                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3716                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
3717                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
3718                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3719                 BPF_STMT(BPF_RET+BPF_K, 0),
3720         };
3721
3722         size_t i, j;
3723         bpfjit_func_t code;
3724         uint8_t pkt[2][34] = {
3725                 {
3726                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3727                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3728                         0x80, 0x03, 0x70, 0x0f,
3729                         0x80, 0x03, 0x70, 0x23
3730                 },
3731                 {
3732                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3733                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3734                         0x80, 0x03, 0x70, 0x23,
3735                         0x80, 0x03, 0x70, 0x0f
3736                 }
3737         };
3738
3739         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3740
3741         RZ(rump_init());
3742
3743         ATF_CHECK(prog_validate(insns, insn_count));
3744
3745         rump_schedule();
3746         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3747         rump_unschedule();
3748         ATF_REQUIRE(code != NULL);
3749
3750         for (i = 0; i < 2; i++) {
3751                 for (j = 1; j < sizeof(pkt[i]); j++)
3752                         ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3753                 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3754         }
3755
3756         rump_schedule();
3757         rumpns_bpfjit_free_code(code);
3758         rump_unschedule();
3759 }
3760
3761 ATF_TC(bpfjit_opt_ld_ind_2);
3762 ATF_TC_HEAD(bpfjit_opt_ld_ind_2, tc)
3763 {
3764         atf_tc_set_md_var(tc, "descr",
3765             "Test JIT compilation with length optimization "
3766             "applied to BPF_LD+BPF_IND");
3767 }
3768
3769 ATF_TC_BODY(bpfjit_opt_ld_ind_2, tc)
3770 {
3771         static struct bpf_insn insns[] = {
3772                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3773                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 26),
3774                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3775                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
3776                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
3777                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
3778                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
3779                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
3780                 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3781                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3782                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3783                 BPF_STMT(BPF_RET+BPF_K, 0),
3784         };
3785
3786         size_t i, j;
3787         bpfjit_func_t code;
3788         uint8_t pkt[2][34] = {
3789                 {
3790                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3791                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3792                         0x80, 0x03, 0x70, 0x0f,
3793                         0x80, 0x03, 0x70, 0x23
3794                 },
3795                 {
3796                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3797                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3798                         0x80, 0x03, 0x70, 0x23,
3799                         0x80, 0x03, 0x70, 0x0f
3800                 }
3801         };
3802
3803         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3804
3805         RZ(rump_init());
3806
3807         ATF_CHECK(prog_validate(insns, insn_count));
3808
3809         rump_schedule();
3810         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3811         rump_unschedule();
3812         ATF_REQUIRE(code != NULL);
3813
3814         for (i = 0; i < 2; i++) {
3815                 for (j = 1; j < sizeof(pkt[i]); j++)
3816                         ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3817                 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3818         }
3819
3820         rump_schedule();
3821         rumpns_bpfjit_free_code(code);
3822         rump_unschedule();
3823 }
3824
3825 ATF_TC(bpfjit_opt_ld_ind_3);
3826 ATF_TC_HEAD(bpfjit_opt_ld_ind_3, tc)
3827 {
3828         atf_tc_set_md_var(tc, "descr",
3829             "Test JIT compilation with length optimization "
3830             "applied to BPF_LD+BPF_IND");
3831 }
3832
3833 ATF_TC_BODY(bpfjit_opt_ld_ind_3, tc)
3834 {
3835         static struct bpf_insn insns[] = {
3836                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 15),
3837                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3838                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3839                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
3840                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
3841                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
3842                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
3843                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
3844                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3845                 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3846                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3847                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3848                 BPF_STMT(BPF_RET+BPF_K, 0),
3849         };
3850
3851         size_t i, j;
3852         bpfjit_func_t code;
3853         uint8_t pkt[2][34] = {
3854                 {
3855                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3856                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3857                         0x80, 0x03, 0x70, 0x0f,
3858                         0x80, 0x03, 0x70, 0x23
3859                 },
3860                 {
3861                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3862                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3863                         0x80, 0x03, 0x70, 0x23,
3864                         0x80, 0x03, 0x70, 0x0f
3865                 }
3866         };
3867
3868         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3869
3870         RZ(rump_init());
3871
3872         ATF_CHECK(prog_validate(insns, insn_count));
3873
3874         rump_schedule();
3875         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3876         rump_unschedule();
3877         ATF_REQUIRE(code != NULL);
3878
3879         for (i = 0; i < 2; i++) {
3880                 for (j = 1; j < sizeof(pkt[i]); j++)
3881                         ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3882                 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3883         }
3884
3885         rump_schedule();
3886         rumpns_bpfjit_free_code(code);
3887         rump_unschedule();
3888 }
3889
3890 ATF_TC(bpfjit_opt_ld_ind_4);
3891 ATF_TC_HEAD(bpfjit_opt_ld_ind_4, tc)
3892 {
3893         atf_tc_set_md_var(tc, "descr",
3894             "Test JIT compilation with length optimization "
3895             "applied to BPF_LD+BPF_IND");
3896 }
3897
3898 ATF_TC_BODY(bpfjit_opt_ld_ind_4, tc)
3899 {
3900         static struct bpf_insn insns[] = {
3901                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 11),
3902                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 19),
3903                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3904                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3905                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
3906                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
3907                 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3908                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
3909                 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3910                 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3911                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3912                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3913                 BPF_STMT(BPF_RET+BPF_K, 0),
3914         };
3915
3916         size_t i, j;
3917         bpfjit_func_t code;
3918         uint8_t pkt[2][34] = {
3919                 {
3920                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3921                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3922                         0x80, 0x03, 0x70, 0x0f,
3923                         0x80, 0x03, 0x70, 0x23
3924                 },
3925                 {
3926                         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3927                         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3928                         0x80, 0x03, 0x70, 0x23,
3929                         0x80, 0x03, 0x70, 0x0f
3930                 }
3931         };
3932
3933         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3934
3935         RZ(rump_init());
3936
3937         ATF_CHECK(prog_validate(insns, insn_count));
3938
3939         rump_schedule();
3940         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3941         rump_unschedule();
3942         ATF_REQUIRE(code != NULL);
3943
3944         for (i = 0; i < 2; i++) {
3945                 for (j = 1; j < sizeof(pkt[i]); j++)
3946                         ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3947                 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3948         }
3949
3950         rump_schedule();
3951         rumpns_bpfjit_free_code(code);
3952         rump_unschedule();
3953 }
3954
3955 ATF_TC(bpfjit_abc_ja);
3956 ATF_TC_HEAD(bpfjit_abc_ja, tc)
3957 {
3958         atf_tc_set_md_var(tc, "descr",
3959             "Test ABC optimization with a single BPF_JMP+BPF_JA");
3960 }
3961
3962 ATF_TC_BODY(bpfjit_abc_ja, tc)
3963 {
3964         static struct bpf_insn insns[] = {
3965                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
3966                 BPF_STMT(BPF_JMP+BPF_JA, 2),
3967                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, UINT32_MAX - 1),
3968                 BPF_STMT(BPF_RET+BPF_K, 0),
3969                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), /* min. length 6 */
3970                 BPF_STMT(BPF_RET+BPF_A, 0),
3971                 BPF_STMT(BPF_RET+BPF_K, 1),
3972                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
3973                 BPF_STMT(BPF_RET+BPF_K, 2),
3974                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
3975                 BPF_STMT(BPF_RET+BPF_K, 3),
3976         };
3977
3978         bpfjit_func_t code;
3979         uint8_t pkt[6] = {0, 0, /* UINT32_MAX: */ 255, 255, 255, 255};
3980
3981         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3982
3983         RZ(rump_init());
3984
3985         ATF_CHECK(prog_validate(insns, insn_count));
3986
3987         rump_schedule();
3988         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3989         rump_unschedule();
3990         ATF_REQUIRE(code != NULL);
3991
3992         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3993         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3994         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3995         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3996         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3997         ATF_CHECK(jitcall(code, pkt, 6, 6) == UINT32_MAX);
3998
3999         rump_schedule();
4000         rumpns_bpfjit_free_code(code);
4001         rump_unschedule();
4002 }
4003
4004 ATF_TC(bpfjit_abc_ja_over);
4005 ATF_TC_HEAD(bpfjit_abc_ja_over, tc)
4006 {
4007         atf_tc_set_md_var(tc, "descr",
4008             "Test ABC optimization when BPF_JMP+BPF_JA jumps over all loads");
4009 }
4010
4011 ATF_TC_BODY(bpfjit_abc_ja_over, tc)
4012 {
4013         static struct bpf_insn insns[] = {
4014                 BPF_STMT(BPF_JMP+BPF_JA, 2),
4015                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3),
4016                 BPF_STMT(BPF_RET+BPF_K, 0),
4017                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
4018                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4),
4019                 BPF_STMT(BPF_RET+BPF_K, 1),
4020                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
4021                 BPF_STMT(BPF_RET+BPF_K, 2),
4022                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
4023                 BPF_STMT(BPF_RET+BPF_K, 3),
4024         };
4025
4026         uint8_t pkt[1]; /* the program doesn't read any data */
4027
4028         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4029
4030         RZ(rump_init());
4031
4032         ATF_CHECK(prog_validate(insns, insn_count));
4033         ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
4034 }
4035
4036 ATF_TC(bpfjit_abc_ld_chain);
4037 ATF_TC_HEAD(bpfjit_abc_ld_chain, tc)
4038 {
4039         atf_tc_set_md_var(tc, "descr",
4040             "Test ABC optimization of a chain of BPF_LD instructions "
4041             "with exits leading to a single BPF_RET");
4042 }
4043
4044 ATF_TC_BODY(bpfjit_abc_ld_chain, tc)
4045 {
4046         static struct bpf_insn insns[] = {
4047                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
4048                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 4),
4049                 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* min. length 6 */
4050                 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 0, 2),
4051                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), /* min. length 10 */
4052                 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 0, 1),
4053                 BPF_STMT(BPF_RET+BPF_K, 123456789),
4054                 BPF_STMT(BPF_RET+BPF_K, 987654321),
4055         };
4056
4057         bpfjit_func_t code;
4058         uint8_t pkt[10] = {};
4059
4060         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4061
4062         RZ(rump_init());
4063
4064         ATF_CHECK(prog_validate(insns, insn_count));
4065
4066         rump_schedule();
4067         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4068         rump_unschedule();
4069         ATF_REQUIRE(code != NULL);
4070
4071         /* Packet is too short. */
4072         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4073         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4074         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4075
4076         /* !(pkt[3] == 8) => return 123456789 */
4077         ATF_CHECK(jitcall(code, pkt, 4, 4) == 123456789);
4078         ATF_CHECK(jitcall(code, pkt, 5, 5) == 123456789);
4079         ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789);
4080         ATF_CHECK(jitcall(code, pkt, 7, 7) == 123456789);
4081         ATF_CHECK(jitcall(code, pkt, 8, 8) == 123456789);
4082         ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789);
4083
4084         /* !(pkt[4:2] >= 7) => too short or return 123456789 */
4085         pkt[3] = 8;
4086         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4087         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4088         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4089         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4090         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4091         ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789);
4092         ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789);
4093
4094         /* !(pkt[6:4] > 6) => too short or return 987654321 */
4095         pkt[4] = pkt[5] = 1;
4096         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4097         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4098         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4099         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4100         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4101         ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4102         ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4103         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4104         ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4105         ATF_CHECK(jitcall(code, pkt, 10, 10) == 987654321);
4106
4107         /* (pkt[6:4] > 6) => too short or return 123456789 */
4108         pkt[6] = pkt[7] = pkt[8] = pkt[9] = 1;
4109         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4110         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4111         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4112         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4113         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4114         ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4115         ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4116         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4117         ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4118         ATF_CHECK(jitcall(code, pkt, 10, 10) == 123456789);
4119
4120         rump_schedule();
4121         rumpns_bpfjit_free_code(code);
4122         rump_unschedule();
4123 }
4124
4125 ATF_TC(bpfjit_examples_1);
4126 ATF_TC_HEAD(bpfjit_examples_1, tc)
4127 {
4128         atf_tc_set_md_var(tc, "descr",
4129             "Test the first example from bpf(4) - "
4130             "accept Reverse ARP requests");
4131 }
4132
4133 ATF_TC_BODY(bpfjit_examples_1, tc)
4134 {
4135         /*
4136          * The following filter is taken from the Reverse ARP
4137          * Daemon. It accepts only Reverse ARP requests.
4138          */
4139         struct bpf_insn insns[] = {
4140                 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
4141                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8035, 0, 3),
4142                 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
4143                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 1),
4144                 BPF_STMT(BPF_RET+BPF_K, 42),
4145                 BPF_STMT(BPF_RET+BPF_K, 0),
4146         };
4147
4148         bpfjit_func_t code;
4149         uint8_t pkt[22] = {};
4150
4151         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4152
4153         RZ(rump_init());
4154
4155         ATF_CHECK(prog_validate(insns, insn_count));
4156
4157         rump_schedule();
4158         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4159         rump_unschedule();
4160         ATF_REQUIRE(code != NULL);
4161
4162         /* Packet is too short. */
4163         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4164         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4165         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4166         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4167         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4168         ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4169         ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4170         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4171         ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4172         ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4173         ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4174         ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4175         ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4176         ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4177         ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4178         ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4179         ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4180         ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4181         ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4182         ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4183         ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4184
4185         /* The packet doesn't match. */
4186         ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4187
4188         /* Still no match after setting the protocol field. */
4189         pkt[12] = 0x80; pkt[13] = 0x35;
4190         ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4191
4192         /* Set RARP message type. */
4193         pkt[21] = 3;
4194         ATF_CHECK(jitcall(code, pkt, 22, 22) == 42);
4195
4196         /* Packet is too short. */
4197         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4198         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4199         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4200         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4201         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4202         ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4203         ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4204         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4205         ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4206         ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4207         ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4208         ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4209         ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4210         ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4211         ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4212         ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4213         ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4214         ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4215         ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4216         ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4217         ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4218
4219         /* Change RARP message type. */
4220         pkt[20] = 3;
4221         ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4222
4223         rump_schedule();
4224         rumpns_bpfjit_free_code(code);
4225         rump_unschedule();
4226 }
4227
4228 ATF_TC(bpfjit_examples_2);
4229 ATF_TC_HEAD(bpfjit_examples_2, tc)
4230 {
4231         atf_tc_set_md_var(tc, "descr",
4232             "Test the second example from bpf(4) - "
4233             "accept IP packets between two specified hosts");
4234 }
4235
4236 ATF_TC_BODY(bpfjit_examples_2, tc)
4237 {
4238         /*
4239          * This filter accepts only IP packets between host 128.3.112.15
4240          * and 128.3.112.35.
4241          */
4242         static 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, 8),
4245                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
4246                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
4247                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
4248                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
4249                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
4250                 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
4251                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
4252                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
4253                 BPF_STMT(BPF_RET+BPF_K, 0),
4254         };
4255
4256         bpfjit_func_t code;
4257         uint8_t pkt[34] = {};
4258
4259         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4260
4261         RZ(rump_init());
4262
4263         ATF_CHECK(prog_validate(insns, insn_count));
4264
4265         rump_schedule();
4266         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4267         rump_unschedule();
4268         ATF_REQUIRE(code != NULL);
4269
4270         /* Packet is too short. */
4271         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4272         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4273         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4274         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4275         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4276         ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4277         ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4278         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4279         ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4280         ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4281         ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4282         ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4283         ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4284         ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4285         ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4286         ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4287         ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4288         ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4289         ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4290         ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4291         ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4292         ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4293         ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
4294         ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
4295         ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
4296         ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
4297         ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
4298         ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
4299         ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
4300         ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4301         ATF_CHECK(jitcall(code, pkt, 31, 31) == 0);
4302         ATF_CHECK(jitcall(code, pkt, 32, 32) == 0);
4303         ATF_CHECK(jitcall(code, pkt, 33, 33) == 0);
4304
4305         /* The packet doesn't match. */
4306         ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4307
4308         /* Still no match after setting the protocol field. */
4309         pkt[12] = 8;
4310         ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4311
4312         pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 15;
4313         ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4314
4315         pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 35;
4316         ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX);
4317
4318         /* Swap the ip addresses. */
4319         pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 35;
4320         ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4321
4322         pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 15;
4323         ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX);
4324
4325         /* Packet is too short. */
4326         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4327         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4328         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4329         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4330         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4331         ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4332         ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4333         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4334         ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4335         ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4336         ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4337         ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4338         ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4339         ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4340         ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4341         ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4342         ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4343         ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4344         ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4345         ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4346         ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4347         ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4348         ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
4349         ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
4350         ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
4351         ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
4352         ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
4353         ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
4354         ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
4355         ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4356         ATF_CHECK(jitcall(code, pkt, 31, 31) == 0);
4357         ATF_CHECK(jitcall(code, pkt, 32, 32) == 0);
4358         ATF_CHECK(jitcall(code, pkt, 33, 33) == 0);
4359
4360         /* Change the protocol field. */
4361         pkt[13] = 8;
4362         ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4363
4364         rump_schedule();
4365         rumpns_bpfjit_free_code(code);
4366         rump_unschedule();
4367 }
4368
4369 ATF_TC(bpfjit_examples_3);
4370 ATF_TC_HEAD(bpfjit_examples_3, tc)
4371 {
4372         atf_tc_set_md_var(tc, "descr",
4373             "Test the third example from bpf(4) - "
4374             "accept TCP finger packets");
4375 }
4376
4377 ATF_TC_BODY(bpfjit_examples_3, tc)
4378 {
4379         /*
4380          * This filter returns only TCP finger packets.
4381          */
4382         struct bpf_insn insns[] = {
4383                 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
4384                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 10),
4385                 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
4386                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 8),
4387                 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
4388                 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
4389                 BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
4390                 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
4391                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0),
4392                 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
4393                 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
4394                 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
4395                 BPF_STMT(BPF_RET+BPF_K, 0),
4396         };
4397
4398         bpfjit_func_t code;
4399         uint8_t pkt[30] = {};
4400
4401         /* Set IP fragment offset to non-zero. */
4402         pkt[20] = 1; pkt[21] = 1;
4403
4404         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4405
4406         RZ(rump_init());
4407
4408         ATF_CHECK(prog_validate(insns, insn_count));
4409
4410         rump_schedule();
4411         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4412         rump_unschedule();
4413         ATF_REQUIRE(code != NULL);
4414
4415         /* Packet is too short. */
4416         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4417         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4418         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4419         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4420         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4421         ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4422         ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4423         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4424         ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4425         ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4426         ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4427         ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4428         ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4429         ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4430         ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4431         ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4432         ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4433         ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4434         ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4435         ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4436         ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4437         ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4438         ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
4439         ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
4440         ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
4441         ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
4442         ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
4443         ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
4444         ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
4445
4446         /* The packet doesn't match. */
4447         ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4448
4449         /* Still no match after setting the protocol field. */
4450         pkt[12] = 8;
4451         ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4452
4453         /* Get one step closer to the match. */
4454         pkt[23] = 6;
4455         ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4456
4457         /* Set IP fragment offset to zero. */
4458         pkt[20] = 0x20; pkt[21] = 0;
4459         ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4460
4461         /* Set IP header length to 12. */
4462         pkt[14] = 0xd3;
4463         ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4464
4465         /* Match one branch of the program. */
4466         pkt[27] = 79;
4467         ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX);
4468
4469         /* Match the other branch of the program. */
4470         pkt[29] = 79; pkt[27] = 0;
4471         ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX);
4472
4473         /* Packet is too short. */
4474         ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4475         ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4476         ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4477         ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4478         ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4479         ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4480         ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4481         ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4482         ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4483         ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4484         ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4485         ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4486         ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4487         ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4488         ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4489         ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4490         ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4491         ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4492         ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4493         ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4494         ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4495         ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4496         ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
4497         ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
4498         ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
4499         ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
4500         ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
4501         ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
4502         ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
4503
4504         /* Set IP header length to 16. Packet is too short. */
4505         pkt[14] = 4;
4506         ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4507
4508         rump_schedule();
4509         rumpns_bpfjit_free_code(code);
4510         rump_unschedule();
4511 }
4512
4513 ATF_TC(bpfjit_cop_no_ctx);
4514 ATF_TC_HEAD(bpfjit_cop_no_ctx, tc)
4515 {
4516         atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COP "
4517             "instruction can't be accepted without a context");
4518 }
4519
4520 ATF_TC_BODY(bpfjit_cop_no_ctx, tc)
4521 {
4522         static struct bpf_insn insns[] = {
4523                 BPF_STMT(BPF_MISC+BPF_COP, 0),
4524                 BPF_STMT(BPF_RET+BPF_K, 7)
4525         };
4526
4527         bpfjit_func_t code;
4528         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4529
4530         RZ(rump_init());
4531
4532         ATF_CHECK(!prog_validate(insns, insn_count));
4533
4534         rump_schedule();
4535         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4536         rump_unschedule();
4537         ATF_CHECK(code == NULL);
4538 }
4539
4540 ATF_TC(bpfjit_copx_no_ctx);
4541 ATF_TC_HEAD(bpfjit_copx_no_ctx, tc)
4542 {
4543         atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COPX "
4544             "instruction can't be accepted without a context");
4545 }
4546
4547 ATF_TC_BODY(bpfjit_copx_no_ctx, tc)
4548 {
4549         static struct bpf_insn insns[] = {
4550                 BPF_STMT(BPF_MISC+BPF_COPX, 0),
4551                 BPF_STMT(BPF_RET+BPF_K, 7)
4552         };
4553
4554         bpfjit_func_t code;
4555         size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4556
4557         RZ(rump_init());
4558
4559         ATF_CHECK(!prog_validate(insns, insn_count));
4560
4561         rump_schedule();
4562         code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4563         rump_unschedule();
4564         ATF_CHECK(code == NULL);
4565 }
4566
4567 ATF_TP_ADD_TCS(tp)
4568 {
4569
4570         /*
4571          * For every new test please also add a similar test
4572          * to ../../lib/libbpfjit/t_bpfjit.c
4573          */
4574         ATF_TP_ADD_TC(tp, bpfjit_empty);
4575         ATF_TP_ADD_TC(tp, bpfjit_ret_k);
4576         ATF_TP_ADD_TC(tp, bpfjit_bad_ret_k);
4577         ATF_TP_ADD_TC(tp, bpfjit_alu_add_k);
4578         ATF_TP_ADD_TC(tp, bpfjit_alu_sub_k);
4579         ATF_TP_ADD_TC(tp, bpfjit_alu_mul_k);
4580         ATF_TP_ADD_TC(tp, bpfjit_alu_div0_k);
4581         ATF_TP_ADD_TC(tp, bpfjit_alu_div1_k);
4582         ATF_TP_ADD_TC(tp, bpfjit_alu_div2_k);
4583         ATF_TP_ADD_TC(tp, bpfjit_alu_div4_k);
4584         ATF_TP_ADD_TC(tp, bpfjit_alu_div10_k);
4585         ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_k);
4586         ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_k);
4587         ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_k);
4588         ATF_TP_ADD_TC(tp, bpfjit_alu_mod0_k);
4589         ATF_TP_ADD_TC(tp, bpfjit_alu_mod1_k);
4590         ATF_TP_ADD_TC(tp, bpfjit_alu_mod2_k);
4591         ATF_TP_ADD_TC(tp, bpfjit_alu_mod4_k);
4592         ATF_TP_ADD_TC(tp, bpfjit_alu_mod10_k);
4593         ATF_TP_ADD_TC(tp, bpfjit_alu_mod10000_k);
4594         ATF_TP_ADD_TC(tp, bpfjit_alu_mod7609801_k);
4595         ATF_TP_ADD_TC(tp, bpfjit_alu_mod80000000_k);
4596         ATF_TP_ADD_TC(tp, bpfjit_alu_and_k);
4597         ATF_TP_ADD_TC(tp, bpfjit_alu_or_k);
4598         ATF_TP_ADD_TC(tp, bpfjit_alu_xor_k);
4599         ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_k);
4600         ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_k);
4601         ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_k);
4602         ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_k);
4603         ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_k);
4604         ATF_TP_ADD_TC(tp, bpfjit_alu_add_x);
4605         ATF_TP_ADD_TC(tp, bpfjit_alu_sub_x);
4606         ATF_TP_ADD_TC(tp, bpfjit_alu_mul_x);
4607         ATF_TP_ADD_TC(tp, bpfjit_alu_div0_x);
4608         ATF_TP_ADD_TC(tp, bpfjit_alu_div1_x);
4609         ATF_TP_ADD_TC(tp, bpfjit_alu_div2_x);
4610         ATF_TP_ADD_TC(tp, bpfjit_alu_div4_x);
4611         ATF_TP_ADD_TC(tp, bpfjit_alu_div10_x);
4612         ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_x);
4613         ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_x);
4614         ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_x);
4615         ATF_TP_ADD_TC(tp, bpfjit_alu_mod0_x);
4616         ATF_TP_ADD_TC(tp, bpfjit_alu_mod1_x);
4617         ATF_TP_ADD_TC(tp, bpfjit_alu_mod2_x);
4618         ATF_TP_ADD_TC(tp, bpfjit_alu_mod4_x);
4619         ATF_TP_ADD_TC(tp, bpfjit_alu_mod10_x);
4620         ATF_TP_ADD_TC(tp, bpfjit_alu_mod10000_x);
4621         ATF_TP_ADD_TC(tp, bpfjit_alu_mod7609801_x);
4622         ATF_TP_ADD_TC(tp, bpfjit_alu_mod80000000_x);
4623         ATF_TP_ADD_TC(tp, bpfjit_alu_and_x);
4624         ATF_TP_ADD_TC(tp, bpfjit_alu_or_x);
4625         ATF_TP_ADD_TC(tp, bpfjit_alu_xor_x);
4626         ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_x);
4627         ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_x);
4628         ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_x);
4629         ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_x);
4630         ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_x);
4631         ATF_TP_ADD_TC(tp, bpfjit_alu_neg);
4632         ATF_TP_ADD_TC(tp, bpfjit_jmp_ja);
4633         ATF_TP_ADD_TC(tp, bpfjit_jmp_ja_invalid);
4634         ATF_TP_ADD_TC(tp, bpfjit_jmp_ja_overflow);
4635         ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_k);
4636         ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_k);
4637         ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_k);
4638         ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_k);
4639         ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_k);
4640         ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_x);
4641         ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_x);
4642         ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x);
4643         ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_x);
4644         ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_ax);
4645         ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_a);
4646         ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_x);
4647         ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_x);
4648         ATF_TP_ADD_TC(tp, bpfjit_ld_abs);
4649         ATF_TP_ADD_TC(tp, bpfjit_ld_abs_k_overflow);
4650         ATF_TP_ADD_TC(tp, bpfjit_ld_ind);
4651         ATF_TP_ADD_TC(tp, bpfjit_ld_ind_k_overflow);
4652         ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow1);
4653         ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow2);
4654         ATF_TP_ADD_TC(tp, bpfjit_ld_len);
4655         ATF_TP_ADD_TC(tp, bpfjit_ld_imm);
4656         ATF_TP_ADD_TC(tp, bpfjit_ldx_imm1);
4657         ATF_TP_ADD_TC(tp, bpfjit_ldx_imm2);
4658         ATF_TP_ADD_TC(tp, bpfjit_ldx_len1);
4659         ATF_TP_ADD_TC(tp, bpfjit_ldx_len2);
4660         ATF_TP_ADD_TC(tp, bpfjit_ldx_msh);
4661         ATF_TP_ADD_TC(tp, bpfjit_misc_tax);
4662         ATF_TP_ADD_TC(tp, bpfjit_misc_txa);
4663         ATF_TP_ADD_TC(tp, bpfjit_st1);
4664         ATF_TP_ADD_TC(tp, bpfjit_st2);
4665         ATF_TP_ADD_TC(tp, bpfjit_st3);
4666         ATF_TP_ADD_TC(tp, bpfjit_st4);
4667         ATF_TP_ADD_TC(tp, bpfjit_st5);
4668         ATF_TP_ADD_TC(tp, bpfjit_stx1);
4669         ATF_TP_ADD_TC(tp, bpfjit_stx2);
4670         ATF_TP_ADD_TC(tp, bpfjit_stx3);
4671         ATF_TP_ADD_TC(tp, bpfjit_stx4);
4672         ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_1);
4673         ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_2);
4674         ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_3);
4675         ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_1);
4676         ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_2);
4677         ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_3);
4678         ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_4);
4679         ATF_TP_ADD_TC(tp, bpfjit_abc_ja);
4680         ATF_TP_ADD_TC(tp, bpfjit_abc_ja_over);
4681         ATF_TP_ADD_TC(tp, bpfjit_abc_ld_chain);
4682         ATF_TP_ADD_TC(tp, bpfjit_examples_1);
4683         ATF_TP_ADD_TC(tp, bpfjit_examples_2);
4684         ATF_TP_ADD_TC(tp, bpfjit_examples_3);
4685         ATF_TP_ADD_TC(tp, bpfjit_cop_no_ctx);
4686         ATF_TP_ADD_TC(tp, bpfjit_copx_no_ctx);
4687
4688         return atf_no_error();
4689 }