[ovs-dev] [PATCH 4/6] OXM: Add special case for VLAN VID == OFPVID12_NONE

Simon Horman horms at verge.net.au
Thu Jul 5 08:27:30 UTC 2012


OpenFlow 1.2 specifies that a VLAN VID value of OFPVID12_NONE and
no mask should match only packets without a VLAN tag. This is the
same behaviour provided when calling mf_set_value for VLAN VID with
a value of OFP10_VLAN_NONE.

Signed-off-by: Simon Horman <horms at verge.net.au>
---
 lib/nx-match.c     | 27 ++++++++++++++++++---------
 tests/ovs-ofctl.at |  4 ++++
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/lib/nx-match.c b/lib/nx-match.c
index e2fc76c..8e2c645 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -135,18 +135,27 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
             memcpy(&value, p + 4, width);
             if (!mf_is_value_valid(mf, &value)) {
                 error = OFPERR_OFPBMC_BAD_VALUE;
-            } else if (!NXM_HASMASK(header)) {
-                error = 0;
-                mf_set_value(mf, &value, rule);
             } else {
-                union mf_value mask;
+                if ((header == OXM_OF_VLAN_VID || header == OXM_OF_VLAN_VID_W)
+                    && !(value.be16 & htons(VLAN_CFI))) {
+                    /* Special case for CFI not set, map to OFP10_VLAN_NONE
+                     * which provides the desired behaviour. */
+                    value.be16 = htons(OFP10_VLAN_NONE);
+                }
 
-                memcpy(&mask, p + 4 + width, width);
-                if (!mf_is_mask_valid(mf, &mask)) {
-                    error = OFPERR_OFPBMC_BAD_MASK;
-                } else {
+                if (!NXM_HASMASK(header)) {
                     error = 0;
-                    mf_set(mf, &value, &mask, rule);
+                    mf_set_value(mf, &value, rule);
+                } else {
+                    union mf_value mask;
+
+                    memcpy(&mask, p + 4 + width, width);
+                    if (!mf_is_mask_valid(mf, &mask)) {
+                        error = OFPERR_OFPBMC_BAD_MASK;
+                    } else {
+                        error = 0;
+                        mf_set(mf, &value, &mask, rule);
+                    }
                 }
             }
         } else {
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index bc20e98..7ef2992 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -1018,8 +1018,10 @@ OXM_OF_ETH_TYPE(0800) OXM_OF_IN_PORT(00000012)
 # vlan
 OXM_OF_VLAN_VID(1009) OXM_OF_VLAN_VID(1009) # Duplicate Field
 OXM_OF_VLAN_VID(f009)           # Bad Value
+OXM_OF_VLAN_VID(0000)           # Packets without 802.1Q header or with VID=0
 OXM_OF_VLAN_VID(1123)           # Packets with VID=123, any PCP
 OXM_OF_VLAN_VID(1123) OXM_OF_VLAN_PCP(01) # Packets with VID=123, PCP=1.
+OXM_OF_VLAN_VID(0123)           # Does not make sense (but supported anyway)
 
 # IP ECN
 OXM_OF_ETH_TYPE(0800) OXM_OF_IP_ECN(03)
@@ -1160,8 +1162,10 @@ OXM_OF_IN_PORT(00000012), OXM_OF_ETH_TYPE(0800)
 # vlan
 nx_pull_match() returned error OFPBMC_DUP_FIELD
 nx_pull_match() returned error OFPBMC_BAD_VALUE
+OXM_OF_VLAN_VID(0000)
 OXM_OF_VLAN_VID(1123)
 OXM_OF_VLAN_VID(1123), OXM_OF_VLAN_PCP(01)
+OXM_OF_VLAN_VID(0000)
 
 # IP ECN
 OXM_OF_ETH_TYPE(0800), OXM_OF_IP_ECN(03)
-- 
1.7.10.2.484.gcd07cc5




More information about the dev mailing list