Skip to content

Commit

Permalink
Add an additional action in test p4 program for testing purposes. [PD…
Browse files Browse the repository at this point in the history
…PI] Add InstallPiEntities overload that works with absl::Span. [packetlib] Add plural form Packets of Packet proto message. [IrP4Info] Adds Table Id in IrMatchFieldReference. (sonic-net#228)



* Add an additional action in test p4 program for testing purposes.[PDPI] Add InstallPiEntities overload that works with absl::Span.[packetlib] Add plural form `Packets` of `Packet` proto message.[IrP4Info] Adds Table Id in IrMatchFieldReference.

---------

Co-authored-by: smolkaj <[email protected]>
Co-authored-by: Srikishen Pondicherry Shanmugam <[email protected]>
  • Loading branch information
3 people authored Jun 24, 2024
1 parent 85dd958 commit 46819fb
Show file tree
Hide file tree
Showing 10 changed files with 308 additions and 14 deletions.
1 change: 0 additions & 1 deletion p4_pdpi/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
76 changes: 63 additions & 13 deletions p4_pdpi/ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <ctype.h>
#include <stdint.h>

#include <optional>
#include <string>
#include <vector>

Expand All @@ -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"
Expand Down Expand Up @@ -194,11 +193,42 @@ absl::Status ValidateMatchFieldDefinition(const IrMatchFieldDefinition &match) {
}
}

absl::StatusOr<uint32_t> TableAliasToId(const p4::config::v1::P4Info &p4_info,
absl::string_view table_alias) {
absl::flat_hash_map<std::string, uint32_t> 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<uint32_t> 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<std::vector<IrMatchFieldReference>> GetRefersToAnnotations(
const p4::config::v1::P4Info &p4info,
const ::google::protobuf::RepeatedPtrField<std::string> &annotations) {
static constexpr char kError[] = "Found invalid @refers_to annotation: ";
constexpr absl::string_view kError = "Found invalid @refers_to annotation: ";
std::vector<IrMatchFieldReference> result;
for (absl::string_view annotation_contents : annotations) {
if (absl::ConsumePrefix(&annotation_contents, "@refers_to(")) {
Expand All @@ -211,11 +241,19 @@ absl::StatusOr<std::vector<IrMatchFieldReference>> 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);
}
}
Expand Down Expand Up @@ -1125,7 +1163,6 @@ StatusOr<IrP4Info> 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<std::pair<std::string, std::string>> seen_references;
for (const auto &action : p4_info.actions()) {
IrActionDefinition ir_action;
*ir_action.mutable_preamble() = action.preamble();
Expand All @@ -1135,12 +1172,19 @@ StatusOr<IrP4Info> 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<IrMatchFieldReference> 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;
}
}
Expand Down Expand Up @@ -1195,12 +1239,18 @@ StatusOr<IrP4Info> 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;
}
}
Expand Down
2 changes: 2 additions & 0 deletions p4_pdpi/ir.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions p4_pdpi/p4_runtime_session_extras.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ absl::Status InstallPiEntities(P4RuntimeSession& p4rt,
return absl::OkStatus();
}

absl::Status InstallPiEntities(P4RuntimeSession& p4rt,
absl::Span<const p4::v1::Entity> 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,
Expand Down
2 changes: 2 additions & 0 deletions p4_pdpi/p4_runtime_session_extras.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<const p4::v1::Entity> entities);

// Like the `InstallPiEntities` above, but takes in the `PiEntities` message in
// text format.
Expand Down
5 changes: 5 additions & 0 deletions p4_pdpi/packetlib/packetlib.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
Loading

0 comments on commit 46819fb

Please sign in to comment.