#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 */
+static void
+add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index);
+
+/* 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 -1;
- }
+ return VNET_API_ERROR_VALUE_EXIST;
+ }
pool_get(lcm->mapping_pool, m);
m->eid = a->deid;
{
clib_warning("Locator set with index %d doesn't exist",
a->locator_set_index);
- return -1;
+ return VNET_API_ERROR_INVALID_VALUE;
}
/* add eid to list of eids supported by locator-set */
{
/* mark as local */
vec_add1(lcm->local_mappings_indexes, map_index);
-
- /* XXX do something else? */
}
map_index_result[0] = map_index;
}
else
{
- if (mi != ~0) {
+ if (mi == GID_LOOKUP_MISS)
+ {
clib_warning("eid %U not found in the eid-table", format_ip_address,
&a->deid);
- return -1;
- }
+ 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, vni;
+ vnet_lisp_gpe_add_del_iface_args_t _ai, *ai = &_ai;
+ lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
+
+ vni = gid_address_vni(&a->deid);
+
+ /* 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, vni);
+
+ if (!table_id)
+ {
+ clib_warning ("vni %d not associated to a vrf!", vni);
+ return VNET_API_ERROR_INVALID_VALUE;
+ }
+
+ refc = hash_get(lcm->dp_if_refcount_by_vni, vni);
+
+ /* enable/disable data-plane interface */
+ if (a->is_add)
+ {
+ /* create interface or update refcount */
+ if (!refc)
+ {
+ ai->is_add = 1;
+ ai->vni = vni;
+ ai->table_id = table_id[0];
+ vnet_lisp_gpe_add_del_iface (ai, 0);
+
+ /* counts the number of eids in a vni that use the interface */
+ hash_set(lcm->dp_if_refcount_by_vni, vni, 1);
+ }
+ 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 = vni;
+ 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)
uword * p;
vnet_lisp_add_del_mapping_args_t _a, * a = &_a;
- gid_address_type (&eid) = IP_PREFIX;
+ gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
/* Get a line of input. */
if (! unformat_user (input, unformat_line_input, line_input))
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;
/* delete locator if it's part of no locator-set */
if (vec_len (ls_indexes[0]) == 0)
pool_put_index(lcm->locator_pool, loc_indexp[0]);
-
- /* remove from local locator-set vector */
- if (ls->local)
- {
- u32 k, *llocp;
- for (k = 0; k < vec_len(lcm->local_locator_set_indexes); k++)
- {
- llocp = vec_elt_at_index(lcm->local_locator_set_indexes, k);
- if (llocp[0] == lsi)
- break;
- }
- vec_del1(lcm->local_locator_set_indexes, k);
- }
}
}
int
locator_t * loc, * itloc;
uword _p = (u32)~0, * p = &_p;
u32 loc_index, ls_index, ** ls_indexes;
+ u32 **eid_indexes;
if (a->is_add)
{
// return -1;
// }
+ if (vec_len(lcm->locator_set_to_eids) != 0)
+ {
+ eid_indexes = vec_elt_at_index(lcm->locator_set_to_eids, p[0]);
+ if (vec_len(eid_indexes[0]) != 0)
+ {
+ clib_warning ("Can't delete a locator that supports a mapping!");
+ return -1;
+ }
+ }
+
+ /* clean locator to locator-sets data */
+ clean_locator_to_locator_set (lcm, p[0]);
+
+ if (ls->local)
+ {
+ u32 it, lsi;
+
+ vec_foreach_index(it, lcm->local_locator_set_indexes)
+ {
+ lsi = vec_elt(lcm->local_locator_set_indexes, it);
+ if (lsi == p[0])
+ {
+ vec_del1(lcm->local_locator_set_indexes, it);
+ break;
+ }
+ }
+ hash_unset_mem(lcm->locator_set_index_by_name, ls->name);
+ vec_free(ls->name);
+ }
+ pool_put(lcm->locator_set_pool, ls);
+ }
+ return 0;
+}
+
+static inline
+uword *vnet_lisp_get_locator(vnet_lisp_add_del_locator_set_args_t * a,
+ uword *p)
+{
+ lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
+
+ ASSERT(a != NULL);
+ ASSERT(p != NULL);
+
+ /* find locator-set */
+ if (a->local)
+ {
+ p = hash_get_mem(lcm->locator_set_index_by_name, a->name);
+ }
+ else
+ {
+ *p = a->index;
+ }
+
+ return p;
+}
+
+int
+vnet_lisp_add_del_locator_set_name (vnet_lisp_add_del_locator_set_args_t * a,
+ u32 * ls_result)
+{
+ lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
+ locator_set_t * ls;
+ uword _p = (u32)~0, * p = &_p;
+ u32 ls_index = ~0;
+ u32 **eid_indexes = NULL;
+
+ ASSERT(a != NULL);
+ ASSERT(ls_result != NULL);
+
+ p = vnet_lisp_get_locator(a, p);
+
+ if (a->is_add)
+ {
+ /* overwrite */
+ if (p && p[0] != (u32)~0)
+ {
+ ls = pool_elt_at_index(lcm->locator_set_pool, p[0]);
+ if (!ls)
+ {
+ clib_warning("locator-set %d to be overwritten doesn't exist!",
+ p[0]);
+ return VNET_API_ERROR_UNSPECIFIED;
+ }
+
+ /* clean locator to locator-set vectors and remove locators if
+ * they're not part of another locator-set */
+ clean_locator_to_locator_set (lcm, p[0]);
+
+ /* remove locator indices from locator set */
+ vec_free(ls->locator_indices);
+
+ ls_index = p[0];
+
+ if (ls_result)
+ ls_result[0] = p[0];
+ }
+ /* new locator-set */
+ else
+ {
+ pool_get(lcm->locator_set_pool, ls);
+ ls_index = ls - lcm->locator_set_pool;
+
+ if (a->local)
+ {
+ ls->name = vec_dup(a->name);
+
+ if (!lcm->locator_set_index_by_name)
+ lcm->locator_set_index_by_name = hash_create_vec(
+ /* size */0, sizeof(ls->name[0]), sizeof(uword));
+ hash_set_mem(lcm->locator_set_index_by_name, ls->name, ls_index);
+
+ /* mark as local locator-set */
+ vec_add1(lcm->local_locator_set_indexes, ls_index);
+ }
+ ls->local = a->local;
+ ls->locator_indices = NULL;
+ if (ls_result)
+ ls_result[0] = ls_index;
+ }
+ }
+ else
+ {
+ if (!p)
+ {
+ clib_warning("locator-set %v doesn't exists", a->name);
+ return VNET_API_ERROR_INVALID_ARGUMENT;
+ }
+
+ ls = pool_elt_at_index(lcm->locator_set_pool, p[0]);
+ if (!ls)
+ {
+ clib_warning("locator-set with index %d doesn't exists", p[0]);
+ return VNET_API_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (vec_len(lcm->locator_set_to_eids) != 0)
+ {
+ eid_indexes = vec_elt_at_index(lcm->locator_set_to_eids, p[0]);
+ if (vec_len(eid_indexes[0]) != 0)
+ {
+ clib_warning ("Can't delete a locator that supports a mapping!");
+ return -1;
+ }
+ }
+
/* clean locator to locator-sets data */
clean_locator_to_locator_set (lcm, p[0]);
return 0;
}
+int
+vnet_lisp_add_del_locator (vnet_lisp_add_del_locator_set_args_t *a,
+ u32 *ls_result)
+{
+ lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
+ locator_set_t *ls = NULL;
+ locator_t *loc = NULL, *itloc = NULL;
+ uword _p = (u32)~0, * p = &_p;
+ u32 loc_index = ~0, ls_index = ~0, *locit = NULL, **ls_indexes = NULL;
+ u32 i = ~0;
+
+ ASSERT(a != NULL);
+ ASSERT(ls_result != NULL);
+
+ p = vnet_lisp_get_locator(a, p);
+ if (!p) {
+ clib_warning("locator-set %v doesn't exists", a->name);
+ return VNET_API_ERROR_INVALID_ARGUMENT;
+ }
+
+ ls_index = p[0];
+
+ if (a->is_add)
+ {
+ ls = pool_elt_at_index(lcm->locator_set_pool, p[0]);
+ if (!ls)
+ {
+ clib_warning("locator-set %d to be overwritten doesn't exist!",
+ p[0]);
+ return VNET_API_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (ls_result)
+ ls_result[0] = p[0];
+
+ /* allocate locators */
+ itloc = a->locators;
+ pool_get(lcm->locator_pool, loc);
+ loc[0] = itloc[0];
+ loc_index = loc - lcm->locator_pool;
+
+ vec_add1(ls->locator_indices, loc_index);
+
+ vec_validate (lcm->locator_to_locator_sets, loc_index);
+ ls_indexes = vec_elt_at_index(lcm->locator_to_locator_sets,
+ loc_index);
+ vec_add1(ls_indexes[0], ls_index);
+ }
+ else
+ {
+ ls = pool_elt_at_index(lcm->locator_set_pool, p[0]);
+ if (!ls)
+ {
+ clib_warning("locator-set with index %d doesn't exists", p[0]);
+ return VNET_API_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (ls->local)
+ {
+ itloc = a->locators;
+ i = 0;
+ vec_foreach (locit, ls->locator_indices)
+ {
+ loc = pool_elt_at_index(lcm->locator_pool, locit[0]);
+ if (loc->local && loc->sw_if_index == itloc->sw_if_index)
+ {
+ ls_indexes = vec_elt_at_index(lcm->locator_to_locator_sets,
+ locit[0]);
+ pool_put_index(lcm->locator_pool, locit[0]);
+ vec_del1(ls->locator_indices, i);
+ vec_del1(ls_indexes[0], ls_index);
+ }
+ i++;
+ }
+ }
+ }
+ return 0;
+}
+
+clib_error_t *
+vnet_lisp_enable_disable (u8 is_enabled)
+{
+ vnet_lisp_gpe_add_del_iface_args_t _ai, * ai= &_ai;
+ uword * table_id, * refc;
+ u32 i;
+ clib_error_t * error = 0;
+ lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
+ vnet_lisp_gpe_enable_disable_args_t _a, * a = &_a;
+
+ a->is_en = is_enabled;
+ error = vnet_lisp_gpe_enable_disable (a);
+ if (error)
+ {
+ return clib_error_return (0, "failed to %s data-plane!",
+ a->is_en ? "enable" : "disable");
+ }
+
+ if (is_enabled)
+ {
+ /* enable all ifaces */
+ for (i = 0; i < vec_len (lcm->local_mappings_indexes); i++)
+ {
+ mapping_t * m = vec_elt_at_index (lcm->mapping_pool, i);
+ ai->is_add = 1;
+ ai->vni = gid_address_vni (&m->eid);
+
+ refc = hash_get (lcm->dp_if_refcount_by_vni, ai->vni);
+ if (!refc)
+ {
+ table_id = hash_get (lcm->table_id_by_vni, ai->vni);
+ if (table_id)
+ {
+ ai->table_id = table_id[0];
+ /* enables interface and adds defaults */
+ vnet_lisp_gpe_add_del_iface (ai, 0);
+ }
+ else
+ return clib_error_return (0, "no table_id found for vni %u!",
+ ai->vni);
+
+ hash_set (lcm->dp_if_refcount_by_vni, ai->vni, 1);
+ }
+ else
+ {
+ refc[0]++;
+ }
+ }
+ }
+ else
+ {
+ /* clear refcount table */
+ hash_free (lcm->dp_if_refcount_by_vni);
+ hash_free (lcm->fwd_entry_by_mapping_index);
+ pool_free (lcm->fwd_entry_pool);
+ }
+
+ /* update global flag */
+ lcm->is_enabled = is_enabled;
+
+ return 0;
+}
+
+static clib_error_t *
+lisp_enable_disable_command_fn (vlib_main_t * vm, unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ unformat_input_t _line_input, * line_input = &_line_input;
+ u8 is_enabled = 0;
+ u8 is_set = 0;
+
+ /* 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, "enable"))
+ {
+ is_set = 1;
+ is_enabled = 1;
+ }
+ else if (unformat (line_input, "disable"))
+ is_set = 1;
+ else
+ {
+ return clib_error_return (0, "parse error: '%U'",
+ format_unformat_error, line_input);
+ }
+ }
+
+ if (!is_set)
+ return clib_error_return (0, "state not set");
+
+ return vnet_lisp_enable_disable (is_enabled);
+}
+
+VLIB_CLI_COMMAND (lisp_cp_enable_disable_command) = {
+ .path = "lisp",
+ .short_help = "lisp [enable|disable]",
+ .function = lisp_enable_disable_command_fn,
+};
+
+u8
+vnet_lisp_enable_disable_status (void)
+{
+ lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
+ return lcm->is_enabled;
+}
+
+static u8 *
+format_lisp_status (u8 * s, va_list * args)
+{
+ lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
+ return format (s, "%s", lcm->is_enabled ? "enabled" : "disabled");
+}
+
+static clib_error_t *
+lisp_show_status_command_fn (vlib_main_t * vm, unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ u8 * msg = 0;
+ msg = format (msg, "feature: %U\ngpe: %U\n",
+ format_lisp_status, format_vnet_lisp_gpe_status);
+ vlib_cli_output (vm, "%v", msg);
+ vec_free (msg);
+ return 0;
+}
+
+VLIB_CLI_COMMAND (lisp_show_status_command) = {
+ .path = "show lisp status",
+ .short_help = "show lisp status",
+ .function = lisp_show_status_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)
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,
};
lisp_cp_lookup_trace_t * t = va_arg (*args, lisp_cp_lookup_trace_t *);
s = format (s, "LISP-CP-LOOKUP: map-resolver: %U destination eid %U",
- format_ip4_address, &t->map_resolver_ip, format_gid_address,
+ format_ip_address, &t->map_resolver_ip, format_gid_address,
&t->dst_eid);
return s;
}
u32 adj_index;
ip_adjacency_t * adj;
ip_interface_address_t * ia = 0;
- ip_lookup_main_t * lm = &lcm->im4->lookup_main;
+ ip_lookup_main_t * lm;
ip4_address_t * l4 = 0;
ip6_address_t * l6 = 0;
+ lm = ip_addr_version (dst) == IP4 ?
+ &lcm->im4->lookup_main : &lcm->im6->lookup_main;
+
adj_index = ip_fib_lookup_with_table (lcm, 0, dst);
adj = ip_get_adjacency (lm, adj_index);
}
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
}
}
+
+static gid_address_t *
+build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set)
+{
+ ip4_address_t * l4;
+ ip6_address_t * l6;
+ u32 i;
+ locator_t * loc;
+ u32 * loc_indexp;
+ ip_interface_address_t * ia = 0;
+ gid_address_t gid_data, * gid = &gid_data;
+ gid_address_t * rlocs = 0;
+ ip_prefix_t * ippref = &gid_address_ippref (gid);
+ ip_address_t * rloc = &ip_prefix_addr (ippref);
+
+ gid_address_type (gid) = GID_ADDR_IP_PREFIX;
+ for (i = 0; i < vec_len(loc_set->locator_indices); i++)
+ {
+ loc_indexp = vec_elt_at_index(loc_set->locator_indices, i);
+ loc = pool_elt_at_index (lcm->locator_pool, loc_indexp[0]);
+
+ ip_addr_version(rloc) = IP4;
+ /* Add ipv4 locators first TODO sort them */
+ foreach_ip_interface_address (&lcm->im4->lookup_main, ia,
+ loc->sw_if_index, 1 /* unnumbered */,
+ ({
+ l4 = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
+ ip_addr_v4 (rloc) = l4[0];
+ vec_add1 (rlocs, gid[0]);
+ }));
+
+ ip_addr_version(rloc) = IP6;
+ /* Add ipv6 locators */
+ foreach_ip_interface_address (&lcm->im6->lookup_main, ia,
+ loc->sw_if_index, 1 /* unnumbered */,
+ ({
+ l6 = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
+ ip_addr_v6 (rloc) = l6[0];
+ vec_add1 (rlocs, gid[0]);
+ }));
+ }
+ return rlocs;
+}
+
static vlib_buffer_t *
build_encapsulated_map_request (vlib_main_t * vm, lisp_cp_main_t *lcm,
gid_address_t * seid, gid_address_t * deid,
vlib_buffer_t * b;
u32 bi;
ip_address_t * mr_ip, sloc;
+ gid_address_t * rlocs = 0;
if (vlib_buffer_alloc (vm, &bi, 1) != 1)
{
/* leave some space for the encap headers */
vlib_buffer_make_headroom (b, MAX_LISP_MSG_ENCAP_LEN);
+ /* get rlocs */
+ rlocs = build_itr_rloc_list (lcm, loc_set);
+
/* put lisp msg */
- lisp_msg_put_mreq (lcm, b, seid, deid, loc_set, is_smr_invoked, nonce_res);
+ lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked, nonce_res);
/* push ecm: udp-ip-lisp */
lisp_msg_push_ecm (vm, b, LISP_CONTROL_PORT, LISP_CONTROL_PORT, seid, deid);
mr_ip);
bi_res[0] = bi;
+
+ if (rlocs)
+ vec_free(rlocs);
return b;
}
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 (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
{
- u32 * from, * to_next_drop;
+ u32 * from, * to_next_drop, di, si;
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main();
u32 pkts_mapped = 0;
uword n_left_from, n_left_to_next_drop;
gid_address_t src, dst;
ip_prefix_t * spref, * dpref;
- gid_address_type (&src) = IP_PREFIX;
+ gid_address_type (&src) = GID_ADDR_IP_PREFIX;
spref = &gid_address_ippref(&src);
- gid_address_type (&dst) = IP_PREFIX;
+ gid_address_type (&dst) = GID_ADDR_IP_PREFIX;
dpref = &gid_address_ippref(&dst);
pi0 = from[0];
ip_prefix_len(spref) = ip_address_max_len (ip_prefix_version(spref));
ip_prefix_len(dpref) = ip_address_max_len (ip_prefix_version(dpref));
- /* send map-request */
- send_encapsulated_map_request (vm, lcm, &src, &dst, 0);
-
- pkts_mapped++;
+ /* 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);
+ if (~0 != di)
+ {
+ si = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &src);
+ if (~0 != si)
+ {
+ add_fwd_entry (lcm, si, di);
+ }
+ }
+ else
+ {
+ /* send map-request */
+ send_encapsulated_map_request (vm, lcm, &src, &dst, 0);
+ pkts_mapped++;
+ }
if (PREDICT_FALSE(p0->flags & VLIB_BUFFER_IS_TRACED))
{
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 = gid_address_vni(&a->deid);
gid_address_copy(&a->deid, &fe->deid);
vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
pool_put(lcm->fwd_entry_pool, fe);
}
-void
+static void
add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
{
mapping_t * src_map, * dst_map;
locator_set_t * dst_ls, * src_ls;
- u32 i, minp = ~0;
+ u32 i, minp = ~0, sw_if_index;
locator_t * dl = 0;
- uword * feip = 0;
+ uword * feip = 0, * tidp;
+ fwd_entry_t* fe;
vnet_lisp_gpe_add_del_fwd_entry_args_t _a, * a = &_a;
+
memset (a, 0, sizeof(*a));
/* remove entry if it already exists */
src_map = pool_elt_at_index (lcm->mapping_pool, src_map_index);
dst_map = pool_elt_at_index (lcm->mapping_pool, dst_map_index);
+ gid_address_copy (&a->deid, &dst_map->eid);
+ a->vni = gid_address_vni(&a->deid);
+
+ 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];
+
/* XXX simple forwarding policy: first lowest (value) priority locator */
dst_ls = pool_elt_at_index (lcm->locator_set_pool,
dst_map->locator_set_index);
{
u32 li = vec_elt (dst_ls->locator_indices, i);
locator_t * l = pool_elt_at_index (lcm->locator_pool, li);
- if (l->priority < minp && gid_address_type(&l->address) == IP_PREFIX)
+ if (l->priority < minp && gid_address_type(&l->address)
+ == GID_ADDR_IP_PREFIX)
{
minp = l->priority;
dl = l;
}
if (dl)
{
- src_ls = pool_elt_at_index (lcm->locator_set_pool,
- src_map->locator_set_index);
- for (i = 0; i < vec_len (src_ls->locator_indices); i++)
+ src_ls = pool_elt_at_index(lcm->locator_set_pool,
+ src_map->locator_set_index);
+ for (i = 0; i < vec_len(src_ls->locator_indices); i++)
{
u32 li = vec_elt (src_ls->locator_indices, i);
locator_t * sl = pool_elt_at_index (lcm->locator_pool, li);
}
}
}
+
/* insert data plane forwarding entry */
- u32 sw_if_index;
a->is_add = 1;
if (dl)
a->dlocator = gid_address_ip(&dl->address);
a->action = dst_map->action;
}
- gid_address_copy (&a->deid, &dst_map->eid);
- a->iid = 0; // XXX should be part of mapping/eid
+ /* TODO remove */
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);
/* add tunnel to fwd entry table XXX check return value from DP insertion */
- fwd_entry_t* fe;
pool_get (lcm->fwd_entry_pool, fe);
fe->dst_loc = a->dlocator;
fe->src_loc = a->slocator;
void
process_map_reply (lisp_cp_main_t * lcm, vlib_buffer_t * b)
{
+ locator_t * loc;
u32 len = 0, i, ls_index = 0;
void * h;
vnet_lisp_add_del_locator_set_args_t _ls_arg, * ls_arg = &_ls_arg;
if (len == ~0)
{
clib_warning ("Failed to parse mapping record!");
+ vec_foreach (loc, ls_arg->locators)
+ {
+ locator_free (loc);
+ }
vec_free(ls_arg->locators);
return;
}
gid_address_t src, dst;
// u64 nonce;
u32 i, len = 0;
- gid_address_t * itr_rlocs = 0;
+ gid_address_t * itr_rlocs = 0, * rloc;
mreq_hdr = vlib_buffer_get_current (b);
vlib_buffer_pull (b, sizeof(*mreq_hdr));
if (len == ~0)
return;
+ /* TODO: RLOCs are currently unused, so free them for now */
+ vec_foreach (rloc, itr_rlocs)
+ {
+ gid_address_free (rloc);
+ }
+
/* parse eid records and send SMR-invoked map-requests */
for (i = 0; i < MREQ_REC_COUNT(mreq_hdr); i++)
{
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 */);