summaryrefslogtreecommitdiffstats
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
parentf3f25416900288d86511133b4d47e68ccf359772 (diff)
LISP multihoming API changes and cleanup
Change-Id: I106352a6da0fad2b91dc8593f8d6d664af3113a8 Signed-off-by: Florin Coras <fcoras@cisco.com>
-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
-rw-r--r--vpp-api-test/vat/api_format.c1
-rw-r--r--vpp/vpp-api/api.c65
-rw-r--r--vpp/vpp-api/vpe.api4
9 files changed, 205 insertions, 161 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;
diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c
index d410955e9ff..051f95f9470 100644
--- a/vpp-api-test/vat/api_format.c
+++ b/vpp-api-test/vat/api_format.c
@@ -10958,6 +10958,7 @@ api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
mp->eid_type = rmt_eid->type;
mp->rmt_len = rmt_eid->len;
mp->lcl_len = lcl_eid->len;
+ mp->action = action;
mp->loc_num = vec_len (rmt_locs);
clib_memcpy (mp->lcl_locs, lcl_locs,
diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c
index 18999a5f7bb..45c3aebd499 100644
--- a/vpp/vpp-api/api.c
+++ b/vpp/vpp-api/api.c
@@ -4975,23 +4975,51 @@ typedef CLIB_PACKED(struct
u8 addr[16]; /**< IPv4/IPv6 address */
}) rloc_t;
+static locator_pair_t *
+unformat_lisp_loc_pairs (void * lcl_locs, void * rmt_locs, u32 rloc_num)
+{
+ u32 i;
+ locator_pair_t * pairs = 0, pair;
+ rloc_t * r;
+
+ for (i = 0; i < rloc_num; i++) {
+ /* local locator */
+ r = &((rloc_t *) lcl_locs)[i];
+ memset(&pair.lcl_loc, 0, sizeof(pair.lcl_loc));
+ ip_address_set(&pair.lcl_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
+
+ /* remote locators */
+ r = &((rloc_t *) rmt_locs)[i];
+ memset(&pair.rmt_loc, 0, sizeof(pair.rmt_loc));
+ ip_address_set(&pair.rmt_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
+
+ pair.priority = r->priority;
+ pair.weight = r->weight;
+
+ vec_add1 (pairs, pair);
+ }
+ return pairs;
+}
+
static locator_t *
-unformat_lisp_locs (void * data, u32 rloc_num)
+unformat_lisp_locs (void * rmt_locs, u32 rloc_num)
{
u32 i;
- locator_t rloc, * rlocs = 0;
+ locator_t * locs = 0, loc;
+ rloc_t * r;
for (i = 0; i < rloc_num; i++) {
- rloc_t * r = &((rloc_t *) data)[i];
- memset(&rloc, 0, sizeof(rloc));
- gid_address_ip_set (&rloc.address, &r->addr, r->is_ip4 ? IP4 : IP6);
- gid_address_ippref_len(&rloc.address) = r->is_ip4 ? 32: 128;
- gid_address_type(&rloc.address) = GID_ADDR_IP_PREFIX;
- rloc.priority = r->priority;
- rloc.weight = r->weight;
- vec_add1 (rlocs, rloc);
+ /* remote locators */
+ r = &((rloc_t *) rmt_locs)[i];
+ memset(&loc, 0, sizeof(loc));
+ gid_address_ip_set(&loc.address, &r->addr, r->is_ip4 ? IP4 : IP6);
+
+ loc.priority = r->priority;
+ loc.weight = r->weight;
+
+ vec_add1 (locs, loc);
}
- return rlocs;
+ return locs;
}
static void
@@ -4999,9 +5027,9 @@ vl_api_lisp_gpe_add_del_fwd_entry_t_handler(
vl_api_lisp_gpe_add_del_fwd_entry_t *mp)
{
vl_api_lisp_gpe_add_del_fwd_entry_reply_t *rmp;
- int rv = 0;
vnet_lisp_gpe_add_del_fwd_entry_args_t _a, * a = &_a;
- locator_t * lcl_locs = 0, * rmt_locs = 0;
+ locator_pair_t * pairs = 0;
+ int rv = 0;
memset (a, 0, sizeof(a[0]));
@@ -5010,20 +5038,19 @@ vl_api_lisp_gpe_add_del_fwd_entry_t_handler(
rv |= unformat_lisp_eid_api (&a->lcl_eid, mp->vni, mp->eid_type,
mp->lcl_eid, mp->lcl_len);
- lcl_locs = unformat_lisp_locs (mp->lcl_locs, mp->loc_num);
- rmt_locs = unformat_lisp_locs (mp->rmt_locs, mp->loc_num);
+ pairs = unformat_lisp_loc_pairs (mp->lcl_locs, mp->rmt_locs, mp->loc_num);
- if (rv || 0 == lcl_locs || 0 == lcl_locs)
+ if (rv || 0 == pairs)
goto send_reply;
a->is_add = mp->is_add;
- a->lcl_loc = gid_address_ip(&lcl_locs[0].address); /* TODO support more */
- a->rmt_loc = gid_address_ip(&rmt_locs[0].address);
+ a->locator_pairs = pairs;
a->dp_table = mp->dp_table;
a->vni = mp->vni;
+ a->action = mp->action;
rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0);
-
+ vec_free(pairs);
send_reply:
REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY);
}
diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api
index 4b8aa818d8d..810d86da811 100644
--- a/vpp/vpp-api/vpe.api
+++ b/vpp/vpp-api/vpe.api
@@ -2278,6 +2278,7 @@ define lisp_add_del_local_eid_reply {
@param loc_num - number of locators
@param lcl_locs - array of local locators
@param rmt_locs - array of remote locators
+ @param action - negative action when 0 locators configured
*/
define lisp_gpe_add_del_fwd_entry {
u32 client_index;
@@ -2287,12 +2288,13 @@ define lisp_gpe_add_del_fwd_entry {
u8 rmt_eid[16];
u8 lcl_eid[16];
u8 rmt_len;
- u8 lcl_len;
+ u8 lcl_len;
u32 vni;
u32 dp_table;
u32 loc_num;
u8 lcl_locs[loc_num];
u8 rmt_locs[loc_num];
+ u8 action;
};
/** \brief Reply for gpe_fwd_entry add/del