实验7:基于REST API的SDN北向应用实践
一、实验目的
1.能够编写程序调用OpenDaylight REST API实现特定网络功能;
2.能够编写程序调用Ryu REST API实现特定网络功能。
二、实验环境
下载虚拟机软件Oracle VisualBox或VMware;
在虚拟机中安装Ubuntu 20.04 Desktop amd64,并完整安装Mininet、OpenDaylight(Carbon版本)、Postman和Ryu;
三、实验基本要求
1.OpenDaylight
(1) 利用Mininet平台搭建下图所示网络拓扑,并连接OpenDaylight
(2) 编写Python程序,调用OpenDaylight的北向接口下发指令删除s1上的流表数据。
- delete.py
#!/usr/bin/python
import requests
from requests.auth import HTTPBasicAuth
if __name__ == "__main__":
url = 'http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/'
headers = {'Content-Type': 'application/json'}
res = requests.delete(url, headers=headers, auth=HTTPBasicAuth('admin', 'admin'))
print (res.content)
(3) 编写Python程序,调用OpenDaylight的北向接口下发硬超时流表,实现拓扑内主机h1和h3网络中断20s。
- put.py
#!/usr/bin/python
import requests
from requests.auth import HTTPBasicAuth
if __name__ == "__main__":
url = 'http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/flow/1'
with open("./flowtable.json") as f:
jstr = f.read()
headers = {'Content-Type': 'application/json'}
res = requests.put(url, jstr, headers=headers, auth=HTTPBasicAuth('admin', 'admin'))
print (res.content)
- flowtable.json
{
"flow": [
{
"id": "1",
"match": {
"in-port": "1",
"ethernet-match": {
"ethernet-type": {
"type": "0x0800"
}
},
"ipv4-destination": "10.0.0.3/32"
},
"instructions": {
"instruction": [
{
"order": "0",
"apply-actions": {
"action": [
{
"order": "0",
"drop-action": {}
}
]
}
}
]
},
"flow-name": "flow1",
"priority": "65535",
"hard-timeout": "20",
"cookie": "2",
"table_id": "0"
}
]
}
(4) 编写Python程序,调用OpenDaylight的北向接口获取s1上活动的流表数。
- get.py
#!/usr/bin/python
import requests
from requests.auth import HTTPBasicAuth
if __name__ == "__main__":
url = 'http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/opendaylight-flow-table-statistics:flow-table-statistics'
headers = {'Content-Type': 'application/json'}
res = requests.get(url,headers=headers, auth=HTTPBasicAuth('admin', 'admin'))
print (res.content)
Ryu操作
(1) 编写Python程序,调用Ryu的北向接口,实现上述OpenDaylight实验拓扑上相同的硬超时流表下发。
- put1.py
import requests
from requests.auth import HTTPBasicAuth
def http_post(url,jstr):
url= url
headers = {'Content-Type':'application/json'}
resp = requests.post(url,jstr,headers=headers)
return resp
if __name__ == "__main__":
url='http://127.0.0.1:8080/stats/flowentry/add'
with open('flowtable1.json') as f:
jstr = f.read()
resp = http_post(url,jstr)
print (resp.content)
- flowtable1.json
{
"dpid": 1,
"cookie": 1,
"cookie_mask": 1,
"table_id": 0,
"hard_timeout": 20,
"priority": 65535,
"flags": 1,
"match":{
"in_port":1
},
"actions":[
{
"type":"OUTPUT",
"port": 2
}
]
}
(2) 利用Mininet平台搭建下图所示网络拓扑,要求支持OpenFlow 1.3协议,主机名、交换机名以及端口对应正确。拓扑生成后需连接Ryu,且Ryu应能够提供REST API服务。
(3) 整理一个Shell脚本,参考Ryu REST API的文档,利用curl命令,实现和实验2相同的VLAN。
VLAN_ID | Hosts |
---|---|
0 | h1 h3 |
1 | h2 h4 |
- shell脚本
curl -X POST -d '{
"dpid": 1,
"priority": 1,
"match":{
"in_port": 1
},
"actions":[
{
"type": "PUSH_VLAN",
"ethertype": 33024
},
{
"type": "SET_FIELD",
"field": "vlan_vid",
"value": 4096
},
{
"type": "OUTPUT",
"port": 3
}
]
}' http://localhost:8080/stats/flowentry/add
curl -X POST -d '{
"dpid": 1,
"priority": 1,
"match":{
"in_port": 2
},
"actions":[
{
"type": "PUSH_VLAN",
"ethertype": 33024
},
{
"type": "SET_FIELD",
"field": "vlan_vid",
"value": 4097
},
{
"type": "OUTPUT",
"port": 3
}
]
}' http://localhost:8080/stats/flowentry/add
curl -X POST -d '{
"dpid": 1,
"priority": 1,
"match":{
"vlan_vid": 0
},
"actions":[
{
"type": "POP_VLAN",
"ethertype": 33024
},
{
"type": "OUTPUT",
"port": 1
}
]
}' http://localhost:8080/stats/flowentry/add
curl -X POST -d '{
"dpid": 1,
"priority": 1,
"match":{
"vlan_vid": 1
},
"actions":[
{
"type": "POP_VLAN",
"ethertype": 33024
},
{
"type": "OUTPUT",
"port": 2
}
]
}' http://localhost:8080/stats/flowentry/add
curl -X POST -d '{
"dpid": 2,
"priority": 1,
"match":{
"in_port": 1
},
"actions":[
{
"type": "PUSH_VLAN",
"ethertype": 33024
},
{
"type": "SET_FIELD",
"field": "vlan_vid",
"value": 4096
},
{
"type": "OUTPUT",
"port": 3
}
]
}' http://localhost:8080/stats/flowentry/add
curl -X POST -d '{
"dpid": 2,
"priority": 1,
"match":{
"in_port": 2
},
"actions":[
{
"type": "PUSH_VLAN",
"ethertype": 33024
},
{
"type": "SET_FIELD",
"field": "vlan_vid",
"value": 4097
},
{
"type": "OUTPUT",
"port": 3
}
]
}' http://localhost:8080/stats/flowentry/add
curl -X POST -d '{
"dpid": 2,
"priority": 1,
"match":{
"vlan_vid": 0
},
"actions":[
{
"type": "POP_VLAN",
"ethertype": 33024
},
{
"type": "OUTPUT",
"port": 1
}
]
}' http://localhost:8080/stats/flowentry/add
curl -X POST -d '{
"dpid": 2,
"priority": 1,
"match":{
"vlan_vid": 1
},
"actions":[
{
"type": "POP_VLAN",
"ethertype": 33024
},
{
"type": "OUTPUT",
"port": 2
}
]
}' http://localhost:8080/stats/flowentry/add
四、实验进阶要求
编程实现基本要求第2部分Ryu(3)中的VLAN划分。
删除流表
curl -X DELETE http://localhost:8080/stats/flowentry/clear/1
curl -X DELETE http://localhost:8080/stats/flowentry/clear/2
#!/usr/bin/python
import json
import requests
if __name__ == "__main__":
url = 'http://127.0.0.1:8080/stats/flowentry/add'
headers = {'Content-Type': 'application/json'}
flow1 = {
"dpid": 1,
"priority": 1,
"match":{
"in_port": 1
},
"actions":[
{
"type": "PUSH_VLAN", # Push a new VLAN tag if a input frame is non-VLAN-tagged
"ethertype": 33024 # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged frame
},
{
"type": "SET_FIELD",
"field": "vlan_vid", # Set VLAN ID
"value": 4096 # Describe sum of vlan_id(e.g. 6) | OFPVID_PRESENT(0x1000=4096)
},
{
"type": "OUTPUT",
"port": 3
}
]
}
flow2 = {
"dpid": 1,
"priority": 1,
"match":{
"in_port": 2
},
"actions":[
{
"type": "PUSH_VLAN", # Push a new VLAN tag if a input frame is non-VLAN-tagged
"ethertype": 33024 # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged frame
},
{
"type": "SET_FIELD",
"field": "vlan_vid", # Set VLAN ID
"value": 4097 # Describe sum of vlan_id(e.g. 6) | OFPVID_PRESENT(0x1000=4096)
},
{
"type": "OUTPUT",
"port": 3
}
]
}
flow3 = {
"dpid": 1,
"priority": 1,
"match":{
"vlan_vid": 0
},
"actions":[
{
"type": "POP_VLAN", # Push a new VLAN tag if a input frame is non-VLAN-tagged
"ethertype": 33024 # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged frame
},
{
"type": "OUTPUT",
"port": 1
}
]
}
flow4 = {
"dpid": 1,
"priority": 1,
"match": {
"vlan_vid": 1
},
"actions": [
{
"type": "POP_VLAN", # Push a new VLAN tag if a input frame is non-VLAN-tagged
"ethertype": 33024 # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged frame
},
{
"type": "OUTPUT",
"port": 2
}
]
}
flow5 = {
"dpid": 2,
"priority": 1,
"match": {
"in_port": 1
},
"actions": [
{
"type": "PUSH_VLAN", # Push a new VLAN tag if a input frame is non-VLAN-tagged
"ethertype": 33024 # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged frame
},
{
"type": "SET_FIELD",
"field": "vlan_vid", # Set VLAN ID
"value": 4096 # Describe sum of vlan_id(e.g. 6) | OFPVID_PRESENT(0x1000=4096)
},
{
"type": "OUTPUT",
"port": 3
}
]
}
flow6 = {
"dpid": 2,
"priority": 1,
"match": {
"in_port": 2
},
"actions": [
{
"type": "PUSH_VLAN", # Push a new VLAN tag if a input frame is non-VLAN-tagged
"ethertype": 33024 # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged frame
},
{
"type": "SET_FIELD",
"field": "vlan_vid", # Set VLAN ID
"value": 4097 # Describe sum of vlan_id(e.g. 6) | OFPVID_PRESENT(0x1000=4096)
},
{
"type": "OUTPUT",
"port": 3
}
]
}
flow7 = {
"dpid": 2,
"priority": 1,
"match": {
"vlan_vid": 0
},
"actions": [
{
"type": "POP_VLAN", # Push a new VLAN tag if a input frame is non-VLAN-tagged
"ethertype": 33024 # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged frame
},
{
"type": "OUTPUT",
"port": 1
}
]
}
flow8 = {
"dpid": 2,
"priority": 1,
"match": {
"vlan_vid": 0
},
"actions": [
{
"type": "POP_VLAN", # Push a new VLAN tag if a input frame is non-VLAN-tagged
"ethertype": 33024 # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged frame
},
{
"type": "OUTPUT",
"port": 1
}
]
}
res1 = requests.post(url, json.dumps(flow1), headers=headers)
res2 = requests.post(url, json.dumps(flow2), headers=headers)
res3 = requests.post(url, json.dumps(flow3), headers=headers)
res4 = requests.post(url, json.dumps(flow4), headers=headers)
res5 = requests.post(url, json.dumps(flow5), headers=headers)
res6 = requests.post(url, json.dumps(flow6), headers=headers)
res7 = requests.post(url, json.dumps(flow7), headers=headers)
res8 = requests.post(url, json.dumps(flow8), headers=headers)
五、个人心得
- 这次作业有点难了,留的挺好,下次不许留了
(皮一下,嘿嘿嘿,无恶意)
- ODL和Ryu的一些操作指令忘得一干二净了,问题不大。。。。。。翻阅了以前的实验指导复习了一遍
- 自从虚拟机重新装了之后,这个pingall总是连不上我也不清楚是怎么回事,要是运行起来了,就什么也不要碰不管他是怎么运行的,再打开可能就用不了了
- 建议做完每次实验之后把流表删除干净,会影响下次实验
- PS:cur忘记下载了。。。。。。问了同学才发现。。。。
实验7:基于REST API的SDN北向应用实践的更多相关文章
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(二)
上文已经介绍了Identity Service的实现过程.今天我们继续,实现一个简单的Weather API和一个基于Ocelot的API网关. 回顾 <Angular SPA基于Ocelot ...
- 实验6、Flask API使用示例和拓展
实验介绍 1. 实验内容 Flask 提供了多种API拓展,本节我们主要学习基于RESTful的Flask应用程序设计 2. 实验要点 学习和掌握多种RESTful的设计模式 3.实验环境 Cento ...
- Atitit 游戏的通常流程 attilax 总结 基于cocos2d api
Atitit 游戏的通常流程 attilax 总结 基于cocos2d api 加载音效1 加载页面1 添加精灵1 设置随机位置2 移动2 垃圾gc2 点击evt2 爆炸效果3 定时生成精灵3 加载音 ...
- 你也可以玩转Skype -- 基于Skype API开发外壳程序入门
原文:你也可以玩转Skype -- 基于Skype API开发外壳程序入门 Skype是目前这个星球上最厉害的IM+VOIP软件,Skype现在已经改变了全球2.8亿人的生活方式.你,值得拥有! :) ...
- 基于 Aliexpress API 的小程序 : 批量 Copy 产品到不同的店铺
第一个基于 Aliexpress API 的小程序 : 批量 Copy 产品到不同的店铺 还没来得及用 API 重写软件, 先写个小程序来缓解一下手工压力: 批量Copy 产品到不同的店铺. 开网店 ...
- 基于V2EX API的nodejs组件.
今天又学习到了新的知(zi)识(shi),来给自己做个笔录,也算在这酷热的天气里给自己写了一篇降温的‘膏药’,话就讲这么多了 ,start off...... 首先 ,依赖选择: /**设置为严格模式 ...
- 实验:基于http的yum源
实验:基于http的yum源 selinux,firewalld已经关闭',系统为CentOS7 repodata所在的目录就是yum源 下面介绍了如何把本地光盘通过httpd服务器变成yum源:多个 ...
- windows下使用pycharm开发基于ansible api的python程序
Window下python安装ansible,基于ansible api开发python程序 在windows下使用pycharm开发基于ansible api的python程序时,发现ansible ...
- FluentAspects -- 基于 Fluent API 的 Aop
FluentAspects -- 基于 Fluent API 的 Aop Intro 上次我们做了一个简单的 AOP 实现示例,但是实现起来主要是基于 Attribute 来做的,对于代码的侵入性太强 ...
随机推荐
- [第五篇]——Docker 镜像加速之Spring Cloud直播商城 b2b2c电子商务技术总结
Docker 镜像加速 国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器.Docker 官方和国内很多云服务商都提供了国内加速器服务,例如: 科大镜像: 网易: 阿里云: 你 ...
- 【Git】给不同目录配置不同的用户名和邮箱
场景 使用 git 时,对于公司项目和个人项目想用不同的用户名和邮箱提交,简单的解决方式就是对 git 仓库单独配置 user.name 和 user.email: 直接修改当前仓库的 .git/co ...
- 【PHP数据结构】图的遍历:深度优先与广度优先
在上一篇文章中,我们学习完了图的相关的存储结构,也就是 邻接矩阵 和 邻接表 .它们分别就代表了最典型的 顺序存储 和 链式存储 两种类型.既然数据结构有了,那么我们接下来当然就是学习对这些数据结构的 ...
- PHP的Hash信息摘要扩展框架
今天我们主要学习的是 PHP 中一些 Hash 散列加密相关的扩展函数的使用,而不是 Hash 算法,这种加密其实也只是一种更复杂一些的密钥算法,与 Hash 算法类似的是,我们输入的一串字符串,就像 ...
- windows10 升级并安装配置 jmeter5.3
一.安装配置JDK Jmeter5.3依赖JDK1.8+版本,JDK安装百度搜索JAVA下载JDK,地址:https://www.oracle.com/technetwork/java/javase/ ...
- Linux服务器通用安全加固指南
一.基本系统安全 1.保护引导过程(以Grub引导为例) 在 /etc/inittab 中添加 sp:S:respawn:/sbin/sulogin,以确保当切换到单用户模式时 运行级的配置要求输入 ...
- 配置阿里云gradle
build.gradle buildscript { ext { springBootVersion = '1.5.15.BUILD-SNAPSHOT' } repositories { // mav ...
- git 要求密码的解决方法:【生成gitLab公钥】:以及如何配置GitLab中的SSH key
参考链接: https://www.cnblogs.com/yjlch1016/p/9692840.html https://blog.csdn.net/u011925641/article/deta ...
- P6620-[省选联考2020A卷]组合数问题【组合数学,斯特林数】
正题 题目链接:https://www.luogu.com.cn/problem/P6620 题目大意 给出\(n,x,p,m\)和一个\(m\)次多项式\(f\)求 \[\sum_{k=0}^nf( ...
- JavaEE & Tomcat 介绍
目录 企业开发介绍 JavaEE 规范 Web 概述 系统结构简介 C/S 结构 B/S 结构 两种结构的区别及优略 Tomcat Tomcat 介绍 关于服务器 Tomcat下载与安装 Tomcat ...