packet-in,table-miss 触发机制

openflow协议版本差异

Posted by chochi on June 15, 2018

ubuntu18.04, mininet 2.3 , OVS 2.9.0, oh-my-zsh, wireshark, DOL

流表项(flow entry),流表(flow table)

1 实验背景

  最近在看OpenFlow协议1.3版本,发现一个印在我脑海里的认知冲突。 :packet-in消息的触发机制有两种:1. 未匹配到流表项,交换机封装数据包头部发送给控制器请求决策。 2. 流表项动作里面含发送给控制器动作(CONTROLLER)。但是昨天看到 table-miss packets 的处理,若没有与之匹配的流表项,则默认drop,那么什么时候是drop什么时候发送packet-in呢。后来查阅了一下资料,是版本的问题。table-miss在1.3之后才出现。那么我推论,1.3版本之后的packet-in就只剩下第二种触发机制。所以今天实验一下。

  关于table-miss 的定义:if a packet does not match a flow entry in a flow table ,this is a table miss. A table-miss flow entry in the flow table may specify how to process unmatched packets.

  对于 table-miss 可以专门下发一条流表项告诉交换机如何处理table-miss packets,可指定的动作有三种,1. drop,2. 将 packets 发送到另一个流表,3. 封装成 packet-in 数据包发送给控制器。   若没有下发流表项告诉交换机如何处理table-miss,则默认drop动作。

2 OpenFlow1.3 实验验证

  1. 开启ODL控制器,使用Miniet建立一个简单的拓扑与控制器链接,指定南向协议OpenFlow13。
➜  chochi.cn# sudo mn --switch=ovsk,protocols=OpenFlow13 --controller=remote,ip=127.0.0.1:6633
  1. 在所有主机没有发送数据包之前(pingall操作前),在Mininet的CLI界面为主机修改IP、MAC地址,以便后面的查看。
mininet> py h1.setIP("10.0.0.1")
mininet> py h2.setIP("10.0.0.2")
mininet> py h1.setMAC("f0:00:00:00:00:01")
mininet> py h2.setMAC("f0:00:00:00:00:02")
  1. 查看一下,交换机链接上控制器后,控制器下发的初始默认流表项(重要)。
  2. 在Mininet的CLI界面,pingall操作后,再次查看交换机的流表项(重要)。

1

  初始默认流表项有四条,由匹配项可以分为三类:LLDP协议、端口、table-miss。OpenFlow13协议中规定,所有匹配项都为任意,且优先级为0的流表项是专门为table-miss数据包为设置的。 以端口为匹配的两条流表项,匹配到数据包时候将请求控制器决策。在MIninet的cli界面输入‘h1 ping h2’之后,让我们来看看是怎么样的过程:

- h1 发送 arp ,询问 h2 的mac地址。
- 匹配到端口流表项,转发给另外一个端口,并且交换机封装packet-in给控制器请求裁决。
- h2 回复arp, h1 更新 arp 缓存,h1 发送 icmp 数据包给h2, h2回复imcp。
- 控制器在交换机上安装以MAC地址为匹配项的流表项,
  1. 因为现在交换机中的流表项有太多可能产生packet-in消息的地发,故删除 s1 中的所有流表项。
➜  chochi.cn# sudo ovs-ofctl del-flows s1 -O OpenFlow13
  1. 下发以ip为匹配项的流表项,并修改h1,h2的arp缓存表,使其不用发送arp报文。
➜  chochi.cn# sudo ovs-ofctl add-flow s1 -O OpenFlow13 \                
"table=0,in_port=2,ip,nw_src=10.0.0.2,nw_dst=10.0.0.1,actions=1"
➜  chochi.cn# sudo ovs-ofctl add-flow s1 -O OpenFlow13 \                
"table=0,in_port=1,ip,nw_src=10.0.0.1,nw_dst=10.0.0.2,actions=2"
mininet> h1 arp -s 10.0.0.2 f0:00:00:00:00:02
mininet> h1 arp
Address                  HWtype  HWaddress           Flags Mask            Iface
10.0.0.2                 ether   f0:00:00:00:00:02   CM                    h1-eth0
mininet> h2 arp -s 10.0.0.1 f0:00:00:00:00:01
mininet> h2 arp
Address                  HWtype  HWaddress           Flags Mask            Iface
10.0.0.1                 ether   f0:00:00:00:00:01   CM                    h2-eth0

3

  这是h1 和 h2 可以ping通,但交换机中没有table-miss流表项,故我们验证一下table-miss是不是默认drop 了,且没有发送packet-in 消息。

➜  chochi.cn# sudo ovs-appctl ofproto/trace s1  in_port=1,ip,nw_src=10.0.0.1,nw_dst=10.0.0.3 -generate
Flow: ip,in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,nw_src=10.0.0.1,nw_dst=10.0.0.3,nw_proto=0,nw_tos=0,nw_ecn=0,nw_ttl=0

bridge("s1")
------------
 0. No match.
    drop

Final flow: unchanged
Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=10.0.0.3,nw_frag=no
Datapath actions: drop

2

  确实是drop掉啦,通过wireshark抓包也没有看到packet-in。添加一条触发packet-in的流表项。

➜  chochi.cn# sudo ovs-ofctl add-flow s1 -O OpenFlow13 \
"table=0,in_port=1,ip,nw_dst=10.0.0.3,actions=CONTROLLER:65535"

  h1 内写入arp,让其直接发送icmp报,而不用先产生arp。

mininet> h1 arp -s 10.0.0.3 f0:00:00:00:00:03

  在验证结果。

➜  chochi.cn# sudo ovs-appctl ofproto/trace s1  in_port=1,ip,nw_src=10.0.0.1,nw_dst=10.0.0.3 -generate
Flow: ip,in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,nw_src=10.0.0.1,nw_dst=10.0.0.3,nw_proto=0,nw_tos=0,nw_ecn=0,nw_ttl=0

bridge("s1")
------------
 0. ip,in_port=1,nw_dst=10.0.0.3, priority 32768
    CONTROLLER:65535

Final flow: unchanged
Megaflow: recirc_id=0,eth,ip,in_port=1,nw_src=10.0.0.1,nw_dst=10.0.0.3,nw_frag=no
Datapath actions: userspace(pid=3960999838,controller(reason=1,dont_send=0,continuation=0,recirc_id=41,rule_cookie=0,controller_id=0,max_len=65535))

  Wireshark抓到packet-in报文。

4

3 OpenFlow1.0 实验验证

1-5 步骤如1.3版本一样。

mininet> h1 arp -s 10.0.0.2 00:00:00:00:00:02
mininet> h1 arp -s 10.0.0.3 00:00:00:00:00:03
mininet> h2 arp -s 10.0.0.1 00:00:00:00:00:01

5

流表中没有table-miss的flowentry,但没有被默认drop,确实发送packet-in了。

6

使用trace可以更清楚的看清过程,发送packet-in给控制器并注明原因是table-miss。

7

4 总结

  OpenFlow1.0没有table-miss,对于没有匹配到流表项的数据报来说,交换机会将其数据包头封装在packet-in内发送给控制器,请求裁决。

  OpenFlow1.3对于没有匹配到流表项的数据报来说,直接默认drop,但是规定每个流表最好要下一条针对table-miss处理的流表项。