diff options
author | Dan Geist <dan@polter.net> | 2024-03-13 11:24:05 -0400 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2024-04-02 06:56:04 +0000 |
commit | e53e29684151330811777135be2d62a564e3664d (patch) | |
tree | b6ffcb4079b98c674a25b3041328f8810938fce5 /src/plugins/map/lpm.c | |
parent | 3a0d7d2c95e8b8087c20b99fed5bcf62fac027d9 (diff) |
map: BR rule lookup update
Update to the MAP rule lookup (in IPv6) based on the rule's source
prefix instead of DMR
Type: improvement
Per RFC, the DMR is allowed to serve multiple MAP Basic Mapping Rules, but this
capability was prevented by the above logic.
Updates to the code include populating a new hash table based on the MAP rule
ip6 prefix and length, changing several functions to reference this new table,
and slight alterations to a few functions regarding pre-lookup bitmasking.
All changes are commented with [dgeist] and are in need of peer review,
especially the bitmask alterations.
An attempt was made at generating an additonal MAP rule in the test_map_br test
harness, but the coding appears very much oriented towards testing just one
rule. I would appreciate suggestions on how to test multi-rule cases.
Issue: VPP-2111
Change-Id: Id1fea280eba625e23cd893575d9b63aac7f48405
Signed-off-by: Dan Geist <dan@polter.net>
Diffstat (limited to 'src/plugins/map/lpm.c')
-rw-r--r-- | src/plugins/map/lpm.c | 28 |
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); } } |