Skip to content

Commit

Permalink
tracing01: update tutorial for bpf 1.0+
Browse files Browse the repository at this point in the history
Signed-off-by: Maryam Tahhan <[email protected]>
Signed-off-by: Donald Hunter <[email protected]>
  • Loading branch information
maryamtahhan authored and donaldh committed Mar 3, 2023
1 parent d3d60e8 commit 888d8a6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 85 deletions.
35 changes: 18 additions & 17 deletions tracing01-xdp-simple/README.org
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,22 @@ This struct is exported in tracepoint format file:
** Tracepoint attaching

To load a tracepoint program for this example we use following bpf
library helper function:
library helper functions:

#+begin_src sh
bpf_prog_load(cfg->filename, BPF_PROG_TYPE_TRACEPOINT, &obj, &bpf_fd))
bpf_object__open_file(cfg->filename, NULL);
#+end_src

It loads all the programs from the object together with maps and
returns file descriptor of the first one.
#+begin_src sh
bpf_object__load(obj);
#+end_src

To attach the program to the tracepoint we need to create a tracepoint
perf event and attach the eBPF program to it, using its file descriptor
via PERF_EVENT_IOC_SET_BPF ioctl call:
perf event and attach the eBPF program to it, using its file descriptor.
Under the hood this function sets up the PERF_EVENT_IOC_SET_BPF ioctl call:

#+begin_src sh
err = ioctl(fd, PERF_EVENT_IOC_SET_BPF, bpf_fd);
bpf_program__attach_tracepoint(prog, "xdp", "xdp_exception");
#+end_src

Please check trace_load_and_stats.c load_bpf_and_trace_attach function
Expand All @@ -112,12 +113,12 @@ for all the details.
This example is using PERCPU HASH map, that stores number of aborted
packets for interface
#+begin_src C
struct bpf_map_def SEC("maps") xdp_stats_map = {
.type = BPF_MAP_TYPE_PERCPU_HASH,
.key_size = sizeof(__s32),
.value_size = sizeof(__u64),
.max_entries = 10,
};
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
__type(key, __s32);
__type(value, __u64);
__uint(max_entries, 10);
} xdp_stats_map SEC(".maps");
#+end_src

The interface is similar to the ARRAY map except that we need to specifically
Expand Down Expand Up @@ -158,7 +159,7 @@ int xdp_drop_func(struct xdp_md *ctx)
}
#+end_src

with xdp_loader from previous lessson:
with xdp-loader:
Assignment 2: Add xdp_abort program [[https://github.com/xdp-project/xdp-tutorial/tree/master/basic02-prog-by-name#assignment-2-add-xdp_abort-program]]

Setup the environment:
Expand All @@ -167,13 +168,13 @@ Setup the environment:
$ sudo ../testenv/testenv.sh setup --name veth-basic02
#+end_src

Load the XDP program, tak produces aborted packets:
Load the XDP program, that produces aborted packets:

#+begin_src sh
$ sudo ./xdp_loader --dev veth-basic02 --force --progsec xdp_abort
$ sudo xdp-loader load veth-basic02 xdp_prog_kern.o -n xdp_drop_func
#+end_src

and make some packets:
and generate some packets:

#+begin_src sh
$ sudo ../testenv/testenv.sh enter --name veth-basic02
Expand Down
98 changes: 31 additions & 67 deletions tracing01-xdp-simple/trace_load_and_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ static const char *__doc__ = "XDP loader and stats program\n"
#include <linux/if_link.h> /* depend on kernel-headers installed */

#include "../common/common_params.h"
#include "../common/common_user_bpf_xdp.h"
#include "../common/common_libbpf.h"

#include <linux/perf_event.h>
#define _GNU_SOURCE /* See feature_test_macros(7) */
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <unistd.h>
#include <sys/syscall.h> /* For SYS_xxx definitions */
#include <sys/ioctl.h>
Expand All @@ -39,13 +37,13 @@ static const char *__doc__ = "XDP loader and stats program\n"
static const char *default_filename = "trace_prog_kern.o";

static const struct option_wrapper long_options[] = {
{{"help", no_argument, NULL, 'h' },
{{"help", no_argument, NULL, 'h' },
"Show help", false},

{{"quiet", no_argument, NULL, 'q' },
{{"quiet", no_argument, NULL, 'q' },
"Quiet mode (no output)"},

{{"filename", required_argument, NULL, 1 },
{{"filename", required_argument, NULL, 1 },
"Load program from <file>", "<file>"},

{{0, 0, NULL, 0 }}
Expand Down Expand Up @@ -122,15 +120,15 @@ static void stats_poll(int map_fd, __u32 map_type, int interval)
* values.
*/
static int __check_map_fd_info(int map_fd, struct bpf_map_info *info,
struct bpf_map_info *exp)
struct bpf_map_info *exp)
{
__u32 info_len = sizeof(*info);
int err;

if (map_fd < 0)
return EXIT_FAIL;

/* BPF-info via bpf-syscall */
/* BPF-info via bpf-syscall */
err = bpf_obj_get_info_by_fd(map_fd, info, &info_len);
if (err) {
fprintf(stderr, "ERR: %s() can't get info - %s\n",
Expand Down Expand Up @@ -183,71 +181,37 @@ int filename__read_int(const char *filename, int *value)
return err;
}

#define TP "/sys/kernel/debug/tracing/events/"

static int read_tp_id(const char *name, int *id)
{
char path[PATH_MAX];

snprintf(path, PATH_MAX, TP "%s/id", name);
return filename__read_int(path, id);
}

static inline int
sys_perf_event_open(struct perf_event_attr *attr,
pid_t pid, int cpu, int group_fd,
unsigned long flags)
{
return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags);
}

static struct bpf_object* load_bpf_and_trace_attach(struct config *cfg)
{
struct perf_event_attr attr;
struct bpf_object *obj;
int err, bpf_fd;
int id, fd;

if (bpf_prog_load(cfg->filename, BPF_PROG_TYPE_TRACEPOINT, &obj, &bpf_fd)) {
fprintf(stderr, "ERR: failed to load program\n");
goto err;
}
int err;
struct bpf_program *prog;
struct bpf_link *link;

if (read_tp_id("xdp/xdp_exception", &id)) {
fprintf(stderr, "ERR: can't get program section\n");
goto err;
}
obj = bpf_object__open_file(cfg->filename, NULL);
err = libbpf_get_error(obj);
if (err)
return NULL;

/* Setup tracepoint perf event */
memset(&attr, 0, sizeof(attr));
attr.type = PERF_TYPE_TRACEPOINT;
attr.config = id;
attr.sample_period = 1;

/* .. and open it */
fd = sys_perf_event_open(&attr, -1, 0, -1, 0);
if (fd <= 0) {
fprintf(stderr, "ERR: failed to open perf event %s\n",
strerror(errno));
goto err;
err = bpf_object__load(obj);
if (err) {
fprintf(stderr, "ERR: loading BPF-OBJ file(%s) (%d): %s\n",
cfg->filename, err, strerror(-err));
goto err;
}

/* Assign the program to the tracepoint perf event */
err = ioctl(fd, PERF_EVENT_IOC_SET_BPF, bpf_fd);
if (err) {
fprintf(stderr, "ERR: failed to connect perf event with eBPF prog %s\n",
strerror(errno));
goto err;
prog = bpf_object__next_program(obj, NULL);
if (!prog) {
fprintf(stderr, "ERR: Failed to retrieve program from BPF-OBJ file(%s) (%d): %s\n",
cfg->filename, err, strerror(-err));
goto err;
}

/* ... and finally enable the event. */
err = ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
if (err) {
fprintf(stderr, "ERR: failed to enable perf event %s\n",
strerror(errno));
link = bpf_program__attach_tracepoint(prog, "xdp", "xdp_exception");
if (libbpf_get_error(link)) {
printf("bpf_program__attach_tracepoint failed\n");
goto err;
}

/*
* As far as this program is concerned, we don't care about
* the perf event file descriptor, it will get closed when
Expand Down Expand Up @@ -289,7 +253,7 @@ int main(int argc, char **argv)
if (stats_map_fd < 0)
return EXIT_FAIL_BPF;

map_expect.key_size = sizeof(__s32);
map_expect.key_size = sizeof(__s32);
map_expect.value_size = sizeof(__u64);

err = __check_map_fd_info(stats_map_fd, &info, &map_expect);
Expand All @@ -300,10 +264,10 @@ int main(int argc, char **argv)
if (verbose) {
printf("\nCollecting stats from BPF map\n");
printf(" - BPF map (bpf_map_type:%d) id:%d name:%s"
" key_size:%d value_size:%d max_entries:%d\n",
info.type, info.id, info.name,
info.key_size, info.value_size, info.max_entries
);
" key_size:%d value_size:%d max_entries:%d\n",
info.type, info.id, info.name,
info.key_size, info.value_size, info.max_entries
);
}

stats_poll(stats_map_fd, info.type, interval);
Expand Down
2 changes: 1 addition & 1 deletion tracing01-xdp-simple/xdp_prog_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

SEC("xdp_abort")
SEC("xdp")
int xdp_drop_func(struct xdp_md *ctx)
{
return XDP_ABORTED;
Expand Down

0 comments on commit 888d8a6

Please sign in to comment.