]> git.proxmox.com Git - ovs.git/commitdiff
ofproto-dpif: Reject partial ct_labels if unsupported.
authorJoe Stringer <joestringer@nicira.com>
Wed, 11 Nov 2015 19:39:49 +0000 (11:39 -0800)
committerJoe Stringer <joestringer@nicira.com>
Tue, 1 Dec 2015 23:29:00 +0000 (15:29 -0800)
If only half of a ct_label is present in a miniflow/minimask (eg, only
matching on one specific bit), then rule_check() would allow the flow
even if ct_label was unsupported, because it required both 64-bit fields
that comprise the ct_label to be present in the miniflow before
performing the check.

Fix this by populating the stack copy of the label directly from the
miniflow fields if available (or zero each 64-bit word if unavailable).

Suggested-by: Jarno Rajahalme <jrajahalme@nicira.com>
Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Jarno Rajahalme <jarno@ovn.org>
lib/flow.h
ofproto/ofproto-dpif.c

index 7be03adba6ccc86a1861f35f4f2c8736cafdec14..5d78615a41990b532c2acf23002855c0cc78ece8 100644 (file)
@@ -788,14 +788,12 @@ miniflow_get__(const struct miniflow *mf, size_t idx)
      [FLOW_U64_OFFREM(FIELD) / sizeof(TYPE)]                            \
      : 0)
 
-/* Get a pointer to the ovs_u128 value of struct flow 'FIELD' from miniflow
- * 'FLOW'. */
-#define MINIFLOW_GET_U128_PTR(FLOW, FIELD)                              \
-    ((MINIFLOW_IN_MAP(FLOW, FLOW_U64_OFFSET(FIELD))                     \
-      && (MINIFLOW_IN_MAP(FLOW, FLOW_U64_OFFSET(FIELD) + 1)))           \
-     ? &((OVS_FORCE const ovs_u128 *)miniflow_get__(FLOW, FLOW_U64_OFFSET(FIELD))) \
-     [FLOW_U64_OFFREM(FIELD) / sizeof(ovs_u128)]                        \
-     : NULL)
+#define MINIFLOW_GET_U128(FLOW, FIELD)                                  \
+    (ovs_u128) { .u64 = {                                               \
+            (MINIFLOW_IN_MAP(FLOW, FLOW_U64_OFFSET(FIELD)) ?            \
+             *miniflow_get__(FLOW, FLOW_U64_OFFSET(FIELD)) : 0),        \
+            (MINIFLOW_IN_MAP(FLOW, FLOW_U64_OFFSET(FIELD) + 1) ?        \
+             *miniflow_get__(FLOW, FLOW_U64_OFFSET(FIELD) + 1) : 0) } }
 
 #define MINIFLOW_GET_U8(FLOW, FIELD)            \
     MINIFLOW_GET_TYPE(FLOW, uint8_t, FIELD)
index 3d41d11b428b91172f36740d0b0c5182fcd51c41..37c5d5da07f8b3ddb3c24f9607c236d897691cd5 100644 (file)
@@ -4016,17 +4016,13 @@ static enum ofperr
 rule_check(struct rule *rule)
 {
     uint16_t ct_state, ct_zone;
-    const ovs_u128 *labelp;
-    ovs_u128 ct_label = { { 0, 0 } };
+    ovs_u128 ct_label;
     uint32_t ct_mark;
 
     ct_state = MINIFLOW_GET_U16(rule->cr.match.flow, ct_state);
     ct_zone = MINIFLOW_GET_U16(rule->cr.match.flow, ct_zone);
     ct_mark = MINIFLOW_GET_U32(rule->cr.match.flow, ct_mark);
-    labelp = MINIFLOW_GET_U128_PTR(rule->cr.match.flow, ct_label);
-    if (labelp) {
-        ct_label = *labelp;
-    }
+    ct_label = MINIFLOW_GET_U128(rule->cr.match.flow, ct_label);
 
     if (ct_state || ct_zone || ct_mark
         || !ovs_u128_is_zero(&ct_label)) {