meta-flow: Correctly set destination MAC in mf_set_flow_value().
[sliver-openvswitch.git] / lib / multipath.c
index 9684556..adc000d 100644 (file)
@@ -37,10 +37,12 @@ int
 multipath_check(const struct nx_action_multipath *mp, const struct flow *flow)
 {
     uint32_t n_links = ntohs(mp->max_link) + 1;
-    size_t min_n_bits = log_2_floor(n_links) + 1;
+    size_t min_n_bits = log_2_ceil(n_links);
+    int ofs = nxm_decode_ofs(mp->ofs_nbits);
+    int n_bits = nxm_decode_n_bits(mp->ofs_nbits);
     int error;
 
-    error = nxm_dst_check(mp->dst, mp->ofs_nbits, min_n_bits, flow);
+    error = nxm_dst_check(mp->dst, ofs, n_bits, flow);
     if (error) {
         return error;
     }
@@ -53,6 +55,9 @@ multipath_check(const struct nx_action_multipath *mp, const struct flow *flow)
                && mp->algorithm != htons(NX_MP_ALG_ITER_HASH)) {
         VLOG_WARN_RL(&rl, "unsupported algorithm %"PRIu16,
                      ntohs(mp->algorithm));
+    } else if (n_bits < min_n_bits) {
+        VLOG_WARN_RL(&rl, "multipath action requires at least %zu bits for "
+                     "%"PRIu32" links", min_n_bits, n_links);
     } else {
         return 0;
     }
@@ -175,11 +180,7 @@ multipath_parse(struct nx_action_multipath *mp, const char *s_)
         ovs_fatal(0, "%s: not enough arguments to multipath action", s_);
     }
 
-    memset(mp, 0, sizeof *mp);
-    mp->type = htons(OFPAT_VENDOR);
-    mp->len = htons(sizeof *mp);
-    mp->vendor = htonl(NX_VENDOR_ID);
-    mp->subtype = htons(NXAST_MULTIPATH);
+    ofputil_init_NXAST_MULTIPATH(mp);
     if (!strcasecmp(fields, "eth_src")) {
         mp->fields = htons(NX_HASH_FIELDS_ETH_SRC);
     } else if (!strcasecmp(fields, "symmetric_l4")) {