p4srv6 (P4-16) design document rev1.0

kentaroebisawa 1,443 views 26 slides Feb 22, 2019
Slide 1
Slide 1 of 26
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26

About This Presentation

"p4srv6 (P4-16) design document rev1.0" Overview of Open Source SRv6 Mobile Userplane P4-16 on BMv2 design (planned to be public in March) #enog #enog55 @Nigata http://enog.jp/archives/2014


Slide Content

p4srv6 (P4-16)
design document
rev1.0
ENOG55@新潟燕三条| 2019年2月22日
海老澤健太郎KentaroEbisawa
Toyota InfoTechnology Center Co., Ltd.
p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0

•p4srv6 ... feature and roadmap
•P4 Difference among Architectures
•p4srv6 ... Pipeline and design
•p4srv6 Pipeline and design
•p4srv6 ... examples of config and packet dump
•p4srv6 ... control planeintegration
•MAT abstraction considerations
•P4 Implementation tips
•SID List (variable length array field)
•SRv6 active segment
p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
TableofContents

p4srv6 ... feature and roadmap
p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
p4srv6 ... feature and roadmap
Whatisp4srv6??
https://github.com/ebiken/p4srv6

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
p4srv6 ... feature and roadmap
Functions used in the SRv6 Mobile UplanePOC

P4 Difference among Architectures
p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
Difference you should care between P4 Architectures
•Pipeline
•Metadata
•Special In/Out port
•Externs (Checksum)
Architecture is also defined using P4
https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4
https://github.com/p4lang/p4c/blob/master/p4include/psa.p4
https://github.com/vmware/p4c-xdp/blob/master/p4include/xdp_model.p4

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
P4 Pipeline ... Difference among Architectures
psa.p4 ... Portable Switch Architecture
package IngressPipeline<IH, IM, NM, CI2EM, RESUBM, RECIRCM>(
IngressParser<IH, IM, RESUBM, RECIRCM> ip,
Ingress<IH, IM> ig,
IngressDeparser<IH, IM, CI2EM, RESUBM, NM> id);
package EgressPipeline<EH, EM, NM, CI2EM, CE2EM, RECIRCM>(
EgressParser<EH, EM, NM, CI2EM, CE2EM> ep,
Egress<EH, EM> eg,
EgressDeparser<EH, EM, CE2EM, RECIRCM> ed);
package PSA_Switch<IH, IM, EH, EM, NM, CI2EM, CE2EM, RESUBM, RECIRCM> (
IngressPipeline<IH, IM, NM, CI2EM, RESUBM, RECIRCM> ingress,
PacketReplicationEnginepre,
EgressPipeline<EH, EM, NM, CI2EM, CE2EM, RECIRCM> egress,
BufferingQueueingEnginebqe);
xdp_model.p4 ... XDP backend of p4c (p4c-xdp)
package xdp<H>(
xdp_parse<H> p,
xdp_switch<H> s,
xdp_deparse<H> d);
v1model.p4 ... p4-14 compatible pipeline
package V1Switch<H, M>(
Parser<H, M> p,
VerifyChecksum<H, M> vr,
Ingress<H, M> ig,
Egress<H, M> eg,
ComputeChecksum<H, M> ck,
Deparser<H> dep);

p4srv6 ... design
p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
p4srv6Pipeline
SwitchParser()
SwitchParser(
packet_inpkt,
out Header hdr,
inoutUserMetadatauser_md,
inoutstandard_metadata_tst_md)
state start {
transition parse_ethernet;
}
SwitchVerifyChecksum()
SwitchVerifyChecksum(
inoutHeader hdr,
inoutUserMetadatauser_md)
SwitchComputeChecksum ()
SwitchComputeChecksum(
inoutHeader hdr,
inoutUserMetadatauser_md)
SwitchEgress()
SwitchEgress(
inoutHeader hdr,
inoutUserMetadatauser_md,
inoutstandard_metadata_tst_md)
< no control implemented so far >
SwitchDeparser()
SwitchDeparser(
packet_outpkt,
in Header hdr)
pkt.emit(hdr.ether);
pkt.emit(hdr.ipv6);
pkt.emit(hdr.srh);
pkt.emit(hdr.srh_sid);
pkt.emit(hdr.ipv4);
pkt.emit(hdr.icmp);
pkt.emit(hdr.tcp);
pkt.emit(hdr.udp);
pkt.emit(hdr.gtpu);
pkt.emit(hdr.inner_ether);
pkt.emit(hdr.inner_ipv6);
pkt.emit(hdr.inner_ipv4);
pkt.emit(hdr.inner_tcp);
pkt.emit(hdr.inner_udp);
SwitchIngress()
SwitchIngress(
inoutHeader hdr,
inoutUserMetadatauser_md,
inoutstandard_metadata_tst_md)
table local_mac;
SRv6() srv6;
L2Fwd(1024) l2fwd;
PortFwd() port_fwd;
No parsing of
vendor specific header
Checksumdone in
ControlBlockdedicated for Checksum
Controls to do main packet header
and metadata processing
Architecture:v1model.p4
v1model.p4 ... p4-14 compatible pipeline
package V1Switch<H, M>(
Parser<H, M> p,
VerifyChecksum<H, M> vr,
Ingress<H, M> ig,
Egress<H, M> eg,
ComputeChecksum<H, M> ck,
Deparser<H> dep);

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
p4srv6 main control (Ingress)SwitchIngress()
SwitchIngress(
inoutHeader hdr,
inoutUserMetadatauser_md,
inoutstandard_metadata_tst_md)
table local_mac;
SRv6() srv6;
L2Fwd(1024) l2fwd;
PortFwd() port_fwd;
control SwitchIngress(
inoutHeader hdr,
inoutUserMetadatauser_md,
inoutstandard_metadata_tst_md) {
...
apply {
mark_to_drop(); // set default action to drop to avoid unexpected packets going out.
// apply srv6 without local_macvalidation for quick testing
srv6.apply(hdr, user_md);
l2fwd.apply(hdr.ether.dstAddr, user_md.ig_md, st_md.egress_spec);
port_fwd.apply(st_md.ingress_port, st_md.egress_spec);
}
}

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
p4srv6 SRv6 control
control SRv6(
inoutHeader hdr,
inoutUserMetadatauser_md) {
...
apply {
if (hdr.srh.isValid()) {
srv6_set_nextsid.apply();
}
if (hdr.ipv6.isValid()) {
if(!srv6_end.apply().hit) {
srv6_transit_v6.apply();
}
} else if (hdr.ipv4.isValid()) {
if(!srv6_transit_udp.apply().hit) {
srv6_transit_v4.apply();
}
}
}
}

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
p4srv6 “Transit” Tables
table srv6_transit_v4 {
key = {
hdr.ipv4.dstAddr: exact;
}
actions = {
@defaultonlyNoAction;
//t_encaps_sid1; // T.Encaps
//t_encaps_l2_sid1; // T.Encaps.L2
}
}
table srv6_transit_v6 {
key = {
hdr.ipv6.dstAddr: exact;
}
actions = {
@defaultonlyNoAction;
// T.Insertwith n+1 SIDs (DA + sid1)
t_insert_sid1;
t_insert_sid2;
t_insert_sid3;
//t_encaps_sid1; // T.Encaps
//t_encaps_l2_sid1; // T.Encaps.L2
}
}
table srv6_transit_udp {
key = {
hdr.udp.dstPort: exact;
}
actions = {
@defaultonlyNoAction;
// SRv6 Mobile User Plane
t_m_tmap;
t_m_tmap_sid1; // 2 SIDs (DA + sid1)
t_m_tmap_sid2; // 3 SIDs (DA + sid1/2)
t_m_tmap_sid3; // 4 SIDs (DA + sid1/2/3)
}
}
Strategy
•Separate tables based on “key” field to reduce
“Match” resource
•“insert” is not required for ipv4 match table
(SRH require IPv6)
•Create action per number of SIDs to insert

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
p4srv6 “End” Tables
table srv6_end { // localsid
key = {
hdr.ipv6.dstAddr : ternary;
// hdr.srh.isValid() : ternary;
// hdr.srh.segmentLeft: ternary;
// hdr.srh.nextHdr: ternary; // for decap
}
actions = {
@defaultonlyNoAction;
// SRv6 Network Program
end; // End
// SRv6 Mobile User Plane
end_m_gtp4_e; // End.M.GTP4.E
}
const default_action= NoAction;
}
Strategy
•“End” must match IPv6 address (SID = IPv6 dstAddr) thus only single table.
(Currently not implemented but)
Match field (key) to generate errors when
invalid packet received matching localsid.

p4srv6
... examples of config and packet dump
p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
GTP to SRv6 with T.M.Tmap& End.M.GTP4.E (no SRH)
SRGW1 R1 SRGW2
veth1
host1
#1
vtap1
#2
vtap2
#11
vtap11
#12
vtap12
host1
172.20.0.1/24 172.20.0.2/24
veth2
BMv2 simple switch with p4srv6
GTP Tunnel
(Linux Kernel)
T.M.Tmap
(BMv2)
End.M.GTP4.E
(BMv2)
GTP Tunnel
(Linux Kernel)
[ICMP][IPv4]=> [ICMP][IPv4][GTP][UDP][IPv4]=> [ICMP][IPv4]=>
(SRv6 with no SRH)
[ICMP][IPv4][IPv6]=> [ICMP][IPv4][GTP][UDP][IPv4]=>
① ①②
① ②
SRv6 SID : fc34:5678:ac14:0002:ac14:0001:0000:0064
Dst: 172.20.0.2
Src: 172.20.0.1
TEID: 100
PREFIX
SRv6 SID

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
GTP to SRv6 with T.M.Tmap& End.M.GTP4.E (with SRH)
GTP Tunnel
(Linux Kernel)
T.M.Tmap
(BMv2)
End.M.GTP4.E
(BMv2)
GTP Tunnel
(Linux Kernel)
[ICMP][IPv4]=> [ICMP][IPv4][GTP][UDP][IPv4]=> [ICMP][IPv4]=>(SRv6 with SRH)
[ICMP][IPv4][SRH][IPv6]=>
[ICMP][IPv4][GTP][UDP][IPv4]=>
① ②
End
(BMv2)
SRGW1 SRGW2
veth1
host1
#1
vtap1
#2
vtap2
#11
vtap11
#12
vtap12
host1
172.20.0.1/24 172.20.0.2/24
veth2
BMv2 simple switch with p4srv6
#13
vtap13
#14
vtap14
R1

p4srv6 ... control plane integration
p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
To Be Updated in Future Rev.

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
Match Action Table (MAT) abstraction considerations
To Be Updated in Future Rev.

P4 Implementation tips
p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0

SID List (variable length array field)
state start {
transition parse_ethernet;
}
state parse_ethernet{
pkt.extract(hdr.ether);
transition
select(hdr.ether.etherType) {
ETH_P_IPV4 : parse_ipv4;
ETH_P_IPV6 : parse_ipv6;
//ETH_P_ARP : parse_arp;
//ETH_P_VLAN : parse_vlan;
default : accept;
}
state parse_ipv4 {
pkt.extract(hdr.ipv4);
transition
select(hdr.ipv4.protocol) {
IPPROTO_TCP : parse_tcp;
IPPROTO_UDP : parse_udp;
default : accept;
}
}
state parse_ipv6 {
pkt.extract(hdr.ipv6);
transition
select(hdr.ipv6.nextHdr) {
IPPROTO_TCP : parse_tcp;
IPPROTO_UDP : parse_udp;
IPPROTO_ROUTE : parse_srh;
IPPROTO_IPV4 :
parse_inner_ipv4;
IPPROTO_IPV6 :
parse_inner_ipv6;
default : accept;
}
}
header SRH_SegmentList_h{
bit<128> sid;
}
struct Header {
Ethernet_hether;
IPv6_h ipv6;
SRH_hsrh;
SRH_SegmentList_h[SRH_SID_MAX] srh_sid;
p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
SID List (variable length array field)
/*** PARSE SRH (SRv6) ***/
state parse_srh{
pkt.extract(hdr.srh);
transition parse_srh_sid_0;
}
#define PARSE_SRH_SID(curr, next) ¥
state parse_srh_sid_##curr{ ¥
pkt.extract(hdr.srh_sid[curr]); ¥
transition select(hdr.srh.lastEntry) { ¥
curr: parse_srh_next_header; ¥
default : parse_srh_sid_##next; ¥
} ¥
} ¥
// switch_srv6.p4:SRH_SID_MAX 4
PARSE_SRH_SID(0, 1)
PARSE_SRH_SID(1, 2)
PARSE_SRH_SID(2, 3)
state parse_srh_sid_3 {
pkt.extract(hdr.srh_sid[3]);
transition select(hdr.srh.lastEntry) {
3 : parse_srh_next_header;
// v1model: no default rule:
// all other packets rejected
}
}
state parse_srh_next_header{
transition select(hdr.srh.nextHdr) {
IPPROTO_TCP : parse_tcp;
IPPROTO_UDP : parse_udp;
IPPROTO_IPV4 : parse_inner_ipv4;
IPPROTO_IPV6 : parse_inner_ipv6;
default : accept;
}
}

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
SRv6 active segment
action end() {
// 1. IF NH=SRH and SL > 0
// 2. decrement SL
hdr.srh.segmentsLeft= hdr.srh.segmentsLeft-1;
// 3. update the IPv6 DA with SRH[SL]
hdr.ipv6.dstAddr = hdr.srh_sid[hdr.segmentsLeft-1];
...
Compiler ERROR!!
Cannotusearray with variable
index in action statement.

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
SRv6 active segment
table srv6_set_nextsid { // helper table
key = {
hdr.srh.segmentsLeft: exact;
}
actions = {
NoAction;
set_nextsid_1;
set_nextsid_2;
set_nextsid_3;
set_nextsid_4;
}
const default_action= NoAction;
const entries = {
(1) : set_nextsid_1();
(2) : set_nextsid_2();
(3) : set_nextsid_3();
(4) : set_nextsid_4();
}
}
action set_nextsid_1() {
user_md.srv6.nextsid = hdr.srh_sid[0].sid;
}
action set_nextsid_2() {
user_md.srv6.nextsid = hdr.srh_sid[1].sid;
}
action set_nextsid_3() {
user_md.srv6.nextsid = hdr.srh_sid[2].sid;
}
action set_nextsid_4() {
user_md.srv6.nextsid = hdr.srh_sid[3].sid;
}
Use constant entries to set next SID to
metadata without user configuration.
Let me know if you have better idea ☺

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
SRv6 active segment
action end() {
// 1. IF NH=SRH and SL > 0
// 2. decrement SL
hdr.srh.segmentsLeft= hdr.srh.segmentsLeft-1;
// 3. update the IPv6 DA with SRH[SL]
hdr.ipv6.dstAddr = hdr.srh_sid[hdr.segmentsLeft-1];
...
action end() {
// 1. IF NH=SRH and SL > 0
// 2. decrement SL
hdr.srh.segmentsLeft= hdr.srh.segmentsLeft-1;
// 3. update the IPv6 DA with SRH[SL]
hdr.ipv6.dstAddr = user_md.srv6.nextsid;
...
Compiler ERROR!!
Cannotusearray with variable
index in action statement.
Set active segment from metadata

p4srv6 (P4-16) design document | ENOG55 in Nigata Tsubame Sanjyo | 2019/02/22 rev1.0
p4srv6 ... feature and roadmap
https://github.com/ebiken/p4srv6