1
2
3
4
5 package bpf_test
6
7 import (
8 "testing"
9
10 "golang.org/x/net/bpf"
11 )
12
13 func TestVMJumpOne(t *testing.T) {
14 vm, done, err := testVM(t, []bpf.Instruction{
15 bpf.LoadAbsolute{
16 Off: 8,
17 Size: 1,
18 },
19 bpf.Jump{
20 Skip: 1,
21 },
22 bpf.RetConstant{
23 Val: 0,
24 },
25 bpf.RetConstant{
26 Val: 9,
27 },
28 })
29 if err != nil {
30 t.Fatalf("failed to load BPF program: %v", err)
31 }
32 defer done()
33
34 out, err := vm.Run([]byte{
35 0xff, 0xff, 0xff, 0xff,
36 0xff, 0xff, 0xff, 0xff,
37 1,
38 })
39 if err != nil {
40 t.Fatalf("unexpected error while running program: %v", err)
41 }
42 if want, got := 1, out; want != got {
43 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
44 want, got)
45 }
46 }
47
48 func TestVMJumpOutOfProgram(t *testing.T) {
49 _, _, err := testVM(t, []bpf.Instruction{
50 bpf.Jump{
51 Skip: 1,
52 },
53 bpf.RetA{},
54 })
55 if errStr(err) != "cannot jump 1 instructions; jumping past program bounds" {
56 t.Fatalf("unexpected error: %v", err)
57 }
58 }
59
60 func TestVMJumpIfTrueOutOfProgram(t *testing.T) {
61 _, _, err := testVM(t, []bpf.Instruction{
62 bpf.JumpIf{
63 Cond: bpf.JumpEqual,
64 SkipTrue: 2,
65 },
66 bpf.RetA{},
67 })
68 if errStr(err) != "cannot jump 2 instructions in true case; jumping past program bounds" {
69 t.Fatalf("unexpected error: %v", err)
70 }
71 }
72
73 func TestVMJumpIfFalseOutOfProgram(t *testing.T) {
74 _, _, err := testVM(t, []bpf.Instruction{
75 bpf.JumpIf{
76 Cond: bpf.JumpEqual,
77 SkipFalse: 3,
78 },
79 bpf.RetA{},
80 })
81 if errStr(err) != "cannot jump 3 instructions in false case; jumping past program bounds" {
82 t.Fatalf("unexpected error: %v", err)
83 }
84 }
85
86 func TestVMJumpIfXTrueOutOfProgram(t *testing.T) {
87 _, _, err := testVM(t, []bpf.Instruction{
88 bpf.JumpIfX{
89 Cond: bpf.JumpEqual,
90 SkipTrue: 2,
91 },
92 bpf.RetA{},
93 })
94 if errStr(err) != "cannot jump 2 instructions in true case; jumping past program bounds" {
95 t.Fatalf("unexpected error: %v", err)
96 }
97 }
98
99 func TestVMJumpIfXFalseOutOfProgram(t *testing.T) {
100 _, _, err := testVM(t, []bpf.Instruction{
101 bpf.JumpIfX{
102 Cond: bpf.JumpEqual,
103 SkipFalse: 3,
104 },
105 bpf.RetA{},
106 })
107 if errStr(err) != "cannot jump 3 instructions in false case; jumping past program bounds" {
108 t.Fatalf("unexpected error: %v", err)
109 }
110 }
111
112 func TestVMJumpIfEqual(t *testing.T) {
113 vm, done, err := testVM(t, []bpf.Instruction{
114 bpf.LoadAbsolute{
115 Off: 8,
116 Size: 1,
117 },
118 bpf.JumpIf{
119 Cond: bpf.JumpEqual,
120 Val: 1,
121 SkipTrue: 1,
122 },
123 bpf.RetConstant{
124 Val: 0,
125 },
126 bpf.RetConstant{
127 Val: 9,
128 },
129 })
130 if err != nil {
131 t.Fatalf("failed to load BPF program: %v", err)
132 }
133 defer done()
134
135 out, err := vm.Run([]byte{
136 0xff, 0xff, 0xff, 0xff,
137 0xff, 0xff, 0xff, 0xff,
138 1,
139 })
140 if err != nil {
141 t.Fatalf("unexpected error while running program: %v", err)
142 }
143 if want, got := 1, out; want != got {
144 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
145 want, got)
146 }
147 }
148
149 func TestVMJumpIfNotEqual(t *testing.T) {
150 vm, done, err := testVM(t, []bpf.Instruction{
151 bpf.LoadAbsolute{
152 Off: 8,
153 Size: 1,
154 },
155 bpf.JumpIf{
156 Cond: bpf.JumpNotEqual,
157 Val: 1,
158 SkipFalse: 1,
159 },
160 bpf.RetConstant{
161 Val: 0,
162 },
163 bpf.RetConstant{
164 Val: 9,
165 },
166 })
167 if err != nil {
168 t.Fatalf("failed to load BPF program: %v", err)
169 }
170 defer done()
171
172 out, err := vm.Run([]byte{
173 0xff, 0xff, 0xff, 0xff,
174 0xff, 0xff, 0xff, 0xff,
175 1,
176 })
177 if err != nil {
178 t.Fatalf("unexpected error while running program: %v", err)
179 }
180 if want, got := 1, out; want != got {
181 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
182 want, got)
183 }
184 }
185
186 func TestVMJumpIfGreaterThan(t *testing.T) {
187 vm, done, err := testVM(t, []bpf.Instruction{
188 bpf.LoadAbsolute{
189 Off: 8,
190 Size: 4,
191 },
192 bpf.JumpIf{
193 Cond: bpf.JumpGreaterThan,
194 Val: 0x00010202,
195 SkipTrue: 1,
196 },
197 bpf.RetConstant{
198 Val: 0,
199 },
200 bpf.RetConstant{
201 Val: 12,
202 },
203 })
204 if err != nil {
205 t.Fatalf("failed to load BPF program: %v", err)
206 }
207 defer done()
208
209 out, err := vm.Run([]byte{
210 0xff, 0xff, 0xff, 0xff,
211 0xff, 0xff, 0xff, 0xff,
212 0, 1, 2, 3,
213 })
214 if err != nil {
215 t.Fatalf("unexpected error while running program: %v", err)
216 }
217 if want, got := 4, out; want != got {
218 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
219 want, got)
220 }
221 }
222
223 func TestVMJumpIfLessThan(t *testing.T) {
224 vm, done, err := testVM(t, []bpf.Instruction{
225 bpf.LoadAbsolute{
226 Off: 8,
227 Size: 4,
228 },
229 bpf.JumpIf{
230 Cond: bpf.JumpLessThan,
231 Val: 0xff010203,
232 SkipTrue: 1,
233 },
234 bpf.RetConstant{
235 Val: 0,
236 },
237 bpf.RetConstant{
238 Val: 12,
239 },
240 })
241 if err != nil {
242 t.Fatalf("failed to load BPF program: %v", err)
243 }
244 defer done()
245
246 out, err := vm.Run([]byte{
247 0xff, 0xff, 0xff, 0xff,
248 0xff, 0xff, 0xff, 0xff,
249 0, 1, 2, 3,
250 })
251 if err != nil {
252 t.Fatalf("unexpected error while running program: %v", err)
253 }
254 if want, got := 4, out; want != got {
255 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
256 want, got)
257 }
258 }
259
260 func TestVMJumpIfGreaterOrEqual(t *testing.T) {
261 vm, done, err := testVM(t, []bpf.Instruction{
262 bpf.LoadAbsolute{
263 Off: 8,
264 Size: 4,
265 },
266 bpf.JumpIf{
267 Cond: bpf.JumpGreaterOrEqual,
268 Val: 0x00010203,
269 SkipTrue: 1,
270 },
271 bpf.RetConstant{
272 Val: 0,
273 },
274 bpf.RetConstant{
275 Val: 12,
276 },
277 })
278 if err != nil {
279 t.Fatalf("failed to load BPF program: %v", err)
280 }
281 defer done()
282
283 out, err := vm.Run([]byte{
284 0xff, 0xff, 0xff, 0xff,
285 0xff, 0xff, 0xff, 0xff,
286 0, 1, 2, 3,
287 })
288 if err != nil {
289 t.Fatalf("unexpected error while running program: %v", err)
290 }
291 if want, got := 4, out; want != got {
292 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
293 want, got)
294 }
295 }
296
297 func TestVMJumpIfLessOrEqual(t *testing.T) {
298 vm, done, err := testVM(t, []bpf.Instruction{
299 bpf.LoadAbsolute{
300 Off: 8,
301 Size: 4,
302 },
303 bpf.JumpIf{
304 Cond: bpf.JumpLessOrEqual,
305 Val: 0xff010203,
306 SkipTrue: 1,
307 },
308 bpf.RetConstant{
309 Val: 0,
310 },
311 bpf.RetConstant{
312 Val: 12,
313 },
314 })
315 if err != nil {
316 t.Fatalf("failed to load BPF program: %v", err)
317 }
318 defer done()
319
320 out, err := vm.Run([]byte{
321 0xff, 0xff, 0xff, 0xff,
322 0xff, 0xff, 0xff, 0xff,
323 0, 1, 2, 3,
324 })
325 if err != nil {
326 t.Fatalf("unexpected error while running program: %v", err)
327 }
328 if want, got := 4, out; want != got {
329 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
330 want, got)
331 }
332 }
333
334 func TestVMJumpIfBitsSet(t *testing.T) {
335 vm, done, err := testVM(t, []bpf.Instruction{
336 bpf.LoadAbsolute{
337 Off: 8,
338 Size: 2,
339 },
340 bpf.JumpIf{
341 Cond: bpf.JumpBitsSet,
342 Val: 0x1122,
343 SkipTrue: 1,
344 },
345 bpf.RetConstant{
346 Val: 0,
347 },
348 bpf.RetConstant{
349 Val: 10,
350 },
351 })
352 if err != nil {
353 t.Fatalf("failed to load BPF program: %v", err)
354 }
355 defer done()
356
357 out, err := vm.Run([]byte{
358 0xff, 0xff, 0xff, 0xff,
359 0xff, 0xff, 0xff, 0xff,
360 0x01, 0x02,
361 })
362 if err != nil {
363 t.Fatalf("unexpected error while running program: %v", err)
364 }
365 if want, got := 2, out; want != got {
366 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
367 want, got)
368 }
369 }
370
371 func TestVMJumpIfBitsNotSet(t *testing.T) {
372 vm, done, err := testVM(t, []bpf.Instruction{
373 bpf.LoadAbsolute{
374 Off: 8,
375 Size: 2,
376 },
377 bpf.JumpIf{
378 Cond: bpf.JumpBitsNotSet,
379 Val: 0x1221,
380 SkipTrue: 1,
381 },
382 bpf.RetConstant{
383 Val: 0,
384 },
385 bpf.RetConstant{
386 Val: 10,
387 },
388 })
389 if err != nil {
390 t.Fatalf("failed to load BPF program: %v", err)
391 }
392 defer done()
393
394 out, err := vm.Run([]byte{
395 0xff, 0xff, 0xff, 0xff,
396 0xff, 0xff, 0xff, 0xff,
397 0x01, 0x02,
398 })
399 if err != nil {
400 t.Fatalf("unexpected error while running program: %v", err)
401 }
402 if want, got := 2, out; want != got {
403 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
404 want, got)
405 }
406 }
407
408 func TestVMJumpIfXEqual(t *testing.T) {
409 vm, done, err := testVM(t, []bpf.Instruction{
410 bpf.LoadAbsolute{
411 Off: 8,
412 Size: 1,
413 },
414 bpf.LoadConstant{
415 Dst: bpf.RegX,
416 Val: 1,
417 },
418 bpf.JumpIfX{
419 Cond: bpf.JumpEqual,
420 SkipTrue: 1,
421 },
422 bpf.RetConstant{
423 Val: 0,
424 },
425 bpf.RetConstant{
426 Val: 9,
427 },
428 })
429 if err != nil {
430 t.Fatalf("failed to load BPF program: %v", err)
431 }
432 defer done()
433
434 out, err := vm.Run([]byte{
435 0xff, 0xff, 0xff, 0xff,
436 0xff, 0xff, 0xff, 0xff,
437 1,
438 })
439 if err != nil {
440 t.Fatalf("unexpected error while running program: %v", err)
441 }
442 if want, got := 1, out; want != got {
443 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
444 want, got)
445 }
446 }
447
448 func TestVMJumpIfXNotEqual(t *testing.T) {
449 vm, done, err := testVM(t, []bpf.Instruction{
450 bpf.LoadAbsolute{
451 Off: 8,
452 Size: 1,
453 },
454 bpf.LoadConstant{
455 Dst: bpf.RegX,
456 Val: 1,
457 },
458 bpf.JumpIfX{
459 Cond: bpf.JumpNotEqual,
460 SkipFalse: 1,
461 },
462 bpf.RetConstant{
463 Val: 0,
464 },
465 bpf.RetConstant{
466 Val: 9,
467 },
468 })
469 if err != nil {
470 t.Fatalf("failed to load BPF program: %v", err)
471 }
472 defer done()
473
474 out, err := vm.Run([]byte{
475 0xff, 0xff, 0xff, 0xff,
476 0xff, 0xff, 0xff, 0xff,
477 1,
478 })
479 if err != nil {
480 t.Fatalf("unexpected error while running program: %v", err)
481 }
482 if want, got := 1, out; want != got {
483 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
484 want, got)
485 }
486 }
487
488 func TestVMJumpIfXGreaterThan(t *testing.T) {
489 vm, done, err := testVM(t, []bpf.Instruction{
490 bpf.LoadAbsolute{
491 Off: 8,
492 Size: 4,
493 },
494 bpf.LoadConstant{
495 Dst: bpf.RegX,
496 Val: 0x00010202,
497 },
498 bpf.JumpIfX{
499 Cond: bpf.JumpGreaterThan,
500 SkipTrue: 1,
501 },
502 bpf.RetConstant{
503 Val: 0,
504 },
505 bpf.RetConstant{
506 Val: 12,
507 },
508 })
509 if err != nil {
510 t.Fatalf("failed to load BPF program: %v", err)
511 }
512 defer done()
513
514 out, err := vm.Run([]byte{
515 0xff, 0xff, 0xff, 0xff,
516 0xff, 0xff, 0xff, 0xff,
517 0, 1, 2, 3,
518 })
519 if err != nil {
520 t.Fatalf("unexpected error while running program: %v", err)
521 }
522 if want, got := 4, out; want != got {
523 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
524 want, got)
525 }
526 }
527
528 func TestVMJumpIfXLessThan(t *testing.T) {
529 vm, done, err := testVM(t, []bpf.Instruction{
530 bpf.LoadAbsolute{
531 Off: 8,
532 Size: 4,
533 },
534 bpf.LoadConstant{
535 Dst: bpf.RegX,
536 Val: 0xff010203,
537 },
538 bpf.JumpIfX{
539 Cond: bpf.JumpLessThan,
540 SkipTrue: 1,
541 },
542 bpf.RetConstant{
543 Val: 0,
544 },
545 bpf.RetConstant{
546 Val: 12,
547 },
548 })
549 if err != nil {
550 t.Fatalf("failed to load BPF program: %v", err)
551 }
552 defer done()
553
554 out, err := vm.Run([]byte{
555 0xff, 0xff, 0xff, 0xff,
556 0xff, 0xff, 0xff, 0xff,
557 0, 1, 2, 3,
558 })
559 if err != nil {
560 t.Fatalf("unexpected error while running program: %v", err)
561 }
562 if want, got := 4, out; want != got {
563 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
564 want, got)
565 }
566 }
567
568 func TestVMJumpIfXGreaterOrEqual(t *testing.T) {
569 vm, done, err := testVM(t, []bpf.Instruction{
570 bpf.LoadAbsolute{
571 Off: 8,
572 Size: 4,
573 },
574 bpf.LoadConstant{
575 Dst: bpf.RegX,
576 Val: 0x00010203,
577 },
578 bpf.JumpIfX{
579 Cond: bpf.JumpGreaterOrEqual,
580 SkipTrue: 1,
581 },
582 bpf.RetConstant{
583 Val: 0,
584 },
585 bpf.RetConstant{
586 Val: 12,
587 },
588 })
589 if err != nil {
590 t.Fatalf("failed to load BPF program: %v", err)
591 }
592 defer done()
593
594 out, err := vm.Run([]byte{
595 0xff, 0xff, 0xff, 0xff,
596 0xff, 0xff, 0xff, 0xff,
597 0, 1, 2, 3,
598 })
599 if err != nil {
600 t.Fatalf("unexpected error while running program: %v", err)
601 }
602 if want, got := 4, out; want != got {
603 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
604 want, got)
605 }
606 }
607
608 func TestVMJumpIfXLessOrEqual(t *testing.T) {
609 vm, done, err := testVM(t, []bpf.Instruction{
610 bpf.LoadAbsolute{
611 Off: 8,
612 Size: 4,
613 },
614 bpf.LoadConstant{
615 Dst: bpf.RegX,
616 Val: 0xff010203,
617 },
618 bpf.JumpIfX{
619 Cond: bpf.JumpLessOrEqual,
620 SkipTrue: 1,
621 },
622 bpf.RetConstant{
623 Val: 0,
624 },
625 bpf.RetConstant{
626 Val: 12,
627 },
628 })
629 if err != nil {
630 t.Fatalf("failed to load BPF program: %v", err)
631 }
632 defer done()
633
634 out, err := vm.Run([]byte{
635 0xff, 0xff, 0xff, 0xff,
636 0xff, 0xff, 0xff, 0xff,
637 0, 1, 2, 3,
638 })
639 if err != nil {
640 t.Fatalf("unexpected error while running program: %v", err)
641 }
642 if want, got := 4, out; want != got {
643 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
644 want, got)
645 }
646 }
647
648 func TestVMJumpIfXBitsSet(t *testing.T) {
649 vm, done, err := testVM(t, []bpf.Instruction{
650 bpf.LoadAbsolute{
651 Off: 8,
652 Size: 2,
653 },
654 bpf.LoadConstant{
655 Dst: bpf.RegX,
656 Val: 0x1122,
657 },
658 bpf.JumpIfX{
659 Cond: bpf.JumpBitsSet,
660 SkipTrue: 1,
661 },
662 bpf.RetConstant{
663 Val: 0,
664 },
665 bpf.RetConstant{
666 Val: 10,
667 },
668 })
669 if err != nil {
670 t.Fatalf("failed to load BPF program: %v", err)
671 }
672 defer done()
673
674 out, err := vm.Run([]byte{
675 0xff, 0xff, 0xff, 0xff,
676 0xff, 0xff, 0xff, 0xff,
677 0x01, 0x02,
678 })
679 if err != nil {
680 t.Fatalf("unexpected error while running program: %v", err)
681 }
682 if want, got := 2, out; want != got {
683 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
684 want, got)
685 }
686 }
687
688 func TestVMJumpIfXBitsNotSet(t *testing.T) {
689 vm, done, err := testVM(t, []bpf.Instruction{
690 bpf.LoadAbsolute{
691 Off: 8,
692 Size: 2,
693 },
694 bpf.LoadConstant{
695 Dst: bpf.RegX,
696 Val: 0x1221,
697 },
698 bpf.JumpIfX{
699 Cond: bpf.JumpBitsNotSet,
700 SkipTrue: 1,
701 },
702 bpf.RetConstant{
703 Val: 0,
704 },
705 bpf.RetConstant{
706 Val: 10,
707 },
708 })
709 if err != nil {
710 t.Fatalf("failed to load BPF program: %v", err)
711 }
712 defer done()
713
714 out, err := vm.Run([]byte{
715 0xff, 0xff, 0xff, 0xff,
716 0xff, 0xff, 0xff, 0xff,
717 0x01, 0x02,
718 })
719 if err != nil {
720 t.Fatalf("unexpected error while running program: %v", err)
721 }
722 if want, got := 2, out; want != got {
723 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
724 want, got)
725 }
726 }
727
View as plain text