Skip to content

Commit

Permalink
P4TC - Support for DirectCounter extern (#4711)
Browse files Browse the repository at this point in the history
* Merge Support of Register Extern

* Support Direct Counter

* Fix cpplint issue

* Change 'type' to 'ptype' in template file.

* Fix for annotation extern reflecting in declaration type

* Change table permissions

* Convert char* into cstring

* Fix sanitizer issue

* Added error test scenario
  • Loading branch information
komaljai authored Jun 11, 2024
1 parent 7124b4e commit 69e4ac6
Show file tree
Hide file tree
Showing 90 changed files with 1,614 additions and 252 deletions.
23 changes: 0 additions & 23 deletions backends/ebpf/psa/ebpfPsaTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,6 @@ limitations under the License.

namespace EBPF {

class EBPFTablePsaPropertyVisitor : public Inspector {
protected:
EBPFTablePSA *table;

public:
explicit EBPFTablePsaPropertyVisitor(EBPFTablePSA *table) : table(table) {}

/// Use these two preorders to print error when property contains something other than name of
/// extern instance. ListExpression is required because without it Expression will take
/// precedence over it and throw error for whole list.
bool preorder(const IR::ListExpression *) override { return true; }
bool preorder(const IR::Expression *expr) override {
::error(ErrorType::ERR_UNSUPPORTED,
"%1%: unsupported expression, expected a named instance", expr);
return false;
}

void visitTableProperty(cstring propertyName) {
auto property = table->table->container->properties->getProperty(propertyName);
if (property != nullptr) property->apply(*this);
}
};

class EBPFTablePSADirectCounterPropertyVisitor : public EBPFTablePsaPropertyVisitor {
public:
explicit EBPFTablePSADirectCounterPropertyVisitor(EBPFTablePSA *table)
Expand Down
23 changes: 23 additions & 0 deletions backends/ebpf/psa/ebpfPsaTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,29 @@ class EBPFTablePSA : public EBPFTable {
DECLARE_TYPEINFO(EBPFTablePSA, EBPFTable);
};

class EBPFTablePsaPropertyVisitor : public Inspector {
protected:
EBPFTablePSA *table;

public:
explicit EBPFTablePsaPropertyVisitor(EBPFTablePSA *table) : table(table) {}

/// Use these two preorders to print error when property contains something other than name of
/// extern instance. ListExpression is required because without it Expression will take
/// precedence over it and throw error for whole list.
bool preorder(const IR::ListExpression *) override { return true; }
bool preorder(const IR::Expression *expr) override {
::error(ErrorType::ERR_UNSUPPORTED,
"%1%: unsupported expression, expected a named instance", expr);
return false;
}

void visitTableProperty(cstring propertyName) {
auto property = table->table->container->properties->getProperty(propertyName);
if (property != nullptr) property->apply(*this);
}
};

} // namespace EBPF

#endif /* BACKENDS_EBPF_PSA_EBPFPSATABLE_H_ */
255 changes: 203 additions & 52 deletions backends/tc/backend.cpp

Large diffs are not rendered by default.

23 changes: 18 additions & 5 deletions backends/tc/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and limitations under the License.
#include <deque>

#include "backends/ebpf/psa/ebpfPsaGen.h"
#include "control-plane/p4RuntimeArchHandler.h"
#include "ebpfCodeGen.h"
#include "frontends/p4/evaluator/evaluator.h"
#include "frontends/p4/parseAnnotations.h"
Expand Down Expand Up @@ -60,6 +61,7 @@ class ConvertToBackendIR : public Inspector {
cstring permissions;
safe_vector<struct ExternInstance *> eInstance;
};
enum CounterType { PACKETS, BYTES, PACKETS_AND_BYTES };
const IR::ToplevelBlock *tlb;
IR::TCPipeline *tcPipeline;
P4::ReferenceMap *refMap;
Expand Down Expand Up @@ -93,12 +95,13 @@ class ConvertToBackendIR : public Inspector {
void postorder(const IR::P4Program *p) override;
void postorder(const IR::Declaration_Instance *d) override;
void postorder(const IR::Type_Struct *ts) override;
void processExternConstructorAnnotations(const IR::Type_Extern *extn,
const IR::Declaration_Instance *decl,
struct ExternInstance *instance);
safe_vector<const IR::TCKey *> processExternControlPath(const IR::Type_SpecializedCanonical *ts,
const IR::Type_Extern *extn,
safe_vector<const IR::TCKey *> processExternConstructor(const IR::Type_Extern *extn,
const IR::Declaration_Instance *decl,
struct ExternInstance *instance);
safe_vector<const IR::TCKey *> processExternControlPath(const IR::Type_Extern *extn,
const IR::Declaration_Instance *decl,
cstring eName);
cstring getControlPathKeyAnnotation(const IR::StructField *field);
unsigned GetAccessNumericValue(std::string_view access);
bool isDuplicateAction(const IR::P4Action *action);
bool isDuplicateOrNoAction(const IR::P4Action *action);
Expand All @@ -107,6 +110,7 @@ class ConvertToBackendIR : public Inspector {
void updateConstEntries(const IR::P4Table *t, IR::TCTable *tdef);
void updateMatchType(const IR::P4Table *t, IR::TCTable *tabledef);
void updateTimerProfiles(IR::TCTable *tabledef);
void updatePnaDirectCounter(const IR::P4Table *t, IR::TCTable *tabledef, unsigned tentries);
bool isPnaParserMeta(const IR::Member *mem);
bool isPnaMainInputMeta(const IR::Member *mem);
bool isPnaMainOutputMeta(const IR::Member *mem);
Expand All @@ -124,6 +128,15 @@ class ConvertToBackendIR : public Inspector {
std::pair<cstring, cstring> *GetAnnotatedAccessPath(const IR::Annotation *anno);
void updateAddOnMissTable(const IR::P4Table *t);
bool checkParameterDirection(const IR::TCAction *tcAction);
bool hasExecuteMethod(const IR::Type_Extern *extn);
safe_vector<const IR::TCKey *> HandleTypeNameStructField(const IR::StructField *field,
const IR::Type_Extern *extn,
const IR::Declaration_Instance *decl,
int &kId, cstring annoName);
safe_vector<const IR::TCKey *> processCounterControlPathKeys(
const IR::Type_Struct *extern_control_path, const IR::Type_Extern *extn,
const IR::Declaration_Instance *decl);
CounterType toCounterType(const int type);
};

class Extern {
Expand Down
31 changes: 30 additions & 1 deletion backends/tc/ebpfCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,11 @@ void EBPFTablePNA::emitValueActionIDNames(EBPF::CodeBuilder *builder) {
builder->emitIndent();
}

void EBPFTablePNA::initDirectCounters() {
EBPFTablePNADirectCounterPropertyVisitor visitor(this);
visitor.visitTableProperty();
}

// =====================IngressDeparserPNA=============================
bool IngressDeparserPNA::build() {
auto pl = controlBlock->container->type->applyParams;
Expand Down Expand Up @@ -1447,7 +1452,10 @@ bool ConvertToEBPFControlPNA::preorder(const IR::ExternBlock *instance) {
} else if (typeName == "Register") {
auto reg = new EBPFRegisterPNA(program, name, di, control->codeGen);
control->pna_registers.emplace(name, reg);
control->defineExtern = true;
control->addExternDeclaration = true;
} else if (typeName == "DirectCounter") {
control->addExternDeclaration = true;
return false;
} else {
::error(ErrorType::ERR_UNEXPECTED, "Unexpected block %s nested within control", instance);
}
Expand Down Expand Up @@ -1978,6 +1986,7 @@ ActionTranslationVisitorPNA::ActionTranslationVisitorPNA(
tcIR, table),
table(table),
isDefaultAction(isDefaultAction) {
this->tcIR = tcIR;
action = act;
}

Expand Down Expand Up @@ -2018,6 +2027,26 @@ cstring ActionTranslationVisitorPNA::getParamName(const IR::PathExpression *expr
return ControlBodyTranslatorPNA::getParamName(expr);
}

void ActionTranslationVisitorPNA::processMethod(const P4::ExternMethod *method) {
auto declType = method->originalExternType;
auto decl = method->object;
BUG_CHECK(decl->is<IR::Declaration_Instance>(), "Extern has not been declared: %1%", decl);
auto di = decl->to<IR::Declaration_Instance>();
auto instanceName = EBPF::EBPFObject::externalName(di);

if (declType->name.name == "DirectCounter") {
auto ctr = table->getDirectCounter(instanceName);
auto pna_ctr = dynamic_cast<EBPFCounterPNA *>(ctr);
if (pna_ctr != nullptr)
pna_ctr->emitDirectMethodInvocation(builder, method, this->tcIR);
else
::error(ErrorType::ERR_NOT_FOUND, "%1%: Table %2% does not own DirectCounter named %3%",
method->expr, table->table->container, instanceName);
} else {
ControlBodyTranslatorPNA::processMethod(method);
}
}

EBPF::ActionTranslationVisitor *EBPFTablePNA::createActionTranslationVisitor(
cstring valueName, const EBPF::EBPFProgram *program, const IR::P4Action *action,
bool isDefault) const {
Expand Down
10 changes: 7 additions & 3 deletions backends/tc/ebpfCodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,15 @@ class EBPFTablePNA : public EBPF::EBPFTablePSA {
const IR::P4Action *action,
bool isDefaultAction) const;
void validateKeys() const override;
void initDirectCounters();
const ConvertToBackendIR *tcIR;

public:
EBPFTablePNA(const EBPF::EBPFProgram *program, const IR::TableBlock *table,
EBPF::CodeGenInspector *codeGen, const ConvertToBackendIR *tcIR)
: EBPF::EBPFTablePSA(program, table, codeGen), tcIR(tcIR) {}
: EBPF::EBPFTablePSA(program, table, codeGen), tcIR(tcIR) {
initDirectCounters();
}
void emitInitializer(EBPF::CodeBuilder *builder) override;
void emitDefaultActionStruct(EBPF::CodeBuilder *builder);
void emitKeyType(EBPF::CodeBuilder *builder) override;
Expand Down Expand Up @@ -261,7 +264,7 @@ class ConvertToEBPFParserPNA : public Inspector {

class EBPFControlPNA : public EBPF::EBPFControlPSA {
public:
bool defineExtern = false;
bool addExternDeclaration = false;
std::map<cstring, EBPFRegisterPNA *> pna_registers;

EBPFControlPNA(const EBPF::EBPFProgram *program, const IR::ControlBlock *control,
Expand All @@ -274,7 +277,7 @@ class EBPFControlPNA : public EBPF::EBPFControlPSA {
return result;
}
void emitExternDefinition(EBPF::CodeBuilder *builder) {
if (defineExtern) {
if (addExternDeclaration) {
builder->emitIndent();
builder->appendLine("struct p4tc_ext_bpf_params ext_params = {};");
builder->emitIndent();
Expand Down Expand Up @@ -374,6 +377,7 @@ class ActionTranslationVisitorPNA : public EBPF::ActionTranslationVisitor,
const IR::P4Action *act, bool isDefaultAction);
bool preorder(const IR::PathExpression *pe) override;
bool isActionParameter(const IR::Expression *expression) const;
void processMethod(const P4::ExternMethod *method) override;

cstring getParamInstanceName(const IR::Expression *expression) const override;
cstring getParamName(const IR::PathExpression *) override;
Expand Down
2 changes: 1 addition & 1 deletion backends/tc/introspection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ void IntrospectionGenerator::collectExternInfo() {
auto externInstanceInfo = new struct ExternInstancesAttributes();
externInstanceInfo->id = externInstance->instanceID;
externInstanceInfo->name = externInstance->instanceName;
for (auto control_field : externInstance->keys) {
for (auto control_field : externInstance->controlKeys) {
auto keyField = new struct KeyFieldAttributes();
keyField->id = control_field->keyID;
keyField->name = control_field->keyName;
Expand Down
17 changes: 11 additions & 6 deletions backends/tc/runtime/pna.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,15 @@ xdp_p4tc_entry_delete(struct xdp_md *xdp_ctx,
void *key, const u32 key__sz) __ksym;

/* Start generic kfunc interface to any extern */

#define P4TC_EXT_CNT_DIRECT 0x1
#define P4TC_EXT_CNT_INDIRECT 0x2

struct p4tc_ext_bpf_params {
u32 pipe_id;
u32 ext_id;
u32 inst_id;
u32 tbl_id;
u32 index;
u32 flags;
u8 in_params[128]; /* extern specific params if any */
Expand All @@ -192,19 +197,19 @@ struct p4tc_ext_bpf_val {

/* Equivalent to PNA indirect counters */
extern int
bpf_p4tc_extern_indirect_count_pktsnbytes(struct __sk_buff *skb_ctx,
bpf_p4tc_extern_count_pktsnbytes(struct __sk_buff *skb_ctx,
struct p4tc_ext_bpf_params *params,
const u32 params__sz) __ksym;
const u32 params__sz, void *key, const u32 key__sz) __ksym;

extern int
bpf_p4tc_extern_indirect_count_pktsonly(struct __sk_buff *skb_ctx,
bpf_p4tc_extern_count_pkts(struct __sk_buff *skb_ctx,
struct p4tc_ext_bpf_params *params,
const u32 params__sz) __ksym;
const u32 params__sz, void *key, const u32 key__sz) __ksym;

extern int
bpf_p4tc_extern_indirect_count_bytesonly(struct __sk_buff *skb_ctx,
bpf_p4tc_extern_count_bytes(struct __sk_buff *skb_ctx,
struct p4tc_ext_bpf_params *params,
const u32 params__sz) __ksym;
const u32 params__sz, void *key, const u32 key__sz) __ksym;

extern int
xdp_p4tc_extern_indirect_count_pktsnbytes(struct xdp_md *xdp_ctx,
Expand Down
Loading

0 comments on commit 69e4ac6

Please sign in to comment.