Add an option to dump details about specific LISP EID in API/CLI
[vpp.git] / vpp / vpp-api / api.c
index 2ea92df..767b9d5 100644 (file)
@@ -333,6 +333,7 @@ _(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable)                     \
 _(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_ADD_DEL_ADJACENCY, lisp_add_del_adjacency)                       \
 _(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)                         \
@@ -3111,10 +3112,10 @@ vl_api_sw_interface_ip6nd_ra_config_t_handler
 {
    vl_api_sw_interface_ip6nd_ra_config_reply_t * rmp;
     int rv = 0;
-    u8  is_no,  surpress, managed, other, ll_option, send_unicast, cease, default_router;
+    u8  is_no,  suppress, managed, other, ll_option, send_unicast, cease, default_router;
 
     is_no = mp->is_no == 1;
-    surpress = mp->surpress == 1;
+    suppress = mp->suppress == 1;
     managed = mp->managed == 1;
    other = mp->other == 1;
     ll_option = mp->ll_option == 1;
@@ -3125,7 +3126,7 @@ vl_api_sw_interface_ip6nd_ra_config_t_handler
     VALIDATE_SW_IF_INDEX(mp);
 
     rv = ip6_neighbor_ra_config(vm, ntohl(mp->sw_if_index),
-                               surpress,  managed,  other,
+                               suppress,  managed,  other,
                                ll_option,  send_unicast,  cease,
                                default_router, ntohl (mp->lifetime),
                                ntohl(mp->initial_count),  ntohl(mp->initial_interval),
@@ -4781,26 +4782,37 @@ vl_api_lisp_add_del_local_eid_t_handler(
     ip_prefix_t  *prefp = NULL;
     ip_address_t *ip_eid = NULL;
     gid_address_t eid;
+    u8 * mac = gid_address_mac (&eid);
     uword * p = NULL;
     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]));
+    memset (&eid, 0, sizeof (eid));
 
     prefp = &gid_address_ippref(&eid);
     ip_eid = &ip_prefix_addr(prefp);
-    gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
 
-    if (mp->is_ipv6) {
-        clib_memcpy(&ip_addr_v6(ip_eid), mp->ip_address,
-               sizeof(ip_addr_v6(ip_eid)));
-        ip_addr_version(ip_eid) = IP6;
-    } else {
-        clib_memcpy(&ip_addr_v4(ip_eid), mp->ip_address,
-               sizeof(ip_addr_v4(ip_eid)));
-        ip_addr_version(ip_eid) = IP4;
-    }
-    ip_prefix_len(prefp) = mp->prefix_len;
+    switch (mp->eid_type)
+      {
+      case 0: /* ipv4*/
+        gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
+        ip_address_set(ip_eid, mp->eid, IP4);
+        ip_prefix_len(prefp) = mp->prefix_len;
+        break;
+      case 1: /* ipv6 */
+        gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
+        ip_address_set(ip_eid, mp->eid, IP6);
+        ip_prefix_len(prefp) = mp->prefix_len;
+        break;
+      case 2: /* l2 mac */
+        gid_address_type (&eid) = GID_ADDR_MAC;
+        clib_memcpy(mac, mp->eid, 6);
+        break;
+      default:
+        rv = VNET_API_ERROR_INVALID_EID_TYPE;
+        goto out;
+      }
 
     name = format(0, "%s", mp->locator_set_name);
     p = hash_get_mem(lcm->locator_set_index_by_name, name);
@@ -4813,14 +4825,14 @@ 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;
+    gid_address_copy (&a->eid, &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);
+    gid_address_free (&a->eid);
 
     REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
 }
@@ -5033,7 +5045,7 @@ vl_api_lisp_add_del_remote_mapping_t_handler (
     vl_api_lisp_add_del_remote_mapping_t *mp)
 {
     u32 i;
-    ip_address_t rloc, * rlocs = 0;
+    locator_t rloc, * rlocs = 0;
     vl_api_lisp_add_del_remote_mapping_reply_t * rmp;
     int rv = 0;
     gid_address_t _seid, * seid = &_seid;
@@ -5041,47 +5053,163 @@ vl_api_lisp_add_del_remote_mapping_t_handler (
     ip_prefix_t * seid_pref = &gid_address_ippref(seid);
     ip_prefix_t * deid_pref = &gid_address_ippref(deid);
 
-    gid_address_type(seid) = GID_ADDR_IP_PREFIX;
-    gid_address_type(deid) = GID_ADDR_IP_PREFIX;
+    /* TODO remove seid from API */
+    memset (seid, 0, sizeof (seid[0]));
+    memset (deid, 0, sizeof (deid[0]));
     ip_address_t * seid_addr = &ip_prefix_addr(seid_pref);
     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;
+    u8 * seid_mac = gid_address_mac (seid);
+    u8 * deid_mac = gid_address_mac (deid);
     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;
-        ip_prefix_version(deid_pref) = IP4;
-        clib_memcpy (&ip_addr_v4(seid_addr),
-                     mp->seid, sizeof (ip_addr_v4(seid_addr)));
-        clib_memcpy (&ip_addr_v4(deid_addr),
-                     mp->deid, sizeof (ip_addr_v4(deid_addr)));
-    } else {
-        ip_prefix_version(seid_pref) = IP6;
-        ip_prefix_version(deid_pref) = IP6;
-        clib_memcpy (&ip_addr_v6(seid_addr),
-                     mp->seid, sizeof (ip_addr_v6(seid_addr)));
-        clib_memcpy (&ip_addr_v6(deid_addr),
-                     mp->deid, sizeof (ip_addr_v6(deid_addr)));
-    }
+    switch (mp->eid_type)
+      {
+      case 0: /* ipv4 */
+        gid_address_type(seid) = GID_ADDR_IP_PREFIX;
+        gid_address_type(deid) = GID_ADDR_IP_PREFIX;
+        ip_address_set (seid_addr, mp->seid, IP4);
+        ip_address_set (deid_addr, mp->deid, IP4);
+        break;
+      case 1: /* ipv6 */
+        gid_address_type(seid) = GID_ADDR_IP_PREFIX;
+        gid_address_type(deid) = GID_ADDR_IP_PREFIX;
+        ip_address_set (seid_addr, mp->seid, IP6);
+        ip_address_set (deid_addr, mp->deid, IP6);
+        break;
+      case 2: /* l2 mac */
+        gid_address_type(seid) = GID_ADDR_MAC;
+        gid_address_type(deid) = GID_ADDR_MAC;
+        clib_memcpy (seid_mac, mp->seid, 6);
+        clib_memcpy (deid_mac, mp->deid, 6);
+        break;
+      default:
+        rv = VNET_API_ERROR_INVALID_EID_TYPE;
+        goto send_reply;
+      }
 
     for (i = 0; i < mp->rloc_num; i++) {
         rloc_t * r = &((rloc_t *) mp->rlocs)[i];
-        if (r->is_ip4) {
-            clib_memcpy (&ip_addr_v4(&rloc), &r->addr, sizeof (rloc_t));
-            ip_addr_version (&rloc) = IP4;
-        } else {
-            clib_memcpy (&ip_addr_v6(&rloc), &r->addr, sizeof (rloc_t));
-            ip_addr_version (&rloc) = IP6;
-        }
+        memset(&rloc, 0, sizeof(rloc));
+        ip_address_set(&gid_address_ip(&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;
+        /* TODO fix API to pass priority and weight */
+        rloc.priority = 1;
+        rloc.weight = 1;
         vec_add1 (rlocs, rloc);
     }
 
-    rv = vnet_lisp_add_del_remote_mapping (deid, seid, rlocs, mp->action,
-                                           mp->is_add, mp->del_all);
+    /* TODO Uncomment once https://gerrit.fd.io/r/#/c/1802 is merged and CSIT
+     * is switched to lisp_add_del_adjacency */
+//    if (!mp->is_add) {
+//        vnet_lisp_add_del_adjacency_args_t _a, * a = &_a;
+//        gid_address_copy(&a->deid, deid);
+//        a->is_add = 0;
+//        rv = vnet_lisp_add_del_adjacency (a);
+//    } else {
+//        /* NOTE: for now this works as a static remote mapping, i.e.,
+//         * not authoritative and ttl infinite. */
+//        rv = vnet_lisp_add_del_mapping (deid, rlocs, mp->action, 0, ~0,
+//                                        mp->is_add, 0);
+//    }
+
+    /* TODO: remove once the above is merged */
+    vnet_lisp_add_del_adjacency_args_t _a, * a = &_a;
+    a->is_add = mp->is_add;
+    a->authoritative = 0;
+    a->action = mp->action;
+    a->locators = rlocs;
+    gid_address_copy(&a->seid, seid);
+    gid_address_copy(&a->deid, deid);
+    rv = vnet_lisp_add_del_adjacency (a);
+
+    if (mp->del_all)
+      vnet_lisp_clear_all_remote_adjacencies ();
+
     vec_free (rlocs);
-    REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
+send_reply:
+    REPLY_MACRO(VL_API_LISP_ADD_DEL_REMOTE_MAPPING_REPLY);
+}
+
+static void
+vl_api_lisp_add_del_adjacency_t_handler (
+    vl_api_lisp_add_del_adjacency_t *mp)
+{
+    u32 i;
+    locator_t rloc;
+    vl_api_lisp_add_del_adjacency_reply_t * rmp;
+    vnet_lisp_add_del_adjacency_args_t _a, * a = &_a;
+
+    int rv = 0;
+    memset(a, 0, sizeof(a[0]));
+
+    ip_prefix_t * seid_pref = &gid_address_ippref(&a->seid);
+    ip_prefix_t * deid_pref = &gid_address_ippref(&a->deid);
+
+    ip_address_t * seid_addr = &ip_prefix_addr(seid_pref);
+    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;
+    u8 * seid_mac = gid_address_mac (&a->seid);
+    u8 * deid_mac = gid_address_mac (&a->deid);
+    gid_address_vni(&a->seid) = ntohl (mp->vni);
+    gid_address_vni(&a->deid) = ntohl (mp->vni);
+
+    switch (mp->eid_type)
+      {
+      case 0: /* ipv4 */
+        gid_address_type(&a->seid) = GID_ADDR_IP_PREFIX;
+        gid_address_type(&a->deid) = GID_ADDR_IP_PREFIX;
+        ip_address_set (seid_addr, mp->seid, IP4);
+        ip_address_set (deid_addr, mp->deid, IP4);
+        break;
+      case 1: /* ipv6 */
+        gid_address_type(&a->seid) = GID_ADDR_IP_PREFIX;
+        gid_address_type(&a->deid) = GID_ADDR_IP_PREFIX;
+        ip_address_set (seid_addr, mp->seid, IP6);
+        ip_address_set (deid_addr, mp->deid, IP6);
+        break;
+      case 2: /* l2 mac */
+        gid_address_type(&a->seid) = GID_ADDR_MAC;
+        gid_address_type(&a->deid) = GID_ADDR_MAC;
+        clib_memcpy (seid_mac, mp->seid, 6);
+        clib_memcpy (deid_mac, mp->deid, 6);
+        break;
+      default:
+        rv = VNET_API_ERROR_INVALID_EID_TYPE;
+        goto send_reply;
+      }
+
+    for (i = 0; i < mp->rloc_num; i++) {
+        rloc_t * r = &((rloc_t *) mp->rlocs)[i];
+        memset(&rloc, 0, sizeof(rloc));
+        ip_address_set(&gid_address_ip(&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;
+        /* TODO fix API to pass priority and weight */
+        rloc.priority = 1;
+        rloc.weight = 1;
+        vec_add1 (a->locators, rloc);
+    }
+
+    a->action = mp->action;
+    a->is_add = mp->is_add;
+
+    /* NOTE: the remote mapping is static, i.e.,  not authoritative and
+     * ttl is infinite. */
+    a->authoritative = 0;
+    a->ttl = ~0;
+
+    rv = vnet_lisp_add_del_adjacency (a);
+
+    vec_free (a->locators);
+send_reply:
+    REPLY_MACRO(VL_API_LISP_ADD_DEL_ADJACENCY_REPLY);
 }
 
 static void
@@ -5152,21 +5280,15 @@ send_lisp_local_eid_table_details (mapping_t *mapit,
     lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
     locator_set_t *ls = NULL;
     gid_address_t *gid = NULL;
+    u8 * mac = 0;
     ip_prefix_t *ip_prefix = NULL;
     u8 * str = NULL;
-    u8 type = ~0;
 
     ls = pool_elt_at_index (lcm->locator_set_pool,
                             mapit->locator_set_index);
-
     gid = &mapit->eid;
-    type = gid_address_type(gid);
-
-    if (type != GID_ADDR_IP_PREFIX) {
-        return;
-    }
-
     ip_prefix = &gid_address_ippref(gid);
+    mac = gid_address_mac(gid);
 
     rmp = vl_msg_api_alloc (sizeof (*rmp));
     memset (rmp, 0, sizeof (*rmp));
@@ -5182,23 +5304,30 @@ send_lisp_local_eid_table_details (mapping_t *mapit,
             vec_free(str);
     }
 
-    switch (ip_prefix_version(ip_prefix)) {
-        case IP4:
-            rmp->eid_is_ipv6 = 0;
-            clib_memcpy(rmp->eid_ip_address, &ip_prefix_v4(ip_prefix),
+    switch (gid_address_type (gid))
+      {
+      case GID_ADDR_IP_PREFIX:
+        rmp->eid_prefix_len = ip_prefix_len(ip_prefix);
+        if (ip_prefix_version(ip_prefix) == IP4)
+          {
+            rmp->eid_type = 0; /* ipv4 type */
+            clib_memcpy(rmp->eid, &ip_prefix_v4(ip_prefix),
                    sizeof(ip_prefix_v4(ip_prefix)));
-            break;
-
-        case IP6:
-            rmp->eid_is_ipv6 = 1;
-            clib_memcpy(rmp->eid_ip_address, &ip_prefix_v6(ip_prefix),
+          }
+        else
+          {
+            rmp->eid_type = 1; /* ipv6 type */
+            clib_memcpy(rmp->eid, &ip_prefix_v6(ip_prefix),
                    sizeof(ip_prefix_v6(ip_prefix)));
-            break;
-
-        default:
-            ASSERT(0);
-    }
-    rmp->eid_prefix_len = ip_prefix_len(ip_prefix);
+          }
+        break;
+      case GID_ADDR_MAC:
+        rmp->eid_type = 2; /* l2 mac type */
+        clib_memcpy(rmp->eid, mac, 6);
+        break;
+      default:
+        ASSERT(0);
+      }
     rmp->context = context;
     rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
     vl_msg_api_send_shmem (q, (u8 *)&rmp);
@@ -5208,19 +5337,50 @@ static void
 vl_api_lisp_local_eid_table_dump_t_handler (
     vl_api_lisp_local_eid_table_dump_t *mp)
 {
+    u32 mi;
     unix_shared_memory_queue_t * q = NULL;
     lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
     mapping_t * mapit = NULL;
+    gid_address_t _eid, * eid = &_eid;
 
     q = vl_api_client_index_to_input_queue (mp->client_index);
     if (q == 0) {
         return;
     }
 
-    pool_foreach (mapit, lcm->mapping_pool,
+    if (mp->eid_set) {
+        memset (eid, 0, sizeof (*eid));
+        gid_address_vni(eid) = ntohl(mp->vni);
+        switch (mp->eid_type) {
+        case 0:
+            gid_address_type(eid) = GID_ADDR_IP_PREFIX;
+            gid_address_ippref_len(eid) = mp->prefix_length;
+            gid_address_ip_version(eid) = IP4;
+            clib_memcpy (&gid_address_ippref(eid), mp->eid, 4);
+            break;
+        case 1:
+            gid_address_type(eid) = GID_ADDR_IP_PREFIX;
+            gid_address_ippref_len(eid) = mp->prefix_length;
+            gid_address_ip_version(eid) = IP6;
+            clib_memcpy (&gid_address_ippref(eid), mp->eid, 16);
+            break;
+        case 2:
+            gid_address_type(eid) = GID_ADDR_MAC;
+            clib_memcpy (gid_address_mac(eid), mp->eid, 6);
+            break;
+        }
+        mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
+        if ((u32)~0 == mi)
+          return;
+
+        mapit = pool_elt_at_index (lcm->mapping_pool, mi);
+        send_lisp_local_eid_table_details(mapit, q, mp->context);
+    } else {
+        pool_foreach (mapit, lcm->mapping_pool,
         ({
             send_lisp_local_eid_table_details(mapit, q, mp->context);
         }));
+    }
 }
 
 static void
@@ -5593,11 +5753,17 @@ static void vl_api_ipsec_spd_add_del_entry_t_handler
     p.is_outbound = mp->is_outbound;
     p.is_ipv6 = mp->is_ipv6;
 
-    clib_memcpy(&p.raddr.start, mp->remote_address_start, 16);
-    clib_memcpy(&p.raddr.stop, mp->remote_address_stop, 16);
-    clib_memcpy(&p.laddr.start, mp->local_address_start, 16);
-    clib_memcpy(&p.laddr.stop, mp->local_address_stop, 16);
-
+    if (mp->is_ipv6) {
+        clib_memcpy(&p.raddr.start, mp->remote_address_start, 16);
+        clib_memcpy(&p.raddr.stop, mp->remote_address_stop, 16);
+        clib_memcpy(&p.laddr.start, mp->local_address_start, 16);
+        clib_memcpy(&p.laddr.stop, mp->local_address_stop, 16);
+    } else {
+        clib_memcpy(&p.raddr.start.ip4.data, mp->remote_address_start, 4);
+        clib_memcpy(&p.raddr.stop.ip4.data, mp->remote_address_stop, 4);
+        clib_memcpy(&p.laddr.start.ip4.data, mp->local_address_start, 4);
+        clib_memcpy(&p.laddr.stop.ip4.data, mp->local_address_stop, 4);
+    }
     p.protocol = mp->protocol;
     p.rport.start = ntohs(mp->remote_port_start);
     p.rport.stop  = ntohs(mp->remote_port_stop);
@@ -5674,8 +5840,13 @@ static void vl_api_ipsec_sad_add_del_entry_t_handler
     sa.use_esn = mp->use_extended_sequence_number;
     sa.is_tunnel = mp->is_tunnel;
     sa.is_tunnel_ip6 = mp->is_tunnel_ipv6;
-    clib_memcpy(&sa.tunnel_src_addr, mp->tunnel_src_address, 16);
-    clib_memcpy(&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16);
+    if (sa.is_tunnel_ip6) {
+        clib_memcpy(&sa.tunnel_src_addr, mp->tunnel_src_address, 16);
+        clib_memcpy(&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16);
+    } else {
+        clib_memcpy(&sa.tunnel_src_addr.ip4.data, mp->tunnel_src_address, 4);
+        clib_memcpy(&sa.tunnel_dst_addr.ip4.data, mp->tunnel_dst_address, 4);
+    }
 
     rv = ipsec_add_del_sa(vm, &sa, mp->is_add);
 #else