LISP EID virtualization support

Change-Id: I892c001cfdff9d8d93e646641d96520beb3c6265
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
This commit is contained in:
Filip Tehlar
2016-06-02 16:07:38 +02:00
committed by Florin Coras
parent 0443212371
commit 324112fad0
11 changed files with 443 additions and 182 deletions

View File

@ -183,6 +183,8 @@ build_map_request (lisp_cp_main_t * lcm, vlib_buffer_t * b,
u8 is_smr_invoked = 1;
u64 nonce = 0;
map_request_hdr_t * h = 0;
memset (deid, 0, sizeof (deid[0]));
memset (seid, 0, sizeof (seid[0]));
gid_address_type (seid) = GID_ADDR_IP_PREFIX;
ip_address_t * ip_addr = &gid_address_ip (seid);
@ -205,6 +207,7 @@ static void
generate_rlocs (gid_address_t **rlocs, u32 * count)
{
gid_address_t gid_addr_data, * gid_addr = &gid_addr_data;
memset (gid_addr, 0, sizeof (gid_addr[0]));
ip_address_t * addr = &gid_address_ip (gid_addr);
gid_address_type (gid_addr) = GID_ADDR_IP_PREFIX;
@ -277,34 +280,20 @@ static clib_error_t * test_lisp_msg_put_mreq_with_lcaf ()
clib_error_t * error = 0;
map_request_hdr_t *h = 0;
gid_address_t * rlocs = 0;
gid_address_t rloc;
ip_prefix_t ippref;
ip_prefix_version (&ippref) = IP4;
ip4_address_t * ip = &ip_prefix_v4 (&ippref);
ip->as_u32 = 0x11223344;
gid_address_t gid1 =
gid_address_t g =
{
.type = GID_ADDR_IP_PREFIX,
.ippref = ippref
.ippref = ippref,
.vni = 0x90919293,
.vni_mask = 0x17
};
lcaf_t lcaf1 =
{
.type = LCAF_INSTANCE_ID,
.uni =
{
.vni_mask_len = 0x17,
.vni = 0x90919293,
.gid_addr = &gid1
}
};
gid_address_type (&rloc) = GID_ADDR_LCAF;
gid_address_lcaf (&rloc) = lcaf1;
vec_add1 (rlocs, rloc);
vec_add1 (rlocs, g);
u8 * data = clib_mem_alloc (500);
memset (data, 0, 500);
@ -482,16 +471,9 @@ test_lisp_parse_lcaf ()
_assert (locs[0].mpriority == 0xc);
_assert (locs[0].mweight == 0xd);
/* check LCAF header data */
lcaf_t * lcaf = &gid_address_lcaf (&locs[0].address);
_assert (gid_address_type (&locs[0].address) == GID_ADDR_LCAF);
_assert (lcaf_type (lcaf) == LCAF_INSTANCE_ID);
vni_t * v = (vni_t *) lcaf;
_assert (vni_vni (v) == 0x09);
gid_address_t * nested_gid = vni_gid (v);
_assert (GID_ADDR_IP_PREFIX == gid_address_type (nested_gid));
ip_prefix_t * ip_pref = &gid_address_ippref (nested_gid);
_assert (gid_address_type (&locs[0].address) == GID_ADDR_IP_PREFIX);
_assert (gid_address_vni (&locs[0].address) == 0x09);
ip_prefix_t * ip_pref = &gid_address_ippref (&locs[0].address);
_assert (IP4 == ip_prefix_version (ip_pref));
/* 2nd locator - LCAF entry with ipv6 address */
@ -501,16 +483,9 @@ test_lisp_parse_lcaf ()
_assert (locs[1].mpriority == 0x5);
_assert (locs[1].mweight == 0x4);
/* LCAF header */
_assert (gid_address_type (&locs[1].address) == GID_ADDR_LCAF);
lcaf = &gid_address_lcaf (&locs[1].address);
_assert (lcaf_type (lcaf) == LCAF_INSTANCE_ID);
v = (vni_t *) lcaf;
_assert (vni_vni (v) == 0x22446688);
nested_gid = vni_gid (v);
_assert (GID_ADDR_IP_PREFIX == gid_address_type (nested_gid));
ip_pref = &gid_address_ippref (nested_gid);
_assert (gid_address_type (&locs[1].address) == GID_ADDR_IP_PREFIX);
_assert (0x22446688 == gid_address_vni (&locs[1].address));
ip_pref = &gid_address_ippref (&locs[1].address);
_assert (IP6 == ip_prefix_version (ip_pref));
/* 3rd locator - simple ipv4 address */

View File

@ -154,21 +154,19 @@ static clib_error_t * test_gid_parse_lcaf ()
_assert (18 == len);
gid_address_copy (gid_addr_copy, gid_addr);
_assert (0 == gid_address_cmp (gid_addr_copy, gid_addr));
_assert (GID_ADDR_IP_PREFIX == gid_address_type (gid_addr));
_assert (9 == gid_address_vni (gid_addr));
_assert (0x18 == gid_address_vni_mask (gid_addr));
_assert (0xddccbb10 == gid_addr->ippref.addr.ip.v4.as_u32);
lcaf_t * lcaf = &gid_address_lcaf (gid_addr_copy);
vni_t * vni = (vni_t *) lcaf;
_assert (lcaf->type == LCAF_INSTANCE_ID);
_assert (vni->vni == 9);
_assert (vni->vni_mask_len == 0x18);
gid_address_t * g = vni_gid (vni);
_assert (gid_address_type (g) == GID_ADDR_IP_PREFIX);
done:
gid_address_free (gid_addr);
gid_address_free (gid_addr_copy);
return error;
}
/* recursive LCAFs are not supported */
#if 0
static clib_error_t * test_gid_parse_lcaf_complex ()
{
clib_error_t * error = 0;
@ -262,59 +260,7 @@ done:
gid_address_free (gid_addr_copy);
return error;
}
static clib_error_t * test_format_unformat_gid_address (void)
{
u8 * s = 0;
clib_error_t * error = 0;
unformat_input_t _input;
unformat_input_t * input = &_input;
gid_address_t _gid_addr, * gid_addr = &_gid_addr;
gid_address_t unformated_gid;
/* format/unformat IPv4 global ID address */
gid_address_type(gid_addr) = GID_ADDR_IP_PREFIX;
gid_address_ippref_len(gid_addr) = 24;
ip_prefix_version(&gid_addr->ippref) = IP4;
gid_addr->ippref.addr.ip.v4.as_u32 = 0x20304050;
s = format(0, "%U", format_gid_address, gid_addr);
vec_add1(s, 0);
unformat_init_string(input, (char *)s, vec_len(s));
_assert (unformat(input, "%U",
unformat_gid_address, &unformated_gid));
_assert (0 == gid_address_cmp (&unformated_gid, gid_addr));
unformat_free(input);
vec_free(s);
s = 0;
/* format/unformat IPv6 global ID address */
gid_address_type(gid_addr) = GID_ADDR_IP_PREFIX;
gid_address_ippref_len(gid_addr) = 64;
ip_prefix_version(&gid_addr->ippref) = IP6;
u8 ipv6[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
clib_memcpy(gid_addr->ippref.addr.ip.v6.as_u8, ipv6, sizeof(ipv6));
s = format(0, "%U", format_gid_address, gid_addr);
vec_add1(s, 0);
unformat_init_string(input, (char *)s, vec_len(s));
_assert (unformat (input, "%U", unformat_gid_address,
&unformated_gid));
_assert (0 == gid_address_cmp(&unformated_gid, gid_addr));
/* test address copy */
gid_address_t gid_addr_copy;
gid_address_copy(&gid_addr_copy, gid_addr);
_assert (0 == gid_address_cmp (&gid_addr_copy, gid_addr));
done:
unformat_free(input);
vec_free(s);
return error;
}
#endif
#if 0 /* uncomment this once VNI is supported */
static clib_error_t * test_write_mac_in_lcaf (void)
@ -393,34 +339,22 @@ static clib_error_t * test_gid_address_write (void)
memset(b, 0, 500);
ip_prefix_version (ippref) = IP4;
ip_prefix_len (ippref) = 9;
ip4_address_t * ip4 = &ip_prefix_v4 (ippref);
ip4->as_u32 = 0xaabbccdd;
gid_address_t nested_gid =
gid_address_t g =
{
.ippref = ippref[0],
.type = GID_ADDR_IP_PREFIX,
.vni = 0x01020304,
.vni_mask = 0x18
};
lcaf_t lcaf =
{
.type = LCAF_INSTANCE_ID,
.uni =
{
.vni_mask_len = 0x18,
.vni = 0x01020304,
.gid_addr = &nested_gid
}
};
_assert (18 == gid_address_size_to_put (&g));
_assert (gid_address_len (&g) == 9);
gid_address_t gid =
{
.type = GID_ADDR_LCAF,
.lcaf = lcaf
};
_assert (18 == gid_address_size_to_put (&gid));
u16 write_len = gid_address_put (b, &gid);
u16 write_len = gid_address_put (b, &g);
_assert (18 == write_len);
u8 expected_gid_data[] =
@ -443,12 +377,10 @@ done:
}
#define foreach_test_case \
_(format_unformat_gid_address) \
_(locator_type) \
_(gid_parse_ip_pref) \
_(gid_parse_mac) \
_(gid_parse_lcaf) \
_(gid_parse_lcaf_complex) \
_(mac_address_write) \
_(gid_address_write)

View File

@ -47,13 +47,13 @@ vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a,
if (mi != GID_LOOKUP_MISS && !gid_address_cmp (&old_map->eid,
&a->deid))
{
clib_warning("eid %U found in the eid-table", format_ip_address,
clib_warning ("eid %U found in the eid-table", format_gid_address,
&a->deid);
return VNET_API_ERROR_VALUE_EXIST;
}
pool_get(lcm->mapping_pool, m);
m->eid = a->deid;
gid_address_copy (&m->eid, &a->deid);
m->locator_set_index = a->locator_set_index;
m->ttl = a->ttl;
m->action = a->action;
@ -87,7 +87,7 @@ vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a,
{
if (mi == GID_LOOKUP_MISS)
{
clib_warning("eid %U not found in the eid-table", format_ip_address,
clib_warning("eid %U not found in the eid-table", format_gid_address,
&a->deid);
return VNET_API_ERROR_INVALID_VALUE;
}
@ -123,6 +123,7 @@ vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a,
/* remove mapping from dictionary */
gid_dictionary_add_del (&lcm->mapping_index_by_gid, &a->deid, 0, 0);
gid_address_free (&m->eid);
pool_put_index (lcm->mapping_pool, mi);
}
@ -217,9 +218,9 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input,
uword * p;
vnet_lisp_add_del_mapping_args_t _a, * a = &_a;
int rv = 0;
u32 vni = 0;
gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
memset (&eid, 0, sizeof (eid));
/* Get a line of input. */
if (! unformat_user (input, unformat_line_input, line_input))
return 0;
@ -230,6 +231,8 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input,
is_add = 1;
else if (unformat (line_input, "del"))
is_add = 0;
else if (unformat (line_input, "vni %d", &vni))
gid_address_vni (&eid) = vni;
else if (unformat (line_input, "eid %U", unformat_ip_prefix, prefp))
{
vec_add1(eids, eid);
@ -251,8 +254,9 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input,
goto done;
}
}
/* XXX treat batch configuration */
gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
a->deid = eid;
a->is_add = is_add;
a->locator_set_index = locator_set_index;
@ -268,15 +272,99 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input,
vec_free(eids);
if (locator_set_name)
vec_free (locator_set_name);
gid_address_free (&a->deid);
return error;
}
VLIB_CLI_COMMAND (lisp_add_del_local_eid_command) = {
.path = "lisp eid-table",
.short_help = "lisp eid-table add/del eid <eid> locator-set <locator-set>",
.short_help = "lisp eid-table add/del [vni <vni>] eid <eid> "
"locator-set <locator-set>",
.function = lisp_add_del_local_eid_command_fn,
};
int
vnet_lisp_eid_table_map (u32 vni, u32 vrf, u8 is_add)
{
lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
uword * table_id, * vnip;
if (vnet_lisp_enable_disable_status () == 0)
{
clib_warning ("LISP is disabled!");
return -1;
}
if (vni == 0 || vrf == 0)
{
clib_warning ("can't add/del default vni-vrf mapping!");
return -1;
}
table_id = hash_get (lcm->table_id_by_vni, vni);
vnip = hash_get (lcm->vni_by_table_id, vrf);
if (is_add)
{
if (table_id || vnip)
{
clib_warning ("vni %d or vrf %d already used in any vrf/vni "
"mapping!", vni, vrf);
return -1;
}
hash_set (lcm->table_id_by_vni, vni, vrf);
hash_set (lcm->vni_by_table_id, vrf, vni);
}
else
{
if (!table_id || !vnip)
{
clib_warning ("vni %d or vrf %d not used in any vrf/vni! "
"mapping!", vni, vrf);
return -1;
}
hash_unset (lcm->table_id_by_vni, vni);
hash_unset (lcm->vni_by_table_id, vrf);
}
return 0;
}
static clib_error_t *
lisp_eid_table_map_command_fn (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
u8 is_add = 1;
u32 vni = 0, vrf = 0;
unformat_input_t _line_input, * line_input = &_line_input;
/* Get a line of input. */
if (! unformat_user (input, unformat_line_input, line_input))
return 0;
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (line_input, "del"))
is_add = 0;
else if (unformat (line_input, "vni %d", &vni))
;
else if (unformat (line_input, "vrf %d", &vrf))
;
else
{
return unformat_parse_error (line_input);
}
}
vnet_lisp_eid_table_map (vni, vrf, is_add);
return 0;
}
VLIB_CLI_COMMAND (lisp_eid_table_map_command) = {
.path = "lisp eid-table map",
.short_help = "lisp eid-table map [del] vni <vni> vrf <vrf>",
.function = lisp_eid_table_map_command_fn,
};
static int
lisp_add_del_negative_static_mapping (gid_address_t * deid,
vnet_lisp_add_del_locator_set_args_t * ls, u8 action, u8 is_add)
@ -605,8 +693,8 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm,
}
else if (unformat (line_input, "vni %u", &vni))
{
gid_address_set_vni (&seid, vni);
gid_address_set_vni (&deid, vni);
gid_address_vni (&seid) = vni;
gid_address_vni (&deid) = vni;
}
else if (unformat (line_input, "seid %U",
unformat_ip_prefix, seid_ippref))
@ -811,13 +899,13 @@ lisp_show_local_eid_table_command_fn (vlib_main_t * vm,
lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
mapping_t * mapit;
vlib_cli_output (vm, "%=20s%=16s", "EID", "Locator");
vlib_cli_output (vm, "%=30s%=16s", "EID", "Locator");
pool_foreach (mapit, lcm->mapping_pool,
({
u8 * msg = 0;
locator_set_t * ls = pool_elt_at_index (lcm->locator_set_pool,
mapit->locator_set_index);
vlib_cli_output (vm, "%-16U%16v", format_gid_address, &mapit->eid,
vlib_cli_output (vm, "%-30U%16v", format_gid_address, &mapit->eid,
ls->name);
vec_free (msg);
}));
@ -1294,6 +1382,28 @@ VLIB_CLI_COMMAND (lisp_show_status_command) = {
.short_help = "show lisp status",
.function = lisp_show_status_command_fn,
};
static clib_error_t *
lisp_show_eid_table_map_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
{
hash_pair_t * p;
lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
vlib_cli_output (vm, "%=10s%=10s", "VNI", "VRF");
hash_foreach_pair (p, lcm->table_id_by_vni,
{
vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
});
return 0;
}
VLIB_CLI_COMMAND (lisp_show_eid_table_map_command) = {
.path = "show lisp eid-table map",
.short_help = "show lisp eid-table vni to vrf mappings",
.function = lisp_show_eid_table_map_command_fn,
};
static clib_error_t *
lisp_add_del_locator_set_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
@ -1886,6 +1996,7 @@ build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set)
ip_prefix_t * ippref = &gid_address_ippref (gid);
ip_address_t * rloc = &ip_prefix_addr (ippref);
memset (gid, 0, sizeof (gid[0]));
gid_address_type (gid) = GID_ADDR_IP_PREFIX;
for (i = 0; i < vec_len(loc_set->locator_indices); i++)
{
@ -2059,6 +2170,43 @@ get_src_and_dst (void *hdr, ip_address_t * src, ip_address_t *dst)
}
}
static u32
lisp_get_vni_from_buffer (vlib_buffer_t * b, u8 version)
{
uword * vnip;
u32 vni = ~0, table_id = ~0, fib_index;
lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
if (version == IP4)
{
ip4_fib_t * fib;
ip4_main_t * im4 = &ip4_main;
fib_index = vec_elt (im4->fib_index_by_sw_if_index,
vnet_buffer (b)->sw_if_index[VLIB_RX]);
fib = find_ip4_fib_by_table_index_or_id (im4, fib_index,
IP4_ROUTE_FLAG_FIB_INDEX);
table_id = fib->table_id;
}
else
{
ip6_fib_t * fib;
ip6_main_t * im6 = &ip6_main;
fib_index = vec_elt (im6->fib_index_by_sw_if_index,
vnet_buffer (b)->sw_if_index[VLIB_RX]);
fib = find_ip6_fib_by_table_index_or_id (im6, fib_index,
IP6_ROUTE_FLAG_FIB_INDEX);
table_id = fib->table_id;
}
vnip = hash_get (lcm->vni_by_table_id, table_id);
if (vnip)
vni = vnip[0];
else
clib_warning ("vrf %d is not mapped to any vni!", table_id);
return vni;
}
static uword
lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
@ -2078,7 +2226,7 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
while (n_left_from > 0 && n_left_to_next_drop > 0)
{
u32 pi0;
u32 pi0, vni;
vlib_buffer_t * p0;
ip4_header_t * ip0;
gid_address_t src, dst;
@ -2105,6 +2253,10 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
ip_prefix_len(spref) = ip_address_max_len (ip_prefix_version(spref));
ip_prefix_len(dpref) = ip_address_max_len (ip_prefix_version(dpref));
vni = lisp_get_vni_from_buffer (p0, ip_prefix_version (spref));
gid_address_vni (&dst) = vni;
gid_address_vni (&src) = vni;
/* if we have remote mapping for destination already in map-chache
add forwarding tunnel directly. If not send a map-request */
di = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst);
@ -2150,6 +2302,8 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
sizeof(ip_address_t));
}
}
gid_address_free (&dst);
gid_address_free (&src);
}
vlib_put_next_frame (vm, node, LISP_CP_LOOKUP_NEXT_DROP, n_left_to_next_drop);
@ -2662,6 +2816,7 @@ lisp_cp_init (vlib_main_t *vm)
/* default vrf mapped to vni 0 */
hash_set(lcm->table_id_by_vni, 0, 0);
hash_set(lcm->vni_by_table_id, 0, 0);
udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp,
lisp_cp_input_node.index, 1 /* is_ip4 */);

View File

@ -100,6 +100,9 @@ typedef struct
/* Lookup vrf by vni */
uword * table_id_by_vni;
/* Lookup vni by vrf */
uword * vni_by_table_id;
/* Number of src prefixes in a vni that use an interface */
uword * dp_if_refcount_by_vni;
@ -200,4 +203,6 @@ vnet_lisp_add_del_mreq_itr_rlocs (vnet_lisp_add_del_mreq_itr_rloc_args_t * a);
int vnet_lisp_clear_all_remote_mappings (void);
int vnet_lisp_eid_table_map (u32 vni, u32 vrf, u8 is_add);
#endif /* VNET_CONTROL_H_ */

View File

@ -15,6 +15,9 @@
#include <vnet/lisp-cp/lisp_types.h>
static u16 gid_address_put_no_vni (u8 * b, gid_address_t * gid);
static u16 gid_address_size_to_put_no_vni (gid_address_t * gid);
typedef u16 (*size_to_write_fct)(void *);
typedef void * (*cast_fct)(gid_address_t *);
typedef u16 (*serdes_fct)(u8 *, void *);
@ -155,7 +158,8 @@ format_gid_address (u8 * s, va_list * args)
switch (type)
{
case GID_ADDR_IP_PREFIX:
return format (s, "%U", format_ip_prefix, &gid_address_ippref(a));
return format (s, "[%d] %U", gid_address_vni(a), format_ip_prefix,
&gid_address_ippref(a));
default:
clib_warning("Can't format gid type %d", type);
return 0;
@ -335,16 +339,17 @@ lcaf_hdr_parse (void * offset, lcaf_t * lcaf)
u16
vni_parse (u8 * p, void * a)
{
vni_t * v = a;
lcaf_t * lcaf = a;
gid_address_t * g = a;
u16 size = 0;
vni_vni (v) = clib_net_to_host_u32 ( *(u32 *) p);
gid_address_vni (g) = clib_net_to_host_u32 ( *(u32 *) p);
size += sizeof (u32);
gid_address_vni_mask (g) = lcaf_vni_len (lcaf);
vni_gid (v) = clib_mem_alloc (sizeof (gid_address_t));
gid_address_t * gid = vni_gid (v);
memset (gid, 0, sizeof (gid[0]));
size += gid_address_parse (p + size, gid);
/* nested LCAFs are not supported - it is expected that nested AFI type is
IP address */
size += gid_address_parse (p + size, g);
return size;
}
@ -448,9 +453,11 @@ ip_prefix_size_to_write (void * pref)
}
u16
ip_prefix_write (u8 * p, void * pref)
ip_prefix_write (u8 * p, void * gid)
{
ip_prefix_t *a = (ip_prefix_t *) pref;
gid_address_t * g = gid;
ip_prefix_t *a = &gid_address_ippref (g);
switch (ip_prefix_version (a))
{
case IP4:
@ -581,9 +588,6 @@ lcaf_write (u8 * p, void * a)
u16 lcaf_len = (*lcaf_body_length_fcts[type])(lcaf);
LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
if (LCAF_INSTANCE_ID == type)
LCAF_RES2 (h) = lcaf_vni_len(lcaf);
clib_memcpy (p + size, h, sizeof (h[0]));
size += sizeof (h[0]);
len = (*lcaf_write_fcts[type])(p + size, lcaf);
@ -605,12 +609,30 @@ mac_write (u8 * p, void * a)
u16
vni_write (u8 * p, void * a)
{
vni_t * v = a;
lcaf_hdr_t _h, *h = &_h;
gid_address_t * g = a;
u16 size = 0, len;
*(u32 *)p = clib_host_to_net_u32 (vni_vni (v));
/* put lcaf header */
*(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
size += sizeof (u16);
memset (h, 0, sizeof (h[0]));
LCAF_TYPE (h) = LCAF_INSTANCE_ID;
u16 lcaf_len = sizeof (u32) /* Instance ID size */
+ gid_address_size_to_put_no_vni (g);
LCAF_LENGTH (h) = clib_host_to_net_u16 (lcaf_len);
LCAF_RES2 (h) = gid_address_vni_mask (g);
/* put vni header */
clib_memcpy (p + size, h, sizeof (h[0]));
size += sizeof (h[0]);
u32 * afip = (u32 *)(p + size);
afip[0] = clib_host_to_net_u32 (gid_address_vni (g));
size += sizeof (u32);
len = gid_address_put (p + size, vni_gid (v));
/* write the actual address */
len = gid_address_put_no_vni (p + size, g);
if ((u16)~0 == len)
return ~0;
@ -634,12 +656,11 @@ no_addr_size_to_write (void * a)
u16
vni_size_to_write (void * a)
{
vni_t * v = a;
u16 size = sizeof (vni_vni (v));
gid_address_t * gid = vni_gid (v);
return (size + sizeof (lcaf_hdr_t)
+ gid_address_size_to_put (gid));
gid_address_t * g = a;
return (sizeof (u32) /* vni size */
+ sizeof (u16) /* LCAF AFI field size */
+ sizeof (lcaf_hdr_t)
+ gid_address_size_to_put_no_vni (g));
}
u16
@ -671,20 +692,38 @@ gid_address_len (gid_address_t *a)
return (*addr_len_fcts[type])((*cast_fcts[type])(a));
}
u16
gid_address_put (u8 * b, gid_address_t * gid)
static u16
gid_address_put_no_vni (u8 * b, gid_address_t * gid)
{
gid_address_type_t type = gid_address_type (gid);
return (*write_fcts[type])(b, (*cast_fcts[type])(gid));
}
u16
gid_address_size_to_put (gid_address_t * gid)
gid_address_put (u8 * b, gid_address_t * gid)
{
if (0 != gid_address_vni (gid))
return vni_write (b, gid);
return gid_address_put_no_vni (b, gid);
}
static u16
gid_address_size_to_put_no_vni (gid_address_t * gid)
{
gid_address_type_t type = gid_address_type (gid);
return (*size_to_write_fcts[type])((*cast_fcts[type])(gid));
}
u16
gid_address_size_to_put (gid_address_t * gid)
{
if (0 != gid_address_vni (gid))
return vni_size_to_write (gid);
return gid_address_size_to_put_no_vni (gid);
}
void *
gid_address_cast (gid_address_t * gid, gid_address_type_t type)
{
@ -697,6 +736,8 @@ gid_address_copy(gid_address_t * dst, gid_address_t * src)
gid_address_type_t type = gid_address_type(src);
(*copy_fcts[type])((*cast_fcts[type])(dst), (*cast_fcts[type])(src));
gid_address_type(dst) = type;
gid_address_vni(dst) = gid_address_vni(src);
gid_address_vni_mask(dst) = gid_address_vni_mask(src);
}
u32
@ -739,8 +780,8 @@ gid_address_parse (u8 * offset, gid_address_t *a)
gid_address_ippref_len(a) = 128;
break;
case LISP_AFI_LCAF:
len = lcaf_parse (offset, a);
gid_address_type(a) = GID_ADDR_LCAF;
len = lcaf_parse (offset, a);
break;
case LISP_AFI_MAC:
len = mac_parse (offset, a);
@ -788,6 +829,10 @@ gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
return -1;
if (gid_address_type(a1) != gid_address_type(a2))
return -1;
if (gid_address_vni(a1) != gid_address_vni(a2))
return -1;
if (gid_address_vni_mask(a1) != gid_address_vni_mask(a2))
return -1;
switch (gid_address_type(a1))
{

View File

@ -79,6 +79,14 @@ typedef enum
struct _gid_address_t;
typedef struct
{
u8 src_len;
u8 dst_len;
struct _gid_address_t *src;
struct _gid_address_t *dst;
} source_dest_t;
typedef struct
{
u8 vni_mask_len;
@ -90,14 +98,6 @@ typedef struct
#define vni_mask_len(_a) (_a)->vni_mask_len
#define vni_gid(_a) (_a)->gid_addr
typedef struct
{
u8 src_len;
u8 dst_len;
struct _gid_address_t *src;
struct _gid_address_t *dst;
} source_dest_t;
typedef struct
{
/* the union needs to be at the beginning! */
@ -112,7 +112,6 @@ typedef struct
#define lcaf_type(_a) (_a)->type
#define lcaf_vni(_a) vni_vni(& (_a)->uni)
#define lcaf_vni_len(_a) vni_mask_len(& (_a)->uni)
#define lcaf_gid (_a) vni_gid(& (_a)->uni)
/* might want to expand this in the future :) */
typedef struct _gid_address_t
@ -124,6 +123,8 @@ typedef struct _gid_address_t
u8 mac[6];
};
u8 type;
u32 vni;
u8 vni_mask;
} gid_address_t;
u8 * format_ip_address (u8 * s, va_list * args);
@ -169,11 +170,8 @@ u32 gid_address_parse (u8 * offset, gid_address_t *a);
#define gid_address_ip_version(_a) ip_addr_version(&gid_address_ip(_a))
#define gid_address_lcaf(_a) (_a)->lcaf
#define gid_address_mac(_a) (_a)->mac
#define gid_address_vni(_a) ( (GID_ADDR_LCAF == gid_address_type(_a)) ? \
lcaf_vni(&gid_address_lcaf(_a)) : 0)
/* setter for vni */
#define gid_address_set_vni(_a, _val) \
(lcaf_vni(&gid_address_lcaf(_a)) = (_val))
#define gid_address_vni(_a) (_a)->vni
#define gid_address_vni_mask(_a) (_a)->vni_mask
/* 'sub'address functions */
#define foreach_gid_address_type_fcns \
@ -235,4 +233,6 @@ typedef struct
u8 local;
} mapping_t;
lcaf_t lcaf_iid_init (u32 vni);
#endif /* VNET_LISP_GPE_LISP_TYPES_H_ */

View File

@ -180,8 +180,10 @@ lisp_gpe_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
/* map iid/vni to lisp-gpe sw_if_index which is used by ipx_input to
* decide the rx vrf and the input features to be applied */
si0 = hash_get(lgm->tunnel_term_sw_if_index_by_vni, lh0->iid);
si1 = hash_get(lgm->tunnel_term_sw_if_index_by_vni, lh1->iid);
si0 = hash_get(lgm->tunnel_term_sw_if_index_by_vni,
clib_net_to_host_u32 (lh0->iid));
si1 = hash_get(lgm->tunnel_term_sw_if_index_by_vni,
clib_net_to_host_u32 (lh1->iid));
if (si0)
{
@ -297,7 +299,8 @@ lisp_gpe_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
/* map iid/vni to lisp-gpe sw_if_index which is used by ipx_input to
* decide the rx vrf and the input features to be applied */
si0 = hash_get(lgm->tunnel_term_sw_if_index_by_vni, lh0->iid);
si0 = hash_get(lgm->tunnel_term_sw_if_index_by_vni,
clib_net_to_host_u32 (lh0->iid));
if (si0)
{

View File

@ -135,6 +135,13 @@ add_del_ip_tunnel (vnet_lisp_gpe_add_del_fwd_entry_args_t *a,
ip_address_copy(&t->src, &a->slocator);
ip_address_copy(&t->dst, &a->dlocator);
/* if vni is non-default */
if (a->vni)
{
t->flags = LISP_GPE_FLAGS_I;
t->vni = a->vni;
}
t->flags |= LISP_GPE_FLAGS_P;
t->next_protocol = ip_prefix_version(&key.eid) == IP4 ?
LISP_GPE_NEXT_PROTO_IP4 : LISP_GPE_NEXT_PROTO_IP6;

View File

@ -1984,7 +1984,8 @@ vl_api_lisp_local_eid_table_details_t_handler (
vat_main_t *vam = &vat_main;
u8 *prefix;
prefix = format(0, "%U/%d",
prefix = format(0, "[&d] %U/%d",
clib_net_to_host_u32 (mp->vni),
mp->eid_is_ipv6 ? format_ip6_address : format_ip4_address,
mp->eid_ip_address,
mp->eid_prefix_len);
@ -2019,6 +2020,7 @@ vl_api_lisp_local_eid_table_details_t_handler_json (
clib_memcpy(&ip4, mp->eid_ip_address, sizeof(ip4));
vat_json_object_add_ip4(node, "eid address", ip4);
}
vat_json_object_add_uint(node, "vni", clib_net_to_host_u32 (mp->vni));
vat_json_object_add_uint(node, "eid prefix len", mp->eid_prefix_len);
}
@ -2449,6 +2451,7 @@ _(lisp_gpe_add_del_iface_reply) \
_(lisp_enable_disable_reply) \
_(lisp_pitr_set_locator_set_reply) \
_(lisp_add_del_map_request_itr_rlocs_reply) \
_(lisp_eid_table_add_del_map_reply) \
_(vxlan_gpe_add_del_tunnel_reply) \
_(af_packet_delete_reply) \
_(policer_add_del_reply) \
@ -2627,6 +2630,7 @@ _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \
_(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \
_(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply) \
_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
_(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details) \
@ -9910,11 +9914,14 @@ api_lisp_add_del_local_eid(vat_main_t * vam)
u8 eid_lenght = ~0;
u8 *locator_set_name = NULL;
u8 locator_set_name_set = 0;
u32 vni = 0;
/* Parse args required to build the message */
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
if (unformat(input, "del")) {
is_add = 0;
} else if (unformat(input, "vni &d", &vni)) {
;
} else if (unformat(input, "eid %U/%d", unformat_ip4_address,
&eidv4, &tmp_eid_lenght)) {
eid_lenght = tmp_eid_lenght;
@ -9977,6 +9984,7 @@ api_lisp_add_del_local_eid(vat_main_t * vam)
clib_memcpy(mp->ip_address, &eidv4, sizeof(eidv4));
}
mp->prefix_len = eid_lenght;
mp->vni = clib_host_to_net_u32(vni);
clib_memcpy(mp->locator_set_name, locator_set_name,
vec_len(locator_set_name));
vec_free(locator_set_name);
@ -10298,6 +10306,53 @@ api_lisp_pitr_set_locator_set (vat_main_t * vam)
return 0;
}
/**
* Add/delete mapping between vni and vrf
*/
static int
api_lisp_eid_table_add_del_map (vat_main_t * vam)
{
f64 timeout = ~0;
unformat_input_t * input = vam->input;
vl_api_lisp_eid_table_add_del_map_t *mp;
u8 is_add = 1, vni_set = 0, vrf_set = 0;
u32 vni, vrf;
/* Parse args required to build the message */
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "del"))
is_add = 0;
else if (unformat(input, "vrf %d", &vrf))
vrf_set = 1;
else if (unformat(input, "vni %d", &vni))
vni_set = 1;
else
break;
}
if (!vni_set || !vrf_set)
{
errmsg ("missing arguments!");
return -99;
}
M(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
mp->is_add = is_add;
mp->vni = htonl (vni);
mp->vrf = htonl (vrf);
/* send */
S;
/* wait for reply */
W;
/* notreached*/
return 0;
}
/**
* Add/del remote mapping from LISP control plane and updates
* forwarding entries in data-plane accordingly.
@ -11447,6 +11502,7 @@ _(lisp_add_del_remote_mapping, "add|del vni <vni> table-id <id> " \
"[rloc <loc> ... ]") \
_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
_(lisp_locator_set_dump, "") \
_(lisp_local_eid_table_dump, "") \
_(lisp_gpe_tunnel_dump, "") \

View File

@ -334,10 +334,12 @@ _(LISP_ENABLE_DISABLE, lisp_enable_disable) \
_(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface) \
_(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping) \
_(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set) \
_(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map) \
_(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump) \
_(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump) \
_(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump) \
_(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump) \
_(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump) \
_(LISP_ENABLE_DISABLE_STATUS_DUMP, \
lisp_enable_disable_status_dump) \
_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, \
@ -4770,6 +4772,7 @@ vl_api_lisp_add_del_local_eid_t_handler(
u32 locator_set_index = ~0, map_index = ~0;
vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
u8 *name = NULL;
memset (a, 0, sizeof (a[0]));
prefp = &gid_address_ippref(&eid);
ip_eid = &ip_prefix_addr(prefp);
@ -4796,18 +4799,30 @@ vl_api_lisp_add_del_local_eid_t_handler(
/* XXX treat batch configuration */
a->is_add = mp->is_add;
gid_address_vni (&eid) = clib_net_to_host_u32 (mp->vni);
a->deid = eid;
a->locator_set_index = locator_set_index;
a->local = 1;
rv = vnet_lisp_add_del_local_mapping(a, &map_index);
out:
vec_free(name);
gid_address_free (&a->deid);
REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
}
static void
vl_api_lisp_eid_table_add_del_map_t_handler(
vl_api_lisp_eid_table_add_del_map_t *mp)
{
vl_api_lisp_eid_table_add_del_map_reply_t *rmp;
int rv = 0;
rv = vnet_lisp_eid_table_map (clib_net_to_host_u32 (mp->vni),
clib_net_to_host_u32 (mp->vrf), mp->is_add);
REPLY_MACRO(VL_API_LISP_EID_TABLE_ADD_DEL_MAP_REPLY)
}
static void
lisp_gpe_add_del_fwd_entry_set_address(
vl_api_lisp_gpe_add_del_fwd_entry_t *mp,
@ -5019,8 +5034,8 @@ vl_api_lisp_add_del_remote_mapping_t_handler (
ip_address_t * deid_addr = &ip_prefix_addr(deid_pref);
ip_prefix_len(seid_pref) = mp->seid_len;
ip_prefix_len(deid_pref) = mp->deid_len;
gid_address_set_vni (seid, ntohl (mp->vni));
gid_address_set_vni (deid, ntohl (mp->vni));
gid_address_vni (seid) = ntohl (mp->vni);
gid_address_vni (deid) = ntohl (mp->vni);
if (mp->eid_is_ip4) {
ip_prefix_version(seid_pref) = IP4;
@ -5172,7 +5187,7 @@ send_lisp_local_eid_table_details (mapping_t *mapit,
}
rmp->eid_prefix_len = ip_prefix_len(ip_prefix);
rmp->context = context;
rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
vl_msg_api_send_shmem (q, (u8 *)&rmp);
}
@ -5229,7 +5244,7 @@ send_lisp_gpe_tunnel_details (lisp_gpe_tunnel_t *tunnel,
static void
vl_api_lisp_gpe_tunnel_dump_t_handler (
vl_api_lisp_local_eid_table_dump_t *mp)
vl_api_lisp_gpe_tunnel_dump_t *mp)
{
unix_shared_memory_queue_t * q = NULL;
lisp_gpe_main_t * lgm = &lisp_gpe_main;
@ -5299,6 +5314,28 @@ vl_api_lisp_map_resolver_dump_t_handler (
}
static void
vl_api_lisp_eid_table_map_dump_t_handler (
vl_api_lisp_eid_table_map_dump_t *mp)
{
unix_shared_memory_queue_t * q = NULL;
lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
hash_pair_t * p;
q = vl_api_client_index_to_input_queue (mp->client_index);
if (q == 0) {
return;
}
hash_foreach_pair (p, lcm->table_id_by_vni, {
vl_api_lisp_eid_table_map_details_t * rmp = NULL;
memset (rmp, 0, sizeof (*rmp));
rmp->_vl_msg_id = ntohs(VL_API_LISP_EID_TABLE_MAP_DETAILS);
rmp->vni = p->key;
rmp->vrf = p->value[0];
rmp->context = mp->context;
});
}
static void
send_lisp_enable_disable_details (unix_shared_memory_queue_t *q,
u32 context)

View File

@ -2205,6 +2205,7 @@ define lisp_add_del_locator_reply {
@param ip_address - array of address bytes
@param prefix_len - prefix len
@param locator_set_name - name of locator_set to add/del eid-table
@param vni - vitual network instance
*/
define lisp_add_del_local_eid {
u32 client_index;
@ -2214,6 +2215,7 @@ define lisp_add_del_local_eid {
u8 ip_address[16];
u8 prefix_len;
u8 locator_set_name[64];
u32 vni;
};
/** \brief Reply for local_eid add/del
@ -2427,6 +2429,30 @@ define lisp_add_del_map_request_itr_rlocs_reply {
i32 retval;
};
/** \brief map/unmap vni to vrf
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param is_add - add or delete mapping
@param vni - virtual network id
@param vrf - vrf
*/
define lisp_eid_table_add_del_map {
u32 client_index;
u32 context;
u8 is_add;
u32 vni;
u32 vrf;
};
/** \brief Reply for lisp_eid_table_add_del_map
@param context - returned sender context, to match reply w/ request
@param retval - return code
*/
define lisp_eid_table_add_del_map_reply {
u32 context;
i32 retval;
};
/** \brief LISP locator_set status
@param locator_set_name - name of the locator_set
@param sw_if_index - sw_if_index of the locator
@ -2464,6 +2490,7 @@ manual_java define lisp_local_eid_table_details {
u32 context;
u8 locator_set_name[64];
u8 eid_is_ipv6;
u32 vni;
u8 eid_ip_address[16];
u8 eid_prefix_len;
};
@ -2477,6 +2504,25 @@ define lisp_local_eid_table_dump {
u32 context;
};
/** \brief Shows relationship between vni and vrf
@param vrf - VRF index
@param vni - vitual network instance
*/
manual_java define lisp_eid_table_map_details {
u32 context;
u32 vni;
u32 vrf;
};
/** \brief Request for lisp_eid_table_map_details
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
*/
define lisp_eid_table_map_dump {
u32 client_index;
u32 context;
};
manual_java define lisp_gpe_tunnel_details {
u32 context;
u32 tunnels;