REST Linkage

该小结主要介绍如何添加一个REST Link 函数

RYU本身提供了一个类似WSGI的web服务器功能。借助这个功能,我们可以创建一个REST API。
基于创建的REST API,可以快速的将RYU系统与其他系统或者是浏览器相连接,非常实用的一个功能。

程序解析

在案例中,实现了两个类

  • SimpleSwitchRest13

    • 继承SimpleSwitch13的功能,即具备父类的三层交换机的基本功能。
    • 注册WSGI服务
    • 配置mac_to_port
  • SimpleSwitchController
    • REST API功能实现的主体类
    • 返回指定交换机的mac_table
    • 更新指定的mac_table条目

SimpleSwitchRest13类实现

_CONTEXTS = {'wsgi': WSGIApplication}

该成员变量用于指明Ryu的兼容WSGI的web服务对象。

wsgi = kwargs['wsgi']
wsgi.register(SimpleSwitchController,{simple_switch_instance_name: self})

通过上一步设置的_CONTEXTS成员变量,可以通过kwargs进行实例化一个WSGIApplication。同时使用register方法注册该服务到
controller类上。

@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):super(SimpleSwitchRest13, self).switch_features_handler(ev)datapath = ev.msg.datapathself.switches[datapath.id] = datapathself.mac_to_port.setdefault(datapath.id, {})

重写父类的switch_features_handler函数

  • 存储datapath到switches
  • 初始化MAC 地址表
def set_mac_to_port(self, dpid, entry):# 获取MAC tablemac_table = self.mac_to_port.setdefault(dpid, {})# 获取datapath,如果为None,证明没有该交换机datapath = self.switches.get(dpid)entry_port = entry['port']entry_mac = entry['mac']if datapath is not None:parser = datapath.ofproto_parser# 如果entry_port不在mac_table中if entry_port not in mac_table.values():# 下发流表for mac, port in mac_table.items():# from known device to new deviceactions = [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 deviceactions = [parser.OFPActionOutput(port)]match = parser.OFPMatch(in_port=entry_port, eth_dst=mac)self.add_flow(datapath, 1, match, actions)# 添加entry_mac, entry_port到mac_tablemac_table.update({entry_mac: entry_port})return mac_table

该方法将MAC地址和端口注册到指定的交换机。该方法主要被REST API的PUT方法所调用。

SimpleSwitchController类实现

@route('simpleswitch', url, methods=['GET'],requirements={'dpid': dpid_lib.DPID_PATTERN})

借助route装饰器关联方法和URL。参数如下:

  • 第一个参数:任何自定义名称
  • 第二个参数:指明URL
  • 第三个参数:指定http方法
  • 第四个参数:指明指定位置的格式,URL(/simpleswitch/mactable/{dpid} 匹配DPID_PATTERN的描述

当使用GET方式访问到该REST API接口时,调用list_mac_table函数

def list_mac_table(self, req, **kwargs):simple_switch = self.simple_switch_app# 获取{dpid}dpid = dpid_lib.str_to_dpid(kwargs['dpid'])# 如果没有dpid,返回404if dpid not in simple_switch.mac_to_port:return Response(status=404)# 获取mac_tablemac_table = simple_switch.mac_to_port.get(dpid, {})body = json.dumps(mac_table)return Response(content_type='application/json', body=body)
# 使用PUT方式设置mac_table
@route('simpleswitch', url, methods=['PUT'],requirements={'dpid': dpid_lib.DPID_PATTERN})def put_mac_table(self, req, **kwargs):simple_switch = self.simple_switch_appdpid = 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)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 -x

启动控制器程序,打印log信息如下:

debugging is available (--enable-debugger option is turned on)
loading app SimpleSwitchRest13
loading app ryu.controller.ofp_handler
creating context wsgi
instantiating app SimpleSwitchRest13 of SimpleSwitchRest13
instantiating app ryu.controller.ofp_handler of OFPHandler
BRICK SimpleSwitchRest13CONSUMES EventOFPPacketInCONSUMES EventOFPSwitchFeatures
BRICK ofp_eventPROVIDES EventOFPPacketIn TO {'SimpleSwitchRest13': set(['main'])}PROVIDES EventOFPSwitchFeatures TO {'SimpleSwitchRest13': set(['config'])}CONSUMES EventOFPEchoReplyCONSUMES EventOFPSwitchFeaturesCONSUMES EventOFPPortDescStatsReplyCONSUMES EventOFPHelloCONSUMES EventOFPErrorMsgCONSUMES EventOFPEchoRequestCONSUMES EventOFPPortStatus
(22238) wsgi starting up on http://0.0.0.0:8080

这里我们可以看到,wsgi服务已经启动,端口号为8080

查询s1的默认MAC table

curl -X GET http://127.0.0.1:8080/simpleswitch/mactable/0000000000000001

返回为{}

在mininet中执行

mininet> h1 ping -c 1 h2

log信息打印如下信息:

EVENT ofp_event->SimpleSwitchRest13 EventOFPPacketIn
packet in 1 00:00:00:00:00:01 ff:ff:ff:ff:ff:ff 1
EVENT ofp_event->SimpleSwitchRest13 EventOFPPacketIn
packet in 1 00:00:00:00:00:02 00:00:00:00:00:01 2
EVENT ofp_event->SimpleSwitchRest13 EventOFPPacketIn
packet in 1 00:00:00:00:00:01 00:00:00:00:00:02 1

返回了三条PackageIn消息(ARP过程)

  1. host1发起的ARP请求,并广播
  2. host2发起的ARP请求,MAC地址是host1
  3. ICMP echo reply request 从host1 发生到host2

此刻按照设计,已经添加了两条条目到MAC table,再次查询进行验证。

curl -X GET http://127.0.0.1:8080/simpleswitch/mactable/0000000000000001

返回如下,证明符合实验预期:

{"00:00:00:00:00:02": 2, "00:00:00:00:00:01": 1}

测试POST API接口,添加h3到MAC Table

curl -X PUT -d '{"mac" : "00:00:00:00:00:03", "port" : 3}' http://127.0.0.1:8080/simpleswitch/mactable/0000000000000001

返回:

{"00:00:00:00:00:03": 3, "00:00:00:00:00:02": 2, "00:00:00:00:00:01": 1}

证明h3 mac已经被添加到MAC table。因为h3已经被添加到MAC Table中,所以理论上当h1 ping h3时将不再通过ARP查找到h3.

测试:在mininet中执行命令

mininet> h1 ping c1 h3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=2.48 ms--- 10.0.0.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.480/2.480/2.480/0.000 ms

控制器log信息如下:

EVENT ofp_event->SimpleSwitchRest13 EventOFPPacketIn
packet in 1 00:00:00:00:00:01 ff:ff:ff:ff:ff:ff 1

我们可以看到,只有h1在不知道h3地址的情况下,发起ARP广播,将PackageIn消息发送到控制器,而不再出现以后的一系列消息。这证明
MAC Table中添加的条目成功生效,符合预期情况。

转载于:https://www.cnblogs.com/NinWoo/p/9530556.html

RyuBook1.0案例三:REST Linkage相关推荐

  1. Scratch3.0——助力新进程序员理解程序(难度案例三、五子棋双人对战-电脑需要AI写不出来)

    Scratch3.0--助力新进程序员理解程序(难度案例三.五子棋双人对战-电脑需要AI写不出来) 前言 一般来说,针对6-18岁的少年儿童开展的编程教育,现在,最常见的形式是线上和线下模式相结合的课 ...

  2. 2021年大数据Flink(二十一):​​​​​​​案例三 会话窗口

    目录 案例三 会话窗口 需求 代码实现 案例三 会话窗口 需求 设置会话超时时间为10s,10s内没有数据到来,则触发上个窗口的计算 代码实现 package cn.it.window;import ...

  3. Redis简单案例(三) 连续登陆活动的简单实现

    原文:Redis简单案例(三) 连续登陆活动的简单实现 连续登陆活动,或许大家都不会陌生,简单理解就是用户连续登陆了多少天之后,系统就会送一些礼品给相应的用户.最常见的 莫过于游戏和商城这些.游戏就送 ...

  4. 案例三:执行 JavaScript 语句

    案例三:执行 JavaScript 语句 隐藏百度图片 from selenium import webdriverdriver = webdriver.PhantomJS() driver.get( ...

  5. zabbix生产环境案例(三)

    生产环境案例(三) 链接:https://pan.baidu.com/s/1q5YwJMTcZLcS5OQ0iOu44A 提取码:8gdi 复制这段内容后打开百度网盘手机App,操作更方便哦 1. Z ...

  6. k8s、Deployment多副本资源详解、SERVICE通信、案例一nginx端口暴漏、案例二tomcat端口暴漏、案例三jenkins端口暴漏

    文章目录 案例一 创建SERVICE 案例一nginx端口暴露 案例二tomcat端口暴露 案例三jenkins端口暴漏 使用yaml创建Deployment k8s deployment资源创建流程 ...

  7. Excel数据分析案例三——预测销量

    Excel数据分析案例三--预测销量 题目:有某服装实体店5.1~5.24每天的销售数据表,要求根据现有的销量数据预测接下来一星期,也就是5.25 ~ 5.30的销量,图表大致信息如下 此时需要用到E ...

  8. Python自学笔记6:实操案例三(十进制转换二、八、十六进制),手机充值,计算能量消耗,预测未来子女身高

    Python自学笔记6:实操案例三(十进制转换二.八.十六进制),手机充值,计算能量消耗,预测未来子女身高 杨淑娟老师网课传送门(非广告):https://www.bilibili.com/video ...

  9. 人工智能学习联盟免费课程——案例三:BMR计算器

    案例三:BMR计算器 文章目录 案例三:BMR计算器 1.一次输入多条信息 2.{}占位符 3.try-except机制 4.最后的BMR计算器 本案例基本是对案例一的回顾和复习,同时添加了三点新内容 ...

  10. 【b站黑马程序员C++视频学习笔记-多态案例三-电脑组装】

    多态案例三-电脑组装 电脑主要组成部件为CPU(用于计算),显卡(用于显示),内存条(用于存储).把每个零件封装出抽象父类,并且提供不同的厂商生产不同的零件,例如Intel厂商和Lenovo厂商.创建 ...

最新文章

  1. 2020年“3D视觉工坊”视频号最受欢迎视频 Top 10!
  2. JS String类型整理
  3. linux块设备驱动(一)——块设备概念介绍
  4. 进程和线程的概念、区别和联系
  5. hibernate oracle驱动,出错场景是升级oracle驱动,将版本从ojdbc14升级到ojdbc6,hibernate执行原生态sql语句会报如下错误...
  6. It is worth noting that among the four
  7. 数据中心生成器行业调研报告 - 市场现状分析与发展前景预测
  8. PHP设计模式——简单工厂
  9. 25 The Go image/draw package go图片/描绘包:图片/描绘包的基本原理
  10. xml property标签注入一个类变量_java开发两年,连Spring的依赖注入的方式都搞不清楚,你工作可能有点悬!...
  11. MATLAB神经网络工具箱(代码简单实现)
  12. Linux 磁盘满了如何扩容
  13. 揭开 LVS 神秘的面纱
  14. Python笔试练习题
  15. 飞思卡尔 S12 (X)串口下载移植
  16. 【系统分析师之路】2015年系统分析师上午综合知识真题
  17. 统计学第八周,第九周
  18. Aruba 无线配置
  19. 身份认证 Session认证机制 Cookie原理
  20. CF-D:Backspace

热门文章

  1. hdu 1231最大连续子序列 动态规划
  2. 在 Mac 上的登录窗口中如何打开辅助功能选项?
  3. 说说vue-cli中使用flexible和px2rem-loader
  4. 文本验证码被曝漏洞,淘宝、京东都中招!
  5. 深度 | 朴素贝叶斯模型算法研究与实例分析
  6. 强大的日志分析工具AWStats
  7. 微软从 Engine Yard 手中收购容器平台 Deis
  8. 韩开发新技术 用纸代替硅制造电路芯片
  9. IOS恢复备份使用帮助
  10. 阿里的dubbo 到底是用来干嘛的?