Supported P4Runtime RPCs
To support the use cases described in Overview, SR Linux supports the following P4Runtime RPCs:
StreamChannel
RPCAllows for session management, client arbitration, and packet injection/extraction. See StreamChannel RPC for information about how SR Linux handles
StreamChannel
RPC messages.Write
RPCInjects rules to select packets to extract to the slow path.
Read
RPCProvides uniformity with the
Write
RPC; that is, it gives the controller the ability to query which rules have been programmed.SetForwardingPipelineConfig
RPCUsed 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.
GetForwardingPipelineConfig
RPCUsed for reading out the P4 forwarding pipeline configuration.
Capabilities
RPCAllows a P4Runtime client to discover the capabilities of a target device, including the P4Runtime API version implemented by the SR Linux
p4rt
service.
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:MasterArbitrationUpdate
P4Runtime clients send
StreamMessageRequest
messages to thep4rt
service on the SR Linux device to perform arbitration viaMasterArbitrationUpdate
messages. See P4Runtime client arbitration.PacketOut
The P4Runtime client selected as primary transmits packets via
PacketOut
messages. See PacketIn and PacketOut messages.- The
DigestListAck
and.google.proto.Any
messages within thedigest_ack
andother
fields 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:MasterArbitrationUpdate
The
p4rt
service sends aStreamMessageResponse
message to a P4Runtime client to respond to an arbitration request via aMasterArbitrationUpdate
message. See P4Runtime client arbitrationPacketIn
The
p4rt
service transmits packets to the primary P4Runtime client viaPacketIn
messages. See PacketIn and PacketOut messages.StreamError
The
p4rt
service transmitsStreamError
message within theerror
field based on any errors occurring. See Stream Error Reporting.- The
DigestList
,IdleTimeoutNotification
,.google.proto.Any
messages within thedigest
,idle_timeout_notification
, andother
fields 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. On 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.