diff --git a/backends/tc/backend.cpp b/backends/tc/backend.cpp index c65f83208dc..104f316cb93 100644 --- a/backends/tc/backend.cpp +++ b/backends/tc/backend.cpp @@ -377,12 +377,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(); @@ -391,14 +391,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(); @@ -409,14 +409,14 @@ void ConvertToBackendIR::updateDefaultMissAction(const IR::P4Table *t, IR::TCTab } auto defaultArg = methodexp->arguments->at(i++); if (auto constVal = defaultArg->expression->to()) { - 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", @@ -433,11 +433,13 @@ void ConvertToBackendIR::updateDefaultHitAction(const IR::P4Table *t, IR::TCTabl unsigned int defaultHit = 0; unsigned int defaultHitConst = 0; cstring defaultActionName = nullptr; + bool isTcMayOverrideHit = false; for (auto action : actionlist->actionList) { auto annoList = action->getAnnotations()->annotations; bool isTableOnly = false; bool isDefaultHit = false; bool isDefaultHitConst = false; + isTcMayOverrideHit = false; for (auto anno : annoList) { if (anno->name == IR::Annotation::tableOnlyAnnotation) { isTableOnly = true; @@ -454,6 +456,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, @@ -479,6 +484,16 @@ 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) { + 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; + } } } if (::errorCount() > 0) { @@ -508,6 +523,9 @@ void ConvertToBackendIR::updateDefaultHitAction(const IR::P4Table *t, IR::TCTabl if (defaultHitConst == 1) { tabledef->setDefaultHitConst(true); } + if (isTcMayOverrideHit) { + tabledef->setTcMayOverrideHit(); + } } } } diff --git a/backends/tc/ebpfCodeGen.cpp b/backends/tc/ebpfCodeGen.cpp index 66a3f1c7b2a..a253bda0a6b 100644 --- a/backends/tc/ebpfCodeGen.cpp +++ b/backends/tc/ebpfCodeGen.cpp @@ -132,7 +132,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( diff --git a/backends/tc/tc.def b/backends/tc/tc.def index 9cd5cc37f85..63d7a6c2822 100644 --- a/backends/tc/tc.def +++ b/backends/tc/tc.def @@ -236,11 +236,13 @@ class TCTable { unsigned defaultTimerProfiles = 4; TCAction defaultHitAction; bool isDefaultHitConst; + bool isTcMayOverrideHit; + optional safe_vector defaultHitActionParams; TCAction defaultMissAction; - optional safe_vector defaultMissActionParams; bool isDefaultMissConst; + bool isTcMayOverrideMiss; + optional safe_vector defaultMissActionParams; bool isTableAddOnMiss; - bool isTcMayOverride; ordered_map actionList; safe_vector const_entries; @@ -268,12 +270,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); } @@ -315,8 +320,9 @@ class TCTable { defaultMissAction = nullptr; isDefaultHitConst = false; isDefaultMissConst = false; + isTcMayOverrideHit = false; + isTcMayOverrideMiss = false; isTableAddOnMiss = false; - isTcMayOverride = false; } toString { std::string tcTable = ""; @@ -358,6 +364,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 @@ -371,7 +383,7 @@ class TCTable { tcTable += " param"; for (auto param : defaultMissActionParams) tcTable += param->toString(); - if (isTcMayOverride) + if (isTcMayOverrideMiss) tcTable += " flags runtime"; } if (const_entries.size() != 0) {