aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/map/lpm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/map/lpm.c')
-rw-r--r--src/plugins/map/lpm.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/plugins/map/lpm.c b/src/plugins/map/lpm.c
index c0e5bad1417..a2fc3337167 100644
--- a/src/plugins/map/lpm.c
+++ b/src/plugins/map/lpm.c
@@ -28,7 +28,13 @@ masked_address32 (uint32_t addr, uint8_t len)
static uint64_t
masked_address64 (uint64_t addr, uint8_t len)
{
- return len == 64 ? addr : addr & ~(~0ull >> len);
+ /* This was originally causing non-64-bit masks to not match due to LSB vs
+ * MSB masking (0s at the head of the value) Probably needs some corner case
+ * checking in case my masking logic was off [dgeist]
+ *
+ * return len == 64 ? addr : addr & ~(~0ull >> len);
+ */
+ return len == 64 ? addr : addr & ((1ull << (len)) - 1);
}
static void
@@ -126,13 +132,25 @@ lpm_128_add (lpm_t *lpm, void *addr_v, u8 pfxlen, u32 value)
BVT(clib_bihash_kv) kv;
ip6_address_t *addr = addr_v;
- kv.key[0] = masked_address64(addr->as_u64[0], pfxlen > 64 ? 64 : pfxlen);
+ /* This is a quick hack. It works for pfxlen < 64 but needs validation for
+ * other [dgeist]
+ *
+ * kv.key[0] = masked_address64(addr->as_u64[0], pfxlen > 64 ? 64 : pfxlen);
+ */
+ kv.key[0] = masked_address64 (addr->as_u64[0], pfxlen > 64 ? 64 : 64);
kv.key[1] = masked_address64(addr->as_u64[1], pfxlen > 64 ? pfxlen - 64 : 0);
kv.key[2] = pfxlen;
kv.value = value;
BV(clib_bihash_add_del)(&lpm->bihash, &kv, 1);
lpm->prefix_length_refcount[pfxlen]++;
- lpm->prefix_lengths_bitmap = clib_bitmap_set (lpm->prefix_lengths_bitmap, 128 - pfxlen, 1);
+ /* Populating the lengths bitmap table with prefix of 48 instead of 80
+ * (128 - 48) [dgeist]
+ *
+ * lpm->prefix_lengths_bitmap = clib_bitmap_set (
+ * lpm->prefix_lengths_bitmap, 128 - pfxlen, 1);
+ */
+ lpm->prefix_lengths_bitmap = clib_bitmap_set (
+ lpm->prefix_lengths_bitmap, pfxlen > 64 ? 128 - pfxlen : pfxlen, 1);
}
static void
@@ -148,8 +166,8 @@ lpm_128_delete (lpm_t *lpm, void *addr_v, u8 pfxlen)
/* refcount accounting */
ASSERT (lpm->prefix_length_refcount[pfxlen] > 0);
if (--lpm->prefix_length_refcount[pfxlen] == 0) {
- lpm->prefix_lengths_bitmap = clib_bitmap_set (lpm->prefix_lengths_bitmap,
- 128 - pfxlen, 0);
+ lpm->prefix_lengths_bitmap =
+ clib_bitmap_set (lpm->prefix_lengths_bitmap, 128 - pfxlen, 0);
}
}