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(略)

安裝完的效果圖(太大了,截了一部分)

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/<int:cnum>/',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)

2用POSTMAN開啓這7個控制器:

 

在postman上輸入對應的URL:http://localhost:5000/master/7/,使用GET方法

返回了一個7表示創建了7個

返回值爲200,出現(PID)...  http://0.0.0.0:wsport表示這個端口對應的控制器開啓

3.開啓拓撲腳本

可見,拓撲連接上了控制器,並開始有數據包的出現


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
        }
    ]
}

 

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操作時影響流表

獲取流表的時候會發現,有了很多很多的流表項足足有幾千行(因爲太多了,就只截圖),對照流表規範可知這個流表格式是open flow1.0的:

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

在postman上輸入對應的URL:http://localhost:5000/master/controller/switch/clearflow,使用POST模式,在body一欄選擇raw,文件格式json,上傳和如下json文件(想要清空1號控制器下1號交換機的流表)

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

點擊send,返回一個clear!,然後再查詢一次流表,發現什麼都沒有:

  • 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


總結:

  • 後端工作基本完成,準備和前端結合
  • 靈活性,功能性,有較大進步
  • 後期將添加各種網絡性能測試的功能
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章