基于SDN的网络状态测量

为了更好地管理和运行网络,非常有必要收集网络资源及其状态信息。在很多网络场景中,SDN控制器的决策都取决时延,带宽和拓扑等网络状态。在开发SDN应用的过程中,笔者总结了一些有用的网络状态测量的解决方案,可以为初学者在解决网络问题时提供一些启发。本文将主要介绍如何通过SDN控制器和OpenFlow协议来测量和收集网络中的时延、带宽以及拓扑状态等信息。

时延

时延的测试在终端会显得很容易,但是在交换机节点上测试时延就比较麻烦。在SDN中,可以通过以下步骤实现交换机之间链路的时延。

(1)控制器向交换机A下发一个Packet_out报文。报文的数据段携带了任意一个约定好的协议报文,其报文的数据段携带了控制器下发报文时的时间戳。Packet_out报文的动作指示交换机将其泛洪或者转发到某端口。
(2)交换机B收到了交换机A发送过来的数据包,无法匹配对应流表项,从而packet_in到控制器。控制器接收到这个数据包之后,和当下时间相减,得到时间差T1。其时间差约等于数据包从控制器到交换机A + 交换机A到交换机B + 交换机B到控制器的时延。
(3)同理,控制器向交换机B发送一个类似的报文。然后控制器从交换机A收到Packet_in报文,记录下时间差T2。所以T1+T2=控制器到交换机A的RTT+控制器到交换机B的RTT+交换机A到交换机B的时延RTT。
(4)控制器向交换机A和交换机B分别发送带有时间戳的Echo request。交换机收到之后即刻回复携带echo request时间戳的echo reply消息。所以控制器可以通过Echo reply的时间戳减去Echo reply携带的时间,从而得到对应交换机和控制器之间的RTT。通过这种方法测得控制器到交换机A,B的RTT分别为Ta,Tb。
(5)T1+T2-Ta-Tb则得到交换机A到交换机B的RTT。假设往返时间一样,则交换机A到交换机B的链路时延为(T1+T2-Ta-Tb)/2。

这种方法可以相对准确地测试到链路的实验,无法计算而忽略掉的部分时间是数据包在交换机中的处理时延。而这种简单的方法已经被申请专利了,不知道我这么写会不会有问题。

带宽

带宽数据是网络状态中的重要数据。在SDN网络中获取带宽可以通过OpenFlow协议,也可以通过第三方的测量软件获取数据,如sFlow。此处仅介绍如何通过OpenFlow协议来获取可用带宽。

一条链路的带宽由两个端口的能力决定。所以我们可以通过获取端口的流量来得到链路的流量。OpenFlow协议中可以通过统计报文来获取端口、流表、流表项、组表和meter表的统计信息。以端口的统计信息为例,控制器通过周期下发Port statistics消息可以获得交换机端口的统计信息,其返回的统计消息格式如下:

从消息格式中可以发现可获取到收发的包数、字节数以及这个统计持续的时间。如果把两个不同时间的统计消息的字节数相减,再除以两个消息差也即统计时间差则可以得到统计流量速度。如果想得到剩余带宽则可以用端口最大带宽减去当前流量带宽,则得端口剩余带宽。同理,可以计算出对应流表项或者组表等的统计流量。基于以上计算出来的端口剩余带宽等数据,可为部署负载均衡等流量优化工程提高数据支撑。

拓扑

拓扑的发现比较容易理解。控制器通过将携带dpid+port_no信息的LLDP数据包从对应端口packet_out出去,然后LLDP数据包被对端交换机Packet_in到控制器,最后再由控制器结合Packet_in消息报头的DPID和in_port和LLDP报文中的DPID和Port_no从而得出一条链路信息。依次类推,控制器可以发现全部的链路信息,从而发现网络拓扑。

以上的解决方案需要向每个端口下发packet_out,而此举会产生很多的OpenFlow消息,消耗OpenFlow channel宝贵的带宽资源。所以可以采用以下的优化结局方式。

(1)收集swicth features时记录交换机上端口号和端口mac的对应关系。
(2)弃用port_id的tlv,转而使用端口的mac作为端口的标记。
(3)下发packet_out时,actions中添加对每个端口的OFPActionSetField(eth_src=port_infor.hw_addr)动作和OFPActionOutput(port_infor.port_no)动作,从而使得仅对交换机下发一个Packet_out就可以完成对所有的端口进行LLDP发送的操作。在每个端口发送数据之前,都需要对数据的src_mac地址置位成端口的mac地址。而控制器收到LLDP的packet_in时,通过mac和port_id的对应关系找出链路。通过这种方法可以将packet_out的数目大大降低,从每个端口发送端口数目N个降低至到1个。

以上的解决方案仅能发现OpenFlow的网络,如果OpenFlow网络中间存在传统网络设备形成的子网络,则以上的解决方案将会将与传统网络连接的端口误认为是接入端口。

这个问题可以通过LLDP和发送广播包的方式解决。首先通过LLDP发现OpenFlow的拓扑。然后再往“边缘端口”(与传统网络相连的端口此时也被认为是边缘端口)发送广播包,如果广播包从某一个交换机端口回来,则说明这个端口之外未知的地方还有一些交换设备,则证明这个端口不是主机的接入端口。但是传统设备如果不通过其他形式去发现还是无法发现具体的网络拓扑的信息。

总结

本文总结了在SDN网络中如何发现和测量网络的一些基础的信息,比如链路的时延和带宽,网络的拓扑等等。发现和测量这些基础的网络状态可以用于其他的网络决策,从而使得网络运行更加合理,进而提高资源利用率。以上部分内容以实现并公布,比如带宽测量模块可查看《SDN网络感知服务与最短路径应用》

作者简介:
李呈,2014/09-至今,北京邮电大学信息与通信工程学院未来网络理论与应用实验室(FNL实验室)攻读硕士研究生。

个人博客:www.muzixing.com


  • 本站原创文章仅代表作者观点,不代表SDNLAB立场。所有原创内容版权均属SDNLAB,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用,转载须注明来自 SDNLAB并附上本文链接。
  • 本文链接http://www.sdnlab.com/15733.html
  • 本文标签技术/tech

分享到:
相关阅读
24条评论

登录后才可以评论

  1. comment reply zmhzcy 2016/01/27 11:28
    时延计算方式,在实际中用过,存在一些问题,主要是计算出结果抖动比较大。出现抖动大的原因有两个,一是openvswitch无法匹配流表会产生packet_in发送到控制器,这段时间会有时间间隔,这个时间是跟openvswitch事件机制有关,2.3版本以后有改进,这个时间没有大的波动。二是时间戳在哪个层次上来计算,如果是在回调函数handle_packet_in里面来计算时间戳,这个时间是比较滞后的,应该在控制器第一个模块收到packet_in消息后就计算时间戳。我从这两个方面改进后,计算出的时间跟ping的延时基本差不多,而且抖动很小。以上供参考
        1楼
  2. comment reply 李呈 2016/01/27 11:53
    @zmhzcy 嗯嗯,你说的对。这种测试的方法影响很大的。所以在OpenFlow1.3协议建议将echo报文的处理放在系统的内核,从而最快地处理。
        2楼
  3. comment reply pixuan 2016/02/05 23:35
    作者您好,我目前在做Group table相关的内容,使用的是Floodlight控制器,Openflow1.3协议版本。 通过 https://floodlight.atlassian.net/wiki/display/floodlightcontroller/How+to+Work+with+Fast-Failover+OpenFlow+Groups 介绍的方法操作组表。 但是并没有成功。。。请问,如何查看交换机的组表项呢,用文中提到的sudo ovs-ofctl dump-groups br_ovs -O OpenFlow13方式,mininet并没有dump-groups命令。另外,流表项里也看不到action=group1之类的信息。总之,凡是跟group相关的信息,如何查看呢。?
        3楼
  4. comment reply 海滩小强 2016/03/01 08:41
    我想问一下,本文的测量延时时,(4)控制器向交换机A和交换机B分别发送带有时间戳的Echo request, 不知道这个该怎么求呀? 求拓补的时候,packet_out的数目大大降低,packet_out的数目通过实验怎么求呢?
        4楼
  5. comment reply 李呈 2016/03/01 09:36
    @海滩小强 echo request的数据段是任意长度的数据,可以把发送时的时间戳放在里面,而echo reply收到后会回复控制器的。最后一句没看懂。
        5楼
  6. comment reply 海滩小强 2016/03/01 09:44
    echo request的数据段是任意长度的数据,可以把发送时的时间戳放在里面,我不太明白?测量延时时,大体我知道这样,但是不知道该怎样操作呢? 现在我只会ping 和iperf(两个虚拟主机之间发数据包)然后通过发送数据包测得交换机之间的延时。 通过这种方法可以将packet_out的数目大大降低,从每个端口发送端口数目N个降低至到1个。 但是用mininet和POX控制器仿真的时候怎么计算packet_out的数目呢? 或者常见的flowstatrequest信息? 非常感谢你。
        6楼
  7. comment reply 海滩小强 2016/03/01 10:00
    @李呈 echo request的数据段是任意长度的数据,可以把发送时的时间戳放在里面,我不太明白?测量延时时,大体我知道这样,但是不知道该怎样操作呢? 现在我只会ping 和iperf(两个虚拟主机之间发数据包)然后通过发送数据包测得交换机之间的延时。 通过这种方法可以将packet_out的数目大大降低,从每个端口发送端口数目N个降低至到1个。 但是用mininet和POX控制器仿真的时候怎么计算packet_out的数目呢? 或者常见的flowstatrequest信息? 非常感谢你。
        7楼
  8. comment reply 李呈 2016/03/01 10:04
    @海滩小强 除了在数据面通过终端获取时延以外,你也可以通过控制器获取啊。控制器才是决策者。我说的都是通过控制器去获取的时延,你说的都是通过终端获取的。Packet_out发了多少个,控制器必然是知道的,为什么要用过交换机来统计,然后再上报给控制器?不是多此一举?从控制器的角度去思考一下 你就明白了。
        8楼
  9. comment reply 海滩小强 2016/03/01 20:04
    @李呈 今天想了很长时间,还是没想明白,特来向你请教。 Packet_out发了多少个,控制器必然是知道的, 但是我不知怎么求呀。 我主要想问你,控制器向交换机发的packet-out 和ofpt_ stats_request信息的数目怎么求出来的, 是否认为求这些信息的数目可以代表控制器的负载。 还有控制器向交换机A和交换机B分别发送带有时间戳的Echo request,这段延时怎么求的? 例如,在POX控制器哪部分怎么反映出来这些信息的数目? 谢谢啦
        9楼
  10. comment reply 541049571 2016/04/08 12:48
    针对上面提到的时延测量 我有问题下请教一下 1 控制器发给交换机A的packet_out到了交换机B后如果匹配到了没有向控制器发packet_in怎么办 2 这是需要新加一个模块,定时的测量网络中任意两个相邻的交换机时延并保存起来吗 3是不是这个模块向交换机进行packet_out然后也是这个模块接受最快到达的packet_in进行计算出时延,并做一些处理防止之后交换机A到B的packet_in进行干扰呢?
        10楼
  11. comment reply 李呈 2016/04/08 15:26
    @541049571 1:既然你要让他packet_in回控制器,那么就不能下发流表项啊。都是控制器的行为,自相矛盾不是特别好吧。 2:可以啊。 3:不能确定是不是最先接收到。在ryu里面注册了之后会接受到分发,但是分发的顺序应该是按照初始化模块时注册事件的顺序决定的。比如一个事件被三个模块的三个处理函数注册监听了,那么分发的时候将会按照函数注册时的顺序发送,因为他是一个list.
        11楼
  12. comment reply 541049571 2016/04/11 21:25
    有些问题还是不明白想去实验室问问学长可以吗,不会耽误学长太多时间,请问最近有空吗?
        12楼
  13. comment reply Hunter 2016/05/19 21:28
    去github下了你的ryu,然后用你说的代码跑不起来,先是six版本过低,然后是这个,新人求指教。 Traceback (most recent call last): File "/usr/local/bin/ryu-manager", line 9, in load_entry_point('ryu==3.14', 'console_scripts', 'ryu-manager')() File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 351, in load_entry_point return get_distribution(dist).load_entry_point(group, name) File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2363, in load_entry_point return ep.load() File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2088, in load entry = __import__(self.module_name, globals(),globals(), ['__name__']) File "/usr/local/lib/python2.7/dist-packages/ryu/cmd/manager.py", line 43, in from ryu.openexchange import oxp_controller ImportError: No module named openexchange
        13楼
  14. comment reply 李呈 2016/05/19 23:20
    @Hunter 重新pull一下代码,这下可以了,之前删代码没有删干净。
        14楼
  15. comment reply Hunter 2016/05/20 09:49
    @李呈 非常感谢!现在应用可以跑起来了,但是在用mininet启动拓扑的时候,应用报unsupported version 0x1. If possible, set the switch to use one of the versions [4]。我的mininet是2.2.1版本,ovs是2.0.2。请问是我的ovs版本过低的原因么?还是我的mininet不支持openflow1.3?
        15楼
  16. comment reply Hunter 2016/05/20 11:19
    @李呈 我把ovs升级到了2.3.3之后又往前进了一步,但是又出现了新的问题,用了你自带的tree.py的拓扑可以pingall,用我自己的拓扑不行,用mininet默认控制器是可以pingall的。两者都出现了以下的情况,您知道原因么? 0.0.0.0 location is not found. 255.255.255.255 location is not found. 而且我的拓扑还出现了link port部分switch全部显示no-link,host部分也是not found。 是我的拓扑问题?但是默认控制器pingall没问题啊。求指点
        16楼
  17. comment reply Hunter 2016/05/20 15:29
    @李呈 我把ovs升级到了2.3.3之后又往前进了一步,但是又出现了新的问题,用了你自带的tree.py的拓扑可以pingall,用我自己的拓扑不行,用mininet默认控制器是可以pingall的。两者都出现了以下的情况,您知道原因么? 0.0.0.0 location is not found. 255.255.255.255 location is not found. 而且我的拓扑还出现了link port部分switch全部显示no-link,host部分也是not found。 是我的拓扑问题?但是默认控制器pingall没问题啊。望不吝赐教
        17楼
  18. comment reply 李呈 2016/08/27 07:01
    @zmhzcyz最近我运行发现echo的时延竟然比lldp 的实验还长,所以我觉得是有问题的。不知道你怎么实现的,能给哥github链接吧,求指导。
        18楼
  19. comment reply 安之茵 2016/09/01 10:41
    @zmhzcy 你好,我尝试了这个时延计算方法,还是存在问题的,我想请问一下:你具体是如何做的?可以给我你的邮箱吗?我现在正在研究,想请教你一些问题,万分感谢!
        19楼
  20. comment reply 李呈 2016/09/03 08:49
    @安之茵 修改过后问题解决了,基本上比ping的数据大一些。原因在于lldp数据包的分发排队。但是基本上可以测试到0.2-0.6ms的链路时延。具体操作请仔细阅读reamde:https://github.com/muzixing/ryu/tree/master/ryu/app/network_awareness
        20楼
  21. comment reply xinlan 2016/09/22 17:23
    您能在详细地介绍一下SDN中即时获取当前带宽的办法吗?或者有什么资料可以提供给我吗?
        21楼
  22. comment reply mengrady 2016/12/12 17:10
    @李呈 :你好,上边提到了带宽,我想知道怎么计算带宽呢,可以用接收的byte数除以时间吗
        22楼
  23. comment reply 李呈 2016/12/13 03:16
    @mengrady http://www.muzixing.com/pages/2016/07/08/ji-yu-tiao-shu-shi-yan-dai-kuan-de-zui-duan-you-lu-jing-he-fu-zai-jun-heng.html
        23楼
  24. comment reply 李呈 2016/12/13 03:16
    @xinlan http://www.muzixing.com/pages/2016/07/08/ji-yu-tiao-shu-shi-yan-dai-kuan-de-zui-duan-you-lu-jing-he-fu-zai-jun-heng.html
        24楼
李呈 发表于16-01-27
0