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