diff --git a/p4_pdpi/BUILD.bazel b/p4_pdpi/BUILD.bazel index 2502a24c..40ac8b86 100644 --- a/p4_pdpi/BUILD.bazel +++ b/p4_pdpi/BUILD.bazel @@ -201,7 +201,6 @@ cc_library( "//gutil:proto", "//gutil:status", "//p4_pdpi/utils:ir", - "@com_github_google_glog//:glog", "@com_github_grpc_grpc//:grpc++", "@com_github_p4lang_p4runtime//:p4info_cc_proto", "@com_github_p4lang_p4runtime//:p4runtime_cc_proto", diff --git a/p4_pdpi/ir.cc b/p4_pdpi/ir.cc index 969a5307..8e1379c3 100644 --- a/p4_pdpi/ir.cc +++ b/p4_pdpi/ir.cc @@ -17,7 +17,6 @@ #include #include -#include #include #include @@ -35,7 +34,7 @@ #include "absl/strings/strip.h" #include "google/protobuf/any.pb.h" #include "google/protobuf/map.h" -#include "google/protobuf/repeated_field.h" +#include "google/protobuf/message.h" #include "google/rpc/code.pb.h" #include "google/rpc/status.pb.h" #include "gutil/collections.h" @@ -194,11 +193,42 @@ absl::Status ValidateMatchFieldDefinition(const IrMatchFieldDefinition &match) { } } +absl::StatusOr TableAliasToId(const p4::config::v1::P4Info &p4_info, + absl::string_view table_alias) { + absl::flat_hash_map table_alias_to_table_id; + for (const p4::config::v1::Table &table : p4_info.tables()) { + if (table.preamble().alias() == table_alias) { + return table.preamble().id(); + } + } + return absl::NotFoundError( + absl::StrCat("Can't find table id for alias `", table_alias, "`")); +} + +absl::StatusOr MatchFieldNameToId( + const p4::config::v1::P4Info &p4_info, uint32_t table_id, + absl::string_view match_field_name) { + for (const p4::config::v1::Table &table : p4_info.tables()) { + if (table.preamble().id() != table_id) { + continue; + } + for (const p4::config::v1::MatchField &match_field : table.match_fields()) { + if (match_field.name() == match_field_name) { + return match_field.id(); + } + } + } + return absl::NotFoundError( + absl::StrCat("Can't find match field id for match field name `", + match_field_name, "` in table `", table_id, "`")); +} + // Returns the set of references for a given set of annotations. Does not // validate the table or match field yet. absl::StatusOr> GetRefersToAnnotations( + const p4::config::v1::P4Info &p4info, const ::google::protobuf::RepeatedPtrField &annotations) { - static constexpr char kError[] = "Found invalid @refers_to annotation: "; + constexpr absl::string_view kError = "Found invalid @refers_to annotation: "; std::vector result; for (absl::string_view annotation_contents : annotations) { if (absl::ConsumePrefix(&annotation_contents, "@refers_to(")) { @@ -211,11 +241,19 @@ absl::StatusOr> GetRefersToAnnotations( << kError << "Incorrect number of arguments, required 2 but got " << parts.size() << " instead."; } + absl::string_view table = absl::StripAsciiWhitespace(parts[0]); absl::string_view match_field = absl::StripAsciiWhitespace(parts[1]); + + ASSIGN_OR_RETURN(uint32_t table_id, TableAliasToId(p4info, table)); + ASSIGN_OR_RETURN(uint32_t match_field_id, + MatchFieldNameToId(p4info, table_id, match_field)); + IrMatchFieldReference reference; reference.set_table(std::string(table)); reference.set_match_field(std::string(match_field)); + reference.set_table_id(table_id); + reference.set_match_field_id(match_field_id); result.push_back(reference); } } @@ -1125,7 +1163,6 @@ StatusOr CreateIrP4Info(const p4::config::v1::P4Info &p4_info) { const P4TypeInfo &type_info = p4_info.type_info(); // Translate all action definitions to IR. - absl::flat_hash_set> seen_references; for (const auto &action : p4_info.actions()) { IrActionDefinition ir_action; *ir_action.mutable_preamble() = action.preamble(); @@ -1135,12 +1172,19 @@ StatusOr CreateIrP4Info(const p4::config::v1::P4Info &p4_info) { ASSIGN_OR_RETURN(const auto format, GetFormatForP4InfoElement(param, type_info)); ir_param.set_format(format); - ASSIGN_OR_RETURN(const auto references, - GetRefersToAnnotations(ir_param.param().annotations())); - for (const auto &reference : references) { + ASSIGN_OR_RETURN( + const std::vector references, + GetRefersToAnnotations(p4_info, ir_param.param().annotations())); + for (const IrMatchFieldReference &reference : references) { *ir_param.add_references() = reference; - if (seen_references.insert({reference.table(), reference.match_field()}) - .second) { + // If an identical reference already exists, don't add it to the global + // list of references. + if (!absl::c_any_of( + info.references(), + [&reference](const IrMatchFieldReference &existing_reference) { + return google::protobuf::util::MessageDifferencer::Equals( + reference, existing_reference); + })) { *info.add_references() = reference; } } @@ -1195,12 +1239,18 @@ StatusOr CreateIrP4Info(const p4::config::v1::P4Info &p4_info) { ir_match_definition.set_format(format); RETURN_IF_ERROR(ValidateMatchFieldDefinition(ir_match_definition)) << "Table " << table.preamble().alias() << " has invalid match field"; - ASSIGN_OR_RETURN(const auto &references, - GetRefersToAnnotations(match_field.annotations())); + + ASSIGN_OR_RETURN( + const auto &references, + GetRefersToAnnotations(p4_info, match_field.annotations())); for (const auto &reference : references) { *ir_match_definition.add_references() = reference; - if (seen_references.insert({reference.table(), reference.match_field()}) - .second) { + if (!absl::c_any_of( + info.references(), + [&reference](const IrMatchFieldReference &existing_reference) { + return google::protobuf::util::MessageDifferencer::Equals( + reference, existing_reference); + })) { *info.add_references() = reference; } } diff --git a/p4_pdpi/ir.proto b/p4_pdpi/ir.proto index a9f46e8e..f772c92a 100644 --- a/p4_pdpi/ir.proto +++ b/p4_pdpi/ir.proto @@ -49,6 +49,8 @@ enum Format { message IrMatchFieldReference { string table = 1; string match_field = 2; + uint32 table_id = 3; + uint32 match_field_id = 4; } // Describes a match field. diff --git a/p4_pdpi/p4_runtime_session_extras.cc b/p4_pdpi/p4_runtime_session_extras.cc index 19121542..9137018a 100644 --- a/p4_pdpi/p4_runtime_session_extras.cc +++ b/p4_pdpi/p4_runtime_session_extras.cc @@ -77,6 +77,14 @@ absl::Status InstallPiEntities(P4RuntimeSession& p4rt, return absl::OkStatus(); } +absl::Status InstallPiEntities(P4RuntimeSession& p4rt, + absl::Span entities) { + for (const p4::v1::Entity& entity : entities) { + RETURN_IF_ERROR(InstallPiEntity(&p4rt, entity)); + } + return absl::OkStatus(); +} + absl::Status InstallPiEntities(P4RuntimeSession& p4rt, absl::string_view entities) { ASSIGN_OR_RETURN(auto parsed_entities, diff --git a/p4_pdpi/p4_runtime_session_extras.h b/p4_pdpi/p4_runtime_session_extras.h index f2c5f658..715882ae 100644 --- a/p4_pdpi/p4_runtime_session_extras.h +++ b/p4_pdpi/p4_runtime_session_extras.h @@ -84,6 +84,8 @@ absl::Status InstallIrTableEntry(P4RuntimeSession& p4rt, // Installs the given `entities` via the given `P4RuntimeSession`. absl::Status InstallPiEntities(P4RuntimeSession& p4rt, const PiEntities& entities); +absl::Status InstallPiEntities(P4RuntimeSession& p4rt, + absl::Span entities); // Like the `InstallPiEntities` above, but takes in the `PiEntities` message in // text format. diff --git a/p4_pdpi/packetlib/packetlib.proto b/p4_pdpi/packetlib/packetlib.proto index 7361a3d4..0aa7b508 100644 --- a/p4_pdpi/packetlib/packetlib.proto +++ b/p4_pdpi/packetlib/packetlib.proto @@ -34,6 +34,11 @@ message Packet { repeated string reasons_invalid = 4; } +// Multiple packets. +message Packets { + repeated Packet packets = 1; +} + // Describes a network packet header. This is not an exhaustive list of headers, // and not every header may support all fields available for that particular // header (e.g. optional fields may not be supported). diff --git a/p4_pdpi/testing/testdata/info.expected b/p4_pdpi/testing/testdata/info.expected index 6b1d010a..364b3c36 100644 --- a/p4_pdpi/testing/testdata/info.expected +++ b/p4_pdpi/testing/testdata/info.expected @@ -600,6 +600,10 @@ tables { id: 16777221 annotations: "@proto_id(1)" } + action_refs { + id: 16777217 + annotations: "@proto_id(2)" + } action_refs { id: 21257015 annotations: "@defaultonly" @@ -3128,6 +3132,60 @@ tables_by_id { } proto_id: 1 } + entry_actions { + ref { + id: 16777217 + annotations: "@proto_id(2)" + } + action { + preamble { + id: 16777217 + name: "do_thing_1" + alias: "do_thing_1" + } + params_by_id { + key: 1 + value { + param { + id: 1 + name: "arg2" + bitwidth: 32 + } + } + } + params_by_id { + key: 2 + value { + param { + id: 2 + name: "arg1" + bitwidth: 32 + } + } + } + params_by_name { + key: "arg1" + value { + param { + id: 2 + name: "arg1" + bitwidth: 32 + } + } + } + params_by_name { + key: "arg2" + value { + param { + id: 1 + name: "arg2" + bitwidth: 32 + } + } + } + } + proto_id: 2 + } default_only_actions { ref { id: 21257015 @@ -3178,6 +3236,8 @@ tables_by_id { references { table: "referring_by_match_field_table" match_field: "referring_id_1" + table_id: 49592401 + match_field_id: 1 } } } @@ -3197,6 +3257,8 @@ tables_by_id { references { table: "referring_by_match_field_table" match_field: "referring_id_1" + table_id: 49592401 + match_field_id: 1 } } } @@ -3329,6 +3391,8 @@ tables_by_id { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } } } @@ -3451,6 +3515,8 @@ tables_by_id { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } } } @@ -3773,6 +3839,8 @@ tables_by_id { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -3791,6 +3859,8 @@ tables_by_id { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -3809,6 +3879,8 @@ tables_by_id { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -3827,6 +3899,8 @@ tables_by_id { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -3860,10 +3934,14 @@ tables_by_id { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -3883,10 +3961,14 @@ tables_by_id { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -3943,6 +4025,8 @@ tables_by_id { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -3962,6 +4046,8 @@ tables_by_id { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -3981,6 +4067,8 @@ tables_by_id { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -4000,6 +4088,8 @@ tables_by_id { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -4214,6 +4304,8 @@ tables_by_name { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } } } @@ -4336,6 +4428,8 @@ tables_by_name { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } } } @@ -5627,6 +5721,8 @@ tables_by_name { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -5645,6 +5741,8 @@ tables_by_name { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -5663,6 +5761,8 @@ tables_by_name { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -5681,6 +5781,8 @@ tables_by_name { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -5714,10 +5816,14 @@ tables_by_name { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -5737,10 +5843,14 @@ tables_by_name { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -5797,6 +5907,8 @@ tables_by_name { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -5816,6 +5928,8 @@ tables_by_name { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -5835,6 +5949,8 @@ tables_by_name { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -5854,6 +5970,8 @@ tables_by_name { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -5922,6 +6040,8 @@ tables_by_name { references { table: "referring_by_match_field_table" match_field: "referring_id_1" + table_id: 49592401 + match_field_id: 1 } } } @@ -5941,6 +6061,8 @@ tables_by_name { references { table: "referring_by_match_field_table" match_field: "referring_id_1" + table_id: 49592401 + match_field_id: 1 } } } @@ -6351,6 +6473,60 @@ tables_by_name { } proto_id: 1 } + entry_actions { + ref { + id: 16777217 + annotations: "@proto_id(2)" + } + action { + preamble { + id: 16777217 + name: "do_thing_1" + alias: "do_thing_1" + } + params_by_id { + key: 1 + value { + param { + id: 1 + name: "arg2" + bitwidth: 32 + } + } + } + params_by_id { + key: 2 + value { + param { + id: 2 + name: "arg1" + bitwidth: 32 + } + } + } + params_by_name { + key: "arg1" + value { + param { + id: 2 + name: "arg1" + bitwidth: 32 + } + } + } + params_by_name { + key: "arg2" + value { + param { + id: 1 + name: "arg2" + bitwidth: 32 + } + } + } + } + proto_id: 2 + } default_only_actions { ref { id: 21257015 @@ -7131,6 +7307,8 @@ actions_by_id { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -7149,6 +7327,8 @@ actions_by_id { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -7167,6 +7347,8 @@ actions_by_id { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -7185,6 +7367,8 @@ actions_by_id { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -7214,10 +7398,14 @@ actions_by_id { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -7237,10 +7425,14 @@ actions_by_id { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -7549,10 +7741,14 @@ actions_by_name { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -7572,10 +7768,14 @@ actions_by_name { references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -7604,6 +7804,8 @@ actions_by_name { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -7622,6 +7824,8 @@ actions_by_name { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -7640,6 +7844,8 @@ actions_by_name { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } } } @@ -7658,6 +7864,8 @@ actions_by_name { references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } } } @@ -7818,18 +8026,26 @@ packet_out_metadata_by_name { references { table: "two_match_fields_table" match_field: "id_1" + table_id: 34805412 + match_field_id: 1 } references { table: "two_match_fields_table" match_field: "id_2" + table_id: 34805412 + match_field_id: 2 } references { table: "one_match_field_table" match_field: "id" + table_id: 46253494 + match_field_id: 1 } references { table: "referring_by_match_field_table" match_field: "referring_id_1" + table_id: 49592401 + match_field_id: 1 } action_profiles_by_id { key: 290772822 diff --git a/p4_pdpi/testing/testdata/main.p4 b/p4_pdpi/testing/testdata/main.p4 index fa14fa4c..86b406ee 100644 --- a/p4_pdpi/testing/testdata/main.p4 +++ b/p4_pdpi/testing/testdata/main.p4 @@ -253,6 +253,7 @@ control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_ } actions = { @proto_id(1) do_thing_4; + @proto_id(2) do_thing_1; @defaultonly NoAction(); } const default_action = NoAction(); diff --git a/p4_pdpi/testing/testdata/main_p4_pd.expected b/p4_pdpi/testing/testdata/main_p4_pd.expected index 179064f4..3074f0f0 100644 --- a/p4_pdpi/testing/testdata/main_p4_pd.expected +++ b/p4_pdpi/testing/testdata/main_p4_pd.expected @@ -251,8 +251,11 @@ message TwoMatchFieldsTableEntry { } Match match = 1; message Action { + oneof action { + DoThing1Action do_thing_1 = 2; DoThing4Action do_thing_4 = 1; } + } Action action = 2; bytes controller_metadata = 8; } diff --git a/p4_pdpi/testing/testdata/sequencing_util.expected b/p4_pdpi/testing/testdata/sequencing_util.expected index da1071a7..68c7e0b7 100644 --- a/p4_pdpi/testing/testdata/sequencing_util.expected +++ b/p4_pdpi/testing/testdata/sequencing_util.expected @@ -5,12 +5,20 @@ CreateReferenceRelationsTest -- IrP4Info's references -- table: "two_match_fields_table" match_field: "id_1" +table_id: 34805412 +match_field_id: 1 table: "two_match_fields_table" match_field: "id_2" +table_id: 34805412 +match_field_id: 2 table: "one_match_field_table" match_field: "id" +table_id: 46253494 +match_field_id: 1 table: "referring_by_match_field_table" match_field: "referring_id_1" +table_id: 49592401 +match_field_id: 1 -- OUTPUT ---------------------------------------------------------------------- -- ReferenceRelations --