linux/samples/bpf/sockex3_user.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <stdio.h>
   3#include <assert.h>
   4#include <bpf/bpf.h>
   5#include <bpf/libbpf.h>
   6#include "sock_example.h"
   7#include <unistd.h>
   8#include <arpa/inet.h>
   9#include <sys/resource.h>
  10
  11struct flow_key_record {
  12        __be32 src;
  13        __be32 dst;
  14        union {
  15                __be32 ports;
  16                __be16 port16[2];
  17        };
  18        __u32 ip_proto;
  19};
  20
  21struct pair {
  22        __u64 packets;
  23        __u64 bytes;
  24};
  25
  26int main(int argc, char **argv)
  27{
  28        int i, sock, key, fd, main_prog_fd, jmp_table_fd, hash_map_fd;
  29        struct bpf_program *prog;
  30        struct bpf_object *obj;
  31        const char *section;
  32        char filename[256];
  33        FILE *f;
  34
  35        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
  36
  37        obj = bpf_object__open_file(filename, NULL);
  38        if (libbpf_get_error(obj)) {
  39                fprintf(stderr, "ERROR: opening BPF object file failed\n");
  40                return 0;
  41        }
  42
  43        /* load BPF program */
  44        if (bpf_object__load(obj)) {
  45                fprintf(stderr, "ERROR: loading BPF object file failed\n");
  46                goto cleanup;
  47        }
  48
  49        jmp_table_fd = bpf_object__find_map_fd_by_name(obj, "jmp_table");
  50        hash_map_fd = bpf_object__find_map_fd_by_name(obj, "hash_map");
  51        if (jmp_table_fd < 0 || hash_map_fd < 0) {
  52                fprintf(stderr, "ERROR: finding a map in obj file failed\n");
  53                goto cleanup;
  54        }
  55
  56        bpf_object__for_each_program(prog, obj) {
  57                fd = bpf_program__fd(prog);
  58
  59                section = bpf_program__section_name(prog);
  60                if (sscanf(section, "socket/%d", &key) != 1) {
  61                        fprintf(stderr, "ERROR: finding prog failed\n");
  62                        goto cleanup;
  63                }
  64
  65                if (key == 0)
  66                        main_prog_fd = fd;
  67                else
  68                        bpf_map_update_elem(jmp_table_fd, &key, &fd, BPF_ANY);
  69        }
  70
  71        sock = open_raw_sock("lo");
  72
  73        /* attach BPF program to socket */
  74        assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &main_prog_fd,
  75                          sizeof(__u32)) == 0);
  76
  77        if (argc > 1)
  78                f = popen("ping -4 -c5 localhost", "r");
  79        else
  80                f = popen("netperf -l 4 localhost", "r");
  81        (void) f;
  82
  83        for (i = 0; i < 5; i++) {
  84                struct flow_key_record key = {}, next_key;
  85                struct pair value;
  86
  87                sleep(1);
  88                printf("IP     src.port -> dst.port               bytes      packets\n");
  89                while (bpf_map_get_next_key(hash_map_fd, &key, &next_key) == 0) {
  90                        bpf_map_lookup_elem(hash_map_fd, &next_key, &value);
  91                        printf("%s.%05d -> %s.%05d %12lld %12lld\n",
  92                               inet_ntoa((struct in_addr){htonl(next_key.src)}),
  93                               next_key.port16[0],
  94                               inet_ntoa((struct in_addr){htonl(next_key.dst)}),
  95                               next_key.port16[1],
  96                               value.bytes, value.packets);
  97                        key = next_key;
  98                }
  99        }
 100
 101cleanup:
 102        bpf_object__close(obj);
 103        return 0;
 104}
 105