u8 smr_invoked;
} map_request_args_t;
+u8
+vnet_lisp_get_map_request_mode (void)
+{
+ lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
+ return lcm->map_request_mode;
+}
+
static int
queue_map_request (gid_address_t * seid, gid_address_t * deid,
u8 smr_invoked, u8 is_resend);
u32 sw_if_index;
a->is_add = 0;
a->locator_pairs = fe->locator_pairs;
- a->vni = gid_address_vni (&fe->deid);
- gid_address_copy (&a->rmt_eid, &fe->deid);
+ a->vni = gid_address_vni (&fe->reid);
+ gid_address_copy (&a->rmt_eid, &fe->reid);
vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
return found;
}
+static void
+gid_address_sd_to_flat (gid_address_t * dst, gid_address_t * src,
+ fid_address_t * fid)
+{
+ ASSERT (GID_ADDR_SRC_DST == gid_address_type (src));
+
+ dst[0] = src[0];
+
+ switch (fid_addr_type (fid))
+ {
+ case FID_ADDR_IP_PREF:
+ gid_address_type (dst) = GID_ADDR_IP_PREFIX;
+ gid_address_ippref (dst) = fid_addr_ippref (fid);
+ break;
+ case FID_ADDR_MAC:
+ gid_address_type (dst) = GID_ADDR_MAC;
+ mac_copy (gid_address_mac (dst), fid_addr_mac (fid));
+ break;
+ default:
+ clib_warning ("Unsupported fid type %d!", fid_addr_type (fid));
+ break;
+ }
+}
+
static void
dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
{
/* insert data plane forwarding entry */
a->is_add = 1;
- gid_address_copy (&a->rmt_eid, &dst_map->eid);
+ if (GID_ADDR_SRC_DST == gid_address_type (&dst_map->eid))
+ {
+ gid_address_sd_to_flat (&a->rmt_eid, &dst_map->eid,
+ &gid_address_sd_dst (&dst_map->eid));
+ gid_address_sd_to_flat (&a->lcl_eid, &dst_map->eid,
+ &gid_address_sd_src (&dst_map->eid));
+ }
+ else
+ gid_address_copy (&a->rmt_eid, &dst_map->eid);
+
a->vni = gid_address_vni (&a->rmt_eid);
/* get vrf or bd_index associated to vni */
- type = gid_address_type (&dst_map->eid);
+ type = gid_address_type (&a->rmt_eid);
if (GID_ADDR_IP_PREFIX == type)
{
dpid = hash_get (lcm->table_id_by_vni, a->vni);
/* add tunnel to fwd entry table XXX check return value from DP insertion */
pool_get (lcm->fwd_entry_pool, fe);
fe->locator_pairs = a->locator_pairs;
- gid_address_copy (&fe->deid, &a->rmt_eid);
+ gid_address_copy (&fe->reid, &a->rmt_eid);
hash_set (lcm->fwd_entry_by_mapping_index, dst_map_index,
fe - lcm->fwd_entry_pool);
}
vnet_lisp_add_del_adjacency (vnet_lisp_add_del_adjacency_args_t * a)
{
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
- return lisp_add_del_adjacency (lcm, &a->seid, &a->deid, a->is_add);
+ return lisp_add_del_adjacency (lcm, &a->leid, &a->reid, a->is_add);
}
/**
unformat_input_t _line_input, *line_input = &_line_input;
vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
u8 is_add = 1;
- locator_t rloc, *rlocs = 0;
- ip_prefix_t *deid_ippref, *seid_ippref;
- gid_address_t seid, deid;
- u8 *dmac = gid_address_mac (&deid);
- u8 *smac = gid_address_mac (&seid);
- u8 deid_set = 0, seid_set = 0;
- u8 *s = 0;
- u32 vni, action = ~0;
+ ip_prefix_t *reid_ippref, *leid_ippref;
+ gid_address_t leid, reid;
+ u8 *dmac = gid_address_mac (&reid);
+ u8 *smac = gid_address_mac (&leid);
+ u8 reid_set = 0, leid_set = 0;
+ u32 vni;
int rv;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
- memset (&deid, 0, sizeof (deid));
- memset (&seid, 0, sizeof (seid));
- memset (&rloc, 0, sizeof (rloc));
+ memset (&reid, 0, sizeof (reid));
+ memset (&leid, 0, sizeof (leid));
- seid_ippref = &gid_address_ippref (&seid);
- deid_ippref = &gid_address_ippref (&deid);
+ leid_ippref = &gid_address_ippref (&leid);
+ reid_ippref = &gid_address_ippref (&reid);
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
is_add = 0;
else if (unformat (line_input, "add"))
;
- else if (unformat (line_input, "deid %U",
- unformat_ip_prefix, deid_ippref))
+ else if (unformat (line_input, "reid %U",
+ unformat_ip_prefix, reid_ippref))
{
- gid_address_type (&deid) = GID_ADDR_IP_PREFIX;
- deid_set = 1;
+ gid_address_type (&reid) = GID_ADDR_IP_PREFIX;
+ reid_set = 1;
}
- else if (unformat (line_input, "deid %U", unformat_mac_address, dmac))
+ else if (unformat (line_input, "reid %U", unformat_mac_address, dmac))
{
- gid_address_type (&deid) = GID_ADDR_MAC;
- deid_set = 1;
+ gid_address_type (&reid) = GID_ADDR_MAC;
+ reid_set = 1;
}
else if (unformat (line_input, "vni %u", &vni))
{
- gid_address_vni (&seid) = vni;
- gid_address_vni (&deid) = vni;
+ gid_address_vni (&leid) = vni;
+ gid_address_vni (&reid) = vni;
}
- else if (unformat (line_input, "seid %U",
- unformat_ip_prefix, seid_ippref))
+ else if (unformat (line_input, "leid %U",
+ unformat_ip_prefix, leid_ippref))
{
- gid_address_type (&seid) = GID_ADDR_IP_PREFIX;
- seid_set = 1;
+ gid_address_type (&leid) = GID_ADDR_IP_PREFIX;
+ leid_set = 1;
}
- else if (unformat (line_input, "seid %U", unformat_mac_address, smac))
+ else if (unformat (line_input, "leid %U", unformat_mac_address, smac))
{
- gid_address_type (&seid) = GID_ADDR_MAC;
- seid_set = 1;
+ gid_address_type (&leid) = GID_ADDR_MAC;
+ leid_set = 1;
}
else
{
}
}
- if (!deid_set)
+ if (!reid_set || !leid_set)
{
- clib_warning ("missing deid!");
+ clib_warning ("missing remote or local eid!");
goto done;
}
- if (GID_ADDR_IP_PREFIX == gid_address_type (&deid))
+ if ((gid_address_type (&leid) != gid_address_type (&reid))
+ || (gid_address_type (&reid) == GID_ADDR_IP_PREFIX
+ && ip_prefix_version (reid_ippref)
+ != ip_prefix_version (leid_ippref)))
{
- /* if seid not set, make sure the ip version is the same as that
- * of the deid. This ensures the seid to be configured will be
- * either 0/0 or ::/0 */
- if (!seid_set)
- ip_prefix_version (seid_ippref) = ip_prefix_version (deid_ippref);
-
- if (is_add &&
- (ip_prefix_version (deid_ippref)
- != ip_prefix_version (seid_ippref)))
- {
- clib_warning ("source and destination EIDs are not"
- " in the same IP family!");
- goto done;
- }
- }
-
- if (is_add && (~0 == action) && 0 == vec_len (rlocs))
- {
- clib_warning ("no action set for negative map-reply!");
- goto done;
+ clib_warning ("remote and local EIDs are of different types!");
+ return error;
}
memset (a, 0, sizeof (a[0]));
- gid_address_copy (&a->seid, &deid);
- gid_address_copy (&a->deid, &seid);
+ gid_address_copy (&a->leid, &leid);
+ gid_address_copy (&a->reid, &reid);
a->is_add = is_add;
rv = vnet_lisp_add_del_adjacency (a);
done:
unformat_free (line_input);
- if (s)
- vec_free (s);
return error;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (lisp_add_del_adjacency_command) = {
.path = "lisp adjacency",
- .short_help = "lisp adjacency add|del vni <vni>"
- "deid <dest-eid> seid <src-eid> [action <no-action|natively-forward|"
- "send-map-request|drop>] rloc <dst-locator> [rloc <dst-locator> ... ]",
+ .short_help = "lisp adjacency add|del vni <vni> reid <remote-eid> "
+ "leid <local-eid>",
.function = lisp_add_del_adjacency_command_fn,
};
/* *INDENT-ON* */
+int
+vnet_lisp_set_map_request_mode (u8 mode)
+{
+ lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
+
+ if (vnet_lisp_enable_disable_status () == 0)
+ {
+ clib_warning ("LISP is disabled!");
+ return VNET_API_ERROR_LISP_DISABLED;
+ }
+
+ if (mode >= _MR_MODE_MAX)
+ {
+ clib_warning ("Invalid LISP map request mode %d!", mode);
+ return VNET_API_ERROR_INVALID_ARGUMENT;
+ }
+
+ lcm->map_request_mode = mode;
+ return 0;
+}
+
+static clib_error_t *
+lisp_map_request_mode_command_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ unformat_input_t _i, *i = &_i;
+ map_request_mode_t mr_mode = _MR_MODE_MAX;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, i))
+ return 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "dst-only"))
+ mr_mode = MR_MODE_DST_ONLY;
+ else if (unformat (i, "src-dst"))
+ mr_mode = MR_MODE_SRC_DST;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ goto done;
+ }
+ }
+
+ if (_MR_MODE_MAX == mr_mode)
+ {
+ clib_warning ("No LISP map request mode entered!");
+ return 0;
+ }
+
+ vnet_lisp_set_map_request_mode (mr_mode);
+done:
+ return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (lisp_map_request_mode_command) = {
+ .path = "lisp map-request mode",
+ .short_help = "lisp map-request mode dst-only|src-dst",
+ .function = lisp_map_request_mode_command_fn,
+};
+/* *INDENT-ON* */
+
+static u8 *
+format_lisp_map_request_mode (u8 * s, va_list * args)
+{
+ u32 mode = va_arg (*args, u32);
+
+ switch (mode)
+ {
+ case 0:
+ return format (0, "dst-only");
+ case 1:
+ return format (0, "src-dst");
+ }
+ return 0;
+}
+
+static clib_error_t *
+lisp_show_map_request_mode_command_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ vlib_cli_output (vm, "map-request mode: %U", format_lisp_map_request_mode,
+ vnet_lisp_get_map_request_mode ());
+ return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (lisp_show_map_request_mode_command) = {
+ .path = "show lisp map-request mode",
+ .short_help = "show lisp map-request mode",
+ .function = lisp_show_map_request_mode_command_fn,
+};
+/* *INDENT-ON* */
+
static clib_error_t *
lisp_show_map_resolvers_command_fn (vlib_main_t * vm,
unformat_input_t * input,
/* get rlocs */
rlocs = build_itr_rloc_list (lcm, loc_set);
- /* put lisp msg */
- lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked, nonce_res);
+ if (MR_MODE_SRC_DST == lcm->map_request_mode)
+ {
+ gid_address_t sd;
+ memset (&sd, 0, sizeof (sd));
+ build_src_dst (&sd, seid, deid);
+ lisp_msg_put_mreq (lcm, b, seid, &sd, rlocs, is_smr_invoked, nonce_res);
+ }
+ else
+ {
+ /* put lisp msg */
+ 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);
/* 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);
+ di = gid_dictionary_sd_lookup (&lcm->mapping_index_by_gid, &dst,
+ &src);
if (~0 != di)
{
mapping_t *m = vec_elt_at_index (lcm->mapping_pool, di);
lcm->pending_map_request_lock[0] = 0;
gid_dictionary_init (&lcm->mapping_index_by_gid);
lcm->do_map_resolver_election = 1;
+ lcm->map_request_mode = MR_MODE_DST_ONLY;
/* default vrf mapped to vni 0 */
hash_set (lcm->table_id_by_vni, 0, 0);