Skip to content

Commit

Permalink
tc_may_override annotation implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Sosutha committed Mar 1, 2024
1 parent d56f93b commit 5af3014
Show file tree
Hide file tree
Showing 11 changed files with 978 additions and 15 deletions.
16 changes: 14 additions & 2 deletions backends/tc/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,10 +360,22 @@ void ConvertToBackendIR::updateDefaultMissAction(const IR::P4Table *t, IR::TCTab
if (param->direction != IR::Direction::None) directionParamPresent = true;
}
if (!directionParamPresent) {
auto annoList = defaultActionProperty->getAnnotations()->annotations;
bool isTCMayOverride = false;
for (auto anno : annoList) {
if (anno->name == ParseTCAnnotations::tcMayOverride) {
isTCMayOverride = true;
}
}
if (isTCMayOverride) tabledef->setTcMayOverride(true);
auto i = 0;
for (auto param : paramList->parameters) {
auto defaultParam = new IR::TCDefaultActionParam();
defaultParam->setParamName(param->name.originalName);
if (isTCMayOverride) {
tabledef->defaultMissActionParams.push_back(defaultParam);
continue;
}
auto defaultArg = methodexp->arguments->at(i++);
if (auto constVal = defaultArg->expression->to<IR::Constant>()) {
bool sign;
Expand Down Expand Up @@ -398,13 +410,13 @@ void ConvertToBackendIR::updateDefaultHitAction(const IR::P4Table *t, IR::TCTabl
if (anno->name == IR::Annotation::tableOnlyAnnotation) {
isTableOnly = true;
}
if (anno->name == ParseTCAnnotations::default_hit) {
if (anno->name == ParseTCAnnotations::defaultHit) {
isDefaultHit = true;
defaultHit++;
auto adecl = refMap->getDeclaration(action->getPath(), true);
defaultActionName = externalName(adecl);
}
if (anno->name == ParseTCAnnotations::default_hit_const) {
if (anno->name == ParseTCAnnotations::defaultHitConst) {
isDefaultHitConst = true;
defaultHitConst++;
auto adecl = refMap->getDeclaration(action->getPath(), true);
Expand Down
18 changes: 13 additions & 5 deletions backends/tc/tc.def
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ class TCDefaultActionParam {
}
toString {
std::string tcActionParam = "";
tcActionParam += " param ";
tcActionParam += paramName;
tcActionParam += " " + defaultValue;
tcActionParam += " " + paramName;
if (defaultValue != nullptr)
tcActionParam += " " + defaultValue;
return tcActionParam;
}
dbprint { out << toString(); }
Expand Down Expand Up @@ -204,6 +204,7 @@ class TCTable {
TCAction defaultMissAction;
optional safe_vector<TCDefaultActionParam> defaultMissActionParams;
bool isDefaultMissConst;
bool isTcMayOverride;
ordered_map<TCAction, unsigned> actionList;
safe_vector<TCEntry> const_entries;

Expand Down Expand Up @@ -231,6 +232,9 @@ class TCTable {
void setDefaultMissConst(bool i) {
isDefaultMissConst = i;
}
void setTcMayOverride(bool i) {
isTcMayOverride = i;
}
void addAction(TCAction action, unsigned flag) {
actionList.emplace(action, flag);
}
Expand Down Expand Up @@ -265,6 +269,7 @@ class TCTable {
defaultMissAction = nullptr;
isDefaultHitConst = false;
isDefaultMissConst = false;
isTcMayOverride = false;
}
toString {
std::string tcTable = "";
Expand Down Expand Up @@ -309,9 +314,12 @@ class TCTable {
tcTable += " permissions 0x1024";
}
tcTable += " action " + defaultMissAction->getName();
for (auto param : defaultMissActionParams) {
if (!defaultMissActionParams.empty())
tcTable += " param";
for (auto param : defaultMissActionParams)
tcTable += param->toString();
}
if (isTcMayOverride)
tcTable += " flags runtime";
}
if (const_entries.size() != 0) {
for (auto entry : const_entries) {
Expand Down
5 changes: 3 additions & 2 deletions backends/tc/tcAnnotations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ and limitations under the License.

namespace TC {

const cstring ParseTCAnnotations::default_hit = "default_hit";
const cstring ParseTCAnnotations::default_hit_const = "default_hit_const";
const cstring ParseTCAnnotations::defaultHit = "default_hit";
const cstring ParseTCAnnotations::defaultHitConst = "default_hit_const";
const cstring ParseTCAnnotations::tcType = "tc_type";
const cstring ParseTCAnnotations::numMask = "nummask";
const cstring ParseTCAnnotations::tcMayOverride = "tc_may_override";

} // namespace TC
14 changes: 8 additions & 6 deletions backends/tc/tcAnnotations.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ namespace TC {
class ParseTCAnnotations : public P4::ParseAnnotations {
public:
// TC specific annotations
static const cstring default_hit;
static const cstring default_hit_const;
static const cstring defaultHit;
static const cstring defaultHitConst;
static const cstring tcType;
static const cstring numMask;
static const cstring tcMayOverride;
ParseTCAnnotations()
: P4::ParseAnnotations("TC", true,
{PARSE_EMPTY(default_hit), PARSE_EMPTY(default_hit_const),
PARSE_CONSTANT_OR_STRING_LITERAL(tcType),
PARSE_CONSTANT_OR_STRING_LITERAL(numMask)}) {}
: P4::ParseAnnotations(
"TC", true,
{PARSE_EMPTY(defaultHit), PARSE_EMPTY(defaultHitConst),
PARSE_CONSTANT_OR_STRING_LITERAL(tcType), PARSE_CONSTANT_OR_STRING_LITERAL(numMask),
PARSE_EMPTY(tcMayOverride)}) {}
};

} // namespace TC
Expand Down
134 changes: 134 additions & 0 deletions testdata/p4tc_samples/tc_may_override_example_01.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#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;
}
@tc_may_override default_action = next_hop((PortId_t)123);
}
table ipv4_tbl_2 {
key = {
hdr.ipv4.dstAddr : exact;
hdr.ipv4.srcAddr : exact;
hdr.ipv4.protocol : exact;
}
actions = {
next_hop;
drop;
}
default_action = drop;
}

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
113 changes: 113 additions & 0 deletions testdata/p4tc_samples_outputs/tc_may_override_example_01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"schema_version" : "1.0.0",
"pipeline_name" : "tc_may_override_example_01",
"tables" : [
{
"name" : "MainControlImpl/ipv4_tbl_1",
"id" : 1,
"tentries" : 2048,
"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" : true
},
{
"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,
"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
}
],
"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" : 3,
"name" : "MainControlImpl/drop",
"action_scope" : "TableAndDefault",
"annotations" : [],
"params" : [],
"default_hit_action" : false,
"default_miss_action" : true
}
]
}
]
}
Empty file.
Loading

0 comments on commit 5af3014

Please sign in to comment.