-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathecho_dispatch.bpf.c
63 lines (53 loc) · 1.57 KB
/
echo_dispatch.bpf.c
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
60
61
62
63
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (c) 2020 Cloudflare */
/*
* BPF socket lookup program that dispatches connections destined to a
* configured set of open ports, to the echo service socket.
*
* Program expects the echo service socket to be in the `echo_socket` BPF map.
* Port is considered open when an entry for that port number exists in the
* `echo_ports` BPF hashmap.
*
*/
#include <linux/bpf.h>
#include <bpf/bpf_endian.h>
#include <bpf/bpf_helpers.h>
/* Declare BPF maps */
/* List of open echo service ports. Key is the port number. */
struct bpf_map_def SEC("maps") echo_ports = {
.type = BPF_MAP_TYPE_HASH,
.max_entries = 1024,
.key_size = sizeof(__u16),
.value_size = sizeof(__u8),
};
/* Echo server socket */
struct bpf_map_def SEC("maps") echo_socket = {
.type = BPF_MAP_TYPE_SOCKMAP,
.max_entries = 1,
.key_size = sizeof(__u32),
.value_size = sizeof(__u64),
};
/* Dispatcher program for the echo service */
SEC("sk_lookup/echo_dispatch")
int echo_dispatch(struct bpf_sk_lookup *ctx)
{
const __u32 zero = 0;
struct bpf_sock *sk;
__u16 port;
__u8 *open;
long err;
/* Is echo service enabled on packets destination port? */
port = ctx->local_port;
open = bpf_map_lookup_elem(&echo_ports, &port);
if (!open)
return SK_PASS;
/* Get echo server socket */
sk = bpf_map_lookup_elem(&echo_socket, &zero);
if (!sk)
return SK_DROP;
/* Dispatch the packet to echo server socket */
err = bpf_sk_assign(ctx, sk, 0);
bpf_sk_release(sk);
return err ? SK_DROP : SK_PASS;
}
SEC("license") const char __license[] = "Dual BSD/GPL";