From 277c389baf714685829389d2db9319f9f81895a4 Mon Sep 17 00:00:00 2001 From: Sosutha Date: Wed, 27 Mar 2024 09:03:39 +0530 Subject: [PATCH] Added default action code for tc backend (#4561) * Added default action code in control block for tc backend * Updated testcase outputs --- backends/tc/ebpfCodeGen.cpp | 111 +++++++++++++----- backends/tc/ebpfCodeGen.h | 11 +- ...c_may_override_example_01_control_blocks.c | 13 +- ...c_may_override_example_04_control_blocks.c | 18 ++- ...c_may_override_example_05_control_blocks.c | 13 +- ...c_may_override_example_06_control_blocks.c | 26 +++- 6 files changed, 145 insertions(+), 47 deletions(-) diff --git a/backends/tc/ebpfCodeGen.cpp b/backends/tc/ebpfCodeGen.cpp index 4c0a97b83c..66a3f1c7b2 100644 --- a/backends/tc/ebpfCodeGen.cpp +++ b/backends/tc/ebpfCodeGen.cpp @@ -131,29 +131,20 @@ void PNAEbpfGenerator::emitP4TCFilterFields(EBPF::CodeBuilder *builder) const { } void PNAEbpfGenerator::emitP4TCActionParam(EBPF::CodeBuilder *builder) const { - std::vector actionParamList; for (auto table : tcIR->tcPipeline->tableDefs) { if (table->isTcMayOverride) { cstring tblName = table->getTableName(); cstring defaultActionName = table->defaultMissAction->getActionName(); - auto actionNameStr = defaultActionName.c_str(); - for (long unsigned int i = 0; i < defaultActionName.size(); i++) { - if (actionNameStr[i] == '/') { - defaultActionName = defaultActionName.substr(i + 1, defaultActionName.size()); - break; - } - } + defaultActionName = defaultActionName.substr( + defaultActionName.find('/') - defaultActionName.begin() + 1, + defaultActionName.size()); for (auto param : table->defaultMissActionParams) { cstring paramName = param->paramDetail->getParamName(); cstring placeholder = tblName + "_" + defaultActionName + "_" + paramName; - auto itr = find(actionParamList.begin(), actionParamList.end(), placeholder); - if (itr == actionParamList.end()) { - actionParamList.push_back(placeholder); - cstring typeName = param->paramDetail->getParamType(); - builder->emitIndent(); - builder->appendFormat("%s %s", typeName, placeholder); - builder->endOfStatement(true); - } + cstring typeName = param->paramDetail->getParamType(); + builder->emitIndent(); + builder->appendFormat("%s %s", typeName, placeholder); + builder->endOfStatement(true); } } } @@ -965,16 +956,63 @@ void EBPFTablePNA::emitAction(EBPF::CodeBuilder *builder, cstring valueName, builder->target->emitTraceMessage(builder, msgStr.c_str()); } } + bool generateDefaultMissCode = false; + for (auto tbl : tcIR->tcPipeline->tableDefs) { + if (tbl->getTableName() == table->container->name.originalName) { + if (tbl->isTcMayOverride) { + cstring defaultActionName = tbl->defaultMissAction->getActionName(); + defaultActionName = defaultActionName.substr( + defaultActionName.find('/') - defaultActionName.begin() + 1, + defaultActionName.size()); + if (defaultActionName == action->name.originalName) + generateDefaultMissCode = true; + } + } + } + if (generateDefaultMissCode) { + builder->emitIndent(); + builder->appendFormat("{"); + builder->newline(); + builder->increaseIndent(); - builder->emitIndent(); + builder->emitIndent(); + builder->appendFormat("if (%s->is_default_miss_act) ", valueName.c_str()); + builder->newline(); - auto visitor = createActionTranslationVisitor(valueName, program); - visitor->setBuilder(builder); - visitor->copySubstitutions(codeGen); - visitor->copyPointerVariables(codeGen); + builder->emitIndent(); + auto defaultVisitor = createActionTranslationVisitor(valueName, program, action, true); + defaultVisitor->setBuilder(builder); + defaultVisitor->copySubstitutions(codeGen); + defaultVisitor->copyPointerVariables(codeGen); + action->apply(*defaultVisitor); + builder->newline(); + + builder->emitIndent(); + builder->appendFormat("else"); + builder->newline(); + + builder->emitIndent(); + auto visitor = createActionTranslationVisitor(valueName, program, action, false); + visitor->setBuilder(builder); + visitor->copySubstitutions(codeGen); + visitor->copyPointerVariables(codeGen); + action->apply(*visitor); + builder->newline(); + + builder->decreaseIndent(); + builder->emitIndent(); + builder->appendFormat("}"); + builder->newline(); + } else { + builder->emitIndent(); + auto visitor = createActionTranslationVisitor(valueName, program, action, false); + visitor->setBuilder(builder); + visitor->copySubstitutions(codeGen); + visitor->copyPointerVariables(codeGen); + action->apply(*visitor); + builder->newline(); + } - action->apply(*visitor); - builder->newline(); builder->emitIndent(); builder->appendLine("break;"); builder->decreaseIndent(); @@ -1866,14 +1904,16 @@ bool ControlBodyTranslatorPNA::preorder(const IR::AssignmentStatement *a) { return EBPF::CodeGenInspector::preorder(a); } // =====================ActionTranslationVisitorPNA============================= -ActionTranslationVisitorPNA::ActionTranslationVisitorPNA(const EBPF::EBPFProgram *program, - cstring valueName, - const EBPF::EBPFTablePSA *table, - const ConvertToBackendIR *tcIR) +ActionTranslationVisitorPNA::ActionTranslationVisitorPNA( + const EBPF::EBPFProgram *program, cstring valueName, const EBPF::EBPFTablePSA *table, + const ConvertToBackendIR *tcIR, const IR::P4Action *action, bool isDefaultAction) : EBPF::CodeGenInspector(program->refMap, program->typeMap), EBPF::ActionTranslationVisitor(valueName, program), ControlBodyTranslatorPNA(program->as().control, tcIR, table), - table(table) {} + table(table), + isDefaultAction(isDefaultAction) { + action = action; +} bool ActionTranslationVisitorPNA::preorder(const IR::PathExpression *pe) { if (isActionParameter(pe)) { @@ -1894,7 +1934,15 @@ bool ActionTranslationVisitorPNA::isActionParameter(const IR::Expression *expres cstring ActionTranslationVisitorPNA::getParamInstanceName(const IR::Expression *expression) const { if (auto cast = expression->to()) expression = cast->expr; - return EBPF::ActionTranslationVisitor::getParamInstanceName(expression); + if (isDefaultAction) { + cstring actionName = action->name.originalName; + auto paramStr = Util::printf_format("p4tc_filter_fields.%s_%s_%s", + table->table->container->name.originalName, actionName, + expression->toString()); + return paramStr; + } else { + return EBPF::ActionTranslationVisitor::getParamInstanceName(expression); + } } cstring ActionTranslationVisitorPNA::getParamName(const IR::PathExpression *expr) { @@ -1905,9 +1953,10 @@ cstring ActionTranslationVisitorPNA::getParamName(const IR::PathExpression *expr } EBPF::ActionTranslationVisitor *EBPFTablePNA::createActionTranslationVisitor( - cstring valueName, const EBPF::EBPFProgram *program) const { + cstring valueName, const EBPF::EBPFProgram *program, const IR::P4Action *action, + bool isDefault) const { return new ActionTranslationVisitorPNA(program->checkedTo(), valueName, - this, tcIR); + this, tcIR, action, isDefault); } void EBPFTablePNA::validateKeys() const { diff --git a/backends/tc/ebpfCodeGen.h b/backends/tc/ebpfCodeGen.h index b20b4f47fe..0c74b1ea38 100644 --- a/backends/tc/ebpfCodeGen.h +++ b/backends/tc/ebpfCodeGen.h @@ -139,8 +139,10 @@ class EBPFPnaParser : public EBPF::EBPFPsaParser { class EBPFTablePNA : public EBPF::EBPFTablePSA { protected: - EBPF::ActionTranslationVisitor *createActionTranslationVisitor( - cstring valueName, const EBPF::EBPFProgram *program) const override; + EBPF::ActionTranslationVisitor *createActionTranslationVisitor(cstring valueName, + const EBPF::EBPFProgram *program, + const IR::P4Action *action, + bool isDefaultAction) const; void validateKeys() const override; const ConvertToBackendIR *tcIR; @@ -333,12 +335,13 @@ class ActionTranslationVisitorPNA : public EBPF::ActionTranslationVisitor, public ControlBodyTranslatorPNA { protected: const EBPF::EBPFTablePSA *table; + bool isDefaultAction; public: const ConvertToBackendIR *tcIR; ActionTranslationVisitorPNA(const EBPF::EBPFProgram *program, cstring valueName, - const EBPF::EBPFTablePSA *table, const ConvertToBackendIR *tcIR); - + const EBPF::EBPFTablePSA *table, const ConvertToBackendIR *tcIR, + const IR::P4Action *action, bool isDefaultAction); bool preorder(const IR::PathExpression *pe) override; bool isActionParameter(const IR::Expression *expression) const; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_01_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_01_control_blocks.c index a1d1ae5bb5..4863df14a4 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_01_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_01_control_blocks.c @@ -111,9 +111,18 @@ if (/* hdr->ipv4.isValid() */ switch (value->action) { case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_NEXT_HOP: { + if (value->is_default_miss_act) + { +/* send_to_port(p4tc_filter_fields.ipv4_tbl_1_next_hop_vport) */ + compiler_meta__->drop = false; + send_to_port(p4tc_filter_fields.ipv4_tbl_1_next_hop_vport); + } + else + { /* send_to_port(value->u.MainControlImpl_next_hop.vport) */ - compiler_meta__->drop = false; - send_to_port(value->u.MainControlImpl_next_hop.vport); + compiler_meta__->drop = false; + send_to_port(value->u.MainControlImpl_next_hop.vport); + } } break; case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_DEFAULT_ROUTE_DROP: diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_04_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_04_control_blocks.c index 57a6ba43b8..6f6da97bb5 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_04_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_04_control_blocks.c @@ -111,10 +111,20 @@ if (/* hdr->ipv4.isValid() */ switch (value->action) { case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_NEXT_HOP: { - hdr->ipv4.dstAddr = value->u.MainControlImpl_next_hop.ipv4addr; - /* send_to_port(8) */ - compiler_meta__->drop = false; - send_to_port(8); + if (value->is_default_miss_act) + { + hdr->ipv4.dstAddr = p4tc_filter_fields.ipv4_tbl_1_next_hop_ipv4addr; + /* send_to_port(8) */ + compiler_meta__->drop = false; + send_to_port(8); + } + else + { + hdr->ipv4.dstAddr = value->u.MainControlImpl_next_hop.ipv4addr; + /* send_to_port(8) */ + compiler_meta__->drop = false; + send_to_port(8); + } } break; case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_DEFAULT_ROUTE_DROP: diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_05_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_05_control_blocks.c index 6d31d4a49f..1854cdf724 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_05_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_05_control_blocks.c @@ -111,9 +111,18 @@ if (/* hdr->ipv4.isValid() */ switch (value->action) { case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_NEXT_HOP: { + if (value->is_default_miss_act) + { +/* send_to_port(p4tc_filter_fields.ipv4_tbl_1_next_hop_vport) */ + compiler_meta__->drop = false; + send_to_port(p4tc_filter_fields.ipv4_tbl_1_next_hop_vport); + } + else + { /* send_to_port(value->u.MainControlImpl_next_hop.vport) */ - compiler_meta__->drop = false; - send_to_port(value->u.MainControlImpl_next_hop.vport); + compiler_meta__->drop = false; + send_to_port(value->u.MainControlImpl_next_hop.vport); + } } break; case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_DEFAULT_ROUTE_DROP: diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_06_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_06_control_blocks.c index be449ad291..7ff682ef7f 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_06_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_06_control_blocks.c @@ -111,9 +111,18 @@ if (/* hdr->ipv4.isValid() */ switch (value->action) { case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_NEXT_HOP: { + if (value->is_default_miss_act) + { +/* send_to_port(p4tc_filter_fields.ipv4_tbl_1_next_hop_vport) */ + compiler_meta__->drop = false; + send_to_port(p4tc_filter_fields.ipv4_tbl_1_next_hop_vport); + } + else + { /* send_to_port(value->u.MainControlImpl_next_hop.vport) */ - compiler_meta__->drop = false; - send_to_port(value->u.MainControlImpl_next_hop.vport); + compiler_meta__->drop = false; + send_to_port(value->u.MainControlImpl_next_hop.vport); + } } break; case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_DEFAULT_ROUTE_DROP: @@ -161,9 +170,18 @@ if (/* hdr->ipv4.isValid() */ switch (value->action) { case MAINCONTROLIMPL_IPV4_TBL_2_ACT_MAINCONTROLIMPL_NEXT_HOP: { + if (value->is_default_miss_act) + { +/* send_to_port(p4tc_filter_fields.ipv4_tbl_2_next_hop_vport) */ + compiler_meta__->drop = false; + send_to_port(p4tc_filter_fields.ipv4_tbl_2_next_hop_vport); + } + else + { /* send_to_port(value->u.MainControlImpl_next_hop.vport) */ - compiler_meta__->drop = false; - send_to_port(value->u.MainControlImpl_next_hop.vport); + compiler_meta__->drop = false; + send_to_port(value->u.MainControlImpl_next_hop.vport); + } } break; case MAINCONTROLIMPL_IPV4_TBL_2_ACT_MAINCONTROLIMPL_DROP: