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