P4C
The P4 Compiler
Loading...
Searching...
No Matches
ebpf/target.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
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
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed 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 and
14limitations under the License.
15*/
16
17#ifndef BACKENDS_EBPF_TARGET_H_
18#define BACKENDS_EBPF_TARGET_H_
19
20#include "frontends/p4/typeMap.h"
21#include "ir/ir.h"
22#include "lib/cstring.h"
23#include "lib/error.h"
24#include "lib/exceptions.h"
25#include "lib/sourceCodeBuilder.h"
26
29
30namespace P4::EBPF {
31
32using namespace P4::literals;
33
34enum TableKind {
35 TableHash,
36 TableArray,
37 TablePerCPUArray,
38 TableProgArray,
39 TableLPMTrie, // Longest prefix match trie.
40 TableHashLRU,
41 TableDevmap
42};
43
44class Target {
45 protected:
46 explicit Target(cstring name) : name(name) {}
47 Target() = delete;
48 virtual ~Target() {}
49
50 public:
51 const cstring name;
52
53 virtual void emitLicense(Util::SourceCodeBuilder *builder, cstring license) const = 0;
54 virtual void emitCodeSection(Util::SourceCodeBuilder *builder, cstring sectionName) const = 0;
55 virtual void emitIncludes(Util::SourceCodeBuilder *builder) const = 0;
56 virtual void emitResizeBuffer(Util::SourceCodeBuilder *builder, cstring buffer,
57 cstring offsetVar) const = 0;
58 virtual void emitTableLookup(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
59 cstring value) const = 0;
60 virtual void emitTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
61 cstring value) const = 0;
62 virtual void emitUserTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
63 cstring value) const = 0;
64 virtual void emitTableDecl(Util::SourceCodeBuilder *builder, cstring tblName,
65 TableKind tableKind, cstring keyType, cstring valueType,
66 unsigned size) const = 0;
67 virtual void emitTableDeclSpinlock(Util::SourceCodeBuilder *builder, cstring tblName,
68 TableKind tableKind, cstring keyType, cstring valueType,
69 unsigned size) const {
70 (void)builder;
71 (void)tblName;
72 (void)tableKind;
73 (void)keyType;
74 (void)valueType;
75 (void)size;
76 ::P4::error(ErrorType::ERR_UNSUPPORTED,
77 "emitTableDeclSpinlock is not supported on %1% target", name);
78 }
81 virtual void emitMapInMapDecl(Util::SourceCodeBuilder *builder, cstring innerName,
82 TableKind innerTableKind, cstring innerKeyType,
83 cstring innerValueType, unsigned innerSize, cstring outerName,
84 TableKind outerTableKind, cstring outerKeyType,
85 unsigned outerSize) const {
86 (void)builder;
87 (void)innerName;
88 (void)innerTableKind;
89 (void)innerKeyType;
90 (void)innerValueType;
91 (void)innerSize;
92 (void)outerName;
93 (void)outerTableKind;
94 (void)outerKeyType;
95 (void)outerSize;
96 ::P4::error(ErrorType::ERR_UNSUPPORTED, "emitMapInMapDecl is not supported on %1% target",
97 name);
98 }
99 virtual void emitMain(Util::SourceCodeBuilder *builder, cstring functionName,
100 cstring argName) const = 0;
101 virtual cstring dataOffset(cstring base) const = 0;
102 virtual cstring dataEnd(cstring base) const = 0;
103 virtual cstring dataLength(cstring base) const = 0;
104 virtual cstring forwardReturnCode() const = 0;
105 virtual cstring dropReturnCode() const = 0;
106 virtual cstring abortReturnCode() const = 0;
107 // Path on /sys filesystem where maps are stored
108 virtual cstring sysMapPath() const = 0;
109 virtual cstring packetDescriptorType() const = 0;
110
111 virtual void emitPreamble(Util::SourceCodeBuilder *builder) const;
123 virtual void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc,
124 ...) const;
125 virtual void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format) const;
126};
127
131 private:
132 mutable unsigned int innerMapIndex;
133
134 cstring getBPFMapType(TableKind kind) const {
135 if (kind == TableHash) {
136 return "BPF_MAP_TYPE_HASH"_cs;
137 } else if (kind == TableArray) {
138 return "BPF_MAP_TYPE_ARRAY"_cs;
139 } else if (kind == TablePerCPUArray) {
140 return "BPF_MAP_TYPE_PERCPU_ARRAY"_cs;
141 } else if (kind == TableLPMTrie) {
142 return "BPF_MAP_TYPE_LPM_TRIE"_cs;
143 } else if (kind == TableHashLRU) {
144 return "BPF_MAP_TYPE_LRU_HASH"_cs;
145 } else if (kind == TableProgArray) {
146 return "BPF_MAP_TYPE_PROG_ARRAY"_cs;
147 } else if (kind == TableDevmap) {
148 return "BPF_MAP_TYPE_DEVMAP"_cs;
149 }
150 BUG("Unknown table kind");
151 }
152
153 protected:
154 bool emitTraceMessages;
155
156 public:
157 explicit KernelSamplesTarget(bool emitTrace = false, cstring name = "Linux kernel"_cs)
158 : Target(name), innerMapIndex(0), emitTraceMessages(emitTrace) {}
159
160 void emitLicense(Util::SourceCodeBuilder *builder, cstring license) const override;
161 void emitCodeSection(Util::SourceCodeBuilder *builder, cstring sectionName) const override;
162 void emitIncludes(Util::SourceCodeBuilder *builder) const override;
163 void emitResizeBuffer(Util::SourceCodeBuilder *builder, cstring buffer,
164 cstring offsetVar) const override;
165 void emitTableLookup(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
166 cstring value) const override;
167 void emitTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
168 cstring value) const override;
169 void emitUserTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
170 cstring value) const override;
171 void emitTableDecl(Util::SourceCodeBuilder *builder, cstring tblName, TableKind tableKind,
172 cstring keyType, cstring valueType, unsigned size) const override;
173 void emitTableDeclSpinlock(Util::SourceCodeBuilder *builder, cstring tblName,
174 TableKind tableKind, cstring keyType, cstring valueType,
175 unsigned size) const override;
176 void emitMapInMapDecl(Util::SourceCodeBuilder *builder, cstring innerName,
177 TableKind innerTableKind, cstring innerKeyType, cstring innerValueType,
178 unsigned innerSize, cstring outerName, TableKind outerTableKind,
179 cstring outerKeyType, unsigned outerSize) const override;
180 void emitMain(Util::SourceCodeBuilder *builder, cstring functionName,
181 cstring argName) const override;
182 void emitPreamble(Util::SourceCodeBuilder *builder) const override;
183 void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc = 0,
184 ...) const override;
185 cstring dataOffset(cstring base) const override {
186 return cstring("((void*)(long)") + base + "->data)";
187 }
188 cstring dataEnd(cstring base) const override {
189 return cstring("((void*)(long)") + base + "->data_end)";
190 }
191 cstring dataLength(cstring base) const override { return cstring(base) + "->len"; }
192 cstring forwardReturnCode() const override { return "TC_ACT_OK"_cs; }
193 cstring dropReturnCode() const override { return "TC_ACT_SHOT"_cs; }
194 cstring abortReturnCode() const override { return "TC_ACT_SHOT"_cs; }
195 cstring sysMapPath() const override { return "/sys/fs/bpf/tc/globals"_cs; }
196
197 cstring packetDescriptorType() const override { return "struct __sk_buff"_cs; }
198
199 void annotateTableWithBTF(Util::SourceCodeBuilder *builder, cstring name, cstring keyType,
200 cstring valueType) const;
201};
202
204 public:
205 explicit P4TCTarget(bool emitTrace) : KernelSamplesTarget(emitTrace, "P4TC"_cs) {}
206 cstring getByteOrderFromAnnotation(const IR::Vector<IR::Annotation> &annotations) const {
207 for (const auto *anno : annotations) {
208 if (anno->name != "tc_type") continue;
209 for (const auto *annoVal : anno->body) {
210 if (annoVal->text == "macaddr" || annoVal->text == "ipv4" ||
211 annoVal->text == "ipv6" || annoVal->text == "be16" || annoVal->text == "be32" ||
212 annoVal->text == "be64") {
213 return "NETWORK"_cs;
214 }
215 }
216 }
217 return "HOST"_cs;
218 }
219
220 cstring getByteOrder(P4::TypeMap *typeMap, const IR::P4Action *action,
221 const IR::Expression *exp) const {
222 if (auto mem = exp->to<IR::Member>()) {
223 auto type = typeMap->getType(mem->expr, true);
224 if (type->is<IR::Type_StructLike>()) {
225 auto field = type->to<IR::Type_StructLike>()->getField(mem->member);
226 return getByteOrderFromAnnotation(field->getAnnotations());
227 }
228 } else if (action) {
229 auto paramList = action->getParameters();
230 if (paramList != nullptr && !paramList->empty()) {
231 for (auto param : paramList->parameters) {
232 if (param->name.originalName == exp->toString()) {
233 return getByteOrderFromAnnotation(param->getAnnotations());
234 }
235 }
236 }
237 }
238 return "HOST"_cs;
239 }
240};
241
244 public:
245 explicit XdpTarget(bool emitTrace) : KernelSamplesTarget(emitTrace, "XDP"_cs) {}
246
247 cstring forwardReturnCode() const override { return "XDP_PASS"_cs; }
248 cstring dropReturnCode() const override { return "XDP_DROP"_cs; }
249 cstring abortReturnCode() const override { return "XDP_ABORTED"_cs; }
250 cstring redirectReturnCode() const { return "XDP_REDIRECT"_cs; }
251 cstring sysMapPath() const override { return "/sys/fs/bpf/xdp/globals"_cs; }
252 cstring packetDescriptorType() const override { return "struct xdp_md"_cs; }
253
254 cstring dataLength(cstring base) const override {
255 return cstring("(") + base + "->data_end - " + base + "->data)";
256 }
257 void emitResizeBuffer(Util::SourceCodeBuilder *builder, cstring buffer,
258 cstring offsetVar) const override;
259 void emitMain(Util::SourceCodeBuilder *builder, cstring functionName,
260 cstring argName) const override {
261 builder->appendFormat("int %v(%v *%v)", functionName, packetDescriptorType(), argName);
262 }
263};
264
266class BccTarget : public Target {
267 public:
268 BccTarget() : Target("BCC"_cs) {}
269 void emitLicense(Util::SourceCodeBuilder *, cstring) const override {}
270 void emitCodeSection(Util::SourceCodeBuilder *, cstring) const override {}
271 void emitIncludes(Util::SourceCodeBuilder *builder) const override;
272 void emitResizeBuffer(Util::SourceCodeBuilder *, cstring, cstring) const override {}
273 void emitTableLookup(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
274 cstring value) const override;
275 void emitTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
276 cstring value) const override;
277 void emitUserTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
278 cstring value) const override;
279 void emitTableDecl(Util::SourceCodeBuilder *builder, cstring tblName, TableKind tableKind,
280 cstring keyType, cstring valueType, unsigned size) const override;
281 void emitMain(Util::SourceCodeBuilder *builder, cstring functionName,
282 cstring argName) const override;
283 cstring dataOffset(cstring base) const override { return base; }
284 cstring dataEnd(cstring base) const override {
285 return cstring("(") + base + " + " + base + "->len)";
286 }
287 cstring dataLength(cstring base) const override { return cstring(base) + "->len"; }
288 cstring forwardReturnCode() const override { return "0"_cs; }
289 cstring dropReturnCode() const override { return "1"_cs; }
290 cstring abortReturnCode() const override { return "1"_cs; }
291 cstring sysMapPath() const override { return "/sys/fs/bpf"_cs; }
292 cstring packetDescriptorType() const override { return "struct __sk_buff"_cs; }
293};
294
298 public:
299 TestTarget() : KernelSamplesTarget(false, "Userspace Test"_cs) {}
300
301 void emitResizeBuffer(Util::SourceCodeBuilder *, cstring, cstring) const override {}
302 void emitIncludes(Util::SourceCodeBuilder *builder) const override;
303 void emitTableDecl(Util::SourceCodeBuilder *builder, cstring tblName, TableKind tableKind,
304 cstring keyType, cstring valueType, unsigned size) const override;
305 cstring dataOffset(cstring base) const override {
306 return cstring("((void*)(long)") + base + "->data)";
307 }
308 cstring dataEnd(cstring base) const override {
309 return cstring("((void*)(long)(") + base + "->data + " + base + "->len))";
310 }
311 cstring forwardReturnCode() const override { return "true"_cs; }
312 cstring dropReturnCode() const override { return "false"_cs; }
313 cstring abortReturnCode() const override { return "false"_cs; }
314 cstring sysMapPath() const override { return "/sys/fs/bpf"_cs; }
315 cstring packetDescriptorType() const override { return "struct __sk_buff"_cs; }
316};
317
318} // namespace P4::EBPF
319
320#endif /* BACKENDS_EBPF_TARGET_H_ */
Represents a target compiled by bcc that uses the TC.
Definition ebpf/target.h:266
Definition ebpf/target.h:130
void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc=0,...) const override
Definition ebpf/target.cpp:179
void emitMapInMapDecl(Util::SourceCodeBuilder *builder, cstring innerName, TableKind innerTableKind, cstring innerKeyType, cstring innerValueType, unsigned innerSize, cstring outerName, TableKind outerTableKind, cstring outerKeyType, unsigned outerSize) const override
Definition ebpf/target.cpp:114
Definition ebpf/target.h:203
Definition ebpf/target.h:44
virtual void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc,...) const
Definition ebpf/target.cpp:25
virtual void emitMapInMapDecl(Util::SourceCodeBuilder *builder, cstring innerName, TableKind innerTableKind, cstring innerKeyType, cstring innerValueType, unsigned innerSize, cstring outerName, TableKind outerTableKind, cstring outerKeyType, unsigned outerSize) const
Definition ebpf/target.h:81
Definition ebpf/target.h:297
Target XDP.
Definition ebpf/target.h:243
Definition vector.h:59
Definition typeMap.h:41
Definition sourceCodeBuilder.h:29
Definition cstring.h:85
Definition codeGen.cpp:25
Definition cstring.h:80
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51