diff --git a/backends/dpdk/DPDK_context_schema.json b/backends/dpdk/DPDK_context_schema.json index 985e99b02d2..428a748ac7f 100644 --- a/backends/dpdk/DPDK_context_schema.json +++ b/backends/dpdk/DPDK_context_schema.json @@ -8,10 +8,6 @@ "type": "string", "description": "Name of the referenced table as in the P4 file." }, - "target_name": { - "type": "string", - "description": "Name of the referenced table as in the spec file." - }, "handle": { "type": "integer", "description": "Handle of the referenced table." @@ -30,10 +26,6 @@ "type": "string", "description": "Name of the action as in P4 file" }, - "target_name": { - "type": "string", - "description": "Name of the action as in spec file" - }, "action_handle": { "type": "integer", "description": "Unique reference handle to this action" @@ -111,6 +103,10 @@ "type": "string", "description": "Name of this table" }, + "target_name": { + "type": "string", + "description": "Name of the table as in the spec file." + }, "handle": { "type": "integer", "description": "Unique reference ID for this table" @@ -229,6 +225,10 @@ "type": "string", "description": "The P4 name of the action." }, + "target_name": { + "type": "string", + "description": "Name of the action as in spec file" + }, "handle": { "type": "integer", "description": "A unique identifier for this action." @@ -325,6 +325,10 @@ "type": "string", "description": "Name of this table" }, + "target_name": { + "type": "string", + "description": "Name of the table as in the spec file." + }, "handle": { "type": "integer", "description": "Unique reference ID for this table" @@ -378,6 +382,10 @@ "type": "string", "description": "Name of this table" }, + "target_name": { + "type": "string", + "description": "Name of the table as in the spec file." + }, "handle": { "type": "integer", "description": "Unique reference ID for this table" @@ -472,6 +480,50 @@ "actions" ], "additionalProperties": false + }, + "__main__.ExternAttributes": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of extern" + } + }, + "additionalProperties": false + }, + "__main__.Externs": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the extern as in the P4 file." + }, + "target_name": { + "type": "string", + "description": "Name of the extern as in the spec file." + }, + "extern_type": { + "type": "string", + "description": "Extern type", + "enum": [ + "Counter", + "Register", + "Meter", + "Hash", + "InternetChecksum" + ] + }, + "match_attributes": { + "$ref": "#/definitions/__main__.ExternAttributes" + } + }, + "required": [ + "name", + "target_name", + "extern_type", + "attributes" + ], + "additionalProperties": false } }, "type": "object", @@ -520,6 +572,13 @@ } ] } + }, + "externs": { + "type": "array", + "description": "List of externs in this P4 program", + "items": { + "$ref": "#/definitions/__main__.Externs" + } } }, "required": [ @@ -528,7 +587,8 @@ "compiler_version", "schema_version", "target", - "tables" + "tables", + "externs" ], "additionalProperties": false } diff --git a/backends/dpdk/dpdkContext.cpp b/backends/dpdk/dpdkContext.cpp index 8264cccea03..556ab7d5446 100644 --- a/backends/dpdk/dpdkContext.cpp +++ b/backends/dpdk/dpdkContext.cpp @@ -109,6 +109,45 @@ void DpdkContextGenerator::CollectTablesAndSetAttributes() { } } + for (auto ed : structure->externDecls) { + if (auto type = ed->type->to()) { + auto externTypeName = type->baseType->path->name.name; + if (externTypeName == "Counter" || + externTypeName == "Register" || + externTypeName == "Meter" || + externTypeName == "Hash" || + externTypeName == "InternetCheckSum") { + struct externAttributes externAttr; + externAttr.externalName = ed->controlPlaneName(); + externAttr.externType = externTypeName; + if (externTypeName == "Counter") { + if (ed->arguments->size() != 2) { + ::error(ErrorType::ERR_UNEXPECTED, + "%1%: expected 2 arguments, number of counters and type" + "of counter", ed); + } + auto counter_type = ed->arguments->at(1)->expression; + BUG_CHECK(counter_type->is(), + "Expected counter type to be constant"); + auto value = counter_type->to()->asUnsigned(); + switch (value) { + case 0: + externAttr.counterType = "packets"; + break; + case 1: + externAttr.counterType = "bytes"; + break; + case 2: + externAttr.counterType = "packets_and_bytes"; + break; + } + } + externAttrMap.emplace(ed->name.name, externAttr); + externs.push_back(ed); + } + } + } + // Keep the compiler generated (hidden) tables at the end for (auto d : selector_tables) tables.push_back(d); @@ -452,9 +491,27 @@ void DpdkContextGenerator::addMatchTables(Util::JsonArray* tablesJson) { } } +// Add extern information to the context json +void DpdkContextGenerator::addExternInfo(Util::JsonArray* externsJson) { + for (auto t : externs) { + auto externAttr = ::get(externAttrMap, t->name.name); + auto* externJson = new Util::JsonObject(); + externJson->emplace("name", externAttr.externalName); + externJson->emplace("target_name", t->name.name); + externJson->emplace("type", externAttr.externType); + auto* attrJson = new Util::JsonObject(); + if (externAttr.externType == "Counter") { + attrJson->emplace("type", externAttr.counterType); + } + externJson->emplace("attributes", attrJson); + externsJson->append(externJson); + } +} + const Util::JsonObject* DpdkContextGenerator::genContextJsonObject() { auto* json = new Util::JsonObject(); auto* tablesJson = new Util::JsonArray(); + auto* externsJson = new Util::JsonArray(); struct TopLevelCtxt tlinfo; tlinfo.initTopLevelCtxt(options); json->emplace("program_name", tlinfo.progName); @@ -465,6 +522,8 @@ const Util::JsonObject* DpdkContextGenerator::genContextJsonObject() { json->emplace("target", cstring("DPDK")); json->emplace("tables", tablesJson); addMatchTables(tablesJson); + json->emplace("externs", externsJson); + addExternInfo(externsJson); return json; } diff --git a/backends/dpdk/dpdkContext.h b/backends/dpdk/dpdkContext.h index 3719526540d..fd0e0a9abfe 100644 --- a/backends/dpdk/dpdkContext.h +++ b/backends/dpdk/dpdkContext.h @@ -66,6 +66,12 @@ struct actionAttributes { IR::IndexedVector *params; }; +struct externAttributes { + cstring externalName; + cstring externType; + cstring counterType; +}; + /* Program level information for context json */ struct TopLevelCtxt{ cstring progName; @@ -123,10 +129,12 @@ class DpdkContextGenerator : public Inspector { DpdkOptions &options; // All tables are collected into this vector IR::IndexedVector tables; + std::vector externs; - // Maps holding table and action attributes needed for context JSON + // Maps holding table, extern and action attributes needed for context JSON std::map tableAttrmap; std::map actionAttrMap; + std::map externAttrMap; // Running unique ID for tables and actions static unsigned newTableHandle; @@ -143,6 +151,7 @@ class DpdkContextGenerator : public Inspector { void serializeContextJson(std::ostream* destination); const Util::JsonObject* genContextJsonObject(); void addMatchTables(Util::JsonArray* tablesJson); + void addExternInfo(Util::JsonArray* externsJson); Util::JsonObject* initTableCommonJson(const cstring name, const struct TableAttributes & attr); void addKeyField(Util::JsonArray* keyJson, const cstring name, const cstring annon, const IR::KeyElement *key, int position);