ONE-4: Add LISP enable/disable API/CLI 39/1039/3
authorFilip Tehlar <ftehlar@cisco.com>
Mon, 9 May 2016 07:39:26 +0000 (09:39 +0200)
committerFilip Tehlar <ftehlar@cisco.com>
Tue, 10 May 2016 11:52:48 +0000 (13:52 +0200)
This patch adds an enable/disable API/CLI for control plane
which calls similar functions for data plane. When re-enabling
it also re-populates dataplane with tunnels and interfaces.

Change-Id: Id8c3d6af90ecc0be331d502756914b1f62824046
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
vnet/vnet/lisp-cp/control.c
vnet/vnet/lisp-cp/control.h
vnet/vnet/lisp-gpe/lisp_gpe.c
vnet/vnet/lisp-gpe/lisp_gpe.h
vpp-api-test/vat/api_format.c
vpp/api/api.c
vpp/api/vpe.api

index 1822c45..7799227 100644 (file)
@@ -660,6 +660,138 @@ vnet_lisp_add_del_locator (vnet_lisp_add_del_locator_set_args_t *a,
   return 0;
 }
 
+clib_error_t *
+vnet_lisp_enable_disable (u8 is_enabled)
+{
+  vnet_lisp_gpe_add_del_iface_args_t _ai, * ai= &_ai;
+  uword * table_id, * refc;
+  u32 i;
+  clib_error_t * error = 0;
+  lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
+  vnet_lisp_gpe_enable_disable_args_t _a, * a = &_a;
+
+  a->is_en = is_enabled;
+  error = vnet_lisp_gpe_enable_disable (a);
+  if (error)
+    {
+      return clib_error_return (0, "failed to %s data-plane!",
+                                a->is_en ? "enable" : "disable");
+    }
+
+  if (is_enabled)
+    {
+      /* enable all ifaces */
+      for (i = 0; i < vec_len (lcm->local_mappings_indexes); i++)
+        {
+          mapping_t * m = vec_elt_at_index (lcm->mapping_pool, i);
+          ai->is_add = 1;
+          ai->vni = gid_address_vni (&m->eid);
+
+          refc = hash_get (lcm->dp_if_refcount_by_vni, ai->vni);
+          if (!refc)
+            {
+              table_id = hash_get (lcm->table_id_by_vni, ai->vni);
+              if (table_id)
+                {
+                  ai->table_id = table_id[0];
+                  /* enables interface and adds defaults */
+                  vnet_lisp_gpe_add_del_iface (ai, 0);
+                }
+              else
+                return clib_error_return (0, "no table_id found for vni %u!",
+                                          ai->vni);
+
+              hash_set (lcm->dp_if_refcount_by_vni, ai->vni, 1);
+            }
+          else
+            {
+              refc[0]++;
+            }
+        }
+    }
+  else
+    {
+      /* clear refcount table */
+      hash_free (lcm->dp_if_refcount_by_vni);
+    }
+
+  /* update global flag */
+  lcm->is_enabled = is_enabled;
+
+  return 0;
+}
+
+static clib_error_t *
+lisp_enable_disable_command_fn (vlib_main_t * vm, unformat_input_t * input,
+                                   vlib_cli_command_t * cmd)
+{
+  unformat_input_t _line_input, * line_input = &_line_input;
+  u8 is_enabled = 0;
+  u8 is_set = 0;
+
+  /* Get a line of input. */
+  if (! unformat_user (input, unformat_line_input, line_input))
+    return 0;
+
+  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (line_input, "enable"))
+        {
+          is_set = 1;
+          is_enabled = 1;
+        }
+      else if (unformat (line_input, "disable"))
+        is_set = 1;
+      else
+        {
+          return clib_error_return (0, "parse error: '%U'",
+                                   format_unformat_error, line_input);
+        }
+    }
+
+  if (!is_set)
+      return clib_error_return (0, "state not set");
+
+  return vnet_lisp_enable_disable (is_enabled);
+}
+
+VLIB_CLI_COMMAND (lisp_cp_enable_disable_command) = {
+    .path = "lisp",
+    .short_help = "lisp [enable|disable]",
+    .function = lisp_enable_disable_command_fn,
+};
+
+u8
+vnet_lisp_enable_disable_status (void)
+{
+  lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
+  return lcm->is_enabled;
+}
+
+static u8 *
+format_lisp_status (u8 * s, va_list * args)
+{
+  lisp_cp_main_t * lcm = vnet_lisp_cp_get_main ();
+  return format (s, "%s", lcm->is_enabled ? "enabled" : "disabled");
+}
+
+static clib_error_t *
+lisp_show_status_command_fn (vlib_main_t * vm, unformat_input_t * input,
+                             vlib_cli_command_t * cmd)
+{
+  u8 * msg = 0;
+  msg = format (msg, "feature: %U\ngpe: %U\n",
+                format_lisp_status, format_vnet_lisp_gpe_status);
+  vlib_cli_output (vm, "%v", msg);
+  vec_free (msg);
+  return 0;
+}
+
+VLIB_CLI_COMMAND (lisp_show_status_command) = {
+    .path = "show lisp status",
+    .short_help = "show lisp status",
+    .function = lisp_show_status_command_fn,
+};
 static clib_error_t *
 lisp_add_del_locator_set_command_fn (vlib_main_t * vm, unformat_input_t * input,
                                      vlib_cli_command_t * cmd)
index f87a6d5..fad90e6 100644 (file)
@@ -51,6 +51,9 @@ typedef struct
 
 typedef struct
 {
+  /* LISP feature status */
+  u8 is_enabled;
+
   /* eid table */
   gid_dictionary_t mapping_index_by_gid;
 
@@ -169,4 +172,7 @@ vnet_lisp_cp_get_main() {
   return &lisp_control_main;
 }
 
+clib_error_t * vnet_lisp_enable_disable (u8 is_enabled);
+u8 vnet_lisp_enable_disable_status (void);
+
 #endif /* VNET_CONTROL_H_ */
index 76d51b1..b7906cd 100644 (file)
@@ -576,4 +576,11 @@ lisp_gpe_init (vlib_main_t *vm)
   return 0;
 }
 
+u8 *
+format_vnet_lisp_gpe_status (u8 * s, va_list * args)
+{
+  lisp_gpe_main_t * lgm = &lisp_gpe_main;
+  return format (s, "%s", lgm->is_en ? "enabled" : "disabled");
+}
+
 VLIB_INIT_FUNCTION(lisp_gpe_init);
index bc0af79..2d18d7d 100644 (file)
@@ -265,4 +265,6 @@ typedef enum lgpe_ip6_lookup_next
   LGPE_IP6_LOOKUP_N_NEXT,
 } lgpe_ip6_lookup_next_t;
 
+u8 * format_vnet_lisp_gpe_status (u8 * s, va_list * args);
+
 #endif /* included_vnet_lisp_gpe_h */
index 1c8a14d..ec43c32 100644 (file)
@@ -2083,24 +2083,28 @@ vl_api_lisp_map_resolver_details_t_handler_json (
 }
 
 static void
-vl_api_lisp_gpe_enable_disable_status_details_t_handler
-(vl_api_lisp_gpe_enable_disable_status_details_t *mp)
+vl_api_lisp_enable_disable_status_details_t_handler
+(vl_api_lisp_enable_disable_status_details_t *mp)
 {
     vat_main_t *vam = &vat_main;
 
-    fformat(vam->ofp, "%=20s\n",
-            mp->is_en ? "enable" : "disable");
+    fformat(vam->ofp, "feature: %s\ngpe: %s\n",
+            mp->feature_status ? "enabled" : "disabled",
+            mp->gpe_status ? "enabled" : "disabled");
 }
 
 static void
-vl_api_lisp_gpe_enable_disable_status_details_t_handler_json
-(vl_api_lisp_gpe_enable_disable_status_details_t *mp)
+vl_api_lisp_enable_disable_status_details_t_handler_json
+(vl_api_lisp_enable_disable_status_details_t *mp)
 {
     vat_main_t *vam = &vat_main;
     vat_json_node_t *node = NULL;
-    u8 *str = NULL;
+    u8 * gpe_status = NULL;
+    u8 * feature_status = NULL;
 
-    str = format(0, "%s", mp->is_en ? "enable" : "disable");
+    gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
+    feature_status = format (0, "%s",
+                            mp->feature_status ? "enabled" : "disabled");
 
     if (VAT_JSON_ARRAY != vam->json_tree.type) {
         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
@@ -2109,7 +2113,11 @@ vl_api_lisp_gpe_enable_disable_status_details_t_handler_json
     node = vat_json_array_add(&vam->json_tree);
 
     vat_json_init_object(node);
-    vat_json_object_add_string_copy(node, "lisp_gpe", str);
+    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);
 }
 
 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
@@ -2202,6 +2210,7 @@ _(lisp_gpe_add_del_fwd_entry_reply)                     \
 _(lisp_add_del_map_resolver_reply)                      \
 _(lisp_gpe_enable_disable_reply)                        \
 _(lisp_gpe_add_del_iface_reply)                         \
+_(lisp_enable_disable_reply)                            \
 _(af_packet_create_reply)                               \
 _(af_packet_delete_reply)
 
@@ -2375,13 +2384,14 @@ _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
+_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
 _(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details)           \
 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
-_(LISP_GPE_ENABLE_DISABLE_STATUS_DETAILS,                               \
-  lisp_gpe_enable_disable_status_details)                               \
+_(LISP_ENABLE_DISABLE_STATUS_DETAILS,                                   \
+  lisp_enable_disable_status_details)                                   \
 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)
 
@@ -10013,6 +10023,52 @@ api_lisp_gpe_enable_disable (vat_main_t * vam)
   return 0;
 }
 
+static int
+api_lisp_enable_disable (vat_main_t * vam)
+{
+  unformat_input_t * input = vam->input;
+  vl_api_lisp_enable_disable_t *mp;
+  f64 timeout = ~0;
+  u8 is_set = 0;
+  u8 is_en = 0;
+
+  /* Parse args required to build the message */
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "enable"))
+        {
+          is_set = 1;
+          is_en = 1;
+        }
+      else if (unformat (input, "disable"))
+        {
+          is_set = 1;
+        }
+      else
+          break;
+    }
+
+  if (!is_set)
+    {
+      errmsg ("Value not set\n");
+      return -99;
+    }
+
+  /* Construct the API message */
+  M(LISP_ENABLE_DISABLE, lisp_enable_disable);
+
+  mp->is_en = is_en;
+
+  /* send it... */
+  S;
+
+  /* Wait for a reply... */
+  W;
+
+  /* NOTREACHED */
+  return 0;
+}
+
 static int
 api_lisp_gpe_add_del_iface(vat_main_t * vam)
 {
@@ -10177,18 +10233,18 @@ api_lisp_map_resolver_dump(vat_main_t *vam)
 }
 
 static int
-api_lisp_gpe_enable_disable_status_dump(vat_main_t *vam)
+api_lisp_enable_disable_status_dump(vat_main_t *vam)
 {
-    vl_api_lisp_gpe_enable_disable_status_dump_t *mp;
+    vl_api_lisp_enable_disable_status_dump_t *mp;
     f64 timeout = ~0;
 
     if (!vam->json_output) {
         fformat(vam->ofp, "%=20s\n",
-                "lisp gpe");
+                "lisp status:");
     }
 
-    M(LISP_GPE_ENABLE_DISABLE_STATUS_DUMP,
-      lisp_gpe_enable_disable_status_dump);
+    M(LISP_ENABLE_DISABLE_STATUS_DUMP,
+      lisp_enable_disable_status_dump);
     /* send it... */
     S;
 
@@ -10765,12 +10821,13 @@ _(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> "              \
     "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]")                        \
 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
 _(lisp_gpe_enable_disable, "enable|disable")                            \
+_(lisp_enable_disable, "enable|disable")                                \
 _(lisp_gpe_add_del_iface, "up|down")                                    \
 _(lisp_locator_set_dump, "")                                            \
 _(lisp_local_eid_table_dump, "")                                        \
 _(lisp_gpe_tunnel_dump, "")                                             \
 _(lisp_map_resolver_dump, "")                                           \
-_(lisp_gpe_enable_disable_status_dump, "")                              \
+_(lisp_enable_disable_status_dump, "")                                  \
 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
 _(af_packet_delete, "name <host interface name>")
 
index 4d7a919..c1f7fef 100644 (file)
@@ -326,14 +326,14 @@ _(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid)                       \
 _(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry)               \
 _(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver)                 \
 _(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_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_GPE_ENABLE_DISABLE_STATUS_DUMP,                                  \
-  lisp_gpe_enable_disable_status_dump)                                  \
-_(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del)                   \
+_(LISP_ENABLE_DISABLE_STATUS_DUMP,                                      \
+  lisp_enable_disable_status_dump)                                      \
 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del)                   \
 _(AF_PACKET_CREATE, af_packet_create)                                   \
 _(AF_PACKET_DELETE, af_packet_delete)
@@ -4883,6 +4883,17 @@ vl_api_lisp_gpe_enable_disable_t_handler(
     REPLY_MACRO(VL_API_LISP_GPE_ENABLE_DISABLE_REPLY);
 }
 
+static void
+vl_api_lisp_enable_disable_t_handler(
+    vl_api_lisp_enable_disable_t *mp)
+{
+    vl_api_lisp_enable_disable_reply_t *rmp;
+    int rv = 0;
+
+    vnet_lisp_enable_disable (mp->is_en);
+    REPLY_MACRO(VL_API_LISP_ENABLE_DISABLE_REPLY);
+}
+
 static void
 vl_api_lisp_gpe_add_del_iface_t_handler(
     vl_api_lisp_gpe_add_del_iface_t *mp)
@@ -5119,26 +5130,25 @@ vl_api_lisp_map_resolver_dump_t_handler (
 }
 
 static void
-send_lisp_gpe_enable_disable_details (unix_shared_memory_queue_t *q,
+send_lisp_enable_disable_details (unix_shared_memory_queue_t *q,
                                       u32 context)
 {
-    vl_api_lisp_gpe_enable_disable_status_details_t *rmp = NULL;
-    u8 is_en;
+    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_GPE_ENABLE_DISABLE_STATUS_DETAILS);
+    rmp->_vl_msg_id = ntohs(VL_API_LISP_ENABLE_DISABLE_STATUS_DETAILS);
 
-    is_en = vnet_lisp_gpe_enable_disable_status();
-    rmp->is_en = is_en;
+    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_gpe_enable_disable_status_dump_t_handler
-(vl_api_lisp_gpe_enable_disable_status_dump_t *mp)
+vl_api_lisp_enable_disable_status_dump_t_handler
+(vl_api_lisp_enable_disable_status_dump_t *mp)
 {
     unix_shared_memory_queue_t * q = NULL;
 
@@ -5147,7 +5157,7 @@ vl_api_lisp_gpe_enable_disable_status_dump_t_handler
         return;
     }
 
-    send_lisp_gpe_enable_disable_details(q, mp->context);
+    send_lisp_enable_disable_details(q, mp->context);
 }
 
 static void 
index c92715f..bef6ffb 100644 (file)
@@ -2323,6 +2323,26 @@ define lisp_gpe_enable_disable_reply {
     i32 retval;
 };
 
+/** \brief enable or disable LISP feature
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param is_en - enable protocol if non-zero, else disable
+*/
+define lisp_enable_disable {
+    u32 client_index;
+    u32 context;
+    u8  is_en;
+};
+
+/** \brief Reply for gpe enable/disable
+    @param context - returned sender context, to match reply w/ request
+    @param retval - return code
+*/
+define lisp_enable_disable_reply {
+    u32 context;
+    i32 retval;
+};
+
 /** \brief add or delete gpe_iface
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
@@ -2441,16 +2461,17 @@ define lisp_map_resolver_dump {
     @param context - sender context, to match reply w/ request
     @param is_en - enable protocol if non-zero, else disable
 */
-manual_java define lisp_gpe_enable_disable_status_details {
+manual_java define lisp_enable_disable_status_details {
     u32 context;
-    u8  is_en;
+    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_gpe_enable_disable_status_dump {
+define lisp_enable_disable_status_dump {
     u32 client_index;
     u32 context;
 };