Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions xdp-forward/xdp-forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <bpf/libbpf.h>
#include <xdp/libxdp.h>
Expand Down Expand Up @@ -140,7 +142,10 @@ static int do_load(const void *cfg, __unused const char *pin_root_path)
{
struct xdp_program *xdp_prog = NULL, *init_prog = NULL;
DECLARE_LIBBPF_OPTS(xdp_program_opts, opts);
struct bpf_program *return_prog = NULL;
const struct load_opts *opt = cfg;
struct bpf_link *link = NULL;
char pin_link_path[PATH_MAX];
struct xdp_forward *skel;
int ret = EXIT_FAILURE;
struct iface *iface;
Expand Down Expand Up @@ -217,6 +222,34 @@ static int do_load(const void *cfg, __unused const char *pin_root_path)
pr_info("Loaded on interface %s\n", iface->ifname);
}

/* Attach xdp_check_return to xdp_frame_return tracepoint and
* pin the link to pin_root_path/xdp_check_return.
*/

return_prog = bpf_object__find_program_by_name(skel->obj,"xdp_check_return");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The program is available in the skeleton as skel->progs.xdp_check_return - no need to use bpf_object__find_program_by_name()

if (!return_prog) {
pr_warn("Failed to find xdp_check_return program\n");
goto end_detach;
}

link = bpf_program__attach_raw_tracepoint(return_prog, "xdp_frame_return");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be possible to just call bpf_program__attach(), since the target is specified in the section definition in the BPF source file.

if (libbpf_get_error((const void *) link)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be possible to just pass the pointers to libbpf_get_error() without the cast...

pr_warn("Couldn't attach to xdp_frame_return: %s\n",
strerror(libbpf_get_error((const void *) link)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...same here

goto end_detach;
}
skel->links.xdp_check_return = link;

snprintf(pin_link_path, sizeof(pin_link_path), "%s/%s", pin_root_path,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use the try_snprintf() function (from lib/util), and check the return code. We should probably also disambiguate the pin path right now, with this path bad things will happen if multiple instances of xdp-forward are loaded at the same time.

"xdp_check_return");
ret = bpf_link__pin(link, pin_link_path);
if (ret) {
pr_warn("Failed to pin link: %s\n",
strerror(errno));
goto end_detach;
}
pr_info("Pinned xdp_check_return to %s\n", pin_link_path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be pr_debug()


end_destroy:
xdp_forward__destroy(skel);
end:
Expand All @@ -225,6 +258,10 @@ static int do_load(const void *cfg, __unused const char *pin_root_path)
end_detach:
for (iface = opt->ifaces; iface; iface = iface->next)
xdp_program__detach(xdp_prog, iface->ifindex, opt->xdp_mode, 0);

bpf_link__unpin(link);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bpf_link__unpin() will crash if link is NULL

bpf_link__destroy(link);

goto end_destroy;
}

Expand All @@ -246,6 +283,8 @@ struct prog_option unload_options[] = {
static int do_unload(const void *cfg, __unused const char *pin_root_path)
{
const struct unload_opts *opt = cfg;
struct bpf_link *link = NULL;
char pin_link_path[PATH_MAX];
int ret = EXIT_SUCCESS;
struct iface *iface;

Expand All @@ -258,6 +297,24 @@ static int do_unload(const void *cfg, __unused const char *pin_root_path)
pr_info("Unloaded from interface %s\n", iface->ifname);
}

snprintf(pin_link_path, sizeof(pin_link_path), "%s/%s", pin_root_path,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above wrt using try_snprintf()

"xdp_check_return");

link = bpf_link__open(pin_link_path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of going through this open/unpin/destroy dance, just unlink the pin file?

ret = bpf_link__unpin(link);
if(ret){
pr_warn("Couldn't unpin link\n");
} else {
pr_info("Unpinned link from %s\n", pin_link_path);
}

ret = bpf_link__destroy(link);
if(ret){
pr_warn("Couldn't destroy link\n");
} else {
pr_info("Destroyed link\n");
}

return ret;
}

Expand Down
1 change: 1 addition & 0 deletions xdp-forward/xdp_forward.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ static int xdp_timer_cb(struct bpf_map *map, __u64 *key, struct bpf_timer *timer

bpf_printk("xdp_timer_cb: Sending to ifindex %d\n", tgt_ifindex);
xdp_packet_send(pkt, tgt_ifindex, 0);
state->outstanding_bytes += pkt->len;
}

xdp_packet_flush();
Expand Down