Blame view

samples/bpf/libbpf.c 2.67 KB
3c731eba4   Alexei Starovoitov   bpf: mini eBPF li...
1
2
3
4
5
6
7
8
9
  /* eBPF mini library */
  #include <stdlib.h>
  #include <stdio.h>
  #include <linux/unistd.h>
  #include <unistd.h>
  #include <string.h>
  #include <linux/netlink.h>
  #include <linux/bpf.h>
  #include <errno.h>
03f4723ed   Alexei Starovoitov   samples: bpf: exa...
10
11
12
13
  #include <net/ethernet.h>
  #include <net/if.h>
  #include <linux/if_packet.h>
  #include <arpa/inet.h>
3c731eba4   Alexei Starovoitov   bpf: mini eBPF li...
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  #include "libbpf.h"
  
  static __u64 ptr_to_u64(void *ptr)
  {
  	return (__u64) (unsigned long) ptr;
  }
  
  int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
  		   int max_entries)
  {
  	union bpf_attr attr = {
  		.map_type = map_type,
  		.key_size = key_size,
  		.value_size = value_size,
  		.max_entries = max_entries
  	};
  
  	return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
  }
ffb65f27a   Alexei Starovoitov   bpf: add a testsu...
33
  int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags)
3c731eba4   Alexei Starovoitov   bpf: mini eBPF li...
34
35
36
37
38
  {
  	union bpf_attr attr = {
  		.map_fd = fd,
  		.key = ptr_to_u64(key),
  		.value = ptr_to_u64(value),
ffb65f27a   Alexei Starovoitov   bpf: add a testsu...
39
  		.flags = flags,
3c731eba4   Alexei Starovoitov   bpf: mini eBPF li...
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  	};
  
  	return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
  }
  
  int bpf_lookup_elem(int fd, void *key, void *value)
  {
  	union bpf_attr attr = {
  		.map_fd = fd,
  		.key = ptr_to_u64(key),
  		.value = ptr_to_u64(value),
  	};
  
  	return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
  }
  
  int bpf_delete_elem(int fd, void *key)
  {
  	union bpf_attr attr = {
  		.map_fd = fd,
  		.key = ptr_to_u64(key),
  	};
  
  	return syscall(__NR_bpf, BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
  }
  
  int bpf_get_next_key(int fd, void *key, void *next_key)
  {
  	union bpf_attr attr = {
  		.map_fd = fd,
  		.key = ptr_to_u64(key),
  		.next_key = ptr_to_u64(next_key),
  	};
  
  	return syscall(__NR_bpf, BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
  }
  
  #define ROUND_UP(x, n) (((x) + (n) - 1u) & ~((n) - 1u))
  
  char bpf_log_buf[LOG_BUF_SIZE];
  
  int bpf_prog_load(enum bpf_prog_type prog_type,
  		  const struct bpf_insn *insns, int prog_len,
  		  const char *license)
  {
  	union bpf_attr attr = {
  		.prog_type = prog_type,
  		.insns = ptr_to_u64((void *) insns),
  		.insn_cnt = prog_len / sizeof(struct bpf_insn),
  		.license = ptr_to_u64((void *) license),
  		.log_buf = ptr_to_u64(bpf_log_buf),
  		.log_size = LOG_BUF_SIZE,
  		.log_level = 1,
  	};
  
  	bpf_log_buf[0] = 0;
  
  	return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
  }
03f4723ed   Alexei Starovoitov   samples: bpf: exa...
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  
  int open_raw_sock(const char *name)
  {
  	struct sockaddr_ll sll;
  	int sock;
  
  	sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, htons(ETH_P_ALL));
  	if (sock < 0) {
  		printf("cannot create raw socket
  ");
  		return -1;
  	}
  
  	memset(&sll, 0, sizeof(sll));
  	sll.sll_family = AF_PACKET;
  	sll.sll_ifindex = if_nametoindex(name);
  	sll.sll_protocol = htons(ETH_P_ALL);
  	if (bind(sock, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
  		printf("bind to %s: %s
  ", name, strerror(errno));
  		close(sock);
  		return -1;
  	}
  
  	return sock;
  }