X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvpp-api%2Fvapi%2Fvapi.c;h=8a9c8e3b450833ffb8d1eb3c021b8e898a02536d;hb=b5c0d35f;hp=25c0b3be1d34c28d64108cb1372877955f663baf;hpb=59b2565cd91a67ced650739f36129650830211ac;p=vpp.git diff --git a/src/vpp-api/vapi/vapi.c b/src/vpp-api/vapi/vapi.c index 25c0b3be1d3..8a9c8e3b450 100644 --- a/src/vpp-api/vapi/vapi.c +++ b/src/vpp-api/vapi/vapi.c @@ -29,7 +29,9 @@ #include #include #include -#include +#include + +#include /* we need to use control pings for some stuff and because we're forced to put * the code in headers, we need a way to be able to grab the ids of these @@ -37,6 +39,9 @@ vapi_msg_id_t vapi_msg_id_control_ping = 0; vapi_msg_id_t vapi_msg_id_control_ping_reply = 0; +DEFINE_VAPI_MSG_IDS_MEMCLNT_API_JSON; +DEFINE_VAPI_MSG_IDS_VPE_API_JSON; + struct { size_t count; @@ -81,6 +86,7 @@ struct vapi_ctx_s u16 vl_msg_id_max; vapi_msg_id_t *vl_msg_id_to_vapi_msg_t; bool connected; + bool handle_keepalives; pthread_mutex_t requests_mutex; }; @@ -238,7 +244,7 @@ vapi_lookup_vapi_msg_id_t (vapi_ctx_t ctx, u16 vl_msg_id) { return ctx->vl_msg_id_to_vapi_msg_t[vl_msg_id]; } - return ~0; + return VAPI_INVALID_MSG_ID; } vapi_error_e @@ -257,6 +263,9 @@ vapi_ctx_alloc (vapi_ctx_t * result) { goto fail; } + clib_memset (ctx->vapi_msg_id_t_to_vl_msg_id, ~0, + __vapi_metadata.count * + sizeof (*ctx->vapi_msg_id_t_to_vl_msg_id)); ctx->event_cbs = calloc (__vapi_metadata.count, sizeof (*ctx->event_cbs)); if (!ctx->event_cbs) { @@ -292,12 +301,17 @@ vapi_error_e vapi_connect (vapi_ctx_t ctx, const char *name, const char *chroot_prefix, int max_outstanding_requests, - int response_queue_size, vapi_mode_e mode) + int response_queue_size, vapi_mode_e mode, + bool handle_keepalives) { if (response_queue_size <= 0 || max_outstanding_requests <= 0) { return VAPI_EINVAL; } + if (!clib_mem_get_per_cpu_heap () && !clib_mem_init (0, 1024 * 1024 * 32)) + { + return VAPI_ENOMEM; + } ctx->requests_size = max_outstanding_requests; const size_t size = ctx->requests_size * sizeof (*ctx->requests); void *tmp = realloc (ctx->requests, size); @@ -306,7 +320,7 @@ vapi_connect (vapi_ctx_t ctx, const char *name, return VAPI_ENOMEM; } ctx->requests = tmp; - memset (ctx->requests, 0, size); + clib_memset (ctx->requests, 0, size); /* coverity[MISSING_LOCK] - 177211 requests_mutex is not needed here */ ctx->requests_start = ctx->requests_count = 0; if (chroot_prefix) @@ -336,8 +350,8 @@ vapi_connect (vapi_ctx_t ctx, const char *name, vapi_message_desc_t *m = __vapi_metadata.msgs[i]; u8 scratch[m->name_with_crc_len + 1]; memcpy (scratch, m->name_with_crc, m->name_with_crc_len + 1); - u32 id = vl_api_get_msg_index (scratch); - if (~0 != id) + u32 id = vl_msg_api_get_msg_index (scratch); + if (VAPI_INVALID_MSG_ID != id) { if (id > UINT16_MAX) { @@ -386,6 +400,14 @@ vapi_connect (vapi_ctx_t ctx, const char *name, } ctx->mode = mode; ctx->connected = true; + if (vapi_is_msg_available (ctx, vapi_msg_id_memclnt_keepalive)) + { + ctx->handle_keepalives = handle_keepalives; + } + else + { + ctx->handle_keepalives = false; + } return VAPI_OK; fail: vl_client_disconnect (); @@ -425,7 +447,7 @@ vapi_send (vapi_ctx_t ctx, void *msg) goto out; } int tmp; - unix_shared_memory_queue_t *q = api_main.shmem_hdr->vl_input_queue; + svm_queue_t *q = vlibapi_get_main ()->shmem_hdr->vl_input_queue; #if VAPI_DEBUG unsigned msgid = be16toh (*(u16 *) msg); if (msgid <= ctx->vl_msg_id_max) @@ -446,13 +468,14 @@ vapi_send (vapi_ctx_t ctx, void *msg) VAPI_DBG ("send msg@%p:%u[UNKNOWN]", msg, msgid); } #endif - tmp = unix_shared_memory_queue_add (q, (u8 *) & msg, - VAPI_MODE_BLOCKING == - ctx->mode ? 0 : 1); + tmp = svm_queue_add (q, (u8 *) & msg, + VAPI_MODE_BLOCKING == ctx->mode ? 0 : 1); if (tmp < 0) { rv = VAPI_EAGAIN; } + else + VL_MSG_API_POISON (msg); out: VAPI_DBG ("vapi_send() rv = %d", rv); return rv; @@ -467,7 +490,7 @@ vapi_send2 (vapi_ctx_t ctx, void *msg1, void *msg2) rv = VAPI_EINVAL; goto out; } - unix_shared_memory_queue_t *q = api_main.shmem_hdr->vl_input_queue; + svm_queue_t *q = vlibapi_get_main ()->shmem_hdr->vl_input_queue; #if VAPI_DEBUG unsigned msgid1 = be16toh (*(u16 *) msg1); unsigned msgid2 = be16toh (*(u16 *) msg2); @@ -491,27 +514,29 @@ vapi_send2 (vapi_ctx_t ctx, void *msg1, void *msg2) } VAPI_DBG ("send two: %u[%s], %u[%s]", msgid1, name1, msgid2, name2); #endif - int tmp = unix_shared_memory_queue_add2 (q, (u8 *) & msg1, (u8 *) & msg2, - VAPI_MODE_BLOCKING == - ctx->mode ? 0 : 1); + int tmp = svm_queue_add2 (q, (u8 *) & msg1, (u8 *) & msg2, + VAPI_MODE_BLOCKING == ctx->mode ? 0 : 1); if (tmp < 0) { rv = VAPI_EAGAIN; } + else + VL_MSG_API_POISON (msg1); out: VAPI_DBG ("vapi_send() rv = %d", rv); return rv; } vapi_error_e -vapi_recv (vapi_ctx_t ctx, void **msg, size_t * msg_size) +vapi_recv (vapi_ctx_t ctx, void **msg, size_t * msg_size, + svm_q_conditional_wait_t cond, u32 time) { if (!ctx || !ctx->connected || !msg || !msg_size) { return VAPI_EINVAL; } vapi_error_e rv = VAPI_OK; - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); uword data; if (am->our_pid == 0) @@ -519,11 +544,15 @@ vapi_recv (vapi_ctx_t ctx, void **msg, size_t * msg_size) return VAPI_EINVAL; } - unix_shared_memory_queue_t *q = am->vl_input_queue; + svm_queue_t *q = am->vl_input_queue; +again: VAPI_DBG ("doing shm queue sub"); - int tmp = unix_shared_memory_queue_sub (q, (u8 *) & data, 0); + + int tmp = svm_queue_sub (q, (u8 *) & data, cond, time); + if (tmp == 0) { + VL_MSG_API_UNPOISON ((void *) data); #if VAPI_DEBUG_ALLOC vapi_add_to_be_freed ((void *) data); #endif @@ -556,6 +585,30 @@ vapi_recv (vapi_ctx_t ctx, void **msg, size_t * msg_size) VAPI_DBG ("recv msg@%p:%u[UNKNOWN]", *msg, msgid); } #endif + if (ctx->handle_keepalives) + { + unsigned msgid = be16toh (*(u16 *) * msg); + if (msgid == + vapi_lookup_vl_msg_id (ctx, vapi_msg_id_memclnt_keepalive)) + { + vapi_msg_memclnt_keepalive_reply *reply = NULL; + do + { + reply = vapi_msg_alloc (ctx, sizeof (*reply)); + } + while (!reply); + reply->header.context = vapi_get_client_index (ctx); + reply->header._vl_msg_id = + vapi_lookup_vl_msg_id (ctx, + vapi_msg_id_memclnt_keepalive_reply); + reply->payload.retval = 0; + vapi_msg_memclnt_keepalive_reply_hton (reply); + while (VAPI_EAGAIN == vapi_send (ctx, reply)); + vapi_msg_free (ctx, *msg); + VAPI_DBG ("autohandled memclnt_keepalive"); + goto again; + } + } } else { @@ -600,14 +653,13 @@ vapi_dispatch_response (vapi_ctx_t ctx, vapi_msg_id_t id, { VAPI_ERR ("No response to req with context=%u", (unsigned) ctx->requests[tmp].context); - ctx->requests[ctx->requests_start].callback (ctx, - ctx->requests + ctx->requests[ctx->requests_start].callback (ctx, ctx->requests [ctx-> requests_start].callback_ctx, VAPI_ENORESP, true, NULL); - memset (&ctx->requests[ctx->requests_start], 0, - sizeof (ctx->requests[ctx->requests_start])); + clib_memset (&ctx->requests[ctx->requests_start], 0, + sizeof (ctx->requests[ctx->requests_start])); ++ctx->requests_start; --ctx->requests_count; if (ctx->requests_start == ctx->requests_size) @@ -648,8 +700,8 @@ vapi_dispatch_response (vapi_ctx_t ctx, vapi_msg_id_t id, } if (is_last) { - memset (&ctx->requests[ctx->requests_start], 0, - sizeof (ctx->requests[ctx->requests_start])); + clib_memset (&ctx->requests[ctx->requests_start], 0, + sizeof (ctx->requests[ctx->requests_start])); ++ctx->requests_start; --ctx->requests_count; if (ctx->requests_start == ctx->requests_size) @@ -702,7 +754,7 @@ vapi_dispatch_one (vapi_ctx_t ctx) VAPI_DBG ("vapi_dispatch_one()"); void *msg; size_t size; - vapi_error_e rv = vapi_recv (ctx, &msg, &size); + vapi_error_e rv = vapi_recv (ctx, &msg, &size, SVM_Q_WAIT, 0); if (VAPI_OK != rv) { VAPI_DBG ("vapi_recv failed with rv=%d", rv); @@ -716,7 +768,7 @@ vapi_dispatch_one (vapi_ctx_t ctx) vapi_msg_free (ctx, msg); return VAPI_EINVAL; } - if (~0 == (unsigned) ctx->vl_msg_id_to_vapi_msg_t[vpp_id]) + if (VAPI_INVALID_MSG_ID == (unsigned) ctx->vl_msg_id_to_vapi_msg_t[vpp_id]) { VAPI_ERR ("Unknown msg ID received, id `%u' marked as not supported", (unsigned) vpp_id); @@ -808,7 +860,7 @@ vapi_lookup_vl_msg_id (vapi_ctx_t ctx, vapi_msg_id_t id) int vapi_get_client_index (vapi_ctx_t ctx) { - return api_main.my_client_index; + return vlibapi_get_main ()->my_client_index; } bool