at v4.10-rc3 136 lines 2.8 kB view raw
1/* eBPF example program: 2 * 3 * - Creates arraymap in kernel with 4 bytes keys and 8 byte values 4 * 5 * - Loads eBPF program 6 * 7 * The eBPF program accesses the map passed in to store two pieces of 8 * information. The number of invocations of the program, which maps 9 * to the number of packets received, is stored to key 0. Key 1 is 10 * incremented on each iteration by the number of bytes stored in 11 * the skb. 12 * 13 * - Attaches the new program to a cgroup using BPF_PROG_ATTACH 14 * 15 * - Every second, reads map[0] and map[1] to see how many bytes and 16 * packets were seen on any socket of tasks in the given cgroup. 17 */ 18 19#define _GNU_SOURCE 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <assert.h> 24#include <unistd.h> 25 26#include <linux/bpf.h> 27 28#include "libbpf.h" 29#include "cgroup_helpers.h" 30 31#define FOO "/foo" 32#define BAR "/foo/bar/" 33#define PING_CMD "ping -c1 -w1 127.0.0.1" 34 35char bpf_log_buf[BPF_LOG_BUF_SIZE]; 36 37static int prog_load(int verdict) 38{ 39 int ret; 40 struct bpf_insn prog[] = { 41 BPF_MOV64_IMM(BPF_REG_0, verdict), /* r0 = verdict */ 42 BPF_EXIT_INSN(), 43 }; 44 size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn); 45 46 ret = bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB, 47 prog, insns_cnt, "GPL", 0, 48 bpf_log_buf, BPF_LOG_BUF_SIZE); 49 50 if (ret < 0) { 51 log_err("Loading program"); 52 printf("Output from verifier:\n%s\n-------\n", bpf_log_buf); 53 return 0; 54 } 55 return ret; 56} 57 58 59int main(int argc, char **argv) 60{ 61 int drop_prog, allow_prog, foo = 0, bar = 0, rc = 0; 62 63 allow_prog = prog_load(1); 64 if (!allow_prog) 65 goto err; 66 67 drop_prog = prog_load(0); 68 if (!drop_prog) 69 goto err; 70 71 if (setup_cgroup_environment()) 72 goto err; 73 74 /* Create cgroup /foo, get fd, and join it */ 75 foo = create_and_get_cgroup(FOO); 76 if (!foo) 77 goto err; 78 79 if (join_cgroup(FOO)) 80 goto err; 81 82 if (bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS)) { 83 log_err("Attaching prog to /foo"); 84 goto err; 85 } 86 87 assert(system(PING_CMD) != 0); 88 89 /* Create cgroup /foo/bar, get fd, and join it */ 90 bar = create_and_get_cgroup(BAR); 91 if (!bar) 92 goto err; 93 94 if (join_cgroup(BAR)) 95 goto err; 96 97 assert(system(PING_CMD) != 0); 98 99 if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS)) { 100 log_err("Attaching prog to /foo/bar"); 101 goto err; 102 } 103 104 assert(system(PING_CMD) == 0); 105 106 107 if (bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS)) { 108 log_err("Detaching program from /foo/bar"); 109 goto err; 110 } 111 112 assert(system(PING_CMD) != 0); 113 114 if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS)) { 115 log_err("Attaching prog to /foo/bar"); 116 goto err; 117 } 118 119 if (bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS)) { 120 log_err("Detaching program from /foo"); 121 goto err; 122 } 123 124 assert(system(PING_CMD) == 0); 125 126 goto out; 127 128err: 129 rc = 1; 130 131out: 132 close(foo); 133 close(bar); 134 cleanup_cgroup_environment(); 135 return rc; 136}