summaryrefslogtreecommitdiffstats
path: root/src/plugins/hs_apps/sapi/vpp_echo_bapi.c
diff options
context:
space:
mode:
authorNathan Skrzypczak <nathan.skrzypczak@gmail.com>2019-08-05 13:43:31 +0200
committerFlorin Coras <florin.coras@gmail.com>2019-08-16 14:47:38 +0000
commitecd1fc7dfa6a36d1774f71093380b3548a22346b (patch)
tree6ed2568a9950e955c4826941216af153c5b08b2f /src/plugins/hs_apps/sapi/vpp_echo_bapi.c
parentd25d364d2bc146d3e17ab7c4d558bcb0ce138b89 (diff)
hsa: Refactor quic_echo to allow other protocols
Type: refactor Change-Id: Iaef9091e1d057110530255e644fad1c298418966 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
Diffstat (limited to 'src/plugins/hs_apps/sapi/vpp_echo_bapi.c')
-rw-r--r--src/plugins/hs_apps/sapi/vpp_echo_bapi.c439
1 files changed, 439 insertions, 0 deletions
diff --git a/src/plugins/hs_apps/sapi/vpp_echo_bapi.c b/src/plugins/hs_apps/sapi/vpp_echo_bapi.c
new file mode 100644
index 00000000000..dafcd8a42b6
--- /dev/null
+++ b/src/plugins/hs_apps/sapi/vpp_echo_bapi.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2019 Cisco and/or its affiliates.
+ * 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 <stdio.h>
+#include <signal.h>
+
+#include <hs_apps/sapi/vpp_echo_common.h>
+
+/*
+ *
+ * Binary API Messages
+ *
+ */
+
+void
+echo_send_attach (echo_main_t * em)
+{
+ vl_api_application_attach_t *bmp;
+ vl_api_application_tls_cert_add_t *cert_mp;
+ vl_api_application_tls_key_add_t *key_mp;
+
+ bmp = vl_msg_api_alloc (sizeof (*bmp));
+ clib_memset (bmp, 0, sizeof (*bmp));
+
+ bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
+ bmp->client_index = em->my_client_index;
+ bmp->context = ntohl (0xfeedface);
+ bmp->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
+ bmp->options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ADD_SEGMENT;
+ bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = 16;
+ bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = em->fifo_size;
+ bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = em->fifo_size;
+ bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = 128 << 20;
+ bmp->options[APP_OPTIONS_SEGMENT_SIZE] = 256 << 20;
+ bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = 256;
+ if (em->appns_id)
+ {
+ bmp->namespace_id_len = vec_len (em->appns_id);
+ clib_memcpy_fast (bmp->namespace_id, em->appns_id,
+ bmp->namespace_id_len);
+ bmp->options[APP_OPTIONS_FLAGS] |= em->appns_flags;
+ bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = em->appns_secret;
+ }
+ vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
+
+ cert_mp = vl_msg_api_alloc (sizeof (*cert_mp) + test_srv_crt_rsa_len);
+ clib_memset (cert_mp, 0, sizeof (*cert_mp));
+ cert_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_CERT_ADD);
+ cert_mp->client_index = em->my_client_index;
+ cert_mp->context = ntohl (0xfeedface);
+ cert_mp->cert_len = clib_host_to_net_u16 (test_srv_crt_rsa_len);
+ clib_memcpy_fast (cert_mp->cert, test_srv_crt_rsa, test_srv_crt_rsa_len);
+ vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & cert_mp);
+
+ key_mp = vl_msg_api_alloc (sizeof (*key_mp) + test_srv_key_rsa_len);
+ clib_memset (key_mp, 0, sizeof (*key_mp) + test_srv_key_rsa_len);
+ key_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_KEY_ADD);
+ key_mp->client_index = em->my_client_index;
+ key_mp->context = ntohl (0xfeedface);
+ key_mp->key_len = clib_host_to_net_u16 (test_srv_key_rsa_len);
+ clib_memcpy_fast (key_mp->key, test_srv_key_rsa, test_srv_key_rsa_len);
+ vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & key_mp);
+}
+
+void
+echo_send_detach (echo_main_t * em)
+{
+ vl_api_application_detach_t *bmp;
+ bmp = vl_msg_api_alloc (sizeof (*bmp));
+ clib_memset (bmp, 0, sizeof (*bmp));
+
+ bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
+ bmp->client_index = em->my_client_index;
+ bmp->context = ntohl (0xfeedface);
+ vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
+}
+
+void
+echo_send_listen (echo_main_t * em)
+{
+ vl_api_bind_uri_t *bmp;
+ bmp = vl_msg_api_alloc (sizeof (*bmp));
+ clib_memset (bmp, 0, sizeof (*bmp));
+
+ bmp->_vl_msg_id = ntohs (VL_API_BIND_URI);
+ bmp->client_index = em->my_client_index;
+ bmp->context = ntohl (0xfeedface);
+ memcpy (bmp->uri, em->uri, vec_len (em->uri));
+ vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
+}
+
+void
+echo_send_unbind (echo_main_t * em)
+{
+ vl_api_unbind_uri_t *ump;
+
+ ump = vl_msg_api_alloc (sizeof (*ump));
+ clib_memset (ump, 0, sizeof (*ump));
+
+ ump->_vl_msg_id = ntohs (VL_API_UNBIND_URI);
+ ump->client_index = em->my_client_index;
+ memcpy (ump->uri, em->uri, vec_len (em->uri));
+ vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & ump);
+}
+
+void
+echo_send_connect (u8 * uri, u32 opaque)
+{
+ echo_main_t *em = &echo_main;
+ vl_api_connect_uri_t *cmp;
+ cmp = vl_msg_api_alloc (sizeof (*cmp));
+ clib_memset (cmp, 0, sizeof (*cmp));
+ cmp->_vl_msg_id = ntohs (VL_API_CONNECT_URI);
+ cmp->client_index = em->my_client_index;
+ cmp->context = ntohl (opaque);
+ memcpy (cmp->uri, uri, vec_len (uri));
+ vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & cmp);
+}
+
+void
+echo_send_disconnect_session (u64 handle, u32 opaque)
+{
+ echo_main_t *em = &echo_main;
+ vl_api_disconnect_session_t *dmp;
+ dmp = vl_msg_api_alloc (sizeof (*dmp));
+ clib_memset (dmp, 0, sizeof (*dmp));
+ dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
+ dmp->client_index = em->my_client_index;
+ dmp->handle = handle;
+ ECHO_LOG (1, "Disconnect session 0x%lx", dmp->handle);
+ vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & dmp);
+}
+
+/*
+ *
+ * Helpers
+ *
+ */
+
+static int
+ssvm_segment_attach (char *name, ssvm_segment_type_t type, int fd)
+{
+ fifo_segment_create_args_t _a, *a = &_a;
+ fifo_segment_main_t *sm = &echo_main.segment_main;
+ int rv;
+
+ clib_memset (a, 0, sizeof (*a));
+ a->segment_name = (char *) name;
+ a->segment_type = type;
+
+ if (type == SSVM_SEGMENT_MEMFD)
+ a->memfd_fd = fd;
+
+ if ((rv = fifo_segment_attach (sm, a)))
+ return rv;
+ vec_reset_length (a->new_segment_indices);
+ return 0;
+}
+
+static inline void
+echo_segment_handle_add_del (echo_main_t * em, u64 segment_handle, u8 add)
+{
+ clib_spinlock_lock (&em->segment_handles_lock);
+ if (add)
+ hash_set (em->shared_segment_handles, segment_handle, 1);
+ else
+ hash_unset (em->shared_segment_handles, segment_handle);
+ clib_spinlock_unlock (&em->segment_handles_lock);
+}
+
+/*
+ *
+ * Binary API callbacks
+ *
+ */
+
+static void
+vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
+ mp)
+{
+ echo_main_t *em = &echo_main;
+ int *fds = 0, i;
+ u32 n_fds = 0;
+ u64 segment_handle;
+ segment_handle = clib_net_to_host_u64 (mp->segment_handle);
+ ECHO_LOG (1, "Attached returned app %u", htons (mp->app_index));
+
+ if (mp->retval)
+ {
+ ECHO_FAIL ("attach failed: %U", format_api_error,
+ clib_net_to_host_u32 (mp->retval));
+ return;
+ }
+
+ if (mp->segment_name_length == 0)
+ {
+ ECHO_FAIL ("segment_name_length zero");
+ return;
+ }
+
+ ASSERT (mp->app_event_queue_address);
+ em->our_event_queue = uword_to_pointer (mp->app_event_queue_address,
+ svm_msg_q_t *);
+
+ if (mp->n_fds)
+ {
+ vec_validate (fds, mp->n_fds);
+ if (vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5))
+ {
+ ECHO_FAIL ("vl_socket_client_recv_fd_msg failed");
+ goto failed;
+ }
+
+ if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
+ if (ssvm_segment_attach (0, SSVM_SEGMENT_MEMFD, fds[n_fds++]))
+ {
+ ECHO_FAIL ("svm_fifo_segment_attach failed");
+ goto failed;
+ }
+
+ if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
+ if (ssvm_segment_attach ((char *) mp->segment_name,
+ SSVM_SEGMENT_MEMFD, fds[n_fds++]))
+ {
+ ECHO_FAIL ("svm_fifo_segment_attach ('%s') failed",
+ mp->segment_name);
+ goto failed;
+ }
+ if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
+ svm_msg_q_set_consumer_eventfd (em->our_event_queue, fds[n_fds++]);
+
+ vec_free (fds);
+ }
+ else
+ {
+ if (ssvm_segment_attach ((char *) mp->segment_name, SSVM_SEGMENT_SHM,
+ -1))
+ {
+ ECHO_FAIL ("svm_fifo_segment_attach ('%s') failed",
+ mp->segment_name);
+ return;
+ }
+ }
+ echo_segment_handle_add_del (em, segment_handle, 1 /* add */ );
+ ECHO_LOG (1, "Mapped segment 0x%lx", segment_handle);
+
+ em->state = STATE_ATTACHED;
+ return;
+failed:
+ for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
+ close (fds[i]);
+ vec_free (fds);
+}
+
+static void
+vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
+ mp)
+{
+ if (mp->retval)
+ {
+ ECHO_FAIL ("detach returned with err: %d", mp->retval);
+ return;
+ }
+ echo_main.state = STATE_DETACHED;
+}
+
+
+static void
+vl_api_unmap_segment_t_handler (vl_api_unmap_segment_t * mp)
+{
+ echo_main_t *em = &echo_main;
+ u64 segment_handle = clib_net_to_host_u64 (mp->segment_handle);
+ echo_segment_handle_add_del (em, segment_handle, 0 /* add */ );
+ ECHO_LOG (1, "Unmaped segment 0x%lx", segment_handle);
+}
+
+static void
+vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
+{
+ fifo_segment_main_t *sm = &echo_main.segment_main;
+ fifo_segment_create_args_t _a, *a = &_a;
+ echo_main_t *em = &echo_main;
+ int *fds = 0, i;
+ char *seg_name = (char *) mp->segment_name;
+ u64 segment_handle = clib_net_to_host_u64 (mp->segment_handle);
+
+ if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
+ {
+ vec_validate (fds, 1);
+ if (vl_socket_client_recv_fd_msg (fds, 1, 5))
+ {
+ ECHO_FAIL ("vl_socket_client_recv_fd_msg failed");
+ goto failed;
+ }
+
+ if (ssvm_segment_attach (seg_name, SSVM_SEGMENT_MEMFD, fds[0]))
+ {
+ ECHO_FAIL ("svm_fifo_segment_attach ('%s')"
+ "failed on SSVM_SEGMENT_MEMFD", seg_name);
+ goto failed;
+ }
+ vec_free (fds);
+ }
+ else
+ {
+ clib_memset (a, 0, sizeof (*a));
+ a->segment_name = seg_name;
+ a->segment_size = mp->segment_size;
+ /* Attach to the segment vpp created */
+ if (fifo_segment_attach (sm, a))
+ {
+ ECHO_FAIL ("svm_fifo_segment_attach ('%s') failed", seg_name);
+ goto failed;
+ }
+ }
+ echo_segment_handle_add_del (em, segment_handle, 1 /* add */ );
+ ECHO_LOG (1, "Mapped segment 0x%lx", segment_handle);
+ return;
+
+failed:
+ for (i = 0; i < vec_len (fds); i++)
+ close (fds[i]);
+ vec_free (fds);
+}
+
+static void
+vl_api_bind_uri_reply_t_handler (vl_api_bind_uri_reply_t * mp)
+{
+ if (mp->retval)
+ {
+ ECHO_FAIL ("bind failed: %U", format_api_error,
+ clib_net_to_host_u32 (mp->retval));
+ }
+}
+
+static void
+vl_api_unbind_uri_reply_t_handler (vl_api_unbind_uri_reply_t * mp)
+{
+ echo_session_t *listen_session;
+ echo_main_t *em = &echo_main;
+ if (mp->retval != 0)
+ {
+ ECHO_FAIL ("returned %d", ntohl (mp->retval));
+ return;
+ }
+ listen_session = pool_elt_at_index (em->sessions, em->listen_session_index);
+ em->proto_cb_vft->cleanup_cb (listen_session, 0 /* parent_died */ );
+ em->state = STATE_DISCONNECTED;
+}
+
+static void
+vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
+ mp)
+{
+ echo_main_t *em = &echo_main;
+ echo_session_t *s;
+
+ if (mp->retval)
+ {
+ ECHO_FAIL ("vpp complained about disconnect: %d", ntohl (mp->retval));
+ return;
+ }
+
+ ECHO_LOG (1, "Got disonnected reply for session 0x%lx", mp->handle);
+ if (!(s = echo_get_session_from_handle (em, mp->handle)))
+ return;
+ em->proto_cb_vft->disconnected_reply_cb (s);
+}
+
+static void
+ vl_api_application_tls_cert_add_reply_t_handler
+ (vl_api_application_tls_cert_add_reply_t * mp)
+{
+ if (mp->retval)
+ ECHO_FAIL ("failed to add tls cert");
+}
+
+static void
+ vl_api_application_tls_key_add_reply_t_handler
+ (vl_api_application_tls_key_add_reply_t * mp)
+{
+ if (mp->retval)
+ ECHO_FAIL ("failed to add tls key");
+}
+
+static void
+vl_api_connect_uri_reply_t_handler (vl_api_connect_uri_reply_t * mp)
+{
+ echo_main_t *em = &echo_main;
+ if (mp->retval && (em->proto_cb_vft->connected_cb))
+ em->proto_cb_vft->connected_cb ((session_connected_bundled_msg_t *) mp,
+ mp->context, 1 /* is_failed */ );
+}
+
+#define foreach_quic_echo_msg \
+_(BIND_URI_REPLY, bind_uri_reply) \
+_(UNBIND_URI_REPLY, unbind_uri_reply) \
+_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
+_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
+_(APPLICATION_DETACH_REPLY, application_detach_reply) \
+_(MAP_ANOTHER_SEGMENT, map_another_segment) \
+_(UNMAP_SEGMENT, unmap_segment) \
+_(APPLICATION_TLS_CERT_ADD_REPLY, application_tls_cert_add_reply) \
+_(APPLICATION_TLS_KEY_ADD_REPLY, application_tls_key_add_reply) \
+_(CONNECT_URI_REPLY, connect_uri_reply) \
+
+void
+echo_api_hookup (echo_main_t * em)
+{
+#define _(N,n) \
+ vl_msg_api_set_handlers(VL_API_##N, #n, \
+ vl_api_##n##_t_handler, \
+ vl_noop_handler, \
+ vl_api_##n##_t_endian, \
+ vl_api_##n##_t_print, \
+ sizeof(vl_api_##n##_t), 1);
+ foreach_quic_echo_msg;
+#undef _
+}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */