multipath: Correctly calculate number of required destination bits.
authorBen Pfaff <blp@nicira.com>
Tue, 27 Dec 2011 21:37:43 +0000 (13:37 -0800)
committerBen Pfaff <blp@nicira.com>
Fri, 13 Jan 2012 00:51:29 +0000 (16:51 -0800)
The previous calculation was wrong when n_links was a power of 2.

Reported-by: Paul Ingram <paul@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/multipath.c
lib/util.c
lib/util.h

index 80d801d671c61615a89cfe404a36cb03c7a1fb77..51758033d040ff7dd7740a2506ba238738131efc 100644 (file)
@@ -38,7 +38,7 @@ enum ofperr
 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);
     enum ofperr error;
index e02f59fb0a0af60d4a71b3c66d297badc86aa924..8379c9ac5e9f99d214e6171ab2ea30b4f8cbe5f8 100644 (file)
@@ -664,6 +664,14 @@ log_2_floor(uint32_t n)
 #endif
 }
 
+/* Given a 32 bit word 'n', calculates ceil(log_2('n')).  It is an error to
+ * call this function with 'n' == 0. */
+int
+log_2_ceil(uint32_t n)
+{
+    return log_2_floor(n) + !IS_POW2(n);
+}
+
 /* Returns the number of trailing 0-bits in 'n', or 32 if 'n' is 0. */
 int
 ctz(uint32_t n)
index 61039be8182f8c60abd55a730076e98bfb95d8ed..b2052f364e0f84f8b7405e396e79c463c20202f2 100644 (file)
@@ -203,6 +203,7 @@ char *abs_file_name(const char *dir, const char *file_name);
 
 void ignore(bool x OVS_UNUSED);
 int log_2_floor(uint32_t);
+int log_2_ceil(uint32_t);
 int ctz(uint32_t);
 
 bool is_all_zeros(const uint8_t *, size_t);