目录

1.Ryu+Mininet应用案例一

1.1Hub+Learning

1.2结果显示

2.Ryu+Mininet应用案例二

2.1Learning Switch/自学习交换机

2.2案例实现

2.3结果显示

3.Ryu+Mininet应用案例三

3.1流量监控

3.1.1流量监控原理

3.2案例实现

3.3结果显示


1.Ryu+Mininet应用案例一

1.1Hub+Learning

通过控制器来实现集线器算法(泛洪),然后指导数据平面实现集线器操作。

在Ryu控制器源码的ryu/app目录下创建hub.py文件。代码如下:

#集线器的应用
class Hub(app_manager.RyuApp):""" 集线器一个端口输入,其余端口输出 """OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]   #说明OpenFlow协议版本为1.3def __init__(self,*args,**kwargs):super(Hub, self).__init__(*args,**kwargs)@set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER)       # 注册:在配置状态下(CONFIG_DISPATCHER)监听事件(EventOFPSwitchFeatures)def switch_features_handler(self,event):      #处理交换机的连接,也就是处理上面所监听到的事件#当接收到Switch Features(Features Reply)消息时(在交换机与控制器握手时接收),Table-miss流表项被添加。#当交换机握手(handshake)完成后,Table-miss流表项被添加到流表中,准备接收Packet-In消息#解析datapath=event.msg.datapath    #datapath在OpenFlow协议中定义,等同于数据平面的通道或Bridge网桥ofproto=datapath.ofprotoofp_parser=datapath.ofproto_parser#install the table-miss flow entry 安装table-miss流表项match =ofp_parser.OFPMatch()   #指明Match域actions=[ofp_parser.OFPActionOutput(          #指明动作集ofproto.OFPP_CONTROLLER,  #说明发送端口为CONTROLLERofproto.OFPCML_NO_BUFFER)]  #数据包在Buffer中存入的Buffer_id,此处不存放Buffer_idself.add_flow(datapath,0,match,actions)def add_flow(self,datapath,priority,match,actions):   #添加流表#add a flow entry,and install it into datapathofproto=datapath.ofprotoofp_parser=datapath.ofproto_parser#construct a flow_mod msg and sent it     (通过Flow-mod消息增删交换机的流表项)inst=[ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]  #添加指令 #指令的动作是:当执行当此指令集时,就执行其动作Actions  #执行的对象flow_mod=ofp_parser.OFPFlowMod(datapath=datapath,priority=priority,match=match,instructions=inst)datapath.send_msg(flow_mod)        #发送信息  使用Ryu,当接收到OpenFlow消息时,将生成与该消息对应的事件@set_ev_cls(ofp_event.EventOFPPacketIn,MAIN_DISPATCHER)                 #注册:在主状态下(MAIN_DISPATCHER)监听事件(EventOFPPacketIn)def packet_in_handler(self,event):msg=event.msgdatapath=msg.datapathofproto=datapath.ofprotoofp_parser=datapath.ofproto_parserin_port=msg.match['in_port']#sent packetIn#首先construct a flow entrymatch=ofp_parser.OFPMatch()actions=[ofp_parser.OFPActionOutput(ofproto.OFPP_FLOOD)]  #对匹配到流表项的数据包,发送到OutPort的Flood端口#install flow_mod to avoid PacketIn next timeself.add_flow(datapath,1,match,actions)out=ofp_parser.OFPPacketOut(datapath=datapath,buffer_id=msg.buffer_id,in_port=in_port,actions=actions)datapath.send_msg(out)

注:ryu控制器基础内容说明:

使用Ryu,当接收到OpenFlow消息时,将生成与该消息对应的事件。

事件处理(Event handler)程序定义了一个函数,该函数的参数为事件对象,并使用ryu.controller.handler.set_ev_cls 装饰器来装饰。

事件(Event)的类名是 ryu.controller.ofp_event.EventOFP + <OpenFlow message name>  例如Packet-in消息,其事件的类名:EventOFPPacketIn。

事件状态(Event State):

ryu.controller.handler.HANDSHAKE_DISPATCHER :交换HELLO消息

ryu.controller.handler.CONFIG_DISPATCHER :等待接收SwitchFeatures消息

ryu.controller.handler.MAIN_DISPATCHER :正常状态

ryu.controller.handler.DEAD_DISPATCHER :断开连接

1.2结果显示

在终端(Terminal)启动Ryu,输入命令ryu-manager hub.py --verbose,会出现如下结果:

可以看到,ofp_event事件提供EventOFPPacketIn和EventOFPSwitchFeatures,而Hub消费到EventOFPPacketIn和EventOFPSwitchFeatures,表示集线器(Hub)功能实现。

启动Mininet,输入命令sudo mn --controller=remote,ip=xx.xx.xx.xx,port=6633,连接控制器,应用系统自带拓扑结构。

进入Mininet后,输入pingall,Ryu控制器终端会有如下结果显示:

2.Ryu+Mininet应用案例二

2.1Learning Switch/自学习交换机

注:本实例来自Ryubook

通过控制器来实现自学习交换算法,然后指导数据平面实现交换机操作。

自学习交换机原理(4歩):

①初始状态

初始状态下流表为空,主机A(host A)连接端口1(port 1),主机B连接端口4,主机C连接端口3。

②Host A ->Host B

当数据包(Packets)要从主机A发送给主机B时,一条Packet-In消息被发送(由交换机发送)并且主机A的MAC地址被端口1获取到,因为主机B的端口还没有发现主机B的MAC地址,控制器也不知道主机B的地址,所以数据包(Packets)被洪泛(控制器下发的Packet-out:action),则主机B和主机C都会收到数据包。

Packet-In消息内容:

in-port:1

eth-dst:Host B

eth-src:Host A

Packet-out消息内容:

action:OUTPUT:Flooding

注:当控制器需要发送分组到数据平面,这时可以通过Packet-out消息封装好数据分组传给OpenFlow,并在该消息中指定特定的动作表指导交换机处理这个数据分组,而不再进行流表的匹配(除非动作表中包含转发到Table的动作)。

③Host B -> Host A

当主机B收到数据包后会返回(reply)消息,此时交换机会给控制器发送Packet-In,控制器会下发packet-out,此时一条流表项(Entry)下发被添加到流表中,数据包(Packets)从主机B返回到主机A。由于主机C并不是目的主机,所以之前主机C收到的数据包后不会返回到主机A(不会发送Reply)会丢弃掉,流表中也不会添加别的流表项。

Packet-In:

in-port:1

eth-dst:Host A

eth-src:Host B

Packet-Out:

action:OUTPUT:Port 1

④Host A ->Host B

当数据包再次从主机A发送到主机B时,交换机上发一条Packet-in消息给控制器,此时控制器知道怎么到达主机B,所以控制器发送Packet-out消息,此时一条流表项被添加到流表中,交换机收到Packet-out后就会将数据包(Packets)发送到数据B。

Packet-In:

in-port:1

eth-dst:Host B

eth-src:Host A

Packet-Out:

action:OUTPUT:Port 4

2.2案例实现

在Ryu控制器源码的ryu/app目录下创建example_switch.py文件,代码如下。

from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet"""
Base组件只包含模块管理器(app_manager)单个组件,它是Ryu应用组件的管理中枢,
具有加载Ryu应用组件、为组件提供上下文(Context)及传递组件消息的作用
"""
class ExampleSwitch(app_manager.RyuApp):"""app_manager中定义的RyuApp类是Ryu应用组件的基础类,Ryu应用组件需要定义继承该类的子类。"""OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]def __init__(self, *args, **kwargs):super(ExampleSwitch, self).__init__(*args, **kwargs)# initialize mac address table.self.mac_to_port = {}          #mac地址到port的对应关系@set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER)  # 注册:在配置状态下(CONFIG_DISPATCHER)监听事件(EventOFPSwitchFeatures)def switch_features_handler(self, event):  # 处理交换机的连接,也就是处理上面所监听到的事件# 解析datapath = event.msg.datapath  # datapath在OpenFlow协议中定义,等同于数据平面的通道或Bridge网桥ofproto = datapath.ofprotoofp_parser = datapath.ofproto_parser# install the table-miss flow entry 安装table-miss流表项match = ofp_parser.OFPMatch()  # 指明Match域actions = [ofp_parser.OFPActionOutput(  # 指明动作集ofproto.OFPP_CONTROLLER,  # 说明发送端口为CONTROLLERofproto.OFPCML_NO_BUFFER)]  # 数据包在Buffer中存入的Buffer_id,此处不存放Buffer_idself.add_flow(datapath, 0, match, actions)def add_flow(self, datapath, priority, match, actions):  # 添加流表# add a flow entry,and install it into datapathofproto = datapath.ofprotoofp_parser = datapath.ofproto_parser# construct a flow_mod msg and sent it     (通过Flow-mod消息增删交换机的流表项)inst = [ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]  # 添加指令 #指令的动作是:当执行当此指令集时,就执行其动作Actions  #执行的对象flow_mod = ofp_parser.OFPFlowMod(datapath=datapath, priority=priority, match=match, instructions=inst)datapath.send_msg(flow_mod)  # 发送信息@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)  # 注册:在主状态下(MAIN_DISPATCHER)监听事件(EventOFPPacketIn)def packet_in_handler(self, event):msg = event.msgdatapath = msg.datapathofproto = datapath.ofprotoofp_parser = datapath.ofproto_parser#逻辑:实现自学习算法#1.获取datapath id 来定位或识别OpenFlow交换机dpid=datapath.idself.mac_to_port.setdefault(dpid,{})#2.保存从OpenFlow交换机获取到的信息#3.解析收到的packets信息 analyse the received packets using the packet librarypkt=packet.Packet(msg.data)eth_pkt=pkt.get_protocol(ethernet.ethernet)   #以太网数据包dst=eth_pkt.dst      #目的mac地址src=eth_pkt.src      #源mac地址in_port=msg.match['in_port']       #从packet-in消息中收到端口号self.logger.info("--- packet in %s %s %s %s",dpid,src,dst,in_port)#4.学会源mac地址到port端口的映射信息,从而避免下一次出现FLOOD操作self.mac_to_port[dpid][src]=in_port#5.如果目的mac地址已经学到,就下发流表项指定端口发送数据包(packets);若果目的mac地址没有学到,则下发流表项的action为flooding(泛洪)if dst in self.mac_to_port[dpid]:out_port=self.mac_to_port[dpid][dst]else:out_port=ofproto.OFPP_FLOOD#6.构造一个 actionsactions=[ofp_parser. OFPActionOutput(out_port)]#7.安装一个flow消息     install a flow to avoid packet_in next timeif out_port !=ofproto.OFPP_FLOOD:match=ofp_parser.OFPMatch(in_port=in_port,eth_dst=dst)self.add_flow(datapath,1,match,actions)    #下发流表#8.构造packet_out消息并且发送packet-outpacketOut=ofp_parser.OFPPacketOut(datapath=datapath,buffer_id=msg.buffer_id,in_port=in_port,actions=actions,data=msg.data)datapath.send_msg(packetOut)

2.3结果显示

在终端(Terminal)启动Ryu,输入命令ryu-manager example_switch.py --verbose,会出现如下结果:

当开启Mininet后(控制平面与数据平面连接上后),有如下结果:

在Mininet中使用pingall/h1 ping h2(使用Mininet默认拓扑2个主机)命令后,有如下结果:

从结果中可以看出,主机1向主机2发出数据包(packets),首先主机1发出数据包后,交换机发送packet-in消息给控制器,由于控制器不知道主机B的地址,所以下发packet-out消息,action为OFPP_FLOOD,从上图可以看出第一次的目的mac地址为ff:ff:ff:ff:ff:ff(ARP请求);然后主机B收到后会向主机A发送packetReply消息,此时控制器就知道主机B的地址,然后下发流表项;最后当主机A再次向主机B发送数据包时,此时控制器就可以找到主机B,直接发送数据包。

3.Ryu+Mininet应用案例三

3.1流量监控

3.1.1流量监控原理:

1)控制器向交换机周期下发获取统计消息,请求交换机信息

①端口流量统计信息

②请求流表项统计信息

2)根据交换机统计信息计算流量信息

①流速公式:speed=(s(t1)-s(t0))/(t1-t0)

②端口/链路剩余带宽公式:free_bw=capability-speed

3.2案例实现

在Ryu控制器源码的ryu/app目录下创建 MyMonitor13.py文件,代码如下。

# 编码时间: 2021/3/3 17:25
# @File : my_monitor_13.py
# @software : PyCharm
from operator import attrgetterfrom ryu.app import simple_switch_13
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, DEAD_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.lib import hubclass MyMonitor13(simple_switch_13.SimpleSwitch13):def __init__(self, *args, **kwargs):          #初始化函数super(MyMonitor13, self).__init__(*args, **kwargs)self.datapaths = {}          #初始化成员变量,用来存储数据self.monitor_thread = hub.spawn(self._monitor)    #用协程方法执行_monitor方法,这样其他方法可以被其他协程执行。 hub.spawn()创建协程"""Controller组件主要由OpenFlowController和Datapath两类构成,其中,OpenFlowController负责监听与Ryu连接的OpenFlow网络中的事件,一旦有事件发生,会创建一个Datapath对象负责接收来自该事件的连接和数据,并将这些事件的数据分组进行解析,封装成Ryu的事件对象,然后派发。"""#get datapath info 获取datapath信息#EventOFPStateChange事件用于检测连接和断开。@set_ev_cls(ofp_event.EventOFPStateChange,[MAIN_DISPATCHER,DEAD_DISPATCHER])#通过ryu.controller.handler.set_ev_cls装饰器(decorator)进行注册,在运行时,ryu控制器就能知道MyMonitor13这个模块的函数_state_change_handler监听了一个事件def _state_change_handler(self,event):  #交换机状态发生变化后,让控制器数据于交换机一致datapath=event.datapathif event.state == MAIN_DISPATCHER:            # 在MAIN_DISPATCHER状态下,交换机处于上线状态if datapath.id not in self.datapaths:self.logger.debug('register datapath: %016x',datapath.id)self.datapaths[datapath.id]=datapath   #datapath用字典来保存,key为id,value为datapathelif event.state == DEAD_DISPATCHER:          #在DEAD_DISPATCHER状态下if datapath.id in self.datapaths:self.logger.debug('unregister datapath:%016x',datapath.id)del self.datapaths[datapath.id]#send request msg periodicallydef _monitor(self):while True:              #对已注册交换机发出统计信息获取请求每10秒无限地重复一次for dp in self.datapaths.values():  #遍历所有的交换机或网桥self._request_stats(dp)hub.sleep(10)         #休眠#send stats request msg to datapath        (完成控制器主动下发逻辑)def _request_stats(self,datapath):self.logger.debug('send stats request:%016x',datapath.id)ofproto=datapath.ofprotoofp_parser=datapath.ofproto_parser   #解析器# send flow stats request msgrequest=ofp_parser.OFPFlowStatsRequest(datapath)datapath.send_msg(request)# send port stats request msgrequest=ofp_parser.OFPPortStatsRequest(datapath,0,ofproto.OFPP_ANY)datapath.send_msg(request)#handle the port stats reply msg             (完成交换机被动发送逻辑)@set_ev_cls(ofp_event.EventOFPPortStatsReply,MAIN_DISPATCHER)def _port_stats_reply_handler(self,event):body=event.msg.body     #消息体self.logger.info('datapath         port      ''rx-pkts  rx-bytes rx-error '  'tx-pkts  tx-bytes tx-error ')     # rx-pkts:receive packets tx-pks:transmit packetsself.logger.info('---------------- -------- ''-------- -------- -------- ''-------- -------- --------')for stat in sorted(body,key=attrgetter('port_no')):     #attrgetter:属性获取工具self.logger.info('%016x %8x %8d %8d %8d %8d %8d %8d',event.msg.datapath.id, stat.port_no,stat.rx_packets, stat.rx_bytes, stat.rx_errors,stat.tx_packets, stat.tx_bytes, stat.tx_errors)#handle the flow entry stats reply msg@set_ev_cls(ofp_event.EventOFPFlowStatsReply,MAIN_DISPATCHER)def _flow_stats_reply_handler(self,event):body=event.msg.body    # body:OFPFlowStats的列表,存储受FlowStatsRequest影响每个流表项的统计信息self.logger.info('datapath         ''in-port  eth-dst           ''out-port packets  bytes')self.logger.info('---------------- ''-------- ----------------- ''-------- -------- --------')for stat in sorted([flow for flow in body if flow.priority==1],key=lambda flow:(flow.match['in_port'],flow.match['eth_dst'])):self.logger.info('%016x %8x %17s %8x %8d %8d',event.msg.datapath.id,stat.match['in_port'],stat.match['eth_dst'],stat.instructions[0].actions[0].port,stat.packet_count,stat.byte_count)

3.3结果显示

流量监控:

交换机连接上控制器,首先注册datapath

然后控制器主动下发请求request;最后通过处理Reply数据包得到相应数据。

控制器Ryu+Mininet完成集线器、自学习交换机、流量监控实例开发相关推荐

  1. 基本中型网络的仿真(RYU+Mininet的SDN架构)-以校园为例

    目录 ​​​​​​​具体问题可以私聊博主 一.设计目标 1.1应用场景介绍 1.2应用场景设计要求 网络配置方式 网络技术要求 网络拓扑要求 互联互通 二.课程设计内容与原理 (1)预期网络拓扑结构和 ...

  2. RYU+Mininet的SDN架构-设计校园网络(三)

    这是基于RYU+Mininet的SDN架构设计仿真校园网络的第一部分 总体详见:[基本中型网络的仿真(RYU+Mininet的SDN架构)-以校园为例]​​​​​​ 章节: [RYU+Mininet的 ...

  3. ryu实例---自学习交换机

    前面的几篇博客介绍了hub.流表的操作.数据包的解析等知识(以下若有不明白之处,建议先把前几篇博客看完).接下来,根据这些知识就可以编写自学习交换机的实例了. 第一部分:相关知识 转发表.路由表.AR ...

  4. SDN实验(四)——Learning Switch自学习交换机

    SDN实验(四)--Learning Switch自学习交换机 一.自学习交换机原理 (一)普通交换机实现 (二)SDN交换机实现 二.自学习交换机代码实现 (一)代码 (二)代码讲解 (三)实验 三 ...

  5. RYU+Mininet的SDN架构-设计校园网络(四)

    这是基于RYU+Mininet的SDN架构设计仿真校园网络的第四部分 总体详见:[基本中型网络的仿真(RYU+Mininet的SDN架构)-以校园为例]​​​​​​ 上一章:[RYU+Mininet的 ...

  6. RYU+Mininet实现Hub泛洪

    RYU+Mininet实现Hub泛洪 系统:Ubuntu20.10 ,已安装 ryu 和 mininet 在ryu/ryu/app下创建了文件hub.py,代码如下: hub.py(含注释) from ...

  7. RYU+Mininet的SDN架构-设计校园网络(一)

    这是基于RYU+Mininet的SDN架构设计仿真校园网络的第一部分 总体详见:[基本中型网络的仿真(RYU+Mininet的SDN架构)-以校园为例] 前言: 本次设计基于虚拟机以及Ubuntu18 ...

  8. 集线器、交换机与路由器

    一.名词解释: 集线器:(Hub)是指将多条以太网双绞线或光纤集合连接在同一段物理介质下的设备.集线器发生在物理层. 交换机:(Switch)是一种用于电(光)信号转发的网络设备.它可以为接入交换机的 ...

  9. 集线器、交换机和路由器之间的区别

    三种设备是相似的,但是他们处理数据的方式有所不同 集线器和交换机就是一栋大楼里面的内部电话.但集线器一打电话,就整栋楼都听得到.但交换机可以专门只向哪一户可以跟指定的其中一户打电话,无关人员听不到.路 ...

  10. 一个故事带你了解集线器、交换机与路由器

    本篇讲诉集线器.交换机和路由器,查看网上关于三者的讲解,觉得看完之后没有太多的理解,下面是我的理解,不对之处欢迎评论 指正! 情节一 舍友A来大学读书,意外发现dota好玩,于是决定回家带着家中的小弟 ...

最新文章

  1. JAVA学习--反射属性操作
  2. Caffeine Cache~高性能 Java 本地缓存之王
  3. 【HihoCoder - 1550】顺序三元组(思维)
  4. Mysql中慢查询Sql的记录查看
  5. easyui的datagrid的editor为combobox,根据每个row的属性的不同,如何动态的设置每个row的combobox的url...
  6. Linux下VsFTP和ProFTP用户管理高级技巧 之一
  7. 机器学习 预测模型_基于机器学习模型的汽车价格预测(第2部分)
  8. MyEclipse中用Maven创建Web项目(亲测有效)
  9. Excel将数据内容导出为数据库DBF文件的操作
  10. h5页面如何预览excel文件_在网页中预览word和excel
  11. lua如何将用户ip转为地理位置信息
  12. 解决问题multiply defined
  13. 数据处理的神来之笔 解决缓存击穿的终极利器
  14. Python爬虫使用lxml模块爬取豆瓣读书排行榜并分析
  15. Spring Cloud LoadBalanced 切换负载均衡策略
  16. 知能行vs传统备考,考研数学可以很轻松!
  17. kesu移动硬盘(固态硬盘)插上电脑后不显示盘符的解决办法
  18. Python + Tkinter:图片浏览器(二)
  19. Python自动化办公:openpyxl绘制图表
  20. pip使用豆瓣的镜像源

热门文章

  1. http 405原因
  2. VSCode插件Code Runner用于C++
  3. Android 百度地图经纬度精确位数,百度map定位 为什么经纬度是准确的 而在map上标注却偏离很远...
  4. Logstash 时间转换(YYYY-MM-dd HH:mm:ss转Unix时间)
  5. VS上位机开发——串口助手
  6. OpenCV之图像轮廓
  7. 记一次西安thoughtworks的面试经历
  8. python基于scrapy框架爬取当当图书信息
  9. 万用表测电容方法-电子技术方案
  10. u盘虚拟启动cd linux,[CDLinux]制作U盘CDLinux系统启动盘