aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/lisp-cp/control.c
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2017-01-24 11:38:18 -0800
committerDamjan Marion <dmarion.lists@gmail.com>2017-01-26 08:21:51 +0000
commitba888e46f799a1ae209c51fffdd6159d75b20cdd (patch)
treebd07381021852decd23fd417ed102bc9491e4822 /src/vnet/lisp-cp/control.c
parent2d6b2d6d1bbb130921ec525a1cc6e88f42717c79 (diff)
Add option to use LISP Proxy-ETR
When enabled, destinations with negative mappings or those not reachable via underlay have their traffic forwarded to the PETR. Change-Id: I1056b0959736144f27fcca7b79263f921e7a8bd9 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/lisp-cp/control.c')
-rw-r--r--src/vnet/lisp-cp/control.c153
1 files changed, 117 insertions, 36 deletions
diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c
index 043d60fc15c..c3406d8c6f2 100644
--- a/src/vnet/lisp-cp/control.c
+++ b/src/vnet/lisp-cp/control.c
@@ -432,11 +432,13 @@ static void
dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
{
vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
- mapping_t *src_map, *dst_map;
+ gid_address_t *rmt_eid, *lcl_eid;
+ mapping_t *lcl_map, *rmt_map;
u32 sw_if_index;
uword *feip = 0, *dpid;
fwd_entry_t *fe;
u8 type, is_src_dst = 0;
+ int rv;
memset (a, 0, sizeof (*a));
@@ -445,33 +447,44 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
if (feip)
dp_del_fwd_entry (lcm, src_map_index, dst_map_index);
+ /*
+ * Determine local mapping and eid
+ */
if (lcm->lisp_pitr)
- src_map = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
+ lcl_map = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
else
- src_map = pool_elt_at_index (lcm->mapping_pool, src_map_index);
- dst_map = pool_elt_at_index (lcm->mapping_pool, dst_map_index);
-
- /* insert data plane forwarding entry */
+ lcl_map = pool_elt_at_index (lcm->mapping_pool, src_map_index);
+ lcl_eid = &lcl_map->eid;
+
+ /*
+ * Determine remote mapping and eid
+ */
+ rmt_map = pool_elt_at_index (lcm->mapping_pool, dst_map_index);
+ rmt_eid = &rmt_map->eid;
+
+ /*
+ * Build and insert data plane forwarding entry
+ */
a->is_add = 1;
if (MR_MODE_SRC_DST == lcm->map_request_mode)
{
- if (GID_ADDR_SRC_DST == gid_address_type (&dst_map->eid))
+ if (GID_ADDR_SRC_DST == gid_address_type (rmt_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));
+ gid_address_sd_to_flat (&a->rmt_eid, rmt_eid,
+ &gid_address_sd_dst (rmt_eid));
+ gid_address_sd_to_flat (&a->lcl_eid, rmt_eid,
+ &gid_address_sd_src (rmt_eid));
}
else
{
- gid_address_copy (&a->rmt_eid, &dst_map->eid);
- gid_address_copy (&a->lcl_eid, &src_map->eid);
+ gid_address_copy (&a->rmt_eid, rmt_eid);
+ gid_address_copy (&a->lcl_eid, lcl_eid);
}
is_src_dst = 1;
}
else
- gid_address_copy (&a->rmt_eid, &dst_map->eid);
+ gid_address_copy (&a->rmt_eid, rmt_eid);
a->vni = gid_address_vni (&a->rmt_eid);
@@ -499,17 +512,22 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
}
/* find best locator pair that 1) verifies LISP policy 2) are connected */
- if (0 == get_locator_pairs (lcm, src_map, dst_map, &a->locator_pairs))
+ rv = get_locator_pairs (lcm, lcl_map, rmt_map, &a->locator_pairs);
+
+ /* Either rmt mapping is negative or we can't find underlay path.
+ * Try again with petr if configured */
+ if (rv == 0 && (lcm->flags & LISP_FLAG_USE_PETR))
{
- /* negative entry */
- a->is_negative = 1;
- a->action = dst_map->action;
+ rmt_map = lisp_get_petr_mapping (lcm);
+ rv = get_locator_pairs (lcm, lcl_map, rmt_map, &a->locator_pairs);
}
- /* TODO remove */
- u8 ipver = ip_prefix_version (&gid_address_ippref (&a->rmt_eid));
- a->decap_next_index = (ipver == IP4) ?
- LISP_GPE_INPUT_NEXT_IP4_INPUT : LISP_GPE_INPUT_NEXT_IP6_INPUT;
+ /* negative entry */
+ if (rv == 0)
+ {
+ a->is_negative = 1;
+ a->action = rmt_map->action;
+ }
vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
@@ -521,7 +539,7 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
if (is_src_dst)
gid_address_copy (&fe->leid, &a->lcl_eid);
else
- gid_address_copy (&fe->leid, &src_map->eid);
+ gid_address_copy (&fe->leid, lcl_eid);
fe->is_src_dst = is_src_dst;
hash_set (lcm->fwd_entry_by_mapping_index, dst_map_index,
@@ -1191,7 +1209,6 @@ vnet_lisp_add_del_adjacency (vnet_lisp_add_del_adjacency_args_t * a)
local_mi = lcm->lisp_pitr ? lcm->pitr_map_index :
gid_dictionary_lookup (&lcm->mapping_index_by_gid, &a->leid);
-
if (GID_LOOKUP_MISS == local_mi)
{
clib_warning ("Local eid %U not found. Cannot add adjacency!",
@@ -1273,6 +1290,69 @@ vnet_lisp_pitr_set_locator_set (u8 * locator_set_name, u8 is_add)
return 0;
}
+/**
+ * Configure Proxy-ETR
+ *
+ * @param ip PETR's IP address
+ * @param is_add Flag that indicates if this is an addition or removal
+ *
+ * return 0 on success
+ */
+int
+vnet_lisp_use_petr (ip_address_t * ip, u8 is_add)
+{
+ lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
+ u32 ls_index = ~0;
+ mapping_t *m;
+ vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args;
+ locator_t loc;
+
+ if (vnet_lisp_enable_disable_status () == 0)
+ {
+ clib_warning ("LISP is disabled!");
+ return VNET_API_ERROR_LISP_DISABLED;
+ }
+
+ memset (ls_args, 0, sizeof (*ls_args));
+
+ if (is_add)
+ {
+ /* Create dummy petr locator-set */
+ gid_address_from_ip (&loc.address, ip);
+ loc.priority = 1;
+ loc.state = loc.weight = 1;
+
+ ls_args->is_add = 1;
+ ls_args->index = ~0;
+ vec_add1 (ls_args->locators, loc);
+ vnet_lisp_add_del_locator_set (ls_args, &ls_index);
+
+ /* Add petr mapping */
+ pool_get (lcm->mapping_pool, m);
+ m->locator_set_index = ls_index;
+ lcm->petr_map_index = m - lcm->mapping_pool;
+
+ /* Enable use-petr */
+ lcm->flags |= LISP_FLAG_USE_PETR;
+ }
+ else
+ {
+ m = pool_elt_at_index (lcm->mapping_pool, lcm->petr_map_index);
+
+ /* Remove petr locator */
+ ls_args->is_add = 0;
+ ls_args->index = m->locator_set_index;
+ vnet_lisp_add_del_locator_set (ls_args, 0);
+
+ /* Remove petr mapping */
+ pool_put_index (lcm->mapping_pool, lcm->petr_map_index);
+
+ /* Disable use-petr */
+ lcm->flags &= ~LISP_FLAG_USE_PETR;
+ }
+ return 0;
+}
+
/* cleans locator to locator-set data and removes locators not part of
* any locator-set */
static void
@@ -2883,21 +2963,21 @@ process_map_reply (map_records_arg_t * a)
m->authoritative, m->ttl,
1, 0 /* is_static */ , &dst_map_index);
+ if (dst_map_index == (u32) ~ 0)
+ continue;
+
/* try to program forwarding only if mapping saved or updated */
- if ((u32) ~ 0 != dst_map_index)
- {
- vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
- memset (adj_args, 0, sizeof (adj_args[0]));
+ vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args;
+ memset (adj_args, 0, sizeof (adj_args[0]));
- gid_address_copy (&adj_args->leid, &pmr->src);
- gid_address_copy (&adj_args->reid, &m->eid);
- adj_args->is_add = 1;
- if (vnet_lisp_add_del_adjacency (adj_args))
- clib_warning ("failed to add adjacency!");
+ gid_address_copy (&adj_args->leid, &pmr->src);
+ gid_address_copy (&adj_args->reid, &m->eid);
+ adj_args->is_add = 1;
+ if (vnet_lisp_add_del_adjacency (adj_args))
+ clib_warning ("failed to add adjacency!");
- if ((u32) ~ 0 != m->ttl)
- mapping_start_expiration_timer (lcm, dst_map_index, m->ttl * 60);
- }
+ if ((u32) ~ 0 != m->ttl)
+ mapping_start_expiration_timer (lcm, dst_map_index, m->ttl * 60);
}
/* remove pending map request entry */
@@ -3442,6 +3522,7 @@ lisp_cp_init (vlib_main_t * vm)
lcm->vnet_main = vnet_get_main ();
lcm->mreq_itr_rlocs = ~0;
lcm->lisp_pitr = 0;
+ lcm->flags = 0;
memset (&lcm->active_map_resolver, 0, sizeof (lcm->active_map_resolver));
gid_dictionary_init (&lcm->mapping_index_by_gid);