P4C
The P4 Compiler
 
Loading...
Searching...
No Matches
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 "lib/cstring.h"
21#include "lib/error.h"
22#include "lib/exceptions.h"
23#include "lib/sourceCodeBuilder.h"
24
25// We are prepared to support code generation using multiple styles
26// (e.g., using BCC or using CLANG).
27
28namespace EBPF {
29
30enum TableKind {
31 TableHash,
32 TableArray,
33 TablePerCPUArray,
34 TableProgArray,
35 TableLPMTrie, // longest prefix match trie
36 TableHashLRU,
37 TableDevmap
38};
39
40class Target {
41 protected:
42 explicit Target(cstring name) : name(name) {}
43 Target() = delete;
44 virtual ~Target() {}
45
46 public:
47 const cstring name;
48
49 virtual void emitLicense(Util::SourceCodeBuilder *builder, cstring license) const = 0;
50 virtual void emitCodeSection(Util::SourceCodeBuilder *builder, cstring sectionName) const = 0;
51 virtual void emitIncludes(Util::SourceCodeBuilder *builder) const = 0;
52 virtual void emitResizeBuffer(Util::SourceCodeBuilder *builder, cstring buffer,
53 cstring offsetVar) const = 0;
54 virtual void emitTableLookup(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
55 cstring value) const = 0;
56 virtual void emitTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
57 cstring value) const = 0;
58 virtual void emitUserTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
59 cstring value) const = 0;
60 virtual void emitTableDecl(Util::SourceCodeBuilder *builder, cstring tblName,
61 TableKind tableKind, cstring keyType, cstring valueType,
62 unsigned size) const = 0;
63 virtual void emitTableDeclSpinlock(Util::SourceCodeBuilder *builder, cstring tblName,
64 TableKind tableKind, cstring keyType, cstring valueType,
65 unsigned size) const {
66 (void)builder;
67 (void)tblName;
68 (void)tableKind;
69 (void)keyType;
70 (void)valueType;
71 (void)size;
72 ::error(ErrorType::ERR_UNSUPPORTED, "emitTableDeclSpinlock is not supported on %1% target",
73 name);
74 }
75 // map-in-map requires declaration of both inner and outer map,
76 // thus we define them together in a single method.
77 virtual void emitMapInMapDecl(Util::SourceCodeBuilder *builder, cstring innerName,
78 TableKind innerTableKind, cstring innerKeyType,
79 cstring innerValueType, unsigned innerSize, cstring outerName,
80 TableKind outerTableKind, cstring outerKeyType,
81 unsigned outerSize) const {
82 (void)builder;
83 (void)innerName;
84 (void)innerTableKind;
85 (void)innerKeyType;
86 (void)innerValueType;
87 (void)innerSize;
88 (void)outerName;
89 (void)outerTableKind;
90 (void)outerKeyType;
91 (void)outerSize;
92 ::error(ErrorType::ERR_UNSUPPORTED, "emitMapInMapDecl is not supported on %1% target",
93 name);
94 }
95 virtual void emitMain(Util::SourceCodeBuilder *builder, cstring functionName,
96 cstring argName) const = 0;
97 virtual cstring dataOffset(cstring base) const = 0;
98 virtual cstring dataEnd(cstring base) const = 0;
99 virtual cstring dataLength(cstring base) const = 0;
100 virtual cstring forwardReturnCode() const = 0;
101 virtual cstring dropReturnCode() const = 0;
102 virtual cstring abortReturnCode() const = 0;
103 // Path on /sys filesystem where maps are stored
104 virtual cstring sysMapPath() const = 0;
105 virtual cstring packetDescriptorType() const = 0;
106
107 virtual void emitPreamble(Util::SourceCodeBuilder *builder) const;
119 virtual void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc,
120 ...) const;
121 virtual void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format) const;
122};
123
124// Represents a target that is compiled within the kernel
125// source tree samples folder and which attaches to a socket
127 private:
128 mutable unsigned int innerMapIndex;
129
130 cstring getBPFMapType(TableKind kind) const {
131 if (kind == TableHash) {
132 return "BPF_MAP_TYPE_HASH";
133 } else if (kind == TableArray) {
134 return "BPF_MAP_TYPE_ARRAY";
135 } else if (kind == TablePerCPUArray) {
136 return "BPF_MAP_TYPE_PERCPU_ARRAY";
137 } else if (kind == TableLPMTrie) {
138 return "BPF_MAP_TYPE_LPM_TRIE";
139 } else if (kind == TableHashLRU) {
140 return "BPF_MAP_TYPE_LRU_HASH";
141 } else if (kind == TableProgArray) {
142 return "BPF_MAP_TYPE_PROG_ARRAY";
143 } else if (kind == TableDevmap) {
144 return "BPF_MAP_TYPE_DEVMAP";
145 }
146 BUG("Unknown table kind");
147 }
148
149 protected:
150 bool emitTraceMessages;
151
152 public:
153 explicit KernelSamplesTarget(bool emitTrace = false, cstring name = "Linux kernel")
154 : Target(name), innerMapIndex(0), emitTraceMessages(emitTrace) {}
155
156 void emitLicense(Util::SourceCodeBuilder *builder, cstring license) const override;
157 void emitCodeSection(Util::SourceCodeBuilder *builder, cstring sectionName) const override;
158 void emitIncludes(Util::SourceCodeBuilder *builder) const override;
159 void emitResizeBuffer(Util::SourceCodeBuilder *builder, cstring buffer,
160 cstring offsetVar) const override;
161 void emitTableLookup(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
162 cstring value) const override;
163 void emitTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
164 cstring value) const override;
165 void emitUserTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
166 cstring value) const override;
167 void emitTableDecl(Util::SourceCodeBuilder *builder, cstring tblName, TableKind tableKind,
168 cstring keyType, cstring valueType, unsigned size) const override;
169 void emitTableDeclSpinlock(Util::SourceCodeBuilder *builder, cstring tblName,
170 TableKind tableKind, cstring keyType, cstring valueType,
171 unsigned size) const override;
172 void emitMapInMapDecl(Util::SourceCodeBuilder *builder, cstring innerName,
173 TableKind innerTableKind, cstring innerKeyType, cstring innerValueType,
174 unsigned innerSize, cstring outerName, TableKind outerTableKind,
175 cstring outerKeyType, unsigned outerSize) const override;
176 void emitMain(Util::SourceCodeBuilder *builder, cstring functionName,
177 cstring argName) const override;
178 void emitPreamble(Util::SourceCodeBuilder *builder) const override;
179 void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc = 0,
180 ...) const override;
181 cstring dataOffset(cstring base) const override {
182 return cstring("((void*)(long)") + base + "->data)";
183 }
184 cstring dataEnd(cstring base) const override {
185 return cstring("((void*)(long)") + base + "->data_end)";
186 }
187 cstring dataLength(cstring base) const override { return cstring(base) + "->len"; }
188 cstring forwardReturnCode() const override { return "TC_ACT_OK"; }
189 cstring dropReturnCode() const override { return "TC_ACT_SHOT"; }
190 cstring abortReturnCode() const override { return "TC_ACT_SHOT"; }
191 cstring sysMapPath() const override { return "/sys/fs/bpf/tc/globals"; }
192
193 cstring packetDescriptorType() const override { return "struct __sk_buff"; }
194
195 void annotateTableWithBTF(Util::SourceCodeBuilder *builder, cstring name, cstring keyType,
196 cstring valueType) const;
197};
198
199// Target XDP
201 public:
202 explicit XdpTarget(bool emitTrace) : KernelSamplesTarget(emitTrace, "XDP") {}
203
204 cstring forwardReturnCode() const override { return "XDP_PASS"; }
205 cstring dropReturnCode() const override { return "XDP_DROP"; }
206 cstring abortReturnCode() const override { return "XDP_ABORTED"; }
207 cstring redirectReturnCode() const { return "XDP_REDIRECT"; }
208 cstring sysMapPath() const override { return "/sys/fs/bpf/xdp/globals"; }
209 cstring packetDescriptorType() const override { return "struct xdp_md"; }
210
211 cstring dataLength(cstring base) const override {
212 return cstring("(") + base + "->data_end - " + base + "->data)";
213 }
214 void emitResizeBuffer(Util::SourceCodeBuilder *builder, cstring buffer,
215 cstring offsetVar) const override;
216 void emitMain(Util::SourceCodeBuilder *builder, cstring functionName,
217 cstring argName) const override {
218 builder->appendFormat("int %s(%s *%s)", functionName.c_str(), packetDescriptorType(),
219 argName.c_str());
220 }
221};
222
223// Represents a target compiled by bcc that uses the TC
224class BccTarget : public Target {
225 public:
226 BccTarget() : Target("BCC") {}
227 void emitLicense(Util::SourceCodeBuilder *, cstring) const override {};
228 void emitCodeSection(Util::SourceCodeBuilder *, cstring) const override {}
229 void emitIncludes(Util::SourceCodeBuilder *builder) const override;
230 void emitResizeBuffer(Util::SourceCodeBuilder *, cstring, cstring) const override {};
231 void emitTableLookup(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
232 cstring value) const override;
233 void emitTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
234 cstring value) const override;
235 void emitUserTableUpdate(Util::SourceCodeBuilder *builder, cstring tblName, cstring key,
236 cstring value) const override;
237 void emitTableDecl(Util::SourceCodeBuilder *builder, cstring tblName, TableKind tableKind,
238 cstring keyType, cstring valueType, unsigned size) const override;
239 void emitMain(Util::SourceCodeBuilder *builder, cstring functionName,
240 cstring argName) const override;
241 cstring dataOffset(cstring base) const override { return base; }
242 cstring dataEnd(cstring base) const override {
243 return cstring("(") + base + " + " + base + "->len)";
244 }
245 cstring dataLength(cstring base) const override { return cstring(base) + "->len"; }
246 cstring forwardReturnCode() const override { return "0"; }
247 cstring dropReturnCode() const override { return "1"; }
248 cstring abortReturnCode() const override { return "1"; }
249 cstring sysMapPath() const override { return "/sys/fs/bpf"; }
250 cstring packetDescriptorType() const override { return "struct __sk_buff"; }
251};
252
253// A userspace test version with functionality equivalent to the kernel
254// Compiles with gcc
256 public:
257 TestTarget() : KernelSamplesTarget(false, "Userspace Test") {}
258
259 void emitResizeBuffer(Util::SourceCodeBuilder *, cstring, cstring) const override {};
260 void emitIncludes(Util::SourceCodeBuilder *builder) const override;
261 void emitTableDecl(Util::SourceCodeBuilder *builder, cstring tblName, TableKind tableKind,
262 cstring keyType, cstring valueType, unsigned size) const override;
263 cstring dataOffset(cstring base) const override {
264 return cstring("((void*)(long)") + base + "->data)";
265 }
266 cstring dataEnd(cstring base) const override {
267 return cstring("((void*)(long)(") + base + "->data + " + base + "->len))";
268 }
269 cstring forwardReturnCode() const override { return "true"; }
270 cstring dropReturnCode() const override { return "false"; }
271 cstring abortReturnCode() const override { return "false"; }
272 cstring sysMapPath() const override { return "/sys/fs/bpf"; }
273 cstring packetDescriptorType() const override { return "struct __sk_buff"; }
274};
275
276} // namespace EBPF
277
278#endif /* BACKENDS_EBPF_TARGET_H_ */
Definition target.h:224
Definition target.h:126
void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc=0,...) const override
Definition target.cpp:177
Definition target.h:40
virtual void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc,...) const
Definition target.cpp:25
Definition target.h:255
Definition target.h:200
Definition sourceCodeBuilder.h:29
Definition cstring.h:72