Skip to content

Commit 0dcbbf6

Browse files
jrfastabborkmann
authored andcommitted
bpf: sockmap sample test for bpf_msg_pull_data
This adds an option to test the msg_pull_data helper. This uses two options txmsg_start and txmsg_end to let the user specify start and end bytes to pull. The options can be used with txmsg_apply, txmsg_cork options as well as with any of the basic tests, txmsg, txmsg_redir and txmsg_drop (plus noisy variants) to run pull_data inline with those tests. By giving user direct control over the variables we can easily do negative testing as well as positive tests. Signed-off-by: John Fastabend <john.fastabend@gmail.com> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent e6373ce commit 0dcbbf6

4 files changed

Lines changed: 101 additions & 15 deletions

File tree

samples/sockmap/sockmap_kern.c

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ struct bpf_map_def SEC("maps") sock_cork_bytes = {
7171
.max_entries = 1
7272
};
7373

74+
struct bpf_map_def SEC("maps") sock_pull_bytes = {
75+
.type = BPF_MAP_TYPE_ARRAY,
76+
.key_size = sizeof(int),
77+
.value_size = sizeof(int),
78+
.max_entries = 2
79+
};
80+
81+
7482
SEC("sk_skb1")
7583
int bpf_prog1(struct __sk_buff *skb)
7684
{
@@ -137,67 +145,104 @@ int bpf_sockmap(struct bpf_sock_ops *skops)
137145
SEC("sk_msg1")
138146
int bpf_prog4(struct sk_msg_md *msg)
139147
{
140-
int *bytes, zero = 0;
148+
int *bytes, zero = 0, one = 1;
149+
int *start, *end;
141150

142151
bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
143152
if (bytes)
144153
bpf_msg_apply_bytes(msg, *bytes);
145154
bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
146155
if (bytes)
147156
bpf_msg_cork_bytes(msg, *bytes);
157+
start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
158+
end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
159+
if (start && end)
160+
bpf_msg_pull_data(msg, *start, *end, 0);
148161
return SK_PASS;
149162
}
150163

151164
SEC("sk_msg2")
152165
int bpf_prog5(struct sk_msg_md *msg)
153166
{
154-
void *data_end = (void *)(long) msg->data_end;
155-
void *data = (void *)(long) msg->data;
156-
int *bytes, err1 = -1, err2 = -1, zero = 0;
167+
int err1 = -1, err2 = -1, zero = 0, one = 1;
168+
int *bytes, *start, *end, len1, len2;
157169

158170
bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
159171
if (bytes)
160172
err1 = bpf_msg_apply_bytes(msg, *bytes);
161173
bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
162174
if (bytes)
163175
err2 = bpf_msg_cork_bytes(msg, *bytes);
176+
len1 = (__u64)msg->data_end - (__u64)msg->data;
177+
start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
178+
end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
179+
if (start && end) {
180+
int err;
181+
182+
bpf_printk("sk_msg2: pull(%i:%i)\n",
183+
start ? *start : 0, end ? *end : 0);
184+
err = bpf_msg_pull_data(msg, *start, *end, 0);
185+
if (err)
186+
bpf_printk("sk_msg2: pull_data err %i\n",
187+
err);
188+
len2 = (__u64)msg->data_end - (__u64)msg->data;
189+
bpf_printk("sk_msg2: length update %i->%i\n",
190+
len1, len2);
191+
}
164192
bpf_printk("sk_msg2: data length %i err1 %i err2 %i\n",
165-
(__u64)data_end - (__u64)data, err1, err2);
193+
len1, err1, err2);
166194
return SK_PASS;
167195
}
168196

169197
SEC("sk_msg3")
170198
int bpf_prog6(struct sk_msg_md *msg)
171199
{
172-
void *data_end = (void *)(long) msg->data_end;
173-
void *data = (void *)(long) msg->data;
174-
int *bytes, zero = 0;
200+
int *bytes, zero = 0, one = 1;
201+
int *start, *end;
175202

176203
bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
177204
if (bytes)
178205
bpf_msg_apply_bytes(msg, *bytes);
179206
bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
180207
if (bytes)
181208
bpf_msg_cork_bytes(msg, *bytes);
209+
start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
210+
end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
211+
if (start && end)
212+
bpf_msg_pull_data(msg, *start, *end, 0);
182213
return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0);
183214
}
184215

185216
SEC("sk_msg4")
186217
int bpf_prog7(struct sk_msg_md *msg)
187218
{
188-
void *data_end = (void *)(long) msg->data_end;
189-
void *data = (void *)(long) msg->data;
190-
int *bytes, err1 = 0, err2 = 0, zero = 0;
219+
int err1 = 0, err2 = 0, zero = 0, one = 1;
220+
int *bytes, *start, *end, len1, len2;
191221

192222
bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
193223
if (bytes)
194224
err1 = bpf_msg_apply_bytes(msg, *bytes);
195225
bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
196226
if (bytes)
197227
err2 = bpf_msg_cork_bytes(msg, *bytes);
198-
228+
len1 = (__u64)msg->data_end - (__u64)msg->data;
229+
start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
230+
end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
231+
if (start && end) {
232+
int err;
233+
234+
bpf_printk("sk_msg2: pull(%i:%i)\n",
235+
start ? *start : 0, end ? *end : 0);
236+
err = bpf_msg_pull_data(msg, *start, *end, 0);
237+
if (err)
238+
bpf_printk("sk_msg2: pull_data err %i\n",
239+
err);
240+
len2 = (__u64)msg->data_end - (__u64)msg->data;
241+
bpf_printk("sk_msg2: length update %i->%i\n",
242+
len1, len2);
243+
}
199244
bpf_printk("sk_msg3: redirect(%iB) err1=%i err2=%i\n",
200-
(__u64)data_end - (__u64)data, err1, err2);
245+
len1, err1, err2);
201246
return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0);
202247
}
203248

@@ -239,14 +284,20 @@ int bpf_prog9(struct sk_msg_md *msg)
239284
SEC("sk_msg7")
240285
int bpf_prog10(struct sk_msg_md *msg)
241286
{
242-
int *bytes, zero = 0;
287+
int *bytes, zero = 0, one = 1;
288+
int *start, *end;
243289

244290
bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
245291
if (bytes)
246292
bpf_msg_apply_bytes(msg, *bytes);
247293
bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
248294
if (bytes)
249295
bpf_msg_cork_bytes(msg, *bytes);
296+
start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
297+
end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
298+
if (start && end)
299+
bpf_msg_pull_data(msg, *start, *end, 0);
300+
250301
return SK_DROP;
251302
}
252303

samples/sockmap/sockmap_user.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ int txmsg_redir_noisy;
6262
int txmsg_drop;
6363
int txmsg_apply;
6464
int txmsg_cork;
65+
int txmsg_start;
66+
int txmsg_end;
6567

6668
static const struct option long_options[] = {
6769
{"help", no_argument, NULL, 'h' },
@@ -79,6 +81,8 @@ static const struct option long_options[] = {
7981
{"txmsg_drop", no_argument, &txmsg_drop, 1 },
8082
{"txmsg_apply", required_argument, NULL, 'a'},
8183
{"txmsg_cork", required_argument, NULL, 'k'},
84+
{"txmsg_start", required_argument, NULL, 's'},
85+
{"txmsg_end", required_argument, NULL, 'e'},
8286
{0, 0, NULL, 0 }
8387
};
8488

@@ -572,6 +576,12 @@ int main(int argc, char **argv)
572576
while ((opt = getopt_long(argc, argv, ":dhvc:r:i:l:t:",
573577
long_options, &longindex)) != -1) {
574578
switch (opt) {
579+
case 's':
580+
txmsg_start = atoi(optarg);
581+
break;
582+
case 'e':
583+
txmsg_end = atoi(optarg);
584+
break;
575585
case 'a':
576586
txmsg_apply = atoi(optarg);
577587
break;
@@ -761,6 +771,28 @@ int main(int argc, char **argv)
761771
}
762772
}
763773

774+
if (txmsg_start) {
775+
err = bpf_map_update_elem(map_fd[5],
776+
&i, &txmsg_start, BPF_ANY);
777+
if (err) {
778+
fprintf(stderr,
779+
"ERROR: bpf_map_update_elem (txmsg_start): %d (%s)\n",
780+
err, strerror(errno));
781+
return err;
782+
}
783+
}
784+
785+
if (txmsg_end) {
786+
i = 1;
787+
err = bpf_map_update_elem(map_fd[5],
788+
&i, &txmsg_end, BPF_ANY);
789+
if (err) {
790+
fprintf(stderr,
791+
"ERROR: bpf_map_update_elem (txmsg_end): %d (%s)\n",
792+
err, strerror(errno));
793+
return err;
794+
}
795+
}
764796
}
765797

766798
if (txmsg_drop)

tools/include/uapi/linux/bpf.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,8 @@ union bpf_attr {
793793
FN(sock_ops_cb_flags_set), \
794794
FN(msg_redirect_map), \
795795
FN(msg_apply_bytes), \
796-
FN(msg_cork_bytes),
796+
FN(msg_cork_bytes), \
797+
FN(msg_pull_data),
797798

798799
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
799800
* function eBPF program intends to call

tools/testing/selftests/bpf/bpf_helpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ static int (*bpf_msg_apply_bytes)(void *ctx, int len) =
9292
(void *) BPF_FUNC_msg_apply_bytes;
9393
static int (*bpf_msg_cork_bytes)(void *ctx, int len) =
9494
(void *) BPF_FUNC_msg_cork_bytes;
95+
static int (*bpf_msg_pull_data)(void *ctx, int start, int end, int flags) =
96+
(void *) BPF_FUNC_msg_pull_data;
9597

9698
/* llvm builtin functions that eBPF C program may use to
9799
* emit BPF_LD_ABS and BPF_LD_IND instructions

0 commit comments

Comments
 (0)