OXM: Allow masking of IPv6 Flow Label
[openvswitch] / lib / nx-match.c
index 3e3b4c69b1b3d547cd7b5739d55398d71f095554..3d017c6a36bc95a81d6357d13bf9248290c7f124 100644 (file)
@@ -67,7 +67,8 @@ nx_entry_ok(const void *p, unsigned int match_len)
 
     if (match_len < 4) {
         if (match_len) {
-            VLOG_DBG_RL(&rl, "nx_match ends with partial nxm_header");
+            VLOG_DBG_RL(&rl, "nx_match ends with partial (%u-byte) nxm_header",
+                        match_len);
         }
         return 0;
     }
@@ -99,6 +100,14 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
 
     assert((cookie != NULL) == (cookie_mask != NULL));
 
+    cls_rule_init_catchall(rule, priority);
+    if (cookie) {
+        *cookie = *cookie_mask = htonll(0);
+    }
+    if (!match_len) {
+        return 0;
+    }
+
     p = ofpbuf_try_pull(b, ROUND_UP(match_len, 8));
     if (!p) {
         VLOG_DBG_RL(&rl, "nx_match length %u, rounded up to a "
@@ -107,10 +116,6 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
         return OFPERR_OFPBMC_BAD_LEN;
     }
 
-    cls_rule_init_catchall(rule, priority);
-    if (cookie) {
-        *cookie = *cookie_mask = htonll(0);
-    }
     for (;
          (header = nx_entry_ok(p, match_len)) != 0;
          p += 4 + NXM_LENGTH(header), match_len -= 4 + NXM_LENGTH(header)) {
@@ -488,7 +493,7 @@ nx_put_match(struct ofpbuf *b, bool oxm, const struct cls_rule *cr,
     int match_len;
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 12);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 13);
 
     /* Metadata. */
     if (!(wc & FWW_IN_PORT)) {
@@ -535,10 +540,8 @@ nx_put_match(struct ofpbuf *b, bool oxm, const struct cls_rule *cr,
                    oxm ? OXM_OF_ICMPV6_TYPE : NXM_NX_ICMPV6_TYPE,
                    oxm ? OXM_OF_ICMPV6_CODE : NXM_NX_ICMPV6_CODE, oxm);
 
-        if (!(wc & FWW_IPV6_LABEL)) {
-            nxm_put_32(b, oxm ? OXM_OF_IPV6_FLABEL : NXM_NX_IPV6_LABEL,
-                       flow->ipv6_label);
-        }
+        nxm_put_32m(b, oxm ? OXM_OF_IPV6_FLABEL : NXM_NX_IPV6_LABEL,
+                    flow->ipv6_label, cr->wc.ipv6_label_mask);
 
         if (flow->nw_proto == IPPROTO_ICMPV6
             && (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) ||