• 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
    " )
    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
    " )
    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
    " )
    33     h0.setIP( '192.168.123.1/24' )
    34     h1.setIP( '192.168.123.2/24' )
    35        
    36     info( "*** Starting network using Open vSwitch
    " )
    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( '
    ' )
    60  
    61     #info( "*** Running test
    " )
    62     h0.cmdPrint( 'ping -Q 0x64 -c 20 ' + h1.IP() )
    63     
    64     sleep( 1 ) 
    65     info( "*** Stopping network
    " )
    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( '
    ' )
    72  
    73 if __name__ == '__main__':
    74     setLogLevel( 'info' )
    75     info( '*** Scratch network demo (kernel datapath)
    ' )
    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 "
    <<<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信息:

    结果符合预期。

  • 相关阅读:
    github打开慢,甚至打不开
    在使用confluent-kafka-go 时遇到如下问题
    Istio Routing极简教程
    kubelet证书过期解决方法
    工具类docker for k8s
    selenium jar包 的下载地址,各版本都有
    使用TestNG进行多浏览器,跨浏览器和并行测试
    简单聊聊TestNG中的并发
    清除Git仓库多余文件及其历史记录 
    【MAVEN】maven系列--pom.xml标签详解
  • 原文地址:https://www.cnblogs.com/pullself/p/10176945.html
Copyright © 2020-2023  润新知