^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * ibumad BPF sample user side
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * modify it under the terms of version 2 of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * License as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright(c) 2018 Ira Weiny, Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sys/resource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <getopt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <net/if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "bpf_load.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "bpf_util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <bpf/libbpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static void dump_counts(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) __u32 key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) __u64 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) for (key = 0; key < 256; key++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (bpf_map_lookup_elem(fd, &key, &value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) printf("failed to read key %u\n", key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) printf("0x%02x : %llu\n", key, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static void dump_all_counts(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) printf("Read 'Class : count'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dump_counts(map_fd[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) printf("Write 'Class : count'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) dump_counts(map_fd[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void dump_exit(int sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) dump_all_counts();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static const struct option long_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {"help", no_argument, NULL, 'h'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {"delay", required_argument, NULL, 'd'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static void usage(char *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) printf("eBPF test program to count packets from various IP addresses\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) "Usage: %s <options>\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) " --help, -h this menu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) " --delay, -d <delay> wait <delay> sec between prints [1 - 1000000]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) , cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int main(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned long delay = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int longindex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) char bpf_file[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Create the eBPF kernel code path name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * This follows the pattern of all of the other bpf samples
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) snprintf(bpf_file, sizeof(bpf_file), "%s_kern.o", argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Do one final dump when exiting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) signal(SIGINT, dump_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) signal(SIGTERM, dump_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) while ((opt = getopt_long(argc, argv, "hd:rSw",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) long_options, &longindex)) != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) delay = strtoul(optarg, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (delay == ULONG_MAX || delay < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) delay > 1000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) fprintf(stderr, "ERROR: invalid delay : %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) usage(argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) usage(argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (load_bpf_file(bpf_file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) fprintf(stderr, "ERROR: failed to load eBPF from file : %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) bpf_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) sleep(delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) dump_all_counts();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }