• 讨论SDN实验中抓不到OpenFlow包的问题 && 分析流表下发过程


    问题描述:1.完全抓不到任何OpenFlow包(wireshark显示)

                     2.仅能够抓到echo_request包和echo_reply包(wireshark显示)

    问题原因:1.mininet和控制器在一台虚拟机中运行,不会有实际的OpenFlow报文从网卡发出的。

                     2.在启动wireshark之前,就启动了控制器,mininet创建了topo并执行ping操作。

                        这种情况,实际是有Packet-in包等报文的,但是wireshark当时没有启动,所以抓不到。

    解决办法:1.mininet和控制器在两台虚拟机上运行,进行抓包,OK。

                     2.先启动wireshark,再去创建topo,启动控制器,执行ping操作。

                        这样保证在ping的开始阶段,wireshark第一时间抓到OpenFlow的报文。

    用wireshark抓到的OpenFlow所有报文如图所示:

    可以看到3次packet-in(发送流请求)和2次flow-mod(下发流表项).

     h1 ping h2过程:

    1). h1 -> ff:ff:ff:ff:ff:ff(广播) ARP Request, 查询h2的MAC地址;
    2). h2-> h1 ARP Reply, 响应h2的MAC地址;
    3). h1-> h2 ICMP echo request;
    4). h2-> h1 ICMP echo reply

    详细过程分析:  

      (1)h1 发送ARP请求报文,源mac为h1mac,目的mac为ffffffffffff,交换机未匹配到流表项,向控制器发送Packet_In报文(编号192)。

      (2)控制器将入端口1与h1的mac地址绑定,并回复Packet_Out报文给交换机,让其执行FLOOD(泛洪)操作,交换机向除了入端口以外的端口泛洪ARP请求报文(编号193)。

      (3)h2接收到ARP请求报文,回复ARP应答报文,源mac为h2mac,目的mac为h1mac,交换机未匹配到流表项,向控制器发送Packet_In报文(编号195).

      (4)控制器将入端口2与h2的mac地址绑定,再看交换机送来的数据包,发现源mac(h2mac)和目的mac(h1mac)都已经和入端口绑定,所以可以下发一条流表项(Flow_Mod报文):

          FlowEntry1:源地址:h2mac,目的地址:h1mac,动作:output 1 (从端口1发出)(编号196)不应该是端口2吗,待解决,入端口为2,动作从1发出

      (5)h1收到ARP应答报文后,开始向h2发送ICMP请求数据包,数据包发送至交换机时,交换机s1未匹配到流表项,向控制器发送Packet_In报文。(编号197)

      (6)控制器查看交换机发来的数据包,发现源mac(h1mac)和目的mac(h2mac)都已经和入端口绑定,所以可以下发一条流表项(Flow_Mod报文):

          FlowEntry2:源地址:h1mac,目的地址:h2mac,动作:output 2 (从端口2发出)(编号198)不应该是端口1吗,待解决,入端口为1,动作从2发出

      (7)交换机按流表项转发ICMP请求/应答数据包,ping过程顺利完成。

    换一种方式说3次Packet-in(博文地址):

      1. 第一次是因为:主机h1 第一次ping主机h2,最初时主机h1中ARP缓存表为空,所以会产生ARP Request数据包发往交换机s1,被S1初始流表中的“漏表项”匹配然后以Packet-in方式转发至Controller处理;Controller发现该request数据包目的地MAC地址在mac_to_port字典不存在,所以会将该request数据包洪泛至所有端口。Controller回应相应的Packet-out,动作(actions)是将该数据包输出(OFPAT_OUTPUT)至除源端口之外的所有物理端口(OFPP_FLOOD)。
          此时没有新增任何流表项,但是将request数据包来源MAC地址与端口保存至mac_to_port中。
      2. 第二次是因为:主机h2为回应ARP Request生成ARP Reply数据包,但是交换机S1中并没有流表可以处理该reply数据包,所以被S1初始流表中的“漏表项”匹配然后以Packet-in方式转发至Controller处理;Controller发现该reply数据包目的地已经被保存至mac_to_port字典中,所以新增一条表项。同时Controller回应相应的Packet-out,动作(actions)是将该数据包输出(OFPAT_OUTPUT)至端口1
          此时新增了一条流表项(1),同时将reply数据包来源MAC地址与端口保存至mac_to_port中。
        (1)表项内容是:
        cookie=0x0, duration=4.219s, table=0, n_packets=2, n_bytes=196, priority=1,
         in_port=2,dl_dst=00:00:00:00:00:01 actions=output:1
      3. 第三次是因为:交换机没有流表项来处理主机h1的ICMP Request数据包,所以以之前两次同样的Packet-in方式发送至Controller,Controller发现该request数据包目的地已经被保存至mac_to_port字典中,所以新增一条表项。同时Controller回应相应的Packet-out,动作(actions)是将该数据包输出(OFPAT_OUTPUT)至端口2
          此时新增了一条流表项(2),内容是
        cookie=0x0, duration=4.215s, table=0, n_packets=1, n_bytes=98, priority=1,
         in_port=1,dl_dst=00:00:00:00:00:02 actions=output:2

    查看交换机流表项:

    ps:最后一条是“漏表项”。OpenFlow1.3及以上版本增加了一个“漏表项”概念,附在每张流表最后,优先级最低,用来匹配处理所有失配的数据包;所以在控制器启动时与交换机连接后,就需要向交换机写入这张表项。 

    交换机多了2条流表项,源mac地址分别为h1和h2,目的mac为h2和h1,优先级为1,入端口分别为1和2,动作分别为从2/1端口发出,这也就是由ping生成的流表项。

    第二条流表项匹配数据包数比第一条少1的原因是h1一开始发的ARP请求是广播形式,所以dst_mac为ff:ff:ff:ff:ff:ff,而不是00:00:00:00:00:01。

    查看控制器日志:

     ps:启动ryu控制器命令:

    cd ryu

    ./bin/ryu-manager --verbose ryu/app/simple_switch_13.py 

     同样,在控制器的Log日志里也写明了触发了多次Packet_In事件,由上述的分析说明最后3次Packet_In事件是由这次ping触发的,

    第一次为 h1的ARP请求报文触发的,第二次由ARP回复报文触发的,第三次是h1给h2发送ICMP请求报文触发的。

     

     参考:https://www.cnblogs.com/kl107/p/13138568.html

    作者:天际使徒
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    javascript之this的深入学习
    记一次前端面试
    nodejs学习
    Javascript内置对象
    Javascript事件
    全屏滚动插件小结
    Javascript函数的深入学习
    近年来前端开发趋势,MVVM框架,Vue.js的核心思想
    Javascript的for ... in循环
    JavaScript的对象深入学习
  • 原文地址:https://www.cnblogs.com/Horizon-asd/p/14202684.html
Copyright © 2020-2023  润新知