aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Geist <dan@polter.net>2024-03-13 11:24:05 -0400
committerOle Tr�an <otroan@employees.org>2024-04-02 06:56:04 +0000
commite53e29684151330811777135be2d62a564e3664d (patch)
treeb6ffcb4079b98c674a25b3041328f8810938fce5
parent3a0d7d2c95e8b8087c20b99fed5bcf62fac027d9 (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>
-rw-r--r--src/plugins/map/ip6_map_t.c5
-rw-r--r--src/plugins/map/lpm.c28
-rw-r--r--src/plugins/map/map.c7
-rw-r--r--src/plugins/map/map.h6
4 files changed, 39 insertions, 7 deletions
diff --git a/src/plugins/map/ip6_map_t.c b/src/plugins/map/ip6_map_t.c
index 6bfc8e0f952..51853d619e6 100644
--- a/src/plugins/map/ip6_map_t.c
+++ b/src/plugins/map/ip6_map_t.c
@@ -529,7 +529,10 @@ ip6_map_t (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
ip60 = vlib_buffer_get_current (p0);
d0 =
- ip6_map_get_domain (&ip60->dst_address,
+ /* Originally using the IPv6 dest for rule lookup, now source
+ * [dgeist] ip6_map_get_domain (&ip60->dst_address,
+ */
+ ip6_map_get_domain (&ip60->src_address,
&vnet_buffer (p0)->map_t.map_domain_index,
&error0);
if (!d0)
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);
}
}
diff --git a/src/plugins/map/map.c b/src/plugins/map/map.c
index 6c9668dde51..3cffadd39e8 100644
--- a/src/plugins/map/map.c
+++ b/src/plugins/map/map.c
@@ -176,6 +176,10 @@ map_create_domain (ip4_address_t * ip4_prefix,
mm->ip6_src_prefix_tbl->add (mm->ip6_src_prefix_tbl, &d->ip6_src,
d->ip6_src_len, *map_domain_index);
+ /* Let's build a table with the MAP rule ip6 prefixes as well [dgeist] */
+ mm->ip6_prefix_tbl->add (mm->ip6_prefix_tbl, &d->ip6_prefix,
+ d->ip6_prefix_len, *map_domain_index);
+
/* Validate packet/byte counters */
map_domain_counter_lock (mm);
int i;
@@ -218,6 +222,9 @@ map_delete_domain (u32 map_domain_index)
d->ip4_prefix_len);
mm->ip6_src_prefix_tbl->delete (mm->ip6_src_prefix_tbl, &d->ip6_src,
d->ip6_src_len);
+ /* Addition to remove the new table [dgeist] */
+ mm->ip6_prefix_tbl->delete (mm->ip6_prefix_tbl, &d->ip6_prefix,
+ d->ip6_prefix_len);
/* Release user-assigned MAP domain name. */
map_free_extras (map_domain_index);
diff --git a/src/plugins/map/map.h b/src/plugins/map/map.h
index d874aa47b3a..86b8ec22df4 100644
--- a/src/plugins/map/map.h
+++ b/src/plugins/map/map.h
@@ -335,7 +335,11 @@ ip6_map_get_domain (ip6_address_t * addr, u32 * map_domain_index, u8 * error)
{
map_main_t *mm = &map_main;
u32 mdi =
- mm->ip6_src_prefix_tbl->lookup (mm->ip6_src_prefix_tbl, addr, 128);
+ /* This is the old src (ip6 destination) hash lookup [dgeist]
+ *
+ * mm->ip6_src_prefix_tbl->lookup (mm->ip6_src_prefix_tbl, addr, 128);
+ */
+ mm->ip6_prefix_tbl->lookup (mm->ip6_prefix_tbl, addr, 128);
if (mdi == ~0)
{
*error = MAP_ERROR_NO_DOMAIN;