// Copyright (c) 2016, Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // 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. syntax = "proto3"; import "google/protobuf/any.proto"; import "google/rpc/status.proto"; import "p4/config/v1/p4info.proto"; import "p4/v1/p4data.proto"; // This package and its contents are a work-in-progress. package p4.v1; option go_package = "github.com/p4lang/p4runtime/go/p4/v1"; option cc_enable_arenas = true; service P4Runtime { // Update one or more P4 entities on the target. rpc Write(WriteRequest) returns (WriteResponse) {} // Read one or more P4 entities from the target. rpc Read(ReadRequest) returns (stream ReadResponse) {} // Sets the P4 forwarding-pipeline config. rpc SetForwardingPipelineConfig(SetForwardingPipelineConfigRequest) returns (SetForwardingPipelineConfigResponse) {} // Gets the current P4 forwarding-pipeline config. rpc GetForwardingPipelineConfig(GetForwardingPipelineConfigRequest) returns (GetForwardingPipelineConfigResponse) {} // Represents the bidirectional stream between the controller and the // switch (initiated by the controller), and is managed for the following // purposes: // - connection initiation through client arbitration // - indicating switch session liveness: the session is live when switch // sends a positive client arbitration update to the controller, and is // considered dead when either the stream breaks or the switch sends a // negative update for client arbitration // - the controller sending/receiving packets to/from the switch // - streaming of notifications from the switch rpc StreamChannel(stream StreamMessageRequest) returns (stream StreamMessageResponse) {} rpc Capabilities(CapabilitiesRequest) returns (CapabilitiesResponse) {} } //------------------------------------------------------------------------------ message WriteRequest { uint64 device_id = 1; // Deprecated in v1.4.0 uint64 role_id = 2 [deprecated=true]; // Added in v1.4.0 string role = 6; Uint128 election_id = 3; // The write batch, comprising a list of Update operations. The P4Runtime // server may arbitrarily reorder messages within a batch to maximize // performance. repeated Update updates = 4; enum Atomicity { // Required. This is the default behavior. The batch is processed in a // non-atomic manner from a data plane point of view. Each operation within // the batch must be attempted even if one or more encounter errors. // Every data plane packet is guaranteed to be processed according to // table contents as they are between two individual operations of the // batch, but there could be several packets processed that see each of // these intermediate stages. CONTINUE_ON_ERROR = 0; // Optional. Operations within the batch are committed to data plane until // an error is encountered. At this point, the operations must be rolled // back such that both software and data plane state is consistent with the // state before the batch was attempted. The resulting behavior is // all-or-none, except the batch is not atomic from a data plane point of // view. Every data plane packet is guaranteed to be processed according to // table contents as they are between two individual operations of the // batch, but there could be several packets processed that see each of // these intermediate stages. ROLLBACK_ON_ERROR = 1; // Optional. Every data plane packet is guaranteed to be processed according // to table contents before the batch began, or after the batch completed // and the operations were programmed to the hardware. // The batch is therefore treated as a transaction. DATAPLANE_ATOMIC = 2; } Atomicity atomicity = 5; } message WriteResponse {} message ReadRequest { uint64 device_id = 1; // When specified, only return table entries for the given role. // Added in 1.4.0. string role = 3; repeated Entity entities = 2; } message ReadResponse { repeated Entity entities = 1; } message Update { enum Type { UNSPECIFIED = 0; INSERT = 1; MODIFY = 2; DELETE = 3; } Type type = 1; Entity entity = 2; } message Entity { oneof entity { ExternEntry extern_entry = 1; TableEntry table_entry = 2; ActionProfileMember action_profile_member = 3; ActionProfileGroup action_profile_group = 4; MeterEntry meter_entry = 5; DirectMeterEntry direct_meter_entry = 6; CounterEntry counter_entry = 7; DirectCounterEntry direct_counter_entry = 8; PacketReplicationEngineEntry packet_replication_engine_entry = 9; ValueSetEntry value_set_entry = 10; RegisterEntry register_entry = 11; DigestEntry digest_entry = 12; } } message ExternEntry { // the extern_type_id is unique for a given architecture and must be in the // range [0x81, 0xfe]. uint32 extern_type_id = 1; uint32 extern_id = 2; // id of the instance .google.protobuf.Any entry = 3; } message TableEntry { uint32 table_id = 1; repeated FieldMatch match = 2; TableAction action = 3; // Should only be set if the match implies a TCAM lookup, i.e. at least one of // the match fields is Optional, Ternary or Range. A higher number indicates // higher priority. Only a highest priority entry that matches the packet // must be selected. Multiple entries in the same table with the same // priority value are permitted. See Section "TableEntry" in the // specification for details of the behavior. int32 priority = 4; // Metadata (cookie) opaque to the target. There is no requirement of where // this is stored, as long as it is returned with the rest of the entry in // a Read RPC. This is deprecated in favor of the more flexible metadata // field. uint64 controller_metadata = 5 [deprecated = true]; // meter_config, counter_data and meter_counter_data are convenience fields // that enable the controller to configure the direct resources associated // with the table at the same time as a match-action entry is inserted or // modified. // Table write: // - If the table does not contain a direct resource, then setting the // corresponding direct resource field in any table write operation will // return an error. // - When inserting a new table entry, leaving these fields unset means that // the direct resources of this table (if any) will assume default values. // For counters, the default value is 0, and for meters, the default value // is always green. // - When updating a table entry, leaving meter_config unset will reset the // meter (if any) to its default configuration, while leaving counter_data // or meter_counter_data unset means that the counter (if any) will not be // updated. // Table read: // - If the table does not contain a direct resource, then the corresponding // field will not be set in the read table entry. // - If meter_config is unset in the request, or if the meter has a default // configuration, meter_config will not be set in the response. // - If counter_data or meter_counter_data is unset in the request, it will // be unset in the response as well. MeterConfig meter_config = 6; CounterData counter_data = 7; // Per color counters for tables with a direct meter. // Added in v1.4.0 MeterCounterData meter_counter_data = 12; // Set to true if the table entry is being used to update the non-const // default action of the table. If true, the "match" field must be empty and // the "action" field must be populated with a valid direct action. bool is_default_action = 8; // The TTL for the entry, in nanoseconds. A value of 0 means that the table // entry never "expires". int64 idle_timeout_ns = 9; message IdleTimeout { // Time elapsed - in nanoseconds - since the table entry was last "hit" as // part of a data plane table lookup. int64 elapsed_ns = 1; } // Table write: this field should be left unset. // Table read: if the table supports idle timeout and time_since_last_hit is // set in the request, this field will be set in the response. IdleTimeout time_since_last_hit = 10; // Arbitrary metadata from the controller that is opaque to the target. bytes metadata = 11; // True if and only if the entry cannot be deleted or modified, // i.e. any of the following: // + Any entry read from a table declared with `const entries` // + The default entry read from a table declared with `const // default_action` // + Any entry declared with `entries` without the `const` qualifier // before `entries`, where the individual entry has the `const` // qualifier on it in the P4 source code. // Note: Older P4Runtime API servers before the `is_const` field was // added to this message will not return a value for `is_const` in // the first two cases above, but newer P4Runtime API servers will. // Added in 1.4.0. bool is_const = 13; } // field_match_type ::= exact | ternary | lpm | range | optional message FieldMatch { uint32 field_id = 1; // Matches can be performed on arbitrarily-large inputs; the protobuf type // 'bytes' is used to model arbitrarily-large values. message Exact { bytes value = 1; } message Ternary { bytes value = 1; bytes mask = 2; } message LPM { bytes value = 1; int32 prefix_len = 2; // in bits } // A Range is logically a set that contains all values numerically between // 'low' and 'high' inclusively. message Range { bytes low = 1; bytes high = 2; } // If the Optional match should be a wildcard, the FieldMatch must be omitted. // Otherwise, this behaves like an exact match. message Optional { bytes value = 1; } oneof field_match_type { Exact exact = 2; Ternary ternary = 3; LPM lpm = 4; Range range = 6; Optional optional = 7; // Architecture-specific match value; it corresponds to the other_match_type // in the P4Info MatchField message. .google.protobuf.Any other = 100; } } // table_actions ::= action_specification | action_profile_specification message TableAction { oneof type { Action action = 1; uint32 action_profile_member_id = 2; uint32 action_profile_group_id = 3; ActionProfileActionSet action_profile_action_set = 4; } } message Action { uint32 action_id = 1; message Param { uint32 param_id = 2; bytes value = 3; } repeated Param params = 4; } message ActionProfileActionSet { repeated ActionProfileAction action_profile_actions = 1; } message ActionProfileAction { Action action = 1; int32 weight = 2; oneof watch_kind { // Using int32 as ports is deprecated, use watch_port instead. int32 watch = 3 [deprecated = true]; bytes watch_port = 4; } } //------------------------------------------------------------------------------ message ActionProfileMember { uint32 action_profile_id = 1; uint32 member_id = 2; Action action = 3; } //------------------------------------------------------------------------------ message ActionProfileGroup { uint32 action_profile_id = 1; uint32 group_id = 2; message Member { uint32 member_id = 1; int32 weight = 2; oneof watch_kind { // Using int32 as ports is deprecated, use watch_port instead. int32 watch = 3 [deprecated = true]; bytes watch_port = 4; } } repeated Member members = 3; // Max number of weighted member entries in this group. It cannot be modified // after a group has been created. It must not exceed the static // max_group_size included in P4Info. If the max size is not known at group // creation-time, the client may leave this field unset (default value 0), in // which case the static max_group_size value will be used and the group will // be able to include up to max_group_size weighted member entries. int32 max_size = 4; } // An index as a protobuf message. In proto3, fields cannot be optional and // there is no difference between an unset integer field and an integer field // set to 0. This is inconvenient for reading from P4 array-like structures, // such as indirect counters and meters. We need a way to do a wildcard read on // these but we cannot use a default zero index value to do so, as zero is a // valid index (first entry in the array). We therefore wrap the index in a // message. message Index { int64 index = 1; } //------------------------------------------------------------------------------ // For WriteRequest, Update.Type must be MODIFY. // For ReadRequest, the scope is defined as follows: // - All meter cells for all meters if meter_id = 0 (default). // - All meter cells for given meter_id if index is unset (default). message MeterEntry { uint32 meter_id = 1; Index index = 2; MeterConfig config = 3; // Added in v1.4.0 MeterCounterData counter_data = 4; } //------------------------------------------------------------------------------ // For WriteRequest, Update.Type must be MODIFY. INSERT and DELETE on direct // meters is not allowed and will return an error. The insertion/deletion // should happen as part of INSERT/DELETE on the associated table-entry. // For ReadRequest, the scope is defined as follows: // - All meter cells for all tables if table_entry.table_id = 0. // - All meter cells of a table if table_entry.table_id is present and // table_entry.match is empty. message DirectMeterEntry { // The associated table entry. This field is required. // table_entry.action is ignored. Other fields specify the match. TableEntry table_entry = 1; MeterConfig config = 2; // Added in v1.4.0 MeterCounterData counter_data = 3; } // Modeled to support both RFC 2698: A Two Rate Three Color Marker (trTCM) and // RFC 2697: A Single Rate Three Color Marker (srTCM) based on the `type` of the // corresponding MeterSpec. // // The trTCM meters a packet stream and marks its packets based on two rates, // Peak Information Rate (PIR) and Committed Information Rate (CIR), and their // associated burst sizes to be either green, yellow, or red. A packet is // marked red if it exceeds the PIR. Otherwise it is marked either yellow or // green depending on whether it exceeds or doesn't exceed the CIR. For this // meter type, `eburst` must be unset. // // The srTCM meters a packet stream and marks its packets based on one rate, // Committed Information Rate (CIR), and its associated burst size as well as an // Excess Burst Size (EBS) to be either green, yellow, or red. Roughly, a packet // is marked green if it doesn't exceed the CIR. Otherwise it is marked either // yellow or green depending on whether it exceeds or doesn't exceed the EBS. // For this meter type, it must be the case that `cir == pir && cburst == // pburst`. message MeterConfig { // Committed information rate (units per sec) int64 cir = 1; // Committed burst size int64 cburst = 2; // Peak information rate (units per sec) int64 pir = 3; // Peak burst size int64 pburst = 4; // Excess burst size (only used by srTCM). // Added in 1.4.0. int64 eburst = 5; } //------------------------------------------------------------------------------ // For WriteRequest, Update.Type must be MODIFY. // For ReadRequest, the scope is defined as follows: // - All counter cells for all counters if counter_id = 0 (default). // - All counter cells for given counter_id if index is unset (default). message CounterEntry { uint32 counter_id = 1; Index index = 2; CounterData data = 3; } //------------------------------------------------------------------------------ // For WriteRequest, Update.Type must be MODIFY. INSERT and DELETE on direct // counters is not allowed and will return an error. The insertion/deletion // should happen as part of INSERT/DELETE on the associated table-entry. // For ReadRequest, the scope is defined as follows: // - All counter cells for all tables if table_entry.table_id = 0. // - All counter cells of a table if table_entry.table_id is present and // table_entry.match is empty. message DirectCounterEntry { // The associated table entry. This field is required. // table_entry.action is ignored. Other fields specify the match. TableEntry table_entry = 1; CounterData data = 2; } message CounterData { int64 byte_count = 1; int64 packet_count = 2; } // Added in v1.4.0 message MeterCounterData { CounterData green = 1; CounterData yellow = 2; CounterData red = 3; } //------------------------------------------------------------------------------ // Only one instance of a Packet Replication Engine (PRE) is expected in the // P4 pipeline. Hence, no instance id is needed to access the PRE. message PacketReplicationEngineEntry { oneof type { MulticastGroupEntry multicast_group_entry = 1; CloneSessionEntry clone_session_entry = 2; } } // A backup replica used as a fallback when the primary replica port goes down. // Added in v1.5.0. message BackupReplica { bytes port = 1; uint32 instance = 2; } // Used for replicas created for cloning and multicasting actions. message Replica { oneof port_kind { // Using uint32 as ports is deprecated, use port field instead. // Deprecated in v1.4.0 uint32 egress_port = 1 [deprecated=true]; // Added in v1.4.0 bytes port = 3; } uint32 instance = 2; // List of backup replicas used as a fallback when the primary replica port // (and all higher-preference backup replica ports) are down. // Added in v1.5.0. repeated BackupReplica backup_replicas = 4; } // The (port, instance) pair must be unique for each replica in a given // multicast group entry. A packet may be multicast by setting the // multicast_group field of PSA ingress output metadata to multicast_group_id // of a programmed multicast group entry. The port and instance fields of each // replica's egress input metadata will be set to the respective values // programmed in the multicast group entry. message MulticastGroupEntry { uint32 multicast_group_id = 1; repeated Replica replicas = 2; // Arbitrary metadata from the controller that is opaque to the target. // Added in 1.4.0. bytes metadata = 3; } // A packet may be cloned by setting the clone_session_id field of PSA // ingress/egress output metadata to session_id of a programmed clone session // entry. Multiple clones may be created via a single clone session entry by // using the replicas message. The clones may be distinguished in the egress // using the instance field. The class_of_service field of the clone's egress // input metadata will be set to the respective value programmed in the clone // session entry. Note that in case of multiple clones, all clones, defined // for a clone session, will get the same class of service. The // packet_length_bytes field must be set to a non-zero value if the clone // packet(s) should be truncated to the given value (in bytes). The packet // length is also common to all clones in the clone session. If the // packet_length_bytes field is 0, no truncation on the clone(s) will be // performed. message CloneSessionEntry { uint32 session_id = 1; repeated Replica replicas = 2; uint32 class_of_service = 3; int32 packet_length_bytes = 4; } // A member in a P4 value set. Each member defines a list of matches, which can // have different match types. message ValueSetMember { repeated FieldMatch match = 1; } //------------------------------------------------------------------------------ // For writing and reading matches in a parser value set. A state transition // on an empty value set will never be taken. The number of matches must be at // most the size of the value set as specified by the size argument of the // value_set constructor in the P4 program. // // For Write Requests: // - MODIFY will write the given matches in the repeated field to the value // set. // - INSERT and DELETE are not allowed. // // For Read Requests: // - All matches for all value-set entries if value_set_id = 0 // - All matches of the value-set if a valid value_set_id is specified // - The 'match' field must never be set in the ReadRequest message ValueSetEntry { uint32 value_set_id = 1; repeated ValueSetMember members = 2; } //------------------------------------------------------------------------------ message RegisterEntry { uint32 register_id = 1; Index index = 2; P4Data data = 3; } //------------------------------------------------------------------------------ // Used to configure the digest extern only, not to stream digests or acks message DigestEntry { uint32 digest_id = 1; // a DigestList message is streamed when the following conditions are met: // - there is at least one digest ready // - the oldest digest in the list has been waiting for at least // max_timeout_ns nanoseconds or we have gathered max_list_size digests // already message Config { int64 max_timeout_ns = 1; // max timeout for outstanding digest data int32 max_list_size = 2; // max size for a digest list int64 ack_timeout_ns = 3; // timeout for DigestListAck message } Config config = 2; } //------------------------------------------------------------------------------ message StreamMessageRequest { oneof update { MasterArbitrationUpdate arbitration = 1; PacketOut packet = 2; DigestListAck digest_ack = 3; .google.protobuf.Any other = 4; } } // Packet sent from the controller to the switch. message PacketOut { bytes payload = 1; // This will be based on P4 header annotated as // @controller_header("packet_out"). // At most one P4 header can have this annotation. repeated PacketMetadata metadata = 2; } // Used by the controller to ack a DigestList message. To avoid flooding the // controller, the switch must not generate digest notifications for the same // data until a DigestListAck message with the same list_id is received or the // ack timeout (ack_timeout_ns field in DigestEntry.Config) expires. message DigestListAck { uint32 digest_id = 1; uint64 list_id = 2; } message StreamMessageResponse { oneof update { MasterArbitrationUpdate arbitration = 1; PacketIn packet = 2; DigestList digest = 3; IdleTimeoutNotification idle_timeout_notification = 4; .google.protobuf.Any other = 5; // Used by the server to asynchronously report errors which occur when // processing StreamMessageRequest messages. StreamError error = 6; } } // Packet sent from the switch to the controller. message PacketIn { bytes payload = 1; // This will be based on P4 header annotated as // @controller_header("packet_in"). // At most one P4 header can have this annotation. repeated PacketMetadata metadata = 2; } message DigestList { uint32 digest_id = 1; // identifies the digest extern instance uint64 list_id = 2; // identifies a list of entries, used by receiver to ack // List of entries: each call to the Digest::pack() method corresponds to // one entry and we can have as little as one entry. repeated P4Data data = 3; // Timestamp at which the server generated the message (in nanoseconds since // Epoch) int64 timestamp = 4; } // Any metadata associated with Packet-IO (controller Packet-In or Packet-Out) // needs to be modeled as P4 headers carrying special annotations // @controller_header("packet_out") and @controller_header("packet_in") // respectively. There can be at most one header each with these annotations. // These special headers are captured in P4Info ControllerPacketMetadata. message PacketMetadata { // This refers to Metadata.id coming from P4Info ControllerPacketMetadata. uint32 metadata_id = 1; bytes value = 2; } message MasterArbitrationUpdate { uint64 device_id = 1; // The role for which the primary client is being arbitrated. For use-cases // where multiple roles are not needed, the controller can leave this unset, // implying default role and full pipeline access. Role role = 2; // The stream RPC with the highest election_id is the primary. The 'primary' // controller instance populates this with its latest election_id. Switch // populates with the highest election ID it has received from all connected // controllers. Uint128 election_id = 3; // Switch populates this with OK for the client that is the primary, and // with an error status for all other connected clients (at every primary // client change). The controller does not populate this field. .google.rpc.Status status = 4; } message Role { // Uniquely identifies this role. // Deprecated in 1.4.0. uint64 id = 1 [deprecated=true]; // Added in 1.4.0. string name = 3; // Describes the role configuration, i.e. what operations, P4 entities, // behaviors, etc. are in the scope of a given role. If config is not set // (default case), it implies all P4 objects and control behaviors are in // scope, i.e. full pipeline access. The format of this message is // out-of-scope of P4Runtime. .google.protobuf.Any config = 2; } message IdleTimeoutNotification { // The only fields that are required to be set in each TableEntry are the // "key" fields (table_id, match and priority) along with controller_metadata, // metadata and idle_timeout_ns. repeated TableEntry table_entry = 1; // Timestamp at which the server generated the message (in nanoseconds since // Epoch) int64 timestamp = 2; } // Used by the server to asynchronously report errors which occur when // processing StreamMessageRequest messages. message StreamError { // gRPC canonical error code (see // https://developers.google.com/maps-booking/reference/grpc-api/status_codes) int32 canonical_code = 1; // Optional. An explanation of the error. string message = 2; // Optional. Target and architecture specific space to which this error // belongs. // We encourage using triplet: --, // e.g."targetX-psa-vendor1" or "targetY-psa-vendor2". string space = 3; // Optional. Numeric code drawn from target-specific error space above. int32 code = 4; // Used by the server to convey additional information about the error. One of // the fields must be set (so that the client can identify which type of // stream message triggered the error), but that field may be set to its // default value. oneof details { PacketOutError packet_out = 5; DigestListAckError digest_list_ack = 6; StreamOtherError other = 7; } } message PacketOutError { // Optional. The packet out message that caused the error. PacketOut packet_out = 1; } message DigestListAckError { // Optional. The digest list acknowledgement message that caused the error. DigestListAck digest_list_ack = 1; } message StreamOtherError { // Optional. The architecture-specific stream message that caused the error. google.protobuf.Any other = 1; } message Uint128 { // Highest 64 bits of a 128 bit number. uint64 high = 1; // Lowest 64 bits of a 128 bit number. uint64 low = 2; } //------------------------------------------------------------------------------ message SetForwardingPipelineConfigRequest { enum Action { UNSPECIFIED = 0; // Verify that the target can realize the given config. Do not modify the // forwarding state in the target. Returns error if config is not provided // of if the provided config cannot be realized. VERIFY = 1; // Save the config if the target can realize it. Do not modify the // forwarding state in the target. Any subsequent read/write requests must // refer to fields in the new config. Returns error if config is not // provided of if the provided config cannot be realized. VERIFY_AND_SAVE = 2; // Verify, save and realize the given config. Clear the forwarding state // in the target. Returns error if config is not provided of if the // provided config cannot be realized. VERIFY_AND_COMMIT = 3; // Realize the last saved, but not yet committed, config. Update the // forwarding state in the target by replaying the write requests since the // last config was saved. Config should not be provided for this action // type. Returns an error if no saved config is found or if a config is // provided with this message. COMMIT = 4; // Verify, save and realize the given config, while preserving the // forwarding state in the target. This is an advanced use case to enable // changes to the P4 forwarding pipeline configuration with minimal traffic // loss. P4Runtime does not impose any constraints on the duration of the // traffic loss. The support for this option is not expected to be uniform // across all P4Runtime targets. A target that does not support this option // may return an UNIMPLEMENTED error. For targets that support this option, // an INVALID_ARGUMENT error is returned if no config is provided, or if // the existing forwarding state cannot be preserved for the given config // by the target. RECONCILE_AND_COMMIT = 5; } uint64 device_id = 1; // Deprecated in 1.4.0. uint64 role_id = 2 [deprecated=true]; // Added in 1.4.0. string role = 6; Uint128 election_id = 3; Action action = 4; ForwardingPipelineConfig config = 5; } message SetForwardingPipelineConfigResponse {} message ForwardingPipelineConfig { config.v1.P4Info p4info = 1; // Target-specific P4 configuration. bytes p4_device_config = 2; // Metadata (cookie) opaque to the target. A control plane may use this field // to uniquely identify this config. There are no restrictions on how such // value is computed, or where this is stored on the target, as long as it is // returned with a GetForwardingPipelineConfig RPC. When reading the cookie, // we need to distinguish those cases where a cookie is NOT present (e.g. not // set in the SetForwardingPipelineConfigRequest, therefore we wrap the actual // uint64 value in a protobuf message. message Cookie { uint64 cookie = 1; } Cookie cookie = 3; } message GetForwardingPipelineConfigRequest { // Specifies the fields to populate in the response. enum ResponseType { // Default behaviour. Returns a ForwardingPipelineConfig with all fields set // as stored by the target. ALL = 0; // Reply by setting only the cookie field, omitting all other fields. COOKIE_ONLY = 1; // Reply by setting the p4info and cookie fields. P4INFO_AND_COOKIE = 2; // Reply by setting the p4_device_config and cookie fields. DEVICE_CONFIG_AND_COOKIE = 3; } uint64 device_id = 1; ResponseType response_type = 2; } message GetForwardingPipelineConfigResponse { ForwardingPipelineConfig config = 1; } // Error message used to report a single P4-entity error for a Write RPC. message Error { // gRPC canonical error code (see // https://developers.google.com/maps-booking/reference/grpc-api/status_codes) int32 canonical_code = 1; // Detailed error message. string message = 2; // Target and architecture specific space to which this error belongs. // We encourage using triplet: --, // e.g."targetX-psa-vendor1" or "targetY-psa-vendor2". string space = 3; // Numeric code drawn from target-specific error space above. int32 code = 4; // Optional: Allows reporting back additional target-specific details on the // error. .google.protobuf.Any details = 5; } //------------------------------------------------------------------------------ // Reserved controller-specified SDN port numbers for reference. enum SdnPort { SDN_PORT_UNKNOWN = 0; // SDN ports are numbered starting form 1. SDN_PORT_MIN = 1; // 0xfffffeff: The maximum value of an SDN port (physical or logical). SDN_PORT_MAX = -257; // Reserved SDN port numbers (0xffffff00 - 0xffffffff) // 0xfffffffa: Recirculate the packet back to ingress SDN_PORT_RECIRCULATE = -6; // 0xfffffffd: Send to CPU SDN_PORT_CPU = -3; } //------------------------------------------------------------------------------ message CapabilitiesRequest {} message CapabilitiesResponse { // The full semantic version string (e.g. "1.1.0-rc.1") corresponding to the // version of the P4Runtime API currently implemented by the server. string p4runtime_api_version = 1; }