首页 > 其他分享 >实验6:开源控制器实践——RYU

实验6:开源控制器实践——RYU

时间:2022-11-14 22:13:12浏览次数:51  
标签:控制器 ryu parser datapath msg 开源 ofproto RYU ofp

搭建下图所示SDN拓扑,协议使用Open Flow 1.0,并连接Ryu控制器,通过Ryu的图形界面查看网络拓扑。

阅读Ryu文档的The First Application一节,运行当中的L2Switch,h1 ping h2或h3,在目标主机使用 tcpdump 验证L2Switch,分析L2Switch和POX的Hub模块有何不同。

编程修改L2Switch.py,另存为L2xxxxxxxxx.py,使之和POX的Hub模块的变得一致?(xxxxxxxxx为学号)

搭建下图所示SDN拓扑,协议使用Open Flow 1.0,并连接Ryu控制器,通过Ryu的图形界面查看网络拓扑。

构建topo
sudo mn --topo=single,3 --mac --controller=remote,ip=127.0.0.1,port=6633 --switch ovsk,protocols=OpenFlow10

连接ryu控制器
ryu-manager ../ryu/ryu/app/gui_topology/gui_topology.py --observe-links

通过Ryu的图形界面查看网络拓扑,在浏览器中输入127.0.0.1:8080

2、阅读Ryu文档的The First Application一节,运行当中的L2Switch,h1 ping h2或h3,在目标主机使用 tcpdump 验证L2Switch,分析L2Switch和POX的Hub模块有何不同。

编写L2Switch.py

 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 L2Switch(app_manager.RyuApp):
     OFP_VERSIONS = [ofproto_v1_0.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)

运行L2Switch.py
ryu-manager L2Switch.py

重新构建拓扑,并对h2、h3节点进行抓包

h1 ping h2

h1 ping h3

查看流表

pox下查看拓扑流表

对比可得,ryu下查不到流表,而在pox下可查看流表!

编程修改L2Switch.py,另存为L2xxxxxxxxx.py,使之和POX的Hub模块的变得一致?(xxxxxxxxx为学号)

L2_212006206.py

from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER
from ryu.controller.handler import CONFIG_DISPATCHER, 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.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        # install table-miss flow entry
        #
        # We specify NO BUFFER to max_len of the output action due to
        # OVS bug. At this moment, if we specify a lesser number, e.g.,
        # 128, OVS will send Packet-In with invalid buffer_id and
        # truncated packet data. In that case, we cannot output packets
        # correctly.  The bug has been fixed in OVS v2.1.0.
        match = parser.OFPMatch()
        actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                          ofproto.OFPCML_NO_BUFFER)]
        self.add_flow(datapath, 0, match, actions)

    def add_flow(self, datapath, priority, match, actions, buffer_id=None):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                             actions)]
        if buffer_id:
            mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id,
                                    priority=priority, match=match,
                                    instructions=inst)
        else:
            mod = 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
        dp = msg.datapath
        ofp = dp.ofproto
        ofp_parser = dp.ofproto_parser
        in_port = msg.match['in_port']

        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=in_port,
            actions=actions, data = data)
        dp.send_msg(out)

运行L2_212006158.py
ryu-manager L2_212006206.py

创建topo
sudo mn --topo=single,3 --mac --controller=remote,ip=127.0.0.1,port=6633 --switch ovsk,protocols=OpenFlow13

测试
pingall

查看流表
dpctl dump-flows

心得体会

通过本次实验,学习了部署RYU控制器;理解RYU控制器实现软件定义的集线器原理;理解RYU控制器实现软件定义的交换机原理。
过程中遇到许多问题,参考了同学实验解决,尝试多次才解决。
查看Open vSwitch中的流表时出错。

sudo ovs-vsctl dump-flows s1

2018-03-08T06:23:42Z|00001|vconn|WARN|unix:/var/run/openvswitch/s1.mgmt: version negotiation failed (we support version 0x01, peer supports version 0x04)
ovs-ofctl: s1: failed to connect to socket (Broken pipe)
解决办法:

sudo ovs-ofctl -O OpenFlow13 dump-flows s1

添加-O OpenFlow13指定协议版本。

标签:控制器,ryu,parser,datapath,msg,开源,ofproto,RYU,ofp
From: https://www.cnblogs.com/jzl-/p/16890145.html

相关文章