-ip_interface_get_first_ip_addres (ip_lookup_main_t *lm, u32 sw_if_index,
- u8 loop)
-{
- ip_interface_address_t * ia = ip_interface_get_first_interface_address (
- lm, sw_if_index, loop);
- return ip_interface_address_get_address (lm, ia);
-}
-
-static void
-del_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;
- fwd_entry_t * fe = 0;
- uword * feip = 0;
- memset(a, 0, sizeof(*a));
-
- feip = hash_get(lcm->fwd_entry_by_mapping_index, dst_map_index);
- if (!feip)
- return;
-
- fe = pool_elt_at_index(lcm->fwd_entry_pool, feip[0]);
-
- /* delete dp fwd entry */
- u32 sw_if_index;
- a->is_add = 0;
- a->dlocator = fe->dst_loc;
- a->slocator = fe->src_loc;
- a->vni = gid_address_vni(&a->deid);
- gid_address_copy(&a->deid, &fe->deid);
-
- vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
-
- /* delete entry in fwd table */
- hash_unset(lcm->fwd_entry_by_mapping_index, dst_map_index);
- pool_put(lcm->fwd_entry_pool, fe);
-}
-
-static void
-add_fwd_entry (lisp_cp_main_t* lcm, u32 src_map_index, u32 dst_map_index)
-{
- mapping_t * src_map, * dst_map;
- locator_set_t * dst_ls, * src_ls;
- u32 i, minp = ~0, sw_if_index;
- locator_t * dl = 0;
- uword * feip = 0, * tidp;
- fwd_entry_t* fe;
- vnet_lisp_gpe_add_del_fwd_entry_args_t _a, * a = &_a;
-
- memset (a, 0, sizeof(*a));
-
- /* remove entry if it already exists */
- feip = hash_get (lcm->fwd_entry_by_mapping_index, dst_map_index);
- if (feip)
- del_fwd_entry (lcm, src_map_index, dst_map_index);
-
- src_map = pool_elt_at_index (lcm->mapping_pool, src_map_index);
- dst_map = pool_elt_at_index (lcm->mapping_pool, dst_map_index);
-
- gid_address_copy (&a->deid, &dst_map->eid);
- a->vni = gid_address_vni(&a->deid);
-
- tidp = hash_get(lcm->table_id_by_vni, a->vni);
- if (!tidp)
- {
- clib_warning("vni %d not associated to a vrf!", a->vni);
- return;
- }
- a->table_id = tidp[0];
-
- /* XXX simple forwarding policy: first lowest (value) priority locator */
- dst_ls = pool_elt_at_index (lcm->locator_set_pool,
- dst_map->locator_set_index);
- for (i = 0; i < vec_len (dst_ls->locator_indices); i++)
- {
- u32 li = vec_elt (dst_ls->locator_indices, i);
- locator_t * l = pool_elt_at_index (lcm->locator_pool, li);
- if (l->priority < minp && gid_address_type(&l->address)
- == GID_ADDR_IP_PREFIX)
- {
- minp = l->priority;
- dl = l;
- }
- }
- if (dl)
- {
- src_ls = pool_elt_at_index(lcm->locator_set_pool,
- src_map->locator_set_index);
- for (i = 0; i < vec_len(src_ls->locator_indices); i++)
- {
- u32 li = vec_elt (src_ls->locator_indices, i);
- locator_t * sl = pool_elt_at_index (lcm->locator_pool, li);
-
- if (ip_addr_version(&gid_address_ip(&dl->address)) == IP4)
- {
- ip4_address_t * l4;
- l4 = ip_interface_get_first_ip_addres (&lcm->im4->lookup_main,
- sl->sw_if_index,
- 1 /* unnumbered */);
- ip_addr_v4(&a->slocator) = *l4;
- ip_addr_version(&a->slocator) = IP4;
- }
- else
- {
- ip6_address_t * l6;
- l6 = ip_interface_get_first_ip_addres (&lcm->im6->lookup_main,
- sl->sw_if_index,
- 1 /* unnumbered */);
- ip_addr_v6(&a->slocator) = *l6;
- ip_addr_version(&a->slocator) = IP6;
- }
- }
- }
-
- /* insert data plane forwarding entry */
- a->is_add = 1;
- if (dl)
- a->dlocator = gid_address_ip(&dl->address);
- else
- {
- a->is_negative = 1;
- a->action = dst_map->action;
- }
-
- /* TODO remove */
- u8 ipver = ip_prefix_version(&gid_address_ippref(&a->deid));
- a->decap_next_index = (ipver == IP4) ?
- LISP_GPE_INPUT_NEXT_IP4_INPUT : LISP_GPE_INPUT_NEXT_IP6_INPUT;
-
- vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_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->dlocator;
- fe->src_loc = a->slocator;
- gid_address_copy (&fe->deid, &a->deid);
- hash_set (lcm->fwd_entry_by_mapping_index, dst_map_index,
- fe - lcm->fwd_entry_pool);
-}
-
-/* return 0 if the two locator sets are identical 1 otherwise */
-static u8
-compare_locators (lisp_cp_main_t *lcm, u32 * old_ls_indexes,
- locator_t * new_locators)
-{
- u32 i, old_li;
- locator_t * old_loc, * new_loc;
-
- if (vec_len (old_ls_indexes) != vec_len(new_locators))
- return 1;
-
- for (i = 0; i < vec_len(new_locators); i++)
- {
- old_li = vec_elt(old_ls_indexes, i);
- old_loc = pool_elt_at_index(lcm->locator_pool, old_li);
-
- new_loc = vec_elt_at_index(new_locators, i);
-
- if (locator_cmp (old_loc, new_loc))
- return 1;
- }
- return 0;
-}
-
-void
-process_map_reply (lisp_cp_main_t * lcm, vlib_buffer_t * b)