RYU实验笔记(二):多RYU控制器拓扑流表操作的接口

多RYU控制器连接拓扑以及相关流表操作:

https://blog.csdn.net/a1164520408/article/details/95509549

流表操作相关规范(这里指的是ryu自己封装好的restAPI,不是本人的):

https://ryu.readthedocs.io/en/latest/app/ofctl_rest.html#delete-all-flow-entries


需要:

  • 基于参数的拓扑脚本:拓扑的生成
  • 自定义控制器类脚本:功能的定义
  • 用户(控制器群)类:整个框架的实例化
  • 流表操作脚本:在实例上进行一系列操作
  • 两个终端:一个用于创建mininet,一个用于启动服务器
  • 环境:mininet,RYU,flask
  • POSTMAN

前三个脚本(基于参数的拓扑脚本,自定义控制器类脚本,用户(控制器群)类)依然使用前一篇博客所使用的脚本(注:在本次实验中的调用顺序和上次有所不同)

拓扑形式:

 
                 MASTER
                 ___|___   
          _____ /   |   \ _____
    ____ /     /    |    \     \ ______
   /    /     /     |     \     \      \
  c0    c1    c2    c3    c4     c5     c6 
   |    |     |     |     |      |      |
   s0   s1    s2    s3    s4     s5     s6
   /\   /\    /\    /\    /\     /\     /\
 h0 h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 h11 h12 h13

前期工作:

1.安装POSTMAN(略)

安装完的效果图(太大了,截了一部分)

RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第1张图片

2.安装flask模块

在ryu/ryu/app上

#创建新的virtualenv
virtualenv flask
#打开文件夹
cd flask
#激活
source bin/activate
#下载模块
pip install flask

3.创建好前三个脚本(略)

4.创建流表操作脚本

#!/usr/bin/python

#from mininet.net import Mininet
#from mininet.node import Controller, RemoteController, OVSSwitch
#from mininet.cli import CLI
#from mininet.log import setLogLevel, info
#from mininet.link import Link, Intf, TCLink
#from mininet.topo import Topo
from tf import MyController
from flask import Flask
from flask import request
from flask import url_for
from flask import jsonify
from ryu.app.wsgi import ControllerBase
from ryu.app.wsgi import Response
from ryu.app.wsgi import WSGIApplication
from rf import master
import logging
import time
import json
import os
app=Flask(__name__)
flow4='{"dpid":1 ,"cookie": 1,"cookie_mask": 1,"table_id": 0,"idle_timeout": 30,"hard_timeout": 3000,"priority": 11111,"flags": 1,"match":{},"actions":[ { "type": "OUTPUT","port":"controller"}]}'
me=None
@app.route('/master//',methods=['GET'])
def create_master(cnum):
	global me
	me=master(cnum)
	me.clear()
	me.createcontroller()
	return str(cnum)
@app.route('/master/controller/switch/getflowtable',methods=['POST'])
def get_p_flowtable():
	global me
	item=request.get_json()
	cnum=item["controller"]
	snum=item["switch"]
	return me.clist[cnum].get_flow_states(str(snum))
@app.route('/master/gets2c',methods=['GET'])
def get_s2c():
	global me
	a={}
	i=0
	for controller in me.clist:
		sws=str(controller.get_switches())
		a[str(i)]=sws
		i+=1		
	return 
@app.route('/master/controller/addflow',methods=['POST'])
def add_cs_flow():
	global me
	item=request.get_json()
	flow=json.dumps(item["flow"])
	cnum=item["controller"]
	return me.clist[cnum].add_flow(flow)
@app.route('/master/controller/deleteflow',methods=['POST'])
def del_cs_flow():
	global me
	item=request.get_json()
	flow=json.dumps(item["flow"])	
	cnum=item["controller"]
	return me.clist[cnum].del_flow_m(flow)
@app.route('/master/controller/switch/clearflow',methods=['POST'])
def clr_flow():
	global me
	item=request.get_json()
	cnum=item["controller"]
	snum=item["switch"]
	return me.clist[cnum].del_all_flow(str(snum))
@app.route('/master/kill',methods=['GET'])
def kill_master():
	global me
	me.clear()
	return 'kill!'
if __name__ == '__main__':
	app.run(host='0.0.0.0',port=5000,debug=True)

实验工作:

1.开启流表操作脚本,如果出现端口占用问题运行下面脚本:

#!/usr/bin/python
from rf import master
from tf import MyController
import logging
import time
import os 
a=7
me=master(a)
me.clear()

(注:运行流表操作脚本要在python3,所以要python3 XXX.py)

RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第2张图片

2用POSTMAN开启这7个控制器:

 

在postman上输入对应的URL:http://localhost:5000/master/7/,使用GET方法

返回了一个7表示创建了7个

RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第3张图片

返回值为200,出现(PID)...  http://0.0.0.0:wsport表示这个端口对应的控制器开启

RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第4张图片

3.开启拓扑脚本

可见,拓扑连接上了控制器,并开始有数据包的出现

RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第5张图片


4.获取某个控制器下的某个交换机的流表

在postman上输入对应的URL:http://localhost:5000/master/controller/switch/getflowtable,使用POST模式,在body一栏选择raw,文件格式json,上传如下json文件(想要查询1号控制器的1号交换机的流表):

{
    "controller":1,
	"switch":1
}

点击send,如果没有错了话(返回值200)就会返回如下json文件:

{
    "1": [
        {
            "actions": [
                "OUTPUT:CONTROLLER"
            ],
            "byte_count": 20430,
            "cookie": 0,
            "duration_nsec": 606000000,
            "duration_sec": 71,
            "flags": 0,
            "hard_timeout": 0,
            "idle_timeout": 0,
            "length": 80,
            "match": {},
            "packet_count": 184,
            "priority": 0,
            "table_id": 0
        }
    ]
}

 

RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第6张图片5.让某个控制器中添加流表

在postman上输入对应的URL:http://localhost:5000/master/controller/addflow,使用POST模式,在body一栏选择raw,文件格式json,上传如下json文件(想要向1号控制器添加流表):

{
		"controller":1,
		"flow":
			{
				"dpid":1 ,
				"cookie": 1,
				"cookie_mask": 1,
				"table_id": 0,
				"idle_timeout": 30,
				"hard_timeout": 3000,
				"priority": 11111,
				"flags": 1,
				"match":{},
				"actions":[ { "type": "OUTPUT","port":"controller"}]}
}

点击send,会返回一个adding flow,此时再获取一次流表,会返回:

{
    "1": [
        {
            "actions": [
                "OUTPUT:CONTROLLER"
            ],
            "byte_count": 22356,
            "cookie": 0,
            "duration_nsec": 899000000,
            "duration_sec": 829,
            "flags": 0,
            "hard_timeout": 0,
            "idle_timeout": 0,
            "length": 80,
            "match": {},
            "packet_count": 202,
            "priority": 0,
            "table_id": 0
        },
        {
            "actions": [
                "OUTPUT:CONTROLLER"
            ],
            "byte_count": 0,
            "cookie": 1,
            "duration_nsec": 659000000,
            "duration_sec": 5,
            "flags": 1,
            "hard_timeout": 3000,
            "idle_timeout": 30,
            "length": 80,
            "match": {},
            "packet_count": 0,
            "priority": 11111,
            "table_id": 0
        }
    ]
}

6.让某个特定控制器删除流表

在postman上输入对应的URL:http://localhost:5000/master/controller/deleteflow,使用POST模式,在body一栏选择raw,文件格式json,上传和添加流表时一样json文件(想要删掉刚才添加的那个流表(优先级11111的那个))

点击send,返回一个deleting flow,然后再查询一次流表,会发现刚才添加的被删了:

{
    "1": [
        {
            "actions": [
                "OUTPUT:CONTROLLER"
            ],
            "byte_count": 22356,
            "cookie": 0,
            "duration_nsec": 436000000,
            "duration_sec": 1019,
            "flags": 0,
            "hard_timeout": 0,
            "idle_timeout": 0,
            "length": 80,
            "match": {},
            "packet_count": 202,
            "priority": 0,
            "table_id": 0
        }
    ]
}

7. 在mininet做ping操作时影响流表

RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第7张图片

获取流表的时候会发现,有了很多很多的流表项足足有几千行(因为太多了,就只截图),对照流表规范可知这个流表格式是open flow1.0的:

RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第8张图片RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第9张图片RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第10张图片

8. 清空特定控制器下的特定交换机的所有流表

在postman上输入对应的URL:http://localhost:5000/master/controller/switch/clearflow,使用POST模式,在body一栏选择raw,文件格式json,上传和如下json文件(想要清空1号控制器下1号交换机的流表)

{
	"controller":1,
	"switch":1	
}

点击send,返回一个clear!,然后再查询一次流表,发现什么都没有:

RYU实验笔记(二):多RYU控制器拓扑流表操作的接口_第11张图片

  • h2 ping h3是ping不通的,因为h1和h2连接的OVS交换机(s1)没有连向控制器的流表,在h2 想要 ping h3的时候,h2无法向控制器c1发出请求,从而得不到回复,
  • h2 ping h7 也是不通的,因为要经过s1
  • h0 ping h1 是可行的
  • 所以h0 ping h7 也是不通,也要经过s1
  • h7 ping h8可以ping通,因为h7h8-s3-c3,s3的流表是没有被操作过的

如果想要再能ping通,就需要添加一个连向控制器的流表才能ping

9.关闭控制器

在postman上输入对应的URL:http://localhost:5000/master/kill,使用GET方法

返回一个kill!,然后就不能正常使用流表操作的url了,返回值不是200


总结:

  • 后端工作基本完成,准备和前端结合
  • 灵活性,功能性,有较大进步
  • 后期将添加各种网络性能测试的功能

你可能感兴趣的:(Level.4,SDN实验)