|
@@ -27,6 +27,11 @@
|
|
#define MAX_INSNS 512
|
|
#define MAX_INSNS 512
|
|
#define MAX_MATCHES 16
|
|
#define MAX_MATCHES 16
|
|
|
|
|
|
|
|
+struct bpf_reg_match {
|
|
|
|
+ unsigned int line;
|
|
|
|
+ const char *match;
|
|
|
|
+};
|
|
|
|
+
|
|
struct bpf_align_test {
|
|
struct bpf_align_test {
|
|
const char *descr;
|
|
const char *descr;
|
|
struct bpf_insn insns[MAX_INSNS];
|
|
struct bpf_insn insns[MAX_INSNS];
|
|
@@ -36,10 +41,14 @@ struct bpf_align_test {
|
|
REJECT
|
|
REJECT
|
|
} result;
|
|
} result;
|
|
enum bpf_prog_type prog_type;
|
|
enum bpf_prog_type prog_type;
|
|
- const char *matches[MAX_MATCHES];
|
|
|
|
|
|
+ /* Matches must be in order of increasing line */
|
|
|
|
+ struct bpf_reg_match matches[MAX_MATCHES];
|
|
};
|
|
};
|
|
|
|
|
|
static struct bpf_align_test tests[] = {
|
|
static struct bpf_align_test tests[] = {
|
|
|
|
+ /* Four tests of known constants. These aren't staggeringly
|
|
|
|
+ * interesting since we track exact values now.
|
|
|
|
+ */
|
|
{
|
|
{
|
|
.descr = "mov",
|
|
.descr = "mov",
|
|
.insns = {
|
|
.insns = {
|
|
@@ -53,11 +62,13 @@ static struct bpf_align_test tests[] = {
|
|
},
|
|
},
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.matches = {
|
|
.matches = {
|
|
- "1: R1=ctx R3=imm2,min_value=2,max_value=2,min_align=2 R10=fp",
|
|
|
|
- "2: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
|
|
|
|
- "3: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
|
|
|
|
- "4: R1=ctx R3=imm16,min_value=16,max_value=16,min_align=16 R10=fp",
|
|
|
|
- "5: R1=ctx R3=imm32,min_value=32,max_value=32,min_align=32 R10=fp",
|
|
|
|
|
|
+ {1, "R1=ctx(id=0,off=0,imm=0)"},
|
|
|
|
+ {1, "R10=fp0"},
|
|
|
|
+ {1, "R3=inv2"},
|
|
|
|
+ {2, "R3=inv4"},
|
|
|
|
+ {3, "R3=inv8"},
|
|
|
|
+ {4, "R3=inv16"},
|
|
|
|
+ {5, "R3=inv32"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
{
|
|
@@ -79,17 +90,19 @@ static struct bpf_align_test tests[] = {
|
|
},
|
|
},
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.matches = {
|
|
.matches = {
|
|
- "1: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R10=fp",
|
|
|
|
- "2: R1=ctx R3=imm2,min_value=2,max_value=2,min_align=2 R10=fp",
|
|
|
|
- "3: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
|
|
|
|
- "4: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
|
|
|
|
- "5: R1=ctx R3=imm16,min_value=16,max_value=16,min_align=16 R10=fp",
|
|
|
|
- "6: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R10=fp",
|
|
|
|
- "7: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm32,min_value=32,max_value=32,min_align=32 R10=fp",
|
|
|
|
- "8: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm16,min_value=16,max_value=16,min_align=16 R10=fp",
|
|
|
|
- "9: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
|
|
|
|
- "10: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
|
|
|
|
- "11: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm2,min_value=2,max_value=2,min_align=2 R10=fp",
|
|
|
|
|
|
+ {1, "R1=ctx(id=0,off=0,imm=0)"},
|
|
|
|
+ {1, "R10=fp0"},
|
|
|
|
+ {1, "R3=inv1"},
|
|
|
|
+ {2, "R3=inv2"},
|
|
|
|
+ {3, "R3=inv4"},
|
|
|
|
+ {4, "R3=inv8"},
|
|
|
|
+ {5, "R3=inv16"},
|
|
|
|
+ {6, "R3=inv1"},
|
|
|
|
+ {7, "R4=inv32"},
|
|
|
|
+ {8, "R4=inv16"},
|
|
|
|
+ {9, "R4=inv8"},
|
|
|
|
+ {10, "R4=inv4"},
|
|
|
|
+ {11, "R4=inv2"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
{
|
|
@@ -106,12 +119,14 @@ static struct bpf_align_test tests[] = {
|
|
},
|
|
},
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.matches = {
|
|
.matches = {
|
|
- "1: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
|
|
|
|
- "2: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=4 R10=fp",
|
|
|
|
- "3: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R10=fp",
|
|
|
|
- "4: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
|
|
|
|
- "5: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm12,min_value=12,max_value=12,min_align=4 R10=fp",
|
|
|
|
- "6: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm14,min_value=14,max_value=14,min_align=2 R10=fp",
|
|
|
|
|
|
+ {1, "R1=ctx(id=0,off=0,imm=0)"},
|
|
|
|
+ {1, "R10=fp0"},
|
|
|
|
+ {1, "R3=inv4"},
|
|
|
|
+ {2, "R3=inv8"},
|
|
|
|
+ {3, "R3=inv10"},
|
|
|
|
+ {4, "R4=inv8"},
|
|
|
|
+ {5, "R4=inv12"},
|
|
|
|
+ {6, "R4=inv14"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
{
|
|
@@ -126,13 +141,16 @@ static struct bpf_align_test tests[] = {
|
|
},
|
|
},
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.matches = {
|
|
.matches = {
|
|
- "1: R1=ctx R3=imm7,min_value=7,max_value=7,min_align=1 R10=fp",
|
|
|
|
- "2: R1=ctx R3=imm7,min_value=7,max_value=7,min_align=1 R10=fp",
|
|
|
|
- "3: R1=ctx R3=imm14,min_value=14,max_value=14,min_align=2 R10=fp",
|
|
|
|
- "4: R1=ctx R3=imm56,min_value=56,max_value=56,min_align=4 R10=fp",
|
|
|
|
|
|
+ {1, "R1=ctx(id=0,off=0,imm=0)"},
|
|
|
|
+ {1, "R10=fp0"},
|
|
|
|
+ {1, "R3=inv7"},
|
|
|
|
+ {2, "R3=inv7"},
|
|
|
|
+ {3, "R3=inv14"},
|
|
|
|
+ {4, "R3=inv56"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
|
|
|
|
+ /* Tests using unknown values */
|
|
#define PREP_PKT_POINTERS \
|
|
#define PREP_PKT_POINTERS \
|
|
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, \
|
|
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, \
|
|
offsetof(struct __sk_buff, data)), \
|
|
offsetof(struct __sk_buff, data)), \
|
|
@@ -166,17 +184,19 @@ static struct bpf_align_test tests[] = {
|
|
},
|
|
},
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.matches = {
|
|
.matches = {
|
|
- "7: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R10=fp",
|
|
|
|
- "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv55,min_align=2 R10=fp",
|
|
|
|
- "9: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv54,min_align=4 R10=fp",
|
|
|
|
- "10: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv53,min_align=8 R10=fp",
|
|
|
|
- "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv52,min_align=16 R10=fp",
|
|
|
|
- "18: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv56 R10=fp",
|
|
|
|
- "19: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv51,min_align=32 R10=fp",
|
|
|
|
- "20: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv52,min_align=16 R10=fp",
|
|
|
|
- "21: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv53,min_align=8 R10=fp",
|
|
|
|
- "22: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv54,min_align=4 R10=fp",
|
|
|
|
- "23: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv55,min_align=2 R10=fp",
|
|
|
|
|
|
+ {7, "R0=pkt(id=0,off=8,r=8,imm=0)"},
|
|
|
|
+ {7, "R3=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
|
|
|
|
+ {8, "R3=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},
|
|
|
|
+ {9, "R3=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
|
|
+ {10, "R3=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},
|
|
|
|
+ {11, "R3=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},
|
|
|
|
+ {18, "R3=pkt_end(id=0,off=0,imm=0)"},
|
|
|
|
+ {18, "R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
|
|
|
|
+ {19, "R4=inv(id=0,umax_value=8160,var_off=(0x0; 0x1fe0))"},
|
|
|
|
+ {20, "R4=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},
|
|
|
|
+ {21, "R4=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},
|
|
|
|
+ {22, "R4=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
|
|
+ {23, "R4=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
{
|
|
@@ -197,16 +217,16 @@ static struct bpf_align_test tests[] = {
|
|
},
|
|
},
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.matches = {
|
|
.matches = {
|
|
- "7: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R10=fp",
|
|
|
|
- "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
|
|
|
|
- "9: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv55,min_align=1 R10=fp",
|
|
|
|
- "10: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
|
|
|
|
- "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv54,min_align=2 R10=fp",
|
|
|
|
- "12: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
|
|
|
|
- "13: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv53,min_align=4 R10=fp",
|
|
|
|
- "14: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
|
|
|
|
- "15: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv52,min_align=8 R10=fp",
|
|
|
|
- "16: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv50,min_align=8 R10=fp"
|
|
|
|
|
|
+ {7, "R3=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
|
|
|
|
+ {8, "R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
|
|
|
|
+ {9, "R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
|
|
|
|
+ {10, "R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
|
|
|
|
+ {11, "R4=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},
|
|
|
|
+ {12, "R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
|
|
|
|
+ {13, "R4=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
|
|
+ {14, "R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
|
|
|
|
+ {15, "R4=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},
|
|
|
|
+ {16, "R4=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
{
|
|
@@ -237,12 +257,14 @@ static struct bpf_align_test tests[] = {
|
|
},
|
|
},
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
|
.matches = {
|
|
.matches = {
|
|
- "4: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R5=pkt(id=0,off=0,r=0) R10=fp",
|
|
|
|
- "5: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R5=pkt(id=0,off=14,r=0) R10=fp",
|
|
|
|
- "6: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R4=pkt(id=0,off=14,r=0) R5=pkt(id=0,off=14,r=0) R10=fp",
|
|
|
|
- "10: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv56 R5=pkt(id=0,off=14,r=18) R10=fp",
|
|
|
|
- "14: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv48 R5=pkt(id=0,off=14,r=18) R10=fp",
|
|
|
|
- "15: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv48 R5=pkt(id=0,off=14,r=18) R10=fp",
|
|
|
|
|
|
+ {4, "R5=pkt(id=0,off=0,r=0,imm=0)"},
|
|
|
|
+ {5, "R5=pkt(id=0,off=14,r=0,imm=0)"},
|
|
|
|
+ {6, "R4=pkt(id=0,off=14,r=0,imm=0)"},
|
|
|
|
+ {10, "R2=pkt(id=0,off=0,r=18,imm=0)"},
|
|
|
|
+ {10, "R5=pkt(id=0,off=14,r=18,imm=0)"},
|
|
|
|
+ {10, "R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
|
|
|
|
+ {14, "R4=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))"},
|
|
|
|
+ {15, "R4=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
{
|
|
@@ -297,62 +319,59 @@ static struct bpf_align_test tests[] = {
|
|
/* Calculated offset in R6 has unknown value, but known
|
|
/* Calculated offset in R6 has unknown value, but known
|
|
* alignment of 4.
|
|
* alignment of 4.
|
|
*/
|
|
*/
|
|
- "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R6=inv54,min_align=4 R10=fp",
|
|
|
|
-
|
|
|
|
- /* Offset is added to packet pointer R5, resulting in known
|
|
|
|
- * auxiliary alignment and offset.
|
|
|
|
|
|
+ {8, "R2=pkt(id=0,off=0,r=8,imm=0)"},
|
|
|
|
+ {8, "R6=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
|
|
+ /* Offset is added to packet pointer R5, resulting in
|
|
|
|
+ * known fixed offset, and variable offset from R6.
|
|
*/
|
|
*/
|
|
- "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R5=pkt(id=1,off=0,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
|
|
|
|
-
|
|
|
|
|
|
+ {11, "R5=pkt(id=1,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
/* At the time the word size load is performed from R5,
|
|
/* At the time the word size load is performed from R5,
|
|
* it's total offset is NET_IP_ALIGN + reg->off (0) +
|
|
* it's total offset is NET_IP_ALIGN + reg->off (0) +
|
|
* reg->aux_off (14) which is 16. Then the variable
|
|
* reg->aux_off (14) which is 16. Then the variable
|
|
* offset is considered using reg->aux_off_align which
|
|
* offset is considered using reg->aux_off_align which
|
|
* is 4 and meets the load's requirements.
|
|
* is 4 and meets the load's requirements.
|
|
*/
|
|
*/
|
|
- "15: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=1,off=4,r=4),aux_off=14,aux_off_align=4 R5=pkt(id=1,off=0,r=4),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+ {15, "R4=pkt(id=1,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
|
|
+ {15, "R5=pkt(id=1,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
/* Variable offset is added to R5 packet pointer,
|
|
/* Variable offset is added to R5 packet pointer,
|
|
* resulting in auxiliary alignment of 4.
|
|
* resulting in auxiliary alignment of 4.
|
|
*/
|
|
*/
|
|
- "18: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off=14,aux_off_align=4 R5=pkt(id=2,off=0,r=0),aux_off_align=4 R6=inv54,min_align=4 R10=fp",
|
|
|
|
-
|
|
|
|
|
|
+ {18, "R5=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
/* Constant offset is added to R5, resulting in
|
|
/* Constant offset is added to R5, resulting in
|
|
* reg->off of 14.
|
|
* reg->off of 14.
|
|
*/
|
|
*/
|
|
- "19: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off=14,aux_off_align=4 R5=pkt(id=2,off=14,r=0),aux_off_align=4 R6=inv54,min_align=4 R10=fp",
|
|
|
|
-
|
|
|
|
|
|
+ {19, "R5=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
/* At the time the word size load is performed from R5,
|
|
/* At the time the word size load is performed from R5,
|
|
- * it's total offset is NET_IP_ALIGN + reg->off (14) which
|
|
|
|
- * is 16. Then the variable offset is considered using
|
|
|
|
- * reg->aux_off_align which is 4 and meets the load's
|
|
|
|
- * requirements.
|
|
|
|
|
|
+ * its total fixed offset is NET_IP_ALIGN + reg->off
|
|
|
|
+ * (14) which is 16. Then the variable offset is 4-byte
|
|
|
|
+ * aligned, so the total offset is 4-byte aligned and
|
|
|
|
+ * meets the load's requirements.
|
|
*/
|
|
*/
|
|
- "23: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=2,off=18,r=18),aux_off_align=4 R5=pkt(id=2,off=14,r=18),aux_off_align=4 R6=inv54,min_align=4 R10=fp",
|
|
|
|
-
|
|
|
|
|
|
+ {23, "R4=pkt(id=2,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
|
|
+ {23, "R5=pkt(id=2,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
/* Constant offset is added to R5 packet pointer,
|
|
/* Constant offset is added to R5 packet pointer,
|
|
* resulting in reg->off value of 14.
|
|
* resulting in reg->off value of 14.
|
|
*/
|
|
*/
|
|
- "26: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=0,off=14,r=8) R6=inv54,min_align=4 R10=fp",
|
|
|
|
- /* Variable offset is added to R5, resulting in an
|
|
|
|
- * auxiliary offset of 14, and an auxiliary alignment of 4.
|
|
|
|
|
|
+ {26, "R5=pkt(id=0,off=14,r=8"},
|
|
|
|
+ /* Variable offset is added to R5, resulting in a
|
|
|
|
+ * variable offset of (4n).
|
|
*/
|
|
*/
|
|
- "27: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=3,off=0,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
|
|
|
|
- /* Constant is added to R5 again, setting reg->off to 4. */
|
|
|
|
- "28: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=3,off=4,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
|
|
|
|
- /* And once more we add a variable, which causes an accumulation
|
|
|
|
- * of reg->off into reg->aux_off_align, with resulting value of
|
|
|
|
- * 18. The auxiliary alignment stays at 4.
|
|
|
|
|
|
+ {27, "R5=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
|
|
+ /* Constant is added to R5 again, setting reg->off to 18. */
|
|
|
|
+ {28, "R5=pkt(id=3,off=18,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
|
|
|
|
+ /* And once more we add a variable; resulting var_off
|
|
|
|
+ * is still (4n), fixed offset is not changed.
|
|
|
|
+ * Also, we create a new reg->id.
|
|
*/
|
|
*/
|
|
- "29: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=4,off=0,r=0),aux_off=18,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
|
|
|
|
|
|
+ {29, "R5=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc))"},
|
|
/* At the time the word size load is performed from R5,
|
|
/* At the time the word size load is performed from R5,
|
|
- * it's total offset is NET_IP_ALIGN + reg->off (0) +
|
|
|
|
- * reg->aux_off (18) which is 20. Then the variable offset
|
|
|
|
- * is considered using reg->aux_off_align which is 4 and meets
|
|
|
|
- * the load's requirements.
|
|
|
|
|
|
+ * its total fixed offset is NET_IP_ALIGN + reg->off (18)
|
|
|
|
+ * which is 20. Then the variable offset is (4n), so
|
|
|
|
+ * the total offset is 4-byte aligned and meets the
|
|
|
|
+ * load's requirements.
|
|
*/
|
|
*/
|
|
- "33: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=4,off=4,r=4),aux_off=18,aux_off_align=4 R5=pkt(id=4,off=0,r=4),aux_off=18,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
|
|
|
|
|
|
+ {33, "R4=pkt(id=4,off=22,r=22,umax_value=2040,var_off=(0x0; 0x7fc))"},
|
|
|
|
+ {33, "R5=pkt(id=4,off=18,r=22,umax_value=2040,var_off=(0x0; 0x7fc))"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
};
|
|
@@ -373,6 +392,9 @@ static int do_test_single(struct bpf_align_test *test)
|
|
{
|
|
{
|
|
struct bpf_insn *prog = test->insns;
|
|
struct bpf_insn *prog = test->insns;
|
|
int prog_type = test->prog_type;
|
|
int prog_type = test->prog_type;
|
|
|
|
+ char bpf_vlog_copy[32768];
|
|
|
|
+ const char *line_ptr;
|
|
|
|
+ int cur_line = -1;
|
|
int prog_len, i;
|
|
int prog_len, i;
|
|
int fd_prog;
|
|
int fd_prog;
|
|
int ret;
|
|
int ret;
|
|
@@ -387,14 +409,31 @@ static int do_test_single(struct bpf_align_test *test)
|
|
ret = 1;
|
|
ret = 1;
|
|
} else {
|
|
} else {
|
|
ret = 0;
|
|
ret = 0;
|
|
|
|
+ /* We make a local copy so that we can strtok() it */
|
|
|
|
+ strncpy(bpf_vlog_copy, bpf_vlog, sizeof(bpf_vlog_copy));
|
|
|
|
+ line_ptr = strtok(bpf_vlog_copy, "\n");
|
|
for (i = 0; i < MAX_MATCHES; i++) {
|
|
for (i = 0; i < MAX_MATCHES; i++) {
|
|
- const char *t, *m = test->matches[i];
|
|
|
|
|
|
+ struct bpf_reg_match m = test->matches[i];
|
|
|
|
|
|
- if (!m)
|
|
|
|
|
|
+ if (!m.match)
|
|
break;
|
|
break;
|
|
- t = strstr(bpf_vlog, m);
|
|
|
|
- if (!t) {
|
|
|
|
- printf("Failed to find match: %s\n", m);
|
|
|
|
|
|
+ while (line_ptr) {
|
|
|
|
+ cur_line = -1;
|
|
|
|
+ sscanf(line_ptr, "%u: ", &cur_line);
|
|
|
|
+ if (cur_line == m.line)
|
|
|
|
+ break;
|
|
|
|
+ line_ptr = strtok(NULL, "\n");
|
|
|
|
+ }
|
|
|
|
+ if (!line_ptr) {
|
|
|
|
+ printf("Failed to find line %u for match: %s\n",
|
|
|
|
+ m.line, m.match);
|
|
|
|
+ ret = 1;
|
|
|
|
+ printf("%s", bpf_vlog);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (!strstr(line_ptr, m.match)) {
|
|
|
|
+ printf("Failed to find match %u: %s\n",
|
|
|
|
+ m.line, m.match);
|
|
ret = 1;
|
|
ret = 1;
|
|
printf("%s", bpf_vlog);
|
|
printf("%s", bpf_vlog);
|
|
break;
|
|
break;
|