Skip to content

Commit

Permalink
xdp-bench: Introduce xdp_redirect_basic_load_bytes_prog
Browse files Browse the repository at this point in the history
This commit introduces xdp_redirect_basic_load_bytes_prog to xdp-bench.
This program uses the bpf_xdp_load_bytes and bpf_xdp_store_bytes helpers for packet data access.
In contrast, xdp_redirect_basic_prog uses direct packet access.

The program that will be attached is determined by the --load-mode flag.

Signed-off-by: Nimrod Oren <[email protected]>
  • Loading branch information
nimrod-oren committed Nov 14, 2024
1 parent 3c68e58 commit 54291b2
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 3 deletions.
14 changes: 14 additions & 0 deletions xdp-bench/README.org
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,20 @@ be redirect to the output interface =<ifname_out>=.

The supported options are:

** -l, --load-mode <MODE>
Specify which mechanism xdp-bench should use to load (and store) the packet data.
The following modes are available:

#+begin_src sh
dpa - Use traditional Direct Packet Access from the XDP program
load-bytes - Use the xdp_load_bytes() and xdp_store_bytes() helper functions
#+end_src

This can be used to benchmark the various packet access modes supported by the
kernel.

The default for this option is =dpa=.

** -i, --interval <SECONDS>
Set the polling interval for collecting all statistics and displaying them to
the output. The unit of interval is in seconds.
Expand Down
12 changes: 11 additions & 1 deletion xdp-bench/tests/test-xdp-bench.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,20 @@ test_xdp_load_bytes()
export XDP_SAMPLE_IMMEDIATE_EXIT=1

for action in drop pass tx; do
check_run $XDP_BENCH $action $NS -p parse-ip -l load-bytes -vv
check_run $XDP_BENCH $action $NS -l load-bytes -vv
check_run $XDP_BENCH $action $NS -p read-data -l load-bytes -vv
check_run $XDP_BENCH $action $NS -p parse-ip -l load-bytes -vv
check_run $XDP_BENCH $action $NS -p swap-macs -l load-bytes -vv
check_run $XDP_BENCH $action $NS -m skb -l load-bytes -vv
check_run $XDP_BENCH $action $NS -e -l load-bytes -vv
done

check_run ip link add dev btest0 type veth peer name btest1
check_run $XDP_BENCH redirect btest0 btest1 -l load-bytes -vv
check_run $XDP_BENCH redirect btest0 btest1 -s -l load-bytes -vv
check_run $XDP_BENCH redirect btest0 btest1 -m skb -l load-bytes -vv
check_run $XDP_BENCH redirect btest0 btest1 -e -l load-bytes -vv
ip link del dev btest0
}

test_rxq_stats()
Expand Down
20 changes: 20 additions & 0 deletions xdp-bench/xdp-bench.8
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,26 @@ be redirect to the output interface \fI<ifname_out>\fP.
.PP
The supported options are:

.SS "-l, --load-mode <MODE>"
.PP
Specify which mechanism xdp-bench should use to load (and store) the packet data.
The following modes are available:

.RS
.nf
\fCdpa - Use traditional Direct Packet Access from the XDP program
load-bytes - Use the xdp_load_bytes() and xdp_store_bytes() helper functions
\fP
.fi
.RE

.PP
This can be used to benchmark the various packet access modes supported by the
kernel.

.PP
The default for this option is \fIdpa\fP.

.SS "-i, --interval <SECONDS>"
.PP
Set the polling interval for collecting all statistics and displaying them to
Expand Down
5 changes: 5 additions & 0 deletions xdp-bench/xdp-bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ struct prog_option basic_options[] = {
};

struct prog_option redirect_basic_options[] = {
DEFINE_OPTION("load-mode", OPT_ENUM, struct redirect_opts, load_mode,
.short_opt = 'l',
.metavar = "<mode>",
.typearg = basic_load_modes,
.help = "How to load (and store) data; default dpa"),
DEFINE_OPTION("interval", OPT_U32, struct redirect_opts, interval,
.short_opt = 'i',
.metavar = "<seconds>",
Expand Down
1 change: 1 addition & 0 deletions xdp-bench/xdp-bench.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct redirect_opts {
bool extended;
__u32 interval;
enum xdp_attach_mode mode;
enum basic_load_mode load_mode;
struct iface iface_in;
struct iface iface_out;
};
Expand Down
33 changes: 32 additions & 1 deletion xdp-bench/xdp_redirect_basic.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@
#include <xdp/xdp_sample_common.bpf.h>
#include <linux/if_ether.h>

#ifndef HAVE_LIBBPF_BPF_PROGRAM__TYPE
static long (*bpf_xdp_load_bytes)(struct xdp_md *xdp_md, __u32 offset, void *buf, __u32 len) = (void *) 189;
static long (*bpf_xdp_store_bytes)(struct xdp_md *xdp_md, __u32 offset, void *buf, __u32 len) = (void *) 190;
#endif

const volatile int ifindex_out;

SEC("xdp")
int xdp_redirect_basic_prog(struct xdp_md *ctx)
int xdp_redirect_prog(struct xdp_md *ctx)
{
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
Expand All @@ -41,4 +46,30 @@ int xdp_redirect_basic_prog(struct xdp_md *ctx)
return bpf_redirect(ifindex_out, 0);
}

SEC("xdp")
int xdp_redirect_load_bytes_prog(struct xdp_md *ctx)
{
__u32 key = bpf_get_smp_processor_id();
int err, offset = 0;
struct datarec *rec;
struct ethhdr eth;

err = bpf_xdp_load_bytes(ctx, offset, &eth, sizeof(eth));
if (err)
return err;

rec = bpf_map_lookup_elem(&rx_cnt, &key);
if (!rec)
return XDP_PASS;
NO_TEAR_INC(rec->processed);

swap_src_dst_mac(&eth);

err = bpf_xdp_store_bytes(ctx, offset, &eth, sizeof(eth));
if (err)
return err;

return bpf_redirect(ifindex_out, 0);
}

char _license[] SEC("license") = "GPL";
9 changes: 8 additions & 1 deletion xdp-bench/xdp_redirect_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ int do_redirect_basic(const void *cfg, __unused const char *pin_root_path)

struct xdp_program *xdp_prog = NULL, *dummy_prog = NULL;
DECLARE_LIBBPF_OPTS(xdp_program_opts, opts);
struct bpf_program *prog = NULL;
struct xdp_redirect_basic *skel;
char str[2 * IF_NAMESIZE + 1];
int ret = EXIT_FAIL_OPTION;
Expand Down Expand Up @@ -73,8 +74,14 @@ int do_redirect_basic(const void *cfg, __unused const char *pin_root_path)
skel->rodata->to_match[0] = opt->iface_out.ifindex;
skel->rodata->ifindex_out = opt->iface_out.ifindex;

/* Make sure we only load the one XDP program we are interested in */
while ((prog = bpf_object__next_program(skel->obj, prog)) != NULL)
if (bpf_program__type(prog) == BPF_PROG_TYPE_XDP &&
bpf_program__expected_attach_type(prog) == BPF_XDP)
bpf_program__set_autoload(prog, false);

opts.obj = skel->obj;
opts.prog_name = bpf_program__name(skel->progs.xdp_redirect_basic_prog);
opts.prog_name = (opt->load_mode == BASIC_LOAD_BYTES) ? "xdp_redirect_load_bytes_prog" : "xdp_redirect_prog";
xdp_prog = xdp_program__create(&opts);
if (!xdp_prog) {
ret = -errno;
Expand Down

0 comments on commit 54291b2

Please sign in to comment.