- 如果你想管理网络节点(如交换机,路由器,或者其他的)按照自己的方式,你需要写一个你自己的RYuApp,你的应用再去告诉Ryu你想怎样去管理这些节点,然后Ryu控制这些节点通过使用Openflow协议,或者其他的协议。
from ryu.base import app_manager
class L2Switch(app_manager.RyuApp):
def __init__(self, *args, **kwargs):
super(L2Switch, self).__init__(*args, **kwargs)
上边是一段Ryu代码,Ryu使用Python编写,创建了一个子类,需要继承app_manager.RyuApp,再定义一个初始化方法,保存之后这段代码便可以运行,但是没有任何功能。
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): 这是基于上边的代码添加的新方法,当Ryu收到Openflow的packet_in包时被调用
msg = ev.msg
dp = msg.datapath
ofp = dp.ofproto
ofp_parser = dp.ofproto_parser
actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]
out = ofp_parser.OFPPacketOut(
datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,
actions=actions)
dp.send_msg(out)
@set_ev_cls是一个装饰器,监听事件,
1、装饰器的第一个参数(ofp_event.EventOFPPacketIn)表示调用函数的事件,
每当Ryu收到packet_in数据包时,就调用该方法。
2、第二个参数(MAIN_DISPATCHER)指示交换机的状态,Probably, youwant to ignore packet_in messages before the negotiation between Ryuand the switch finishes. Using 'MAIN_DISPATCHER' as the secondargument means this function is called only after the negotiationcompletes.
- ev.msg是一个对象,表示packet_in的数据结构
- msg.datapath是一个对象,表示数据通路(switch)
- dp.ofproto和dp.ofproto_parser也是一个对象,表示Ryu与switch之间的Openflow协议。
- OFPActionOutput类,使用一个packet_out消息指定要发送的数据包到一个交换机端口,需要switch发送到所以的端口,所以使用OFPP_FLOOD
- OFPPacketOut class 是用来建立一个packet_out 消息.
- If you call Datapath class's send_msg method with a OpenFlow messageclass object, Ryu builds and send the on-wire data format to the switch.