MAP: Add RFC6052 mapping to MAP-T
Change-Id: I2e311f8b7f50133678b9172e8d071826af491609 Signed-off-by: Ole Troan <ot@cisco.com> Signed-off-by: Juraj Sloboda <jsloboda@cisco.com>
This commit is contained in:
@@ -59,7 +59,8 @@ ip6_map_fragment_cache (ip6_header_t * ip6, ip6_frag_hdr_t * frag,
|
||||
{
|
||||
u32 *ignore = NULL;
|
||||
map_ip4_reass_lock ();
|
||||
map_ip4_reass_t *r = map_ip4_reass_get (map_get_ip4 (&ip6->src_address),
|
||||
map_ip4_reass_t *r = map_ip4_reass_get (map_get_ip4 (&ip6->src_address,
|
||||
d->flags),
|
||||
ip6_map_t_embedded_address (d,
|
||||
&ip6->
|
||||
dst_address),
|
||||
@@ -82,7 +83,8 @@ ip6_map_fragment_get (ip6_header_t * ip6, ip6_frag_hdr_t * frag,
|
||||
{
|
||||
u32 *ignore = NULL;
|
||||
map_ip4_reass_lock ();
|
||||
map_ip4_reass_t *r = map_ip4_reass_get (map_get_ip4 (&ip6->src_address),
|
||||
map_ip4_reass_t *r = map_ip4_reass_get (map_get_ip4 (&ip6->src_address,
|
||||
d->flags),
|
||||
ip6_map_t_embedded_address (d,
|
||||
&ip6->
|
||||
dst_address),
|
||||
@@ -110,7 +112,7 @@ ip6_to_ip4_set_icmp_cb (ip6_header_t * ip6, ip4_header_t * ip4, void *arg)
|
||||
|
||||
//Security check
|
||||
//Note that this prevents an intermediate IPv6 router from answering the request
|
||||
ip4_sadr = map_get_ip4 (&ip6->src_address);
|
||||
ip4_sadr = map_get_ip4 (&ip6->src_address, ctx->d->flags);
|
||||
if (ip6->src_address.as_u64[0] !=
|
||||
map_get_pfx_net (ctx->d, ip4_sadr, ctx->sender_port)
|
||||
|| ip6->src_address.as_u64[1] != map_get_sfx_net (ctx->d, ip4_sadr,
|
||||
@@ -132,7 +134,7 @@ ip6_to_ip4_set_inner_icmp_cb (ip6_header_t * ip6, ip4_header_t * ip4,
|
||||
u32 inner_ip4_dadr;
|
||||
|
||||
//Security check of inner packet
|
||||
inner_ip4_dadr = map_get_ip4 (&ip6->dst_address);
|
||||
inner_ip4_dadr = map_get_ip4 (&ip6->dst_address, ctx->d->flags);
|
||||
if (ip6->dst_address.as_u64[0] !=
|
||||
map_get_pfx_net (ctx->d, inner_ip4_dadr, ctx->sender_port)
|
||||
|| ip6->dst_address.as_u64[1] != map_get_sfx_net (ctx->d,
|
||||
@@ -612,8 +614,10 @@ ip6_map_t (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
|
||||
ip60 = vlib_buffer_get_current (p0);
|
||||
ip61 = vlib_buffer_get_current (p1);
|
||||
|
||||
saddr0 = map_get_ip4 (&ip60->src_address);
|
||||
saddr1 = map_get_ip4 (&ip61->src_address);
|
||||
saddr0 = 0; /* TODO */
|
||||
saddr1 = 0; /* TODO */
|
||||
/* NOTE: ip6_map_get_domain currently doesn't utilize second argument */
|
||||
|
||||
d0 = ip6_map_get_domain (vnet_buffer (p0)->ip.adj_index[VLIB_TX],
|
||||
(ip4_address_t *) & saddr0,
|
||||
&vnet_buffer (p0)->map_t.map_domain_index,
|
||||
@@ -624,6 +628,9 @@ ip6_map_t (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
|
||||
&vnet_buffer (p1)->map_t.map_domain_index,
|
||||
&error1);
|
||||
|
||||
saddr0 = map_get_ip4 (&ip60->src_address, d0->flags);
|
||||
saddr1 = map_get_ip4 (&ip61->src_address, d1->flags);
|
||||
|
||||
vnet_buffer (p0)->map_t.v6.saddr = saddr0;
|
||||
vnet_buffer (p1)->map_t.v6.saddr = saddr1;
|
||||
vnet_buffer (p0)->map_t.v6.daddr =
|
||||
@@ -790,13 +797,18 @@ ip6_map_t (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
|
||||
|
||||
p0 = vlib_get_buffer (vm, pi0);
|
||||
ip60 = vlib_buffer_get_current (p0);
|
||||
|
||||
//Save saddr in a different variable to not overwrite ip.adj_index
|
||||
saddr = map_get_ip4 (&ip60->src_address);
|
||||
saddr = 0; /* TODO */
|
||||
/* NOTE: ip6_map_get_domain currently doesn't utilize second argument */
|
||||
|
||||
d0 = ip6_map_get_domain (vnet_buffer (p0)->ip.adj_index[VLIB_TX],
|
||||
(ip4_address_t *) & saddr,
|
||||
&vnet_buffer (p0)->map_t.map_domain_index,
|
||||
&error0);
|
||||
|
||||
saddr = map_get_ip4 (&ip60->src_address, d0->flags);
|
||||
|
||||
//FIXME: What if d0 is null
|
||||
vnet_buffer (p0)->map_t.v6.saddr = saddr;
|
||||
vnet_buffer (p0)->map_t.v6.daddr =
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
vl_api_version 1.0.0
|
||||
vl_api_version 1.1.0
|
||||
|
||||
/** \brief Add MAP domains
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@@ -27,6 +27,7 @@ vl_api_version 1.0.0
|
||||
@param psid_offset - Port Set Identifider (PSID) offset
|
||||
@param psid_length - PSID length
|
||||
@param is_translation - MAP-E / MAP-T
|
||||
@param is_rfc6052 - rfc6052 translation
|
||||
@param mtu - MTU
|
||||
*/
|
||||
define map_add_domain
|
||||
@@ -43,6 +44,7 @@ define map_add_domain
|
||||
u8 psid_offset;
|
||||
u8 psid_length;
|
||||
u8 is_translation;
|
||||
u8 is_rfc6052;
|
||||
u16 mtu;
|
||||
};
|
||||
|
||||
|
||||
+23
-2
@@ -85,6 +85,12 @@ map_create_domain (ip4_address_t * ip4_prefix,
|
||||
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
|
||||
{
|
||||
@@ -586,6 +592,8 @@ map_add_domain_command_fn (vlib_main_t * vm,
|
||||
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'",
|
||||
@@ -919,6 +927,18 @@ done:
|
||||
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)
|
||||
{
|
||||
@@ -933,13 +953,14 @@ 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)
|
||||
{
|
||||
|
||||
+21
-9
@@ -35,10 +35,12 @@ int map_add_del_psid (u32 map_domain_index, u16 psid, ip6_address_t * tep,
|
||||
u8 is_add);
|
||||
u8 *format_map_trace (u8 * s, va_list * args);
|
||||
|
||||
typedef enum __attribute__ ((__packed__))
|
||||
typedef enum
|
||||
{
|
||||
MAP_DOMAIN_PREFIX = 1 << 0, MAP_DOMAIN_TRANSLATION = 1 << 1, // The domain uses MAP-T
|
||||
} map_domain_flags_e;
|
||||
MAP_DOMAIN_PREFIX = 1 << 0,
|
||||
MAP_DOMAIN_TRANSLATION = 1 << 1, // The domain uses MAP-T
|
||||
MAP_DOMAIN_RFC6052 = 1 << 2,
|
||||
} __attribute__ ((__packed__)) map_domain_flags_e;
|
||||
|
||||
/**
|
||||
* IP4 reassembly logic:
|
||||
@@ -382,6 +384,9 @@ map_get_sfx (map_domain_t *d, u32 addr, u16 port)
|
||||
if (d->ip6_prefix_len == 128)
|
||||
return clib_net_to_host_u64(d->ip6_prefix.as_u64[1]);
|
||||
|
||||
if (d->flags & MAP_DOMAIN_RFC6052)
|
||||
return (clib_net_to_host_u64(d->ip6_prefix.as_u64[1]) | addr);
|
||||
|
||||
/* IPv4 prefix */
|
||||
if (d->flags & MAP_DOMAIN_PREFIX)
|
||||
return (u64) (addr & (0xFFFFFFFF << d->suffix_shift)) << 16;
|
||||
@@ -398,9 +403,12 @@ map_get_sfx_net (map_domain_t *d, u32 addr, u16 port)
|
||||
}
|
||||
|
||||
static_always_inline u32
|
||||
map_get_ip4 (ip6_address_t *addr)
|
||||
map_get_ip4 (ip6_address_t *addr, map_domain_flags_e flags)
|
||||
{
|
||||
return clib_host_to_net_u32(clib_net_to_host_u64(addr->as_u64[1]) >> 16);
|
||||
if (flags & MAP_DOMAIN_RFC6052)
|
||||
return clib_host_to_net_u32(clib_net_to_host_u64(addr->as_u64[1]));
|
||||
else
|
||||
return clib_host_to_net_u32(clib_net_to_host_u64(addr->as_u64[1]) >> 16);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -427,16 +435,19 @@ ip6_map_get_domain (u32 mdi,
|
||||
{
|
||||
map_main_t *mm = &map_main;
|
||||
|
||||
#ifdef TODO
|
||||
/*
|
||||
* Disable direct MAP domain lookup on decap, until the security check is updated to verify IPv4 SA.
|
||||
* (That's done implicitly when MAP domain is looked up in the IPv4 FIB)
|
||||
*/
|
||||
#ifdef MAP_NONSHARED_DOMAIN_ENABLED
|
||||
#error "How can you be sure this domain is not shared?"
|
||||
*map_domain_index = mdi;
|
||||
return pool_elt_at_index(mm->domains, mdi);
|
||||
//#ifdef MAP_NONSHARED_DOMAIN_ENABLED
|
||||
//#error "How can you be sure this domain is not shared?"
|
||||
#endif
|
||||
|
||||
*map_domain_index = mdi;
|
||||
return pool_elt_at_index(mm->domains, mdi);
|
||||
|
||||
#ifdef TODO
|
||||
u32 lbi = ip4_fib_forwarding_lookup(0, addr);
|
||||
const dpo_id_t *dpo = load_balance_get_bucket(lbi, 0);
|
||||
if (PREDICT_TRUE(dpo->dpoi_type == map_dpo_type ||
|
||||
@@ -447,6 +458,7 @@ ip6_map_get_domain (u32 mdi,
|
||||
}
|
||||
*error = MAP_ERROR_NO_DOMAIN;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
map_ip4_reass_t *
|
||||
|
||||
@@ -56,7 +56,14 @@ vl_api_map_add_domain_t_handler (vl_api_map_add_domain_t * mp)
|
||||
vl_api_map_add_domain_reply_t *rmp;
|
||||
int rv = 0;
|
||||
u32 index;
|
||||
u8 flags = mp->is_translation ? MAP_DOMAIN_TRANSLATION : 0;
|
||||
u8 flags = 0;
|
||||
|
||||
if (mp->is_translation)
|
||||
flags |= MAP_DOMAIN_TRANSLATION;
|
||||
|
||||
if (mp->is_rfc6052)
|
||||
flags |= MAP_DOMAIN_RFC6052;
|
||||
|
||||
rv =
|
||||
map_create_domain ((ip4_address_t *) & mp->ip4_prefix, mp->ip4_prefix_len,
|
||||
(ip6_address_t *) & mp->ip6_prefix, mp->ip6_prefix_len,
|
||||
|
||||
Reference in New Issue
Block a user