实验目标:

(1)实现网络拓扑的各个主机之间的相互通信

(2)实现各个自治域的控制器的流表获取(各个控制器的流表信息互通)

(3)实现应用层对控制器的控制,进而实现对整个网络的控制

大致的实现效果如下:

实验原理:

利用mininet进行拓扑的模拟,构建多个控制器组成的网络。由于SDN网络留有北向接口,所以利用北向接口就可以对网络的流表等信息进行获取,在ryu中,ofctl_rest.py即是restapi的实现。本次实验,通过在docker中运行ryu控制器,同时运行ofctl_rest.py和simple_switch_13.py,然后利用python程序的get()、post()等方法对控制器的流表信息进行获取和添加,这样就实现了对流表信息的操作,同时也可以实现多个控制器流表信息的互通(公用一块公共的存储空间,如数据库),但是本次只演示基本的获取和流表的基本添加删除等操作。

实验拓扑构建:

工具:mininet进行拓扑搭建,Docker作为控制器

mininet构建实验拓扑,模拟自治域AS1和AS2,r4和r5作为自治域的边界路由器,实现域间路由。每个自治域由一台控制器控制(远端控制器最终运行在Docker上),若干台主机组成。最终通过配置路由表,实现域间的通信,实现整个网络架构各个主机之间的通信即为拓扑搭建完成。如图所示。

主机、交换机、控制器设置如下图所示。

各项设置完成无误后,运行网络拓扑。

路由表和Docker ryu配置:

(1)Docker ryu配置

关于Docker镜像ymumu/ryu:0.1:

可以参考文章(Docker命令、基于Docker的SDN实验环境部署(1)_北风-CSDN博客)

使用如下命令进行镜像ymumu/ryu的安装:

docker pull ymumu/ryu:0.1

新建两个Docker并且进行空间挂载,分别运行两个自治域的控制器,命令如下。

root@ymumu-VirtualBox:/home/ymumu# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ymumu/ryu    0.1       edb38c9e5a5c   3 weeks ago   719MB
root@ymumu-VirtualBox:/home/ymumu# docker run -it --name as1-ryu1 -v /home/ymumu/ryu/ryu/app:/home/ryu/ryu/app ymumu/ryu:0.1 /bin/bashroot@ymumu-VirtualBox:/home/ymumu# docker run -it --name as2-ryu1 -v /home/ymumu/ryu/ryu/app:/home/ryu/ryu/app ymumu/ryu:0.1 /bin/bash

以simple_switch_13为例,接下来,在各个Docker中开启ryu,命令步骤如下所示。其中,ofctl_rest.py是开启控制器的北向接口,simple_switch_13.py作为自学习交换机。

以上完成后,各个自治域内部的各个主机之间就可以通过自学习交换机进行通信,而不可以进行跨域通信,接下来就需要设置路由器和路由表。

(2)路由表配置

首先,设置两个路由器各个端口ip,命令如下。

mininet> r4 ip addr add 10.0.1.101/24 dev r4-eth0
mininet> r4 ip addr add 10.0.1.102/24 dev r4-eth1
mininet> r4 ip addr add 10.0.3.1/24 dev r4-eth2
mininet> r5 ip addr add 10.0.2.101/24 dev r5-eth0
mininet> r5 ip addr add 10.0.3.2/24 dev r5-eth1

接下来,设置路由器的路由表,命令如下。

# 添加路由表
mininet> r4 ip route add 10.0.2.0/24 via 10.0.3.2 dev r4-eth2
mininet> r5 ip route add 10.0.1.0/24 via 10.0.3.1 dev r5-eth1
# 查看路由器中的路由表
mininet> r4 ip r
10.0.1.0/24 dev r4-eth0 proto kernel scope link src 10.0.1.101
10.0.1.0/24 dev r4-eth1 proto kernel scope link src 10.0.1.102
10.0.2.0/24 via 10.0.3.2 dev r4-eth2
10.0.3.0/24 dev r4-eth2 proto kernel scope link src 10.0.3.1
mininet> r5 ip r
10.0.1.0/24 via 10.0.3.1 dev r5-eth1
10.0.2.0/24 dev r5-eth0 proto kernel scope link src 10.0.2.101
10.0.3.0/24 dev r5-eth1 proto kernel scope link src 10.0.3.2 

然后,向各个主机添加路由表,为了简单起见,直接在各个主机中添加默认路由表,命令如下。

# 向as1-h1添加默认路由表
ip route add default via 10.0.1.101 dev as1-h1-eth0
# 向as1-h2添加默认路由表
ip route add default via 10.0.1.101 dev as1-h2-eth0
# 向as1-h3添加默认路由表
ip route add default via 10.0.1.102 dev as1-h3-eth0
# 向as2-h1添加默认路由表
ip route add default via 10.0.2.101 dev as2-h1-eth0
# 向as2-h2添加默认路由表
ip route add default via 10.0.2.101 dev as2-h2-eth0

以上所有路由表设置完成,网络中各个主机之间就可以相互通信了。

应用层编码

(1)原理

ryu控制器留有北向接口,即ofctl_rest.py,其通过restapi向应用层提供接口,应用层可以通过接口获取流表等信息并对流表进行操作。关于ryu的应用层接口的api使用,可以参考ryu docs:ryu.app.ofctl_rest — Ryu 4.34 documentation

通过文档可以知道,使用get()方法可以进行流表等信息的获取,使用post()方法可以实现流表等的下发操作,使用delete()方法可以实现流表等信息的删除。因此,使用pytho的get()等方法进行应用层程序的编写。

(2)获取流表

根据ryu docs中获取流表的方法为get(),url=http://ip:port/stats/flow/dpid,所以首先需要获取转发层面的控制器的dpid,获取dpid的url=http://ip:port/stats/switches,所以利用get()方法获取dpid,再根据dpid获取所有的流表,最后将流表显示出来。

    # 通过get()获取交换机的dpid,并将其转化为16进制存入列表def get_switch_id(self):url = 'http://' + self.ip + ':' + self.port + '/stats/switches're_switch_id = requests.get(url=url).json()switch_id_hex = []for i in re_switch_id:switch_id_hex.append(hex(i))return switch_id_hex# 通过get()和获取的dpid得到每一个交换机的流表项def get_flow_table(self):url = 'http://' + self.ip + ':' + self.port + '/stats/flow/%d'list_switch = self.get_switch_id()all_flow = []for switch in list_switch:new_url = format(url % int(switch, 16))re_switch_flow = requests.get(url=new_url).json()all_flow.append(re_switch_flow)return all_flow

(3)下发流表操作(添加、删除、清空)

下发流表操作的方法使用post(),对于流表的添加,在ryu docs中使用的api的url=http://ip:port/stats/flowentry/add。然后,发送的信息包括,dpid,cookie,in_port在内的各项流表项信息。添加流表项的程序如下。

    # 向控制器发送添加流表项的请求def post_add_flow(self, dpid=None, cookie=0, priority=0, in_port=1, type='OUTPUT', port='CONTROLLER'):url = 'http://' + self.ip + ':' + self.port + '/stats/flowentry/add'if in_port == 'None':# 添加的默认流表项数据信息data = {"dpid": dpid,"cookie": cookie,"cookie_mask": 0,"table_id": 0,"priority": priority,"flags": 0,"actions": [{"type": type,"port": port}]}else:in_port = int(in_port)data = {"dpid": dpid,"cookie": cookie,"cookie_mask": 0,"table_id": 0,"priority": priority,"flags": 0,"match": {"in_port": in_port},"actions": [{"type": type,"port": port}]}# 如果正确添加,则返回200OKresponse = requests.post(url=url, json=data)if response.status_code == 200:print('Successfully Add!')else:print('Fail!')

删除流表项,即通过发送匹配信息,删除和指令匹配的流表项,在ryu docs中的url=http://ip:port/stats/flowentry/delete_strict,然后,发送的信息包括,dpid,cookie,in_port在内的各项流表项匹配信息。删除流表项的程序如下。

    def post_del_flow(self, dpid=None, cookie=0, priority=0, in_port=1, type='OUTPUT', port='CONTROLLER'):url = url = 'http://' + self.ip + ':' + self.port + '/stats/flowentry/delete_strict'data = {"dpid": dpid,"cookie": cookie,"cookie_mask": 1,"table_id": 0,"priority": priority,"flags": 1,"match": {"in_port": in_port,},"actions": [{"type": type,"port": port}]}response = requests.post(url=url, json=data)if response.status_code == 200:print('Successfully Delete!')else:print('Fail!')

对于清空流表项,在ryu docs中给出的例子,只需要用delete()方法向控制器请求特定url即可清空指定的交换机的流表项。程序如下。

    def post_clear_flow(self, dpid=None):url = 'http://' + self.ip + ':' + self.port + '/stats/flowentry/clear/' + str(dpid)response = requests.delete(url=url)if response.status_code == 200:print('Successfully Clear!')else:print('Fail!')

接下来,就是主函数的编写,调用各个方法实现目标,这里不再叙述,文末有完整源码链接。

实验效果:

实验演示和操作如视频所示。

ryu_operation_哔哩哔哩_bilibili

github源码地址:https://github.com/Yang-Jianlin/ryu/tree/master/ryu/app/ryu_restapi_operation

以上就是全部内容,如有疑问请私信或留言,谢谢。

ryu--北向接口(流表的操作以及多控制器流表信息互通)相关推荐

  1. mysql触发器对同一张表做操作_MySql 触发器对同表操作

    触发器初始结构: DELIMITER $$ CREATE TRIGGER `数据库名`.`触发器名` BEFORE/AFTER INSERT/UPDATE/DELETE ON `数据库名`.`表名` ...

  2. 字符流、转换流、对象操作流、Properties

    目录 编码表 字符流编码和解码的方式 字符流-读取中文的过程 字符流-写出数据(字符流写数据) 字符流写出数据的注意事项 字符流-flush和close方法 字符流-读取数据(字符流读数据) 字符缓冲 ...

  3. Node 简介、模块、模板引擎、NPM、文件操作、缓冲区、文件流、网络操作、Express框架

    一.Node简介 1.1 客户端的JavaScript是怎样的 问题 答 什么是 JavaScript 脚本语言 运行在浏览器中 一般用来做客户端页面的交互(Interactive) JavaScri ...

  4. 淘宝直通车为什么要低价引流,低价引流的原理、低价引流的具体操作

    前期也跟大讲了不少关于直通车的一些小技巧了,总所周知开直通车是需要有一定的资金的,但是低价能开直通吗,今天我们就来跟大家讲讲怎样低价开直通车. 一.低价引流的核心原理 1.做到低价的两个核心就是精准长 ...

  5. day12 字符流、字符缓冲流、转换流、对象操作流、Properties

    目录 一.字符流 1.1 字节流操作文本文件出现乱码问题 1.2 编码表 1.3 String字符串中编码和解码的方法 1.3.1.编码 1.3.2.解码 1.4 字节流读取中文出现乱码的原因 1.5 ...

  6. 数据库基础操作(二)数据库表数据的增删查改

    一.插入数据 insert 向表中制定字段添加数据:insert into 表 (字段名1,字段名2......) values(值1,值2......); 向表中所有字段添加数据:insert in ...

  7. 【MySQL】数据库基本操作、表的操作

    一.数据库 1.什么是数据库 2.数据库基本操作 2.1.显示数据库 2.2. 创建数据库 2.3.选中数据库 2.4.删除数据库 3.数据库分类 4.MySQL 安装 二.数据表的使用 1. 常用数 ...

  8. 实验报告微型计算机拆卸顺序表,顺序表的操作实验报告馒头制作.doc

    顺序表的操作实验报告馒头制作 实验二 顺序表的操作实验报告 班 级10计科2学号20104012010姓名翁朝伟实验名称顺序表的操作实验目的掌握线性表的顺序存储结构的基本概念.基本操作和应用实验环境硬 ...

  9. SDN软件定义网络 学习笔记(3)--北向接口、东西向接口

    1. 北向接口 北向接口提供了 SDN 中开发者与控制器间的交互功能.从更为宽泛的角度考虑,北向接口在 SDN 控制器中的作用类似于命令行在传统NOS 中的作用,都是实现了网络管理者对网络的设计与管理 ...

最新文章

  1. Code Hunt SECTOR2(Loops) SECTOR3(Loops2)
  2. 5、CSS 派生选择器
  3. wxWidgets:wxHashTable类用法
  4. jquery this 与javascript的this
  5. 黄金寨景区、缥缈间温泉2019北京推介会成功举办
  6. golang import中的.和_的使用,import的几种方式点,下划线,别名
  7. 7-218 修理牧场 (25 分)
  8. 格力又双叒发福利了 将给所有员工交电话费!
  9. 微信分享接口 略缩图 php
  10. 《Big Data Glossary》笔记
  11. 编译WINDOWS版FFmpeg:编译FFmpeg
  12. MTK(Android N)设置SDCard为默认存储
  13. xubuntu装macos未能与服务器,macbook 安装ubuntu(Xubuntu)完整攻略
  14. 网站流量日志数据分析系统与技术架构
  15. 【学术相关】人工智能300年!LSTM之父万字长文:详解现代AI和深度学习发展史...
  16. mybaties学习笔记
  17. 树莓派3B安装64位操作系统(树莓派无需连接显示器键盘鼠标)
  18. Android,SharedPreferences的使用
  19. 机械秒表的使用方法_浪琴 L683、L688自动上弦机械计时秒表设置方法
  20. DEVC++小游戏狼人杀

热门文章

  1. 如何写出优雅的代码 吐血整理
  2. java nio下载_Java Nio 多线程网络下载
  3. 中南大学941计算机网络考试大纲,中南大学计算机网络问答题
  4. 华为手机内存总是不够用?这几个设置没关闭,内存再大也不够用
  5. JEDEC标准的DDR频率
  6. PythonStock(11):使用pandas计算股票波峰波谷猜想
  7. cdb取得死循环进程的调用栈
  8. 翻译:通往WinDbg的捷径(一)
  9. 单片机C语言视频教程转让
  10. TCP协议详解之TCP Flag标志位来判断TCP会话的开始和结束