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

一、基本要求

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

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

L2Switch.py


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)

h1 ping h2

L2Switch和POX的Hub模块有何不同:

RYU的L2Switch模块和POX的Hub模块都是洪泛转发,但pox的Hub模块是下发流表到交换机,然后交换机直接根据流表进行洪泛转发,ryu的L2Switch模块运行时不下发对应的转发流表,而是将包发送给控制器,由控制器利用packet-out指定为洪泛转发。

修改后的l2switch代码:

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)

查看流表

三、个人总结

本机的python版本不同,有一些函数的名字已经改变了,导致一开始一直现实找不到相对性的函数。多亏有同学和我遇到了相同的问题并在总结中说明了解决方法,靠他给的方法很成功就让ryu运行了。

posted @ 2022-10-19 16:49  WWWW132  阅读(73)  评论(0)    收藏  举报