]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - samples/bpf/sockex3_user.c
staging: vboxvideo: Add vboxvideo to drivers/staging
[karo-tx-linux.git] / samples / bpf / sockex3_user.c
1 #include <stdio.h>
2 #include <assert.h>
3 #include <linux/bpf.h>
4 #include "libbpf.h"
5 #include "bpf_load.h"
6 #include "sock_example.h"
7 #include <unistd.h>
8 #include <arpa/inet.h>
9 #include <sys/resource.h>
10
11 #define PARSE_IP 3
12 #define PARSE_IP_PROG_FD (prog_fd[0])
13 #define PROG_ARRAY_FD (map_fd[0])
14
15 struct bpf_flow_keys {
16         __be32 src;
17         __be32 dst;
18         union {
19                 __be32 ports;
20                 __be16 port16[2];
21         };
22         __u32 ip_proto;
23 };
24
25 struct pair {
26         __u64 packets;
27         __u64 bytes;
28 };
29
30 int main(int argc, char **argv)
31 {
32         struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
33         char filename[256];
34         FILE *f;
35         int i, sock, err, id, key = PARSE_IP;
36         struct bpf_prog_info info = {};
37         uint32_t info_len = sizeof(info);
38
39         snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
40         setrlimit(RLIMIT_MEMLOCK, &r);
41
42         if (load_bpf_file(filename)) {
43                 printf("%s", bpf_log_buf);
44                 return 1;
45         }
46
47         /* Test fd array lookup which returns the id of the bpf_prog */
48         err = bpf_obj_get_info_by_fd(PARSE_IP_PROG_FD, &info, &info_len);
49         assert(!err);
50         err = bpf_map_lookup_elem(PROG_ARRAY_FD, &key, &id);
51         assert(!err);
52         assert(id == info.id);
53
54         sock = open_raw_sock("lo");
55
56         assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd[4],
57                           sizeof(__u32)) == 0);
58
59         if (argc > 1)
60                 f = popen("ping -c5 localhost", "r");
61         else
62                 f = popen("netperf -l 4 localhost", "r");
63         (void) f;
64
65         for (i = 0; i < 5; i++) {
66                 struct bpf_flow_keys key = {}, next_key;
67                 struct pair value;
68
69                 sleep(1);
70                 printf("IP     src.port -> dst.port               bytes      packets\n");
71                 while (bpf_map_get_next_key(map_fd[2], &key, &next_key) == 0) {
72                         bpf_map_lookup_elem(map_fd[2], &next_key, &value);
73                         printf("%s.%05d -> %s.%05d %12lld %12lld\n",
74                                inet_ntoa((struct in_addr){htonl(next_key.src)}),
75                                next_key.port16[0],
76                                inet_ntoa((struct in_addr){htonl(next_key.dst)}),
77                                next_key.port16[1],
78                                value.bytes, value.packets);
79                         key = next_key;
80                 }
81         }
82         return 0;
83 }