Skip to content

Commit

Permalink
P4TC - Emit 'NoAction' in table actions list in template file (#4622)
Browse files Browse the repository at this point in the history
* Emit 'NoAction' in template file.

* Update testcases

* Addressed comment
  • Loading branch information
komaljai authored Apr 22, 2024
1 parent 8cb15e8 commit 37c13dc
Show file tree
Hide file tree
Showing 16 changed files with 949 additions and 21 deletions.
29 changes: 22 additions & 7 deletions backends/tc/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,21 @@ cstring ConvertToBackendIR::externalName(const IR::IDeclaration *declaration) co
return Name;
}

bool ConvertToBackendIR::isDuplicateOrNoAction(const IR::P4Action *action) {
bool ConvertToBackendIR::isDuplicateAction(const IR::P4Action *action) {
auto actionName = externalName(action);
if (actions.find(actionName) != actions.end()) return true;
if (actionName == P4::P4CoreLibrary::instance().noAction.name) return true;
return false;
}

void ConvertToBackendIR::postorder(const IR::P4Action *action) {
if (action != nullptr) {
if (isDuplicateOrNoAction(action)) return;
if (isDuplicateAction(action)) return;
auto actionName = externalName(action);
if (actionName == P4::P4CoreLibrary::instance().noAction.name) {
tcPipeline->addNoActionDefinition(new IR::TCAction("NoAction"));
actions.emplace("NoAction", action);
return;
}
actions.emplace(actionName, action);
actionCount++;
unsigned int actionId = actionCount;
Expand Down Expand Up @@ -671,11 +675,20 @@ void ConvertToBackendIR::postorder(const IR::P4Table *t) {
}
tableDefinition->setTablePermission(HandleTableAccessPermission(t));
auto actionlist = t->getActionList();
for (auto action : actionlist->actionList) {
for (auto actionDef : tcPipeline->actionDefs) {
if (actionlist->size() == 0) {
tableDefinition->addAction(tcPipeline->NoAction, TC::TABLEDEFAULT);
} else {
for (auto action : actionlist->actionList) {
const IR::TCAction *tcAction = nullptr;
auto adecl = refMap->getDeclaration(action->getPath(), true);
auto actionName = externalName(adecl);
if (actionName != actionDef->actionName) continue;
for (auto actionDef : tcPipeline->actionDefs) {
if (actionName != actionDef->actionName) continue;
tcAction = actionDef;
}
if (actionName == P4::P4CoreLibrary::instance().noAction.name) {
tcAction = tcPipeline->NoAction;
}
auto annoList = action->getAnnotations()->annotations;
unsigned int tableFlag = TC::TABLEDEFAULT;
for (auto anno : annoList) {
Expand All @@ -686,7 +699,9 @@ void ConvertToBackendIR::postorder(const IR::P4Table *t) {
tableFlag = TC::DEFAULTONLY;
}
}
tableDefinition->addAction(actionDef, tableFlag);
if (tcAction) {
tableDefinition->addAction(tcAction, tableFlag);
}
}
}
updateDefaultHitAction(t, tableDefinition);
Expand Down
2 changes: 1 addition & 1 deletion backends/tc/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ConvertToBackendIR : public Inspector {
void postorder(const IR::P4Action *a) override;
void postorder(const IR::P4Table *t) override;
void postorder(const IR::P4Program *p) override;
bool isDuplicateOrNoAction(const IR::P4Action *action);
bool isDuplicateAction(const IR::P4Action *action);
void updateDefaultHitAction(const IR::P4Table *t, IR::TCTable *tdef);
void updateDefaultMissAction(const IR::P4Table *t, IR::TCTable *tdef);
void updateConstEntries(const IR::P4Table *t, IR::TCTable *tdef);
Expand Down
7 changes: 7 additions & 0 deletions backends/tc/tc.def
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ class TCAction {
unsigned actId;
optional safe_vector<TCActionParam> actionParams;
cstring getName() const {
if (actionName == "NoAction") {
return "NoAction";
}
cstring tcAction = pipelineName;
tcAction += "/" + actionName;
return tcAction;
Expand Down Expand Up @@ -394,6 +397,7 @@ class TCTable {
class TCPipeline {
cstring pipelineName;
unsigned numTables;
TCAction NoAction;
safe_vector<TCAction> actionDefs;
safe_vector<TCTable> tableDefs;
void setPipelineName(cstring pName) {
Expand All @@ -402,6 +406,9 @@ class TCPipeline {
void setNumTables(unsigned n) {
numTables = n;
}
void addNoActionDefinition(TCAction actionDef) {
NoAction = actionDef;
}
void addActionDefinition(TCAction actionDef) {
actionDefs.push_back(actionDef);
}
Expand Down
129 changes: 129 additions & 0 deletions testdata/p4tc_samples/default_action_example_01.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#include <core.p4>
#include <tc/pna.p4>

typedef bit<48> EthernetAddress;

header ethernet_t {
EthernetAddress dstAddr;
EthernetAddress srcAddr;
bit<16> etherType;
}

header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> totalLen;
bit<16> identification;
bit<3> flags;
bit<13> fragOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdrChecksum;
@tc_type ("ipv4") bit<32> srcAddr;
@tc_type ("ipv4") bit<32> dstAddr;
}

//////////////////////////////////////////////////////////////////////
// Struct types for holding user-defined collections of headers and
// metadata in the P4 developer's program.
//
// Note: The names of these struct types are completely up to the P4
// developer, as are their member fields, with the only restriction
// being that the structs intended to contain headers should only
// contain members whose types are header, header stack, or
// header_union.
//////////////////////////////////////////////////////////////////////

struct main_metadata_t {
// empty for this skeleton
}

// User-defined struct containing all of those headers parsed in the
// main parser.
struct headers_t {
ethernet_t ethernet;
ipv4_t ipv4;
}

parser MainParserImpl(
packet_in pkt,
out headers_t hdr,
inout main_metadata_t main_meta,
in pna_main_parser_input_metadata_t istd)
{
state start {
pkt.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
0x0800 : parse_ipv4;
default : accept;
}
}
state parse_ipv4 {
pkt.extract(hdr.ipv4);
transition accept;
}
}

control MainControlImpl(
inout headers_t hdr, // from main parser
inout main_metadata_t user_meta, // from main parser, to "next block"
in pna_main_input_metadata_t istd,
inout pna_main_output_metadata_t ostd)
{
action next_hop(PortId_t vport) {
send_to_port(vport);
}
action default_route_drop() {
drop_packet();
}
action drop() {
drop_packet();
}

table ipv4_tbl_1 {
key = {
hdr.ipv4.dstAddr : exact;
istd.input_port : exact;
}
actions = {
next_hop;
default_route_drop;
}
}
table ipv4_tbl_2 {
key = {
hdr.ipv4.dstAddr : exact;
hdr.ipv4.srcAddr : exact;
hdr.ipv4.protocol : exact;
}
actions = {}
}

apply {
if (hdr.ipv4.isValid()) {
ipv4_tbl_1.apply();
ipv4_tbl_2.apply();
}
}
}

control MainDeparserImpl(
packet_out pkt,
inout headers_t hdr, // from main control
in main_metadata_t user_meta, // from main control
in pna_main_output_metadata_t ostd)
{
apply {
pkt.emit(hdr.ethernet);
pkt.emit(hdr.ipv4);
}
}

// BEGIN:Package_Instantiation_Example
PNA_NIC(
MainParserImpl(),
MainControlImpl(),
MainDeparserImpl()
) main;
// END:Package_Instantiation_Example
88 changes: 88 additions & 0 deletions testdata/p4tc_samples_outputs/default_action_example_01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{
"schema_version" : "1.0.0",
"pipeline_name" : "default_action_example_01",
"tables" : [
{
"name" : "MainControlImpl/ipv4_tbl_1",
"id" : 1,
"tentries" : 2048,
"permissions" : "0x3da4",
"nummask" : 8,
"keysize" : 64,
"keyfields" : [
{
"id" : 1,
"name" : "hdr.ipv4.dstAddr",
"type" : "bit32",
"match_type" : "exact",
"bitwidth" : 32
},
{
"id" : 2,
"name" : "istd.input_port",
"type" : "bit32",
"match_type" : "exact",
"bitwidth" : 32
}
],
"actions" : [
{
"id" : 1,
"name" : "MainControlImpl/next_hop",
"action_scope" : "TableAndDefault",
"annotations" : [],
"params" : [
{
"id" : 1,
"name" : "vport",
"type" : "bit32",
"bitwidth" : 32
}
],
"default_hit_action" : false,
"default_miss_action" : false
},
{
"id" : 2,
"name" : "MainControlImpl/default_route_drop",
"action_scope" : "TableAndDefault",
"annotations" : [],
"params" : [],
"default_hit_action" : false,
"default_miss_action" : false
}
]
},
{
"name" : "MainControlImpl/ipv4_tbl_2",
"id" : 2,
"tentries" : 2048,
"permissions" : "0x3da4",
"nummask" : 8,
"keysize" : 72,
"keyfields" : [
{
"id" : 1,
"name" : "hdr.ipv4.dstAddr",
"type" : "bit32",
"match_type" : "exact",
"bitwidth" : 32
},
{
"id" : 2,
"name" : "hdr.ipv4.srcAddr",
"type" : "bit32",
"match_type" : "exact",
"bitwidth" : 32
},
{
"id" : 3,
"name" : "hdr.ipv4.protocol",
"type" : "bit8",
"match_type" : "exact",
"bitwidth" : 8
}
]
}
]
}
Empty file.
28 changes: 28 additions & 0 deletions testdata/p4tc_samples_outputs/default_action_example_01.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash -x

set -e

TC="tc"
$TC p4template create pipeline/default_action_example_01 numtables 2

$TC p4template create action/default_action_example_01/MainControlImpl/next_hop actid 1 \
param vport type bit32
$TC p4template update action/default_action_example_01/MainControlImpl/next_hop state active

$TC p4template create action/default_action_example_01/MainControlImpl/default_route_drop actid 2
$TC p4template update action/default_action_example_01/MainControlImpl/default_route_drop state active

$TC p4template create table/default_action_example_01/MainControlImpl/ipv4_tbl_1 \
tblid 1 \
type exact \
keysz 64 nummasks 8 permissions 0x3da4 tentries 2048 \
table_acts act name default_action_example_01/MainControlImpl/next_hop \
act name default_action_example_01/MainControlImpl/default_route_drop \
act name NoAction flags defaultonly

$TC p4template create table/default_action_example_01/MainControlImpl/ipv4_tbl_2 \
tblid 2 \
type exact \
keysz 72 nummasks 8 permissions 0x3da4 tentries 2048 \
table_acts act name NoAction flags defaultonly
$TC p4template update pipeline/default_action_example_01 state ready
Loading

0 comments on commit 37c13dc

Please sign in to comment.