1. 代码解析

ryu/app/example_switch_13.py:

from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet class ExampleSwitch13(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self, *args, **kwargs):
super(ExampleSwitch13, self).__init__(*args, **kwargs)
# initialize mac address table.
self.mac_to_port = {} @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 the table-miss flow entry.
match = parser.OFPMatch() # OFPCML_NO_BUFFER: 不缓冲,将发送整个数据包
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):
ofproto = datapath.ofproto
parser = datapath.ofproto_parser # construct flow_mod message and send it.
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
actions)]
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
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser # get Datapath ID to identify OpenFlow switches.
dpid = datapath.id
self.mac_to_port.setdefault(dpid, {}) # analyse the received packets using the packet library.
pkt = packet.Packet(msg.data)
eth_pkt = pkt.get_protocol(ethernet.ethernet)
dst = eth_pkt.dst
src = eth_pkt.src # get the received port number from packet_in message.
in_port = msg.match['in_port'] self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time.
self.mac_to_port[dpid][src] = in_port # if the destination mac address is already learned,
# decide which port to output the packet, otherwise FLOOD.
if dst in self.mac_to_port[dpid]:
out_port = self.mac_to_port[dpid][dst]
else:
out_port = ofproto.OFPP_FLOOD # construct action list.
actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time.
if out_port != ofproto.OFPP_FLOOD:
match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
self.add_flow(datapath, 1, match, actions) # construct packet_out message and send it.
out = parser.OFPPacketOut(datapath=datapath,
buffer_id=ofproto.OFP_NO_BUFFER,
in_port=in_port, actions=actions,
data=msg.data)
datapath.send_msg(out)
  • Ryu 应用需要继承 ryu.base.app_manager.RyuApp
  • OFP_VERSIONS指定支持的OpenFlow版本;
  • Ryu 会自己完成交换机和控制器间的握手等初始化过程;
  • 每当 Ryu 接收到一个OpenFlow消息时,便会生成对应的事件;使用 ryu.controller.handler.set_ev_cls装饰器可以指定事件处理器:
    • 第一个参数指定事件类型;
    • 第二个参数指定交换机状态;
状态 解释
HANDSHAKE_DISPATCHER Exchange of HELLO message
CONFIG_DISPATCHER Waiting to receive SwitchFeatures message
MAIN_DISPATCHER Normal status
DEAD_DISPATCHER Disconnection of connection
  • ryu.controller.controller.Datapath类表示和控制器相连的交换机;主要属性如下,
==================================== ======================================
Attribute Description
==================================== ======================================
id 64-bit OpenFlow Datapath ID.
Only available for
ryu.controller.handler.MAIN_DISPATCHER
phase. ofproto A module which exports OpenFlow
definitions, mainly constants appeared
in the specification, for the
negotiated OpenFlow version. For
example, ryu.ofproto.ofproto_v1_0 for
OpenFlow 1.0. ofproto_parser A module which exports OpenFlow wire
message encoder and decoder for the
negotiated OpenFlow version.
For example,
ryu.ofproto.ofproto_v1_0_parser
for OpenFlow 1.0. ofproto_parser.OFPxxxx(datapath,...) A callable to prepare an OpenFlow
message for the given switch. It can
be sent with Datapath.send_msg later.
xxxx is a name of the message. For
example OFPFlowMod for flow-mod
message. Arguemnts depend on the
message. set_xid(self, msg) Generate an OpenFlow XID and put it
in msg.xid. send_msg(self, msg) Queue an OpenFlow message to send to
the corresponding switch. If msg.xid
is None, set_xid is automatically
called on the message before queueing. send_barrier Queue an OpenFlow barrier message to
send to the switch.
==================================== ======================================
  • ryu.ofproto.ofproto_v1_3_parser.OFPMatch类表示流匹配结构体;
================ =============== ==================================
Argument Value Description
================ =============== ==================================
in_port Integer 32bit Switch input port
in_phy_port Integer 32bit Switch physical input port
metadata Integer 64bit Metadata passed between tables
eth_dst MAC address Ethernet destination address
eth_src MAC address Ethernet source address
eth_type Integer 16bit Ethernet frame type
vlan_vid Integer 16bit VLAN id
vlan_pcp Integer 8bit VLAN priority
ip_dscp Integer 8bit IP DSCP (6 bits in ToS field)
ip_ecn Integer 8bit IP ECN (2 bits in ToS field)
ip_proto Integer 8bit IP protocol
ipv4_src IPv4 address IPv4 source address
ipv4_dst IPv4 address IPv4 destination address
tcp_src Integer 16bit TCP source port
tcp_dst Integer 16bit TCP destination port
udp_src Integer 16bit UDP source port
udp_dst Integer 16bit UDP destination port
sctp_src Integer 16bit SCTP source port
sctp_dst Integer 16bit SCTP destination port
icmpv4_type Integer 8bit ICMP type
icmpv4_code Integer 8bit ICMP code
arp_op Integer 16bit ARP opcode
arp_spa IPv4 address ARP source IPv4 address
arp_tpa IPv4 address ARP target IPv4 address
arp_sha MAC address ARP source hardware address
arp_tha MAC address ARP target hardware address
ipv6_src IPv6 address IPv6 source address
ipv6_dst IPv6 address IPv6 destination address
ipv6_flabel Integer 32bit IPv6 Flow Label
icmpv6_type Integer 8bit ICMPv6 type
icmpv6_code Integer 8bit ICMPv6 code
ipv6_nd_target IPv6 address Target address for ND
ipv6_nd_sll MAC address Source link-layer for ND
ipv6_nd_tll MAC address Target link-layer for ND
mpls_label Integer 32bit MPLS label
mpls_tc Integer 8bit MPLS TC
mpls_bos Integer 8bit MPLS BoS bit
pbb_isid Integer 24bit PBB I-SID
tunnel_id Integer 64bit Logical Port Metadata
ipv6_exthdr Integer 16bit IPv6 Extension Header pseudo-field
pbb_uca Integer 8bit PBB UCA header field
(EXT-256 Old version of ONF Extension)
tcp_flags Integer 16bit TCP flags
(EXT-109 ONF Extension)
actset_output Integer 32bit Output port from action set metadata
(EXT-233 ONF Extension)
================ =============== ==================================
  • ryu.ofproto.ofproto_v1_3_parser.OFPFlowMod类表示Flow Mod消息,即修改流项;支持以下参数:
================ ======================================================
Attribute Description
================ ======================================================
cookie Opaque controller-issued identifier
cookie_mask Mask used to restrict the cookie bits that must match
when the command is OPFFC_MODIFY* or
OFPFC_DELETE* table_id ID of the table to put the flow in command One of the following values.
| OFPFC_ADD
| OFPFC_MODIFY
| OFPFC_MODIFY_STRICT
| OFPFC_DELETE
| OFPFC_DELETE_STRICT idle_timeout Idle time before discarding (seconds)
hard_timeout Max time before discarding (seconds) priority Priority level of flow entry buffer_id Buffered packet to apply to (or OFP_NO_BUFFER) out_port For OFPFC_DELETE* commands, require matching
entries to include this as an output port out_group For OFPFC_DELETE* commands, require matching
entries to include this as an output group flags Bitmap of the following flags.
| OFPFF_SEND_FLOW_REM
| OFPFF_CHECK_OVERLAP
| OFPFF_RESET_COUNTS
| OFPFF_NO_PKT_COUNTS
| OFPFF_NO_BYT_COUNTS match Instance of OFPMatch
instructions list of OFPInstruction* instance
================ ======================================================
  • ryu.ofproto.ofproto_v1_3_parser.OFPPacketIn类表示Packet-In消息,即交换机发向控制器;包含以下属性:
============= =========================================================
Attribute Description
============= =========================================================
buffer_id ID assigned by datapath
total_len Full length of frame
reason Reason packet is being sent.
| OFPR_NO_MATCH
| OFPR_ACTION
| OFPR_INVALID_TTL table_id ID of the table that was looked up
cookie Cookie of the flow entry that was looked up
match Instance of OFPMatch
data Ethernet frame
============= =========================================================
  • ryu.ofproto.ofproto_v1_3_parser.OFPPacketOut类表示Packet-Out消息,即控制器发向交换机;包含以下属性:
================ ======================================================
Attribute Description
================ ======================================================
buffer_id ID assigned by datapath (OFP_NO_BUFFER if none)
in_port Packet's input port or OFPP_CONTROLLER
actions list of OpenFlow action class
data Packet data of a binary type value or
an instances of packet.Packet.
================ ======================================================
  • ryu.ofproto.ofproto_v1_3_parser.OFPActionOutput类表示输出动作;支持以下参数:
================ ======================================================
Attribute Description
================ ======================================================
port Output port
max_len Max length to send to controller
================ ======================================================
  • ryu.ofproto.ofproto_v1_3_parser.OFPInstructionActions 表示写/应用/清空 actions 的指令:
================ ======================================================
Attribute Description
================ ======================================================
type One of following values.
| OFPIT_WRITE_ACTIONS
| OFPIT_APPLY_ACTIONS
| OFPIT_CLEAR_ACTIONS actions list of OpenFlow action class
================ ======================================================
  • 支持的指令如下:
OFPIT_GOTO_TABLE = 1            # Setup the next table in the lookup pipeline.
OFPIT_WRITE_METADATA = 2 # Setup the metadata field for use later in
# pipeline.
OFPIT_WRITE_ACTIONS = 3 # Write the action(s) onto the datapath
# action set
OFPIT_APPLY_ACTIONS = 4 # Applies the action(s) immediately
OFPIT_CLEAR_ACTIONS = 5 # Clears all actions from the datapath action
# set
OFPIT_METER = 6 # Apply meter (rate limiter)
OFPIT_EXPERIMENTER = 0xFFFF # Experimenter instruction

2. 运行

# --topo sigle,3: 单个交换机,3个主机
# --mac: 自动设置主机的MAC地址
# --switch ovsk: 使用 ovs
# --controller remote: 使用外部OpenFlow控制器
# -x: 启动xterm
$ sudo mn --topo single,3 --mac --switch ovsk --controller remote -x

此时会启动5个xterm:h1~h3, switch, controller.

设置OpenFlow版本:switch: s1

# ovs-vsctl set Bridge s1 protocols=OpenFlow13

启动控制器:controller: c0

# ryu-manager --verbose ryu/app/example_switch_13.py

查看Table-miss流项:switch: s1

# ovs-ofctl -O OpenFlow13 dump-flows s1

ping:

mininet> h1 ping -c1 h2

再次查看流项:switch: s1

# ovs-ofctl -O OpenFlow13 dump-flows s1

参考资料

https://osrg.github.io/ryu-book/en/Ryubook.pdf

ryu—交换机的更多相关文章

  1. 使用mininet创建网络拓扑,使ryu、ovs、主机连接

    实验拓扑 控制器:RYU 交换机:s1,s2 主机:h1,h2,h3,h3 联通性(直连): h1<->s1;h2<->s1 h3<->s2;h4<-> ...

  2. Ryu控制器编程开发——packet_in和packet_out简易交换机实现

    Ryu控制器二次开发,实现一个简单的只能够简单地广播数据包的交换机. from ryu.base import app_manager from ryu.controller import ofp_e ...

  3. 在RYU中实现交换机的功能

    首先源码,解析部分如下,同时可以参考RYU_BOOK上的解释说明  原文链接参考:https://blog.csdn.net/qq_34099967/article/details/89047741 ...

  4. Ryu

    What's Ryu? Ryu is a component-based software defined networking framework. Ryu provides software co ...

  5. SDN环境搭建(mininet,OVS,ryu安装及命令)

    1.mininet安装与使用 1.1mininet安装 ubuntu 12.04/14.04/14.10      命令行  sudo apt-get install mininet 1.2 mini ...

  6. 基于RYU控制器(controller)上的simple-switch 的APP做的測试-SDN/OpenFlow

    近期一直在学习RYU控制器,在使用的过程中,发现有下面几方面的长处:RYU控制器全然使用Python语言编写,在理解起来和上手速度上是挺快的:RYU控制器的总体架构清晰明了,在日后有时间我会整理一个关 ...

  7. SDN学习之RYU源码安装

    近些天开始接触SDN,即软件定义网络的学习,由于是初学者,想通过写博客来分享自己对sdn学习中所使用的ryu以及mininet仿真软件. Mininet源码安装: 尽管网上对mininet的安装教程很 ...

  8. 基于RYU的拓扑发现

    基于RYU的拓扑发现 前言 本次实验是一个基于RYU的拓扑发现功能.参考了呈神的实现方式,并加了一些自己实现方式,做了一些数据结构的改动. 数据结构 link_to_port 字典 有两种关系: 一是 ...

  9. RYU 灭龙战 fourth day (2)

    RYU 灭龙战 fourth day (2) 前言 之前试过在ODL调用他们的rest api,一直想自己写一个基于ODL的rest api,结果还是无果而终.这个小目标却在RYU身上实现了.今日说法 ...

随机推荐

  1. 【electron-playground系列】打包优化之路

    作者:梁棒棒 简介 electron打包工具有两个:electron-builder,electron-packager,官方还提到electron-forge,其实它不是一个打包工具,而是一个类似于 ...

  2. 一场由fork引发的超时,让我们重新探讨了Redis的抖动问题

    摘要:一次由fork引发的时延抖动问题. 背景介绍 华为云数据库GaussDB(for Redis) 是一款基于计算存储分离架构,兼容Redis生态的云原生NoSQL数据库:它依靠共享存储池实现了强一 ...

  3. K-NN(最近邻分类算法 python

    # algorithm:K-NN(最近邻分类算法)# author:Kermit.L# time: 2016-8-7 #======================================== ...

  4. jquery 局部刷新load 某个div或者某个表格

    在使用 ajax 进行删除用户操作的时候,可以在 success 里写一个 window.location.reload(); 让页面刷新. 但是,我不想那样,我只想局部刷新 比如,我删除几个用户后, ...

  5. ARP局域网断网攻击

    Kali--ARP局域网攻击 什么是ARP? ARP ( Address Resolution Protocol)地址转换协议,工作在OSI模型的数据链路层,在以太网中,网络设备之间互相通信是用MAC ...

  6. Redis 设计与实现 6:五大数据类型之字符串

    前文 Redis 设计与实现 2:Redis 对象 说到,五大数据类型都会封装成 RedisObject. typedef struct redisObject { unsigned type:4; ...

  7. 想成为Git大神?从学会reset开始吧

    大家好,今天我们来着重介绍一个非常关键的功能就是reset.在上一篇文章介绍修改历史记录的时候曾经提到过,当我们需要拆分一个历史提交记录的时候需要使用reset.估计很多小伙伴不明白,reset究竟做 ...

  8. flowable中使用到的一些方法。获取人员部门信息

    package org.springblade.desk.utils; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf ...

  9. Sentinel滑动窗口算法

    在前面搞清楚了Sentinel的使用后,大致理了一下Sentinel的责任链,搞清楚了这个,基本就已经梳理清楚sentinel-core模块的大部分内容,顺着这条链路可以继续梳理很多东西. 知其然.知 ...

  10. nginx二级域名配置[CentOS]

    目录 背景 域名配置 服务器配置 Nginx配置 页面访问生效 背景 只有一台云服务器,部署了自己写的后端管理系统,又需要部署下自己的个人博客平台,但是只有一个域名,想要合理的利用下二级域名. 域名配 ...