Skip to content

Commit 4a627a5

Browse files
committed
experiment01-tailgrow: Clean up example xdp_prog_kern2.c
Signed-off-by: Jesper Dangaard Brouer <[email protected]>
1 parent 745b587 commit 4a627a5

File tree

2 files changed

+29
-87
lines changed

2 files changed

+29
-87
lines changed

experiment01-tailgrow/README.org

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ the overhead when doing =XDP_TX=. Selecting others BPF programs via
3636
sudo ./xdp_loader --dev mlx5p1 --force --prog xdp_tailgrow_tx
3737
#+end_src
3838

39+
* Alternative methods
40+
41+
** Works: Use loop to access data_end
42+
43+
Code in [[file:xdp_prog_kern2.c]] shows howto find the =data_end=,
44+
*without parsing packet contents*, but by advancing a =data= position
45+
pointer one-byte at the time in a bounded loop. The bounded loop with
46+
max number of iterations allows the verifier to see the bound. (This
47+
obviously depend on the bounded loop support that was added in kernel
48+
[[https://git.kernel.org/torvalds/c/v5.3-rc1~140^2~179^2^2~5][v5.3]]).
49+
This is not very effecient, but it works.
50+
3951
* Methods that fail
4052

4153
Methods for accessing access BPF packet data at XDP =data_end=.
Lines changed: 17 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
#include <linux/bpf.h>
3-
#include <linux/in.h>
43
#include <bpf/bpf_helpers.h>
5-
#include <bpf/bpf_endian.h>
6-
7-
// The parsing helper functions from the packet01 lesson have moved here
8-
#include "../common/parsing_helpers.h"
9-
#include "../common/rewrite_helpers.h"
10-
11-
/* Defines xdp_stats_map */
12-
#include "../common/xdp_stats_kern_user.h"
13-
#include "../common/xdp_stats_kern.h"
144

155
#define MTU 1536
16-
#define MIN_LEN 64
17-
18-
SEC("xdp_test1b")
19-
int _xdp_test1b(struct xdp_md *ctx)
6+
#define MIN_LEN 14
7+
8+
/*
9+
* This example show howto access packet last byte in XDP packet,
10+
* without parsing packet contents.
11+
*
12+
* It is not very effecient, as it advance the data pointer one-byte in a
13+
* loop until reaching data_end. This is needed as the verifier only allows
14+
* accessing data via advancing the position of the data pointer. The bounded
15+
* loop with a max number of iterations allows the verifier to see the bound.
16+
*/
17+
18+
SEC("xdp_end_loop")
19+
int _xdp_end_loop(struct xdp_md *ctx)
2020
{
2121
void *data_end = (void *)(long)ctx->data_end;
2222
void *data = (void *)(long)ctx->data;
2323
unsigned char *ptr;
2424
unsigned int i;
2525
void *pos;
2626

27+
/* Assume minimum length to reduce loops needed a bit */
2728
unsigned int offset = MIN_LEN;
2829

2930
pos = data;
3031

31-
/* Verifier can handle this bounded basic-loop construct */
32+
/* Verifier can handle this bounded 'basic-loop' construct */
3233
for (i = 0; i < (MTU - MIN_LEN); i++ ) {
3334
if (pos + offset > data_end) {
3435
/* Promise verifier no access beyond data_end */
@@ -54,80 +55,9 @@ int _xdp_test1b(struct xdp_md *ctx)
5455
goto out;
5556

5657
read:
57-
// ptr = pos + (offset - );
58-
// ptr = pos + (offset - sizeof(*ptr) - 1);
59-
ptr = pos + (offset - sizeof(*ptr));
58+
ptr = pos + (offset - sizeof(*ptr)); /* Parentheses needed */
6059
if (*ptr == 0xFF)
6160
return XDP_ABORTED;
6261
out:
6362
return XDP_PASS;
6463
}
65-
66-
67-
SEC("xdp_test1")
68-
int _xdp_test1(struct xdp_md *ctx)
69-
{
70-
void *data_end = (void *)(long)ctx->data_end;
71-
void *data = (void *)(long)ctx->data;
72-
unsigned char *ptr;
73-
unsigned int i;
74-
void *pos;
75-
76-
unsigned int offset = 64;
77-
78-
pos = data;
79-
80-
if (pos + 64 > data_end)
81-
goto out;
82-
83-
for (i = 0; i < (1536-64); i++ ) {
84-
if (pos + offset > data_end) {
85-
goto out;
86-
}
87-
if (pos + offset == data_end) {
88-
goto read;
89-
}
90-
offset++;
91-
}
92-
goto out;
93-
94-
read:
95-
// ptr = pos + (offset - );
96-
// ptr = pos + (offset - sizeof(*ptr) - 1);
97-
ptr = pos + (offset - sizeof(*ptr));
98-
if (*ptr == 0xFF)
99-
return XDP_ABORTED;
100-
out:
101-
return XDP_PASS;
102-
}
103-
104-
105-
SEC("xdp_test2")
106-
int _xdp_test2(struct xdp_md *ctx)
107-
{
108-
void *data_end = (void *)(long)ctx->data_end;
109-
void *data = (void *)(long)ctx->data;
110-
struct hdr_cursor nh;
111-
unsigned char *ptr;
112-
113-
unsigned int offset = 64;
114-
115-
nh.pos = data;
116-
117-
if (nh.pos + offset > data_end)
118-
goto out;
119-
120-
// ptr = nh.pos + (offset - 1);
121-
ptr = nh.pos + (offset - sizeof(*ptr));
122-
if (*ptr == 0xFF)
123-
return XDP_ABORTED;
124-
out:
125-
return xdp_stats_record_action(ctx, XDP_PASS);
126-
}
127-
128-
SEC("xdp_pass")
129-
int xdp_pass_f1(struct xdp_md *ctx)
130-
{
131-
return xdp_stats_record_action(ctx, XDP_PASS);
132-
}
133-

0 commit comments

Comments
 (0)