forked from cilium/cilium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbpf_network.c
98 lines (82 loc) · 2.71 KB
/
bpf_network.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
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
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright Authors of Cilium */
#include <bpf/ctx/skb.h>
#include <bpf/api.h>
#include <node_config.h>
#include <netdev_config.h>
#include "lib/common.h"
#include "lib/trace.h"
#include "lib/encrypt.h"
__section_entry
int cil_from_network(struct __ctx_buff *ctx)
{
int ret = CTX_ACT_OK;
__u16 proto __maybe_unused;
__u32 ingress_ifindex = ctx->ingress_ifindex;
struct trace_ctx trace = {
.reason = TRACE_REASON_UNKNOWN,
.monitor = 0,
};
enum trace_point obs_point_to = TRACE_TO_STACK;
enum trace_point obs_point_from = TRACE_FROM_NETWORK;
bpf_clear_meta(ctx);
barrier_data(ctx); /* clang-10 workaround */
/* This program should be attached to the tc-ingress of
* the network-facing device. Thus, as far as Cilium
* knows, no one touches to the ctx->mark before this
* program.
*
* One exception is the case the packets are re-insearted
* from the stack by xfrm. In that case, the packets should
* be marked with MARK_MAGIC_DECRYPT.
*/
if ((ctx->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT)
obs_point_from = TRACE_FROM_STACK;
#ifdef ENABLE_IPSEC
/* Pass unknown protocols to the stack */
if (!validate_ethertype(ctx, &proto))
goto out;
ret = do_decrypt(ctx, proto);
#endif
/* We need to handle following possible packets come to this program
*
* 1. ESP packets coming from network (encrypted and not marked)
* 2. Non-ESP packets coming from network (plain and not marked)
* 3. Non-ESP packets coming from stack re-inserted by xfrm (plain
* and marked with MARK_MAGIC_DECRYPT, IPSec mode only)
*
* 1. will be traced with TRACE_REASON_ENCRYPTED, because
* do_decrypt marks them with MARK_MAGIC_DECRYPT.
*
* 2. will be traced without TRACE_REASON_ENCRYPTED, because
* do_decrypt does't touch to mark.
*
* 3. will be traced without TRACE_REASON_ENCRYPTED, because
* do_decrypt clears the mark.
*
* Note that 1. contains the ESP packets someone else generated.
* In that case, we trace it as "encrypted", but it doesn't mean
* "encrypted by Cilium".
*
* We won't use TRACE_REASON_ENCRYPTED even if the packets are ESP,
* because it doesn't matter for the non-IPSec mode.
*/
#ifdef ENABLE_IPSEC
if ((ctx->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT)
trace.reason = TRACE_REASON_ENCRYPTED;
/* Only possible redirect in here is the one in the do_decrypt
* which redirects to cilium_host.
*/
if (ret == CTX_ACT_REDIRECT)
obs_point_to = TRACE_TO_HOST;
#endif
out:
send_trace_notify(ctx, obs_point_from, 0, 0, 0,
ingress_ifindex,
trace.reason, trace.monitor);
send_trace_notify(ctx, obs_point_to, 0, 0, 0,
ingress_ifindex,
trace.reason, trace.monitor);
return ret;
}
BPF_LICENSE("Dual BSD/GPL");