Mininet实验 基于Mininet测量路径的损耗率

实验原理

在SDN环境中,控制器可以通过对交换机下发流表操作来控制交换机的转发行为,此外,还可以利用控制器测量路径的损耗率。在本实验中,基于Mininet脚本,设置特定的交换机间的路径损耗速率,然后编写POX脚本,实现对路径的损耗率的测量。


拓扑图:

在该环境下,h0向h1发送数据包,由于在mininet脚本中设置了连接损耗率,在传输过程中会丢失一些包,本次实验的目的是展示如何通过控制器计算路径损耗速率(h0-s0-s1-h1)。这里假设控制器预先知道网络拓扑,所以我没有显示发现网络的代码以及其他相关代码。控制器将向s0和s1发送flowstatsrequest,当控制器接收到来自s0的response时,将特定流的数据包数保存在inputpkts中,当控制器接收到来自s1的response时,将接收到特定流的数据包数保存在outputpkts中,差值就是丢失的数据包数量。

实验操作

编写mininet脚本

 1 #!/usr/bin/python
 2  
 3 from mininet.net import Mininet
 4 from mininet.node import Node
 5 from mininet.link import TCLink
 6 from mininet.log import  setLogLevel, info
 7 from threading import Timer
 8 from mininet.util import quietRun
 9 from time import sleep
10  
11 def myNet(cname='controller', cargs='-v ptcp:'):
12     "Create network from scratch using Open vSwitch."
13     info( "*** Creating nodes\n" )
14     controller = Node( 'c0', inNamespace=False )
15     switch = Node( 's0', inNamespace=False )
16     switch1 = Node( 's1', inNamespace=False )
17     h0 = Node( 'h0' )
18     h1 = Node( 'h1' )
19     
20     info( "*** Creating links\n" )
21     linkopts0=dict(bw=100, delay='1ms', loss=0)
22     linkopts1=dict(bw=100, delay='1ms', loss=10)
23     link0=TCLink( h0, switch, **linkopts0)
24     link1 = TCLink( switch, switch1, **linkopts1)     
25     link2 = TCLink( h1, switch1, **linkopts0)
26     #print link0.intf1, link0.intf2
27     link0.intf2.setMAC("0:0:0:0:0:1")
28     link1.intf1.setMAC("0:0:0:0:0:2")
29     link1.intf2.setMAC("0:1:0:0:0:1") 
30     link2.intf2.setMAC("0:1:0:0:0:2")
31  
32     info( "*** Configuring hosts\n" )
33     h0.setIP( '192.168.123.1/24' )
34     h1.setIP( '192.168.123.2/24' )
35        
36     info( "*** Starting network using Open vSwitch\n" )
37     switch.cmd( 'ovs-vsctl del-br dp0' )
38     switch.cmd( 'ovs-vsctl add-br dp0' )
39     switch1.cmd( 'ovs-vsctl del-br dp1' )
40     switch1.cmd( 'ovs-vsctl add-br dp1' )
41  
42     controller.cmd( cname + ' ' + cargs + '&' )     
43     for intf in switch.intfs.values():
44         print intf
45         print switch.cmd( 'ovs-vsctl add-port dp0 %s' % intf )
46     for intf in switch1.intfs.values():
47         print intf
48         print switch1.cmd( 'ovs-vsctl add-port dp1 %s' % intf )
49    
50     # Note: controller and switch are in root namespace, and we
51     # can connect via loopback interface
52     switch.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' )
53     switch1.cmd( 'ovs-vsctl set-controller dp1 tcp:127.0.0.1:6633' )
54   
55     info( '*** Waiting for switch to connect to controller' )
56     while 'is_connected' not in quietRun( 'ovs-vsctl show' ):
57         sleep( 1 )
58         info( '.' )
59     info( '\n' )
60  
61     #info( "*** Running test\n" )
62     h0.cmdPrint( 'ping -Q 0x64 -c 20 ' + h1.IP() )
63     
64     sleep( 1 ) 
65     info( "*** Stopping network\n" )
66     controller.cmd( 'kill %' + cname )
67     switch.cmd( 'ovs-vsctl del-br dp0' )
68     switch.deleteIntfs()
69     switch1.cmd( 'ovs-vsctl del-br dp1' )
70     switch1.deleteIntfs()
71     info( '\n' )
72  
73 if __name__ == '__main__':
74     setLogLevel( 'info' )
75     info( '*** Scratch network demo (kernel datapath)\n' )
76     Mininet.init()
77     myNet()

 PS:52,53行的地址是pox所在的ip地址,根据实际修改。不然会链接不上控制器。

编写POX脚本

  1 # standard includes
  2 from pox.core import core
  3 from pox.lib.util import dpidToStr
  4 import pox.openflow.libopenflow_01 as of
  5 from pox.lib.addresses import IPAddr, EthAddr
  6  
  7 # include as part of the betta branch
  8 from pox.openflow.of_json import *
  9 from pox.lib.recoco import Timer
 10 import time
 11  
 12 log = core.getLogger()
 13  
 14 src_dpid = 0
 15 dst_dpid = 0
 16 input_pkts = 0
 17 output_pkts = 0
 18  
 19 def getTheTime():  #fuction to create a timestamp
 20   flock = time.localtime()
 21   then = "[%s-%s-%s" %(str(flock.tm_year),str(flock.tm_mon),str(flock.tm_mday))
 22   
 23   if int(flock.tm_hour)<10:
 24     hrs = "0%s" % (str(flock.tm_hour))
 25   else:
 26     hrs = str(flock.tm_hour)
 27   if int(flock.tm_min)<10:
 28     mins = "0%s" % (str(flock.tm_min))
 29   else:
 30     mins = str(flock.tm_min)
 31   if int(flock.tm_sec)<10:
 32     secs = "0%s" % (str(flock.tm_sec))
 33   else:
 34     secs = str(flock.tm_sec)
 35   then +="]%s.%s.%s" % (hrs,mins,secs)
 36   return then
 37  
 38 # handler for timer function that sends the requests to all the
 39 # switches connected to the controller.
 40 def _timer_func ():
 41   for connection in core.openflow._connections.values():
 42     connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request()))
 43     connection.send(of.ofp_stats_request(body=of.ofp_port_stats_request()))
 44   log.debug("Sent %i flow/port stats request(s)", len(core.openflow._connections))
 45  
 46 # handler to display flow statistics received in JSON format
 47 # structure of event.stats is defined by ofp_flow_stats()
 48 def _handle_flowstats_received (event):
 49    #stats = flow_stats_to_list(event.stats)
 50    #log.debug("FlowStatsReceived from %s: %s", dpidToStr(event.connection.dpid), stats)
 51    global src_dpid, dst_dpid, input_pkts, output_pkts
 52    #print "src_dpid=", dpidToStr(src_dpid), "dst_dpid=", dpidToStr(dst_dpid)
 53    for f in event.stats:
 54      if f.match.dl_type==0x0800 and f.match.nw_dst==IPAddr("192.168.123.2") and f.match.nw_tos==0x64 and event.connection.dpid==src_dpid: 
 55        #print "input: ", f.byte_count, f.packet_count
 56        input_pkts = f.packet_count
 57      if f.match.dl_type==0x0800 and f.match.nw_dst==IPAddr("192.168.123.2") and f.match.nw_tos==0x64 and event.connection.dpid==dst_dpid:
 58        #print "output: ", f.byte_count, f.packet_count  
 59        output_pkts = f.packet_count
 60        if input_pkts !=0:
 61          print getTheTime(), "Path Loss Rate =", (input_pkts-output_pkts)*1.0/input_pkts*100, "%"
 62  
 63 # handler to display port statistics received in JSON format
 64 def _handle_portstats_received (event):
 65    #print "\n<<<STATS-REPLY: Return PORT stats for Switch", event.connection.dpid,"at ",getTheTime()
 66    #for f in event.stats:
 67       #if int(f.port_no)<65534:
 68         #print "   PortNo:", f.port_no, " Fwd's Pkts:", f.tx_packets, " Fwd's Bytes:", f.tx_bytes, " Rc'd Pkts:", f.rx_packets, " Rc's Bytes:", f.rx_bytes
 69         #print "   PortNo:", f.port_no,  " TxDrop:", f.tx_dropped, " RxDrop:", f.rx_dropped, " TxErr:", f.tx_errors, " RxErr:", f.rx_errors, " CRC:", f.rx_crc_err, " Coll:", f.collisions 
 70   stats = flow_stats_to_list(event.stats)
 71   log.debug("PortStatsReceived from %s: %s", dpidToStr(event.connection.dpid), stats)
 72  
 73 def _handle_ConnectionUp (event):
 74   global src_dpid, dst_dpid
 75   print "ConnectionUp: ", dpidToStr(event.connection.dpid)
 76   for m in event.connection.features.ports:
 77     if m.name == "s0-eth0":
 78       src_dpid = event.connection.dpid
 79     elif m.name == "s1-eth0":
 80       dst_dpid = event.connection.dpid
 81  
 82   msg = of.ofp_flow_mod()
 83   msg.priority =1
 84   msg.idle_timeout = 0
 85   msg.match.in_port =1
 86   msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
 87   event.connection.send(msg)
 88  
 89   msg = of.ofp_flow_mod()
 90   msg.priority =1
 91   msg.idle_timeout = 0
 92   msg.match.in_port =2
 93   msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
 94   event.connection.send(msg)
 95  
 96   msg = of.ofp_flow_mod()
 97   msg.priority =10
 98   msg.idle_timeout = 0
 99   msg.hard_timeout = 0
100   msg.match.dl_type = 0x0800
101   msg.match.nw_tos = 0x64
102   msg.match.in_port=1
103   msg.match.nw_dst = "192.168.123.2"
104   msg.actions.append(of.ofp_action_output(port = 2))
105   event.connection.send(msg)
106  
107   msg = of.ofp_flow_mod()
108   msg.priority =10
109   msg.idle_timeout = 0
110   msg.hard_timeout = 0
111   msg.match.dl_type = 0x0800
112   msg.match.nw_tos = 0x64
113   msg.match.nw_dst = "192.168.123.1"
114   msg.actions.append(of.ofp_action_output(port = 1))
115   event.connection.send(msg)
116     
117 # main functiont to launch the module
118 def launch ():
119   # attach handsers to listners
120   core.openflow.addListenerByName("FlowStatsReceived", 
121     _handle_flowstats_received) 
122   core.openflow.addListenerByName("PortStatsReceived", 
123     _handle_portstats_received) 
124   core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp)
125  
126   # timer set to execute every five seconds
127   Timer(1, _timer_func, recurring=True)


运行POX脚本flow_stats.py

1 ./pox.py flow_stats

运行mininet脚本

1 sudo ./sckmininet.py

mininet信息:

pox信息:

结果符合预期。

猜你喜欢

转载自www.cnblogs.com/pullself/p/10176945.html