Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ofproto-dpif-xlate: Fix tun_metadata match after recirc
Consider the following OpenFlow rules that match on tun_metadata0 after recirculation. If we start ICMP flow with tun_metadata0=0x1 follow by a flow with tun_metadata0=0x3, OVS will incorrectly match the second flow with the tun_metadata0=0x1 rule. table=0, in_port=gnv1, icmp, action=ct(table=1) table=0, in_port=gnv0, icmp action=ct(table=1) table=1, in_port=gnv1, icmp, action=output:gnv0 table=1, in_port=gnv0, icmp, ct_state=+trk+new, action=ct(commit),output:gnv1 table=1, in_port=gnv0, icmp, ct_state=+trk+est, tun_metadata0=0x1 action=output:gnv1 table=1, in_port=gnv0, icmp, ct_state=+trk+est, tun_metadata0=0x3 action=output:gnv1 The root cause of this issue is because during recirculation, OVS will overwrite the tun_metadata0 with the one stored in the frozen state. This will result in erroneous behavior if tun_metadata0 is wildcarded in the megaflow as shown below. Notice that both the second and the third megaflow both carry 0x1 in tun_metadata0. recirc_id(0),tunnel(tun_id=0x2,src=172.31.1.1,dst=172.31.1.100,geneve({}{}{}), flags(-df-csum+key)),in_port(5),eth(),eth_type(0x0800),ipv4(proto=1,frag=no), packets:213, bytes:20774, used:0.672s, actions:ct,recirc(0x4) recirc_id(0x4),tunnel(tun_id=0x2,src=172.31.1.1,dst=172.31.1.100, geneve({class=0x102,type=0x7,len=4,0x3}{class=0,type=0,len=0}), flags(-df-csum+key)),in_port(5),ct_state(-new+est+trk),eth(),eth_type(0x0800), ipv4(proto=1,tos=0/0x3,frag=no), packets:98, bytes:9506, used:0.992s, actions:set(tunnel(tun_id=0x2,dst=172.31.1.2,ttl=64,tp_src=64725,tp_dst=6081, geneve({class=0x102,type=0x7,len=4,0x1}),flags(df|key))),5 recirc_id(0x4),tunnel(tun_id=0x2,src=172.31.1.1,dst=172.31.1.100, geneve({class=0x102,type=0x7,len=4,0x1}{class=0,type=0,len=0}), flags(-df-csum+key)),in_port(5),ct_state(-new+est+trk),eth(),eth_type(0x0800), ipv4(proto=1,tos=0/0x3,frag=no), packets:112, bytes:10976, used:0.672s, actions:set(tunnel(tun_id=0x2,dst=172.31.1.2,ttl=64,tp_src=64725,tp_dst=6081, geneve({class=0x102,type=0x7,len=4,0x1}),flags(df|key))),5 It seems to be two ways to fix this issue, one is to unwildcarded all the tunnel metadata when OVS generates megaflow with recirculation. The other one is to add a bool flag in the frozen state, and ask OVS to honor the tunnel metadata from the packet instead of the from the frozen state. Since the first approach will increase the number of megaflows and may incur performance impact, this patch takes the second approach. With this patch, the megaflows are as following: recirc_id(0),tunnel(tun_id=0x2,src=172.31.1.1,dst=172.31.1.100, geneve({}{}{}),flags(-df-csum+key)),in_port(5),eth(),eth_type(0x0800), ipv4(proto=1,frag=no), packets:60, bytes:5850, used:0.004s, actions:ct,recirc(0x8) recirc_id(0x8),tunnel(tun_id=0x2,src=172.31.1.1,dst=172.31.1.100, geneve({class=0x102,type=0x7,len=4,0x1}{class=0,type=0,len=0}), flags(-df-csum+key)),in_port(5),ct_state(-new+est+trk),eth(),eth_type(0x0800), ipv4(proto=1,tos=0/0x3,frag=no), packets:29, bytes:2842, used:0.356s, actions:set(tunnel(tun_id=0x2,dst=172.31.1.2,ttl=64,tp_src=64725,tp_dst=6081, geneve({class=0x102,type=0x7,len=4,0x1}),flags(df|key))),5 recirc_id(0x8),tunnel(tun_id=0x2,src=172.31.1.1,dst=172.31.1.100, geneve({class=0x102,type=0x7,len=4,0x3}{class=0,type=0,len=0}), flags(-df-csum+key)),in_port(5),ct_state(-new+est+trk), eth(),eth_type(0x0800), ipv4(proto=1,tos=0/0x3,frag=no), packets:28, bytes:2716, used:0.004s, actions:set(tunnel(tun_id=0x2,dst=172.31.1.2,ttl=64,tp_src=64725,tp_dst=6081, geneve({class=0x102,type=0x7,len=4,0x3}),flags(df|key))),5 VMWare-BZ: 2617696 Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
- Loading branch information