基于ODL与Pica8交换机端到端的限速实验
一、介绍
本实验中,使用OpenDaylight控制器的REST APIs来控制Pica8交换机。使用flow table与meter table(OF1.3的特性)来达到端到端限速的目的。没有实体交换机的同学可以使用CPqD与Mininet来完成实验(安装指南见参考资料1)。目前,OpenvSwitch 2.5不支持meter。
1.1 OF1.3 Meter简介
Meter Table是在OF1.3中引入的一个新概念。个人认为它最与众不同的地方是用它可以实现per-flow的QoS,例如本次实验展示的就是rate-limiting。OVSDB也具有限流功能,但OVSDB的限流只能针对端口(不知道有没有小伙伴成功使用过OVSDB限流的,在本机上测试可行,但是用两台实体机操作暂时还未成功)。
每一个Meter Table表项由三元组构成,Meter Identifier,Meter Bands和Counters。这里介绍一下Meter Bands,在Meter Bands中定义了这个Meter的速率(rate)以及busrt size。不同交换机在拥有相同Meter rate的情况下,不同的burst size会带来不同的限流结果。在某台交换机上,使用rate=8000,burst size=200的时候,实际限流效果为7000多左右,而在另一台交换机上,使用rate=8000,burst size=8000的时候,实际限流效果才为7000多左右。
Band由四元组构成Band Type、Rate、Counters、Type specific arguments。OF1.3中只定义了drop与dscp remark两种类型的band。前者就是当包的速率超过一个阈值的时候,会丢包。dscp remark,当包的速率超过一定阈值的时候,会减少包IP头中的DSCP域的值。上述这个阈值即为rate。
每一个flow entry可以在其instruction域里对应一个meter。
二、实验环境
OpenDaylight distribution-karaf-0.4.1-Beryllium-SR1
Pica8 Switch (p3, p4)
FW Version: 2.6.5/24714
OF Version: 1.3
OVS Version: 2.3
Switch ID in OpenDaylight:
p3: openflow:6790870225108767794
p4: openflow:6790870225108767797
Iperf Server (SR1)
IP: 1.1.1.1 (eth2)
Iperf Client (SR2)
IP: 1.1.1.2 (eth3)
2.1 实验拓扑
2.2 步骤与结果
注意1:必须先下meter然后才能下flow entry! 注意2:在写request的时候要记得填写authorization,默认用户名和密码都是admin!
A. 配置交换机P3
往交换机P3上加meter
方法: PUT
URI: http://{controller-IP}:8181/restconf/config/opendaylight-inventory:nodes/node/{node-id}/meter/{meter-id}
这个URI很好理解,就是往一个id为{node-id}的交换机上添加一个id为{meter-id}的meter。Request body中的中的meter-kbps和meter-burst特别重要,因为ODL默认发送的rate的单位是package per second。Meter-burst也一定要填,是因为不填的时候限速没效果。
<meter xmlns="urn:opendaylight:flow:inventory">
<meter-id>5</meter-id>
<flags>meter-kbps meter-burst</flags>
<container-name>abcd</container-name>
<meter-band-headers>
<meter-band-header>
<band-id>0</band-id>
<meter-band-types>
<flags>ofpmbt-drop</flags>
</meter-band-types>
<drop-rate>8000</drop-rate>
<drop-burst-size>100</drop-burst-size>
</meter-band-header>
</meter-band-headers>
<meter-name>Foo</meter-name>
</meter>
B. 往交换机P3上加带有meter的flow entry (从源IP到目的IP)
方法: PUT
URI: http://{controller-IP}:8181/restconf/config/opendaylight-inventory:nodes/node/{node-id}/table/{table-id}/flow/{flow-id}
通过这个可以看出一个简单的OF1.3的flow table表项是由match和instructions构成的(当然还有priority、couter、timeout和cookie)。Instructions由instruction构成,然后每一个instruction又由一个或多个action构成。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<flow xmlns="urn:opendaylight:flow:inventory">
<priority>1</priority>
<flow-name>Foo</flow-name>
<match>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
</ethernet-match>
<in-port>48</in-port>
</match>
<id>2</id>
<table_id>0</table_id>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>68</output-node-connector>
</output-action>
</action>
</apply-actions>
</instruction>
<instruction>
<order>1</order>
<meter>
<meter-id>5</meter-id>
</meter>
</instruction>
</instructions>
</flow>
C. 往交换机P3上加从目的IP到源IP的flow entry
方法: PUT
URI: http://{controller-ip}:8181/restconf/config/opendaylight-inventory:nodes/node/{node-id}/table/{table-id}/flow/{flow-id}
本条流与上条流最大的区别就是在action中没有指定meter-id。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<flow xmlns="urn:opendaylight:flow:inventory">
<priority>1</priority>
<flow-name>Foo</flow-name>
<match>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
</ethernet-match>
<in-port>68</in-port>
</match>
<id>2</id>
<table_id>0</table_id>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>48</output-node-connector>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>
D. 查看P3上的流表
其中最后两条是应用meter的flow entry。事实上只要指定单向流即可。
这个meter的结果是缺少meter-burst的。当你添加了meter-burst,这个结果会增加一项burst_size=100。
2.3 测试结果
在P3与P4都设置了8000Kbits/sec的限流。然后使用SR2来以10000Kbits/s的速度向SR1发送UDP。然后结果显示传输速率已经被限制为7767Kbits/s。
SR1 Server
SR2 client
三、遇到问题与解决方案
1.删除了一些流表项,但是他们过了一段时间又出现了。
据猜测,OpenDaylight会将一些流表项存在其data store中,他们不会被自动删除。而且就算在交换机端手动删除掉了流表,ODL里的这个流表还是存在的。故当ODL试图保持data store和交换机中的数据的一致性时,会再次下发这个流表。
2.配置了流表项和meter项,但是发送的限速的效果不好。
可能是由于没有设置burst size导致。解决方案就是设置burst size。经测试,如果多条flow entries使用了同一个meter,那么这个meter的效果会变差。多个meter同时存在的时候,那么meter的效果也没有有且只有一个meter的效果好。
参考资料
1.https://github.com/CPqD/ofsoftswitch13/wiki/OpenFlow-1.3-Tutorial
2.https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-spec-v1.3.0.pdf
- PHP数据结构(二十三) ——快速排序
- PHP数据结构(二十四) ——堆排序
- PHP数据结构(二十五) ——并归排序
- PHP数据结构(二十六) ——基数排序实现36进制数排序
- Apache配置
- jquery事件
- 设计模式专题(二)——策略模式
- ASP.NET AJAX(10)__Authentication ServiceAuthentication ServiceAuthentication Service属性Authentication
- 高效开发 MVVM 和 databinding 你需要使用的工具
- ASP.NET AJAX(9)__Profile Service什么是ASP.NET Profile如何使用ASP.NET ProfileProfile ServiceProfile Service预
- 设计模式专题(三)——装饰模式
- ASP.NET AJAX(8)__Microsoft AJAX Library中异步通信层的使用什么是异步通信层Micorsoft AJAX Library异步通信层的组成WebRequestExec
- ASP.NET AJAX(7)_Microsoft AJAX Library扩展客户端组件继承时需要注意的问题扩展类型如何修改已有类型
- ASP.NET AJAX(6)__Microsoft AJAX Library中的面向对象类型系统命名空间类类——构造函数类——定义方法类——定义属性类——注册类类——抽象类类——继承类——调用父类方
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 每日一题 | 老板出的下棋问题
- Qt音视频开发12-mpv解码播放
- 算法专题 | 10行代码实现的最短路算法——Bellman-ford与SPFA
- 每日一题 | 土豪割草问题
- 高阶面试:伯努利过程
- Python 分析电影《南方车站的聚会》
- Python 基础(十八):命名空间 & 作用域
- Python爬虫(三):BeautifulSoup库
- Python 爬虫(四):Selenium 框架
- Python 爬虫(五):PyQuery 框架
- Python 爬虫(六):Scrapy 爬取景区信息
- Python 爬虫(七):pyspider 使用
- 你的童年有俄罗斯方块吗?教你用 Python 实现俄罗斯方块!
- Python 基础(七):字典与集合
- 5 分钟教你用 Python 实现贪吃蛇!