zoukankan      html  css  js  c++  java
  • Ryu学习总结(持续更新)

    Ryu学习总结

    该篇学习笔记,与其他分析Ryu控制器代码的笔记不同,主要按照程序的构成来进行分块总结,由于本人为新手入门,不能保证没有错误,如果发现错误,欢迎指教。

    以下的内容主要来源:

    • 源码
    • 官方文档
    • OpenFlow1.3.3 手册

    处理一个事件的标准模板

    首先,我们来看一个标准的控制器处理事件的模板

    @set_ev_cls(ofp_event.Event, DISPATCHER(s))
    def your_function(self, ev):
    ...
    

    简单说,@set_ev_cls(ofp_event.Event, DISPATCHER(s))的含义就是,当接收到DISPATCHER(s)情况的Event事件进行your_function处理。

    DISPATCHER(s)可以为单独一个,也可以为由多个DISPATCHER组成的列表,DISPATCHER描述的情况包括:

    Defination Explanation
    HANDSHAKE_DISPATCHER 交换HELLO消息
    CONFIG_DISPATCHER 等待接收SwitchFeatures消息
    MAIN_DISPATCHER 正常状态
    DEAD_DISPATCHER 连接断开

    其中your_function是由你自己定义的函数处理过程,命名可以任意指定;ofp_event.Event是由ofp_event.py提供的一系列事件,在学习了几个Ryu的程序之后,深感,其核心就在于对这些事件的理解。所以,接下来,在分析学习官方案例的同时,也会整合Ryu源码与OpenFlow1.3.3协议的内容,对这些事件进行深入的理解与分析。

    ofp_event

    ofp_event类位于ryu/controller/ofp_event.py,主要定义了OpenFlow中的各种事件,配合set_cls_ev可以对指定事件进行处理。

    ofp_event.EventOFPSwitchFeatures

    ofp_event.EventOFPPacketIn

    ofp_event.EventOFPStateChange

    在源码中,对EventOFPStateChange这样进行介绍:

        An event class for negotiation phase change notification.
    
        An instance of this class is sent to observer after changing
        the negotiation phase.
        An instance has at least the following attributes.
    
        ========= =================================================================
        Attribute Description
        ========= =================================================================
        datapath  ryu.controller.controller.Datapath instance of the switch
        ========= =================================================================
    

    意思说,该class是处理协商阶段变更通知的事件,在协商更改后发生此消息给观察者。

    当我们使用一下的命令,我们就成为了观察者,发生此类消息时,便可以进行接收和处理

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

    详细案例见Traffic Monitor

    在协商阶段,MAIN_DISPATCHER意味着有新的交换机接入,DEAD_DISPATCHER意味着有交换机脱离连接。

    总结:

    发起事件 处理事件
    交换机状态变化 EventOFPStateChange

    ofp_event.EventOFPFlowStatsReply

    在源码中,对EventOFPFlowStatsReply这样介绍:

        Individual flow statistics reply message
    
        The switch responds with this message to an individual flow statistics
        request.
    

    意思说,该事件用于处理个体流量统计回复消息,即统计某一交换机上的流量信息。而流量统计信息存储在bodyev.msg.body)结构体中。具体包括:

    • table_id
    • duration_sec
    • duration_nsec
    • priority
    • idle_timeout
    • hard_timeout
    • flags
    • cookie
    • packet_count
    • byte_count
    • match
    • instructions

    使用范例:

    @set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER)
    def flow_stats_reply_handler(self, ev):
           flows = []
           for stat in ev.msg.body:
                flows.append('table_id=%s '
                       'duration_sec=%d duration_nsec=%d '
                       'priority=%d '
                       'idle_timeout=%d hard_timeout=%d flags=0x%04x '
                       'cookie=%d packet_count=%d byte_count=%d '
                       'match=%s instructions=%s' %
                       (stat.table_id,
                       stat.duration_sec, stat.duration_nsec,
                       stat.priority,
                       stat.idle_timeout, stat.hard_timeout, stat.flags,
                       stat.cookie, stat.packet_count, stat.byte_count,
                       stat.match, stat.instructions))
            self.logger.debug('FlowStats: %s', flows)
    

    来源:源码ryuofprotoofproto_v1_3_parser.py

    与上一个事件的产生来源不同,该事件并不是由交换机状态改变而产生,而是由控制器主动发出,触发该事件并接收处理的。控制器主动发出的命令为OFPFlowStatsRequest函数。

    同样,查看源码中该函数的文档

        """
        Individual flow statistics request message
    
        The controller uses this message to query individual flow statistics.
    
        ================ ======================================================
        Attribute        Description
        ================ ======================================================
        flags            Zero or ``OFPMPF_REQ_MORE``
        table_id         ID of table to read
        out_port         Require matching entries to include this as an output
                         port
        out_group        Require matching entries to include this as an output
                         group
        cookie           Require matching entries to contain this cookie value
        cookie_mask      Mask used to restrict the cookie bits that must match
        match            Instance of ``OFPMatch``
        ================ ======================================================
    

    看见,该函数作用就是发出流量统计请求的。文档同样给出范例程序:

        Example::
    
            def send_flow_stats_request(self, datapath):
                ofp = datapath.ofproto
                ofp_parser = datapath.ofproto_parser
    
                cookie = cookie_mask = 0
                match = ofp_parser.OFPMatch(in_port=1)
                req = ofp_parser.OFPFlowStatsRequest(datapath, 0,
                                                     ofp.OFPTT_ALL,
                                                     ofp.OFPP_ANY, ofp.OFPG_ANY,
                                                     cookie, cookie_mask,
                                                     match)
                datapath.send_msg(req)
    

    查看构造函数:

    def __init__(self, datapath, flags=0, table_id=ofproto.OFPTT_ALL,
                     out_port=ofproto.OFPP_ANY,
                     out_group=ofproto.OFPG_ANY,
                     cookie=0, cookie_mask=0, match=None, type_=None):
    

    实际使用过程中,如果没有特定需要,这里我们可以只指定一个datapath参数,其他为缺省的默认值。

    小结:

    发起事件 处理事件
    OFPFlowStatsRequest EventOFPFlowStatsReply

    ofp_event.EventOFPPortStatsReply

    在源码中对该函数的说明如下:

    """
        Port statistics reply message
    
        The switch responds with this message to a port statistics request.
    
        ================ ======================================================
        Attribute        Description
        ================ ======================================================
        body             List of ``OFPPortStats`` instance
        ================ ======================================================
    

    该函数为端口统计应答消息,文档中给的范例程序如下:

    Example::
    
            @set_ev_cls(ofp_event.EventOFPPortStatsReply, MAIN_DISPATCHER)
            def port_stats_reply_handler(self, ev):
                ports = []
                for stat in ev.msg.body:
                    ports.append('port_no=%d '
                                 'rx_packets=%d tx_packets=%d '
                                 'rx_bytes=%d tx_bytes=%d '
                                 'rx_dropped=%d tx_dropped=%d '
                                 'rx_errors=%d tx_errors=%d '
                                 'rx_frame_err=%d rx_over_err=%d rx_crc_err=%d '
                                 'collisions=%d duration_sec=%d duration_nsec=%d' %
                                 (stat.port_no,
                                  stat.rx_packets, stat.tx_packets,
                                  stat.rx_bytes, stat.tx_bytes,
                                  stat.rx_dropped, stat.tx_dropped,
                                  stat.rx_errors, stat.tx_errors,
                                  stat.rx_frame_err, stat.rx_over_err,
                                  stat.rx_crc_err, stat.collisions,
                                  stat.duration_sec, stat.duration_nsec))
                self.logger.debug('PortStats: %s', ports)
    

    通过案例程序,我们可以看到,从该消息中,我们可以获取到:

    • rx_packets
    • tx_packets
    • rx_bytes
    • tx_bytes
    • rx_dropped
    • tx_dropped
    • rx_errors
    • tx_errors
    • rx_frame_err
    • tx_overerr
    • rx_crc_err
    • collisions
    • duration_sec
    • duration_nsec

    同样该事件同样对应存在一个端口统计请求事件OFPPortStatsRequest,源码中对该函数的说明如下:

        """
        Port statistics request message
    
        The controller uses this message to query information about ports
        statistics.
    
        ================ ======================================================
        Attribute        Description
        ================ ======================================================
        flags            Zero or ``OFPMPF_REQ_MORE``
        port_no          Port number to read (OFPP_ANY to all ports)
        ================ ======================================================
    

    使用范例如下:

    Example::
    
            def send_port_stats_request(self, datapath):
                ofp = datapath.ofproto
                ofp_parser = datapath.ofproto_parser
    
                req = ofp_parser.OFPPortStatsRequest(datapath, 0, ofp.OFPP_ANY)
                datapath.send_msg(req)
    

    小结:

    发起事件 处理事件
    OFPPortStatsRequest EventOFPPortStatsReply
  • 相关阅读:
    SQL学习
    FOR XML PATH
    IOS学习网址
    weak nonatomic strong等介绍(ios)
    UVALive3045 POJ2000 ZOJ2345 Gold Coins
    UVA713 UVALive5539 POJ1504 ZOJ2001 Adding Reversed Numbers
    UVA713 UVALive5539 POJ1504 ZOJ2001 Adding Reversed Numbers
    UVA439 POJ2243 HDU1372 ZOJ1091 Knight Moves【BFS】
    UVA439 POJ2243 HDU1372 ZOJ1091 Knight Moves【BFS】
    UVA10905 Children's Game
  • 原文地址:https://www.cnblogs.com/NinWoo/p/9398310.html
Copyright © 2011-2022 走看看