1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| // SPDX-License-Identifier: GPL-2.0
| /* Copyright (c) 2020 Cloudflare */
| #include "bpf_iter.h"
| #include "bpf_tracing_net.h"
| #include <bpf/bpf_helpers.h>
| #include <bpf/bpf_tracing.h>
| #include <errno.h>
|
| char _license[] SEC("license") = "GPL";
|
| struct {
| __uint(type, BPF_MAP_TYPE_SOCKMAP);
| __uint(max_entries, 64);
| __type(key, __u32);
| __type(value, __u64);
| } sockmap SEC(".maps");
|
| struct {
| __uint(type, BPF_MAP_TYPE_SOCKHASH);
| __uint(max_entries, 64);
| __type(key, __u32);
| __type(value, __u64);
| } sockhash SEC(".maps");
|
| struct {
| __uint(type, BPF_MAP_TYPE_SOCKHASH);
| __uint(max_entries, 64);
| __type(key, __u32);
| __type(value, __u64);
| } dst SEC(".maps");
|
| __u32 elems = 0;
| __u32 socks = 0;
|
| SEC("iter/sockmap")
| int copy(struct bpf_iter__sockmap *ctx)
| {
| struct sock *sk = ctx->sk;
| __u32 tmp, *key = ctx->key;
| int ret;
|
| if (!key)
| return 0;
|
| elems++;
|
| /* We need a temporary buffer on the stack, since the verifier doesn't
| * let us use the pointer from the context as an argument to the helper.
| */
| tmp = *key;
|
| if (sk) {
| socks++;
| return bpf_map_update_elem(&dst, &tmp, sk, 0) != 0;
| }
|
| ret = bpf_map_delete_elem(&dst, &tmp);
| return ret && ret != -ENOENT;
| }
|
|