Download presentation
Presentation is loading. Please wait.
1
Debugging P4 Programs with Vera
Radu Stoenescu, Dragos Dumitrescu, Matei Popovici, Lorina Negreanu, Costin Raiciu University Politehnica of Bucharest
2
Vera: static verification of functional correctness for P414 programs
3
Vera: static verification of functional correctness for P414 programs
No concrete test traffic is generated Runs before deployment
4
Vera: static verification of functional correctness for P414 programs
Does the program have bugs? Does the program correctly implement the policy?
5
P4 by example: route and encapsulate
Ingress Pipeline TTL>0 Buffers Egress Pipeline encap * IN OUT ipv4_lpm /8 Ge0 DEPARSER PARSER Control program – what sequence of M/A tables is applied to a packet Match-action (M/A) tables - how a P4 switch can tranform packets What packets the switch accepts and outputs
6
P4 by example: route and encapsulate
Ingress Pipeline TTL>0 Buffers Egress Pipeline encap * IN OUT ipv4_lpm /8 Ge0 DEPARSER PARSER parser start { extract(eth); return select(eth.type){ 0x800 : parse_ipv4; default: ingress; }} parser parse_ipv4 { extract(ipv4); return ingress; } Deparsing uses the same parser specification. Common problem: forget to parse output packets.
7
P4 by example: route and encapsulate
Ingress Pipeline TTL>0 Buffers Egress Pipeline encap * IN OUT ipv4_lpm /8 Ge0 DEPARSER PARSER parser start { extract(eth); return select(eth.type){ 0x800 : parse_ipv4; default: ingress; }} parser parse_ipv4 { extract(ipv4); return select(ipv4.protocol){ 0x5E : parse_inner_ipv4; parser parse_inner_ipv4 { extract(inner_ipv4); return ingress; }}
8
P4 by example: route and encapsulate
Ingress Pipeline TTL>0 Buffers Egress Pipeline encap * IN OUT ipv4_lpm /8 Ge0 DEPARSER PARSER parser start { extract(eth); return select(eth.type){ 0x800 : parse_ipv4; default: ingress; }} parser parse_ipv4 { extract(ipv4); return select(ipv4.protocol){ 0x5E : parse_inner_ipv4; parser parse_inner_ipv4 { extract(inner_ipv4); return ingress; }} control ingress(){ if (ipv4.TTL>0) apply(ipv4_lpm); } Reading unparsed header fields will return undefined values
9
P4 by example: route and encapsulate
Ingress Pipeline valid(ipv4) &&TTL>0 Buffers Egress Pipeline encap * IN OUT ipv4_lpm /8 Ge0 DEPARSER PARSER control ingress(){ if (valid(ipv4) and ipv4.TTL>0) apply(ipv4_lpm); } Non IPv4 packets will be sent directly to buffering resulting in undefined behavior because the egress_spec is not set
10
P4 by example: route and encapsulate
Ingress Pipeline valid(ipv4) &&TTL>0 Buffers Egress Pipeline encap * IN OUT ipv4_lpm /8 Ge0 DEPARSER PARSER Re-adding existing header fields: undefined behavior
11
Vera design goals Easy to use General Scalable
high bug coverage with no to little intervention General policy verification for more complex properties Scalable comparable to compilation times
12
Vera at work
13
How Vera works P4 program P4 to SEFL Compiler Implicit bug checks
P4 table entries P4 to SEFL Compiler Implicit bug checks Symnet verification engine[Sigcomm’16] Network Policy For each possible path: full instruction trace, header field values, constraints and, if needed, bug type
14
Vera at work: route and encapsulate
Ingress Pipeline valid(ipv4) &&TTL>0 Buffers Egress Pipeline encap * IN OUT ipv4_lpm /8 Ge0 DEPARSER PARSER parser start { extract(eth); return select(eth.type){ 0x800 : parse_ipv4; default: ingress; }} parser parse_ipv4 { extract(ipv4); return select(ipv4.protocol){ 0x5E : parse_inner_ipv4; parser parse_inner_ipv4 { extract(inner_ipv4); return ingress; }}
15
Generating all header layouts
parser start { extract(eth); return select(eth.type){ 0x800 : parse_ipv4; default: ingress; }} parser parse_ipv4 { extract(ipv4); return select(ipv4.protocol){ 0x5E : parse_inner_ipv4; parser parse_inner_ipv4 { extract(inner_ipv4); return ingress; }}
16
Generating all header layouts
parser start { extract(eth); return select(eth.type){ 0x800 : parse_ipv4; default: ingress; }} parser parse_ipv4 { extract(ipv4); return select(ipv4.protocol){ 0x5E : parse_inner_ipv4; parser parse_inner_ipv4 { extract(inner_ipv4); return ingress; }} Eth IPv4 Inner_IPv4
17
Generating all header layouts
Eth Eth IPv4 Inner_IPv4
18
Generating all header layouts
Eth Eth Eth IPv4 IPv4 Inner_IPv4
19
Generating all header layouts
Eth Eth Eth IPv4 IPv4 Eth Inner_IPv4 IPv4 Inner_IPv4
20
Symbolic execution of P4 models
Eth Eth IPv4 Eth Inner_IPv4 IPv4
21
Symbolic execution of P4 models
Ethernet IPv4 Eth Dst Src EtherType * 0x800 Src Dst TTL ... * IPv4
22
Symbolic execution of P4 models
Ethernet IPv4 Eth Dst Src EtherType * 0x800 Src Dst TTL ... * IPv4 control ingress(){ if (valid(ipv4) && ipv4.TTL>0) apply(lpm); }
23
Symbolic execution of P4 models
control ingress(){ if (valid(ipv4) && ipv4.TTL>0) apply(lpm); }
24
Symbolic execution of P4 models
SEFL control ingress(){ if (valid(ipv4) && ipv4.TTL>0) apply(lpm); } ‘ingress’: If(Constrain(‘ipv4.TTL’>0)) Forward(‘table.lpm’) else Forward(‘buffer.in’)
25
Symbolic execution of P4 models
SEFL ‘ingress’: If(Constrain(‘ipv4.TTL’>0)) Forward(‘table.lpm’) else Forward(‘buffer.in’) Ethernet IPv4 Dst Src EtherType * 0x800 Src Dst TTL ... *
26
Symbolic execution of P4 models
SEFL ‘ingress’: If(Constrain(‘ipv4.TTL’>0)) Forward(‘table.lpm’) else Forward(‘buffer.in’) Ethernet IPv4 Dst Src EtherType * 0x800 Src Dst TTL ... * Dst Src EtherType * 0x800 Src Dst TTL ... * >0 Dst Src EtherType * 0x800 Src Dst TTL ... * <=0
27
Symbolic execution of P4 models
SEFL ‘ingress’: If(Constrain(‘ipv4.TTL’>0)) Forward(‘table.lpm’) else Forward(‘buffer.in’) Ethernet IPv4 Dst Src EtherType * 0x800 Src Dst TTL ... * Dst Src EtherType * 0x800 Src Dst TTL ... * >0 Dst Src EtherType * 0x800 Src Dst TTL ... * <=0 call ‘table.lpm’
28
Symbolic execution of P4 models
SEFL ‘ingress’: If(Constrain(‘ipv4.TTL’>0)) Forward(‘table.lpm’) else Forward(‘buffer.in’) Ethernet IPv4 Dst Src EtherType * 0x800 Src Dst TTL ... * Dst Src EtherType * 0x800 Src Dst TTL ... * >0 Dst Src EtherType * 0x800 Src Dst TTL ... * <=0 call ‘buffer.in’
29
Symbolic execution of a P4 pipeline
parser.start *
30
Symbolic execution of a P4 pipeline
parser.start control.ingress * Eth: type=0x800 IPv4: proto != 0x5E
31
Symbolic execution of a P4 pipeline
parser.start control.ingress table.lpm * Eth: type=0x800 IPv4: ttl > 0 proto != 0x5E Non-IPv4 Packets or TTL <= 0
32
Symbolic execution of a P4 pipeline
parser.start control.ingress table.lpm buffer.in table.encap deparser * Eth: type=0x800 IPv4: ipDst ∈ /8 ttl > 0 proto != 0x5E Default table action
33
Symbolic execution of a P4 pipeline
parser.start control.ingress table.lpm buffer.in table.encap deparser * Eth: type=0x800 ipv4: ipSrc = ipDst = proto = 0x5E inner: ipDst ∈ /8 ttl > 0 proto != 0x5E Default table action
34
Symbolic execution of a P4 pipeline
parser.start control.ingress table.lpm buffer.in table.encap deparser * Non-IPv4 Packets or TTL <= 0
35
Symbolic execution of a P4 pipeline
parser.start control.ingress table.lpm buffer.in table.encap deparser * Non-IPv4 Packets or TTL <= 0
36
Symbolic execution of a P4 pipeline
parser.start control.ingress table.lpm buffer.in table.encap deparser * Non-IPv4 Packets or TTL <= 0 Error reported (no egress spec)
37
Symbolic execution of a P4 pipeline
parser.start control.ingress table.lpm buffer.in table.encap deparser * Default table action No egress spec set Default table action Successfully routed and encapsulated
38
Vera in depth Scalable modeling of match-action tables Symbolic table entries Policy language
39
Vera in depth Scalable modeling of match-action tables Symbolic table entries Policy language
40
Match-action table modeling
table ipv4_lpm { reads { ipv4.dstAddr : lpm; } actions { set_nhop; _drop; size: 1024; simple_router.p4
41
Match-action table modeling
table ipv4_lpm { reads { ipv4.dstAddr : lpm; } actions { set_nhop; _drop; size: 1024; Match Action /24 set_nhop(h1) /24 set_nhop(h2) /16 set_nhop(h3) /0 set_nhop(h4) simple_router.p4
42
Match-action table modeling
If(IPDst ∈ /24) else set_nhop(h1) If(IPDst ∈ /24) else set_nhop(h2) If(IPDst ∈ /16) else set_nhop(h3) If(IPDst ∈ /0) else set_nhop(h4) Match Action /24 set_nhop(h1) /24 set_nhop(h2) /16 set_nhop(h3) /0 set_nhop(h4) straw man SEFL model
43
Match-action table modeling
If(IPDst ∈ /24) else set_nhop(h1) If(IPDst ∈ /24) else set_nhop(h2) If(IPDst ∈ /16) else set_nhop(h3) If(IPDst ∈ /0) else set_nhop(h4) Match Action /24 set_nhop(h1) /24 set_nhop(h2) /16 set_nhop(h3) /0 set_nhop(h4) straw man SEFL model
44
Match-action table modeling
Path condition: IPDst ∈ /0 If(IPDst ∈ /24) else set_nhop(h1) If(IPDst ∈ /24) else set_nhop(h2) If(IPDst ∈ /16) else set_nhop(h3) If(IPDst ∈ /0) else set_nhop(h4) straw man SEFL model
45
Match-action table modeling
Path condition: IPDst ∈ /0 && IPDst ∉ /16 && IPDst ∉ /24 && IPDst ∉ /24 If(IPDst ∈ /24) else set_nhop(h1) If(IPDst ∈ /24) else set_nhop(h2) If(IPDst ∈ /16) else set_nhop(h3) If(IPDst ∈ /0) else set_nhop(h4) straw man SEFL model
46
Match-action table modeling
Path condition: IPDst ∈ /0 && IPDst ∉ /16 && IPDst ∉ /24 && IPDst ∉ /24 If(IPDst ∈ /24) else set_nhop(h1) If(IPDst ∈ /24) else set_nhop(h2) If(IPDst ∈ /16) else set_nhop(h3) If(IPDst ∈ /0) else set_nhop(h4) straw man SEFL model
47
Match-action table modeling
Path condition: IPDst ∈ /0 && IPDst ∉ /16 && IPDst ∉ /24 && IPDst ∉ /24 If(IPDst ∈ /24) else set_nhop(h1) If(IPDst ∈ /24) else set_nhop(h2) If(IPDst ∈ /16) else set_nhop(h3) If(IPDst ∈ /0) else set_nhop(h4) 3 out of 10 constraints are redundant straw man SEFL model
48
Tree data structure for fast optimal M/A model compilation
49
Tree data structure for fast optimal M/A model compilation
/24 /24
50
Tree data structure for fast optimal M/A model compilation
/16 /24 /24
51
Tree data structure for fast optimal M/A model compilation
/0 /16 /24 /24
52
Tree data structure for fast optimal M/A model compilation
/0 /16 /24 /24
53
Tree data structure for fast optimal M/A model compilation
/0 /16 /24 /24
54
Tree data structure for fast optimal M/A model compilation
/0 /16 /24 /24
55
Tree data structure for fast optimal M/A model compilation
/0 /16 /24 /24
56
Tree data structure for fast optimal M/A model compilation
/0 Optimal number of constraints without losing precision Fast model compilation and update Works for other matching strategies (except from ternary) and multiple match fields /16 /24 /24
57
M/A table model comparison
Modeling procedure Action 1K 10K 100K Naive Compile Model 2ms 5ms - Symbolic Execution 34s 1h lpm-heuristics 23ms 1.5s 218s 220ms 2.7s 12s Vera 36ms 83s 230ms
58
M/A table model comparison
Modeling procedure Action 1K 10K 100K Naive Compile Model 2ms 5ms - Symbolic Execution 34s 1h lpm-heuristics 23ms 1.5s 218s 220ms 2.7s 12s Vera 36ms 83s 230ms
59
Related work p4v requires P4 programs manually annotated with control plane assertions finer-grained control over verification process, fast. higher burden on programmer p4pktgen – dynamic testing framework concrete bug examples weaker definition of correct behavior (P4 behavioral model) P4Nod can handle large P4 deployments (multiple switches) smaller bug coverage
60
Conclusions P4 programs contain surprisingly many bugs.
Vera automatically finds bugs in P414 program snapshots in seconds, with no spec required. Symbolic table entries help explore many (or all) possible P4 data plane snapshots. Soon: github.com/nets-cs-pub-ro/Vera
61
Future work Support P416 Further evaluate symbolic table entries as an aid for developing correct controllers Develop correct by construction P4 controllers Improve scalability for fully symbolic M/A table contents
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.