问题描述: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(博文地址):
- 第一次是因为:主机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
中。 - 第二次是因为:主机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
- 第三次是因为:交换机没有流表项来处理主机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请求报文触发的。