RYU控制器代码解析-Hub
2017-09-20 07:58
911 查看
我们的目标是用Python程序实现一个Hub,Hub的主要功能是把收到的数据包进行泛洪,Hub的算法有很多,这里以官方给出的一个来说明。
OpenFlow 交换机可以根据控制器(如RYU)的指令来进行以下操作:
1.重写收到数据包的地址,或者从指定的接口传输数据包。
2.传输收到的数据包给控制器(Packet-In)。
2.传输由控制器指定的转发接口的数据包(Packet-Out)。
下面放上代码:
开始的两行是因为官方默认的RYU程序在ryu/ryu/app目录里面,导入的格式就都是这样的,所以如果在外面的文件夹里创建了app程序,就需要修改导入格式,很麻烦,于是我把目录改了。
app_manager是RYU应用的管理中心,它加载应用,在应用之间传递消息。
controller是控制器的主要组成部分,处理交换机的连接,生成事件并将事件送到控制器。
还要引入一个OpenFlow协议的版本。
首先我们定义一个类名叫Hub。
为了使用版本1.0,我们在类的开头设定了版本。1_0指的是1.0,1_3是1.3版本,然后初始化这个类。
当控制器收到OpenFlow消息的时候,我们的控制器需要一个处理消息的方法,于是我们定义了packet_in_handler函数,由set_ev_cls修饰器来调用这个函数,在修饰器里面我们可以指定一个事件,当这个事件发生的时候会调用下面的函数;在本例中,第一个参数是收到Packet-In消息,第二个参数表示的是交换机的状态,本例中交换机的状态是正常状态,也就是说在交换机和控制器协商完成之前不会调用以下的函数。
说到这里,我们有必要讲一下set_ev_cls支持的消息的事件类和交换机的状态参数。
事件类名字叫做ryu.controller.ofp_event.EventOFP + 。
例如:Packet-In消息,名字就是EventOFPPacketIn。
对于状态,请参考以下表格:
接下来我们开始看packet_in_handler函数:
ev在这里就是Packet-In数据包的数据结构。
msg是OpenFlow消息类的一个实例。
msg.datapath就是该数据包的发送者交换机的ID。
ofproto_parser和ofproto是跟OpenFlow协议结构和解析有关的。
当收到数据包的时候,交换机因为没有流表,会请求控制器做决定。
然后是后半部分的函数:
OFPActionOutput是和Packet-Out报文一起使用的,用来指定传出接口。
OFPP_FLOOD指的是泛洪的端口。
OFPPacketOut被用来构建一个Packet-Out信息。
send_msg构建在线的数据格式发送到对应datapath的交换机。
控制器对所有的数据包的处理方式都是以广播的形式发出去。
需要注意的是:本例的代码需要运行在OpenFlow1.0下,如果运行在其他版本上,会出现问题。
代码解析完成,下面展示运行过程:
1.首先我们使用mininet创建一个拓扑。
mn –topo linear,2 –mac –switch ovsk –controller remote
这个命令的意思是创建一个线性拓扑,两台交换机各自连接一个主机然后相连。
mac地址采用简化版的,使用Openvswitch交换机。
2.然后就可以运行RYU文件了。
运行完毕之后,使用ping测试,通信成功。
在Ryu控制器上我们可以看到以下输出:
因为是Hub,所以如果多连接几台电脑,其他的电脑也能收到他们的ICMP报文,大家有兴趣的可以自行抓包查看。
有关Hub的解析到此结束。
OpenFlow 交换机可以根据控制器(如RYU)的指令来进行以下操作:
1.重写收到数据包的地址,或者从指定的接口传输数据包。
2.传输收到的数据包给控制器(Packet-In)。
2.传输由控制器指定的转发接口的数据包(Packet-Out)。
下面放上代码:
#by man #!/usr/bin/env python #!!!!!OpenFlow-1.0 import sys sys.path.append("/home/manminglei/ryu") 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 Hub(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] def __init__(self, *args, **kwargs): super(Hub, self).__init__(*args, **kwargs) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) #decorator declare an event handler #the first parameter is an event which ryu wants to receive def packet_in_handler(self, ev): msg=ev.msg # ev = PacketIn'data structure msg = openflow message dp = msg.datapath #dp=switch'id 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) self.logger.info("switch is %s,buffer_id is %s,in_port is %s.",dp.id,msg.buffer_id,msg.in_port)
开始的两行是因为官方默认的RYU程序在ryu/ryu/app目录里面,导入的格式就都是这样的,所以如果在外面的文件夹里创建了app程序,就需要修改导入格式,很麻烦,于是我把目录改了。
app_manager是RYU应用的管理中心,它加载应用,在应用之间传递消息。
controller是控制器的主要组成部分,处理交换机的连接,生成事件并将事件送到控制器。
还要引入一个OpenFlow协议的版本。
首先我们定义一个类名叫Hub。
为了使用版本1.0,我们在类的开头设定了版本。1_0指的是1.0,1_3是1.3版本,然后初始化这个类。
当控制器收到OpenFlow消息的时候,我们的控制器需要一个处理消息的方法,于是我们定义了packet_in_handler函数,由set_ev_cls修饰器来调用这个函数,在修饰器里面我们可以指定一个事件,当这个事件发生的时候会调用下面的函数;在本例中,第一个参数是收到Packet-In消息,第二个参数表示的是交换机的状态,本例中交换机的状态是正常状态,也就是说在交换机和控制器协商完成之前不会调用以下的函数。
说到这里,我们有必要讲一下set_ev_cls支持的消息的事件类和交换机的状态参数。
事件类名字叫做ryu.controller.ofp_event.EventOFP + 。
例如:Packet-In消息,名字就是EventOFPPacketIn。
对于状态,请参考以下表格:
状态名 | 状态含义 |
---|---|
ryu.controller.handler.HANDSHAKE_DISPATCHER | 互相发送hello包交换信息 |
ryu.controller.handler.CONFIG_DISPATCHER | 等待接收交换机设备信息 |
ryu.controller.handler.MAIN_DISPATCHER | 一般状态 |
ryu.controller.handler.DEAD_DISPATCHER | 断开连接 |
ev在这里就是Packet-In数据包的数据结构。
msg是OpenFlow消息类的一个实例。
msg.datapath就是该数据包的发送者交换机的ID。
ofproto_parser和ofproto是跟OpenFlow协议结构和解析有关的。
当收到数据包的时候,交换机因为没有流表,会请求控制器做决定。
然后是后半部分的函数:
OFPActionOutput是和Packet-Out报文一起使用的,用来指定传出接口。
OFPP_FLOOD指的是泛洪的端口。
OFPPacketOut被用来构建一个Packet-Out信息。
send_msg构建在线的数据格式发送到对应datapath的交换机。
控制器对所有的数据包的处理方式都是以广播的形式发出去。
需要注意的是:本例的代码需要运行在OpenFlow1.0下,如果运行在其他版本上,会出现问题。
代码解析完成,下面展示运行过程:
1.首先我们使用mininet创建一个拓扑。
mn –topo linear,2 –mac –switch ovsk –controller remote
这个命令的意思是创建一个线性拓扑,两台交换机各自连接一个主机然后相连。
mac地址采用简化版的,使用Openvswitch交换机。
2.然后就可以运行RYU文件了。
运行完毕之后,使用ping测试,通信成功。
在Ryu控制器上我们可以看到以下输出:
因为是Hub,所以如果多连接几台电脑,其他的电脑也能收到他们的ICMP报文,大家有兴趣的可以自行抓包查看。
有关Hub的解析到此结束。
相关文章推荐
- Ryu控制器代码解析-任意地址Ping应答
- RYU控制器代码解析-简单交换机
- Ryu代码解析(五)
- Ryu代码解析(六)
- RYU控制器代码结构的总结
- discuz代码解析(二、控制器与视图解析)
- Ryu代码解析(一)
- Ryu控制器controller/event.py源码解析
- Ryu代码解析(二)
- RYU控制器代码结构的总结
- Ryu代码解析(三)
- Ryu代码解析(四)
- 论--如何通过代码解析plist文件创建对应的控制器,以及控制器中的控件
- KMP算法 next函数 代码解析
- 中缀逻辑表达式解析成前缀逻辑表达式代码--java(以elasticsearch搜索为例)
- java二维码生成与解析代码实现
- 剑指offer代码解析——面试题11求a的b次方
- 29.Case class 和Case object代码实战解析
- [置顶] 分享微博@功能jquery代码及全面解析
- java解析json,只有我自己能看懂得乱代码