[ovs-dev] [PATCH 1/6] classifier: Honour CFI bit internally

Simon Horman horms at verge.net.au
Mon Jul 23 02:36:41 UTC 2012


In preparation for supporting the OpenFlow 1.2 VLAN_VID and VLAN_PCP
matches, internally honour the CFI bit and add come special cases
to provide backwards-compatible behaviour for ovs-ofputil add-flows dl_vlan.

Signed-off-by: Simon Horman <horms at verge.net.au>
---
 lib/classifier.c | 14 +-------------
 lib/flow.c       | 13 +++++--------
 lib/ofp-parse.c  | 20 ++++++++++++++++++++
 lib/packets.h    |  1 +
 4 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/lib/classifier.c b/lib/classifier.c
index 33245ae..d1adce6 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -255,23 +255,11 @@ cls_rule_set_any_vid(struct cls_rule *rule)
     }
 }
 
-/* Modifies 'rule' depending on 'dl_vlan':
- *
- *   - If 'dl_vlan' is htons(OFP_VLAN_NONE), makes 'rule' match only packets
- *     without an 802.1Q header.
- *
- *   - Otherwise, makes 'rule' match only packets with an 802.1Q header whose
- *     VID equals the low 12 bits of 'dl_vlan'.
- */
 void
 cls_rule_set_dl_vlan(struct cls_rule *rule, ovs_be16 dl_vlan)
 {
     flow_set_vlan_vid(&rule->flow, dl_vlan);
-    if (dl_vlan == htons(OFP10_VLAN_NONE)) {
-        rule->wc.vlan_tci_mask = htons(UINT16_MAX);
-    } else {
-        rule->wc.vlan_tci_mask |= htons(VLAN_VID_MASK | VLAN_CFI);
-    }
+    rule->wc.vlan_tci_mask |= htons(VLAN_VID_MASK | VLAN_CFI);
 }
 
 /* Modifies 'rule' so that the VLAN PCP is wildcarded.  If the VID is already
diff --git a/lib/flow.c b/lib/flow.c
index 5ba3e10..07f1aa0 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -970,13 +970,9 @@ flow_hash_fields_valid(enum nx_hash_fields fields)
 void
 flow_set_vlan_vid(struct flow *flow, ovs_be16 vid)
 {
-    if (vid == htons(OFP10_VLAN_NONE)) {
-        flow->vlan_tci = htons(0);
-    } else {
-        vid &= htons(VLAN_VID_MASK);
-        flow->vlan_tci &= ~htons(VLAN_VID_MASK);
-        flow->vlan_tci |= htons(VLAN_CFI) | vid;
-    }
+    ovs_be16 mask = htons(VLAN_VID_MASK | VLAN_CFI);
+    flow->vlan_tci &= ~mask;
+    flow->vlan_tci |= vid & mask;
 }
 
 /* Sets the VLAN PCP that 'flow' matches to 'pcp', which should be in the
@@ -989,9 +985,10 @@ flow_set_vlan_vid(struct flow *flow, ovs_be16 vid)
 void
 flow_set_vlan_pcp(struct flow *flow, uint8_t pcp)
 {
+    uint16_t cfi = (pcp & VLAN_PCP_SET_CFI_FLAG) ? VLAN_CFI : 0;
     pcp &= 0x07;
     flow->vlan_tci &= ~htons(VLAN_PCP_MASK);
-    flow->vlan_tci |= htons((pcp << VLAN_PCP_SHIFT) | VLAN_CFI);
+    flow->vlan_tci |= htons((pcp << VLAN_PCP_SHIFT) | cfi);
 }
 
 /* Puts into 'b' a packet that flow_extract() would parse as having the given
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 32d3836..1df3275 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -528,6 +528,26 @@ parse_field(const struct mf_field *mf, const char *s, struct cls_rule *rule)
         ovs_fatal(0, "%s", error);
     }
 
+    if (mf->id == MFF_VLAN_VID) {
+        /* Provide backwards compatibility for ovs-ofctl to set 'dl_vlan'
+         * via code that supports OpenFlow 1.2 VLAN_VID. */
+        if (value.be16 == htons(OFP10_VLAN_NONE)) {
+            /* Special case for OFP10_VLAN_NONE, map to OFPVID12_NONE
+             * which provides the desired behaviour. */
+            value.be16 = htons(OFPVID12_NONE);
+        } else {
+            /* Else, ensure the CFI bit set set */
+            value.be16 |= htons(VLAN_CFI);
+        }
+    }
+    else if (mf->id == MFF_VLAN_PCP) {
+        /* Provide backwards compatibility for ovs-ofctl to set * 'dl_vlan_pcp'
+         * via code that supports OpenFlow 1.2 VLAN_PCP.
+         * Set the most significant bit, which is otherwise unused,
+         * to indicate that the CFI bit should be set internally */
+        value.u8 |= VLAN_PCP_SET_CFI_FLAG;
+    }
+
     mf_set(mf, &value, &mask, rule);
 }
 
diff --git a/lib/packets.h b/lib/packets.h
index ad5631d..8fb6d4b 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -255,6 +255,7 @@ BUILD_ASSERT_DECL(RARP_HEADER_LEN == sizeof(struct rarp_header));
 #define VLAN_PCP_SHIFT 13
 
 #define VLAN_CFI 0x1000
+#define VLAN_PCP_SET_CFI_FLAG 0x8
 
 /* Given the vlan_tci field from an 802.1Q header, in network byte order,
  * returns the VLAN ID in host byte order. */
-- 
1.7.10.2.484.gcd07cc5




More information about the dev mailing list