2019 SDN第五次上机作业

作业链接

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

码的理解,包括但不限于:

安装RYU控制器并测试

安装教程

安装过程及遇到各种问题解决方案

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

官方教程实现了一个交换机功能:将接收到的数据包发送到所有端口的。

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

OpenFlow v1.0

#dp.ofproto和dp.ofproto_parser是代表Ryu和交换机协商的OpenFlow协议的对象
from ryu.ofproto import ofproto_v1_0 OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] ofp = dp.ofproto ofp_parser = dp.ofproto_parser

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

  • 交换机处理数据包的代码如下所示:
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
  • 当ryu控制器接收到数据包时,通过set_ev_cls来告知交换机,调用新增函数packet_in_handler来处理数据包。其中第一个参数ofp_event.EventOFPPacketIn指示应调用此函数的事件类型;第二个参数MAIN_DISPATCHER指示开关的状态,使用 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)]
out = ofp_parser.OFPPacketOut(
datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,
actions=actions)
dp.send_msg(out)

​新方法'packet_in_handler'已添加到L2Switch类。当Ryu收到OpenFlow packet_in消息时,将调用此方法。

packet_in_handler函数:

  • ev.msg是表示packet_in数据结构的对象。
  • msg.dp是代表数据路径(开关)的对象。
  • dp.ofproto和dp.ofproto_parser是代表Ryu和交换机协商的OpenFlow协议的对象。
  • OFPActionOutput类与packet_out消息一起使用,以指定要从中发送数据包的交换机端口。该应用程序使用OFPP_FLOOD标志来指示应在所有端口上发送数据包。
  • OFPPacketOut类用于构建packet_out消息。
  • 如果使用OpenFlow消息类对象调用Datapath类的send_msg方法,则Ryu会生成联机数据格式并将其发送到交换机。

2.根据官方教程和提供的示例代码(SimpleSwitch.py),将具有自学习功能的#

交换机代码(SelfLearning.py)补充完整:

  • SimpleSwitch.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 from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib.packet import ether_types
from ryu.lib.packet import ipv4 class SimpleSwitch(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] def __init__(self, *args, **kwargs):
super(SimpleSwitch, self).__init__(*args, **kwargs) @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) if eth.ethertype == ether_types.ETH_TYPE_LLDP:
#ignore lldp packet
return
if eth.ethertype == ether_types.ETH_TYPE_IPV6:
#ignore ipv6 packet
return print ("PACKET_IN:") print (eth.ethertype)
print ("ethernet:")
print ("eth_src=",eth.src)
print ("eth_dst=",eth.dst) if eth.ethertype == ether_types.ETH_TYPE_IP:
_ipv4 = pkt.get_protocol(ipv4.ipv4)
print ("ipv4:")
print ("ip_src=",_ipv4.src)
print ("ip_dst=",_ipv4.dst) dpid = datapath.id out_port = ofproto.OFPP_FLOOD
actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] data = None out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions, data=data)
datapath.send_msg(out)
print ("PACKET_OUT...")
print

补充后的具有自学习功能的交换机代码如下(共有四处地方需要补充):

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
from ryu.lib.packet import ether_types class SimpleSwitch(app_manager.RyuApp):
# TODO define OpenFlow 1.0 version for the switch
# add your code here
OFP_VERSIONS=[ofproto_v1_0.OFP_VERSION] def __init__(self, *args, **kwargs):
super(SimpleSwitch, self).__init__(*args, **kwargs)
self.mac_to_port = {} def add_flow(self, datapath, in_port, dst, src, actions):
ofproto = datapath.ofproto match = datapath.ofproto_parser.OFPMatch(
in_port=in_port,
dl_dst=haddr_to_bin(dst), dl_src=haddr_to_bin(src)) mod = datapath.ofproto_parser.OFPFlowMod(
datapath=datapath, match=match, cookie=0,
command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
# TODO send modified message out
# add your code here
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) if eth.ethertype == ether_types.ETH_TYPE_LLDP:
# ignore lldp packet
return
if eth.ethertype == ether_types.ETH_TYPE_IPV6:
# ignore ipv6 packet
return dst = eth.dst
src = eth.src
dpid = datapath.id
self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in DPID:%s MAC_SRC:%s MAC_DST:%s IN_PORT:%s", dpid, src, dst, msg.in_port) # learn a mac address to avoid FLOOD next time.
self.mac_to_port[dpid][src] = msg.in_port if dst in self.mac_to_port[dpid]:
out_port = self.mac_to_port[dpid][dst]
else:
out_port = ofproto.OFPP_FLOOD # TODO define the action for output
# add your code here
actions=[datapath.ofproto_parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time
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)
self.add_flow(datapath, msg.in_port, dst, src, actions) data = None
if msg.buffer_id == ofproto.OFP_NO_BUFFER:
data = msg.data # TODO define the OpenFlow Packet Out
# add your code here
out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath,
buffer_id=msg.buffer_id,
in_port=msg.in_port, actions=actions,
data=data)
datapath.send_msg(out)
print ("PACKET_OUT...")

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

拓扑结构图如下所示:

  • 创建拓扑python脚本:
from mininet.topo import Topo
class MyTopo(Topo):
def __init__(self):
Topo.__init__(self)
h1 = self.addHost('h1')
h2 = self.addHost('h2')
s1 = self.addSwitch('s1')
self.addLink(h1, s1, 1, 1)
self.addLink(h2, s1, 1, 2)
topos = {'mytopo': (lambda: MyTopo())}
  • 使用命令运行python脚本
sudo mn --custom mytopo.py --topo mytopo --controller=remote,ip=127.0.0.1,port=6633 --switch ovsk,protocols=OpenFlow10

  • 未连接RYU控制器时查看s1的流表:
sudo ovs-ofctl dump-flows s1

  • 连接RYU控制器:
ryu-manager SelfLearning.py

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

  • 再次查看s1流表:

  • 在RYU控制器中可以看到目的主机的MAC地址、源主机的MAC地址、输入端口、输出端口等数据:

  • 使用wireshark抓包分析如下所示:

心得体会

这次实验安装占了大部分的时间,前前后后至少重装了十几次,Mininet,pip3,ryu,python各个版本之间莫名其妙的冲突,翻遍了全网的安装教程(心态爆炸),最后还找到了老师(旺得福)的安装博客(真是太巧了),最后终于安装成功,学到了好多个命令行的使用,真是太好了太惨了,最后总算摸透了各个路径,安装的配置更新。好在后面的具体操作部分不会很难,中间python文件缩进的问题又卡了很久(自闭了,以为代码不对,原来是缩进问题),后面在了老师发的实例和网上的教程之后和同学的帮助下,最后终于完成了。通过这次实验,我对交换机的自学习功能、ryu控制器的基本原理和使用方法也有了一定的了解。

2019 SDN第五次上机作业的更多相关文章

  1. SDN第五次上机作业

    作业链接 1.建立拓扑,并连接上ODL控制器. 2.利用ODL下发组表.流表,实现建议负载均衡 查看s2接收的数据包都被drop掉了 在s1中下发组表 在s1中下发流表使组表生效 下发流表覆盖S2中d ...

  2. SDN第五次上机作业--基于组表的简单负载均衡

    0.作业链接 http://www.cnblogs.com/easteast/p/8125383.html 1.实验目的 1.搭建如下拓扑并连接控制器 2.下发相关流表和组表实现负载均衡 3.抓包分析 ...

  3. 2019 SDN第6次上机作业

    1.作业要求: 作业链接 参考资料: Ryu控制器的API文档:ryu.app.ofctl_rest Ryu的拓扑展示 助教博客:基于RYU restful api实现的VLAN网络虚拟化 2.具体操 ...

  4. 2019 SDN第四次上机作业

    作业博客链接:http://edu.cnblogs.com/campus/fzu/fzusdn2019/homework/10017 1. 解压安装OpenDayLight控制器(本次实验统一使用Be ...

  5. 2019 SDN第三次上机作业

    作业要求: 利用Mininet仿真平台构建给定的网络拓扑,配置主机h1和h2的IP地址(h1:10.0.0.1,h2:10.0.0.2),测试两台主机之间的网络连通性: 利用Wireshark工具,捕 ...

  6. 2019 SDN第3次上机作业

    0.报文类型与含义 1.Controller-to-Switch 报文 ​ Cortoller-to-Switch是由控制器初始化并下发给交换机的报文类型,其可能会要求交换机回复对应的报文,此类型报文 ...

  7. SDN 第五次上机作业

    1.搭建如下拓扑并连接控制器 2.下发相关流表和组表实现负载均衡 s1: s2: s3: s4: 3.抓包分析验证负载均衡 s4-eth1: s4-eth2: s4-eth3

  8. 17秋 SDN课程 第五次上机作业

    17秋 SDN课程 第五次上机作业 Project:https://github.com/Wasdns/new_balance Slide is available at https://github ...

  9. SDN第5次上机作业

    SDN第5次上机作业 实验目的 1.搭建如下拓扑并连接控制器 2.下发相关流表和组表实现负载均衡 3.抓包分析验证负载均衡 实验步骤 1.建立以下拓扑,并连接上ODL控制器. 提交要求:ODL拓扑界面 ...

随机推荐

  1. Java中强大的format

    Java中强大的format Java中允许我们对指定的对象进行某种格式化,从而得到我们想要的格式化样式. Format 首先介绍java.text包中的Format Foramt是一个抽象基类,其具 ...

  2. springCloud学习4(Zuul服务路由)

    镇博图 springcloud 总集:https://www.tapme.top/blog/detail/2019-02-28-11-33 本篇中 Zuul 版本为 1.x,目前最新的是 2.x,二者 ...

  3. ubuntu16.04+GTX2080Ti+torch7安装记录

    环境说明 ubuntu16.04 cuda10.0 2080Ti显卡 拉取代码和修改编译脚本 拉取代码 用户先clone代码: git clone https://github.com/torch/d ...

  4. Linux命令——pidof

    参考:Linux pidof Command Examples To Find PID of A Program/Command Linux pidof Command Tutorial for Be ...

  5. SWD烧录/仿真方式

    单片机在烧写/仿真的时候具有一种方式叫做SWD,这种方式只用到两根线SWDIO,SWCLK.一般SWD和JTAG中的JTMS和JTCK共用的.由于线少,所以使用非常方便,但是速率相对较低. 在接线时, ...

  6. Python的csv文件(csv模块)和ini文件(configparser模块)处理

    Python的csv文本文件(csv模块)和ini文本文件(configparser模块)处理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.csv文件 1>.CSV文件 ...

  7. k8s部署etcd集群

    1.k8s部署高可用etcd集群时遇到了一些麻烦,这个是自己其中一个etcd的配置文件 例如: [Unit] Description=Etcd Server After=network.target ...

  8. PHP三种输出的不同类型

    var_dump() 能打印出类型print_r() 只能打出值echo() 是正常输出... 需要精确调试的时候用 var_dump();一般查看的时候用 print_r()另外 , echo不能显 ...

  9. 《CoderXiaoban》第九次团队作业:Beta冲刺与验收准备

    项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 实验十三 团队作业9:BETA冲刺与团队项目验收 团队名称 Coderxiaoban团队 作业学习目标 (1)掌握软件黑盒 ...

  10. web scraper——爬取知乎|微博用户数据模板【三】

    前言 在这里呢,我就只给模板,不写具体的教程啦,具体的可以参考我之前写的博文. https://www.cnblogs.com/wangyang0210/p/10338574.html 模板 进入微博 ...