Edit Lisp locator_set API

Change the output format of lisp locator_set API.
Create new API for lisp locator.
Change lisp_enable_disable_status_dump -> show_lisp_status, not use dump
function.

Change-Id: Ie2024cbf5e55b22ba077266220bf8584d5cac07a
Signed-off-by: Andrej Kozemcak <akozemca@cisco.com>
diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c
index a220066..b9ee377 100644
--- a/vpp-api-test/vat/api_format.c
+++ b/vpp-api-test/vat/api_format.c
@@ -1218,6 +1218,46 @@
     vam->result_ready = 1;
 }
 
+static void vl_api_noprint_control_ping_reply_t_handler
+(vl_api_noprint_control_ping_reply_t * mp)
+{
+    vat_main_t * vam = &vat_main;
+    i32 retval = ntohl(mp->retval);
+    if (vam->async_mode) {
+        vam->async_errors += (retval < 0);
+    } else {
+        vam->retval = retval;
+        vam->result_ready = 1;
+    }
+}
+
+static void vl_api_noprint_control_ping_reply_t_handler_json
+(vl_api_noprint_control_ping_reply_t * mp)
+{
+    vat_main_t * vam = &vat_main;
+    i32 retval = ntohl(mp->retval);
+
+    if (vam->noprint_msg) {
+      vam->retval = retval;
+      vam->result_ready = 1;
+      return;
+    }
+
+    if (VAT_JSON_NONE != vam->json_tree.type) {
+        vat_json_print(vam->ofp, &vam->json_tree);
+        vat_json_free(&vam->json_tree);
+        vam->json_tree.type = VAT_JSON_NONE;
+    } else {
+        /* just print [] */
+        vat_json_init_array(&vam->json_tree);
+        vat_json_print(vam->ofp, &vam->json_tree);
+        vam->json_tree.type = VAT_JSON_NONE;
+    }
+
+    vam->retval = retval;
+    vam->result_ready = 1;
+}
+
 static void vl_api_l2_flags_reply_t_handler
 (vl_api_l2_flags_reply_t * mp)
 {
@@ -2014,42 +2054,71 @@
 }
 
 static void
-vl_api_lisp_locator_set_details_t_handler (
-    vl_api_lisp_locator_set_details_t *mp)
+vl_api_lisp_locator_details_t_handler (
+    vl_api_lisp_locator_details_t *mp)
 {
     vat_main_t *vam = &vat_main;
-    u8 * tmp_str = NULL;
+    locator_msg_t loc;
+    u8 * tmp_str = 0;
 
-    if (mp->local) {
-      fformat(vam->ofp, "%=20s%=16d%=16d%=16d\n",
-              mp->locator_set_name,
-              ntohl(mp->sw_if_index),
-              mp->priority,
-              mp->weight);
+    memset(&loc, 0, sizeof(loc));
+    if (vam->noprint_msg) {
+      loc.local = mp->local;
+      loc.priority = mp->priority;
+      loc.weight = mp->weight;
+      if (loc.local) {
+        loc.sw_if_index = ntohl(mp->sw_if_index);
+      } else {
+        loc.is_ipv6 = mp->is_ipv6;
+        clib_memcpy(loc.ip_address, mp->ip_address, sizeof(loc.ip_address));
+      }
+      vec_add1(vam->locator_msg, loc);
     } else {
-      tmp_str = format(0,"%U/%d",
-              mp->is_ipv6 ? format_ip6_address : format_ip4_address,
-              mp->ip_address,
-              mp->prefix_len);
+      if (mp->local) {
+        tmp_str = format(tmp_str, "%=16d%=16d%=16d\n",
+                         ntohl(mp->sw_if_index),
+                         mp->priority,
+                         mp->weight);
+      } else {
+        tmp_str = format(tmp_str, "%=16U%=16d%=16d\n",
+                         mp->is_ipv6 ? format_ip6_address :
+                         format_ip4_address,
+                         mp->ip_address,
+                         mp->priority,
+                         mp->weight);
+      }
 
-      fformat(vam->ofp, "%=20s%=16s%=16d%=16d\n",
-              mp->locator_set_name,
-              tmp_str,
-              mp->priority,
-              mp->weight);
+      fformat(vam->ofp, "%s", tmp_str);
+
       vec_free(tmp_str);
     }
 }
 
 static void
-vl_api_lisp_locator_set_details_t_handler_json (
-    vl_api_lisp_locator_set_details_t *mp)
+vl_api_lisp_locator_details_t_handler_json (
+    vl_api_lisp_locator_details_t *mp)
 {
     vat_main_t *vam = &vat_main;
     vat_json_node_t *node = NULL;
+    locator_msg_t loc;
     struct in6_addr ip6;
     struct in_addr ip4;
 
+    memset(&loc, 0, sizeof(loc));
+    if (vam->noprint_msg) {
+        loc.local = mp->local;
+        loc.priority = mp->priority;
+        loc.weight = mp->weight;
+        if (loc.local) {
+            loc.sw_if_index = ntohl(mp->sw_if_index);
+        } else {
+            loc.is_ipv6 = mp->is_ipv6;
+            clib_memcpy(loc.ip_address, mp->ip_address, sizeof(loc.ip_address));
+        }
+        vec_add1(vam->locator_msg, loc);
+        return;
+    }
+
     if (VAT_JSON_ARRAY != vam->json_tree.type) {
         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
         vat_json_init_array(&vam->json_tree);
@@ -2057,24 +2126,47 @@
     node = vat_json_array_add(&vam->json_tree);
 
     vat_json_init_object(node);
-    vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
+
     if (mp->local) {
-        vat_json_object_add_uint(node, "locator", ntohl(mp->sw_if_index));
+        vat_json_object_add_uint(node, "locator_index", ntohl(mp->sw_if_index));
     } else {
-        if (mp->is_ipv6) {
-            clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
-            vat_json_object_add_ip6(node, "locator", ip6);
-        } else {
-            clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
-            vat_json_object_add_ip4(node, "locator", ip4);
-        }
-        vat_json_object_add_uint(node, "prefix-length", mp->prefix_len);
+      if (mp->is_ipv6) {
+        clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
+        vat_json_object_add_ip6(node, "locator", ip6);
+      } else {
+        clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
+        vat_json_object_add_ip4(node, "locator", ip4);
+      }
     }
     vat_json_object_add_uint(node, "priority", mp->priority);
     vat_json_object_add_uint(node, "weight", mp->weight);
 }
 
 static void
+vl_api_lisp_locator_set_details_t_handler (
+    vl_api_lisp_locator_set_details_t *mp)
+{
+    vat_main_t *vam = &vat_main;
+    locator_set_msg_t ls;
+
+    ls.locator_set_index = ntohl(mp->locator_set_index);
+    ls.locator_set_name = format(0, "%s", mp->locator_set_name);
+    vec_add1(vam->locator_set_msg, ls);
+}
+
+static void
+vl_api_lisp_locator_set_details_t_handler_json (
+    vl_api_lisp_locator_set_details_t *mp)
+{
+    vat_main_t *vam = &vat_main;
+    locator_set_msg_t ls;
+
+    ls.locator_set_index = ntohl(mp->locator_set_index);
+    ls.locator_set_name = format(0, "%s", mp->locator_set_name);
+    vec_add1(vam->locator_set_msg, ls);
+}
+
+static void
 vl_api_lisp_local_eid_table_details_t_handler (
     vl_api_lisp_local_eid_table_details_t *mp)
 {
@@ -2154,16 +2246,18 @@
       {
       case 0:
         clib_memcpy(&ip4, mp->eid, sizeof(ip4));
-        vat_json_object_add_ip4(node, "eid-address", ip4);
+        vat_json_object_add_ip4(node, "eid", ip4);
+        vat_json_object_add_uint(node, "eid-prefix-len", mp->eid_prefix_len);
         break;
       case 1:
         clib_memcpy(&ip6, mp->eid, sizeof(ip6));
-        vat_json_object_add_ip6(node, "eid-address", ip6);
+        vat_json_object_add_ip6(node, "eid", ip6);
+        vat_json_object_add_uint(node, "eid-prefix-len", mp->eid_prefix_len);
         break;
       case 2:
         s = format (0, "%U", format_ethernet_address, mp->eid);
         vec_add1(s, 0);
-        vat_json_object_add_string_copy(node, "eid-address", s);
+        vat_json_object_add_string_copy(node, "eid", s);
         vec_free(s);
         break;
       default:
@@ -2171,7 +2265,6 @@
         return;
       }
     vat_json_object_add_uint(node, "vni", clib_net_to_host_u32 (mp->vni));
-    vat_json_object_add_uint(node, "eid-prefix-len", mp->eid_prefix_len);
 }
 
 static u8 *
@@ -2307,22 +2400,28 @@
 }
 
 static void
-vl_api_lisp_enable_disable_status_details_t_handler
-(vl_api_lisp_enable_disable_status_details_t *mp)
+vl_api_show_lisp_status_reply_t_handler
+(vl_api_show_lisp_status_reply_t * mp)
 {
     vat_main_t *vam = &vat_main;
+    i32 retval = ntohl(mp->retval);
 
-    fformat(vam->ofp, "feature: %s\ngpe: %s\n",
-            mp->feature_status ? "enabled" : "disabled",
-            mp->gpe_status ? "enabled" : "disabled");
+    if (0 <= retval) {
+      fformat(vam->ofp, "feature: %s\ngpe: %s\n",
+              mp->feature_status ? "enabled" : "disabled",
+              mp->gpe_status ? "enabled" : "disabled");
+    }
+
+    vam->retval = retval;
+    vam->result_ready = 1;
 }
 
 static void
-vl_api_lisp_enable_disable_status_details_t_handler_json
-(vl_api_lisp_enable_disable_status_details_t *mp)
+vl_api_show_lisp_status_reply_t_handler_json
+(vl_api_show_lisp_status_reply_t *mp)
 {
     vat_main_t *vam = &vat_main;
-    vat_json_node_t *node = NULL;
+    vat_json_node_t node;
     u8 * gpe_status = NULL;
     u8 * feature_status = NULL;
 
@@ -2332,18 +2431,18 @@
     vec_add1 (gpe_status, 0);
     vec_add1 (feature_status, 0);
 
-    if (VAT_JSON_ARRAY != vam->json_tree.type) {
-        ASSERT(VAT_JSON_NONE == vam->json_tree.type);
-        vat_json_init_array(&vam->json_tree);
-    }
-    node = vat_json_array_add(&vam->json_tree);
-
-    vat_json_init_object(node);
-    vat_json_object_add_string_copy(node, "gpe_status", gpe_status);
-    vat_json_object_add_string_copy(node, "feature_status", feature_status);
+    vat_json_init_object(&node);
+    vat_json_object_add_string_copy(&node, "gpe_status", gpe_status);
+    vat_json_object_add_string_copy(&node, "feature_status", feature_status);
 
     vec_free (gpe_status);
     vec_free (feature_status);
+
+    vat_json_print(vam->ofp, &node);
+    vat_json_free(&node);
+
+    vam->retval = ntohl(mp->retval);
+    vam->result_ready = 1;
 }
 
 static void
@@ -3042,6 +3141,7 @@
 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
 _(CONTROL_PING_REPLY, control_ping_reply)                               \
+_(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
 _(CLI_REPLY, cli_reply)                                                 \
 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
   sw_interface_add_del_address_reply)                                   \
@@ -3177,12 +3277,12 @@
 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
+_(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
 _(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details)           \
 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
-_(LISP_ENABLE_DISABLE_STATUS_DETAILS,                                   \
-  lisp_enable_disable_status_details)                                   \
+_(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
   lisp_add_del_map_request_itr_rlocs_reply)                             \
 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
@@ -3262,6 +3362,21 @@
     return -99;                                 \
 } while(0);
 
+/* W_L: wait for results, with timeout */
+#define W_L(body)                               \
+do {                                            \
+    timeout = vat_time_now (vam) + 1.0;         \
+                                                \
+    while (vat_time_now (vam) < timeout) {      \
+        if (vam->result_ready == 1) {           \
+          (body);                               \
+          return (vam->retval);                 \
+        }                                       \
+    }                                           \
+    vam->noprint_msg = 0;     \
+    return -99;                                 \
+} while(0);
+
 typedef struct {
     u8 * name;
     u32 value;
@@ -11504,33 +11619,326 @@
 }
 
 static int
-api_lisp_locator_set_dump(vat_main_t *vam)
+lisp_locator_dump_send_msg(vat_main_t * vam, u32 locator_set_index, u8 filter)
 {
-    vl_api_lisp_locator_set_dump_t *mp;
+    vl_api_lisp_locator_dump_t *mp;
     f64 timeout = ~0;
 
-    if (!vam->json_output) {
-        fformat(vam->ofp, "%=20s%=16s%=16s%=16s\n",
-                "Locator-set", "Locator", "Priority", "Weight");
-    }
+    M(LISP_LOCATOR_DUMP, lisp_locator_dump);
 
-    M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
+    mp->locator_set_index = htonl(locator_set_index);
+    mp->filter = filter;
+
     /* send it... */
     S;
 
     /* Use a control ping for synchronization */
     {
-        vl_api_control_ping_t * mp;
-        M(CONTROL_PING, control_ping);
-        S;
+      vl_api_noprint_control_ping_t * mp;
+      M(NOPRINT_CONTROL_PING, noprint_control_ping);
+      S;
     }
     /* Wait for a reply... */
     W;
+}
+
+static int
+print_locator_in_locator_set(vat_main_t * vam, u8 filter)
+{
+    locator_set_msg_t * ls;
+    locator_msg_t * loc;
+    u8 * tmp_str = 0;
+    int i = 0, ret = 0;
+
+    vec_foreach(ls, vam->locator_set_msg) {
+        ret = lisp_locator_dump_send_msg(vam, ls->locator_set_index, filter);
+        if (ret) {
+            vec_free(ls->locator_set_name);
+            vec_free(vam->locator_msg);
+            vec_free(vam->locator_set_msg);
+            return ret;
+        }
+
+        tmp_str = format(0, "%=20s%=16d%s", ls->locator_set_name,
+                         ls->locator_set_index,
+                         vec_len(vam->locator_msg) ? "" : "\n");
+        i = 0;
+        vec_foreach(loc, vam->locator_msg) {
+            if (i) {
+                tmp_str = format(tmp_str, "%=37s", " ");
+            }
+            if (loc->local) {
+                tmp_str = format(tmp_str, "%=16d%=16d%=16d\n",
+                                 loc->sw_if_index,
+                                 loc->priority,
+                                 loc->weight);
+            } else {
+                tmp_str = format(tmp_str, "%=16U%=16d%=16d\n",
+                                 loc->is_ipv6 ? format_ip6_address :
+                                 format_ip4_address,
+                                 loc->ip_address,
+                                 loc->priority,
+                                 loc->weight);
+            }
+            i++;
+        }
+
+        fformat(vam->ofp, "%s", tmp_str);
+        vec_free(tmp_str);
+        vec_free(ls->locator_set_name);
+        vec_free(vam->locator_msg);
+    }
+
+    vec_free(vam->locator_set_msg);
+
+    return ret;
+}
+
+static int
+json_locator_in_locator_set(vat_main_t * vam, u8 filter)
+{
+    locator_set_msg_t * ls;
+    locator_msg_t * loc;
+    vat_json_node_t * node = NULL;
+    vat_json_node_t * locator_array;
+    vat_json_node_t * locator;
+    struct in6_addr ip6;
+    struct in_addr ip4;
+    int ret = 0;
+
+    if (!vec_len(vam->locator_set_msg)) {
+        /* just print [] */
+        vat_json_init_array(&vam->json_tree);
+        vat_json_print(vam->ofp, &vam->json_tree);
+        vam->json_tree.type = VAT_JSON_NONE;
+        return ret;
+    }
+
+    if (VAT_JSON_ARRAY != vam->json_tree.type) {
+      ASSERT(VAT_JSON_NONE == vam->json_tree.type);
+      vat_json_init_array(&vam->json_tree);
+    }
+
+    vec_foreach(ls, vam->locator_set_msg) {
+        ret = lisp_locator_dump_send_msg(vam, ls->locator_set_index, filter);
+        if (ret) {
+            vec_free(ls->locator_set_name);
+            vec_free(vam->locator_msg);
+            vec_free(vam->locator_set_msg);
+            vat_json_free(&vam->json_tree);
+            vam->json_tree.type = VAT_JSON_NONE;
+            return ret;
+        }
+
+        node = vat_json_array_add(&vam->json_tree);
+        vat_json_init_object(node);
+
+        vat_json_object_add_uint(node, "locator-set-index",
+                                 ls->locator_set_index);
+        vat_json_object_add_string_copy(node, "locator-set",
+                                        ls->locator_set_name);
+        locator_array = vat_json_object_add_list(node, "locator");
+        vec_foreach(loc, vam->locator_msg) {
+            locator = vat_json_array_add(locator_array);
+            vat_json_init_object(locator);
+            if (loc->local) {
+                vat_json_object_add_uint(locator, "locator-index",
+                                         loc->sw_if_index);
+            } else {
+                if (loc->is_ipv6) {
+                    clib_memcpy(&ip6, loc->ip_address, sizeof(ip6));
+                    vat_json_object_add_ip6(locator, "locator", ip6);
+                } else {
+                    clib_memcpy(&ip4, loc->ip_address, sizeof(ip4));
+                    vat_json_object_add_ip4(locator, "locator", ip4);
+                }
+            }
+            vat_json_object_add_uint(locator, "priority", loc->priority);
+            vat_json_object_add_uint(locator, "weight", loc->weight);
+        }
+
+        vec_free(ls->locator_set_name);
+        vec_free(vam->locator_msg);
+    }
+
+    vat_json_print(vam->ofp, &vam->json_tree);
+    vat_json_free(&vam->json_tree);
+    vam->json_tree.type = VAT_JSON_NONE;
+
+    vec_free(vam->locator_set_msg);
+
+    return ret;
+}
+
+static int
+get_locator_set_index_from_msg(vat_main_t * vam, u8 * locator_set,
+                               u32 * locator_set_index)
+{
+    locator_set_msg_t * ls;
+    int ret = 0;
+
+    * locator_set_index = ~0;
+
+    if (!vec_len(vam->locator_set_msg)) {
+      return ret;
+    }
+
+    vec_foreach(ls, vam->locator_set_msg) {
+        if (!strcmp((char *) locator_set, (char *) ls->locator_set_name)) {
+            * locator_set_index = ls->locator_set_index;
+            vec_free(vam->locator_set_msg);
+            return ret;
+        }
+    }
+
+    vec_free(vam->locator_set_msg);
+
+    return ret;
+}
+
+static int
+get_locator_set_index(vat_main_t * vam, u8 * locator_set,
+                      u32 * locator_set_index)
+{
+    vl_api_lisp_locator_set_dump_t *mp;
+    f64 timeout = ~0;
+
+    M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
+    /* send it... */
+    S;
+
+   /* Use a control ping for synchronization */
+   {
+     vl_api_noprint_control_ping_t * mp;
+     M(NOPRINT_CONTROL_PING, noprint_control_ping);
+     S;
+   }
+
+   vam->noprint_msg = 1;
+    /* Wait for a reply... */
+    W_L({
+      get_locator_set_index_from_msg(vam, locator_set, locator_set_index);
+      vam->noprint_msg = 0;
+    })
 
     /* NOTREACHED */
     return 0;
 }
 
+static inline int
+lisp_locator_dump(vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
+                  u8 filter)
+{
+    int ret = 0;
+
+    ASSERT(vam);
+
+    if (!vam->json_output) {
+      fformat(vam->ofp, "%=20s%=16s%=16s\n",
+              "locator", "priority", "weight");
+    }
+
+    if (locator_set) {
+      ret = get_locator_set_index(vam, locator_set, &locator_set_index);
+    }
+
+    if (!ret && ~0 == locator_set_index) {
+      return -99;
+    }
+
+    ret = lisp_locator_dump_send_msg(vam, locator_set_index, filter);
+
+    return ret;
+}
+
+static int
+lisp_locator_set_dump(vat_main_t * vam, u8 filter)
+{
+    vl_api_lisp_locator_set_dump_t *mp;
+    f64 timeout = ~0;
+
+    if (!vam->json_output) {
+        fformat(vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
+                "locator-set", "locator-set-index", "locator", "priority",
+                "weight");
+    }
+
+    vam->noprint_msg = 1;
+
+    M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
+
+    mp->filter = filter;
+
+    /* send it... */
+    S;
+
+   /* Use a control ping for synchronization */
+   {
+     vl_api_noprint_control_ping_t * mp;
+     M(NOPRINT_CONTROL_PING, noprint_control_ping);
+     S;
+   }
+
+    /* Wait for a reply... */
+    W_L({
+      if (vam->noprint_msg) {
+          if (!vam->json_output) {
+              print_locator_in_locator_set(vam, filter);
+          } else {
+              json_locator_in_locator_set(vam, filter);
+          }
+      }
+
+      vam->noprint_msg = 0;
+    });
+
+    /* NOTREACHED */
+    return 0;
+}
+
+static int
+api_lisp_locator_set_dump(vat_main_t *vam)
+{
+    unformat_input_t * input = vam->input;
+    vam->noprint_msg = 0;
+    u32 locator_set_index = ~0;
+    u8 locator_set_index_set = 0;
+    u8 * locator_set = 0;
+    u8 locator_set_set = 0;
+    u8 filter = 0;
+    int ret = 0;
+
+    /* Parse args required to build the message */
+    while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
+        if (unformat(input, "locator-set-index %u", &locator_set_index)) {
+            locator_set_index_set = 1;
+        } else if (unformat(input, "locator-set %s", &locator_set)) {
+            locator_set_set = 1;
+        } else if (unformat(input, "local")) {
+            filter = 1;
+        } else if (unformat(input, "remote")) {
+            filter = 2;
+        } else {
+            break;
+        }
+    }
+
+    if (locator_set_index_set && locator_set_set) {
+        errmsg ("use only input parameter!\n");
+        return -99;
+    }
+
+    if (locator_set_index_set || locator_set_set) {
+        ret = lisp_locator_dump(vam, locator_set_index, locator_set, filter);
+    } else {
+        ret = lisp_locator_set_dump(vam, filter);
+    }
+
+    vec_free(locator_set);
+
+    return ret;
+}
+
 static int
 api_lisp_eid_table_map_dump(vat_main_t *vam)
 {
@@ -11568,7 +11976,7 @@
     struct in_addr ip4;
     struct in6_addr ip6;
     u8 mac[6];
-    u8 eid_type = ~0, eid_set;
+    u8 eid_type = ~0, eid_set = 0;
     u32 prefix_length = ~0, t, vni = 0;
 
     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
@@ -11696,9 +12104,9 @@
 }
 
 static int
-api_lisp_enable_disable_status_dump(vat_main_t *vam)
+api_show_lisp_status(vat_main_t *vam)
 {
-    vl_api_lisp_enable_disable_status_dump_t *mp;
+    vl_api_show_lisp_status_t *mp;
     f64 timeout = ~0;
 
     if (!vam->json_output) {
@@ -11706,17 +12114,9 @@
                 "lisp status", "locator-set");
     }
 
-    M(LISP_ENABLE_DISABLE_STATUS_DUMP,
-      lisp_enable_disable_status_dump);
+    M(SHOW_LISP_STATUS, show_lisp_status);
     /* send it... */
     S;
-
-    /* Use a control ping for synchronization */
-    {
-        vl_api_control_ping_t * mp;
-        M(CONTROL_PING, control_ping);
-        S;
-    }
     /* Wait for a reply... */
     W;
 
@@ -13182,7 +13582,8 @@
 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
                         "iface <intf> | sw_if_index <sw_if_index> "     \
                         "p <priority> w <weight> [del]")                \
-_(lisp_add_del_local_eid, "<ipv4|ipv6>/<prefix> "                       \
+_(lisp_add_del_local_eid,"vni <vni> eid "                               \
+                         "<ipv4|ipv6>/<prefix> | <L2 address> "         \
                           "locator-set <locator_name> [del]")           \
 _(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> "              \
     "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]")                        \
@@ -13200,12 +13601,13 @@
 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
-_(lisp_locator_set_dump, "")                                            \
+_(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
+                         "locator-set <loc-set-name>] [local | remote]")\
 _(lisp_local_eid_table_dump, "")                                        \
 _(lisp_eid_table_map_dump, "")                                          \
 _(lisp_gpe_tunnel_dump, "")                                             \
 _(lisp_map_resolver_dump, "")                                           \
-_(lisp_enable_disable_status_dump, "")                                  \
+_(show_lisp_status, "")                                                 \
 _(lisp_get_map_request_itr_rlocs, "")                                   \
 _(show_lisp_pitr, "")                                                   \
 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
diff --git a/vpp-api-test/vat/vat.h b/vpp-api-test/vat/vat.h
index 4772f2e..684ad4c 100644
--- a/vpp-api-test/vat/vat.h
+++ b/vpp-api-test/vat/vat.h
@@ -85,6 +85,20 @@
 } ip6_fib_counter_t;
 
 typedef struct {
+    u8 * locator_set_name;
+    u32 locator_set_index;
+} locator_set_msg_t;
+
+typedef struct {
+    u8 local;
+    u32 sw_if_index;
+    u8 is_ipv6;
+    u8 ip_address[16];
+    u8 priority;
+    u8 weight;
+} locator_msg_t;
+
+typedef struct {
     /* vpe input queue */
     unix_shared_memory_queue_t * vl_input_queue;
 
@@ -171,6 +185,11 @@
     ip6_fib_counter_t **ip6_fib_counters;
     u32 *ip6_fib_counters_vrf_id_by_index;
 
+    /* Lisp */
+    u8 noprint_msg;
+    locator_set_msg_t * locator_set_msg;
+    locator_msg_t * locator_msg;
+
 } vat_main_t;
 
 vat_main_t vat_main;
diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c
index 076d16a..1f63065 100644
--- a/vpp/vpp-api/api.c
+++ b/vpp/vpp-api/api.c
@@ -265,6 +265,7 @@
 _(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered)		\
 _(CREATE_LOOPBACK, create_loopback)					\
 _(CONTROL_PING, control_ping)                                           \
+_(NOPRINT_CONTROL_PING, noprint_control_ping)                           \
 _(CLI_REQUEST, cli_request)                                             \
 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit)			\
 _(L2_PATCH_ADD_DEL, l2_patch_add_del)					\
@@ -339,12 +340,12 @@
 _(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_LOCATOR_DUMP, lisp_locator_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)                                      \
+_(SHOW_LISP_STATUS, show_lisp_status)                                   \
 _(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)       \
@@ -3345,6 +3346,18 @@
     }));
 }
 
+static void vl_api_noprint_control_ping_t_handler
+(vl_api_noprint_control_ping_t *mp)
+{
+    vl_api_noprint_control_ping_reply_t * rmp;
+    int rv = 0;
+
+    REPLY_MACRO2(VL_API_NOPRINT_CONTROL_PING_REPLY,
+    ({
+        rmp->vpe_pid = ntohl (getpid());
+    }));
+}
+
 static void shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
 {
     u8 **shmem_vecp = (u8 **)arg;
@@ -5116,23 +5129,6 @@
 }) rloc_t;
 
 static void
-send_lisp_locator_set_details_set_address
-(vl_api_lisp_locator_set_details_t *rmp,
- gid_address_t *gid_address)
-{
-    ip_prefix_t *ip_addr;
-
-    if (gid_address_type(gid_address) != GID_ADDR_IP_PREFIX) {
-        return;
-    }
-
-    ip_addr = &gid_address_ippref(gid_address);
-    rmp->prefix_len = ip_prefix_len(ip_addr);
-    rmp->is_ipv6 = ip_prefix_version(ip_addr);
-    ip_address_copy_addr(rmp->ip_address, &ip_prefix_addr(ip_addr));
-}
-
-static void
 vl_api_lisp_add_del_remote_mapping_t_handler (
     vl_api_lisp_add_del_remote_mapping_t *mp)
 {
@@ -5276,42 +5272,91 @@
 }
 
 static void
+send_lisp_locator_details (lisp_cp_main_t *lcm,
+                           locator_t *loc,
+                           unix_shared_memory_queue_t *q,
+                           u32 context)
+{
+    vl_api_lisp_locator_details_t *rmp;
+
+    rmp = vl_msg_api_alloc (sizeof (*rmp));
+    memset (rmp, 0, sizeof (*rmp));
+    rmp->_vl_msg_id = ntohs(VL_API_LISP_LOCATOR_DETAILS);
+    rmp->context = context;
+
+    rmp->local = loc->local;
+    if (loc->local) {
+        rmp->sw_if_index = ntohl(loc->sw_if_index);
+    } else {
+        rmp->is_ipv6 = gid_address_ip_version(&loc->address);
+        ip_address_copy_addr(rmp->ip_address, &gid_address_ip(&loc->address));
+    }
+    rmp->priority = loc->priority;
+    rmp->weight = loc->weight;
+
+    vl_msg_api_send_shmem (q, (u8 *)&rmp);
+}
+
+static void
+vl_api_lisp_locator_dump_t_handler (vl_api_lisp_locator_dump_t *mp)
+{
+    unix_shared_memory_queue_t * q = 0;
+    lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
+    locator_set_t * lsit = 0;
+    locator_t * loc = 0;
+    u32 ls_index = ~0, * locit = 0;
+    u8 filter;
+
+    q = vl_api_client_index_to_input_queue (mp->client_index);
+    if (q == 0) {
+        return;
+    }
+
+    ls_index = htonl(mp->locator_set_index);
+
+    lsit = pool_elt_at_index(lcm->locator_set_pool, ls_index);
+
+    filter = mp->filter;
+    if (filter && !((1 == filter && lsit->local) ||
+                    (2 == filter && !lsit->local))) {
+          return;
+      }
+
+    vec_foreach(locit, lsit->locator_indices) {
+        loc = pool_elt_at_index(lcm->locator_pool, locit[0]);
+        send_lisp_locator_details(lcm, loc, q, mp->context);
+    };
+}
+
+static void
 send_lisp_locator_set_details (lisp_cp_main_t *lcm,
                                locator_set_t *lsit,
                                unix_shared_memory_queue_t *q,
                                u32 context,
-                               u32 index)
+                               u32 ls_index)
 {
     vl_api_lisp_locator_set_details_t *rmp;
-    locator_t *loc = NULL;
-    u32 * locit = NULL;
-    u8 * str = NULL;
+    u8 * str = 0;
 
-    vec_foreach (locit, lsit->locator_indices) {
-        loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
-        rmp = vl_msg_api_alloc (sizeof (*rmp));
-        memset (rmp, 0, sizeof (*rmp));
-        rmp->_vl_msg_id = ntohs(VL_API_LISP_LOCATOR_SET_DETAILS);
-        rmp->local = lsit->local;
-        if (lsit->local) {
-            ASSERT(lsit->name != NULL);
-            strncpy((char *) rmp->locator_set_name,
-                    (char *) lsit->name, ARRAY_LEN(rmp->locator_set_name) - 1);
-            rmp->sw_if_index = htonl(loc->sw_if_index);
-        } else {
-            str = format(0, "remote-%d", index);
-            strncpy((char *) rmp->locator_set_name, (char *) str,
-                    ARRAY_LEN(rmp->locator_set_name) - 1);
-            send_lisp_locator_set_details_set_address(rmp, &loc->address);
+    rmp = vl_msg_api_alloc (sizeof (*rmp));
+    memset (rmp, 0, sizeof (*rmp));
+    rmp->_vl_msg_id = ntohs(VL_API_LISP_LOCATOR_SET_DETAILS);
+    rmp->context = context;
 
-            vec_free(str);
-        }
-        rmp->priority = loc->priority;
-        rmp->weight = loc->weight;
-        rmp->context = context;
-
-        vl_msg_api_send_shmem (q, (u8 *)&rmp);
+    rmp->local = lsit->local;
+    rmp->locator_set_index= htonl(ls_index);
+    if (lsit->local) {
+      ASSERT(lsit->name != NULL);
+      strncpy((char *) rmp->locator_set_name,
+              (char *) lsit->name, ARRAY_LEN(rmp->locator_set_name) - 1);
+    } else {
+      str = format(0, "remote-%d", ls_index);
+      strncpy((char *) rmp->locator_set_name, (char *) str,
+              ARRAY_LEN(rmp->locator_set_name) - 1);
+      vec_free(str);
     }
+
+    vl_msg_api_send_shmem (q, (u8 *)&rmp);
 }
 
 static void
@@ -5321,15 +5366,23 @@
     lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
     locator_set_t * lsit = NULL;
     u32 index;
+    u8 filter;
 
     q = vl_api_client_index_to_input_queue (mp->client_index);
     if (q == 0) {
         return;
     }
 
+    filter = mp->filter;
     index = 0;
     pool_foreach (lsit, lcm->locator_set_pool,
         ({
+            if (filter && !((1 == filter && lsit->local) ||
+                            (2 == filter && !lsit->local))) {
+                index++;
+                continue;
+            }
+
             send_lisp_locator_set_details(lcm, lsit, q, mp->context, index++);
         }));
 }
@@ -5585,34 +5638,23 @@
 }
 
 static void
-send_lisp_enable_disable_details (unix_shared_memory_queue_t *q,
-                                      u32 context)
-{
-    vl_api_lisp_enable_disable_status_details_t *rmp = NULL;
-
-    rmp = vl_msg_api_alloc (sizeof (*rmp));
-    memset (rmp, 0, sizeof (*rmp));
-    rmp->_vl_msg_id = ntohs(VL_API_LISP_ENABLE_DISABLE_STATUS_DETAILS);
-
-    rmp->gpe_status = vnet_lisp_gpe_enable_disable_status ();
-    rmp->feature_status = vnet_lisp_enable_disable_status ();
-    rmp->context = context;
-
-    vl_msg_api_send_shmem (q, (u8 *)&rmp);
-}
-
-static void
-vl_api_lisp_enable_disable_status_dump_t_handler
-(vl_api_lisp_enable_disable_status_dump_t *mp)
+vl_api_show_lisp_status_t_handler
+(vl_api_show_lisp_status_t *mp)
 {
     unix_shared_memory_queue_t * q = NULL;
+    vl_api_show_lisp_status_reply_t *rmp = NULL;
+    int rv = 0;
 
     q = vl_api_client_index_to_input_queue (mp->client_index);
     if (q == 0) {
         return;
     }
 
-    send_lisp_enable_disable_details(q, mp->context);
+    REPLY_MACRO2(VL_API_SHOW_LISP_STATUS_REPLY,
+    ({
+      rmp->gpe_status = vnet_lisp_gpe_enable_disable_status ();
+      rmp->feature_status = vnet_lisp_enable_disable_status ();
+    }));
 }
 
 static void
diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api
index 0783949..f8cf370 100644
--- a/vpp/vpp-api/vpe.api
+++ b/vpp/vpp-api/vpe.api
@@ -1073,6 +1073,28 @@
     u32 vpe_pid;
 };
 
+/** \brief Control ping from client to api server request, no print json output
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+*/
+define noprint_control_ping {
+    u32 client_index;
+    u32 context;
+};
+
+/** \brief Control ping from the client to the server response
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param retval - return code for the request
+    @param vpe_pid - the pid of the vpe, returned by the server
+*/
+define noprint_control_ping_reply {
+    u32 context;
+    i32 retval;
+    u32 client_index;
+    u32 vpe_pid;
+};
+
 /** \brief Process a vpe parser cli string request
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
@@ -2500,31 +2522,66 @@
     i32 retval;
 };
 
+/** \brief Request for map lisp locator status
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param locator_set_index - index of locator_set
+    @param filter - filter type;
+      Support value:
+        0: all locator
+        1: local locator
+        2: remote locator
+ */
+define lisp_locator_dump {
+    u32 client_index;
+    u32 context;
+    u32 locator_set_index;
+    u8  filter;
+};
+
 /** \brief LISP locator_set status
+    @param local - if is set, then locator is local
     @param locator_set_name - name of the locator_set
     @param sw_if_index - sw_if_index of the locator
     @param priority - locator priority
     @param weight - locator weight
+  */
+define lisp_locator_details {
+    u32 context;
+    u8  local;
+    u32 sw_if_index;
+    u8  is_ipv6;
+    u8  ip_address[16];
+    u8  priority;
+    u8  weight;
+};
+
+/** \brief LISP locator_set status
+    @param locator_set_name - name of the locator_set
+    @param local - if is set, then locator_set is local
+    @param locator_count - number of locator this stats block includes
+    @param locator - locator data
  */
 define lisp_locator_set_details {
     u32 context;
     u8  local;
+    u32 locator_set_index;
     u8  locator_set_name[64];
-    u32 sw_if_index;
-    u8  is_ipv6;
-    u8  ip_address[16];
-    u8  prefix_len;
-    u8  priority;
-    u8  weight;
 };
 
 /** \brief Request for locator_set summary status
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
+    @param filter - filter type;
+      Support value:
+        0: all locator_set
+        1: local locator_set
+        2: remote locator_set
  */
 define lisp_locator_set_dump {
     u32 client_index;
     u32 context;
+    u8  filter;
 };
 
 /** \brief LISP local eid table status
@@ -2631,25 +2688,27 @@
     u32 context;
 };
 
-/** \brief Status of lisp-gpe protocol, enable or disable
-    @param context - sender context, to match reply w/ request
-    @param is_en - enable protocol if non-zero, else disable
-*/
-define lisp_enable_disable_status_details {
-    u32 context;
-    u8 feature_status;
-    u8 gpe_status;
-};
-
 /** \brief Request for lisp-gpe protocol status
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
 */
-define lisp_enable_disable_status_dump {
+define show_lisp_status{
     u32 client_index;
     u32 context;
 };
 
+/** \brief Status of lisp, enable or disable
+    @param context - sender context, to match reply w/ request
+    @param feature_status - lisp enable if non-zero, else disable
+    @param gpe_status - lisp enable if non-zero, else disable
+*/
+define show_lisp_status_reply{
+    u32 context;
+    i32 retval;
+    u8 feature_status;
+    u8 gpe_status;
+};
+
 /** \brief Get LISP map request itr rlocs status
     @param context - sender context, to match reply w/ request
     @param locator_set_name - name of the locator_set