Skip to content

Commit

Permalink
Add functions to get name from IrTable and IrField.Add commonly-neede…
Browse files Browse the repository at this point in the history
…d convenience functions to get IrP4Info/install entities.Add function declaration for `PiPacketReplicationEngineEntryToIr` to header file.Add missing declaration to header for `IrPacketReplicationEngineEntryToPi` (sonic-net#471)

Co-authored-by: Srikishen Pondicherry Shanmugam <[email protected]>
  • Loading branch information
VSuryaprasad-HCL and kishanps authored Aug 14, 2024
1 parent 1f88357 commit 843c3c3
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 26 deletions.
3 changes: 3 additions & 0 deletions p4_pdpi/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ cc_library(
":built_ins",
":ir_cc_proto",
"//gutil:collections",
"//gutil:proto",
"//gutil:status",
"//p4_pdpi/internal:ordered_map",
"//p4_pdpi/utils:annotation_parser",
Expand All @@ -67,6 +68,7 @@ cc_library(
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:string_view",
"@com_google_protobuf//:protobuf",
],
Expand Down Expand Up @@ -431,6 +433,7 @@ cc_library(
":pd",
"//gutil:proto",
"//gutil:status",
"@com_github_p4lang_p4runtime//:p4info_cc_proto",
"@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
"@com_google_absl//absl/algorithm:container",
"@com_google_absl//absl/status",
Expand Down
10 changes: 10 additions & 0 deletions p4_pdpi/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ absl::StatusOr<IrTableEntries> PiTableEntriesToIr(
const IrP4Info& info, absl::Span<const p4::v1::TableEntry> pi,
TranslationOptions options PDPI_TRANSLATION_OPTIONS_DEFAULT);

absl::StatusOr<IrPacketReplicationEngineEntry>
PiPacketReplicationEngineEntryToIr(
const IrP4Info& info, const p4::v1::PacketReplicationEngineEntry& pi,
TranslationOptions options PDPI_TRANSLATION_OPTIONS_DEFAULT);

absl::StatusOr<IrMulticastGroupEntry> PiMulticastGroupEntryToIr(
const IrP4Info& info, const p4::v1::MulticastGroupEntry& pi,
TranslationOptions options PDPI_TRANSLATION_OPTIONS_DEFAULT);
Expand Down Expand Up @@ -103,6 +108,11 @@ absl::StatusOr<std::vector<p4::v1::TableEntry>> IrTableEntriesToPi(
const IrP4Info& info, absl::Span<const IrTableEntry> ir,
TranslationOptions options PDPI_TRANSLATION_OPTIONS_DEFAULT);

absl::StatusOr<p4::v1::PacketReplicationEngineEntry>
IrPacketReplicationEngineEntryToPi(
const IrP4Info& info, const IrPacketReplicationEngineEntry& ir,
TranslationOptions options PDPI_TRANSLATION_OPTIONS_DEFAULT);

absl::StatusOr<p4::v1::MulticastGroupEntry> IrMulticastGroupEntryToPi(
const IrP4Info& info, const IrMulticastGroupEntry& ir,
TranslationOptions options PDPI_TRANSLATION_OPTIONS_DEFAULT);
Expand Down
70 changes: 46 additions & 24 deletions p4_pdpi/p4_runtime_session_extras.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,9 @@ namespace pdpi {
absl::Status InstallPdTableEntries(
P4RuntimeSession& p4rt, const google::protobuf::Message& pd_table_entries) {
// Convert entries to PI representation.
ASSIGN_OR_RETURN(p4::v1::GetForwardingPipelineConfigResponse config,
GetForwardingPipelineConfig(&p4rt));
if (gutil::IsEmptyProto(config.config().p4info())) {
return gutil::FailedPreconditionErrorBuilder()
<< "cannot install entries on switch since no P4Info has been "
"installed";
}
ASSIGN_OR_RETURN(IrP4Info info, CreateIrP4Info(config.config().p4info()));
ASSIGN_OR_RETURN(IrP4Info info, GetIrP4Info(p4rt),
_.SetPrepend() << "cannot install entries on switch: failed "
"to pull P4Info from switch: ");
ASSIGN_OR_RETURN(
std::vector<p4::v1::Entity> pi_entities,
PdTableEntriesToPiEntities(info, pd_table_entries),
Expand All @@ -51,6 +46,7 @@ absl::Status InstallPdTableEntry(
"installed";
}
ASSIGN_OR_RETURN(IrP4Info info, CreateIrP4Info(config.config().p4info()));
// Convert entry to PI representation.
ASSIGN_OR_RETURN(
p4::v1::Entity pi_entity, PdTableEntryToPiEntity(info, pd_table_entry),
_.SetPrepend()
Expand All @@ -63,9 +59,9 @@ absl::Status InstallPdTableEntry(
absl::Status InstallIrTableEntries(P4RuntimeSession& p4rt,
const IrTableEntries& ir_table_entries) {
// Get P4Info from switch.
ASSIGN_OR_RETURN(p4::v1::GetForwardingPipelineConfigResponse config,
GetForwardingPipelineConfig(&p4rt));
ASSIGN_OR_RETURN(IrP4Info info, CreateIrP4Info(config.config().p4info()));
ASSIGN_OR_RETURN(IrP4Info info, GetIrP4Info(p4rt),
_.SetPrepend() << "cannot install entries on switch: failed "
"to pull P4Info from switch: ");

// Convert entries to PI representation.
ASSIGN_OR_RETURN(std::vector<p4::v1::TableEntry> pi_entries,
Expand All @@ -75,12 +71,27 @@ absl::Status InstallIrTableEntries(P4RuntimeSession& p4rt,
return InstallPiTableEntries(&p4rt, info, pi_entries);
}

absl::Status InstallIrEntities(P4RuntimeSession& p4rt,
const IrEntities& ir_entities) {
// Get P4Info from switch.
ASSIGN_OR_RETURN(IrP4Info info, GetIrP4Info(p4rt),
_.SetPrepend() << "cannot install entries on switch: failed "
"to pull P4Info from switch: ");

// Convert entries to PI representation.
ASSIGN_OR_RETURN(std::vector<p4::v1::Entity> pi_entities,
IrEntitiesToPi(info, ir_entities));

// Install entries.
return InstallPiEntities(&p4rt, info, pi_entities);
}

absl::Status InstallIrTableEntry(P4RuntimeSession& p4rt,
const IrTableEntry& ir_table_entry) {
// Get P4Info from switch.
ASSIGN_OR_RETURN(p4::v1::GetForwardingPipelineConfigResponse config,
GetForwardingPipelineConfig(&p4rt));
ASSIGN_OR_RETURN(IrP4Info info, CreateIrP4Info(config.config().p4info()));
ASSIGN_OR_RETURN(IrP4Info info, GetIrP4Info(p4rt),
_.SetPrepend() << "cannot install entries on switch: failed "
"to pull P4Info from switch: ");

// Convert entry to PI representation.
ASSIGN_OR_RETURN(p4::v1::TableEntry pi_entry,
Expand Down Expand Up @@ -128,26 +139,24 @@ absl::StatusOr<std::vector<p4::v1::TableEntry>> ReadPiTableEntriesSorted(
}

absl::StatusOr<IrTableEntries> ReadIrTableEntries(P4RuntimeSession& p4rt) {
ASSIGN_OR_RETURN(p4::v1::GetForwardingPipelineConfigResponse response,
GetForwardingPipelineConfig(&p4rt));
ASSIGN_OR_RETURN(IrP4Info ir_info,
CreateIrP4Info(response.config().p4info()));
ASSIGN_OR_RETURN(IrP4Info info, GetIrP4Info(p4rt),
_.SetPrepend() << "cannot install entries on switch: failed "
"to pull P4Info from switch: ");

ASSIGN_OR_RETURN(std::vector<p4::v1::TableEntry> entries,
ReadPiTableEntries(&p4rt));
return PiTableEntriesToIr(ir_info, entries);
return PiTableEntriesToIr(info, entries);
}

absl::StatusOr<IrTableEntries> ReadIrTableEntriesSorted(
P4RuntimeSession& p4rt) {
ASSIGN_OR_RETURN(p4::v1::GetForwardingPipelineConfigResponse response,
GetForwardingPipelineConfig(&p4rt));
ASSIGN_OR_RETURN(IrP4Info ir_info,
CreateIrP4Info(response.config().p4info()));
ASSIGN_OR_RETURN(IrP4Info info, GetIrP4Info(p4rt),
_.SetPrepend() << "cannot install entries on switch: failed "
"to pull P4Info from switch: ");

ASSIGN_OR_RETURN(std::vector<p4::v1::TableEntry> entries,
ReadPiTableEntriesSorted(p4rt));
return PiTableEntriesToIr(ir_info, entries);
return PiTableEntriesToIr(info, entries);
}

absl::StatusOr<IrWriteRpcStatus> SendPiUpdatesAndReturnPerUpdateStatus(
Expand All @@ -169,5 +178,18 @@ absl::StatusOr<IrWriteRpcStatus> SendPiUpdatesAndReturnPerUpdateStatus(
return SendPiUpdatesAndReturnPerUpdateStatus(
p4rt, std::vector<p4::v1::Update>(updates.begin(), updates.end()));
}
absl::StatusOr<p4::config::v1::P4Info> GetP4Info(P4RuntimeSession& p4rt) {
ASSIGN_OR_RETURN(auto response, GetForwardingPipelineConfig(&p4rt));
if (gutil::IsEmptyProto(response.config().p4info())) {
return gutil::FailedPreconditionErrorBuilder()
<< "no P4Info configured on switch";
}
return response.config().p4info();
}

absl::StatusOr<IrP4Info> GetIrP4Info(P4RuntimeSession& p4rt) {
ASSIGN_OR_RETURN(p4::config::v1::P4Info p4info, GetP4Info(p4rt));
return CreateIrP4Info(p4info);
}

} // namespace pdpi
17 changes: 15 additions & 2 deletions p4_pdpi/p4_runtime_session_extras.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// =============================================================================
// Convenience functions to simplify working with `P4RuntimeSession`.
//
// These functions are in a separate file since they pull in additional
// dependencies that some users may wish to avoid.
//
// NOTE: Like `P4RuntimeSession` itself, these function are optimized for
// NOTE: Like `P4RuntimeSession` itself, these function are optimized for
// convenience, not for performance. They are intended for use in testing &
// experimentation, not for use in production.

Expand All @@ -27,12 +27,14 @@
#include <vector>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "google/protobuf/message.h"
#include "google/protobuf/repeated_field.h"
#include "gutil/proto.h"
#include "gutil/status.h"
#include "p4/config/v1/p4info.pb.h"
#include "p4/v1/p4runtime.pb.h"
#include "p4_pdpi/ir.pb.h"
#include "p4_pdpi/p4_runtime_session.h"
Expand Down Expand Up @@ -76,6 +78,8 @@ absl::Status InstallPdTableEntry(P4RuntimeSession& p4rt,
// in translation from the switch.
absl::Status InstallIrTableEntries(P4RuntimeSession& p4rt,
const IrTableEntries& ir_table_entries);
absl::Status InstallIrEntities(P4RuntimeSession& p4rt,
const IrEntities& ir_entities);

// Like `InstallIrTableEntries`, but for a single entry.
absl::Status InstallIrTableEntry(P4RuntimeSession& p4rt,
Expand Down Expand Up @@ -116,6 +120,15 @@ absl::StatusOr<IrWriteRpcStatus> SendPiUpdatesAndReturnPerUpdateStatus(
P4RuntimeSession& p4rt,
const google::protobuf::RepeatedPtrField<p4::v1::Update>& updates);

// Reads the P4Info currently configured on the switch and returns it, or
// returns an error if no P4Info is configured.
absl::StatusOr<p4::config::v1::P4Info> GetP4Info(P4RuntimeSession& p4rt);

// Reads the P4Info currently configured on the switch, converts it to IR
// format, and returns it, or returns an error if no P4Info is configured or the
// conversion fails.
absl::StatusOr<IrP4Info> GetIrP4Info(P4RuntimeSession& p4rt);

// == END OF PUBLIC INTERFACE ==================================================

// -- Internal implementation details follow -----------------------------------
Expand Down
65 changes: 65 additions & 0 deletions p4_pdpi/reference_annotations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/repeated_ptr_field.h"
#include "gutil/collections.h"
Expand Down Expand Up @@ -135,6 +136,70 @@ absl::StatusOr<IrActionField> CreateIrActionField(absl::string_view action_name,
return field;
}

absl::StatusOr<std::string> GetNameOfTable(const IrTable &table) {
switch (table.table_case()) {
case IrTable::kP4Table: {
return table.p4_table().table_name();
}
case IrTable::kBuiltInTable: {
return IrBuiltInTableToString(table.built_in_table());
}
case IrTable::TABLE_NOT_SET: {
return gutil::InvalidArgumentErrorBuilder()
<< "IrTable table oneof not set.";
}
}
}

absl::StatusOr<std::string> GetNameOfField(const IrField &field) {
switch (field.field_case()) {
case IrField::kMatchField: {
return field.match_field().field_name();
}
case IrField::kActionField: {
return absl::StrCat(field.action_field().action_name(), ".",
field.action_field().parameter_name());
}
case IrField::kBuiltInField: {
return IrBuiltInFieldToString(field.built_in_field());
}
case IrField::FIELD_NOT_SET: {
return gutil::InvalidArgumentErrorBuilder()
<< "IrField field oneof not set.";
}
}
}

absl::StatusOr<std::string> GetNameOfAction(const IrField &field) {
switch (field.field_case()) {
case IrField::kActionField: {
return field.action_field().action_name();
}
case IrField::kBuiltInField: {
switch (field.built_in_field()) {
case IrBuiltInField::BUILT_IN_FIELD_REPLICA_INSTANCE:
case IrBuiltInField::BUILT_IN_FIELD_REPLICA_PORT:
return "replica";
default:
return gutil::InvalidArgumentErrorBuilder()
<< "Built-in field '"
<< IrBuiltInField_Name(field.built_in_field())
<< "' is not considered an action field";
}
}
case IrField::kMatchField: {
return gutil::InvalidArgumentErrorBuilder()
<< "Match fields are not part of an action. Provided IrField "
"contained a match field: "
<< field.match_field().DebugString();
}
case IrField::FIELD_NOT_SET: {
return gutil::InvalidArgumentErrorBuilder()
<< "IrField field oneof not set.";
}
}
}

absl::StatusOr<std::vector<ParsedRefersToAnnotation>>
ParseAllRefersToAnnotations(const RepeatedPtrField<std::string> &annotations) {
return GetAllParsedAnnotations<ParsedRefersToAnnotation>(
Expand Down
28 changes: 28 additions & 0 deletions p4_pdpi/reference_annotations.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,34 @@ absl::StatusOr<IrActionField> CreateIrActionField(absl::string_view action_name,
absl::string_view param_name,
const IrP4Info &info);

// Returns string representation of `IrTable`. String uniquely identifies table
// within the scope of a p4 program. String representation differs based on
// type.
// `IrP4Table`: { table_name: "t" } -> "t"
// `IrBuiltInTable`: Translation provided by built_ins.h
// - BUILT_IN_TABLE_MULTICAST_GROUP_TABLE -> "builtin::multicast_group_table"
// Returns error if an unknown `IrBuiltInTable` is provided.
absl::StatusOr<std::string> GetNameOfTable(const IrTable &table);

// Returns string representation of `IrField`. String uniquely identifies field
// within the scope of a table entry. The string representation differs based on
// type.
// `IrMatchField`: { field_name: "m" } - > "m"
// `IrActionField`: {action_name: "a" parameter_name: "p"} -> "a.p"
// `IrBuiltInField`: Translation provided by built_ins.h
// - BUILT_IN_FIELD_REPLICA_INSTANCE -> "replica.instance"
// Returns error if an unknown `IrBuiltInField` is provided.
absl::StatusOr<std::string> GetNameOfField(const IrField &field);

// Returns string representation of action `IrField` belongs to. String
// uniquely identifies the action within the scope of a table entry. The string
// representation differs based on type.
// `IrMatchField`: Returns error
// `IrActionField`: {action_name: "a" parameter_name: "p"} -> "a"
// `IrBuiltInField`: refer to implementation details
// Returns error if an unknown or invalid `IrBuiltInField` is provided.
absl::StatusOr<std::string> GetNameOfAction(const IrField &field);

} // namespace pdpi

#endif // PINS_P4_PDPI_REFERENCE_ANNOTATIONS_H_
Loading

0 comments on commit 843c3c3

Please sign in to comment.