LISP EID virtualization support
[vpp.git] / vpp / api / api.c
index f398e4f..54545cc 100644 (file)
@@ -334,12 +334,17 @@ _(LISP_ENABLE_DISABLE, lisp_enable_disable)                             \
 _(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface)                       \
 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping)             \
 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set)                 \
+_(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map)               \
 _(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump)                         \
 _(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump)                 \
 _(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump)                           \
 _(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump)                       \
+_(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump)                     \
 _(LISP_ENABLE_DISABLE_STATUS_DUMP,                                      \
   lisp_enable_disable_status_dump)                                      \
+_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS,                                   \
+  lisp_add_del_map_request_itr_rlocs)                                   \
+_(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs)       \
 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del)                   \
 _(AF_PACKET_CREATE, af_packet_create)                                   \
 _(AF_PACKET_DELETE, af_packet_delete)                                   \
@@ -974,7 +979,18 @@ static int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t *mp)
         }
 
         nh_adj = ip_get_adjacency (lm, ai);
-        vec_add1 (add_adj, nh_adj[0]);
+       if (nh_adj->lookup_next_index == IP_LOOKUP_NEXT_ARP &&
+           nh_adj->arp.next_hop.ip4.as_u32 == 0) {
+           /* the next-hop resovles via a glean adj. create and use
+            * a ARP adj for the next-hop */
+           a.adj_index = vnet_arp_glean_add(fib_index, &next_hop_address);
+           a.add_adj = NULL;
+           a.n_add_adj = 0;
+           ip4_add_del_route (im, &a);
+
+           goto done;
+       }
+       vec_add1 (add_adj, nh_adj[0]);
         if (mp->lookup_in_vrf) {
             p = hash_get (im->fib_index_by_table_id, ntohl(mp->lookup_in_vrf));
             if (p)
@@ -1016,6 +1032,7 @@ do_add_del:
 
     vec_free (add_adj);
 
+done:
     dsunlock (sm);
     return 0;
 }
@@ -1330,6 +1347,8 @@ static void
 vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t *mp)
 {
     vlib_main_t *vm = vlib_get_main();
+    ip4_main_t * im4 = &ip4_main;
+    ip6_main_t * im6 = &ip6_main;
     vl_api_sw_interface_set_vpath_reply_t * rmp;
     int rv = 0;
     u32 ci;
@@ -1349,36 +1368,52 @@ vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t *mp)
     if (mp->enable) {
         ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
         ci = vnet_config_add_feature(vm, &rx_cm4u->config_main,
-                                     ci, IP4_RX_FEATURE_VPATH, 0, 0);
+                                     ci, 
+                                     im4->ip4_unicast_rx_feature_vpath,
+                                     0, 0);
         rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
         ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
         ci = vnet_config_add_feature(vm, &rx_cm4m->config_main,
-                                     ci, IP4_RX_FEATURE_VPATH, 0, 0);
+                                     ci, 
+                                     im4->ip4_multicast_rx_feature_vpath,
+                                     0, 0);
         rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
         ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
         ci = vnet_config_add_feature(vm, &rx_cm6u->config_main,
-                                     ci, IP6_RX_FEATURE_VPATH, 0, 0);
+                                     ci, 
+                                     im6->ip6_unicast_rx_feature_vpath,
+                                     0, 0);
         rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
         ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
         ci = vnet_config_add_feature(vm, &rx_cm6m->config_main,
-                                     ci, IP6_RX_FEATURE_VPATH, 0, 0);
+                                     ci, 
+                                     im6->ip6_multicast_rx_feature_vpath,
+                                     0, 0);
         rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
     } else {
         ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
         ci = vnet_config_del_feature(vm, &rx_cm4u->config_main,
-                                     ci, IP4_RX_FEATURE_VPATH, 0, 0);
+                                     ci, 
+                                     im4->ip4_unicast_rx_feature_vpath,
+                                     0, 0);
         rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
         ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
         ci = vnet_config_del_feature(vm, &rx_cm4m->config_main,
-                                     ci, IP4_RX_FEATURE_VPATH, 0, 0);
+                                     ci, 
+                                     im4->ip4_multicast_rx_feature_vpath,
+                                     0, 0);
         rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
         ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
         ci = vnet_config_del_feature(vm, &rx_cm6u->config_main,
-                                     ci, IP6_RX_FEATURE_VPATH, 0, 0);
+                                     ci, 
+                                     im6->ip6_unicast_rx_feature_vpath,
+                                     0, 0);
         rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
         ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
         ci = vnet_config_del_feature(vm, &rx_cm6m->config_main,
-                                     ci, IP6_RX_FEATURE_VPATH, 0, 0);
+                                     ci, 
+                                     im6->ip6_multicast_rx_feature_vpath,
+                                     0, 0);
         rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
     }
 
@@ -4737,6 +4772,7 @@ vl_api_lisp_add_del_local_eid_t_handler(
     u32 locator_set_index = ~0, map_index = ~0;
     vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
     u8 *name = NULL;
+    memset (a, 0, sizeof (a[0]));
 
     prefp = &gid_address_ippref(&eid);
     ip_eid = &ip_prefix_addr(prefp);
@@ -4763,18 +4799,30 @@ vl_api_lisp_add_del_local_eid_t_handler(
 
   /* XXX treat batch configuration */
     a->is_add = mp->is_add;
+    gid_address_vni (&eid) = clib_net_to_host_u32 (mp->vni);
     a->deid = eid;
     a->locator_set_index = locator_set_index;
     a->local = 1;
-
     rv = vnet_lisp_add_del_local_mapping(a, &map_index);
 
 out:
     vec_free(name);
+    gid_address_free (&a->deid);
 
     REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
 }
 
+static void
+vl_api_lisp_eid_table_add_del_map_t_handler(
+    vl_api_lisp_eid_table_add_del_map_t *mp)
+{
+    vl_api_lisp_eid_table_add_del_map_reply_t *rmp;
+    int rv = 0;
+    rv = vnet_lisp_eid_table_map (clib_net_to_host_u32 (mp->vni),
+                                  clib_net_to_host_u32 (mp->vrf), mp->is_add);
+    REPLY_MACRO(VL_API_LISP_EID_TABLE_ADD_DEL_MAP_REPLY)
+}
+
 static void
 lisp_gpe_add_del_fwd_entry_set_address(
     vl_api_lisp_gpe_add_del_fwd_entry_t *mp,
@@ -4902,7 +4950,7 @@ vl_api_lisp_gpe_add_del_iface_t_handler(
     a->is_add = mp->is_add;
     a->table_id = mp->table_id;
     a->vni = mp->vni;
-    vnet_lisp_gpe_add_del_iface (a, 0);
+    rv = vnet_lisp_gpe_add_del_iface (a, 0);
 
     REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
 }
@@ -4922,6 +4970,27 @@ vl_api_lisp_pitr_set_locator_set_t_handler(
     REPLY_MACRO(VL_API_LISP_PITR_SET_LOCATOR_SET_REPLY);
 }
 
+static void
+vl_api_lisp_add_del_map_request_itr_rlocs_t_handler
+(vl_api_lisp_add_del_map_request_itr_rlocs_t *mp)
+{
+    vl_api_lisp_add_del_map_request_itr_rlocs_reply_t *rmp;
+    int rv = 0;
+    u8 * locator_set_name = NULL;
+    vnet_lisp_add_del_mreq_itr_rloc_args_t _a, * a = &_a;
+
+    locator_set_name = format (0, "%s", mp->locator_set_name);
+
+    a->is_add = mp->is_add;
+    a->locator_set_name = locator_set_name;
+
+    rv = vnet_lisp_add_del_mreq_itr_rlocs(a);
+
+    vec_free(locator_set_name);
+
+    REPLY_MACRO(VL_API_LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY);
+}
+
 /** Used for transferring locators via VPP API */
 typedef CLIB_PACKED(struct
 {
@@ -4965,8 +5034,8 @@ vl_api_lisp_add_del_remote_mapping_t_handler (
     ip_address_t * deid_addr = &ip_prefix_addr(deid_pref);
     ip_prefix_len(seid_pref) = mp->seid_len;
     ip_prefix_len(deid_pref) = mp->deid_len;
-    gid_address_set_vni (seid, ntohl (mp->vni));
-    gid_address_set_vni (deid, ntohl (mp->vni));
+    gid_address_vni (seid) = ntohl (mp->vni);
+    gid_address_vni (deid) = ntohl (mp->vni);
 
     if (mp->eid_is_ip4) {
         ip_prefix_version(seid_pref) = IP4;
@@ -5118,7 +5187,7 @@ send_lisp_local_eid_table_details (mapping_t *mapit,
     }
     rmp->eid_prefix_len = ip_prefix_len(ip_prefix);
     rmp->context = context;
-
+    rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
     vl_msg_api_send_shmem (q, (u8 *)&rmp);
 }
 
@@ -5175,7 +5244,7 @@ send_lisp_gpe_tunnel_details (lisp_gpe_tunnel_t *tunnel,
 
 static void
 vl_api_lisp_gpe_tunnel_dump_t_handler (
-    vl_api_lisp_local_eid_table_dump_t *mp)
+    vl_api_lisp_gpe_tunnel_dump_t *mp)
 {
     unix_shared_memory_queue_t * q = NULL;
     lisp_gpe_main_t * lgm = &lisp_gpe_main;
@@ -5228,7 +5297,7 @@ send_lisp_map_resolver_details (ip_address_t *ip,
 
 static void
 vl_api_lisp_map_resolver_dump_t_handler (
-    vl_api_lisp_local_eid_table_dump_t *mp)
+    vl_api_lisp_map_resolver_dump_t *mp)
 {
     unix_shared_memory_queue_t * q = NULL;
     lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
@@ -5245,6 +5314,28 @@ vl_api_lisp_map_resolver_dump_t_handler (
 
 }
 
+static void
+vl_api_lisp_eid_table_map_dump_t_handler (
+    vl_api_lisp_eid_table_map_dump_t *mp)
+{
+    unix_shared_memory_queue_t * q = NULL;
+    lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
+    hash_pair_t * p;
+
+    q = vl_api_client_index_to_input_queue (mp->client_index);
+    if (q == 0) {
+        return;
+    }
+    hash_foreach_pair (p, lcm->table_id_by_vni, {
+        vl_api_lisp_eid_table_map_details_t * rmp = NULL;
+        memset (rmp, 0, sizeof (*rmp));
+        rmp->_vl_msg_id = ntohs(VL_API_LISP_EID_TABLE_MAP_DETAILS);
+        rmp->vni = p->key;
+        rmp->vrf = p->value[0];
+        rmp->context = mp->context;
+    });
+}
+
 static void
 send_lisp_enable_disable_details (unix_shared_memory_queue_t *q,
                                       u32 context)
@@ -5276,6 +5367,38 @@ vl_api_lisp_enable_disable_status_dump_t_handler
     send_lisp_enable_disable_details(q, mp->context);
 }
 
+static void
+vl_api_lisp_get_map_request_itr_rlocs_t_handler (
+    vl_api_lisp_get_map_request_itr_rlocs_t *mp)
+{
+    unix_shared_memory_queue_t * q = NULL;
+    vl_api_lisp_get_map_request_itr_rlocs_reply_t *rmp = NULL;
+    lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
+    locator_set_t * loc_set = 0;
+    u8 * tmp_str = 0;
+    int rv = 0;
+
+    q = vl_api_client_index_to_input_queue (mp->client_index);
+    if (q == 0) {
+        return;
+    }
+
+    if (~0 == lcm->mreq_itr_rlocs) {
+      tmp_str = format(0, " ");
+    } else {
+      loc_set = pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
+      tmp_str = format(0, "%s", loc_set->name);
+    }
+
+    REPLY_MACRO2(VL_API_LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,
+    ({
+      strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
+              ARRAY_LEN(rmp->locator_set_name) - 1);
+    }));
+
+    vec_free(tmp_str);
+}
+
 static void
 vl_api_interface_name_renumber_t_handler (vl_api_interface_name_renumber_t *mp)
 {