aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/sflow/sflow_vapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/sflow/sflow_vapi.c')
-rw-r--r--src/plugins/sflow/sflow_vapi.c226
1 files changed, 0 insertions, 226 deletions
diff --git a/src/plugins/sflow/sflow_vapi.c b/src/plugins/sflow/sflow_vapi.c
deleted file mode 100644
index cdc89a54c80..00000000000
--- a/src/plugins/sflow/sflow_vapi.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2024 InMon Corp.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sflow/sflow_vapi.h>
-
-#ifdef SFLOW_USE_VAPI
-
-#include <vlibapi/api.h>
-#include <vlibmemory/api.h>
-#include <vpp/app/version.h>
-#include <stdbool.h>
-
-#include <vapi/vapi.h>
-#include <vapi/memclnt.api.vapi.h>
-#include <vapi/vlib.api.vapi.h>
-
-#ifdef included_interface_types_api_types_h
-#define defined_vapi_enum_if_status_flags
-#define defined_vapi_enum_mtu_proto
-#define defined_vapi_enum_link_duplex
-#define defined_vapi_enum_sub_if_flags
-#define defined_vapi_enum_rx_mode
-#define defined_vapi_enum_if_type
-#define defined_vapi_enum_direction
-#endif
-#include <vapi/lcp.api.vapi.h>
-
-DEFINE_VAPI_MSG_IDS_LCP_API_JSON;
-
-static vapi_error_e
-my_pair_get_cb (struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv,
- bool is_last, vapi_payload_lcp_itf_pair_get_v2_reply *reply)
-{
- // this is a no-op, but it seems like it's presence is still required. For
- // example, it is called if the pair lookup does not find anything.
- return VAPI_OK;
-}
-
-static vapi_error_e
-my_pair_details_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
- vapi_error_e rv, bool is_last,
- vapi_payload_lcp_itf_pair_details *details)
-{
- sflow_per_interface_data_t *sfif =
- (sflow_per_interface_data_t *) callback_ctx;
- // Setting this here will mean it is sent to hsflowd with the interface
- // counters.
- sfif->linux_if_index = details->vif_index;
- return VAPI_OK;
-}
-
-static vapi_error_e
-sflow_vapi_connect (sflow_vapi_client_t *vac)
-{
- vapi_error_e rv = VAPI_OK;
- vapi_ctx_t ctx = vac->vapi_ctx;
- if (ctx == NULL)
- {
- // first time - open and connect.
- if ((rv = vapi_ctx_alloc (&ctx)) != VAPI_OK)
- {
- SFLOW_ERR ("vap_ctx_alloc() returned %d", rv);
- }
- else
- {
- vac->vapi_ctx = ctx;
- if ((rv = vapi_connect_from_vpp (
- ctx, "api_from_sflow_plugin", SFLOW_VAPI_MAX_REQUEST_Q,
- SFLOW_VAPI_MAX_RESPONSE_Q, VAPI_MODE_BLOCKING, true)) !=
- VAPI_OK)
- {
- SFLOW_ERR ("vapi_connect_from_vpp() returned %d", rv);
- }
- else
- {
- // Connected - but is there a handler for the request we want to
- // send?
- if (!vapi_is_msg_available (ctx,
- vapi_msg_id_lcp_itf_pair_add_del_v2))
- {
- SFLOW_WARN ("vapi_is_msg_available() returned false => "
- "linux-cp plugin not loaded");
- rv = VAPI_EUSER;
- }
- }
- }
- }
- return rv;
-}
-
-// in forked thread
-static void *
-get_lcp_itf_pairs (void *magic)
-{
- sflow_vapi_client_t *vac = magic;
- vapi_error_e rv = VAPI_OK;
-
- sflow_per_interface_data_t *intfs = vac->vapi_itfs;
- vlib_set_thread_name (SFLOW_VAPI_THREAD_NAME);
- if ((rv = sflow_vapi_connect (vac)) != VAPI_OK)
- {
- vac->vapi_unavailable = true;
- }
- else
- {
- vapi_ctx_t ctx = vac->vapi_ctx;
-
- for (int ii = 1; ii < vec_len (intfs); ii++)
- {
- sflow_per_interface_data_t *sfif = vec_elt_at_index (intfs, ii);
- if (sfif && sfif->sflow_enabled)
- {
- // TODO: if we try non-blocking we might not be able to just pour
- // all the requests in here. Might be better to do them one at a
- // time - e.g. when we poll for counters.
- vapi_msg_lcp_itf_pair_get_v2 *msg =
- vapi_alloc_lcp_itf_pair_get_v2 (ctx);
- if (msg)
- {
- msg->payload.sw_if_index = sfif->sw_if_index;
- if ((rv = vapi_lcp_itf_pair_get_v2 (ctx, msg, my_pair_get_cb,
- sfif, my_pair_details_cb,
- sfif)) != VAPI_OK)
- {
- SFLOW_ERR ("vapi_lcp_itf_pair_get_v2 returned %d", rv);
- // vapi.h: "message must be freed by vapi_msg_free if not
- // consumed by vapi_send"
- vapi_msg_free (ctx, msg);
- }
- }
- }
- }
- // We no longer disconnect or free the client structures
- // vapi_disconnect_from_vpp (ctx);
- // vapi_ctx_free (ctx);
- }
- // indicate that we are done - more portable that using pthread_tryjoin_np()
- vac->vapi_request_status = (int) rv;
- clib_atomic_store_rel_n (&vac->vapi_request_active, false);
- // TODO: how to tell if heap-allocated data is stored separately per thread?
- // And if so, how to tell the allocator to GC all data for the thread when it
- // exits?
- return (void *) rv;
-}
-
-int
-sflow_vapi_read_linux_if_index_numbers (sflow_vapi_client_t *vac,
- sflow_per_interface_data_t *itfs)
-{
-
-#ifdef SFLOW_VAPI_TEST_PLUGIN_SYMBOL
- // don't even fork the query thread if the symbol is not there
- if (!vlib_get_plugin_symbol ("linux_cp_plugin.so", "lcp_itf_pair_get"))
- {
- return false;
- }
-#endif
- // previous query is done and results extracted?
- int req_active = clib_atomic_load_acq_n (&vac->vapi_request_active);
- if (req_active == false && vac->vapi_itfs == NULL)
- {
- // make a copy of the current interfaces vector for the lookup thread to
- // write into
- vac->vapi_itfs = vec_dup (itfs);
- pthread_attr_t attr;
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize (&attr, VLIB_THREAD_STACK_SIZE);
- vac->vapi_request_active = true;
- pthread_create (&vac->vapi_thread, &attr, get_lcp_itf_pairs, vac);
- pthread_attr_destroy (&attr);
- return true;
- }
- return false;
-}
-
-int
-sflow_vapi_check_for_linux_if_index_results (sflow_vapi_client_t *vac,
- sflow_per_interface_data_t *itfs)
-{
- // request completed?
- // TODO: if we use non-blocking mode do we have to call something here to
- // receive results?
- int req_active = clib_atomic_load_acq_n (&vac->vapi_request_active);
- if (req_active == false && vac->vapi_itfs != NULL)
- {
- // yes, extract what we learned
- // TODO: would not have to do this if vector were array of pointers
- // to sflow_per_interface_data_t rather than an actual array, but
- // it does mean we have very clear separation between the threads.
- for (int ii = 1; ii < vec_len (vac->vapi_itfs); ii++)
- {
- sflow_per_interface_data_t *sfif1 =
- vec_elt_at_index (vac->vapi_itfs, ii);
- sflow_per_interface_data_t *sfif2 = vec_elt_at_index (itfs, ii);
- if (sfif1 && sfif2 && sfif1->sflow_enabled && sfif2->sflow_enabled)
- sfif2->linux_if_index = sfif1->linux_if_index;
- }
- vec_free (vac->vapi_itfs);
- vac->vapi_itfs = NULL;
- return true;
- }
- return false;
-}
-
-#endif /* SFLOW_USE_VAPI */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */