nicira-ext: Support masking of nd_target field
[sliver-openvswitch.git] / lib / nx-match.c
index 66f8ea2..91dd7fc 100644 (file)
@@ -103,7 +103,7 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
         VLOG_DBG_RL(&rl, "nx_match length %u, rounded up to a "
                     "multiple of 8, is longer than space in message (max "
                     "length %zu)", match_len, b->size);
-        return OFPERR_OFPBRC_BAD_LEN;
+        return OFPERR_OFPBMC_BAD_LEN;
     }
 
     cls_rule_init_catchall(rule, priority);
@@ -119,21 +119,21 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
         mf = mf_from_nxm_header(header);
         if (!mf) {
             if (strict) {
-                error = OFPERR_NXBRC_NXM_BAD_TYPE;
+                error = OFPERR_OFPBMC_BAD_FIELD;
             } else {
                 continue;
             }
         } else if (!mf_are_prereqs_ok(mf, &rule->flow)) {
-            error = OFPERR_NXBRC_NXM_BAD_PREREQ;
+            error = OFPERR_OFPBMC_BAD_PREREQ;
         } else if (!mf_is_all_wild(mf, &rule->wc)) {
-            error = OFPERR_NXBRC_NXM_DUP_TYPE;
+            error = OFPERR_OFPBMC_DUP_FIELD;
         } else {
             unsigned int width = mf->n_bytes;
             union mf_value value;
 
             memcpy(&value, p + 4, width);
             if (!mf_is_value_valid(mf, &value)) {
-                error = OFPERR_NXBRC_NXM_BAD_VALUE;
+                error = OFPERR_OFPBMC_BAD_VALUE;
             } else if (!NXM_HASMASK(header)) {
                 error = 0;
                 mf_set_value(mf, &value, rule);
@@ -142,7 +142,7 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
 
                 memcpy(&mask, p + 4 + width, width);
                 if (!mf_is_mask_valid(mf, &mask)) {
-                    error = OFPERR_NXBRC_NXM_BAD_MASK;
+                    error = OFPERR_OFPBMC_BAD_MASK;
                 } else {
                     error = 0;
                     mf_set(mf, &value, &mask, rule);
@@ -153,7 +153,7 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
         /* Check if the match is for a cookie rather than a classifier rule. */
         if ((header == NXM_NX_COOKIE || header == NXM_NX_COOKIE_W) && cookie) {
             if (*cookie_mask) {
-                error = OFPERR_NXBRC_NXM_DUP_TYPE;
+                error = OFPERR_OFPBMC_DUP_FIELD;
             } else {
                 unsigned int width = sizeof *cookie;
 
@@ -178,7 +178,7 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
         }
     }
 
-    return match_len ? OFPERR_NXBRC_NXM_INVALID : 0;
+    return match_len ? OFPERR_OFPBMC_BAD_LEN : 0;
 }
 
 /* Parses the nx_match formatted match description in 'b' with length
@@ -433,24 +433,16 @@ nxm_put_ip(struct ofpbuf *b, const struct cls_rule *cr,
         nxm_put_8(b, NXM_OF_IP_PROTO, flow->nw_proto);
 
         if (flow->nw_proto == IPPROTO_TCP) {
-            if (!(wc & FWW_TP_SRC)) {
-                nxm_put_16(b, NXM_OF_TCP_SRC, flow->tp_src);
-            }
-            if (!(wc & FWW_TP_DST)) {
-                nxm_put_16(b, NXM_OF_TCP_DST, flow->tp_dst);
-            }
+            nxm_put_16m(b, NXM_OF_TCP_SRC, flow->tp_src, cr->wc.tp_src_mask);
+            nxm_put_16m(b, NXM_OF_TCP_DST, flow->tp_dst, cr->wc.tp_dst_mask);
         } else if (flow->nw_proto == IPPROTO_UDP) {
-            if (!(wc & FWW_TP_SRC)) {
-                nxm_put_16(b, NXM_OF_UDP_SRC, flow->tp_src);
-            }
-            if (!(wc & FWW_TP_DST)) {
-                nxm_put_16(b, NXM_OF_UDP_DST, flow->tp_dst);
-            }
+            nxm_put_16m(b, NXM_OF_UDP_SRC, flow->tp_src, cr->wc.tp_src_mask);
+            nxm_put_16m(b, NXM_OF_UDP_DST, flow->tp_dst, cr->wc.tp_dst_mask);
         } else if (flow->nw_proto == icmp_proto) {
-            if (!(wc & FWW_TP_SRC)) {
+            if (cr->wc.tp_src_mask) {
                 nxm_put_8(b, icmp_type, ntohs(flow->tp_src));
             }
-            if (!(wc & FWW_TP_DST)) {
+            if (cr->wc.tp_dst_mask) {
                 nxm_put_8(b, icmp_code, ntohs(flow->tp_dst));
             }
         }
@@ -479,7 +471,7 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr,
     int match_len;
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
 
     /* Metadata. */
     if (!(wc & FWW_IN_PORT)) {
@@ -522,10 +514,8 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr,
         if (flow->nw_proto == IPPROTO_ICMPV6
             && (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) ||
                 flow->tp_src == htons(ND_NEIGHBOR_ADVERT))) {
-            if (!(wc & FWW_ND_TARGET)) {
-                nxm_put_ipv6(b, NXM_NX_ND_TARGET, &flow->nd_target,
-                             &in6addr_exact);
-            }
+            nxm_put_ipv6(b, NXM_NX_ND_TARGET, &flow->nd_target,
+                         &cr->wc.nd_target_mask);
             if (!(wc & FWW_ARP_SHA)
                 && flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) {
                 nxm_put_eth(b, NXM_NX_ND_SLL, flow->arp_sha);