Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49a086c2 authored by Roman Gushchin's avatar Roman Gushchin Committed by Daniel Borkmann
Browse files

bpftool: implement prog load command



Add the prog load command to load a bpf program from a specified
binary file and pin it to bpffs.

Usage description and examples are given in the corresponding man
page.

Syntax:
$ bpftool prog load OBJ FILE

FILE is a non-existing file on bpffs.

Signed-off-by: default avatarRoman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Quentin Monnet <quentin.monnet@netronome.com>
Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent fe4d44b2
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ SYNOPSIS
	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } }

	*COMMANDS* :=
	{ **show** | **dump xlated** | **dump jited** | **pin** | **help** }
	{ **show** | **dump xlated** | **dump jited** | **pin** | **load** | **help** }

MAP COMMANDS
=============
@@ -24,6 +24,7 @@ MAP COMMANDS
|	**bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}]
|	**bpftool** **prog dump jited**  *PROG* [{**file** *FILE* | **opcodes**}]
|	**bpftool** **prog pin** *PROG* *FILE*
|	**bpftool** **prog load** *OBJ* *FILE*
|	**bpftool** **prog help**
|
|	*PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
@@ -57,6 +58,11 @@ DESCRIPTION

		  Note: *FILE* must be located in *bpffs* mount.

	**bpftool prog load** *OBJ* *FILE*
		  Load bpf program from binary *OBJ* and pin as *FILE*.

		  Note: *FILE* must be located in *bpffs* mount.

	**bpftool prog help**
		  Print short help message.

@@ -126,8 +132,10 @@ EXAMPLES
|
| **# mount -t bpf none /sys/fs/bpf/**
| **# bpftool prog pin id 10 /sys/fs/bpf/prog**
| **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2**
| **# ls -l /sys/fs/bpf/**
|   -rw------- 1 root root 0 Jul 22 01:43 prog
|   -rw------- 1 root root 0 Jul 22 01:44 prog2

**# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes**

+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ SYNOPSIS
	| **pin** | **help** }

	*PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin**
	| **help** }
	| **load** | **help** }

DESCRIPTION
===========
+40 −31
Original line number Diff line number Diff line
@@ -163,13 +163,49 @@ int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type)
	return fd;
}

int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
int do_pin_fd(int fd, const char *name)
{
	char err_str[ERR_MAX_LEN];
	unsigned int id;
	char *endptr;
	char *file;
	char *dir;
	int err = 0;

	err = bpf_obj_pin(fd, name);
	if (!err)
		goto out;

	file = malloc(strlen(name) + 1);
	strcpy(file, name);
	dir = dirname(file);

	if (errno != EPERM || is_bpffs(dir)) {
		p_err("can't pin the object (%s): %s", name, strerror(errno));
		goto out_free;
	}

	/* Attempt to mount bpffs, then retry pinning. */
	err = mnt_bpffs(dir, err_str, ERR_MAX_LEN);
	if (!err) {
		err = bpf_obj_pin(fd, name);
		if (err)
			p_err("can't pin the object (%s): %s", name,
			      strerror(errno));
	} else {
		err_str[ERR_MAX_LEN - 1] = '\0';
		p_err("can't mount BPF file system to pin the object (%s): %s",
		      name, err_str);
	}

out_free:
	free(file);
out:
	return err;
}

int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
{
	unsigned int id;
	char *endptr;
	int err;
	int fd;

@@ -195,35 +231,8 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
		return -1;
	}

	err = bpf_obj_pin(fd, *argv);
	if (!err)
		goto out_close;

	file = malloc(strlen(*argv) + 1);
	strcpy(file, *argv);
	dir = dirname(file);

	if (errno != EPERM || is_bpffs(dir)) {
		p_err("can't pin the object (%s): %s", *argv, strerror(errno));
		goto out_free;
	}
	err = do_pin_fd(fd, *argv);

	/* Attempt to mount bpffs, then retry pinning. */
	err = mnt_bpffs(dir, err_str, ERR_MAX_LEN);
	if (!err) {
		err = bpf_obj_pin(fd, *argv);
		if (err)
			p_err("can't pin the object (%s): %s", *argv,
			      strerror(errno));
	} else {
		err_str[ERR_MAX_LEN - 1] = '\0';
		p_err("can't mount BPF file system to pin the object (%s): %s",
		      *argv, err_str);
	}

out_free:
	free(file);
out_close:
	close(fd);
	return err;
}
+1 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ char *get_fdinfo(int fd, const char *key);
int open_obj_pinned(char *path);
int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type);
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32));
int do_pin_fd(int fd, const char *name);

int do_prog(int argc, char **arg);
int do_map(int argc, char **arg);
+28 −1
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include <sys/stat.h>

#include <bpf.h>
#include <libbpf.h>

#include "main.h"
#include "disasm.h"
@@ -635,6 +636,30 @@ static int do_pin(int argc, char **argv)
	return err;
}

static int do_load(int argc, char **argv)
{
	struct bpf_object *obj;
	int prog_fd;

	if (argc != 2)
		usage();

	if (bpf_prog_load(argv[0], BPF_PROG_TYPE_UNSPEC, &obj, &prog_fd)) {
		p_err("failed to load program\n");
		return -1;
	}

	if (do_pin_fd(prog_fd, argv[1])) {
		p_err("failed to pin program\n");
		return -1;
	}

	if (json_output)
		jsonw_null(json_wtr);

	return 0;
}

static int do_help(int argc, char **argv)
{
	if (json_output) {
@@ -647,13 +672,14 @@ static int do_help(int argc, char **argv)
		"       %s %s dump xlated PROG [{ file FILE | opcodes }]\n"
		"       %s %s dump jited  PROG [{ file FILE | opcodes }]\n"
		"       %s %s pin   PROG FILE\n"
		"       %s %s load  OBJ  FILE\n"
		"       %s %s help\n"
		"\n"
		"       " HELP_SPEC_PROGRAM "\n"
		"       " HELP_SPEC_OPTIONS "\n"
		"",
		bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
		bin_name, argv[-2], bin_name, argv[-2]);
		bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]);

	return 0;
}
@@ -663,6 +689,7 @@ static const struct cmd cmds[] = {
	{ "help",	do_help },
	{ "dump",	do_dump },
	{ "pin",	do_pin },
	{ "load",	do_load },
	{ 0 }
};