Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 62 additions & 6 deletions backends/tc/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,16 @@ void ConvertToBackendIR::postorder(const IR::P4Action *action) {
"tc_type annotation cannot have '%1%' as value", expr);
}
}
auto direction = param->direction;
if (direction == IR::Direction::InOut) {
tcActionParam->setDirection(TC::INOUT);
} else if (direction == IR::Direction::In) {
tcActionParam->setDirection(TC::IN);
} else if (direction == IR::Direction::Out) {
tcActionParam->setDirection(TC::OUT);
} else {
tcActionParam->setDirection(TC::NONE);
}
tcAction->addActionParams(tcActionParam);
}
}
Expand Down Expand Up @@ -381,12 +391,12 @@ void ConvertToBackendIR::updateDefaultMissAction(const IR::P4Table *t, IR::TCTab
if (defaultActionProperty->isConstant) {
tabledef->setDefaultMissConst(true);
}
bool isTCMayOverride = false;
bool isTCMayOverrideMiss = false;
const IR::Annotation *overrideAnno =
defaultActionProperty->getAnnotations()->getSingle(
ParseTCAnnotations::tcMayOverride);
if (overrideAnno) {
isTCMayOverride = true;
isTCMayOverrideMiss = true;
}
bool directionParamPresent = false;
auto paramList = actionCall->action->getParameters();
Expand All @@ -395,14 +405,14 @@ void ConvertToBackendIR::updateDefaultMissAction(const IR::P4Table *t, IR::TCTab
}
if (!directionParamPresent) {
auto i = 0;
if (isTCMayOverride) {
if (isTCMayOverrideMiss) {
if (paramList->parameters.empty())
::warning(ErrorType::WARN_INVALID,
"%1% annotation cannot be used with default_action without "
"parameters",
overrideAnno);
else
tabledef->setTcMayOverride();
tabledef->setTcMayOverrideMiss();
}
for (auto param : paramList->parameters) {
auto defaultParam = new IR::TCDefaultActionParam();
Expand All @@ -413,14 +423,14 @@ void ConvertToBackendIR::updateDefaultMissAction(const IR::P4Table *t, IR::TCTab
}
auto defaultArg = methodexp->arguments->at(i++);
if (auto constVal = defaultArg->expression->to<IR::Constant>()) {
if (!isTCMayOverride)
if (!isTCMayOverrideMiss)
defaultParam->setDefaultValue(
Util::toString(constVal->value, 0, true, constVal->base));
tabledef->defaultMissActionParams.push_back(defaultParam);
}
}
} else {
if (isTCMayOverride)
if (isTCMayOverrideMiss)
::warning(ErrorType::WARN_INVALID,
"%1% annotation cannot be used with default_action with "
"directional parameters",
Expand All @@ -437,11 +447,13 @@ void ConvertToBackendIR::updateDefaultHitAction(const IR::P4Table *t, IR::TCTabl
unsigned int defaultHit = 0;
unsigned int defaultHitConst = 0;
cstring defaultActionName = nullptr;
bool isTcMayOverrideHitAction = false;
for (auto action : actionlist->actionList) {
auto annoList = action->getAnnotations()->annotations;
bool isTableOnly = false;
bool isDefaultHit = false;
bool isDefaultHitConst = false;
bool isTcMayOverrideHit = false;
for (auto anno : annoList) {
if (anno->name == IR::Annotation::tableOnlyAnnotation) {
isTableOnly = true;
Expand All @@ -458,6 +470,9 @@ void ConvertToBackendIR::updateDefaultHitAction(const IR::P4Table *t, IR::TCTabl
auto adecl = refMap->getDeclaration(action->getPath(), true);
defaultActionName = externalName(adecl);
}
if (anno->name == ParseTCAnnotations::tcMayOverride) {
isTcMayOverrideHit = true;
}
}
if (isTableOnly && isDefaultHit && isDefaultHitConst) {
::error(ErrorType::ERR_INVALID,
Expand All @@ -483,6 +498,26 @@ void ConvertToBackendIR::updateDefaultHitAction(const IR::P4Table *t, IR::TCTabl
"annotated with '@default_hit' and '@default_hit_const'",
t->name.originalName, action->getName().originalName);
break;
} else if (isTcMayOverrideHit) {
auto adecl = refMap->getDeclaration(action->getPath(), true);
auto p4Action = adecl->getNode()->checkedTo<IR::P4Action>();
if (!isDefaultHit && !isDefaultHitConst) {
::warning(ErrorType::WARN_INVALID,
"Table '%1%' has an action reference '%2%' which is "
"annotated with '@tc_may_override' without '@default_hit' or "
"'@default_hit_const'",
t->name.originalName, action->getName().originalName);
isTcMayOverrideHit = false;
break;
} else if (p4Action->getParameters()->parameters.empty()) {
::warning(ErrorType::WARN_INVALID,
" '@tc_may_override' cannot be used for %1% action "
" without parameters",
action->getName().originalName);
isTcMayOverrideHit = false;
break;
}
isTcMayOverrideHitAction = true;
}
}
if (::errorCount() > 0) {
Expand Down Expand Up @@ -512,6 +547,16 @@ void ConvertToBackendIR::updateDefaultHitAction(const IR::P4Table *t, IR::TCTabl
if (defaultHitConst == 1) {
tabledef->setDefaultHitConst(true);
}
if (isTcMayOverrideHitAction) {
if (!checkParameterDirection(tcAction)) {
tabledef->setTcMayOverrideHit();
for (auto param : tcAction->actionParams) {
auto defaultParam = new IR::TCDefaultActionParam();
defaultParam->setParamDetail(param);
tabledef->defaultHitActionParams.push_back(defaultParam);
}
}
}
}
}
}
Expand Down Expand Up @@ -1101,4 +1146,15 @@ void ConvertToBackendIR::updateMatchType(const IR::P4Table *t, IR::TCTable *tabl
tabledef->setMatchType(tableMatchType);
}

bool ConvertToBackendIR::checkParameterDirection(const IR::TCAction *tcAction) {
bool dirParam = false;
for (auto actionParam : tcAction->actionParams) {
if (actionParam->getDirection() != TC::NONE) {
dirParam = true;
break;
}
}
return dirParam;
}

} // namespace TC
1 change: 1 addition & 0 deletions backends/tc/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class ConvertToBackendIR : public Inspector {
cstring HandleTableAccessPermission(const IR::P4Table *t);
std::pair<cstring, cstring> *GetAnnotatedAccessPath(const IR::Annotation *anno);
void updateAddOnMissTable(const IR::P4Table *t);
bool checkParameterDirection(const IR::TCAction *tcAction);
};

class Extern {
Expand Down
35 changes: 31 additions & 4 deletions backends/tc/ebpfCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void PNAEbpfGenerator::emitP4TCFilterFields(EBPF::CodeBuilder *builder) const {

void PNAEbpfGenerator::emitP4TCActionParam(EBPF::CodeBuilder *builder) const {
for (auto table : tcIR->tcPipeline->tableDefs) {
if (table->isTcMayOverride) {
if (table->isTcMayOverrideMiss) {
cstring tblName = table->getTableName();
cstring defaultActionName = table->defaultMissAction->getActionName();
defaultActionName = defaultActionName.substr(
Expand All @@ -148,6 +148,21 @@ void PNAEbpfGenerator::emitP4TCActionParam(EBPF::CodeBuilder *builder) const {
builder->endOfStatement(true);
}
}
if (table->isTcMayOverrideHit) {
cstring tblName = table->getTableName();
cstring defaultActionName = table->defaultHitAction->getActionName();
defaultActionName = defaultActionName.substr(
defaultActionName.find('/') - defaultActionName.begin() + 1,
defaultActionName.size());
for (auto param : table->defaultHitActionParams) {
cstring paramName = param->paramDetail->getParamName();
cstring placeholder = tblName + "_" + defaultActionName + "_" + paramName;
cstring typeName = param->paramDetail->getParamType();
builder->emitIndent();
builder->appendFormat("%s %s", typeName, placeholder);
builder->endOfStatement(true);
}
}
}
}

Expand Down Expand Up @@ -968,26 +983,38 @@ void EBPFTablePNA::emitAction(EBPF::CodeBuilder *builder, cstring valueName,
}
}
bool generateDefaultMissCode = false;
bool generateDefaultHitCode = false;
for (auto tbl : tcIR->tcPipeline->tableDefs) {
if (tbl->getTableName() == table->container->name.originalName) {
if (tbl->isTcMayOverride) {
if (tbl->isTcMayOverrideMiss) {
cstring defaultActionName = tbl->defaultMissAction->getActionName();
defaultActionName = defaultActionName.substr(
defaultActionName.find('/') - defaultActionName.begin() + 1,
defaultActionName.size());
if (defaultActionName == action->name.originalName)
generateDefaultMissCode = true;
}
if (tbl->isTcMayOverrideHit) {
cstring defaultActionName = tbl->defaultHitAction->getActionName();
defaultActionName = defaultActionName.substr(
defaultActionName.find('/') - defaultActionName.begin() + 1,
defaultActionName.size());
if (defaultActionName == action->name.originalName)
generateDefaultHitCode = true;
}
}
}
if (generateDefaultMissCode) {
if (generateDefaultMissCode || generateDefaultHitCode) {
builder->emitIndent();
builder->appendFormat("{");
builder->newline();
builder->increaseIndent();

builder->emitIndent();
builder->appendFormat("if (%s->is_default_miss_act) ", valueName.c_str());
if (generateDefaultMissCode)
builder->appendFormat("if (%s->is_default_miss_act) ", valueName.c_str());
else if (generateDefaultHitCode)
builder->appendFormat("if (%s->is_default_hit_act) ", valueName.c_str());
builder->newline();

builder->emitIndent();
Expand Down
33 changes: 26 additions & 7 deletions backends/tc/tc.def
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class TCActionParam {
cstring paramName;
unsigned dataType;
unsigned bitSize;
unsigned direction;
void setParamName(cstring pN) {
paramName = pN;
}
Expand All @@ -58,6 +59,9 @@ class TCActionParam {
void setDataType(unsigned d) {
dataType = d;
}
void setDirection(unsigned d){
direction = d;
}
TCActionParam() {
paramName = nullptr;
bitSize = 0;
Expand All @@ -68,6 +72,9 @@ class TCActionParam {
cstring getName() const {
return "param." + paramName;
}
unsigned getDirection() const {
return direction;
}
cstring getParamType() const {
std::string paramType = "";
switch(dataType) {
Expand Down Expand Up @@ -240,11 +247,13 @@ class TCTable {
unsigned defaultTimerProfiles = 4;
TCAction defaultHitAction;
bool isDefaultHitConst;
bool isTcMayOverrideHit;
optional safe_vector<TCDefaultActionParam> defaultHitActionParams;
TCAction defaultMissAction;
optional safe_vector<TCDefaultActionParam> defaultMissActionParams;
bool isDefaultMissConst;
bool isTcMayOverrideMiss;
optional safe_vector<TCDefaultActionParam> defaultMissActionParams;
bool isTableAddOnMiss;
bool isTcMayOverride;
ordered_map<TCAction, unsigned> actionList;
safe_vector<TCEntry> const_entries;

Expand Down Expand Up @@ -275,12 +284,15 @@ class TCTable {
void setDefaultMissConst(bool i) {
isDefaultMissConst = i;
}
void setTcMayOverrideHit() {
isTcMayOverrideHit = true;
}
void setTcMayOverrideMiss() {
isTcMayOverrideMiss = true;
}
void setTableAddOnMiss() {
isTableAddOnMiss = true;
}
void setTcMayOverride() {
isTcMayOverride = true;
}
void addAction(TCAction action, unsigned flag) {
actionList.emplace(action, flag);
}
Expand Down Expand Up @@ -322,8 +334,9 @@ class TCTable {
defaultMissAction = nullptr;
isDefaultHitConst = false;
isDefaultMissConst = false;
isTcMayOverrideHit = false;
isTcMayOverrideMiss = false;
isTableAddOnMiss = false;
isTcMayOverride = false;
}
toString {
std::string tcTable = "";
Expand Down Expand Up @@ -363,6 +376,12 @@ class TCTable {
tcTable += " permissions 0x1024";
}
tcTable += " action " + defaultHitAction->getName();
if (!defaultHitActionParams.empty())
tcTable += " param";
for (auto param : defaultHitActionParams)
tcTable += param->toString();
if (isTcMayOverrideHit)
tcTable += " flags runtime";
}
if (defaultMissAction != nullptr) {
tcTable += "\n$TC p4template update table/" + pipelineName
Expand All @@ -376,7 +395,7 @@ class TCTable {
tcTable += " param";
for (auto param : defaultMissActionParams)
tcTable += param->toString();
if (isTcMayOverride)
if (isTcMayOverrideMiss)
tcTable += " flags runtime";
}
if (const_entries.size() != 0) {
Expand Down
5 changes: 5 additions & 0 deletions backends/tc/tc_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ inline constexpr auto DEFAULTONLY = 2;
inline constexpr auto EXACT_TYPE = 0;
inline constexpr auto LPM_TYPE = 1;
inline constexpr auto TERNARY_TYPE = 2;

inline constexpr auto NONE = 0;
inline constexpr auto IN = 1;
inline constexpr auto OUT = 2;
inline constexpr auto INOUT = 3;
} // namespace TC

#endif /* BACKENDS_TC_TC_DEFINES_H_ */
2 changes: 1 addition & 1 deletion testdata/p4tc_samples/tc_may_override_example_01.p4
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ control MainControlImpl(
hdr.ipv4.protocol : exact;
}
actions = {
next_hop;
@tc_may_override @default_hit_const next_hop;
drop;
}
default_action = drop;
Expand Down
Loading