Greg Kroah-Hartman | b244131 | 2017-11-01 15:07:57 +0100 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
David Ahern | 554ae6e | 2016-12-01 08:48:08 -0800 | [diff] [blame] | 2 | /* eBPF example program: |
| 3 | * |
| 4 | * - Loads eBPF program |
| 5 | * |
| 6 | * The eBPF program loads a filter from file and attaches the |
| 7 | * program to a cgroup using BPF_PROG_ATTACH |
| 8 | */ |
| 9 | |
| 10 | #define _GNU_SOURCE |
| 11 | |
| 12 | #include <stdio.h> |
| 13 | #include <stdlib.h> |
| 14 | #include <stddef.h> |
| 15 | #include <string.h> |
| 16 | #include <unistd.h> |
| 17 | #include <assert.h> |
| 18 | #include <errno.h> |
| 19 | #include <fcntl.h> |
| 20 | #include <net/if.h> |
| 21 | #include <linux/bpf.h> |
Jakub Kicinski | 8d93045 | 2018-05-14 22:35:03 -0700 | [diff] [blame] | 22 | #include <bpf/bpf.h> |
Daniel T. Lee | d89af13 | 2020-11-24 09:03:05 +0000 | [diff] [blame] | 23 | #include <bpf/libbpf.h> |
David Ahern | 554ae6e | 2016-12-01 08:48:08 -0800 | [diff] [blame] | 24 | |
Jakub Kicinski | 8d93045 | 2018-05-14 22:35:03 -0700 | [diff] [blame] | 25 | #include "bpf_insn.h" |
David Ahern | 554ae6e | 2016-12-01 08:48:08 -0800 | [diff] [blame] | 26 | |
| 27 | static int usage(const char *argv0) |
| 28 | { |
| 29 | printf("Usage: %s cg-path filter-path [filter-id]\n", argv0); |
| 30 | return EXIT_FAILURE; |
| 31 | } |
| 32 | |
| 33 | int main(int argc, char **argv) |
| 34 | { |
Daniel T. Lee | d89af13 | 2020-11-24 09:03:05 +0000 | [diff] [blame] | 35 | int cg_fd, err, ret = EXIT_FAILURE, filter_id = 0, prog_cnt = 0; |
| 36 | const char *link_pin_path = "/sys/fs/bpf/test_cgrp2_sock2"; |
| 37 | struct bpf_link *link = NULL; |
| 38 | struct bpf_program *progs[2]; |
| 39 | struct bpf_program *prog; |
| 40 | struct bpf_object *obj; |
David Ahern | 554ae6e | 2016-12-01 08:48:08 -0800 | [diff] [blame] | 41 | |
| 42 | if (argc < 3) |
| 43 | return usage(argv[0]); |
| 44 | |
David Ahern | 554ae6e | 2016-12-01 08:48:08 -0800 | [diff] [blame] | 45 | if (argc > 3) |
| 46 | filter_id = atoi(argv[3]); |
| 47 | |
Daniel T. Lee | d89af13 | 2020-11-24 09:03:05 +0000 | [diff] [blame] | 48 | cg_fd = open(argv[1], O_DIRECTORY | O_RDONLY); |
| 49 | if (cg_fd < 0) { |
| 50 | printf("Failed to open cgroup path: '%s'\n", strerror(errno)); |
| 51 | return ret; |
| 52 | } |
| 53 | |
| 54 | obj = bpf_object__open_file(argv[2], NULL); |
| 55 | if (libbpf_get_error(obj)) { |
| 56 | printf("ERROR: opening BPF object file failed\n"); |
| 57 | return ret; |
| 58 | } |
| 59 | |
| 60 | bpf_object__for_each_program(prog, obj) { |
| 61 | progs[prog_cnt] = prog; |
| 62 | prog_cnt++; |
| 63 | } |
| 64 | |
Dan Carpenter | ee58301 | 2018-07-13 18:05:37 +0300 | [diff] [blame] | 65 | if (filter_id >= prog_cnt) { |
David Ahern | 554ae6e | 2016-12-01 08:48:08 -0800 | [diff] [blame] | 66 | printf("Invalid program id; program not found in file\n"); |
Daniel T. Lee | d89af13 | 2020-11-24 09:03:05 +0000 | [diff] [blame] | 67 | goto cleanup; |
David Ahern | 554ae6e | 2016-12-01 08:48:08 -0800 | [diff] [blame] | 68 | } |
| 69 | |
Daniel T. Lee | d89af13 | 2020-11-24 09:03:05 +0000 | [diff] [blame] | 70 | /* load BPF program */ |
| 71 | if (bpf_object__load(obj)) { |
| 72 | printf("ERROR: loading BPF object file failed\n"); |
| 73 | goto cleanup; |
David Ahern | 554ae6e | 2016-12-01 08:48:08 -0800 | [diff] [blame] | 74 | } |
| 75 | |
Daniel T. Lee | d89af13 | 2020-11-24 09:03:05 +0000 | [diff] [blame] | 76 | link = bpf_program__attach_cgroup(progs[filter_id], cg_fd); |
| 77 | if (libbpf_get_error(link)) { |
| 78 | printf("ERROR: bpf_program__attach failed\n"); |
| 79 | link = NULL; |
| 80 | goto cleanup; |
| 81 | } |
| 82 | |
| 83 | err = bpf_link__pin(link, link_pin_path); |
| 84 | if (err < 0) { |
| 85 | printf("ERROR: bpf_link__pin failed: %d\n", err); |
| 86 | goto cleanup; |
| 87 | } |
| 88 | |
| 89 | ret = EXIT_SUCCESS; |
| 90 | |
| 91 | cleanup: |
| 92 | bpf_link__destroy(link); |
| 93 | bpf_object__close(obj); |
| 94 | return ret; |
David Ahern | 554ae6e | 2016-12-01 08:48:08 -0800 | [diff] [blame] | 95 | } |