OpenDaylight Lithium版本简单应用及流表操作指南

OpenDaylight(以下简写为ODL)的Lithium(锂)版本的最新版Lithium-SR2已经与2015年10月8日发布,具体详情可参考ODL官网。Lithium(锂)版本发布至今已经发布了二个版本,即Lithium-SR1与Lithium-SR2。下载链接地址为https://www.opendaylight.org/software/downloads/lithium-sr2。官网中分别共享了版本、安装向导、用户向导、开发者向导手册,可进行下载学习。

1 OpenDayLight的简单应用

1.1ODL控制器与Mininet的连接

ODL的Lithium(锂)版本已安装成功且已安装基本的OpenFlow功能组件。接下来将通过Mininet模拟网络设备简单地验证ODL的功能,包括拓扑、链路发现、交换机管理等等。 打开装有Mininet的设备,执行命令创建模拟拓扑并连接ODL,本文实现安装ODL的主机IP地址为127.0.0.1:(此命令为建立支持OpenFlow1.3协议的拓扑) # sudo mn --switch ovs,protocol=OpenFlow13 --controller=remote,ip=127.0.0.1,port=6633 登录后显示ODL锂版本最新界面,如下两图分别是Topology界面和Nodes界面:

1.2Postman安装及使用方法

如下图所述,OpenFlowplugin不能像controller那样通过浏览器直接查看和使用其提供的功能。OpenFlowplugin获取当前交换机的连接状态以及下发流表都需要手动发送http的put/get请求。使用的工具是google的Chromium浏览器(Windows上的chrome浏览器)所提供的“Postman rest client”插件。在Ubuntu中通过包管理中心可以下载Chromium Web Browser,如下图所示:

下载安装完Chromium后,使用Tools->Extensions进入Chromium的扩展下载页面,搜索Postman,选择Postman rest api,点击“下载”,下载前需要注册Google账号。下载完成后,可在如下界面看到Postman已经安装好。

注:由于Google服务在大陆地区被禁,可能导致谷歌的插件市场无法访问,那么就只能下载第三方插件,然后在安装到Chromium浏览器中,具体方法如下: 1.百度搜索Postman-REST-Client_v0.8.1,下载Postman插件。下载地址:

http://download.csdn.net/detail/u010037410/8400395

2.打开Chromium浏览器,点击右上角菜单按钮,如图所示进入应用中心。

按照下图所写出的顺序即步骤1 2 3将下载好的Postman插件导入到Chromium浏览器中。

安装好Postman之后打开Chromium浏览器按如下步骤打开。

2 OpenDayLight流表操作

2.1获取交换机信息

Response message body:

Attribute

Description

Example

id

Openflow Switch id

“Openflow:1”

mfr_desc

Manufacturer description

“Nicira, Inc. ”

hw_desc

Hardware description

“Open vSwitch”

sw_desc

Software description

“2.3. 0”

serial_num

Serial number

“None”

dp_desc

Human readable description of datapath

“None”

ODL获取交换机信息的界面在Yang UI中,具体节点为:Yang UI API opendaylight-inventory operational nodes node{id} 点击node{id},在下方出现的path中输入Node id(在主页面的Nodes中找,本机id为openflow:1),提交方式为GET,点击Send发出消息,则交换机信息则会出现在path下方。 在Postman中获取交换机信息的方法: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如下] 如下图,在URL地址中输入:

http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1

此处需要填写Headers,前两项内容如图所示,第三项Authorization需要填写ODL的用户名密码,一般情况下都为admin,点击1处输入admin之后点击2处,则3处会自动生成一串以Basic为开头的密码字符。 设置完成之后点击Send,获取的结果如下图所示:

如上图所示,openflow:1表示有一个openflow节点连接到controller, <switch-features>里面代表连接上来的交换机的feature信息。 注:官方wiki上面对获取交换机信息功能有更详细的介绍(但官方给出的wiki上提供的方法有时也不一定都能完全实现,这里仅提供参考,以实际试验的为准),地址如下:

https://wiki.opendaylight.org/view/OpenDaylightOpenFlowPlugin::End_toEndInventory

2.2获取flow table信息

2.2.1获取table统计信息 Response message body(OpenFlow1.3):

Attribute

Description

Example

id

Openflow Switch id

Openflow:1

Table_id

Table ID to put the flow in.(int)

0

active_count

Number of active entries

1

lookup_count

Number of packets looked up in table

12

matched_count

Number of packets that hit table

5

在Postman中获取table统计信息的方法: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如下] 在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

统计信息如下图:

2.2.2获取所有flow entry统计信息 Response message body:

Attribute

Description

Example

id

Openflow Switch id

Openflow:1

packet_count

Number of packets in flows

5

flow_count

Number of flows

1

byte_count

Number of bytes in flows

390

在Postman中获取flow统计信息的方法: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如下] 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/opendaylight-flow-statistics:aggregate-flow-statistics

统计信息如下图:

2.2.3获取单条flow entry信息 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令: http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1(注意:如要获取不同flow table的信息只需在URL中更改相应的tableid和flow id的值即可。如果想要获取整个tableid为0的信息,则只需输入table_id即可。) 提交方式:GET 统计信息如下图:

2.3获取group table信息

2.3.1获取group统计信息 Response message body:

Attribute

Description

Example

id

Openflow Switch id

Openflow:1

group_id

Group identifier(int)

1

length

Length of this entry

56

ref_count

Number of flows or groups that directly forward to this group

1

packet_count

Number of packets processed by group

0

byte_count

Number of bytes processed by group

0

duration_sec

Time group has been alive in seconds

6142

duration_nsec

Time group has been alive in nanoseconds beyond duration_sec

132000000

bucket_stats

struct ofp_bucket_counter

-packet_count

Number of packets processed by bucket

0

-byte_count

Number of bytes processed by bucket

0

在Postman中获取group统计信息的方法: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如下] 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:group/100/opendaylight-group-statistics:group-statistics

统计信息如下图:

2.3.2获取单条group entry信息 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令: http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/group/0(注意:如要获取不同group table的信息只需在URL中更改相应的group_id即可) 提交方式:GET

2.4获取meter table信息

2.4.1获取meter统计信息 Response message body:

Attribute

Description

Example

id

Openflow Switch id

Openflow:1

group_id

Group identifier(int)

1

length

Length of this entry

56

ref_count

Number of flows or groups that directly forward to this group

1

packet_count

Number of packets processed by group

0

byte_count

Number of bytes processed by group

0

duration_sec

Time group has been alive in seconds

6142

duration_nsec

Time group has been alive in nanoseconds beyond duration_sec

132000000

bucket_stats

struct ofp_bucket_counter

-packet_count

Number of packets processed by bucket

0

-byte_count

Number of bytes processed by bucket

0

在Postman中获取meter统计信息的方法: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如下] 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:meter/1/opendaylight-meter-statistics:meter-statistics

统计信息如下图:

2.4.2获取单条meter entry信息 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令: http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/meter/0(注意:如要获取不同meter table的信息只需在URL中更改相应的meter_id即可) 提交方式:GET

2.5Flow table

Response message body:

Attribute

Description

Example

Default

id

Openflow Switch id

Openflow:1

Mandatory

flow_id

Flow identifier(int)

1

0

table_id

Table ID to put the flow in.(int)

0

0

priority

Matching precedence of the flow entry.(int)

2

0

cookie

Opaque controller-issued identifier.(int)

1

0

cookie_mask

Mask used to restrict the cookie bits thatmust match.(int)

1

0

buffer_id

Buffered packet to apply to,or OFP_NO_BUFFER.(int)

1

OFP_NO_BUFFER

idle-timeout

Idle time before discarding(seconds).(int)

20

0

hard-timeout

Max time before discarding(seconds)(int)

20

0

flow-name

Flow’s name.

flow1

None

match

Fields to match (dict)

<in-port>0</in-port>

Wildcarded

instructions

To modify the action set or pipeline processing.

<dec-nw-ttl/>

Drop

2.5.1添加一条流表 OpenDayLight Flows功能:该模块的功能主要实现静态流表添加,下发,删除及修改等功能。(注:只是静态流表,不包括动态生成的流表) ODL下发flow table的界面也在Yang UI中,具体节点为:Yang UI API opendaylight-inventory config nodes node{id} table{id} flow{id} 如下两图所示,为ODL控制器下发flow entry的界面。按照给出的字段可以下发所需的flow entry。 注:需要说明的是,目前OpenDayLight Lithium SR2版本中下发flow entry时的instruction字段中的apply-action-case所列举的action并没有得到很好的支持,即并不是每个action都可以被下发的交换机中,例如controller-action-case、flood-action-case等。比如下发copy-ttl-in-case提示成功下发并且抓包显示已抓到flowadd消息,flowadd中的ofinstruction list里也有ofactioncopyttlin动作,但查看交换机流表的时显示并没有此条流表。又比如下发set-dl-type-action-case,提示成功下发并且可以抓到flowadd消息,但是查看其of_instruction list时确并没有此action。查看交换机流表显示有此条流表,但是actions=drop。其中只有大约15中action可以被正确下发到交换机中。具体有哪些可以被成功下发,会在本文最后详细列出,仅供参考。

在Postman中通过config方式下发flow entry的方法: With XML: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令: http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1 (注意:如果是下发多条flow entry每次下发需要更改flow id的值,相应的URL地址中的table/0/flow/1中的1就是所对应的flow id,也需要修改。) 提交方式:PUT

Use Body:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<flow xmlns="urn:opendaylight:flow:inventory">
    <match>
        <ethernet-match>
            <ethernet-type>
                <type>2048</type>
            </ethernet-type>
        </ethernet-match>
        <ipv4-destination>10.0.0.1/24</ipv4-destination>
    </match>
    <instructions>
        <instruction>
            <order>0</order>
            <apply-actions>
                <action>
                    <order>0</order>
                    <dec-nw-ttl/>
                </action>
            </apply-actions>
        </instruction>
    </instructions>
    <table_id>0</table_id>
    <id>1</id>
    <hard-timeout>12</hard-timeout>
    <cookie>1</cookie>
    <idle-timeout>34</idle-timeout>
    <flow-name>lihao</flow-name>
    <priority>1</priority>
</flow>

With JSON: 首先输入Headers: Content-Type: application/json Accept: application/json Authorization: [方法如上] 在URL地址栏中输入以下命令: http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1 (注意:如果是下发多条flow entry每次下发需要更改flow id的值,相应的URL地址中的table/0/flow/1中的1就是所对应的flow id,也需要修改。) 提交方式:PUT

Use Body:
{
"flow": [
{
"id": "1",
"match": {
"ethernet-match": {
"ethernet-type": {
"type": "0x0800"
}
},
"ipv4-destination": "10.0.0.1/24"
},
"instructions": {
"instruction": [
{
"apply-actions": {
"action": [
{
"dec-nw-ttl": {},
"order": "0"
}
]
},
"order": "0"
}
]
},
"flow-name": "lihao",
"priority": "1",
"idle-timeout": "20",
"hard-timeout": "20",
"cookie": "1",
"table_id": "0"
}
]
}

以上下发的都为流表cookie为1,table id为0,flow-name为lihao,优先级为1,match字段为匹配目的IP地址10.0.0.1,action为减少ttl。 查询下发flow entry的命令为: # ovs-ofctl dump-flows s1 -O OpenFlow13 成功下发流表如下图:

注:官方wiki上面对flow table功能有更详细的介绍(但官方给出的wiki上提供的方法有时也不一定都能完全实现,这里仅提供参考,以实际试验的为准), 地址如下:

https://wiki.opendaylight.org/view/OpenDaylightOpenFlowPlugin:EndtoEndFlows

在Postman中通过RPC方式下发flow entry的方法: 与通过config操作流表不同的是,通过rpc方式操作流表,只需要交换机的id即可,即openflow:1。flow name和flow id都不需要。 With XML: 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/operations/sal-flow:add-flow

提交方式: POST Content:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<input xmlns="urn:opendaylight:flow:service">
   <node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>
   <cookie>1</cookie>
   <flags>SEND_FLOW_REM</flags>
   <hard-timeout>0</hard-timeout>
   <idle-timeout>0</idle-timeout>
   <installHw>false</installHw>
   <match>
    <ethernet-match>
     <ethernet-type>
       <type>2048</type>
     </ethernet-type>
    </ethernet-match>
    <ipv4-destination>10.0.0.1/24</ipv4-destination>
   </match>
   <instructions>
    <instruction>
     <order>0</order>
     <apply-actions>
       <action>
         <output-action>
           <output-node-connector>openflow:1:2</output-node-connector>
         </output-action>
         <order>0</order>
       </action>
     </apply-actions>
    </instruction>
   </instructions>
   <priority>1</priority>
   <strict>false</strict>
   <table_id>0</table_id>
</input>

以上下发的流表都为cookie为1,tableid为0,优先级为1,match字段为匹配目的IP地址10.0.0.1,action为output-action,即2口输出。 2.5.2修改一条流表 在Postman中通过config方式修改flow entry的方法: With XML: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1

提交方式:PUT Use Body: 要修改的流表中的tableid,flowid,cookie,idletimeout,hardtimeout,flags,counters和duration都要保持不变,其他字段则可以被修改。 在Postman中通过RPC方式修改flow table的方法: 通过rpc方式操作流表,原始的Content十分重要。无论是对流表的添加,修改还是删除都需要用到原始的Content。一条通过rpc方式下发的流表如果想要被正确修改,流表的match,priority,table id,cookie都不能改变。方法如下: 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/operations/sal-flow:update-flow

提交方式: POST Content:(通过rpc方式修改流表需将按照其格式输入原始流表的匹配信息,然后再输入更新过后的流表)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<input xmlns="urn:opendaylight:flow:service">
 <node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>
 <original-flow>
   <cookie>1</cookie>
   <flags>SEND_FLOW_REM</flags>
   <hard-timeout>0</hard-timeout>
   <idle-timeout>0</idle-timeout>
   <installHw>false</installHw>
   <priority>1</priority>
   <match>
     <ethernet-match>
       <ethernet-type>
         <type>2048</type>
       </ethernet-type>
     </ethernet-match>
     <ipv4-destination>10.0.0.1/24</ipv4-destination>
   </match>
   <table_id>0</table_id>
 </original-flow>
 <updated-flow>
   <cookie>1</cookie>
   <hard-timeout>0</hard-timeout>
   <idle-timeout>0</idle-timeout>
   <flags>SEND_FLOW_REM</flags>
   <priority>1</priority>
   <match>
     <ethernet-match>
       <ethernet-type>
         <type>2048</type>
       </ethernet-type>
     </ethernet-match>
     <ipv4-destination>10.0.0.1/24</ipv4-destination>
   </match>
   <instructions>
     <instruction>
       <order>0</order>
       <apply-actions>
         <action>
           <dec-nw-ttl/>
           <order>0</order>
         </action>
       </apply-actions>
     </instruction>
   </instructions>
   <table_id>0</table_id>
 </updated-flow>
</input>

以上命令为将cookie=1,table=0,优先级为0,action为在2口输出的流表修改为cookie=1,table=0,优先级为0,action为减少ttl的值。除了action字段被修改其他字段均保持不变。 查询修改后的flow table的命令为: # ovs-ofctl dump-flows s1 -O OpenFlow13 修改前后的流表如下两图:

2.5.3删除一条流表 在Postman中通过config方式删除flow entry的方法: 通过获取交换机的流表信息,查询要删除流表的tableid和flowid。提交方式为DELETE,则可无需输入流表内容即可删除流表,在YANG UI中也只需要URL即可删除。具体命令如下: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1(通过获取交换机的流表信息,查询要删除流表的tableid和flowid。在URL中输入相应的tableid和flowid)

提交方式:DELETE 在Postman中通过RPC方式删除flow table的方法: 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/operations/sal-flow:remove-flow

提交方式: POST Content: rpc方式删除流表只需匹配流表的match,priority,table id,cookie即只要在Content中输入相应格式的以上字段就能够把流表删除。如果不全部匹配以上字段,则有可能将其它流表删除。因此通过rpc方式删除流表必须严格按照匹配相应字段删除流表的原则。

以上两种方式都为将tableid为0,flowid为1的流表删除。

2.6Group table

Response message body:

Attribute

Description

Example

Default

id

Openflow Switch id

Openflow:1

Mandatory

group_id

Group identifier(int)

1

0

type

One of OFPGT_* (string)

‘ALL’

‘ALL’

buckets

Struct ofp_bucket

-weight

Relative weight of bucket (Only defined for select groups)

1

0

-watch_port

Port whose state affects whether this bucket is live (Only required for fast failover groups)

4294967295

OFPP_ANY

-watch_group

Group whose state affects whether this bucket is live (Only required for fast failover groups)

4294967295

OFPP_ANY

-action

0 or more actions associated with the bucket (list of dict)

DROP

Group Table不是一个Flow Table。它是一个动作组的集合。一个动作组称之为group entry。它的结构如下:

当flow entry中有ofpactiongroup时,将指明该flow entry选择执行的group table的ID。结构为:

2.6.1添加一条Group Entry (1)在Postman中通过config方式下发group entry的方法: ODL下发group的界面在Yang UI中,具体节点为:Yang UI API opendaylight-inventory config nodes node{id} group{group id} 找到ODL控制器下发group的界面。按照给出的字段可以下发所需的group即可。 注:需要说明的是,目前OpenDayLight Lithium SR2版本中下发group entry时的action list字段中所列举的action并没有得到很好的支持,即并不是每个action都可以被下发的交换机中,例如controller-action-case、flood-action-case等。其中只有大约15中action可以被正确下发到交换机中。这与flow table中的action一致,不能在flow table中下发的action也不能在group table中被下发。具体有哪些可以被成功下发,会在本文最后详细列出,仅供参考。

在Postman中通过config方式下发group entry的方法: With XML: 输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令: http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/group/1 (注意:如果是下发多条group,每次下发需要更改groupid的值,相应的URL地址中的/group/1中的1就是所对应的groupid,也需要修改。) 提交方式:PUT Use Body:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<group xmlns="urn:opendaylight:flow:inventory">
    <group-type>group-all</group-type>
    <buckets>
        <bucket>
            <action>
                <set-field>
                  <ipv4-source>10.0.0.1/24</ipv4-source>
                </set-field>
                <order>0</order>
            </action>
            <bucket-id>0</bucket-id>
        </bucket>
    </buckets>
    <barrier>false</barrier>
    <group-name>lihao</group-name>
    <group-id>1</group-id>
</group>

With JSON: 首先输入Headers: Content-Type: application/json Accept: application/json Authorization: [方法如上] 在URL地址栏中输入以下命令: http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/group/1 (注意:如果是下发多条group每次下发需要更改group-id的值,相应的URL地址中的group/1中的1就是所对应的group-id,也需要修改。) 提交方式:PUT Use Body:

{
"group": [
{
"group-type": "group-all",
"group-id": "1",
"group-name": "lihao",
"barrier": "false",
"buckets": {
"bucket": [
{
"bucket-id": "0",
"action": [
{
"set-nw-src-action": {
"ipv4-address": "10.0.0.1/24"
},
"order": "0"
}
]
}
]
}
}
]
}

在Postman中通过RPC方式下发group的方法: With XML: 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/operations/sal-group:add-group

提交方式: POST Content:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<input xmlns="urn:opendaylight:group:service">
   <barrier>false</barrier>
   <group-id>1</group-id>
   <group-name>lihao</group-name>
   <group-type>group-all</group-type>
   <buckets>
       <bucket>
           <action>
               <set-field>
                 <ipv4-source>10.0.0.1/24</ipv4-source>
               </set-field>
               <order>0</order>
           </action>
           <bucket-id>0</bucket-id>
       </bucket>
   </buckets>
   <node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>
</input>

以上下发的group都为group-id为1,group-name为lihao,bucket字段中的action为匹配目的IP地址10.0.0.1。 查询下发group entry的命令为: # ovs-ofctl dump-groups s1 -O OpenFlow13 成功下发流表如下图:

(2)除上述添加group流表以外,还可以通过Python-Requests实现ODL对OVS的流表下发,通过借助Python的Requests库,可以方便的完成调用ODL Restful API的流表PUT操作。 对于Python requests模块的安装,直接使用pip install requests即可安装。 创建桥br0,为给br0添加group流表:

 
# ovs-vsctl add-br br0
# ovs-vsctl set bridge br0 protocols=OpenFlow13

将JSON字段的流表描述存入文件,供后面调用

$ cat odl.json
{
 "group": [
     {
         "group-type": "group-all",
         "group-id": "1",
         "buckets": {
             "bucket": [
                 {
                     "bucket-id": "0",
                     "action": [
                         {
                             "order": "0",
                             "set-field": {
                                 "ethernet-match": {
                                     "ethernet-destination": {
                                         "address": "00:00:00:00:00:05"
                                     }
                                 }
                             }
                         },
                         {
                             "order": "1',
                             "set-field": {
                                 "ipv4-destination": "192.168.100.105/32"
                             }
                         },
                         {
                             "order": "2",
                             "output-action": {
                                 "output-node-connector": "5"
                             }
                         }
                     ]
                 },
                 {
                     "bucket-id": "1",
                     "action": [
                         {
                             "order": "0",
                             "set-field": {
                                 "ethernet-match": {
                                     "ethernet-destination": {
                                         "address": "00:00:00:00:00:06"
                                     }
                                 }
                             }
                         },
                         {
                             "order": "1",
                             "set-field": {
                                 "ipv4-destination": "192.168.100.106/32"
                             }
                         },
                         {
                             "order": "2",
                             "output-action": {
                                 "output-node-connector": "6"
                             }
                         }
                     ]
                 },
                 {
                     "bucket-id": "2",
                     "action": [
                         {
                             "order": "0",
                             "set-field": {
                                 "ethernet-match": {
                                     "ethernet-destination": {
                                         "address": "00:00:00:00:00:07"
                                     }
                                 }
                             }
                         },
                         {
                             "order": "1",
                             "set-field": {
                                 "ipv4-destination": "192.168.100.107/32"
                             }
                         },
                         {
                             "order": "2",
                             "output-action": {
                                 "output-node-connector": "7"
                             }
                         }
                     ]
                 }
             ]
         }
     }
 ]
}
  • ‘Content-Type’:’application/json’
  • Basic Authentication: admin/admin
  • 下面是编写下发group流表的代码

新建odl_http.py 脚本文件,编写下面代码,代码编写完成后执行odl_http.py脚本:

$ cat odl_http.py      
#!/usr/bin/env python
 
import requests
from requests.auth import HTTPBasicAuth
 
def http_post(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://10.10.11.80:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:128983912192/flow-node-inventory:group/1'
    with open('odl.json') as f:
        jstr = f.read()
    resp = http_post(url,jstr)
    print resp.content
  • 抓取报文如下
  • OVS查看流表,期望的group已经被添加成功。
 
# ovs-ofctl dump-groups br0 -O openflow13
OFPST_GROUP_DESC reply (OF1.3) (xid=0x2):
 group_id=1,type=all,bucket=weight:0,set_field:00:00:00:00:00:05->eth_dst,set_field:192.168.100.105->ip_dst,output:5,bucket=weight:0,set_field:00:00:00:00:00:06->eth_dst,set_field:192.168.100.106->ip_dst,output:6,bucket=weight:0,set_field:00:00:00:00:00:07->eth_dst,set_field:192.168.100.107->ip_dst,output:7

注:官方wiki上面对group table功能有更详细的介绍(但官方给出的wiki上提供的方法有时也不一定都能完全实现,这里仅提供参考,以实际试验的为准),地址如下:

https://wiki.opendaylight.org/view/OpenDaylightOpenFlowPlugin:EndtoEndGroups

2.6.2修改一条Group Entry 修改group entry只需保持group的group-id不变,修改原group表的相应内容即可。比如将4.6.1下发的group entry中的action修改为2口输出,两种操作方法如下: 在Postman中通过config方式修改group entry的方法: 输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/group/1

提交方式:PUT Use Body:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<group xmlns="urn:opendaylight:flow:inventory">
    <group-type>group-all</group-type>
    <buckets>
        <bucket>
           <action>
              <output-action>
               <output-node-connector>openflow:1:2</output-node-connector>
              </output-action>
                <order>0</order>
            </action>
            <bucket-id>0</bucket-id>
        </bucket>
    </buckets>
    <barrier>false</barrier>
    <group-name>lihao</group-name>
    <group-id>1</group-id>
</group>

在Postman中通过RPC方式修改group entry的方法: With XML: 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/operations/sal-group:update-group

提交方式: POST Content:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<input xmlns="urn:opendaylight:group:service">
   <barrier>false</barrier>
   <group-id>1</group-id>
   <group-name>lihao</group-name>
   <group-type>group-all</group-type>
   <buckets>
       <bucket>
           <action>
             <output-action>
               <output-node-connector>openflow:1:2</output-node-connector>
             </output-action>
               <order>0</order>
           </action>
           <bucket-id>0</bucket-id>
       </bucket>
   </buckets>
   <node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>
</input>

2.6.3删除一条Group Entry 在Postman中通过config方式删除group entry的方法: 通过在控制台输入ovs-ofctl dump-groups s1 -O OpenFlow13命令查询所要删除group的groupid或者通过获取交换机的group entry信息查询要删除group entry的group_id。提交方式为DELETE,则可无需输入group entry的内容即可删除group,在YANG UI中也只需要URL即可删除。具体命令如下: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/group/1

提交方式:DELETE 在Postman中通过rpc方式删除group table的方法: 首先输入Headers: Content-Type: application/xml Accept: application/xml Authorization: [方法如上] 在URL地址栏中输入以下命令:

http://127.0.0.1:8181/restconf/operations/sal-group:remove-group

提交方式:POST Content: rpc方式删除group entry只需匹配group entry的group-id,group-name,group-type即只要在Content中输入相应格式的以上字段就能够把group entry删除。不必再把bucket字段写入Content中。如删除4.6.1所下发的group entry,操作如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<input xmlns="urn:opendaylight:group:service">
   <barrier>false</barrier>
   <group-id>1</group-id>
   <group-name>lihao</group-name>
   <group-type>group-all</group-type>
   <node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>
</input>

2.7Meter table

Response message body:

Attribute

Description

Example

Default

id

Openflow Switch id

Openflow:1

Mandatory

flags

Bitmap of OFPMF_* flags (list)

[“KBPS”]

Empty

meter_id

Meter identifier(int)

1

0

bands

struct ofp_meter_band_header

0

0

– type

One of OFPMBT_* (string)

“DROP”

None

– rate

Rate for this band (int)

1000

None

– burst_size

Size of bursts (int)

1

None

一个meter table包含若干计量表项,确定每个流量的计数。单位流量的计量可以使 OpenFlow 实现各种简单的 QoS 业务,如限速,并且可以结合每个端口队列来实现复杂的QoS 框架,如 DiffServ。Meter table的结构如下:

经过本人的一些实验与测试发现Meter table在OpenDayLight Lithum SR2版本中不能成功下发。至于不能成功下发的原因目前不得而知,有可能是最新版本的ODL出现的bug导致的,也有可能是ODL与OpenFlow1.3协议没有很好的兼容的原因,我也会在后续的工作中去验证。 注:官方wiki上面对meter table功能有更详细的介绍(但官方给出的wiki上提供的方法有时也不一定都能完全实现,这里仅提供参考,以实际试验的为准),地址如下:

https://wiki.opendaylight.org/view/OpenDaylightOpenFlowPlugin:End_toEndMeters

3 ODL目前支持下发的action列表

以下能够成功下发的action仅为本人实验成功,不代表ODL只支持这些action,还有待后续的继续研究。 1.dec-nw-ttl-case 2.set-nw-src-action-case 3.set-nw-dst-action-case 4.set-nw-ttl-action-case 5.dec-mpls-ttl-case 6.pop-vlan-action-case 7.set-dl-src-action-case 8.set-dl-dst-action-case 9.set-mpls-ttl-action-case 10.set-field-case 11.output-action-case 12.set-queue-action-case 13.set-vlan-id-action-case 14.set-vlan-pcp-action-case 15.strip-vlan-action-case

原文发布于微信公众号 - SDNLAB(SDNLAB)

原文发表时间:2015-12-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大内老A

ASP.NET MVC集成EntLib实现“自动化”异常处理[实例篇]

个人觉得异常处理对于程序员来说是最为熟悉的同时也是最难掌握的。说它熟悉,因为仅仅就是try/catch/finally而已。说它难以掌握,则是因为很多开发人员却...

20610
来自专栏空帆船w

Android 专用的日志封装库

所以在程序开发或者上线后如果出现了 Bug,能够及时查看日志,对修复 Bug 非常有帮助。

852
来自专栏Golang语言社区

package http

要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport:

1944
来自专栏开发与安全

80386的分段机制、分页机制和物理地址的形成

注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了...

2625
来自专栏lzj_learn_note

Volley源码分析学习

2)根据SDK版本来创建HttpStack的实现,如果是2.3以上的,则使用基于HttpUrlConnection实现的HurlStack,反之,则利用Http...

1076
来自专栏程序员互动联盟

android apk 防止反编译技术第三篇-伪加密

经过了忙碌的一周终于有时间静下来写点东西了,我们继续介绍android apk防止反编译技术的另一种方法。前两篇我们讲了加壳技术和运行时修改字节码,如果有不明白...

4469
来自专栏岑玉海

Hadoop源码系列(一)FairScheduler申请和分配container的过程

1、如何申请资源 1.1 如何启动AM并申请资源 1.1.1 如何启动AM val yarnClient = YarnClient.createYarnClie...

4293
来自专栏Java帮帮-微信公众号-技术文章全总结

JavaWeb11-jsp.cookie.session(1)

? Jsp&cookie & session 一.jsp 1. jsp的介绍 JSP全名为Java Server Pages,中文名叫java服务器页面,本质...

2925
来自专栏坚毅的PHP

jersey处理支付宝异步回调通知的问题:java.lang.IllegalArgumentException: Error parsing media type 'application/x-www

tcpflow以流为单位分析请求内容,非常适合服务器端接口类服务查问题 这次遇到的问题跟支付宝支付后的回调post结果有关 淘宝的代码例子: publi...

5385
来自专栏企鹅号快讯

微信支付之微信小程序支付

今天给大家介绍一下微信小程序是如果实现支付的流程,在开发之前我们首先要获取到商户的appId和mchId最后就是商户的key值了。这些值在商户申请成功之后都会通...

4515

扫码关注云+社区