ryu实例---Hub

news/2024/5/17 19:47:04 标签: ryu, ovs, SDN, hub

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

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

第一部分:代码

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

from ryu.base import app_manager
from ryu.ofproto import ofproto_v1_3


class 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_3


class 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.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)

将方法'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.msg
        dp = msg.datapath
        ofp = dp.ofproto
        ofp_parser = dp.ofproto_parser
        dp_id = dp.id

        # 计算出in_port
        start = str(msg).index('oxm_fields') + 11
        end = 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 = None
        if msg.buffer_id == ofp.OFP_NO_BUFFER:
             data = msg.data
        print('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


http://www.niftyadmin.cn/n/1220986.html

相关文章

java 伪静态的方法

1.jar包支持urlrewritefilter-4.0.3.jar http://files.cnblogs.com/simpledev/urlrewritefilter-4.0.3.rar 2.在web.xml文件中加入&#xff1a; <filter><filter-name>UrlRewriteFilter</filter-name><filter-class>org.tuckey.web.filters.urlrewrit…

ryu实例---数据包解析

本文章基于https://ryu.readthedocs.io/en/latest/library_packet.html里面的Packet library的内容进行讲解的&#xff0c;即数据包解析的简单实现。ryu包库可以帮助我们去解析和构造各种数据协议包。 下面就着重讲一下&#xff0c;ryu如何对数据包进行解析。 首先&#xff0…

s2sh集成配置

2019独角兽企业重金招聘Python工程师标准>>> --------------------Struts2-------------------- Struts.xml的配置如下&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foun…

ryu实例---流表的操作

本文章基于https://ryu.readthedocs.io/en/latest/ofproto_v1_3_ref.html里面的Modify State Messages的内容进行讲解的&#xff0c;即openflow1.3的流表的操作的简单实现。通过这里的讲解&#xff0c;可以实现控制器对交换机的流表的增加删除等操作。 接下来&#xff0c;着重…

转发表(MAC表)、ARP表、路由表总结

https://cloud.tencent.com/developer/article/1173761

澄清大数据存储——系统集成商篇

大数据考验整合能力大数据在带来新的商机和用户的同时&#xff0c;也带来了诸多挑战。大数据存储主要考验的是技术整合能力和资源整合能力。大数据是一项持久的工程&#xff0c;也是一个不断迭代的过程&#xff0c;不能一蹴而就。业务集中在云计算、大数据和业务连续性方面的柏…

java从字符串中截取数字

java从字符串中提取数字 随便给你一个含有数字的字符串&#xff0c;比如&#xff1a; String s"eert343dfg56756dtry66fggg89dfgf"; 那我们如何把其中的数字提取出来呢&#xff1f;大致有以下几种方法&#xff0c;正则表达式&#xff0c;集合类&#xff0c;还有就是S…

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

前面的几篇博客介绍了hub、流表的操作、数据包的解析等知识(以下若有不明白之处&#xff0c;建议先把前几篇博客看完)。接下来&#xff0c;根据这些知识就可以编写自学习交换机的实例了。 第一部分&#xff1a;相关知识 转发表、路由表、ARP表之间的关系需要先行了解&#xf…