Skip to content

Commit

Permalink
Use attach_mode everywhere and clean up old xdp flags
Browse files Browse the repository at this point in the history
Signed-off-by: Donald Hunter <donald.hunter@gmail.com>
  • Loading branch information
donaldh committed Mar 3, 2023
1 parent c95e334 commit d8da8c0
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 109 deletions.
3 changes: 1 addition & 2 deletions advanced03-AF_XDP/af_xdp_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ static struct xdp_program *prog;
int xsk_map_fd;
bool custom_xsk = false;
struct config cfg = {
.xdp_flags = XDP_FLAGS_DRV_MODE,
.ifindex = -1,
};

Expand Down Expand Up @@ -565,7 +564,7 @@ int main(int argc, char **argv)
return err;
}

err = xdp_program__attach(prog, cfg.ifindex, cfg.xdp_flags, 0);
err = xdp_program__attach(prog, cfg.ifindex, cfg.attach_mode, 0);
if (err) {
libxdp_strerror(err, errmsg, sizeof(errmsg));
fprintf(stderr, "Couldn't attach XDP program on iface '%s' : %s (%d)\n",
Expand Down
19 changes: 11 additions & 8 deletions basic-solutions/xdp_loader.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
static const char *__doc__ = "XDP loader\n"
" - Allows selecting BPF section --progname name to XDP-attach to --dev\n";
" - Allows selecting BPF program --progname name to XDP-attach to --dev\n";

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -77,7 +77,7 @@ int pin_maps_in_bpf_object(struct bpf_object *bpf_obj, struct config *cfg)
int err, len;

len = snprintf(map_filename, PATH_MAX, "%s/%s/%s",
pin_basedir, cfg->ifname, map_name);
cfg->pin_dir, cfg->ifname, map_name);
if (len < 0) {
fprintf(stderr, "ERR: creating map_name\n");
return EXIT_FAIL_OPTION;
Expand All @@ -101,8 +101,10 @@ int pin_maps_in_bpf_object(struct bpf_object *bpf_obj, struct config *cfg)

/* This will pin all maps in our bpf_object */
err = bpf_object__pin_maps(bpf_obj, cfg->pin_dir);
if (err)
if (err) {
fprintf(stderr, "ERR: Pinning maps in %s\n", cfg->pin_dir);
return EXIT_FAIL_BPF;
}

return 0;
}
Expand All @@ -113,9 +115,9 @@ int main(int argc, char **argv)
int err, len;

struct config cfg = {
.xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE,
.ifindex = -1,
.do_unload = false,
.attach_mode = XDP_MODE_NATIVE,
.ifindex = -1,
.do_unload = false,
};
/* Set default BPF-ELF object file and BPF program name */
strncpy(cfg.filename, default_filename, sizeof(cfg.filename));
Expand All @@ -135,7 +137,8 @@ int main(int argc, char **argv)
/* return xdp_link_detach(cfg.ifindex, cfg.xdp_flags, 0); */
}

len = snprintf(cfg.pin_dir, PATH_MAX, "%s/%s", pin_basedir, cfg.ifname);
/* Initialize the pin_dir configuration */
len = snprintf(cfg.pin_dir, 512, "%s/%s", pin_basedir, cfg.ifname);
if (len < 0) {
fprintf(stderr, "ERR: creating pin dirname\n");
return EXIT_FAIL_OPTION;
Expand All @@ -147,7 +150,7 @@ int main(int argc, char **argv)
return EXIT_FAIL_BPF;

if (verbose) {
printf("Success: Loaded BPF-object(%s) and used section(%s)\n",
printf("Success: Loaded BPF-object(%s) and used program(%s)\n",
cfg.filename, cfg.progname);
printf(" - XDP prog attached on device:%s(ifindex:%d)\n",
cfg.ifname, cfg.ifindex);
Expand Down
1 change: 1 addition & 0 deletions basic02-prog-by-name/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ XDP_TARGETS := xdp_prog_kern
USER_TARGETS := xdp_loader

COMMON_DIR = ../common
COMMON_OBJS += $(COMMON_DIR)/common_user_bpf_xdp.o

include $(COMMON_DIR)/common.mk

148 changes: 71 additions & 77 deletions basic02-prog-by-name/xdp_loader.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
static const char *__doc__ = "XDP loader\n"
" - Specify BPF-object --filename to load \n"
" - and select BPF section --progname name to XDP-attach to --dev\n";
" - and select BPF program --progname name to XDP-attach to --dev\n";

#include <stdio.h>
#include <stdlib.h>
Expand All @@ -17,6 +17,7 @@ static const char *__doc__ = "XDP loader\n"
#include <linux/if_link.h> /* depend on kernel-headers installed */

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

static const char *default_filename = "xdp_prog_kern.o";
static const char *default_progname = "xdp_pass_func";
Expand All @@ -37,14 +38,14 @@ static const struct option_wrapper long_options[] = {
{{"auto-mode", no_argument, NULL, 'A' },
"Auto-detect SKB or native mode"},

{{"offload-mode",no_argument, NULL, 3 },
{{"offload-mode",no_argument, NULL, 3 },
"Hardware offload XDP program to NIC"},

{{"force", no_argument, NULL, 'F' },
"Force install, replacing existing program on interface"},
{{"unload", required_argument, NULL, 'U' },
"Unload XDP program <id> instead of loading", "<id>"},

{{"unload", no_argument, NULL, 'U' },
"Unload XDP program instead of loading"},
{{"unload-all", no_argument, NULL, 4 },
"Unload all XDP programs on device"},

{{"quiet", no_argument, NULL, 'q' },
"Quiet mode (no output)"},
Expand All @@ -58,61 +59,6 @@ static const struct option_wrapper long_options[] = {
{{0, 0, NULL, 0 }, NULL, false}
};

/* Lesson#1: More advanced load_bpf_object_file and bpf_object */


/* Lesson#2: This is a central piece of this lesson:
* - Notice how BPF-ELF obj can have several programs
* - Find by program name via: xdp_program__create
*/
struct xdp_program *__load_bpf_and_xdp_attach(struct config *cfg)
{
/* In next assignment this will be moved into ../common/ */
int prog_fd = -1;
int err;

DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts);
DECLARE_LIBXDP_OPTS(xdp_program_opts, xdp_opts, 0);

xdp_opts.open_filename = cfg->filename;
xdp_opts.prog_name = cfg->progname;
xdp_opts.opts = &opts;

/* If flags indicate hardware offload, supply ifindex */
/* if (cfg->xdp_flags & XDP_FLAGS_HW_MODE) */
/* offload_ifindex = cfg->ifindex; */

struct xdp_program *prog = xdp_program__create(&xdp_opts);
err = libxdp_get_error(prog);
if (err) {
char errmsg[1024];
libxdp_strerror(err, errmsg, sizeof(errmsg));
fprintf(stderr, "ERR: loading program: %s\n", errmsg);
exit(EXIT_FAIL_BPF);
}

/* At this point: All XDP/BPF programs from the cfg->filename have been
* loaded into the kernel, and evaluated by the verifier. Only one of
* these gets attached to XDP hook, the others will get freed once this
* process exit.
*/

/* At this point: BPF-progs are (only) loaded by the kernel, and prog_fd
* is our select file-descriptor handle. Next step is attaching this FD
* to a kernel hook point, in this case XDP net_device link-level hook.
*/
err = xdp_program__attach(prog, cfg->ifindex, XDP_MODE_SKB, 0);
if (err)
exit(err);

prog_fd = xdp_program__fd(prog);
if (prog_fd < 0) {
fprintf(stderr, "ERR: xdp_program__fd failed: %s\n", strerror(errno));
exit(EXIT_FAIL_BPF);
}

return prog;
}

static void list_avail_progs(struct bpf_object *obj)
{
Expand All @@ -122,20 +68,26 @@ static void list_avail_progs(struct bpf_object *obj)
bpf_object__name(obj));

bpf_object__for_each_program(pos, obj) {
printf("*** %s\n", bpf_program__name(pos));
printf("*** %d\n", bpf_program__type(pos));
if (bpf_program__type(pos) == BPF_PROG_TYPE_XDP)
printf(" %s\n", bpf_program__name(pos));
}
}

/* Lesson#1: This is a central piece of this lesson:
* - Notice how BPF-ELF obj can have several programs
* - Find by program name via: xdp_program__create
*/
int main(int argc, char **argv)
{
struct config cfg = {
.xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE,
.ifindex = -1,
.do_unload = false,
.attach_mode = XDP_MODE_NATIVE,
.ifindex = -1,
.do_unload = false,
};
struct bpf_object *obj;
char errmsg[1024];
int err;

/* Set default BPF-ELF object file and BPF program name */
strncpy(cfg.filename, default_filename, sizeof(cfg.filename));
strncpy(cfg.progname, default_progname, sizeof(cfg.progname));
Expand All @@ -148,22 +100,64 @@ int main(int argc, char **argv)
usage(argv[0], __doc__, long_options, (argc == 1));
return EXIT_FAIL_OPTION;
}
/* if (cfg.do_unload) */
/* return xdp_link_detach(cfg.ifindex, cfg.xdp_flags, 0); */

struct xdp_program *prog = __load_bpf_and_xdp_attach(&cfg);
if (!prog)
return EXIT_FAIL_BPF;
/* Unload a program by prog_id, or
* unload all programs on net device
*/
if (cfg.do_unload || cfg.unload_all) {
err = do_unload(&cfg);
if (err) {
libxdp_strerror(err, errmsg, sizeof(errmsg));
fprintf(stderr, "Couldn't unload XDP program %s: %s\n",
cfg.progname, errmsg);
return err;
}

printf("Success: Unloading XDP prog name: %s\n", cfg.progname);
return EXIT_OK;
}

/* Open a BPF object file */
DECLARE_LIBBPF_OPTS(bpf_object_open_opts, bpf_opts);
obj = bpf_object__open_file(cfg.filename, &bpf_opts);
err = libbpf_get_error(obj);
if (err) {
libxdp_strerror(err, errmsg, sizeof(errmsg));
fprintf(stderr, "Couldn't open BPF object file %s: %s\n",
cfg.filename, errmsg);
return err;
}

/* List available programs */
if (verbose)
list_avail_progs(xdp_program__bpf_obj(prog));
list_avail_progs(obj);

DECLARE_LIBXDP_OPTS(xdp_program_opts, xdp_opts,
.obj = obj,
.prog_name = cfg.progname);
struct xdp_program *prog = xdp_program__create(&xdp_opts);
err = libxdp_get_error(prog);
if (err) {
libxdp_strerror(err, errmsg, sizeof(errmsg));
fprintf(stderr, "ERR: loading program %s: %s\n", cfg.progname, errmsg);
exit(EXIT_FAIL_BPF);
}

/* At this point: BPF-progs are (only) loaded by the kernel, and prog
* is our selected program handle. Next step is attaching this prog
* to a kernel hook point, in this case XDP net_device link-level hook.
*/
err = xdp_program__attach(prog, cfg.ifindex, cfg.attach_mode, 0);
if (err) {
perror("xdp_program__attach");
exit(err);
}

if (verbose) {
printf("Success: Loaded BPF-object(%s) and used section(%s)\n",
printf("Success: Loaded BPF-object(%s) and used program(%s)\n",
cfg.filename, cfg.progname);
printf(" - XDP prog attached on device:%s(ifindex:%d)\n",
cfg.ifname, cfg.ifindex);
printf(" - XDP prog id:%d attached on device:%s(ifindex:%d)\n",
xdp_program__id(prog), cfg.ifname, cfg.ifindex);
}
/* Other BPF section programs will get freed on exit */
/* Other BPF programs from ELF file will get freed on exit */
return EXIT_OK;
}
34 changes: 24 additions & 10 deletions basic03-map-counter/xdp_load_and_stats.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
static const char *__doc__ = "XDP loader and stats program\n"
" - Allows selecting BPF section --progname name to XDP-attach to --dev\n";
" - Allows selecting BPF --progname name to XDP-attach to --dev\n";

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -42,11 +42,11 @@ static const struct option_wrapper long_options[] = {
{{"auto-mode", no_argument, NULL, 'A' },
"Auto-detect SKB or native mode"},

{{"force", no_argument, NULL, 'F' },
"Force install, replacing existing program on interface"},
{{"unload", required_argument, NULL, 'U' },
"Unload XDP program <id> instead of loading", "<id>"},

{{"unload", no_argument, NULL, 'U' },
"Unload XDP program instead of loading"},
{{"unload-all", no_argument, NULL, 4 },
"Unload all XDP programs on device"},

{{"quiet", no_argument, NULL, 'q' },
"Quiet mode (no output)"},
Expand Down Expand Up @@ -274,10 +274,10 @@ int main(int argc, char **argv)
struct xdp_program *program;
int stats_map_fd;
int interval = 2;
char errmsg[1024];
int err;

struct config cfg = {
.xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE,
.ifindex = -1,
.do_unload = false,
};
Expand All @@ -293,8 +293,22 @@ int main(int argc, char **argv)
usage(argv[0], __doc__, long_options, (argc == 1));
return EXIT_FAIL_OPTION;
}
/* if (cfg.do_unload) */
/* return xdp_link_detach(cfg.ifindex, cfg.xdp_flags, 0); */

/* Unload a program by prog_id, or
* unload all programs on net device
*/
if (cfg.do_unload || cfg.unload_all) {
err = do_unload(&cfg);
if (err) {
libxdp_strerror(err, errmsg, sizeof(errmsg));
fprintf(stderr, "Couldn't unload XDP program %d: %s\n",
cfg.prog_id, errmsg);
return err;
}

printf("Success: Unloading XDP prog name: %s\n", cfg.progname);
return EXIT_OK;
}

program = load_bpf_and_xdp_attach(&cfg);
if (!program)
Expand All @@ -303,8 +317,8 @@ int main(int argc, char **argv)
if (verbose) {
printf("Success: Loaded BPF-object(%s) and used section(%s)\n",
cfg.filename, cfg.progname);
printf(" - XDP prog attached on device:%s(ifindex:%d)\n",
cfg.ifname, cfg.ifindex);
printf(" - XDP prog id:%d attached on device:%s(ifindex:%d)\n",
xdp_program__id(program), cfg.ifname, cfg.ifindex);
}

/* Lesson#3: Locate map file descriptor */
Expand Down
10 changes: 5 additions & 5 deletions basic04-pinning-maps/xdp_loader.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
static const char *__doc__ = "XDP loader\n"
" - Allows selecting BPF section --progname name to XDP-attach to --dev\n";
" - Allows selecting BPF program --progname name to XDP-attach to --dev\n";

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -118,9 +118,9 @@ int main(int argc, char **argv)
int err;

struct config cfg = {
.xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE,
.ifindex = -1,
.do_unload = false,
.attach_mode = XDP_MODE_NATIVE,
.ifindex = -1,
.do_unload = false,
};
/* Set default BPF-ELF object file and BPF program name */
strncpy(cfg.filename, default_filename, sizeof(cfg.filename));
Expand All @@ -143,7 +143,7 @@ int main(int argc, char **argv)
return EXIT_FAIL_BPF;

if (verbose) {
printf("Success: Loaded BPF-object(%s) and used section(%s)\n",
printf("Success: Loaded BPF-object(%s) and used program(%s)\n",
cfg.filename, cfg.progname);
printf(" - XDP prog attached on device:%s(ifindex:%d)\n",
cfg.ifname, cfg.ifindex);
Expand Down
Loading

0 comments on commit d8da8c0

Please sign in to comment.