Ryu快速入门

Posted by Bokala on March 20, 2016

Ryu是一个以组件为基础的软件定义网络开发框架。 通过Ryu自身提供的各种丰富的API,开发者可以轻松的实现需求的网络管理功能,Ryu支持多种软件定义网络的协议,例如OpenFlow,NetConf,OF-config等。

1. 安装

  • 环境:python-eventlet, python-routes, python-webob, python-paramiko
  • pip安装
$ pip install ryu
  • 源文件安装
$ git clone https://github.com/osrg/ryu 
$ git clone git://github.com/osrg/ryu.git //两种均可以,任选其一
$ cd ryu
$ sudo pip install -r tools/pip-requires
$ sudo python setup.py install

2. 开始使用

$ ryu-manager app.py

3. Ryu框架及组件介绍

ryu

4. Ryu应用程序API

  • 开发模型

线程Threads $\Rightarrow$ 事件Events $\Rightarrow$ 事件队列Event queues

Ryu中,APP是一个实现网络功能的实例化的单线程应用程序,事件是不同APP之间传递的消息;Ryu的APP之间通过异步消息(事件)来进行通讯,此外,还有一些不是Ryu的APP产生的事件,例如OpenFlow Controller就是一个会产生Ryu事件的一个非Ryu的APP。

每个Ryu应用程序(APP)都会有一个用于接受事件的队列,该队列是FIFO,它保持一个先进先出的规则,每个Ryu应用程序都会有一个专门用于处理事件的线程,将事件队列中的事件取出并传递到相应的方法做处理,这时要注意避免事件线程拥塞,因为当事件线程出现拥塞时,不会处理之后的事件。

在Ryu中,线程和事件队列使用的是eventlet/greenlet。

上下文Contexts

Contexts是一个用于共享不同APP之间的python对象。

  • 如何开发一个APP

Ryu的APP是一个继承了ryu.base.app_manager.RyuApp的子类模块,一个APP是一个独立执行个体,对应一个实例对象。

  1. 事件接收:APP通过 ryu.controller.handler.set_ev_cls 来注册需要接收的事件
  2. 事件生成:可通过ryu.base.app_manager.RyuApp的send_event或send_event_to_observers传送事件到特定APP或注册该事件的APP
  3. 事件类:事件类表示了Ryu中生成的事件,一般,在名称前加上“Event”来标记事件类。

OpenFlow事件类

当交换机转发OpenFlow消息时,ryu.controller.ofp_event能将其消息转换成事件类别,在Ryu中,控制器会自动将接收到的OpenFlow消息解码,然后转发至ryu.controller.handler.set_ev_cls 注册该事件的APP。

classryu.controller.ofp_event.EventOFPMsgBase(msg)

属性 描述
msg 描述对应OpenFlow消息的对象
msg.datapath 接收到该消息的ryu.controller.controller.Datapath实例
timestamp Datapath实例生成该事件的时间戳
  • ryu.controller.handler.set_ev_cls(ev_cls, dispatchers=None)

APP注册事件的装饰器,被装饰的方法作为该事件处理器,ev_cls 表示要处理的事件类,dispatchers表示该事件处理器处理此类型事件的阶段。

阶段 描述
ryu.controller.handler.HANDSHAKE_DISPATCHER 送出以及等待 hello 消息
ryu.controller.handler.CONFIG_DISPATCHER 版本协议以及送出feature-request消息
ryu.controller.handler.MAIN_DISPATCHER 接收 Switch-features 消息以及转发set-config 消息
ryu.controller.handler.DEAD_DISPATCHER 连接中断或未知错误导致双方连接中断
  • ryu.controller.controller.Datapath(socket, address)

描述了连接控制器的交换机类,任何APP需要转发OpenFlow消息均需要通过该类的实例来给控制器转发。

属性 描述
id 64位的OpenFlow Datapath ID,该属性只在ryu.controller.handler.MAIN_DISPATCHER 阶段有效
ofproto 表示该控制器使用的OpenFlow版本, 该属性以 ryu.ofproto.ofproto_vxxx 为主
ofproto_parser 该属性是一个以该交换器所用协议实例化的编解码器
ofproto_parser.OFPxxxx(datapath, ….) 通过OFPXXX产生消息,并用send_msg方法转发给交换机
set_xid(self, msg) 产生一个OpenFlow的XID,然后将这个XID放到msg.xid中
send_msg(self, msg) 将消息放到事件队列中,随后会被一个专门转发消息的线程转发
send_packet_out 将弃用
send_flow_mod 将弃用
send_flow_del 将弃用
send_delete_all_flows 将弃用
send_barrier 将barrier消息放置到转发用的队列中
send_nxt_set_flow_format 将弃用
is_reserved_port 将弃用
  • ryu.controller.event.EventBase

所有事件类的基类

  • ryu.base.app_manager.RyuApp(*args, **kwargs)

Ryu APP的基类,在ryu_manager加载完成所有APP模块之后实例化。

属性 描述
OFP_VERSIONS=None 此APP支持的所有OpenFlow版本列表
_CONTEXTS={} 用于指定该APP要使用的上下文的字典,key是context名称,value是对应的子类
_EVENTS=[] 此APP生成的事件列表,该事件类的定义一定要在不同的模块中
close() 拆卸方法
context_iteritems() 返回(kwy, context class)的APP context迭代器
reply_to_request(req, rep) 发送来自send_request的同步请求回复
send_event(name,ev,state=None) 将事件发送到指定名称的APP实例中
send_event_to_observers(ev,state=None) 发送指定事件到接收的APP中
send_request(req) 发送一个同步请求
start() 启动初始化完成之后,调用Hook