• Mininet实验 测量路径损耗率


    参照:基于Mininet测量路径的损耗率

    在SDN环境中,可以利用控制器来测量特定路径的损耗率,在本实验中,基于Mininet脚本,设置特定的交换机间的路径损耗速率,然后编写POX脚本,实现对路径的损耗率的测量。

    实验介绍(参照原文):


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

    本实验需要在装有Mininet和POX的环境下运行。

    实验过程

    touch ChenMininet.py
    vim ChenMininet.py

    #Mininet example 2016/9/19 by Wasdns
    
    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: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( '
    ' )
    
    

    看上去很厉害,但是大部分还是有点没看懂,惭愧···

    修改权限:chmod +x ChenMininet.py

    接下来是编写POX文件:
    cd pox
    touch 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)
    

    执行:

    ./pox.py flow_stats
    

    打开一个新的终端,进入Mininet目录,执行刚才的文件:

    chmod +x mymininet.py
    ./mymininet.py 
    或者
    python mymininet.py
    

    结果不是很理想,POX的Controller一直没有连接上去,没有得到想要的结果:

    2016/9/29

  • 相关阅读:
    Shell 脚本学习 — 简单的执行跟踪
    CentOS — 安装Git客户端
    Linux — cat 命令的使用方法
    关于“分叉/联接方案”的一般做法
    读书笔记 —— 《MySQL技术内幕 InnoDB存储引擎》
    MySQL InnoDB 索引
    CentOS — MySQL备份 Shell 脚本
    CI system/libraries/Session.php
    WinForm 处理未处理的异常 Application.ThreadException + AppDomain.CurrentDomain.UnhandledException
    重构案例1 — ECShop (lib_common.php build_url 函数)
  • 原文地址:https://www.cnblogs.com/qq952693358/p/5883844.html
Copyright © 2020-2023  润新知