Advertisement

Ryu学习总结(持续更新)

阅读量:

Ryu学习总结

这篇学习笔记与对Ryu控制器代码进行分析的笔记相异,在内容安排上主要根据程序架构进行模块化总结。鉴于本人是刚入门的学习者,在理论掌握上可能存在不足之处,请指导指正;如有其他问题或建议,请随时提出。

以下的内容主要来源:

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

处理一个事件的标准模板

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

复制代码
    @set_ev_cls(ofp_event.Event, DISPATCHER(s))
    def your_function(self, ev):
    ...
    
      
      
      
    
    代码解释

具体来说,在OFPPacketEvent框架中,
@set_ev_cls(ofp_event.Event,_DISPATCHER(s))
这一注释的作用体现在每当有DISPATCHER(s)事件发生时会自动触发your_function处理流程。

支持单个DISPATCHER以及支持多个DISPATCHER构成的列表。

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

在研习了若干个Ryu程序后,深刻认识到理解这些事件是关键;并深入解析其源码和OpenFlow 1.3.3协议的相关内容,结合官方方案例题的学习过程中

ofp_event

该Python文件中的ofp_event类主要用于实现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
    ========= =================================================================
    
      
      
      
      
      
      
      
      
      
      
      
    
    代码解释

可以理解为该类负责处理协商阶段中的变更通知事件,在协商更改完成后,则会向观察者发送此消息

当我们运行某个特定的命令时, 我们就可以充当一个观察者. 当接收到此类消息时, 我们可以依次进行接收和处理.

复制代码
    @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 表ID
duration_sec 持续秒数
duration_nsec 持续纳秒数
priority 优先级
idle_timeout 空闲超时时间和硬超时时间
hard_timeout 硬截止时间
flags 标志位
cookie 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)
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解释

来源:源码ryu\ofproto\ofproto_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)
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解释

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

receiver Packets, transmitter Packets, receiver Bytes, transmitter Bytes, receiver dropped, transmitter dropped, receiver errors, transmitter errors, receiver frame errors, transmitter overflows, receiver CRC errors, collisions, duration in seconds (单位:秒), duration in nanoseconds (单位:纳秒)

也即该事件亦有对应地存在一个端口统计请求事件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

全部评论 (0)

还没有任何评论哟~