summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/lisp-gpe/lisp_gpe.c
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/vnet/lisp-gpe/lisp_gpe.c
parentf3f25416900288d86511133b4d47e68ccf359772 (diff)
LISP multihoming API changes and cleanup
Change-Id: I106352a6da0fad2b91dc8593f8d6d664af3113a8 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'vnet/vnet/lisp-gpe/lisp_gpe.c')
-rw-r--r--vnet/vnet/lisp-gpe/lisp_gpe.c229
1 files changed, 115 insertions, 114 deletions
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);