P4 Tutorial
P4 Tutorial
Welcome
Noa Zilberman
University of Cambridge
Switch OS
Network Demands
?
“This is how I know to
Run-time API
Driver
process packets”
(i.e. the ASIC datasheet
makes the rules)
Fixed-function ASIC
Copyright © 2018 – P4.org 4
A Better Approach: Top-down design
Switch OS
Network Demands
Feedback
Run-time API
Driver
P4
State machine,
Parsers bitfield extraction
Tables, Actions,
Controls control flow
statements
Basic operations
Expressions and operators
Bistrings, headers,
Data Types structures, arrays
Term Explanation
Community-Developed Vendor-supplied
P416
Language
P416 Core
Library
Extern Architecture
Libraries Definition
TM
SimpleSumeSwitch
TM
TM Anything
Control Plane
RUNTIME
P4 Program P4 Compiler Add/remove Extern Packet-in/out
table entries control
CPU port
P4 Architecture Target-specific Extern
configuration Load Tables Data Plane
Model objects
binary
Target
Vendor supplied
Traffic
Manager
h1 h2
(10.0.1.1) (10.0.2.2)
s1 s2
s3
h3
(10.0.3.3)
Copyright © 2018 – P4.org 25
P416 Types (Basic and Header Types)
typedef bit<48> macAddr_t; Basic Types
typedef bit<32> ip4Addr_t;
header ethernet_t { • bit<n>: Unsigned integer (bitstring) of size n
macAddr_t dstAddr; • bit is the same as bit<1>
macAddr_t srcAddr;
• int<n>: Signed integer of size n (>=2)
bit<16> etherType;
} • varbit<n>: Variable-length bitstring
header ipv4_t {
bit<4> version;
Header Types: Ordered collection of members
bit<4> ihl;
bit<8> diffserv; • Can contain bit<n>, int<n>, and varbit<n>
bit<16> totalLen; • Byte-aligned
bit<16> identification;
bit<3> flags;
• Can be valid or invalid
bit<13> fragOffset; • Provides several operations to test and set validity bit:
bit<8> ttl; isValid(), setValid(), and setInvalid()
bit<8> protocol;
bit<16> hdrChecksum;
ip4Addr_t srcAddr; Typedef: Alternative name for a type
ip4Addr_t dstAddr;
}
/* User program */
struct metadata {
...
}
struct headers {
ethernet_t ethernet;
ipv4_t ipv4;
}
(DataPlane)
Parameters
Directional
Headers and Metadata
Lookup Key
Hit
Key Action ID Action Data
Action
ID
Action ID
Code
Selector
Hit/Miss
(Action Data)
Directionless
Parameters
Data
(DataPlane)
Parameters
Directional
action NoAction() { types of parameters
} ◦ Directional (from the Data Plane)
◦ Directionless (from the Control
/* basic.p4 */ Plane)
action drop() { • Actions that are called directly:
mark_to_drop(); ◦ Only use directional parameters Action
} • Actions used in tables: Code
(Action Data)
Directionless
Parameters
action ipv4_forward(macAddr_t dstAddr, ◦ May sometimes use directional
bit<9> port) { parameters too
...
}
Action
Execution
h1 h2
1 1
(10.0.1.1) 2 2 (10.0.2.2)
(dst_id: 1) s1 3 3 s2 (dst_id: 2)
2 3
1
s3
h3
(10.0.3.3) (dst_id: 3)
Copyright © 2018 – P4.org 46
Coding Break
1
Copyright © 2018 – P4.org, ONF
P4 Software Tools
2
Copyright © 2018 – P4.org, ONF
Makefile: under the hood
P4Runtime static controller
runtime.json
P4Runtime client
test.p4
P4Runtime server
p4c-bm2-ss L
simple_switch_grpc (BMv2)
o
TM g
Egress
Ingress
P4
D Debugger
test.json test.p4info e
b
u
g
Parser Deparser
Packet Packet
generator Port Interface sniffer
veth0..n
Linux Kernel
3
Copyright © 2018 – P4.org, ONF
Step 1: P4 Program compilation
test.json test.p4info
4
Copyright © 2018 – P4.org, ONF
Step 2: Preparing veth Interfaces
Linux
Kernel
2n
veth 1 3 5 +1
5
Copyright © 2018 – P4.org, ONF
Step 3: Starting BMv2
$ sudo simple_switch_grpc --log-console --dump-packet-data 64 \
–i 0@veth0 -i 1@veth2 … [--pcap] --no-p4 \
test.p4 -- --grpc-server-addr 0.0.0.0:50051 --cpu-port 255 \
test.json
p4c-bm2-ss L
simple_switch_grpc (BMv2)
o
TM g
Egress
Ingress
D
test.json test.p4info e
b
u
g
Parser Deparser
Port Interface
veth0..n
Linux Kernel
6
Copyright © 2018 – P4.org, ONF
Step 4: Starting P4Runtime static controller
P4Runtime static controller
$ python $(RUN_SCRIPT) -t runtime.json
$(TOPO) $(run_args) P4Runtime client (gRPC)
simple_switch_grpc (BMv2)
TM o ● BMv2 JSON and
g
P4Info to deploy
● Table entries
p4c-bm2-ss
Egress
Ingress
D
e
b
u
g
Port Interface
veth0..n
Linux Kernel
7
Copyright © 2018 – P4.org, ONF
P4Runtime
• API overview
• Workflow
• Exercise - Tunneling
8
Copyright © 2018 – P4.org, ONF
Runtime control of P4 data planes
User supplied
Control Plane
P4 Program P4 Compiler Add/remove Extern Packet-in/out
table entries control
CPU port
P4 Architecture Target-specific Extern
configuration Load Tables Data Plane
Model objects
binary
• BMv2 CLI
◦ Program-independent, but target-specific -- control plane not portable!
• OpenFlow
◦ Target-independent, but protocol-dependent -- protocol headers and
actions baked in the specification!
11
Copyright © 2018 – P4.org, ONF
Properties of a runtime control API
P4 compiler
auto-generated ✔ ✘
BMv2 CLI ✘ ✔
OpenFlow ✔ ✘
SAI ✔ ✘
P4Runtime ✔ ✔
12
Copyright © 2018 – P4.org, ONF
What is P4Runtime?
• Framework for runtime control of P4 targets
◦ Open-source API + server implementation
https://github.com/p4lang/PI
◦ Initial contribution by Google and Barefoot
• P4 program-independent
◦ API doesn’t change with the P4 program
14
Copyright © 2018 – P4.org, ONF
gRPC Basics
● Use Protocol Buffers to define service API and messages
● Automatically generate native stubs in:
○ C / C++
○ C#
○ Dart
○ Go
○ Java
○ Node.js
○ PHP
○ Python
○ Ruby
● Transport over HTTP/2.0 and TLS
○ Efficient single TCP connection implementation that supports
bidirectional streaming
15
Copyright © 2018 – P4.org, ONF
gRPC Service Example
// The greeter service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
17
Copyright © 2018 – P4.org, ONF
P4Runtime Service
Service Specification:
Working draft of version 1.0 is available now
https://p4.org/p4-spec/docs/P4Runtime-v1.0.0.pdf
18
Copyright © 2018 – P4.org, ONF
P4Runtime Write Request
message WriteRequest { message Entity {
uint64 device_id = 1; oneof entity {
uint64 role_id = 2; ExternEntry extern_entry = 1;
Uint128 election_id = 3; TableEntry table_entry = 2;
repeated Update updates = 4; ActionProfileMember
} action_profile_member = 3;
ActionProfileGroup
action_profile_group = 4;
message Update { MeterEntry meter_entry = 5;
enum Type { DirectMeterEntry direct_meter_entry = 6;
UNSPECIFIED = 0; CounterEntry counter_entry = 7;
INSERT = 1; DirectCounterEntry direct_counter_entry = 8;
MODIFY = 2; PacketReplicationEngineEntry
DELETE = 3; packet_replication_engine_entry = 9;
} ValueSetEntry value_set_entry = 10;
Type type = 1; RegisterEntry register_entry = 11;
Entity entity = 2; }
} }
19
Copyright © 2018 – P4.org, ONF
P4Runtime Table Entry
p4runtime.proto simplified excerpts:
message TableEntry { message FieldMatch {
To add a table entry, the control
uint32 table_id; uint32 field_id; plane needs to know:
repeated FieldMatch match; message Exact {
Action action; bytes value;
int32 priority; } • IDs of P4 entities
... message Ternary { ◦ Tables, field matches, actions,
} bytes value; params, etc.
bytes mask;
}
message Action { ... • Field matches for the
uint32 action_id; oneof field_match_type { particular table
message Param { Exact exact;
◦ Match type, bitwidth, etc.
uint32 param_id; Ternary ternary;
bytes value; ...
}
} • Parameters for the particular
}
repeated Param params; action
}
20
Copyright © 2018 – P4.org, ONF
P4Runtime workflow
P4Info test.p4
test.p4info
• Protobuf-based format
23
Copyright © 2018 – P4.org, ONF
P4Runtime SetPipelineConfig
message SetForwardingPipelineConfigRequest { test.p4
enum Action {
UNSPECIFIED = 0; Pipeline config
VERIFY = 1; p4info json
VERIFY_AND_SAVE = 2;
VERIFY_AND_COMMIT = 3; p4c-bm2-ss SetPipelineConfig()
COMMIT = 4; (compiler)
Pipeline config bits
RECONCILE_AND_COMMIT = 5;
}
uint64 device_id = 1;
uint64 role_id = 2;
Uint128 election_id = 3; BMv2
Action action = 4;
ForwardingPipelineConfig config = 5;
} message ForwardingPipelineConfig {
config.P4Info p4info = 1;
// Target-specific P4 configuration.
bytes p4_device_config = 2;
}
24
Copyright © 2018 – P4.org, ONF
P4Runtime StreamChannel
// Packet sent from the controller to the switch.
message StreamMessageRequest { message PacketOut {
oneof update { bytes payload = 1;
MasterArbitrationUpdate // This will be based on P4 header annotated as
arbitration = 1; // @controller_header("packet_out").
PacketOut packet = 2; // At most one P4 header can have this annotation.
DigestListAck digest_ack = 3; repeated PacketMetadata metadata = 2;
} }
}
// Packet sent from the switch to the controller.
message StreamMessageResponse { message PacketIn {
oneof update { bytes payload = 1;
MasterArbitrationUpdate // This will be based on P4 header annotated as
arbitration = 1; // @controller_header("packet_in").
PacketIn packet = 2; // At most one P4 header can have this annotation.
DigestList digest = 3; repeated PacketMetadata metadata = 2;
} }
}
25
Copyright © 2018 – P4.org, ONF
P4Runtime Common Parameters
• device_id
◦ Specifies the specific forwarding chip or software bridge
◦ Set to 0 for single chip platforms
• role_id
◦ Corresponds to a role with specific capabilities (i.e. what operations, P4
entities, behaviors, etc. are in the scope of a given role)
◦ Role definition is currently agreed upon between control and data planes
offline
◦ Default role_id (0) has full pipeline access
• election_id
◦ P4Runtime supports mastership on a per-role basis
◦ Client with the highest election ID is referred to as the "master", while all
other clients are referred to as "slaves"
◦ Set to 0 for single instance controllers
26
Copyright © 2018 – P4.org, ONF
Mastership Arbitration
• Upon connecting to the device, the client (e.g. controller)
needs to open a StreamChannel
• The client must advertise its role_id and election_id using a
MasterArbitrationUpdate message
◦ If role_id is not set, it implies the default role and will be granted full
pipeline access
◦ The election_id is opaque to the server and determined by the control
plane (can be omitted for single-instance control plane)
• The switch marks the client for each role with the highest
election_id as master
• Master can:
◦ Perform Write requests
◦ Receive PacketIn messages
◦ Send PacketOut messages 27
Copyright © 2018 – P4.org, ONF
Remote control
table_entry {
table_id: 33581985
Target-independent P4-defined
match { protobuf format OSPF BGP etc.
field_id: 1
lpm {
custom protocol
value: "\f\000\...
prefix_len: 8
p4info
}
}
action {
Remote control plane
action_id: 16786453
params {
param_id: 1
value: "\000\0...
}
params {
param_id: 2
value: 7
}
}
}
28
Copyright © 2018 – P4.org, ONF
Local control
table_entry {
Same table_id: 33581985
match {
P4-defined
etc.
target-independent field_id: 1
OSPF BGP lpm {
protocol protobuf format value: "\f\000\...
prefix_len: 8
p4info }
Local control plane }
action {
action_id: 16786453
params {
param_id: 1
p4info value: "\000\0...
}
params {
param_id: 2
value: 7
}
}
}
P4 target
30
Copyright © 2018 – P4.org, ONF
l ide ogle
S o
G
o m
fr ● P4 program tailored to apps / role - does not describe the hardware
● Switch maps program to fixed-function ASIC
● Enables portability
Control
Logical
Physical
ASIC 1 ASIC 2
P4Runtime API recap
Things we covered: What we didn’t cover:
• P4Info • How to control other P4 entities
• Table entries ◦ Externs, counters, meters
• Set pipeline config • Packet-in/out support
• Controller replication
◦ Via master-slave arbitration
• Batched reads/writes
• Switch configuration
◦ Outside the P4Runtime scope
◦ Achieved with other mechanisms
■ e.g., OpenConfig and gNMI
test.p4
P4 compiler generates 2 files:
1. Target-specific binaries
○ Used to configure switch pipeline
p4c
(e.g. binary config for ASIC, bitstream for FPGA, etc.)
(compiler)
2. P4Info file
○ Captures P4 program attributes needed to
runtime control
■ Tables, actions, parameters, etc. test.p4info
○ Protobuf-based format
○ Target-independent compiler output
■ Same P4Info for SW switch, ASIC, etc. test.bin
34
Copyright © 2018 – P4.org, ONF
Exercise Overview
Controller’s responsibilities:
1. Establish a gRPC connection to the
switches for the P4Runtime service mycontroller.py
2. Push the P4 program to each switch
3. Write the tunnel forwarding rules:
a. myTunnel_ingress rule to
encapsulate packets on the ingress
switch
b. myTunnel_forward rule to
forward packets on the ingress
switch
c. myTunnel_egress rule to
decapsulate and forward packets
on the egress switch
4. Read the tunnel ingress and egress
counters every 2 seconds
35
Copyright © 2018 – P4.org, ONF
Getting started
The source code has already been downloaded on your VM:
~/tutorials/exercises/p4runtime
36
Copyright © 2018 – P4.org, ONF
Lab 3: Advanced P4 Features
h1 2 2 1 h2
(10.0.1.1) 1
(10.0.2.2)
s1 3 3 s2
2 3
1 s3
3
h3
(10.0.3.3)
Copyright © 2018 – P4.org
Source Routing: Packet Format
#define MAX_HOPS 9 • Parse source routes only if etherType is
0x1234
const bit<16> TYPE_IPV4 = 0x800;
const bit<16> TYPE_SRCROUTING = 0x1234;
header srcRoute_t { • The special value bos == 1 indicates the
bit<1> bos; “bottom of stack”
bit<15> port;
}
• Forward packets using source routes,
struct headers { and also decrement IPv4 TTL
ethernet_t ethernet;
srcRoute_t[MAX_HOPS] srcRoutes; • Drop the packet if source routes are not
ipv4_t ipv4; valid
}
h1 h2
(10.0.1.1) (10.0.2.2)
s1 s2
Virtual IP (10.0.0.1)
shared by h2 and h3
s3
h3
(10.0.3.3)
Copyright © 2018 – P4.org 5
Hashing (V1Model)
enum HashAlgorithm {
csum16,
Computes the hash of data
xor16, (using algo) modulo max
crc32,
crc32_custom, and adds it to base
crc16,
crc16_custom,
random, Uses type variables (like
identity
}
C++ templates / Java
extern void hash<O, T, D, M>( Generics) to allow hashing
out O result,
in HashAlgorithm algo, primitive to be used with
in T base, many different types.
in D data,
in M max);
Congestion!
Fine … h2
h1
(10.0.1.1) (10.0.2.2)
h11 h22
(10.0.1.11) s1 s2 (10.0.2.22)
h3
(10.0.3.3)
s1
Copyright © 2018 – P4.org 8
Multi-Route Inspection
Switch ID, queue h2
h1 depth, … (anything)
(10.0.2.2)
(10.0.1.1) pkt
s1 s2
h22
h11 (10.0.2.22)
(10.0.1.11)
• Consortium of academic
and industry members
• Membership is free:
contributions are welcome
• Independent, set up as a
California nonprofit