1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
3
4 #include <argp.h>
5 #include "bench.h"
6 #include "crypto_bench.skel.h"
7
8 #define MAX_CIPHER_LEN 32
9 static char *input;
10 static struct crypto_ctx {
11 struct crypto_bench *skel;
12 int pfd;
13 } ctx;
14
15 static struct crypto_args {
16 u32 crypto_len;
17 char *crypto_cipher;
18 } args = {
19 .crypto_len = 16,
20 .crypto_cipher = "ecb(aes)",
21 };
22
23 enum {
24 ARG_CRYPTO_LEN = 5000,
25 ARG_CRYPTO_CIPHER = 5001,
26 };
27
28 static const struct argp_option opts[] = {
29 { "crypto-len", ARG_CRYPTO_LEN, "CRYPTO_LEN", 0,
30 "Set the length of crypto buffer" },
31 { "crypto-cipher", ARG_CRYPTO_CIPHER, "CRYPTO_CIPHER", 0,
32 "Set the cipher to use (default:ecb(aes))" },
33 {},
34 };
35
crypto_parse_arg(int key,char * arg,struct argp_state * state)36 static error_t crypto_parse_arg(int key, char *arg, struct argp_state *state)
37 {
38 switch (key) {
39 case ARG_CRYPTO_LEN:
40 args.crypto_len = strtoul(arg, NULL, 10);
41 if (!args.crypto_len ||
42 args.crypto_len > sizeof(ctx.skel->bss->dst)) {
43 fprintf(stderr, "Invalid crypto buffer len (limit %zu)\n",
44 sizeof(ctx.skel->bss->dst));
45 argp_usage(state);
46 }
47 break;
48 case ARG_CRYPTO_CIPHER:
49 args.crypto_cipher = strdup(arg);
50 if (!strlen(args.crypto_cipher) ||
51 strlen(args.crypto_cipher) > MAX_CIPHER_LEN) {
52 fprintf(stderr, "Invalid crypto cipher len (limit %d)\n",
53 MAX_CIPHER_LEN);
54 argp_usage(state);
55 }
56 break;
57 default:
58 return ARGP_ERR_UNKNOWN;
59 }
60
61 return 0;
62 }
63
64 const struct argp bench_crypto_argp = {
65 .options = opts,
66 .parser = crypto_parse_arg,
67 };
68
crypto_validate(void)69 static void crypto_validate(void)
70 {
71 if (env.consumer_cnt != 0) {
72 fprintf(stderr, "bpf crypto benchmark doesn't support consumer!\n");
73 exit(1);
74 }
75 }
76
crypto_setup(void)77 static void crypto_setup(void)
78 {
79 LIBBPF_OPTS(bpf_test_run_opts, opts);
80
81 int err, pfd;
82 size_t i, sz;
83
84 sz = args.crypto_len;
85 if (!sz || sz > sizeof(ctx.skel->bss->dst)) {
86 fprintf(stderr, "invalid encrypt buffer size (source %zu, target %zu)\n",
87 sz, sizeof(ctx.skel->bss->dst));
88 exit(1);
89 }
90
91 setup_libbpf();
92
93 ctx.skel = crypto_bench__open();
94 if (!ctx.skel) {
95 fprintf(stderr, "failed to open skeleton\n");
96 exit(1);
97 }
98
99 snprintf(ctx.skel->bss->cipher, 128, "%s", args.crypto_cipher);
100 memcpy(ctx.skel->bss->key, "12345678testtest", 16);
101 ctx.skel->bss->key_len = 16;
102 ctx.skel->bss->authsize = 0;
103
104 srandom(time(NULL));
105 input = malloc(sz);
106 for (i = 0; i < sz - 1; i++)
107 input[i] = '1' + random() % 9;
108 input[sz - 1] = '\0';
109
110 ctx.skel->rodata->len = args.crypto_len;
111
112 err = crypto_bench__load(ctx.skel);
113 if (err) {
114 fprintf(stderr, "failed to load skeleton\n");
115 crypto_bench__destroy(ctx.skel);
116 exit(1);
117 }
118
119 pfd = bpf_program__fd(ctx.skel->progs.crypto_setup);
120 if (pfd < 0) {
121 fprintf(stderr, "failed to get fd for setup prog\n");
122 crypto_bench__destroy(ctx.skel);
123 exit(1);
124 }
125
126 err = bpf_prog_test_run_opts(pfd, &opts);
127 if (err || ctx.skel->bss->status) {
128 fprintf(stderr, "failed to run setup prog: err %d, status %d\n",
129 err, ctx.skel->bss->status);
130 crypto_bench__destroy(ctx.skel);
131 exit(1);
132 }
133 }
134
crypto_encrypt_setup(void)135 static void crypto_encrypt_setup(void)
136 {
137 crypto_setup();
138 ctx.pfd = bpf_program__fd(ctx.skel->progs.crypto_encrypt);
139 }
140
crypto_decrypt_setup(void)141 static void crypto_decrypt_setup(void)
142 {
143 crypto_setup();
144 ctx.pfd = bpf_program__fd(ctx.skel->progs.crypto_decrypt);
145 }
146
crypto_measure(struct bench_res * res)147 static void crypto_measure(struct bench_res *res)
148 {
149 res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
150 }
151
crypto_producer(void * unused)152 static void *crypto_producer(void *unused)
153 {
154 LIBBPF_OPTS(bpf_test_run_opts, opts,
155 .repeat = 64,
156 .data_in = input,
157 .data_size_in = args.crypto_len,
158 );
159
160 while (true)
161 (void)bpf_prog_test_run_opts(ctx.pfd, &opts);
162 return NULL;
163 }
164
165 const struct bench bench_crypto_encrypt = {
166 .name = "crypto-encrypt",
167 .argp = &bench_crypto_argp,
168 .validate = crypto_validate,
169 .setup = crypto_encrypt_setup,
170 .producer_thread = crypto_producer,
171 .measure = crypto_measure,
172 .report_progress = hits_drops_report_progress,
173 .report_final = hits_drops_report_final,
174 };
175
176 const struct bench bench_crypto_decrypt = {
177 .name = "crypto-decrypt",
178 .argp = &bench_crypto_argp,
179 .validate = crypto_validate,
180 .setup = crypto_decrypt_setup,
181 .producer_thread = crypto_producer,
182 .measure = crypto_measure,
183 .report_progress = hits_drops_report_progress,
184 .report_final = hits_drops_report_final,
185 };
186