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_server
process.
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_server
process uses fields in the
StreamMessageRequest
messages as follows:MasterArbitrationUpdate
P4Runtime clients send
StreamMessageRequest
messages to thep4rt_server
on the SR Linux 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_server
process uses fields in the
StreamMessageResponse
messages as follows:MasterArbitrationUpdate
The
p4rt_server
sends aStreamMessageResponse
message to a P4Runtime client to respond to an arbitration request via aMasterArbitrationUpdate
message. See P4Runtime client arbitrationPacketIn
The
p4rt_server
transmits packets to the primary P4Runtime client viaPacketIn
messages. See PacketIn and PacketOut messages.StreamError
The
p4rt_server
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 controller with the highest election_id
disconnects, the
controller with the next-highest election_id
is automatically used as
the new
primary,
resulting in PacketIn
messages being forwarded to the new primary, and
p4rt_server
only accepting PacketOut
from the new
primary. If a controller does not specify an election_id
, it is
considered to be the lowest election_id
and never becomes the
primary.
PacketIn
and PacketOut
messages
PacketIn
messages are sent by p4rt_server
to the
P4Runtime client within StreamMessageResponse
messages, and
PacketOut
messages are sent by the P4Runtime client to
p4rt_server
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_server
.
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.