基于ryu实现集线器的功能---Hub实现

31 篇文章 2 订阅
17 篇文章 9 订阅

Hub实现环境:两台Ubuntu虚拟机、mininet、ryu控制器、pycharm

环境搭建见前几篇文章,有具体的搭建步骤。

对于ryu的开发,推荐ryubook这本工具书。

首先,在Ubuntu上安装pycharm,安装完成后,导入ryu项目,若出现无法修改或者权限问题,则需要通过命令chmod [ u / g / o / a ] [ + / - / = ] [ r / w / x ] file修改文件的权限。

接下来,就解释一下代码的编写:

导入包,将导包放在最前面,主要是刚开始学实在不知道导入哪几个包,未来避免出错,可以将所有的包都导入,可以参考ryubook的交换机的程序。

from ryu.base import app_manager
from ryu.ofproto import ofproto_v1_3
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls

接下来,定义一个类hub,继承app_manager,位于ryu下的base内,版本选择openflow1.3,然后初始化操作。

lass hub(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]

    def __init__(self, *args, **kwargs):
        super(hub, self).__init__(*args, **kwargs)

接下来,需要定义packet in函数,用来处理交换机和控制器的流表交互,在执行之前需要先对packetin事件进行监听。

@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def packet_in_handler(self, ev):
        # 这几句是对数据结构进行解析,是一种固定的形式,可以记住就行
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        ofp_parser = datapath.ofproto_parser
        in_port = msg.match['in_port']  # get in port of the packet

        # add a flow entry for the packet
        match = ofp_parser.OFPMatch()
        actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_FLOOD)]
        self.add_flow(datapath, 1, match, actions)

        # to output the current packet. for install rules only output later packets
        out = ofp_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions)
        # buffer id: locate the buffered packet
        datapath.send_msg(out)

在Ryu控制器上,我们需要写一个函数去处理openvswitch的连接,同时需要开启一个监听,监听交换机事件。

@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_feathers_handler(self, ev):
        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        # install flow table-miss flow entry
        match = ofp_parser.OFPMatch()
        #OFPActionOutput将数据包发送出去,
        #第一个参数OFPP_CONTROLLER是接收端口,
        #第二个是数据包在交换机上缓存buffer_id,由于我们将数据包全部传送到控制器,所以不在交换            
        #机上缓存
        actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)]
        # 1\OUTPUT PORT, 2\BUFF IN SWITCH?
        self.add_flow(datapath, 0, match, actions)

 ryu的数据平面是由若干网元(Network Element)组成,每个网元包含一个或多个SDN数据路径(SDN Datapath)。SDN Datapath是逻辑上的网络设备,负责转发和处理数据无控制能力,一个SDN DataPath包含控制数据平面接口(Control Data Plane Interface,CDPI)、代理、转发引擎(Forwarding Engine)表和处理功能(Processing Function)SDN数据面(转发面)的关键技术:对数据面进行抽象建模。对于添加流表,可以将其单独拿出了写一个函数。

    def add_flow(self, datapath, priority, match, actions):
        # 1\ datapath for the switch, 2\priority for flow entry, 3\match field, 4\action for packet
        ofproto = datapath.ofproto
        ofp_parser = datapath.ofproto_parser
        # install flow
        inst = [ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
        mod = ofp_parser.OFPFlowMod(datapath=datapath, priority=priority, match=match, instructions=inst)
        datapath.send_msg(mod)

代码完成之后,就是实验的验证。

首先,在装有ryu控制器的虚拟机中,运行Hub,具体的运行步骤如下:即先进入ryu目录下,使用ryu-manager Hub.py运行Hub。

然后,实验验证需要使用mininet进行模拟网络架构,具体的模拟方式见之前的博客,此次实验的拓扑如下。交换机选择ovs,控制器远程连接ryu控制器。

然后,运行拓扑,进行pingall测试,如图显示,Hub可以成功转发数据流。

 

Hub的完整代码如下:

from ryu.base import app_manager
from ryu.ofproto import ofproto_v1_3
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls


class hub(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]

    def __init__(self, *args, **kwargs):
        super(hub, self).__init__(*args, **kwargs)

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_feathers_handler(self, ev):
        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        # install flow table-miss flow entry
        match = ofp_parser.OFPMatch()
        actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)]
        # 1\OUTPUT PORT, 2\BUFF IN SWITCH?
        self.add_flow(datapath, 0, match, actions)

    def add_flow(self, datapath, priority, match, actions):
        # 1\ datapath for the switch, 2\priority for flow entry, 3\match field, 4\action for packet
        ofproto = datapath.ofproto
        ofp_parser = datapath.ofproto_parser
        # install flow
        inst = [ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
        mod = ofp_parser.OFPFlowMod(datapath=datapath, priority=priority, match=match, instructions=inst)
        datapath.send_msg(mod)

    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        ofp_parser = datapath.ofproto_parser
        in_port = msg.match['in_port']  # get in port of the packet

        # add a flow entry for the packet
        match = ofp_parser.OFPMatch()
        actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_FLOOD)]
        self.add_flow(datapath, 1, match, actions)

        # to output the current packet. for install rules only output later packets
        out = ofp_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions)
        # buffer id: locate the buffered packet
        datapath.send_msg(out)

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楊木木8023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值