实验7:基于REST API的SDN北向应用实践

(一)基础

1.OpenDaylight

(1)删除交换机上的流表

#!/usr/bin/python
import requests
from requests.auth import HTTPBasicAuth

def http_del(url, jstr):
    url = url
    headers = {'Content-Type': 'application/json'}
    resp = requests.delete(url, headers=headers, auth=HTTPBasicAuth('admin', 'admin'))
    return resp

if __name__ == "__main__":
    url = 'http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/'
    with open('my.json') as f:
        jstr = f.read()
    resp = http_del(url, jstr)
    print(resp.content)

(2)硬超时流表

image

#!/usr/bin/python
import requests
from requests.auth import HTTPBasicAuth

def http_put(url, jstr):
    url = url
    headers = {'Content-Type': 'application/json'}
    resp = requests.put(url, jstr, headers=headers, auth=HTTPBasicAuth('admin', 'admin'))
    return resp

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('my.json') as f:
        jstr = f.read()
    resp = http_put(url, jstr)
    print(resp.content)

(3)获取s1上活动的流表数

image

#!/usr/bin/python
import requests
from requests.auth import HTTPBasicAuth

def http_get(url, jstr):
    url = url
    headers = {'Content-Type': 'application/json'}
    resp = requests.get(url, jstr, headers=headers, auth=HTTPBasicAuth('admin', 'admin'))
    return resp

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'
    with open('my.json') as f:
        jstr = f.read()
    resp = http_get(url, jstr)
    print(resp.content)

附上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"
    }
  ]
}

2.Ryu

(1)硬超时

image

python代码:

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, auth=HTTPBasicAuth('admin', 'admin'))
    return resp

if __name__ == "__main__":
    url = 'http://127.0.0.1:8080/stats/flowentry/add'

    with open('ryu.json') as f:
        jstr = f.read()
    resp = http_post(url, jstr)
    print(resp.content)

json代码:

{
    "dpid": 1,
    "cookie": 1,
    "cookie_mask": 1,
    "table_id": 0,
    "idle_timeout": 0,
    "hard_timeout": 20,
    "priority": 65535,
    "flags": 1,
    "match":{
        "in_port":1,
        "ip_dst": "10.0.0.3/32"
    },
    "actions":[]
 }

(2)Shell脚本划分vlan

image

 curl -X POST -d '{
    "dpid": 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
        }
    ],
    "priority":65535
 }' http://localhost:8080/stats/flowentry/add


 curl -X POST -d '{
    "dpid": 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
        }
    ],
    "priority":65535
 }' http://localhost:8080/stats/flowentry/add

 curl -X POST -d '{
    "dpid": 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
        }
    ],
    "priority":65535
 }' http://localhost:8080/stats/flowentry/add

 curl -X POST -d '{
    "dpid": 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
        }
    ],
    "priority":65535
 }' http://localhost:8080/stats/flowentry/add

 curl -X POST -d '{
    "dpid": 2,
    "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
        }
    ],
    "priority":65535
 }' http://localhost:8080/stats/flowentry/add

 curl -X POST -d '{
    "dpid": 2,
    "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
        }
    ],
    "priority":65535
 }' http://localhost:8080/stats/flowentry/add

 curl -X POST -d '{
    "dpid": 2,
    "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
        }
    ],
    "priority":65535
 }' http://localhost:8080/stats/flowentry/add

 curl -X POST -d '{
    "dpid": 2,
    "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
        }
    ],
    "priority":65535
 }' http://localhost:8080/stats/flowentry/add

(二)进阶

image

python代码如下:

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, auth=HTTPBasicAuth('admin', 'admin'))
    return resp


if __name__ == "__main__":
    url = 'http://127.0.0.1:8080/stats/flowentry/add'

    for i in range(8):
        filename = 'vlan' + str(i + 1) + '.json'
        with open(filename) as f:
            jstr = f.read()
        resp = http_post(url, jstr)
        print(resp.content)

json代码同Ryu(3)中的shell中,此处举例:

{
  "dpid": 1,
    "match":{
        "in_port": 1
    },
    "actions":[
        {
            "type": "PUSH_VLAN",
            "ethertype": 33024
        },
        {
            "type": "SET_FIELD",
            "field": "vlan_vid",
            "value": 4096
        },
        {
            "type": "OUTPUT",
            "port": 3
        }
    ],
    "priority":65535
}

image

(三)总结

本次实验综合了实验四与实验二,回顾了一些操作,也让我进一步了解代码的含义。

基本要求主要是将代码对应相应控制器的url、增删操作的函数,以及相应的流规则。需要注意:

1.odl的删除操作没有'jstr'参数,且一开始运行测试的时候是没有流表的会报错,添加流表再删除可进行验证。

2.odl的流规则对应在实验四中,ryu的流规则在实验指导的连接中,需要补充上"ip_dst"指定目的地址,action为空表示丢弃数据包。

3.划分vlan要将优先级调高

进阶主要解决的问题是多个json的读取,流规则内容从shell脚本中抠出来就好。

除开vlan划分能找到比较详细的资料外,不理解代码的话在网上查资料还是比较难完成本次的作业。感谢张炜龙同学的指点给了我思路。

posted @ 2021-10-26 15:16  hqqqql  阅读(33)  评论(0编辑  收藏  举报