P4C
The P4 Compiler
Loading...
Searching...
No Matches
ebpfCodeGen.h
1/*
2Copyright (C) 2023 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing,
11software distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions
14and limitations under the License.
15*/
16
17#ifndef BACKENDS_TC_EBPFCODEGEN_H_
18#define BACKENDS_TC_EBPFCODEGEN_H_
19
20// FIXME: these include each other and present file
21#include "backend.h"
22#include "tcExterns.h"
23
24namespace P4::TC {
25
26using namespace P4::literals;
27
28class ConvertToBackendIR;
29class EBPFPnaParser;
30class EBPFRegisterPNA;
31class EBPFHashPNA;
32
33// Similar to class PSAEbpfGenerator in backends/ebpf/psa/ebpfPsaGen.h
34
36 public:
37 EBPF::EBPFPipeline *pipeline;
38 const ConvertToBackendIR *tcIR;
39
40 PNAEbpfGenerator(const EbpfOptions &options, std::vector<EBPF::EBPFType *> &ebpfTypes,
41 EBPF::EBPFPipeline *pipeline, const ConvertToBackendIR *tcIR)
42 : EBPF::EbpfCodeGenerator(options, ebpfTypes), pipeline(pipeline), tcIR(tcIR) {}
43
44 virtual void emit(EBPF::CodeBuilder *builder) const = 0;
45 virtual void emitInstances(EBPF::CodeBuilder *builder) const = 0;
46 virtual void emitParser(EBPF::CodeBuilder *builder) const = 0;
47 virtual void emitHeader(EBPF::CodeBuilder *builder) const = 0;
48 void emitPNAIncludes(EBPF::CodeBuilder *builder) const;
49 void emitPreamble(EBPF::CodeBuilder *builder) const override;
50 void emitCommonPreamble(EBPF::CodeBuilder *builder) const override;
51 void emitInternalStructures(EBPF::CodeBuilder *pBuilder) const override;
52 void emitTypes(EBPF::CodeBuilder *builder) const override;
53 void emitGlobalHeadersMetadata(EBPF::CodeBuilder *builder) const override;
54 void emitPipelineInstances(EBPF::CodeBuilder *builder) const override;
55 void emitP4TCFilterFields(EBPF::CodeBuilder *builder) const;
56 void emitP4TCActionParam(EBPF::CodeBuilder *builder) const;
57 cstring getProgramName() const;
58};
59
60// Similar to class PSAErrorCodesGen in backends/ebpf/psa/ebpfPsaGen.cpp
61
63 EBPF::CodeBuilder *builder;
64
65 public:
66 explicit PNAErrorCodesGen(EBPF::CodeBuilder *builder) : builder(builder) {}
67
68 bool preorder(const IR::Type_Error *errors) override {
69 int id = -1;
70 for (auto decl : errors->members) {
71 ++id;
72 if (decl->srcInfo.isValid()) {
73 auto sourceFile = decl->srcInfo.getSourceFile();
74 // all the error codes are located in core.p4 file, they are defined in pna.h
75 if (sourceFile.endsWith("p4include/core.p4")) continue;
76 }
77
78 builder->emitIndent();
79 builder->appendFormat("static const ParserError_t %s = %d", decl->name.name, id);
80 builder->endOfStatement(true);
81
82 // type ParserError_t is u8, which can have values from 0 to 255
83 if (id > 255) {
84 ::P4::error(ErrorType::ERR_OVERLIMIT,
85 "%1%: Reached maximum number of possible errors", decl);
86 }
87 }
88 builder->newline();
89 return false;
90 }
91};
92
93// Similar to class PSAArchTC in backends/ebpf/psa/ebpfPsaGen.h
94
96 public:
98
99 PNAArchTC(const EbpfOptions &options, std::vector<EBPF::EBPFType *> &ebpfTypes,
101 const ConvertToBackendIR *tcIR)
102 : PNAEbpfGenerator(options, ebpfTypes, pipeline, tcIR), xdp(xdp) {}
103
104 void emit(EBPF::CodeBuilder *builder) const override;
105 void emitParser(EBPF::CodeBuilder *builder) const override;
106 void emitHeader(EBPF::CodeBuilder *builder) const override;
107 void emitInstances(EBPF::CodeBuilder *builder) const override;
108};
109
111 public:
113 P4::TypeMap *typeMap)
114 : EBPF::TCIngressPipeline(name, options, refMap, typeMap) {}
115
116 void emit(EBPF::CodeBuilder *builder) override;
117 void emitLocalVariables(EBPF::CodeBuilder *builder) override;
118 void emitGlobalMetadataInitializer(EBPF::CodeBuilder *builder) override;
119 void emitTrafficManager(EBPF::CodeBuilder *builder) override;
120
122};
123
125 public:
128 : EBPF::PsaStateTranslationVisitor(refMap, typeMap, prsr) {}
129
130 bool preorder(const IR::Member *expression) override;
131
132 protected:
133 void compileExtractField(const IR::Expression *expr, const IR::StructField *field,
134 unsigned hdrOffsetBits, EBPF::EBPFType *type) override;
135 void compileLookahead(const IR::Expression *destination) override;
136};
137
139 public:
140 EBPFPnaParser(const EBPF::EBPFProgram *program, const IR::ParserBlock *block,
141 const P4::TypeMap *typeMap);
142 void emit(EBPF::CodeBuilder *builder) override;
143 void emitRejectState(EBPF::CodeBuilder *) override;
144 void emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl) override;
145
146 DECLARE_TYPEINFO(EBPFPnaParser, EBPF::EBPFPsaParser);
147};
148
150 protected:
151 EBPF::ActionTranslationVisitor *createActionTranslationVisitor(cstring valueName,
152 const EBPF::EBPFProgram *program,
153 const IR::P4Action *action,
154 bool isDefaultAction) const;
155 void validateKeys() const override;
156 void initDirectCounters();
157 void initDirectMeters();
158 const ConvertToBackendIR *tcIR;
159
160 public:
161 EBPFTablePNA(const EBPF::EBPFProgram *program, const IR::TableBlock *table,
162 EBPF::CodeGenInspector *codeGen, const ConvertToBackendIR *tcIR)
163 : EBPF::EBPFTablePSA(program, table, codeGen), tcIR(tcIR) {
164 initDirectCounters();
165 initDirectMeters();
166 }
167 void emitInitializer(EBPF::CodeBuilder *builder) override;
168 void emitDefaultActionStruct(EBPF::CodeBuilder *builder);
169 void emitKeyType(EBPF::CodeBuilder *builder) override;
170 void emitValueType(EBPF::CodeBuilder *builder) override;
171 void emitValueStructStructure(EBPF::CodeBuilder *builder) override;
172 void emitActionArguments(EBPF::CodeBuilder *builder, const IR::P4Action *action, cstring name);
173 void emitKeyPNA(EBPF::CodeBuilder *builder, cstring keyName);
174 bool isMatchTypeSupported(const IR::Declaration_ID *matchType) override {
175 if (matchType->name.name == "range" || matchType->name.name == "rangelist" ||
176 matchType->name.name == "optional")
177 return 1;
178 return EBPF::EBPFTable::isMatchTypeSupported(matchType);
179 }
180 void emitAction(EBPF::CodeBuilder *builder, cstring valueName,
181 cstring actionRunVariable) override;
182 void emitValueActionIDNames(EBPF::CodeBuilder *builder) override;
183 cstring p4ActionToActionIDName(const IR::P4Action *action) const;
184
185 DECLARE_TYPEINFO(EBPFTablePNA, EBPF::EBPFTablePSA);
186};
187
189 public:
190 IngressDeparserPNA(const EBPF::EBPFProgram *program, const IR::ControlBlock *control,
191 const IR::Parameter *parserHeaders, const IR::Parameter *istd)
192 : EBPF::EBPFDeparserPSA(program, control, parserHeaders, istd) {}
193
194 bool addExternDeclaration = false;
195 bool build() override;
196 void emit(EBPF::CodeBuilder *builder) override;
197 void emitPreDeparser(EBPF::CodeBuilder *builder) override;
198 void emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl) override;
199
200 void emitExternDefinition(EBPF::CodeBuilder *builder) {
201 if (addExternDeclaration) {
202 builder->emitIndent();
203 builder->appendLine("struct p4tc_ext_bpf_params ext_params = {};");
204 }
205 }
206 DECLARE_TYPEINFO(IngressDeparserPNA, EBPF::EBPFDeparserPSA);
207};
208
209// Similar to class ConvertToEbpfPSA in backends/ebpf/psa/ebpfPsaGen.h
210
212 const EbpfOptions &options;
213 P4::TypeMap *typemap;
214 P4::ReferenceMap *refmap;
215 const PNAEbpfGenerator *ebpf_program;
216 const ConvertToBackendIR *tcIR;
217
218 public:
219 ConvertToEbpfPNA(const EbpfOptions &options, P4::ReferenceMap *refmap, P4::TypeMap *typemap,
220 const ConvertToBackendIR *tcIR)
221 : options(options), typemap(typemap), refmap(refmap), ebpf_program(nullptr), tcIR(tcIR) {}
222
223 const PNAEbpfGenerator *build(const IR::ToplevelBlock *prog);
224 const IR::Node *preorder(IR::ToplevelBlock *p) override;
225 const PNAEbpfGenerator *getEBPFProgram() { return ebpf_program; }
226};
227
228// Similar to class ConvertToEbpfPipeline in backends/ebpf/psa/ebpfPsaGen.h
229
231 const cstring name;
232 const EBPF::pipeline_type type;
233 const EbpfOptions &options;
234 const IR::ParserBlock *parserBlock;
235 const IR::ControlBlock *controlBlock;
236 const IR::ControlBlock *deparserBlock;
237 P4::TypeMap *typemap;
238 P4::ReferenceMap *refmap;
239 EBPF::EBPFPipeline *pipeline;
240 const ConvertToBackendIR *tcIR;
241
242 public:
243 ConvertToEbpfPipelineTC(cstring name, EBPF::pipeline_type type, const EbpfOptions &options,
244 const IR::ParserBlock *parserBlock,
245 const IR::ControlBlock *controlBlock,
246 const IR::ControlBlock *deparserBlock, P4::ReferenceMap *refmap,
247 P4::TypeMap *typemap, const ConvertToBackendIR *tcIR)
248 : name(name),
249 type(type),
250 options(options),
251 parserBlock(parserBlock),
252 controlBlock(controlBlock),
253 deparserBlock(deparserBlock),
254 typemap(typemap),
255 refmap(refmap),
256 pipeline(nullptr),
257 tcIR(tcIR) {}
258
259 bool preorder(const IR::PackageBlock *block) override;
260 EBPF::EBPFPipeline *getEbpfPipeline() { return pipeline; }
261};
262
263// Similar to class ConvertToEBPFParserPSA in backends/ebpf/psa/ebpfPsaGen.h
264
266 EBPF::EBPFProgram *program;
267 P4::TypeMap *typemap;
268 TC::EBPFPnaParser *parser;
269
270 public:
272 : program(program), typemap(typemap), parser(nullptr) {}
273
274 bool preorder(const IR::ParserBlock *prsr) override;
275 bool preorder(const IR::P4ValueSet *pvs) override;
276 EBPF::EBPFParser *getEBPFParser() { return parser; }
277};
278
280 public:
281 bool addExternDeclaration = false;
282 std::map<cstring, EBPFRegisterPNA *> pna_registers;
283 std::map<cstring, EBPFHashPNA *> pna_hashes;
284
285 EBPFControlPNA(const EBPF::EBPFProgram *program, const IR::ControlBlock *control,
286 const IR::Parameter *parserHeaders)
287 : EBPF::EBPFControlPSA(program, control, parserHeaders) {}
288
289 EBPFRegisterPNA *getRegister(cstring name) const {
290 auto result = ::P4::get(pna_registers, name);
291 BUG_CHECK(result != nullptr, "No register named %1%", name);
292 return result;
293 }
294 EBPFHashPNA *getHash(cstring name) const {
295 auto result = ::P4::get(pna_hashes, name);
296 return result;
297 }
298 void emitExternDefinition(EBPF::CodeBuilder *builder) {
299 if (addExternDeclaration) {
300 builder->emitIndent();
301 builder->appendLine("struct p4tc_ext_bpf_params ext_params = {};");
302 builder->emitIndent();
303 builder->appendLine("struct p4tc_ext_bpf_val ext_val = {};");
304 builder->emitIndent();
305 builder->appendLine("struct p4tc_ext_bpf_val *ext_val_ptr;");
306 }
307 }
308 void emitTableTypes(EBPF::CodeBuilder *builder) { EBPF::EBPFControl::emitTableTypes(builder); }
309 void emit(EBPF::CodeBuilder *builder);
310};
311
312// Similar to class ConvertToEBPFControlPSA in backends/ebpf/psa/ebpfPsaGen.h
313
315 EBPF::EBPFProgram *program;
316 EBPF::pipeline_type type;
317 EBPFControlPNA *control;
318
319 const IR::Parameter *parserHeaders;
320 P4::ReferenceMap *refmap;
321
322 const ConvertToBackendIR *tcIR;
323
324 public:
325 ConvertToEBPFControlPNA(EBPF::EBPFProgram *program, const IR::Parameter *parserHeaders,
326 P4::ReferenceMap *refmap, EBPF::pipeline_type type,
327 const ConvertToBackendIR *tcIR)
328 : program(program),
329 type(type),
330 control(nullptr),
331 parserHeaders(parserHeaders),
332 refmap(refmap),
333 tcIR(tcIR) {}
334
335 bool preorder(const IR::TableBlock *) override;
336 bool preorder(const IR::ControlBlock *) override;
337 bool preorder(const IR::Declaration_Variable *) override;
338 bool preorder(const IR::Member *m) override;
339 bool preorder(const IR::IfStatement *a) override;
340 bool preorder(const IR::ExternBlock *instance) override;
341 bool checkPnaTimestampMem(const IR::Member *m);
342 EBPFControlPNA *getEBPFControl() { return control; }
343};
344
345// Similar to class ConvertToEBPFDeparserPSA in backends/ebpf/psa/ebpfPsaGen.h
346
348 EBPF::EBPFProgram *program;
349 const IR::Parameter *parserHeaders;
350 const IR::Parameter *istd;
351 const ConvertToBackendIR *tcIR;
352 TC::IngressDeparserPNA *deparser;
353
354 public:
355 ConvertToEBPFDeparserPNA(EBPF::EBPFProgram *program, const IR::Parameter *parserHeaders,
356 const IR::Parameter *istd, const ConvertToBackendIR *tcIR)
357 : program(program),
358 parserHeaders(parserHeaders),
359 istd(istd),
360 tcIR(tcIR),
361 deparser(nullptr) {}
362
363 bool preorder(const IR::ControlBlock *) override;
364 bool preorder(const IR::Declaration_Instance *) override;
365 EBPF::EBPFDeparserPSA *getEBPFDeparser() { return deparser; }
366};
367
368// Similar to class ControlBodyTranslatorPSA in backends/ebpf/psa/ebpfPsaControl.h
369
371 public:
372 const ConvertToBackendIR *tcIR;
373 const EBPF::EBPFTablePSA *table;
374 explicit ControlBodyTranslatorPNA(const EBPFControlPNA *control);
375 explicit ControlBodyTranslatorPNA(const EBPFControlPNA *control,
376 const ConvertToBackendIR *tcIR);
377 explicit ControlBodyTranslatorPNA(const EBPFControlPNA *control, const ConvertToBackendIR *tcIR,
378 const EBPF::EBPFTablePSA *table);
379 void processFunction(const P4::ExternFunction *function) override;
380 void processApply(const P4::ApplyMethod *method) override;
381 virtual cstring getParamName(const IR::PathExpression *);
382 bool preorder(const IR::AssignmentStatement *a) override;
383 void processMethod(const P4::ExternMethod *method) override;
384 bool preorder(const IR::Member *) override;
385 bool IsTableAddOnMiss(const IR::P4Table *table);
386 const IR::P4Action *GetAddOnMissHitAction(cstring actionName);
387 void ValidateAddOnMissMissAction(const IR::P4Action *act);
388};
389
390// Similar to class ActionTranslationVisitorPSA in backends/ebpf/psa/ebpfPsaControl.h
391
394 protected:
395 const EBPF::EBPFTablePSA *table;
396 bool isDefaultAction;
397
398 public:
399 const ConvertToBackendIR *tcIR;
400 ActionTranslationVisitorPNA(const EBPF::EBPFProgram *program, cstring valueName,
401 const EBPF::EBPFTablePSA *table, const ConvertToBackendIR *tcIR,
402 const IR::P4Action *act, bool isDefaultAction);
403 bool preorder(const IR::PathExpression *pe) override;
404 bool isActionParameter(const IR::Expression *expression) const;
405 void processMethod(const P4::ExternMethod *method) override;
406
407 cstring getParamInstanceName(const IR::Expression *expression) const override;
408 cstring getParamName(const IR::PathExpression *) override;
409};
410
411// Similar to class DeparserHdrEmitTranslator in backends/ebpf/ebpfDeparser.h
412
414 protected:
415 const EBPF::EBPFDeparser *deparser;
416
417 public:
418 explicit DeparserHdrEmitTranslatorPNA(const EBPF::EBPFDeparser *deparser);
419
420 void processMethod(const P4::ExternMethod *method) override;
421 void emitField(EBPF::CodeBuilder *builder, cstring field, const IR::Expression *hdrExpr,
422 unsigned alignment, EBPF::EBPFType *type, bool isMAC);
423};
424
426 public:
427 static EBPFHashAlgorithmTypeFactoryPNA *instance() {
428 static EBPFHashAlgorithmTypeFactoryPNA factory;
429 return &factory;
430 }
431
432 EBPF::EBPFHashAlgorithmPSA *create(int type, const EBPF::EBPFProgram *program, cstring name);
433};
434
435} // namespace P4::TC
436
437#endif /* BACKENDS_TC_EBPFCODEGEN_H_ */
Definition methodInstance.h:129
Definition ebpfTable.h:26
Definition ebpf/codeGen.h:33
Definition ebpf/codeGen.h:41
Definition ebpfControl.h:28
This translator emits buffer preparation (eg. which headers will be emitted)
Definition ebpfDeparser.h:38
Definition ebpfPsaControl.h:58
Definition ebpfDeparser.h:63
Definition ebpfPsaDeparser.h:39
Definition ebpfPsaHashAlgorithm.h:26
Definition ebpfPsaHashAlgorithm.h:172
Definition ebpfParser.h:79
EBPFPipeline represents a single eBPF program in the TC/XDP hook.
Definition ebpfPipeline.h:28
cstring name
A custom name of eBPF program.
Definition ebpfPipeline.h:31
Definition ebpfProgram.h:39
Definition ebpfPsaParser.h:40
Definition ebpfPsaTable.h:29
Base class for EBPF types.
Definition ebpfType.h:29
Definition ebpfPsaGen.h:31
Definition ebpfPsaParser.h:29
Definition ebpfPipeline.h:199
Definition xdpHelpProgram.h:24
Definition ebpfOptions.h:26
Definition methodInstance.h:194
Definition methodInstance.h:168
Definition node.h:95
Definition visitor.h:400
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition ebpfCodeGen.h:393
Definition ebpfCodeGen.h:370
Definition tc/backend.h:49
Definition ebpfCodeGen.h:314
Definition ebpfCodeGen.h:347
Definition ebpfCodeGen.h:265
Definition ebpfCodeGen.h:211
Definition ebpfCodeGen.h:230
Definition ebpfCodeGen.h:413
Definition ebpfCodeGen.h:279
Definition ebpfCodeGen.h:425
Definition tcExterns.h:180
Definition ebpfCodeGen.h:138
Definition tcExterns.h:53
Definition ebpfCodeGen.h:149
void validateKeys() const override
Definition ebpfCodeGen.cpp:2169
Definition ebpfCodeGen.h:188
void emitPreDeparser(EBPF::CodeBuilder *builder) override
Definition ebpfCodeGen.cpp:1190
Definition ebpfCodeGen.h:95
void emit(EBPF::CodeBuilder *builder) const override
Definition ebpfCodeGen.cpp:169
void emitParser(EBPF::CodeBuilder *builder) const override
Definition ebpfCodeGen.cpp:215
Definition ebpfCodeGen.h:35
Definition ebpfCodeGen.h:62
Definition ebpfCodeGen.h:124
Definition ebpfCodeGen.h:110
void emitLocalVariables(EBPF::CodeBuilder *builder) override
Generates a set of helper variables that are used during packet processing.
Definition ebpfCodeGen.cpp:514
void emitGlobalMetadataInitializer(EBPF::CodeBuilder *builder) override
Definition ebpfCodeGen.cpp:442
void emitTrafficManager(EBPF::CodeBuilder *builder) override
Definition ebpfCodeGen.cpp:483
Definition visitor.h:424
Definition typeMap.h:41
Definition cstring.h:85
This file defines functions for the pass to generate the introspection file.
Definition tc/backend.cpp:24
Definition cstring.h:80
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51