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=5/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 <ronald...@vmware.com> Signed-off-by: Alex Wang <al...@nicira.com> --- lib/odp-util.c | 6 +++++- tests/ofproto-dpif.at | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/odp-util.c b/lib/odp-util.c index 3204d16..63f2660 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -3486,10 +3486,14 @@ odp_flow_key_from_flow__(struct ofpbuf *buf, const struct flow *flow, if (flow->vlan_tci != htons(0) || flow->dl_type == htons(ETH_TYPE_VLAN)) { if (export_mask) { nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, OVS_BE16_MAX); + /* When there is a VLAN, the VLAN match must always include match + * on "present" bit. */ + nl_msg_put_be16(buf, OVS_KEY_ATTR_VLAN, + data->vlan_tci | htons(VLAN_CFI)); } else { nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, htons(ETH_TYPE_VLAN)); + nl_msg_put_be16(buf, OVS_KEY_ATTR_VLAN, data->vlan_tci); } - nl_msg_put_be16(buf, OVS_KEY_ATTR_VLAN, data->vlan_tci); encap = nl_msg_start_nested(buf, OVS_KEY_ATTR_ENCAP); if (flow->vlan_tci == htons(0)) { goto unencap; diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index b5a9ad9..ec885a5 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -6673,3 +6673,19 @@ icmp6,vlan_tci=0x0000,dl_src=00:00:86:05:80:da,dl_dst=00:60:97:07:69:ea,ipv6_src 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 +recirc_id=0,ip,in_port=1,vlan_tci=0x100a/0x0fff,nw_frag=no, actions: <del> +]) +OVS_VSWITCHD_STOP +AT_CLEANUP \ No newline at end of file -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev