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); 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_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, 62 insns, sizeof(insns), "GPL", 0); 63 } 64 } 65 66 static int bpf_do_map(const char *file, uint32_t flags, uint32_t key, 67 uint32_t value) 68 { 69 int fd, ret; 70 71 if (flags & BPF_F_PIN) { 72 fd = bpf_map_create(); 73 printf("bpf: map fd:%d (%s)\n", fd, strerror(errno)); 74 assert(fd > 0); 75 76 ret = bpf_obj_pin(fd, file); 77 printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno)); 78 assert(ret == 0); 79 } else { 80 fd = bpf_obj_get(file); 81 printf("bpf: get fd:%d (%s)\n", fd, strerror(errno)); 82 assert(fd > 0); 83 } 84 85 if ((flags & BPF_F_KEY_VAL) == BPF_F_KEY_VAL) { 86 ret = bpf_update_elem(fd, &key, &value, 0); 87 printf("bpf: fd:%d u->(%u:%u) ret:(%d,%s)\n", fd, key, value, 88 ret, strerror(errno)); 89 assert(ret == 0); 90 } else if (flags & BPF_F_KEY) { 91 ret = bpf_lookup_elem(fd, &key, &value); 92 printf("bpf: fd:%d l->(%u):%u ret:(%d,%s)\n", fd, key, value, 93 ret, strerror(errno)); 94 assert(ret == 0); 95 } 96 97 return 0; 98 } 99 100 static int bpf_do_prog(const char *file, uint32_t flags, const char *object) 101 { 102 int fd, sock, ret; 103 104 if (flags & BPF_F_PIN) { 105 fd = bpf_prog_create(object); 106 printf("bpf: prog fd:%d (%s)\n", fd, strerror(errno)); 107 assert(fd > 0); 108 109 ret = bpf_obj_pin(fd, file); 110 printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno)); 111 assert(ret == 0); 112 } else { 113 fd = bpf_obj_get(file); 114 printf("bpf: get fd:%d (%s)\n", fd, strerror(errno)); 115 assert(fd > 0); 116 } 117 118 sock = open_raw_sock("lo"); 119 assert(sock > 0); 120 121 ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &fd, sizeof(fd)); 122 printf("bpf: sock:%d <- fd:%d attached ret:(%d,%s)\n", sock, fd, 123 ret, strerror(errno)); 124 assert(ret == 0); 125 126 return 0; 127 } 128 129 int main(int argc, char **argv) 130 { 131 const char *file = NULL, *object = NULL; 132 uint32_t key = 0, value = 0, flags = 0; 133 int opt, mode = BPF_M_UNSPEC; 134 135 while ((opt = getopt(argc, argv, "F:PGmk:v:po:")) != -1) { 136 switch (opt) { 137 /* General args */ 138 case 'F': 139 file = optarg; 140 break; 141 case 'P': 142 flags |= BPF_F_PIN; 143 break; 144 case 'G': 145 flags |= BPF_F_GET; 146 break; 147 /* Map-related args */ 148 case 'm': 149 mode = BPF_M_MAP; 150 break; 151 case 'k': 152 key = strtoul(optarg, NULL, 0); 153 flags |= BPF_F_KEY; 154 break; 155 case 'v': 156 value = strtoul(optarg, NULL, 0); 157 flags |= BPF_F_VAL; 158 break; 159 /* Prog-related args */ 160 case 'p': 161 mode = BPF_M_PROG; 162 break; 163 case 'o': 164 object = optarg; 165 break; 166 default: 167 goto out; 168 } 169 } 170 171 if (!(flags & BPF_F_PIN_GET) || !file) 172 goto out; 173 174 switch (mode) { 175 case BPF_M_MAP: 176 return bpf_do_map(file, flags, key, value); 177 case BPF_M_PROG: 178 return bpf_do_prog(file, flags, object); 179 } 180 out: 181 usage(); 182 return -1; 183 } 184