]>
git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - tools/testing/selftests/bpf/test_tag.c
13 #include <sys/socket.h>
14 #include <sys/resource.h>
16 #include <linux/filter.h>
17 #include <linux/bpf.h>
18 #include <linux/if_alg.h>
22 #include "../../../include/linux/filter.h"
24 static struct bpf_insn prog
[BPF_MAXINSNS
];
26 static void bpf_gen_imm_prog(unsigned int insns
, int fd_map
)
31 for (i
= 0; i
< insns
; i
++)
32 prog
[i
] = BPF_ALU64_IMM(BPF_MOV
, i
% BPF_REG_10
, rand());
33 prog
[i
- 1] = BPF_EXIT_INSN();
36 static void bpf_gen_map_prog(unsigned int insns
, int fd_map
)
40 for (i
= 0; i
+ 1 < insns
; i
+= 2) {
41 struct bpf_insn tmp
[] = {
42 BPF_LD_MAP_FD(j
++ % BPF_REG_10
, fd_map
)
45 memcpy(&prog
[i
], tmp
, sizeof(tmp
));
48 prog
[insns
- 2] = BPF_ALU64_IMM(BPF_MOV
, i
% BPF_REG_10
, 42);
49 prog
[insns
- 1] = BPF_EXIT_INSN();
52 static int bpf_try_load_prog(int insns
, int fd_map
,
53 void (*bpf_filler
)(unsigned int insns
,
58 bpf_filler(insns
, fd_map
);
59 fd_prog
= bpf_load_program(BPF_PROG_TYPE_SCHED_CLS
, prog
, insns
, "", 0,
67 static int __hex2bin(char ch
)
69 if ((ch
>= '0') && (ch
<= '9'))
72 if ((ch
>= 'a') && (ch
<= 'f'))
77 static int hex2bin(uint8_t *dst
, const char *src
, size_t count
)
80 int hi
= __hex2bin(*src
++);
81 int lo
= __hex2bin(*src
++);
83 if ((hi
< 0) || (lo
< 0))
85 *dst
++ = (hi
<< 4) | lo
;
90 static void tag_from_fdinfo(int fd_prog
, uint8_t *tag
, uint32_t len
)
92 const int prefix_len
= sizeof("prog_tag:\t") - 1;
97 snprintf(buff
, sizeof(buff
), "/proc/%d/fdinfo/%d", getpid(),
99 fp
= fopen(buff
, "r");
102 while (fgets(buff
, sizeof(buff
), fp
)) {
103 if (strncmp(buff
, "prog_tag:\t", prefix_len
))
105 ret
= hex2bin(tag
, buff
+ prefix_len
, len
);
113 static void tag_from_alg(int insns
, uint8_t *tag
, uint32_t len
)
115 static const struct sockaddr_alg alg
= {
116 .salg_family
= AF_ALG
,
120 int fd_base
, fd_alg
, ret
;
123 fd_base
= socket(AF_ALG
, SOCK_SEQPACKET
, 0);
126 ret
= bind(fd_base
, (struct sockaddr
*)&alg
, sizeof(alg
));
129 fd_alg
= accept(fd_base
, NULL
, 0);
132 insns
*= sizeof(struct bpf_insn
);
133 size
= write(fd_alg
, prog
, insns
);
134 assert(size
== insns
);
136 size
= read(fd_alg
, tag
, len
);
143 static void tag_dump(const char *prefix
, uint8_t *tag
, uint32_t len
)
147 printf("%s", prefix
);
148 for (i
= 0; i
< len
; i
++)
149 printf("%02x", tag
[i
]);
153 static void tag_exit_report(int insns
, int fd_map
, uint8_t *ftag
,
154 uint8_t *atag
, uint32_t len
)
156 printf("Program tag mismatch for %d insns%s!\n", insns
,
157 fd_map
< 0 ? "" : " with map");
159 tag_dump(" fdinfo result: ", ftag
, len
);
160 tag_dump(" af_alg result: ", atag
, len
);
164 static void do_test(uint32_t *tests
, int start_insns
, int fd_map
,
165 void (*bpf_filler
)(unsigned int insns
, int fd
))
169 for (i
= start_insns
; i
<= BPF_MAXINSNS
; i
++) {
170 uint8_t ftag
[8], atag
[sizeof(ftag
)];
172 fd_prog
= bpf_try_load_prog(i
, fd_map
, bpf_filler
);
173 tag_from_fdinfo(fd_prog
, ftag
, sizeof(ftag
));
174 tag_from_alg(i
, atag
, sizeof(atag
));
175 if (memcmp(ftag
, atag
, sizeof(ftag
)))
176 tag_exit_report(i
, fd_map
, ftag
, atag
, sizeof(ftag
));
186 struct rlimit rinf
= { RLIM_INFINITY
, RLIM_INFINITY
};
190 setrlimit(RLIMIT_MEMLOCK
, &rinf
);
191 fd_map
= bpf_create_map(BPF_MAP_TYPE_HASH
, sizeof(int),
192 sizeof(int), 1, BPF_F_NO_PREALLOC
);
195 for (i
= 0; i
< 5; i
++) {
196 do_test(&tests
, 2, -1, bpf_gen_imm_prog
);
197 do_test(&tests
, 3, fd_map
, bpf_gen_map_prog
);
200 printf("test_tag: OK (%u tests)\n", tests
);