1 #include <linux/unistd.h> 2 #include <linux/bpf.h> 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <stdint.h> 7 #include <unistd.h> 8 #include <string.h> 9 #include <assert.h> 10 #include <errno.h> 11 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 15 #include "bpf_load.h" 16 #include "libbpf.h" 17 18 #define BPF_F_PIN (1 << 0) 19 #define BPF_F_GET (1 << 1) 20 #define BPF_F_PIN_GET (BPF_F_PIN | BPF_F_GET) 21 22 #define BPF_F_KEY (1 << 2) 23 #define BPF_F_VAL (1 << 3) 24 #define BPF_F_KEY_VAL (BPF_F_KEY | BPF_F_VAL) 25 26 #define BPF_M_UNSPEC 0 27 #define BPF_M_MAP 1 28 #define BPF_M_PROG 2 29 30 static void usage(void) 31 { 32 printf("Usage: fds_example [...]\n"); 33 printf(" -F <file> File to pin/get object\n"); 34 printf(" -P |- pin object\n"); 35 printf(" -G `- get object\n"); 36 printf(" -m eBPF map mode\n"); 37 printf(" -k <key> |- map key\n"); 38 printf(" -v <value> `- map value\n"); 39 printf(" -p eBPF prog mode\n"); 40 printf(" -o <object> `- object file\n"); 41 printf(" -h Display this help.\n"); 42 } 43 44 static int bpf_map_create(void) 45 { 46 return bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(uint32_t), 47 sizeof(uint32_t), 1024, 0); 48 } 49 50 static int bpf_prog_create(const char *object) 51 { 52 static const struct bpf_insn insns[] = { 53 BPF_MOV64_IMM(BPF_REG_0, 1), 54 BPF_EXIT_INSN(), 55 }; 56 57 if (object) { 58 assert(!load_bpf_file((char *)object)); 59 return prog_fd[0]; 60 } else { 61 return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, 62 insns, sizeof(insns), "GPL", 0, 63 bpf_log_buf, BPF_LOG_BUF_SIZE); 64 } 65 } 66 67 static int bpf_do_map(const char *file, uint32_t flags, uint32_t key, 68 uint32_t value) 69 { 70 int fd, ret; 71 72 if (flags & BPF_F_PIN) { 73 fd = bpf_map_create(); 74 printf("bpf: map fd:%d (%s)\n", fd, strerror(errno)); 75 assert(fd > 0); 76 77 ret = bpf_obj_pin(fd, file); 78 printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno)); 79 assert(ret == 0); 80 } else { 81 fd = bpf_obj_get(file); 82 printf("bpf: get fd:%d (%s)\n", fd, strerror(errno)); 83 assert(fd > 0); 84 } 85 86 if ((flags & BPF_F_KEY_VAL) == BPF_F_KEY_VAL) { 87 ret = bpf_map_update_elem(fd, &key, &value, 0); 88 printf("bpf: fd:%d u->(%u:%u) ret:(%d,%s)\n", fd, key, value, 89 ret, strerror(errno)); 90 assert(ret == 0); 91 } else if (flags & BPF_F_KEY) { 92 ret = bpf_map_lookup_elem(fd, &key, &value); 93 printf("bpf: fd:%d l->(%u):%u ret:(%d,%s)\n", fd, key, value, 94 ret, strerror(errno)); 95 assert(ret == 0); 96 } 97 98 return 0; 99 } 100 101 static int bpf_do_prog(const char *file, uint32_t flags, const char *object) 102 { 103 int fd, sock, ret; 104 105 if (flags & BPF_F_PIN) { 106 fd = bpf_prog_create(object); 107 printf("bpf: prog fd:%d (%s)\n", fd, strerror(errno)); 108 assert(fd > 0); 109 110 ret = bpf_obj_pin(fd, file); 111 printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno)); 112 assert(ret == 0); 113 } else { 114 fd = bpf_obj_get(file); 115 printf("bpf: get fd:%d (%s)\n", fd, strerror(errno)); 116 assert(fd > 0); 117 } 118 119 sock = open_raw_sock("lo"); 120 assert(sock > 0); 121 122 ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &fd, sizeof(fd)); 123 printf("bpf: sock:%d <- fd:%d attached ret:(%d,%s)\n", sock, fd, 124 ret, strerror(errno)); 125 assert(ret == 0); 126 127 return 0; 128 } 129 130 int main(int argc, char **argv) 131 { 132 const char *file = NULL, *object = NULL; 133 uint32_t key = 0, value = 0, flags = 0; 134 int opt, mode = BPF_M_UNSPEC; 135 136 while ((opt = getopt(argc, argv, "F:PGmk:v:po:")) != -1) { 137 switch (opt) { 138 /* General args */ 139 case 'F': 140 file = optarg; 141 break; 142 case 'P': 143 flags |= BPF_F_PIN; 144 break; 145 case 'G': 146 flags |= BPF_F_GET; 147 break; 148 /* Map-related args */ 149 case 'm': 150 mode = BPF_M_MAP; 151 break; 152 case 'k': 153 key = strtoul(optarg, NULL, 0); 154 flags |= BPF_F_KEY; 155 break; 156 case 'v': 157 value = strtoul(optarg, NULL, 0); 158 flags |= BPF_F_VAL; 159 break; 160 /* Prog-related args */ 161 case 'p': 162 mode = BPF_M_PROG; 163 break; 164 case 'o': 165 object = optarg; 166 break; 167 default: 168 goto out; 169 } 170 } 171 172 if (!(flags & BPF_F_PIN_GET) || !file) 173 goto out; 174 175 switch (mode) { 176 case BPF_M_MAP: 177 return bpf_do_map(file, flags, key, value); 178 case BPF_M_PROG: 179 return bpf_do_prog(file, flags, object); 180 } 181 out: 182 usage(); 183 return -1; 184 } 185