diff options
Diffstat (limited to 'samples/bpf/fds_example.c')
| -rw-r--r-- | samples/bpf/fds_example.c | 183 | 
1 files changed, 183 insertions, 0 deletions
| diff --git a/samples/bpf/fds_example.c b/samples/bpf/fds_example.c new file mode 100644 index 000000000000..e2fd16c3d0f0 --- /dev/null +++ b/samples/bpf/fds_example.c @@ -0,0 +1,183 @@ +#include <linux/unistd.h> +#include <linux/bpf.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <string.h> +#include <assert.h> +#include <errno.h> + +#include <sys/types.h> +#include <sys/socket.h> + +#include "bpf_load.h" +#include "libbpf.h" + +#define BPF_F_PIN	(1 << 0) +#define BPF_F_GET	(1 << 1) +#define BPF_F_PIN_GET	(BPF_F_PIN | BPF_F_GET) + +#define BPF_F_KEY	(1 << 2) +#define BPF_F_VAL	(1 << 3) +#define BPF_F_KEY_VAL	(BPF_F_KEY | BPF_F_VAL) + +#define BPF_M_UNSPEC	0 +#define BPF_M_MAP	1 +#define BPF_M_PROG	2 + +static void usage(void) +{ +	printf("Usage: fds_example [...]\n"); +	printf("       -F <file>   File to pin/get object\n"); +	printf("       -P          |- pin object\n"); +	printf("       -G          `- get object\n"); +	printf("       -m          eBPF map mode\n"); +	printf("       -k <key>    |- map key\n"); +	printf("       -v <value>  `- map value\n"); +	printf("       -p          eBPF prog mode\n"); +	printf("       -o <object> `- object file\n"); +	printf("       -h          Display this help.\n"); +} + +static int bpf_map_create(void) +{ +	return bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(uint32_t), +			      sizeof(uint32_t), 1024); +} + +static int bpf_prog_create(const char *object) +{ +	static const struct bpf_insn insns[] = { +		BPF_MOV64_IMM(BPF_REG_0, 1), +		BPF_EXIT_INSN(), +	}; + +	if (object) { +		assert(!load_bpf_file((char *)object)); +		return prog_fd[0]; +	} else { +		return bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, +				     insns, sizeof(insns), "GPL", 0); +	} +} + +static int bpf_do_map(const char *file, uint32_t flags, uint32_t key, +		      uint32_t value) +{ +	int fd, ret; + +	if (flags & BPF_F_PIN) { +		fd = bpf_map_create(); +		printf("bpf: map fd:%d (%s)\n", fd, strerror(errno)); +		assert(fd > 0); + +		ret = bpf_obj_pin(fd, file); +		printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno)); +		assert(ret == 0); +	} else { +		fd = bpf_obj_get(file); +		printf("bpf: get fd:%d (%s)\n", fd, strerror(errno)); +		assert(fd > 0); +	} + +	if ((flags & BPF_F_KEY_VAL) == BPF_F_KEY_VAL) { +		ret = bpf_update_elem(fd, &key, &value, 0); +		printf("bpf: fd:%d u->(%u:%u) ret:(%d,%s)\n", fd, key, value, +		       ret, strerror(errno)); +		assert(ret == 0); +	} else if (flags & BPF_F_KEY) { +		ret = bpf_lookup_elem(fd, &key, &value); +		printf("bpf: fd:%d l->(%u):%u ret:(%d,%s)\n", fd, key, value, +		       ret, strerror(errno)); +		assert(ret == 0); +	} + +	return 0; +} + +static int bpf_do_prog(const char *file, uint32_t flags, const char *object) +{ +	int fd, sock, ret; + +	if (flags & BPF_F_PIN) { +		fd = bpf_prog_create(object); +		printf("bpf: prog fd:%d (%s)\n", fd, strerror(errno)); +		assert(fd > 0); + +		ret = bpf_obj_pin(fd, file); +		printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno)); +		assert(ret == 0); +	} else { +		fd = bpf_obj_get(file); +		printf("bpf: get fd:%d (%s)\n", fd, strerror(errno)); +		assert(fd > 0); +	} + +	sock = open_raw_sock("lo"); +	assert(sock > 0); + +	ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &fd, sizeof(fd)); +	printf("bpf: sock:%d <- fd:%d attached ret:(%d,%s)\n", sock, fd, +	       ret, strerror(errno)); +	assert(ret == 0); + +	return 0; +} + +int main(int argc, char **argv) +{ +	const char *file = NULL, *object = NULL; +	uint32_t key = 0, value = 0, flags = 0; +	int opt, mode = BPF_M_UNSPEC; + +	while ((opt = getopt(argc, argv, "F:PGmk:v:po:")) != -1) { +		switch (opt) { +		/* General args */ +		case 'F': +			file = optarg; +			break; +		case 'P': +			flags |= BPF_F_PIN; +			break; +		case 'G': +			flags |= BPF_F_GET; +			break; +		/* Map-related args */ +		case 'm': +			mode = BPF_M_MAP; +			break; +		case 'k': +			key = strtoul(optarg, NULL, 0); +			flags |= BPF_F_KEY; +			break; +		case 'v': +			value = strtoul(optarg, NULL, 0); +			flags |= BPF_F_VAL; +			break; +		/* Prog-related args */ +		case 'p': +			mode = BPF_M_PROG; +			break; +		case 'o': +			object = optarg; +			break; +		default: +			goto out; +		} +	} + +	if (!(flags & BPF_F_PIN_GET) || !file) +		goto out; + +	switch (mode) { +	case BPF_M_MAP: +		return bpf_do_map(file, flags, key, value); +	case BPF_M_PROG: +		return bpf_do_prog(file, flags, object); +	} +out: +	usage(); +	return -1; +} |