summaryrefslogtreecommitdiffstats
path: root/vnet
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2016-08-02 02:31:03 +0200
committerDave Barach <openvpp@barachs.net>2016-08-04 11:58:07 +0000
commitbb5c22f1b6f48cb53fa2d0e5abcac7248318f8e0 (patch)
tree6744b25f4af97e88094a3dbd1536ed056b198de8 /vnet
parentf3f25416900288d86511133b4d47e68ccf359772 (diff)
LISP multihoming API changes and cleanup
Change-Id: I106352a6da0fad2b91dc8593f8d6d664af3113a8 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'vnet')
-rw-r--r--vnet/vnet/lisp-cp/control.c24
-rw-r--r--vnet/vnet/lisp-cp/control.h3
-rw-r--r--vnet/vnet/lisp-cp/lisp_types.c5
-rw-r--r--vnet/vnet/lisp-cp/lisp_types.h21
-rw-r--r--vnet/vnet/lisp-gpe/lisp_gpe.c229
-rw-r--r--vnet/vnet/lisp-gpe/lisp_gpe.h14
6 files changed, 155 insertions, 141 deletions
diff --git a/vnet/vnet/lisp-cp/control.c b/vnet/vnet/lisp-cp/control.c
index 9b86da5c8f1..4424b60199a 100644
--- a/vnet/vnet/lisp-cp/control.c
+++ b/vnet/vnet/lisp-cp/control.c
@@ -221,8 +221,7 @@ dp_del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
/* delete dp fwd entry */
u32 sw_if_index;
a->is_add = 0;
- a->rmt_loc = fe->dst_loc;
- a->lcl_loc = fe->src_loc;
+ a->locator_pairs = fe->locator_pairs;
a->vni = gid_address_vni(&a->rmt_eid);
gid_address_copy(&a->rmt_eid, &fe->deid);
@@ -230,6 +229,7 @@ dp_del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
/* delete entry in fwd table */
hash_unset(lcm->fwd_entry_by_mapping_index, dst_map_index);
+ vec_free(fe->locator_pairs);
pool_put(lcm->fwd_entry_pool, fe);
}
@@ -240,13 +240,14 @@ dp_del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
*/
static u32
get_locator_pair (lisp_cp_main_t* lcm, mapping_t * lcl_map, mapping_t * rmt_map,
- ip_address_t * lcl_loc, ip_address_t * rmt_loc)
+ locator_pair_t ** locator_pairs)
{
u32 i, minp = ~0, limitp = 0, li, check_index = 0, done = 0, esi;
locator_set_t * rmt_ls, * lcl_ls;
ip_address_t _lcl, * lcl = &_lcl;
locator_t * l, * rmt = 0;
uword * checked = 0;
+ locator_pair_t pair;
rmt_ls = pool_elt_at_index(lcm->locator_set_pool, rmt_map->locator_set_index);
lcl_ls = pool_elt_at_index(lcm->locator_set_pool, lcl_map->locator_set_index);
@@ -299,8 +300,10 @@ get_locator_pair (lisp_cp_main_t* lcm, mapping_t * lcl_map, mapping_t * rmt_map,
gid_address_ip_version(&rmt->address), lcl))
continue;
- ip_address_copy(rmt_loc, &gid_address_ip(&rmt->address));
- ip_address_copy(lcl_loc, lcl);
+ memset(&pair, 0, sizeof(pair));
+ ip_address_copy(&pair.rmt_loc, &gid_address_ip(&rmt->address));
+ ip_address_copy(&pair.lcl_loc, lcl);
+ vec_add1(locator_pairs[0], pair);
done = 2;
}
}
@@ -366,7 +369,7 @@ 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_pair (lcm, src_map, dst_map, &a->lcl_loc, &a->rmt_loc))
+ if (0 == get_locator_pair (lcm, src_map, dst_map, &a->locator_pairs))
{
/* negative entry */
a->is_negative = 1;
@@ -382,8 +385,7 @@ dp_add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
/* add tunnel to fwd entry table XXX check return value from DP insertion */
pool_get (lcm->fwd_entry_pool, fe);
- fe->dst_loc = a->rmt_loc;
- fe->src_loc = a->lcl_loc;
+ fe->locator_pairs = a->locator_pairs;
gid_address_copy (&fe->deid, &a->rmt_eid);
hash_set (lcm->fwd_entry_by_mapping_index, dst_map_index,
fe - lcm->fwd_entry_pool);
@@ -985,7 +987,7 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm,
is_add = 0;
else if (unformat (line_input, "add"))
;
- else if (unformat (line_input, "%U", unformat_gid_address, &eid))
+ else if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
eid_set = 1;
else if (unformat (line_input, "vni %u", &vni))
{
@@ -1002,7 +1004,7 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm,
curr_rloc->weight = w;
}
else if (unformat (line_input, "rloc %U", unformat_ip_address,
- &rloc.address))
+ &gid_address_ip(&rloc.address)))
{
vec_add1 (rlocs, rloc);
curr_rloc = &rlocs[vec_len (rlocs) - 1];
@@ -1025,8 +1027,6 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm,
if (!del_all)
{
-
-
if (is_add && (~0 == action)
&& 0 == vec_len (rlocs))
{
diff --git a/vnet/vnet/lisp-cp/control.h b/vnet/vnet/lisp-cp/control.h
index 74ade39cc58..ff722feb8f4 100644
--- a/vnet/vnet/lisp-cp/control.h
+++ b/vnet/vnet/lisp-cp/control.h
@@ -30,8 +30,7 @@ typedef struct
{
gid_address_t seid;
gid_address_t deid;
- ip_address_t src_loc;
- ip_address_t dst_loc;
+ locator_pair_t * locator_pairs;
} fwd_entry_t;
typedef enum
diff --git a/vnet/vnet/lisp-cp/lisp_types.c b/vnet/vnet/lisp-cp/lisp_types.c
index e62edb93875..ad420a46c7c 100644
--- a/vnet/vnet/lisp-cp/lisp_types.c
+++ b/vnet/vnet/lisp-cp/lisp_types.c
@@ -210,16 +210,15 @@ unformat_gid_address (unformat_input_t * input, va_list * args)
ip_prefix_t ippref;
memset (&ippref, 0, sizeof (ippref));
- memset(a, 0, sizeof(a[0]));
if (unformat (input, "%U", unformat_ip_prefix, &ippref))
{
- clib_memcpy (&gid_address_ippref(a), &ippref, sizeof(ippref));
+ ip_prefix_copy (&gid_address_ippref(a), &ippref);
gid_address_type(a) = GID_ADDR_IP_PREFIX;
}
else if (unformat (input, "%U", unformat_mac_address, mac))
{
- clib_memcpy (gid_address_mac(a), mac, sizeof(mac));
+ mac_copy (gid_address_mac(a), mac);
gid_address_type(a) = GID_ADDR_MAC;
}
else if (unformat (input, "[%d]", &vni))
diff --git a/vnet/vnet/lisp-cp/lisp_types.h b/vnet/vnet/lisp-cp/lisp_types.h
index b1b4b9db3f0..6542b009ffd 100644
--- a/vnet/vnet/lisp-cp/lisp_types.h
+++ b/vnet/vnet/lisp-cp/lisp_types.h
@@ -252,4 +252,25 @@ typedef struct
uword
unformat_negative_mapping_action (unformat_input_t * input, va_list * args);
+/* dp works with a subset of ids */
+typedef struct lisp_dp_address
+{
+ union
+ {
+ ip_prefix_t ippref;
+ u8 mac[6];
+ };
+ u8 type;
+} dp_address_t;
+
+typedef struct locator_pair
+{
+ /* local and remote locators (underlay attachment points) */
+ ip_address_t lcl_loc;
+ ip_address_t rmt_loc;
+
+ u8 priority;
+ u8 weight;
+} locator_pair_t;
+
#endif /* VNET_LISP_GPE_LISP_TYPES_H_ */
diff --git a/vnet/vnet/lisp-gpe/lisp_gpe.c b/vnet/vnet/lisp-gpe/lisp_gpe.c
index 812e0aed7ad..ae3a5e0f7fd 100644
--- a/vnet/vnet/lisp-gpe/lisp_gpe.c
+++ b/vnet/vnet/lisp-gpe/lisp_gpe.c
@@ -113,12 +113,10 @@ add_del_ip_tunnel (vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u8 is_l2,
/* fill in the key's remote eid */
if (!is_l2)
- ip_prefix_copy (&key.rmt_ippref, &gid_address_ippref(&a->rmt_eid));
+ ip_prefix_copy (&key.rmt.ippref, &gid_address_ippref(&a->rmt_eid));
else
- mac_copy (&key.rmt_mac, &gid_address_mac(&a->rmt_eid));
+ mac_copy (&key.rmt.mac, &gid_address_mac(&a->rmt_eid));
-
- ip_address_copy(&key.rmt_loc, &a->rmt_loc);
key.vni = clib_host_to_net_u32 (a->vni);
p = mhash_get (&lgm->lisp_gpe_tunnel_by_key, &key);
@@ -140,8 +138,12 @@ add_del_ip_tunnel (vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u8 is_l2,
foreach_copy_field;
#undef _
- ip_address_copy(&t->src, &a->lcl_loc);
- ip_address_copy(&t->dst, &a->rmt_loc);
+ /* TODO multihoming */
+ if (!a->is_negative)
+ {
+ ip_address_copy (&t->src, &a->locator_pairs[0].lcl_loc);
+ ip_address_copy (&t->dst, &a->locator_pairs[0].rmt_loc);
+ }
/* if vni is non-default */
if (a->vni)
@@ -152,7 +154,7 @@ add_del_ip_tunnel (vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u8 is_l2,
/* next proto */
if (!is_l2)
- t->next_protocol = ip_prefix_version(&key.rmt_ippref) == IP4 ?
+ t->next_protocol = ip_prefix_version(&key.rmt.ippref) == IP4 ?
LISP_GPE_NEXT_PROTO_IP4 : LISP_GPE_NEXT_PROTO_IP6;
else
t->next_protocol = LISP_GPE_NEXT_PROTO_ETHERNET;
@@ -194,94 +196,29 @@ add_del_ip_tunnel (vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u8 is_l2,
}
static int
-add_del_negative_ip_fwd_entry (lisp_gpe_main_t * lgm,
- vnet_lisp_gpe_add_del_fwd_entry_args_t * a)
-{
- ip_adjacency_t adj;
- ip_prefix_t * dpref = &gid_address_ippref(&a->rmt_eid);
- ip_prefix_t * spref = &gid_address_ippref(&a->lcl_eid);
-
- /* setup adjacency for eid */
- memset (&adj, 0, sizeof(adj));
- adj.n_adj = 1;
-
- /* fill in 'legal' data to avoid issues */
- adj.lookup_next_index = (ip_prefix_version(dpref) == IP4) ?
- lgm->ip4_lookup_next_lgpe_ip4_lookup :
- lgm->ip6_lookup_next_lgpe_ip6_lookup;
-
- adj.rewrite_header.sw_if_index = ~0;
- adj.rewrite_header.next_index = ~0;
-
- switch (a->action)
- {
- case LISP_NO_ACTION:
- /* TODO update timers? */
- case LISP_FORWARD_NATIVE:
- /* TODO check if route/next-hop for eid exists in fib and add
- * more specific for the eid with the next-hop found */
- case LISP_SEND_MAP_REQUEST:
- /* insert tunnel that always sends map-request */
- adj.explicit_fib_index = (ip_prefix_version(dpref) == IP4) ?
- LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP:
- LGPE_IP6_LOOKUP_NEXT_LISP_CP_LOOKUP;
- /* add/delete route for prefix */
- return ip_sd_fib_add_del_route (lgm, dpref, spref, a->table_id, &adj,
- a->is_add);
- case LISP_DROP:
- /* for drop fwd entries, just add route, no need to add encap tunnel */
- adj.explicit_fib_index = (ip_prefix_version(dpref) == IP4 ?
- LGPE_IP4_LOOKUP_NEXT_DROP : LGPE_IP6_LOOKUP_NEXT_DROP);
-
- /* add/delete route for prefix */
- return ip_sd_fib_add_del_route (lgm, dpref, spref, a->table_id, &adj,
- a->is_add);
- default:
- return -1;
- }
-}
-
-static int
-add_del_ip_fwd_entry (lisp_gpe_main_t * lgm,
- vnet_lisp_gpe_add_del_fwd_entry_args_t * a)
+build_ip_adjacency (lisp_gpe_main_t * lgm, ip_adjacency_t * adj, u32 table_id,
+ u32 vni, u32 tun_index, u8 is_negative, u8 action,
+ u8 ip_ver)
{
- ip_adjacency_t adj, * adjp;
- u32 adj_index, rv, tun_index = ~0;
- ip_prefix_t * dpref, * spref;
uword * lookup_next_index, * lgpe_sw_if_index, * lnip;
- u8 ip_ver;
-
- /* treat negative fwd entries separately */
- if (a->is_negative)
- return add_del_negative_ip_fwd_entry (lgm, a);
-
- /* add/del tunnel to tunnels pool and prepares rewrite */
- rv = add_del_ip_tunnel (a, 0 /* is_l2 */, &tun_index);
- if (rv)
- return rv;
-
- dpref = &gid_address_ippref(&a->rmt_eid);
- spref = &gid_address_ippref(&a->lcl_eid);
- ip_ver = ip_prefix_version(dpref);
-
- /* setup adjacency for eid */
- memset (&adj, 0, sizeof(adj));
- adj.n_adj = 1;
+ memset(adj, 0, sizeof(adj[0]));
+ adj->n_adj = 1;
/* fill in lookup_next_index with a 'legal' value to avoid problems */
- adj.lookup_next_index = (ip_ver == IP4) ?
+ adj->lookup_next_index = (ip_ver == IP4) ?
lgm->ip4_lookup_next_lgpe_ip4_lookup :
lgm->ip6_lookup_next_lgpe_ip6_lookup;
- if (a->is_add)
+ /* positive mapping */
+ if (!is_negative)
{
/* send packets that hit this adj to lisp-gpe interface output node in
* requested vrf. */
lnip = (ip_ver == IP4) ?
lgm->lgpe_ip4_lookup_next_index_by_table_id :
lgm->lgpe_ip6_lookup_next_index_by_table_id;
- lookup_next_index = hash_get(lnip, a->table_id);
- lgpe_sw_if_index = hash_get(lgm->l3_ifaces.sw_if_index_by_vni, a->vni);
+ lookup_next_index = hash_get(lnip, table_id);
+ lgpe_sw_if_index = hash_get(lgm->l3_ifaces.sw_if_index_by_vni, vni);
/* the assumption is that the interface must've been created before
* programming the dp */
@@ -290,19 +227,84 @@ add_del_ip_fwd_entry (lisp_gpe_main_t * lgm,
/* hijack explicit fib index to store lisp interface node index and
* if_address_index for the tunnel index */
- adj.explicit_fib_index = lookup_next_index[0];
- adj.if_address_index = tun_index;
- adj.rewrite_header.sw_if_index = lgpe_sw_if_index[0];
+ adj->explicit_fib_index = lookup_next_index[0];
+ adj->if_address_index = tun_index;
+ adj->rewrite_header.sw_if_index = lgpe_sw_if_index[0];
+ }
+ /* negative mapping */
+ else
+ {
+ adj->rewrite_header.sw_if_index = ~0;
+ adj->rewrite_header.next_index = ~0;
+
+ switch (action)
+ {
+ case LISP_NO_ACTION:
+ /* TODO update timers? */
+ case LISP_FORWARD_NATIVE:
+ /* TODO check if route/next-hop for eid exists in fib and add
+ * more specific for the eid with the next-hop found */
+ case LISP_SEND_MAP_REQUEST:
+ /* insert tunnel that always sends map-request */
+ adj->explicit_fib_index = (ip_ver == IP4) ?
+ LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP:
+ LGPE_IP6_LOOKUP_NEXT_LISP_CP_LOOKUP;
+ break;
+ case LISP_DROP:
+ /* for drop fwd entries, just add route, no need to add encap tunnel */
+ adj->explicit_fib_index = (ip_ver == IP4 ?
+ LGPE_IP4_LOOKUP_NEXT_DROP : LGPE_IP6_LOOKUP_NEXT_DROP);
+ break;
+ default:
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+add_del_ip_fwd_entry (lisp_gpe_main_t * lgm,
+ vnet_lisp_gpe_add_del_fwd_entry_args_t * a)
+{
+ ip_adjacency_t adj, * adjp;
+ u32 rv, tun_index = ~0;
+ ip_prefix_t * rmt_pref, * lcl_pref;
+ u8 ip_ver;
+
+ rmt_pref = &gid_address_ippref(&a->rmt_eid);
+ lcl_pref = &gid_address_ippref(&a->lcl_eid);
+ ip_ver = ip_prefix_version(rmt_pref);
+
+ /* add/del tunnel to tunnels pool and prepares rewrite */
+ if (!a->is_negative)
+ {
+ rv = add_del_ip_tunnel (a, 0 /* is_l2 */, &tun_index);
+ if (rv)
+ {
+ clib_warning ("failed to build tunnel!");
+ return rv;
+ }
}
- /* add/delete route for prefix */
- rv = ip_sd_fib_add_del_route (lgm, dpref, spref, a->table_id, &adj,
+ /* setup adjacency for eid */
+ rv = build_ip_adjacency (lgm, &adj, a->table_id, a->vni, tun_index,
+ a->is_negative, a->action, ip_ver);
+
+ /* add/delete route for eid */
+ rv |= ip_sd_fib_add_del_route (lgm, rmt_pref, lcl_pref, a->table_id, &adj,
a->is_add);
+ if (rv)
+ {
+ clib_warning ("failed to insert route for tunnel!");
+ return rv;
+ }
+
/* check that everything worked */
if (CLIB_DEBUG && a->is_add)
{
- adj_index = ip_sd_fib_get_route (lgm, dpref, spref, a->table_id);
+ u32 adj_index;
+ adj_index = ip_sd_fib_get_route (lgm, rmt_pref, lcl_pref, a->table_id);
ASSERT(adj_index != 0);
adjp = ip_get_adjacency ((ip_ver == IP4) ? lgm->lm4 : lgm->lm6,
@@ -438,11 +440,12 @@ lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm,
{
unformat_input_t _line_input, * line_input = &_line_input;
u8 is_add = 1;
- ip_address_t lloc, rloc, *llocs = 0, *rlocs = 0;
+ ip_address_t lloc, rloc;
clib_error_t * error = 0;
gid_address_t _reid, * reid = &_reid, _leid, * leid = &_leid;
u8 reid_set = 0, leid_set = 0, is_negative = 0, vrf_set = 0, vni_set = 0;
- u32 vni, vrf, action = ~0;
+ u32 vni, vrf, action = ~0, p, w;
+ locator_pair_t pair, * pairs = 0;
int rv;
/* Get a line of input. */
@@ -480,13 +483,15 @@ lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm,
{
is_negative = 1;
}
- else if (unformat (line_input, "lloc %U rloc %U",
+ else if (unformat (line_input, "loc-pair %U %U p %d w %d",
unformat_ip_address, &lloc,
- unformat_ip_address, &rloc))
+ unformat_ip_address, &rloc, &p, &w))
{
- /* TODO: support p and w */
- vec_add1 (llocs, lloc);
- vec_add1 (rlocs, rloc);
+ pair.lcl_loc = lloc;
+ pair.rmt_loc = rloc;
+ pair.priority = p;
+ pair.weight = w;
+ vec_add1(pairs, pair);
}
else
{
@@ -518,17 +523,11 @@ lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm,
}
else
{
- if (vec_len (llocs) == 0)
+ if (vec_len (pairs) == 0)
{
error = clib_error_return (0, "expected ip4/ip6 locators.");
goto done;
}
-
- if (vec_len (llocs) != 1)
- {
- error = clib_error_return (0, "multihoming not supported for now!");
- goto done;
- }
}
@@ -550,12 +549,7 @@ lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm,
a->table_id = vrf;
gid_address_copy(&a->lcl_eid, leid);
gid_address_copy(&a->rmt_eid, reid);
-
- if (!is_negative)
- {
- a->lcl_loc = llocs[0];
- a->rmt_loc = rlocs[0];
- }
+ a->locator_pairs = pairs;
rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0);
if (0 != rv)
@@ -565,8 +559,7 @@ lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm,
}
done:
- vec_free(llocs);
- vec_free(rlocs);
+ vec_free(pairs);
return error;
}
@@ -699,12 +692,20 @@ vnet_lisp_gpe_enable_disable (vnet_lisp_gpe_enable_disable_args_t * a)
vec_add1(tunnels, tunnel[0]);
}));
- vec_foreach(tunnel, tunnels) {
+ vec_foreach(tunnel, tunnels)
+ {
memset(at, 0, sizeof(at[0]));
at->is_add = 0;
- gid_address_type(&at->rmt_eid) = GID_ADDR_IP_PREFIX;
- ip_prefix_copy(&gid_address_ippref(&at->rmt_eid), &tunnel->rmt_ippref);
- ip_address_copy(&at->rmt_loc, &tunnel->rmt_loc);
+ if (tunnel->rmt.type == GID_ADDR_IP_PREFIX)
+ {
+ gid_address_type(&at->rmt_eid) = GID_ADDR_IP_PREFIX;
+ ip_prefix_copy(&gid_address_ippref(&at->rmt_eid), &tunnel->rmt.ippref);
+ }
+ else
+ {
+ gid_address_type(&at->rmt_eid) = GID_ADDR_MAC;
+ mac_copy(&gid_address_mac(&at->rmt_eid), &tunnel->rmt.mac);
+ }
vnet_lisp_gpe_add_del_fwd_entry (at, 0);
}
vec_free(tunnels);
diff --git a/vnet/vnet/lisp-gpe/lisp_gpe.h b/vnet/vnet/lisp-gpe/lisp_gpe.h
index c3f024229e3..f3e75772ee7 100644
--- a/vnet/vnet/lisp-gpe/lisp_gpe.h
+++ b/vnet/vnet/lisp-gpe/lisp_gpe.h
@@ -46,13 +46,8 @@ typedef struct
{
struct
{
- /* within the dp only ip and mac can be eids */
- union
- {
- ip_prefix_t rmt_ippref;
- u8 rmt_mac[6];
- };
- ip_address_t rmt_loc;
+ dp_address_t rmt;
+ dp_address_t lcl;
u32 vni;
};
u8 as_u8[40];
@@ -246,9 +241,8 @@ typedef struct
gid_address_t lcl_eid;
gid_address_t rmt_eid;
- /* local and remote locators (underlay attachment points) */
- ip_address_t lcl_loc;
- ip_address_t rmt_loc;
+ /* vector of locator pairs */
+ locator_pair_t * locator_pairs;
/* FIB indices to lookup remote locator at encap and inner IP at decap */
u32 encap_fib_index;