#include <vnet/lisp-cp/lisp_msg_serdes.h>
#include <vnet/lisp-gpe/lisp_gpe.h>
-/* Adds mapping to map-cache but does NOT program LISP forwarding */
+/* Stores mapping in map-cache. It does NOT program data plane forwarding for
+ * remote/learned mappings. */
int
vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a,
u32 * map_index_result)
if (a->is_add)
{
/* TODO check if overwriting and take appropriate actions */
- if (mi != GID_LOOKUP_MISS) {
+ if (mi != GID_LOOKUP_MISS)
+ {
clib_warning("eid %U found in the eid-table", format_ip_address,
&a->deid);
return VNET_API_ERROR_VALUE_EXIST;
- }
+ }
pool_get(lcm->mapping_pool, m);
m->eid = a->deid;
{
/* mark as local */
vec_add1(lcm->local_mappings_indexes, map_index);
-
- /* XXX do something else? */
}
map_index_result[0] = map_index;
}
else
{
- if (mi == GID_LOOKUP_MISS) {
+ if (mi == GID_LOOKUP_MISS)
+ {
clib_warning("eid %U not found in the eid-table", format_ip_address,
&a->deid);
return VNET_API_ERROR_INVALID_VALUE;
- }
+ }
/* clear locator-set to eids binding */
eid_indexes = vec_elt_at_index(lcm->locator_set_to_eids,
return 0;
}
+/* Stores mapping in map-cache and programs data plane for local mappings. */
+int
+vnet_lisp_add_del_local_mapping (vnet_lisp_add_del_mapping_args_t * a,
+ u32 * map_index_result)
+{
+ uword * table_id, * refc;
+ u32 rv;
+ vnet_lisp_gpe_add_del_iface_args_t _ai, *ai = &_ai;
+ lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
+
+ /* store/remove mapping from map-cache */
+ rv = vnet_lisp_add_del_mapping (a, map_index_result);
+ if (rv)
+ return rv;
+
+ table_id = hash_get(lcm->table_id_by_vni, /* default for now */ 0);
+
+ if (!table_id)
+ {
+ clib_warning ("vni %d not associated to a vrf!", 0);
+ return VNET_API_ERROR_INVALID_VALUE;
+ }
+
+ refc = hash_get(lcm->dp_if_refcount_by_vni, 0);
+
+ /* enable/disable data-plane interface */
+ if (a->is_add)
+ {
+ /* create interface or update refcount */
+ if (!refc)
+ {
+ ai->is_add = 1;
+ ai->vni = 0; /* default for now, pass vni as parameter */
+ ai->table_id = table_id[0];
+ vnet_lisp_gpe_add_del_iface (ai, 0);
+ }
+ else
+ {
+ refc[0]++;
+ }
+ }
+ else
+ {
+ /* since this is a remove for an existing eid, the iface should exist */
+ ASSERT(refc != 0);
+ refc[0]--;
+
+ /* remove iface if needed */
+ if (refc[0] == 0)
+ {
+ ai->is_add = 0;
+ ai->vni = 0; /* default for now, pass vni as parameter */
+ ai->table_id = table_id[0];
+ vnet_lisp_gpe_add_del_iface (ai, 0);
+ }
+ }
+
+ return rv;
+}
+
static clib_error_t *
lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
a->locator_set_index = locator_set_index;
a->local = 1;
- vnet_lisp_add_del_mapping (a, &map_index);
+ vnet_lisp_add_del_local_mapping (a, &map_index);
done:
vec_free(eids);
return error;
VLIB_CLI_COMMAND (lisp_cp_add_del_locator_set_command) = {
.path = "lisp locator-set",
- .short_help = "lisp locator-set add/del <name> <iface-name> <priority> <weight>",
+ .short_help = "lisp locator-set add/del <name> iface <iface-name> "
+ "<priority> <weight>",
.function = lisp_add_del_locator_set_command_fn,
};
}
else if (l6)
{
- memcpy (&ip_addr_v6(sloc), l6, sizeof(*l6));
+ clib_memcpy (&ip_addr_v6(sloc), l6, sizeof(*l6));
ip_addr_version(sloc) = IP6;
}
else
else
{
ip6 = hdr;
- memcpy (&ip_addr_v6(src), &ip6->src_address, sizeof(ip6->src_address));
+ clib_memcpy (&ip_addr_v6(src), &ip6->src_address, sizeof(ip6->src_address));
ip_addr_version(src) = IP6;
- memcpy (&ip_addr_v6(dst), &ip6->dst_address, sizeof(ip6->dst_address));
+ clib_memcpy (&ip_addr_v6(dst), &ip6->dst_address, sizeof(ip6->dst_address));
ip_addr_version(dst) = IP6;
}
}
lisp_cp_lookup_trace_t *tr = vlib_add_trace (vm, node, p0,
sizeof(*tr));
gid_address_copy (&tr->dst_eid, &dst);
- memcpy (&tr->map_resolver_ip,
+ clib_memcpy (&tr->map_resolver_ip,
vec_elt_at_index(lcm->map_resolvers, 0),
sizeof(ip_address_t));
}
a->is_add = 0;
a->dlocator = fe->dst_loc;
a->slocator = fe->src_loc;
- a->iid = 0; // XXX should be part of mapping/eid
+ a->vni = 0; // XXX should be part of mapping/eid
gid_address_copy(&a->deid, &fe->deid);
vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
locator_set_t * dst_ls, * src_ls;
u32 i, minp = ~0;
locator_t * dl = 0;
- uword * feip = 0;
+ uword * feip = 0, * tidp;
vnet_lisp_gpe_add_del_fwd_entry_args_t _a, * a = &_a;
+
memset (a, 0, sizeof(*a));
/* remove entry if it already exists */
}
gid_address_copy (&a->deid, &dst_map->eid);
- a->iid = 0; // XXX should be part of mapping/eid
+ a->vni = 0; // XXX should be part of mapping/eid
+
+ tidp = hash_get(lcm->table_id_by_vni, a->vni);
+ if (!tidp)
+ {
+ clib_warning("vni %d not associated to a vrf!", a->vni);
+ return;
+ }
+ a->table_id = tidp[0];
+
u8 ipver = ip_prefix_version(&gid_address_ippref(&a->deid));
a->decap_next_index = (ipver == IP4) ?
LISP_GPE_INPUT_NEXT_IP4_INPUT : LISP_GPE_INPUT_NEXT_IP6_INPUT;
+
/* XXX tunnels work only with IP4 now */
vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
lcm->vnet_main = vnet_get_main();
gid_dictionary_init (&lcm->mapping_index_by_gid);
- gid_dictionary_init (&lcm->mapping_index_by_gid);
+
+ /* default vrf mapped to vni 0 */
+ hash_set(lcm->table_id_by_vni, 0, 0);
udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp,
lisp_cp_input_node.index, 1 /* is_ip4 */);