api: binary api cleanup 13/20813/1
authorDave Barach <dave@barachs.net>
Tue, 23 Jul 2019 20:28:36 +0000 (16:28 -0400)
committerDave Barach <dave@barachs.net>
Tue, 23 Jul 2019 20:29:10 +0000 (16:29 -0400)
Multiple API message handlers call vnet_get_sup_hw_interface(...)
without checking the inbound sw_if_index. This can cause a
pool_elt_at_index ASSERT in a debug image, and major disorder in a
production image.

Given that a number of places are coded as follows, add an
"api_visible_or_null" variant of vnet_get_sup_hw_interface, which
returns NULL given an invalid sw_if_index, or a hidden sw interface:

-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || memif_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a memif interface");

Rename two existing xxx_safe functions -> xxx_or_null to make it
obvious what they return.

Type: fix

Change-Id: I29996e8d0768fd9e0c5495bd91ff8bedcf2c5697
Signed-off-by: Dave Barach <dave@barachs.net>
22 files changed:
src/plugins/avf/avf_api.c
src/plugins/avf/cli.c
src/plugins/marvell/pp2/cli.c
src/plugins/memif/cli.c
src/plugins/memif/memif_api.c
src/plugins/rdma/cli.c
src/plugins/vmxnet3/cli.c
src/plugins/vmxnet3/vmxnet3_api.c
src/vnet/adj/rewrite.c
src/vnet/bfd/bfd_cli.c
src/vnet/bfd/bfd_udp.c
src/vnet/devices/tap/tap.c
src/vnet/devices/virtio/cli.c
src/vnet/devices/virtio/vhost_user.c
src/vnet/devices/virtio/virtio_api.c
src/vnet/interface_api.c
src/vnet/interface_format.c
src/vnet/interface_funcs.h
src/vnet/l2/l2_fib.c
src/vnet/l2/l2_vtr.c
src/vnet/session/application_namespace.c
src/vpp/api/custom_dump.c

index 3503177..e9c7f49 100644 (file)
@@ -94,7 +94,9 @@ vl_api_avf_delete_t_handler (vl_api_avf_delete_t * mp)
   vnet_hw_interface_t *hw;
   int rv = 0;
 
-  hw = vnet_get_sup_hw_interface (vnm, htonl (mp->sw_if_index));
+  hw =
+    vnet_get_sup_hw_interface_api_visible_or_null (vnm,
+                                                  htonl (mp->sw_if_index));
   if (hw == NULL || avf_device_class.index != hw->dev_class_index)
     {
       rv = VNET_API_ERROR_INVALID_INTERFACE;
index f8fc05a..414163a 100644 (file)
@@ -109,7 +109,7 @@ avf_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || avf_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not an AVF interface");
 
@@ -168,7 +168,7 @@ avf_test_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || avf_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a AVF interface");
 
index 3264cc8..761cdb5 100644 (file)
@@ -94,7 +94,7 @@ mrvl_pp2_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || mrvl_pp2_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a Marvell PP2 interface");
 
index dd13adb..00c947a 100644 (file)
@@ -298,7 +298,7 @@ memif_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || memif_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a memif interface");
 
index bbc9e5c..ebe7a35 100644 (file)
@@ -209,11 +209,14 @@ vl_api_memif_delete_t_handler (vl_api_memif_delete_t * mp)
   vlib_main_t *vm = vlib_get_main ();
   vnet_main_t *vnm = vnet_get_main ();
   vl_api_memif_delete_reply_t *rmp;
-  vnet_hw_interface_t *hi =
-    vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
+  vnet_hw_interface_t *hi;
   memif_if_t *mif;
   int rv = 0;
 
+  hi =
+    vnet_get_sup_hw_interface_api_visible_or_null (vnm,
+                                                  ntohl (mp->sw_if_index));
+
   if (hi == NULL || memif_device_class.index != hi->dev_class_index)
     rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
   else
index 1f377a7..d4ef17d 100644 (file)
@@ -107,7 +107,7 @@ rdma_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || rdma_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a RDMA interface");
 
index 76db1ca..e1d74e8 100644 (file)
@@ -109,7 +109,7 @@ vmxnet3_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || vmxnet3_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a vmxnet3 interface");
 
@@ -166,7 +166,7 @@ vmxnet3_test_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || vmxnet3_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a vmxnet3 interface");
 
index 8395f15..8afc40e 100644 (file)
@@ -125,10 +125,12 @@ vl_api_vmxnet3_delete_t_handler (vl_api_vmxnet3_delete_t * mp)
   vnet_hw_interface_t *hw;
   int rv = 0;
 
-  hw = vnet_get_sup_hw_interface (vnm, htonl (mp->sw_if_index));
+  hw =
+    vnet_get_sup_hw_interface_api_visible_or_null (vnm,
+                                                  htonl (mp->sw_if_index));
   if (hw == NULL || vmxnet3_device_class.index != hw->dev_class_index)
     {
-      rv = VNET_API_ERROR_INVALID_INTERFACE;
+      rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
       goto reply;
     }
 
index cf3cf41..c8508c4 100644 (file)
@@ -53,7 +53,7 @@ format_vnet_rewrite (u8 * s, va_list * args)
   if (rw->sw_if_index != ~0)
     {
       vnet_sw_interface_t *si;
-      si = vnet_get_sw_interface_safe (vnm, rw->sw_if_index);
+      si = vnet_get_sw_interface_or_null (vnm, rw->sw_if_index);
       if (NULL != si)
        s = format (s, "%U:", format_vnet_sw_interface_name, vnm, si);
       else
index cab20a6..4b5f75e 100644 (file)
@@ -170,7 +170,7 @@ show_bfd (vlib_main_t * vm, unformat_input_t * input,
       if (is_set)
        {
          vnet_sw_interface_t *sw_if =
-           vnet_get_sw_interface_safe (&vnet_main, sw_if_index);
+           vnet_get_sw_interface_or_null (&vnet_main, sw_if_index);
          vnet_hw_interface_t *hw_if =
            vnet_get_hw_interface (&vnet_main, sw_if->hw_if_index);
          u8 *s = format (NULL, "UDP echo source is: %v\n", hw_if->name);
index 5c0da0a..cc3b40c 100644 (file)
@@ -82,7 +82,7 @@ vnet_api_error_t
 bfd_udp_set_echo_source (u32 sw_if_index)
 {
   vnet_sw_interface_t *sw_if =
-    vnet_get_sw_interface_safe (bfd_udp_main.vnet_main, sw_if_index);
+    vnet_get_sw_interface_or_null (bfd_udp_main.vnet_main, sw_if_index);
   if (sw_if)
     {
       bfd_udp_main.echo_source_sw_if_index = sw_if_index;
@@ -114,8 +114,8 @@ bfd_udp_is_echo_available (bfd_transport_e transport)
    * pick an unused address from that subnet
    */
   vnet_sw_interface_t *sw_if =
-    vnet_get_sw_interface_safe (bfd_udp_main.vnet_main,
-                               bfd_udp_main.echo_source_sw_if_index);
+    vnet_get_sw_interface_or_null (bfd_udp_main.vnet_main,
+                                  bfd_udp_main.echo_source_sw_if_index);
   if (sw_if && sw_if->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
     {
       if (BFD_TRANSPORT_UDP4 == transport)
@@ -566,7 +566,7 @@ bfd_udp_validate_api_input (u32 sw_if_index,
 {
   bfd_udp_main_t *bum = &bfd_udp_main;
   vnet_sw_interface_t *sw_if =
-    vnet_get_sw_interface_safe (bfd_udp_main.vnet_main, sw_if_index);
+    vnet_get_sw_interface_or_null (bfd_udp_main.vnet_main, sw_if_index);
   u8 local_ip_valid = 0;
   ip_interface_address_t *ia = NULL;
   if (!sw_if)
index c090bed..974a417 100644 (file)
@@ -514,7 +514,7 @@ tap_delete_if (vlib_main_t * vm, u32 sw_if_index)
   virtio_if_t *vif;
   vnet_hw_interface_t *hw;
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
     return VNET_API_ERROR_INVALID_SW_IF_INDEX;
 
@@ -565,9 +565,11 @@ tap_gso_enable_disable (vlib_main_t * vm, u32 sw_if_index, int enable_disable)
   vnet_main_t *vnm = vnet_get_main ();
   virtio_main_t *mm = &virtio_main;
   virtio_if_t *vif;
-  vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  vnet_hw_interface_t *hw;
   clib_error_t *err = 0;
 
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
+
   if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
     return VNET_API_ERROR_INVALID_SW_IF_INDEX;
 
index 10b545e..86639e4 100644 (file)
@@ -96,7 +96,7 @@ virtio_pci_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a virtio interface");
 
index 5c552f9..e26cfdf 100644 (file)
@@ -1250,8 +1250,10 @@ vhost_user_delete_if (vnet_main_t * vnm, vlib_main_t * vm, u32 sw_if_index)
   vnet_hw_interface_t *hwif;
   u16 qid;
 
-  if (!(hwif = vnet_get_sup_hw_interface (vnm, sw_if_index)) ||
-      hwif->dev_class_index != vhost_user_device_class.index)
+  if (!
+      (hwif =
+       vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index))
+      || hwif->dev_class_index != vhost_user_device_class.index)
     return VNET_API_ERROR_INVALID_SW_IF_INDEX;
 
   vui = pool_elt_at_index (vum->vhost_user_interfaces, hwif->dev_instance);
@@ -1534,8 +1536,10 @@ vhost_user_modify_if (vnet_main_t * vnm, vlib_main_t * vm,
   vnet_hw_interface_t *hwif;
   uword *if_index;
 
-  if (!(hwif = vnet_get_sup_hw_interface (vnm, sw_if_index)) ||
-      hwif->dev_class_index != vhost_user_device_class.index)
+  if (!
+      (hwif =
+       vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index))
+      || hwif->dev_class_index != vhost_user_device_class.index)
     return VNET_API_ERROR_INVALID_SW_IF_INDEX;
 
   if (sock_filename == NULL || !(strlen (sock_filename) > 0))
@@ -1658,7 +1662,7 @@ vhost_user_delete_command_fn (vlib_main_t * vm,
                &sw_if_index))
        {
          vnet_hw_interface_t *hwif =
-           vnet_get_sup_hw_interface (vnm, sw_if_index);
+           vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
          if (hwif == NULL ||
              vhost_user_device_class.index != hwif->dev_class_index)
            {
index d73e6f8..e354958 100644 (file)
@@ -99,10 +99,12 @@ vl_api_virtio_pci_delete_t_handler (vl_api_virtio_pci_delete_t * mp)
   vl_api_virtio_pci_delete_reply_t *rmp;
   vl_api_registration_t *reg;
 
-  hw = vnet_get_sup_hw_interface (vnm, htonl (mp->sw_if_index));
+  hw =
+    vnet_get_sup_hw_interface_api_visible_or_null (vnm,
+                                                  htonl (mp->sw_if_index));
   if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
     {
-      rv = VNET_API_ERROR_INVALID_INTERFACE;
+      rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
       goto reply;
     }
 
index 50921f2..fb1982a 100644 (file)
@@ -1385,6 +1385,9 @@ interface_api_hookup (vlib_main_t * vm)
   am->is_mp_safe[VL_API_SW_INTERFACE_DETAILS] = 1;
   am->is_mp_safe[VL_API_SW_INTERFACE_TAG_ADD_DEL] = 1;
 
+  /* Do not replay VL_API_SW_INTERFACE_DUMP messages */
+  am->api_trace_cfg[VL_API_SW_INTERFACE_DUMP].replay_enable = 0;
+
   /*
    * Set up the (msg_name, crc, message-id) table
    */
index 1a3ef02..209da18 100644 (file)
@@ -190,7 +190,7 @@ format_vnet_sw_if_index_name (u8 * s, va_list * args)
   u32 sw_if_index = va_arg (*args, u32);
   vnet_sw_interface_t *si;
 
-  si = vnet_get_sw_interface_safe (vnm, sw_if_index);
+  si = vnet_get_sw_interface_or_null (vnm, sw_if_index);
 
   if (NULL == si)
     {
index 6d404b4..c0ad81c 100644 (file)
@@ -47,7 +47,7 @@ vnet_get_hw_interface (vnet_main_t * vnm, u32 hw_if_index)
 }
 
 always_inline vnet_hw_interface_t *
-vnet_get_hw_interface_safe (vnet_main_t * vnm, u32 hw_if_index)
+vnet_get_hw_interface_or_null (vnet_main_t * vnm, u32 hw_if_index)
 {
   if (!pool_is_free_index (vnm->interface_main.hw_interfaces, hw_if_index))
     return pool_elt_at_index (vnm->interface_main.hw_interfaces, hw_if_index);
@@ -61,7 +61,7 @@ vnet_get_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
 }
 
 always_inline vnet_sw_interface_t *
-vnet_get_sw_interface_safe (vnet_main_t * vnm, u32 sw_if_index)
+vnet_get_sw_interface_or_null (vnet_main_t * vnm, u32 sw_if_index)
 {
   if (!pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
     return pool_elt_at_index (vnm->interface_main.sw_interfaces, sw_if_index);
@@ -97,6 +97,22 @@ vnet_get_sup_hw_interface (vnet_main_t * vnm, u32 sw_if_index)
   return vnet_get_hw_interface (vnm, sw->hw_if_index);
 }
 
+always_inline vnet_hw_interface_t *
+vnet_get_sup_hw_interface_api_visible_or_null (vnet_main_t * vnm,
+                                              u32 sw_if_index)
+{
+  vnet_sw_interface_t *si;
+  if (PREDICT_FALSE (pool_is_free_index (vnm->interface_main.sw_interfaces,
+                                        sw_if_index)))
+    return NULL;
+  si = vnet_get_sup_sw_interface (vnm, sw_if_index);
+  if (PREDICT_FALSE (si->flags & VNET_SW_INTERFACE_FLAG_HIDDEN))
+    return NULL;
+  ASSERT ((si->type == VNET_SW_INTERFACE_TYPE_HARDWARE) ||
+         (si->type == VNET_SW_INTERFACE_TYPE_PIPE));
+  return vnet_get_hw_interface (vnm, si->hw_if_index);
+}
+
 always_inline vnet_hw_interface_class_t *
 vnet_get_hw_interface_class (vnet_main_t * vnm, u32 hw_class_index)
 {
index b7646ca..600d0c9 100644 (file)
@@ -95,12 +95,13 @@ format_vnet_sw_if_index_name_with_NA (u8 * s, va_list * args)
   if (sw_if_index == ~0)
     return format (s, "N/A");
 
-  vnet_sw_interface_t *swif = vnet_get_sw_interface_safe (vnm, sw_if_index);
+  vnet_sw_interface_t *swif =
+    vnet_get_sw_interface_or_null (vnm, sw_if_index);
   if (!swif)
     return format (s, "Stale");
 
   return format (s, "%U", format_vnet_sw_interface_name, vnm,
-                vnet_get_sw_interface_safe (vnm, sw_if_index));
+                vnet_get_sw_interface_or_null (vnm, sw_if_index));
 }
 
 typedef struct l2fib_dump_walk_ctx_t_
index aa3d5c4..bfd1dcb 100644 (file)
@@ -61,7 +61,7 @@ l2pbb_configure (vlib_main_t * vlib_main,
 
   l2_output_config_t *config = 0;
   vnet_hw_interface_t *hi;
-  hi = vnet_get_sup_hw_interface (vnet_main, sw_if_index);
+  hi = vnet_get_sup_hw_interface_api_visible_or_null (vnet_main, sw_if_index);
 
   if (!hi)
     {
@@ -149,7 +149,7 @@ l2vtr_configure (vlib_main_t * vlib_main, vnet_main_t * vnet_main, u32 sw_if_ind
   u32 push_outer_et;
   u32 cfg_tags;
 
-  hi = vnet_get_sup_hw_interface (vnet_main, sw_if_index);
+  hi = vnet_get_sup_hw_interface_api_visible_or_null (vnet_main, sw_if_index);
   if (!hi || (hi->hw_class_index != ethernet_hw_interface_class.index))
     {
       error = VNET_API_ERROR_INVALID_INTERFACE;        /* non-ethernet interface */
@@ -364,7 +364,7 @@ l2vtr_get (vlib_main_t * vlib_main, vnet_main_t * vnet_main, u32 sw_if_index, u3
   *vtr_tag2 = 0;
   *push_dot1q = 0;
 
-  hi = vnet_get_sup_hw_interface (vnet_main, sw_if_index);
+  hi = vnet_get_sup_hw_interface_api_visible_or_null (vnet_main, sw_if_index);
   if (!hi || (hi->hw_class_index != ethernet_hw_interface_class.index))
     {
       /* non-ethernet interface */
index 47a369e..294192c 100644 (file)
@@ -70,7 +70,8 @@ vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t * a)
   if (a->is_add)
     {
       if (a->sw_if_index != APP_NAMESPACE_INVALID_INDEX
-         && !vnet_get_sw_interface_safe (vnet_get_main (), a->sw_if_index))
+         && !vnet_get_sw_interface_or_null (vnet_get_main (),
+                                            a->sw_if_index))
        return VNET_API_ERROR_INVALID_SW_IF_INDEX;
 
 
index c6427f2..840889d 100644 (file)
@@ -3775,6 +3775,18 @@ static void *vl_api_qos_record_enable_disable_t_print
   FINISH;
 }
 
+#define foreach_no_print_function               \
+_(memclnt_keepalive_reply)
+
+#define _(f)                                    \
+static void * vl_api_ ## f ## _t_print          \
+  (vl_api_ ## f ## _t * mp, void * handle)      \
+{                                               \
+  return handle;                                \
+}
+foreach_no_print_function;
+#undef _
+
 #define foreach_custom_print_no_arg_function                            \
 _(lisp_eid_table_vni_dump)                                              \
 _(lisp_map_resolver_dump)                                               \
@@ -3791,7 +3803,7 @@ static void * vl_api_ ## f ## _t_print                                  \
   s = format (0, "SCRIPT: " #f );                                       \
   FINISH;                                                               \
 }
-foreach_custom_print_no_arg_function
+foreach_custom_print_no_arg_function;
 #undef _
 #define foreach_custom_print_function                                   \
 _(CREATE_LOOPBACK, create_loopback)                                     \
@@ -3993,8 +4005,10 @@ _(DNS_RESOLVE_NAME, dns_resolve_name)                                    \
 _(DNS_RESOLVE_IP, dns_resolve_ip)                                      \
 _(SESSION_RULE_ADD_DEL, session_rule_add_del)                           \
 _(OUTPUT_ACL_SET_INTERFACE, output_acl_set_interface)                   \
-_(QOS_RECORD_ENABLE_DISABLE, qos_record_enable_disable)
-  void
+_(QOS_RECORD_ENABLE_DISABLE, qos_record_enable_disable)                        \
+_(MEMCLNT_KEEPALIVE_REPLY, memclnt_keepalive_reply)
+
+void
 vl_msg_api_custom_dump_configure (api_main_t * am)
 {
 #define _(n,f) am->msg_print_handlers[VL_API_##n]       \