zoukankan      html  css  js  c++  java
  • 2019 SDN上机第5次作业

    1.浏览RYU官网学习RYU控制器的安装和RYU开发入门教程,提交你对于教程代码的理解

    1.描述官方教程实现了一个什么样的交换机功能?

    让交换机在各个端口发送它接收到的数据包

    2. 控制器设定交换机支持什么版本的OpenFlow?

    OpenFlow v1.0

    3. 控制器设定了交换机如何处理数据包?

    这里把官方给出的代码放上来,备注中解释处理函数的部分

     @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
         //表明当Ryu收到OpenFlow packet_in消息时,将产生事件(调用“packet_in_handler”方法)
        def packet_in_handler(self, ev):
            msg = ev.msg//ev.msg是表示packet_in数据结构的对象。
            dp = msg.datapath//msg.dp是代表数据路径(开关)的对象。
            ofp = dp.ofproto
            ofp_parser = dp.ofproto_parser
               //dp.ofproto和dp.ofproto_parser是代表Ryu和交换机协商的OpenFlow协议的对象。
            actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]
               //动作列表。OFPActionOutput类与packet_out消息一起使用,以指定要从中发送数据包的交换机端口。该应用程序使用OFPP_FLOOD标志来指示应在所有端口上发送数据包。
            out = ofp_parser.OFPPacketOut(
               //OFPPacketOut类用于构建packet_out消息。
                datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,
                actions=actions)
            dp.send_msg(out)
               //datapath类的send_msg方法,Ryu生成联机数据格式并将其发送到交换机。
    

    2.根据官方教程和提供的示例代码(SimpleSwitch.py),将具有自学习功能的交换机代码(SelfLearning.py)补充完整

    #coding=utf-8
    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
    from ryu.lib.mac import haddr_to_bin
    from ryu.lib.packet import packet
    from ryu.lib.packet import ethernet
    
    class L2Switch(app_manager.RyuApp):
    
        OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION]  #定下使用的OpenFlow版本
    
        def __init__(self, *args, **kwargs):
            super(L2Switch, self).__init__(*args, **kwargs)
            self.mac_to_port = {}
    
        def add_flow(self, datapath, in_port, dst, actions):
            ofproto = datapath.ofproto
    
            match = datapath.ofproto_parser.OFPMatch(
                in_port = in_port, dl_dst = haddr_to_bin(dst))
    
            mod = datapath.ofproto_parser.OFPFlowMod(
                datapath = datapath, match = match, cookie = 0,
                command = ofproto.OFPFC_ADD, idle_timeout = 10,hard_timeout = 30,
                priority = ofproto.OFP_DEFAULT_PRIORITY,
                flags =ofproto.OFPFF_SEND_FLOW_REM, actions = actions)
    
            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
    
            pkt = packet.Packet(msg.data)
            eth = pkt.get_protocol(ethernet.ethernet)
    
            dst = eth.dst
            src = eth.src
    
            dpid = datapath.id    #获取dpid
            self.mac_to_port.setdefault(dpid, {}) #设置交换机的mac地址表
    
            self.logger.info("packet in %s %s %s %s", dpid, src, dst , msg.in_port)  #显示dpid,映射host的mac地址与交换机那块对应的端口号
    
            self.mac_to_port[dpid][src] = msg.in_port  #判断目的mac地址是否存在于mac位址表中,若不存在,进行洪泛
    
            out_port = ofproto.OFPP_FLOOD #将输出端口指定为洪泛
    
            if dst in self.mac_to_port[dpid]:  #如果已经获取目的mac地址,查询输出用端口
                out_port = self.mac_to_port[dpid][dst]
    
            ofp_parser = datapath.ofproto_parser
    
            actions = [ofp_parser.OFPActionOutput(out_port)]
    
            if out_port != ofproto.OFPP_FLOOD:  #下发流表
                self.logger.info("add flow s:DPID:%s Match:[ MAC_SRC:%s MAC_DST:%s IN_PORT:%s ], Action:[OUT_PUT:%s] ",dpid, src, dst, msg.in_port, out_port) #显示datapath id,目标的MAC地址,源的MAC地址,进入端口,输出端口等信息
                self.add_flow(datapath, msg.in_port, dst, actions)
    
            packet_out = ofp_parser.OFPPacketOut(datapath = datapath, buffer_id = msg.buffer_id,in_port = msg.in_port, actions = actions)  #发送packet_out消息以处理数据包
            datapath.send_msg(packet_out)
    
        @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) #这里则是展示端口状态
        def _port_status_handler(self, ev):
            msg = ev.msg
            reason = msg.reason
            port_no = msg.desc.port_no
    
            ofproto = msg.datapath.ofproto
    
            if reason == ofproto.OFPPR_ADD:
                self.logger.info("port added %s", port_no)
            elif reason == ofproto.OFPPR_DELETE:
                self.logger.info("port deleted %s", port_no)
            elif reason == ofproto.OFPPR_MODIFY:
                self.logger.info("port modified %s", port_no)
            else:
                self.logger.info("Illeagal port state %s %s", port_no, reason)
    

    3.在mininet创建一个最简拓扑,并连接RYU控制器

    用命令创建拓扑
    image.png

    创建成功

    4.验证自学习交换机的功能,提交分析过程和验证结果

    在mininet中查看此时s1的流表
    image.png

    开启具有SelfLearning功能的控制器
    image.png

    进行h1对h2的ping操作
    image.png

    控制器中显示出预期信息
    image.png

    此时再次查看s1的流表

    image.png

    至此,Selflearning简单验证成功

    5.写下你的实验体会

    主要繁琐在安装RYU的过程,代码也花了时间去看,觉得还是opendayly简单

  • 相关阅读:
    【leetcode】1020. Partition Array Into Three Parts With Equal Sum
    【leetcode】572. Subtree of Another Tree
    【leetcode】123. Best Time to Buy and Sell Stock III
    【leetcode】309. Best Time to Buy and Sell Stock with Cooldown
    【leetcode】714. Best Time to Buy and Sell Stock with Transaction Fee
    【leetcode】467. Unique Substrings in Wraparound String
    【leetcode】823. Binary Trees With Factors
    【leetcode】143. Reorder List
    【leetcode】1014. Capacity To Ship Packages Within D Days
    【leetcode】1013. Pairs of Songs With Total Durations Divisible by 60
  • 原文地址:https://www.cnblogs.com/zuodengfeng/p/11969933.html
Copyright © 2011-2022 走看看