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;
31
32// Similar to class PSAEbpfGenerator in backends/ebpf/psa/ebpfPsaGen.h
33
35 public:
36 EBPF::EBPFPipeline *pipeline;
37 const ConvertToBackendIR *tcIR;
38
39 PNAEbpfGenerator(const EbpfOptions &options, std::vector<EBPF::EBPFType *> &ebpfTypes,
40 EBPF::EBPFPipeline *pipeline, const ConvertToBackendIR *tcIR)
41 : EBPF::EbpfCodeGenerator(options, ebpfTypes), pipeline(pipeline), tcIR(tcIR) {}
42
43 virtual void emit(EBPF::CodeBuilder *builder) const = 0;
44 virtual void emitInstances(EBPF::CodeBuilder *builder) const = 0;
45 virtual void emitParser(EBPF::CodeBuilder *builder) const = 0;
46 virtual void emitHeader(EBPF::CodeBuilder *builder) const = 0;
47 void emitPNAIncludes(EBPF::CodeBuilder *builder) const;
48 void emitPreamble(EBPF::CodeBuilder *builder) const override;
49 void emitCommonPreamble(EBPF::CodeBuilder *builder) const override;
50 void emitInternalStructures(EBPF::CodeBuilder *pBuilder) const override;
51 void emitTypes(EBPF::CodeBuilder *builder) const override;
52 void emitGlobalHeadersMetadata(EBPF::CodeBuilder *builder) const override;
53 void emitPipelineInstances(EBPF::CodeBuilder *builder) const override;
54 void emitP4TCFilterFields(EBPF::CodeBuilder *builder) const;
55 void emitP4TCActionParam(EBPF::CodeBuilder *builder) const;
56 cstring getProgramName() const;
57};
58
59// Similar to class PSAErrorCodesGen in backends/ebpf/psa/ebpfPsaGen.cpp
60
62 EBPF::CodeBuilder *builder;
63
64 public:
65 explicit PNAErrorCodesGen(EBPF::CodeBuilder *builder) : builder(builder) {}
66
67 bool preorder(const IR::Type_Error *errors) override {
68 int id = -1;
69 for (auto decl : errors->members) {
70 ++id;
71 if (decl->srcInfo.isValid()) {
72 auto sourceFile = decl->srcInfo.getSourceFile();
73 // all the error codes are located in core.p4 file, they are defined in pna.h
74 if (sourceFile.endsWith("p4include/core.p4")) continue;
75 }
76
77 builder->emitIndent();
78 builder->appendFormat("static const ParserError_t %s = %d", decl->name.name, id);
79 builder->endOfStatement(true);
80
81 // type ParserError_t is u8, which can have values from 0 to 255
82 if (id > 255) {
83 ::P4::error(ErrorType::ERR_OVERLIMIT,
84 "%1%: Reached maximum number of possible errors", decl);
85 }
86 }
87 builder->newline();
88 return false;
89 }
90};
91
92// Similar to class PSAArchTC in backends/ebpf/psa/ebpfPsaGen.h
93
95 public:
97
98 PNAArchTC(const EbpfOptions &options, std::vector<EBPF::EBPFType *> &ebpfTypes,
100 const ConvertToBackendIR *tcIR)
101 : PNAEbpfGenerator(options, ebpfTypes, pipeline, tcIR), xdp(xdp) {}
102
103 void emit(EBPF::CodeBuilder *builder) const override;
104 void emitParser(EBPF::CodeBuilder *builder) const override;
105 void emitHeader(EBPF::CodeBuilder *builder) const override;
106 void emitInstances(EBPF::CodeBuilder *builder) const override;
107};
108
110 public:
112 P4::TypeMap *typeMap)
113 : EBPF::TCIngressPipeline(name, options, refMap, typeMap) {}
114
115 void emit(EBPF::CodeBuilder *builder) override;
116 void emitLocalVariables(EBPF::CodeBuilder *builder) override;
117 void emitGlobalMetadataInitializer(EBPF::CodeBuilder *builder) override;
118 void emitTrafficManager(EBPF::CodeBuilder *builder) override;
119
121};
122
124 public:
127 : EBPF::PsaStateTranslationVisitor(refMap, typeMap, prsr) {}
128
129 protected:
130 void compileExtractField(const IR::Expression *expr, const IR::StructField *field,
131 unsigned hdrOffsetBits, EBPF::EBPFType *type) override;
132 void compileLookahead(const IR::Expression *destination) override;
133};
134
136 public:
137 EBPFPnaParser(const EBPF::EBPFProgram *program, const IR::ParserBlock *block,
138 const P4::TypeMap *typeMap);
139 void emit(EBPF::CodeBuilder *builder) override;
140 void emitRejectState(EBPF::CodeBuilder *) override;
141 void emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl) override;
142
143 DECLARE_TYPEINFO(EBPFPnaParser, EBPF::EBPFPsaParser);
144};
145
147 protected:
148 EBPF::ActionTranslationVisitor *createActionTranslationVisitor(cstring valueName,
149 const EBPF::EBPFProgram *program,
150 const IR::P4Action *action,
151 bool isDefaultAction) const;
152 void validateKeys() const override;
153 void initDirectCounters();
154 void initDirectMeters();
155 const ConvertToBackendIR *tcIR;
156
157 public:
158 EBPFTablePNA(const EBPF::EBPFProgram *program, const IR::TableBlock *table,
159 EBPF::CodeGenInspector *codeGen, const ConvertToBackendIR *tcIR)
160 : EBPF::EBPFTablePSA(program, table, codeGen), tcIR(tcIR) {
161 initDirectCounters();
162 initDirectMeters();
163 }
164 void emitInitializer(EBPF::CodeBuilder *builder) override;
165 void emitDefaultActionStruct(EBPF::CodeBuilder *builder);
166 void emitKeyType(EBPF::CodeBuilder *builder) override;
167 void emitValueType(EBPF::CodeBuilder *builder) override;
168 void emitValueStructStructure(EBPF::CodeBuilder *builder) override;
169 void emitActionArguments(EBPF::CodeBuilder *builder, const IR::P4Action *action, cstring name);
170 void emitKeyPNA(EBPF::CodeBuilder *builder, cstring keyName);
171 bool isMatchTypeSupported(const IR::Declaration_ID *matchType) override {
172 if (matchType->name.name == "range" || matchType->name.name == "rangelist" ||
173 matchType->name.name == "optional")
174 return 1;
175 return EBPF::EBPFTable::isMatchTypeSupported(matchType);
176 }
177 void emitAction(EBPF::CodeBuilder *builder, cstring valueName,
178 cstring actionRunVariable) override;
179 void emitValueActionIDNames(EBPF::CodeBuilder *builder) override;
180 cstring p4ActionToActionIDName(const IR::P4Action *action) const;
181
182 DECLARE_TYPEINFO(EBPFTablePNA, EBPF::EBPFTablePSA);
183};
184
186 public:
187 IngressDeparserPNA(const EBPF::EBPFProgram *program, const IR::ControlBlock *control,
188 const IR::Parameter *parserHeaders, const IR::Parameter *istd)
189 : EBPF::EBPFDeparserPSA(program, control, parserHeaders, istd) {}
190
191 bool addExternDeclaration = false;
192 bool build() override;
193 void emit(EBPF::CodeBuilder *builder) override;
194 void emitPreDeparser(EBPF::CodeBuilder *builder) override;
195 void emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl) override;
196
197 void emitExternDefinition(EBPF::CodeBuilder *builder) {
198 if (addExternDeclaration) {
199 builder->emitIndent();
200 builder->appendLine("struct p4tc_ext_bpf_params ext_params = {};");
201 }
202 }
203 DECLARE_TYPEINFO(IngressDeparserPNA, EBPF::EBPFDeparserPSA);
204};
205
206// Similar to class ConvertToEbpfPSA in backends/ebpf/psa/ebpfPsaGen.h
207
209 const EbpfOptions &options;
210 P4::TypeMap *typemap;
211 P4::ReferenceMap *refmap;
212 const PNAEbpfGenerator *ebpf_program;
213 const ConvertToBackendIR *tcIR;
214
215 public:
216 ConvertToEbpfPNA(const EbpfOptions &options, P4::ReferenceMap *refmap, P4::TypeMap *typemap,
217 const ConvertToBackendIR *tcIR)
218 : options(options), typemap(typemap), refmap(refmap), ebpf_program(nullptr), tcIR(tcIR) {}
219
220 const PNAEbpfGenerator *build(const IR::ToplevelBlock *prog);
221 const IR::Node *preorder(IR::ToplevelBlock *p) override;
222 const PNAEbpfGenerator *getEBPFProgram() { return ebpf_program; }
223};
224
225// Similar to class ConvertToEbpfPipeline in backends/ebpf/psa/ebpfPsaGen.h
226
228 const cstring name;
229 const EBPF::pipeline_type type;
230 const EbpfOptions &options;
231 const IR::ParserBlock *parserBlock;
232 const IR::ControlBlock *controlBlock;
233 const IR::ControlBlock *deparserBlock;
234 P4::TypeMap *typemap;
235 P4::ReferenceMap *refmap;
236 EBPF::EBPFPipeline *pipeline;
237 const ConvertToBackendIR *tcIR;
238
239 public:
240 ConvertToEbpfPipelineTC(cstring name, EBPF::pipeline_type type, const EbpfOptions &options,
241 const IR::ParserBlock *parserBlock,
242 const IR::ControlBlock *controlBlock,
243 const IR::ControlBlock *deparserBlock, P4::ReferenceMap *refmap,
244 P4::TypeMap *typemap, const ConvertToBackendIR *tcIR)
245 : name(name),
246 type(type),
247 options(options),
248 parserBlock(parserBlock),
249 controlBlock(controlBlock),
250 deparserBlock(deparserBlock),
251 typemap(typemap),
252 refmap(refmap),
253 pipeline(nullptr),
254 tcIR(tcIR) {}
255
256 bool preorder(const IR::PackageBlock *block) override;
257 EBPF::EBPFPipeline *getEbpfPipeline() { return pipeline; }
258};
259
260// Similar to class ConvertToEBPFParserPSA in backends/ebpf/psa/ebpfPsaGen.h
261
263 EBPF::EBPFProgram *program;
264 P4::TypeMap *typemap;
265 TC::EBPFPnaParser *parser;
266
267 public:
269 : program(program), typemap(typemap), parser(nullptr) {}
270
271 bool preorder(const IR::ParserBlock *prsr) override;
272 bool preorder(const IR::P4ValueSet *pvs) override;
273 EBPF::EBPFParser *getEBPFParser() { return parser; }
274};
275
277 public:
278 bool addExternDeclaration = false;
279 std::map<cstring, EBPFRegisterPNA *> pna_registers;
280
281 EBPFControlPNA(const EBPF::EBPFProgram *program, const IR::ControlBlock *control,
282 const IR::Parameter *parserHeaders)
283 : EBPF::EBPFControlPSA(program, control, parserHeaders) {}
284
285 EBPFRegisterPNA *getRegister(cstring name) const {
286 auto result = ::P4::get(pna_registers, name);
287 BUG_CHECK(result != nullptr, "No register named %1%", name);
288 return result;
289 }
290 void emitExternDefinition(EBPF::CodeBuilder *builder) {
291 if (addExternDeclaration) {
292 builder->emitIndent();
293 builder->appendLine("struct p4tc_ext_bpf_params ext_params = {};");
294 builder->emitIndent();
295 builder->appendLine("struct p4tc_ext_bpf_val ext_val = {};");
296 builder->emitIndent();
297 builder->appendLine("struct p4tc_ext_bpf_val *ext_val_ptr;");
298 }
299 }
300 void emitTableTypes(EBPF::CodeBuilder *builder) { EBPF::EBPFControl::emitTableTypes(builder); }
301};
302
303// Similar to class ConvertToEBPFControlPSA in backends/ebpf/psa/ebpfPsaGen.h
304
306 EBPF::EBPFProgram *program;
307 EBPF::pipeline_type type;
308 EBPFControlPNA *control;
309
310 const IR::Parameter *parserHeaders;
311 P4::ReferenceMap *refmap;
312
313 const ConvertToBackendIR *tcIR;
314
315 public:
316 ConvertToEBPFControlPNA(EBPF::EBPFProgram *program, const IR::Parameter *parserHeaders,
317 P4::ReferenceMap *refmap, EBPF::pipeline_type type,
318 const ConvertToBackendIR *tcIR)
319 : program(program),
320 type(type),
321 control(nullptr),
322 parserHeaders(parserHeaders),
323 refmap(refmap),
324 tcIR(tcIR) {}
325
326 bool preorder(const IR::TableBlock *) override;
327 bool preorder(const IR::ControlBlock *) override;
328 bool preorder(const IR::Declaration_Variable *) override;
329 bool preorder(const IR::Member *m) override;
330 bool preorder(const IR::IfStatement *a) override;
331 bool preorder(const IR::ExternBlock *instance) override;
332 bool checkPnaTimestampMem(const IR::Member *m);
333 EBPFControlPNA *getEBPFControl() { return control; }
334};
335
336// Similar to class ConvertToEBPFDeparserPSA in backends/ebpf/psa/ebpfPsaGen.h
337
339 EBPF::EBPFProgram *program;
340 const IR::Parameter *parserHeaders;
341 const IR::Parameter *istd;
342 const ConvertToBackendIR *tcIR;
343 TC::IngressDeparserPNA *deparser;
344
345 public:
346 ConvertToEBPFDeparserPNA(EBPF::EBPFProgram *program, const IR::Parameter *parserHeaders,
347 const IR::Parameter *istd, const ConvertToBackendIR *tcIR)
348 : program(program),
349 parserHeaders(parserHeaders),
350 istd(istd),
351 tcIR(tcIR),
352 deparser(nullptr) {}
353
354 bool preorder(const IR::ControlBlock *) override;
355 bool preorder(const IR::Declaration_Instance *) override;
356 EBPF::EBPFDeparserPSA *getEBPFDeparser() { return deparser; }
357};
358
359// Similar to class ControlBodyTranslatorPSA in backends/ebpf/psa/ebpfPsaControl.h
360
362 public:
363 const ConvertToBackendIR *tcIR;
364 const EBPF::EBPFTablePSA *table;
365 explicit ControlBodyTranslatorPNA(const EBPFControlPNA *control);
366 explicit ControlBodyTranslatorPNA(const EBPFControlPNA *control,
367 const ConvertToBackendIR *tcIR);
368 explicit ControlBodyTranslatorPNA(const EBPFControlPNA *control, const ConvertToBackendIR *tcIR,
369 const EBPF::EBPFTablePSA *table);
370 void processFunction(const P4::ExternFunction *function) override;
371 void processApply(const P4::ApplyMethod *method) override;
372 virtual cstring getParamName(const IR::PathExpression *);
373 bool preorder(const IR::AssignmentStatement *a) override;
374 void processMethod(const P4::ExternMethod *method) override;
375 bool preorder(const IR::Member *) override;
376 bool IsTableAddOnMiss(const IR::P4Table *table);
377 const IR::P4Action *GetAddOnMissHitAction(cstring actionName);
378 void ValidateAddOnMissMissAction(const IR::P4Action *act);
379};
380
381// Similar to class ActionTranslationVisitorPSA in backends/ebpf/psa/ebpfPsaControl.h
382
385 protected:
386 const EBPF::EBPFTablePSA *table;
387 bool isDefaultAction;
388
389 public:
390 const ConvertToBackendIR *tcIR;
391 ActionTranslationVisitorPNA(const EBPF::EBPFProgram *program, cstring valueName,
392 const EBPF::EBPFTablePSA *table, const ConvertToBackendIR *tcIR,
393 const IR::P4Action *act, bool isDefaultAction);
394 bool preorder(const IR::PathExpression *pe) override;
395 bool isActionParameter(const IR::Expression *expression) const;
396 void processMethod(const P4::ExternMethod *method) override;
397
398 cstring getParamInstanceName(const IR::Expression *expression) const override;
399 cstring getParamName(const IR::PathExpression *) override;
400};
401
402// Similar to class DeparserHdrEmitTranslator in backends/ebpf/ebpfDeparser.h
403
405 protected:
406 const EBPF::EBPFDeparser *deparser;
407
408 public:
409 explicit DeparserHdrEmitTranslatorPNA(const EBPF::EBPFDeparser *deparser);
410
411 void processMethod(const P4::ExternMethod *method) override;
412 void emitField(EBPF::CodeBuilder *builder, cstring field, const IR::Expression *hdrExpr,
413 unsigned alignment, EBPF::EBPFType *type, bool isMAC);
414};
415
417 public:
418 CRCChecksumAlgorithmPNA(const EBPF::EBPFProgram *program, cstring name, int width)
419 : EBPF::CRCChecksumAlgorithm(program, name, width) {}
420
421 static void emitUpdateMethod(EBPF::CodeBuilder *builder, int crcWidth);
422};
423
425 public:
427 : CRCChecksumAlgorithmPNA(program, name, 16) {
428 initialValue = "0"_cs;
429 // We use a 0x8005 polynomial.
430 // 0xA001 comes from 0x8005 value bits reflection.
431 polynomial = "0xA001"_cs;
432 updateMethod = "crc16_update"_cs;
433 finalizeMethod = "crc16_finalize"_cs;
434 }
435
436 static void emitGlobals(EBPF::CodeBuilder *builder);
437};
438
440 public:
442 : CRCChecksumAlgorithmPNA(program, name, 32) {
443 initialValue = "0xffffffff"_cs;
444 // We use a 0x04C11DB7 polynomial.
445 // 0xEDB88320 comes from 0x04C11DB7 value bits reflection.
446 polynomial = "0xEDB88320"_cs;
447 updateMethod = "crc32_update"_cs;
448 finalizeMethod = "crc32_finalize"_cs;
449 }
450
451 static void emitGlobals(EBPF::CodeBuilder *builder);
452};
453
455 public:
456 static EBPFHashAlgorithmTypeFactoryPNA *instance() {
457 static EBPFHashAlgorithmTypeFactoryPNA factory;
458 return &factory;
459 }
460
461 void emitGlobals(EBPF::CodeBuilder *builder) {
462 CRC16ChecksumAlgorithmPNA::emitGlobals(builder);
463 CRC32ChecksumAlgorithmPNA::emitGlobals(builder);
464 }
465
466 EBPF::EBPFHashAlgorithmPSA *create(int type, const EBPF::EBPFProgram *program, cstring name);
467};
468
469} // namespace P4::TC
470
471#endif /* BACKENDS_TC_EBPFCODEGEN_H_ */
Definition methodInstance.h:129
Definition ebpfTable.h:26
Definition ebpfPsaHashAlgorithm.h:74
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:384
Definition ebpfCodeGen.h:424
Definition ebpfCodeGen.h:439
Definition ebpfCodeGen.h:416
Definition ebpfCodeGen.h:361
Definition tc/backend.h:49
Definition ebpfCodeGen.h:305
Definition ebpfCodeGen.h:338
Definition ebpfCodeGen.h:262
Definition ebpfCodeGen.h:208
Definition ebpfCodeGen.h:227
Definition ebpfCodeGen.h:404
Definition ebpfCodeGen.h:276
Definition ebpfCodeGen.h:454
Definition ebpfCodeGen.h:135
Definition tcExterns.h:53
Definition ebpfCodeGen.h:146
void validateKeys() const override
Definition ebpfCodeGen.cpp:2147
Definition ebpfCodeGen.h:185
void emitPreDeparser(EBPF::CodeBuilder *builder) override
Definition ebpfCodeGen.cpp:1173
Definition ebpfCodeGen.h:94
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:34
Definition ebpfCodeGen.h:61
Definition ebpfCodeGen.h:123
Definition ebpfCodeGen.h:109
void emitLocalVariables(EBPF::CodeBuilder *builder) override
Generates a set of helper variables that are used during packet processing.
Definition ebpfCodeGen.cpp:515
void emitGlobalMetadataInitializer(EBPF::CodeBuilder *builder) override
Definition ebpfCodeGen.cpp:443
void emitTrafficManager(EBPF::CodeBuilder *builder) override
Definition ebpfCodeGen.cpp:484
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 error.h:51