aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/map/map.c
diff options
context:
space:
mode:
authorJon Loeliger <jdl@netgate.com>2019-03-12 13:09:08 -0500
committerOle Trøan <otroan@employees.org>2019-03-19 20:44:34 +0000
commit4dc5c7b905d9ccfa24f6fd7365a7d656c3efaa78 (patch)
tree39e02ddb7f5a4275680ed6f3623af512a87b3f28 /src/plugins/map/map.c
parent2e2c91f9256ff06cb79bc9816772e098dd6b7987 (diff)
MAP: Add optional user-supplied 'tag' field in MAPs.
Like other entities, allow an arbitrray user-supplied 'tag' field to be place on created MAP domains. It is also later returned with the MAP details. You might be thinking "User assigned MAP name" here. As the MAP domain structure was at the limit of a cacheline size, introduce a parallel "extra data" vector with non-essential domain information in it. Change-Id: Icc12b64cc4cb3e040c9a475908b19f6abaf4c293 Signed-off-by: Jon Loeliger <jdl@netgate.com>
Diffstat (limited to 'src/plugins/map/map.c')
-rw-r--r--src/plugins/map/map.c78
1 files changed, 70 insertions, 8 deletions
diff --git a/src/plugins/map/map.c b/src/plugins/map/map.c
index d77b141593b..a5354422b41 100644
--- a/src/plugins/map/map.c
+++ b/src/plugins/map/map.c
@@ -59,6 +59,52 @@ map_main_t map_main;
*/
+/*
+ * Save usre-assigned MAP domain names ("tags") in a vector of
+ * extra domain information.
+ */
+static void
+map_save_extras (u32 map_domain_index, char *tag)
+{
+ map_main_t *mm = &map_main;
+ map_domain_extra_t *de;
+ u32 len;
+
+ if (map_domain_index == ~0)
+ return;
+
+ vec_validate (mm->domain_extras, map_domain_index);
+ de = vec_elt_at_index (mm->domain_extras, map_domain_index);
+ clib_memset (de, 0, sizeof (*de));
+
+ if (!tag)
+ return;
+
+ len = strlen (tag) + 1;
+ de->tag = clib_mem_alloc (len);
+ clib_memcpy (de->tag, tag, len);
+}
+
+
+static void
+map_free_extras (u32 map_domain_index)
+{
+ map_main_t *mm = &map_main;
+ map_domain_extra_t *de;
+ char *tag;
+
+ if (map_domain_index == ~0)
+ return;
+
+ de = vec_elt_at_index (mm->domain_extras, map_domain_index);
+ tag = de->tag;
+ if (!tag)
+ return;
+
+ clib_mem_free (tag);
+ de->tag = 0;
+}
+
int
map_create_domain (ip4_address_t * ip4_prefix,
@@ -69,7 +115,8 @@ map_create_domain (ip4_address_t * ip4_prefix,
u8 ip6_src_len,
u8 ea_bits_len,
u8 psid_offset,
- u8 psid_length, u32 * map_domain_index, u16 mtu, u8 flags)
+ u8 psid_length,
+ u32 * map_domain_index, u16 mtu, u8 flags, char *tag)
{
u8 suffix_len, suffix_shift;
map_main_t *mm = &map_main;
@@ -122,6 +169,10 @@ map_create_domain (ip4_address_t * ip4_prefix,
d->psid_mask = (1 << d->psid_length) - 1;
d->ea_shift = 64 - ip6_prefix_len - suffix_len - d->psid_length;
+ /* Save a user-assigned MAP domain name if provided. */
+ if (tag)
+ map_save_extras (*map_domain_index, tag);
+
/* MAP longest match lookup table (input feature / FIB) */
mm->ip4_prefix_tbl->add (mm->ip4_prefix_tbl, &d->ip4_prefix,
d->ip4_prefix_len, *map_domain_index);
@@ -173,6 +224,9 @@ map_delete_domain (u32 map_domain_index)
mm->ip6_src_prefix_tbl->delete (mm->ip6_src_prefix_tbl, &d->ip6_src,
d->ip6_src_len);
+ /* Release user-assigned MAP domain name. */
+ map_free_extras (map_domain_index);
+
/* Deleting rules */
if (d->rules)
clib_mem_free (d->rules);
@@ -476,6 +530,7 @@ map_add_domain_command_fn (vlib_main_t * vm,
u32 ea_bits_len = 0, psid_offset = 0, psid_length = 0;
u32 mtu = 0;
u8 flags = 0;
+ u8 *tag = 0;
ip6_src_len = 128;
clib_error_t *error = NULL;
@@ -511,6 +566,8 @@ map_add_domain_command_fn (vlib_main_t * vm,
num_m_args++;
else if (unformat (line_input, "mtu %d", &mtu))
num_m_args++;
+ else if (unformat (line_input, "tag %s", &tag))
+ ;
else
{
error = clib_error_return (0, "unknown input `%U'",
@@ -528,7 +585,7 @@ map_add_domain_command_fn (vlib_main_t * vm,
map_create_domain (&ip4_prefix, ip4_prefix_len,
&ip6_prefix, ip6_prefix_len, &ip6_src, ip6_src_len,
ea_bits_len, psid_offset, psid_length, &map_domain_index,
- mtu, flags);
+ mtu, flags, (char *) tag);
done:
unformat_free (line_input);
@@ -870,16 +927,20 @@ format_map_domain (u8 * s, va_list * args)
bool counters = va_arg (*args, int);
map_main_t *mm = &map_main;
ip6_address_t ip6_prefix;
+ u32 map_domain_index = d - mm->domains;
+ map_domain_extra_t *de;
if (d->rules)
clib_memset (&ip6_prefix, 0, sizeof (ip6_prefix));
else
ip6_prefix = d->ip6_prefix;
+ de = vec_elt_at_index (mm->domain_extras, map_domain_index);
+
s = format (s,
- "[%d] ip4-pfx %U/%d ip6-pfx %U/%d ip6-src %U/%d ea-bits-len %d "
- "psid-offset %d psid-len %d mtu %d %s",
- d - mm->domains,
+ "[%d] tag {%s} ip4-pfx %U/%d ip6-pfx %U/%d ip6-src %U/%d "
+ "ea-bits-len %d psid-offset %d psid-len %d mtu %d %s",
+ map_domain_index, de->tag,
format_ip4_address, &d->ip4_prefix, d->ip4_prefix_len,
format_ip6_address, &ip6_prefix, d->ip6_prefix_len,
format_ip6_address, &d->ip6_src, d->ip6_src_len,
@@ -891,10 +952,10 @@ format_map_domain (u8 * s, va_list * args)
map_domain_counter_lock (mm);
vlib_counter_t v;
vlib_get_combined_counter (&mm->domain_counters[MAP_DOMAIN_COUNTER_TX],
- d - mm->domains, &v);
+ map_domain_index, &v);
s = format (s, " TX: %lld/%lld", v.packets, v.bytes);
vlib_get_combined_counter (&mm->domain_counters[MAP_DOMAIN_COUNTER_RX],
- d - mm->domains, &v);
+ map_domain_index, &v);
s = format (s, " RX: %lld/%lld", v.packets, v.bytes);
map_domain_counter_unlock (mm);
}
@@ -2078,7 +2139,8 @@ VLIB_CLI_COMMAND(map_fragment_command, static) = {
?*/
VLIB_CLI_COMMAND(map_add_domain_command, static) = {
.path = "map add domain",
- .short_help = "map add domain ip4-pfx <ip4-pfx> ip6-pfx <ip6-pfx> "
+ .short_help = "map add domain [tag <tag>] ip4-pfx <ip4-pfx> "
+ "ip6-pfx <ip6-pfx> "
"ip6-src <ip6-pfx> ea-bits-len <n> psid-offset <n> psid-len <n> "
"[map-t] [mtu <mtu>]",
.function = map_add_domain_command_fn,