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