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 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 ::error(ErrorType::ERR_OVERLIMIT, "%1%: Reached maximum number of possible errors",
84 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 const ConvertToBackendIR *tcIR;
155
156 public:
157 EBPFTablePNA(const EBPF::EBPFProgram *program, const IR::TableBlock *table,
158 EBPF::CodeGenInspector *codeGen, const ConvertToBackendIR *tcIR)
159 : EBPF::EBPFTablePSA(program, table, codeGen), tcIR(tcIR) {
160 initDirectCounters();
161 }
162 void emitInitializer(EBPF::CodeBuilder *builder) override;
163 void emitDefaultActionStruct(EBPF::CodeBuilder *builder);
164 void emitKeyType(EBPF::CodeBuilder *builder) override;
165 void emitValueType(EBPF::CodeBuilder *builder) override;
166 void emitValueStructStructure(EBPF::CodeBuilder *builder) override;
167 void emitActionArguments(EBPF::CodeBuilder *builder, const IR::P4Action *action, cstring name);
168 void emitKeyPNA(EBPF::CodeBuilder *builder, cstring keyName);
169 bool isMatchTypeSupported(const IR::Declaration_ID *matchType) override {
170 if (matchType->name.name == "range" || matchType->name.name == "rangelist" ||
171 matchType->name.name == "optional")
172 return 1;
173 return EBPF::EBPFTable::isMatchTypeSupported(matchType);
174 }
175 void emitAction(EBPF::CodeBuilder *builder, cstring valueName,
176 cstring actionRunVariable) override;
177 void emitValueActionIDNames(EBPF::CodeBuilder *builder) override;
178 cstring p4ActionToActionIDName(const IR::P4Action *action) const;
179
180 DECLARE_TYPEINFO(EBPFTablePNA, EBPF::EBPFTablePSA);
181};
182
184 public:
185 IngressDeparserPNA(const EBPF::EBPFProgram *program, const IR::ControlBlock *control,
186 const IR::Parameter *parserHeaders, const IR::Parameter *istd)
187 : EBPF::EBPFDeparserPSA(program, control, parserHeaders, istd) {}
188
189 bool build() override;
190 void emit(EBPF::CodeBuilder *builder) override;
191 void emitPreDeparser(EBPF::CodeBuilder *builder) override;
192 void emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl) override;
193
194 DECLARE_TYPEINFO(IngressDeparserPNA, EBPF::EBPFDeparserPSA);
195};
196
197// Similar to class ConvertToEbpfPSA in backends/ebpf/psa/ebpfPsaGen.h
198
200 const EbpfOptions &options;
201 P4::TypeMap *typemap;
202 P4::ReferenceMap *refmap;
203 const PNAEbpfGenerator *ebpf_program;
204 const ConvertToBackendIR *tcIR;
205
206 public:
207 ConvertToEbpfPNA(const EbpfOptions &options, P4::ReferenceMap *refmap, P4::TypeMap *typemap,
208 const ConvertToBackendIR *tcIR)
209 : options(options), typemap(typemap), refmap(refmap), ebpf_program(nullptr), tcIR(tcIR) {}
210
211 const PNAEbpfGenerator *build(const IR::ToplevelBlock *prog);
212 const IR::Node *preorder(IR::ToplevelBlock *p) override;
213 const PNAEbpfGenerator *getEBPFProgram() { return ebpf_program; }
214};
215
216// Similar to class ConvertToEbpfPipeline in backends/ebpf/psa/ebpfPsaGen.h
217
219 const cstring name;
220 const EBPF::pipeline_type type;
221 const EbpfOptions &options;
222 const IR::ParserBlock *parserBlock;
223 const IR::ControlBlock *controlBlock;
224 const IR::ControlBlock *deparserBlock;
225 P4::TypeMap *typemap;
226 P4::ReferenceMap *refmap;
227 EBPF::EBPFPipeline *pipeline;
228 const ConvertToBackendIR *tcIR;
229
230 public:
231 ConvertToEbpfPipelineTC(cstring name, EBPF::pipeline_type type, const EbpfOptions &options,
232 const IR::ParserBlock *parserBlock,
233 const IR::ControlBlock *controlBlock,
234 const IR::ControlBlock *deparserBlock, P4::ReferenceMap *refmap,
235 P4::TypeMap *typemap, const ConvertToBackendIR *tcIR)
236 : name(name),
237 type(type),
238 options(options),
239 parserBlock(parserBlock),
240 controlBlock(controlBlock),
241 deparserBlock(deparserBlock),
242 typemap(typemap),
243 refmap(refmap),
244 pipeline(nullptr),
245 tcIR(tcIR) {}
246
247 bool preorder(const IR::PackageBlock *block) override;
248 EBPF::EBPFPipeline *getEbpfPipeline() { return pipeline; }
249};
250
251// Similar to class ConvertToEBPFParserPSA in backends/ebpf/psa/ebpfPsaGen.h
252
254 EBPF::EBPFProgram *program;
255 P4::TypeMap *typemap;
256 TC::EBPFPnaParser *parser;
257
258 public:
260 : program(program), typemap(typemap), parser(nullptr) {}
261
262 bool preorder(const IR::ParserBlock *prsr) override;
263 bool preorder(const IR::P4ValueSet *pvs) override;
264 EBPF::EBPFParser *getEBPFParser() { return parser; }
265};
266
268 public:
269 bool addExternDeclaration = false;
270 std::map<cstring, EBPFRegisterPNA *> pna_registers;
271
272 EBPFControlPNA(const EBPF::EBPFProgram *program, const IR::ControlBlock *control,
273 const IR::Parameter *parserHeaders)
274 : EBPF::EBPFControlPSA(program, control, parserHeaders) {}
275
276 EBPFRegisterPNA *getRegister(cstring name) const {
277 auto result = ::get(pna_registers, name);
278 BUG_CHECK(result != nullptr, "No register named %1%", name);
279 return result;
280 }
281 void emitExternDefinition(EBPF::CodeBuilder *builder) {
282 if (addExternDeclaration) {
283 builder->emitIndent();
284 builder->appendLine("struct p4tc_ext_bpf_params ext_params = {};");
285 builder->emitIndent();
286 builder->appendLine("struct p4tc_ext_bpf_val ext_val = {};");
287 builder->emitIndent();
288 builder->appendLine("struct p4tc_ext_bpf_val *ext_val_ptr;");
289 }
290 }
291};
292
293// Similar to class ConvertToEBPFControlPSA in backends/ebpf/psa/ebpfPsaGen.h
294
296 EBPF::EBPFProgram *program;
297 EBPF::pipeline_type type;
298 EBPFControlPNA *control;
299
300 const IR::Parameter *parserHeaders;
301 P4::ReferenceMap *refmap;
302
303 const ConvertToBackendIR *tcIR;
304
305 public:
306 ConvertToEBPFControlPNA(EBPF::EBPFProgram *program, const IR::Parameter *parserHeaders,
307 P4::ReferenceMap *refmap, EBPF::pipeline_type type,
308 const ConvertToBackendIR *tcIR)
309 : program(program),
310 type(type),
311 control(nullptr),
312 parserHeaders(parserHeaders),
313 refmap(refmap),
314 tcIR(tcIR) {}
315
316 bool preorder(const IR::TableBlock *) override;
317 bool preorder(const IR::ControlBlock *) override;
318 bool preorder(const IR::Declaration_Variable *) override;
319 bool preorder(const IR::Member *m) override;
320 bool preorder(const IR::IfStatement *a) override;
321 bool preorder(const IR::ExternBlock *instance) override;
322 bool checkPnaTimestampMem(const IR::Member *m);
323 EBPFControlPNA *getEBPFControl() { return control; }
324};
325
326// Similar to class ConvertToEBPFDeparserPSA in backends/ebpf/psa/ebpfPsaGen.h
327
329 EBPF::EBPFProgram *program;
330 const IR::Parameter *parserHeaders;
331 const IR::Parameter *istd;
332 TC::IngressDeparserPNA *deparser;
333
334 public:
335 ConvertToEBPFDeparserPNA(EBPF::EBPFProgram *program, const IR::Parameter *parserHeaders,
336 const IR::Parameter *istd)
337 : program(program), parserHeaders(parserHeaders), istd(istd), deparser(nullptr) {}
338
339 bool preorder(const IR::ControlBlock *) override;
340 bool preorder(const IR::Declaration_Instance *) override;
341 EBPF::EBPFDeparserPSA *getEBPFDeparser() { return deparser; }
342};
343
344// Similar to class ControlBodyTranslatorPSA in backends/ebpf/psa/ebpfPsaControl.h
345
347 public:
348 const ConvertToBackendIR *tcIR;
349 const EBPF::EBPFTablePSA *table;
350 explicit ControlBodyTranslatorPNA(const EBPFControlPNA *control);
351 explicit ControlBodyTranslatorPNA(const EBPFControlPNA *control,
352 const ConvertToBackendIR *tcIR);
353 explicit ControlBodyTranslatorPNA(const EBPFControlPNA *control, const ConvertToBackendIR *tcIR,
354 const EBPF::EBPFTablePSA *table);
355 void processFunction(const P4::ExternFunction *function) override;
356 void processApply(const P4::ApplyMethod *method) override;
357 bool checkPnaPortMem(const IR::Member *m);
358 virtual cstring getParamName(const IR::PathExpression *);
359 bool preorder(const IR::AssignmentStatement *a) override;
360 void processMethod(const P4::ExternMethod *method) override;
361 bool preorder(const IR::Member *) override;
362 bool IsTableAddOnMiss(const IR::P4Table *table);
363 const IR::P4Action *GetAddOnMissHitAction(cstring actionName);
364 void ValidateAddOnMissMissAction(const IR::P4Action *act);
365};
366
367// Similar to class ActionTranslationVisitorPSA in backends/ebpf/psa/ebpfPsaControl.h
368
371 protected:
372 const EBPF::EBPFTablePSA *table;
373 bool isDefaultAction;
374
375 public:
376 const ConvertToBackendIR *tcIR;
377 ActionTranslationVisitorPNA(const EBPF::EBPFProgram *program, cstring valueName,
378 const EBPF::EBPFTablePSA *table, const ConvertToBackendIR *tcIR,
379 const IR::P4Action *act, bool isDefaultAction);
380 bool preorder(const IR::PathExpression *pe) override;
381 bool isActionParameter(const IR::Expression *expression) const;
382 void processMethod(const P4::ExternMethod *method) override;
383
384 cstring getParamInstanceName(const IR::Expression *expression) const override;
385 cstring getParamName(const IR::PathExpression *) override;
386};
387
388// Similar to class DeparserHdrEmitTranslator in backends/ebpf/ebpfDeparser.h
389
391 protected:
392 const EBPF::EBPFDeparser *deparser;
393
394 public:
395 explicit DeparserHdrEmitTranslatorPNA(const EBPF::EBPFDeparser *deparser);
396
397 void processMethod(const P4::ExternMethod *method) override;
398 void emitField(EBPF::CodeBuilder *builder, cstring field, const IR::Expression *hdrExpr,
399 unsigned alignment, EBPF::EBPFType *type, bool isMAC);
400};
401
403 public:
404 CRCChecksumAlgorithmPNA(const EBPF::EBPFProgram *program, cstring name, int width)
405 : EBPF::CRCChecksumAlgorithm(program, name, width) {}
406
407 static void emitUpdateMethod(EBPF::CodeBuilder *builder, int crcWidth);
408};
409
411 public:
413 : CRCChecksumAlgorithmPNA(program, name, 16) {
414 initialValue = "0"_cs;
415 // We use a 0x8005 polynomial.
416 // 0xA001 comes from 0x8005 value bits reflection.
417 polynomial = "0xA001"_cs;
418 updateMethod = "crc16_update"_cs;
419 finalizeMethod = "crc16_finalize"_cs;
420 }
421
422 static void emitGlobals(EBPF::CodeBuilder *builder);
423};
424
426 public:
428 : CRCChecksumAlgorithmPNA(program, name, 32) {
429 initialValue = "0xffffffff"_cs;
430 // We use a 0x04C11DB7 polynomial.
431 // 0xEDB88320 comes from 0x04C11DB7 value bits reflection.
432 polynomial = "0xEDB88320"_cs;
433 updateMethod = "crc32_update"_cs;
434 finalizeMethod = "crc32_finalize"_cs;
435 }
436
437 static void emitGlobals(EBPF::CodeBuilder *builder);
438};
439
441 public:
442 static EBPFHashAlgorithmTypeFactoryPNA *instance() {
443 static EBPFHashAlgorithmTypeFactoryPNA factory;
444 return &factory;
445 }
446
447 void emitGlobals(EBPF::CodeBuilder *builder) {
448 CRC16ChecksumAlgorithmPNA::emitGlobals(builder);
449 CRC32ChecksumAlgorithmPNA::emitGlobals(builder);
450 }
451
452 EBPF::EBPFHashAlgorithmPSA *create(int type, const EBPF::EBPFProgram *program, cstring name);
453};
454
455} // namespace TC
456
457#endif /* BACKENDS_TC_EBPFCODEGEN_H_ */
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:24
Definition node.h:93
Definition visitor.h:396
Definition methodInstance.h:129
Definition methodInstance.h:181
Definition methodInstance.h:149
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition typeMap.h:41
Definition ebpfCodeGen.h:370
Definition ebpfCodeGen.h:410
Definition ebpfCodeGen.h:425
Definition ebpfCodeGen.h:402
Definition ebpfCodeGen.h:346
Definition tc/backend.h:49
Definition ebpfCodeGen.h:295
Definition ebpfCodeGen.h:328
Definition ebpfCodeGen.h:253
Definition ebpfCodeGen.h:199
Definition ebpfCodeGen.h:218
Definition ebpfCodeGen.h:390
Definition ebpfCodeGen.h:267
Definition ebpfCodeGen.h:440
Definition ebpfCodeGen.h:135
Definition tcExterns.h:53
Definition ebpfCodeGen.h:146
void validateKeys() const override
Definition ebpfCodeGen.cpp:2093
Definition ebpfCodeGen.h:183
void emitPreDeparser(EBPF::CodeBuilder *builder) override
Definition ebpfCodeGen.cpp:1174
Definition ebpfCodeGen.h:94
void emitParser(EBPF::CodeBuilder *builder) const override
Definition ebpfCodeGen.cpp:216
void emit(EBPF::CodeBuilder *builder) const override
Definition ebpfCodeGen.cpp:170
Definition ebpfCodeGen.h:34
Definition ebpfCodeGen.h:61
Definition ebpfCodeGen.h:123
Definition ebpfCodeGen.h:109
void emitTrafficManager(EBPF::CodeBuilder *builder) override
Definition ebpfCodeGen.cpp:485
void emitGlobalMetadataInitializer(EBPF::CodeBuilder *builder) override
Definition ebpfCodeGen.cpp:444
void emitLocalVariables(EBPF::CodeBuilder *builder) override
Generates a set of helper variables that are used during packet processing.
Definition ebpfCodeGen.cpp:516
Definition visitor.h:420
Definition cstring.h:80
Definition cstring.h:76
This file defines functions for the pass to generate the introspection file.
Definition tc/backend.cpp:24