RYU 灭龙战 fourth day (2)
RYU 灭龙战 fourth day (2)
前言
之前试过在ODL调用他们的rest api,一直想自己写一个基于ODL的rest api,结果还是无果而终。这个小目标却在RYU身上实现了。今日说法,为你带来,基于RYU的北向rest api开发
目的
mac地址表获取 API
取得基于RYU 灭龙战 third day实验的mac地址表内容。即 对应的mac地址和连接端口 以JSON的形式回传
mac地址表注册 API
向mac地址表加入新的mac地址和端口号,同时加到交换机的流表中
实验方案
# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
from ryu.app import simple_switch_13
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.app.wsgi import ControllerBase
from ryu.app.wsgi import Response
from ryu.app.wsgi import route
from ryu.app.wsgi import WSGIApplication
from ryu.lib import dpid as dpid_lib
simple_switch_instance_name = 'simple_switch_api_app'
url = '/simpleswitch/mactable/{dpid}'
#SimpleSwitchRest13用来扩展实验一的功能,让它可以更新mac地址表,其中switch_features_handler方法由于需要更新mac地址表,所以这个地方继承原方法,进行重写
class SimpleSwitchRest13(simple_switch_13.SimpleSwitch13):
#指定RYU使用的为WSGI网页服务器
_CONTEXTS = {'wsgi': WSGIApplication}
def __init__(self, *args, **kwargs):
super(SimpleSwitchRest13, self).__init__(*args, **kwargs)
#已连接交换机集合
self.switches = {}
wsgi = kwargs['wsgi']
wsgi.register(SimpleSwitchController,
{simple_switch_instance_name: self})
#接收消息为OPFSwitchFeatures,交换机状态为接收SwitchFeatures消息
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
#继承原方法
super(SimpleSwitchRest13, self).switch_features_handler(ev)
datapath = ev.msg.datapath
self.switches[datapath.id] = datapath
self.mac_to_port.setdefault(datapath.id, {})
def set_mac_to_port(self, dpid, entry):
mac_table = self.mac_to_port.setdefault(dpid, {})
datapath = self.switches.get(dpid)
#entry用来存储已经注册的mac地址和端口
entry_port = entry['port']
entry_mac = entry['mac']
if datapath is not None:
parser = datapath.ofproto_parser
if entry_port not in mac_table.values():
for mac, port in mac_table.items():
# from known device to new device
actions = [parser.OFPActionOutput(entry_port)]
match = parser.OFPMatch(in_port=port, eth_dst=entry_mac)
self.add_flow(datapath, 1, match, actions)
# from new device to known device
actions = [parser.OFPActionOutput(port)]
match = parser.OFPMatch(in_port=entry_port, eth_dst=mac)
self.add_flow(datapath, 1, match, actions)
mac_table.update({entry_mac: entry_port})
return mac_table
#SimpleSwitchController用来实现收到HTTP请求时所需要回应的方法
class SimpleSwitchController(ControllerBase):
def __init__(self, req, link, data, **config):
super(SimpleSwitchController, self).__init__(req, link, data, **config)
self.simple_switch_app = data[simple_switch_instance_name]
#参数说明,第一个参数任意名称,第二个参数url,指定url,使得对应的url为http://<IP>:8080/simpleswitch/mactable/<datapath ID>,第三个参数为GET方法,
# 第四个参数为指定的URL形式,即simpleswitch/mactable/<datapath ID>的<datapapath ID>要和目标文件的值相对应
@route('simpleswitch', url, methods=['GET'],
requirements={'dpid': dpid_lib.DPID_PATTERN})
def list_mac_table(self, req, **kwargs):
simple_switch = self.simple_switch_app
dpid = dpid_lib.str_to_dpid(kwargs['dpid'])
#如果dpid不在表中的话,就会返回404
if dpid not in simple_switch.mac_to_port:
return Response(status=404)
#把对应的dpid对应的mac地址表用json的形式返回
mac_table = simple_switch.mac_to_port.get(dpid, {})
body = json.dumps(mac_table)
return Response(content_type='application/json', body=body)
#同上
@route('simpleswitch', url, methods=['PUT'],
requirements={'dpid': dpid_lib.DPID_PATTERN})
def put_mac_table(self, req, **kwargs):
simple_switch = self.simple_switch_app
dpid = dpid_lib.str_to_dpid(kwargs['dpid'])
try:
new_entry = req.json if req.body else {}
except ValueError:
raise Response(status=400)
if dpid not in simple_switch.mac_to_port:
return Response(status=404)
#调用set_mac_to_port方法,注册相应的mac,port,并下发流表
try:
mac_table = simple_switch.set_mac_to_port(dpid, new_entry)
body = json.dumps(mac_table)
return Response(content_type='application/json', body=body)
except Exception as e:
return Response(status=500)
实验过程
- mininet端
sudo mn --topo single,3 --mac --switch ovsk,protocols=OpenFlow13 --controller remote

- 另外一个终端,目录为ryu/app
ryu-manager --verbose ./simple_switch_rest_13.py

- mininet端,让h1 ping h2 ,看RYU端的变化
h1 ping -c1 h2

- 使用curl调用rest api进行获取mac地址表

- 使用curl调用rest api进行mac地址表的注册

- 在OVS上查看流表

可以看得到刚刚PUT的请求,也转化为流表的形式下发了
总结
学习到这里,基本了解一些RYU的一些大概框架和结构,知道如何相应事件去做相应的处理。接下来我将
- 学一下RYU对LLDP报文的机制
- 对该机制进行这3天来的实验汇总,功能包括对LLDP报文做相应处理,并在这基础上增加rest api的调用
RYU 灭龙战 fourth day (2)的更多相关文章
- RYU 灭龙战 fourth day (1)
RYU 灭龙战 fourth day (1) 前言 对于流量的监控,对于一个网络管理人员来说是非常重要的,可以从可视化的角度,方便检测出哪里的设备出了问题:而在传统网络中,如果是哪里的设备出了问题的话 ...
- RYU 灭龙战 third day
RYU 灭龙战 third day 前言 传统的交换机有自学习能力.然而你知道在SDN的世界里,脑子空空的OpenFlow交换机是如何学习的吗?今日说法带你领略SDN的mac学习能力. RYUBook ...
- RYU 灭龙战 second day(内容大部分引自网络)
RYU 灭龙战 second day(内容大部分引自网络) 写好的markdown重启忘了保存...再写一次RLG 巨龙的稀有装备-RYU代码结构 RYU控制器代码结构的总结 RYU入门教程 RYU基 ...
- RYU 灭龙战 first day
RYU 灭龙战 first day 前言 由于RYU翻译过来是龙的意思,此次主题就叫灭龙战吧 灵感来源 恶龙的三位真火-问题所在 参照了官方文档的基本操作 笔者以此执行 一个终端里 sudo mn - ...
- mininet和ryu控制器的连接
1.执行ryu应用程式:ryu-manager --verbose ryu.app.simple_switch_13 2.启动mininet,配置如下:创建3个host,1个交换器(open vSwi ...
- Ubuntu下搭建ryu环境
RYU环境搭建总共四步: step1:首先下载相应的python套件,并且更新pip $ sudo apt-get install python-pip python-dev build-essent ...
- Ryu
What's Ryu? Ryu is a component-based software defined networking framework. Ryu provides software co ...
- PIC12F629帮我用C语言写个程序,控制三个LED亮灭
http://power.baidu.com/question/240873584599025684.html?entry=browse_difficult PIC12F629帮我用C语言写个程序,控 ...
- (三)开关检测来控制LED灯的亮灭
开关检测案例一: 具体电路图如下: K1--K4闭合,控制 D1—D4 亮灭 产生的问题: 1.关于 R8 R9 R7 R10 的阻值选择问题,倘若太大的话, 比如10K 不管开关断开还是闭合,好像 ...
随机推荐
- AIX平台安装Oracle11gR2数据库
1. 前提条件 1.1 认证操作系统 Certification Information for Oracle Database on IBM AIX on Power systems(Doc ID ...
- Scala学习之路 (八)Scala的隐式转换和隐式参数
一.概念 Scala 2.10引入了一种叫做隐式类的新特性.隐式类指的是用implicit关键字修饰的类.在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换. 隐式转换和隐式参数是Scal ...
- ZOJ 4100 浙江省第16届大学生程序设计竞赛 A题 Vertices in the Pocket 线段树+并查集
正赛的时候完全没看这个题,事后winterzz告诉我他想出来的解法. 首先题意是给出n个点,m次操作. 操作有一种是连接两个点,另一种是求此时再为这个图连k条边,最少和最多能有几个联通块. 最少的求法 ...
- JVM系列三:JVM参数设置
JVM系列三:JVM参数设置.分析 不管是YGC还是Full GC,GC过程中都会对导致程序运行中中断,正确的选择不同的GC策略,调整JVM.GC的参数,可以极大的减少由于GC工作,而导致的程序运 ...
- OpenCV 中轮廓包裹的几个函数boundingRect、minAreaRect、minEnclosingCircle用法
当我们得到对象轮廓后,可用boundingRect()得到包覆此轮廓的最小正矩形,minAreaRect()得到包覆轮廓的最小斜矩形,minEnclosingCircle()得到包覆此轮廓的最小圆形, ...
- PAT B1005 继续(3n+1)猜想 (25 分)
卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数.例如对 n=3 进行验证的时 ...
- 404 Note Found队 Beta答辩总结
目录 所有成员 项目宣传视频链接 贡献比例 工作流程 组员分工 本组 Beta 冲刺站立会议博客链接汇总 燃尽图 原计划.达成情况及原因分析 组员:胡绪佩 组员:周政演 组员:庄卉 组员:何家伟 组员 ...
- OpenCV学习C++接口 Mat像素遍历详解
OpenCV学习C++接口 Mat像素遍历详解
- libgdx学习记录16——资源加载器AssetManager
AssetManager用于对游戏中的资源进行加载.当游戏中资源(图片.背景音乐等)较大时,加载时会需要较长时间,可能会阻塞渲染线程,使用AssetManager可以解决此类问题. 主要优点: 1. ...
- CS190.1x-ML_lab5_pca_student
这次lab也是最后一次lab了,前面两次lab介绍了回归和分类,特别详细地介绍了线性回归和逻辑回归,这次的作业主要是非监督学习--降维,主要是PCA.数据集是神经科学的数据,来自于Ahrens Lab ...