Supported P4Runtime RPCs
To support the use cases described in Overview, SR Linux supports the following P4Runtime RPCs:
StreamChannelRPCAllows for session management, client arbitration, and packet injection/extraction. See StreamChannel RPC for information about how SR Linux handles
StreamChannelRPC messages.WriteRPCInjects rules to select packets to extract to the slow path.
ReadRPCProvides uniformity with the
WriteRPC; that is, it gives the controller the ability to query which rules have been programmed.SetForwardingPipelineConfigRPCUsed for pushing a P4 program from a P4Runtime controller to a target SR Linux device. The P4 program must be the same program that is distributed with SR Linux.
GetForwardingPipelineConfigRPCUsed for reading out the P4 forwarding pipeline configuration.
CapabilitiesRPCAllows a P4Runtime client to discover the capabilities of a target device, including the P4Runtime API version implemented by the SR Linux
p4rtservice.
StreamChannel RPC
The P4Runtime StreamChannel RPC is used for session management, arbitration, and packet I/O. It has the following definition:
rpc StreamChannel(stream StreamMessageRequest) returns (stream StreamMessageResponse)
The StreamChannel RPC has two top-level messages, StreamMessageRequest
and StreamMessageResponse.
The following is an example of the StreamMessageRequest message.
message StreamMessageRequest {
oneof update {
MasterArbitrationUpdate arbitration = 1;
PacketOut packet = 2;
DigestListAck digest_ack = 3;
.google.protobuf.Any other = 4;
}
}
p4rt service uses fields in the
StreamMessageRequest messages as follows:MasterArbitrationUpdateP4Runtime clients send
StreamMessageRequestmessages to thep4rtservice on the SR Linux device to perform arbitration viaMasterArbitrationUpdatemessages. See P4Runtime client arbitration.PacketOutThe P4Runtime client selected as primary transmits packets via
PacketOutmessages. See PacketIn and PacketOut messages.- The
DigestListAckand.google.proto.Anymessages within thedigest_ackandotherfields are not supported by SR Linux.
The following is an example of the StreamMessageResponse message:
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;
}
}
p4rt service uses fields in the
StreamMessageResponse messages as follows:MasterArbitrationUpdateThe
p4rtservice sends aStreamMessageResponsemessage to a P4Runtime client to respond to an arbitration request via aMasterArbitrationUpdatemessage. See P4Runtime client arbitrationPacketInThe
p4rtservice transmits packets to the primary P4Runtime client viaPacketInmessages. See PacketIn and PacketOut messages.StreamErrorThe
p4rtservice transmitsStreamErrormessage within theerrorfield based on any errors occurring. See Stream Error Reporting.- The
DigestList,IdleTimeoutNotification,.google.proto.Anymessages within thedigest,idle_timeout_notification, andotherfields are not are not supported by SR Linux.
P4Runtime client arbitration
P4Runtime client arbitration refers to the process by which a single P4Runtime controller becomes
the "primary", with any other controllers serving as backups. Only one P4Runtime
controller can be the primary. In SR Linux, P4Runtime
arbitration works as described in the P4
Runtime specification: the primary is elected based on the
election_id within the MasterArbitrationUpdate
message in the StreamChannel RPC.
MasterArbitrationUpdate message is defined as
follows: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.
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;
}Only the primary controller is allowed to send PacketOut messages and
receive PacketIn messages for a specific ASIC.
In the event a client with the highest election_id for a given
device_id disconnects, all clients with active sessions to the same
device_id are sent an Advisory message indicating
that the primary has gone down. On receiving this message clients increment their
election_id to be greater than the election_id of
the previous master. Until this is done no primary will exist for the
device_id; there is no automatic re-selection of a primary with the
next highest election_id. Once a new election has occurred, this
results in PacketIn messages being forwarded to the new master, and the
p4rt service only accepting PacketOut from the new
master.
PacketIn and PacketOut messages
PacketIn messages are sent by the p4rt service to the P4Runtime
client within StreamMessageResponse messages, and
PacketOut messages are sent by the P4Runtime client to the
p4rt service within StreamMessageRequest
messages.
An ACL pushed to the device via the Write RPC is used to mark/extract packets
for PacketIn handling by the p4rt service.
PacketIn and PacketOut messages are defined as
follows:// 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;
}
// 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 PacketMetadata {
// This refers to Metadata.id coming from P4Info ControllerPacketMetadata.
uint32 metadata_id = 1;
bytes value = 2;
}The PacketIn and PacketOut messages require that the
interface a packet is received on or transmitted out of be uniquely identified. To do
this, unique identifiers are configured for SR Linux interfaces. See Identifying interfaces to P4Runtime.