zoukankan      html  css  js  c++  java
  • 4 Mininet测量路径的损耗率

    原理

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

    本实验拓扑图:

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

    实验环境

    需要安装有 POX 和支持OpenFlow1.3协议的Mininet下运行。

    如果是在ubuntu中用apt安装的,需要从另一台用源码装的机器中拷贝整个pox文件夹过来,用于运行pox脚本。

    步骤

    1 在装有POX的虚拟机里新建文件flow_stats.py。

    cd pox
    vim flow_stats.py
    
    #!/usr/bin/python
    # Copyright 2012 William Yu
    # wyu@ateneo.edu
    #
    # This file is part of POX.
    #
    # POX is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.
    #
    # POX is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with POX. If not, see <http://www.gnu.org/licenses/>.
    #
     
    """
    This is a demonstration file created to show how to obtain flow 
    and port statistics from OpenFlow 1.0-enabled switches. The flow
    statistics handler contains a summary of web-only traffic.
    """
     
    # standard includes
    from pox.core import core
    from pox.lib.util import dpidToStr
    import pox.openflow.libopenflow_01 as of
    from pox.lib.addresses import IPAddr, EthAddr
     
    # include as part of the betta branch
    from pox.openflow.of_json import *
    from pox.lib.recoco import Timer
    import time
     
    log = core.getLogger()
     
    src_dpid = 0
    dst_dpid = 0
    input_pkts = 0
    output_pkts = 0
     
    def getTheTime():  #fuction to create a timestamp
      flock = time.localtime()
      then = "[%s-%s-%s" %(str(flock.tm_year),str(flock.tm_mon),str(flock.tm_mday))
      
      if int(flock.tm_hour)<10:
        hrs = "0%s" % (str(flock.tm_hour))
      else:
        hrs = str(flock.tm_hour)
      if int(flock.tm_min)<10:
        mins = "0%s" % (str(flock.tm_min))
      else:
        mins = str(flock.tm_min)
      if int(flock.tm_sec)<10:
        secs = "0%s" % (str(flock.tm_sec))
      else:
        secs = str(flock.tm_sec)
      then +="]%s.%s.%s" % (hrs,mins,secs)
      return then
     
    # handler for timer function that sends the requests to all the
    # switches connected to the controller.
    def _timer_func ():
      for connection in core.openflow._connections.values():
        connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request()))
        connection.send(of.ofp_stats_request(body=of.ofp_port_stats_request()))
      log.debug("Sent %i flow/port stats request(s)", len(core.openflow._connections))
     
    # handler to display flow statistics received in JSON format
    # structure of event.stats is defined by ofp_flow_stats()
    def _handle_flowstats_received (event):
       #stats = flow_stats_to_list(event.stats)
       #log.debug("FlowStatsReceived from %s: %s", dpidToStr(event.connection.dpid), stats)
       global src_dpid, dst_dpid, input_pkts, output_pkts
       #print "src_dpid=", dpidToStr(src_dpid), "dst_dpid=", dpidToStr(dst_dpid)
       for f in event.stats:
         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: 
           #print "input: ", f.byte_count, f.packet_count
           input_pkts = f.packet_count
         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:
           #print "output: ", f.byte_count, f.packet_count  
           output_pkts = f.packet_count
           if input_pkts !=0:
             print getTheTime(), "Path Loss Rate =", (input_pkts-output_pkts)*1.0/input_pkts*100, "%"
     
    # handler to display port statistics received in JSON format
    def _handle_portstats_received (event):
       #print "
    <<<STATS-REPLY: Return PORT stats for Switch", event.connection.dpid,"at ",getTheTime()
       #for f in event.stats:
          #if int(f.port_no)<65534:
            #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
            #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 
      stats = flow_stats_to_list(event.stats)
      log.debug("PortStatsReceived from %s: %s", dpidToStr(event.connection.dpid), stats)
     
    def _handle_ConnectionUp (event):
      global src_dpid, dst_dpid
      print "ConnectionUp: ", dpidToStr(event.connection.dpid)
      for m in event.connection.features.ports:
        if m.name == "s0-eth0":
          src_dpid = event.connection.dpid
        elif m.name == "s1-eth0":
          dst_dpid = event.connection.dpid
     
      msg = of.ofp_flow_mod()
      msg.priority =1
      msg.idle_timeout = 0
      msg.match.in_port =1
      msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
      event.connection.send(msg)
     
      msg = of.ofp_flow_mod()
      msg.priority =1
      msg.idle_timeout = 0
      msg.match.in_port =2
      msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
      event.connection.send(msg)
     
      msg = of.ofp_flow_mod()
      msg.priority =10
      msg.idle_timeout = 0
      msg.hard_timeout = 0
      msg.match.dl_type = 0x0800
      msg.match.nw_tos = 0x64
      msg.match.in_port=1
      msg.match.nw_dst = "192.168.123.2"
      msg.actions.append(of.ofp_action_output(port = 2))
      event.connection.send(msg)
     
      msg = of.ofp_flow_mod()
      msg.priority =10
      msg.idle_timeout = 0
      msg.hard_timeout = 0
      msg.match.dl_type = 0x0800
      msg.match.nw_tos = 0x64
      msg.match.nw_dst = "192.168.123.1"
      msg.actions.append(of.ofp_action_output(port = 1))
      event.connection.send(msg)
        
    # main functiont to launch the module
    def launch ():
      # attach handsers to listners
      core.openflow.addListenerByName("FlowStatsReceived", 
        _handle_flowstats_received) 
      core.openflow.addListenerByName("PortStatsReceived", 
        _handle_portstats_received) 
      core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp)
     
      # timer set to execute every five seconds
      Timer(1, _timer_func, recurring=True)
    

    2 运行flow_stats.py,需借助pox.py

    ./pox.py flow_stats
    

    3 编写和运行mymininet.py

    注意,下面配置controller的ip,应该填pox控制器所在的ip,在本机做实验所以用 127.0.0.1

    switch.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' )
    switch1.cmd( 'ovs-vsctl set-controller dp1 tcp:127.0.0.1:6633' )
    

    完整代码:

    #!/usr/bin/python
     
    from mininet.net import Mininet
    from mininet.node import Node
    from mininet.link import TCLink
    from mininet.log import  setLogLevel, info
    from threading import Timer
    from mininet.util import quietRun
    from time import sleep
     
    def myNet(cname='controller', cargs='-v ptcp:'):
        "Create network from scratch using Open vSwitch."
        info( "*** Creating nodes
    " )
        controller = Node( 'c0', inNamespace=False )
        switch = Node( 's0', inNamespace=False )
        switch1 = Node( 's1', inNamespace=False )
        h0 = Node( 'h0' )
        h1 = Node( 'h1' )
        
        info( "*** Creating links
    " )
        linkopts0=dict(bw=100, delay='1ms', loss=0)
        linkopts1=dict(bw=100, delay='1ms', loss=10)
        link0=TCLink( h0, switch, **linkopts0)
        link1 = TCLink( switch, switch1, **linkopts1)     
        link2 = TCLink( h1, switch1, **linkopts0)
        #print link0.intf1, link0.intf2
        link0.intf2.setMAC("0:0:0:0:0:1")
        link1.intf1.setMAC("0:0:0:0:0:2")
        link1.intf2.setMAC("0:1:0:0:0:1") 
        link2.intf2.setMAC("0:1:0:0:0:2")
     
        info( "*** Configuring hosts
    " )
        h0.setIP( '192.168.123.1/24' )
        h1.setIP( '192.168.123.2/24' )
           
        info( "*** Starting network using Open vSwitch
    " )
        switch.cmd( 'ovs-vsctl del-br dp0' )
        switch.cmd( 'ovs-vsctl add-br dp0' )
        switch1.cmd( 'ovs-vsctl del-br dp1' )
        switch1.cmd( 'ovs-vsctl add-br dp1' )
     
        controller.cmd( cname + ' ' + cargs + '&' )     
        for intf in switch.intfs.values():
            print intf
            print switch.cmd( 'ovs-vsctl add-port dp0 %s' % intf )
        for intf in switch1.intfs.values():
            print intf
            print switch1.cmd( 'ovs-vsctl add-port dp1 %s' % intf )
       
        # Note: controller and switch are in root namespace, and we
        # can connect via loopback interface
        switch.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' )
        switch1.cmd( 'ovs-vsctl set-controller dp1 tcp:127.0.0.1:6633' )
        # switch.cmd( 'ovs-vsctl set-controller dp0 tcp:10.0.0.13:6633' )
        # switch1.cmd( 'ovs-vsctl set-controller dp1 tcp:10.0.0.13:6633' )
      
        info( '*** Waiting for switch to connect to controller' )
        while 'is_connected' not in quietRun( 'ovs-vsctl show' ):
            sleep( 1 )
            info( '.' )
        info( '
    ' )
     
        #info( "*** Running test
    " )
        h0.cmdPrint( 'ping -Q 0x64 -c 20 ' + h1.IP() )
        
        sleep( 1 ) 
        info( "*** Stopping network
    " )
        controller.cmd( 'kill %' + cname )
        switch.cmd( 'ovs-vsctl del-br dp0' )
        switch.deleteIntfs()
        switch1.cmd( 'ovs-vsctl del-br dp1' )
        switch1.deleteIntfs()
        info( '
    ' )
     
    if __name__ == '__main__':
        setLogLevel( 'info' )
        info( '*** Scratch network demo (kernel datapath)
    ' )
        Mininet.init()
        myNet()
    
    chmod +x mymininet.py
    sudo python mymininet.py
    

    参考:https://www.sdnlab.com/15100.html

  • 相关阅读:
    python各种类型转换-int,str,char,float,ord,hex,oct等
    pandas快速入门
    python里面,将多个list列表合并成一个list列表
    对字符串进行切分的技巧
    Ubuntu 16.04 安装navicat (tar.gz)
    ubuntu 16.04 如何升级系统的scrapy旧版本(1.0.3)到最新版本
    ubuntu下,敲命令scrapy出现:0: UserWarning: You do not have a working installation of the service_identity module: 'cannot import name 'opentype''. Please install it from <https://pypi.python.org/pypi/servic
    Ubuntu下解压缩zip,tar,tar.gz,tar.bz2格式的文件
    简单的查看进程信息
    python正则表达式
  • 原文地址:https://www.cnblogs.com/xrszff/p/11259015.html
Copyright © 2011-2022 走看看