一、实验目的

  • Mininet 安装之后,会连带安装 Open vSwitch,可以直接通过 Python 脚本调用Open vSwitch 命令,从而直接控制 Open vSwitch,通过实验了解调用控制的方法。

    二、实验任务

  • 在本实验中,使用 Mininet 基于 Python 的脚本,调用“ovs-vsctl”命令直接控制Open vSwitch。使用默认的交换机泛洪规则,设置更高的优先级规则进行预先定义 IP 报文的转发。在多个交换机中通过设置不同 TOS 值的数据包将通过不同的方式到达目的地址,验证主机间的连通性及到达目的地址的时间。

    三、实验步骤

    1. 实验环境

  • Ryu虚拟机

    2. 实验步骤

    (1)创建 ovsSingleBr.py 脚本并运行

  • 实验内容
    执行 ovsSingleBr.py,在没有控制器的情况下,在Mininet 脚本中通过调用 ovs 命令直接向 switch0 交换机下发流表,将入端口号为1/2/3 的数据包泛洪广播,并对目的地址为 192.168.123.1/2/3 的数据包分别从1/2/3 端口转发出去。之后测试 h0 ping h1,h0 ping h2,网络连通。

  • ovsSingleBr.py 对应拓扑

Open vSwitch 实验——Mininet 中使用 OVS 命令 - 图1

  • ovsSingleBr.py 对应代码

image.png

  1. #!/usr/bin/python
  2. from mininet.net import Mininet
  3. from mininet.node import Node
  4. from mininet.link import Link
  5. from mininet.log import setLogLevel, info
  6. def myNet():
  7. "Create network from scratch using Open vSwitch."
  8. info( "*** Creating nodes\n" )
  9. switch0 = Node( 's0', inNamespace=False )
  10. h0 = Node( 'h0' )
  11. h1 = Node( 'h1' )
  12. h2 = Node( 'h2' )
  13. info( "*** Creating links\n" )
  14. Link( h0, switch0)
  15. Link( h1, switch0)
  16. Link( h2, switch0)
  17. info( "*** Configuring hosts\n" )
  18. h0.setIP( '192.168.123.1/24' )
  19. h1.setIP( '192.168.123.2/24' )
  20. h2.setIP( '192.168.123.3/24' )
  21. info( "*** Starting network using Open vSwitch\n" )
  22. switch0.cmd( 'ovs-vsctl del-br dp0' )
  23. switch0.cmd( 'ovs-vsctl add-br dp0' )
  24. for intf in switch0.intfs.values():
  25. print intf
  26. print switch0.cmd( 'ovs-vsctl add-port dp0 %s' % intf )
  27. # Note: controller and switch are in root namespace, and we
  28. # can connect via loopback interface
  29. #switch0.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' )
  30. print switch0.cmd(r'ovs-vsctl show')
  31. print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=1,in_port=1,actions=flood' )
  32. print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=1,in_port=2,actions=flood' )
  33. print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=1,in_port=3,actions=flood' )
  34. print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.1,actions=output:1' )
  35. print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,actions=output:2' )
  36. print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.3,actions=output:3')
  37. #switch0.cmd('tcpdump -i s0-eth0 -U -w aaa &')
  38. #h0.cmd('tcpdump -i h0-eth0 -U -w aaa &')
  39. info( "*** Running test\n" )
  40. h0.cmdPrint( 'ping -c 3 ' + h1.IP() )
  41. h0.cmdPrint( 'ping -c 3 ' + h2.IP() )
  42. #print switch0.cmd( 'ovs-ofctl show dp0' )
  43. #print switch0.cmd( 'ovs-ofctl dump-tables dp0' )
  44. #print switch0.cmd( 'ovs-ofctl dump-ports dp0' )
  45. #print switch0.cmd( 'ovs-ofctl dump-flows dp0' )
  46. #print switch0.cmd( 'ovs-ofctl dump-aggregate dp0' )
  47. #print switch0.cmd( 'ovs-ofctl queue-stats dp0' )
  48. info( "*** Stopping network\n" )
  49. switch0.cmd( 'ovs-vsctl del-br dp0' )
  50. switch0.deleteIntfs()
  51. info( '\n' )
  52. if __name__ == '__main__':
  53. setLogLevel( 'info' )
  54. info( '*** Scratch network demo (kernel datapath)\n' )
  55. Mininet.init()
  56. myNet()
  • 运行结果

image.png
image.png
image.png
image.png

(2)创建 ovsMultiBr.py 脚本并运行

  • 实验内容

在没有控制器的情况下,在Mininet 脚本中通过调用 ovs 命令给多个交换机下发流表,通过 h0 ping h1 操作测试验证主机间的连通性,并通过-Q 参数设置不通的 tos 值查看主机间的连通性。通过验证发现,tos 值设置越大,时间使用越少。

  • ovsMultiBr.py 对应拓扑

Open vSwitch 实验——Mininet 中使用 OVS 命令 - 图7

  • ovsMultiBr.py 对应代码

image.png

  1. #!/usr/bin/python
  2. from mininet.net import Mininet
  3. from mininet.node import Node
  4. from mininet.link import TCLink
  5. from mininet.log import setLogLevel, info
  6. def myNet():
  7. "Create network from scratch using Open vSwitch."
  8. info( "*** Creating nodes\n" )
  9. switch0 = Node( 's0', inNamespace=False )
  10. switch1 = Node( 's1', inNamespace=False )
  11. switch2 = Node( 's2', inNamespace=False )
  12. switch3 = Node( 's3', inNamespace=False )
  13. switch4 = Node( 's4', inNamespace=False )
  14. h0 = Node( 'h0' )
  15. h1 = Node( 'h1' )
  16. info( "*** Creating links\n" )
  17. linkopts0=dict(bw=100, delay='1ms', loss=0)
  18. linkopts1=dict(bw=1, delay='100ms', loss=0)
  19. linkopts2=dict(bw=10, delay='50ms', loss=0)
  20. linkopts3=dict(bw=100, delay='1ms', loss=0)
  21. TCLink( h0, switch0, **linkopts0)
  22. TCLink( switch0, switch1, **linkopts0)
  23. TCLink( switch0, switch2, **linkopts0)
  24. TCLink( switch0, switch3, **linkopts0)
  25. TCLink( switch1, switch4, **linkopts1)
  26. TCLink( switch2, switch4, **linkopts2)
  27. TCLink( switch3, switch4, **linkopts3)
  28. TCLink( h1, switch4, **linkopts0)
  29. info( "*** Configuring hosts\n" )
  30. h0.setIP( '192.168.123.1/24' )
  31. h1.setIP( '192.168.123.2/24' )
  32. info( str( h0 ) + '\n' )
  33. info( str( h1 ) + '\n' )
  34. info( "*** Starting network using Open vSwitch\n" )
  35. switch0.cmd( 'ovs-vsctl del-br dp0' )
  36. switch0.cmd( 'ovs-vsctl add-br dp0' )
  37. switch1.cmd( 'ovs-vsctl del-br dp1' )
  38. switch1.cmd( 'ovs-vsctl add-br dp1' )
  39. switch2.cmd( 'ovs-vsctl del-br dp2' )
  40. switch2.cmd( 'ovs-vsctl add-br dp2' )
  41. switch3.cmd( 'ovs-vsctl del-br dp3' )
  42. switch3.cmd( 'ovs-vsctl add-br dp3' )
  43. switch4.cmd( 'ovs-vsctl del-br dp4' )
  44. switch4.cmd( 'ovs-vsctl add-br dp4' )
  45. for intf in switch0.intfs.values():
  46. print intf
  47. print switch0.cmd( 'ovs-vsctl add-port dp0 %s' % intf )
  48. for intf in switch1.intfs.values():
  49. print intf
  50. print switch1.cmd( 'ovs-vsctl add-port dp1 %s' % intf )
  51. for intf in switch2.intfs.values():
  52. print intf
  53. print switch2.cmd( 'ovs-vsctl add-port dp2 %s' % intf )
  54. for intf in switch3.intfs.values():
  55. print intf
  56. print switch3.cmd( 'ovs-vsctl add-port dp3 %s' % intf )
  57. for intf in switch4.intfs.values():
  58. print intf
  59. print switch4.cmd( 'ovs-vsctl add-port dp4 %s' % intf )
  60. print switch1.cmd(r'ovs-ofctl add-flow dp1 idle_timeout=0,priority=1,in_port=1,actions=flood' )
  61. print switch1.cmd(r'ovs-ofctl add-flow dp1 idle_timeout=0,priority=1,in_port=1,actions=output:2' )
  62. print switch1.cmd(r'ovs-ofctl add-flow dp1 idle_timeout=0,priority=1,in_port=2,actions=output:1' )
  63. print switch2.cmd(r'ovs-ofctl add-flow dp2 idle_timeout=0,priority=1,in_port=1,actions=output:2' )
  64. print switch2.cmd(r'ovs-ofctl add-flow dp2 idle_timeout=0,priority=1,in_port=2,actions=output:1' )
  65. print switch3.cmd(r'ovs-ofctl add-flow dp3 idle_timeout=0,priority=1,in_port=1,actions=output:2' )
  66. print switch3.cmd(r'ovs-ofctl add-flow dp3 idle_timeout=0,priority=1,in_port=2,actions=output:1' )
  67. print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=1,actions=output:4' )
  68. print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=2,actions=output:4' )
  69. print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=3,actions=output:4' )
  70. print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=4,actions=output:3' )
  71. #print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,actions=output:4')
  72. print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,nw_tos=0x10,actions=output:2')
  73. print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,nw_tos=0x20,actions=output:3')
  74. print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,nw_tos=0x30,actions=output:4')
  75. #print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.1,actions=output:1')
  76. #switch0.cmd('tcpdump -i s0-eth0 -U -w aaa &')
  77. #h0.cmd('tcpdump -i h0-eth0 -U -w aaa &')
  78. info( "*** Running test\n" )
  79. h0.cmdPrint( 'ping -Q 0x10 -c 3 ' + h1.IP() )
  80. h0.cmdPrint( 'ping -Q 0x20 -c 3 ' + h1.IP() )
  81. h0.cmdPrint( 'ping -Q 0x30 -c 3 ' + h1.IP() )
  82. #h1.cmdPrint('iperf -s -p 12345 -u &')
  83. #h0.cmdPrint('iperf -c ' + h1.IP() +' -u -b 10m -p 12345 -t 10 -i 1')
  84. #print switch0.cmd( 'ovs-ofctl show dp0' )
  85. #print switch1.cmd( 'ovs-ofctl show dp1' )
  86. #print switch2.cmd( 'ovs-ofctl show dp2' )
  87. #print switch3.cmd( 'ovs-ofctl show dp3' )
  88. #print switch4.cmd( 'ovs-ofctl show dp4' )
  89. #print switch0.cmd( 'ovs-ofctl dump-tables dp0' )
  90. #print switch0.cmd( 'ovs-ofctl dump-ports dp0' )
  91. #print switch0.cmd( 'ovs-ofctl dump-flows dp0' )
  92. #print switch0.cmd( 'ovs-ofctl dump-aggregate dp0' )
  93. #print switch0.cmd( 'ovs-ofctl queue-stats dp0' )
  94. #print "Testing video transmission between h1 and h2"
  95. #h1.cmd('./myrtg_svc -u > myrd &')
  96. #h0.cmd('./mystg_svc -trace st 192.168.123.2')
  97. info( "*** Stopping network\n" )
  98. switch0.cmd( 'ovs-vsctl del-br dp0' )
  99. switch0.deleteIntfs()
  100. switch1.cmd( 'ovs-vsctl del-br dp1' )
  101. switch1.deleteIntfs()
  102. switch2.cmd( 'ovs-vsctl del-br dp2' )
  103. switch2.deleteIntfs()
  104. switch3.cmd( 'ovs-vsctl del-br dp3' )
  105. switch3.deleteIntfs()
  106. switch4.cmd( 'ovs-vsctl del-br dp4' )
  107. switch4.deleteIntfs()
  108. info( '\n' )
  109. if __name__ == '__main__':
  110. setLogLevel( 'info' )
  111. info( '*** Scratch network demo (kernel datapath)\n' )
  112. Mininet.init()
  113. myNet()
  • 运行结果

image.png
image.png
image.png

(3) 创建 vlanBr.py 脚本并运行

  • 实验内容

尝试修改代码,利用 ovs 命令直接下发 VLAN 设置的流表项,最终测试 h0 和 h2 互通,h1 和 h3 互通,其余主机均不通

  • vlanBr.py对应拓扑

Open vSwitch 实验——Mininet 中使用 OVS 命令 - 图12

  • vlanBr.py对应代码

image.png

  1. #!/usr/bin/python
  2. from mininet.net import Mininet
  3. from mininet.node import Node
  4. from mininet.link import TCLink
  5. from mininet.log import setLogLevel, info
  6. def myNet():
  7. "Create network from scratch using Open vSwitch."
  8. info( "*** Creating nodes\n" )
  9. switch0 = Node( 's0', inNamespace=False )
  10. switch1 = Node( 's1', inNamespace=False )
  11. h0 = Node( 'h0' )
  12. h1 = Node( 'h1' )
  13. h2 = Node( 'h2' )
  14. h3 = Node( 'h3' )
  15. info( "*** Creating links\n" )
  16. linkopts0=dict(bw=100, delay='1ms', loss=0)
  17. linkopts1=dict(bw=1, delay='100ms', loss=0)
  18. linkopts2=dict(bw=10, delay='50ms', loss=0)
  19. TCLink( switch0, switch1, **linkopts0)
  20. TCLink( h0, switch0, **linkopts1)
  21. TCLink( h2, switch1, **linkopts1)
  22. TCLink( h1, switch0, **linkopts2)
  23. TCLink( h3, switch1, **linkopts2)
  24. info( "*** Configuring hosts\n" )
  25. h0.setIP( '192.168.123.1/24' )
  26. h1.setIP( '192.168.123.2/24' )
  27. h2.setIP( '192.168.123.3/24' )
  28. h3.setIP( '192.168.123.4/24' )
  29. info( str( h0 ) + '\n' )
  30. info( str( h1 ) + '\n' )
  31. info( str( h2 ) + '\n' )
  32. info( str( h3 ) + '\n' )
  33. info( "*** Starting network using Open vSwitch\n" )
  34. switch0.cmd( 'ovs-vsctl del-br dp0' )
  35. switch0.cmd( 'ovs-vsctl add-br dp0' )
  36. switch1.cmd( 'ovs-vsctl del-br dp1' )
  37. switch1.cmd( 'ovs-vsctl add-br dp1' )
  38. for intf in switch0.intfs.values():
  39. print intf
  40. print switch0.cmd( 'ovs-vsctl add-port dp0 %s' % intf )
  41. for intf in switch1.intfs.values():
  42. print intf
  43. print switch1.cmd( 'ovs-vsctl add-port dp1 %s' % intf )
  44. print switch0.cmd(r'ovs-ofctl -O OpenFlow13 add-flow dp0 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:3' )
  45. print switch0.cmd(r'ovs-ofctl -O OpenFlow13 add-flow dp0 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:3' )
  46. print switch0.cmd(r'sudo ovs-ofctl -O OpenFlow13 add-flow dp0 priority=1,dl_vlan=0,actions=pop_vlan,output:1' )
  47. print switch0.cmd(r'sudo ovs-ofctl -O OpenFlow13 add-flow dp0 priority=1,dl_vlan=1,actions=pop_vlan,output:2' )
  48. print switch1.cmd(r'ovs-ofctl -O OpenFlow13 add-flow dp1 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:3' )
  49. print switch1.cmd(r'ovs-ofctl -O OpenFlow13 add-flow dp1 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:3' )
  50. print switch1.cmd(r'ovs-ofctl -O OpenFlow13 add-flow dp1 priority=1,dl_vlan=0,actions=pop_vlan,output:1' )
  51. print switch1.cmd(r'ovs-ofctl -O OpenFlow13 add-flow dp1 priority=1,dl_vlan=1,actions=pop_vlan,output:2' )
  52. #switch0.cmd('tcpdump -i s0-eth0 -U -w aaa &')
  53. #h0.cmd('tcpdump -i h0-eth0 -U -w aaa &')
  54. info( "*** Running test\n" )
  55. h0.cmdPrint( 'ping -Q 0x10 -c 3 ' + h1.IP() )
  56. h0.cmdPrint( 'ping -Q 0x20 -c 3 ' + h2.IP() )
  57. h0.cmdPrint( 'ping -Q 0x30 -c 3 ' + h3.IP() )
  58. h1.cmdPrint( 'ping -Q 0x40 -c 3 ' + h2.IP() )
  59. h1.cmdPrint( 'ping -Q 0x50 -c 3 ' + h3.IP() )
  60. h2.cmdPrint( 'ping -Q 0x60 -c 3 ' + h3.IP() )
  61. #h1.cmdPrint('iperf -s -p 12345 -u &')
  62. #h0.cmdPrint('iperf -c ' + h1.IP() +' -u -b 10m -p 12345 -t 10 -i 1')
  63. info( "*** Stopping network\n" )
  64. switch0.cmd( 'ovs-vsctl del-br dp0' )
  65. switch0.deleteIntfs()
  66. switch1.cmd( 'ovs-vsctl del-br dp1' )
  67. switch1.deleteIntfs()
  68. info( '\n' )
  69. if __name__ == '__main__':
  70. setLogLevel( 'info' )
  71. info( '*** Scratch network demo (kernel datapath)\n' )
  72. Mininet.init()
  73. myNet()
  • 运行结果

image.png
image.png
image.png