• RyuBook1.0案例二:Traffic Monitor项目源码分析


    Traffic Monitor源码分析

    从simple_switch_13.SimpleSwitch13控制器继承并开发

    class SimpleMonitor13(simple_switch_13.SimpleSwitch13):
    

    增添datapaths列表,存储交换机id

    def __init__(self, *args, **kwargs):
        super(SimpleMonitor13, self).__init__(*args, **kwargs)
        self.datapaths = {}
    

    引入hub.spawn()函数启动一个新线程,输入为一个新的方法_monitor

    创建一个EventOFPStateChange监听事件,监听MAIN_DISPATCHER,DEAD_DISPATCHER两种情况。

    @set_ev_cls(ofp_event.EventOFPStateChange,
                    [MAIN_DISPATCHER, DEAD_DISPATCHER])
    

    监听如果为MAIN_DISPATCHER,并且datapath.id不在datapath列表中,则证明是新加入的交换机

    if ev.state == MAIN_DISPATCHER:
          if datapath.id not in self.datapaths:
               self.logger.debug('register datapath: %016x', datapath.id)
               self.datapaths[datapath.id] = datapath
    

    如果为DEAD_DISPATCHER,并且datapath.id在datapath列表中,则证明是掉线的交换机

     elif ev.state == DEAD_DISPATCHER:
            if datapath.id in self.datapaths:
                self.logger.debug('unregister datapath: %016x', datapath.id)
                del self.datapaths[datapath.id]
    

    _monitor方法,循环不断向datapath列表中的交换机发送Flow状态请求,和Port状态请求

    def _monitor(self):
        while True:
            for dp in self.datapaths.values():
                self._request_stats(dp)
            hub.sleep(10)
    
    
    def _request_stats(self, datapath):
          self.logger.debug('send stats request: %016x', datapath.id)
          ofproto = datapath.ofproto
          parser = datapath.ofproto_parser
    
          req = parser.OFPFlowStatsRequest(datapath)
          datapath.send_msg(req)
    
          req = parser.OFPPortStatsRequest(datapath, 0, ofproto.OFPP_ANY)
          datapath.send_msg(req)
    

    刚刚发送了请求,现在监听其回复

    @set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER)
    ...
    
    @set_ev_cls(ofp_event.EventOFPPortStatsReply, MAIN_DISPATCHER)
    ...
    

    打印返回的信息

    for stat in sorted([flow for flow in body if flow.priority == 1],
                       key=lambda flow: (flow.match['in_port'],
                                         flow.match['eth_dst'])):
        self.logger.info('%016x %8x %17s %8x %8d %8d',
                         ev.msg.datapath.id,
                         stat.match['in_port'], stat.match['eth_dst'],
                         stat.instructions[0].actions[0].port,
                         stat.packet_count, stat.byte_count)
    
    ...
    for stat in sorted(body, key=attrgetter('port_no')):
         self.logger.info('%016x %8x %8d %8d %8d %8d %8d %8d',
              ev.msg.datapath.id, stat.port_no,
              stat.rx_packets, stat.rx_bytes, stat.rx_errors,
              stat.tx_packets, stat.tx_bytes, stat.tx_errors)
    
    

    其中sorted ... lambda语法,指元组的排列顺序按照先in_porteth_dst

    至此,整个程序解析完毕。

  • 相关阅读:
    Collections类
    delphi Tdxribbon 设置背景和skin 皮肤
    模拟一个带背景的 TPanel
    将控件画成圆角的效果(Delphi)
    Delphi自写组件:可设置颜色的按钮
    delphi StringGrid 表格的复制粘贴
    学习人工智能
    python 环境搭建和Spyder的安装应用
    python 廖雪峰的官方网站
    spyder 安装
  • 原文地址:https://www.cnblogs.com/NinWoo/p/9398351.html
Copyright © 2020-2023  润新知