本文章基于https://ryu.readthedocs.io/en/latest/writing_ryu_app.html里面的第一个应用,即hub的简单实现。但是,按照这里的原程序,出现了一些问题,这篇文章里我给出了一些我自己的解决方案。

接下来,我就按照官网的示例进行讲解。

第一部分:代码

新建一个类L2Switch,内容如下:

from ryu.base import app_manager
from ryu.ofproto import ofproto_v1_3class L2Switch(app_manager.RyuApp):OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)

从ryu.base import app_manager,在开发APP的时候只需要继承这个基类,就获得你想要的一个APP的一切了。from ryu.ofproto import ofproto_v1_3意思是导入openflow1.3协议的数据,本次开发就是使用openflow1.3协议。此时,这个程序就是一个完整的程序了,运行并没有错误,但是由于尚未添加如何处理代码,所以这段程序说明也做不了。

接下来,接需要继续向类中添加代码以完成hub功能的开发。

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_3class L2Switch(app_manager.RyuApp):OFP_VERSIONS = [ofproto_v1_3.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.msgdp = msg.datapathofp = dp.ofprotoofp_parser = dp.ofproto_parseractions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]data = Noneif msg.buffer_id == ofp.OFP_NO_BUFFER:data = msg.dataout = ofp_parser.OFPPacketOut(datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,actions=actions, data = data)dp.send_msg(out)

将方法'packet_in_handler'添加到L2Switch类中。当ryu控制器收到OpenFlow packet_in消息时,将调用此方法。

其中“ set_ev_cls”装饰器。该装饰器告诉Ryu何时应调用装饰的函数。装饰器的第一个参数表示事件发生时应调用此函数。即,每次Ryu收到packet_in消息时,都会调用此函数。第二个参数表示交换机的状态。ryu与交换机之间的握手完成之前忽略packet_in消息,使用“ MAIN_DISPATCHER”作为第二个参数表示仅在握手完成后才调用此函数。

接下来,介绍“ packet_in_handler”函数的前半部分。

  • ev.msg是表示packet_in数据结构的对象。
  • msg.dp是代表已经格式化的msg其实就是一个packet_in报文,msg.datapath直接可以获得packet_in报文的datapath结构。datapath用于描述一个交换网桥,也是和控制器通信的实体单元。datapath.send_msg()函数用于发送数据到指定datapath,通过datapath.id可获得dpid数据。
  • dp.ofproto和dp.ofproto_parser是代表Ryu和交换机握手的OpenFlow协议的对象。

接下来时函数的下半部分。

  • OFPActionOutput类与packet_out消息一起使用,以指定要从中发送数据包的交换机端口。该应用程序使用OFPP_FLOOD标志来指示应在所有端口上发送数据包。
  • OFPPacketOut类用于构建packet_out消息。
  • 如果使用OpenFlow消息类对象调用Datapath类的send_msg方法,则Ryu会生成联机数据格式并将其发送到交换机。

至此,一个完整的HUB功能就可以实现了。(当然,这只是官网这样说的,在我实际操作中发现有错误,接下来,我就介绍一下我遇到的问题和解决方案)

第二部分:实验

首先,利用mininet构建网络拓扑,如下所示。

在Ubuntu终端命令行中运行HUB程序,命令如下。

root@yang-VirtualBox:/home/yang/ryu/ryu/app# ryu-manager hub1_yjl.py

接下来,设置c0控制器,h1、h2、h3的ip地址分别为10.0.0.1、10.0.0.2、10.0.0.3。全部设置完成后,运行拓扑。

运行拓扑后,在Ubuntu命令行查看交换机s1的流表,可以发现s1并未有任何流表项存在,所以此时需要手动添加默认流表项,如下所示。

在mininet命令行中输入命令 h1 ping h3,此时观察控制器输出的日志信息,如下所示。

可以看出,报错AttributeError: 'OFPPacketIn' object has no attribute 'in_port'。也就是说,程序msg.in_port报错,并没有in_port。至于为什么没有,主要是官网示例给的是openflow1.0版本的,而这里我用的是openflow1.3版本的,所以收到的msg的格式有所差别。通过将msg打印到控制台上,打印结果如下。

可以看出,msg中包含的还是会有in_port的信息的,所以为了解决错误,我们只需要将in_port的信息提取出来就可以了。为此,我改进了一下代码,多了处理字符串的部分,提取出in_port的值。改进后的完整代码如下。(当然,这里完全可用json解析出in_port数据,但是为了更清晰看出示例,我使用字符串一点点解析的)

from ryu.base import app_manager
from ryu.controller.handler import set_ev_cls
from ryu.controller.handler import MAIN_DISPATCHER
from ryu.controller import ofp_event
from ryu.ofproto import ofproto_v1_3
'''
实现了一个hub的功能,
即控制器通过packet_in数据包的解析,进行命令的下发,
这个程序的一切指令处理均在控制器进行,并不会进行流表的下发,只会下发转发指令,
所以,在运行之前需要手动在ovs上添加默认controller的流表
'''class L2Switch(app_manager.RyuApp):OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)def packet_in_handler(self, ev):msg = ev.msgdp = msg.datapathofp = dp.ofprotoofp_parser = dp.ofproto_parserdp_id = dp.id# 计算出in_portstart = str(msg).index('oxm_fields') + 11end = str(msg).index('),reason')inport_str = str(msg)[start:end]instr = eval(inport_str)in_port = instr['in_port']actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]data = Noneif msg.buffer_id == ofp.OFP_NO_BUFFER:data = msg.dataprint('id:{0}'.format(dp_id))print('in_port:{0}'.format(in_port))out = ofp_parser.OFPPacketOut(datapath=dp, buffer_id=msg.buffer_id, in_port=in_port,actions=actions, data=data)dp.send_msg(out)

接下来,重新在Ubuntu控制台运行程序。在mininet命令行中输入命令 h1 ping h3,此时可以看出h1 h3之间和相互ping通了,切换h2主机也可以,至此,HUB程序就实现了,各位也可以使用tcpdump监控一下链路的数据流,看看是否真的实现了,这里我就不在赘述。

github地址:https://github.com/Yang-Jianlin/ryu/blob/master/ryu/app/hub1_yjl.py

ryu实例---Hub相关推荐

  1. ryu实例---网络时延探测

    一.前言 前面的博文写到了基于跳数的最短路径的案例实现(ryu实例---基于跳数的最短路径转发_北风-CSDN博客),然而基于跳数的最短路径转发并未考虑网络链路的质量(时延.可用带宽.丢包率...), ...

  2. ryu实例---基于跳数的最短路径转发

    参考网上的一些知识,本篇内容主要介绍如何利用networkx实现最短路径转发,同时介绍ryu如何获取链路拓扑. 一.获取拓扑 对于ryu控制器而言,获取链路拓扑的主要模块在ryu/topology目录 ...

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

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

  4. ryu实例---数据包解析

    本文章基于https://ryu.readthedocs.io/en/latest/library_packet.html里面的Packet library的内容进行讲解的,即数据包解析的简单实现.r ...

  5. ryu实例---ECMP的rr(轮询)算法实现

    最近,做到一个实验,需要每隔一段时间,就改变数据的传输路径,如下图所示,主机之间的数据传输需要经过s1和s2两个交换机,交换机之间的链路有两条,实验是在这两条链路之间每隔10秒切换一次,也就是相当于E ...

  6. 【Openstack】实录手动部署Openstack Rocky 双节点(5)- Neutron

    第一篇:手动部署Openstack Rocky 双节点(1)- 基础服务 上一篇:手动部署Openstack Rocky 双节点(4)- Nova 下一篇:手动部署Openstack Rocky 双节 ...

  7. 前端开发基础知识汇总

    一.HTML 1.前言与常用标签 浏览器 内核 备注 IE Trident IE.猎豹安全.360极速浏览器.百度浏览器 firefox Gecko 可惜这几年已经没落了,打开速度慢.升级频繁.猪一样 ...

  8. ryu---北向接口(利用socket对外通信)

    一.原理 最近有人问ryu控制器如何实现与应用层(如web.app等)的通信,实际上,实现通信就需要利用SDN的北向接口,关于SDN的北向接口,各种文章的解释不一,难以理解.实质上,北向接口实现的功能 ...

  9. 使用docker-compose 大杀器来部署服务 - 上

    我们都听过或者用过 docker,然而使用方式却是仅仅用手动的方式,这样去操作 docker 还是很原始. 好吧,可能在小白的眼中噼里啪啦的对着 term 一顿操作会很拉风,但是高手很不屑!在高手眼里 ...

  10. 使用docker-compose 大杀器来部署服务 上

    我们都听过或者用过 docker,然而使用方式却是仅仅用手动的方式,这样去操作 docker 还是很原始. 好吧,可能在小白的眼中噼里啪啦的对着 term 一顿操作会很拉风,但是高手很不屑!在高手眼里 ...

最新文章

  1. 【机器学习】太香啦!只需一行Python代码就可以自动完成模型训练!
  2. java中printarray和selectsort方法_算法题(一)
  3. CentOS7Selinux设置
  4. 地球不是圆的,别让教科书限制了孩子的想象力!
  5. ESP32开发板开源啦 ESP32-IOT-KIT全开源物联网开发板
  6. eclipse调试第一个java程序
  7. matlab库存点仿真教程,MATLAB Simulink 汽车整车动力总成仿真 视频教程
  8. 获取元素属性(offsetHeight、clientHeight...)无效
  9. AssetBundle接口详解与优化
  10. vue-router 三级路由
  11. 计算机网络应用ppt,1分钟骚操作顶别人10分钟!不可不懂的PPT神技
  12. android app隐藏图标不见了,Android 10如何隐藏应用图标
  13. R语言 生存分析与cox模型的学习笔记
  14. Spring IoC容器与Bean管理18:Bean对象的作用域及生命周期三:对象生命周期;
  15. 成为顶尖的AI算法工程师,你该具备些什么?
  16. Windows 程序设计作者
  17. word中使页眉不同的同时,页码相同 的问题解决
  18. Piggy-Bank HDU - 1114(多重背包)
  19. 数据分析师需要学习什么?
  20. 调功器PA400X系列选型+个人理解

热门文章

  1. AndroidMPChart——BarChart
  2. Java实现批量发送邮件
  3. 黑马程序员:一些简单的设计模式
  4. linux搭建代理服务器
  5. 时间序列复杂性的度量—近似熵和样本熵
  6. Android实现淘宝购物车
  7. 项目合同管理:合同分类、费用支付方式、违约责任承担方式、签订注意事项、合同索赔流程
  8. PS的一些常用快捷键和学习笔记
  9. 【Racket】安装与入门
  10. Racket 8.3下载安装(Win10)