前言
SDN 是未来网络的发展方向,其中RYU是受到大家推荐的控制器,今天,我们就来学习它。
目录
实现你的控制器
如果你想控制网络设备,比如,交换机或者路由器,你只需要实现RYU应用即可。
你可以用你自己定义的控制规则,管理网络设备。只需要满足openflow协议即可
而且 RYU控制器的实现非常简单,和其他python代码一模一样。
第一个例子
让我们开始吧!
这里我们实现了一个仅实现二层转发功能的openflow交换机,通过编写python代码实现的ryu应用。
首先,使用你最顺手的python编辑器,并创建一个文件
将以下python代码写入。
from ryu.base import app_manager
class L2Switch(app_manager.RyuApp):
def __init__(self, *args, **kwargs):
super(L2Switch, self).__init__(*args, **kwargs)
Ryu应用和其他python程序文件一样,这里我们为了方便,将该文件命名为 test1.py,方便之后的使用。
这个文件仅仅是个演示,它啥也不做,但也是一个完整的Ryu控制器了。
现在,我们来做一个测试,
% ryu-manager test1.py
loading app test1.py
instantiating app test1.py of L2Switch
我是在windows平台上做的测试,其他平台看到的东西可能不一样。
功能增加
我们定义的类是RyuApp的子类。
Ryu控制器就是python的脚步。
接下来,我们添加把所有的包发送给所有端口的功能。
//导入要用的包
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_0
//二层交换机类
class L2Switch(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION]
def __init__(self, *args, **kwargs):
super(L2Switch, self).__init__(*args, **kwargs)
//装饰器
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def packet_in_handler(self, ev):
msg = ev.msg
dp = msg.datapath
ofp = dp.ofproto
ofp_parser = dp.ofproto_parser
actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]
data = None
if msg.buffer_id == ofp.OFP_NO_BUFFER:
data = msg.data
out = ofp_parser.OFPPacketOut(
datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,
actions=actions, data = data)
dp.send_msg(out)
我们给L2Switch 类添加了新功能,“packet_in_handler”,在Ryu接受到一个openflow packe_in消息包时会调用这个功能。‘Set_ev_cls’装饰器是个小技巧,这个装饰器告诉Ryu在什么时候调用这个装饰功能。
装饰器的第一个参数指明了什么时候应该调用它,正如这个函数展示的那样,每当Ryu处理一个 packet_in消息时,它都会使用这个装饰器。
第二个参数指明了,交换机的状态,在交换机和Ryu协商结束之前,你可能想忽略packet_in这个消息。
可以使用"main_dispatcher"作为第二个参数来实现这个功能,即在Ryu和交换机协商结束之前,再调用这个装饰器函数。
现在,我们来分析一下packet_in_handler 函数
ev.msg 代表了packet_in数据结构
msg.dp 代表了 交换机路径
dp.ofproto and dp.ofproto_parser代表了Ryu和交换机协商的openflow协议。
接下来看剩下的部分。
OFPActionOutput 类指明了,该包发往那个交换机端口。当它为OFPP_FLOOD时,发往发往所有端口。
OFPPacketOut 类用来构造一个packet_out 消息。
如果你在openflow对象的情况下调用了Dp的send_msg方法,Ryu会使用on-wire数据格式。
现在,你已经实现你的Ryu控制器了。
有问题的可以关注公众号,博主会在24小时内回复。