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)

来源:源码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)

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

  • 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

Ryu学习总结(持续更新)的更多相关文章

  1. 【pwn】学pwn日记——栈学习(持续更新)

    [pwn]学pwn日记--栈学习(持续更新) 前言 从8.2开始系统性学习pwn,在此之前,学习了部分汇编指令以及32位c语言程序的堆栈图及函数调用. 学习视频链接:XMCVE 2020 CTF Pw ...

  2. Pig基础学习【持续更新中】

    *本文参考了Pig官方文档以及已有的一些博客,并加上了自己的一些知识性的理解.目前正在持续更新中.* Pig作为一种处理大规模数据的高级查询语言,底层是转换成MapReduce实现的,可以作为MapR ...

  3. [读书]10g/11g编程艺术深入体现结构学习笔记(持续更新...)

    持续更新...) 第8章 1.在过程性循环中提交更新容易产生ora-01555:snapshot too old错误.P257 (这种情况我觉得应该是在高并发的情况下才会产生) 假设的一个场景是系统一 ...

  4. Java同步学习(持续更新)

    在需要考虑线程安全性的场合,可以考虑以下五种方式来实现线程的安全性: 1.同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,   ...

  5. Linux学习历程(持续更新整理中)

    1.文件目录操作命令 (1) ls   显示文件和目录列表 a ls -l  显示文件的详细信息 b ls -a 列出当前目录的所有文件,包含隐藏文件. c stat '目录/文件'   显示指定目录 ...

  6. 数据分析之Pandas和Numpy学习笔记(持续更新)<1>

    pandas and numpy notebook        最近工作交接,整理电脑资料时看到了之前的基于Jupyter学习数据分析相关模块学习笔记.想着拿出来分享一下,可是Jupyter导出来h ...

  7. Python基础学习总结(持续更新)

    https://www.cnblogs.com/jin-xin/articles/7459977.html 嗯,学完一天,白天上班,眼睛要瞎了= = DAY1 1,计算机基础. CPU:相当于人的大脑 ...

  8. Cadence物理库 LEF 文件语法学习【持续更新】

    我是 雪天鱼,一名FPGA爱好者,研究方向是FPGA架构探索. 关注公众号,拉你进"IC设计交流群". @ 目录 一.LEF简介 1.1 通用规则 1.2 管理 LEF 文件 二. ...

  9. [Hadoop] Hadoop学习历程 [持续更新中…]

    1. Hadoop FS Shell Hadoop之所以可以实现分布式计算,主要的原因之一是因为其背后的分布式文件系统(HDFS).所以,对于Hadoop的文件操作需要有一套全新的shell指令来完成 ...

随机推荐

  1. EF Core 中DbContext不会跟踪聚合方法和Join方法返回的结果,及FromSql方法使用讲解

    EF Core中: 如果调用Queryable.Count等聚合方法,不会导致DbContext跟踪(track)任何实体. 此外调用Queryable.Join方法返回的匿名类型也不会被DbCont ...

  2. ArcMap中用python的split方法提取字段的值

    提取PROPERTY_L字段空格分隔符前面的地址编号 提取前:5105 ABERDEEN LANE 提取后:5105 提取的表达式:!PROPERTY_L!.split(" ")[ ...

  3. JS模拟Dictionary

    function Map() { this.keys = new Array(); this.data = new Array(); //添加键值对 this.set = function (key, ...

  4. 【星云测试】Wings-让单元测试智能全自动生成

    Wings-让单元测试智能全自动生成 前言 单元测试是保证软件质量非常有效的手段,无论是从测试理论早期介入测试的理念来看或是从单元测试不受UI影响可以高速批量验证的特性,所以业界所倡导的测试驱动开发, ...

  5. iOS 中系统与 SDK 版本检测

    一.编译时检测 1. 判断 SDK 是否是某个版本或更高版本 ifdef __IPHONE_11_0 2.判断当前需要支持的最低版本 __IPHONE_OS_VERSION_MIN_REQUIRED ...

  6. 解决不能修改 Mysql 慢查询 long_query_time 值的问题

    起因:想修改一下自己电脑上的MySQL的 long_query_time 值,以此来测试 MySQL的慢查询功能. 可是,无论怎么改,show variables like 'long_query_t ...

  7. MySQL 基础小技巧

    把MySQL软件制作成系统服务 .把mysqld软件做成系统服务 注意:制作之前先把mysqld关掉 C:\Windows\system32>tasklist |findstr mysqld m ...

  8. 1、win10下的Docker+Redis 的下载及简单使用

    一.下载Docker: 因为始终注册docker账号不成功,所以在这里点击下载. 选中docker-for-windows/ 选中beta/ 下载这个.msi文件 二.安装 1.安装.msi文件,桌面 ...

  9. Linux系统查找清理磁盘大文件

    本文主要介绍Linux系统磁盘使用空间不足时,如何查找大文件并进行清理的方法. 使用df-h检查一台服务器磁盘使用空间,发现磁盘已经使用了100%,其中/dev/mapper/vg_iavp-lv_r ...

  10. JavaScript入门学习(0)相关 软件工具

    JavaScript本地脚本编辑工具(1st JavaScript Editor Pro ) 必要设置     https://pan.baidu.com/s/1XoaNA9o0qt2eJfLgoZ5 ...