Skip to content

Commit 715dddb

Browse files
ecree-solarflaredavem330
authored andcommitted
selftests/bpf: add a test to test_align
New test adds 14 to the unknown value before adding to the packet pointer, meaning there's no 'fixed offset' field and instead we add into the var_off, yielding a '4n+2' value. Signed-off-by: Edward Cree <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9fafa80 commit 715dddb

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

tools/testing/selftests/bpf/test_align.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,73 @@ static struct bpf_align_test tests[] = {
374374
{33, "R5=pkt(id=4,off=18,r=22,umax_value=2040,var_off=(0x0; 0x7fc))"},
375375
},
376376
},
377+
{
378+
.descr = "packet variable offset 2",
379+
.insns = {
380+
/* Create an unknown offset, (4n+2)-aligned */
381+
LOAD_UNKNOWN(BPF_REG_6),
382+
BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 2),
383+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 14),
384+
/* Add it to the packet pointer */
385+
BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
386+
BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
387+
/* Check bounds and perform a read */
388+
BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
389+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
390+
BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
391+
BPF_EXIT_INSN(),
392+
BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_5, 0),
393+
/* Make a (4n) offset from the value we just read */
394+
BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 0xff),
395+
BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 2),
396+
/* Add it to the packet pointer */
397+
BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
398+
/* Check bounds and perform a read */
399+
BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
400+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
401+
BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
402+
BPF_EXIT_INSN(),
403+
BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_5, 0),
404+
BPF_MOV64_IMM(BPF_REG_0, 0),
405+
BPF_EXIT_INSN(),
406+
},
407+
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
408+
.matches = {
409+
/* Calculated offset in R6 has unknown value, but known
410+
* alignment of 4.
411+
*/
412+
{8, "R2=pkt(id=0,off=0,r=8,imm=0)"},
413+
{8, "R6=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
414+
/* Adding 14 makes R6 be (4n+2) */
415+
{9, "R6=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"},
416+
/* Packet pointer has (4n+2) offset */
417+
{11, "R5=pkt(id=1,off=0,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"},
418+
{13, "R4=pkt(id=1,off=4,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"},
419+
/* At the time the word size load is performed from R5,
420+
* its total fixed offset is NET_IP_ALIGN + reg->off (0)
421+
* which is 2. Then the variable offset is (4n+2), so
422+
* the total offset is 4-byte aligned and meets the
423+
* load's requirements.
424+
*/
425+
{15, "R5=pkt(id=1,off=0,r=4,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"},
426+
/* Newly read value in R6 was shifted left by 2, so has
427+
* known alignment of 4.
428+
*/
429+
{18, "R6=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
430+
/* Added (4n) to packet pointer's (4n+2) var_off, giving
431+
* another (4n+2).
432+
*/
433+
{19, "R5=pkt(id=2,off=0,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc))"},
434+
{21, "R4=pkt(id=2,off=4,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc))"},
435+
/* At the time the word size load is performed from R5,
436+
* its total fixed offset is NET_IP_ALIGN + reg->off (0)
437+
* which is 2. Then the variable offset is (4n+2), so
438+
* the total offset is 4-byte aligned and meets the
439+
* load's requirements.
440+
*/
441+
{23, "R5=pkt(id=2,off=0,r=4,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc))"},
442+
},
443+
},
377444
};
378445

379446
static int probe_filter_length(const struct bpf_insn *fp)

0 commit comments

Comments
 (0)