Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SYMNET — A Tool for Static Network Verification

0286822f506fc4621bd3ea0bcbfef238?s=47 Bucharest FP
September 24, 2014

SYMNET — A Tool for Static Network Verification

0286822f506fc4621bd3ea0bcbfef238?s=128

Bucharest FP

September 24, 2014
Tweet

More Decks by Bucharest FP

Other Decks in Programming

Transcript

  1. SYMNET Matei Popovici, Costin Raiciu, Radu Stoenescu a static tool

    for network verification
  2. Network function virtualization

  3. None
  4. None
  5. Hard to reason about

  6. Hard to maintain Hard to reason about

  7. None
  8. None
  9. Hardware

  10. Hardware // Change the following line to refer to your

    interface's IP and Ethernet // addresses. AddressInfo(the_interface 1.0.0.1 0:0:c0:8a:67:ef); classifier :: Classifier(12/0800 /* IP packets */, 12/0806 20/0001 /* ARP requests */, - /* everything else */); ip_classifier :: IPClassifier(dst udp port 1234 /* relevant UDP packets */, - /* everything else Software
  11. Hardware // Change the following line to refer to your

    interface's IP and Ethernet // addresses. AddressInfo(the_interface 1.0.0.1 0:0:c0:8a:67:ef); classifier :: Classifier(12/0800 /* IP packets */, 12/0806 20/0001 /* ARP requests */, - /* everything else */); ip_classifier :: IPClassifier(dst udp port 1234 /* relevant UDP packets */, - /* everything else Software Click
  12. Hardware // Change the following line to refer to your

    interface's IP and Ethernet // addresses. AddressInfo(the_interface 1.0.0.1 0:0:c0:8a:67:ef); classifier :: Classifier(12/0800 /* IP packets */, 12/0806 20/0001 /* ARP requests */, - /* everything else */); ip_classifier :: IPClassifier(dst udp port 1234 /* relevant UDP packets */, - /* everything else Software Click
  13. Hardware // Change the following line to refer to your

    interface's IP and Ethernet // addresses. AddressInfo(the_interface 1.0.0.1 0:0:c0:8a:67:ef); classifier :: Classifier(12/0800 /* IP packets */, 12/0806 20/0001 /* ARP requests */, - /* everything else */); ip_classifier :: IPClassifier(dst udp port 1234 /* relevant UDP packets */, - /* everything else Software Click ClickOS
  14. Hardware // Change the following line to refer to your

    interface's IP and Ethernet // addresses. AddressInfo(the_interface 1.0.0.1 0:0:c0:8a:67:ef); classifier :: Classifier(12/0800 /* IP packets */, 12/0806 20/0001 /* ARP requests */, - /* everything else */); ip_classifier :: IPClassifier(dst udp port 1234 /* relevant UDP packets */, - /* everything else Software Click ClickOS
  15. Hardware // Change the following line to refer to your

    interface's IP and Ethernet // addresses. AddressInfo(the_interface 1.0.0.1 0:0:c0:8a:67:ef); classifier :: Classifier(12/0800 /* IP packets */, 12/0806 20/0001 /* ARP requests */, - /* everything else */); ip_classifier :: IPClassifier(dst udp port 1234 /* relevant UDP packets */, - /* everything else Software Click ClickOS
  16. Examples

  17. Examples

  18. Examples

  19. Examples

  20. Examples

  21. Virtualization vs. configuration 12/0806 20/0001

  22. Virtualization vs. configuration access-list extended permit tcp host 192.168.1.1 any

    12/0806 20/0001
  23. Virtualization vs. configuration access-list extended permit tcp host 192.168.1.1 any

    12/0806 20/0001
  24. Virtualization vs. configuration access-list extended permit tcp host 192.168.1.1 any

    in -> IPClassifier(„dst host 192.168.1.1 and tcp”) -> out 12/0806 20/0001
  25. Virtualization vs. configuration access-list extended permit tcp host 192.168.1.1 any

    in -> IPClassifier(„dst host 192.168.1.1 and tcp”) -> out 12/0806 20/0001 in -> IPClassifier(„12/0806 20/0001”) -> out
  26. Virtualization vs. configuration access-list extended permit tcp host 192.168.1.1 any

    in -> IPClassifier(„dst host 192.168.1.1 and tcp”) -> out 12/0806 20/0001 in -> IPClassifier(„12/0806 20/0001”) -> out ARP req
  27. Challenges

  28. Challenges • Debugging

  29. Challenges • Debugging • Understanding the „software” topology

  30. Challenges • Debugging • Understanding the „software” topology • Offering

    guarantees that software processing behaves as intended
  31. Verifying network processing

  32. Verifying network processing formally

  33. What is out there...

  34. What is out there... on off off on off

  35. What is out there... on off off on off

  36. What is out there... on off off on off

  37. What is out there... on off off on off

  38. What is out there... on off off on off

  39. What is out there... on off off on off Model

    checking
  40. What is out there... on off off on off Model

    checking A(int x, int y) { if (x == 2) return A(x,x+y); if (y == 1) return A(x-1,y); return x-y; }
  41. What is out there... on off off on off Model

    checking A(int x, int y) { if (x == 2) return A(x,x+y); if (y == 1) return A(x-1,y); return x-y; } -32767 < x < 32767
  42. What is out there... on off off on off Model

    checking A(int x, int y) { if (x == 2) return A(x,x+y); if (y == 1) return A(x-1,y); return x-y; } -32767 < x < 32767 -32767 < y < 32767
  43. What is out there... on off off on off Model

    checking A(int x, int y) { if (x == 2) return A(x,x+y); if (y == 1) return A(x-1,y); return x-y; } -32767 < x < 32767 -32767 < y < 32767 x =2
  44. What is out there... on off off on off Model

    checking A(int x, int y) { if (x == 2) return A(x,x+y); if (y == 1) return A(x-1,y); return x-y; } -32767 < x < 32767 -32767 < y < 32767 x =2 y =1
  45. What is out there... on off off on off Model

    checking A(int x, int y) { if (x == 2) return A(x,x+y); if (y == 1) return A(x-1,y); return x-y; } -32767 < x < 32767 -32767 < y < 32767 x =2 y =1 Symbolic execution
  46. Our setting FromDevice(eth0) ->Strip(14) ->c :: IPClassifier(„tcp”,”udp”)[0] ->IPRewriter(„pattern 10.0.0.1 20

    - -”) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth1) c[1] ->IPEncap(4, 18.26.4.24, 140.247.60.147) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth2)
  47. Our setting FromDevice(eth0) ->Strip(14) ->c :: IPClassifier(„tcp”,”udp”)[0] ->IPRewriter(„pattern 10.0.0.1 20

    - -”) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth1) c[1] ->IPEncap(4, 18.26.4.24, 140.247.60.147) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth2) Arbitrary packet
  48. Our setting FromDevice(eth0) ->Strip(14) ->c :: IPClassifier(„tcp”,”udp”)[0] ->IPRewriter(„pattern 10.0.0.1 20

    - -”) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth1) c[1] ->IPEncap(4, 18.26.4.24, 140.247.60.147) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth2) Arbitrary packet Trim ethernet
  49. Our setting FromDevice(eth0) ->Strip(14) ->c :: IPClassifier(„tcp”,”udp”)[0] ->IPRewriter(„pattern 10.0.0.1 20

    - -”) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth1) c[1] ->IPEncap(4, 18.26.4.24, 140.247.60.147) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth2) Arbitrary packet Trim ethernet TCP packet
  50. Our setting FromDevice(eth0) ->Strip(14) ->c :: IPClassifier(„tcp”,”udp”)[0] ->IPRewriter(„pattern 10.0.0.1 20

    - -”) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth1) c[1] ->IPEncap(4, 18.26.4.24, 140.247.60.147) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth2) Arbitrary packet Trim ethernet TCP packet RW src IP and TCP
  51. Our setting FromDevice(eth0) ->Strip(14) ->c :: IPClassifier(„tcp”,”udp”)[0] ->IPRewriter(„pattern 10.0.0.1 20

    - -”) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth1) c[1] ->IPEncap(4, 18.26.4.24, 140.247.60.147) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth2) Arbitrary packet Trim ethernet TCP packet RW src IP and TCP Add ethernet header
  52. Our setting FromDevice(eth0) ->Strip(14) ->c :: IPClassifier(„tcp”,”udp”)[0] ->IPRewriter(„pattern 10.0.0.1 20

    - -”) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth1) c[1] ->IPEncap(4, 18.26.4.24, 140.247.60.147) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth2) Arbitrary packet Trim ethernet TCP packet UDP packet RW src IP and TCP Add ethernet header
  53. Our setting FromDevice(eth0) ->Strip(14) ->c :: IPClassifier(„tcp”,”udp”)[0] ->IPRewriter(„pattern 10.0.0.1 20

    - -”) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth1) c[1] ->IPEncap(4, 18.26.4.24, 140.247.60.147) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth2) Arbitrary packet Trim ethernet TCP packet UDP packet RW src IP and TCP Add ethernet header Encapsulate in IP
  54. Our setting FromDevice(eth0) ->Strip(14) ->c :: IPClassifier(„tcp”,”udp”)[0] ->IPRewriter(„pattern 10.0.0.1 20

    - -”) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth1) c[1] ->IPEncap(4, 18.26.4.24, 140.247.60.147) ->EtherEncap(0x0800, 1:1:1:1:1:1, 2:2:2:2:2:2) ->ToDevice(eth2) Arbitrary packet Trim ethernet TCP packet UDP packet RW src IP and TCP Add ethernet header Encapsulate in IP Add ethernet header
  55. Arbitrary packet Trim ethernet TCP packet UDP packet RW src

    IP and TCP Add ethernet header Encapsulate in IP Add ethernet header
  56. Arbitrary packet Trim ethernet TCP packet UDP packet RW src

    IP and TCP Add ethernet header Encapsulate in IP Add ethernet header
  57. Our idea

  58. Our idea Symbolic execution

  59. Our idea Symbolic execution ...

  60. Our idea Symbolic execution on all paths... ...

  61. Treat sets of packets as n-dimensional spaces

  62. Treat sets of packets as n-dimensional spaces Source IP =

    169.168.0.1 Source IP = 169.168.0.255
  63. Treat sets of packets as n-dimensional spaces Source IP =

    169.168.0.1 Source IP = 169.168.0.255 IP proto = 6 IP proto = 17
  64. Treat packet processing elements as functions

  65. Treat packet processing elements as functions

  66. Treat packet processing elements as functions

  67. Treat packet processing elements as functions

  68. Treat packet processing elements as functions Filtering function

  69. Treat packet processing elements as functions Filtering function

  70. Treat packet processing elements as functions Filtering function

  71. Treat packet processing elements as functions Filtering function

  72. Treat packet processing elements as functions Filtering function Modify function

  73. Treat packet processing elements as functions Filtering function Modify function

    Reunion, disjunction, complement, set difference
  74. Compute reachability and loop detection

  75. Compute reachability and loop detection Src FW R1 R2 R3

    Dst
  76. Compute reachability and loop detection Src FW R1 R2 R3

    Dst
  77. Compute reachability and loop detection Src FW R1 R2 R3

    Dst
  78. Compute reachability and loop detection Src FW R1 R2 R3

    Dst
  79. Compute reachability and loop detection Src FW R1 R2 R3

    Dst
  80. Compute reachability and loop detection Src FW R1 R2 R3

    Dst
  81. Compute reachability and loop detection Src FW R1 R2 R3

    Dst
  82. Compute reachability and loop detection Src FW R1 R2 R3

    Dst
  83. Compute reachability and loop detection Src FW R1 R2 R3

    Dst
  84. ... where functional programming comes into play

  85. Writing flow operations intuitively

  86. Writing flow operations intuitively („IPSrc” .=. „192.168.0.1”) .>. nil

  87. Writing flow operations intuitively („IPSrc” .=. „192.168.0.1”) .>. nil („proto”

    .=. „4”) .>. nil
  88. Writing flow operations intuitively („IPSrc” .=. „192.168.0.1”) .>. nil („proto”

    .=. „4”) .>. nil ((„IPSrc” .=. „192.168.0.1”) .>. nil) `cup` ((„proto” .=. „4”) .>. nil)
  89. Writing flow operations intuitively („IPSrc” .=. „192.168.0.1”) .>. nil („proto”

    .=. „4”) .>. nil ((„IPSrc” .=. „192.168.0.1”) .>. nil) `cup` ((„proto” .=. „4”) .>. nil) („DstPort” .=. „80”) .>. ((„IPSrc” .=. „192.168.0.1”) .>. nil) `cup` ((„proto” .=. „4”) .>. nil)
  90. Hiding actual representation

  91. Hiding actual representation class AsExpression a where (.=.) :: Var

    -> a -> VarBinding
  92. Hiding actual representation class AsExpression a where (.=.) :: Var

    -> a -> VarBinding instance AsExpression String where v .=. s = ...
  93. Hiding actual representation class AsExpression a where (.=.) :: Var

    -> a -> VarBinding instance AsExpression String where v .=. s = ... instance AsExpression Integer where v .=. i =
  94. Hiding actual representation class AsExpression a where (.=.) :: Var

    -> a -> VarBinding instance AsExpression String where v .=. s = ... instance AsExpression Integer where v .=. i = instance AsExpression Expr where v .=. e = v `Bind` e
  95. Hiding actual representation class AsExpression a where (.=.) :: Var

    -> a -> VarBinding instance AsExpression String where v .=. s = ... instance AsExpression Integer where v .=. i = instance AsExpression Expr where v .=. e = v `Bind` e data VarBinding = Bind Var Expr
  96. Processing elements as functions type Rule = (Flow -> Bool,

    Flow -> Flow)
  97. Processing elements as functions type Rule = (Flow -> Bool,

    Flow -> Flow)
  98. Processing elements as functions type Rule = (Flow -> Bool,

    Flow -> Flow) Should I process this flow?
  99. Processing elements as functions type Rule = (Flow -> Bool,

    Flow -> Flow) Should I process this flow?
  100. Processing elements as functions type Rule = (Flow -> Bool,

    Flow -> Flow) Should I process this flow? How should I modify the flow?
  101. Processing elements as functions type Rule = (Flow -> Bool,

    Flow -> Flow) Should I process this flow? How should I modify the flow? (m,a) `comp` (m',a') = let mfin f = (m f) && (m' f) afin = a . a' in (mfin, afin)
  102. Processing elements as functions type Rule = (Flow -> Bool,

    Flow -> Flow) Should I process this flow? How should I modify the flow? (m,a) `comp` (m',a') = let mfin f = (m f) && (m' f) afin = a . a' in (mfin, afin) (m,a) `comp` (m',a') = let mfin f = (m f) && (m' (a f)) afin = a . a' in (mfin, afin)
  103. Processing elements as functions type Rule = (Flow -> Bool,

    Flow -> Flow) Should I process this flow? How should I modify the flow? (m,a) `comp` (m',a') = let mfin f = (m f) && (m' f) afin = a . a' in (mfin, afin) (m,a) `comp` (m',a') = let mfin f = (m f) && (m' (a f)) afin = a . a' in (mfin, afin) Building more sofisticated processing from simpler one
  104. Compute reachability and loop detection Src FW R1 R2 R3

    Dst „Object-oriented” style
  105. Compute reachability and loop detection Src FW R1 R2 R3

    Dst Visitable „Object-oriented” style Visitable Visitable Visitable Visitable Visitable
  106. Compute reachability and loop detection Src FW R1 R2 R3

    Dst Visitable „Object-oriented” style Visitable Visitable Visitable Visitable Visitable Visitor
  107. Compute reachability and loop detection Src FW R1 R2 R3

    Dst Visitable „Object-oriented” style Visitable Visitable Visitable Visitable Visitable Visitor Visitor
  108. Compute reachability and loop detection Src FW R1 R2 R3

    Dst Visitable „Object-oriented” style Visitable Visitable Visitable Visitable Visitable Visitor Visitor
  109. Compute reachability and loop detection Src FW R1 R2 R3

    Dst Visitable „Object-oriented” style Visitable Visitable Visitable Visitable Visitable Visitor Visitor
  110. Compute reachability and loop detection Src FW R1 R2 R3

    Dst Visitable „Object-oriented” style Visitable Visitable Visitable Visitable Visitable Visitor
  111. Compute reachability and loop detection Src FW R1 R2 R3

    Dst Visitable „Object-oriented” style Visitable Visitable Visitable Visitable Visitable Visitor
  112. Compute reachability and loop detection Src FW R1 R2 R3

    Dst Visitable „Object-oriented” style Visitable Visitable Visitable Visitable Visitable Visitor
  113. How the code looks like...

  114. How the code looks like... abstract class Element {

  115. How the code looks like... abstract class Element { public

    boolean match(Flow f);
  116. How the code looks like... abstract class Element { public

    boolean match(Flow f); public Map<Element,Flow> apply(Flow f);
  117. How the code looks like... abstract class Element { public

    boolean match(Flow f); public Map<Element,Flow> apply(Flow f); }
  118. How the code looks like... abstract class Element { public

    boolean match(Flow f); public Map<Element,Flow> apply(Flow f); public void accept(Visitor v){ ... } }
  119. How the code looks like... abstract class Visitor { private

    Flow currentFlow(); public Set<Element> visit(Element e){ ... } }
  120. How the code looks like... abstract class Visitor { private

    Flow currentFlow(); public Set<Element> visit(Element e){ Map<Element, Flow> m = ... if (e.match(currentFlow()){ m = e.apply(currentFlow()); // process m } return m.keySet(); } }
  121. How the code looks like... abstract class Element { public

    boolean match(Flow f); public Map<Element,Flow> apply(Flow f); public void accept(Visitor v){ for (Element e:v.visit(this)){ e.accept(v); } }
  122. Compute reachability and loop detection „Functional” style

  123. Compute reachability and loop detection Src FW R1 R2 R3

    Dst „Functional” style
  124. Compute reachability and loop detection Src FW R1 R2 R3

    Dst „Functional” style (match,apply) (match,apply) (match,apply) (match,apply)
  125. Compute reachability and loop detection Src FW R1 R2 R3

    Dst „Functional” style (match,apply) (match,apply) (match,apply) (match,apply) Push ports into the flow
  126. Compute reachability and loop detection Src FW R1 R2 R3

    Dst „Functional” style (match,apply) (match,apply) (match,apply) (match,apply) Push ports into the flow
  127. Compute reachability and loop detection FW R1 R2 R3 „Functional”

    style (match,apply) (match,apply) (match,apply) (match,apply) Network Function F
  128. How the code looks like... F :: [Flow] -> [Flow]

  129. How the code looks like... F :: [Flow] -> [Flow]

    F [] = [„the initial flow, with it’s corresponding port” ]
  130. How the code looks like... F :: [Flow] -> [Flow]

    F [] = [„the initial flow, with it’s corresponding port” ] F X = map (\(f,r) -> apply f r) $ [(f,r) | f <- X , r <- ruleList, match f r]
  131. How the code looks like... F :: [Flow] -> [Flow]

    F [] = [„the initial flow, with it’s corresponding port” ] F X = map (\(f,r) -> apply f r) $ [(f,r) | f <- X , r <- ruleList, match f r] What happens next?
  132. We compute...

  133. We compute... F [] = F0

  134. We compute... F [] = F0 F F0 = F1

  135. We compute... F [] = F0 F F0 = F1

    ...
  136. We compute... F [] = F0 F F0 = F1

    ... F Fn = Fn+1
  137. We compute... F [] = F0 F F0 = F1

    ... F Fn = Fn+1 ...
  138. We compute... F [] = F0 F F0 = F1

    ... F Fn = Fn+1 ... The sequence stabilises eventually
  139. We compute... F [] = F0 F F0 = F1

    ... F Fn = Fn+1 ... lfp :: ([Flow] -> [Flow]) -> [Flow] lfp F = let g x y = if x == x ++ y then x else g (x++y) (F y) in g [] (F []) The sequence stabilises eventually
  140. Final remarks

  141. Final remarks • The code on the slides will not

    compile
  142. Final remarks • The code on the slides will not

    compile • Many ideas are due: – Kazemian et al. Header Space Analysis: Static Checking For Networks
  143. Final remarks • The code on the slides will not

    compile • Many ideas are due: – Kazemian et al. Header Space Analysis: Static Checking For Networks • One of our contributions is in modelling packet state, by pushing it in the flow
  144. Final remarks • The code on the slides will not

    compile • Many ideas are due: – Kazemian et al. Header Space Analysis: Static Checking For Networks • One of our contributions is in modelling packet state, by pushing it in the flow • Does the functional style beat the object oriented one?