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

SYMNET — A Tool for Static Network Verification

Bucharest FP
September 24, 2014

SYMNET — A Tool for Static Network Verification

Bucharest FP

September 24, 2014
Tweet

More Decks by Bucharest FP

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. Challenges • Debugging • Understanding the „software” topology • Offering

    guarantees that software processing behaves as intended
  11. 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; }
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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)
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. Arbitrary packet Trim ethernet TCP packet UDP packet RW src

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

    IP and TCP Add ethernet header Encapsulate in IP Add ethernet header
  28. Treat sets of packets as n-dimensional spaces Source IP =

    169.168.0.1 Source IP = 169.168.0.255
  29. 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
  30. Writing flow operations intuitively („IPSrc” .=. „192.168.0.1”) .>. nil („proto”

    .=. „4”) .>. nil ((„IPSrc” .=. „192.168.0.1”) .>. nil) `cup` ((„proto” .=. „4”) .>. nil)
  31. 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)
  32. Hiding actual representation class AsExpression a where (.=.) :: Var

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

    -> a -> VarBinding instance AsExpression String where v .=. s = ... instance AsExpression Integer where v .=. i =
  34. 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
  35. 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
  36. Processing elements as functions type Rule = (Flow -> Bool,

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

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

    Flow -> Flow) Should I process this flow? How should I modify the flow?
  39. 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)
  40. 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)
  41. 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
  42. Compute reachability and loop detection Src FW R1 R2 R3

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

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

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

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

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

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

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

    Dst Visitable „Object-oriented” style Visitable Visitable Visitable Visitable Visitable Visitor
  50. How the code looks like... abstract class Element { public

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

    boolean match(Flow f); public Map<Element,Flow> apply(Flow f); }
  52. 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){ ... } }
  53. How the code looks like... abstract class Visitor { private

    Flow currentFlow(); public Set<Element> visit(Element e){ ... } }
  54. 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(); } }
  55. 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); } }
  56. Compute reachability and loop detection Src FW R1 R2 R3

    Dst „Functional” style (match,apply) (match,apply) (match,apply) (match,apply)
  57. 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
  58. 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
  59. Compute reachability and loop detection FW R1 R2 R3 „Functional”

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

    F [] = [„the initial flow, with it’s corresponding port” ]
  61. 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]
  62. 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?
  63. We compute... F [] = F0 F F0 = F1

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

    ... F Fn = Fn+1 ... The sequence stabilises eventually
  65. 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
  66. Final remarks • The code on the slides will not

    compile • Many ideas are due: – Kazemian et al. Header Space Analysis: Static Checking For Networks
  67. 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
  68. 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?