odp-util: Make sure vlan tci mask has exact match for VLAN_CFI.
authorAlex Wang <alexw@nicira.com>
Sun, 7 Jun 2015 18:38:52 +0000 (11:38 -0700)
committerAlex Wang <alexw@nicira.com>
Sun, 7 Jun 2015 19:09:37 +0000 (12:09 -0700)
OVS datapath has check which prevents the installation of flow
that matches VLAN TCI but does not have exact match for VLAN_CFI
bit.  To follow this rule, ovs userspace must make sure the
flow key for datapath flow matching VLAN TCI has exact match for
VLAN_CFI bit.

Before this commit, this is not enforced, so OpenFlow flow like
"vlan_tci=0x000a/0x0fff,action=output:local" can generate datapath
flow like "vlan(vid=10/0xfff,pcp=0/0x0,cfi=1/0)".

With the OVS datapath check, the installation of such datapath
flow will be rejected with:
"|WARN|system@ovs-system: failed to put[create][modify] (Invalid argument)"

This commit makes ovs userspace always exact match the VLAN_CFI
bit if the flow matches VLAN TCI.

Reported-by: Ronald Lee <ronaldlee@vmware.com>
Signed-off-by: Alex Wang <alexw@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
ofproto/ofproto-dpif-xlate.c
tests/ofproto-dpif.at

index c5dc9e8..028e7e0 100644 (file)
@@ -3574,6 +3574,7 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out *xout)
     ofpbuf_uninit(&ctx.stack);
     ofpbuf_uninit(&ctx.action_set);
 
+
     /* Clear the metadata and register wildcard masks, because we won't
      * use non-header fields as part of the cache. */
     flow_wildcards_clear_non_packet_fields(wc);
@@ -3592,6 +3593,10 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out *xout)
         wc->masks.tp_src &= htons(UINT8_MAX);
         wc->masks.tp_dst &= htons(UINT8_MAX);
     }
+    /* VLAN_TCI CFI bit must be matched if any of the TCI is matched. */
+    if (wc->masks.vlan_tci) {
+        wc->masks.vlan_tci |= htons(VLAN_CFI);
+    }
 }
 
 /* Sends 'packet' out 'ofport'.
index 50e820f..d350b40 100644 (file)
@@ -4782,3 +4782,20 @@ icmp6,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=00:00:86:05:80:da,dl_dst=00:60
 
 OVS_VSWITCHD_STOP
 AT_CLEANUP
+
+# Tests the exact match of CFI bit in installed datapath flows matching VLAN.
+AT_SETUP([ofproto-dpif - vlan matching])
+OVS_VSWITCHD_START(
+  [add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1])
+AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
+
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_CHECK([ovs-ofctl add-flow br0 "vlan_tci=0x000a/0x0fff,action=output:local"])
+
+AT_CHECK([ovs-appctl netdev-dummy/receive p0 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x8100),vlan(vid=10,pcp=0),encap(eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0))'])
+
+AT_CHECK([cat ovs-vswitchd.log | grep 'in_port(1)' | FILTER_FLOW_INSTALL | STRIP_XOUT], [0], [dnl
+skb_priority(0),skb_mark(0/0),in_port(1),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x8100),vlan(vid=10/0xfff,pcp=0/0x0,cfi=1/1),encap(eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0xff),icmp(type=8/0,code=0/0)), actions: <del>
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP