#include <vnet/fib/ip6_fib.h>
#include <vnet/adj/adj.h>
#include <vnet/map/map_dpo.h>
+#include <vppinfra/crc32.h>
#include "map.h"
-#ifdef __SSE4_2__
-static inline u32
-crc_u32 (u32 data, u32 value)
-{
- __asm__ volatile ("crc32l %[data], %[value];":[value] "+r" (value):[data]
- "rm" (data));
- return value;
-}
-#else
-#include <vppinfra/xxhash.h>
-
-static inline u32
-crc_u32 (u32 data, u32 value)
-{
- u64 tmp = ((u64) data << 32) | (u64) value;
- return (u32) clib_xxhash (tmp);
-}
-#endif
-
+map_main_t map_main;
/*
* This code supports the following MAP modes:
clib_warning ("MAP-T only supports ip6_src_len = 96 for now.");
return -1;
}
+ if ((flags & MAP_DOMAIN_RFC6052) && ip6_prefix_len != 96)
+ {
+ clib_warning ("RFC6052 translation only supports ip6_prefix_len = "
+ "96 for now");
+ return -1;
+ }
}
else
{
/* How many, and which bits to grab from the IPv4 DA */
if (ip4_prefix_len + ea_bits_len < 32)
{
- flags |= MAP_DOMAIN_PREFIX;
+ if (!(flags & MAP_DOMAIN_TRANSLATION))
+ flags |= MAP_DOMAIN_PREFIX;
suffix_shift = 32 - ip4_prefix_len - ea_bits_len;
suffix_len = ea_bits_len;
}
return -1;
}
+ if (mm->is_ce && !(flags & MAP_DOMAIN_TRANSLATION))
+ {
+ clib_warning ("MAP-E CE is not supported yet");
+ return -1;
+ }
+
/* Get domain index */
pool_get_aligned (mm->domains, d, CLIB_CACHE_LINE_BYTES);
memset (d, 0, sizeof (*d));
map_dpo_create (DPO_PROTO_IP4, *map_domain_index, &dpo_v4);
/* Create ip4 route */
+ u8 ip4_pfx_len;
+ ip4_address_t ip4_pfx;
+ if (mm->is_ce)
+ {
+ ip4_pfx_len = 0;
+ ip4_pfx.as_u32 = 0;
+ }
+ else
+ {
+ ip4_pfx_len = d->ip4_prefix_len;
+ ip4_pfx = d->ip4_prefix;
+ }
fib_prefix_t pfx = {
.fp_proto = FIB_PROTOCOL_IP4,
- .fp_len = d->ip4_prefix_len,
+ .fp_len = ip4_pfx_len,
.fp_addr = {
- .ip4 = d->ip4_prefix,
+ .ip4 = ip4_pfx,
}
,
};
* already exists and is MAP sourced, it is now MAP source n+1 times
* and will need to be removed n+1 times.
*/
+ u8 ip6_pfx_len;
+ ip6_address_t ip6_pfx;
+ if (mm->is_ce)
+ {
+ ip6_pfx_len = d->ip6_prefix_len;
+ ip6_pfx = d->ip6_prefix;
+ }
+ else
+ {
+ ip6_pfx_len = d->ip6_src_len;
+ ip6_pfx = d->ip6_src;
+ }
fib_prefix_t pfx6 = {
.fp_proto = FIB_PROTOCOL_IP6,
- .fp_len = d->ip6_src_len,
- .fp_addr.ip6 = d->ip6_src,
+ .fp_len = ip6_pfx_len,
+ .fp_addr.ip6 = ip6_pfx,
};
fib_table_entry_special_dpo_add (0, &pfx6,
}
static u8 *
-format_map_pre_resolve (u8 * s, va_list ap)
+format_map_pre_resolve (u8 * s, va_list * ap)
{
- map_main_pre_resolved_t *pr = va_arg (ap, map_main_pre_resolved_t *);
+ map_main_pre_resolved_t *pr = va_arg (*ap, map_main_pre_resolved_t *);
if (FIB_NODE_INDEX_INVALID != pr->fei)
{
static map_main_pre_resolved_t *
map_from_fib_node (fib_node_t * node)
{
-#if (CLIB_DEBUG > 0)
ASSERT (FIB_NODE_TYPE_MAP_E == node->fn_type);
-#endif
return ((map_main_pre_resolved_t *)
(((char *) node) -
STRUCT_OFFSET_OF (map_main_pre_resolved_t, node)));
num_m_args++;
else if (unformat (line_input, "map-t"))
flags |= MAP_DOMAIN_TRANSLATION;
+ else if (unformat (line_input, "rfc6052"))
+ flags |= (MAP_DOMAIN_TRANSLATION | MAP_DOMAIN_RFC6052);
else
{
error = clib_error_return (0, "unknown input `%U'",
return error;
}
+static char *
+map_flags_to_string (u32 flags)
+{
+ if (flags & MAP_DOMAIN_RFC6052)
+ return "rfc6052";
+ if (flags & MAP_DOMAIN_PREFIX)
+ return "prefix";
+ if (flags & MAP_DOMAIN_TRANSLATION)
+ return "map-t";
+ return "";
+}
+
static u8 *
format_map_domain (u8 * s, va_list * args)
{
ip6_prefix = d->ip6_prefix;
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] 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,
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,
d->ea_bits_len, d->psid_offset, d->psid_length, d->mtu,
- (d->flags & MAP_DOMAIN_TRANSLATION) ? "map-t" : "");
+ map_flags_to_string (d->flags));
if (counters)
{
map_domain_t *d;
int domains = 0, rules = 0, domaincount = 0, rulecount = 0;
if (pool_elts (mm->domains) == 0)
- vlib_cli_output (vm, "No MAP domains are configured...");
+ {
+ vlib_cli_output (vm, "No MAP domains are configured...");
+ return 0;
+ }
/* *INDENT-OFF* */
pool_foreach(d, mm->domains, ({
};
u32 h = 0;
- h = crc_u32 (k.as_u32[0], h);
- h = crc_u32 (k.as_u32[1], h);
- h = crc_u32 (k.as_u32[2], h);
- h = crc_u32 (k.as_u32[3], h);
+#ifdef clib_crc32c_uses_intrinsics
+ h = clib_crc32c ((u8 *) k.as_u32, 16);
+#else
+ u64 tmp = k.as_u32[0] ^ k.as_u32[1] ^ k.as_u32[2] ^ k.as_u32[3];
+ h = clib_xxhash (tmp);
+#endif
h = h >> (32 - mm->ip4_reass_ht_log2len);
f64 now = vlib_time_now (mm->vlib_main);
u32 h = 0;
int i;
- for (i = 0; i < 10; i++)
- h = crc_u32 (k.as_u32[i], h);
+
+#ifdef clib_crc32c_uses_intrinsics
+ h = clib_crc32c ((u8 *) k.as_u32, 40);
+#else
+ u64 tmp =
+ k.as_u64[0] ^ k.as_u64[1] ^ k.as_u64[2] ^ k.as_u64[3] ^ k.as_u64[4];
+ h = clib_xxhash (tmp);
+#endif
+
h = h >> (32 - mm->ip6_reass_ht_log2len);
f64 now = vlib_time_now (mm->vlib_main);
.path = "map add domain",
.short_help = "map add domain 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>]",
+ "[map-t] [map-ce] [mtu <mtu>]",
.function = map_add_domain_command_fn,
};
};
/* *INDENT-ON* */
+static clib_error_t *
+map_config (vlib_main_t * vm, unformat_input_t * input)
+{
+ map_main_t *mm = &map_main;
+ u8 is_ce = false;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "customer edge"))
+ is_ce = true;
+ else
+ return clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, input);
+ }
+
+ mm->is_ce = is_ce;
+
+ return 0;
+}
+
+VLIB_CONFIG_FUNCTION (map_config, "map");
+
/*
* map_init
*/
/* ICMP6 Type 1, Code 5 for security check failure */
mm->icmp6_enabled = false;
+ mm->is_ce = false;
+
/* Inner or outer fragmentation */
mm->frag_inner = false;
mm->frag_ignore_df = false;
mm->ip4_reass_pool = 0;
mm->ip4_reass_lock =
clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES);
+ *mm->ip4_reass_lock = 0;
mm->ip4_reass_conf_ht_ratio = MAP_IP4_REASS_HT_RATIO_DEFAULT;
mm->ip4_reass_conf_lifetime_ms = MAP_IP4_REASS_LIFETIME_DEFAULT;
mm->ip4_reass_conf_pool_size = MAP_IP4_REASS_POOL_SIZE_DEFAULT;
mm->ip6_reass_pool = 0;
mm->ip6_reass_lock =
clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES);
+ *mm->ip6_reass_lock = 0;
mm->ip6_reass_conf_ht_ratio = MAP_IP6_REASS_HT_RATIO_DEFAULT;
mm->ip6_reass_conf_lifetime_ms = MAP_IP6_REASS_LIFETIME_DEFAULT;
mm->ip6_reass_conf_pool_size = MAP_IP6_REASS_POOL_SIZE_DEFAULT;