SDN-Postman及python編程對流表的操作

目錄

實驗環境

實驗步驟

Postman查看流表

python代碼查看流表

流表分析

Postman查看流表項

Python代碼查看流表項

Postman添加流表項

 Python添加流表項

Postman、Python修改流表項


一些postman介紹、基本使用,以及mininet創建拓撲之類的我就不再重複寫了。

本文使用拓撲:SDN-Mininet安裝使用

實驗環境

  • VM14.0
  • Ubuntu 18.04
  • JDK1.8
  • OpenDaylight-Nitro版本
  • Mininet
  • postman

實驗步驟

打開opendaylight

使用mininet創建拓撲並連接opendaylight

Postman查看流表

訪問網址,http://你的ip:8181/index.html

打開Nodes標籤,查看Node Id

opendaylight dlux界面

打開YANG UI標籤,opendaylight-inventory rev.2013-08-19->operational->nodes->node{id}->table{id}

打開YANGUI

點擊小眼睛獲得完整url

完整url顯示

複製url,粘貼到postman。選擇GET方式,驗證方式爲Basic Auth,Headers中的Content-Type和Accept填入application/xml(不填的話默認是application/json格式),賬號密碼均爲admin,填入參數,table的id爲0,node的id爲之前Node標籤看到的。

獲得流表

python代碼查看流表

import urllib.request
from base64 import encodebytes

ip = "192.168.31.174"
node_id = "openflow:1"
table_id = "0"
username = "admin"
password = "admin"
url = "http://" + ip + ":8181/restconf/operational/opendaylight-inventory:nodes/node/" + node_id + "/flow-node-inventory:table/" + table_id
print(url)
# 添加請求的url
req = urllib.request.Request(url)
# 添加請求方法
req.get_method = lambda: "GET"
# 添加header
b64str = encodebytes(bytes('%s:%s' % (username, password), 'utf-8'))[:-1]
req.add_header("Authorization", "Basic %s" % b64str.decode('utf-8'))
returnData = urllib.request.urlopen(req)
res_json = returnData.read().decode('utf-8')
print(res_json)

 xml形式的流表

<table xmlns="urn:opendaylight:flow:inventory">
    <id>0</id>
    <flow>
        <id>L2switch-2</id>
        <flow-statistics xmlns="urn:opendaylight:flow:statistics">
            <packet-count>1</packet-count>
            <duration>
                <nanosecond>645000000</nanosecond>
                <second>258</second>
            </duration>
            <byte-count>70</byte-count>
        </flow-statistics>
        <priority>2</priority>
        <table_id>0</table_id>
        <hard-timeout>0</hard-timeout>
        <match>
            <in-port>openflow:1:3</in-port>
        </match>
        <cookie>3098476543630901250</cookie>
        <instructions>
            <instruction>
                <order>0</order>
                <apply-actions>
                    <action>
                        <order>0</order>
                        <output-action>
                            <max-length>65535</max-length>
                            <output-node-connector>2</output-node-connector>
                        </output-action>
                    </action>
                    <action>
                        <order>2</order>
                        <output-action>
                            <max-length>65535</max-length>
                            <output-node-connector>CONTROLLER</output-node-connector>
                        </output-action>
                    </action>
                    <action>
                        <order>1</order>
                        <output-action>
                            <max-length>65535</max-length>
                            <output-node-connector>1</output-node-connector>
                        </output-action>
                    </action>
                </apply-actions>
            </instruction>
        </instructions>
        <idle-timeout>0</idle-timeout>
    </flow>
    <flow>
        <id>L2switch-1</id>
        <flow-statistics xmlns="urn:opendaylight:flow:statistics">
            <packet-count>53</packet-count>
            <duration>
                <nanosecond>145000000</nanosecond>
                <second>264</second>
            </duration>
            <byte-count>4505</byte-count>
        </flow-statistics>
        <priority>100</priority>
        <table_id>0</table_id>
        <hard-timeout>0</hard-timeout>
        <match>
            <ethernet-match>
                <ethernet-type>
                    <type>35020</type>
                </ethernet-type>
            </ethernet-match>
        </match>
        <cookie>3098476543630901249</cookie>
        <instructions>
            <instruction>
                <order>0</order>
                <apply-actions>
                    <action>
                        <order>0</order>
                        <output-action>
                            <max-length>65535</max-length>
                            <output-node-connector>CONTROLLER</output-node-connector>
                        </output-action>
                    </action>
                </apply-actions>
            </instruction>
        </instructions>
        <idle-timeout>0</idle-timeout>
    </flow>
    <flow>
        <id>#UF$TABLE*0-2</id>
        <flow-statistics xmlns="urn:opendaylight:flow:statistics">
            <packet-count>0</packet-count>
            <duration>
                <nanosecond>145000000</nanosecond>
                <second>264</second>
            </duration>
            <byte-count>0</byte-count>
        </flow-statistics>
        <priority>0</priority>
        <table_id>0</table_id>
        <hard-timeout>0</hard-timeout>
        <match></match>
        <cookie>3098476543630901249</cookie>
        <idle-timeout>0</idle-timeout>
    </flow>
    <flow>
        <id>L2switch-0</id>
        <flow-statistics xmlns="urn:opendaylight:flow:statistics">
            <packet-count>1</packet-count>
            <duration>
                <nanosecond>652000000</nanosecond>
                <second>258</second>
            </duration>
            <byte-count>70</byte-count>
        </flow-statistics>
        <priority>2</priority>
        <table_id>0</table_id>
        <hard-timeout>0</hard-timeout>
        <match>
            <in-port>openflow:1:2</in-port>
        </match>
        <cookie>3098476543630901248</cookie>
        <instructions>
            <instruction>
                <order>0</order>
                <apply-actions>
                    <action>
                        <order>0</order>
                        <output-action>
                            <max-length>65535</max-length>
                            <output-node-connector>1</output-node-connector>
                        </output-action>
                    </action>
                    <action>
                        <order>2</order>
                        <output-action>
                            <max-length>65535</max-length>
                            <output-node-connector>CONTROLLER</output-node-connector>
                        </output-action>
                    </action>
                    <action>
                        <order>1</order>
                        <output-action>
                            <max-length>65535</max-length>
                            <output-node-connector>3</output-node-connector>
                        </output-action>
                    </action>
                </apply-actions>
            </instruction>
        </instructions>
        <idle-timeout>0</idle-timeout>
    </flow>
    <flow>
        <id>#UF$TABLE*0-3</id>
        <flow-statistics xmlns="urn:opendaylight:flow:statistics">
            <packet-count>3</packet-count>
            <duration>
                <nanosecond>647000000</nanosecond>
                <second>258</second>
            </duration>
            <byte-count>247</byte-count>
        </flow-statistics>
        <priority>2</priority>
        <table_id>0</table_id>
        <hard-timeout>0</hard-timeout>
        <match>
            <in-port>openflow:1:1</in-port>
        </match>
        <cookie>3098476543630901249</cookie>
        <instructions>
            <instruction>
                <order>0</order>
                <apply-actions>
                    <action>
                        <order>0</order>
                        <output-action>
                            <max-length>65535</max-length>
                            <output-node-connector>2</output-node-connector>
                        </output-action>
                    </action>
                    <action>
                        <order>1</order>
                        <output-action>
                            <max-length>65535</max-length>
                            <output-node-connector>3</output-node-connector>
                        </output-action>
                    </action>
                </apply-actions>
            </instruction>
        </instructions>
        <idle-timeout>0</idle-timeout>
    </flow>
    <flow-table-statistics xmlns="urn:opendaylight:flow:table:statistics">
        <packets-matched>57</packets-matched>
        <active-flows>5</active-flows>
        <packets-looked-up>105</packets-looked-up>
    </flow-table-statistics>
</table>

流表分析

從這個xml中,我們可以看到流表的一些信息,包括流表的id,使用的交換機,一個流表項的入端口等,另外<flow></flow>標籤中是流表的一個流表項,共5條。

流表中字段含義
字段 含義
table_id int,流表的id
id string,流表項的id
priority int,流表項的優先級
cookie int,控制器發出的標識符
cookie_mask int,掩碼,用於限制必須匹配的cookie位
idle-timeout int,丟棄前的空閒時間(秒)
hard-timeout int,丟棄前的最長時間(秒)
match dict,匹配域
ethernet-match dict,以太網匹配
ethernet-type dict,以太網類型
type str,0x0800:使用ip匹配,0x8847:使用mac匹配
ipv4-destination ipv4的目的ip地址
instructions dict,動作集
instruction list,動作,指令
order int,順序

Postman查看流表項

 

標題

 json格式的流表項

{
    "flow-node-inventory:flow": [
        {
            "id": "L2switch-2",
            "opendaylight-flow-statistics:flow-statistics": {
                "packet-count": 2,
                "duration": {
                    "nanosecond": 81000000,
                    "second": 768
                },
                "byte-count": 140
            },
            "priority": 2,
            "table_id": 0,
            "hard-timeout": 0,
            "match": {
                "in-port": "openflow:1:3"
            },
            "cookie": 3098476543630901250,
            "instructions": {
                "instruction": [
                    {
                        "order": 0,
                        "apply-actions": {
                            "action": [
                                {
                                    "order": 0,
                                    "output-action": {
                                        "max-length": 65535,
                                        "output-node-connector": "2"
                                    }
                                },
                                {
                                    "order": 2,
                                    "output-action": {
                                        "max-length": 65535,
                                        "output-node-connector": "CONTROLLER"
                                    }
                                },
                                {
                                    "order": 1,
                                    "output-action": {
                                        "max-length": 65535,
                                        "output-node-connector": "1"
                                    }
                                }
                            ]
                        }
                    }
                ]
            },
            "idle-timeout": 0
        }
    ]
}

Python代碼查看流表項

import urllib.request
from base64 import encodebytes

ip = "192.168.31.174"
node_id = "openflow:1"
table_id = "0"
flow_id = "L2switch-2"
username = "admin"
password = "admin"
url = "http://" + ip + ":8181/restconf/operational/opendaylight-inventory:nodes/node/" + node_id + "/flow-node-inventory:table/" + table_id +"/flow/"+flow_id
print(url)
# 添加請求的url和method
req = urllib.request.Request(url, method="GET")
# 添加header
b64str = encodebytes(bytes('%s:%s' % (username, password), 'utf-8'))[:-1]
req.add_header("Authorization", "Basic %s" % b64str.decode('utf-8'))
returnData = urllib.request.urlopen(req)
res_json = returnData.read().decode('utf-8')
print(res_json)

Postman添加流表項

命令查看流表項
命令刪除流表項

使用PUT方式,賬號密碼依然還是admin,注意url是使用的config,不是operational,選擇json格式,點擊send。

使用Postman添加流表項
再次查看流表

再次查看流表後發現添加了一條流表項,h1、h2使用的是交換機s1的端口s1-eth1與s1-eth2,所以,h1與h2可以ping通。

 Python添加流表項

import urllib.request
from base64 import encodebytes

from django.contrib.sites import requests

ip = "192.168.31.174"
# node_id = "openflow:1"
print("please input name of switch:")
node_id = input()
table_id = "0"
# flow_id = "L2switch-2"
print("please input id of flow:")
flow_id = input()
username = "admin"
password = "admin"
url = "http://" + ip + ":8181/restconf/config/opendaylight-inventory:nodes/node/" + node_id + "/flow-node-inventory:table/" + table_id + "/flow/" + flow_id
print(url)
flow = {
    "flow-node-inventory:flow": [
        {
            "id": "L2switch-2",
            "priority": 2,
            "table_id": 0,
            "hard-timeout": 0,
            "match": {
                "in-port": "openflow:1:3"
            },
            "cookie": 3098476543630901250,
            "instructions": {
                "instruction": [
                    {
                        "order": 0,
                        "apply-actions": {
                            "action": [
                                {
                                    "order": 0,
                                    "output-action": {
                                        "max-length": 65535,
                                        "output-node-connector": "2"
                                    }
                                }
                            ]
                        }
                    }
                ]
            },
            "idle-timeout": 0
        }
    ]
}
flow["flow-node-inventory:flow"][0]["id"] = flow_id
print("please input priority of this flow:")
flow["flow-node-inventory:flow"][0]["priority"] = int(input())
print("please input hard-timeout of this flow:")
flow["flow-node-inventory:flow"][0]["hard-timeout"] = int(input())
print("please input idle-timeout of this flow:")
flow["flow-node-inventory:flow"][0]["idle-timeout"] = int(input())
print("please input in-port of this flow:")
flow["flow-node-inventory:flow"][0]["match"]["in-port"] = node_id + ":" + input()
print("please input output-port of this flow:")
flow["flow-node-inventory:flow"][0]["instructions"]["instruction"][0]["apply-actions"]["action"][0]["output-action"][
    "output-node-connector"] = input()

print("flow_id:" + str(flow["flow-node-inventory:flow"][0]["id"]))
print("priority:" + str(flow["flow-node-inventory:flow"][0]["priority"]))
print("hard-timeout:" + str(flow["flow-node-inventory:flow"][0]["hard-timeout"]))
print("idle-timeout:" + str(flow["flow-node-inventory:flow"][0]["idle-timeout"]))
print("in-port:" + flow["flow-node-inventory:flow"][0]["match"]["in-port"])
print("output-port:" +
      flow["flow-node-inventory:flow"][0]["instructions"]["instruction"][0]["apply-actions"]["action"][0][
          "output-action"]["output-node-connector"])
print(flow)
# 添加請求的url、data、method
req = urllib.request.Request(url=url, data=bytes(str(flow), 'utf-8'), method="PUT")
# 添加header
b64str = encodebytes(bytes('%s:%s' % (username, password), 'utf-8'))[:-1]
req.add_header("Authorization", "Basic %s" % b64str.decode('utf-8'))
req.add_header("Accept", "application/json")
req.add_header("Content-Type", "application/json")
returnData = urllib.request.urlopen(req)
res_json = returnData.read().decode('utf-8')
print(res_json)

 

實驗結果
流表項添加成功

 我是通過端口添加的流表項,除此之外,你還可以使用ip或mac添加,使用ethernet-type、ipv4-destination等字段。

Postman、Python修改流表項

這個只需要使你請求的數據中流表項的id在流表中存在,就會覆蓋掉原來的。

更多SDN相關內容,請查看:SDN-自學筆記

有問題請下方評論,轉載請註明出處,並附有原文鏈接,謝謝!如有侵權,請及時聯繫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章