Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
Note: File does not exist in v4.6.
  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/bpf.h>
 27#include "bpf_util.h"
 28#include <bpf/libbpf.h>
 29
 30static struct bpf_link *tp_links[3];
 31static struct bpf_object *obj;
 32static int map_fd[2];
 33static int tp_cnt;
 34
 35static void dump_counts(int fd)
 36{
 37	__u32 key;
 38	__u64 value;
 39
 40	for (key = 0; key < 256; key++) {
 41		if (bpf_map_lookup_elem(fd, &key, &value)) {
 42			printf("failed to read key %u\n", key);
 43			continue;
 44		}
 45		if (value)
 46			printf("0x%02x : %llu\n", key, value);
 47	}
 48}
 49
 50static void dump_all_counts(void)
 51{
 52	printf("Read 'Class : count'\n");
 53	dump_counts(map_fd[0]);
 54	printf("Write 'Class : count'\n");
 55	dump_counts(map_fd[1]);
 56}
 57
 58static void dump_exit(int sig)
 59{
 60	dump_all_counts();
 61	/* Detach tracepoints */
 62	while (tp_cnt)
 63		bpf_link__destroy(tp_links[--tp_cnt]);
 64
 65	bpf_object__close(obj);
 66	exit(0);
 67}
 68
 69static const struct option long_options[] = {
 70	{"help",      no_argument,       NULL, 'h'},
 71	{"delay",     required_argument, NULL, 'd'},
 72};
 73
 74static void usage(char *cmd)
 75{
 76	printf("eBPF test program to count packets from various IP addresses\n"
 77		"Usage: %s <options>\n"
 78		"       --help,   -h  this menu\n"
 79		"       --delay,  -d  <delay>  wait <delay> sec between prints [1 - 1000000]\n"
 80		, cmd
 81		);
 82}
 83
 84int main(int argc, char **argv)
 85{
 86	struct bpf_program *prog;
 87	unsigned long delay = 5;
 88	char filename[256];
 89	int longindex = 0;
 90	int opt, err = -1;
 91
 92	while ((opt = getopt_long(argc, argv, "hd:rSw",
 93				  long_options, &longindex)) != -1) {
 94		switch (opt) {
 95		case 'd':
 96			delay = strtoul(optarg, NULL, 0);
 97			if (delay == ULONG_MAX || delay < 0 ||
 98			    delay > 1000000) {
 99				fprintf(stderr, "ERROR: invalid delay : %s\n",
100					optarg);
101				usage(argv[0]);
102				return 1;
103			}
104			break;
105		default:
106		case 'h':
107			usage(argv[0]);
108			return 1;
109		}
110	}
111
112	/* Do one final dump when exiting */
113	signal(SIGINT, dump_exit);
114	signal(SIGTERM, dump_exit);
115
116	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
117	obj = bpf_object__open_file(filename, NULL);
118	if (libbpf_get_error(obj)) {
119		fprintf(stderr, "ERROR: opening BPF object file failed\n");
120		return err;
121	}
122
123	/* load BPF program */
124	if (bpf_object__load(obj)) {
125		fprintf(stderr, "ERROR: loading BPF object file failed\n");
126		goto cleanup;
127	}
128
129	map_fd[0] = bpf_object__find_map_fd_by_name(obj, "read_count");
130	map_fd[1] = bpf_object__find_map_fd_by_name(obj, "write_count");
131	if (map_fd[0] < 0 || map_fd[1] < 0) {
132		fprintf(stderr, "ERROR: finding a map in obj file failed\n");
133		goto cleanup;
134	}
135
136	bpf_object__for_each_program(prog, obj) {
137		tp_links[tp_cnt] = bpf_program__attach(prog);
138		if (libbpf_get_error(tp_links[tp_cnt])) {
139			fprintf(stderr, "ERROR: bpf_program__attach failed\n");
140			tp_links[tp_cnt] = NULL;
141			goto cleanup;
142		}
143		tp_cnt++;
144	}
145
146	while (1) {
147		sleep(delay);
148		dump_all_counts();
149	}
150	err = 0;
151
152cleanup:
153	/* Detach tracepoints */
154	while (tp_cnt)
155		bpf_link__destroy(tp_links[--tp_cnt]);
156
157	bpf_object__close(obj);
158	return err;
159}