8#ifndef BACKENDS_EBPF_TARGET_H_
9#define BACKENDS_EBPF_TARGET_H_
11#include "frontends/p4/typeMap.h"
13#include "lib/cstring.h"
15#include "lib/exceptions.h"
16#include "lib/sourceCodeBuilder.h"
23using namespace P4::literals;
37 explicit Target(
cstring name) : name(name) {}
57 unsigned size)
const = 0;
60 unsigned size)
const {
68 "emitTableDeclSpinlock is not supported on %1% target", name);
73 TableKind innerTableKind,
cstring innerKeyType,
75 TableKind outerTableKind,
cstring outerKeyType,
76 unsigned outerSize)
const {
87 ::P4::error(ErrorType::ERR_UNSUPPORTED,
"emitMapInMapDecl is not supported on %1% target",
95 virtual cstring forwardReturnCode()
const = 0;
96 virtual cstring dropReturnCode()
const = 0;
97 virtual cstring abortReturnCode()
const = 0;
99 virtual cstring sysMapPath()
const = 0;
100 virtual cstring packetDescriptorType()
const = 0;
121class KernelSamplesTarget :
public Target {
123 mutable unsigned int innerMapIndex;
125 cstring getBPFMapType(TableKind kind)
const {
126 if (kind == TableHash) {
127 return "BPF_MAP_TYPE_HASH"_cs;
128 }
else if (kind == TableArray) {
129 return "BPF_MAP_TYPE_ARRAY"_cs;
130 }
else if (kind == TablePerCPUArray) {
131 return "BPF_MAP_TYPE_PERCPU_ARRAY"_cs;
132 }
else if (kind == TableLPMTrie) {
133 return "BPF_MAP_TYPE_LPM_TRIE"_cs;
134 }
else if (kind == TableHashLRU) {
135 return "BPF_MAP_TYPE_LRU_HASH"_cs;
136 }
else if (kind == TableProgArray) {
137 return "BPF_MAP_TYPE_PROG_ARRAY"_cs;
138 }
else if (kind == TableDevmap) {
139 return "BPF_MAP_TYPE_DEVMAP"_cs;
141 BUG(
"Unknown table kind");
145 bool emitTraceMessages;
148 explicit KernelSamplesTarget(
bool emitTrace =
false,
cstring name =
"Linux kernel"_cs)
149 : Target(name), innerMapIndex(0), emitTraceMessages(emitTrace) {}
155 cstring offsetVar)
const override;
163 cstring keyType,
cstring valueType,
unsigned size)
const override;
166 unsigned size)
const override;
168 TableKind innerTableKind,
cstring innerKeyType,
cstring innerValueType,
169 unsigned innerSize,
cstring outerName, TableKind outerTableKind,
170 cstring outerKeyType,
unsigned outerSize)
const override;
172 cstring argName)
const override;
177 return cstring(
"((void*)(long)") + base +
"->data)";
180 return cstring(
"((void*)(long)") + base +
"->data_end)";
183 cstring forwardReturnCode()
const override {
return "TC_ACT_OK"_cs; }
184 cstring dropReturnCode()
const override {
return "TC_ACT_SHOT"_cs; }
185 cstring abortReturnCode()
const override {
return "TC_ACT_SHOT"_cs; }
186 cstring sysMapPath()
const override {
return "/sys/fs/bpf/tc/globals"_cs; }
188 cstring packetDescriptorType()
const override {
return "struct __sk_buff"_cs; }
194class P4TCTarget :
public KernelSamplesTarget {
196 explicit P4TCTarget(
bool emitTrace) : KernelSamplesTarget(emitTrace,
"P4TC"_cs) {}
199 static cstring getByteOrderFromAnnotation(
const IR::IAnnotated *node) {
200 if (
const auto *anno = node->getAnnotation(
"tc_type"_cs)) {
201 cstring value = anno->needsParsing()
202 ? anno->getUnparsed().at(0)->text
203 : anno->getExpr().at(0)->checkedTo<IR::StringLiteral>()->value;
204 if (value ==
"macaddr" || value ==
"ipv4" || value ==
"ipv6" || value ==
"be16" ||
205 value ==
"be32" || value ==
"be64") {
213 const IR::Expression *exp)
const {
214 if (
auto mem = exp->to<IR::Member>()) {
215 auto type = typeMap->getType(mem->expr,
true);
216 if (type->is<IR::Type_StructLike>()) {
217 auto field = type->to<IR::Type_StructLike>()->getField(mem->member);
218 return getByteOrderFromAnnotation(field);
221 auto paramList = action->getParameters();
222 if (paramList !=
nullptr && !paramList->empty()) {
223 for (
auto param : paramList->parameters) {
224 if (param->name.originalName == exp->toString()) {
225 return getByteOrderFromAnnotation(param);
233 bool isPrimitiveByteAligned(
int width)
const {
234 return (width <= 8 || width <= 16 || (width > 24 && width <= 32) ||
235 (width > 56 && width <= 64));
240class XdpTarget :
public KernelSamplesTarget {
242 explicit XdpTarget(
bool emitTrace) : KernelSamplesTarget(emitTrace,
"XDP"_cs) {}
244 cstring forwardReturnCode()
const override {
return "XDP_PASS"_cs; }
245 cstring dropReturnCode()
const override {
return "XDP_DROP"_cs; }
246 cstring abortReturnCode()
const override {
return "XDP_ABORTED"_cs; }
247 cstring redirectReturnCode()
const {
return "XDP_REDIRECT"_cs; }
248 cstring sysMapPath()
const override {
return "/sys/fs/bpf/xdp/globals"_cs; }
249 cstring packetDescriptorType()
const override {
return "struct xdp_md"_cs; }
252 return cstring(
"(") + base +
"->data_end - " + base +
"->data)";
255 cstring offsetVar)
const override;
257 cstring argName)
const override {
258 builder->appendFormat(
"int %v(%v *%v)", functionName, packetDescriptorType(), argName);
263class BccTarget :
public Target {
265 BccTarget() : Target(
"BCC"_cs) {}
277 cstring keyType,
cstring valueType,
unsigned size)
const override;
279 cstring argName)
const override;
282 return cstring(
"(") + base +
" + " + base +
"->len)";
285 cstring forwardReturnCode()
const override {
return "0"_cs; }
286 cstring dropReturnCode()
const override {
return "1"_cs; }
287 cstring abortReturnCode()
const override {
return "1"_cs; }
288 cstring sysMapPath()
const override {
return "/sys/fs/bpf"_cs; }
289 cstring packetDescriptorType()
const override {
return "struct __sk_buff"_cs; }
296 TestTarget() : KernelSamplesTarget(
false,
"Userspace Test"_cs) {}
301 cstring keyType,
cstring valueType,
unsigned size)
const override;
303 return cstring(
"((void*)(long)") + base +
"->data)";
306 return cstring(
"((void*)(long)(") + base +
"->data + " + base +
"->len))";
308 cstring forwardReturnCode()
const override {
return "true"_cs; }
309 cstring dropReturnCode()
const override {
return "false"_cs; }
310 cstring abortReturnCode()
const override {
return "false"_cs; }
311 cstring sysMapPath()
const override {
return "/sys/fs/bpf"_cs; }
312 cstring packetDescriptorType()
const override {
return "struct __sk_buff"_cs; }
Definition ebpf/target.h:121
void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc=0,...) const override
Definition ebpf/target.cpp:168
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:103
virtual void emitTraceMessage(Util::SourceCodeBuilder *builder, const char *format, int argc,...) const
Definition ebpf/target.cpp:14
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:72
Definition sourceCodeBuilder.h:20
Definition codeGen.cpp:14
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:49