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. C#中的委托、事件及事件的订阅

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. 英伟达 cuda 开发套件下载

    下载地址 https://developer.nvidia.com/cuda-toolkit 安装比较简单,就不多说了.

  3. CSS-锚点笔记

    注意点: position属性 定义建议元素布局所用的定位机制 {position:static/absolute/relative/fixed;} static:默认值,没有定位 absolute: ...

  4. CentOS 7 - 修改时区为上海时区

    1.查看时间各种状态: timedatectl Local time: 四 2014-12-25 10:52:10 CSTUniversal time: 四 2014-12-25 02:52:10 U ...

  5. mysql 设置查看字符集

    MySQL查看和修改字符集的方法   一.查看字符集 1.查看MYSQL数据库服务器和数据库字符集 方法一:show variables like '%character%';方法二:show var ...

  6. MySQL Case--优化OR语句踩坑记录

    问题描述 研发同事反馈某应用执行较慢,对应SQL为: UPDATE bs_serial_trac , LOCK_VALUE = '', UPDATE_USER = 'transSys' ' AND ( ...

  7. 虚拟机网络设置(NAT模式)

    虚拟机网络设置(NAT模式) linux 1. 设置虚拟机网络 1.1. NAT子网设置 1.2. 网卡配置文件设置 1.3. 重启网络服务 1.4. 配置端口转发 2. 配置网络共享 预期想要搭建本 ...

  8. vscode编写html,常用快捷方式与插件

      一.tab键补全 1.1打开vscode新建html文件,在第一行输入!,然后按下tab键,会直接出现编写html语言的基本框架标签 效果如下: <!DOCTYPE html> < ...

  9. Kotlin反射实践操作详解

    继续对反射进行实战. 获取构造方法: 先定义一个主构造方法,2个次构造方法,接下来咱们用反射来获取一下构造方法: 其结果: [fun <init>(kotlin.Int, kotlin.S ...

  10. php数组打乱顺序

    shuffle() PHP shuffle() 函数随机排列数组单元的顺序(将数组打乱).本函数为数组中的单元赋予新的键名,这将删除原有的键名而不仅是重新排序. 语法: bool shuffle ( ...