RYU是一款基于python的控制器,你可用Ryu实现各种想要实现的网络功能,它可以下发或接收流表进行各种路由运算。
apt install gcc libffi-dev libssl-dev libxml2-dev libxslt1-dev zlib1g-dev
pip3 install ryu
ryu --version
如果正确输出版本信息,则说明安装成功。
.
sudo mn --controller=remote,ip=127.0.0.1,port=6653
注:从OpenFlow 1.3.3 (EXT-133)版本以后,IANA 分配给 OpenFlow 的端口号是 6653,但有些应用仍然使用6633,所以设置监听端口为6653和6633都行
ryu-manager --verbose simple_switch_13.py ofctl_rest.py rest_topology.py
simple_switch_13.py模块是一个简单的交换机,是openflow1.3的交换机。后面的两个文件是为了进行restapi的调用加载的,方便直接用浏览器查看。
在浏览器中调用ryu的api
http://127.0.0.1:8080/stats/desc/1
{
"1":(DPID)
{
"dp_desc": "None",(datapath的描述信息)
"sw_desc": "2.0.2",(软件机的描述信息)
"hw_desc": "Open vSwitch",(交换机描述信息)
"serial_num": "None",(序列号)
"mfr_desc": "Nicira, Inc."(生产商信息)
}
}
http://127.0.0.1:8080/stats/flow/1
"1": [
{
"actions": [ "OUTPUT:3" ],(动作,转发到3 号端口)
"idle_timeout": 0,(空闲后存活时间)
"cookie": 0,
"packet_count": 2,(包计数)
"hard_timeout": 0,(存活时间)
"byte_count": 140,(比特计数)
"duration_nsec": 111000000,
"priority": 32768,(优先级)
"duration_sec": 985,(已经存活时间)
"table_id": 0,(在流表1)
"match": (匹配字段)
{
"dl_dst": "02:28:7c:93:27:af",(过滤目的地址为02:28:7c:93:27:af的包,就是去主机3的包)
"in_port": 2(从2号端口进入)
}
(作用:从2号端口进入,要到h3主机的报文都从3号端口转发)
}
查询指定交换机上所有流表的统计信息
得到端口的统计信息
得到端口配置信息:
在浏览器中除了可以查询流表信息外,还可以对流表进行操作,但需要支持构造post、delete等请求的浏览器插件,如httprequester、restclient等,具体操作如下:
# 获取交换机列表
GET /stats/switches
# 获取某台交换机的设备信息
GET /stats/desc/<dpid>
# get flows desc stats of the switch
GET /stats/flowdesc/<dpid>
# get flows desc stats of the switch filtered by the fields
POST /stats/flowdesc/<dpid>
# 得到指定交换机的所有flow的状态信息
GET /stats/flow/<dpid>
# 有条件地查询某台交换机的流表
POST /stats/flow/<dpid>
# 查询指定交换机的全局统计流表的字段
GET /stats/aggregateflow/<dpid>
# 有条件的查询指定交换机的全局统计流表的字段
POST /stats/aggregateflow/<dpid>
# 查询指定交换机上所有流表的统计信息
GET /stats/table/<dpid>
# get table features stats of the switch
GET /stats/tablefeatures/<dpid>
# 得到端口的统计信息
GET /stats/port/<dpid>[/<port>]
# Note: Specification of port number is optional
# get queues stats of the switch
GET /stats/queue/<dpid>[/<port>[/<queue_id>]]
# Note: Specification of port number and queue id are optional
# If you want to omitting the port number and setting the queue id,
# please specify the keyword "ALL" to the port number
# e.g. GET /stats/queue/1/ALL/1
# get queues config stats of the switch
GET /stats/queueconfig/<dpid>[/<port>]
# Note: Specification of port number is optional
# get queues desc stats of the switch
GET /stats/queuedesc/<dpid>[/<port>[/<queue_id>]]
# Note: Specification of port number and queue id are optional
# If you want to omitting the port number and setting the queue id,
# please specify the keyword "ALL" to the port number
# e.g. GET /stats/queuedesc/1/ALL/1
# get meter features stats of the switch
GET /stats/meterfeatures/<dpid>
# get meter config stats of the switch
GET /stats/meterconfig/<dpid>[/<meter_id>]
# Note: Specification of meter id is optional
# get meter desc stats of the switch
GET /stats/meterdesc/<dpid>[/<meter_id>]
# Note: Specification of meter id is optional
# get meters stats of the switch
GET /stats/meter/<dpid>[/<meter_id>]
# Note: Specification of meter id is optional
# get group features stats of the switch
GET /stats/groupfeatures/<dpid>
# get groups desc stats of the switch
GET /stats/groupdesc/<dpid>[/<group_id>]
# Note: Specification of group id is optional (OpenFlow 1.5 or later)
# get groups stats of the switch
GET /stats/group/<dpid>[/<group_id>]
# Note: Specification of group id is optional
# get ports description of the switch
GET /stats/portdesc/<dpid>[/<port_no>]
# Note: Specification of port number is optional (OpenFlow 1.5 or later)
# 添加流表项
POST /stats/flowentry/add
# 修改所有匹配的流表项
POST /stats/flowentry/modify
# modify flow entry strictly matching wildcards and priority
POST /stats/flowentry/modify_strict
# delete all matching flow entries
POST /stats/flowentry/delete
# delete flow entry strictly matching wildcards and priority
POST /stats/flowentry/delete_strict
# delete all flow entries of the switch
DELETE /stats/flowentry/clear/<dpid>
# add a meter entry
POST /stats/meterentry/add
# modify a meter entry
POST /stats/meterentry/modify
# delete a meter entry
POST /stats/meterentry/delete
# add a group entry
POST /stats/groupentry/add
# modify a group entry
POST /stats/groupentry/modify
# delete a group entry
POST /stats/groupentry/delete
# modify behavior of the physical port
POST /stats/portdesc/modify
# modify role of controller
POST /stats/role
# send a experimeter message
POST /stats/experimenter/<dpid>
具体操作方法见RYU实战,REST API流表控制1,RYU实战,REST API流表控制2
.
Ryu自带了网络拓扑可视化的app,名称为gui_topology.py
,在ryu/ryu/app/gui_topology/gui_topology.py下。使用方法同其他的app,可以和其他app一起运行。同样进入ryu/ryu/app/目录,运行:
ryu-manager gui_topology/gui_topology.py
启动成功后,将交换机连接到Ryu,用浏览器访问ryu运行的主机ip:8080即可看到当前的网络拓扑,一般是http://localhost:8080。
但这样只能看到所有的交换机,但看不到它们之间的连接,启动ryu时加上
–observe-links
参数,就可以看到交换机之间的连接,即:
ryu-manager gui_topology/gui_topology.py --observe-links
不仅有交换机,他们之间的连接也都显示出来了。同时,在这个界面,我们还可以点击某个交换机来查看当中的流表项。
这样做的一个问题是,带上–observe-links
启动ryu之后,Ryu会收到非常大量的包含LLDP协议报文的PacketIn
消息,如果不对这一PacketIn
消息进行特殊处理的话,很容易导致Ryu奔溃,无法正常工作!为了避免这一问题,当使用–observe-links
启动Ryu时,在你处理PacketIn
消息的函数开头,建议包含如下代码,即可解决问题:
if eth.ethertype == ether_types.ETH_TYPE_LLDP:
# ignore lldp packet
return
本节内容转自Ryu网络拓扑可视化app使用简介,具体可参考原博客。