From 300c69464ca88ca97d4ce842b590ce6ce603201b Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 27 Dec 2011 13:37:43 -0800 Subject: [PATCH] multipath: Correctly calculate number of required destination bits. The previous calculation was wrong when n_links was a power of 2. Reported-by: Paul Ingram Signed-off-by: Ben Pfaff --- lib/multipath.c | 2 +- lib/util.c | 8 ++++++++ lib/util.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/multipath.c b/lib/multipath.c index 80d801d6..51758033 100644 --- a/lib/multipath.c +++ b/lib/multipath.c @@ -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; diff --git a/lib/util.c b/lib/util.c index e02f59fb..8379c9ac 100644 --- a/lib/util.c +++ b/lib/util.c @@ -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) diff --git a/lib/util.h b/lib/util.h index 61039be8..b2052f36 100644 --- a/lib/util.h +++ b/lib/util.h @@ -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); -- 2.30.2