P4C
The P4 Compiler
Loading...
Searching...
No Matches
ebpfPipeline.h
1/*
2Copyright 2022-present Orange
3Copyright 2022-present Open Networking Foundation
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16*/
17#ifndef BACKENDS_EBPF_PSA_EBPFPIPELINE_H_
18#define BACKENDS_EBPF_PSA_EBPFPIPELINE_H_
19
20#include "backends/ebpf/ebpfProgram.h"
21#include "backends/ebpf/target.h"
22#include "ebpfPsaControl.h"
23#include "ebpfPsaDeparser.h"
24
25namespace P4::EBPF {
26
28class EBPFPipeline : public EBPFProgram {
29 public:
43 cstring packetPathVar, pktInstanceVar;
49 unsigned packetMark;
52
53 EBPFControlPSA *control;
54 EBPFDeparserPSA *deparser;
55
56 EBPFPipeline(cstring name, const EbpfOptions &options, P4::ReferenceMap *refMap,
57 P4::TypeMap *typeMap)
58 : EBPFProgram(options, nullptr, refMap, typeMap, nullptr),
59 name(name),
60 packetMark(0x99),
61 control(nullptr),
62 deparser(nullptr) {
63 sectionName = "classifier/" + name;
64 functionName = name.replace('-', '_') + "_func";
65 errorEnum = "ParserError_t"_cs;
66 packetStartVar = "pkt"_cs;
67 headerStartVar = "hdr_start"_cs;
68 contextVar = "skb"_cs;
69 lengthVar = "pkt_len"_cs;
70 endLabel = "deparser"_cs;
71 timestampVar = "tstamp"_cs;
72 ifindexVar = "skb->ifindex"_cs;
73 compilerGlobalMetadata = "compiler_meta__"_cs;
74 packetPathVar = compilerGlobalMetadata + "->packet_path"_cs;
75 pktInstanceVar = compilerGlobalMetadata + "->instance"_cs;
76 priorityVar = "skb->priority"_cs;
77 oneKey = EBPFModel::reserved("one"_cs);
78 inputPortVar = "ebpf_input_port"_cs;
79 progTarget = new KernelSamplesTarget(options.emitTraceMessages);
80 }
81
84 bool isEmpty() const;
85
86 virtual cstring dropReturnCode() {
87 if (sectionName.startsWith("xdp")) {
88 return "XDP_DROP"_cs;
89 }
90
91 // TC is the default hookpoint
92 return "TC_ACT_SHOT"_cs;
93 }
94 virtual cstring forwardReturnCode() {
95 if (sectionName.startsWith("xdp")) {
96 return "XDP_PASS"_cs;
97 }
98
99 // TC is the default hookpoint
100 return "TC_ACT_OK"_cs;
101 }
102
103 virtual void emit(CodeBuilder *builder) = 0;
104 virtual void emitTrafficManager(CodeBuilder *builder) = 0;
105 virtual void emitPSAControlInputMetadata(CodeBuilder *builder) = 0;
106 virtual void emitPSAControlOutputMetadata(CodeBuilder *builder) = 0;
107
109 void emitLocalHeaderInstancesAsPointers(CodeBuilder *builder);
111 void emitCPUMAPHeadersInitializers(CodeBuilder *builder);
114 void emitHeaderInstances(CodeBuilder *builder) override;
116 void emitLocalVariables(CodeBuilder *builder) override;
117
120 void emitUserMetadataInstance(CodeBuilder *builder);
121
122 virtual void emitCPUMAPInitializers(CodeBuilder *builder);
123 virtual void emitCPUMAPLookup(CodeBuilder *builder);
126 virtual void emitGlobalMetadataInitializer(CodeBuilder *builder);
127
128 virtual void emitPacketLength(CodeBuilder *builder);
129 virtual void emitTimestamp(CodeBuilder *builder);
130 void emitInputPortMapping(CodeBuilder *builder);
131
132 void emitHeadersFromCPUMAP(CodeBuilder *builder);
133 void emitMetadataFromCPUMAP(CodeBuilder *builder);
134
135 bool hasAnyMeter() const {
136 auto directMeter = std::find_if(control->tables.begin(), control->tables.end(),
137 [](std::pair<const cstring, EBPFTable *> elem) {
138 return !elem.second->to<EBPFTablePSA>()->meters.empty();
139 });
140 bool anyDirectMeter = directMeter != control->tables.end();
141 return anyDirectMeter || (!control->meters.empty());
142 }
148 bool shouldEmitTimestamp() const { return hasAnyMeter() || control->timestampIsUsed; }
149
150 DECLARE_TYPEINFO(EBPFPipeline, EBPFProgram);
151};
152
156 public:
157 unsigned int maxResubmitDepth;
161
163 P4::TypeMap *typeMap)
164 : EBPFPipeline(name, options, refMap, typeMap) {
165 // FIXME: hardcoded
166 maxResubmitDepth = 4;
167 // actUnspecCode should not collide with TC/XDP return codes,
168 // but it's safe to use the same value as TC_ACT_UNSPEC.
169 actUnspecCode = -1;
170 }
171
172 void emitSharedMetadataInitializer(CodeBuilder *builder);
173
174 void emit(CodeBuilder *builder) override;
175 void emitPSAControlInputMetadata(CodeBuilder *builder) override;
176 void emitPSAControlOutputMetadata(CodeBuilder *builder) override;
177
178 DECLARE_TYPEINFO(EBPFIngressPipeline, EBPFPipeline);
179};
180
184 public:
186 P4::TypeMap *typeMap)
187 : EBPFPipeline(name, options, refMap, typeMap) {}
188
189 void emit(CodeBuilder *builder) override;
190 void emitPSAControlInputMetadata(CodeBuilder *builder) override;
191 void emitPSAControlOutputMetadata(CodeBuilder *builder) override;
192 void emitCPUMAPLookup(CodeBuilder *builder) override;
193
194 virtual void emitCheckPacketMarkMetadata(CodeBuilder *builder) = 0;
195
196 DECLARE_TYPEINFO(EBPFEgressPipeline, EBPFPipeline);
197};
198
200 public:
202 P4::TypeMap *typeMap)
203 : EBPFIngressPipeline(name, options, refMap, typeMap) {}
204
205 void emitGlobalMetadataInitializer(CodeBuilder *builder) override;
206 void emitTrafficManager(CodeBuilder *builder) override;
207
208 private:
209 void emitTCWorkaroundUsingMeta(CodeBuilder *builder);
210 void emitTCWorkaroundUsingHead(CodeBuilder *builder);
211 void emitTCWorkaroundUsingCPUMAP(CodeBuilder *builder);
212
213 DECLARE_TYPEINFO(TCIngressPipeline, EBPFIngressPipeline);
214};
215
217 public:
219 P4::TypeMap *typeMap)
220 : EBPFEgressPipeline(name, options, refMap, typeMap) {}
221
222 void emitTrafficManager(CodeBuilder *builder) override;
223 void emitCheckPacketMarkMetadata(CodeBuilder *builder) override;
224
225 DECLARE_TYPEINFO(TCEgressPipeline, EBPFEgressPipeline);
226};
227
229 public:
231 P4::TypeMap *typeMap)
232 : EBPFIngressPipeline(name, options, refMap, typeMap) {
233 sectionName = "xdp_ingress/" + name;
234 ifindexVar = "skb->ingress_ifindex"_cs;
235 packetPathVar = compilerGlobalMetadata + "->packet_path"_cs;
236 progTarget = new XdpTarget(options.emitTraceMessages);
237 }
238
239 void emitGlobalMetadataInitializer(CodeBuilder *builder) override;
240 void emitTrafficManager(CodeBuilder *builder) override;
241
242 DECLARE_TYPEINFO(XDPIngressPipeline, EBPFIngressPipeline);
243};
244
246 public:
248 P4::TypeMap *typeMap)
249 : EBPFEgressPipeline(name, options, refMap, typeMap) {
250 sectionName = "xdp_devmap/" + name;
251 ifindexVar = "skb->egress_ifindex"_cs;
252 // we do not support packet path, instance & priority in the XDP egress.
253 packetPathVar = "0"_cs;
254 pktInstanceVar = "0"_cs;
255 priorityVar = "0"_cs;
256 progTarget = new XdpTarget(options.emitTraceMessages);
257 }
258
259 void emitGlobalMetadataInitializer(CodeBuilder *builder) override;
260 void emitTrafficManager(CodeBuilder *builder) override;
261 void emitCheckPacketMarkMetadata(CodeBuilder *builder) override;
262
263 DECLARE_TYPEINFO(XDPEgressPipeline, EBPFEgressPipeline);
264};
265
267 public:
269 P4::TypeMap *typeMap)
270 : TCIngressPipeline(name, options, refMap, typeMap) {}
271
272 void emitGlobalMetadataInitializer(CodeBuilder *builder) override;
273 void emit(CodeBuilder *builder) override;
274
275 private:
276 void emitReadXDP2TCMetadataFromHead(CodeBuilder *builder);
277 void emitReadXDP2TCMetadataFromCPUMAP(CodeBuilder *builder);
278
279 DECLARE_TYPEINFO(TCTrafficManagerForXDP, TCIngressPipeline);
280};
281
282} // namespace P4::EBPF
283
284#endif /* BACKENDS_EBPF_PSA_EBPFPIPELINE_H_ */
Definition ebpf/codeGen.h:33
Definition ebpfPsaControl.h:58
bool timestampIsUsed
Keeps track if ingress_timestamp or egress_timestamp is used within a control block.
Definition ebpfPsaControl.h:61
Definition ebpfPsaDeparser.h:39
Definition ebpfPipeline.h:183
Definition ebpfPipeline.h:155
int actUnspecCode
Definition ebpfPipeline.h:160
EBPFPipeline represents a single eBPF program in the TC/XDP hook.
Definition ebpfPipeline.h:28
void emitLocalHeaderInstancesAsPointers(CodeBuilder *builder)
Generates a pointer to struct Headers_t and puts it on the BPF program's stack.
Definition ebpfPipeline.cpp:105
cstring name
A custom name of eBPF program.
Definition ebpfPipeline.h:31
void emitHeaderInstances(CodeBuilder *builder) override
Definition ebpfPipeline.cpp:117
cstring packetPathVar
Variables storing global metadata (packet_path & instance).
Definition ebpfPipeline.h:43
cstring inputPortVar
A variable to store ifindex after mapping (e.g. due to recirculation).
Definition ebpfPipeline.h:51
bool shouldEmitTimestamp() const
Definition ebpfPipeline.h:148
cstring ifindexVar
Variable storing ingress interface index.
Definition ebpfPipeline.h:39
cstring oneKey
A variable name storing "1" value. Used to access BPF array map index.
Definition ebpfPipeline.h:47
virtual void emitGlobalMetadataInitializer(CodeBuilder *builder)
Definition ebpfPipeline.cpp:153
void emitLocalVariables(CodeBuilder *builder) override
Generates a set of helper variables that are used during packet processing.
Definition ebpfPipeline.cpp:50
bool isEmpty() const
Definition ebpfPipeline.cpp:23
unsigned packetMark
A unique mark used to differentiate packets processed by P4/eBPF from others.
Definition ebpfPipeline.h:49
void emitCPUMAPHeadersInitializers(CodeBuilder *builder)
Generates a pointer to struct hdr_md. The pointer is used to access data from per-CPU map.
Definition ebpfPipeline.cpp:112
cstring sectionName
eBPF section name, which should a concatenation of classifier/ + a custom name.
Definition ebpfPipeline.h:33
cstring compilerGlobalMetadata
A name of an internal variable storing global metadata.
Definition ebpfPipeline.h:45
cstring timestampVar
Variable name storing current timestamp retrieved from bpf_ktime_get_ns().
Definition ebpfPipeline.h:37
cstring priorityVar
Variable storing skb->priority value (TC only).
Definition ebpfPipeline.h:41
void emitUserMetadataInstance(CodeBuilder *builder)
Definition ebpfPipeline.cpp:94
cstring contextVar
Variable name storing pointer to eBPF packet descriptor (e.g., __sk_buff).
Definition ebpfPipeline.h:35
Definition ebpfProgram.h:39
Definition ebpf/target.h:130
Definition ebpfPipeline.h:216
Definition ebpfPipeline.h:199
void emitTrafficManager(CodeBuilder *builder) override
Definition ebpfPipeline.cpp:558
void emitGlobalMetadataInitializer(CodeBuilder *builder) override
Definition ebpfPipeline.cpp:474
Definition ebpfPipeline.h:266
void emitGlobalMetadataInitializer(CodeBuilder *builder) override
Definition ebpfPipeline.cpp:754
Definition ebpfPipeline.h:245
void emitGlobalMetadataInitializer(CodeBuilder *builder) override
Definition ebpfPipeline.cpp:710
Definition ebpfPipeline.h:228
void emitGlobalMetadataInitializer(CodeBuilder *builder) override
Definition ebpfPipeline.cpp:686
Target XDP.
Definition ebpf/target.h:243
Definition ebpfOptions.h:26
bool emitTraceMessages
tracing eBPF code execution
Definition ebpfOptions.h:35
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition typeMap.h:41
Definition cstring.h:85
Definition codeGen.cpp:25