Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/* eBPF mini library */
  2#include <stdlib.h>
  3#include <stdio.h>
  4#include <linux/unistd.h>
  5#include <unistd.h>
  6#include <string.h>
  7#include <linux/netlink.h>
  8#include <linux/bpf.h>
  9#include <errno.h>
 10#include <net/ethernet.h>
 11#include <net/if.h>
 12#include <linux/if_packet.h>
 13#include <arpa/inet.h>
 14#include "libbpf.h"
 15
 16static __u64 ptr_to_u64(void *ptr)
 17{
 18	return (__u64) (unsigned long) ptr;
 19}
 20
 21int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
 22		   int max_entries, int map_flags)
 23{
 24	union bpf_attr attr = {
 25		.map_type = map_type,
 26		.key_size = key_size,
 27		.value_size = value_size,
 28		.max_entries = max_entries,
 29		.map_flags = map_flags,
 30	};
 31
 32	return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
 33}
 34
 35int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags)
 36{
 37	union bpf_attr attr = {
 38		.map_fd = fd,
 39		.key = ptr_to_u64(key),
 40		.value = ptr_to_u64(value),
 41		.flags = flags,
 42	};
 43
 44	return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
 45}
 46
 47int bpf_lookup_elem(int fd, void *key, void *value)
 48{
 49	union bpf_attr attr = {
 50		.map_fd = fd,
 51		.key = ptr_to_u64(key),
 52		.value = ptr_to_u64(value),
 53	};
 54
 55	return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
 56}
 57
 58int bpf_delete_elem(int fd, void *key)
 59{
 60	union bpf_attr attr = {
 61		.map_fd = fd,
 62		.key = ptr_to_u64(key),
 63	};
 64
 65	return syscall(__NR_bpf, BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
 66}
 67
 68int bpf_get_next_key(int fd, void *key, void *next_key)
 69{
 70	union bpf_attr attr = {
 71		.map_fd = fd,
 72		.key = ptr_to_u64(key),
 73		.next_key = ptr_to_u64(next_key),
 74	};
 75
 76	return syscall(__NR_bpf, BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
 77}
 78
 79#define ROUND_UP(x, n) (((x) + (n) - 1u) & ~((n) - 1u))
 80
 81char bpf_log_buf[LOG_BUF_SIZE];
 82
 83int bpf_prog_load(enum bpf_prog_type prog_type,
 84		  const struct bpf_insn *insns, int prog_len,
 85		  const char *license, int kern_version)
 86{
 87	union bpf_attr attr = {
 88		.prog_type = prog_type,
 89		.insns = ptr_to_u64((void *) insns),
 90		.insn_cnt = prog_len / sizeof(struct bpf_insn),
 91		.license = ptr_to_u64((void *) license),
 92		.log_buf = ptr_to_u64(bpf_log_buf),
 93		.log_size = LOG_BUF_SIZE,
 94		.log_level = 1,
 95	};
 96
 97	/* assign one field outside of struct init to make sure any
 98	 * padding is zero initialized
 99	 */
100	attr.kern_version = kern_version;
101
102	bpf_log_buf[0] = 0;
103
104	return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
105}
106
107int bpf_obj_pin(int fd, const char *pathname)
108{
109	union bpf_attr attr = {
110		.pathname	= ptr_to_u64((void *)pathname),
111		.bpf_fd		= fd,
112	};
113
114	return syscall(__NR_bpf, BPF_OBJ_PIN, &attr, sizeof(attr));
115}
116
117int bpf_obj_get(const char *pathname)
118{
119	union bpf_attr attr = {
120		.pathname	= ptr_to_u64((void *)pathname),
121	};
122
123	return syscall(__NR_bpf, BPF_OBJ_GET, &attr, sizeof(attr));
124}
125
126int open_raw_sock(const char *name)
127{
128	struct sockaddr_ll sll;
129	int sock;
130
131	sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, htons(ETH_P_ALL));
132	if (sock < 0) {
133		printf("cannot create raw socket\n");
134		return -1;
135	}
136
137	memset(&sll, 0, sizeof(sll));
138	sll.sll_family = AF_PACKET;
139	sll.sll_ifindex = if_nametoindex(name);
140	sll.sll_protocol = htons(ETH_P_ALL);
141	if (bind(sock, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
142		printf("bind to %s: %s\n", name, strerror(errno));
143		close(sock);
144		return -1;
145	}
146
147	return sock;
148}
149
150int perf_event_open(struct perf_event_attr *attr, int pid, int cpu,
151		    int group_fd, unsigned long flags)
152{
153	return syscall(__NR_perf_event_open, attr, pid, cpu,
154		       group_fd, flags);
155}